serviceControl.cpp
上传用户:nnxzhh
上传日期:2007-01-11
资源大小:742k
文件大小:11k
开发平台:

WINDOWS

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright 1999 - 2000 Mark Roddy
  4. // All Rights Reserved
  5. //
  6. // Hollis Technology Solutions
  7. // 94 Dow Road
  8. // Hollis, NH 03049
  9. // info@hollistech.com
  10. //
  11. // Synopsis: 
  12. // 
  13. //
  14. // Version Information:
  15. //
  16. // $Header: /iphook/usr/IpMonitor/serviceControl.cpp 2     1/27/00 10:35p Markr $ 
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "ServiceControl.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. ServiceControl::ServiceControl()
  27. {
  28. driverHandle = INVALID_HANDLE_VALUE;
  29. SchSCManager = (SC_HANDLE) INVALID_HANDLE_VALUE;   
  30.     UnloadInDestructor = TRUE;
  31.     RemoveInDestructor = FALSE;
  32.     lastError = 0;
  33. ChangeIfExists = FALSE;
  34. }
  35. DWORD ServiceControl::init(LPCTSTR Name, 
  36.  DWORD flagsAndAttributes, 
  37.  LPCTSTR Path, 
  38.  LPCTSTR DosName)
  39. {
  40. attributes = flagsAndAttributes;
  41. DriverName = Name;
  42. if (Path) {
  43. BinaryPath = Path;
  44. } else {
  45.         //
  46.         // allow two choices, first the CWD, second the system root.
  47.         //
  48.         DWORD length = GetCurrentDirectory(0, NULL);
  49.         CString cwd;
  50.         
  51.         LPTSTR buff = cwd.GetBufferSetLength(length);
  52.         DWORD result = GetCurrentDirectory(length, buff);
  53.         cwd.ReleaseBuffer();
  54.         
  55.         if (result != 0xffffffff) {
  56.             BinaryPath = cwd + CString("\") + DriverName + CString(".sys");
  57.             result = GetFileAttributes(LPCTSTR(BinaryPath));
  58.         }
  59.         if (result == 0xffffffff) {
  60.             
  61.             BinaryPath = CString("%SystemRoot%\system32\Drivers\") + DriverName + CString(".sys");
  62.         }
  63. }
  64. if (DosName) {
  65. DosDevice = DosName;
  66. } else {
  67. DosDevice = DriverName;
  68. }
  69.     //
  70.     // if the current string is not the fully qualified
  71.     // dos device name, make it so.
  72.     //
  73.     if ( CString(DosDevice.Left(2)) != CString("\\")) {
  74.     
  75.         DosDevice = CString("\\.\") + DosDevice;
  76.     }
  77.     try {
  78.         LoadDriver();
  79.     }
  80.     catch (DWORD error)
  81.     {
  82.         //
  83.         // don't throw a simple interface error as
  84.         // an exception or we get a leak (ugh.)
  85.         //
  86.         lastError = error;
  87.     }
  88.     if (lastError != 0) {
  89.         try {
  90.             closeDevice();
  91.         }
  92.         catch (...) {};
  93.     }
  94. return lastError;    
  95. }
  96. ServiceControl::~ServiceControl()
  97. {
  98.     try {
  99.         closeDevice();
  100.     }
  101.     catch (...) {};
  102.     if (UnloadInDestructor) {
  103.     try {
  104.     UnloadDriver();
  105.     } 
  106.     catch (...) {};
  107.     }
  108. }
  109. /****************************************************************************
  110. *
  111. *    FUNCTION: LoadDeviceDriver( const TCHAR, const TCHAR, HANDLE *)
  112. *
  113. *    PURPOSE: Registers a driver with the system configuration manager 
  114. *  and then loads it.
  115. *
  116. ****************************************************************************/
  117. void ServiceControl::LoadDriver()
  118. {
  119. BOOL okay;
  120. SchSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
  121. if (SchSCManager == INVALID_HANDLE_VALUE) {
  122. throw GetLastError();
  123. }
  124. // Ignore success of installation: it may already be installed.
  125. (void) InstallDriver();
  126. // Ignore success of start: it may already be started.
  127. (void) StartDriver();
  128. // Do make sure we can open it.
  129. okay = OpenDevice();
  130. if (!okay) {
  131. throw GetLastError();
  132. }
  133.   SchSCManager = closeSVC(SchSCManager);
  134. }
  135. /****************************************************************************
  136. *
  137. *    FUNCTION: InstallDriver( IN SC_HANDLE, IN LPCTSTR, IN LPCTSTR)
  138. *
  139. *    PURPOSE: Creates a driver service.
  140. *
  141. ****************************************************************************/
  142. BOOL ServiceControl::InstallDriver( )
  143. {
  144.     SC_HANDLE  schService;
  145.     //
  146.     // NOTE: This creates an entry for a standalone driver. If this
  147.     //       is modified for use with a driver that requires a Tag,
  148.     //       Group, and/or Dependencies, it may be necessary to
  149.     //       query the registry for existing driver information
  150.     //       (in order to determine a unique Tag, etc.).
  151.     //
  152.     schService = CreateService( SchSCManager,          // SCManager database
  153.                                 DriverName,           // name of service
  154.                                 DriverName,           // name to display
  155.                                 SERVICE_ALL_ACCESS,    // desired access
  156.                                 SERVICE_KERNEL_DRIVER, // service type
  157.                                 SERVICE_DEMAND_START,  // start type
  158.                                 SERVICE_ERROR_NORMAL,  // error control type
  159.                                 BinaryPath,            // service's binary
  160.                                 NULL,                  // no load ordering group
  161.                                 NULL,                  // no tag identifier
  162.                                 NULL,                  // no dependencies
  163.                                 NULL,                  // LocalSystem account
  164.                                 NULL                   // no password
  165.                                 );
  166.     if ( schService == NULL ) {
  167. //
  168. // Fine, try to Open it and change it
  169. //
  170. schService =  OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
  171. if (schService == NULL) {
  172. //
  173. // this is truly hosed
  174. //
  175. return FALSE;
  176. } else if (ChangeIfExists) {
  177. if (FALSE == ChangeServiceConfig(
  178. schService, // handle to service 
  179. SERVICE_KERNEL_DRIVER, // type of service 
  180. SERVICE_DEMAND_START, // when to start service 
  181. SERVICE_ERROR_NORMAL, // severity if service fails to start 
  182. BinaryPath, // pointer to service binary file name 
  183. NULL, // pointer to load ordering group name 
  184. NULL, // pointer to variable to get tag identifier 
  185. NULL, // pointer to array of dependency names 
  186. NULL, // pointer to account name of service 
  187. NULL, // pointer to password for service account  
  188. DriverName  // pointer to display name 
  189. )) {
  190. //
  191. // oh mama, we are not going to be happy
  192. //
  193. return FALSE;
  194. }
  195. }
  196. }
  197.     schService = closeSVC( schService );
  198.     return TRUE;
  199. }
  200. /****************************************************************************
  201. *
  202. *    FUNCTION: StartDriver( IN SC_HANDLE, IN LPCTSTR)
  203. *
  204. *    PURPOSE: Starts the driver service.
  205. *
  206. ****************************************************************************/
  207. BOOL ServiceControl::StartDriver()
  208. {
  209.     SC_HANDLE  schService;
  210.     BOOL       ret;
  211.     schService = OpenService( SchSCManager,
  212.                               DriverName,
  213.                               SERVICE_ALL_ACCESS
  214.                               );
  215.     
  216. if ( schService == NULL ) {
  217.         return FALSE;
  218. }
  219.     ret = StartService( schService, 0, NULL );
  220.     if (!ret) {
  221.         if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) {
  222.             ret = 1; // OK
  223.             //
  224.             // we didn't start it, we don't unload it
  225.             //
  226.             UnloadInDestructor = FALSE;
  227.         }
  228.     }
  229.     //
  230.     // whatever happened close our handle to the SCManager
  231.     //
  232.     schService = closeSVC( schService );
  233.     return ret;
  234. }
  235. /****************************************************************************
  236. *
  237. *    FUNCTION: OpenDevice( IN LPCTSTR, HANDLE *)
  238. *
  239. *    PURPOSE: Opens the device and returns a handle if desired.
  240. *
  241. ****************************************************************************/
  242. BOOL ServiceControl::OpenDevice( )
  243. {
  244.    
  245. if (driverHandle != INVALID_HANDLE_VALUE) {
  246. CloseHandle(driverHandle);
  247. }
  248.     driverHandle = CreateFile( DosDevice,
  249.                           GENERIC_READ | GENERIC_WRITE,
  250.                           0,
  251.                           NULL,
  252.                           OPEN_EXISTING,
  253.                           attributes,
  254.                           NULL
  255.                           );
  256.     return driverHandle != INVALID_HANDLE_VALUE;
  257. }
  258. /****************************************************************************
  259. *
  260. *    FUNCTION: UnloadDeviceDriver( const TCHAR *)
  261. *
  262. *    PURPOSE: Stops the driver and has the configuration manager unload it.
  263. *
  264. ****************************************************************************/
  265. void ServiceControl::UnloadDriver()
  266. {
  267. if (SchSCManager == INVALID_HANDLE_VALUE) {
  268. SchSCManager = OpenSCManager( NULL,                 // machine (NULL == local)
  269.                                NULL,                 // database (NULL == default)
  270. SC_MANAGER_ALL_ACCESS // access required
  271. );
  272. }
  273. if (SchSCManager != INVALID_HANDLE_VALUE) {
  274.         if (TRUE == StopDriver()) {
  275.             if (RemoveInDestructor) {
  276.  
  277.                 RemoveDriver();
  278.             }
  279.         }
  280.  
  281. SchSCManager = closeSVC(SchSCManager);
  282. }
  283. }
  284. /****************************************************************************
  285. *
  286. *    FUNCTION: StopDriver( IN SC_HANDLE, IN LPCTSTR)
  287. *
  288. *    PURPOSE: Has the configuration manager stop the driver (unload it)
  289. *
  290. ****************************************************************************/
  291. BOOL ServiceControl::StopDriver()
  292. {
  293.     SC_HANDLE       schService;
  294.     BOOL            ret;
  295.     SERVICE_STATUS  serviceStatus;
  296.     schService = OpenService( SchSCManager, DriverName, SERVICE_ALL_ACCESS );
  297.     if ( schService == NULL )
  298.         return FALSE;
  299. closeDevice();
  300.     ret = ControlService( schService, SERVICE_CONTROL_STOP, &serviceStatus );
  301.     schService = closeSVC( schService );
  302.     return ret;
  303. }
  304. /****************************************************************************
  305. *
  306. *    FUNCTION: RemoveDriver( IN SC_HANDLE, IN LPCTSTR)
  307. *
  308. *    PURPOSE: Deletes the driver service.
  309. *
  310. ****************************************************************************/
  311. BOOL ServiceControl::RemoveDriver( )
  312. {
  313.     SC_HANDLE  schService;
  314.     BOOL       ret;
  315.     
  316.     schService = OpenService( SchSCManager,
  317.                               DriverName,
  318.                               SERVICE_ALL_ACCESS
  319.                               );
  320.     if ( schService == NULL ) {
  321.         return FALSE;
  322.     }
  323.     ret = DeleteService( schService );
  324.     schService = closeSVC( schService );
  325.     return ret;
  326. }
  327. void ServiceControl::RemoveDriverOnExit(BOOL val)
  328. {
  329.     RemoveInDestructor = val;
  330. }
  331. ///////////////////////////////////////////////////////////////////////////////
  332. // 
  333. // Change History Log
  334. //
  335. // $Log: /iphook/usr/IpMonitor/serviceControl.cpp $
  336. // 
  337. // 2     1/27/00 10:35p Markr
  338. // Prepare to release!
  339. //
  340. ///////////////////////////////////////////////////////////////////////////////