diff --git a/ThunksList.md b/ThunksList.md index 65e9d85..93eb66b 100644 --- a/ThunksList.md +++ b/ThunksList.md @@ -232,4 +232,7 @@ | [EnumSystemLocalesEx](https://docs.microsoft.com/windows/win32/api/winnls/nf-winnls-enumsystemlocalesex) | 不存在时,调用 EnumSystemLocalesW。 | [GetThreadPreferredUILanguages](https://docs.microsoft.com/windows/win32/api/winnls/nf-winnls-getthreadpreferreduilanguages) | 不存在时,调用 GetThreadLocale、GetUserDefaultLangID以及GetSystemDefaultLangID。 | [GetThreadUILanguage](https://docs.microsoft.com/windows/win32/api/winnls/nf-winnls-getthreaduilanguage) | 不存在时,调用 GetThreadLocale。 -| [ResolveLocaleName](https://docs.microsoft.com/windows/win32/api/winnls/nf-winnls-resolvelocalename) | 不存在时,调用 LocaleNameToLCID以及LCIDToLocaleName。 \ No newline at end of file +| [ResolveLocaleName](https://docs.microsoft.com/windows/win32/api/winnls/nf-winnls-resolvelocalename) | 不存在时,调用 LocaleNameToLCID以及LCIDToLocaleName。 +| [InitializeProcThreadAttributeList](https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-initializeprocthreadattributelist) | 不存在时,内部实现。 +| [DeleteProcThreadAttributeList](https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-deleteprocthreadattributelist) | 不存在时,内部实现。 +| [UpdateProcThreadAttribute](https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute) | 不存在时,内部实现。PROC_THREAD_ATTRIBUTE_PARENT_PROCESS与PROC_THREAD_ATTRIBUTE_HANDLE_LIST特性会被忽略处理。 \ No newline at end of file diff --git a/src/Thunks/api-ms-win-core-processthreads.hpp b/src/Thunks/api-ms-win-core-processthreads.hpp index 1da1a51..1a6a0c6 100644 --- a/src/Thunks/api-ms-win-core-processthreads.hpp +++ b/src/Thunks/api-ms-win-core-processthreads.hpp @@ -1,13 +1,38 @@  + +#ifdef YY_Thunks_Implemented + +//结构体来源:http://www.rohitab.com/discuss/topic/38601-proc-thread-attribute-list-structure-documentation/ + + +// This structure stores the value for each attribute +typedef struct _PROC_THREAD_ATTRIBUTE_ENTRY +{ + DWORD_PTR Attribute; // PROC_THREAD_ATTRIBUTE_xxx + SIZE_T cbSize; + PVOID lpValue; +} PROC_THREAD_ATTRIBUTE_ENTRY, * LPPROC_THREAD_ATTRIBUTE_ENTRY; + +// This structure contains a list of attributes that have been added using UpdateProcThreadAttribute +typedef struct _PROC_THREAD_ATTRIBUTE_LIST +{ + DWORD dwFlags; + ULONG Size; + ULONG Count; + ULONG Reserved; + LPPROC_THREAD_ATTRIBUTE_ENTRY lpExtendedFlags; + PROC_THREAD_ATTRIBUTE_ENTRY Entries[ANYSIZE_ARRAY]; +} PROC_THREAD_ATTRIBUTE_LIST, * LPPROC_THREAD_ATTRIBUTE_LIST; + +#endif + namespace YY { namespace Thunks { -#if (YY_Thunks_Support_Version < NTDDI_WIN6) - -#ifdef YY_Thunks_Implemented +#if defined(YY_Thunks_Implemented) && (YY_Thunks_Support_Version < NTDDI_WIN6) namespace Fallback { static void __cdecl UninitPageVirtualProtect(); @@ -36,7 +61,7 @@ namespace YY } #endif -#endif + #if (YY_Thunks_Support_Version < NTDDI_WS03) @@ -319,6 +344,284 @@ namespace YY #endif + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + //Minimum supported client Windows Vista [desktop apps only] + //Minimum supported server Windows Server 2008 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 16, + _Success_(return != FALSE) + BOOL, + WINAPI, + InitializeProcThreadAttributeList, + _Out_writes_bytes_to_opt_(*lpSize,*lpSize) LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, + _In_ DWORD dwAttributeCount, + _Reserved_ DWORD dwFlags, + _When_(lpAttributeList == nullptr,_Out_) _When_(lpAttributeList != nullptr,_Inout_) PSIZE_T lpSize + ) + { + if (const auto pInitializeProcThreadAttributeList = try_get_InitializeProcThreadAttributeList()) + { + return pInitializeProcThreadAttributeList(lpAttributeList, dwAttributeCount, dwFlags, lpSize); + } + + + LSTATUS lStatus = ERROR_SUCCESS; + + do + { + //参数验证 + if (dwFlags) + { + lStatus = ERROR_INVALID_PARAMETER; + break; + } + + //Vista只支持 3个 Type,所以只有三个 + if (dwAttributeCount > 3) + { + lStatus = ERROR_INVALID_PARAMETER; + break; + } + + + const auto cbSize = *lpSize; + const auto cbSizeNeed = sizeof(PROC_THREAD_ATTRIBUTE_LIST) + dwAttributeCount * sizeof(PROC_THREAD_ATTRIBUTE_ENTRY); + *lpSize = cbSizeNeed; + + if (lpAttributeList == nullptr || cbSize < cbSizeNeed) + { + lStatus = ERROR_INSUFFICIENT_BUFFER; + break; + } + + lpAttributeList->dwFlags = 0; + lpAttributeList->lpExtendedFlags = nullptr; + lpAttributeList->Size = dwAttributeCount; + lpAttributeList->Count = 0; + + return TRUE; + + } while (false); + + + SetLastError(lStatus); + return FALSE; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + //Minimum supported client Windows Vista [desktop apps only] + //Minimum supported server Windows Server 2008 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + DeleteProcThreadAttributeList, + _Inout_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList + ) + { + if (const auto pDeleteProcThreadAttributeList = try_get_DeleteProcThreadAttributeList()) + { + return pDeleteProcThreadAttributeList(lpAttributeList); + } + + + //Vista原版什么也没有做…… + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + //Minimum supported client Windows Vista [desktop apps only] + //Minimum supported server Windows Server 2008 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 28, + BOOL, + WINAPI, + UpdateProcThreadAttribute, + _Inout_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, + _In_ DWORD dwFlags, + _In_ DWORD_PTR Attribute, + _In_reads_bytes_opt_(cbSize) PVOID lpValue, + _In_ SIZE_T cbSize, + _Out_writes_bytes_opt_(cbSize) PVOID lpPreviousValue, + _In_opt_ PSIZE_T lpReturnSize + ) + { + if (const auto pUpdateProcThreadAttribute = try_get_UpdateProcThreadAttribute()) + { + return pUpdateProcThreadAttribute(lpAttributeList, dwFlags, Attribute, lpValue, cbSize, lpPreviousValue, lpReturnSize); + } + + + LSTATUS lStatus = ERROR_SUCCESS; + + do + { + auto AttributeMark = 1ul << Attribute; + + ///////////////////////////////////////////////////// + // + // 参数检查 + // + + if (dwFlags & (~PROC_THREAD_ATTRIBUTE_REPLACE_VALUE)) + { + lStatus = ERROR_INVALID_PARAMETER; + break; + } + + + if ((Attribute & PROC_THREAD_ATTRIBUTE_ADDITIVE) == 0) + { + if (lpAttributeList->Count == lpAttributeList->Size) + { + //internal::BaseSetLastNTError(0xC0000001); + lStatus = ERROR_GEN_FAILURE; + break; + } + else if (AttributeMark & lpAttributeList->dwFlags) + { + //internal::BaseSetLastNTError(0x40000000); + lStatus = ERROR_OBJECT_NAME_EXISTS; + break; + } + else if (lpPreviousValue) + { + //internal::BaseSetLastNTError(0xC00000F4); + lStatus = ERROR_INVALID_PARAMETER; + break; + } + else if (dwFlags & PROC_THREAD_ATTRIBUTE_REPLACE_VALUE) + { + //internal::BaseSetLastNTError(0xC00000F0); + lStatus = ERROR_INVALID_PARAMETER; + break; + } + } + + + if ((PROC_THREAD_ATTRIBUTE_INPUT & Attribute) && lpReturnSize) + { + //internal::BaseSetLastNTError(0xC00000F5); + lStatus = ERROR_INVALID_PARAMETER; + break; + } + + // + // + //////////////////////////////////////////////////// + + + auto pAttribute = &lpAttributeList->Entries[lpAttributeList->Count]; + + constexpr auto ProcThreadAttributeExtendedFlags = 1; + //0x60001,文档没有公开 + constexpr auto PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS = ProcThreadAttributeValue(ProcThreadAttributeExtendedFlags, FALSE, TRUE, TRUE); + + + if (Attribute == PROC_THREAD_ATTRIBUTE_PARENT_PROCESS) //0x20000 + { + //WinXP不支持 UAC,没实现似乎也没什么的。 + + if (cbSize != sizeof(HANDLE)) + { + //internal::BaseSetLastNTError(0xC0000004); + lStatus = ERROR_INVALID_PARAMETER; + break; + } + } + else if (Attribute == PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS) //0x60001 + { + //系统没有公开这个含义,暂时让他允许通过把…… + + if (cbSize != sizeof(DWORD)) + { + //internal::BaseSetLastNTError(0xC0000004); + lStatus = ERROR_INVALID_PARAMETER; + break; + } + + DWORD dwOrgFlags; + + if (lpAttributeList->lpExtendedFlags) + { + pAttribute = lpAttributeList->lpExtendedFlags; + dwOrgFlags = (DWORD)lpAttributeList->lpExtendedFlags->lpValue; + AttributeMark = 0; + } + else + { + lpAttributeList->lpExtendedFlags = pAttribute; + dwOrgFlags = 0; + } + + + auto dwNewFlags = *(DWORD*)lpValue; + + if (dwNewFlags & ~0x00000003ul) + { + //internal::BaseSetLastNTError(0xC000000D); + lStatus = ERROR_BAD_LENGTH; + break; + } + + if ((dwFlags & PROC_THREAD_ATTRIBUTE_REPLACE_VALUE) == 0 && dwOrgFlags) + { + dwNewFlags |= dwOrgFlags; + } + + if (lpPreviousValue) + *(DWORD*)lpPreviousValue = dwOrgFlags; + + lpValue = (PVOID)dwNewFlags; + } + else if (Attribute == PROC_THREAD_ATTRIBUTE_HANDLE_LIST) //0x20002 + { + //WinXP也不支持指定句柄继承,他会直接继承所有可继承的句柄,所以没实现好像也没什么大不了的。 + + if (cbSize == 0 || cbSize % sizeof(HANDLE) != 0) + { + //internal::BaseSetLastNTError(0xC0000004); + lStatus = ERROR_INVALID_PARAMETER; + break; + } + } + else + { + //internal::BaseSetLastNTError(0xC00000BB); + lStatus = ERROR_NOT_SUPPORTED; + break; + } + + //LABEL_17 + pAttribute->lpValue = lpValue; + + if (AttributeMark) + { + pAttribute->Attribute = Attribute; + pAttribute->cbSize = cbSize; + ++lpAttributeList->Count; + lpAttributeList->dwFlags |= AttributeMark; + } + + return TRUE; + + } while (false); + + SetLastError(lStatus); + + return FALSE; + } +#endif }//namespace Thunks } //namespace YY \ No newline at end of file