如何判断WOW文件系统是否为线程打开
How to tell if WOW file system redirection is on for a thread?
说,我可以使用WOW64DisableWow64fsredirection API禁用文件系统重定向,但是是否有办法知道该线程当前是否正在重定向?换句话说,是否有像GetWow64FsRedirection
这样的API?
没有报告此状态的API函数。期望您记住您禁用重定向。
对不起,忘了发布后续行动。正如公认的答案所暗示的那样,没有API可检测到这一点。太糟糕了,因为该信息在线程TEB
结构的无证件部分中存储。(请参阅代码中的评论。)
下面的代码将检索它。
我必须通过说这是通过逆转上述API获得的。因此,这是一个高度无证件的东西,可能会在将来的OS版本中破坏。因此,请确保在使用版本保障措施之前。对于所有已发布的Windows版本,都应该可以,包括Windows 10 Build 17134:
enum YESNOERR{
ERR = -1,
NO = 0,
YES = 1,
};
struct PROC_STATS{
BOOL b32BitProcessOn64BitOS;
DWORD dwOS_Major;
DWORD dwOS_Minor;
DWORD dwOS_Build;
PROC_STATS()
{
BOOL (WINAPI *pfnIsWow64Process)(HANDLE, PBOOL);
(FARPROC&)pfnIsWow64Process = ::GetProcAddress(::GetModuleHandle(_T("kernel32.dll")), "IsWow64Process");
BOOL bWow64 = FALSE;
b32BitProcessOn64BitOS = pfnIsWow64Process && pfnIsWow64Process(::GetCurrentProcess(), &bWow64) && bWow64;
LONG (WINAPI *pfnRtlGetVersion)(RTL_OSVERSIONINFOEXW*);
(FARPROC&)pfnRtlGetVersion = ::GetProcAddress(::GetModuleHandle(_T("ntdll.dll")), "RtlGetVersion");
OSVERSIONINFOEX osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(osvi);
pfnRtlGetVersion(&osvi);
dwOS_Major = osvi.dwMajorVersion;
dwOS_Minor = osvi.dwMinorVersion;
dwOS_Build = osvi.dwBuildNumber;
}
};
PROC_STATS procStats;
YESNOERR __cdecl GetWow64FsRedirection()
{
//Checks if Wow64 file system redirection is on for the current thread
YESNOERR res = ERR;
__try
{
if(procStats.b32BitProcessOn64BitOS)
{
//Really easy pre-Win10 v.10.0.10041.0
if(procStats.dwOS_Major < 10 ||
(procStats.dwOS_Major == 10 && procStats.dwOS_Build <= 10041))
{
//Win XP, 7, 8.1 & earlier builds of Win10
__asm
{
mov eax, fs:18h ; TEB
mov eax, [eax + 0F70h]
mov eax, [eax + 14C0h]
xor ecx, ecx
test eax, eax ; 0=Wow64FsRedir is on, 1=Off
setz cl
mov [res], ecx
}
}
else
{
//Latest builds of Win10 have a separate WoW TEB block
__asm
{
mov eax, fs:18h ; TEB
mov ecx, [eax + 0FDCh] ; WowTebOffset
test ecx, ecx
jns lbl_no_offset ; it must precede TEB
add eax, ecx
lbl_no_offset:
cmp eax, [eax + 18h] ; pick version of the struct
jz lbl_alt
mov eax, [eax + 14C0h]
jmp lbl_check
lbl_alt:
mov eax, [eax + 0E30h]
lbl_check:
xor ecx, ecx
test eax, eax ; 0=Wow64FsRedir is on, 1=Off
setz cl
mov [res], ecx
}
}
}
else
{
//It's off by default
res = NO;
}
}
__except(1)
{
//Oops, too far in the future -- this no longer works
res = ERR;
}
return res;
}
这是您可以测试的方式:
resWow64FsOn = GetWow64FsRedirection();
_tprintf(L"Wow64FsRedirection=%dn", resWow64FsOn);
void* pOldV;
if(::Wow64DisableWow64FsRedirection(&pOldV))
{
resWow64FsOn = GetWow64FsRedirection();
_tprintf(L"Wow64FsRedirection=%dn", resWow64FsOn);
::Wow64RevertWow64FsRedirection(pOldV);
resWow64FsOn = GetWow64FsRedirection();
_tprintf(L"Wow64FsRedirection=%dn", resWow64FsOn);
}
else
{
_tprintf(L"ERROR: (%d) API Failedn", ::GetLastError());
}
另一种方法是检查Windows System32目录中wow32.dll
的存在(通常是C:WindowsSystem32
)。在64位系统上,该文件应位于SysWOW64
目录中,因此,如果启用了文件重定向,它将找到。同样,可以检查位于64位系统上的System32目录中的wow64.dll
的不存在,如果找不到它,则启用了重定向。
伪代码为:
bool IsWow64FileSystemRedirectionEnabled()
{
if (!Is64BitOS()) return false;
if (FileExists(GetSystem32Directory() + "\wow32.dll")) return true;
return false;
}
其中:
-
Is64BitOS
可以如下所示实现 -
FileExists
可以如下所示实现 -
GetSystem32Directory
-可以如下所示实现
相关文章:
- 如何检查线程是否锁定
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- 在 openmp 中,omp_get_thread_num是否绑定到物理线程?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- 我是否生成线程并导致内存泄漏?
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 是否可以创建一个从不同类调用函数的线程?
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- C++:在多个线程中访问同一数组/向量的不同单元格是否会产生数据竞赛?
- 线程调用的函数对对象删除是否安全?
- 在不同的内存位置同时写入 std::d eque 是否线程安全?
- 在 OpenCV 中访问具有多个线程的 Mat 是否线程安全?
- 在 C++20 中获取当前日期/时间是否线程安全?
- 在 c++ 的多个线程中编写 c 数组的不同项是否线程安全
- 当结构数组在主线程中填充数据时,从结构数组的低索引元素读取是否线程安全
- boost套接字读写功能是否线程安全
- 对磁盘的openmp写入是否线程安全
- 测试静态局部对象的初始化是否线程安全
- Boost ptime是否线程安全