diff --git a/reactos/base/system/services/driver.c b/reactos/base/system/services/driver.c index 236657d408f..b8023dcedb9 100644 --- a/reactos/base/system/services/driver.c +++ b/reactos/base/system/services/driver.c @@ -16,6 +16,50 @@ /* FUNCTIONS ****************************************************************/ +static DWORD EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege) +{ + DWORD dwRet = ERROR_SUCCESS; + HANDLE hToken = NULL; + + if (OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES, + &hToken)) + { + TOKEN_PRIVILEGES tp; + + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0); + + if (LookupPrivilegeValueW(NULL, + lpszPrivilegeName, + &tp.Privileges[0].Luid)) + { + if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL)) + { + if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) + dwRet = ERROR_NOT_ALL_ASSIGNED; + } + else + { + dwRet = GetLastError(); + } + } + else + { + dwRet = GetLastError(); + } + + CloseHandle(hToken); + } + else + { + dwRet = GetLastError(); + } + + return dwRet; +} + + DWORD ScmLoadDriver(PSERVICE lpService) { @@ -40,18 +84,28 @@ ScmLoadDriver(PSERVICE lpService) RtlInitUnicodeString(&DriverPath, pszDriverPath); - /* FIXME: Acquire privilege */ - DPRINT(" Path: %wZ\n", &DriverPath); + + /* Acquire driver-loading privilege */ + dwError = EnablePrivilege(SE_LOAD_DRIVER_NAME, TRUE); + if (dwError != ERROR_SUCCESS) + { + /* We encountered a failure, exit properly */ + DPRINT1("SERVICES: Cannot acquire driver-loading privilege, error = %lu\n", dwError); + goto done; + } + Status = NtLoadDriver(&DriverPath); - /* FIXME: Release privilege */ + /* Release driver-loading privilege */ + EnablePrivilege(SE_LOAD_DRIVER_NAME, FALSE); if (!NT_SUCCESS(Status)) { dwError = RtlNtStatusToDosError(Status); } +done: HeapFree(GetProcessHeap(), 0, pszDriverPath); return dwError; @@ -82,17 +136,26 @@ ScmUnloadDriver(PSERVICE lpService) RtlInitUnicodeString(&DriverPath, pszDriverPath); - /* FIXME: Acquire privilege */ + /* Acquire driver-unloading privilege */ + dwError = EnablePrivilege(SE_LOAD_DRIVER_NAME, TRUE); + if (dwError != ERROR_SUCCESS) + { + /* We encountered a failure, exit properly */ + DPRINT1("SERVICES: Cannot acquire driver-unloading privilege, error = %lu\n", dwError); + goto done; + } Status = NtUnloadDriver(&DriverPath); - /* FIXME: Release privilege */ + /* Release driver-unloading privilege */ + EnablePrivilege(SE_LOAD_DRIVER_NAME, FALSE); if (!NT_SUCCESS(Status)) { dwError = RtlNtStatusToDosError(Status); } +done: HeapFree(GetProcessHeap(), 0, pszDriverPath); return dwError; diff --git a/reactos/base/system/services/services.c b/reactos/base/system/services/services.c index ca7401e5fc0..982e0fbdeb3 100644 --- a/reactos/base/system/services/services.c +++ b/reactos/base/system/services/services.c @@ -327,28 +327,6 @@ StartScmNamedPipeThreadListener(VOID) } -VOID FASTCALL -AcquireLoadDriverPrivilege(VOID) -{ - HANDLE hToken; - TOKEN_PRIVILEGES tkp; - - /* Get a token for this process */ - if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) - { - /* Get the LUID for the debug privilege */ - LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &tkp.Privileges[0].Luid); - - /* One privilege to set */ - tkp.PrivilegeCount = 1; - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - /* Get the debug privilege for this process */ - AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); - } -} - - BOOL WINAPI ShutdownHandlerRoutine(DWORD dwCtrlType) { @@ -378,7 +356,7 @@ wWinMain(HINSTANCE hInstance, { HANDLE hScmStartEvent = NULL; SC_RPC_LOCK Lock = NULL; - BOOL bDeleteCriticalSection = FALSE; + BOOL bCanDeleteNamedPipeCriticalSection = FALSE; DWORD dwError; DPRINT("SERVICES: Service Control Manager\n"); @@ -400,6 +378,10 @@ wWinMain(HINSTANCE hInstance, goto done; } + /* Initialize our communication named pipe's critical section */ + ScmInitNamedPipeCriticalSection(); + bCanDeleteNamedPipeCriticalSection = TRUE; + // ScmInitThreadManager(); /* FIXME: more initialization */ @@ -422,12 +404,20 @@ wWinMain(HINSTANCE hInstance, /* Update service database */ ScmGetBootAndSystemDriverState(); - /* Start the RPC server */ - ScmStartRpcServer(); - /* Register service process with CSRSS */ RegisterServicesProcess(GetCurrentProcessId()); + /* Acquire the service start lock until autostart services have been started */ + dwError = ScmAcquireServiceStartLock(TRUE, &Lock); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("SERVICES: failed to acquire the service start lock (Error %lu)\n", dwError); + goto done; + } + + /* Start the RPC server */ + ScmStartRpcServer(); + DPRINT("SERVICES: Initialized.\n"); /* Signal start event */ @@ -439,20 +429,6 @@ wWinMain(HINSTANCE hInstance, /* Wait for the LSA server */ ScmWaitForLsa(); - /* Acquire privileges to load drivers */ - AcquireLoadDriverPrivilege(); - - ScmInitNamedPipeCriticalSection(); - bDeleteCriticalSection = TRUE; - - /* Acquire the service start lock until autostart services have been started */ - dwError = ScmAcquireServiceStartLock(TRUE, &Lock); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("SERVICES: failed to acquire the service start lock (Error %lu)\n", dwError); - goto done; - } - /* Start auto-start services */ ScmAutoStartServices(); @@ -467,7 +443,8 @@ wWinMain(HINSTANCE hInstance, WaitForSingleObject(hScmShutdownEvent, INFINITE); done: - if (bDeleteCriticalSection == TRUE) + /* Delete our communication named pipe's critical section */ + if (bCanDeleteNamedPipeCriticalSection == TRUE) ScmDeleteNamedPipeCriticalSection(); /* Close the shutdown event */