Skip to content

Commit

Permalink
添加InitializeProcThreadAttributeList、DeleteProcThreadAttributeList、Upd…
Browse files Browse the repository at this point in the history
…ateProcThreadAttribute的仅接口实现(#29
  • Loading branch information
mingkuang-Chuyu committed Jul 7, 2021
1 parent 7a95d02 commit 3dfa8c1
Show file tree
Hide file tree
Showing 2 changed files with 311 additions and 5 deletions.
5 changes: 4 additions & 1 deletion ThunksList.md
Original file line number Diff line number Diff line change
Expand Up @@ -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。
| [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特性会被忽略处理。
311 changes: 307 additions & 4 deletions src/Thunks/api-ms-win-core-processthreads.hpp
Original file line number Diff line number Diff line change
@@ -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();
Expand Down Expand Up @@ -36,7 +61,7 @@ namespace YY
}

#endif
#endif


#if (YY_Thunks_Support_Version < NTDDI_WS03)

Expand Down Expand Up @@ -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

0 comments on commit 3dfa8c1

Please sign in to comment.