打开文件对话框中有些文件无法显示

paschen 2015-12-24 05:38:52
加精
为何打开文件对话框中有些文件显示不出来
比如这个文件: C:\Windows\System32\ActionQueue.dll
在其他程序打开对话框中就可以看得到,但我写的就不行
另外,以下这句话也执行失败:

CreateFile("C:\\Windows\\System32\\ActionQueue.dll", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

GetLastError得到的结果是2(不存在该文件)

这张图是我程序的:



这张图是其他程序的:



看了下这个DLL,不是隐藏的,也不是只读的,之前以为是dwFlag参数没有设置对,后来各种试了半天还是出不来
...全文
1845 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 2015-12-28
  • 打赏
  • 举报
回复
引用 24 楼 BeanJoy 的回复:
此帖的重点不在于system32和syswow64,而在于楼主提到了TLS,让我多学了点知识,感谢。
不过还是zzz3265给我指出了问题,我才想到的,在此谢过 另外TLS也是前段时间看PE文件中的TLS表才了解的
lx624909677 2015-12-28
  • 打赏
  • 举报
回复
之前看错了
BeanJoy 2015-12-28
  • 打赏
  • 举报
回复
此帖的重点不在于system32和syswow64,而在于楼主提到了TLS,让我多学了点知识,感谢。
全哥爱你 2015-12-27
  • 打赏
  • 举报
回复
这个情况我也有!
paschen 2015-12-27
  • 打赏
  • 举报
回复
引用 22 楼 lx624909677 的回复:
"为何打开文件对话框中有些文件显示不出来"这个不是你问的第一个问题吗?我的那个图就是打开文件对话框,但是可以显示出你说的那个dll呀
你的哪里显示有C:\Windows\System32\ActionQueue.dll这个dll
lx624909677 2015-12-27
  • 打赏
  • 举报
回复
"为何打开文件对话框中有些文件显示不出来"这个不是你问的第一个问题吗?我的那个图就是打开文件对话框,但是可以显示出你说的那个dll呀
qq_28230789 2015-12-27
  • 打赏
  • 举报
回复
看不懂,打打酱油吧。。。。。
paschen 2015-12-26
  • 打赏
  • 举报
回复
引用 18 楼 lx624909677 的回复:
[quote=引用 17 楼 paschen 的回复:] [quote=引用 16 楼 lx624909677 的回复:] 是这种选择文件对话框出不显示那个DLL吗?
对,WINDWOS的通用打开/保存文件对话框[/quote] 我这个就是用的CFileDialog 类来打开的对话框,里面有你说的那个文件呀,也是64位系统 [/quote] CFileDialog一样的,他内部调用的仍然是GetOpenFileName 我举例的文件是那个ActionQueue 1楼说的很好,其实是被重定位了,你在System32文件夹看到的其实是SysWow64文件夹中的内容 另外这几个贴是我后来看的,觉得挺不错,给大家分享下: http://blog.csdn.net/magictong/article/details/41082663 http://blog.csdn.net/xiunai78/article/details/8208250
lx624909677 2015-12-26
  • 打赏
  • 举报
回复
引用 17 楼 paschen 的回复:
[quote=引用 16 楼 lx624909677 的回复:] 是这种选择文件对话框出不显示那个DLL吗?
对,WINDWOS的通用打开/保存文件对话框[/quote] 我这个就是用的CFileDialog 类来打开的对话框,里面有你说的那个文件呀,也是64位系统
paschen 2015-12-25
  • 打赏
  • 举报
回复
谢谢,已经可以了,但打开对话框的重定向还是不对,以下测试代码:

BOOL EnableX64FileRedirect(BOOL bEnable)
{
	typedef BOOL (__stdcall *Fun_Wow64DisableWow64FsRedirection)(PVOID*);  
	typedef BOOL (__stdcall *Fun_Wow64RevertWow64FsRedirection)(PVOID);   
	static    Fun_Wow64DisableWow64FsRedirection    _Wow64DisableWow64FsRedirection = NULL;
	static    Fun_Wow64RevertWow64FsRedirection    _Wow64RevertWow64FsRedirection = NULL;
	static    VOID        *s_pOldVal = NULL;
	BOOL    bRetVal;

	if(_Wow64DisableWow64FsRedirection == NULL || _Wow64RevertWow64FsRedirection == NULL)
	{
		HINSTANCE hinstLib; 
		hinstLib = LoadLibrary(_T("Kernel32.dll")); 
		_Wow64DisableWow64FsRedirection = (Fun_Wow64DisableWow64FsRedirection) GetProcAddress(hinstLib, "Wow64DisableWow64FsRedirection");
		_Wow64RevertWow64FsRedirection = (Fun_Wow64RevertWow64FsRedirection) GetProcAddress(hinstLib, "Wow64RevertWow64FsRedirection");
	}
	if(_Wow64DisableWow64FsRedirection == NULL || _Wow64RevertWow64FsRedirection == NULL)
		return FALSE;

	if(bEnable)
	{
		bRetVal = _Wow64RevertWow64FsRedirection(&s_pOldVal);
	}
	else
	{
		bRetVal = _Wow64DisableWow64FsRedirection(&s_pOldVal);
	}

	return bRetVal;
}

int main()
{
	if(!EnableX64FileRedirect(FALSE))
		return 0;

	//测试1
	HANDLE hFile = ::CreateFile(_T("C:\\Windows\\System32\\ActionQueue.dll"), GENERIC_READ, 
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	//测试2
	TCHAR strFile[MAX_PATH];
	OPENFILENAMEA ofn;
	ZeroMemory(&ofn, sizeof(OPENFILENAME));  
	ofn.lStructSize = sizeof(OPENFILENAME);  
	ofn.lpstrFile = strFile;
	ofn.nMaxFile = MAX_PATH;
	ofn.lpstrInitialDir = _T("C:\\Windows\\System32");
	ofn.lpstrFile[0] = _T('\0');
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_FORCESHOWHIDDEN;
	GetOpenFileName(&ofn);

	return 1;
}
发现现在用CreateFile成功了,说明CreateFile时重定向已经关闭了,但是在打开文件对话框中仍然定位到了SysWOW64文件夹
BeanJoy 2015-12-25
  • 打赏
  • 举报
回复
引用 2 楼 paschen 的回复:
[quote=引用 1 楼 zzz3265 的回复:] 如果系统是64位, 容易被被系统的重定向所误导, ... 感谢您的回答,应该是这个原因了,我系统确实是64位 刚试了一下,提示找不到NSys::GetDllProcAdders这个函数 网上完全找不到这个函数资料,是否需要包含什么头文件
其实就是动态调用而已: 试试这样:

HINSTANCE hinstLib; 
hinstLib = LoadLibrary(_T("Kernel32.dll")); 
_Wow64DisableWow64FsRedirection = (Fun_Wow64DisableWow64FsRedirection) GetProcAddress(hinstLib, "Wow64DisableWow64FsRedirection"); 
paschen 2015-12-25
  • 打赏
  • 举报
回复
引用 1 楼 zzz3265 的回复:
如果系统是64位, 容易被被系统的重定向所误导, 如果是64位系统请继续看, 否则请无视以下 32位程序在64位系统直接访问 C:\Windows\System32 会被重定向到 C:\Windows\SysWOW64 除了文件, 还有注册表等都会被重定向到其他位置, 如果要直接访问System32 目录可以使用未公开的一些API: Wow64DisableWow64FsRedirection, Wow64RevertWow64FsRedirection..

BOOL	NSys::EnableX64FileRedirect(BOOL bEnable)
{
	typedef BOOL (__stdcall *Fun_Wow64DisableWow64FsRedirection)(PVOID*);  
	typedef BOOL (__stdcall *Fun_Wow64RevertWow64FsRedirection)(PVOID);   
	static	Fun_Wow64DisableWow64FsRedirection	_Wow64DisableWow64FsRedirection = NULL;
	static	Fun_Wow64RevertWow64FsRedirection	_Wow64RevertWow64FsRedirection = NULL;
	static	VOID		*s_pOldVal = NULL;
	BOOL	bRetVal;

	if(_Wow64DisableWow64FsRedirection == NULL || _Wow64RevertWow64FsRedirection == NULL)
	{
		_Wow64DisableWow64FsRedirection = (Fun_Wow64DisableWow64FsRedirection)NSys::GetDllProcAdders("Kernel32.dll", "Wow64DisableWow64FsRedirection");
		_Wow64RevertWow64FsRedirection = (Fun_Wow64RevertWow64FsRedirection)NSys::GetDllProcAdders("Kernel32.dll", "Wow64RevertWow64FsRedirection");
	}
	if(_Wow64DisableWow64FsRedirection == NULL || _Wow64RevertWow64FsRedirection == NULL)
		return FALSE;

	if(bEnable)
	{
		bRetVal = _Wow64RevertWow64FsRedirection(&s_pOldVal);
	}
	else
	{
		bRetVal = _Wow64DisableWow64FsRedirection(&s_pOldVal);
	}

	return bRetVal;
}
感谢您的回答,应该是这个原因了,我系统确实是64位 刚试了一下,提示找不到NSys::GetDllProcAdders这个函数 网上完全找不到这个函数资料,是否需要包含什么头文件
paschen 2015-12-25
  • 打赏
  • 举报
回复
引用 16 楼 lx624909677 的回复:
是这种选择文件对话框出不显示那个DLL吗?
对,WINDWOS的通用打开/保存文件对话框
Yofoo 2015-12-25
  • 打赏
  • 举报
回复
如果系统是64位, 容易被被系统的重定向所误导, 如果是64位系统请继续看, 否则请无视以下 32位程序在64位系统直接访问 C:\Windows\System32 会被重定向到 C:\Windows\SysWOW64 除了文件, 还有注册表等都会被重定向到其他位置, 如果要直接访问System32 目录可以使用未公开的一些API: Wow64DisableWow64FsRedirection, Wow64RevertWow64FsRedirection..

BOOL	NSys::EnableX64FileRedirect(BOOL bEnable)
{
	typedef BOOL (__stdcall *Fun_Wow64DisableWow64FsRedirection)(PVOID*);  
	typedef BOOL (__stdcall *Fun_Wow64RevertWow64FsRedirection)(PVOID);   
	static	Fun_Wow64DisableWow64FsRedirection	_Wow64DisableWow64FsRedirection = NULL;
	static	Fun_Wow64RevertWow64FsRedirection	_Wow64RevertWow64FsRedirection = NULL;
	static	VOID		*s_pOldVal = NULL;
	BOOL	bRetVal;

	if(_Wow64DisableWow64FsRedirection == NULL || _Wow64RevertWow64FsRedirection == NULL)
	{
		_Wow64DisableWow64FsRedirection = (Fun_Wow64DisableWow64FsRedirection)NSys::GetDllProcAdders("Kernel32.dll", "Wow64DisableWow64FsRedirection");
		_Wow64RevertWow64FsRedirection = (Fun_Wow64RevertWow64FsRedirection)NSys::GetDllProcAdders("Kernel32.dll", "Wow64RevertWow64FsRedirection");
	}
	if(_Wow64DisableWow64FsRedirection == NULL || _Wow64RevertWow64FsRedirection == NULL)
		return FALSE;

	if(bEnable)
	{
		bRetVal = _Wow64RevertWow64FsRedirection(&s_pOldVal);
	}
	else
	{
		bRetVal = _Wow64DisableWow64FsRedirection(&s_pOldVal);
	}

	return bRetVal;
}
lx624909677 2015-12-25
  • 打赏
  • 举报
回复

是这种选择文件对话框出不显示那个DLL吗?
paschen 2015-12-25
  • 打赏
  • 举报
回复
刚试了一下,用TLS方式也成功了,贴上最终测试代码:

void NTAPI tls_callback(PVOID h, DWORD reason, PVOID pv);

#pragma data_seg(".tls")
#pragma comment(linker, "/INCLUDE:__tls_used")
#pragma data_seg(".CRT$XLB")
PIMAGE_TLS_CALLBACK p_thread_callback[] = {tls_callback,0};
#pragma data_seg(".rdata$T")
#pragma data_seg()
DWORD _tls_index=0;
DWORD _tls_start=0;
DWORD _tls_end=0;
PIMAGE_TLS_CALLBACK tls_callbacktbl[] = {tls_callback,0};
IMAGE_TLS_DIRECTORY32 _tls_used=
{
	(DWORD)&_tls_start,
	(DWORD)&_tls_end,
	(DWORD)&_tls_index,
	(DWORD)tls_callbacktbl,
	0,
	0
};

BOOL EnableX64FileRedirect(BOOL bEnable)
{
	typedef BOOL (__stdcall *Fun_Wow64DisableWow64FsRedirection)(PVOID*);  
	typedef BOOL (__stdcall *Fun_Wow64RevertWow64FsRedirection)(PVOID);   
	static    Fun_Wow64DisableWow64FsRedirection    _Wow64DisableWow64FsRedirection = NULL;
	static    Fun_Wow64RevertWow64FsRedirection    _Wow64RevertWow64FsRedirection = NULL;
	static    VOID        *s_pOldVal = NULL;
	BOOL    bRetVal;

	if(_Wow64DisableWow64FsRedirection == NULL || _Wow64RevertWow64FsRedirection == NULL)
	{
		HINSTANCE hinstLib; 
		hinstLib = LoadLibrary(_T("Kernel32.dll")); 
		_Wow64DisableWow64FsRedirection = (Fun_Wow64DisableWow64FsRedirection) GetProcAddress(hinstLib, "Wow64DisableWow64FsRedirection");
		_Wow64RevertWow64FsRedirection = (Fun_Wow64RevertWow64FsRedirection) GetProcAddress(hinstLib, "Wow64RevertWow64FsRedirection");
	}
	if(_Wow64DisableWow64FsRedirection == NULL || _Wow64RevertWow64FsRedirection == NULL)
		return FALSE;

	if(bEnable)
	{
		bRetVal = _Wow64RevertWow64FsRedirection(&s_pOldVal);
	}
	else
	{
		bRetVal = _Wow64DisableWow64FsRedirection(&s_pOldVal);
	}

	return bRetVal;
}

void NTAPI tls_callback(PVOID h, DWORD reason, PVOID pv)
{
	if(reason==DLL_PROCESS_ATTACH || reason==DLL_THREAD_ATTACH)
	{
		EnableX64FileRedirect(FALSE);
	}
};

int main()
{
	TCHAR strFile[MAX_PATH];
	OPENFILENAMEA ofn;
	ZeroMemory(&ofn, sizeof(OPENFILENAME));  
	ofn.lStructSize = sizeof(OPENFILENAME);  
	ofn.lpstrFile = strFile;
	ofn.nMaxFile = MAX_PATH;
	ofn.lpstrInitialDir = _T("C:\\Windows\\System32");
	ofn.lpstrFile[0] = _T('\0');
	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
	GetOpenFileName(&ofn);
	return 1;
}
上面代码可能导致一些不需要关闭重定向的线程因关闭而出错,只些可以具体在优化了,比如用一个变量控制是否执行EnableX64FileRedirect函数
BeanJoy 2015-12-25
  • 打赏
  • 举报
回复
可是如下帖子中selbie介绍的方法: 32-bit OpenFileDialog --> 64-bit System32?
paschen 2015-12-25
  • 打赏
  • 举报
回复
引用 11 楼 zzz3265 的回复:
实际的实现我也没试过, 不过有些想法, 不确定是否可以 如果是在dll中可以在DllMain的 DLL_THREAD_ATTACH 时关闭定向 exe比较麻烦, 可以Hook线程的初始化函数比如 LdrInitializeThunk, 在里面插入代码关闭定向 或者暂停线程 然后用 SetThreadContext 执行关闭的代码再回去 或者另外弄个dll来检测线程事件也可以 驱动就简单多了, 找到TEB直接修改就好了
之前看PE中的TLS中有一个回调函数,不知是否可以在这里设置,迟点试一下
paschen 2015-12-25
  • 打赏
  • 举报
回复
引用 11 楼 zzz3265 的回复:
实际的实现我也没试过, 不过有些想法, 不确定是否可以 如果是在dll中可以在DllMain的 DLL_THREAD_ATTACH 时关闭定向 exe比较麻烦, 可以Hook线程的初始化函数比如 LdrInitializeThunk, 在里面插入代码关闭定向 或者暂停线程 然后用 SetThreadContext 执行关闭的代码再回去 或者另外弄个dll来检测线程事件也可以 驱动就简单多了, 找到TEB直接修改就好了
非常感谢,刚才用你的方法试了,在DLL中使用一个函数封装一下GetOpenFileName,然后在EXE中调用DLL中的函数成功了 顺便说一下,譔函数竟然创建了10多个后台线程,DLL_THREAD_ATTACH 执行了10多次
Yofoo 2015-12-25
  • 打赏
  • 举报
回复
实际的实现我也没试过, 不过有些想法, 不确定是否可以 如果是在dll中可以在DllMain的 DLL_THREAD_ATTACH 时关闭定向 exe比较麻烦, 可以Hook线程的初始化函数比如 LdrInitializeThunk, 在里面插入代码关闭定向 或者暂停线程 然后用 SetThreadContext 执行关闭的代码再回去 或者另外弄个dll来检测线程事件也可以 驱动就简单多了, 找到TEB直接修改就好了
加载更多回复(6)

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧