reactos/lib/rosrtl
diff -u -r1.13 -r1.14
--- makefile 10 Aug 2004 10:57:54 -0000 1.13
+++ makefile 11 Aug 2004 08:28:13 -0000 1.14
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.13 2004/08/10 10:57:54 weiden Exp $
+# $Id: makefile,v 1.14 2004/08/11 08:28:13 weiden Exp $
PATH_TO_TOP = ../..
@@ -13,7 +13,8 @@
THREAD_OBJECTS = \
thread/create.o \
thread/exit.o \
- thread/stack.o
+ thread/stack.o \
+ thread/priv.o
STRING_OBJECTS = \
string/append.o \
reactos/include/rosrtl
diff -N priv.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ priv.h 11 Aug 2004 08:28:13 -0000 1.1
@@ -0,0 +1,23 @@
+/* $Id: priv.h,v 1.1 2004/08/11 08:28:13 weiden Exp $
+ */
+
+#ifndef ROSRTL_SEC_H__
+#define ROSRTL_SEC_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+BOOL
+RosEnableThreadPrivileges(HANDLE *hToken, DWORD *Privileges, DWORD PrivilegeCount);
+BOOL
+RosResetThreadPrivileges(HANDLE hToken);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* EOF */
reactos/lib/rosrtl/thread
diff -N priv.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ priv.c 11 Aug 2004 08:28:13 -0000 1.1
@@ -0,0 +1,117 @@
+#include <windows.h>
+#include <string.h>
+#include <rosrtl/priv.h>
+
+/*
+ * Utility to copy and enable thread privileges
+ *
+ * OUT HANDLE *hPreviousToken -> Pointer to a variable that receives the previous token handle
+ * IN DWORD *Privileges -> Points to an array of privileges to be enabled
+ * IN DWORD PrivilegeCount -> Number of the privileges in the array
+ *
+ * Returns TRUE on success and copies the thread token (if any) handle that was active before impersonation.
+ */
+BOOL
+RosEnableThreadPrivileges(HANDLE *hPreviousToken,
+ DWORD *Privileges,
+ DWORD PrivilegeCount)
+{
+ HANDLE hToken;
+
+ if(hPreviousToken == NULL ||
+ Privileges == NULL || PrivilegeCount == 0)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Just open the thread token, we'll duplicate the handle later */
+ if(OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken))
+ {
+ PTOKEN_PRIVILEGES privs;
+ PLUID_AND_ATTRIBUTES la;
+ HANDLE hNewToken;
+ BOOL Ret;
+
+ /* duplicate the token handle */
+ if(!DuplicateTokenEx(hToken, TOKEN_IMPERSONATE, NULL, SecurityImpersonation,
+ TokenImpersonation, &hNewToken))
+ {
+ CloseHandle(hToken);
+ return FALSE;
+ }
+
+ /* Allocate the required space for the privilege list */
+ privs = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, sizeof(TOKEN_PRIVILEGES) +
+ ((PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES)));
+ if(privs == NULL)
+ {
+ CloseHandle(hNewToken);
+ CloseHandle(hToken);
+ return FALSE;
+ }
+
+ /* Build the privilege list */
+ privs->PrivilegeCount = PrivilegeCount;
+ for(la = privs->Privileges; PrivilegeCount-- > 0; la++)
+ {
+ la->Luid.LowPart = *(Privileges++);
+ la->Luid.HighPart = 0;
+ la->Attributes = SE_PRIVILEGE_ENABLED;
+ }
+
+ /* Enable the token privileges */
+ if(!AdjustTokenPrivileges(hNewToken, FALSE, privs, 0, NULL, NULL))
+ {
+ LocalFree((HLOCAL)privs);
+ CloseHandle(hNewToken);
+ CloseHandle(hToken);
+ return FALSE;
+ }
+
+ /* we don't need the privileges list anymore */
+ LocalFree((HLOCAL)privs);
+
+ /* Perform the impersonation */
+ Ret = SetThreadToken(NULL, hToken);
+
+ if(Ret)
+ {
+ /* only copy the previous token handle on success */
+ *hPreviousToken = hToken;
+ }
+
+ /* We don't need the handle to the new token anymore */
+ CloseHandle(hNewToken);
+
+ return Ret;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Utility to reset the thread privileges previously changed with RosEnableThreadPrivileges()
+ *
+ * IN HANDLE hToken -> Handle of the thread token to be restored
+ *
+ * Returns TRUE on success.
+ */
+BOOL
+RosResetThreadPrivileges(HANDLE hToken)
+{
+ if(hToken != INVALID_HANDLE_VALUE)
+ {
+ BOOL Ret;
+
+ /* Set the previous token handle */
+ Ret = SetThreadToken(NULL, hToken);
+
+ /* We don't need the handle anymore, close it */
+ CloseHandle(hToken);
+ return Ret;
+ }
+ return FALSE;
+}
+