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.

955 lines
28 KiB

  1. // FrcOwn.cpp : Implementation of CForceOwnership
  2. #include "pch.cxx"
  3. #pragma hdrstop
  4. #define TRKDATA_ALLOCATE
  5. #include <trklib.hxx>
  6. #include <trksvr.hxx>
  7. #undef TRKDATA_ALLOCATE
  8. #include "stdafx.h"
  9. #include "ITrkAdmn.h"
  10. #include "FrcOwn.h"
  11. STDMETHODIMP
  12. CTrkForceOwnership::Volumes(BSTR bstrUncPath, long scope )
  13. {
  14. HRESULT hr = S_OK;
  15. HANDLE hFile = NULL;
  16. CVolumeId volid;
  17. CMachineId mcid( (LPWSTR) bstrUncPath );
  18. CRpcClientBinding rc;
  19. CPCVolumes cpcVolumes( &mcid, &_voltab, &_refreshSequenceStorage );
  20. TRpcPipeControl< TRK_VOLUME_TRACKING_INFORMATION_PIPE,
  21. TRK_VOLUME_TRACKING_INFORMATION,
  22. CPCVolumes
  23. > cpipeVolumes( &cpcVolumes );
  24. rc.Initialize( mcid );
  25. if( TRKINFOSCOPE_VOLUME == scope )
  26. {
  27. NTSTATUS status;
  28. IO_STATUS_BLOCK Iosb;
  29. FILE_FS_OBJECTID_INFORMATION fsobOID;
  30. status = TrkCreateFile( bstrUncPath, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
  31. FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
  32. FILE_OPEN_NO_RECALL, NULL, &hFile );
  33. if( !NT_SUCCESS(status) )
  34. {
  35. hFile = NULL;
  36. TrkLog((TRKDBG_ERROR, TEXT("Couldn't open volume %s"), bstrUncPath ));
  37. TrkRaiseNtStatus( status );
  38. }
  39. status = NtQueryVolumeInformationFile( hFile, &Iosb, &fsobOID, sizeof(fsobOID),
  40. FileFsObjectIdInformation );
  41. if( STATUS_OBJECT_NAME_NOT_FOUND == status )
  42. {
  43. TRK_VOLUME_TRACKING_INFORMATION volinfo;
  44. volinfo.volindex = -1;
  45. cpcVolumes.Push( &volinfo, 1 );
  46. hr = S_OK;
  47. goto Exit;
  48. }
  49. else if( !NT_SUCCESS(status) )
  50. {
  51. TrkLog((TRKDBG_ERROR, TEXT("Failed NtQueryVolumeInformationFile (%s)"), bstrUncPath ));
  52. TrkRaiseNtStatus( status );
  53. }
  54. volid.Load( &volid, fsobOID );
  55. NtClose( hFile );
  56. hFile = NULL;
  57. }
  58. else if( TRKINFOSCOPE_MACHINE != scope )
  59. {
  60. TrkLog((TRKDBG_ERROR, TEXT("Bad scope to CTrkForceOwnership::VolumeStatus (%l)"), scope ));
  61. TrkRaiseWin32Error( ERROR_INVALID_PARAMETER );
  62. }
  63. RpcTryExcept
  64. {
  65. hr = GetVolumeTrackingInformation( rc, volid, static_cast<TrkInfoScope>(scope), cpipeVolumes );
  66. if( SUCCEEDED(hr) && SUCCEEDED(cpcVolumes.GetHResult()) )
  67. hr = TriggerVolumeClaims( rc, cpcVolumes.Count(), cpcVolumes.GetVolIds() );
  68. }
  69. RpcExcept( BreakOnDebuggableException() )
  70. {
  71. hr = RpcExceptionCode();
  72. }
  73. RpcEndExcept;
  74. Exit:
  75. if( NULL != hFile )
  76. NtClose( hFile );
  77. return( hr );
  78. }
  79. STDMETHODIMP
  80. CTrkForceOwnership::Files(BSTR bstrUncPath, long scope)
  81. {
  82. HRESULT hr = E_FAIL;
  83. HANDLE hFile = NULL;
  84. CPCFiles cpcFiles( &_idt );
  85. TRpcPipeControl< TRK_FILE_TRACKING_INFORMATION_PIPE,
  86. TRK_FILE_TRACKING_INFORMATION,
  87. CPCFiles
  88. > cpipeFiles( &cpcFiles);
  89. CMachineId mcid( (LPWSTR) bstrUncPath );
  90. CRpcClientBinding rc;
  91. __try
  92. {
  93. NTSTATUS status;
  94. CDomainRelativeObjId droidCurrent, droidBirth;
  95. if( TRKINFOSCOPE_ONE_FILE == scope )
  96. {
  97. // BUGBUG P2: Optimize this; we don't need droidBirth
  98. status = GetDroids( bstrUncPath, &droidCurrent, &droidBirth, RGO_READ_OBJECTID );
  99. if( STATUS_OBJECT_NAME_NOT_FOUND == status )
  100. {
  101. TRK_FILE_TRACKING_INFORMATION fileinfo;
  102. _tcscpy( fileinfo.tszFilePath, TEXT("") );
  103. fileinfo.hr = HRESULT_FROM_NT( status );
  104. cpcFiles.Push( &fileinfo, 1 );
  105. hr = S_OK;
  106. goto Exit;
  107. }
  108. else if( !NT_SUCCESS(status) )
  109. {
  110. TrkLog((TRKDBG_ERROR, TEXT("Failed GetDroids (%s)"), bstrUncPath ));
  111. TrkRaiseNtStatus( status );
  112. }
  113. }
  114. else if( TRKINFOSCOPE_VOLUME == scope )
  115. {
  116. NTSTATUS status;
  117. IO_STATUS_BLOCK Iosb;
  118. FILE_FS_OBJECTID_INFORMATION fsobOID;
  119. CVolumeId volid;
  120. status = TrkCreateFile( bstrUncPath, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
  121. FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
  122. FILE_OPEN_NO_RECALL, NULL, &hFile );
  123. if( !NT_SUCCESS(status) )
  124. {
  125. hFile = NULL;
  126. TrkLog((TRKDBG_ERROR, TEXT("Couldn't open volume %s"), bstrUncPath ));
  127. TrkRaiseNtStatus( status );
  128. }
  129. status = NtQueryVolumeInformationFile( hFile, &Iosb, &fsobOID, sizeof(fsobOID),
  130. FileFsObjectIdInformation );
  131. if( STATUS_OBJECT_NAME_NOT_FOUND == status )
  132. {
  133. TRK_FILE_TRACKING_INFORMATION fileinfo;
  134. _tcscpy( fileinfo.tszFilePath, TEXT("") );
  135. fileinfo.hr = HRESULT_FROM_NT( status );
  136. cpcFiles.Push( &fileinfo, 1 );
  137. hr = S_OK;
  138. goto Exit;
  139. }
  140. else if( !NT_SUCCESS(status) )
  141. {
  142. TrkLog((TRKDBG_ERROR, TEXT("Failed NtQueryVolumeInformationFile (%s)"), bstrUncPath ));
  143. TrkRaiseNtStatus( status );
  144. }
  145. volid.Load( &volid, fsobOID );
  146. droidCurrent = CDomainRelativeObjId( volid, CObjId() );
  147. NtClose( hFile );
  148. hFile = NULL;
  149. }
  150. else if( TRKINFOSCOPE_MACHINE != scope )
  151. {
  152. TrkLog((TRKDBG_ERROR, TEXT("Bad scope to CTrkForceOwnership::FileStatus (%d)"), scope ));
  153. TrkRaiseWin32Error( ERROR_INVALID_PARAMETER );
  154. }
  155. rc.Initialize( mcid );
  156. RpcTryExcept
  157. {
  158. hr = GetFileTrackingInformation( rc, droidCurrent, static_cast<TrkInfoScope>(scope), cpipeFiles );
  159. }
  160. RpcExcept( BreakOnDebuggableException() )
  161. {
  162. hr = HRESULT_FROM_WIN32( RpcExceptionCode() );
  163. }
  164. RpcEndExcept;
  165. if( FAILED(hr) ) goto Exit;
  166. }
  167. __except( BreakOnDebuggableException() )
  168. {
  169. hr = GetExceptionCode();
  170. }
  171. Exit:
  172. if( NULL != hFile )
  173. NtClose( hFile );
  174. return( hr );
  175. }
  176. STDMETHODIMP
  177. CTrkForceOwnership::VolumeStatus(BSTR bstrUncPath, long scope,
  178. VARIANT *pvarlongVolIndex, VARIANT *pvarbstrVolId, VARIANT *pvarlongStatus)
  179. {
  180. HRESULT hr = E_FAIL;
  181. HANDLE hFile = NULL;
  182. SAFEARRAYBOUND sabound;
  183. CVolumeId volid;
  184. // Determine the machine ID
  185. CMachineId mcid( (LPWSTR) bstrUncPath );
  186. CRpcClientBinding rc;
  187. // This is used by the RPC server to pull the bstrUncPath
  188. CPCPath cpcPath( bstrUncPath );
  189. TRpcPipeControl< TCHAR_PIPE, TCHAR, CPCPath> cpipePath( &cpcPath );
  190. // This is used by the RPC server to push the volume information
  191. CPCVolumeStatus cpcVolumeStatus( &_voltab );
  192. TRpcPipeControl< TRK_VOLUME_TRACKING_INFORMATION_PIPE, TRK_VOLUME_TRACKING_INFORMATION, CPCVolumeStatus
  193. > cpipeVolumeStatus( &cpcVolumeStatus );
  194. __try
  195. {
  196. NTSTATUS status;
  197. // Initialize the outputs
  198. VariantInit( pvarlongVolIndex );
  199. VariantInit( pvarbstrVolId );
  200. VariantInit( pvarlongStatus );
  201. // Initialize the pipe callback
  202. cpcVolumeStatus.Initialize( &mcid, pvarlongVolIndex, pvarbstrVolId, pvarlongStatus );
  203. // Connect to the workstation in question
  204. rc.Initialize( mcid );
  205. if( TRKINFOSCOPE_VOLUME == scope )
  206. {
  207. IO_STATUS_BLOCK Iosb;
  208. FILE_FS_OBJECTID_INFORMATION fsobOID;
  209. status = TrkCreateFile( bstrUncPath, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
  210. FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
  211. FILE_OPEN_NO_RECALL, NULL, &hFile );
  212. if( !NT_SUCCESS(status) )
  213. {
  214. hFile = NULL;
  215. TrkLog((TRKDBG_ERROR, TEXT("Couldn't open volume %s"), bstrUncPath ));
  216. TrkRaiseNtStatus( status );
  217. }
  218. status = NtQueryVolumeInformationFile( hFile, &Iosb, &fsobOID, sizeof(fsobOID),
  219. FileFsObjectIdInformation );
  220. if( STATUS_OBJECT_NAME_NOT_FOUND == status )
  221. {
  222. TRK_VOLUME_TRACKING_INFORMATION volinfo;
  223. volinfo.volindex = -1;
  224. cpcVolumeStatus.Push( &volinfo, 1 );
  225. hr = S_OK;
  226. goto Exit;
  227. }
  228. else if( !NT_SUCCESS(status) )
  229. {
  230. TrkLog((TRKDBG_ERROR, TEXT("Failed NtQueryVolumeInformationFile (%s)"), bstrUncPath ));
  231. TrkRaiseNtStatus( status );
  232. }
  233. volid.Load( &volid, fsobOID );
  234. NtClose( hFile );
  235. hFile = NULL;
  236. }
  237. else if( TRKINFOSCOPE_MACHINE != scope )
  238. {
  239. TrkLog((TRKDBG_ERROR, TEXT("Bad scope to CTrkForceOwnership::VolumeStatus (%l)"), scope ));
  240. TrkRaiseWin32Error( ERROR_INVALID_PARAMETER );
  241. }
  242. RpcTryExcept
  243. {
  244. hr = GetVolumeTrackingInformation( rc, volid, static_cast<TrkInfoScope>(scope), cpipeVolumeStatus );
  245. }
  246. RpcExcept( BreakOnDebuggableException() )
  247. {
  248. hr = HRESULT_FROM_WIN32( RpcExceptionCode() );
  249. }
  250. RpcEndExcept;
  251. if( FAILED(hr) )
  252. {
  253. TrkLog((TRKDBG_ERROR, TEXT("Failed call to GetVolumeTrackInformation")));
  254. TrkRaiseException( hr );
  255. }
  256. if( FAILED(cpcVolumeStatus.GetHResult()) )
  257. {
  258. TrkLog((TRKDBG_ERROR, TEXT("Failed in VolumeStatus pipe callback")));
  259. TrkRaiseException( cpcVolumeStatus.GetHResult() );
  260. }
  261. // Truncate the safearrays
  262. cpcVolumeStatus.Compact();
  263. }
  264. __except( BreakOnDebuggableException() )
  265. {
  266. cpcVolumeStatus.UnInitialize();
  267. hr = GetExceptionCode();
  268. }
  269. Exit:
  270. if( FAILED(hr) )
  271. {
  272. VariantClear( pvarlongVolIndex );
  273. VariantClear( pvarbstrVolId );
  274. VariantClear( pvarlongStatus );
  275. }
  276. if( NULL != hFile )
  277. NtClose( hFile );
  278. return( hr );
  279. }
  280. void
  281. CPCVolumeStatus::Initialize( CMachineId *pmcid, VARIANT *pvarlongVolIndex, VARIANT *pvarbstrVolId, VARIANT *pvarlongStatus )
  282. {
  283. _pmcid = pmcid;
  284. _pvarlongVolIndex = pvarlongVolIndex;
  285. _pvarbstrVolId = pvarbstrVolId;
  286. _pvarlongStatus = pvarlongStatus;
  287. _iArrays = 0;
  288. _hr = S_OK;
  289. _sabound.lLbound = 0;
  290. _sabound.cElements = NUM_VOLUMES;
  291. _fInitialized = TRUE;
  292. _pvarlongVolIndex->parray = SafeArrayCreate( VT_I4, 1, &_sabound );
  293. if( NULL == _pvarlongVolIndex->parray )
  294. {
  295. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
  296. TrkRaiseWin32Error( E_OUTOFMEMORY );
  297. }
  298. _pvarlongVolIndex->vt = VT_I4 | VT_ARRAY;
  299. _pvarbstrVolId->parray = SafeArrayCreate( VT_BSTR, 1, &_sabound );
  300. if( NULL == _pvarbstrVolId->parray )
  301. {
  302. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
  303. TrkRaiseWin32Error( E_OUTOFMEMORY );
  304. }
  305. _pvarbstrVolId->vt = VT_BSTR | VT_ARRAY;
  306. _pvarlongStatus->parray = SafeArrayCreate( VT_I4, 1, &_sabound );
  307. if( NULL == _pvarlongStatus->parray )
  308. {
  309. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
  310. TrkRaiseWin32Error( E_OUTOFMEMORY );
  311. }
  312. _pvarlongStatus->vt = VT_I4 | VT_ARRAY;
  313. }
  314. void
  315. CPCVolumeStatus::UnInitialize()
  316. {
  317. // Nothing to do, the Variants are cleaned by the caller
  318. return;
  319. }
  320. void
  321. CPCVolumeStatus::Push( TRK_VOLUME_TRACKING_INFORMATION *pVolInfo, unsigned long cElems )
  322. {
  323. TrkLog(( TRKDBG_ADMIN, TEXT("CPCVolumeStatus received %d elements"), cElems ));
  324. HRESULT hr = S_OK;
  325. HRESULT hrGet;
  326. ULONG iElem = 0;
  327. BSTR bstrVolId = NULL;
  328. __try
  329. {
  330. for( iElem = 0; iElem < cElems; iElem++ )
  331. {
  332. CMachineId mcidCheck;
  333. CVolumeSecret volsecCheck;
  334. SequenceNumber seqCheck;
  335. CVolumeId volNULL;
  336. TCHAR tszVolId[ 40 ];
  337. TCHAR *ptszVolId = tszVolId;
  338. long VolOwnership = OBJOWN_UNKNOWN;
  339. if( pVolInfo[iElem].volume != volNULL )
  340. hrGet = _pvoltab->GetVolumeInfo( pVolInfo[iElem].volume, &mcidCheck, &volsecCheck, &seqCheck );
  341. if( _iArrays >= static_cast<LONG>(_sabound.cElements) )
  342. {
  343. TrkAssert( !TEXT("Not yet implemented") );
  344. // BUGBUG: do a SafeArrayReDim
  345. return;
  346. }
  347. TrkAssert( sizeof(long) == sizeof(pVolInfo[iElem].volindex) );
  348. hr = SafeArrayPutElement( _pvarlongVolIndex->parray, &_iArrays, &pVolInfo[iElem].volindex );
  349. if( FAILED(hr) )
  350. {
  351. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElement")));
  352. TrkRaiseException( hr );
  353. }
  354. // BUGBUG: Add a Serialize(BSTR) method to CVolumeId
  355. pVolInfo[iElem].volume.Stringize( ptszVolId );
  356. bstrVolId = SysAllocString( tszVolId );
  357. if( NULL == bstrVolId )
  358. {
  359. TrkLog((TRKDBG_ERROR, TEXT("Failed SysAllocString")));
  360. TrkRaiseWin32Error( E_OUTOFMEMORY );
  361. }
  362. hr = SafeArrayPutElement( _pvarbstrVolId->parray, &_iArrays, bstrVolId );
  363. if( FAILED(hr) )
  364. {
  365. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElement")));
  366. TrkRaiseException( hr );
  367. }
  368. if( S_OK != hrGet )
  369. {
  370. VolOwnership = OBJOWN_DOESNT_EXIST;
  371. }
  372. else if( mcidCheck == *_pmcid )
  373. {
  374. VolOwnership = OBJOWN_OWNED;
  375. }
  376. else if( volNULL == pVolInfo[iElem].volume )
  377. {
  378. VolOwnership = OBJOWN_NO_ID;
  379. }
  380. else
  381. {
  382. VolOwnership = OBJOWN_NOT_OWNED;
  383. }
  384. hr = SafeArrayPutElement( _pvarlongStatus->parray, &_iArrays, &VolOwnership );
  385. if( FAILED(hr) )
  386. {
  387. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElemnt")));
  388. TrkRaiseException( hr );
  389. }
  390. SysFreeString( bstrVolId ); bstrVolId = NULL;
  391. _iArrays++;
  392. }
  393. }
  394. __except( BreakOnDebuggableException() )
  395. {
  396. hr = GetExceptionCode();
  397. }
  398. Exit:
  399. if( FAILED(hr) )
  400. {
  401. if( NULL != bstrVolId )
  402. SysFreeString( bstrVolId );
  403. if( !FAILED(_hr) )
  404. _hr = hr;
  405. }
  406. return;
  407. }
  408. void
  409. CPCVolumeStatus::Compact()
  410. {
  411. HRESULT hr = S_OK;
  412. _sabound.cElements = _iArrays;
  413. hr = SafeArrayRedim( _pvarlongVolIndex->parray, &_sabound );
  414. if( FAILED(hr) )
  415. {
  416. TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
  417. TrkRaiseException( hr );
  418. }
  419. hr = SafeArrayRedim( _pvarbstrVolId->parray, &_sabound );
  420. if( FAILED(hr) )
  421. {
  422. TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
  423. TrkRaiseException( hr );
  424. }
  425. hr = SafeArrayRedim( _pvarlongStatus->parray, &_sabound );
  426. if( FAILED(hr) )
  427. {
  428. TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
  429. TrkRaiseException( hr );
  430. }
  431. }
  432. void
  433. CPCVolumes::Push( TRK_VOLUME_TRACKING_INFORMATION *pVolInfo, unsigned long cElems )
  434. {
  435. TrkLog(( TRKDBG_ADMIN, TEXT("CPCVolumeStatus received %d elements"), cElems ));
  436. HRESULT hr = S_OK;
  437. ULONG iElem = 0;
  438. __try
  439. {
  440. for( iElem = 0; iElem < cElems; iElem++ )
  441. {
  442. hr = _pvoltab->SetMachine( pVolInfo[iElem].volume, *_pmcid );
  443. if( TRK_S_VOLUME_NOT_FOUND == hr )
  444. _pvoltab->CreateVolume(
  445. pVolInfo[iElem].volume,
  446. *_pmcid,
  447. CVolumeSecret(),
  448. _pRefreshSequenceStorage->GetSequenceNumber() );
  449. // BUGBUG P1: Handle this error
  450. TrkAssert( SUCCEEDED(hr) );
  451. _rgvolid[ _cVolIds++ ] = pVolInfo[iElem].volume;
  452. }
  453. }
  454. __except( BreakOnDebuggableException() )
  455. {
  456. hr = GetExceptionCode();
  457. }
  458. if( FAILED(hr) )
  459. {
  460. if( !FAILED(_hr) )
  461. _hr = hr;
  462. }
  463. return;
  464. }
  465. void
  466. CPCFiles::Push( TRK_FILE_TRACKING_INFORMATION *pFileInfo, unsigned long cElems )
  467. {
  468. ULONG iFile;
  469. __try
  470. {
  471. // BUGBUG P2: Instead of a loop, batch these up
  472. for( iFile = 0; iFile < cElems; iFile++ )
  473. {
  474. _pidt->Delete( pFileInfo[iFile].droidBirth );
  475. TrkVerify( _pidt->Add( pFileInfo[iFile].droidBirth, pFileInfo[iFile].droidLast,
  476. pFileInfo[iFile].droidBirth ));
  477. }
  478. }
  479. __except( BreakOnDebuggableException() )
  480. {
  481. TrkLog(( TRKDBG_ERROR, TEXT("CPCFiles::Push had an exception (%08x)"), GetExceptionCode() ));
  482. }
  483. }
  484. void
  485. CPCFileStatus::Push( TRK_FILE_TRACKING_INFORMATION *pFileInfo, unsigned long cElems )
  486. {
  487. TrkLog(( TRKDBG_ADMIN, TEXT("CPCFileStatus received %d elements"), cElems ));
  488. HRESULT hr = S_OK;
  489. ULONG iElem = 0;
  490. BSTR bstr = NULL;
  491. __try
  492. {
  493. for( iElem = 0; iElem < cElems; iElem++ )
  494. {
  495. BOOL fExistsInTable = FALSE;
  496. BOOL fAtBirthplace = FALSE;
  497. CDomainRelativeObjId droidBirthCheck;
  498. CDomainRelativeObjId droidNowCheck;
  499. const CDomainRelativeObjId droidNULL;
  500. TCHAR tszDroid[ MAX_PATH ];
  501. long FileOwnership;
  502. if( droidNULL == pFileInfo[iElem].droidBirth
  503. ||
  504. pFileInfo[iElem].droidBirth == pFileInfo[iElem].droidLast )
  505. {
  506. fAtBirthplace = TRUE;
  507. }
  508. else
  509. {
  510. fExistsInTable = _pidt->Query( pFileInfo[iElem].droidBirth, &droidNowCheck, &droidBirthCheck );
  511. }
  512. if( _iArrays >= static_cast<LONG>(_sabound.cElements) )
  513. {
  514. TrkAssert( !TEXT("Not yet impelemented") );
  515. // BUGBUG: do a SafeArrayReDim
  516. return;
  517. }
  518. bstr = SysAllocString( pFileInfo[iElem].tszFilePath );
  519. if( NULL == bstr )
  520. {
  521. TrkLog((TRKDBG_ERROR, TEXT("Failed SysAllocString")));
  522. TrkRaiseWin32Error( E_OUTOFMEMORY );
  523. }
  524. hr = SafeArrayPutElement( _pvarrgbstrFileName->parray, &_iArrays, bstr );
  525. if( FAILED(hr) )
  526. {
  527. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElement")));
  528. TrkRaiseException( hr );
  529. }
  530. SysFreeString( bstr ); bstr = NULL;
  531. // BUGBUG: Add a Serialize(BSTR) method to CDroid
  532. pFileInfo[iElem].droidBirth.Stringize( tszDroid, sizeof(tszDroid) );
  533. bstr = SysAllocString( tszDroid );
  534. if( NULL == bstr )
  535. {
  536. TrkLog((TRKDBG_ERROR, TEXT("Failed SysAllocString")));
  537. TrkRaiseWin32Error( E_OUTOFMEMORY );
  538. }
  539. hr = SafeArrayPutElement( _pvarrgbstrFileId->parray, &_iArrays, bstr );
  540. if( FAILED(hr) )
  541. {
  542. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElement")));
  543. TrkRaiseException( hr );
  544. }
  545. if( fAtBirthplace )
  546. FileOwnership = OBJOWN_OWNED;
  547. else if( !fExistsInTable )
  548. FileOwnership = OBJOWN_DOESNT_EXIST;
  549. else if( droidNowCheck == pFileInfo[iElem].droidLast
  550. &&
  551. droidBirthCheck == pFileInfo[iElem].droidBirth )
  552. FileOwnership = OBJOWN_OWNED;
  553. else
  554. FileOwnership = OBJOWN_NOT_OWNED;
  555. hr = SafeArrayPutElement( _pvarrglongStatus->parray, &_iArrays, &FileOwnership );
  556. if( FAILED(hr) )
  557. {
  558. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElemnt")));
  559. TrkRaiseException( hr );
  560. }
  561. _iArrays++;
  562. }
  563. }
  564. __except( BreakOnDebuggableException() )
  565. {
  566. hr = GetExceptionCode();
  567. }
  568. Exit:
  569. if( FAILED(hr) )
  570. {
  571. if( NULL != bstr )
  572. SysFreeString( bstr );
  573. if( !FAILED(_hr) )
  574. _hr = hr;
  575. }
  576. return;
  577. }
  578. void
  579. CPCFileStatus::Initialize( CMachineId *pmcid, VARIANT *pvarrgbstrFileName,
  580. VARIANT *pvarrgbstrFileId, VARIANT *pvarrglongStatus )
  581. {
  582. _pmcid = pmcid;
  583. _pvarrgbstrFileName = pvarrgbstrFileName;
  584. _pvarrgbstrFileId = pvarrgbstrFileId;
  585. _pvarrglongStatus = pvarrglongStatus;
  586. _iArrays = 0;
  587. _hr = S_OK;
  588. _sabound.lLbound = 0;
  589. _sabound.cElements = 10;
  590. _fInitialized = TRUE;
  591. _pvarrgbstrFileName->parray = SafeArrayCreate( VT_BSTR, 1, &_sabound );
  592. if( NULL == _pvarrgbstrFileName->parray )
  593. {
  594. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
  595. TrkRaiseWin32Error( E_OUTOFMEMORY );
  596. }
  597. _pvarrgbstrFileName->vt = VT_BSTR | VT_ARRAY;
  598. _pvarrgbstrFileId->parray = SafeArrayCreate( VT_BSTR, 1, &_sabound );
  599. if( NULL == _pvarrgbstrFileId->parray )
  600. {
  601. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
  602. TrkRaiseWin32Error( E_OUTOFMEMORY );
  603. }
  604. _pvarrgbstrFileId->vt = VT_BSTR | VT_ARRAY;
  605. _pvarrglongStatus->parray = SafeArrayCreate( VT_I4, 1, &_sabound );
  606. if( NULL == _pvarrglongStatus->parray )
  607. {
  608. TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
  609. TrkRaiseWin32Error( E_OUTOFMEMORY );
  610. }
  611. _pvarrglongStatus->vt = VT_I4 | VT_ARRAY;
  612. } // CPCFileStatus::Initialize
  613. void
  614. CPCFileStatus::Compact()
  615. {
  616. HRESULT hr = S_OK;
  617. _sabound.cElements = _iArrays;
  618. hr = SafeArrayRedim( _pvarrgbstrFileName->parray, &_sabound );
  619. if( FAILED(hr) )
  620. {
  621. TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
  622. TrkRaiseException( hr );
  623. }
  624. hr = SafeArrayRedim( _pvarrgbstrFileId->parray, &_sabound );
  625. if( FAILED(hr) )
  626. {
  627. TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
  628. TrkRaiseException( hr );
  629. }
  630. hr = SafeArrayRedim( _pvarrglongStatus->parray, &_sabound );
  631. if( FAILED(hr) )
  632. {
  633. TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
  634. TrkRaiseException( hr );
  635. }
  636. }
  637. STDMETHODIMP CTrkForceOwnership::FileStatus(BSTR bstrUncPath, long scope,
  638. VARIANT * pvarrgbstrFileName, VARIANT *pvarrgbstrFileId, VARIANT * pvarrglongStatus)
  639. {
  640. HRESULT hr = E_FAIL;
  641. SAFEARRAYBOUND sabound;
  642. HANDLE hFile = NULL;
  643. // Determine the machine ID
  644. CMachineId mcid( (LPWSTR) bstrUncPath );
  645. CRpcClientBinding rc;
  646. // This is used by the RPC server to push the volume information
  647. CPCFileStatus cpcFileStatus( &_idt );
  648. TRpcPipeControl< TRK_FILE_TRACKING_INFORMATION_PIPE, TRK_FILE_TRACKING_INFORMATION, CPCFileStatus
  649. > cpipeFileStatus( &cpcFileStatus );
  650. __try
  651. {
  652. NTSTATUS status;
  653. // Initialize the outputs
  654. VariantInit( pvarrgbstrFileName );
  655. VariantInit( pvarrgbstrFileId );
  656. VariantInit( pvarrglongStatus );
  657. CDomainRelativeObjId droidCurrent, droidBirth;
  658. // Initialize the pipe callback
  659. cpcFileStatus.Initialize( &mcid, pvarrgbstrFileName, pvarrgbstrFileId, pvarrglongStatus );
  660. if( TRKINFOSCOPE_ONE_FILE == scope )
  661. {
  662. // BUGBUG P2: Optimize this; we don't need droidBirth
  663. status = GetDroids( bstrUncPath, &droidCurrent, &droidBirth, RGO_READ_OBJECTID );
  664. if( STATUS_OBJECT_NAME_NOT_FOUND == status )
  665. {
  666. TRK_FILE_TRACKING_INFORMATION fileinfo;
  667. _tcscpy( fileinfo.tszFilePath, TEXT("") );
  668. fileinfo.hr = HRESULT_FROM_NT( status );
  669. cpcFileStatus.Push( &fileinfo, 1 );
  670. hr = S_OK;
  671. goto Exit;
  672. }
  673. else if( !NT_SUCCESS(status) )
  674. {
  675. TrkLog((TRKDBG_ERROR, TEXT("Failed GetDroids (%s)"), bstrUncPath ));
  676. TrkRaiseNtStatus( status );
  677. }
  678. }
  679. else if( TRKINFOSCOPE_VOLUME == scope )
  680. {
  681. NTSTATUS status;
  682. IO_STATUS_BLOCK Iosb;
  683. FILE_FS_OBJECTID_INFORMATION fsobOID;
  684. CVolumeId volid;
  685. status = TrkCreateFile( bstrUncPath, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
  686. FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
  687. FILE_OPEN_NO_RECALL, NULL, &hFile );
  688. if( !NT_SUCCESS(status) )
  689. {
  690. hFile = NULL;
  691. TrkLog((TRKDBG_ERROR, TEXT("Couldn't open volume %s"), bstrUncPath ));
  692. TrkRaiseNtStatus( status );
  693. }
  694. status = NtQueryVolumeInformationFile( hFile, &Iosb, &fsobOID, sizeof(fsobOID),
  695. FileFsObjectIdInformation );
  696. if( STATUS_OBJECT_NAME_NOT_FOUND == status )
  697. {
  698. TRK_FILE_TRACKING_INFORMATION fileinfo;
  699. _tcscpy( fileinfo.tszFilePath, TEXT("") );
  700. fileinfo.hr = HRESULT_FROM_NT( status );
  701. cpcFileStatus.Push( &fileinfo, 1 );
  702. hr = S_OK;
  703. goto Exit;
  704. }
  705. else if( !NT_SUCCESS(status) )
  706. {
  707. TrkLog((TRKDBG_ERROR, TEXT("Failed NtQueryVolumeInformationFile (%s)"), bstrUncPath));
  708. TrkRaiseNtStatus( status );
  709. }
  710. volid.Load( &volid, fsobOID );
  711. droidCurrent = CDomainRelativeObjId( volid, CObjId() );
  712. NtClose( hFile );
  713. hFile = NULL;
  714. }
  715. else if( TRKINFOSCOPE_MACHINE != scope )
  716. {
  717. TrkLog((TRKDBG_ERROR, TEXT("Bad scope to CTrkForceOwnership::FileStatus (%d)"), scope ));
  718. TrkRaiseWin32Error( ERROR_INVALID_PARAMETER );
  719. }
  720. // Connect to the workstation in question
  721. rc.Initialize( mcid );
  722. // Get the volume status info
  723. RpcTryExcept
  724. {
  725. hr = GetFileTrackingInformation( rc, droidCurrent, static_cast<TrkInfoScope>(scope), cpipeFileStatus );
  726. }
  727. RpcExcept( BreakOnDebuggableException() )
  728. {
  729. hr = HRESULT_FROM_WIN32( RpcExceptionCode() );
  730. }
  731. RpcEndExcept;
  732. if( FAILED(hr) )
  733. {
  734. TrkLog((TRKDBG_ERROR, TEXT("Failed call to GetFileTrackInformation")));
  735. TrkRaiseException( hr );
  736. }
  737. if( FAILED(cpcFileStatus.GetHResult()) )
  738. {
  739. TrkLog((TRKDBG_ERROR, TEXT("Failed in FileStatus pipe callback")));
  740. TrkRaiseException( cpcFileStatus.GetHResult() );
  741. }
  742. // Truncate the safearrays
  743. cpcFileStatus.Compact();
  744. }
  745. __except( BreakOnDebuggableException() )
  746. {
  747. cpcFileStatus.UnInitialize();
  748. hr = GetExceptionCode();
  749. }
  750. Exit:
  751. if( NULL != hFile )
  752. NtClose( hFile );
  753. if( FAILED(hr) )
  754. {
  755. VariantClear( pvarrgbstrFileName );
  756. VariantClear( pvarrgbstrFileId );
  757. VariantClear( pvarrglongStatus );
  758. }
  759. return( hr );
  760. }