Skip to content

Commit

Permalink
Fea #29,FindFirstFileEx,添加Windows XP、Vista兼容 FIND_FIRST_EX_LARGE_FETC…
Browse files Browse the repository at this point in the history
…H、FindExInfoStandard参数。
  • Loading branch information
mingkuang-Chuyu committed Oct 1, 2023
1 parent 9847db4 commit 79fdd60
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 20 deletions.
8 changes: 8 additions & 0 deletions ThunksList.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@
| GetFirmwareType | 不存在时,调用NtQuerySystemInformation。
| IsNativeVhdBoot | 不存在时,调用NtQuerySystemInformation。
| RtlCaptureStackBackTrace | 调用ntdll.RtlCaptureStackBackTrace。
| SetFileCompletionNotificationModes | 不存在时,什么也不做。
| GetQueuedCompletionStatusEx | 不存在时,调用 GetQueuedCompletionStatus,注意:丢失可警报状态支持。
| FindFirstFileEx(W/A) | Windows XP、Vista兼容 FIND_FIRST_EX_LARGE_FETCH、FindExInfoStandard参数。

## mfplat.dll
| 函数 | Fallback
Expand All @@ -305,6 +308,11 @@
| NetGetAadJoinInformation | 不存在时,始终认为没有加入 Azure AD 帐户 账号。
| NetFreeAadJoinInformation | 不存在时,什么也不做。

## ntdll.dll
| 函数 | Fallback
| ---- | -----------
| NtCancelIoFileEx | 不存在时,调用 NtCancelIoFile。注意:将取消此文件的所有IO请求。

## ole32.dll
| 函数 | Fallback
| ---- | -----------
Expand Down
9 changes: 9 additions & 0 deletions src/Shared/km.h
Original file line number Diff line number Diff line change
Expand Up @@ -5104,6 +5104,15 @@ LdrAddRefDll(
IN PVOID BaseAddress
);

EXTERN_C NTSTATUS NTAPI NtCancelIoFileEx(HANDLE handle, IO_STATUS_BLOCK* io, IO_STATUS_BLOCK* io_status);

EXTERN_C
NTSTATUS
NTAPI
NtCancelIoFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock);

#if defined __cplusplus && !defined _Disallow_YY_KM_Namespace
} //namespace YY
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/Thunks/YY_Thunks.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// 忽略非标准的 0 数组警告。
#pragma warning(disable:4200)
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

#define _YY_APPLY_TO_LATE_BOUND_MODULES(_APPLY) \
_APPLY(ntdll, "ntdll" , USING_UNSAFE_LOAD ) \
Expand Down Expand Up @@ -57,6 +58,7 @@
_APPLY(LdrLoadDll, ntdll ) \
_APPLY(RtlDllShutdownInProgress, ntdll ) \
_APPLY(RtlCutoverTimeToSystemTime, ntdll ) \
_APPLY(NtCancelIoFile, ntdll ) \
_APPLY(AddDllDirectory, kernel32 ) \
_APPLY(SystemFunction036, advapi32 )

Expand Down
78 changes: 78 additions & 0 deletions src/Thunks/api-ms-win-core-file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,84 @@ namespace YY
}
#endif

#if (YY_Thunks_Support_Version < NTDDI_WIN7)

// 最低受支持的客户端 Windows XP [桌面应用 |UWP 应用]
// 最低受支持的服务器 Windows Server 2003[桌面应用 | UWP 应用]
__DEFINE_THUNK(
kernel32,
24,
HANDLE,
WINAPI,
FindFirstFileExW,
_In_ LPCWSTR lpFileName,
_In_ FINDEX_INFO_LEVELS fInfoLevelId,
_Out_writes_bytes_(sizeof(WIN32_FIND_DATAW)) LPVOID lpFindFileData,
_In_ FINDEX_SEARCH_OPS fSearchOp,
_Reserved_ LPVOID lpSearchFilter,
_In_ DWORD dwAdditionalFlags
)
{
if (const auto _pfnFindFirstFileExW = try_get_FindFirstFileExW())
{
const auto _uMajorVersion = ((TEB*)NtCurrentTeb())->ProcessEnvironmentBlock->OSMajorVersion;
const auto _uMinorVersion = ((TEB*)NtCurrentTeb())->ProcessEnvironmentBlock->OSMinorVersion;

if (internal::MakeVersion(_uMajorVersion, _uMinorVersion) < internal::MakeVersion(6, 1))
{
// dwAdditionalFlags : Windows 7开始才支持 FIND_FIRST_EX_LARGE_FETCH
dwAdditionalFlags &= (FIND_FIRST_EX_CASE_SENSITIVE | FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY);

// Windows 7开始才支持 FindExInfoBasic
fInfoLevelId = FindExInfoStandard;
}


return _pfnFindFirstFileExW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
}

return FindFirstFileW(lpFileName, (WIN32_FIND_DATAW*)lpFindFileData);
}
#endif

#if (YY_Thunks_Support_Version < NTDDI_WIN7)

// 最低受支持的客户端 Windows XP [桌面应用 |UWP 应用]
// 最低受支持的服务器 Windows Server 2003[桌面应用 | UWP 应用]
__DEFINE_THUNK(
kernel32,
24,
HANDLE,
WINAPI,
FindFirstFileExA,
_In_ LPCSTR lpFileName,
_In_ FINDEX_INFO_LEVELS fInfoLevelId,
_Out_writes_bytes_(sizeof(WIN32_FIND_DATAA)) LPVOID lpFindFileData,
_In_ FINDEX_SEARCH_OPS fSearchOp,
_Reserved_ LPVOID lpSearchFilter,
_In_ DWORD dwAdditionalFlags
)
{
if (const auto _pfnFindFirstFileExA = try_get_FindFirstFileExA())
{
const auto _uMajorVersion = ((TEB*)NtCurrentTeb())->ProcessEnvironmentBlock->OSMajorVersion;
const auto _uMinorVersion = ((TEB*)NtCurrentTeb())->ProcessEnvironmentBlock->OSMinorVersion;

if (internal::MakeVersion(_uMajorVersion, _uMinorVersion) < internal::MakeVersion(6, 1))
{
// dwAdditionalFlags : Windows 7开始才支持 FIND_FIRST_EX_LARGE_FETCH
dwAdditionalFlags &= (FIND_FIRST_EX_CASE_SENSITIVE | FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY);

// Windows 7开始才支持 FindExInfoBasic
fInfoLevelId = FindExInfoStandard;
}

return _pfnFindFirstFileExA(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
}

return FindFirstFileA(lpFileName, (WIN32_FIND_DATAA*)lpFindFileData);
}
#endif
}//namespace Thunks

} //namespace YY
43 changes: 43 additions & 0 deletions src/Thunks/api-ms-win-core-io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,49 @@ namespace YY
return FALSE;
}
#endif

#if (YY_Thunks_Support_Version < NTDDI_WIN6)

// 最低受支持的客户端 Windows Vista [桌面应用 | UWP 应用]
// 最低受支持的服务器 Windows Server 2008[桌面应用 | UWP 应用]
__DEFINE_THUNK(
kernel32,
24,
BOOL,
WINAPI,
GetQueuedCompletionStatusEx,
_In_ HANDLE CompletionPort,
_Out_writes_to_(ulCount,*ulNumEntriesRemoved) LPOVERLAPPED_ENTRY lpCompletionPortEntries,
_In_ ULONG ulCount,
_Out_ PULONG ulNumEntriesRemoved,
_In_ DWORD dwMilliseconds,
_In_ BOOL fAlertable
)
{
if (const auto _pfnGetQueuedCompletionStatusEx = try_get_GetQueuedCompletionStatusEx())
{
return _pfnGetQueuedCompletionStatusEx(CompletionPort, lpCompletionPortEntries, ulCount, ulNumEntriesRemoved, dwMilliseconds, fAlertable);
}

if (ulCount == 0 || lpCompletionPortEntries == nullptr || ulNumEntriesRemoved == nullptr)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}

*ulNumEntriesRemoved = 0;

auto& _Entry = lpCompletionPortEntries[0];

// TODO: 已知问题:可警报状态丢失!(fAlertable)
auto _bRet = GetQueuedCompletionStatus(CompletionPort, &_Entry.dwNumberOfBytesTransferred, &_Entry.lpCompletionKey, &_Entry.lpOverlapped, dwMilliseconds);
if (_bRet)
{
*ulNumEntriesRemoved = 1;
}
return _bRet;
}
#endif
}//namespace Thunks

} //namespace YY
25 changes: 25 additions & 0 deletions src/Thunks/api-ms-win-core-kernel32-legacy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,31 @@ namespace YY
}
#endif

#if (YY_Thunks_Support_Version < NTDDI_WIN6)

// 支持的最低客户端 Windows Vista [桌面应用程序 |UWP 应用]
// 支持的最低服务器 Windows Server 2008 [桌面应用程序 |UWP 应用]
__DEFINE_THUNK(
kernel32,
8,
BOOL,
WINAPI,
SetFileCompletionNotificationModes,
_In_ HANDLE FileHandle,
_In_ UCHAR Flags
)
{
if (const auto _pfnSetFileCompletionNotificationModes = try_get_SetFileCompletionNotificationModes())
{
return _pfnSetFileCompletionNotificationModes(FileHandle, Flags);
}

// 初步看起来没有什么的,只是会降低完成端口的效率。
// 至少需要 Vista才支持 FileIoCompletionNotificationInformation
// 只能假定先返回成功。
return TRUE;
}
#endif
}//namespace Thunks

} //namespace YY
36 changes: 36 additions & 0 deletions src/Thunks/ntdll.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace YY
{
namespace Thunks
{
#if (YY_Thunks_Support_Version < NTDDI_WIN6)

// 最低受支持的客户端 Windows Vista [桌面应用|UWP 应用]
// 最低受支持的服务器 Windows Server 2008[桌面应用 | UWP 应用]
__DEFINE_THUNK(
ntdll,
12,
NTSTATUS,
NTAPI,
NtCancelIoFileEx,
HANDLE handle,
IO_STATUS_BLOCK* io,
IO_STATUS_BLOCK* io_status
)
{
if (const auto _pfnNtCancelIoFileEx = try_get_NtCancelIoFileEx())
{
return _pfnNtCancelIoFileEx(handle, io, io_status);
}

// 最坏打算,清除所有的调用
if (const auto _pfnNtCancelIoFile = try_get_NtCancelIoFile())
{
return _pfnNtCancelIoFile(handle, io_status);
}

// 正常来说不应该走到这里
return STATUS_NOT_SUPPORTED;
}
#endif
}
}
1 change: 1 addition & 0 deletions src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@
<ClInclude Include="..\Thunks\Iphlpapi.hpp" />
<ClInclude Include="..\Thunks\mfplat.hpp" />
<ClInclude Include="..\Thunks\netapi32.hpp" />
<ClInclude Include="..\Thunks\ntdll.hpp" />
<ClInclude Include="..\Thunks\Pdh.hpp" />
<ClInclude Include="..\Thunks\powrprof.hpp" />
<ClInclude Include="..\Thunks\ThreadRunner.h" />
Expand Down
3 changes: 3 additions & 0 deletions src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@
<ClInclude Include="..\Thunks\api-ms-win-core-rtlsupport.hpp">
<Filter>Thunks</Filter>
</ClInclude>
<ClInclude Include="..\Thunks\ntdll.hpp">
<Filter>Thunks</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\def\x86\PSAPI2Kernel32.def">
Expand Down
4 changes: 2 additions & 2 deletions src/YY-Thunks.UnitTest/api-ms-win-core-fibers.UnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ namespace api_ms_win_core_fibers

for (auto hHandle : hHandles)
{
Assert::AreEqual(WaitForSingleObject(hHandle, 1000), WAIT_OBJECT_0);
Assert::AreEqual(WaitForSingleObject(hHandle, 1000), (DWORD)WAIT_OBJECT_0);

CloseHandle(hHandle);
}
Expand Down Expand Up @@ -158,7 +158,7 @@ namespace api_ms_win_core_fibers

for (auto hHandle : hHandles)
{
Assert::AreEqual(WaitForSingleObject(hHandle, 1000), WAIT_OBJECT_0);
Assert::AreEqual(WaitForSingleObject(hHandle, 1000), (DWORD)WAIT_OBJECT_0);

CloseHandle(hHandle);
}
Expand Down
8 changes: 4 additions & 4 deletions src/YY-Thunks.UnitTest/api-ms-win-core-synch.UnitTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ namespace api_ms_win_core_synch

for (auto hThreadHandle : hThreadHandles)
{
Assert::AreEqual(WaitForSingleObject(hThreadHandle, 500), WAIT_OBJECT_0);
Assert::AreEqual(WaitForSingleObject(hThreadHandle, 500), (DWORD)WAIT_OBJECT_0);
}

Assert::AreEqual(100l, (long)Data.RunCount);
Expand Down Expand Up @@ -157,7 +157,7 @@ namespace api_ms_win_core_synch

for (auto hThreadHandle : hThreadHandles)
{
Assert::AreEqual(WaitForSingleObject(hThreadHandle, 500), WAIT_OBJECT_0);
Assert::AreEqual(WaitForSingleObject(hThreadHandle, 500), (DWORD)WAIT_OBJECT_0);
}

Assert::AreEqual(100l, (long)Data.RunCount);
Expand Down Expand Up @@ -205,7 +205,7 @@ namespace api_ms_win_core_synch
auto _nRet = WaitForSingleObject(_hThreadHandle, 5 * 1000);
::ReleaseSRWLockExclusive(&_SRWLock);

Assert::AreEqual(WAIT_OBJECT_0, _nRet);
Assert::AreEqual((DWORD)WAIT_OBJECT_0, _nRet);

DWORD _uCode = -1;
GetExitCodeThread(_hThreadHandle, &_uCode);
Expand Down Expand Up @@ -237,7 +237,7 @@ namespace api_ms_win_core_synch

auto _nRet = WaitForSingleObject(_hThreadHandle, 5 * 1000);

Assert::AreEqual(WAIT_OBJECT_0, _nRet);
Assert::AreEqual((DWORD)WAIT_OBJECT_0, _nRet);

DWORD _uCode = -1;
GetExitCodeThread(_hThreadHandle, &_uCode);
Expand Down
Loading

0 comments on commit 79fdd60

Please sign in to comment.