Leaked source code of windows server 2003
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.

907 lines
26 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. cleanup.cpp
  5. Abstract:
  6. This file implements the BITS server extensions cleanup worker
  7. --*/
  8. #include "precomp.h"
  9. const UINT64 NanoSec100PerSec = 10000000; //no of 100 nanosecs per second
  10. inline UINT64 FILETIMEToUINT64( const FILETIME & FileTime )
  11. {
  12. ULARGE_INTEGER LargeInteger;
  13. LargeInteger.HighPart = FileTime.dwHighDateTime;
  14. LargeInteger.LowPart = FileTime.dwLowDateTime;
  15. return LargeInteger.QuadPart;
  16. };
  17. class PollKillError
  18. {
  19. public:
  20. HRESULT m_Hr;
  21. PollKillError( HRESULT Hr ) :
  22. m_Hr( Hr )
  23. {
  24. }
  25. };
  26. class CleanupWorker
  27. {
  28. public:
  29. CleanupWorker( BOOL DeleteAll, HWND hwnd, const WCHAR* Path,
  30. const WCHAR *WorkItemName, const WCHAR *GuidString );
  31. ~CleanupWorker();
  32. void DoIt();
  33. private:
  34. BOOL m_DeleteAll;
  35. HWND m_hwnd;
  36. const WCHAR * m_Path;
  37. const WCHAR * m_WorkItemName;
  38. const WCHAR * m_GuidString;
  39. const WCHAR * m_ADSIPath;
  40. IADs * m_VDir;
  41. BSTR m_VDirPath;
  42. BSTR m_SessionDirectory;
  43. BSTR m_UNCUsername;
  44. BSTR m_UNCPassword;
  45. UINT64 m_CleanupThreshold;
  46. StringHandle m_SessionDirPath;
  47. StringHandle m_RequestsDirPath;
  48. StringHandle m_RepliesDirPath;
  49. VARIANT m_vt;
  50. HANDLE m_UserToken;
  51. HANDLE m_EventLog;
  52. BSTR m_BITSCleanupWorkItemKeyBSTR;
  53. BSTR m_BITSUploadEnabledBSTR;
  54. BSTR m_BITSSessionTimeoutBSTR;
  55. BSTR m_PathBSTR;
  56. BSTR m_BITSSessionDirectoryBSTR;
  57. BSTR m_UNCUserNameBSTR;
  58. BSTR m_UNCPasswordBSTR;
  59. void PollKill();
  60. void DeleteDirectoryAndFiles( StringHandle Directory );
  61. bool DirectoryExists( StringHandle Directory );
  62. UINT64 LastDirectoryTime( StringHandle Directory );
  63. void RemoveSession( StringHandle SessionGuid );
  64. void RemoveSessions( bool SecondPass );
  65. void RemoveConnectionsFromTree(
  66. const WCHAR * DirectoryPath,
  67. bool IsConnectionDirectory,
  68. const WCHAR * FileSystemPath = NULL );
  69. void RemoveConnection( const WCHAR * ConnectionDirectory, const WCHAR *FilesystemPath,
  70. const WCHAR * SessionGuid );
  71. void LogDeletedJob( const WCHAR *SessionGuid );
  72. void LogUnableToRemoveSession( const WCHAR *SessionGuid, HRESULT Hr );
  73. void LogUnexpectedError( HRESULT Hr );
  74. void LogUnableToScanDirectory( const WCHAR *Path, HRESULT Hr );
  75. };
  76. void
  77. BITSSetCurrentThreadToken(
  78. HANDLE hToken )
  79. {
  80. if ( !SetThreadToken( NULL, hToken ) )
  81. {
  82. for( unsigned int i = 0; i < 100; i ++ )
  83. {
  84. Sleep( 10 );
  85. if ( SetThreadToken( NULL, hToken ) )
  86. return;
  87. }
  88. TerminateProcess( NULL, GetLastError() );
  89. }
  90. }
  91. CleanupWorker::CleanupWorker(
  92. BOOL DeleteAll,
  93. HWND hwnd,
  94. const WCHAR* Path,
  95. const WCHAR* WorkItemName,
  96. const WCHAR* GuidString ) :
  97. m_DeleteAll( DeleteAll ),
  98. m_hwnd( hwnd ),
  99. m_Path( Path ),
  100. m_WorkItemName( WorkItemName ),
  101. m_GuidString( GuidString ),
  102. m_ADSIPath( NULL ),
  103. m_VDir( NULL ),
  104. m_VDirPath( NULL ),
  105. m_SessionDirectory( NULL ),
  106. m_CleanupThreshold( 0 ),
  107. m_UNCUsername( NULL ),
  108. m_UNCPassword( NULL ),
  109. m_UserToken( NULL ),
  110. m_EventLog( NULL ),
  111. m_BITSCleanupWorkItemKeyBSTR( NULL ),
  112. m_BITSUploadEnabledBSTR( NULL ),
  113. m_BITSSessionTimeoutBSTR( NULL ),
  114. m_PathBSTR( NULL ),
  115. m_BITSSessionDirectoryBSTR( NULL ),
  116. m_UNCUserNameBSTR( NULL ),
  117. m_UNCPasswordBSTR( NULL )
  118. {
  119. VariantInit( &m_vt );
  120. m_BITSCleanupWorkItemKeyBSTR = SysAllocString( L"BITSCleanupWorkItemKey" );
  121. m_BITSUploadEnabledBSTR = SysAllocString( L"BITSUploadEnabled" );
  122. m_BITSSessionTimeoutBSTR = SysAllocString( L"BITSSessionTimeout" );
  123. m_PathBSTR = SysAllocString( L"Path" );
  124. m_BITSSessionDirectoryBSTR = SysAllocString( L"BITSSessionDirectory" );
  125. m_UNCUserNameBSTR = SysAllocString( L"UNCUserName" );
  126. m_UNCPasswordBSTR = SysAllocString( L"UNCPassword" );
  127. if ( !m_BITSCleanupWorkItemKeyBSTR || !m_BITSUploadEnabledBSTR || !m_BITSSessionTimeoutBSTR ||
  128. !m_PathBSTR || !m_BITSSessionDirectoryBSTR || !m_UNCUserNameBSTR || !m_UNCPasswordBSTR )
  129. {
  130. SysFreeString( m_BITSCleanupWorkItemKeyBSTR );
  131. SysFreeString( m_BITSUploadEnabledBSTR );
  132. SysFreeString( m_BITSSessionTimeoutBSTR );
  133. SysFreeString( m_PathBSTR );
  134. SysFreeString( m_BITSSessionDirectoryBSTR );
  135. SysFreeString( m_UNCUserNameBSTR );
  136. SysFreeString( m_UNCPasswordBSTR );
  137. throw ComError( E_OUTOFMEMORY );
  138. }
  139. m_EventLog =
  140. RegisterEventSource(
  141. NULL, // server name
  142. EVENT_LOG_SOURCE_NAME // source name
  143. );
  144. if ( !m_EventLog )
  145. throw ComError( HRESULT_FROM_WIN32( GetLastError() ) );
  146. }
  147. CleanupWorker::~CleanupWorker()
  148. {
  149. if ( m_EventLog )
  150. DeregisterEventSource( m_EventLog );
  151. if ( m_UserToken )
  152. {
  153. BITSSetCurrentThreadToken( NULL );
  154. CloseHandle( m_UserToken );
  155. }
  156. delete m_ADSIPath;
  157. SysFreeString( m_VDirPath );
  158. SysFreeString( m_SessionDirectory );
  159. SysFreeString( m_UNCUsername );
  160. SysFreeString( m_UNCPassword );
  161. // Free hardcoded strings
  162. SysFreeString( m_BITSCleanupWorkItemKeyBSTR );
  163. SysFreeString( m_BITSUploadEnabledBSTR );
  164. SysFreeString( m_BITSSessionTimeoutBSTR );
  165. SysFreeString( m_PathBSTR );
  166. SysFreeString( m_BITSSessionDirectoryBSTR );
  167. SysFreeString( m_UNCUserNameBSTR );
  168. SysFreeString( m_UNCPasswordBSTR );
  169. }
  170. //---------------------------------------------------------------------------
  171. // CleanupWorker::DeleteDirectoryAndFiles()
  172. //
  173. // This method deletes the specified directory and the files it contains. If
  174. // the specified directory contains subdirectories, then they will not be
  175. // deleted (and the delete of the main directory will fail).
  176. //
  177. // If the directory is a reparse point, then it will do nothing. If the
  178. // specified directory contains reparse points then they will be ignored as
  179. // well.
  180. //---------------------------------------------------------------------------
  181. void
  182. CleanupWorker::DeleteDirectoryAndFiles( StringHandle Directory )
  183. {
  184. HANDLE FindHandle = INVALID_HANDLE_VALUE;
  185. WIN32_FILE_ATTRIBUTE_DATA FileAttributes;
  186. try
  187. {
  188. // Check the specified directory. If its not actually a directory, or
  189. // it's a reparse point then don't process it.
  190. if (!GetFileAttributesEx( Directory,
  191. GetFileExInfoStandard,
  192. &FileAttributes))
  193. {
  194. throw ComError(HRESULT_FROM_WIN32(GetLastError()));
  195. }
  196. if ( (FileAttributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
  197. || !(FileAttributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
  198. {
  199. return;
  200. }
  201. StringHandle SearchPath = Directory + StringHandle(L"\\*");
  202. WIN32_FIND_DATA FindData;
  203. FindHandle = FindFirstFile( SearchPath,
  204. &FindData );
  205. if ( INVALID_HANDLE_VALUE == FindHandle )
  206. {
  207. throw ComError( HRESULT_FROM_WIN32( GetLastError() ) );
  208. }
  209. do
  210. {
  211. if ( (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  212. || (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) )
  213. {
  214. continue;
  215. }
  216. StringHandle FileName = StringHandle( Directory ) + StringHandle( L"\\" ) +
  217. StringHandle( FindData.cFileName );
  218. DeleteFile( FileName );
  219. }
  220. while ( FindNextFile( FindHandle, &FindData ) );
  221. FindClose( FindHandle );
  222. FindHandle = INVALID_HANDLE_VALUE;
  223. if ( !RemoveDirectory( Directory ) )
  224. {
  225. throw ComError( HRESULT_FROM_WIN32( GetLastError() ) );
  226. }
  227. }
  228. catch( ComError Error )
  229. {
  230. if ( INVALID_HANDLE_VALUE != FindHandle )
  231. {
  232. FindClose( FindHandle );
  233. }
  234. throw;
  235. }
  236. if ( INVALID_HANDLE_VALUE != FindHandle )
  237. {
  238. FindClose( FindHandle );
  239. }
  240. }
  241. bool
  242. CleanupWorker::DirectoryExists(
  243. StringHandle Directory )
  244. {
  245. DWORD dwAttributes =
  246. GetFileAttributes( Directory );
  247. if ( INVALID_FILE_ATTRIBUTES == dwAttributes )
  248. {
  249. if ( GetLastError() == ERROR_PATH_NOT_FOUND ||
  250. GetLastError() == ERROR_FILE_NOT_FOUND )
  251. return false;
  252. throw ComError( HRESULT_FROM_WIN32( GetLastError() ) );
  253. }
  254. return true;
  255. }
  256. //-------------------------------------------------------------------------
  257. // CleanupWorker::LastDirectoryTime()
  258. //
  259. // Walk a directory and find the most recent "Last Write Time" for it or
  260. // and of its contents.
  261. //
  262. // Note: Ignore reparse points.
  263. //
  264. //-------------------------------------------------------------------------
  265. UINT64
  266. CleanupWorker::LastDirectoryTime(
  267. StringHandle Directory )
  268. {
  269. UINT64 LatestTime = 0;
  270. HANDLE FindHandle = INVALID_HANDLE_VALUE;
  271. WIN32_FILE_ATTRIBUTE_DATA FileAttributesData;
  272. if (!GetFileAttributesEx( Directory,
  273. GetFileExInfoStandard,
  274. &FileAttributesData ) )
  275. {
  276. throw ComError( HRESULT_FROM_WIN32( GetLastError() ) );
  277. }
  278. LatestTime = FILETIMEToUINT64( FileAttributesData.ftCreationTime );
  279. StringHandle SearchPath = Directory + StringHandle(L"\\*");
  280. WIN32_FIND_DATA FindData;
  281. FindHandle =
  282. FindFirstFile(
  283. SearchPath,
  284. &FindData
  285. );
  286. if ( INVALID_HANDLE_VALUE == FindHandle )
  287. throw ComError( HRESULT_FROM_WIN32( GetLastError() ) );
  288. try
  289. {
  290. do
  291. {
  292. if ( (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  293. || (FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) )
  294. {
  295. continue;
  296. }
  297. UINT64 CreationTime = FILETIMEToUINT64( FindData.ftCreationTime );
  298. UINT64 LastWriteTime = FILETIMEToUINT64( FindData.ftLastWriteTime );
  299. LatestTime = max( LatestTime, max( CreationTime, LastWriteTime ) );
  300. }
  301. while ( FindNextFile( FindHandle, &FindData ) );
  302. FindClose( FindHandle );
  303. FindHandle = INVALID_HANDLE_VALUE;
  304. }
  305. catch( ComError Error )
  306. {
  307. if ( INVALID_HANDLE_VALUE == FindHandle )
  308. FindClose( FindHandle );
  309. throw;
  310. }
  311. return LatestTime;
  312. }
  313. void
  314. CleanupWorker::RemoveSession(
  315. StringHandle SessionGuid )
  316. {
  317. StringHandle RequestDir = m_RequestsDirPath + StringHandle("\\") + SessionGuid;
  318. StringHandle ReplyDir = m_RepliesDirPath + StringHandle("\\") + SessionGuid;
  319. bool RequestExists = DirectoryExists( RequestDir );
  320. bool ReplyExists = DirectoryExists( ReplyDir );
  321. UINT64 LastTime = 0;
  322. if ( RequestExists )
  323. {
  324. try
  325. {
  326. LastTime = LastDirectoryTime( RequestDir );
  327. }
  328. catch( ComError Error )
  329. {
  330. LogUnableToScanDirectory( RequestDir, Error.m_Hr );
  331. return;
  332. }
  333. }
  334. if ( ReplyExists )
  335. {
  336. try
  337. {
  338. LastTime = max( LastTime, LastDirectoryTime( ReplyDir ) );
  339. }
  340. catch( ComError Error )
  341. {
  342. LogUnableToScanDirectory( ReplyDir, Error.m_Hr );
  343. return;
  344. }
  345. }
  346. FILETIME ftCurrentTime;
  347. GetSystemTimeAsFileTime( &ftCurrentTime );
  348. UINT64 CurrentTime = FILETIMEToUINT64( ftCurrentTime );
  349. if ( ( 0xFFFFFFFF - LastTime > m_CleanupThreshold ) &&
  350. ( LastTime + m_CleanupThreshold < CurrentTime ) )
  351. {
  352. try
  353. {
  354. if ( RequestExists )
  355. {
  356. DeleteDirectoryAndFiles( RequestDir );
  357. }
  358. if ( ReplyExists )
  359. {
  360. DeleteDirectoryAndFiles( ReplyDir );
  361. }
  362. LogDeletedJob( SessionGuid );
  363. }
  364. catch( ComError Error )
  365. {
  366. LogUnableToRemoveSession( SessionGuid, Error.m_Hr );
  367. }
  368. }
  369. }
  370. //--------------------------------------------------------------------------
  371. // CleanupWorker::RemoveSessions()
  372. //
  373. // Inspect the current "Replies directory" and "Requests directory" and
  374. // remove any BITS session directories that are older than the current
  375. // cleanup threshold.
  376. //
  377. // Arguments:
  378. //
  379. // SecondPass TRUE: Inspect the Replies Directory Path.
  380. // FALSE: Inspect the Requests Directory Path.
  381. //--------------------------------------------------------------------------
  382. void
  383. CleanupWorker::RemoveSessions( IN bool SecondPass )
  384. {
  385. StringHandle SearchDirectory = (SecondPass)? m_RepliesDirPath : m_RequestsDirPath;
  386. StringHandle SearchString = SearchDirectory + StringHandle( L"\\*" );
  387. HANDLE FindHandle = INVALID_HANDLE_VALUE;
  388. WIN32_FIND_DATA FindData;
  389. WIN32_FILE_ATTRIBUTE_DATA FileAttributes;
  390. try
  391. {
  392. if (!GetFileAttributesEx(SearchDirectory,
  393. GetFileExInfoStandard,
  394. &FileAttributes))
  395. {
  396. throw ComError(HRESULT_FROM_WIN32(GetLastError()));
  397. }
  398. if ( (FileAttributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
  399. || !(FileAttributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
  400. {
  401. return;
  402. }
  403. FindHandle = FindFirstFile( SearchString, &FindData );
  404. if ( INVALID_HANDLE_VALUE == FindHandle )
  405. {
  406. throw ComError(HRESULT_FROM_WIN32(GetLastError()));
  407. }
  408. do
  409. {
  410. PollKill();
  411. // If its not a directory then ignore it...
  412. if ( !(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
  413. {
  414. continue;
  415. }
  416. // If its a reparse point then ignore it.
  417. if ( FindData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT )
  418. {
  419. continue;
  420. }
  421. // If its this directory or the parent directory reference then
  422. // ignore it.
  423. if ( ( _wcsicmp( L".", FindData.cFileName ) == 0 )
  424. || ( _wcsicmp( L"..", FindData.cFileName ) == 0 ) )
  425. {
  426. continue;
  427. }
  428. // If the name isn't a GUID then ignore it.
  429. GUID Guid;
  430. if ( FAILED( IIDFromString( FindData.cFileName, &Guid ) ) )
  431. {
  432. continue;
  433. }
  434. try
  435. {
  436. RemoveSession( StringHandle( FindData.cFileName ) );
  437. }
  438. catch( ComError Error )
  439. {
  440. LogUnexpectedError( Error.m_Hr );
  441. }
  442. } while( FindNextFile( FindHandle, &FindData ) );
  443. FindClose( FindHandle );
  444. FindHandle = INVALID_HANDLE_VALUE;
  445. }
  446. catch( const ComError & )
  447. {
  448. if ( INVALID_HANDLE_VALUE != FindHandle )
  449. {
  450. FindClose( FindHandle );
  451. }
  452. throw;
  453. }
  454. catch( const PollKillError & )
  455. {
  456. if ( INVALID_HANDLE_VALUE != FindHandle )
  457. {
  458. FindClose( FindHandle );
  459. }
  460. }
  461. }
  462. void
  463. CleanupWorker::PollKill()
  464. {
  465. if ( m_hwnd )
  466. {
  467. MSG msg;
  468. while( PeekMessage(
  469. &msg,
  470. m_hwnd,
  471. 0,
  472. 0,
  473. PM_REMOVE ) )
  474. {
  475. if ( WM_QUIT == msg.message )
  476. throw PollKillError( (HRESULT)msg.wParam );
  477. TranslateMessage( &msg );
  478. DispatchMessage( &msg );
  479. }
  480. }
  481. }
  482. void
  483. CleanupWorker::DoIt()
  484. {
  485. try
  486. {
  487. m_ADSIPath = CSimplePropertyReader::ConvertObjectPathToADSI( m_Path );
  488. try
  489. {
  490. THROW_COMERROR( ADsGetObject( m_ADSIPath, __uuidof(*m_VDir), (void**)&m_VDir ) );
  491. if ( m_GuidString )
  492. {
  493. BSTR BSTRGuid = CSimplePropertyReader::GetADsStringProperty( m_VDir, m_BITSCleanupWorkItemKeyBSTR );
  494. int Result = wcscmp( (LPWSTR)BSTRGuid, m_GuidString );
  495. SysFreeString( BSTRGuid );
  496. if ( Result != 0 )
  497. throw ComError( E_ADS_UNKNOWN_OBJECT );
  498. }
  499. }
  500. catch( ComError Error )
  501. {
  502. if ( ( Error.m_Hr == E_ADS_UNKNOWN_OBJECT ) ||
  503. ( Error.m_Hr == HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ) ) ||
  504. ( Error.m_Hr == E_ADS_PROPERTY_NOT_FOUND ) )
  505. {
  506. // Somehow the virtual directory was deleted, but the
  507. // task scheduler work item wasn't. Try to delete it now.
  508. if ( m_WorkItemName )
  509. {
  510. SmartITaskSchedulerPointer TaskScheduler;
  511. try
  512. {
  513. ConnectToTaskScheduler( NULL, &TaskScheduler );
  514. TaskScheduler->Delete( m_WorkItemName );
  515. }
  516. catch( ComError Error )
  517. {
  518. }
  519. }
  520. }
  521. // Nothing more to do after deleting the task.
  522. return;
  523. }
  524. THROW_COMERROR( m_VDir->Get( m_BITSUploadEnabledBSTR, &m_vt ) );
  525. THROW_COMERROR( VariantChangeType( &m_vt, &m_vt, 0, VT_BOOL ) );
  526. if ( !m_vt.boolVal ) // Uploads arn't enabled on this directory
  527. return;
  528. if ( !m_DeleteAll )
  529. {
  530. THROW_COMERROR( m_VDir->Get( m_BITSSessionTimeoutBSTR, &m_vt ) );
  531. THROW_COMERROR( VariantChangeType( &m_vt, &m_vt, 0, VT_BSTR ) );
  532. if ( L'-' == *m_vt.bstrVal )
  533. return; // do not run cleanup in this directory since cleanup has been disabled
  534. UINT64 CleanupSeconds;
  535. if ( 1 != swscanf( (WCHAR*)m_vt.bstrVal, L"%I64u", &CleanupSeconds ) )
  536. return;
  537. if ( CleanupSeconds > ( 0xFFFFFFFFFFFFFFFF / NanoSec100PerSec ) )
  538. m_CleanupThreshold = 0xFFFFFFFFFFFFFFFF; // overflow case
  539. else
  540. m_CleanupThreshold = CleanupSeconds * NanoSec100PerSec;
  541. }
  542. else
  543. m_CleanupThreshold = 0;
  544. m_VDirPath = CSimplePropertyReader::GetADsStringProperty( m_VDir, m_PathBSTR );
  545. m_SessionDirectory = CSimplePropertyReader::GetADsStringProperty( m_VDir, m_BITSSessionDirectoryBSTR );
  546. m_UNCUsername = CSimplePropertyReader::GetADsStringProperty( m_VDir, m_UNCUserNameBSTR );
  547. m_UNCPassword = CSimplePropertyReader::GetADsStringProperty( m_VDir, m_UNCPasswordBSTR );
  548. m_SessionDirPath = StringHandle( (WCHAR*)m_VDirPath) + StringHandle(L"\\") +
  549. StringHandle( (WCHAR*)m_SessionDirectory );
  550. m_RequestsDirPath = m_SessionDirPath + StringHandle(L"\\") + StringHandle( REQUESTS_DIR_NAMEW );
  551. m_RepliesDirPath = m_SessionDirPath + StringHandle(L"\\") + StringHandle( REPLIES_DIR_NAMEW );
  552. if (CAccessRemoteVDir::IsUNCPath(m_VDirPath))
  553. {
  554. CAccessRemoteVDir::ImpersonateUNCUser(m_VDirPath, m_UNCUsername, m_UNCPassword, &m_UserToken);
  555. }
  556. RemoveSessions( false );
  557. RemoveSessions( true );
  558. }
  559. catch( PollKillError Error )
  560. {
  561. throw;
  562. }
  563. catch( ComError Error )
  564. {
  565. LogUnexpectedError( Error.m_Hr );
  566. throw;
  567. }
  568. }
  569. void
  570. CleanupWorker::LogDeletedJob(
  571. const WCHAR *SessionGuid )
  572. {
  573. if ( m_EventLog )
  574. {
  575. const WCHAR *Strings[] = { (const WCHAR*)m_SessionDirPath, SessionGuid };
  576. ReportEvent(
  577. m_EventLog, // handle to event log
  578. EVENTLOG_INFORMATION_TYPE, // event type
  579. BITSRV_EVENTLOG_CLEANUP_CATAGORY, // event category
  580. BITSSRV_EVENTLOG_DELETED_SESSION, // event identifier
  581. NULL, // user security identifier
  582. 2, // number of strings to merge
  583. 0, // size of binary data
  584. Strings, // array of strings to merge
  585. NULL // binary data buffer
  586. );
  587. }
  588. }
  589. void
  590. CleanupWorker::LogUnableToRemoveSession(
  591. const WCHAR *SessionGuid,
  592. HRESULT Hr )
  593. {
  594. if ( m_EventLog )
  595. {
  596. const WCHAR *Strings[] = { (const WCHAR*)m_SessionDirPath, SessionGuid };
  597. ReportEvent(
  598. m_EventLog, // handle to event log
  599. EVENTLOG_ERROR_TYPE, // event type
  600. BITSRV_EVENTLOG_CLEANUP_CATAGORY, // event category
  601. BITSSRV_EVENTLOG_CANT_REMOVE_SESSION, // event identifier
  602. NULL, // user security identifier
  603. 2, // number of strings to merge
  604. sizeof(Hr), // size of binary data
  605. Strings, // array of strings to merge
  606. &Hr // binary data buffer
  607. );
  608. }
  609. }
  610. void
  611. CleanupWorker::
  612. LogUnableToScanDirectory(
  613. const WCHAR *Path,
  614. HRESULT Hr )
  615. {
  616. if ( m_EventLog )
  617. {
  618. const WCHAR *Strings[] = { Path };
  619. ReportEvent(
  620. m_EventLog, // handle to event log
  621. EVENTLOG_ERROR_TYPE, // event type
  622. BITSRV_EVENTLOG_CLEANUP_CATAGORY, // event category
  623. BITSSRV_EVENTLOG_CANT_SCAN_DIRECTORY, // event identifier
  624. NULL, // user security identifier
  625. 1, // number of strings to merge
  626. sizeof(Hr), // size of binary data
  627. Strings, // array of strings to merge
  628. &Hr // binary data buffer
  629. );
  630. }
  631. }
  632. void
  633. CleanupWorker::LogUnexpectedError(
  634. HRESULT Hr )
  635. {
  636. if ( m_EventLog )
  637. {
  638. const WCHAR *Strings[] = { m_Path };
  639. ReportEvent(
  640. m_EventLog, // handle to event log
  641. EVENTLOG_ERROR_TYPE, // event type
  642. BITSRV_EVENTLOG_CLEANUP_CATAGORY, // event category
  643. BITSSRV_EVENTLOG_UNEXPECTED_ERROR, // event identifier
  644. NULL, // user security identifier
  645. 1, // number of strings to merge
  646. sizeof( Hr ), // size of binary data
  647. Strings, // array of strings to merge
  648. &Hr // binary data buffer
  649. );
  650. }
  651. }
  652. void Cleanup_RunDLLW(HWND hwndStub, HINSTANCE hAppInstance, LPWSTR lpszCmdLine, int nCmdShow )
  653. {
  654. int NumArgs;
  655. LPWSTR * CommandArgs =
  656. CommandLineToArgvW(
  657. lpszCmdLine,
  658. &NumArgs );
  659. if ( !CommandArgs )
  660. return;
  661. if ( FAILED( CoInitializeEx( NULL, COINIT_MULTITHREADED ) ) )
  662. return;
  663. if ( NumArgs != 2 && NumArgs != 3 )
  664. return;
  665. LPWSTR Path = CommandArgs[0];
  666. LPWSTR WorkItemName = CommandArgs[1];
  667. LPWSTR GuidString = NumArgs == 3 ? CommandArgs[2] : NULL;
  668. try
  669. {
  670. CleanupWorker Worker( FALSE, hwndStub, Path, WorkItemName, GuidString );
  671. Worker.DoIt();
  672. }
  673. catch( PollKillError PollAbort )
  674. {
  675. }
  676. catch( ComError Error )
  677. {
  678. }
  679. CoUninitialize( );
  680. GlobalFree( CommandArgs );
  681. }
  682. void CleanupForRemoval( LPCWSTR Path )
  683. {
  684. HANDLE hToken = NULL;
  685. try
  686. {
  687. if (!OpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hToken ) )
  688. {
  689. if ( GetLastError() != ERROR_NO_TOKEN )
  690. return;
  691. }
  692. CleanupWorker Worker( TRUE, NULL, Path, NULL, NULL );
  693. Worker.DoIt();
  694. }
  695. catch( ComError Error )
  696. {
  697. }
  698. catch( PollKillError PollAbort )
  699. {
  700. }
  701. if ( hToken )
  702. BITSSetCurrentThreadToken( hToken );
  703. }