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.

939 lines
24 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. ftapi.c
  5. Abstract:
  6. This implements the FT API services.
  7. Author:
  8. Norbert Kusters 16-May-1995
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include <windows.h>
  13. #include <winioctl.h>
  14. #include <ntddft2.h>
  15. #include <ftapi.h>
  16. BOOL
  17. FtCreatePartitionLogicalDisk(
  18. IN HANDLE PartitionHandle,
  19. OUT PFT_LOGICAL_DISK_ID NewLogicalDiskId
  20. )
  21. /*++
  22. Routine Description:
  23. This routine creates a new logical disk from a single partition.
  24. Arguments:
  25. PartitionHandle - Supplies a handle to the partition.
  26. NewLogicalDiskId - Returns the new logical disk id.
  27. Return Value:
  28. FALSE - Failure.
  29. TRUE - Success.
  30. --*/
  31. {
  32. BOOL b;
  33. FT_CREATE_PARTITION_LOGICAL_DISK_OUTPUT output;
  34. DWORD bytes;
  35. b = DeviceIoControl(PartitionHandle, FT_CREATE_PARTITION_LOGICAL_DISK,
  36. NULL, 0, &output, sizeof(output),
  37. &bytes, NULL);
  38. *NewLogicalDiskId = output.NewLogicalDiskId;
  39. return b;
  40. }
  41. BOOL
  42. FtCreateLogicalDisk(
  43. IN FT_LOGICAL_DISK_TYPE LogicalDiskType,
  44. IN WORD NumberOfMembers,
  45. IN PFT_LOGICAL_DISK_ID RootLogicalDiskIds,
  46. IN WORD ConfigurationInformationSize,
  47. IN PVOID ConfigurationInformation,
  48. OUT PFT_LOGICAL_DISK_ID NewLogicalDiskId
  49. )
  50. /*++
  51. Routine Description:
  52. This routine creates a new logical disk.
  53. Arguments:
  54. LogicalDiskType - Supplies the logical disk type.
  55. NumberOfMembers - Supplies the number of members.
  56. RootLogicalDiskIds - Supplies the array of members.
  57. ConfigurationInformationSize - Supplies the number of bytes in the
  58. configuration information.
  59. ConfigurationInformation - Supplies the configuration information.
  60. NewLogicalDiskId - Returns the new logical disk id.
  61. Return Value:
  62. FALSE - Failure.
  63. TRUE - Success.
  64. --*/
  65. {
  66. HANDLE h;
  67. DWORD inputBufferSize;
  68. PFT_CREATE_LOGICAL_DISK_INPUT input;
  69. FT_CREATE_LOGICAL_DISK_OUTPUT output;
  70. WORD i;
  71. BOOL b;
  72. DWORD bytes;
  73. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  74. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  75. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  76. INVALID_HANDLE_VALUE);
  77. if (h == INVALID_HANDLE_VALUE) {
  78. return FALSE;
  79. }
  80. inputBufferSize = FIELD_OFFSET(FT_CREATE_LOGICAL_DISK_INPUT, MemberArray) +
  81. NumberOfMembers*sizeof(FT_LOGICAL_DISK_ID) +
  82. ConfigurationInformationSize;
  83. input = (PFT_CREATE_LOGICAL_DISK_INPUT) LocalAlloc(0, inputBufferSize);
  84. if (!input) {
  85. CloseHandle(h);
  86. return FALSE;
  87. }
  88. input->LogicalDiskType = LogicalDiskType;
  89. input->NumberOfMembers = NumberOfMembers;
  90. input->ConfigurationInformationSize = ConfigurationInformationSize;
  91. for (i = 0; i < NumberOfMembers; i++) {
  92. input->MemberArray[i] = RootLogicalDiskIds[i];
  93. }
  94. CopyMemory(&input->MemberArray[i], ConfigurationInformation,
  95. ConfigurationInformationSize);
  96. b = DeviceIoControl(h, FT_CREATE_LOGICAL_DISK, input,
  97. inputBufferSize, &output, sizeof(output),
  98. &bytes, NULL);
  99. *NewLogicalDiskId = output.NewLogicalDiskId;
  100. LocalFree(input);
  101. CloseHandle(h);
  102. return b;
  103. }
  104. BOOL
  105. FtInitializeLogicalDisk(
  106. IN FT_LOGICAL_DISK_ID RootLogicalDiskId,
  107. IN BOOL RegenerateOrphans
  108. )
  109. /*++
  110. Routine Description:
  111. This routine initializes the given root logical disk.
  112. Arguments:
  113. RootLogicalDiskId - Supplies the root logical disk id to initialize.
  114. RegenerateOrphans - Supplies whether or not to try and regenerate
  115. orphans.
  116. Return Value:
  117. FALSE - Failure.
  118. TRUE - Success.
  119. --*/
  120. {
  121. HANDLE h;
  122. FT_INITIALIZE_LOGICAL_DISK_INPUT input;
  123. BOOL b;
  124. DWORD bytes;
  125. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  126. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  127. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  128. INVALID_HANDLE_VALUE);
  129. if (h == INVALID_HANDLE_VALUE) {
  130. return FALSE;
  131. }
  132. input.RootLogicalDiskId = RootLogicalDiskId;
  133. input.RegenerateOrphans = (RegenerateOrphans != FALSE);
  134. b = DeviceIoControl(h, FT_INITIALIZE_LOGICAL_DISK, &input, sizeof(input),
  135. NULL, 0, &bytes, NULL);
  136. CloseHandle(h);
  137. return b;
  138. }
  139. BOOL
  140. FtBreakLogicalDisk(
  141. IN FT_LOGICAL_DISK_ID RootLogicalDiskId
  142. )
  143. /*++
  144. Routine Description:
  145. This routine breaks a given logical disk into its constituents.
  146. Arguments:
  147. RootLogicalDiskId - Supplies the root logical disk id to break.
  148. Return Value:
  149. FALSE - Failure.
  150. TRUE - Success.
  151. --*/
  152. {
  153. HANDLE h;
  154. FT_BREAK_LOGICAL_DISK_INPUT input;
  155. BOOL b;
  156. DWORD bytes;
  157. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  158. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  159. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  160. INVALID_HANDLE_VALUE);
  161. if (h == INVALID_HANDLE_VALUE) {
  162. return FALSE;
  163. }
  164. input.RootLogicalDiskId = RootLogicalDiskId;
  165. b = DeviceIoControl(h, FT_BREAK_LOGICAL_DISK, &input, sizeof(input), NULL,
  166. 0, &bytes, NULL);
  167. CloseHandle(h);
  168. return b;
  169. }
  170. BOOL
  171. FtEnumerateLogicalDisks(
  172. IN DWORD ArraySize,
  173. OUT PFT_LOGICAL_DISK_ID RootLogicalDiskIds, /* OPTIONAL */
  174. OUT PDWORD NumberOfRootLogicalDiskIds
  175. )
  176. /*++
  177. Routine Description:
  178. This routine enumerates all of the root logical disk ids in the system.
  179. If the 'RootLogicalDiskIds' is not present then this routine just returns
  180. the number of root logical disk ids in 'NumberOfRootLogicalDiskIds'.
  181. Arguments:
  182. ArraySize - Supplies the number of root logical disk ids that
  183. the given array can hold.
  184. RootLogicalDiskIds - Returns an array of root logical disk ids.
  185. NumberOfRootLogicalDiskIds - Returns the number of root logical disk ids.
  186. Return Value:
  187. FALSE - Failure.
  188. TRUE - Success.
  189. --*/
  190. {
  191. HANDLE h;
  192. DWORD outputSize;
  193. PFT_ENUMERATE_LOGICAL_DISKS_OUTPUT poutput;
  194. BOOL b;
  195. DWORD bytes;
  196. DWORD i;
  197. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  198. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  199. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  200. INVALID_HANDLE_VALUE);
  201. if (h == INVALID_HANDLE_VALUE) {
  202. return FALSE;
  203. }
  204. outputSize = sizeof(FT_ENUMERATE_LOGICAL_DISKS_OUTPUT);
  205. if (RootLogicalDiskIds) {
  206. outputSize += ArraySize*sizeof(FT_LOGICAL_DISK_ID);
  207. }
  208. poutput = LocalAlloc(0, outputSize);
  209. if (!poutput) {
  210. CloseHandle(h);
  211. return FALSE;
  212. }
  213. b = DeviceIoControl(h, FT_ENUMERATE_LOGICAL_DISKS, NULL, 0, poutput,
  214. outputSize, &bytes, NULL);
  215. CloseHandle(h);
  216. *NumberOfRootLogicalDiskIds = poutput->NumberOfRootLogicalDisks;
  217. if (!b) {
  218. if (GetLastError() == ERROR_MORE_DATA && !RootLogicalDiskIds) {
  219. return TRUE;
  220. }
  221. LocalFree(poutput);
  222. return b;
  223. }
  224. if (RootLogicalDiskIds &&
  225. *NumberOfRootLogicalDiskIds <= ArraySize) {
  226. for (i = 0; i < *NumberOfRootLogicalDiskIds; i++) {
  227. RootLogicalDiskIds[i] = poutput->RootLogicalDiskIds[i];
  228. }
  229. }
  230. LocalFree(poutput);
  231. return b;
  232. }
  233. BOOL
  234. FtQueryLogicalDiskInformation(
  235. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  236. OUT PFT_LOGICAL_DISK_TYPE LogicalDiskType, /* OPTIONAL */
  237. OUT PLONGLONG VolumeSize, /* OPTIONAL */
  238. IN WORD MembersArraySize,
  239. OUT PFT_LOGICAL_DISK_ID Members, /* OPTIONAL */
  240. OUT PWORD NumberOfMembers, /* OPTIONAL */
  241. IN WORD ConfigurationInformationSize,
  242. OUT PVOID ConfigurationInformation, /* OPTIONAL */
  243. IN WORD StateInformationSize,
  244. OUT PVOID StateInformation /* OPTIONAL */
  245. )
  246. /*++
  247. Routine Description:
  248. This routine returns information for the given logical disk.
  249. Arguments:
  250. LogicalDiskId - Supplies the logical disk id.
  251. LogicalDiskType - Returns the logical disk type.
  252. VolumeSize - Returns the size of the volume.
  253. MembersArraySize - Supplies the size of the members array.
  254. Members - Returns the members of the logical disk.
  255. NumberOfMembers - Returns the number of members for this
  256. logical disk.
  257. ConfigurationInformationSize - Supplies the configuration information
  258. size.
  259. ConfigurationInformation - Returns the configuration information.
  260. StateInformationSize - Supplies the state information size.
  261. StateInformation - Returns the state information.
  262. Return Value:
  263. FALSE - Failure.
  264. TRUE - Success.
  265. --*/
  266. {
  267. HANDLE h;
  268. FT_QUERY_LOGICAL_DISK_INFORMATION_INPUT input;
  269. DWORD outputSize;
  270. PFT_QUERY_LOGICAL_DISK_INFORMATION_OUTPUT output;
  271. BOOL b;
  272. DWORD bytes;
  273. DWORD i;
  274. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  275. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  276. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  277. INVALID_HANDLE_VALUE);
  278. if (h == INVALID_HANDLE_VALUE) {
  279. return FALSE;
  280. }
  281. input.LogicalDiskId = LogicalDiskId;
  282. outputSize = sizeof(FT_QUERY_LOGICAL_DISK_INFORMATION_OUTPUT);
  283. output = LocalAlloc(0, outputSize);
  284. if (!output) {
  285. CloseHandle(h);
  286. return FALSE;
  287. }
  288. b = DeviceIoControl(h, FT_QUERY_LOGICAL_DISK_INFORMATION, &input,
  289. sizeof(input), output, outputSize, &bytes, NULL);
  290. if (!b && GetLastError() != ERROR_MORE_DATA) {
  291. LocalFree(output);
  292. CloseHandle(h);
  293. return FALSE;
  294. }
  295. outputSize = FIELD_OFFSET(FT_QUERY_LOGICAL_DISK_INFORMATION_OUTPUT,
  296. MemberArray) +
  297. output->NumberOfMembers*sizeof(FT_LOGICAL_DISK_ID) +
  298. output->ConfigurationInformationSize +
  299. output->StateInformationSize;
  300. LocalFree(output);
  301. output = LocalAlloc(0, outputSize);
  302. if (!output) {
  303. CloseHandle(h);
  304. return FALSE;
  305. }
  306. b = DeviceIoControl(h, FT_QUERY_LOGICAL_DISK_INFORMATION, &input,
  307. sizeof(input), output, outputSize, &bytes, NULL);
  308. CloseHandle(h);
  309. if (!b) {
  310. return FALSE;
  311. }
  312. if (LogicalDiskType) {
  313. *LogicalDiskType = output->LogicalDiskType;
  314. }
  315. if (VolumeSize) {
  316. *VolumeSize = output->VolumeSize;
  317. }
  318. if (Members) {
  319. if (output->NumberOfMembers > MembersArraySize) {
  320. LocalFree(output);
  321. SetLastError(ERROR_MORE_DATA);
  322. return FALSE;
  323. }
  324. for (i = 0; i < output->NumberOfMembers; i++) {
  325. Members[i] = output->MemberArray[i];
  326. }
  327. }
  328. if (NumberOfMembers) {
  329. *NumberOfMembers = output->NumberOfMembers;
  330. }
  331. if (ConfigurationInformation) {
  332. if (ConfigurationInformationSize <
  333. output->ConfigurationInformationSize) {
  334. LocalFree(output);
  335. SetLastError(ERROR_MORE_DATA);
  336. return FALSE;
  337. }
  338. CopyMemory(ConfigurationInformation,
  339. &output->MemberArray[output->NumberOfMembers],
  340. output->ConfigurationInformationSize);
  341. }
  342. if (StateInformation) {
  343. if (StateInformationSize < output->StateInformationSize) {
  344. LocalFree(output);
  345. SetLastError(ERROR_MORE_DATA);
  346. return FALSE;
  347. }
  348. CopyMemory(StateInformation,
  349. (PCHAR) &output->MemberArray[output->NumberOfMembers] +
  350. output->ConfigurationInformationSize,
  351. output->StateInformationSize);
  352. }
  353. LocalFree(output);
  354. return TRUE;
  355. }
  356. BOOL
  357. FtOrphanLogicalDiskMember(
  358. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  359. IN WORD MemberNumberToOrphan
  360. )
  361. /*++
  362. Routine Description:
  363. This routine orphans a member of a logical disk.
  364. Arguments:
  365. LogicalDiskId - Supplies the logical disk id.
  366. MemberNumberToOrphan - Supplies the member number to orphan.
  367. Return Value:
  368. FALSE - Failure.
  369. TRUE - Success.
  370. --*/
  371. {
  372. HANDLE h;
  373. FT_ORPHAN_LOGICAL_DISK_MEMBER_INPUT input;
  374. BOOL b;
  375. DWORD bytes;
  376. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  377. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  378. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  379. INVALID_HANDLE_VALUE);
  380. if (h == INVALID_HANDLE_VALUE) {
  381. return FALSE;
  382. }
  383. input.LogicalDiskId = LogicalDiskId;
  384. input.MemberNumberToOrphan = MemberNumberToOrphan;
  385. b = DeviceIoControl(h, FT_ORPHAN_LOGICAL_DISK_MEMBER, &input,
  386. sizeof(input), NULL, 0, &bytes, NULL);
  387. CloseHandle(h);
  388. return b;
  389. }
  390. BOOL
  391. FtReplaceLogicalDiskMember(
  392. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  393. IN WORD MemberNumberToReplace,
  394. IN FT_LOGICAL_DISK_ID NewMemberLogicalDiskId,
  395. OUT PFT_LOGICAL_DISK_ID NewLogicalDiskId /* OPTIONAL */
  396. )
  397. /*++
  398. Routine Description:
  399. This routine replaces a member of a logical disk.
  400. Arguments:
  401. LogicalDiskId - Supplies the logical disk id.
  402. MemberNumberToReplace - Supplies the member number to replace.
  403. NewMemberLogicalDiskId - Supplies the new member.
  404. NewLogicalDiskId - Returns the new logical disk id for the disk set
  405. that contains the replaced member.
  406. Return Value:
  407. FALSE - Failure.
  408. TRUE - Success.
  409. --*/
  410. {
  411. HANDLE h;
  412. FT_REPLACE_LOGICAL_DISK_MEMBER_INPUT input;
  413. FT_REPLACE_LOGICAL_DISK_MEMBER_OUTPUT output;
  414. BOOL b;
  415. DWORD bytes;
  416. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  417. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  418. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  419. INVALID_HANDLE_VALUE);
  420. if (h == INVALID_HANDLE_VALUE) {
  421. return FALSE;
  422. }
  423. input.LogicalDiskId = LogicalDiskId;
  424. input.MemberNumberToReplace = MemberNumberToReplace;
  425. input.NewMemberLogicalDiskId = NewMemberLogicalDiskId;
  426. b = DeviceIoControl(h, FT_REPLACE_LOGICAL_DISK_MEMBER, &input,
  427. sizeof(input), &output, sizeof(output), &bytes, NULL);
  428. CloseHandle(h);
  429. if (NewLogicalDiskId) {
  430. *NewLogicalDiskId = output.NewLogicalDiskId;
  431. }
  432. return b;
  433. }
  434. BOOL
  435. FtQueryLogicalDiskId(
  436. IN HANDLE RootLogicalDiskHandle,
  437. OUT PFT_LOGICAL_DISK_ID RootLogicalDiskId
  438. )
  439. /*++
  440. Routine Description:
  441. This routine returns the root logical disk id for a given disk.
  442. Arguments:
  443. RootLogicalDiskHandle - Supplies a handle to a logical disk.
  444. RootLogicalDiskId - Returns a logical disk id for the given logical
  445. disk.
  446. Return Value:
  447. FALSE - Failure.
  448. TRUE - Success.
  449. --*/
  450. {
  451. BOOL b;
  452. FT_QUERY_LOGICAL_DISK_ID_OUTPUT output;
  453. DWORD bytes;
  454. b = DeviceIoControl(RootLogicalDiskHandle, FT_QUERY_LOGICAL_DISK_ID,
  455. NULL, 0, &output, sizeof(output), &bytes, NULL);
  456. *RootLogicalDiskId = output.RootLogicalDiskId;
  457. return b;
  458. }
  459. BOOL
  460. FtQueryStickyDriveLetter(
  461. IN FT_LOGICAL_DISK_ID RootLogicalDiskId,
  462. OUT PUCHAR DriveLetter
  463. )
  464. /*++
  465. Routine Description:
  466. This routine queries the sticky drive letter for the given disk id.
  467. Arguments:
  468. RootLogicalDiskId - Supplies the logical disk id.
  469. DriveLetter - Returns the sticky drive letter.
  470. Return Value:
  471. FALSE - Failure.
  472. TRUE - Success.
  473. --*/
  474. {
  475. HANDLE h;
  476. FT_QUERY_DRIVE_LETTER_FOR_LOGICAL_DISK_INPUT input;
  477. FT_QUERY_DRIVE_LETTER_FOR_LOGICAL_DISK_OUTPUT output;
  478. BOOL b;
  479. DWORD bytes;
  480. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  481. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  482. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  483. INVALID_HANDLE_VALUE);
  484. if (h == INVALID_HANDLE_VALUE) {
  485. return FALSE;
  486. }
  487. input.RootLogicalDiskId = RootLogicalDiskId;
  488. b = DeviceIoControl(h, FT_QUERY_DRIVE_LETTER_FOR_LOGICAL_DISK, &input,
  489. sizeof(input), &output, sizeof(output), &bytes, NULL);
  490. CloseHandle(h);
  491. *DriveLetter = output.DriveLetter;
  492. return b;
  493. }
  494. BOOL
  495. FtSetStickyDriveLetter(
  496. IN FT_LOGICAL_DISK_ID RootLogicalDiskId,
  497. IN UCHAR DriveLetter
  498. )
  499. /*++
  500. Routine Description:
  501. This routine sets the sticky drive letter for the given disk id.
  502. Arguments:
  503. RootLogicalDiskId - Supplies the logical disk id.
  504. DriveLetter - Supplies the sticky drive letter.
  505. Return Value:
  506. FALSE - Failure.
  507. TRUE - Success.
  508. --*/
  509. {
  510. HANDLE h;
  511. FT_SET_DRIVE_LETTER_FOR_LOGICAL_DISK_INPUT input;
  512. BOOL b;
  513. DWORD bytes;
  514. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  515. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  516. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  517. INVALID_HANDLE_VALUE);
  518. if (h == INVALID_HANDLE_VALUE) {
  519. return FALSE;
  520. }
  521. input.RootLogicalDiskId = RootLogicalDiskId;
  522. input.DriveLetter = DriveLetter;
  523. b = DeviceIoControl(h, FT_SET_DRIVE_LETTER_FOR_LOGICAL_DISK, &input,
  524. sizeof(input), NULL, 0, &bytes, NULL);
  525. CloseHandle(h);
  526. return b;
  527. }
  528. BOOL
  529. FtChangeNotify(
  530. )
  531. /*++
  532. Routine Description:
  533. This routine returns when a change to the FT configuration occurrs.
  534. Arguments:
  535. None.
  536. Return Value:
  537. FALSE - Failure.
  538. TRUE - Success.
  539. --*/
  540. {
  541. HANDLE h;
  542. BOOL b;
  543. DWORD bytes;
  544. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  545. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  546. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  547. INVALID_HANDLE_VALUE);
  548. if (h == INVALID_HANDLE_VALUE) {
  549. return FALSE;
  550. }
  551. b = DeviceIoControl(h, FT_CHANGE_NOTIFY, NULL, 0, NULL, 0, &bytes, NULL);
  552. CloseHandle(h);
  553. return b;
  554. }
  555. BOOL
  556. FtStopSyncOperations(
  557. IN FT_LOGICAL_DISK_ID RootLogicalDiskId
  558. )
  559. /*++
  560. Routine Description:
  561. This routine stops all sync operations on the logical disk.
  562. Arguments:
  563. RootLogicalDiskId - Supplies the root logical disk id.
  564. Return Value:
  565. FALSE - Failure.
  566. TRUE - Success.
  567. --*/
  568. {
  569. HANDLE h;
  570. FT_STOP_SYNC_OPERATIONS_INPUT input;
  571. BOOL b;
  572. DWORD bytes;
  573. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  574. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  575. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  576. INVALID_HANDLE_VALUE);
  577. if (h == INVALID_HANDLE_VALUE) {
  578. return FALSE;
  579. }
  580. input.RootLogicalDiskId = RootLogicalDiskId;
  581. b = DeviceIoControl(h, FT_STOP_SYNC_OPERATIONS, &input, sizeof(input),
  582. NULL, 0, &bytes, NULL);
  583. CloseHandle(h);
  584. return b;
  585. }
  586. BOOL
  587. FtCheckIo(
  588. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  589. OUT PBOOL IsIoOk
  590. )
  591. /*++
  592. Routine Description:
  593. This routine returns whether or not enough members of the given logical
  594. disk are online so that IO is possible on all parts of the volume.
  595. Arguments:
  596. LogicalDiskId - Supplies the logical disk id.
  597. IsIoOk - Returns whether or not IO is possible on the entire
  598. logical disk.
  599. Return Value:
  600. FALSE - Failure.
  601. TRUE - Success.
  602. --*/
  603. {
  604. HANDLE h;
  605. FT_CHECK_IO_INPUT input;
  606. FT_CHECK_IO_OUTPUT output;
  607. BOOL b;
  608. DWORD bytes;
  609. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  610. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  611. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  612. INVALID_HANDLE_VALUE);
  613. if (h == INVALID_HANDLE_VALUE) {
  614. return FALSE;
  615. }
  616. input.LogicalDiskId = LogicalDiskId;
  617. b = DeviceIoControl(h, FT_CHECK_IO, &input, sizeof(input), &output,
  618. sizeof(output), &bytes, NULL);
  619. CloseHandle(h);
  620. *IsIoOk = output.IsIoOk;
  621. return b;
  622. }
  623. BOOL
  624. FtCheckDriver(
  625. OUT PBOOL IsDriverLoaded
  626. )
  627. /*++
  628. Routine Description:
  629. This routine returns whether or not the FTDISK driver is loaded.
  630. Arguments:
  631. IsDriverLoaded - Returns whether or not the driver is loaded.
  632. Return Value:
  633. FALSE - Failure.
  634. TRUE - Success.
  635. --*/
  636. {
  637. HANDLE h;
  638. h = CreateFile("\\\\.\\FtControl", GENERIC_READ | GENERIC_WRITE,
  639. FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
  640. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
  641. INVALID_HANDLE_VALUE);
  642. if (h == INVALID_HANDLE_VALUE) {
  643. if (GetLastError() == ERROR_FILE_NOT_FOUND) {
  644. *IsDriverLoaded = FALSE;
  645. return TRUE;
  646. }
  647. return FALSE;
  648. }
  649. CloseHandle(h);
  650. *IsDriverLoaded = TRUE;
  651. return TRUE;
  652. }