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.

245 lines
6.5 KiB

  1. // Copyright (c) 1996-1999 Microsoft Corporation
  2. //+-------------------------------------------------------------------------
  3. //
  4. // Microsoft Windows
  5. //
  6. // File: main.cxx
  7. //
  8. // Contents: Main startup for Tracking (Workstation) Service
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. //
  15. //
  16. // History: 18-Nov-96 BillMo Created.
  17. //
  18. // Notes:
  19. //
  20. // Codework:
  21. //
  22. //--------------------------------------------------------------------------
  23. #include "pch.cxx"
  24. #pragma hdrstop
  25. #define TRKDATA_ALLOCATE
  26. #include "trkwks.hxx"
  27. #undef TRKDATA_ALLOCATE
  28. #include "svcs.h"
  29. #define THIS_FILE_NUMBER MAIN_CXX_FILE_NO
  30. //+----------------------------------------------------------------------------
  31. //
  32. // SvcsWorkerCallback
  33. //
  34. // This is the callback routine that we register with the services.exe
  35. // thread pool. We only register one item with that thread pool, an
  36. // event that gets signaled when the service has been stopped.
  37. //
  38. //+----------------------------------------------------------------------------
  39. //HANDLE g_hWait = NULL;
  40. void
  41. ServiceStopCallback( PVOID pContext, BOOLEAN fTimeout )
  42. {
  43. CTrkWksSvc *ptrkwks = reinterpret_cast<CTrkWksSvc*>(pContext);
  44. __try
  45. {
  46. /*
  47. UnregisterWait( g_hWait );
  48. g_hWait = NULL;
  49. */
  50. // Close down the service. This could block while threads are
  51. // completed.
  52. ptrkwks->UnInitialize( S_OK );
  53. CTrkRpcConfig::_fInitialized = FALSE;
  54. delete ptrkwks;
  55. TrkAssert( NULL == g_ptrkwks );
  56. // Close the stop event and the debug log
  57. // Uninitialize the DLL, since it's never actually unloaded.
  58. CommonDllUnInit( &g_ctrkwks );
  59. #if DBG
  60. TrkDebugDelete( );
  61. #endif
  62. TrkLog((TRKDBG_WKS, TEXT("TrkWks service stopped") ));
  63. }
  64. __except( BreakOnDebuggableException() )
  65. {
  66. TrkLog(( TRKDBG_ERROR, TEXT("Exception during service stop - %08x"), GetExceptionCode() ));
  67. }
  68. }
  69. //+----------------------------------------------------------------------------
  70. //
  71. // ServiceMain
  72. //
  73. // This function is exported from the dll, and is called when we run
  74. // under svchost.exe.
  75. //
  76. //+----------------------------------------------------------------------------
  77. VOID WINAPI
  78. ServiceMain(DWORD dwArgc, LPTSTR *lptszArgv)
  79. {
  80. SVCS_ENTRY_POINT( dwArgc, lptszArgv, NULL, NULL );
  81. }
  82. //+----------------------------------------------------------------------------
  83. //
  84. // ServiceEntry
  85. //
  86. // This function is also exported from the dll, and is called directly when
  87. // we run under services.exe (the normal case), but is also called by
  88. // ServiceMain when we run under svchost.exe. We distinguish between the
  89. // two by checking pSvcsGlobalData (non-NULL iff running under services.exe).
  90. // Since we use the Win32 thread pool, this routine returns after some
  91. // initialization, it isn't held for the lifetime of the service (except
  92. // when run under svchost.exe).
  93. //
  94. //+----------------------------------------------------------------------------
  95. VOID
  96. SVCS_ENTRY_POINT(
  97. DWORD NumArgs,
  98. LPTSTR *ArgsArray,
  99. PSVCHOST_GLOBAL_DATA pSvcsGlobalData,
  100. IN HANDLE SvcRefHandle
  101. )
  102. {
  103. HRESULT hr = S_OK;
  104. BOOL fDllInitialized = FALSE;
  105. CTrkWksSvc *ptrkwks = NULL;
  106. #if DBG
  107. BOOL fDbgLogInitialized = FALSE;
  108. #endif
  109. __try
  110. {
  111. #if DBG
  112. {
  113. CTrkConfiguration cTrkConfiguration;
  114. cTrkConfiguration.Initialize();
  115. TrkDebugCreate( cTrkConfiguration._dwDebugStoreFlags, "TrkWks" );
  116. cTrkConfiguration.UnInitialize();
  117. fDbgLogInitialized = TRUE;
  118. }
  119. #endif
  120. // Initialize the DLL itself. This raises if there is already a running
  121. // trkwks service.
  122. CommonDllInit( &g_ctrkwks );
  123. TrkLog(( TRKDBG_WKS, TEXT("\n") ));
  124. // Create and initialize the primary service object
  125. ptrkwks = new CTrkWksSvc;
  126. if( NULL == ptrkwks )
  127. {
  128. TrkLog(( TRKDBG_ERROR, TEXT("Couldn't alloc CTrkWksSvc") ));
  129. return;
  130. }
  131. ptrkwks->Initialize( pSvcsGlobalData );
  132. TrkAssert( NULL != g_ptrkwks );
  133. // Are we in services.exe?
  134. /*
  135. if( NULL != pSvcsGlobalData )
  136. {
  137. // Yes. Register the stop event with the thread pool.
  138. // Register as a long function, so that when we do an LPC connect
  139. // in CPort::UnInitialize, the thread pool will be willing to create
  140. // a thread for CPort::DoWork to process the connect.
  141. if( !RegisterWaitForSingleObject( &g_hWait,
  142. g_hServiceStopEvent,
  143. ServiceStopCallback,
  144. g_ptrkwks, INFINITE,
  145. WT_EXECUTEONLYONCE | WT_EXECUTELONGFUNCTION ))
  146. {
  147. TrkLog(( TRKDBG_ERROR, TEXT("Couldn't add service stop event to thread pool") ));
  148. TrkReportInternalError( THIS_FILE_NUMBER, __LINE__,
  149. HRESULT_FROM_WIN32(GetLastError()),
  150. TRKREPORT_LAST_PARAM );
  151. TrkRaiseLastError();
  152. }
  153. }
  154. else
  155. {
  156. // No, we're running in svchost.exe. We'll use this thread to wait
  157. // on the stop event.
  158. if( WAIT_OBJECT_0 != WaitForSingleObject( g_hServiceStopEvent, INFINITE ))
  159. {
  160. TrkLog(( TRKDBG_ERROR, TEXT("Couldn't wait for g_hServiceStopEvent (%lu)"),
  161. GetLastError() ));
  162. TrkRaiseLastError();
  163. }
  164. // The service is stopping. Call the same callback routine that's called
  165. // by the services thread pool when we run under services.exe.
  166. ServiceStopCallback( ptrkwks, FALSE );
  167. }
  168. */
  169. ptrkwks = NULL;
  170. }
  171. __except(BreakOnDebuggableException())
  172. {
  173. hr = GetExceptionCode();
  174. #if DBG
  175. if( fDbgLogInitialized )
  176. TrkLog((TRKDBG_ERROR, TEXT("couldn't initialize, hr=%08X"),hr));
  177. #endif
  178. if( NULL != ptrkwks )
  179. {
  180. __try
  181. {
  182. ptrkwks->UnInitialize( hr );
  183. }
  184. __except( EXCEPTION_EXECUTE_HANDLER )
  185. {
  186. TrkAssert( !TEXT("Unexpected exception in trkwks!ServiceEntry") );
  187. }
  188. TrkAssert( NULL == g_ptrkwks );
  189. delete ptrkwks;
  190. ptrkwks = NULL;
  191. }
  192. if( fDllInitialized )
  193. CommonDllUnInit( &g_ctrkwks );
  194. }
  195. }