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.

282 lines
6.2 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1991 - 1992
  6. //
  7. // File: spmgr.c
  8. //
  9. // Contents: Main file of the SPMgr component
  10. //
  11. // Functions: SetKsecEvent -- Sets the event exported by DD
  12. // ServerMain -- Main startup
  13. //
  14. //
  15. // History: 27 May 92, RichardW Commented
  16. //
  17. //------------------------------------------------------------------------
  18. #include <lsapch.hxx>
  19. extern "C"
  20. {
  21. #include "spinit.h"
  22. }
  23. ///////////////////////////////////////////////////////////////////////////
  24. //
  25. //
  26. // Global "Variables"
  27. //
  28. //
  29. // Most of these variables are set during initialization, and are used
  30. // in a read-only fashion afterwards.
  31. //
  32. //
  33. ///////////////////////////////////////////////////////////////////////////
  34. PWSTR pszPackageList; // Not really needed
  35. LUID SystemLogonId = SYSTEM_LUID; // Logon Session for the system (should be 999:0)
  36. DWORD dwSession; // TLS: Thread Session ptr
  37. DWORD dwLastError; // TLS: Thread last error
  38. DWORD dwExceptionInfo; // TLS: Thread exception info
  39. DWORD dwCallInfo; // TLS: Thread LPC message ptr
  40. DWORD dwThreadPackage; // TLS: Thread Package ID
  41. DWORD dwThreadHeap; // TLS: Thread Heap
  42. BOOLEAN SetupPhase;
  43. HANDLE hShutdownEvent; // Shutdown synch event
  44. HANDLE hStateChangeEvent; // State change event
  45. SECURITY_STRING MachineName;
  46. PWSTR * ppszPackages; // Contains a null terminated array of dll names
  47. PWSTR * ppszOldPkgs; // Contains a null terminated array of old pkgs
  48. LsaState lsState; // State of the process, for relay to the dll
  49. LSA_TUNING_PARAMETERS LsaTuningParameters ;
  50. BOOL ShutdownBegun ;
  51. //
  52. // Name of event which says that the LSA RPC server is ready
  53. //
  54. #define LSA_RPC_SERVER_ACTIVE L"\\BaseNamedObjects\\LSA_RPC_SERVER_ACTIVE"
  55. #if TRACK_MEM
  56. extern FILE * pMemoryFile;
  57. extern DWORD dwTotalHeap;
  58. extern DWORD dwHeapHW;
  59. #endif
  60. HANDLE hPrelimShutdownEvent;
  61. DWORD
  62. ShutdownWorker(
  63. PVOID Ignored
  64. )
  65. {
  66. NTSTATUS Status ;
  67. PLSAP_SECURITY_PACKAGE pAuxPackage;
  68. ULONG_PTR iPackage ;
  69. DWORD Tick ;
  70. DWORD TickMax ;
  71. //
  72. // Stop any new calls from getting through
  73. //
  74. ShutdownBegun = TRUE ;
  75. LsapShutdownInprocDll();
  76. if ( LsaTuningParameters.Options & TUNE_SRV_HIGH_PRIORITY )
  77. {
  78. TickMax = 100 ;
  79. }
  80. else
  81. {
  82. TickMax = 10 ;
  83. }
  84. pAuxPackage = SpmpIteratePackagesByRequest( NULL, SP_ORDINAL_SHUTDOWN );
  85. while (pAuxPackage)
  86. {
  87. iPackage = pAuxPackage->dwPackageID;
  88. pAuxPackage->fPackage |= SP_SHUTDOWN_PENDING | SP_SHUTDOWN ;
  89. DebugLog((DEB_TRACE, "Shutting down package %ws\n",
  90. pAuxPackage->Name.Buffer ));
  91. //
  92. // Spin wait for the calls in progress to complete
  93. //
  94. Tick = 0 ;
  95. while ( (pAuxPackage->CallsInProgress > 0) &&
  96. ( Tick < TickMax ) )
  97. {
  98. Sleep( 100 );
  99. Tick++ ;
  100. }
  101. if ( Tick == TickMax )
  102. {
  103. DebugLog(( DEB_ERROR, "Package %ws did not respond in %d seconds for shutdown\n",
  104. pAuxPackage->Name.Buffer,
  105. Tick / 10 ));
  106. pAuxPackage = SpmpIteratePackagesByRequest( pAuxPackage,
  107. SP_ORDINAL_SHUTDOWN );
  108. continue;
  109. }
  110. SetCurrentPackageId( iPackage );
  111. __try
  112. {
  113. Status = pAuxPackage->FunctionTable.Shutdown();
  114. }
  115. __except (EXCEPTION_EXECUTE_HANDLER)
  116. {
  117. Status = (NTSTATUS) GetExceptionCode();
  118. }
  119. pAuxPackage->fPackage &= ~SP_SHUTDOWN_PENDING ;
  120. pAuxPackage = SpmpIteratePackagesByRequest( pAuxPackage,
  121. SP_ORDINAL_SHUTDOWN );
  122. }
  123. SetCurrentPackageId( SPMGR_ID );
  124. SetEvent( hShutdownEvent );
  125. return 0;
  126. }
  127. //+-------------------------------------------------------------------------
  128. //
  129. // Function: ServerStop
  130. //
  131. // Synopsis: Stop the SPM. Clean shutdown
  132. //
  133. //--------------------------------------------------------------------------
  134. HRESULT
  135. ServerStop(void)
  136. {
  137. // First, see if we are already in the middle of a shutdown. The
  138. // hShutdownEvent handle will be non-null.
  139. if (hShutdownEvent)
  140. {
  141. return(0);
  142. }
  143. DebugLog((DEB_TRACE, "LSA shutdown:\n"));
  144. hShutdownEvent = SpmCreateEvent(NULL, TRUE, FALSE, L"\\SpmShutdownEvent");
  145. if (hPrelimShutdownEvent)
  146. {
  147. SetEvent(hPrelimShutdownEvent);
  148. }
  149. QueueUserWorkItem( ShutdownWorker, NULL, FALSE );
  150. return(S_OK);
  151. }
  152. #if DBG
  153. void
  154. SpmpThreadStartupEx(void)
  155. {
  156. PSpmExceptDbg pExcept;
  157. pExcept = (PSpmExceptDbg) LsapAllocateLsaHeap(sizeof(SpmExceptDbg));
  158. MarkPermanent(pExcept);
  159. TlsSetValue(dwExceptionInfo, pExcept);
  160. }
  161. void
  162. SpmpThreadExitEx(void)
  163. {
  164. PSpmExceptDbg pExcept;
  165. pExcept = (PSpmExceptDbg) TlsGetValue(dwExceptionInfo);
  166. if (pExcept)
  167. {
  168. UnmarkPermanent(pExcept);
  169. LsapFreeLsaHeap(pExcept);
  170. }
  171. }
  172. #endif // DBG
  173. //+-------------------------------------------------------------------------
  174. //
  175. // Function: SpControlHandler
  176. //
  177. // Synopsis: Console Control Function handler
  178. //
  179. // Effects: Handles system shutdown
  180. //
  181. // Arguments:
  182. //
  183. // Requires:
  184. //
  185. // Returns:
  186. //
  187. // Notes:
  188. //
  189. //--------------------------------------------------------------------------
  190. BOOL
  191. SpConsoleHandler(DWORD dwCtrlType)
  192. {
  193. SpmpThreadStartup();
  194. DebugLog((DEB_TRACE, "Entered SpConsoleHandler(%d)\n", dwCtrlType));
  195. switch (dwCtrlType)
  196. {
  197. case CTRL_C_EVENT:
  198. case CTRL_BREAK_EVENT:
  199. SpmpThreadExit();
  200. return(FALSE);
  201. break;
  202. case CTRL_CLOSE_EVENT:
  203. case CTRL_SHUTDOWN_EVENT:
  204. DebugLog((DEB_TRACE, "Shutdown event received\n"));
  205. LsapState.SystemShutdownPending = TRUE;
  206. (void) ServerStop();
  207. (void) WaitForSingleObject(hShutdownEvent, 10000L);
  208. DebugLog((DEB_TRACE, "Shutdown complete\n"));
  209. // Fall through to:
  210. default:
  211. SpmpThreadExit();
  212. return(FALSE);
  213. }
  214. }