- partially implemented RegisterGPNotification() and
UnregisterGPNotification() (depends on GetModuleHandleEx which is not
yet implemented)
- use debug.h
Modified: trunk/reactos/lib/userenv/desktop.c
Modified: trunk/reactos/lib/userenv/directory.c
Modified: trunk/reactos/lib/userenv/environment.c
Added: trunk/reactos/lib/userenv/gpolicy.c
Modified: trunk/reactos/lib/userenv/internal.h
Modified: trunk/reactos/lib/userenv/misc.c
Modified: trunk/reactos/lib/userenv/profile.c
Modified: trunk/reactos/lib/userenv/registry.c
Modified: trunk/reactos/lib/userenv/setup.c
Modified: trunk/reactos/lib/userenv/userenv.c
Modified: trunk/reactos/lib/userenv/userenv.def
Modified: trunk/reactos/lib/userenv/userenv.xml
_____
Modified: trunk/reactos/lib/userenv/desktop.c
--- trunk/reactos/lib/userenv/desktop.c 2006-01-11 22:13:02 UTC (rev
20791)
+++ trunk/reactos/lib/userenv/desktop.c 2006-01-11 22:40:31 UTC (rev
20792)
@@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG
+#include <debug.h>
+
/* FUNCTIONS
***************************************************************/
static BOOL
_____
Modified: trunk/reactos/lib/userenv/directory.c
--- trunk/reactos/lib/userenv/directory.c 2006-01-11 22:13:02 UTC
(rev 20791)
+++ trunk/reactos/lib/userenv/directory.c 2006-01-11 22:40:31 UTC
(rev 20792)
@@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG
+#include <debug.h>
+
/* FUNCTIONS
***************************************************************/
BOOL STDCALL
_____
Modified: trunk/reactos/lib/userenv/environment.c
--- trunk/reactos/lib/userenv/environment.c 2006-01-11 22:13:02 UTC
(rev 20791)
+++ trunk/reactos/lib/userenv/environment.c 2006-01-11 22:40:31 UTC
(rev 20792)
@@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG
+#include <debug.h>
+
static BOOL
SetUserEnvironmentVariable (LPVOID *Environment,
LPWSTR lpName,
_____
Added: trunk/reactos/lib/userenv/gpolicy.c
--- trunk/reactos/lib/userenv/gpolicy.c 2006-01-11 22:13:02 UTC (rev
20791)
+++ trunk/reactos/lib/userenv/gpolicy.c 2006-01-11 22:40:31 UTC (rev
20792)
@@ -0,0 +1,403 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 2006 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or
modify
+ * it under the terms of the GNU General Public License as published
by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/userenv/gpolicy.c
+ * PURPOSE: Group policy functions
+ * PROGRAMMER: Thomas Weidenmueller <w3seek(a)reactos.com>
+ */
+
+#include <precomp.h>
+
+#define NDEBUG
+#include <debug.h>
+
+
+typedef struct _GP_NOTIFY
+{
+ struct _GP_NOTIFY *Next;
+ HANDLE hEvent;
+ BOOL bMachine;
+} GP_NOTIFY, *PGP_NOTIFY;
+
+typedef enum
+{
+ gpaUpdate = 0,
+ gpaTerminate
+} GP_ACTION;
+
+static const WCHAR szLocalGPApplied[] = L"userenv: User Group Policy
has been applied";
+static const WCHAR szMachineGPApplied[] = L"Global\\userenv: Machine
Group Policy has been applied";
+
+static CRITICAL_SECTION GPNotifyLock;
+static PGP_NOTIFY NotificationList = NULL;
+static GP_ACTION GPNotificationAction = gpaUpdate;
+static HANDLE hNotificationThread = NULL;
+static HANDLE hNotificationThreadEvent = NULL;
+static HANDLE hLocalGPAppliedEvent = NULL;
+static HANDLE hMachineGPAppliedEvent = NULL;
+
+VOID
+InitializeGPNotifications(VOID)
+{
+ InitializeCriticalSection(&GPNotifyLock);
+}
+
+VOID
+UninitializeGPNotifications(VOID)
+{
+ EnterCriticalSection(&GPNotifyLock);
+
+ /* rundown the notification thread */
+ if (hNotificationThread != NULL)
+ {
+ ASSERT(hNotificationThreadEvent != NULL);
+
+ /* notify the thread */
+ GPNotificationAction = gpaTerminate;
+ SetEvent(hNotificationThreadEvent);
+
+ LeaveCriticalSection(&GPNotifyLock);
+
+ /* wait for the thread to terminate itself */
+ WaitForSingleObject(hNotificationThread,
+ INFINITE);
+
+ EnterCriticalSection(&GPNotifyLock);
+
+ if (hNotificationThread != NULL)
+ {
+ /* the handle should be closed by the thread,
+ just in case that didn't happen for an unknown reason */
+ CloseHandle(hNotificationThread);
+ hNotificationThread = NULL;
+ }
+ }
+
+ if (hNotificationThreadEvent != NULL)
+ {
+ CloseHandle(hNotificationThreadEvent);
+ hNotificationThreadEvent = NULL;
+ }
+
+ LeaveCriticalSection(&GPNotifyLock);
+
+ DeleteCriticalSection(&GPNotifyLock);
+}
+
+static VOID
+NotifyGPEvents(IN BOOL bMachine)
+{
+ PGP_NOTIFY Notify = NotificationList;
+
+ while (Notify != NULL)
+ {
+ if (Notify->bMachine == bMachine)
+ {
+ SetEvent(Notify->hEvent);
+ }
+
+ Notify = Notify->Next;
+ }
+}
+
+static DWORD WINAPI
+GPNotificationThreadProc(IN LPVOID lpParameter)
+{
+ HMODULE hModule;
+ DWORD WaitResult, WaitCount;
+ HANDLE WaitHandles[3];
+
+ /* reference the library so we don't screw up if the application
+ causes the DLL to unload while this thread is still running */
+ if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ (LPCWSTR)hInstance,
+ &hModule))
+ {
+ ASSERT(hModule == hInstance);
+
+ EnterCriticalSection(&GPNotifyLock);
+
+ ASSERT(hNotificationThreadEvent != NULL);
+ WaitHandles[0] = hNotificationThreadEvent;
+ for (;;)
+ {
+ ASSERT(hMachineGPAppliedEvent != NULL);
+
+ if (NotificationList == NULL)
+ break;
+
+ WaitCount = 2;
+ WaitHandles[1] = hMachineGPAppliedEvent;
+
+ if (hLocalGPAppliedEvent != NULL)
+ {
+ WaitHandles[2] = hLocalGPAppliedEvent;
+ WaitCount++;
+ }
+
+ LeaveCriticalSection(&GPNotifyLock);
+
+ WaitResult = WaitForMultipleObjects(WaitCount,
+ WaitHandles,
+ FALSE,
+ INFINITE);
+
+ EnterCriticalSection(&GPNotifyLock);
+
+ if (WaitResult != WAIT_FAILED)
+ {
+ if (WaitResult == WAIT_OBJECT_0)
+ {
+ ResetEvent(hNotificationThreadEvent);
+
+ if (GPNotificationAction == gpaTerminate)
+ {
+ /* terminate the thread */
+ break;
+ }
+ }
+ else if (WaitResult == WAIT_OBJECT_0 + 1 || WaitResult
== WAIT_OBJECT_0 + 2)
+ {
+ /* group policies have been applied */
+ if (NotificationList != NULL)
+ {
+ NotifyGPEvents((WaitResult == WAIT_OBJECT_0 +
1));
+ }
+ }
+ else if (WaitResult == WAIT_ABANDONED_0 + 2)
+ {
+ /* In case the local group policies event was
abandoned, keep watching!
+ But close the handle as it's no longer of any
use. */
+ if (hLocalGPAppliedEvent != NULL)
+ {
+ CloseHandle(hLocalGPAppliedEvent);
+ hLocalGPAppliedEvent = NULL;
+ }
+ }
+ else if (WaitResult == WAIT_ABANDONED_0 || WaitResult
== WAIT_ABANDONED_0 + 1)
+ {
+ /* terminate the thread if the machine group
policies event was abandoned
+ or for some reason the rundown event got
abandoned. */
+ break;
+ }
+ else
+ {
+ DPRINT("Unexpected wait result watching the group
policy events: 0x%x\n", WaitResult);
+ ASSERT(FALSE);
+ break;
+ }
+
+ if (NotificationList == NULL)
+ break;
+ }
+ else
+ break;
+
+ }
+
+ /* cleanup handles no longer used */
+ ASSERT(hNotificationThread != NULL);
+ ASSERT(hNotificationThreadEvent != NULL);
+
+ CloseHandle(hNotificationThread);
+ CloseHandle(hNotificationThreadEvent);
+ hNotificationThread = NULL;
+ hNotificationThreadEvent = NULL;
+
+ if (hLocalGPAppliedEvent != NULL)
+ {
+ CloseHandle(hLocalGPAppliedEvent);
+ hLocalGPAppliedEvent = NULL;
+ }
+ if (hMachineGPAppliedEvent != NULL)
+ {
+ CloseHandle(hMachineGPAppliedEvent);
+ hMachineGPAppliedEvent = NULL;
+ }
+
+ LeaveCriticalSection(&GPNotifyLock);
+
+ /* dereference the library and exit */
+ FreeLibraryAndExitThread(hModule,
+ 0);
+ }
+ else
+ {
+ DPRINT1("Referencing the library failed!\n");
+ }
+
+ return 1;
+}
+
+static HANDLE
+CreateGPEvent(IN BOOL bMachine,
+ IN PVOID lpSecurityDescriptor)
+{
+ HANDLE hEvent;
+ SECURITY_ATTRIBUTES SecurityAttributes;
+
+ SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ SecurityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
+ SecurityAttributes.bInheritHandle = FALSE;
+
+ hEvent = CreateEventW((lpSecurityDescriptor != NULL ?
&SecurityAttributes : NULL),
+ TRUE,
+ FALSE,
+ (bMachine ? szMachineGPApplied :
szLocalGPApplied));
+
+ return hEvent;
+}
+
+BOOL WINAPI
+RegisterGPNotification(IN HANDLE hEvent,
+ IN BOOL bMachine)
+{
+ PGP_NOTIFY Notify;
+ PVOID lpSecurityDescriptor = NULL;
+ BOOL Ret = FALSE;
+
+ EnterCriticalSection(&GPNotifyLock);
+
+ /* create the thread notification event */
+ if (hNotificationThreadEvent == NULL)
+ {
+ hNotificationThreadEvent = CreateEvent(NULL,
+ TRUE,
+ FALSE,
+ NULL);
+ if (hNotificationThreadEvent == NULL)
+ {
+ goto Cleanup;
+ }
+ }
+
+ /* create or open the machine group policy event */
+ if (hMachineGPAppliedEvent == NULL)
+ {
+ lpSecurityDescriptor = CreateDefaultSD();
+
+ hMachineGPAppliedEvent = CreateGPEvent(TRUE,
+ lpSecurityDescriptor);
+ if (hMachineGPAppliedEvent == NULL)
+ {
+ goto Cleanup;
+ }
+ }
+
+ /* create or open the local group policy event only if necessary */
+ if (!bMachine && hLocalGPAppliedEvent == NULL)
+ {
+ if (lpSecurityDescriptor == NULL)
+ {
+ lpSecurityDescriptor = CreateDefaultSD();
+ }
+
+ hLocalGPAppliedEvent = CreateGPEvent(FALSE,
+ lpSecurityDescriptor);
+ if (hLocalGPAppliedEvent == NULL)
+ {
+ goto Cleanup;
+ }
+ }
+
+ if (hNotificationThread == NULL)
+ {
+ hNotificationThread = CreateThread(NULL,
+ 0,
+ GPNotificationThreadProc,
+ NULL,
+ 0,
+ NULL);
+ }
+
+ if (hNotificationThread != NULL)
+ {
+ Notify = (PGP_NOTIFY)LocalAlloc(LMEM_FIXED,
+ sizeof(GP_NOTIFY));
+ if (Notify != NULL)
+ {
+ /* add the item to the beginning of the list */
+ Notify->Next = NotificationList;
+ Notify->hEvent = hEvent;
+ Notify->bMachine = bMachine;
+
+ NotificationList = Notify;
+
+ /* notify the thread */
+ GPNotificationAction = gpaUpdate;
+ SetEvent(hNotificationThreadEvent);
+
+ Ret = TRUE;
+ }
+ }
+
+Cleanup:
+ LeaveCriticalSection(&GPNotifyLock);
+
+ if (lpSecurityDescriptor != NULL)
+ {
+ LocalFree((HLOCAL)lpSecurityDescriptor);
+ }
+
+ /* NOTE: don't delete the events or close the handles created */
+
+ return Ret;
+}
+
+BOOL WINAPI
+UnregisterGPNotification(IN HANDLE hEvent)
+{
+ PGP_NOTIFY Notify = NULL, *NotifyLink;
+ BOOL Ret = FALSE;
+
+ EnterCriticalSection(&GPNotifyLock);
+
+ Notify = NotificationList;
+ NotifyLink = &NotificationList;
+
+ while (Notify != NULL)
+ {
+ if (Notify->hEvent == hEvent)
+ {
+ /* remove and free the item */
+ *NotifyLink = Notify->Next;
+ LocalFree((HLOCAL)Notify);
+
+ /* notify the thread */
+ if (hNotificationThread != NULL &&
+ hNotificationThreadEvent != NULL)
+ {
+ GPNotificationAction = gpaUpdate;
+ SetEvent(hNotificationThreadEvent);
+ }
+
+ Ret = TRUE;
+ break;
+ }
+
+ NotifyLink = &Notify->Next;
+ Notify = Notify->Next;
+ }
+
+ LeaveCriticalSection(&GPNotifyLock);
+
+ return Ret;
+}
Property changes on: trunk/reactos/lib/userenv/gpolicy.c
___________________________________________________________________
Name: svn:keywords
+ author date revision
Name: svn:eol-style
+ native
_____
Modified: trunk/reactos/lib/userenv/internal.h
--- trunk/reactos/lib/userenv/internal.h 2006-01-11 22:13:02 UTC
(rev 20791)
+++ trunk/reactos/lib/userenv/internal.h 2006-01-11 22:40:31 UTC
(rev 20792)
@@ -28,20 +28,6 @@
#ifndef _INTERNAL_H
#define _INTERNAL_H
-/* debug.h */
-void
-DebugPrint (char* fmt,...);
-
-#define DPRINT1 DebugPrint("(%s:%d) ",__FILE__,__LINE__), DebugPrint
-#define CHECKPOINT1 do { DebugPrint("%s:%d\n",__FILE__,__LINE__); }
while(0);
-
-#ifdef __GNUC__
-#define DPRINT(args...)
-#else
-#define DPRINT
-#endif /* __GNUC__ */
-#define CHECKPOINT
-
/* directory.c */
BOOL
CopyDirectory (LPCWSTR lpDestinationPath,
@@ -91,6 +77,9 @@
GetUserSidFromToken (HANDLE hToken,
PUNICODE_STRING SidString);
+PVOID
+CreateDefaultSD(VOID);
+
/* profile.c */
BOOL
AppendSystemPostfix (LPWSTR lpName,
@@ -109,6 +98,14 @@
/* userenv.c */
extern HINSTANCE hInstance;
+/* gpolicy.c */
+
+VOID
+InitializeGPNotifications(VOID);
+
+VOID
+UninitializeGPNotifications(VOID);
+
#endif /* _INTERNAL_H */
/* EOF */
_____
Modified: trunk/reactos/lib/userenv/misc.c
--- trunk/reactos/lib/userenv/misc.c 2006-01-11 22:13:02 UTC (rev
20791)
+++ trunk/reactos/lib/userenv/misc.c 2006-01-11 22:40:31 UTC (rev
20792)
@@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG
+#include <debug.h>
+
/* FUNCTIONS
***************************************************************/
LPWSTR
@@ -109,6 +112,13 @@
return TRUE;
}
+PVOID
+CreateDefaultSD(VOID)
+{
+ /* FIXME - create a default security descriptor */
+ return NULL;
+}
+
/* Dynamic DLL loading interface
**********************************************/
/* OLE32.DLL import table */
_____
Modified: trunk/reactos/lib/userenv/profile.c
--- trunk/reactos/lib/userenv/profile.c 2006-01-11 22:13:02 UTC (rev
20791)
+++ trunk/reactos/lib/userenv/profile.c 2006-01-11 22:40:31 UTC (rev
20792)
@@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG
+#include <debug.h>
+
/* FUNCTIONS
***************************************************************/
BOOL
_____
Modified: trunk/reactos/lib/userenv/registry.c
--- trunk/reactos/lib/userenv/registry.c 2006-01-11 22:13:02 UTC
(rev 20791)
+++ trunk/reactos/lib/userenv/registry.c 2006-01-11 22:40:31 UTC
(rev 20792)
@@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG
+#include <debug.h>
+
/* FUNCTIONS
***************************************************************/
static BOOL
_____
Modified: trunk/reactos/lib/userenv/setup.c
--- trunk/reactos/lib/userenv/setup.c 2006-01-11 22:13:02 UTC (rev
20791)
+++ trunk/reactos/lib/userenv/setup.c 2006-01-11 22:40:31 UTC (rev
20792)
@@ -27,6 +27,10 @@
#include <precomp.h>
+#define NDEBUG
+#include <debug.h>
+
+
typedef struct _FOLDERDATA
{
LPWSTR lpValueName;
_____
Modified: trunk/reactos/lib/userenv/userenv.c
--- trunk/reactos/lib/userenv/userenv.c 2006-01-11 22:13:02 UTC (rev
20791)
+++ trunk/reactos/lib/userenv/userenv.c 2006-01-11 22:40:31 UTC (rev
20792)
@@ -27,6 +27,9 @@
#include <precomp.h>
+#define NDEBUG
+#include <debug.h>
+
HINSTANCE hInstance = NULL;
BOOL WINAPI
@@ -37,9 +40,11 @@
if (fdwReason == DLL_PROCESS_ATTACH)
{
hInstance = hinstDLL;
+ InitializeGPNotifications();
}
else if (fdwReason == DLL_PROCESS_DETACH)
{
+ UninitializeGPNotifications();
}
return TRUE;
_____
Modified: trunk/reactos/lib/userenv/userenv.def
--- trunk/reactos/lib/userenv/userenv.def 2006-01-11 22:13:02 UTC
(rev 20791)
+++ trunk/reactos/lib/userenv/userenv.def 2006-01-11 22:40:31 UTC
(rev 20792)
@@ -31,5 +31,7 @@
GetUserProfileDirectoryW@12
LoadUserProfileA@8
LoadUserProfileW@8
+RegisterGPNotification@8
UnloadUserProfile@8
+UnregisterGPNotification@4
;EOF
_____
Modified: trunk/reactos/lib/userenv/userenv.xml
--- trunk/reactos/lib/userenv/userenv.xml 2006-01-11 22:13:02 UTC
(rev 20791)
+++ trunk/reactos/lib/userenv/userenv.xml 2006-01-11 22:40:31 UTC
(rev 20792)
@@ -13,6 +13,7 @@
<file>desktop.c</file>
<file>directory.c</file>
<file>environment.c</file>
+ <file>gpolicy.c</file>
<file>misc.c</file>
<file>profile.c</file>
<file>registry.c</file>