INT EncServiceInstall() { SC_HANDLE hSCManager = NULL; SC_HANDLE hService = NULL; SERVICE_DESCRIPTION ServiceDescription; SERVICE_PRESHUTDOWN_INFO ServicePreshutdownInfo; CHAR BinaryPath[MAX_PATH + 64]; INT Ret = -1; if(!GetBinaryPath(BinaryPath, sizeof(BinaryPath))) { PrintLastError("EncServiceInstall:"); goto err; } hSCManager = OpenSCManager( NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS ); if(NULL == hSCManager) { PrintLastError("EncServiceInstall:"); goto err; } hService = CreateService( hSCManager, ENC_MON_SERVICE_NAME, ENC_MON_SERVICE_DISPLAY_NAME, SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, BinaryPath, NULL, NULL, ENC_DISK_SERVICE_NAME, NULL, NULL ); if(NULL == hService) { PrintLastError("EncServiceInstall:"); goto err; } ServiceDescription.lpDescription = ENC_MON_SERVICE_DESCRIPTION; if(!ChangeServiceConfig2( hService, SERVICE_CONFIG_DESCRIPTION, &ServiceDescription )) { PrintLastError("EncServiceInstall:"); goto err; } ServicePreshutdownInfo.dwPreshutdownTimeout = ENC_MON_SERVICE_MAX_WAIT_MS; if(!ChangeServiceConfig2( hService, SERVICE_CONFIG_PRESHUTDOWN_INFO, &ServicePreshutdownInfo )) { PrintLastError("EncServiceInstall:"); goto err; } Ret = 0; err: if(NULL != hService) { CloseServiceHandle(hService); hService = NULL; } if(NULL != hSCManager) { CloseServiceHandle(hSCManager); hSCManager = NULL; } return Ret; }
BOOL StopDependentServices(SC_HANDLE hSCManager, SC_HANDLE hService) { LPENUM_SERVICE_STATUS lpDependencies = NULL; ENUM_SERVICE_STATUS ess; SC_HANDLE hDepService; SERVICE_STATUS_PROCESS ssp; DWORD i, dwBytesNeeded, dwCount; DWORD dwStartTime = GetTickCount(); DWORD dwTimeout = 30000; // 30 секундна пауза // Пускане на буфер с нулева дължина, за да се получи желания размер на буфера. if (EnumDependentServices(hService, SERVICE_ACTIVE, lpDependencies, 0, &dwBytesNeeded, &dwCount)) // Ако извикването на Enum-а е успешно, тогава няма зависими // сервиси, така че не се прави нищо. return TRUE; if (GetLastError() != ERROR_MORE_DATA) return FALSE; // Неочаквана грешка // Алокиране на буфер за зависимостите. lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded); if (!lpDependencies) return FALSE; __try { // Избройват се зависимостите. if (!EnumDependentServices(hService, SERVICE_ACTIVE, lpDependencies, dwBytesNeeded, &dwBytesNeeded, &dwCount)) return FALSE; for (i=0; i<dwCount; i++) { ess = *(lpDependencies + i); // Отваря се сервиса hDepService = OpenService(hSCManager, ess.lpServiceName, SERVICE_STOP|SERVICE_QUERY_STATUS); if (!hDepService) return FALSE; __try { // Изпраща се стоп код. if (!ControlService(hDepService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp)) return FALSE; // Изчаква се сервиса да спре. while (ssp.dwCurrentState != SERVICE_STOPPED) { Sleep(ssp.dwWaitHint); if (!QueryServiceStatusEx(hDepService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) return FALSE; if (ssp.dwCurrentState == SERVICE_STOPPED) break; if (GetTickCount() - dwStartTime > dwTimeout) return FALSE; } } __finally { // Винаги се изпуска дръжката на сервиса. CloseServiceHandle(hDepService); } } } __finally { // Винаги се освобождава изброения буфер. HeapFree(GetProcessHeap(), 0, lpDependencies); } return TRUE; }
NOEXPORT int service_stop(void) { SC_HANDLE scm, service; SERVICE_STATUS serviceStatus; scm=OpenSCManager(0, 0, SC_MANAGER_CONNECT); if(!scm) { error_box(TEXT("OpenSCManager")); return 1; } service=OpenService(scm, SERVICE_NAME, SERVICE_QUERY_STATUS|SERVICE_STOP); if(!service) { error_box(TEXT("OpenService")); CloseServiceHandle(scm); return 1; } if(!QueryServiceStatus(service, &serviceStatus)) { error_box(TEXT("QueryServiceStatus")); CloseServiceHandle(service); CloseServiceHandle(scm); return 1; } if(serviceStatus.dwCurrentState==SERVICE_STOPPED) { message_box(TEXT("The service is already stopped"), MB_ICONERROR); CloseServiceHandle(service); CloseServiceHandle(scm); return 1; } if(!ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus)) { error_box(TEXT("ControlService")); CloseServiceHandle(service); CloseServiceHandle(scm); return 1; } do { Sleep(1000); if(!QueryServiceStatus(service, &serviceStatus)) { error_box(TEXT("QueryServiceStatus")); CloseServiceHandle(service); CloseServiceHandle(scm); return 1; } } while(serviceStatus.dwCurrentState!=SERVICE_STOPPED); message_box(TEXT("Service stopped"), MB_ICONINFORMATION); CloseServiceHandle(service); CloseServiceHandle(scm); return 0; }
BOOL ServiceRun() { SC_HANDLE scm, Service; SERVICE_STATUS ssStatus; DWORD dwOldCheckPoint; DWORD dwStartTickCount; DWORD dwWaitTime; DWORD dwStatus; scm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!scm) { ErrorHandler("OpenSCManager", GetLastError()); } Service = OpenService(scm, ServiceName, SERVICE_ALL_ACCESS); if (!Service) { ErrorHandler("OpenService", GetLastError()); return FALSE; } else { StartService(Service, 0, NULL); srvc.GetStatus(Service); if (!QueryServiceStatus( Service, &ssStatus) ) { ErrorHandler("QueryServiceStatus", GetLastError()); } dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; while (ssStatus.dwCurrentState == SERVICE_START_PENDING) { dwWaitTime = ssStatus.dwWaitHint / 10; if( dwWaitTime < 1000 ) { dwWaitTime = 1000; } else if ( dwWaitTime > 10000 ) { dwWaitTime = 10000; } Sleep( dwWaitTime ); if (!QueryServiceStatus(Service, &ssStatus) ) { break; } if ( ssStatus.dwCheckPoint > dwOldCheckPoint ) { dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; } else { if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint) { break; } } } if (ssStatus.dwCurrentState == SERVICE_RUNNING) { srvc.GetStatus(Service); dwStatus = NO_ERROR; } else { printf("\nService not started.\n"); printf(" Current State: %d\n", ssStatus.dwCurrentState); printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode); printf(" Service Specific Exit Code: %d\n", ssStatus.dwServiceSpecificExitCode); printf(" Check Point: %d\n", ssStatus.dwCheckPoint); printf(" Wait Hint: %d\n", ssStatus.dwWaitHint); dwStatus = GetLastError(); } } CloseServiceHandle(scm); CloseServiceHandle(Service); return TRUE; }
/** * Waits for a service to enter a stopped state. * This function does not stop the service, it just blocks until the service * is stopped. * * @param serviceName The service to wait for. * @param maxWaitSeconds The maximum number of seconds to wait * @return state of the service after a timeout or when stopped. * A value of 255 is returned for an error. Typical values are: * SERVICE_STOPPED 0x00000001 * SERVICE_START_PENDING 0x00000002 * SERVICE_STOP_PENDING 0x00000003 * SERVICE_RUNNING 0x00000004 * SERVICE_CONTINUE_PENDING 0x00000005 * SERVICE_PAUSE_PENDING 0x00000006 * SERVICE_PAUSED 0x00000007 * last status not set 0x000000CF * Could no query status 0x000000DF * Could not open service, access denied 0x000000EB * Could not open service, invalid handle 0x000000EC * Could not open service, invalid name 0x000000ED * Could not open service, does not exist 0x000000EE * Could not open service, other error 0x000000EF * Could not open SCM, access denied 0x000000FD * Could not open SCM, database does not exist 0x000000FE; * Could not open SCM, other error 0x000000FF; * Note: The strange choice of error codes above SERVICE_PAUSED are chosen * in case Windows comes out with other service stats higher than 7, they * would likely call it 8 and above. JS code that uses this in TestAUSHelper * only handles values up to 255 so that's why we don't use GetLastError * directly. */ DWORD WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds) { // 0x000000CF is defined above to be not set DWORD lastServiceState = 0x000000CF; // Get a handle to the SCM database. SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); if (!serviceManager) { DWORD lastError = GetLastError(); switch(lastError) { case ERROR_ACCESS_DENIED: return 0x000000FD; case ERROR_DATABASE_DOES_NOT_EXIST: return 0x000000FE; default: return 0x000000FF; } } // Get a handle to the service. SC_HANDLE service = OpenServiceW(serviceManager, serviceName, SERVICE_QUERY_STATUS); if (!service) { DWORD lastError = GetLastError(); CloseServiceHandle(serviceManager); switch(lastError) { case ERROR_ACCESS_DENIED: return 0x000000EB; case ERROR_INVALID_HANDLE: return 0x000000EC; case ERROR_INVALID_NAME: return 0x000000ED; case ERROR_SERVICE_DOES_NOT_EXIST: return 0x000000EE; default: return 0x000000EF; } } DWORD currentWaitMS = 0; SERVICE_STATUS_PROCESS ssp; ssp.dwCurrentState = lastServiceState; while (currentWaitMS < maxWaitSeconds * 1000) { DWORD bytesNeeded; if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) { DWORD lastError = GetLastError(); switch (lastError) { case ERROR_INVALID_HANDLE: ssp.dwCurrentState = 0x000000D9; break; case ERROR_ACCESS_DENIED: ssp.dwCurrentState = 0x000000DA; break; case ERROR_INSUFFICIENT_BUFFER: ssp.dwCurrentState = 0x000000DB; break; case ERROR_INVALID_PARAMETER: ssp.dwCurrentState = 0x000000DC; break; case ERROR_INVALID_LEVEL: ssp.dwCurrentState = 0x000000DD; break; case ERROR_SHUTDOWN_IN_PROGRESS: ssp.dwCurrentState = 0x000000DE; break; // These 3 errors can occur when the service is not yet stopped but // it is stopping. case ERROR_INVALID_SERVICE_CONTROL: case ERROR_SERVICE_CANNOT_ACCEPT_CTRL: case ERROR_SERVICE_NOT_ACTIVE: currentWaitMS += 50; Sleep(50); continue; default: ssp.dwCurrentState = 0x000000DF; } // We couldn't query the status so just break out break; } // The service is already in use. if (ssp.dwCurrentState == SERVICE_STOPPED) { break; } currentWaitMS += 50; Sleep(50); } lastServiceState = ssp.dwCurrentState; CloseServiceHandle(service); CloseServiceHandle(serviceManager); return lastServiceState; }
int main(int argc, char *argv[]) { if(argc<6) { printf("Insufficient arguments: Service u/i ServiceName ServicePath DisplayName m/a [DependOnServiceName]\n"); return 1; } SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); SC_HANDLE hService; if(hSCM == NULL) { printf("Could not open Service Control Manager. Aborting.\n"); return 1; } char *depend = NULL; if (argc >= 7) { int slen = strlen(argv[6]); int len = slen + 10; depend = (char *) malloc(len); memset(depend, 0, len); strcpy(depend, argv[6]); printf("Service depend on %s\n", depend); } if(*argv[1]!='u' && *argv[1]!='U') { if (argv[5][0] == 'm') { printf("installing on demand start service\n"); hService = CreateService(hSCM, argv[2],_T(argv[4]),SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, argv[3], NULL,NULL, depend, NULL, NULL ); } else { printf("installing autostart service\n"); hService = CreateService(hSCM, argv[2], _T(argv[4]), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, argv[3], NULL,NULL, depend, NULL, NULL ); } if (hService == NULL) { printf("Create Service failed (%d)\n", GetLastError() ); CloseServiceHandle(hSCM); } } else { hService = OpenService( hSCM, argv[2], DELETE); if(hService!=NULL) DeleteService( hService ); } CloseServiceHandle(hService); CloseServiceHandle(hService); CloseServiceHandle(hSCM); return 0; }
BOOL CALLBACK Main_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) { static UINT msgCheckTerminate = 0; if (msgCheckTerminate == 0) msgCheckTerminate = RegisterWindowMessage (TEXT("AfsCredsCheckTerminate")); if (msg == msgCheckTerminate) { Main_OnCheckTerminate(); } else switch (msg) { case WM_INITDIALOG: g.hMain = hDlg; Main_OnInitDialog (hDlg); break; case WM_DESTROY: Creds_CloseLibraries(); ChangeTrayIcon (NIM_DELETE); break; case WM_ACTIVATEAPP: if (wp) { Main_RepopulateTabs (FALSE); } break; case WM_COMMAND: switch (LOWORD(wp)) { case IDOK: case IDCANCEL: Main_Show (FALSE); break; case M_ACTIVATE: if (g.fIsWinNT || IsServiceRunning()) { if (!lp) // Got here from "/show" parameter? switch tabs. { HWND hTab = GetDlgItem (g.hMain, IDC_TABS); TabCtrl_SetCurSel (hTab, 0); Main_OnSelectTab(); } Main_Show (TRUE); } else { Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95); } break; case M_TERMINATE: #ifndef UAC_COMPATIBLE if (g.fIsWinNT && IsServiceRunning()) ModalDialog (IDD_TERMINATE, NULL, (DLGPROC)Terminate_DlgProc); else #endif if (g.fIsWinNT) ModalDialog (IDD_TERMINATE_SMALL, NULL, (DLGPROC)Terminate_DlgProc); else // (!g.fIsWinNT) ModalDialog (IDD_TERMINATE_SMALL_95, NULL, (DLGPROC)Terminate_DlgProc); break; case M_TERMINATE_NOW: Quit(); break; case M_REMIND: Main_OnCheckMenuRemind(); break; } break; case WM_TIMER: Main_OnRemindTimer(); break; case WM_NOTIFY: switch (((NMHDR*)lp)->code) { case TCN_SELCHANGE: Main_OnSelectTab(); break; } break; case WM_TRAYICON: switch (lp) { case WM_LBUTTONDOWN: if (IsServiceRunning() || !IsServiceConfigured()) Main_Show (TRUE); else if (!g.fIsWinNT) Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95); else ShowStartupWizard(); break; case WM_RBUTTONDOWN: HMENU hm; if ((hm = TaLocale_LoadMenu (MENU_TRAYICON)) != 0) { POINT pt; GetCursorPos(&pt); HMENU hmDummy = CreateMenu(); InsertMenu (hmDummy, 0, MF_POPUP, (UINT)hm, NULL); BOOL fRemind = FALSE; lock_ObtainMutex(&g.credsLock); for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds) { if (g.aCreds[ iCreds ].fRemind) fRemind = TRUE; } lock_ReleaseMutex(&g.credsLock); CheckMenuItem (hm, M_REMIND, MF_BYCOMMAND | ((fRemind) ? MF_CHECKED : MF_UNCHECKED)); SetForegroundWindow(hDlg); TrackPopupMenu (GetSubMenu (hmDummy, 0), TPM_RIGHTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, NULL, hDlg, NULL); PostMessage(hDlg, WM_NULL, 0, 0); DestroyMenu (hmDummy); } break; case WM_MOUSEMOVE: Main_OnMouseOver(); break; } break; case WM_OBTAIN_TOKENS: if ( InterlockedIncrement (&g.fShowingMessage) != 1 ) InterlockedDecrement (&g.fShowingMessage); else ShowObtainCreds (wp, (char *)lp); GlobalFree((void *)lp); break; case WM_START_SERVICE: { SC_HANDLE hManager; if ((hManager = OpenSCManager ( NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_QUERY_LOCK_STATUS)) != NULL) { SC_HANDLE hService; if ((hService = OpenService ( hManager, TEXT("TransarcAFSDaemon"), SERVICE_QUERY_STATUS | SERVICE_START)) != NULL) { if (StartService (hService, 0, 0)) TestAndDoMapShare(SERVICE_START_PENDING); if ( KFW_is_available() && KFW_AFS_wait_for_service_start() ) { #ifdef USE_MS2MIT KFW_import_windows_lsa(); #endif /* USE_MS2MIT */ KFW_AFS_renew_tokens_for_all_cells(); } CloseServiceHandle (hService); } CloseServiceHandle (hManager); } if (KFW_AFS_wait_for_service_start()) ObtainTokensFromUserIfNeeded(g.hMain); } break; } return FALSE; }
static void nx_win32_svc_stop() { SC_HANDLE service_manager = NULL; SC_HANDLE service_handle = NULL; SERVICE_STATUS status; nx_exception_t e; // Connect to service manager service_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if ( service_manager == NULL ) { nx_win32_error("Cannot initialize access to the service manager"); } try { service_handle = OpenService(service_manager, "nxlog", SERVICE_ALL_ACCESS); if ( service_handle == NULL ) { nx_win32_error("Couldn't open nxlog service"); } else { if ( QueryServiceStatus(service_handle, &status) ) { if ( status.dwCurrentState != SERVICE_STOPPED ) { log_info("Service currenty active - stopping service..."); if ( !ControlService(service_handle, SERVICE_CONTROL_STOP, &status) ) { nx_win32_error("Couldn't stop service"); } else { Sleep(500); } } else { log_error("Service is already stopped"); } } // Close connection to service CloseServiceHandle(service_handle); } // Close connection to service manager CloseServiceHandle(service_manager); } catch(e) { if ( service_handle != NULL ) { CloseServiceHandle(service_handle); } if ( service_manager != NULL ) { CloseServiceHandle(service_manager); } rethrow(e); } }
/** * Installs the service. */ RTEXITCODE VBoxServiceWinInstall(void) { VBoxServiceVerbose(1, "Installing service ...\n"); TCHAR imagePath[MAX_PATH] = { 0 }; GetModuleFileName(NULL, imagePath, sizeof(imagePath)); SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCManager == NULL) { VBoxServiceError("Could not open SCM! Error: %ld\n", GetLastError()); return RTEXITCODE_FAILURE; } RTEXITCODE rc = RTEXITCODE_SUCCESS; SC_HANDLE hService = CreateService(hSCManager, VBOXSERVICE_NAME, VBOXSERVICE_FRIENDLY_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, imagePath, NULL, NULL, NULL, NULL, NULL); if (hService != NULL) VBoxServiceVerbose(0, "Service successfully installed!\n"); else { DWORD dwErr = GetLastError(); switch (dwErr) { case ERROR_SERVICE_EXISTS: VBoxServiceVerbose(1, "Service already exists, just updating the service config.\n"); hService = OpenService(hSCManager, VBOXSERVICE_NAME, SERVICE_ALL_ACCESS); if (hService) { if (ChangeServiceConfig (hService, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, imagePath, NULL, NULL, NULL, NULL, NULL, VBOXSERVICE_FRIENDLY_NAME)) VBoxServiceVerbose(1, "The service config has been successfully updated.\n"); else rc = VBoxServiceError("Could not change service config! Error: %ld\n", GetLastError()); } else rc = VBoxServiceError("Could not open service! Error: %ld\n", GetLastError()); break; default: rc = VBoxServiceError("Could not create service! Error: %ld\n", dwErr); break; } } if (rc == RTEXITCODE_SUCCESS) rc = vboxServiceWinSetDesc(hService); CloseServiceHandle(hService); CloseServiceHandle(hSCManager); return rc; }
int WinPmem::install_driver() { SC_HANDLE scm, service; int status = -1; // Try to load the driver from the resource section. if (extract_driver() < 0) goto error; uninstall_driver(); scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (!scm) { dprintf("[WINPMEM] Can not open SCM. Are you administrator?\n"); goto error; } service = CreateService(scm, service_name, service_name, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, driver_filename_, NULL, NULL, NULL, NULL, NULL); if (GetLastError() == ERROR_SERVICE_EXISTS) { service = OpenService(scm, service_name, SERVICE_ALL_ACCESS); } if (!service) { goto error; }; if (!StartService(service, 0, NULL)) { if (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) { dprintf("[WINPMEM] Error: StartService(), Cannot start the driver.\n"); goto service_error; } } dprintf("[WINPMEM] Loaded Driver %s.\n", driver_filename_); fd_ = CreateFile(TEXT("\\\\.\\") TEXT(PMEM_DEVICE_NAME), // Write is needed for IOCTL. GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fd_ == INVALID_HANDLE_VALUE) { dprintf("[WINPMEM] Can not open raw device."); status = -1; }; status = 1; service_error: CloseServiceHandle(service); CloseServiceHandle(scm); error: // Only remove the driver file if it was a temporary file. if (driver_is_tempfile_) { dprintf("[WINPMEM] Deleting %S", driver_filename_); DeleteFile(driver_filename_); }; return status; }
static void nx_win32_svc_uninstall() { SC_HANDLE service_manager = NULL; SC_HANDLE service_handle = NULL; SERVICE_STATUS query_status; nx_exception_t e; // Connect to service manager service_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if ( service_manager == NULL ) { nx_win32_error("Cannot initialize access to the service manager"); } try { // Connect to service service_handle = OpenService(service_manager, "nxlog", SERVICE_ALL_ACCESS | DELETE); if ( service_handle == NULL ) { nx_win32_error("Couldn't open nxlog service"); } else { // Check that the service is stopped if ( QueryServiceStatus(service_handle, &query_status) && (query_status.dwCurrentState == SERVICE_RUNNING) ) { throw_msg("Service is running, please stop it first."); } else { // we can remove if ( DeleteService(service_handle) == FALSE ) { nx_win32_error("Couldn't delete service"); } else { log_info("Service successfully uninstalled"); } } // Close connection to service CloseServiceHandle(service_handle); } // Close connection to service manager CloseServiceHandle(service_manager); } catch(e) { if ( service_handle != NULL ) { CloseServiceHandle(service_handle); } if ( service_manager != NULL ) { CloseServiceHandle(service_manager); } rethrow(e); } }
DWORD LoadDriver( __in PCWSTR Name, __in PCWSTR DriverFileName ) { SC_HANDLE ScMgr, Service; WCHAR DriverPath[ MAX_PATH ]; WCHAR FullPath[ MAX_PATH ]; PWSTR FilePart; DWORD RetVal; SYSTEM_INFO SystemInfo; // // Prepend architecture-specific directory. // CfixklGetNativeSystemInfo( &SystemInfo ); switch ( SystemInfo.wProcessorArchitecture ) { case PROCESSOR_ARCHITECTURE_INTEL: TEST( SUCCEEDED( StringCchPrintf( DriverPath, _countof( DriverPath ), L"..\\i386\\%s", DriverFileName ) ) ); break; case PROCESSOR_ARCHITECTURE_AMD64: TEST( SUCCEEDED( StringCchPrintf( DriverPath, _countof( DriverPath ), L"..\\amd64\\%s", DriverFileName ) ) ); break; default: CFIX_ASSERT( !"Unsupported processor architecture" ); return ERROR_FUNCTION_FAILED; } ScMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); CFIX_ASSUME( ScMgr != NULL ); TEST( GetFullPathName( DriverPath, _countof( FullPath ), FullPath, &FilePart ) ); // CFIX_LOG( L"Attempting to load %s", FullPath ); // // Windows 2000 may require a pause here. // Sleep( 1000 ); Service = CreateService( ScMgr, Name, Name, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, FullPath, NULL, NULL, NULL, NULL, NULL ); TEST( Service || GetLastError() == ERROR_SERVICE_EXISTS ); if ( ERROR_SUCCESS == GetLastError() ) { // Fine. } else if ( GetLastError() == ERROR_SERVICE_EXISTS ) { // // Windows 2000 may require a pause here. // Sleep( 1000 ); Service = OpenService( ScMgr, Name, SERVICE_ALL_ACCESS ); TEST( Service ); } else { TEST( !"Unexpected SCM failure" ); } // // Windows 2000 may require a pause here. // Sleep( 1000 ); if ( ! StartService( Service, 0, NULL ) ) { RetVal = GetLastError(); } else { RetVal = ERROR_SUCCESS; } TEST( CloseServiceHandle( ScMgr ) ); TEST( CloseServiceHandle( Service ) ); // // Windows 2000 may require a pause here. // Sleep( 1000 ); return RetVal; }
int lutil_srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName, LPCTSTR lpszBinaryPathName, int auto_start) { HKEY hKey; DWORD dwValue, dwDisposition; SC_HANDLE schSCManager, schService; char *sp = strchr( lpszBinaryPathName, ' '); if ( sp ) *sp = '\0'; fprintf( stderr, "The install path is %s.\n", lpszBinaryPathName ); if ( sp ) *sp = ' '; if ((schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT|SC_MANAGER_CREATE_SERVICE ) ) != NULL ) { if ((schService = CreateService( schSCManager, lpszServiceName, lpszDisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, auto_start ? SERVICE_AUTO_START : SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, lpszBinaryPathName, NULL, NULL, NULL, NULL, NULL)) != NULL) { char regpath[132]; CloseServiceHandle(schService); CloseServiceHandle(schSCManager); snprintf( regpath, sizeof regpath, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s", lpszServiceName ); /* Create the registry key for event logging to the Windows NT event log. */ if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) != ERROR_SUCCESS) { fprintf( stderr, "RegCreateKeyEx() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() ); RegCloseKey(hKey); return(0); } if ( sp ) *sp = '\0'; if ( RegSetValueEx(hKey, "EventMessageFile", 0, REG_EXPAND_SZ, lpszBinaryPathName, strlen(lpszBinaryPathName) + 1) != ERROR_SUCCESS) { fprintf( stderr, "RegSetValueEx(EventMessageFile) failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() ); RegCloseKey(hKey); return(0); } dwValue = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; if ( RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (LPBYTE) &dwValue, sizeof(DWORD)) != ERROR_SUCCESS) { fprintf( stderr, "RegCreateKeyEx(TypesSupported) failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() ); RegCloseKey(hKey); return(0); } RegCloseKey(hKey); return(1); } else { fprintf( stderr, "CreateService() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() ); CloseServiceHandle(schSCManager); return(0); } } else fprintf( stderr, "OpenSCManager() failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() ); return(0); }
int ACE_NT_Service::insert (DWORD start_type, DWORD error_control, const ACE_TCHAR *exe_path, const ACE_TCHAR *group_name, LPDWORD tag_id, const ACE_TCHAR *dependencies, const ACE_TCHAR *account_name, const ACE_TCHAR *password, DWORD desired_access) { ACE_TCHAR this_exe[MAXPATHLEN + 2]; // Insure ACE_OS::last_error finds GetLastError unless we set errno. errno = 0; if (exe_path == 0) { if (ACE_TEXT_GetModuleFileName (0, this_exe + 1, MAXPATHLEN) == 0) return -1; // Make sure that this_exe is quoted this_exe[0] = ACE_TEXT ('\"'); ACE_OS::strcat (this_exe, ACE_TEXT ("\"")); exe_path = this_exe; } SC_HANDLE sc_mgr = ACE_TEXT_OpenSCManager (this->host (), 0, SC_MANAGER_ALL_ACCESS); if (sc_mgr == 0) return -1; SC_HANDLE sh = ACE_TEXT_CreateService (sc_mgr, this->name (), this->desc (), desired_access, this->svc_status_.dwServiceType, start_type, error_control, exe_path, group_name, tag_id, dependencies, account_name, password); // If there was an error, stash GetLastError before CloseServiceHandle // smashes it. ACE_OS::last_error will find the saved error value. if (sh == 0) ACE_OS::set_errno_to_last_error (); CloseServiceHandle (sc_mgr); if (sh == 0) return -1; if (this->svc_sc_handle_ != 0) CloseServiceHandle (this->svc_sc_handle_); this->svc_sc_handle_ = sh; return 0; }
/* * Install the WinDivert driver. */ static SC_HANDLE WinDivertDriverInstall(VOID) { DWORD err, retries = 2; SC_HANDLE manager = NULL, service = NULL; wchar_t windivert_sys[MAX_PATH+1]; SERVICE_STATUS status; // Open the service manager: manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (manager == NULL) { goto WinDivertDriverInstallExit; } // Check if the WinDivert service already exists; if so, start it. WinDivertDriverInstallReTry: service = OpenService(manager, WINDIVERT_DEVICE_NAME, SERVICE_ALL_ACCESS); if (service != NULL) { goto WinDivertDriverInstallExit; } // Get driver file: if (!WinDivertGetDriverFileName(windivert_sys)) { goto WinDivertDriverInstallExit; } // Create the service: service = CreateService(manager, WINDIVERT_DEVICE_NAME, WINDIVERT_DEVICE_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, windivert_sys, NULL, NULL, NULL, NULL, NULL); if (service == NULL) { if (GetLastError() == ERROR_SERVICE_EXISTS) { if (retries != 0) { retries--; goto WinDivertDriverInstallReTry; } } goto WinDivertDriverInstallExit; } WinDivertDriverInstallExit: if (service != NULL) { // Start the service: if (!StartService(service, 0, NULL)) { err = GetLastError(); if (err == ERROR_SERVICE_ALREADY_RUNNING) { SetLastError(0); } else { // Failed to start service; clean-up: ControlService(service, SERVICE_CONTROL_STOP, &status); DeleteService(service); CloseServiceHandle(service); service = NULL; SetLastError(err); } } } err = GetLastError(); if (manager != NULL) { CloseServiceHandle(manager); } SetLastError(err); return service; }
/***************************************************************************** * NT Service utility functions *****************************************************************************/ static int NTServiceInstall( intf_thread_t *p_intf ) { intf_sys_t *p_sys = p_intf->p_sys; char psz_path[10*MAX_PATH], psz_pathtmp[MAX_PATH], *psz_extra; SC_HANDLE handle = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( handle == NULL ) { msg_Err( p_intf, "could not connect to Services Control Manager database" ); return VLC_EGENERIC; } /* Find out the filename of ourselves so we can install it to the * service control manager */ GetModuleFileName( NULL, psz_pathtmp, MAX_PATH ); sprintf( psz_path, "\"%s\" -I "MODULE_STRING, psz_pathtmp ); psz_extra = var_InheritString( p_intf, "ntservice-extraintf" ); if( psz_extra ) { strcat( psz_path, " --ntservice-extraintf " ); strcat( psz_path, psz_extra ); free( psz_extra ); } psz_extra = var_InheritString( p_intf, "ntservice-options" ); if( psz_extra && *psz_extra ) { strcat( psz_path, " " ); strcat( psz_path, psz_extra ); free( psz_extra ); } SC_HANDLE service = CreateService( handle, p_sys->psz_service, p_sys->psz_service, GENERIC_READ | GENERIC_EXECUTE, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, psz_path, NULL, NULL, NULL, NULL, NULL ); if( service == NULL ) { if( GetLastError() != ERROR_SERVICE_EXISTS ) { msg_Err( p_intf, "could not create new service: \"%s\" (%s)", p_sys->psz_service ,psz_path ); CloseServiceHandle( handle ); return VLC_EGENERIC; } else { msg_Warn( p_intf, "service \"%s\" already exists", p_sys->psz_service ); } } else { msg_Warn( p_intf, "service successfuly created" ); } if( service ) CloseServiceHandle( service ); CloseServiceHandle( handle ); return VLC_SUCCESS; }
/* * Open a WinDivert handle. */ extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer, INT16 priority, UINT64 flags) { struct windivert_ioctl_filter_s object[WINDIVERT_FILTER_MAXLEN]; UINT obj_len; ERROR comp_err; DWORD err; HANDLE handle; SC_HANDLE service; UINT32 priority32; // Parameter checking. if (!WINDIVERT_FLAGS_VALID(flags) || layer > WINDIVERT_LAYER_MAX) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } priority32 = WINDIVERT_PRIORITY(priority); if (priority32 < WINDIVERT_PRIORITY_MIN || priority32 > WINDIVERT_PRIORITY_MAX) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } // Compile the filter: comp_err = WinDivertCompileFilter(filter, layer, object, &obj_len); if (IS_ERROR(comp_err)) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } #ifdef WINDIVERT_DEBUG WinDivertFilterDump(object, obj_len); #endif // Attempt to open the WinDivert device: handle = CreateFile(L"\\\\.\\" WINDIVERT_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE); if (handle == INVALID_HANDLE_VALUE) { err = GetLastError(); if (err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND) { return INVALID_HANDLE_VALUE; } // Open failed because the device isn't installed; install it now. SetLastError(0); service = WinDivertDriverInstall(); if (service == NULL) { if (GetLastError() == 0) { SetLastError(ERROR_OPEN_FAILED); } return INVALID_HANDLE_VALUE; } handle = CreateFile(L"\\\\.\\" WINDIVERT_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE); // Schedule the service to be deleted (once all handles are closed). DeleteService(service); CloseServiceHandle(service); if (handle == INVALID_HANDLE_VALUE) { return INVALID_HANDLE_VALUE; } } // Set the layer: if (layer != WINDIVERT_LAYER_DEFAULT) { if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_LAYER, 0, (UINT64)layer, NULL, 0, NULL)) { CloseHandle(handle); return INVALID_HANDLE_VALUE; } } // Set the flags: if (flags != 0) { if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_FLAGS, 0, (UINT64)flags, NULL, 0, NULL)) { CloseHandle(handle); return INVALID_HANDLE_VALUE; } } // Set the priority: if (priority32 != WINDIVERT_PRIORITY_DEFAULT) { if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_PRIORITY, 0, (UINT64)priority32, NULL, 0, NULL)) { CloseHandle(handle); return INVALID_HANDLE_VALUE; } } // Start the filter: if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_START_FILTER, 0, 0, object, obj_len*sizeof(struct windivert_ioctl_filter_s), NULL)) { CloseHandle(handle); return INVALID_HANDLE_VALUE; } // Success! return handle; }
static void Test_LockUnlockServiceDatabaseWithServiceStart(void) { BOOL bError = FALSE; SC_HANDLE hScm = NULL; SC_HANDLE hSvc = NULL; SC_LOCK hLock = NULL; LPQUERY_SERVICE_CONFIGW lpConfig = NULL; DWORD dwRequiredSize = 0; SERVICE_STATUS status; BOOL bWasRunning = FALSE; DWORD dwOldStartType = 0; /* Open the services database */ SetLastError(0xdeadbeef); hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* Grab a handle to the testing service */ SetLastError(0xdeadbeef); hSvc = OpenServiceW(hScm, TESTING_SERVICE, SERVICE_START | SERVICE_STOP | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS); ok(hSvc != NULL, "hSvc = 0x%p, expected non-null, error=0x%08lx\n", hSvc, GetLastError()); if (!hSvc) { skip("Cannot open a handle to service %S; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n", TESTING_SERVICE); goto cleanup; } ok_err(ERROR_SUCCESS); /* Lock the services database */ SetLastError(0xdeadbeef); hLock = LockServiceDatabase(hScm); ok(hLock != NULL, "hLock = 0x%p, expected non-zero, error=0x%08lx\n", hLock, GetLastError()); if (!hLock) { skip("Cannot lock the services database; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* To proceed further, firstly attempt to stop the testing service */ QueryServiceConfigW(hSvc, NULL, 0, &dwRequiredSize); lpConfig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); QueryServiceConfigW(hSvc, lpConfig, dwRequiredSize, &dwRequiredSize); dwOldStartType = lpConfig->dwStartType; HeapFree(GetProcessHeap(), 0, lpConfig); if (dwOldStartType == SERVICE_DISABLED) { ChangeServiceConfigW(hSvc, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } QueryServiceStatus(hSvc, &status); bWasRunning = (status.dwCurrentState != SERVICE_STOPPED); if (bWasRunning) { ControlService(hSvc, SERVICE_CONTROL_STOP, &status); Sleep(1000); /* Wait 1 second for the service to stop */ } /* Now try to start it (this test won't work under Windows Vista / 7 / 8) */ SetLastError(0xdeadbeef); bError = StartServiceW(hSvc, 0, NULL); ok(bError == FALSE, "bError = %u, expected FALSE\n", bError); ok_err(ERROR_SERVICE_DATABASE_LOCKED); Sleep(1000); /* Wait 1 second for the service to start */ /* Stop the testing service */ ControlService(hSvc, SERVICE_CONTROL_STOP, &status); Sleep(1000); /* Wait 1 second for the service to stop */ /* Now unlock the services database */ SetLastError(0xdeadbeef); bError = UnlockServiceDatabase(hLock); ok(bError == TRUE, "bError = %u, expected TRUE\n", bError); ok_err(ERROR_SUCCESS); /* Try to start again the service, this time the database unlocked */ SetLastError(0xdeadbeef); bError = StartServiceW(hSvc, 0, NULL); ok(bError == TRUE, "bError = %u, expected TRUE\n", bError); ok_err(ERROR_SUCCESS); Sleep(1000); /* Wait 1 second for the service to start */ /* Stop the testing service */ ControlService(hSvc, SERVICE_CONTROL_STOP, &status); Sleep(1000); /* Wait 1 second for the service to stop */ /* Restore its original state */ if (bWasRunning) { StartServiceW(hSvc, 0, NULL); } if (dwOldStartType == SERVICE_DISABLED) { ChangeServiceConfigW(hSvc, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } cleanup: if (hSvc) CloseServiceHandle(hSvc); if (hScm) CloseServiceHandle(hScm); return; }
/// Prelude actions to start up the service, e.g. to set any global variables from the settings or perform /// any system specific actions. E.g. the Windows implementation registers with the service control manager /// and can optionally set the security descriptor on the process to allow clients to kill/restart it. /// /// @param[in] nReason how the startup is occuring (e.g. SERVICE_RUN_INLINE) - different actions may be /// required depending on whether the code is running direct from main() or through another mechansim static void _ServiceStartup (int nReason) { CSettings oSettings; #ifdef _WIN32 if (nReason == SERVICE_RUN_SCM) { g_hServiceStatus = RegisterServiceCtrlHandler (oSettings.GetServiceName (), ServiceHandler); } PCTSTR pszSDDL = oSettings.GetServiceSDDL (); if (pszSDDL) { LOGDEBUG (TEXT ("Setting security descriptor ") << pszSDDL); PSECURITY_DESCRIPTOR psdRelative; if (ConvertStringSecurityDescriptorToSecurityDescriptor (pszSDDL, SDDL_REVISION_1, &psdRelative, NULL)) { DWORD cbAbsolute = 1024; PSECURITY_DESCRIPTOR psdAbsolute = (PSECURITY_DESCRIPTOR)malloc (cbAbsolute); DWORD cbD = 1024; PACL paclD = (PACL)malloc (cbD); DWORD cbS = 1024; PACL paclS = (PACL)malloc (cbS); DWORD cbOwner = 1024; PSID psidOwner = (PSID)malloc (cbOwner); DWORD cbPGroup = 1024; PSID psidPGroup = (PSID)malloc (cbPGroup); if (MakeAbsoluteSD (psdRelative, psdAbsolute, &cbAbsolute, paclD, &cbD, paclS, &cbS, psidOwner, &cbOwner, psidPGroup, &cbPGroup)) { DWORD dwError = SetSecurityInfo (GetCurrentProcess (), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, paclD, NULL); if (dwError == ERROR_SUCCESS) { LOGINFO (TEXT ("Security descriptor set on process handle")); } else { LOGWARN (TEXT ("Couldn't set security descriptor on process handle, error ") << GetLastError ()); } if (nReason == SERVICE_RUN_SCM) { SC_HANDLE hSCM = OpenSCManager (NULL, NULL, GENERIC_READ); if (hSCM) { SC_HANDLE hService = OpenService (hSCM, oSettings.GetServiceName (), GENERIC_WRITE | WRITE_DAC); if (hService) { dwError = SetSecurityInfo (hService, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, NULL, paclD, NULL); if (dwError == ERROR_SUCCESS) { LOGINFO (TEXT ("Security descriptor set on service")); } else { LOGWARN (TEXT ("Couldn't set security descriptor on service, error ") << GetLastError ()); } CloseServiceHandle (hService); } else { LOGWARN (TEXT ("Couldn't open service, error ") << GetLastError ()); } CloseServiceHandle (hSCM); } else { LOGWARN (TEXT ("Couldn't open SCM, error ") << GetLastError ()); } } } else { LOGWARN (TEXT ("Couldn't create absolute security description, error ") << GetLastError ()); } free (psdAbsolute); free (paclD); free (paclS); free (psidOwner); free (psidPGroup); LocalFree (psdRelative); } else { LOGWARN (TEXT ("Couldn't parse SDDL ") << pszSDDL << TEXT (", error ") << GetLastError ()); } } else { LOGDEBUG (TEXT ("No security descriptor specified")); } #else /* ifdef _WIN32 */ if (nReason == SERVICE_RUN_DAEMON) { const TCHAR *pszPID = oSettings.GetPidFile (); if (pszPID) { LOGINFO (TEXT ("Creating PID file ") << pszPID); FILE *f = fopen (pszPID, "wt"); if (f) { fprintf (f, "%d", getpid ()); fclose (f); } else { LOGWARN (TEXT ("Couldn't write to PID file ") << pszPID << TEXT (", error ") << GetLastError ()); } } else { LOGWARN (TEXT ("No PID file")); } } #endif /* ifdef _WIN32 */ g_lBusyTimeout = oSettings.GetBusyTimeout (); _ReportStateStarting (); }
static void Test_LockUnlockServiceDatabase(void) { BOOL bError = FALSE; SC_HANDLE hScm = NULL; SC_LOCK hLock = NULL; /* First of all, try to lock / unlock the services database with invalid handles */ SetLastError(0xdeadbeef); hScm = NULL; hLock = LockServiceDatabase(hScm); ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock); ok_err(ERROR_INVALID_HANDLE); SetLastError(0xdeadbeef); hScm = (SC_HANDLE)0xdeadbeef; hLock = LockServiceDatabase(hScm); ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock); ok_err(ERROR_INVALID_HANDLE); /** This test seems to make this application crash on Windows 7... I do not know why... **/ SetLastError(0xdeadbeef); hLock = NULL; bError = UnlockServiceDatabase(hLock); ok(bError == FALSE, "bError = %u, expected FALSE\n", bError); ok_err(ERROR_INVALID_SERVICE_LOCK); /*****************************************************************************************/ SetLastError(0xdeadbeef); hLock = (SC_LOCK)0xdeadbeef; bError = UnlockServiceDatabase(hLock); ok(bError == FALSE, "bError = %u, expected FALSE\n", bError); ok_err(ERROR_INVALID_SERVICE_LOCK); /* Then, try to lock the services database without having rights */ SetLastError(0xdeadbeef); hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with LockUnlockServiceDatabase test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); SetLastError(0xdeadbeef); hLock = LockServiceDatabase(hScm); ok(hLock == NULL, "hLock = 0x%p, expected 0\n", hLock); ok_err(ERROR_ACCESS_DENIED); if (hLock) UnlockServiceDatabase(hLock); CloseServiceHandle(hScm); /* Try to lock the services database with good rights */ SetLastError(0xdeadbeef); hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with LockUnlockServiceDatabase test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); SetLastError(0xdeadbeef); hLock = LockServiceDatabase(hScm); ok(hLock != NULL, "hLock = 0x%p, expected non-zero\n", hLock); ok_err(ERROR_SUCCESS); /* Now unlock it */ if (hLock) { SetLastError(0xdeadbeef); bError = UnlockServiceDatabase(hLock); ok(bError == TRUE, "bError = %u, expected TRUE\n", bError); ok_err(ERROR_SUCCESS); } cleanup: if (hScm) CloseServiceHandle(hScm); return; }
static BOOL DokanServiceControl( LPCWSTR ServiceName, ULONG Type) { SC_HANDLE controlHandle; SC_HANDLE serviceHandle; SERVICE_STATUS ss; BOOL result = TRUE; controlHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (controlHandle == NULL) { DokanDbgPrint("failed to open SCM: %d\n", GetLastError()); return FALSE; } serviceHandle = OpenService(controlHandle, ServiceName, SERVICE_START | SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE); if (serviceHandle == NULL) { DokanDbgPrintW(L"failed to open Service (%s): %d\n", ServiceName, GetLastError()); CloseServiceHandle(controlHandle); return FALSE; } QueryServiceStatus(serviceHandle, &ss); if (Type == DOKAN_SERVICE_DELETE) { if (DeleteService(serviceHandle)) { DokanDbgPrintW(L"Service (%s) deleted\n", ServiceName); result = TRUE; } else { DokanDbgPrintW(L"failed to delete service (%s): %d\n", ServiceName, GetLastError()); result = FALSE; } } else if (ss.dwCurrentState == SERVICE_STOPPED && Type == DOKAN_SERVICE_START) { if (StartService(serviceHandle, 0, NULL)) { DokanDbgPrintW(L"Service (%s) started\n", ServiceName); result = TRUE; } else { DokanDbgPrintW(L"failed to start service (%s): %d\n", ServiceName, GetLastError()); result = FALSE; } } else if (ss.dwCurrentState == SERVICE_RUNNING && Type == DOKAN_SERVICE_STOP) { if (ControlService(serviceHandle, SERVICE_CONTROL_STOP, &ss)) { DokanDbgPrintW(L"Service (%s) stopped\n", ServiceName); result = TRUE; } else { DokanDbgPrintW(L"failed to stop service (%s): %d\n", ServiceName, GetLastError()); result = FALSE; } } CloseServiceHandle(serviceHandle); CloseServiceHandle(controlHandle); Sleep(100); return result; }
static void Test_QueryLockStatusA(void) { BOOL bError = FALSE; SC_HANDLE hScm = NULL; SC_LOCK hLock = NULL; LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus = NULL; DWORD dwRequiredSize = 0; /* Firstly try to get lock status with invalid handles */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INVALID_HANDLE, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INVALID_HANDLE); ok(dwRequiredSize == 0, "dwRequiredSize is non-zero, expected zero\n"); /* Open the services database without having rights */ SetLastError(0xdeadbeef); hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* Try to get lock status */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_ACCESS_DENIED, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_ACCESS_DENIED); ok(dwRequiredSize == 0, "dwRequiredSize is non-zero, expected zero\n"); CloseServiceHandle(hScm); /* * Query only the lock status. */ SetLastError(0xdeadbeef); hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_QUERY_LOCK_STATUS); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } /* Allocate memory */ lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpLockStatus == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); goto cleanup; } /* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, lpLockStatus, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); /* These conditions must be verified iff the services database wasn't previously locked */ ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected 0\n", lpLockStatus->fIsLocked); ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null, expected non-null\n"); ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0, "*lpLockStatus->lpLockOwner != \"\\0\", expected \"\\0\"\n"); ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu, expected 0\n", lpLockStatus->dwLockDuration); HeapFree(GetProcessHeap(), 0, lpLockStatus); CloseServiceHandle(hScm); /* * Now, try to lock the database and check its lock status. */ SetLastError(0xdeadbeef); hScm = OpenSCManagerA(NULL, NULL, SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS); ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError()); if (!hScm) { skip("No service control manager; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } ok_err(ERROR_SUCCESS); /* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } /* Allocate memory */ lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpLockStatus == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); goto cleanup; } /* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, lpLockStatus, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); /* These conditions must be verified iff the services database wasn't previously locked */ ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected 0\n", lpLockStatus->fIsLocked); ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null, expected non-null\n"); ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0, "*lpLockStatus->lpLockOwner != \"\\0\", expected \"\\0\"\n"); ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu, expected 0\n", lpLockStatus->dwLockDuration); HeapFree(GetProcessHeap(), 0, lpLockStatus); /* * Try again, this time with the database locked. */ SetLastError(0xdeadbeef); hLock = LockServiceDatabase(hScm); ok(hLock != NULL, "hLock = 0x%p, expected non-zero\n", hLock); ok_err(ERROR_SUCCESS); Sleep(1000); /* Wait 1 second to let lpLockStatus->dwLockDuration increment */ /* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } /* Allocate memory */ lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpLockStatus == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); goto cleanup; } /* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, lpLockStatus, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); /* These conditions must be verified iff the services database is locked */ ok(lpLockStatus->fIsLocked != 0, "lpLockStatus->fIsLocked = %lu, expected non-zero\n", lpLockStatus->fIsLocked); ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null, expected non-null\n"); ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner != 0, "*lpLockStatus->lpLockOwner = \"\\0\", expected non-zero\n"); ok(lpLockStatus->dwLockDuration != 0, "lpLockStatus->dwLockDuration = %lu, expected non-zero\n", lpLockStatus->dwLockDuration); HeapFree(GetProcessHeap(), 0, lpLockStatus); /* * Last try, with the database again unlocked. */ SetLastError(0xdeadbeef); bError = UnlockServiceDatabase(hLock); ok(bError == TRUE, "bError = %u, expected TRUE\n", bError); ok_err(ERROR_SUCCESS); hLock = NULL; /* Get the needed size */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, NULL, 0, &dwRequiredSize); ok(bError == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "(bError, GetLastError()) = (%u, 0x%08lx), expected (FALSE, 0x%08lx)\n", bError, GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER); ok(dwRequiredSize != 0, "dwRequiredSize is zero, expected non-zero\n"); if (dwRequiredSize == 0) { skip("Required size is null; cannot proceed with QueryLockStatusA test\n"); goto cleanup; } /* Allocate memory */ lpLockStatus = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize); if (lpLockStatus == NULL) { skip("Cannot allocate %lu bytes of memory\n", dwRequiredSize); goto cleanup; } /* Get the actual value */ SetLastError(0xdeadbeef); bError = QueryServiceLockStatusA(hScm, lpLockStatus, dwRequiredSize, &dwRequiredSize); ok(bError, "bError = %u, expected TRUE\n", bError); /* These conditions must be verified iff the services database is unlocked */ ok(lpLockStatus->fIsLocked == 0, "lpLockStatus->fIsLocked = %lu, expected 0\n", lpLockStatus->fIsLocked); ok(lpLockStatus->lpLockOwner != NULL, "lpLockStatus->lpLockOwner is null, expected non-null\n"); ok(lpLockStatus->lpLockOwner && *lpLockStatus->lpLockOwner == 0, "*lpLockStatus->lpLockOwner != \"\\0\", expected \"\\0\"\n"); ok(lpLockStatus->dwLockDuration == 0, "lpLockStatus->dwLockDuration = %lu, expected 0\n", lpLockStatus->dwLockDuration); HeapFree(GetProcessHeap(), 0, lpLockStatus); cleanup: if (hLock) UnlockServiceDatabase(hLock); if (hScm) CloseServiceHandle(hScm); return; }
BOOL CDriveControl::Install( __in LPWSTR lpServiceName, __in LPWSTR lpPath ) { BOOL bRet = FALSE; SC_HANDLE hScManager = NULL; SC_HANDLE hService = NULL; WCHAR wchTemp[MAX_PATH] = {0}; HKEY hkResult = NULL; DWORD dwData = 0; LONG lResult = 0; __try { hScManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!hScManager) { printf("OpenSCManager failed. (%d) \n", GetLastError()); __leave; } hService = CreateService( hScManager, lpServiceName, NULL, SERVICE_ALL_ACCESS, SERVICE_FILE_SYSTEM_DRIVER, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, lpPath, L"FSFilter Activity Monitor", NULL, L"FltMgr", NULL, NULL ); if (!hService) { printf("CreateService failed. (%d) \n", GetLastError()); __leave; } wcscat_s(wchTemp, _countof(wchTemp), L"SYSTEM\\CurrentControlSet\\services\\"); wcscat_s(wchTemp, _countof(wchTemp), lpServiceName); wcscat_s(wchTemp, _countof(wchTemp), L"\\Instances"); lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, wchTemp, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkResult, NULL ); if (ERROR_SUCCESS != lResult) { printf("RegCreateKeyEx failed. (%d) \n", lResult); __leave; } if (!hkResult) __leave; lResult = RegFlushKey(hkResult); if (ERROR_SUCCESS != lResult) { printf("RegFlushKey failed. (%d) \n", lResult); __leave; } ZeroMemory(wchTemp, sizeof(wchTemp)); wcscat_s(wchTemp, _countof(wchTemp), lpServiceName); wcscat_s(wchTemp, _countof(wchTemp), L" Instance"); lResult = RegSetValueEx( hkResult, L"DefaultInstance", 0, REG_SZ, (const BYTE*)wchTemp, wcslen(wchTemp) * sizeof(WCHAR) ); if (ERROR_SUCCESS != lResult) { printf("RegSetValueEx failed. (%d) \n", lResult); __leave; } lResult = RegFlushKey(hkResult); if (ERROR_SUCCESS != lResult) { printf("RegFlushKey failed. (%d) \n", lResult); __leave; } lResult = RegCloseKey(hkResult); if (ERROR_SUCCESS != lResult) { printf("RegCloseKey failed. (%d) \n", lResult); __leave; } hkResult = NULL; ZeroMemory(wchTemp, sizeof(wchTemp)); wcscat_s(wchTemp, _countof(wchTemp), L"SYSTEM\\CurrentControlSet\\services\\"); wcscat_s(wchTemp, _countof(wchTemp), lpServiceName); wcscat_s(wchTemp, _countof(wchTemp), L"\\Instances\\"); wcscat_s(wchTemp, _countof(wchTemp), lpServiceName); wcscat_s(wchTemp, _countof(wchTemp), L" Instance"); lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, wchTemp, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkResult, NULL ); if (ERROR_SUCCESS != lResult) { printf("RegCreateKeyEx failed. (%d) \n", lResult); __leave; } if (!hkResult) __leave; lResult = RegFlushKey(hkResult); if (ERROR_SUCCESS != lResult) { printf("RegFlushKey failed. (%d) \n", lResult); __leave; } ZeroMemory(wchTemp, sizeof(wchTemp)); wcscat_s(wchTemp, _countof(wchTemp), L"370030"); lResult = RegSetValueEx( hkResult, L"Altitude", 0, REG_SZ, (const BYTE*)wchTemp, wcslen(wchTemp) * sizeof(WCHAR) ); if (ERROR_SUCCESS != lResult) { printf("RegSetValueEx failed. (%d) \n", lResult); __leave; } lResult = RegFlushKey(hkResult); if (ERROR_SUCCESS != lResult) { printf("RegFlushKey failed. (%d) \n", lResult); __leave; } dwData = 0x0; lResult = RegSetValueEx( hkResult, L"Flags", 0, REG_DWORD, (const BYTE*)&dwData, sizeof(DWORD) ); if (ERROR_SUCCESS != lResult) { printf("RegSetValueEx failed. (%d) \n", lResult); __leave; } lResult = RegFlushKey(hkResult); if (ERROR_SUCCESS != lResult) { printf("RegFlushKey failed. (%d) \n", lResult); __leave; } bRet = TRUE; } __finally { if (hkResult) { RegCloseKey(hkResult); hkResult = NULL; } if (hService) { CloseServiceHandle(hService); hService = NULL; } if (hScManager) { CloseServiceHandle(hScManager); hScManager = NULL; } } return bRet; }
// PURPOSE: Installs the service on the local machine void CNTService::CmdInstallService() { char szPath[_MAX_PATH * 2]; char szErr[256]; ReportEvent(EVENTLOG_INFORMATION_TYPE, 0, "Installing Service."); // Try to determine the name and path of this application. if ( !GetModuleFileName(NULL, szPath, sizeof(szPath)) ) { ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Install GetModuleFileName", GetLastErrorText(szErr, sizeof(szErr))); return; } // Try to open the Service Control Manager SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if ( !schSCManager ) { ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Install OpenSCManager", GetLastErrorText(szErr, sizeof(szErr))); return; } // Try to create the service char szInternalName[MAX_PATH]; sprintf(szInternalName, SPHERE_TITLE " - %s", g_Serv.GetName()); SC_HANDLE schService = CreateService( schSCManager, // handle of the Service Control Manager szInternalName, // Internal name of the service (used when controlling the service using "net start" or "netsvc") szInternalName, // Display name of the service (displayed in the Control Panel | Services page) SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, // Start automatically when the OS starts SERVICE_ERROR_NORMAL, szPath, // Path and filename of this executable NULL, NULL, NULL, NULL, NULL ); if ( !schService ) { ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Install CreateService", GetLastErrorText(szErr, sizeof(szErr))); bailout1: CloseServiceHandle(schSCManager); return; } // Configure service - Service description char szDescription[MAX_PATH]; sprintf(szDescription, "SphereServer Service for %s", g_Serv.GetName()); SERVICE_DESCRIPTION sdDescription; sdDescription.lpDescription = szDescription; if ( !ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdDescription) ) { // not critical, so no need to abort the service creation ReportEvent(EVENTLOG_WARNING_TYPE, 0, "Install SetDescription", GetLastErrorText(szErr, sizeof(szErr))); } // Configure service - Restart options SC_ACTION scAction[3]; scAction[0].Type = SC_ACTION_RESTART; // restart process on failure scAction[0].Delay = 10000; // wait 10 seconds before restarting scAction[1].Type = SC_ACTION_RESTART; scAction[1].Delay = 10000; scAction[2].Type = SC_ACTION_RESTART; // wait 2 minutes before restarting the third time scAction[2].Delay = 120000; SERVICE_FAILURE_ACTIONS sfaFailure; sfaFailure.dwResetPeriod = (1 * 60 * 60); // reset failure count after an hour passes with no fails sfaFailure.lpRebootMsg = NULL; // no reboot message sfaFailure.lpCommand = NULL; // no command executed sfaFailure.cActions = COUNTOF(scAction); // number of actions sfaFailure.lpsaActions = scAction; // if ( !ChangeServiceConfig2(schService, SERVICE_CONFIG_FAILURE_ACTIONS, &sfaFailure) ) { // not critical, so no need to abort the service creation ReportEvent(EVENTLOG_WARNING_TYPE, 0, "Install SetAutoRestart", GetLastErrorText(szErr, sizeof(szErr))); } HKEY hKey; char szKey[MAX_PATH]; // Register the application for event logging DWORD dwData; // Try to create the registry key containing information about this application strcpy(szKey, "System\\CurrentControlSet\\Services\\EventLog\\Application\\" SPHERE_FILE "svr"); if (RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &hKey)) ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Install RegCreateKey", GetLastErrorText(szErr, sizeof(szErr))); else { // Try to create the registry key containing the name of the EventMessageFile // Replace the name of the exe with the name of the dll in the szPath variable if (RegSetValueEx(hKey, "EventMessageFile", 0, REG_EXPAND_SZ, (LPBYTE) szPath, strlen(szPath) + 1)) ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Install RegSetValueEx", GetLastErrorText(szErr, sizeof(szErr))); else { // Try to create the registry key containing the types of errors this application will generate dwData = EVENTLOG_ERROR_TYPE|EVENTLOG_INFORMATION_TYPE|EVENTLOG_WARNING_TYPE; if ( RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (LPBYTE) &dwData, sizeof(DWORD)) ) ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Install RegSetValueEx", GetLastErrorText(szErr, sizeof(szErr))); } RegCloseKey(hKey); } // Set the working path for the application sprintf(szKey, "System\\CurrentControlSet\\Services\\" SPHERE_TITLE " - %s\\Parameters", g_Serv.GetName()); if ( RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &hKey) ) { ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Install RegCreateKey", GetLastErrorText(szErr, sizeof(szErr))); bailout2: CloseServiceHandle(schService); goto bailout1; } ExtractPath(szPath); if ( RegSetValueEx(hKey, "WorkingPath", 0, REG_SZ, (const unsigned char *) &szPath[0], strlen(szPath)) ) ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Install RegSetValueEx", GetLastErrorText(szErr, sizeof(szErr))); ReportEvent(EVENTLOG_INFORMATION_TYPE, 0, "Install OK", g_Serv.GetName()); goto bailout2; }
BOOL StopServiceEx(HWND hWnd, SC_HANDLE schSCManager, char *szSvcName) { SC_HANDLE schService; SERVICE_STATUS_PROCESS ssp; DWORD dwStartTime = GetTickCount(); DWORD dwBytesNeeded; DWORD dwTimeout = 30000; // 30 секундна пауза DWORD dwWaitTime; schService = OpenService(schSCManager, szSvcName, SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS); if (schService == NULL) { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); return FALSE; } // Проверява дали сервиса не е вече спрян. if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } if (ssp.dwCurrentState == SERVICE_STOPPED) { MessageBox(hWnd, "Сервисът е бил спрен", "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } // Ако стопирането е в очакване, изчакай го. while (ssp.dwCurrentState == SERVICE_STOP_PENDING) { dwWaitTime = ssp.dwWaitHint / 10; if(dwWaitTime < 1000) dwWaitTime = 1000; else if (dwWaitTime > 10000) dwWaitTime = 10000; Sleep(dwWaitTime); if ( !QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } if (ssp.dwCurrentState == SERVICE_STOPPED) { MessageBox(hWnd, "Сервисът е спрян", "FileHide", MB_ICONEXCLAMATION); CloseServiceHandle(schService); return TRUE; } if (GetTickCount() - dwStartTime > dwTimeout) { MessageBox(hWnd, "Времето за спиране на сервиса изтече", "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } } // Ако сервиса работи, зависимите сервиси първо се спират. StopDependentServices(schSCManager, schService); // Изпраща стоп код към сервиса. if (!ControlService(schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp)) { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } // Изчака сервиса да спре. while (ssp.dwCurrentState != SERVICE_STOPPED) { Sleep(ssp.dwWaitHint); if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } if (ssp.dwCurrentState == SERVICE_STOPPED) break; if (GetTickCount() - dwStartTime > dwTimeout) { MessageBox(hWnd, "Времето за спиране на сервиса изтече", "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } } MessageBox(hWnd, "Сервисът е спрян", "FileHide", MB_ICONEXCLAMATION); CloseServiceHandle(schService); return TRUE; }
NTSTATUS EspLoadRecoveryInfo( _In_ HWND hwndDlg, _In_ PSERVICE_RECOVERY_CONTEXT Context ) { NTSTATUS status = STATUS_SUCCESS; SC_HANDLE serviceHandle; LPSERVICE_FAILURE_ACTIONS failureActions; SERVICE_FAILURE_ACTIONS_FLAG failureActionsFlag; SC_ACTION_TYPE lastType; ULONG returnLength; ULONG i; if (!(serviceHandle = PhOpenService(Context->ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG))) return NTSTATUS_FROM_WIN32(GetLastError()); if (!(failureActions = PhQueryServiceVariableSize(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS))) { CloseServiceHandle(serviceHandle); return NTSTATUS_FROM_WIN32(GetLastError()); } // Failure action types Context->NumberOfActions = failureActions->cActions; if (failureActions->cActions != 0 && failureActions->cActions != 3) status = STATUS_SOME_NOT_MAPPED; // If failure actions are not defined for a particular fail count, the // last failure action is used. Here we duplicate this behaviour when there // are fewer than 3 failure actions. lastType = SC_ACTION_NONE; ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_FIRSTFAILURE), failureActions->cActions >= 1 ? (lastType = failureActions->lpsaActions[0].Type) : lastType); ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_SECONDFAILURE), failureActions->cActions >= 2 ? (lastType = failureActions->lpsaActions[1].Type) : lastType); ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_SUBSEQUENTFAILURES), failureActions->cActions >= 3 ? (lastType = failureActions->lpsaActions[2].Type) : lastType); // Reset fail count after SetDlgItemInt(hwndDlg, IDC_RESETFAILCOUNT, failureActions->dwResetPeriod / (60 * 60 * 24), FALSE); // s to days // Restart service after SetDlgItemText(hwndDlg, IDC_RESTARTSERVICEAFTER, L"1"); for (i = 0; i < failureActions->cActions; i++) { if (failureActions->lpsaActions[i].Type == SC_ACTION_RESTART) { if (failureActions->lpsaActions[i].Delay != 0) { SetDlgItemInt(hwndDlg, IDC_RESTARTSERVICEAFTER, failureActions->lpsaActions[i].Delay / (1000 * 60), FALSE); // ms to min } break; } } // Enable actions for stops with errors // This is Vista and above only. if (WindowsVersion >= WINDOWS_VISTA && QueryServiceConfig2( serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, (BYTE *)&failureActionsFlag, sizeof(SERVICE_FAILURE_ACTIONS_FLAG), &returnLength )) { Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS), failureActionsFlag.fFailureActionsOnNonCrashFailures ? BST_CHECKED : BST_UNCHECKED); Context->EnableFlagCheckBox = TRUE; } else { Context->EnableFlagCheckBox = FALSE; } // Restart computer options Context->RebootAfter = 1 * 1000 * 60; for (i = 0; i < failureActions->cActions; i++) { if (failureActions->lpsaActions[i].Type == SC_ACTION_REBOOT) { if (failureActions->lpsaActions[i].Delay != 0) Context->RebootAfter = failureActions->lpsaActions[i].Delay; break; } } if (failureActions->lpRebootMsg && failureActions->lpRebootMsg[0] != 0) PhMoveReference(&Context->RebootMessage, PhCreateString(failureActions->lpRebootMsg)); else PhClearReference(&Context->RebootMessage); // Run program SetDlgItemText(hwndDlg, IDC_RUNPROGRAM, failureActions->lpCommand); PhFree(failureActions); CloseServiceHandle(serviceHandle); return status; }
BOOL StartServiceEx(HWND hWnd, SC_HANDLE schSCManager, char *szSvcName) { SC_HANDLE schService; SERVICE_STATUS_PROCESS ssStatus; DWORD dwOldCheckPoint; DWORD dwStartTickCount; DWORD dwWaitTime; DWORD dwBytesNeeded; char str[50]; schService = OpenService( schSCManager, // SCM база с данни szSvcName, // име на сервиса SERVICE_ALL_ACCESS); // пълен достъп if (schService == NULL) { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); return FALSE; } // Проверка на състоянието в случай, че сервиса не е спрял. if (!QueryServiceStatusEx( schService, // дръжка до сервиса SC_STATUS_PROCESS_INFO, // информационно ниво (LPBYTE) &ssStatus, // адреса на структура sizeof(SERVICE_STATUS_PROCESS), // големина на структура &dwBytesNeeded)) // необходима големина, ако буфера е много малък { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } // Проверява дали сервиса работи. if(ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING) { MessageBox(hWnd, "Сервисът не може да се стартува, защото е вече стартуван и работи", "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } // Спасяване на цъканията и първоначалния контролно-пропусквателен пункт. dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; // Изчакване на сервиса да спре преди да се опита да стартува. while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) { // Да не се чака по-дълго, отколкото изчакващия намек. Интервала е // една десета от изчакващия намек, но не помалко от една секунда // и не по-вече от 10 секунди. dwWaitTime = ssStatus.dwWaitHint / 10; if(dwWaitTime < 1000) dwWaitTime = 1000; else if (dwWaitTime > 10000) dwWaitTime = 10000; Sleep(dwWaitTime); // Проверка на състоянието, докато сервиса не спре в очакване. if (!QueryServiceStatusEx( schService, // дръжка до сервиса SC_STATUS_PROCESS_INFO, // информационно ниво (LPBYTE) &ssStatus, // адреса на структура sizeof(SERVICE_STATUS_PROCESS), // големина на структура &dwBytesNeeded)) // необходима големина, ако буфера е много малък { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } if (ssStatus.dwCheckPoint > dwOldCheckPoint) { // Продължаване на изчакването и проверката. dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; } else { if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint) { MessageBox(hWnd, "Времето за чакане на сервиса за спиране измина", "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } } } // Опит да се стартува сервиса. if (!StartService( schService, // handle to service 0, // number of arguments NULL) ) // no arguments { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } // Започва очакването... // Проверка на състоянието, докато сервиса не започне в очакване. if (!QueryServiceStatusEx( schService, // дръжка до сервиса SC_STATUS_PROCESS_INFO, // информационно ниво (LPBYTE) &ssStatus, // адреса на структура sizeof(SERVICE_STATUS_PROCESS), // големина на структура &dwBytesNeeded)) // ако буфера е много малък { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } // Спасяване на цъканията и първоначалния контролно-пропусквателен пункт. dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; while (ssStatus.dwCurrentState == SERVICE_START_PENDING) { dwWaitTime = ssStatus.dwWaitHint / 10; if(dwWaitTime < 1000) dwWaitTime = 1000; else if (dwWaitTime > 10000) dwWaitTime = 10000; Sleep(dwWaitTime); // Отново проверка на състоянието. if (!QueryServiceStatusEx( schService, SC_STATUS_PROCESS_INFO, (LPBYTE) &ssStatus, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded)) { MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR); break; } if (ssStatus.dwCheckPoint > dwOldCheckPoint) { // Продължаване на изчакването и проверката. dwStartTickCount = GetTickCount(); dwOldCheckPoint = ssStatus.dwCheckPoint; } else { if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint) { // Без напредък в изчекащия намек. break; } } } // Определя дали сервиса е стартуван. if (ssStatus.dwCurrentState == SERVICE_RUNNING) { MessageBox(hWnd, "Сервисът е стартуван", "FileHide", MB_ICONEXCLAMATION); CloseServiceHandle(schService); return TRUE; } else { sprintf(str, "Сервисът не е стартуван.\n"); sprintf(str, "Текущо състояние: %d\n", ssStatus.dwCurrentState); sprintf(str, " Exit Code: %d\n", ssStatus.dwWin32ExitCode); sprintf(str, " Check Point: %d\n", ssStatus.dwCheckPoint); sprintf(str, " Wait Hint: %d\n", ssStatus.dwWaitHint); MessageBox(hWnd, str, "FileHide", MB_ICONERROR); CloseServiceHandle(schService); return FALSE; } }
INT_PTR CALLBACK EspServiceRecoveryDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_RECOVERY_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_RECOVERY_CONTEXT)); memset(context, 0, sizeof(SERVICE_RECOVERY_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_RECOVERY_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; context->ServiceItem = serviceItem; EspAddServiceActionStrings(GetDlgItem(hwndDlg, IDC_FIRSTFAILURE)); EspAddServiceActionStrings(GetDlgItem(hwndDlg, IDC_SECONDFAILURE)); EspAddServiceActionStrings(GetDlgItem(hwndDlg, IDC_SUBSEQUENTFAILURES)); status = EspLoadRecoveryInfo(hwndDlg, context); if (status == STATUS_SOME_NOT_MAPPED) { if (context->NumberOfActions > 3) { PhShowWarning( hwndDlg, L"The service has %lu failure actions configured, but this program only supports editing 3. " L"If you save the recovery information using this program, the additional failure actions will be lost.", context->NumberOfActions ); } } else if (!NT_SUCCESS(status)) { SetDlgItemText(hwndDlg, IDC_RESETFAILCOUNT, L"0"); if (WindowsVersion >= WINDOWS_VISTA) { context->EnableFlagCheckBox = TRUE; EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS), TRUE); } PhShowWarning(hwndDlg, L"Unable to query service recovery information: %s", ((PPH_STRING)PhAutoDereferenceObject(PhGetNtMessage(status)))->Buffer); } EspFixControls(hwndDlg, context); context->Ready = TRUE; } break; case WM_DESTROY: { PhClearReference(&context->RebootMessage); PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_FIRSTFAILURE: case IDC_SECONDFAILURE: case IDC_SUBSEQUENTFAILURES: { if (HIWORD(wParam) == CBN_SELCHANGE) { EspFixControls(hwndDlg, context); } } break; case IDC_RESTARTCOMPUTEROPTIONS: { DialogBoxParam( PluginInstance->DllBase, MAKEINTRESOURCE(IDD_RESTARTCOMP), hwndDlg, RestartComputerDlgProc, (LPARAM)context ); } break; case IDC_BROWSE: { static PH_FILETYPE_FILTER filters[] = { { L"Executable files (*.exe;*.cmd;*.bat)", L"*.exe;*.cmd;*.bat" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; PPH_STRING fileName; fileDialog = PhCreateOpenFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); fileName = PhaGetDlgItemText(hwndDlg, IDC_RUNPROGRAM); PhSetFileDialogFileName(fileDialog, fileName->Buffer); if (PhShowFileDialog(hwndDlg, fileDialog)) { fileName = PhGetFileDialogFileName(fileDialog); SetDlgItemText(hwndDlg, IDC_RUNPROGRAM, fileName->Buffer); PhDereferenceObject(fileName); } PhFreeFileDialog(fileDialog); } break; case IDC_ENABLEFORERRORSTOPS: { context->Dirty = TRUE; } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { if (context->Ready) context->Dirty = TRUE; } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { NTSTATUS status; PPH_SERVICE_ITEM serviceItem = context->ServiceItem; SC_HANDLE serviceHandle; ULONG restartServiceAfter; SERVICE_FAILURE_ACTIONS failureActions; SC_ACTION actions[3]; ULONG i; BOOLEAN enableRestart = FALSE; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); if (!context->Dirty) { return TRUE; } // Build the failure actions structure. failureActions.dwResetPeriod = GetDlgItemInt(hwndDlg, IDC_RESETFAILCOUNT, NULL, FALSE) * 60 * 60 * 24; failureActions.lpRebootMsg = PhGetStringOrEmpty(context->RebootMessage); failureActions.lpCommand = PhaGetDlgItemText(hwndDlg, IDC_RUNPROGRAM)->Buffer; failureActions.cActions = 3; failureActions.lpsaActions = actions; actions[0].Type = ComboBoxToServiceAction(GetDlgItem(hwndDlg, IDC_FIRSTFAILURE)); actions[1].Type = ComboBoxToServiceAction(GetDlgItem(hwndDlg, IDC_SECONDFAILURE)); actions[2].Type = ComboBoxToServiceAction(GetDlgItem(hwndDlg, IDC_SUBSEQUENTFAILURES)); restartServiceAfter = GetDlgItemInt(hwndDlg, IDC_RESTARTSERVICEAFTER, NULL, FALSE) * 1000 * 60; for (i = 0; i < 3; i++) { switch (actions[i].Type) { case SC_ACTION_RESTART: actions[i].Delay = restartServiceAfter; enableRestart = TRUE; break; case SC_ACTION_REBOOT: actions[i].Delay = context->RebootAfter; break; case SC_ACTION_RUN_COMMAND: actions[i].Delay = 0; break; } } // Try to save the changes. serviceHandle = PhOpenService( serviceItem->Name->Buffer, SERVICE_CHANGE_CONFIG | (enableRestart ? SERVICE_START : 0) // SC_ACTION_RESTART requires SERVICE_START ); if (serviceHandle) { if (ChangeServiceConfig2( serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, &failureActions )) { if (context->EnableFlagCheckBox) { SERVICE_FAILURE_ACTIONS_FLAG failureActionsFlag; failureActionsFlag.fFailureActionsOnNonCrashFailures = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS)) == BST_CHECKED; ChangeServiceConfig2( serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, &failureActionsFlag ); } CloseServiceHandle(serviceHandle); } else { CloseServiceHandle(serviceHandle); goto ErrorCase; } } else { if (GetLastError() == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { if (NT_SUCCESS(status = PhSvcCallChangeServiceConfig2( serviceItem->Name->Buffer, SERVICE_CONFIG_FAILURE_ACTIONS, &failureActions ))) { if (context->EnableFlagCheckBox) { SERVICE_FAILURE_ACTIONS_FLAG failureActionsFlag; failureActionsFlag.fFailureActionsOnNonCrashFailures = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS)) == BST_CHECKED; PhSvcCallChangeServiceConfig2( serviceItem->Name->Buffer, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, &failureActionsFlag ); } } PhUiDisconnectFromPhSvc(); if (!NT_SUCCESS(status)) { SetLastError(PhNtStatusToDosError(status)); goto ErrorCase; } } else { // User cancelled elevation. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } else { goto ErrorCase; } } return TRUE; ErrorCase: if (PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service recovery information: %s", ((PPH_STRING)PhAutoDereferenceObject(PhGetWin32Message(GetLastError())))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } return TRUE; } } break; } return FALSE; }
bool WinServiceInstall() { CSD_T ChangeService_Config2; HMODULE advapi32; SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); if (serviceControlManager) { char path[_MAX_PATH + 10]; if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0) { SC_HANDLE service; std::strcat(path, " -s run"); service = CreateService(serviceControlManager, serviceName, // name of service serviceLongName, // service name to display SERVICE_ALL_ACCESS, // desired access // service type SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, // start type SERVICE_ERROR_IGNORE, // error control type path, // service's binary 0, // no load ordering group 0, // no tag identifier 0, // no dependencies 0, // LocalSystem account 0); // no password if (service) { advapi32 = GetModuleHandle("ADVAPI32.DLL"); if (!advapi32) { CloseServiceHandle(service); CloseServiceHandle(serviceControlManager); return false; } ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A"); if (!ChangeService_Config2) { CloseServiceHandle(service); CloseServiceHandle(serviceControlManager); return false; } SERVICE_DESCRIPTION sdBuf; sdBuf.lpDescription = serviceDescription; ChangeService_Config2( service, // handle to service SERVICE_CONFIG_DESCRIPTION, // change: description &sdBuf); // new data SC_ACTION _action[1]; _action[0].Type = SC_ACTION_RESTART; _action[0].Delay = 10000; SERVICE_FAILURE_ACTIONS sfa; ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS)); sfa.lpsaActions = _action; sfa.cActions = 1; sfa.dwResetPeriod =INFINITE; ChangeService_Config2( service, // handle to service SERVICE_CONFIG_FAILURE_ACTIONS, // information level &sfa); // new data CloseServiceHandle(service); } } CloseServiceHandle(serviceControlManager); } return true; }
//卸载驱动程序 BOOL UnloadNTDriver(char * szSvrName) { BOOL bRet = FALSE; SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄 SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄 SERVICE_STATUS SvrSta; //打开SCM管理器 hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( hServiceMgr == NULL ) { //带开SCM管理器失败 printf( "OpenSCManager() Faild %d ! \n", GetLastError() ); bRet = FALSE; goto BeforeLeave; } else { //带开SCM管理器失败成功 printf( "OpenSCManager() ok ! \n" ); } //打开驱动所对应的服务 hServiceDDK = OpenServiceA( hServiceMgr, szSvrName, SERVICE_ALL_ACCESS ); if( hServiceDDK == NULL ) { //打开驱动所对应的服务失败 printf( "OpenService() Faild %d ! \n", GetLastError() ); bRet = FALSE; goto BeforeLeave; } else { printf( "OpenService() ok ! \n" ); } //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。 if( !ControlService( hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ) ) { printf( "ControlService() Faild %d !\n", GetLastError() ); } else { //打开驱动所对应的失败 printf( "ControlService() ok !\n" ); } //动态卸载驱动程序。 if( !DeleteService( hServiceDDK ) ) { //卸载失败 printf( "DeleteSrevice() Faild %d !\n", GetLastError() ); } else { //卸载成功 printf( "DelServer:eleteSrevice() ok !\n" ); } bRet = TRUE; BeforeLeave: //离开前关闭打开的句柄 if(hServiceDDK) { CloseServiceHandle(hServiceDDK); } if(hServiceMgr) { CloseServiceHandle(hServiceMgr); } return bRet; }