Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
11 KiB

  1. /*************************************************************************
  2. * Microsoft Windows NT *
  3. * *
  4. * Copyright(c) Microsoft Corp., 1994 *
  5. * *
  6. * Revision History: *
  7. * *
  8. * Jan. 22,94 Koti Created *
  9. * *
  10. * Description: *
  11. * *
  12. * This file contains functions that enable LPD service to interact *
  13. * with the Service Controller *
  14. * *
  15. *************************************************************************/
  16. #include "lpd.h"
  17. #include <tcpsvcs.h>
  18. /*****************************************************************************
  19. * *
  20. * Service Entry(): *
  21. * Entry point called by the Service Controller. This function returns *
  22. * only when the service is stopped. *
  23. * *
  24. * Returns: *
  25. * Nothing *
  26. * *
  27. * Parameters: *
  28. * dwArgc (IN): number of arguments passed in *
  29. * lpszArgv (IN): arguments to this function (array of null-terminated *
  30. * strings). First arg is the name of the service and the *
  31. * remaining are the ones passed by the calling process. *
  32. * (e.g. net start lpd /p:xyz) *
  33. * *
  34. * History: *
  35. * Jan.22, 94 Koti Created *
  36. * *
  37. *****************************************************************************/
  38. VOID ServiceEntry( DWORD dwArgc, LPTSTR *lpszArgv,
  39. PTCPSVCS_GLOBAL_DATA pGlobalData )
  40. {
  41. DWORD dwErrcode;
  42. DBG_TRACEIN( "ServiceEntry" );
  43. // Register our control handler
  44. hSvcHandleGLB = RegisterServiceCtrlHandler( LPD_SERVICE_NAME,
  45. LPDCntrlHandler );
  46. if ( hSvcHandleGLB == 0 )
  47. {
  48. LOGIT(( "ServiceEntry: RegisterServiceCtrlHandler() failed %d\n",
  49. GetLastError() ));
  50. return;
  51. }
  52. // Initialize events, objects; event logging etc.
  53. if ( !InitStuff() ){
  54. LPD_DEBUG( "ServiceEntry: InitStuff() failed\n" );
  55. return;
  56. }
  57. // Tell the Service Controller that we are starting
  58. if (!TellSrvcController( SERVICE_START_PENDING, NO_ERROR, 1, LPD_WAIT_HINT ))
  59. {
  60. LPD_DEBUG( "ServiceEntry: TellSrvcController(SERVICE_START_PENDING)"
  61. " failed\n" );
  62. EndLogging();
  63. return;
  64. }
  65. // Ok, this is where we start the service (and keep it running)
  66. dwErrcode = StartLPD( dwArgc, lpszArgv );
  67. if ( dwErrcode != NO_ERROR )
  68. {
  69. LOGIT(( "ServiceEntry: StartLPD() failed %d\n", GetLastError() ));
  70. LpdReportEvent( LPDLOG_LPD_DIDNT_START, 0, NULL, dwErrcode );
  71. EndLogging();
  72. return;
  73. }
  74. // Tell the Service Controller that we are up and running
  75. // If we have trouble telling srv controller, stop LPD and return
  76. if ( !TellSrvcController( SERVICE_RUNNING, NO_ERROR, 0, 0 ) )
  77. {
  78. LPD_DEBUG( "TellSrvcController(): stopping LPD and quitting!\n" );
  79. StopLPD();
  80. TellSrvcController( SERVICE_STOPPED, NO_ERROR, 0, 0 );
  81. EndLogging();
  82. DBG_TRACEOUT( "ServiceEntry" );
  83. return;
  84. }
  85. LPD_DEBUG( "Started LpdSvc successfully\n" );
  86. LpdReportEvent( LPDLOG_LPD_STARTED, 0, NULL, 0 );
  87. // wait here until SetEvent is invoked (i.e. LPD is stopped or shutdown)
  88. WaitForSingleObject( hEventShutdownGLB, INFINITE );
  89. // Tell the Service Controller that we are going to stop now!
  90. if ( !TellSrvcController( SERVICE_STOP_PENDING, NO_ERROR, 1, LPD_WAIT_HINT ) )
  91. {
  92. LPD_DEBUG( "TellSrvcController( SERVICE_STOP_PENDING, .. ) failed\n" );
  93. }
  94. // Stop the LPD service
  95. StopLPD();
  96. FreeStrings();
  97. DBG_DUMPLEAKS();
  98. LPD_DEBUG( "ServiceEntry: Stopped LpdSvc successfully\n" );
  99. LpdReportEvent( LPDLOG_LPD_STOPPED, 0, NULL, 0 );
  100. EndLogging();
  101. DBG_UNINIT();
  102. #ifdef DBG
  103. if( LogFile ){
  104. stoplogging( LogFile );
  105. }
  106. #endif
  107. // if we can still connect, tell the Service Controller that we are gone!
  108. if ( hSvcHandleGLB != 0 )
  109. {
  110. TellSrvcController( SERVICE_STOPPED, NO_ERROR, 0, 0 );
  111. }
  112. } // end ServiceEntry()
  113. /*****************************************************************************
  114. * *
  115. * TellSrvcController(): *
  116. * This function updates the status of our service (LPD) with the Service *
  117. * Controller. *
  118. * *
  119. * Returns: *
  120. * TRUE if everything went ok *
  121. * FALSE if something went wrong *
  122. * *
  123. * Parameters: *
  124. * The four parameters correspond to the 2nd, 4th, 6th and 7th parameters *
  125. * respectively of the SERVICE_STATUS structure passed to the *
  126. * SetServiceStatus call. *
  127. * *
  128. * History: *
  129. * Jan.22, 94 Koti Created *
  130. * *
  131. *****************************************************************************/
  132. BOOL TellSrvcController( DWORD dwCurrentState, DWORD dwWin32ExitCode,
  133. DWORD dwCheckPoint, DWORD dwWaitHint)
  134. {
  135. BOOL fResult;
  136. LOGIT(( "Entering TellSrvcController %d\n", dwCurrentState ));
  137. // initialize the service status structure
  138. ssSvcStatusGLB.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  139. ssSvcStatusGLB.dwCurrentState = dwCurrentState;
  140. ssSvcStatusGLB.dwControlsAccepted = SERVICE_ACCEPT_STOP |
  141. SERVICE_ACCEPT_PAUSE_CONTINUE |
  142. SERVICE_ACCEPT_SHUTDOWN;
  143. ssSvcStatusGLB.dwWin32ExitCode = dwWin32ExitCode;
  144. ssSvcStatusGLB.dwServiceSpecificExitCode = NO_ERROR;
  145. ssSvcStatusGLB.dwCheckPoint = dwCheckPoint;
  146. ssSvcStatusGLB.dwWaitHint = dwWaitHint;
  147. // Tell the Service Controller what our status is
  148. fResult = SetServiceStatus( hSvcHandleGLB, &ssSvcStatusGLB );
  149. DBG_TRACEOUT( "TellSrvcController" );
  150. return (fResult);
  151. } // end TellSrvcController()
  152. /*****************************************************************************
  153. * *
  154. * LPDCntrlHandler(): *
  155. * This function gets called (indirectly by the Service Controller) *
  156. * whenever there is a control request for the LPD service. Depending on *
  157. * the control request, this function takes appropriate action. *
  158. * *
  159. * Returns: *
  160. * Nothing *
  161. * *
  162. * Parameters: *
  163. * dwControl (IN): The requested control code. *
  164. * *
  165. * History: *
  166. * Jan.22, 94 Koti Created *
  167. * *
  168. *****************************************************************************/
  169. VOID LPDCntrlHandler( DWORD dwControl )
  170. {
  171. BOOL fMustStopSrvc=FALSE;
  172. time_t now;
  173. time( &now );
  174. LOGIT(("Entering LPDCntrlHandler %d at %s", dwControl, ctime(&now) ));
  175. switch( dwControl )
  176. {
  177. // Treat _STOP and _SHUTDOWN in the same manner
  178. case SERVICE_CONTROL_STOP:
  179. LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_STOP\n"));
  180. case SERVICE_CONTROL_SHUTDOWN:
  181. LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_SHUTDOWN\n"));
  182. ssSvcStatusGLB.dwCurrentState = SERVICE_STOP_PENDING;
  183. ssSvcStatusGLB.dwCheckPoint = 0;
  184. fMustStopSrvc = TRUE;
  185. break;
  186. // don't accept any new connections: the service is now PAUSED
  187. case SERVICE_CONTROL_PAUSE:
  188. LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_PAUSE\n"));
  189. ssSvcStatusGLB.dwCurrentState = SERVICE_PAUSED;
  190. break;
  191. // the service was paused earlier: continue it now
  192. case SERVICE_CONTROL_CONTINUE:
  193. LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_CONTINUE\n"));
  194. ssSvcStatusGLB.dwCurrentState = SERVICE_RUNNING;
  195. break;
  196. // we don't do anything with this
  197. case SERVICE_CONTROL_INTERROGATE:
  198. LOGIT(("LPDCntrlHandler: SERVICE_CONTROL_INTERROGATE\n"));
  199. break;
  200. default:
  201. LOGIT(("Unknown control word received in LPDCntrlHandler\n"));
  202. break;
  203. }
  204. // Update the status (even if it didn't change!) with Service Controller
  205. SetServiceStatus( hSvcHandleGLB, &ssSvcStatusGLB );
  206. // If we must stop or shutdown the service, set our shutdown event
  207. if ( fMustStopSrvc )
  208. {
  209. fShuttingDownGLB = 1;
  210. SetEvent( hEventShutdownGLB );
  211. LOGIT(("LPDCntrlHandler: fShuttingDownGLB=%d\n", fShuttingDownGLB ));
  212. }
  213. DBG_TRACEOUT( "LPDCntrlHandler" );
  214. } // end LPDCntrlHandler()