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.

362 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: dmnstart.cxx
  7. //
  8. // Contents: A class for providing startup data to the CiDaemon.
  9. //
  10. // History: 12-11-96 srikants Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <frmutils.hxx>
  16. #include <sizeser.hxx>
  17. #include <memser.hxx>
  18. #include <memdeser.hxx>
  19. #include <dmnstart.hxx>
  20. #include <imprsnat.hxx>
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Member: CDaemonStartupData::CDaemonStartupData
  24. //
  25. // Synopsis: Constructor on the sending side
  26. //
  27. // Arguments: [fIndexingW3Svc] - Set to TRUE if W3Svc data is being
  28. // indexed.
  29. // [ipVirtualServer] - IP address of the virtual server.
  30. // [pwszCatDir] - Catalog directory
  31. // [pwszName] - Catalog name
  32. //
  33. // History: 12-11-96 srikants Created
  34. //
  35. //----------------------------------------------------------------------------
  36. CDaemonStartupData::CDaemonStartupData(
  37. WCHAR const * pwszCatDir,
  38. WCHAR const * pwszName )
  39. :_sigDaemonStartup(eSigDaemonStartup),
  40. _fValid(TRUE)
  41. {
  42. _xwszCatDir.Set( AllocHeapAndCopy( pwszCatDir ) );
  43. _xwszName.Set( AllocHeapAndCopy( pwszName ) );
  44. }
  45. //+---------------------------------------------------------------------------
  46. //
  47. // Member: CDaemonStartupData::CDaemonStartupData
  48. //
  49. // Synopsis: Constructor to be used on the receiving side.
  50. //
  51. // Arguments: [pbData] - Pointer to the data buffer.
  52. // [cbData] - Number of bytes in the data buffer.
  53. //
  54. // History: 12-11-96 srikants Created
  55. //
  56. //----------------------------------------------------------------------------
  57. CDaemonStartupData::CDaemonStartupData( BYTE const * pbData, ULONG cbData )
  58. :_fValid(FALSE)
  59. {
  60. // Copy the buffer to guarantee alignment
  61. XArray<BYTE> xByte(cbData);
  62. RtlCopyMemory( xByte.GetPointer(), pbData, cbData );
  63. CMemDeSerStream stm( xByte.GetPointer(), cbData );
  64. _DeSerialize( stm );
  65. }
  66. //+---------------------------------------------------------------------------
  67. //
  68. // Member: CDaemonStartupData::_Serialize
  69. //
  70. // Synopsis: Serializes the data into the provided serializer
  71. //
  72. // Arguments: [stm] - The stream to serailize into.
  73. //
  74. // History: 12-11-96 srikants Created
  75. //
  76. //----------------------------------------------------------------------------
  77. void CDaemonStartupData::_Serialize( PSerStream & stm ) const
  78. {
  79. PutWString( stm, GetCatDir() );
  80. PutWString( stm, GetName() );
  81. ULARGE_INTEGER * pLi = (ULARGE_INTEGER *) &_sigDaemonStartup;
  82. stm.PutULong( pLi->LowPart );
  83. stm.PutULong( pLi->HighPart );
  84. }
  85. //+---------------------------------------------------------------------------
  86. //
  87. // Member: CDaemonStartupData::_DeSerialize
  88. //
  89. // Synopsis: Deserializes the data from the given de-serializer
  90. //
  91. // Arguments: [stm] - The stream to deserialize from.
  92. //
  93. // History: 12-11-96 srikants Created
  94. //
  95. //----------------------------------------------------------------------------
  96. void CDaemonStartupData::_DeSerialize( PDeSerStream & stm )
  97. {
  98. _xwszCatDir.Set( AllocHeapAndGetWString( stm ) );
  99. _xwszName.Set( AllocHeapAndGetWString( stm ) );
  100. ULARGE_INTEGER * pLi = (ULARGE_INTEGER *) &_sigDaemonStartup;
  101. pLi->LowPart = stm.GetULong();
  102. pLi->HighPart = stm.GetULong();
  103. _fValid = eSigDaemonStartup == _sigDaemonStartup;
  104. }
  105. //+---------------------------------------------------------------------------
  106. //
  107. // Member: CDaemonStartupData::Serialize
  108. //
  109. // Synopsis: Serializes the data into a buffer and returns the pointer
  110. // to the buffer. The memory is allocated using HEAP.
  111. //
  112. // Arguments: [cb] - on output, will have the number of bytes in the
  113. // serialized buffer.
  114. //
  115. // Returns: Pointer to a memory buffer. The caller owns it.
  116. //
  117. // History: 12-11-96 srikants Created
  118. //
  119. //----------------------------------------------------------------------------
  120. BYTE * CDaemonStartupData::Serialize( ULONG & cb ) const
  121. {
  122. cb = 0;
  123. Win4Assert( _fValid );
  124. //
  125. // First determine the size of the buffer needed.
  126. //
  127. CSizeSerStream sizeSer;
  128. _Serialize( sizeSer );
  129. cb = sizeSer.Size();
  130. XArray<BYTE> xBuffer(cb);
  131. CMemSerStream memSer( xBuffer.GetPointer(), cb );
  132. _Serialize( memSer );
  133. return xBuffer.Acquire();
  134. }
  135. //+---------------------------------------------------------------------------
  136. //
  137. // Member: CCiRegistryEvent::DoIt
  138. //
  139. // Synopsis: Refreshes the CI registry values.
  140. //
  141. // History: 12-19-96 srikants Created
  142. //
  143. //----------------------------------------------------------------------------
  144. void CCiRegistryEvent::DoIt(ICiAdminParams * pICiAdminParams)
  145. {
  146. ciDebugOut(( DEB_ITRACE, "CiDaemon::Processing CI registry change\n" ));
  147. _regParams.Refresh(pICiAdminParams);
  148. //
  149. // It's ok for the QI to fail. Don't always have a language cache.
  150. //
  151. XInterface<ICiAdmin> xICiAdmin;
  152. SCODE sc = pICiAdminParams->QueryInterface( IID_ICiAdmin, xICiAdmin.GetQIPointer() );
  153. Win4Assert( SUCCEEDED(sc) );
  154. if ( SUCCEEDED(sc) )
  155. xICiAdmin->InvalidateLangResources();
  156. //
  157. // Re-enable the notifications.
  158. //
  159. Reset();
  160. } //DoIt()
  161. //+---------------------------------------------------------------------------
  162. //
  163. // Member: CClientDaemonWorker::CClientDaemonWorker
  164. //
  165. // Synopsis: Constructor of the CClientDaemonWorker class.
  166. //
  167. // Arguments: [startupData] - start data for the daemon worker
  168. // [nameGen] - name generator for inter-proc events
  169. // [pICiAdminParams] - registry/admin parameters
  170. //
  171. // History: 12-19-96 srikants Created
  172. //
  173. //----------------------------------------------------------------------------
  174. CClientDaemonWorker::CClientDaemonWorker( CDaemonStartupData & startupData,
  175. CSharedNameGen & nameGen,
  176. ICiAdminParams * pICiAdminParams )
  177. : _cHandles(cTotal),
  178. _fShutdown(FALSE),
  179. _perfMon( startupData.GetName() ? startupData.GetName() : startupData.GetCatDir() ),
  180. _regParams( startupData.GetName() ),
  181. _tokenCache( startupData.GetName() ),
  182. _ciRegChange( _regParams ),
  183. _evtRescanTC( 0, nameGen.GetRescanTCEventName() ),
  184. #pragma warning( disable : 4355 ) // this used in base initialization
  185. _controlThread( WorkerThread, this, TRUE ) // create suspended
  186. #pragma warning( default : 4355 )
  187. {
  188. pICiAdminParams->AddRef();
  189. _xICiAdminParams.Set(pICiAdminParams);
  190. _regParams.Refresh( pICiAdminParams );
  191. BOOL fIndexW3Roots = _regParams.IsIndexingW3Roots();
  192. BOOL fIndexNNTPRoots = _regParams.IsIndexingNNTPRoots();
  193. BOOL fIndexIMAPRoots = _regParams.IsIndexingIMAPRoots();
  194. ULONG W3SvcInstance = _regParams.GetW3SvcInstance();
  195. ULONG NNTPSvcInstance = _regParams.GetNNTPSvcInstance();
  196. ULONG IMAPSvcInstance = _regParams.GetIMAPSvcInstance();
  197. _tokenCache.Initialize( CI_DAEMON_NAME,
  198. fIndexW3Roots,
  199. fIndexNNTPRoots,
  200. fIndexIMAPRoots,
  201. W3SvcInstance,
  202. NNTPSvcInstance,
  203. IMAPSvcInstance );
  204. RtlZeroMemory( _aWait, sizeof(_aWait) );
  205. _aWait[iThreadControl] = _evtControl.GetHandle();
  206. _evtControl.Reset();
  207. _aWait[iCiRegistry] = _ciRegChange.GetEventHandle();
  208. _aWait[iRescanTC] = _evtRescanTC.GetHandle();
  209. _controlThread.Resume();
  210. } //CClientDaemonWorker
  211. //+---------------------------------------------------------------------------
  212. //
  213. // Member: CClientDaemonWorker::WorkerThread
  214. //
  215. // Synopsis: WIN32 Thread starting entry point.
  216. //
  217. // Arguments: [self] -
  218. //
  219. // History: 12-19-96 srikants Created
  220. //
  221. //----------------------------------------------------------------------------
  222. DWORD CClientDaemonWorker::WorkerThread( void * self )
  223. {
  224. ((CClientDaemonWorker *) self)->_DoWork();
  225. ciDebugOut(( DEB_ITRACE, "CClientDaemonWorker::Terminating thread\n" ));
  226. return 0;
  227. }
  228. //+---------------------------------------------------------------------------
  229. //
  230. // Member: CClientDaemonWorker::_DoWork
  231. //
  232. // Synopsis: The main loop where the thread waits and tracks the registry
  233. //
  234. // History: 12-19-96 srikants Created
  235. //
  236. //----------------------------------------------------------------------------
  237. void CClientDaemonWorker::_DoWork()
  238. {
  239. ciDebugOut(( DEB_ITRACE, "CClientDaemonWorker::_DoWork \n" ));
  240. do
  241. {
  242. DWORD status = WaitForMultipleObjectsEx( _cHandles, // num handles
  243. _aWait, // array of handles
  244. FALSE, // wake up if any is set
  245. 10000, // Timeout
  246. FALSE ); // Not Alertable
  247. TRY
  248. {
  249. if ( WAIT_FAILED == status )
  250. {
  251. ciDebugOut(( DEB_ERROR, "DLDaemon - WaitFailed. Error 0x%X\n",
  252. GetLastError() ));
  253. _fShutdown = TRUE;
  254. }
  255. else if ( WAIT_TIMEOUT == status )
  256. {
  257. // See if a filter is out of control allocating memory. We
  258. // may be using gobs of RAM, but we only care about page
  259. // file usage.
  260. VM_COUNTERS vmInfo;
  261. NTSTATUS s = NtQueryInformationProcess( GetCurrentProcess(),
  262. ProcessVmCounters,
  263. &vmInfo,
  264. sizeof vmInfo,
  265. 0 );
  266. SIZE_T cbUsageInK = vmInfo.PagefileUsage / 1024;
  267. SIZE_T cbMaxInK = _regParams.GetMaxDaemonVmUse();
  268. if ( NT_SUCCESS( s ) && ( cbUsageInK > cbMaxInK ) )
  269. TerminateProcess( GetCurrentProcess(), E_OUTOFMEMORY );
  270. }
  271. else
  272. {
  273. DWORD iWake = status - WAIT_OBJECT_0;
  274. if ( iThreadControl == iWake )
  275. {
  276. ciDebugOut(( DEB_ITRACE, "DaemonWorkerThread - Control Event\n" ));
  277. _evtControl.Reset();
  278. }
  279. else if ( iCiRegistry == iWake )
  280. {
  281. ResetEvent( _aWait[iCiRegistry] );
  282. _ciRegChange.DoIt( _xICiAdminParams.GetPointer() );
  283. }
  284. else
  285. {
  286. ciDebugOut(( DEB_ITRACE, "daemon rescanning tokenCache\n" ));
  287. Win4Assert( iRescanTC == iWake );
  288. ResetEvent( _aWait[iRescanTC] );
  289. _tokenCache.ReInitializeIISScopes();
  290. _tokenCache.ReInitializeScopes();
  291. }
  292. }
  293. }
  294. CATCH( CException,e )
  295. {
  296. ciDebugOut(( DEB_ERROR, "Error 0x%X caught in daemon worker thread\n",
  297. e.GetErrorCode() ));
  298. }
  299. END_CATCH
  300. }
  301. while ( !_fShutdown );
  302. } //_DoWork