aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPali Rohár <pali@kernel.org>2023-05-07 17:05:42 +0200
committerMartin Mares <mj@ucw.cz>2024-02-18 15:48:29 +0100
commit63a7a33fac118b10980ce2f2e8e0da7a85c3c5e9 (patch)
treef1d828ee4b516f820d80c118afe77c8924d653c8
parentde65a6f92973eb2aeb241f0c46e06e17a57a3c60 (diff)
downloadpciutils-63a7a33fac118b10980ce2f2e8e0da7a85c3c5e9.tar.gz
windows: Translate NT status to Win32 error
-rw-r--r--lib/i386-io-windows.h27
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);