diff options
author | Pali Rohár <pali@kernel.org> | 2023-05-07 17:05:42 +0200 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 2024-02-18 15:48:29 +0100 |
commit | 63a7a33fac118b10980ce2f2e8e0da7a85c3c5e9 (patch) | |
tree | f1d828ee4b516f820d80c118afe77c8924d653c8 | |
parent | de65a6f92973eb2aeb241f0c46e06e17a57a3c60 (diff) | |
download | pciutils-63a7a33fac118b10980ce2f2e8e0da7a85c3c5e9.tar.gz |
windows: Translate NT status to Win32 error
-rw-r--r-- | lib/i386-io-windows.h | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/i386-io-windows.h b/lib/i386-io-windows.h index 5bb26bb..fa0db58 100644 --- a/lib/i386-io-windows.h +++ b/lib/i386-io-windows.h @@ -129,6 +129,7 @@ typedef BOOL (WINAPI *SetThreadErrorModeProt)(DWORD dwNewMode, LPDWORD lpOldMode #define ProcessUserModeIOPL 16 #endif typedef NTSTATUS (NTAPI *NtSetInformationProcessProt)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength); +typedef ULONG (NTAPI *RtlNtStatusToDosErrorProt)(NTSTATUS Status); /* * Check if the current thread has particular privilege in current active access @@ -1183,16 +1184,25 @@ ret: static BOOL SetProcessUserModeIOPLFunc(LPVOID Arg) { - NtSetInformationProcessProt NtSetInformationProcessPtr = (NtSetInformationProcessProt)Arg; + RtlNtStatusToDosErrorProt RtlNtStatusToDosErrorPtr = (RtlNtStatusToDosErrorProt)(((LPVOID *)Arg)[1]); + NtSetInformationProcessProt NtSetInformationProcessPtr = (NtSetInformationProcessProt)(((LPVOID *)Arg)[0]); NTSTATUS nt_status = NtSetInformationProcessPtr(GetCurrentProcess(), ProcessUserModeIOPL, NULL, 0); if (nt_status >= 0) return TRUE; - if (nt_status == STATUS_NOT_IMPLEMENTED) + /* + * If we have optional RtlNtStatusToDosError() function then use it for + * translating NT status to Win32 error. If we do not have it then translate + * two important status codes which we use later STATUS_NOT_IMPLEMENTED and + * STATUS_PRIVILEGE_NOT_HELD. + */ + if (RtlNtStatusToDosErrorPtr) + SetLastError(RtlNtStatusToDosErrorPtr(nt_status)); + else if (nt_status == STATUS_NOT_IMPLEMENTED) SetLastError(ERROR_INVALID_FUNCTION); else if (nt_status == STATUS_PRIVILEGE_NOT_HELD) SetLastError(ERROR_PRIVILEGE_NOT_HELD); - else /* TODO: convert NT STATUS to WIN32 ERROR */ + else SetLastError(ERROR_GEN_FAILURE); return FALSE; @@ -1207,7 +1217,7 @@ SetProcessUserModeIOPLFunc(LPVOID Arg) static BOOL SetProcessUserModeIOPL(VOID) { - NtSetInformationProcessProt NtSetInformationProcessPtr; + LPVOID Arg[2]; UINT prev_error_mode; HMODULE ntdll; BOOL ret; @@ -1227,16 +1237,19 @@ SetProcessUserModeIOPL(VOID) } /* Retrieve pointer to NtSetInformationProcess() function. */ - NtSetInformationProcessPtr = (NtSetInformationProcessProt)(LPVOID)GetProcAddress(ntdll, "NtSetInformationProcess"); - if (!NtSetInformationProcessPtr) + Arg[0] = (LPVOID)GetProcAddress(ntdll, "NtSetInformationProcess"); + if (!Arg[0]) { FreeLibrary(ntdll); SetLastError(ERROR_INVALID_FUNCTION); return FALSE; } + /* Retrieve pointer to optional RtlNtStatusToDosError() function, it may be NULL. */ + Arg[1] = (LPVOID)GetProcAddress(ntdll, "RtlNtStatusToDosError"); + /* Call ProcessUserModeIOPL with Tcb privilege. */ - ret = CallFuncWithTcbPrivilege(SetProcessUserModeIOPLFunc, (LPVOID)NtSetInformationProcessPtr); + ret = CallFuncWithTcbPrivilege(SetProcessUserModeIOPLFunc, (LPVOID)&Arg); FreeLibrary(ntdll); |