Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/windirstat.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/priv.c')
-rw-r--r--3rdparty/priv.c319
1 files changed, 319 insertions, 0 deletions
diff --git a/3rdparty/priv.c b/3rdparty/priv.c
new file mode 100644
index 0000000..c47b9a9
--- /dev/null
+++ b/3rdparty/priv.c
@@ -0,0 +1,319 @@
+///////////////////////////////////////////////////////////////////////////////
+///
+/// Written by Oliver Schneider (assarbad.net) - PUBLIC DOMAIN/CC0
+///
+/// Purpose : Functions to deal with NT privileges.
+///
+///////////////////////////////////////////////////////////////////////////////
+#include "priv.h"
+
+#pragma comment(lib, "advapi32.lib")
+
+// A struct that should fit all possible privileges ... twice over
+typedef struct _ALL_TOKEN_PRIVILEGES
+{
+ DWORD PrivilegeCount;
+ LUID_AND_ATTRIBUTES Privileges[2*MaxTokenInfoClass + 1];
+} ALL_TOKEN_PRIVILEGES;
+
+HANDLE PrivGetProcessToken(DWORD dwAdditionalAccess)
+{
+ HANDLE hToken = NULL;
+
+ if (!OpenProcessToken(GetCurrentProcess(), dwAdditionalAccess | TOKEN_QUERY, &hToken))
+ {
+ return NULL;
+ }
+ return hToken;
+}
+
+HANDLE PrivGetThreadToken(DWORD dwAdditionalAccess)
+{
+ HANDLE hToken = NULL;
+
+ if (!OpenThreadToken(GetCurrentThread(), dwAdditionalAccess | TOKEN_QUERY, TRUE, &hToken))
+ {
+ return NULL;
+ }
+ return hToken;
+}
+
+BOOL PrivSetTokenPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
+{
+ TOKEN_PRIVILEGES tp;
+ LUID luid;
+
+ if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
+ {
+ return FALSE;
+ }
+
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ if (bEnablePrivilege)
+ {
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ }
+ else
+ {
+ tp.Privileges[0].Attributes = 0;
+ }
+
+ if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+BOOL PrivSetContextPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
+{
+ HANDLE hToken = PrivGetThreadToken(TOKEN_ADJUST_PRIVILEGES);
+
+ if (!hToken)
+ {
+ hToken = PrivGetProcessToken(TOKEN_ADJUST_PRIVILEGES);
+ if (!hToken)
+ {
+ return FALSE;
+ }
+ }
+
+ if (!PrivSetTokenPrivilege(hToken, lpszPrivilege, bEnablePrivilege))
+ {
+ (void)CloseHandle(hToken);
+ return FALSE;
+ }
+
+ (void)CloseHandle(hToken);
+ return TRUE;
+}
+
+BOOL PrivSetProcessPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
+{
+ HANDLE hToken = PrivGetProcessToken(TOKEN_ADJUST_PRIVILEGES);
+
+ if (!hToken)
+ {
+ return FALSE;
+ }
+
+ if (!PrivSetTokenPrivilege(hToken, lpszPrivilege, bEnablePrivilege))
+ {
+ (void)CloseHandle(hToken);
+ return FALSE;
+ }
+
+ (void)CloseHandle(hToken);
+ return TRUE;
+}
+
+BOOL PrivSetThreadPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
+{
+ HANDLE hToken = PrivGetThreadToken(TOKEN_ADJUST_PRIVILEGES);
+
+ if (!hToken)
+ {
+ return FALSE;
+ }
+
+ if (!PrivSetTokenPrivilege(hToken, lpszPrivilege, bEnablePrivilege))
+ {
+ (void)CloseHandle(hToken);
+ return FALSE;
+ }
+
+ (void)CloseHandle(hToken);
+ return TRUE;
+}
+
+BOOL PrivHasTokenPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, LPDWORD lpdwAttributes)
+{
+ struct {
+ union
+ {
+ TOKEN_PRIVILEGES tp;
+ ALL_TOKEN_PRIVILEGES atp;
+#pragma warning(suppress : 4201)
+ };
+ } tp;
+ DWORD dwLength = 0;
+
+ RtlZeroMemory(&tp, sizeof(tp));
+ SetLastError(ERROR_INVALID_DATA);
+
+ if (GetTokenInformation(hToken, TokenPrivileges, (LPVOID)&tp, sizeof(tp), &dwLength))
+ {
+ DWORD i, dwPrivNameLength = MAX_PATH;
+ LPTSTR lpszPrivName = calloc(dwPrivNameLength, sizeof(TCHAR));
+
+ if (lpszPrivName)
+ {
+ for (i = 0; i < tp.atp.PrivilegeCount; i++)
+ {
+ dwLength = dwPrivNameLength;
+ if (!LookupPrivilegeName(NULL, &tp.atp.Privileges[i].Luid, lpszPrivName, &dwLength))
+ {
+ if (dwLength > dwPrivNameLength)
+ {
+ free(lpszPrivName);
+ dwPrivNameLength = dwLength + 1;
+ lpszPrivName = calloc(dwPrivNameLength, sizeof(TCHAR));
+ if (!lpszPrivName)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ }
+ else
+ {
+ free(lpszPrivName);
+ // Last error should be set already
+ return FALSE;
+ }
+ }
+ dwLength = dwPrivNameLength; // no error, this value will have been changed by the previous call
+ if (!LookupPrivilegeName(NULL, &tp.atp.Privileges[i].Luid, lpszPrivName, &dwLength))
+ {
+ free(lpszPrivName);
+ // Last error should be set already
+ return FALSE;
+ }
+ if (0 == _tcscmp(lpszPrivilege, lpszPrivName))
+ {
+ free(lpszPrivName);
+ if (lpdwAttributes)
+ {
+ *lpdwAttributes = tp.atp.Privileges[i].Attributes;
+ }
+ SetLastError(ERROR_SUCCESS);
+ return TRUE;
+ }
+ }
+ free(lpszPrivName);
+ lpszPrivName = NULL;
+ SetLastError(ERROR_NO_MATCH);
+ return FALSE;
+ }
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ return FALSE;
+}
+
+BOOL PrivHasContextTokenPrivilege(LPCTSTR lpszPrivilege, LPDWORD lpdwAttributes)
+{
+ HANDLE hToken = PrivGetThreadToken(0);
+
+ if (!hToken)
+ {
+ hToken = PrivGetProcessToken(0);
+ if (!hToken)
+ {
+ return FALSE;
+ }
+ }
+
+ if (!PrivHasTokenPrivilege(hToken, lpszPrivilege, lpdwAttributes))
+ {
+ DWORD dwError = GetLastError(); // save
+ (void)CloseHandle(hToken);
+ SetLastError(dwError); // restore
+ return FALSE;
+ }
+
+ (void)CloseHandle(hToken);
+ return TRUE;
+}
+
+BOOL PrivIsContextTokenPrivilegeEnabled(LPCTSTR lpszPrivilege)
+{
+ DWORD dwAttributes = 0;
+ if (PrivHasContextTokenPrivilege(lpszPrivilege, &dwAttributes))
+ {
+ if (SE_PRIVILEGE_REMOVED & dwAttributes)
+ {
+ return FALSE;
+ }
+ if ((SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT) & dwAttributes)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOL PrivHasProcessTokenPrivilege(LPCTSTR lpszPrivilege, LPDWORD lpdwAttributes)
+{
+ HANDLE hToken = PrivGetProcessToken(0);
+
+ if (!hToken)
+ {
+ return FALSE;
+ }
+
+ if (!PrivHasTokenPrivilege(hToken, lpszPrivilege, lpdwAttributes))
+ {
+ DWORD dwError = GetLastError(); // save
+ (void)CloseHandle(hToken);
+ SetLastError(dwError); // restore
+ return FALSE;
+ }
+
+ (void)CloseHandle(hToken);
+ return TRUE;
+}
+
+BOOL PrivIsProcessTokenPrivilegeEnabled(LPCTSTR lpszPrivilege)
+{
+ DWORD dwAttributes = 0;
+ if (PrivHasProcessTokenPrivilege(lpszPrivilege, &dwAttributes))
+ {
+ if (SE_PRIVILEGE_REMOVED & dwAttributes)
+ {
+ return FALSE;
+ }
+ if ((SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT) & dwAttributes)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOL PrivHasThreadTokenPrivilege(LPCTSTR lpszPrivilege, LPDWORD lpdwAttributes)
+{
+ HANDLE hToken = PrivGetThreadToken(0);
+
+ if (!hToken)
+ {
+ return FALSE;
+ }
+
+ if (!PrivHasTokenPrivilege(hToken, lpszPrivilege, lpdwAttributes))
+ {
+ DWORD dwError = GetLastError(); // save
+ (void)CloseHandle(hToken);
+ SetLastError(dwError); // restore
+ return FALSE;
+ }
+
+ (void)CloseHandle(hToken);
+ return TRUE;
+}
+
+BOOL PrivIsThreadTokenPrivilegeEnabled(LPCTSTR lpszPrivilege)
+{
+ DWORD dwAttributes = 0;
+ if (PrivHasThreadTokenPrivilege(lpszPrivilege, &dwAttributes))
+ {
+ if (SE_PRIVILEGE_REMOVED & dwAttributes)
+ {
+ return FALSE;
+ }
+ if ((SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT) & dwAttributes)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}