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.

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