static DWORD ScmUnloadDriver(PSERVICE lpService) { NTSTATUS Status = STATUS_SUCCESS; BOOLEAN WasPrivilegeEnabled = FALSE; PWSTR pszDriverPath; UNICODE_STRING DriverPath; DWORD dwError; /* Build the driver path */ /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */ pszDriverPath = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (52 + wcslen(lpService->lpServiceName) + 1) * sizeof(WCHAR)); if (pszDriverPath == NULL) return ERROR_NOT_ENOUGH_MEMORY; wcscpy(pszDriverPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"); wcscat(pszDriverPath, lpService->lpServiceName); RtlInitUnicodeString(&DriverPath, pszDriverPath); DPRINT(" Path: %wZ\n", &DriverPath); /* Acquire driver-unloading privilege */ Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, TRUE, FALSE, &WasPrivilegeEnabled); if (!NT_SUCCESS(Status)) { /* We encountered a failure, exit properly */ DPRINT1("SERVICES: Cannot acquire driver-unloading privilege, Status = 0x%08lx\n", Status); dwError = RtlNtStatusToDosError(Status); goto done; } Status = NtUnloadDriver(&DriverPath); if (Status == STATUS_INVALID_DEVICE_REQUEST) dwError = ERROR_INVALID_SERVICE_CONTROL; else dwError = RtlNtStatusToDosError(Status); /* Release driver-unloading privilege */ RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE, WasPrivilegeEnabled, FALSE, &WasPrivilegeEnabled); done: HeapFree(GetProcessHeap(), 0, pszDriverPath); return dwError; }
//-------------------------------------------------------------------------- void term_win32_subsystem(void) { if ( hPSAPI != NULL ) { FreeLibrary(hPSAPI); hPSAPI = NULL; } if ( DriverHandle != NULL ) { CloseHandle(DriverHandle); DriverHandle = NULL; NtUnloadDriver(&DriverPath); } }