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.

812 lines
18 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. FTMan
  5. File Name:
  6. FTUtil.cpp
  7. Abstract:
  8. Implementation of FT utilities
  9. Author:
  10. Cristian Teodorescu October 29, 1998
  11. Notes:
  12. Revision History:
  13. --*/
  14. #include "stdafx.h"
  15. #include "DiskMap.h"
  16. #include "FTUtil.h"
  17. #include "Global.h"
  18. #include "Item.h"
  19. #include "Resource.h"
  20. extern "C"
  21. {
  22. #include <FTAPI.h>
  23. }
  24. #include <ntddft2.h>
  25. #include <winioctl.h>
  26. #ifdef _DEBUG
  27. #define new DEBUG_NEW
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. /*
  32. Global function: FTBreak
  33. Purpose: Break a logical volume
  34. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  35. ID of the logical volume
  36. Return value: TRUE if the volume is broken successfully
  37. */
  38. BOOL FTBreak( FT_LOGICAL_DISK_ID llVolID )
  39. {
  40. MY_TRY
  41. CWaitCursor wc;
  42. BOOL bResult;
  43. DisplayStatusBarMessage( IDS_STATUS_FTBREAK );
  44. bResult = FtBreakLogicalDisk( llVolID );
  45. if( bResult )
  46. {
  47. //AfxMessageBox( IDS_MSG_FTBREAK, MB_ICONINFORMATION );
  48. }
  49. else
  50. DisplaySystemErrorMessage( IDS_ERR_FTBREAK );
  51. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  52. return bResult;
  53. MY_CATCH_AND_THROW
  54. }
  55. /*
  56. Global function: FTChkIO
  57. Purpose: Check the IO status of a logical volume
  58. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  59. ID of the logical volume
  60. [OUT] BOOL* pbOK
  61. The result of the IO check
  62. Return value: TRUE if the IO check operation succeeded
  63. */
  64. BOOL FTChkIO( FT_LOGICAL_DISK_ID llVolID, BOOL* pbOK )
  65. {
  66. MY_TRY
  67. BOOL bResult;
  68. bResult = FtCheckIo( llVolID, pbOK );
  69. /*
  70. if( bResult )
  71. {
  72. CString strMsg, strOK;
  73. strOK.LoadString( bOK ? IDS_OK : IDS_NOTOK );
  74. AfxFormatString1(strMsg, IDS_MSG_FTCHKIO, strOK);
  75. AfxMessageBox(strMsg,MB_ICONINFORMATION);
  76. }
  77. else
  78. DisplaySystemErrorMessage( IDS_ERR_FTCHKIO );
  79. */
  80. return bResult;
  81. MY_CATCH_AND_THROW
  82. }
  83. /*
  84. Global function: FTExtend
  85. Purpose: Extend the file system of a volume to the maximum possible
  86. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  87. ID of the logical volume
  88. Return value: TRUE if the file system is extended successfully
  89. */
  90. BOOL FTExtend( FT_LOGICAL_DISK_ID llVolID )
  91. {
  92. MY_TRY
  93. CWaitCursor wc;
  94. BOOL bReturn;
  95. HANDLE h;
  96. PARTITION_INFORMATION partInfo;
  97. DISK_GEOMETRY geometry;
  98. ULONG ulBytes;
  99. LONGLONG llNewSectors;
  100. CString strVolumeName;
  101. if( !FTQueryVolumeName( llVolID, strVolumeName ) )
  102. return FALSE;
  103. h = CreateFile( strVolumeName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  104. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE );
  105. if( h == INVALID_HANDLE_VALUE )
  106. {
  107. DisplaySystemErrorMessage( IDS_ERR_FTEXTEND );
  108. return FALSE;
  109. }
  110. bReturn = DeviceIoControl( h, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
  111. &partInfo, sizeof(partInfo), &ulBytes, NULL );
  112. if( !bReturn )
  113. {
  114. DisplaySystemErrorMessage( IDS_ERR_FTEXTEND );
  115. CloseHandle(h);
  116. return FALSE;
  117. }
  118. bReturn = DeviceIoControl( h, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
  119. &geometry, sizeof(geometry), &ulBytes, NULL );
  120. if( !bReturn )
  121. {
  122. DisplaySystemErrorMessage( IDS_ERR_FTEXTEND );
  123. CloseHandle(h);
  124. return FALSE;
  125. }
  126. llNewSectors = partInfo.PartitionLength.QuadPart / geometry.BytesPerSector;
  127. bReturn = DeviceIoControl( h, FSCTL_EXTEND_VOLUME, &llNewSectors, sizeof(llNewSectors),
  128. NULL, 0, &ulBytes, NULL );
  129. CloseHandle(h);
  130. return bReturn;
  131. MY_CATCH_AND_THROW
  132. }
  133. /*
  134. Global function: FTInit
  135. Purpose: Initialize a logical volume with repairing ( or not ) the orphan member
  136. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  137. The ID of the logical volume
  138. [BOOL] bInitOrphans
  139. Initialize the orphan member or not
  140. Return value: TRUE if the logical volume was initialized successfully
  141. */
  142. BOOL FTInit( FT_LOGICAL_DISK_ID llVolID, BOOL bInitOrphans /* = TRUE */ )
  143. {
  144. MY_TRY
  145. CWaitCursor wc;
  146. BOOL bResult;
  147. DisplayStatusBarMessage( IDS_STATUS_FTINIT );
  148. bResult = FtInitializeLogicalDisk( llVolID, bInitOrphans );
  149. if( bResult )
  150. {
  151. //AfxMessageBox( IDS_MSG_FTINIT, MB_ICONINFORMATION );
  152. }
  153. else
  154. DisplaySystemErrorMessage( IDS_ERR_FTINIT );
  155. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  156. return bResult;
  157. MY_CATCH_AND_THROW
  158. }
  159. /*
  160. Global function: FTMirror
  161. Purpose: Create a mirror set based on the given logical volumes
  162. Parameters: [IN] FT_LOGICAL_DISK_ID* arrVolID
  163. ID's of the members
  164. [IN] WORD wNumVols
  165. The number of members ( must be 2 )
  166. [OUT] FT_LOGICAL_DISK_ID* pllVolID
  167. Address where the logical volume ID of the new mirror set is to be stored
  168. If NULL then don't return the ID
  169. Return value: TRUE if the mirror set is created successfully
  170. */
  171. BOOL FTMirror( FT_LOGICAL_DISK_ID* arrVolID, WORD wNumVols, FT_LOGICAL_DISK_ID* pllVolID /* = NULL */ )
  172. {
  173. MY_TRY
  174. ASSERT( arrVolID );
  175. ASSERT( wNumVols == 2 );
  176. CWaitCursor wc;
  177. BOOL bResult;
  178. FT_MIRROR_SET_CONFIGURATION_INFORMATION configInfo;
  179. FT_LOGICAL_DISK_ID llNewVolID;
  180. LONGLONG llMemberSize, llZeroMemberSize;
  181. DisplayStatusBarMessage( IDS_STATUS_FTMIRROR );
  182. configInfo.MemberSize = MAXLONGLONG;
  183. for( int i = 0; i < wNumVols; i++ )
  184. {
  185. bResult = FtQueryLogicalDiskInformation( arrVolID[i], NULL, &llMemberSize, 0,
  186. NULL, NULL, 0, NULL, 0, NULL );
  187. if( !bResult )
  188. {
  189. DisplaySystemErrorMessage(IDS_ERR_RETRIEVING_VOL_INFO);
  190. return FALSE;
  191. }
  192. if( llMemberSize < configInfo.MemberSize )
  193. configInfo.MemberSize = llMemberSize;
  194. if( i == 0 )
  195. llZeroMemberSize = llMemberSize;
  196. }
  197. if( llMemberSize < llZeroMemberSize )
  198. {
  199. CString str, strSize1, strSize2;
  200. FormatVolumeSize( strSize1, llZeroMemberSize );
  201. FormatVolumeSize( strSize2, llMemberSize );
  202. AfxFormatString2(str, IDS_QST_FTMIRROR, strSize1, strSize2);
  203. if( IDYES != AfxMessageBox( str, MB_YESNO | MB_DEFBUTTON2 ) )
  204. {
  205. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  206. return FALSE;
  207. }
  208. wc.Restore();
  209. }
  210. bResult = FtCreateLogicalDisk( FtMirrorSet, wNumVols, arrVolID, sizeof(configInfo),
  211. &configInfo, &llNewVolID );
  212. if( bResult )
  213. {
  214. //AfxMessageBox( IDS_MSG_FTMIRROR, MB_ICONINFORMATION );
  215. if( pllVolID )
  216. *pllVolID = llNewVolID;
  217. }
  218. else
  219. DisplaySystemErrorMessage( IDS_ERR_FTMIRROR );
  220. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  221. return bResult;
  222. MY_CATCH_AND_THROW
  223. }
  224. /*
  225. Global function: FTOrphan
  226. Purpose: Orphan the given member of the given logical volume.
  227. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  228. ID of the logical volume
  229. [IN] WORD wMember
  230. Zero-based index of the member to be orphaned
  231. Return value: TRUE if the member is orphaned successfully
  232. */
  233. BOOL FTOrphan( FT_LOGICAL_DISK_ID llVolID, WORD wMember )
  234. {
  235. MY_TRY
  236. CWaitCursor wc;
  237. BOOL bResult;
  238. DisplayStatusBarMessage( IDS_STATUS_FTORPHAN );
  239. bResult = FtOrphanLogicalDiskMember( llVolID, wMember );
  240. if( bResult )
  241. {
  242. // AfxMessageBox( IDS_MSG_FTORPHAN, MB_ICONINFORMATION );
  243. }
  244. else
  245. DisplaySystemErrorMessage( IDS_ERR_FTORPHAN );
  246. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  247. return bResult;
  248. MY_CATCH_AND_THROW
  249. }
  250. /*
  251. Global function: FTPart
  252. Purpose: Converts a physical partition into a FT partition
  253. Parameters: [IN] CString& strVolumeName
  254. Volume name of the physical partition
  255. It should be like this: "\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
  256. [IN] TCHAR cDriveLetter
  257. The drive letter of the physical partition
  258. '\0' if none
  259. [OUT] FT_LOGICAL_DISK_ID* pllVolID
  260. Address where the logical volume ID of the new FT partitions to be stored
  261. If NULL then don't return the ID
  262. Return value: TRUE if the FT partition is created successfully
  263. */
  264. BOOL FTPart( const CString& strVolumeName, TCHAR cDriveLetter /* =_T('\0') */, FT_LOGICAL_DISK_ID* pllVolID /* = NULL */ )
  265. {
  266. MY_TRY
  267. CWaitCursor wc;
  268. BOOL bResult;
  269. HANDLE hPart;
  270. FT_LOGICAL_DISK_ID llVolID;
  271. // First open the partition
  272. hPart = OpenVolume( strVolumeName );
  273. if( hPart == INVALID_HANDLE_VALUE )
  274. {
  275. DisplaySystemErrorMessage( IDS_ERR_FTPART );
  276. return FALSE;
  277. }
  278. // Second create the logical volume
  279. bResult = FtCreatePartitionLogicalDisk( hPart, &llVolID );
  280. CloseHandle(hPart);
  281. if( bResult )
  282. {
  283. //AfxMessageBox( IDS_MSG_FTPART, MB_ICONINFORMATION );
  284. if( cDriveLetter != _T('\0') )
  285. {
  286. #ifdef UNICODE
  287. cDriveLetter = (WCHAR)(towupper( cDriveLetter ));
  288. #else
  289. cDriveLetter = (char)(toupper( cDriveLetter ));
  290. #endif
  291. FtSetStickyDriveLetter( llVolID, (UCHAR) cDriveLetter );
  292. }
  293. if( pllVolID )
  294. *pllVolID = llVolID;
  295. }
  296. else
  297. DisplaySystemErrorMessage( IDS_ERR_FTPART );
  298. return bResult;
  299. MY_CATCH_AND_THROW
  300. }
  301. /*
  302. Global function: FTRegen
  303. Purpose: Replace a member of a logical volume with another logical volume and start the
  304. regeneration process.
  305. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  306. ID of the logical volume whose member is to be replaced
  307. [IN] WORD wMember
  308. Zero-based index of the member to be replced
  309. [IN] FT_LOGICAL_DISK_ID llReplVolID
  310. ID of the replacement
  311. [OUT] FT_LOGICAL_DISK_ID* pllVolID
  312. Address where the logical volume ID of the new set is to be stored
  313. If NULL then don't return the ID
  314. Return value: TRUE if the stripe set is created successfully
  315. */
  316. BOOL FTRegen( FT_LOGICAL_DISK_ID llVolID, WORD wMember, FT_LOGICAL_DISK_ID llReplVolID,
  317. FT_LOGICAL_DISK_ID* pllVolID /* =NULL */ )
  318. {
  319. MY_TRY
  320. CWaitCursor wc;
  321. BOOL bResult;
  322. FT_LOGICAL_DISK_ID llNewVolID;
  323. DisplayStatusBarMessage( IDS_STATUS_FTREGEN );
  324. bResult = FtReplaceLogicalDiskMember( llVolID, wMember, llReplVolID, &llNewVolID );
  325. if( bResult )
  326. {
  327. //AfxMessageBox( IDS_MSG_FTREGEN, MB_ICONINFORMATION );
  328. if( pllVolID )
  329. *pllVolID = llNewVolID;
  330. }
  331. else
  332. DisplaySystemErrorMessage( IDS_ERR_FTREGEN );
  333. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  334. return bResult;
  335. MY_CATCH_AND_THROW
  336. }
  337. /*
  338. Global function: FTStripe
  339. Purpose: Create a stripe set based on the given logical volumes
  340. Parameters: [IN] FT_LOGICAL_DISK_ID* arrVolID
  341. ID's of the members
  342. [IN] WORD wNumVols
  343. The number of members
  344. [IN] LONGLONG llStripeSize
  345. The size of the stripe chunks
  346. [OUT] FT_LOGICAL_DISK_ID* pllVolID
  347. Address where the logical volume ID of the new stripe set is to be stored
  348. If NULL then don't return the ID
  349. Return value: TRUE if the stripe set is created successfully
  350. */
  351. BOOL FTStripe( FT_LOGICAL_DISK_ID* arrVolID, WORD wNumVols, ULONG ulStripeSize, FT_LOGICAL_DISK_ID* pllVolID /* = NULL */)
  352. {
  353. MY_TRY
  354. ASSERT( arrVolID );
  355. ASSERT( wNumVols >= 2 );
  356. CWaitCursor wc;
  357. BOOL bResult;
  358. FT_STRIPE_SET_CONFIGURATION_INFORMATION configInfo;
  359. FT_LOGICAL_DISK_ID llNewVolID;
  360. DisplayStatusBarMessage( IDS_STATUS_FTSTRIPE );
  361. configInfo.StripeSize = ulStripeSize;
  362. bResult = FtCreateLogicalDisk( FtStripeSet, wNumVols, arrVolID, sizeof(configInfo),
  363. &configInfo, &llNewVolID );
  364. if( bResult )
  365. {
  366. //AfxMessageBox( IDS_MSG_FTSTRIPE, MB_ICONINFORMATION );
  367. if( pllVolID )
  368. *pllVolID = llNewVolID;
  369. }
  370. else
  371. DisplaySystemErrorMessage( IDS_ERR_FTSTRIPE );
  372. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  373. return bResult;
  374. MY_CATCH_AND_THROW
  375. }
  376. /*
  377. Global function: FTSWP
  378. Purpose: Create a stripe set with parity based on the given logical volumes
  379. Parameters: [IN] FT_LOGICAL_DISK_ID* arrVolID
  380. ID's of the members
  381. [IN] WORD wNumVols
  382. The number of members
  383. [IN] LONGLONG llStripeSize
  384. The size of the stripe chunks
  385. [OUT] FT_LOGICAL_DISK_ID* pllVolID
  386. Address where the logical volume ID of the new stripe set with parity is to be stored
  387. If NULL then don't return the ID
  388. Return value: TRUE if the stripe set with parity is created successfully
  389. */
  390. BOOL FTSWP( FT_LOGICAL_DISK_ID* arrVolID, WORD wNumVols, ULONG ulStripeSize, FT_LOGICAL_DISK_ID* pllVolID /* = NULL */ )
  391. {
  392. MY_TRY
  393. ASSERT( arrVolID );
  394. ASSERT( wNumVols >= 3 );
  395. CWaitCursor wc;
  396. BOOL bResult;
  397. FT_STRIPE_SET_WITH_PARITY_CONFIGURATION_INFORMATION configInfo;
  398. FT_LOGICAL_DISK_ID llNewVolID;
  399. LONGLONG llMemberSize;
  400. DisplayStatusBarMessage( IDS_STATUS_FTSWP );
  401. configInfo.MemberSize = MAXLONGLONG;
  402. for( int i=0; i < wNumVols; i++ )
  403. {
  404. bResult = FtQueryLogicalDiskInformation( arrVolID[i], NULL, &llMemberSize, 0,
  405. NULL, NULL, 0, NULL, 0, NULL );
  406. if( !bResult )
  407. {
  408. DisplaySystemErrorMessage(IDS_ERR_RETRIEVING_VOL_INFO);
  409. return FALSE;
  410. }
  411. if( llMemberSize < configInfo.MemberSize )
  412. configInfo.MemberSize = llMemberSize;
  413. }
  414. configInfo.StripeSize = ulStripeSize;
  415. bResult = FtCreateLogicalDisk( FtStripeSetWithParity, wNumVols, arrVolID, sizeof( configInfo),
  416. &configInfo, &llNewVolID );
  417. if( bResult )
  418. {
  419. //AfxMessageBox(IDS_MSG_FTSWP, MB_ICONINFORMATION);
  420. if( pllVolID )
  421. *pllVolID = llNewVolID;
  422. }
  423. else
  424. DisplaySystemErrorMessage(IDS_ERR_FTSWP);
  425. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  426. return bResult;
  427. MY_CATCH_AND_THROW
  428. }
  429. /*
  430. Global function: FTVolSet
  431. Purpose: Create a volume set based on the given logical volumes
  432. Parameters: [IN] FT_LOGICAL_DISK_ID* arrVolID
  433. ID's of the members
  434. [IN] WORD wNumVols
  435. The number of members
  436. [OUT] FT_LOGICAL_DISK_ID* pllVolID
  437. Address where the logical volume ID of the new volume set is to be stored
  438. If NULL then don't return the ID
  439. Return value: TRUE if the volume set is created successfully
  440. */
  441. BOOL FTVolSet( FT_LOGICAL_DISK_ID* arrVolID, WORD wNumVols, FT_LOGICAL_DISK_ID* pllVolID /* = NULL */)
  442. {
  443. MY_TRY
  444. ASSERT( arrVolID );
  445. ASSERT( wNumVols >= 2 );
  446. CWaitCursor wc;
  447. BOOL bResult;
  448. FT_LOGICAL_DISK_ID llNewVolID;
  449. DisplayStatusBarMessage( IDS_STATUS_FTVOLSET );
  450. bResult = FtCreateLogicalDisk( FtVolumeSet, wNumVols, arrVolID, 0,
  451. NULL, &llNewVolID );
  452. if( bResult )
  453. {
  454. //AfxMessageBox( IDS_MSG_FTVOLSET, MB_ICONINFORMATION );
  455. if( pllVolID )
  456. *pllVolID = llNewVolID;
  457. }
  458. else
  459. DisplaySystemErrorMessage( IDS_ERR_FTVOLSET );
  460. DisplayStatusBarMessage( AFX_IDS_IDLEMESSAGE );
  461. return bResult;
  462. MY_CATCH_AND_THROW
  463. }
  464. BOOL FTQueryNTDeviceName( FT_LOGICAL_DISK_ID llVolID, CString& strNTName )
  465. {
  466. MY_TRY
  467. CWaitCursor wc;
  468. HANDLE h;
  469. FT_QUERY_NT_DEVICE_NAME_FOR_LOGICAL_DISK_INPUT Input;
  470. ULONG ulOutputSize;
  471. PFT_QUERY_NT_DEVICE_NAME_FOR_LOGICAL_DISK_OUTPUT pOutput;
  472. BOOL b;
  473. ULONG ulBytes;
  474. h = CreateFile(_T("\\\\.\\FtControl"), GENERIC_READ,
  475. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  476. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  477. INVALID_HANDLE_VALUE);
  478. if (h == INVALID_HANDLE_VALUE)
  479. return FALSE;
  480. Input.RootLogicalDiskId = llVolID;
  481. ulOutputSize = MAX_PATH;
  482. pOutput = (PFT_QUERY_NT_DEVICE_NAME_FOR_LOGICAL_DISK_OUTPUT)LocalAlloc(0, ulOutputSize);
  483. if (!pOutput)
  484. {
  485. CloseHandle(h);
  486. return FALSE;
  487. }
  488. b = DeviceIoControl(h, FT_QUERY_NT_DEVICE_NAME_FOR_LOGICAL_DISK, &Input,
  489. sizeof(Input), pOutput, ulOutputSize, &ulBytes, NULL);
  490. CloseHandle(h);
  491. if (!b )
  492. {
  493. LocalFree(pOutput);
  494. return FALSE;
  495. }
  496. CopyW2Str( strNTName, pOutput->NtDeviceName, pOutput->NumberOfCharactersInNtDeviceName );
  497. LocalFree(pOutput);
  498. return TRUE;
  499. MY_CATCH_AND_THROW
  500. }
  501. /*
  502. Global function: FTGetDisksSet
  503. Purpose: Retrieves all disks the logical volume is located on
  504. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  505. The ID of the logical volume
  506. [OUT] CULONGSet& setDisks
  507. The set of disks
  508. Return value: TRUE if the functions succeeds
  509. */
  510. BOOL FTGetDisksSet( FT_LOGICAL_DISK_ID llVolID, CULONGSet& setDisks )
  511. {
  512. MY_TRY
  513. CWaitCursor wc;
  514. FT_LOGICAL_DISK_TYPE nVolType;
  515. LONGLONG llVolSize;
  516. WORD numMembers;
  517. FT_LOGICAL_DISK_ID members[100];
  518. CHAR stateInfo[100];
  519. CHAR configInfo[100];
  520. setDisks.RemoveAll();
  521. // Read all information related to this logical volume
  522. BOOL b = FtQueryLogicalDiskInformation ( llVolID,
  523. &nVolType,
  524. &llVolSize,
  525. 100,
  526. members,
  527. &numMembers,
  528. sizeof(configInfo),
  529. &configInfo,
  530. sizeof(stateInfo),
  531. &stateInfo );
  532. if(!b)
  533. return FALSE;
  534. if( nVolType == FtPartition )
  535. {
  536. setDisks.Add( ((PFT_PARTITION_CONFIGURATION_INFORMATION)configInfo)->DiskNumber );
  537. return TRUE;
  538. }
  539. // The disks set is the reunion of all members disk sets
  540. for( WORD i = 0; i < numMembers; i++ )
  541. {
  542. CULONGSet setMemberDisks;
  543. if( !FTGetDisksSet( members[i], setMemberDisks ) )
  544. return FALSE;
  545. setDisks += setMemberDisks;
  546. }
  547. return TRUE;
  548. MY_CATCH_AND_THROW
  549. }
  550. /*
  551. Global function: FTQueryVolumeName
  552. Purpose: Retrieve the volume name of a logical volume
  553. The volume name should be like this: "\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
  554. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  555. The ID of the logical volume
  556. [OUT] CString& strVolumeName
  557. Reference to a string to receive the volume name
  558. Return value: TRUE if the functions succeeds
  559. */
  560. BOOL FTQueryVolumeName( FT_LOGICAL_DISK_ID llVolID, CString& strVolumeName )
  561. {
  562. MY_TRY
  563. CWaitCursor wc;
  564. CString strNTName;
  565. if (!FTQueryNTDeviceName( llVolID, strNTName ) )
  566. return FALSE;
  567. TCHAR cDriveLetter;
  568. return QueryDriveLetterAndVolumeName( strNTName, cDriveLetter, strVolumeName );
  569. MY_CATCH_AND_THROW
  570. }
  571. /*
  572. Global function: FTDelete
  573. Purpose: Delete a logical volume by deleting all its physical partitions
  574. Parameters: [IN] FT_LOGICAL_DISK_ID llVolID
  575. The ID of the logical volume
  576. Return value: TRUE if all its physical partitions were deleted
  577. */
  578. BOOL FTDelete( FT_LOGICAL_DISK_ID llVolID )
  579. {
  580. MY_TRY
  581. CWaitCursor wc;
  582. FT_LOGICAL_DISK_TYPE nVolType;
  583. LONGLONG llVolSize;
  584. WORD numMembers;
  585. FT_LOGICAL_DISK_ID members[100];
  586. CHAR stateInfo[100];
  587. CHAR configInfo[100];
  588. // Read all information related to this logical volume
  589. BOOL b = FtQueryLogicalDiskInformation ( llVolID,
  590. &nVolType,
  591. &llVolSize,
  592. 100,
  593. members,
  594. &numMembers,
  595. sizeof(configInfo),
  596. &configInfo,
  597. sizeof(stateInfo),
  598. &stateInfo );
  599. if(!b)
  600. {
  601. ::DisplaySystemErrorMessage( IDS_ERR_RETRIEVING_VOL_INFO );
  602. return FALSE;
  603. }
  604. if( nVolType == FtPartition )
  605. {
  606. CDiskMap diskMap( ((PFT_PARTITION_CONFIGURATION_INFORMATION)configInfo)->DiskNumber );
  607. return diskMap.DeletePartition( ((PFT_PARTITION_CONFIGURATION_INFORMATION)configInfo)->ByteOffset );
  608. }
  609. // Delete all members
  610. BOOL bResult = TRUE;
  611. for( WORD i = 0; i < numMembers; i++ )
  612. bResult = FTDelete( members[i] ) && bResult;
  613. return bResult;
  614. MY_CATCH_AND_THROW
  615. }