00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00026 #ifndef OW32_ServiceManager_h
00027 #define OW32_ServiceManager_h
00028
00029 #include <OW32/XSC_HANDLE.h>
00030 #include <OW32/auto_buf.h>
00031
00032 namespace OW32
00033 {
00034 class OW32_LIB_EXPORT CEnumDependentServices;
00035
00037 class OW32_LIB_EXPORT CSCService
00038 {
00039 private:
00040 XSC_HANDLE m_hService;
00041
00042 public:
00044 CSCService(SC_HANDLE hService) :
00045 m_hService(hService)
00046 {
00047 }
00048
00050 ~CSCService()
00051 {
00052
00053 DWORD dwLastError = ::GetLastError();
00054 m_hService.Close();
00055 ::SetLastError(dwLastError);
00056 }
00057
00059 SC_HANDLE GetHandle() const { return m_hService; }
00060
00066 BOOL Control(DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
00067 {
00068 return ::ControlService(m_hService, dwControl, lpServiceStatus);
00069 }
00070
00076 BOOL Start(DWORD dwNumServiceArgs = 0, LPCTSTR* lpServiceArgVectors = NULL)
00077 {
00078 return ::StartService(m_hService, dwNumServiceArgs, lpServiceArgVectors);
00079 }
00080
00085 BOOL Stop(LPSERVICE_STATUS lpServiceStatus)
00086 {
00087 return ::ControlService(m_hService, SERVICE_CONTROL_STOP, lpServiceStatus);
00088 }
00089
00094 BOOL Delete()
00095 {
00096 return ::DeleteService(m_hService);
00097 }
00098
00103 BOOL QueryStatus(LPSERVICE_STATUS lpServiceStatus) { return ::QueryServiceStatus(m_hService, lpServiceStatus); }
00104
00109 inline CEnumDependentServices* EnumDependentServices(DWORD dwServiceState = SERVICE_STATE_ALL);
00110
00112 operator SC_HANDLE() { return m_hService; }
00113 };
00114
00115 #ifdef _MSC_VER
00116 #pragma warning(disable: 4251)
00117 #endif
00118
00120 class OW32_LIB_EXPORT CEnumDependentServices
00121 {
00122 public:
00127 CEnumDependentServices(CSCService& parent, DWORD dwServiceState) :
00128 m_parent(parent),
00129 m_dwServiceState(dwServiceState),
00130 m_dwCount(0),
00131 m_dwPos(0),
00132 m_bGot(false)
00133 {
00134 m_buf.reserve(sizeof(ENUM_SERVICE_STATUS) + 256*2);
00135 }
00136
00141 BOOL Next(ENUM_SERVICE_STATUS** ppEntry)
00142 {
00143 if (!m_bGot)
00144 {
00145 for (int i = 0; i < 2; i++) {
00146 DWORD cbBytesNeeded;
00147 if (!EnumDependentServices(m_parent, m_dwServiceState, (ENUM_SERVICE_STATUS*)m_buf.str(),
00148 (DWORD)m_buf.capacity(), &cbBytesNeeded, &m_dwCount)) {
00149 if (i > 0 || GetLastError() != ERROR_MORE_DATA)
00150 return FALSE;
00151 }
00152 m_buf.reserve(cbBytesNeeded);
00153 }
00154 m_bGot = true;
00155 }
00156
00157 if (m_dwPos >= m_dwCount) {
00158 SetLastError(ERROR_NO_MORE_ITEMS);
00159 return FALSE;
00160 }
00161
00162 *ppEntry = &((ENUM_SERVICE_STATUS*)m_buf.str())[m_dwPos++];
00163 return TRUE;
00164 }
00165
00166 private:
00167 CEnumDependentServices(const CEnumDependentServices &other);
00168 CEnumDependentServices& operator=(const CEnumDependentServices &other);
00169
00170 CSCService &m_parent;
00171 DWORD m_dwServiceState;
00172 DWORD m_dwPos, m_dwCount;
00173 auto_byte_buf m_buf;
00174 bool m_bGot;
00175 };
00176
00177 #ifdef _MSC_VER
00178 #pragma warning(default: 4251)
00179 #endif
00180
00181 inline CEnumDependentServices* CSCService::EnumDependentServices(DWORD dwServiceState)
00182 {
00183 return new CEnumDependentServices(*this, dwServiceState);
00184 }
00185
00186 class OW32_LIB_EXPORT CEnumServicesStatus;
00187
00189 class OW32_LIB_EXPORT CSCManager
00190 {
00191 private:
00192 XSC_HANDLE m_SCManager;
00193
00194 public:
00199 BOOL Open(DWORD dwDesiredAccess = SC_MANAGER_ALL_ACCESS, LPCTSTR lpszMachineName = NULL)
00200 {
00201 m_SCManager = ::OpenSCManager(lpszMachineName, SERVICES_ACTIVE_DATABASE, dwDesiredAccess);
00202 return m_SCManager != NULL;
00203 }
00204
00206 void Close()
00207 {
00208 m_SCManager.Close();
00209 }
00210
00212 ~CSCManager()
00213 {
00214
00215 DWORD dwLastError = ::GetLastError();
00216 m_SCManager.Close();
00217 ::SetLastError(dwLastError);
00218 }
00219
00221 SC_HANDLE GetHandle() const { return m_SCManager; }
00222
00228 inline CEnumServicesStatus* EnumServicesStatus(DWORD dwServiceType=SERVICE_WIN32, DWORD dwServiceState=SERVICE_STATE_ALL);
00229
00245 CSCService* CreateService(
00246 LPCTSTR lpServiceName,
00247 LPCTSTR lpPath,
00248 LPCTSTR lpServiceDescription = NULL,
00249 DWORD dwDesiredAccess = STANDARD_RIGHTS_REQUIRED,
00250 DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS,
00251 DWORD dwStartType = SERVICE_AUTO_START,
00252 DWORD dwErrorControl = SERVICE_ERROR_NORMAL,
00253 LPCTSTR lpLoadOrderGroup = NULL,
00254 LPDWORD lpLoadOrderTag = NULL,
00255 LPCTSTR lpDependencies = NULL,
00256 LPCTSTR lpAccountName = NULL,
00257 LPCTSTR lpPassword = NULL)
00258 {
00259 SC_HANDLE hService =
00260 ::CreateService(m_SCManager, lpServiceName, lpServiceDescription, dwDesiredAccess,
00261 dwServiceType, dwStartType, dwErrorControl, lpPath,
00262 lpLoadOrderGroup, lpLoadOrderTag, lpDependencies, lpAccountName, lpPassword);
00263 if (hService==NULL)
00264 return NULL;
00265 return new CSCService(hService);
00266 }
00267
00273 CSCService* OpenService(LPCTSTR lpServiceName, DWORD dwDesiredAccess = SERVICE_ALL_ACCESS)
00274 {
00275 SC_HANDLE hService = ::OpenService(m_SCManager, lpServiceName, dwDesiredAccess);
00276 if (hService==NULL)
00277 return NULL;
00278 return new CSCService(hService);
00279 }
00280 };
00281
00283 class OW32_LIB_EXPORT CEnumServicesStatus
00284 {
00285 public:
00291 inline CEnumServicesStatus(CSCManager& parent, DWORD dwServiceType, DWORD dwServiceState);
00292
00297 inline DWORD Next(ENUM_SERVICE_STATUS** ppEntry);
00298
00299 private:
00300 CEnumServicesStatus(const CEnumServicesStatus &other);
00301 CEnumServicesStatus& operator=(const CEnumServicesStatus &other);
00302
00303 CSCManager &m_Parent;
00304 DWORD m_CurrentPos,m_BufferCount;
00305 DWORD m_dwServiceType,m_dwServiceState,m_dwResumeHandle;
00306 bool m_bMoreToCome;
00307 ENUM_SERVICE_STATUS m_StatusBuffer[1024 / sizeof(ENUM_SERVICE_STATUS)];
00308 };
00309
00310 inline CEnumServicesStatus* CSCManager::EnumServicesStatus(DWORD dwServiceType, DWORD dwServiceState)
00311 {
00312 return new CEnumServicesStatus(*this, dwServiceType, dwServiceState);
00313 }
00314
00315 inline CEnumServicesStatus::CEnumServicesStatus(CSCManager& parent, DWORD dwServiceType, DWORD dwServiceState) :
00316 m_Parent(parent),
00317 m_CurrentPos(0),
00318 m_BufferCount(0),
00319 m_dwServiceType(dwServiceType),
00320 m_dwServiceState(dwServiceState),
00321 m_dwResumeHandle(0),
00322 m_bMoreToCome(true)
00323 {
00324 }
00325
00326 inline DWORD CEnumServicesStatus::Next(ENUM_SERVICE_STATUS** ppEntry)
00327 {
00328
00329 if (m_CurrentPos < m_BufferCount) {
00330 *ppEntry = &m_StatusBuffer[m_CurrentPos++];
00331 return ERROR_SUCCESS;
00332 }
00333
00334
00335 if (m_bMoreToCome) {
00336 DWORD dwBytesNeeded;
00337 if (!EnumServicesStatus(m_Parent.GetHandle(), m_dwServiceType, m_dwServiceState, m_StatusBuffer,
00338 sizeof(m_StatusBuffer), &dwBytesNeeded, &m_BufferCount, &m_dwResumeHandle))
00339 {
00340 DWORD dwError=GetLastError();
00341 if (dwError!=ERROR_MORE_DATA)
00342 return dwError;
00343 } else
00344 m_bMoreToCome = false;
00345 } else {
00346 return 1;
00347 }
00348
00349
00350 m_CurrentPos=0;
00351 *ppEntry = &m_StatusBuffer[m_CurrentPos++];
00352 return ERROR_SUCCESS;
00353 }
00354
00355 }
00356
00357 #endif // OW32_ServiceManager_h