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.

3150 lines
67 KiB

  1. /*++
  2. Copyright (C) 1991-5 Microsoft Corporation
  3. Module Name:
  4. ftdisk.h
  5. Abstract:
  6. These are the structures that FtDisk driver
  7. uses to support IO to NTFT volumes.
  8. Notes:
  9. Revision History:
  10. --*/
  11. extern "C" {
  12. #include "stdio.h"
  13. #include <ntdskreg.h>
  14. #include <ntddft.h>
  15. #include <ntddft2.h>
  16. #include <ntdddisk.h>
  17. #include "ftlog.h"
  18. #include <wdmguid.h>
  19. #include <devguid.h>
  20. #include <stdarg.h>
  21. #include <volmgr.h>
  22. #include <mountdev.h>
  23. #include <ntddvol.h>
  24. #include <wmilib.h>
  25. }
  26. #if DBG
  27. extern "C" {
  28. VOID
  29. FtDebugPrint(
  30. ULONG DebugPrintLevel,
  31. PCCHAR DebugMessage,
  32. ...
  33. );
  34. extern ULONG FtDebug;
  35. }
  36. #define DebugPrint(X) FtDebugPrint X
  37. #else
  38. #define DebugPrint(X)
  39. #endif // DBG
  40. #ifdef POOL_TAGGING
  41. #undef ExAllocatePool
  42. #undef ExAllocatePoolWithQuota
  43. #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'tFcS')
  44. #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,'tFcS')
  45. #define FTDISK_TAG_IOCTL_BUFFER 'iFcS'
  46. #endif
  47. #define STRIPE_SIZE ((ULONG) 0x00010000)
  48. #define DISK_REGISTRY_KEY_W L"\\Registry\\Machine\\System\\DISK"
  49. #define FT_STATE_REGISTRY_KEY L"\\Registry\\Machine\\System\\DISK\\FtState"
  50. //
  51. // NEC98 machines have drive-letter A and B which are non FD too.
  52. //
  53. #define FirstDriveLetter (IsNEC_98 ? 'A' : 'C')
  54. #define LastDriveLetter 'Z'
  55. class TRANSFER_PACKET;
  56. typedef TRANSFER_PACKET* PTRANSFER_PACKET;
  57. typedef
  58. VOID
  59. (*FT_TRANSFER_COMPLETION_ROUTINE)(
  60. IN PTRANSFER_PACKET TransferPacket
  61. );
  62. typedef
  63. VOID
  64. (*FT_COMPLETION_ROUTINE)(
  65. IN PVOID Context,
  66. IN NTSTATUS Status
  67. );
  68. class FT_VOLUME;
  69. typedef FT_VOLUME* PFT_VOLUME;
  70. typedef struct _FT_COMPLETION_ROUTINE_CONTEXT {
  71. KSPIN_LOCK SpinLock;
  72. NTSTATUS Status;
  73. LONG RefCount;
  74. FT_COMPLETION_ROUTINE CompletionRoutine;
  75. PVOID Context;
  76. PFT_VOLUME ParentVolume;
  77. } FT_COMPLETION_ROUTINE_CONTEXT, *PFT_COMPLETION_ROUTINE_CONTEXT;
  78. class FT_BASE_CLASS;
  79. typedef FT_BASE_CLASS* PFT_BASE_CLASS;
  80. class FT_BASE_CLASS {
  81. public:
  82. static
  83. PVOID
  84. operator new(
  85. IN size_t Size
  86. );
  87. static
  88. VOID
  89. operator delete(
  90. IN PVOID MemPtr
  91. );
  92. };
  93. class VOLUME_EXTENSION;
  94. typedef VOLUME_EXTENSION* PVOLUME_EXTENSION;
  95. class ROOT_EXTENSION;
  96. typedef ROOT_EXTENSION* PROOT_EXTENSION;
  97. #include <ondisk.hxx>
  98. class TRANSFER_PACKET : public FT_BASE_CLASS {
  99. public:
  100. static
  101. PVOID
  102. operator new(
  103. IN size_t Size
  104. );
  105. static
  106. VOID
  107. operator delete(
  108. IN PVOID MemPtr
  109. );
  110. TRANSFER_PACKET(
  111. ) { _freeMdl = FALSE; _freeBuffer = FALSE; SpecialRead = 0;
  112. OriginalIrp = NULL; };
  113. virtual
  114. ~TRANSFER_PACKET(
  115. );
  116. BOOLEAN
  117. AllocateMdl(
  118. IN PVOID Buffer,
  119. IN ULONG Length
  120. );
  121. BOOLEAN
  122. AllocateMdl(
  123. IN ULONG Length
  124. );
  125. VOID
  126. FreeMdl(
  127. );
  128. // These fields must be filled in by the caller.
  129. PMDL Mdl;
  130. PIRP OriginalIrp;
  131. ULONG Length;
  132. LONGLONG Offset;
  133. FT_TRANSFER_COMPLETION_ROUTINE CompletionRoutine;
  134. PFT_VOLUME TargetVolume;
  135. PETHREAD Thread;
  136. UCHAR IrpFlags;
  137. BOOLEAN ReadPacket;
  138. UCHAR SpecialRead;
  139. // A spin lock which may be used to resolve contention for the
  140. // fields below. This spin lock must be initialized by the callee.
  141. KSPIN_LOCK SpinLock;
  142. // This field must be filled in by the callee.
  143. IO_STATUS_BLOCK IoStatus;
  144. // These fields are for use by the callee.
  145. LONG RefCount;
  146. LIST_ENTRY QueueEntry;
  147. private:
  148. BOOLEAN _freeMdl;
  149. BOOLEAN _freeBuffer;
  150. UCHAR _allocationType;
  151. };
  152. #define TP_SPECIAL_READ_PRIMARY (1)
  153. #define TP_SPECIAL_READ_SECONDARY (2)
  154. #define TP_ALLOCATION_STRIPE_POOL (1)
  155. #define TP_ALLOCATION_MIRROR_POOL (2)
  156. class DISPATCH_TP;
  157. typedef DISPATCH_TP* PDISPATCH_TP;
  158. class DISPATCH_TP : public TRANSFER_PACKET {
  159. public:
  160. DISPATCH_TP(
  161. ) {};
  162. PIRP Irp;
  163. PVOLUME_EXTENSION Extension;
  164. };
  165. class VOLUME_SET;
  166. typedef VOLUME_SET* PVOLUME_SET;
  167. class VOLSET_TP;
  168. typedef VOLSET_TP* PVOLSET_TP;
  169. class VOLSET_TP : public TRANSFER_PACKET {
  170. public:
  171. VOLSET_TP(
  172. ) {};
  173. PTRANSFER_PACKET MasterPacket;
  174. PVOLUME_SET VolumeSet;
  175. USHORT WhichMember;
  176. };
  177. class STRIPE;
  178. typedef STRIPE* PSTRIPE;
  179. class STRIPE_TP;
  180. typedef STRIPE_TP* PSTRIPE_TP;
  181. class STRIPE_TP : public TRANSFER_PACKET {
  182. public:
  183. STRIPE_TP(
  184. ) {};
  185. PTRANSFER_PACKET MasterPacket;
  186. PSTRIPE Stripe;
  187. USHORT WhichMember;
  188. };
  189. class OVERLAPPED_IO_MANAGER;
  190. typedef OVERLAPPED_IO_MANAGER* POVERLAPPED_IO_MANAGER;
  191. class OVERLAP_TP;
  192. typedef OVERLAP_TP* POVERLAP_TP;
  193. class OVERLAP_TP : public TRANSFER_PACKET {
  194. friend class OVERLAPPED_IO_MANAGER;
  195. public:
  196. OVERLAP_TP(
  197. ) { InQueue = FALSE; };
  198. virtual
  199. ~OVERLAP_TP(
  200. );
  201. private:
  202. BOOLEAN AllMembers;
  203. BOOLEAN InQueue;
  204. LIST_ENTRY OverlapQueue;
  205. LIST_ENTRY CompletionList;
  206. POVERLAPPED_IO_MANAGER OverlappedIoManager;
  207. };
  208. class MIRROR;
  209. typedef MIRROR* PMIRROR;
  210. class MIRROR_TP;
  211. typedef MIRROR_TP* PMIRROR_TP;
  212. class MIRROR_TP : public OVERLAP_TP {
  213. public:
  214. MIRROR_TP(
  215. ) { OneReadFailed = FALSE; };
  216. PTRANSFER_PACKET MasterPacket;
  217. PMIRROR Mirror;
  218. USHORT WhichMember;
  219. BOOLEAN OneReadFailed;
  220. PMIRROR_TP SecondWritePacket;
  221. FT_TRANSFER_COMPLETION_ROUTINE SavedCompletionRoutine;
  222. };
  223. class MIRROR_RECOVER_TP;
  224. typedef MIRROR_RECOVER_TP* PMIRROR_RECOVER_TP;
  225. class MIRROR_RECOVER_TP : public MIRROR_TP {
  226. public:
  227. MIRROR_RECOVER_TP(
  228. ) { PartialMdl = NULL; VerifyMdl = NULL; };
  229. virtual
  230. ~MIRROR_RECOVER_TP(
  231. );
  232. BOOLEAN
  233. AllocateMdls(
  234. IN ULONG Length
  235. );
  236. VOID
  237. FreeMdls(
  238. );
  239. PMDL PartialMdl;
  240. PMDL VerifyMdl;
  241. };
  242. class PARITY_IO_MANAGER;
  243. typedef PARITY_IO_MANAGER* PPARITY_IO_MANAGER;
  244. class PARITY_TP;
  245. typedef PARITY_TP* PPARITY_TP;
  246. class PARITY_TP : public TRANSFER_PACKET {
  247. friend class PARITY_IO_MANAGER;
  248. friend
  249. VOID
  250. UpdateParityCompletionRoutine(
  251. IN OUT PTRANSFER_PACKET TransferPacket
  252. );
  253. friend
  254. VOID
  255. ParityCarefulWritePhase1(
  256. IN OUT PTRANSFER_PACKET TransferPacket
  257. );
  258. public:
  259. PARITY_TP(
  260. ) {};
  261. private:
  262. BOOLEAN Idle;
  263. BOOLEAN OneWriteFailed;
  264. LIST_ENTRY OverlapQueue;
  265. LIST_ENTRY UpdateQueue;
  266. PPARITY_IO_MANAGER ParityIoManager;
  267. LONGLONG BucketNumber;
  268. };
  269. class PARITY_RECOVER_TP;
  270. typedef PARITY_RECOVER_TP* PPARITY_RECOVER_TP;
  271. class PARITY_RECOVER_TP : public PARITY_TP {
  272. public:
  273. PARITY_RECOVER_TP(
  274. ) {};
  275. PPARITY_TP MasterPacket;
  276. };
  277. class STRIPE_WP;
  278. typedef STRIPE_WP* PSTRIPE_WP;
  279. class SWP_TP;
  280. typedef SWP_TP* PSWP_TP;
  281. class SWP_TP : public OVERLAP_TP {
  282. public:
  283. SWP_TP(
  284. ) {};
  285. PTRANSFER_PACKET MasterPacket;
  286. PSTRIPE_WP StripeWithParity;
  287. USHORT WhichMember;
  288. FT_TRANSFER_COMPLETION_ROUTINE SavedCompletionRoutine;
  289. BOOLEAN OneReadFailed;
  290. };
  291. class SWP_RECOVER_TP;
  292. typedef SWP_RECOVER_TP* PSWP_RECOVER_TP;
  293. class SWP_RECOVER_TP : public SWP_TP {
  294. public:
  295. SWP_RECOVER_TP(
  296. ) { PartialMdl = NULL; VerifyMdl = NULL; };
  297. virtual
  298. ~SWP_RECOVER_TP(
  299. );
  300. BOOLEAN
  301. AllocateMdls(
  302. IN ULONG Length
  303. );
  304. VOID
  305. FreeMdls(
  306. );
  307. PMDL PartialMdl;
  308. PMDL VerifyMdl;
  309. PARITY_TP ParityPacket;
  310. };
  311. class SWP_WRITE_TP;
  312. typedef SWP_WRITE_TP* PSWP_WRITE_TP;
  313. class SWP_WRITE_TP : public SWP_TP {
  314. public:
  315. SWP_WRITE_TP(
  316. ) { ReadAndParityMdl = NULL; WriteMdl = NULL; };
  317. virtual
  318. ~SWP_WRITE_TP(
  319. );
  320. BOOLEAN
  321. AllocateMdls(
  322. IN ULONG Length
  323. );
  324. VOID
  325. FreeMdls(
  326. );
  327. PMDL ReadAndParityMdl;
  328. PMDL WriteMdl;
  329. FT_MEMBER_STATE TargetState;
  330. USHORT ParityMember;
  331. SWP_TP ReadWritePacket;
  332. PARITY_TP ParityPacket;
  333. };
  334. class SWP_REGENERATE_TP;
  335. typedef SWP_REGENERATE_TP *PSWP_REGENERATE_TP;
  336. class SWP_REGENERATE_TP : public TRANSFER_PACKET {
  337. public:
  338. SWP_REGENERATE_TP(
  339. ) {};
  340. PSWP_TP MasterPacket;
  341. USHORT WhichMember;
  342. LIST_ENTRY RegenPacketList;
  343. };
  344. class SWP_REBUILD_TP;
  345. typedef SWP_REBUILD_TP *PSWP_REBUILD_TP;
  346. class SWP_REBUILD_TP : public SWP_TP {
  347. public:
  348. SWP_REBUILD_TP(
  349. ) {};
  350. PFT_COMPLETION_ROUTINE_CONTEXT Context;
  351. BOOLEAN Initialize;
  352. };
  353. class REDISTRIBUTION;
  354. typedef REDISTRIBUTION *PREDISTRIBUTION;
  355. class REDISTRIBUTION_TP;
  356. typedef REDISTRIBUTION_TP* PREDISTRIBUTION_TP;
  357. class REDISTRIBUTION_TP : public TRANSFER_PACKET {
  358. public:
  359. REDISTRIBUTION_TP(
  360. ) {};
  361. PTRANSFER_PACKET MasterPacket;
  362. PREDISTRIBUTION Redistribution;
  363. USHORT WhichMember;
  364. };
  365. class REDISTRIBUTION_LOCK_TP;
  366. typedef REDISTRIBUTION_LOCK_TP* PREDISTRIBUTION_LOCK_TP;
  367. class REDISTRIBUTION_LOCK_TP : public OVERLAP_TP {
  368. public:
  369. REDISTRIBUTION_LOCK_TP(
  370. ) {};
  371. PTRANSFER_PACKET MasterPacket;
  372. PREDISTRIBUTION Redistribution;
  373. };
  374. class REDISTRIBUTION_SYNC_TP;
  375. typedef REDISTRIBUTION_SYNC_TP* PREDISTRIBUTION_SYNC_TP;
  376. class REDISTRIBUTION_SYNC_TP : public OVERLAP_TP {
  377. public:
  378. REDISTRIBUTION_SYNC_TP(
  379. ) {};
  380. PFT_COMPLETION_ROUTINE_CONTEXT Context;
  381. PREDISTRIBUTION Redistribution;
  382. REDISTRIBUTION_TP IoPacket;
  383. };
  384. class REDISTRIBUTION_CW_TP;
  385. typedef REDISTRIBUTION_CW_TP* PREDISTRIBUTION_CW_TP;
  386. class REDISTRIBUTION_CW_TP : public REDISTRIBUTION_TP {
  387. public:
  388. REDISTRIBUTION_CW_TP(
  389. ) { PartialMdl = NULL; VerifyMdl = NULL; };
  390. virtual
  391. ~REDISTRIBUTION_CW_TP(
  392. );
  393. BOOLEAN
  394. AllocateMdls(
  395. IN ULONG Length
  396. );
  397. VOID
  398. FreeMdls(
  399. );
  400. PMDL PartialMdl;
  401. PMDL VerifyMdl;
  402. };
  403. class OVERLAPPED_IO_MANAGER : public FT_BASE_CLASS {
  404. public:
  405. NTSTATUS
  406. Initialize(
  407. IN ULONG BucketSize
  408. );
  409. VOID
  410. AcquireIoRegion(
  411. IN OUT POVERLAP_TP TransferPacket,
  412. IN BOOLEAN AllMembers
  413. );
  414. VOID
  415. ReleaseIoRegion(
  416. IN OUT POVERLAP_TP TransferPacket
  417. );
  418. VOID
  419. PromoteToAllMembers(
  420. IN OUT POVERLAP_TP TransferPacket
  421. );
  422. OVERLAPPED_IO_MANAGER(
  423. ) { _spinLock = NULL; _ioQueue = NULL; };
  424. ~OVERLAPPED_IO_MANAGER(
  425. );
  426. private:
  427. ULONG _numQueues;
  428. ULONG _bucketSize;
  429. PKSPIN_LOCK _spinLock;
  430. PLIST_ENTRY _ioQueue;
  431. };
  432. class PARITY_IO_MANAGER : public FT_BASE_CLASS {
  433. friend
  434. VOID
  435. UpdateParityCompletionRoutine(
  436. IN OUT PTRANSFER_PACKET TransferPacket
  437. );
  438. friend
  439. VOID
  440. ParityCarefulWritePhase1(
  441. IN OUT PTRANSFER_PACKET TransferPacket
  442. );
  443. public:
  444. NTSTATUS
  445. Initialize(
  446. IN ULONG BucketSize,
  447. IN ULONG SectorSize
  448. );
  449. VOID
  450. StartReadForUpdateParity(
  451. IN LONGLONG Offset,
  452. IN ULONG Length,
  453. IN PFT_VOLUME TargetVolume,
  454. IN PETHREAD Thread,
  455. IN UCHAR IrpFlags
  456. );
  457. VOID
  458. UpdateParity(
  459. IN OUT PPARITY_TP TransferPacket
  460. );
  461. PARITY_IO_MANAGER(
  462. ) { _spinLock = NULL; _ioQueue = NULL; _ePacket = NULL; };
  463. ~PARITY_IO_MANAGER(
  464. );
  465. private:
  466. VOID
  467. CarefulWrite(
  468. IN OUT PPARITY_TP TransferPacket
  469. );
  470. ULONG _numQueues;
  471. ULONG _bucketSize;
  472. ULONG _sectorSize;
  473. PKSPIN_LOCK _spinLock;
  474. PLIST_ENTRY _ioQueue;
  475. //
  476. // Emergency packet.
  477. //
  478. PPARITY_TP _ePacket;
  479. BOOLEAN _ePacketInUse;
  480. BOOLEAN _ePacketQueueBeingServiced;
  481. LIST_ENTRY _ePacketQueue;
  482. KSPIN_LOCK _ePacketSpinLock;
  483. };
  484. class PARTITION;
  485. typedef PARTITION* PPARTITION;
  486. class FT_VOLUME : public FT_BASE_CLASS {
  487. friend
  488. VOID
  489. SetMemberStateWorker(
  490. IN PVOID Context
  491. );
  492. friend
  493. VOID
  494. FtVolumeNotifyWorker(
  495. IN PVOID FtVolume
  496. );
  497. public:
  498. VOID
  499. Initialize(
  500. IN OUT PROOT_EXTENSION RootExtension,
  501. IN FT_LOGICAL_DISK_ID LogicalDiskId
  502. );
  503. FT_LOGICAL_DISK_ID
  504. QueryLogicalDiskId(
  505. );
  506. VOID
  507. SetLogicalDiskId(
  508. IN FT_LOGICAL_DISK_ID NewLogicalDiskId
  509. );
  510. virtual
  511. VOID
  512. Notify(
  513. );
  514. virtual
  515. FT_LOGICAL_DISK_TYPE
  516. QueryLogicalDiskType(
  517. ) = 0;
  518. virtual
  519. USHORT
  520. QueryNumberOfMembers(
  521. ) = 0;
  522. virtual
  523. PFT_VOLUME
  524. GetMember(
  525. IN USHORT MemberNumber
  526. ) = 0;
  527. virtual
  528. NTSTATUS
  529. OrphanMember(
  530. IN USHORT MemberNumber,
  531. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  532. IN PVOID Context
  533. ) = 0;
  534. virtual
  535. NTSTATUS
  536. RegenerateMember(
  537. IN USHORT MemberNumber,
  538. IN OUT PFT_VOLUME NewMember,
  539. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  540. IN PVOID Context
  541. ) = 0;
  542. virtual
  543. VOID
  544. Transfer(
  545. IN OUT PTRANSFER_PACKET TransferPacket
  546. ) = 0;
  547. virtual
  548. VOID
  549. ReplaceBadSector(
  550. IN OUT PTRANSFER_PACKET TransferPacket
  551. ) = 0;
  552. virtual
  553. VOID
  554. StartSyncOperations(
  555. IN BOOLEAN RegenerateOrphans,
  556. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  557. IN PVOID Context
  558. ) = 0;
  559. virtual
  560. VOID
  561. StopSyncOperations(
  562. ) = 0;
  563. virtual
  564. VOID
  565. BroadcastIrp(
  566. IN PIRP Irp,
  567. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  568. IN PVOID Context
  569. ) = 0;
  570. virtual
  571. ULONG
  572. QuerySectorSize(
  573. ) = 0;
  574. virtual
  575. LONGLONG
  576. QueryVolumeSize(
  577. ) = 0;
  578. virtual
  579. PFT_VOLUME
  580. GetContainedLogicalDisk(
  581. IN FT_LOGICAL_DISK_ID LogicalDiskId
  582. ) = 0;
  583. virtual
  584. PFT_VOLUME
  585. GetContainedLogicalDisk(
  586. IN PDEVICE_OBJECT TargetObject
  587. ) = 0;
  588. virtual
  589. PFT_VOLUME
  590. GetContainedLogicalDisk(
  591. IN ULONG Signature,
  592. IN LONGLONG Offset
  593. ) = 0;
  594. virtual
  595. PFT_VOLUME
  596. GetParentLogicalDisk(
  597. IN PFT_VOLUME Volume
  598. ) = 0;
  599. virtual
  600. VOID
  601. SetDirtyBit(
  602. IN BOOLEAN IsDirty,
  603. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  604. IN PVOID Context
  605. ) = 0;
  606. virtual
  607. VOID
  608. SetMember(
  609. IN USHORT MemberNumber,
  610. IN PFT_VOLUME Member
  611. ) = 0;
  612. virtual
  613. BOOLEAN
  614. IsComplete(
  615. IN BOOLEAN IoPending
  616. ) = 0;
  617. virtual
  618. VOID
  619. CompleteNotification(
  620. IN BOOLEAN IoPending
  621. ) = 0;
  622. virtual
  623. NTSTATUS
  624. CheckIo(
  625. OUT PBOOLEAN IsIoOk
  626. ) = 0;
  627. virtual
  628. ULONG
  629. QueryNumberOfPartitions(
  630. ) = 0;
  631. virtual
  632. NTSTATUS
  633. SetPartitionType(
  634. IN UCHAR PartitionType
  635. ) = 0;
  636. virtual
  637. UCHAR
  638. QueryPartitionType(
  639. ) = 0;
  640. virtual
  641. UCHAR
  642. QueryStackSize(
  643. ) = 0;
  644. virtual
  645. VOID
  646. CreateLegacyNameLinks(
  647. IN PUNICODE_STRING DeviceName
  648. ) = 0;
  649. virtual
  650. BOOLEAN
  651. IsVolumeSuitableForRegenerate(
  652. IN USHORT MemberNumber,
  653. IN PFT_VOLUME Volume
  654. );
  655. virtual
  656. VOID
  657. NewStateArrival(
  658. IN PVOID NewStateInstance
  659. );
  660. virtual
  661. PDEVICE_OBJECT
  662. GetLeftmostPartitionObject(
  663. ) = 0;
  664. virtual
  665. NTSTATUS
  666. QueryDiskExtents(
  667. OUT PDISK_EXTENT* DiskExtents,
  668. OUT PULONG NumberOfDiskExtents
  669. ) = 0;
  670. virtual
  671. BOOLEAN
  672. QueryVolumeState(
  673. IN PFT_VOLUME Volume,
  674. OUT PFT_MEMBER_STATE State
  675. ) = 0;
  676. virtual
  677. NTSTATUS
  678. QueryPhysicalOffsets(
  679. IN LONGLONG LogicalOffset,
  680. OUT PVOLUME_PHYSICAL_OFFSET* PhysicalOffsets,
  681. OUT PULONG NumberOfPhysicalOffsets
  682. ) = 0;
  683. virtual
  684. NTSTATUS
  685. QueryLogicalOffset(
  686. IN PVOLUME_PHYSICAL_OFFSET PhysicalOffset,
  687. OUT PLONGLONG LogicalOffset
  688. ) = 0;
  689. virtual
  690. VOID
  691. ModifyStateForUser(
  692. IN OUT PVOID State
  693. );
  694. virtual
  695. ~FT_VOLUME(
  696. );
  697. FT_VOLUME(
  698. ) { _refCount = 1; };
  699. LONG _refCount;
  700. protected:
  701. KSPIN_LOCK _spinLock;
  702. PFT_LOGICAL_DISK_INFORMATION_SET _diskInfoSet;
  703. PROOT_EXTENSION _rootExtension;
  704. private:
  705. FT_LOGICAL_DISK_ID _logicalDiskId;
  706. };
  707. #define TRANSFER(a) ((a)->TargetVolume->Transfer((a)))
  708. class PARTITION : public FT_VOLUME {
  709. friend
  710. NTSTATUS
  711. PartitionTransferCompletionRoutine(
  712. IN PDEVICE_OBJECT DeviceObject,
  713. IN PIRP Irp,
  714. IN PVOID TransferPacket
  715. );
  716. public:
  717. PARTITION(
  718. ) { _emergencyIrp = NULL; };
  719. virtual
  720. ~PARTITION(
  721. );
  722. NTSTATUS
  723. Initialize(
  724. IN OUT PROOT_EXTENSION RootExtension,
  725. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  726. IN OUT PDEVICE_OBJECT TargetObject,
  727. IN OUT PDEVICE_OBJECT WholeDiskPdo
  728. );
  729. virtual
  730. FT_LOGICAL_DISK_TYPE
  731. QueryLogicalDiskType(
  732. );
  733. virtual
  734. USHORT
  735. QueryNumberOfMembers(
  736. );
  737. virtual
  738. PFT_VOLUME
  739. GetMember(
  740. IN USHORT MemberNumber
  741. );
  742. virtual
  743. NTSTATUS
  744. OrphanMember(
  745. IN USHORT MemberNumber,
  746. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  747. IN PVOID Context
  748. );
  749. virtual
  750. NTSTATUS
  751. RegenerateMember(
  752. IN USHORT MemberNumber,
  753. IN OUT PFT_VOLUME NewMember,
  754. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  755. IN PVOID Context
  756. );
  757. virtual
  758. VOID
  759. Transfer(
  760. IN OUT PTRANSFER_PACKET TransferPacket
  761. );
  762. virtual
  763. VOID
  764. ReplaceBadSector(
  765. IN OUT PTRANSFER_PACKET TransferPacket
  766. );
  767. virtual
  768. VOID
  769. StartSyncOperations(
  770. IN BOOLEAN RegenerateOrphans,
  771. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  772. IN PVOID Context
  773. );
  774. virtual
  775. VOID
  776. StopSyncOperations(
  777. );
  778. virtual
  779. VOID
  780. BroadcastIrp(
  781. IN PIRP Irp,
  782. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  783. IN PVOID Context
  784. );
  785. virtual
  786. ULONG
  787. QuerySectorSize(
  788. );
  789. virtual
  790. LONGLONG
  791. QueryVolumeSize(
  792. );
  793. virtual
  794. PFT_VOLUME
  795. GetContainedLogicalDisk(
  796. IN FT_LOGICAL_DISK_ID LogicalDiskId
  797. );
  798. virtual
  799. PFT_VOLUME
  800. GetContainedLogicalDisk(
  801. IN PDEVICE_OBJECT TargetObject
  802. );
  803. virtual
  804. PFT_VOLUME
  805. GetContainedLogicalDisk(
  806. IN ULONG Signature,
  807. IN LONGLONG Offset
  808. );
  809. virtual
  810. PFT_VOLUME
  811. GetParentLogicalDisk(
  812. IN PFT_VOLUME Volume
  813. );
  814. virtual
  815. VOID
  816. SetDirtyBit(
  817. IN BOOLEAN IsDirty,
  818. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  819. IN PVOID Context
  820. );
  821. virtual
  822. VOID
  823. SetMember(
  824. IN USHORT MemberNumber,
  825. IN PFT_VOLUME Member
  826. );
  827. virtual
  828. BOOLEAN
  829. IsComplete(
  830. IN BOOLEAN IoPending
  831. );
  832. virtual
  833. VOID
  834. CompleteNotification(
  835. IN BOOLEAN IoPending
  836. );
  837. virtual
  838. NTSTATUS
  839. CheckIo(
  840. OUT PBOOLEAN IsIoOk
  841. );
  842. virtual
  843. ULONG
  844. QueryNumberOfPartitions(
  845. );
  846. virtual
  847. NTSTATUS
  848. SetPartitionType(
  849. IN UCHAR PartitionType
  850. );
  851. virtual
  852. UCHAR
  853. QueryPartitionType(
  854. );
  855. virtual
  856. UCHAR
  857. QueryStackSize(
  858. );
  859. virtual
  860. VOID
  861. CreateLegacyNameLinks(
  862. IN PUNICODE_STRING DeviceName
  863. );
  864. virtual
  865. PDEVICE_OBJECT
  866. GetLeftmostPartitionObject(
  867. );
  868. virtual
  869. NTSTATUS
  870. QueryDiskExtents(
  871. OUT PDISK_EXTENT* DiskExtents,
  872. OUT PULONG NumberOfDiskExtents
  873. );
  874. virtual
  875. BOOLEAN
  876. QueryVolumeState(
  877. IN PFT_VOLUME Volume,
  878. OUT PFT_MEMBER_STATE State
  879. );
  880. virtual
  881. NTSTATUS
  882. QueryPhysicalOffsets(
  883. IN LONGLONG LogicalOffset,
  884. OUT PVOLUME_PHYSICAL_OFFSET* PhysicalOffsets,
  885. OUT PULONG NumberOfPhysicalOffsets
  886. );
  887. virtual
  888. NTSTATUS
  889. QueryLogicalOffset(
  890. IN PVOLUME_PHYSICAL_OFFSET PhysicalOffset,
  891. OUT PLONGLONG LogicalOffset
  892. );
  893. PDEVICE_OBJECT
  894. GetTargetObject(
  895. ) { return _targetObject; };
  896. PDEVICE_OBJECT
  897. GetWholeDiskPdo(
  898. ) { return _wholeDiskPdo; };
  899. private:
  900. PDEVICE_OBJECT _targetObject;
  901. PDEVICE_OBJECT _wholeDiskPdo;
  902. ULONG _sectorSize;
  903. LONGLONG _partitionOffset;
  904. LONGLONG _partitionLength;
  905. PIRP _emergencyIrp;
  906. BOOLEAN _emergencyIrpInUse;
  907. LIST_ENTRY _emergencyIrpQueue;
  908. };
  909. class COMPOSITE_FT_VOLUME;
  910. typedef COMPOSITE_FT_VOLUME *PCOMPOSITE_FT_VOLUME;
  911. class COMPOSITE_FT_VOLUME : public FT_VOLUME {
  912. public:
  913. virtual
  914. NTSTATUS
  915. Initialize(
  916. IN OUT PROOT_EXTENSION RootExtension,
  917. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  918. IN OUT PFT_VOLUME* VolumeArray,
  919. IN USHORT ArraySize,
  920. IN PVOID ConfigInfo,
  921. IN PVOID StateInfo
  922. );
  923. virtual
  924. FT_LOGICAL_DISK_TYPE
  925. QueryLogicalDiskType(
  926. ) = 0;
  927. virtual
  928. USHORT
  929. QueryNumberOfMembers(
  930. );
  931. virtual
  932. PFT_VOLUME
  933. GetMember(
  934. IN USHORT MemberNumber
  935. );
  936. virtual
  937. NTSTATUS
  938. OrphanMember(
  939. IN USHORT MemberNumber,
  940. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  941. IN PVOID Context
  942. );
  943. virtual
  944. NTSTATUS
  945. RegenerateMember(
  946. IN USHORT MemberNumber,
  947. IN OUT PFT_VOLUME NewMember,
  948. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  949. IN PVOID Context
  950. );
  951. virtual
  952. VOID
  953. Transfer(
  954. IN OUT PTRANSFER_PACKET TransferPacket
  955. ) = 0;
  956. virtual
  957. VOID
  958. ReplaceBadSector(
  959. IN OUT PTRANSFER_PACKET TransferPacket
  960. ) = 0;
  961. virtual
  962. VOID
  963. StartSyncOperations(
  964. IN BOOLEAN RegenerateOrphans,
  965. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  966. IN PVOID Context
  967. );
  968. virtual
  969. VOID
  970. StopSyncOperations(
  971. );
  972. virtual
  973. VOID
  974. BroadcastIrp(
  975. IN PIRP Irp,
  976. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  977. IN PVOID Context
  978. );
  979. virtual
  980. ULONG
  981. QuerySectorSize(
  982. );
  983. virtual
  984. LONGLONG
  985. QueryVolumeSize(
  986. ) = 0;
  987. virtual
  988. PFT_VOLUME
  989. GetContainedLogicalDisk(
  990. IN FT_LOGICAL_DISK_ID LogicalDiskId
  991. );
  992. virtual
  993. PFT_VOLUME
  994. GetContainedLogicalDisk(
  995. IN PDEVICE_OBJECT TargetObject
  996. );
  997. virtual
  998. PFT_VOLUME
  999. GetContainedLogicalDisk(
  1000. IN ULONG Signature,
  1001. IN LONGLONG Offset
  1002. );
  1003. virtual
  1004. PFT_VOLUME
  1005. GetParentLogicalDisk(
  1006. IN PFT_VOLUME Volume
  1007. );
  1008. virtual
  1009. VOID
  1010. SetDirtyBit(
  1011. IN BOOLEAN IsDirty,
  1012. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1013. IN PVOID Context
  1014. );
  1015. virtual
  1016. VOID
  1017. SetMember(
  1018. IN USHORT MemberNumber,
  1019. IN PFT_VOLUME Member
  1020. );
  1021. virtual
  1022. BOOLEAN
  1023. IsComplete(
  1024. IN BOOLEAN IoPending
  1025. );
  1026. virtual
  1027. VOID
  1028. CompleteNotification(
  1029. IN BOOLEAN IoPending
  1030. );
  1031. virtual
  1032. NTSTATUS
  1033. CheckIo(
  1034. OUT PBOOLEAN IsIoOk
  1035. ) = 0;
  1036. virtual
  1037. ULONG
  1038. QueryNumberOfPartitions(
  1039. );
  1040. virtual
  1041. NTSTATUS
  1042. SetPartitionType(
  1043. IN UCHAR PartitionType
  1044. );
  1045. virtual
  1046. UCHAR
  1047. QueryPartitionType(
  1048. );
  1049. virtual
  1050. UCHAR
  1051. QueryStackSize(
  1052. );
  1053. virtual
  1054. VOID
  1055. CreateLegacyNameLinks(
  1056. IN PUNICODE_STRING DeviceName
  1057. );
  1058. virtual
  1059. PDEVICE_OBJECT
  1060. GetLeftmostPartitionObject(
  1061. );
  1062. virtual
  1063. NTSTATUS
  1064. QueryDiskExtents(
  1065. OUT PDISK_EXTENT* DiskExtents,
  1066. OUT PULONG NumberOfDiskExtents
  1067. );
  1068. virtual
  1069. BOOLEAN
  1070. QueryVolumeState(
  1071. IN PFT_VOLUME Volume,
  1072. OUT PFT_MEMBER_STATE State
  1073. );
  1074. virtual
  1075. NTSTATUS
  1076. QueryPhysicalOffsets(
  1077. IN LONGLONG LogicalOffset,
  1078. OUT PVOLUME_PHYSICAL_OFFSET* PhysicalOffsets,
  1079. OUT PULONG NumberOfPhysicalOffsets
  1080. ) = 0;
  1081. virtual
  1082. NTSTATUS
  1083. QueryLogicalOffset(
  1084. IN PVOLUME_PHYSICAL_OFFSET PhysicalOffset,
  1085. OUT PLONGLONG LogicalOffset
  1086. ) = 0;
  1087. COMPOSITE_FT_VOLUME(
  1088. ) { _volumeArray = NULL; };
  1089. virtual
  1090. ~COMPOSITE_FT_VOLUME(
  1091. );
  1092. protected:
  1093. PFT_VOLUME
  1094. GetMemberUnprotected(
  1095. IN USHORT MemberNumber
  1096. ) { return _volumeArray[MemberNumber]; };
  1097. VOID
  1098. SetMemberUnprotected(
  1099. IN USHORT MemberNumber,
  1100. IN PFT_VOLUME NewVolume
  1101. ) { _volumeArray[MemberNumber] = NewVolume; };
  1102. USHORT
  1103. QueryNumMembers(
  1104. ) { return _arraySize; };
  1105. VOID
  1106. SetSectorSize(
  1107. IN ULONG SectorSize
  1108. ) { _sectorSize = SectorSize; };
  1109. private:
  1110. PFT_VOLUME* _volumeArray;
  1111. USHORT _arraySize;
  1112. ULONG _sectorSize;
  1113. };
  1114. class VOLUME_SET : public COMPOSITE_FT_VOLUME {
  1115. friend
  1116. VOID
  1117. VolsetTransferSequentialCompletionRoutine(
  1118. IN PTRANSFER_PACKET TransferPacket
  1119. );
  1120. public:
  1121. VOLUME_SET(
  1122. ) { _ePacket = NULL; };
  1123. virtual
  1124. ~VOLUME_SET(
  1125. );
  1126. virtual
  1127. NTSTATUS
  1128. Initialize(
  1129. IN OUT PROOT_EXTENSION RootExtension,
  1130. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  1131. IN OUT PFT_VOLUME* VolumeArray,
  1132. IN USHORT ArraySize,
  1133. IN PVOID ConfigInfo,
  1134. IN PVOID StateInfo
  1135. );
  1136. virtual
  1137. FT_LOGICAL_DISK_TYPE
  1138. QueryLogicalDiskType(
  1139. );
  1140. virtual
  1141. VOID
  1142. Transfer(
  1143. IN OUT PTRANSFER_PACKET TransferPacket
  1144. );
  1145. virtual
  1146. VOID
  1147. ReplaceBadSector(
  1148. IN OUT PTRANSFER_PACKET TransferPacket
  1149. );
  1150. virtual
  1151. LONGLONG
  1152. QueryVolumeSize(
  1153. );
  1154. virtual
  1155. VOID
  1156. CompleteNotification(
  1157. IN BOOLEAN IoPending
  1158. );
  1159. virtual
  1160. NTSTATUS
  1161. CheckIo(
  1162. OUT PBOOLEAN IsIoOk
  1163. );
  1164. virtual
  1165. NTSTATUS
  1166. QueryPhysicalOffsets(
  1167. IN LONGLONG LogicalOffset,
  1168. OUT PVOLUME_PHYSICAL_OFFSET* PhysicalOffsets,
  1169. OUT PULONG NumberOfPhysicalOffsets
  1170. );
  1171. virtual
  1172. NTSTATUS
  1173. QueryLogicalOffset(
  1174. IN PVOLUME_PHYSICAL_OFFSET PhysicalOffset,
  1175. OUT PLONGLONG LogicalOffset
  1176. );
  1177. private:
  1178. BOOLEAN
  1179. LaunchParallel(
  1180. IN OUT PTRANSFER_PACKET TransferPacket
  1181. );
  1182. VOID
  1183. LaunchSequential(
  1184. IN OUT PTRANSFER_PACKET TransferPacket
  1185. );
  1186. LONGLONG _volumeSize;
  1187. PVOLSET_TP _ePacket;
  1188. BOOLEAN _ePacketInUse;
  1189. LIST_ENTRY _ePacketQueue;
  1190. };
  1191. class STRIPE : public COMPOSITE_FT_VOLUME {
  1192. friend
  1193. VOID
  1194. StripeSequentialTransferCompletionRoutine(
  1195. IN PTRANSFER_PACKET TransferPacket
  1196. );
  1197. public:
  1198. STRIPE(
  1199. ) { _ePacket = NULL; };
  1200. virtual
  1201. ~STRIPE(
  1202. );
  1203. virtual
  1204. NTSTATUS
  1205. Initialize(
  1206. IN OUT PROOT_EXTENSION RootExtension,
  1207. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  1208. IN OUT PFT_VOLUME* VolumeArray,
  1209. IN USHORT ArraySize,
  1210. IN PVOID ConfigInfo,
  1211. IN PVOID StateInfo
  1212. );
  1213. virtual
  1214. FT_LOGICAL_DISK_TYPE
  1215. QueryLogicalDiskType(
  1216. );
  1217. virtual
  1218. VOID
  1219. Transfer(
  1220. IN OUT PTRANSFER_PACKET TransferPacket
  1221. );
  1222. virtual
  1223. VOID
  1224. ReplaceBadSector(
  1225. IN OUT PTRANSFER_PACKET TransferPacket
  1226. );
  1227. virtual
  1228. LONGLONG
  1229. QueryVolumeSize(
  1230. );
  1231. virtual
  1232. VOID
  1233. CompleteNotification(
  1234. IN BOOLEAN IoPending
  1235. );
  1236. virtual
  1237. NTSTATUS
  1238. CheckIo(
  1239. OUT PBOOLEAN IsIoOk
  1240. );
  1241. virtual
  1242. NTSTATUS
  1243. QueryPhysicalOffsets(
  1244. IN LONGLONG LogicalOffset,
  1245. OUT PVOLUME_PHYSICAL_OFFSET* PhysicalOffsets,
  1246. OUT PULONG NumberOfPhysicalOffsets
  1247. );
  1248. virtual
  1249. NTSTATUS
  1250. QueryLogicalOffset(
  1251. IN PVOLUME_PHYSICAL_OFFSET PhysicalOffset,
  1252. OUT PLONGLONG LogicalOffset
  1253. );
  1254. private:
  1255. BOOLEAN
  1256. LaunchParallel(
  1257. IN OUT PTRANSFER_PACKET TransferPacket
  1258. );
  1259. VOID
  1260. LaunchSequential(
  1261. IN OUT PTRANSFER_PACKET TransferPacket
  1262. );
  1263. ULONG _stripeSize;
  1264. ULONG _stripeShift;
  1265. ULONG _stripeMask;
  1266. LONGLONG _memberSize;
  1267. LONGLONG _volumeSize;
  1268. PSTRIPE_TP _ePacket;
  1269. BOOLEAN _ePacketInUse;
  1270. LIST_ENTRY _ePacketQueue;
  1271. };
  1272. class MIRROR : public COMPOSITE_FT_VOLUME {
  1273. friend
  1274. VOID
  1275. FinishRegenerate(
  1276. IN PMIRROR Mirror,
  1277. IN PFT_COMPLETION_ROUTINE_CONTEXT RegenContext,
  1278. IN PMIRROR_TP TransferPacket
  1279. );
  1280. friend
  1281. VOID
  1282. MirrorRegenerateCompletionRoutine(
  1283. IN PTRANSFER_PACKET TransferPacket
  1284. );
  1285. friend
  1286. VOID
  1287. StartRegeneration(
  1288. IN PVOID Context,
  1289. IN NTSTATUS Status
  1290. );
  1291. friend
  1292. VOID
  1293. MirrorTransferCompletionRoutine(
  1294. IN PTRANSFER_PACKET TransferPacket
  1295. );
  1296. friend
  1297. VOID
  1298. MirrorRecoverPhase8(
  1299. IN OUT PTRANSFER_PACKET TransferPacket
  1300. );
  1301. friend
  1302. VOID
  1303. MirrorRecoverPhase7(
  1304. IN OUT PTRANSFER_PACKET TransferPacket
  1305. );
  1306. friend
  1307. VOID
  1308. MirrorRecoverPhase6(
  1309. IN OUT PTRANSFER_PACKET TransferPacket
  1310. );
  1311. friend
  1312. VOID
  1313. MirrorRecoverPhase5(
  1314. IN OUT PTRANSFER_PACKET TransferPacket
  1315. );
  1316. friend
  1317. VOID
  1318. MirrorRecoverPhase4(
  1319. IN OUT PTRANSFER_PACKET TransferPacket
  1320. );
  1321. friend
  1322. VOID
  1323. MirrorRecoverPhase3(
  1324. IN OUT PTRANSFER_PACKET TransferPacket
  1325. );
  1326. friend
  1327. VOID
  1328. MirrorRecoverPhase2(
  1329. IN OUT PTRANSFER_PACKET TransferPacket
  1330. );
  1331. friend
  1332. VOID
  1333. MirrorRecoverEmergencyCompletion(
  1334. IN OUT PTRANSFER_PACKET TransferPacket
  1335. );
  1336. friend
  1337. VOID
  1338. MirrorRecoverPhase1(
  1339. IN OUT PTRANSFER_PACKET TransferPacket
  1340. );
  1341. friend
  1342. VOID
  1343. MirrorMaxTransferCompletionRoutine(
  1344. IN OUT PTRANSFER_PACKET TransferPacket
  1345. );
  1346. friend
  1347. VOID
  1348. MirrorMaxTransferEmergencyCompletion(
  1349. IN OUT PTRANSFER_PACKET TransferPacket
  1350. );
  1351. friend
  1352. VOID
  1353. MirrorPropogateStateChangesWorker(
  1354. IN PVOID Mirror
  1355. );
  1356. friend
  1357. VOID
  1358. MirrorCarefulWritePhase1(
  1359. IN OUT PTRANSFER_PACKET TransferPacket
  1360. );
  1361. friend
  1362. VOID
  1363. MirrorCarefulWritePhase2(
  1364. IN OUT PTRANSFER_PACKET TransferPacket
  1365. );
  1366. friend
  1367. VOID
  1368. MirrorCarefulWriteEmergencyCompletion(
  1369. IN OUT PTRANSFER_PACKET TransferPacket
  1370. );
  1371. public:
  1372. virtual
  1373. ~MIRROR(
  1374. );
  1375. virtual
  1376. NTSTATUS
  1377. Initialize(
  1378. IN OUT PROOT_EXTENSION RootExtension,
  1379. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  1380. IN OUT PFT_VOLUME* VolumeArray,
  1381. IN USHORT ArraySize,
  1382. IN PVOID ConfigInfo,
  1383. IN PVOID StateInfo
  1384. );
  1385. virtual
  1386. FT_LOGICAL_DISK_TYPE
  1387. QueryLogicalDiskType(
  1388. );
  1389. virtual
  1390. NTSTATUS
  1391. OrphanMember(
  1392. IN USHORT MemberNumber,
  1393. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1394. IN PVOID Context
  1395. );
  1396. virtual
  1397. NTSTATUS
  1398. RegenerateMember(
  1399. IN USHORT MemberNumber,
  1400. IN OUT PFT_VOLUME NewMember,
  1401. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1402. IN PVOID Context
  1403. );
  1404. virtual
  1405. VOID
  1406. Transfer(
  1407. IN OUT PTRANSFER_PACKET TransferPacket
  1408. );
  1409. virtual
  1410. VOID
  1411. ReplaceBadSector(
  1412. IN OUT PTRANSFER_PACKET TransferPacket
  1413. );
  1414. virtual
  1415. VOID
  1416. StartSyncOperations(
  1417. IN BOOLEAN RegenerateOrphans,
  1418. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1419. IN PVOID Context
  1420. );
  1421. virtual
  1422. VOID
  1423. StopSyncOperations(
  1424. );
  1425. virtual
  1426. LONGLONG
  1427. QueryVolumeSize(
  1428. );
  1429. virtual
  1430. VOID
  1431. SetDirtyBit(
  1432. IN BOOLEAN IsDirty,
  1433. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1434. IN PVOID Context
  1435. );
  1436. virtual
  1437. BOOLEAN
  1438. IsComplete(
  1439. IN BOOLEAN IoPending
  1440. );
  1441. virtual
  1442. VOID
  1443. CompleteNotification(
  1444. IN BOOLEAN IoPending
  1445. );
  1446. virtual
  1447. NTSTATUS
  1448. CheckIo(
  1449. OUT PBOOLEAN IsIoOk
  1450. );
  1451. virtual
  1452. BOOLEAN
  1453. IsVolumeSuitableForRegenerate(
  1454. IN USHORT MemberNumber,
  1455. IN PFT_VOLUME Volume
  1456. );
  1457. virtual
  1458. VOID
  1459. NewStateArrival(
  1460. IN PVOID NewStateInstance
  1461. );
  1462. virtual
  1463. PDEVICE_OBJECT
  1464. GetLeftmostPartitionObject(
  1465. );
  1466. virtual
  1467. BOOLEAN
  1468. QueryVolumeState(
  1469. IN PFT_VOLUME Volume,
  1470. OUT PFT_MEMBER_STATE State
  1471. );
  1472. virtual
  1473. NTSTATUS
  1474. QueryPhysicalOffsets(
  1475. IN LONGLONG LogicalOffset,
  1476. OUT PVOLUME_PHYSICAL_OFFSET* PhysicalOffsets,
  1477. OUT PULONG NumberOfPhysicalOffsets
  1478. );
  1479. virtual
  1480. NTSTATUS
  1481. QueryLogicalOffset(
  1482. IN PVOLUME_PHYSICAL_OFFSET PhysicalOffset,
  1483. OUT PLONGLONG LogicalOffset
  1484. );
  1485. virtual
  1486. VOID
  1487. ModifyStateForUser(
  1488. IN OUT PVOID State
  1489. );
  1490. MIRROR(
  1491. ) { _ePacket = NULL; _ePacket2 = NULL; _eRecoverPacket = NULL; };
  1492. private:
  1493. FT_MEMBER_STATE
  1494. QueryMemberState(
  1495. IN USHORT MemberNumber
  1496. ) { return MemberNumber == _state.UnhealthyMemberNumber ?
  1497. _state.UnhealthyMemberState : FtMemberHealthy; }
  1498. BOOLEAN
  1499. SetMemberState(
  1500. IN USHORT MemberNumber,
  1501. IN FT_MEMBER_STATE MemberState
  1502. );
  1503. BOOLEAN
  1504. LaunchRead(
  1505. IN OUT PTRANSFER_PACKET TransferPacket,
  1506. IN OUT PMIRROR_TP Packet1
  1507. );
  1508. BOOLEAN
  1509. LaunchWrite(
  1510. IN OUT PTRANSFER_PACKET TransferPacket,
  1511. IN OUT PMIRROR_TP Packet1,
  1512. IN OUT PMIRROR_TP Packet2
  1513. );
  1514. VOID
  1515. Recycle(
  1516. IN OUT PMIRROR_TP TransferPacket,
  1517. IN BOOLEAN ServiceEmergencyQueue
  1518. );
  1519. VOID
  1520. Recover(
  1521. IN OUT PMIRROR_TP TransferPacket
  1522. );
  1523. VOID
  1524. MaxTransfer(
  1525. IN OUT PMIRROR_TP TransferPacket
  1526. );
  1527. VOID
  1528. PropogateStateChanges(
  1529. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1530. IN PVOID Context
  1531. );
  1532. VOID
  1533. CarefulWrite(
  1534. IN OUT PMIRROR_TP TransferPacket
  1535. );
  1536. LONGLONG _volumeSize;
  1537. //
  1538. // Keep track of requests for load balancing.
  1539. //
  1540. LONG _requestCount[2];
  1541. LONGLONG _lastPosition[2];
  1542. //
  1543. // The dynamic state of this volume.
  1544. //
  1545. FT_MIRROR_AND_SWP_STATE_INFORMATION _state;
  1546. BOOLEAN _originalDirtyBit;
  1547. BOOLEAN _orphanedBecauseOfMissingMember;
  1548. //
  1549. // Indicates whether or not 'StartSyncOperations' or
  1550. // 'RegenerateMember' is ok.
  1551. //
  1552. BOOLEAN _syncOk;
  1553. //
  1554. // Indicate whether or not balanced reads are allowed.
  1555. //
  1556. BOOLEAN _balancedReads;
  1557. //
  1558. // Indicates whether or not to stop syncs.
  1559. //
  1560. BOOLEAN _stopSyncs;
  1561. //
  1562. // Emergency packet.
  1563. //
  1564. PMIRROR_TP _ePacket, _ePacket2;
  1565. BOOLEAN _ePacketInUse;
  1566. LIST_ENTRY _ePacketQueue;
  1567. //
  1568. // Emergency recover packet.
  1569. //
  1570. PMIRROR_RECOVER_TP _eRecoverPacket;
  1571. BOOLEAN _eRecoverPacketInUse;
  1572. LIST_ENTRY _eRecoverPacketQueue;
  1573. //
  1574. // Overlapped io manager.
  1575. //
  1576. OVERLAPPED_IO_MANAGER _overlappedIoManager;
  1577. };
  1578. class STRIPE_WP : public COMPOSITE_FT_VOLUME {
  1579. friend
  1580. VOID
  1581. StripeWpSyncFinalCompletion(
  1582. IN PVOID Context,
  1583. IN NTSTATUS Status
  1584. );
  1585. friend
  1586. VOID
  1587. StripeWpSyncCompletionRoutine(
  1588. IN PTRANSFER_PACKET TransferPacket
  1589. );
  1590. friend
  1591. VOID
  1592. StartStripeRegeneration(
  1593. IN PVOID Context,
  1594. IN NTSTATUS Status
  1595. );
  1596. friend
  1597. VOID
  1598. StripeWpParallelTransferCompletionRoutine(
  1599. IN PTRANSFER_PACKET TransferPacket
  1600. );
  1601. friend
  1602. VOID
  1603. StripeWpSequentialTransferCompletionRoutine(
  1604. IN PTRANSFER_PACKET TransferPacket
  1605. );
  1606. friend
  1607. VOID
  1608. StripeWpWritePhase31(
  1609. IN OUT PTRANSFER_PACKET Packet
  1610. );
  1611. friend
  1612. VOID
  1613. StripeWpWritePhase30(
  1614. IN OUT PTRANSFER_PACKET Packet
  1615. );
  1616. friend
  1617. VOID
  1618. StripeWpWriteRecover(
  1619. IN OUT PTRANSFER_PACKET MasterPacket
  1620. );
  1621. friend
  1622. VOID
  1623. StripeWpWritePhase2(
  1624. IN OUT PTRANSFER_PACKET ReadPacket
  1625. );
  1626. friend
  1627. VOID
  1628. StripeWpWritePhase1(
  1629. IN OUT PTRANSFER_PACKET TransferPacket
  1630. );
  1631. friend
  1632. VOID
  1633. StripeWpSequentialRegenerateCompletion(
  1634. IN OUT PTRANSFER_PACKET TransferPacket
  1635. );
  1636. friend
  1637. VOID
  1638. StripeWpSequentialEmergencyCompletion(
  1639. IN OUT PTRANSFER_PACKET TransferPacket
  1640. );
  1641. friend
  1642. VOID
  1643. StripeWpParallelRegenerateCompletion(
  1644. IN OUT PTRANSFER_PACKET TransferPacket
  1645. );
  1646. friend
  1647. VOID
  1648. StripeWpRegeneratePacketPhase1(
  1649. IN OUT PTRANSFER_PACKET TransferPacket
  1650. );
  1651. friend
  1652. VOID
  1653. StripeWpRecoverPhase8(
  1654. IN OUT PTRANSFER_PACKET TransferPacket
  1655. );
  1656. friend
  1657. VOID
  1658. StripeWpRecoverPhase7(
  1659. IN OUT PTRANSFER_PACKET TransferPacket
  1660. );
  1661. friend
  1662. VOID
  1663. StripeWpRecoverPhase6(
  1664. IN OUT PTRANSFER_PACKET TransferPacket
  1665. );
  1666. friend
  1667. VOID
  1668. StripeWpRecoverPhase5(
  1669. IN OUT PTRANSFER_PACKET TransferPacket
  1670. );
  1671. friend
  1672. VOID
  1673. StripeWpRecoverPhase4(
  1674. IN OUT PTRANSFER_PACKET TransferPacket
  1675. );
  1676. friend
  1677. VOID
  1678. StripeWpRecoverPhase3(
  1679. IN OUT PTRANSFER_PACKET TransferPacket
  1680. );
  1681. friend
  1682. VOID
  1683. StripeWpRecoverPhase2(
  1684. IN OUT PTRANSFER_PACKET TransferPacket
  1685. );
  1686. friend
  1687. VOID
  1688. StripeWpRecoverEmergencyCompletion(
  1689. IN OUT PTRANSFER_PACKET TransferPacket
  1690. );
  1691. friend
  1692. VOID
  1693. StripeWpRecoverPhase1(
  1694. IN OUT PTRANSFER_PACKET TransferPacket
  1695. );
  1696. friend
  1697. VOID
  1698. StripeWpMaxTransferCompletionRoutine(
  1699. IN OUT PTRANSFER_PACKET TransferPacket
  1700. );
  1701. friend
  1702. VOID
  1703. StripeWpMaxTransferEmergencyCompletion(
  1704. IN OUT PTRANSFER_PACKET TransferPacket
  1705. );
  1706. friend
  1707. VOID
  1708. StripeWpPropogateStateChangesWorker(
  1709. IN PVOID StripeWp
  1710. );
  1711. friend
  1712. VOID
  1713. StripeWpCompleteWritePhase4(
  1714. IN OUT PTRANSFER_PACKET TransferPacket
  1715. );
  1716. friend
  1717. VOID
  1718. StripeWpCompleteWritePhase3(
  1719. IN OUT PTRANSFER_PACKET TransferPacket
  1720. );
  1721. friend
  1722. VOID
  1723. StripeWpCompleteWritePhase2(
  1724. IN OUT PTRANSFER_PACKET TransferPacket
  1725. );
  1726. friend
  1727. VOID
  1728. StripeWpCompleteWritePhase1(
  1729. IN OUT PTRANSFER_PACKET TransferPacket
  1730. );
  1731. friend
  1732. VOID
  1733. StripeWpCarefulWritePhase2(
  1734. IN OUT PTRANSFER_PACKET TransferPacket
  1735. );
  1736. friend
  1737. VOID
  1738. StripeWpCarefulWritePhase1(
  1739. IN OUT PTRANSFER_PACKET TransferPacket
  1740. );
  1741. friend
  1742. VOID
  1743. StripeWpCarefulWriteEmergencyCompletion(
  1744. IN OUT PTRANSFER_PACKET TransferPacket
  1745. );
  1746. friend
  1747. VOID
  1748. StripeWpCarefulUpdateCompletion(
  1749. IN OUT PTRANSFER_PACKET TransferPacket
  1750. );
  1751. friend
  1752. VOID
  1753. StripeWpCarefulUpdateEmergencyCompletion(
  1754. IN OUT PTRANSFER_PACKET TransferPacket
  1755. );
  1756. public:
  1757. virtual
  1758. NTSTATUS
  1759. Initialize(
  1760. IN OUT PROOT_EXTENSION RootExtension,
  1761. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  1762. IN OUT PFT_VOLUME* VolumeArray,
  1763. IN USHORT ArraySize,
  1764. IN PVOID ConfigInfo,
  1765. IN PVOID StateInfo
  1766. );
  1767. virtual
  1768. FT_LOGICAL_DISK_TYPE
  1769. QueryLogicalDiskType(
  1770. );
  1771. virtual
  1772. NTSTATUS
  1773. OrphanMember(
  1774. IN USHORT MemberNumber,
  1775. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1776. IN PVOID Context
  1777. );
  1778. virtual
  1779. NTSTATUS
  1780. RegenerateMember(
  1781. IN USHORT MemberNumber,
  1782. IN OUT PFT_VOLUME NewMember,
  1783. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1784. IN PVOID Context
  1785. );
  1786. virtual
  1787. VOID
  1788. Transfer(
  1789. IN OUT PTRANSFER_PACKET TransferPacket
  1790. );
  1791. virtual
  1792. VOID
  1793. ReplaceBadSector(
  1794. IN OUT PTRANSFER_PACKET TransferPacket
  1795. );
  1796. virtual
  1797. VOID
  1798. StartSyncOperations(
  1799. IN BOOLEAN RegenerateOrphans,
  1800. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1801. IN PVOID Context
  1802. );
  1803. virtual
  1804. VOID
  1805. StopSyncOperations(
  1806. );
  1807. virtual
  1808. LONGLONG
  1809. QueryVolumeSize(
  1810. );
  1811. virtual
  1812. VOID
  1813. SetDirtyBit(
  1814. IN BOOLEAN IsDirty,
  1815. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1816. IN PVOID Context
  1817. );
  1818. virtual
  1819. BOOLEAN
  1820. IsComplete(
  1821. IN BOOLEAN IoPending
  1822. );
  1823. virtual
  1824. VOID
  1825. CompleteNotification(
  1826. IN BOOLEAN IoPending
  1827. );
  1828. virtual
  1829. NTSTATUS
  1830. CheckIo(
  1831. OUT PBOOLEAN IsIoOk
  1832. );
  1833. virtual
  1834. BOOLEAN
  1835. IsVolumeSuitableForRegenerate(
  1836. IN USHORT MemberNumber,
  1837. IN PFT_VOLUME Volume
  1838. );
  1839. virtual
  1840. VOID
  1841. NewStateArrival(
  1842. IN PVOID NewStateInstance
  1843. );
  1844. virtual
  1845. BOOLEAN
  1846. QueryVolumeState(
  1847. IN PFT_VOLUME Volume,
  1848. OUT PFT_MEMBER_STATE State
  1849. );
  1850. virtual
  1851. NTSTATUS
  1852. QueryPhysicalOffsets(
  1853. IN LONGLONG LogicalOffset,
  1854. OUT PVOLUME_PHYSICAL_OFFSET* PhysicalOffsets,
  1855. OUT PULONG NumberOfPhysicalOffsets
  1856. );
  1857. virtual
  1858. NTSTATUS
  1859. QueryLogicalOffset(
  1860. IN PVOLUME_PHYSICAL_OFFSET PhysicalOffset,
  1861. OUT PLONGLONG LogicalOffset
  1862. );
  1863. virtual
  1864. VOID
  1865. ModifyStateForUser(
  1866. IN OUT PVOID State
  1867. );
  1868. STRIPE_WP(
  1869. );
  1870. virtual
  1871. ~STRIPE_WP(
  1872. );
  1873. private:
  1874. FT_MEMBER_STATE
  1875. QueryMemberState(
  1876. IN USHORT MemberNumber
  1877. ) { return MemberNumber == _state.UnhealthyMemberNumber ?
  1878. _state.UnhealthyMemberState : FtMemberHealthy; }
  1879. BOOLEAN
  1880. SetMemberState(
  1881. IN USHORT MemberNumber,
  1882. IN FT_MEMBER_STATE MemberState
  1883. );
  1884. BOOLEAN
  1885. LaunchParallel(
  1886. IN OUT PTRANSFER_PACKET TransferPacket
  1887. );
  1888. VOID
  1889. LaunchSequential(
  1890. IN OUT PTRANSFER_PACKET TransferPacket
  1891. );
  1892. VOID
  1893. ReadPacket(
  1894. IN OUT PSWP_TP TransferPacket
  1895. );
  1896. VOID
  1897. WritePacket(
  1898. IN OUT PSWP_WRITE_TP TransferPacket
  1899. );
  1900. VOID
  1901. RegeneratePacket(
  1902. IN OUT PSWP_TP TransferPacket,
  1903. IN BOOLEAN AllocateRegion
  1904. );
  1905. VOID
  1906. Recover(
  1907. IN OUT PSWP_TP TransferPacket,
  1908. IN BOOLEAN NeedAcquire
  1909. );
  1910. VOID
  1911. MaxTransfer(
  1912. IN OUT PSWP_TP TransferPacket
  1913. );
  1914. VOID
  1915. RecycleRecoverTp(
  1916. IN OUT PSWP_RECOVER_TP TransferPacket
  1917. );
  1918. VOID
  1919. PropogateStateChanges(
  1920. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  1921. IN PVOID Context
  1922. );
  1923. VOID
  1924. CompleteWrite(
  1925. IN OUT PSWP_WRITE_TP TransferPacket
  1926. );
  1927. VOID
  1928. CarefulWrite(
  1929. IN OUT PSWP_TP TransferPacket
  1930. );
  1931. VOID
  1932. CarefulUpdate(
  1933. IN OUT PSWP_TP ParityPacket
  1934. );
  1935. ULONG _stripeSize;
  1936. LONGLONG _memberSize;
  1937. LONGLONG _volumeSize;
  1938. //
  1939. // The dynamic state of this volume.
  1940. //
  1941. FT_MIRROR_AND_SWP_STATE_INFORMATION _state;
  1942. BOOLEAN _originalDirtyBit;
  1943. BOOLEAN _orphanedBecauseOfMissingMember;
  1944. //
  1945. // Indicates whether or not 'StartSyncOperations' or
  1946. // 'RegenerateMember' is ok.
  1947. //
  1948. BOOLEAN _syncOk;
  1949. //
  1950. // Indicates whether or not to stop syncs.
  1951. //
  1952. BOOLEAN _stopSyncs;
  1953. //
  1954. // State for keeping track of overlapping write requests.
  1955. // One OVERLAPPED_IO_MANAGER for each member.
  1956. //
  1957. OVERLAPPED_IO_MANAGER _overlappedIoManager;
  1958. //
  1959. // State for serializing parity I/O.
  1960. //
  1961. PARITY_IO_MANAGER _parityIoManager;
  1962. //
  1963. // Emergency read/write packet.
  1964. //
  1965. PSWP_WRITE_TP _ePacket;
  1966. BOOLEAN _ePacketInUse;
  1967. BOOLEAN _ePacketQueueBeingServiced;
  1968. LIST_ENTRY _ePacketQueue;
  1969. //
  1970. // Emergency regenerate packet.
  1971. //
  1972. PSWP_REGENERATE_TP _eRegeneratePacket;
  1973. BOOLEAN _eRegeneratePacketInUse;
  1974. LIST_ENTRY _eRegeneratePacketQueue;
  1975. //
  1976. // Emergency recover packet.
  1977. //
  1978. PSWP_RECOVER_TP _eRecoverPacket;
  1979. BOOLEAN _eRecoverPacketInUse;
  1980. LIST_ENTRY _eRecoverPacketQueue;
  1981. };
  1982. class REDISTRIBUTION : public COMPOSITE_FT_VOLUME {
  1983. friend
  1984. VOID
  1985. RedistributionSyncPhase6(
  1986. IN OUT PVOID SyncPacket,
  1987. IN NTSTATUS Status
  1988. );
  1989. friend
  1990. VOID
  1991. RedistributionSyncPhase5(
  1992. IN OUT PTRANSFER_PACKET TransferPacket
  1993. );
  1994. friend
  1995. VOID
  1996. RedistributionSyncPhase4(
  1997. IN OUT PTRANSFER_PACKET TransferPacket
  1998. );
  1999. friend
  2000. VOID
  2001. RedistributionSyncPhase3(
  2002. IN OUT PTRANSFER_PACKET TransferPacket
  2003. );
  2004. friend
  2005. VOID
  2006. RedistributionSyncPhase2(
  2007. IN OUT PTRANSFER_PACKET TransferPacket
  2008. );
  2009. friend
  2010. VOID
  2011. RedistributionSyncPhase1(
  2012. IN OUT PTRANSFER_PACKET TransferPacket
  2013. );
  2014. friend
  2015. VOID
  2016. RedistributionRegionLockCompletion(
  2017. IN OUT PTRANSFER_PACKET LockPacket
  2018. );
  2019. friend
  2020. VOID
  2021. RedistributionLockReplaceCompletion(
  2022. IN OUT PTRANSFER_PACKET TransferPacket
  2023. );
  2024. friend
  2025. VOID
  2026. RedistributionPropogateStateChangesWorker(
  2027. IN PVOID WorkItem
  2028. );
  2029. public:
  2030. virtual
  2031. ~REDISTRIBUTION(
  2032. );
  2033. virtual
  2034. NTSTATUS
  2035. Initialize(
  2036. IN OUT PROOT_EXTENSION RootExtension,
  2037. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  2038. IN OUT PFT_VOLUME* VolumeArray,
  2039. IN USHORT ArraySize,
  2040. IN PVOID ConfigInfo,
  2041. IN PVOID StateInfo
  2042. );
  2043. virtual
  2044. FT_LOGICAL_DISK_TYPE
  2045. QueryLogicalDiskType(
  2046. );
  2047. virtual
  2048. VOID
  2049. Transfer(
  2050. IN OUT PTRANSFER_PACKET TransferPacket
  2051. );
  2052. virtual
  2053. VOID
  2054. ReplaceBadSector(
  2055. IN OUT PTRANSFER_PACKET TransferPacket
  2056. );
  2057. virtual
  2058. VOID
  2059. StartSyncOperations(
  2060. IN BOOLEAN RegenerateOrphans,
  2061. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  2062. IN PVOID Context
  2063. );
  2064. virtual
  2065. VOID
  2066. StopSyncOperations(
  2067. );
  2068. virtual
  2069. LONGLONG
  2070. QueryVolumeSize(
  2071. );
  2072. virtual
  2073. VOID
  2074. CompleteNotification(
  2075. IN BOOLEAN IoPending
  2076. );
  2077. virtual
  2078. NTSTATUS
  2079. CheckIo(
  2080. OUT PBOOLEAN IsIoOk
  2081. );
  2082. virtual
  2083. VOID
  2084. NewStateArrival(
  2085. IN PVOID NewStateInstance
  2086. );
  2087. virtual
  2088. NTSTATUS
  2089. QueryPhysicalOffsets(
  2090. IN LONGLONG LogicalOffset,
  2091. OUT PVOLUME_PHYSICAL_OFFSET* PhysicalOffsets,
  2092. OUT PULONG NumberOfPhysicalOffsets
  2093. );
  2094. virtual
  2095. NTSTATUS
  2096. QueryLogicalOffset(
  2097. IN PVOLUME_PHYSICAL_OFFSET PhysicalOffset,
  2098. OUT PLONGLONG LogicalOffset
  2099. );
  2100. private:
  2101. VOID
  2102. RedistributeTransfer(
  2103. IN OUT PTRANSFER_PACKET TransferPacket
  2104. );
  2105. VOID
  2106. RedistributeReplaceBadSector(
  2107. IN OUT PTRANSFER_PACKET TransferPacket
  2108. );
  2109. VOID
  2110. PropogateStateChanges(
  2111. IN FT_COMPLETION_ROUTINE CompletionRoutine,
  2112. IN PVOID Context
  2113. );
  2114. VOID
  2115. MaxTransfer(
  2116. IN OUT PREDISTRIBUTION_TP TransferPacket
  2117. );
  2118. VOID
  2119. VerifyWrite(
  2120. IN OUT PREDISTRIBUTION_TP TransferPacket
  2121. );
  2122. VOID
  2123. CarefulWrite(
  2124. IN OUT PREDISTRIBUTION_TP TransferPacket
  2125. );
  2126. ULONG _stripeSize;
  2127. USHORT _firstWidth;
  2128. USHORT _totalWidth;
  2129. LONGLONG _firstSize;
  2130. LONGLONG _totalSize;
  2131. BOOLEAN _syncOk;
  2132. BOOLEAN _stopSyncs;
  2133. FT_REDISTRIBUTION_STATE_INFORMATION _state;
  2134. BOOLEAN _redistributionComplete;
  2135. OVERLAPPED_IO_MANAGER _overlappedIoManager;
  2136. };
  2137. typedef struct _FTP_GPT_ATTRIBUTE_REVERT_ENTRY {
  2138. GUID PartitionUniqueId;
  2139. ULONGLONG GptAttributes;
  2140. ULONG MbrSignature;
  2141. ULONG Reserved;
  2142. } FTP_GPT_ATTRIBUTE_REVERT_ENTRY, *PFTP_GPT_ATTRIBUTE_REVERT_ENTRY;
  2143. struct DEVICE_EXTENSION {
  2144. //
  2145. // Pointer to the device object for this extension.
  2146. //
  2147. PDEVICE_OBJECT DeviceObject; // 00
  2148. //
  2149. // Pointer to the root device extension.
  2150. //
  2151. PROOT_EXTENSION Root; // 04
  2152. //
  2153. // The type of device extension.
  2154. //
  2155. ULONG DeviceExtensionType; // 08
  2156. //
  2157. // A spinlock for synchronization.
  2158. //
  2159. KSPIN_LOCK SpinLock; // 0C
  2160. };
  2161. class ROOT_EXTENSION : public DEVICE_EXTENSION {
  2162. public:
  2163. //
  2164. // Pointer to the driver object.
  2165. //
  2166. PDRIVER_OBJECT DriverObject; // 10
  2167. //
  2168. // Pointer to the next device in the stack.
  2169. //
  2170. PDEVICE_OBJECT TargetObject; // 14
  2171. //
  2172. // Pointer to the PDO.
  2173. //
  2174. PDEVICE_OBJECT Pdo; // 18
  2175. //
  2176. // List of volumes in the system. Protect with 'Semaphore'.
  2177. //
  2178. LIST_ENTRY VolumeList; // 1C
  2179. //
  2180. // List of dead volumes. Protect with 'Semaphore'.
  2181. //
  2182. LIST_ENTRY DeadVolumeList; // 2C
  2183. //
  2184. // The next volume number. Protect with 'Semaphore'.
  2185. //
  2186. ULONG NextVolumeNumber; // 34
  2187. //
  2188. // The disk information set for the on disk storage of FT sets.
  2189. // Protect with 'Semaphore'.
  2190. //
  2191. PFT_LOGICAL_DISK_INFORMATION_SET DiskInfoSet; // 38
  2192. //
  2193. // Private worker thread and queue. Protect queue with 'SpinLock'.
  2194. //
  2195. PVOID WorkerThread; // 3C
  2196. LIST_ENTRY WorkerQueue; // 40
  2197. KSEMAPHORE WorkerSemaphore; // 44
  2198. LONG TerminateThread; // 58
  2199. //
  2200. // Change notify Irp list. Protect with cancel spin lock.
  2201. //
  2202. LIST_ENTRY ChangeNotifyIrpList; // 5C
  2203. //
  2204. // A semaphore for synchronization.
  2205. //
  2206. KSEMAPHORE Mutex; // 64
  2207. //
  2208. // Device Interface name.
  2209. //
  2210. UNICODE_STRING VolumeManagerInterfaceName; // 78
  2211. //
  2212. // Whether or not we are past the boot reinitialize code.
  2213. //
  2214. BOOLEAN PastBootReinitialize; // 80
  2215. //
  2216. // Whether or not the FT specific code has been locked down.
  2217. //
  2218. BOOLEAN FtCodeLocked; // 81
  2219. //
  2220. // Whether or not we are past the reinitialize code.
  2221. //
  2222. BOOLEAN PastReinitialize; // 82
  2223. //
  2224. // Registry Path.
  2225. //
  2226. UNICODE_STRING DiskPerfRegistryPath;
  2227. //
  2228. // Table of PmWmiCounter Functions.
  2229. //
  2230. PMWMICOUNTERLIB_CONTEXT PmWmiCounterLibContext;
  2231. //
  2232. // The Unique partition type GUID of the ESP.
  2233. //
  2234. GUID ESPUniquePartitionGUID;
  2235. //
  2236. // An array of gpt attribute revert records retrieved from the
  2237. // registry at boot up.
  2238. //
  2239. ULONG NumberOfAttributeRevertEntries;
  2240. PFTP_GPT_ATTRIBUTE_REVERT_ENTRY GptAttributeRevertEntries;
  2241. //
  2242. // The number of pre-exposures. Protect with 'Semaphore'.
  2243. //
  2244. ULONG PreExposureCount;
  2245. };
  2246. typedef DEVICE_EXTENSION *PDEVICE_EXTENSION;
  2247. typedef
  2248. VOID
  2249. (*ZERO_REF_CALLBACK)(
  2250. IN PVOLUME_EXTENSION VolumeExtension
  2251. );
  2252. class VOLUME_EXTENSION : public DEVICE_EXTENSION {
  2253. public:
  2254. //
  2255. // A pointer to the target object or the FT volume for this
  2256. // volume. Protect these with 'SpinLock'.
  2257. //
  2258. PDEVICE_OBJECT TargetObject; // 10
  2259. PFT_VOLUME FtVolume; // 14
  2260. LONG RefCount; // 18
  2261. ZERO_REF_CALLBACK ZeroRefCallback; // 1C
  2262. PVOID ZeroRefContext; // 20
  2263. LIST_ENTRY ZeroRefHoldQueue; // 24
  2264. BOOLEAN IsStarted; // 2C
  2265. BOOLEAN IsComplete; // 2D
  2266. BOOLEAN InPagingPath; // 2E
  2267. BOOLEAN RemoveInProgress; // 2F
  2268. BOOLEAN IsOffline; // 30
  2269. BOOLEAN DeadToPnp; // 31
  2270. BOOLEAN DeviceDeleted; // 32
  2271. BOOLEAN IsPreExposure; // 33
  2272. BOOLEAN IsGpt; // 34
  2273. BOOLEAN IsHidden; // 35
  2274. BOOLEAN IsSuperFloppy; // 36
  2275. BOOLEAN IsReadOnly; // 37
  2276. BOOLEAN IsEspType; // 38
  2277. BOOLEAN IsInstalled;
  2278. LONG AllSystemsGo; // 38
  2279. //
  2280. // List entry for volume list or dead volume list.
  2281. // Protect with 'Root->Semaphore'.
  2282. //
  2283. LIST_ENTRY ListEntry; // 3C
  2284. //
  2285. // The volume number.
  2286. //
  2287. ULONG VolumeNumber; // 44
  2288. //
  2289. // Emergency queue for a transfer packet. Protect with 'SpinLock'.
  2290. //
  2291. PDISPATCH_TP EmergencyTransferPacket; // 48
  2292. LIST_ENTRY EmergencyTransferPacketQueue; // 4C
  2293. BOOLEAN EmergencyTransferPacketInUse; // 54
  2294. //
  2295. // List of unique id change notify IRPs.
  2296. //
  2297. LIST_ENTRY ChangeNotifyIrps; // 58
  2298. //
  2299. // The dev node name for this device.
  2300. //
  2301. UNICODE_STRING DeviceNodeName; // 60
  2302. //
  2303. // Whole disk PDO, if this extension is a partition and
  2304. // not an FT volume.
  2305. //
  2306. PDEVICE_OBJECT WholeDiskPdo; // 68
  2307. PDEVICE_OBJECT WholeDisk; // 6C
  2308. LONGLONG PartitionOffset; // 70
  2309. LONGLONG PartitionLength; // 78
  2310. //
  2311. // Device Interface name.
  2312. //
  2313. UNICODE_STRING MountedDeviceInterfaceName; // 80
  2314. //
  2315. // A semaphore to protect 'ZeroRefCallback'.
  2316. //
  2317. KSEMAPHORE Semaphore; // 8C
  2318. //
  2319. // Old whole disk PDO to facilitate debugging.
  2320. //
  2321. PDEVICE_OBJECT OldWholeDiskPdo; // A0
  2322. //
  2323. // Unique Id Guid in the GPT case.
  2324. //
  2325. GUID UniqueIdGuid; // A4
  2326. //
  2327. // A copy of the current power state. Protect with 'SpinLock'.
  2328. //
  2329. DEVICE_POWER_STATE PowerState; // B4
  2330. //
  2331. // Whether or not the counters are running.
  2332. //
  2333. BOOLEAN CountersEnabled;
  2334. //
  2335. // Leave counters always enabled if we see IOCTL_DISK_PERFORMANCE
  2336. //
  2337. LONG EnableAlways;
  2338. //
  2339. // Counter structure.
  2340. //
  2341. PVOID PmWmiCounterContext;
  2342. //
  2343. // Table of Wmi Functions.
  2344. //
  2345. PWMILIB_CONTEXT WmilibContext;
  2346. //
  2347. // State for reverting GPT attributes. Protect with 'Root->Semaphore'.
  2348. //
  2349. ULONGLONG GptAttributesToRevertTo;
  2350. PFILE_OBJECT RevertOnCloseFileObject;
  2351. BOOLEAN ApplyToAllConnectedVolumes;
  2352. //
  2353. // Cached MBR GPT attributes.
  2354. //
  2355. ULONGLONG MbrGptAttributes;
  2356. };
  2357. #define DEVICE_EXTENSION_ROOT (0)
  2358. #define DEVICE_EXTENSION_VOLUME (1)
  2359. BOOLEAN
  2360. FtpIsWorseStatus(
  2361. IN NTSTATUS Status1,
  2362. IN NTSTATUS Status2
  2363. );
  2364. VOID
  2365. FtpComputeParity(
  2366. IN PVOID TargetBuffer,
  2367. IN PVOID SourceBuffer,
  2368. IN ULONG BufferLength
  2369. );
  2370. VOID
  2371. FtpLogError(
  2372. IN PDEVICE_EXTENSION Extension,
  2373. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  2374. IN NTSTATUS SpecificIoStatus,
  2375. IN NTSTATUS FinalStatus,
  2376. IN ULONG UniqueErrorValue
  2377. );
  2378. VOID
  2379. FtpQueueWorkItem(
  2380. IN PROOT_EXTENSION RootExtension,
  2381. IN PWORK_QUEUE_ITEM WorkItem
  2382. );
  2383. VOID
  2384. FtpNotify(
  2385. IN OUT PROOT_EXTENSION RootExtension,
  2386. IN PVOLUME_EXTENSION Extension
  2387. );
  2388. VOID
  2389. FtpAcquire(
  2390. IN OUT PROOT_EXTENSION RootExtension
  2391. );
  2392. NTSTATUS
  2393. FtpAcquireWithTimeout(
  2394. IN OUT PROOT_EXTENSION RootExtension
  2395. );
  2396. VOID
  2397. FtpRelease(
  2398. IN OUT PROOT_EXTENSION RootExtension
  2399. );
  2400. VOID
  2401. FtpDecrementRefCount(
  2402. IN OUT PVOLUME_EXTENSION Extension
  2403. );
  2404. FT_LOGICAL_DISK_ID
  2405. GenerateNewLogicalDiskId(
  2406. );
  2407. NTSTATUS
  2408. FtpQueryPartitionInformation(
  2409. IN PROOT_EXTENSION RootExtension,
  2410. IN PDEVICE_OBJECT Partition,
  2411. OUT PULONG DiskNumber,
  2412. OUT PLONGLONG Offset,
  2413. OUT PULONG PartitionNumber,
  2414. OUT PUCHAR PartitionType,
  2415. OUT PLONGLONG PartitionLength,
  2416. OUT GUID* PartitionTypeGuid,
  2417. OUT GUID* PartitionUniqueIdGuid,
  2418. OUT PBOOLEAN IsGpt,
  2419. OUT PULONGLONG GptAttributes
  2420. );
  2421. ULONG
  2422. FtpQueryDiskSignature(
  2423. IN PDEVICE_OBJECT WholeDiskPdo
  2424. );
  2425. NTSTATUS
  2426. FtpDiskRegistryQueryRoutine(
  2427. IN PWSTR ValueName,
  2428. IN ULONG ValueType,
  2429. IN PVOID ValueData,
  2430. IN ULONG ValueLength,
  2431. IN PVOID Context,
  2432. IN PVOID EntryContext
  2433. );
  2434. PDISK_PARTITION
  2435. FtpFindDiskPartition(
  2436. IN PDISK_REGISTRY DiskRegistry,
  2437. IN ULONG Signature,
  2438. IN LONGLONG Offset
  2439. );
  2440. VOID
  2441. FtpCopyStateToRegistry(
  2442. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  2443. IN PVOID LogicalDiskState,
  2444. IN USHORT LogicalDiskStateSize
  2445. );
  2446. BOOLEAN
  2447. FtpQueryStateFromRegistry(
  2448. IN FT_LOGICAL_DISK_ID LogicalDiskId,
  2449. IN PVOID LogicalDiskState,
  2450. IN USHORT BufferSize,
  2451. OUT PUSHORT LogicalDiskStateSize
  2452. );
  2453. VOID
  2454. FtpDeleteStateInRegistry(
  2455. IN FT_LOGICAL_DISK_ID LogicalDiskId
  2456. );
  2457. PVOLUME_EXTENSION
  2458. FtpFindExtensionCoveringDiskId(
  2459. IN PROOT_EXTENSION RootExtension,
  2460. IN FT_LOGICAL_DISK_ID LogicalDiskId
  2461. );
  2462. NTSTATUS
  2463. FtpReadPartitionTableEx(
  2464. IN PDEVICE_OBJECT DeviceObject,
  2465. IN PDRIVE_LAYOUT_INFORMATION_EX* DriveLayout
  2466. );
  2467. NTSTATUS
  2468. FtpApplyESPProtection(
  2469. IN PUNICODE_STRING PartitionName
  2470. );