📄 gpolicy.c
字号:
/*
* 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@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 szLocalGPMutex[] = L"userenv: user policy mutex";
static const WCHAR szLocalGPRefreshEvent[] = L"userenv: user policy refresh event";
static const WCHAR szLocalGPForceRefreshEvent[] = L"userenv: user policy force refresh event";
static const WCHAR szLocalGPDoneEvent[] = L"userenv: User Policy Foreground Done Event";
static const WCHAR szMachineGPApplied[] = L"Global\\userenv: Machine Group Policy has been applied";
static const WCHAR szMachineGPMutex[] = L"Global\\userenv: machine policy mutex";
static const WCHAR szMachineGPRefreshEvent[] = L"Global\\userenv: machine policy refresh event";
static const WCHAR szMachineGPForceRefreshEvent[] = L"Global\\userenv: machine policy force refresh event";
static const WCHAR szMachineGPDoneEvent[] = L"Global\\userenv: Machine Policy Foreground Done Event";
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 PSECURITY_DESCRIPTOR lpSecurityDescriptor)
{
HANDLE hEvent;
SECURITY_ATTRIBUTES SecurityAttributes;
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
SecurityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
SecurityAttributes.bInheritHandle = FALSE;
hEvent = CreateEventW(&SecurityAttributes,
TRUE,
FALSE,
(bMachine ? szMachineGPApplied : szLocalGPApplied));
return hEvent;
}
BOOL WINAPI
RegisterGPNotification(IN HANDLE hEvent,
IN BOOL bMachine)
{
PGP_NOTIFY Notify;
PSECURITY_DESCRIPTOR lpSecurityDescriptor = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -