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.

1407 lines
40 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. volsnap.h
  5. Abstract:
  6. This file provides the internal data structures for the volume snapshot
  7. driver.
  8. Author:
  9. Norbert P. Kusters (norbertk) 22-Jan-1999
  10. Environment:
  11. kernel mode only
  12. Notes:
  13. Revision History:
  14. --*/
  15. #ifdef POOL_TAGGING
  16. #undef ExAllocatePool
  17. #undef ExAllocatePoolWithQuota
  18. #define ExAllocatePool #assert(FALSE)
  19. #define ExAllocatePoolWithQuota #assert(FALSE)
  20. #endif
  21. #define VOLSNAP_TAG_APP_INFO 'aSoV' // VoSa - Application information allocations
  22. #define VOLSNAP_TAG_BUFFER 'bSoV' // VoSb - Buffer allocations
  23. #define VOLSNAP_TAG_CONTEXT 'cSoV' // VoSc - Snapshot context allocations
  24. #define VOLSNAP_TAG_DIFF_VOLUME 'dSoV' // VoSd - Diff area volume allocations
  25. #define VOLSNAP_TAG_DIFF_FILE 'fSoV' // VoSf - Diff area file allocations
  26. #define VOLSNAP_TAG_BIT_HISTORY 'hSoV' // VoSh - Bit history allocations
  27. #define VOLSNAP_TAG_IO_STATUS 'iSoV' // VoSi - Io status block allocations
  28. #define VOLSNAP_TAG_LOOKUP 'lSoV' // VoSl - Snasphot lookup table entry
  29. #define VOLSNAP_TAG_BITMAP 'mSoV' // VoSm - Bitmap allocations
  30. #define VOLSNAP_TAG_OLD_HEAP 'oSoV' // VoSo - Old heap entry allocations
  31. #define VOLSNAP_TAG_PNP_ID 'pSoV' // VoSp - Pnp id allocations
  32. #define VOLSNAP_TAG_RELATIONS 'rSoV' // VoSr - Device relations allocations
  33. #define VOLSNAP_TAG_SHORT_TERM 'sSoV' // VoSs - Short term allocations
  34. #define VOLSNAP_TAG_TEMP_TABLE 'tSoV' // VoSt - Temp table allocations
  35. #define VOLSNAP_TAG_WORK_QUEUE 'wSoV' // VoSw - Work queue allocations
  36. #define VOLSNAP_TAG_DISPATCH 'xSoV' // VoSx - Dispatch context allocations
  37. #define VOLSNAP_TAG_COPY 'CSoV' // VoSx - Copy On Write Structures
  38. #define NUMBER_OF_THREAD_POOLS (3)
  39. struct _VSP_CONTEXT;
  40. typedef struct _VSP_CONTEXT VSP_CONTEXT, *PVSP_CONTEXT;
  41. class FILTER_EXTENSION;
  42. typedef FILTER_EXTENSION* PFILTER_EXTENSION;
  43. class VOLUME_EXTENSION;
  44. typedef VOLUME_EXTENSION* PVOLUME_EXTENSION;
  45. //
  46. // Write context buffer.
  47. //
  48. typedef struct _VSP_WRITE_CONTEXT {
  49. LIST_ENTRY ListEntry;
  50. PFILTER_EXTENSION Filter;
  51. PVOLUME_EXTENSION Extension;
  52. PIRP Irp;
  53. LIST_ENTRY CompletionRoutines;
  54. } VSP_WRITE_CONTEXT, *PVSP_WRITE_CONTEXT;
  55. //
  56. // Copy On Write List Entry.
  57. //
  58. typedef struct _VSP_COPY_ON_WRITE {
  59. LIST_ENTRY ListEntry;
  60. LONGLONG RoundedStart;
  61. PVOID Buffer;
  62. } VSP_COPY_ON_WRITE, *PVSP_COPY_ON_WRITE;
  63. struct _TEMP_TRANSLATION_TABLE_ENTRY;
  64. typedef struct _TEMP_TRANSLATION_TABLE_ENTRY TEMP_TRANSLATION_TABLE_ENTRY,
  65. *PTEMP_TRANSLATION_TABLE_ENTRY;
  66. typedef struct _DO_EXTENSION {
  67. //
  68. // Pointer to the driver object.
  69. //
  70. PDRIVER_OBJECT DriverObject;
  71. //
  72. // List of volume filters in they system. Protect with 'Semaphore'.
  73. //
  74. LIST_ENTRY FilterList;
  75. //
  76. // HOLD/RELEASE Data. Protect with cancel spin lock.
  77. //
  78. LONG HoldRefCount;
  79. GUID HoldInstanceGuid;
  80. ULONG SecondsToHoldFsTimeout;
  81. ULONG SecondsToHoldIrpTimeout;
  82. LIST_ENTRY HoldIrps;
  83. KTIMER HoldTimer;
  84. KDPC HoldTimerDpc;
  85. //
  86. // A semaphore for synchronization.
  87. //
  88. KSEMAPHORE Semaphore;
  89. //
  90. // Worker Thread. Protect with 'SpinLock'.
  91. // Protect 'WorkerThreadObjects' and 'Wait*' with
  92. // 'ThreadsRefCountSemaphore'.
  93. //
  94. LIST_ENTRY WorkerQueue[NUMBER_OF_THREAD_POOLS];
  95. KSEMAPHORE WorkerSemaphore[NUMBER_OF_THREAD_POOLS];
  96. KSPIN_LOCK SpinLock[NUMBER_OF_THREAD_POOLS];
  97. PVOID* WorkerThreadObjects;
  98. BOOLEAN WaitForWorkerThreadsToExitWorkItemInUse;
  99. WORK_QUEUE_ITEM WaitForWorkerThreadsToExitWorkItem;
  100. //
  101. // Low-Priority Queue for sending stuff to the DelayedWorkQueue in a
  102. // single threaded manner. Protect with 'ESpinLock'.
  103. //
  104. LIST_ENTRY LowPriorityQueue;
  105. BOOLEAN WorkerItemInUse;
  106. WORK_QUEUE_ITEM LowPriorityWorkItem;
  107. PWORK_QUEUE_ITEM ActualLowPriorityWorkItem;
  108. //
  109. // The threads ref count. Protect with 'ThreadsRefCountSemaphore'.
  110. //
  111. LONG ThreadsRefCount;
  112. KSEMAPHORE ThreadsRefCountSemaphore;
  113. //
  114. // Notification entry.
  115. //
  116. PVOID NotificationEntry;
  117. //
  118. // Lookaside list for contexts.
  119. //
  120. NPAGED_LOOKASIDE_LIST ContextLookasideList;
  121. //
  122. // Emergency Context. Protect with 'ESpinLock'.
  123. //
  124. PVSP_CONTEXT EmergencyContext;
  125. BOOLEAN EmergencyContextInUse;
  126. LIST_ENTRY IrpWaitingList;
  127. LONG IrpWaitingListNeedsChecking;
  128. KSPIN_LOCK ESpinLock;
  129. //
  130. // Lookaside list for write context buffers.
  131. //
  132. NPAGED_LOOKASIDE_LIST WriteContextLookasideList;
  133. //
  134. // Emergency Write Context Buffer. Protect with 'ESpinLock'.
  135. //
  136. PVSP_WRITE_CONTEXT EmergencyWriteContext;
  137. BOOLEAN EmergencyWriteContextInUse;
  138. LIST_ENTRY WriteContextIrpWaitingList;
  139. LONG WriteContextIrpWaitingListNeedsChecking;
  140. //
  141. // Lookaside list for temp table entries.
  142. //
  143. NPAGED_LOOKASIDE_LIST TempTableEntryLookasideList;
  144. //
  145. // Emergency Temp Table Entry. Protect with 'ESpinLock'.
  146. //
  147. PVOID EmergencyTableEntry;
  148. BOOLEAN EmergencyTableEntryInUse;
  149. LIST_ENTRY WorkItemWaitingList;
  150. LONG WorkItemWaitingListNeedsChecking;
  151. //
  152. // Stack count for allocating IRPs. Use InterlockedExchange to update
  153. // along with Root->Semaphore. Then, can be read for use in allocating
  154. // copy irps.
  155. //
  156. LONG StackSize;
  157. //
  158. // Is the code locked? Protect with interlocked and 'Semaphore'.
  159. //
  160. LONG IsCodeLocked;
  161. //
  162. // Copy of registry path input to DriverEntry.
  163. //
  164. UNICODE_STRING RegistryPath;
  165. //
  166. // Queue for AdjustBitmap operations. Just one at at time in the delayed
  167. // work queue. Protect with 'ESpinLock'.
  168. //
  169. LIST_ENTRY AdjustBitmapQueue;
  170. BOOLEAN AdjustBitmapInProgress;
  171. //
  172. // Are we past re-init?
  173. //
  174. LONG PastReinit;
  175. //
  176. // Are we part boot-re-init?
  177. //
  178. KEVENT PastBootReinit;
  179. //
  180. // Keep a table of persistent information to facilitate matching
  181. // up a snapshot with its diff area. Protect with 'LookupTableMutex'.
  182. //
  183. RTL_GENERIC_TABLE PersistentSnapshotLookupTable;
  184. KMUTEX LookupTableMutex;
  185. //
  186. // Remember whether or not this is SETUP.
  187. //
  188. BOOLEAN IsSetup;
  189. //
  190. // Indicates that the volumes in the system are safe for write access.
  191. //
  192. LONG VolumesSafeForWriteAccess;
  193. //
  194. // Supplies the next volume number to be used for a snapshot.
  195. // Protect with InterlockedIncrement.
  196. //
  197. LONG NextVolumeNumber;
  198. //
  199. // Keep a table of used devnode numbers. Protect with 'Semaphore'.
  200. //
  201. RTL_GENERIC_TABLE UsedDevnodeNumbers;
  202. } DO_EXTENSION, *PDO_EXTENSION;
  203. #define DEVICE_EXTENSION_VOLUME (0)
  204. #define DEVICE_EXTENSION_FILTER (1)
  205. struct DEVICE_EXTENSION {
  206. //
  207. // Pointer to the device object for this extension.
  208. //
  209. PDEVICE_OBJECT DeviceObject;
  210. //
  211. // Pointer to the root device extension.
  212. //
  213. PDO_EXTENSION Root;
  214. //
  215. // The type of device extension.
  216. //
  217. ULONG DeviceExtensionType;
  218. //
  219. // A spinlock for synchronization.
  220. //
  221. KSPIN_LOCK SpinLock;
  222. };
  223. typedef DEVICE_EXTENSION* PDEVICE_EXTENSION;
  224. struct _VSP_DIFF_AREA_FILE;
  225. typedef struct _VSP_DIFF_AREA_FILE VSP_DIFF_AREA_FILE, *PVSP_DIFF_AREA_FILE;
  226. class VOLUME_EXTENSION : public DEVICE_EXTENSION {
  227. public:
  228. //
  229. // A pointer to the filter for the volume that we are snapshotting.
  230. //
  231. PFILTER_EXTENSION Filter;
  232. //
  233. // Local state to handle PNP's START and REMOVE.
  234. // Protect 'IsStarted' with 'InterlockedExchange'.
  235. // Protect 'DeadToPnp' with 'InterlockedExchange'.
  236. // Protect 'DeviceDeleted' with 'InterlockedExchange'.
  237. // Write protect 'IsDead' with 'InterlockedExchange' and
  238. // 'Root->Semaphore.'. 'IsDead' indicates that this device is really
  239. // dead now. It is illegal to turn IsStarted to TRUE.
  240. // Protect 'AliveToPnp' with 'InterlockedExchange'.
  241. // Protect 'IsOffline' with 'InterlockedExchange'.
  242. //
  243. LONG IsStarted;
  244. LONG DeadToPnp;
  245. LONG DeviceDeleted;
  246. LONG IsDead;
  247. LONG AliveToPnp;
  248. LONG IsOffline;
  249. //
  250. // Keep track of all requests outstanding in order to support
  251. // remove.
  252. // Protect 'RefCount' with 'InterlockedIncrement/Decrement'.
  253. // Write protect 'HoldIncomingRequests' with 'SpinLock' and
  254. // 'InterlockedExchange'.
  255. // Protect 'HoldQueue' with 'SpinLock'.
  256. // Protect 'ZeroRefEvent' with the setting of 'HoldIncomingRequests'
  257. // from 0 to 1.
  258. //
  259. LONG RefCount;
  260. LONG HoldIncomingRequests;
  261. KEVENT ZeroRefEvent;
  262. //
  263. // Post Commit Processing has occurred. Protect with 'Root->Semaphore'.
  264. // Don't return this device in BusRelations until this is TRUE.
  265. //
  266. BOOLEAN HasEndCommit;
  267. //
  268. // Indicates that this device has been installed. Protect with
  269. // 'Root->Semaphore'.
  270. //
  271. BOOLEAN IsInstalled;
  272. //
  273. // Indicates that this is a persistent snapshot.
  274. //
  275. BOOLEAN IsPersistent;
  276. //
  277. // Indicates that this persistent snapshot was detected, not created.
  278. //
  279. BOOLEAN IsDetected;
  280. //
  281. // Indicates that there we a need to grow the diff area found when
  282. // the snapshot was detected.
  283. //
  284. BOOLEAN DetectedNeedForGrow;
  285. //
  286. // Indicates that the persistent on disk structure has been
  287. // committed. Protect with 'NonPagedResource'.
  288. //
  289. BOOLEAN OnDiskNotCommitted;
  290. //
  291. // Indicates that the device is visible. Protect with
  292. // 'Root->Semaphore'.
  293. //
  294. BOOLEAN IsVisible;
  295. //
  296. // Indicates that no diff area fill is necessary for this persistent
  297. // snapshot.
  298. BOOLEAN NoDiffAreaFill;
  299. //
  300. // Indicates that the root semaphore is held.
  301. //
  302. BOOLEAN RootSemaphoreHeld;
  303. //
  304. // Indicates that this device object is a pre-exposure.
  305. // Protect with 'Root->Semaphore'.
  306. //
  307. BOOLEAN IsPreExposure;
  308. //
  309. // Indictates that this snapshot is keeping a reference to
  310. // 'IgnoreCopyData'. Protect with 'Root->Semaphore'.
  311. //
  312. BOOLEAN IgnoreCopyDataReference;
  313. //
  314. // Indicates that the grow failed and whether or not the limit
  315. // was user imposed.
  316. //
  317. BOOLEAN UserImposedLimit;
  318. LONG GrowFailed;
  319. //
  320. // Keep an event here for waiting for the pre-exposure.
  321. //
  322. KEVENT PreExposureEvent;
  323. //
  324. // Indicates that growing the diff area file is now safe.
  325. // Protect with 'InterlockedExchange'.
  326. //
  327. LONG OkToGrowDiffArea;
  328. //
  329. // Time stamp when commit took place.
  330. //
  331. LARGE_INTEGER CommitTimeStamp;
  332. //
  333. // A list entry for 'Filter->VolumeList'.
  334. // Write protect with 'Filter->SpinLock', 'Root->Semaphore', and
  335. // 'Filter->RefCount == 0'.
  336. // Blink points to an older snapshot.
  337. // Flink points to a newer snapshot.
  338. //
  339. LIST_ENTRY ListEntry;
  340. //
  341. // The volume number.
  342. //
  343. ULONG VolumeNumber;
  344. //
  345. // The devnode number.
  346. //
  347. ULONG DevnodeNumber;
  348. //
  349. // The volume snapshot GUID.
  350. //
  351. GUID SnapshotGuid;
  352. //
  353. // The snapshot order number. Set at commit time.
  354. //
  355. LONGLONG SnapshotOrderNumber;
  356. //
  357. // A table to translate volume offset to backing store offset.
  358. // Protect with 'PagedResource'.
  359. //
  360. RTL_GENERIC_TABLE VolumeBlockTable;
  361. RTL_GENERIC_TABLE CopyBackPointerTable;
  362. //
  363. // A table to store entries in flight. This table is non-paged.
  364. // Protect with 'NonPagedResource'.
  365. //
  366. RTL_GENERIC_TABLE TempVolumeBlockTable;
  367. ULONG MaximumNumberOfTempEntries;
  368. ULONG DiffAreaFileIncrease;
  369. //
  370. // The Diff Area File for this snapshot.
  371. // Write protect 'DiffAreaFile' pointer with 'NonPagedResource',
  372. // 'Root->Semaphore', 'RefCount == 0', and
  373. // 'extension->Filter->RefCount == 0'.
  374. //
  375. PVSP_DIFF_AREA_FILE DiffAreaFile;
  376. //
  377. // Memory mapped section of a diff area file to be used for a heap.
  378. // Protect with 'PagedResource'.
  379. //
  380. PVOID DiffAreaFileMap;
  381. ULONG DiffAreaFileMapSize;
  382. PVOID DiffAreaFileMapProcess;
  383. ULONG NextAvailable;
  384. PVOID NextDiffAreaFileMap;
  385. ULONG NextDiffAreaFileMapSize;
  386. LIST_ENTRY OldHeaps;
  387. //
  388. // A bitmap of blocks that do not need to be copy on writed.
  389. // Protect with 'SpinLock'.
  390. //
  391. PRTL_BITMAP VolumeBlockBitmap;
  392. //
  393. // A bitmap product of ignorable blocks from previous snapshots.
  394. // Protect with 'SpinLock'.
  395. //
  396. PRTL_BITMAP IgnorableProduct;
  397. //
  398. // Application Information. Protect with 'PagedResource'.
  399. //
  400. ULONG ApplicationInformationSize;
  401. PVOID ApplicationInformation;
  402. //
  403. // Volume size.
  404. //
  405. LONGLONG VolumeSize;
  406. //
  407. // Emergency copy irp. Protect with 'SpinLock'.
  408. //
  409. PIRP EmergencyCopyIrp;
  410. LONG EmergencyCopyIrpInUse;
  411. LIST_ENTRY EmergencyCopyIrpQueue;
  412. //
  413. // This field is used to pass a buffer to the TempTableAllocateRoutine.
  414. // Protect with 'NonPagedResource'.
  415. //
  416. PVOID TempTableEntry;
  417. //
  418. // These fields are there to help with the lag in creating new
  419. // page file space. Non paged pool can be used until the page file
  420. // space can be acquired. Protect 'PageFileSpaceCreatePending' and
  421. // 'WaitingForPageFileSpace' with 'SpinLock'.
  422. //
  423. LONG PageFileSpaceCreatePending;
  424. LIST_ENTRY WaitingForPageFileSpace;
  425. //
  426. // Mounted device interface name.
  427. //
  428. UNICODE_STRING MountedDeviceInterfaceName;
  429. //
  430. // These fields are there to help with the lag in creating new
  431. // diff area space. If the diff area volume does not have any
  432. // snapshots present on it, then a copy on write can block
  433. // on the arrival on new diff area space.
  434. //
  435. BOOLEAN GrowDiffAreaFilePending;
  436. BOOLEAN PastFileSystemOperations;
  437. LIST_ENTRY WaitingForDiffAreaSpace;
  438. //
  439. // States whether or not this snapshot has the crashdump file.
  440. //
  441. BOOLEAN ContainsCrashdumpFile;
  442. //
  443. // States whether or not this snapshot has copy on writed the hiber
  444. // file. Protect with 'InterlockedExchange'.
  445. //
  446. LONG HiberFileCopied;
  447. LONG PageFileCopied;
  448. //
  449. // Keep a list of Write Contexts. Protect with 'SpinLock'.
  450. //
  451. LIST_ENTRY WriteContextList;
  452. //
  453. // List entry for deleting the device objects.
  454. //
  455. LIST_ENTRY AnotherListEntry;
  456. };
  457. typedef
  458. VOID
  459. (*ZERO_REF_CALLBACK)(
  460. IN PFILTER_EXTENSION Filter
  461. );
  462. struct _VSP_CONTEXT {
  463. ULONG Type;
  464. WORK_QUEUE_ITEM WorkItem;
  465. union {
  466. struct {
  467. PVOLUME_EXTENSION Extension;
  468. PIRP OriginalReadIrp;
  469. ULONG_PTR OriginalReadIrpOffset;
  470. LONGLONG OriginalVolumeOffset;
  471. ULONG BlockOffset;
  472. ULONG Length;
  473. PDEVICE_OBJECT TargetObject;
  474. BOOLEAN IsCopyTarget;
  475. LONGLONG TargetOffset;
  476. } ReadSnapshot;
  477. struct {
  478. PDO_EXTENSION RootExtension;
  479. ULONG QueueNumber;
  480. } ThreadCreation;
  481. struct {
  482. PIO_WORKITEM IoWorkItem;
  483. PIRP Irp;
  484. } Dispatch;
  485. struct {
  486. PVOLUME_EXTENSION Extension;
  487. PIRP Irp;
  488. } Extension;
  489. struct {
  490. PFILTER_EXTENSION Filter;
  491. PIRP Irp;
  492. } Filter;
  493. struct {
  494. PVOLUME_EXTENSION Extension;
  495. LIST_ENTRY ExtentList;
  496. LONGLONG Current;
  497. ULONG Increase;
  498. KSPIN_LOCK SpinLock;
  499. PLIST_ENTRY CurrentEntry;
  500. ULONG CurrentEntryOffset;
  501. PDEVICE_OBJECT TargetObject;
  502. NTSTATUS ResultStatus;
  503. KEVENT Event;
  504. LONG RefCount;
  505. } GrowDiffArea;
  506. struct {
  507. KEVENT Event;
  508. } Event;
  509. struct {
  510. PVOLUME_EXTENSION Extension;
  511. PFILTER_EXTENSION DiffAreaFilter;
  512. NTSTATUS SpecificIoStatus;
  513. NTSTATUS FinalStatus;
  514. ULONG UniqueErrorValue;
  515. } ErrorLog;
  516. struct {
  517. PDO_EXTENSION RootExtension;
  518. } RootExtension;
  519. struct {
  520. PVOLUME_EXTENSION Extension;
  521. PIRP Irp;
  522. LONGLONG RoundedStart;
  523. } WriteVolume;
  524. struct {
  525. PFILTER_EXTENSION Filter;
  526. PKTIMER Timer;
  527. PKDPC Dpc;
  528. } DeleteDiffAreaFiles;
  529. struct {
  530. PFILTER_EXTENSION Filter;
  531. BOOLEAN KeepOnDisk;
  532. BOOLEAN SynchronousCall;
  533. } DestroyAllSnapshots;
  534. struct {
  535. PVOLUME_EXTENSION Extension;
  536. PIRP Irp;
  537. LIST_ENTRY ExtentList;
  538. BOOLEAN HiberfileIncluded;
  539. BOOLEAN PagefileIncluded;
  540. } CopyExtents;
  541. struct {
  542. PFILTER_EXTENSION Filter;
  543. HANDLE Handle1;
  544. HANDLE Handle2;
  545. } CloseHandles;
  546. struct {
  547. PFILTER_EXTENSION Filter;
  548. PIRP Irp;
  549. } DismountCleanupOnWrite;
  550. struct {
  551. PFILTER_EXTENSION Filter;
  552. KDPC TimerDpc;
  553. PKTIMER Timer;
  554. } PnpWaitTimer;
  555. struct {
  556. PFILTER_EXTENSION Filter;
  557. PIRP Irp;
  558. LONGLONG RoundedStart;
  559. LONGLONG RoundedEnd;
  560. } CopyOnWrite;
  561. };
  562. };
  563. #define VSP_CONTEXT_TYPE_READ_SNAPSHOT (1)
  564. #define VSP_CONTEXT_TYPE_THREAD_CREATION (2)
  565. #define VSP_CONTEXT_TYPE_DISPATCH (3)
  566. #define VSP_CONTEXT_TYPE_EXTENSION (4)
  567. #define VSP_CONTEXT_TYPE_FILTER (5)
  568. #define VSP_CONTEXT_TYPE_GROW_DIFF_AREA (6)
  569. #define VSP_CONTEXT_TYPE_EVENT (7)
  570. #define VSP_CONTEXT_TYPE_ERROR_LOG (8)
  571. #define VSP_CONTEXT_TYPE_ROOT_EXTENSION (9)
  572. #define VSP_CONTEXT_TYPE_WRITE_VOLUME (10)
  573. #define VSP_CONTEXT_TYPE_DELETE_DA_FILES (11)
  574. #define VSP_CONTEXT_TYPE_DESTROY_SNAPSHOTS (12)
  575. #define VSP_CONTEXT_TYPE_COPY_EXTENTS (13)
  576. #define VSP_CONTEXT_TYPE_CLOSE_HANDLES (14)
  577. #define VSP_CONTEXT_TYPE_DISMOUNT_CLEANUP (15)
  578. #define VSP_CONTEXT_TYPE_PNP_WAIT_TIMER (16)
  579. #define VSP_CONTEXT_TYPE_COPY_ON_WRITE (17)
  580. class FILTER_EXTENSION : public DEVICE_EXTENSION {
  581. public:
  582. //
  583. // The target object for this filter.
  584. //
  585. PDEVICE_OBJECT TargetObject;
  586. //
  587. // The PDO for this filter.
  588. //
  589. PDEVICE_OBJECT Pdo;
  590. //
  591. // Do we have any snapshots? Are they persistent?
  592. // Write protect with 'InterlockedExchange' and 'Root->Semaphore'.
  593. //
  594. LONG SnapshotsPresent;
  595. LONG PersistentSnapshots;
  596. //
  597. // Persistent only fields.
  598. // Protect 'FirstControlBlockVolumeOffset' with 'NonPagedResource'.
  599. // Protect 'ControlBlockFileHandle' with 'InterlockedExchange'.
  600. // Protect 'SnapshotOnDiskIrp' and control file contents with
  601. // 'NonPagedResource'.
  602. // Protect '*LookupTableEntries' with 'NonPagedResource'.
  603. //
  604. LONGLONG FirstControlBlockVolumeOffset;
  605. HANDLE ControlBlockFileHandle;
  606. KSEMAPHORE ControlBlockFileHandleSemaphore;
  607. PIRP SnapshotOnDiskIrp;
  608. LIST_ENTRY SnapshotLookupTableEntries;
  609. LIST_ENTRY DiffAreaLookupTableEntries;
  610. KEVENT ControlBlockFileHandleReady;
  611. //
  612. // Keep track of I/Os so that freeze/thaw is possible.
  613. // Protect 'RefCount' with 'InterlockedIncrement/Decrement'.
  614. // Write Protect 'HoldIncomingWrites' with InterlockedIncrement and
  615. // 'SpinLock'.
  616. // Protect 'HoldQueue' with 'SpinLock'.
  617. // Protect 'ZeroRefCallback', 'ZeroRefContext' with the setting
  618. // of 'ExternalWaiter' to 1 and 'SpinLock'.
  619. //
  620. LONG RefCount;
  621. LONG HoldIncomingWrites;
  622. LIST_ENTRY HoldQueue;
  623. BOOLEAN ExternalWaiter;
  624. ZERO_REF_CALLBACK ZeroRefCallback;
  625. PVOID ZeroRefContext;
  626. KEVENT ZeroRefEvent;
  627. KSEMAPHORE ZeroRefSemaphore;
  628. KTIMER HoldWritesTimer;
  629. KDPC HoldWritesTimerDpc;
  630. ULONG HoldWritesTimeout;
  631. //
  632. // The flush and hold irp is kept here while it is cancellable.
  633. // Protect with the cancel spin lock.
  634. //
  635. PIRP FlushAndHoldIrp;
  636. //
  637. // This event indicates that the end commit process is completed.
  638. // This means that PNP has kicked into gear and that the ignorable
  639. // bitmap computation has taken place.
  640. //
  641. KEVENT EndCommitProcessCompleted;
  642. //
  643. // Keep a notification entry on this object to watch for a
  644. // dismount. Protect with 'Root->Semaphore'.
  645. //
  646. PVOID TargetDeviceNotificationEntry;
  647. //
  648. // A list entry for 'Root->FilterList'.
  649. // Protect these with 'Root->Semaphore'.
  650. //
  651. LIST_ENTRY ListEntry;
  652. BOOLEAN NotInFilterList;
  653. //
  654. // Keep a list of snapshot volumes.
  655. // Write protect with 'Root->Semaphore', 'RefCount == 0', and
  656. // 'SpinLock'.
  657. // Flink points to the oldest snapshot.
  658. // Blink points to the newest snapshot.
  659. //
  660. LIST_ENTRY VolumeList;
  661. //
  662. // Cache the prepared snapshot for committing later.
  663. // Write protect with 'SpinLock' and 'Root->Semaphore'.
  664. //
  665. PVOLUME_EXTENSION PreparedSnapshot;
  666. //
  667. // A semaphore preventing 2 simultaneous critical operations.
  668. //
  669. KSEMAPHORE CriticalOperationSemaphore;
  670. //
  671. // List of dead snapshot volumes. Protect with 'Root->Semaphore'.
  672. //
  673. LIST_ENTRY DeadVolumeList;
  674. //
  675. // List of volume snapshots which depend on this filter for
  676. // diff area support. This will serve as removal relations.
  677. // Protect with 'Root->Semaphore' and 'SpinLock'.
  678. //
  679. LIST_ENTRY DiffAreaFilesOnThisFilter;
  680. //
  681. // The designated diff area volume that makes up the Diff Area for this
  682. // volume.
  683. // Protect with 'Root->Semaphore'.
  684. //
  685. PFILTER_EXTENSION DiffAreaVolume;
  686. //
  687. // Diff area sizes information total for all diff area files.
  688. // Protect with 'SpinLock'.
  689. // Additionally protect 'MaximumVolumeSpace' with 'NonPagedResource'.
  690. //
  691. LONGLONG UsedVolumeSpace;
  692. LONGLONG AllocatedVolumeSpace;
  693. LONGLONG MaximumVolumeSpace;
  694. //
  695. // Timer for completing END_COMMIT if device doesn't install.
  696. //
  697. KTIMER EndCommitTimer;
  698. KDPC EndCommitTimerDpc;
  699. //
  700. // File object for AUTO_CLEANUP. Protect with cancel spin lock.
  701. //
  702. PFILE_OBJECT AutoCleanupFileObject;
  703. //
  704. // Is a delete all snapshots pending. Protect with
  705. // 'InterlockedExchange'.
  706. //
  707. LONG DestroyAllSnapshotsPending;
  708. VSP_CONTEXT DestroyContext;
  709. //
  710. // Resource to use for protection. Don't page when holding this
  711. // resource. Protect the queueing with 'SpinLock'.
  712. //
  713. LIST_ENTRY NonPagedResourceList;
  714. BOOLEAN NonPagedResourceInUse;
  715. //
  716. // Page resource to use for protection. It is ok to page when
  717. // holding this resource. Protect the queueing with 'SpinLock'.
  718. //
  719. LIST_ENTRY PagedResourceList;
  720. BOOLEAN PagedResourceInUse;
  721. //
  722. // Indicates that a snapshot discovery is still pending. The
  723. // snapshot discovery will end upon the first write if not
  724. // all of the pieces make it in time. Protect with
  725. // 'InterlockedExchange' and 'RefCount == 0'.
  726. //
  727. LONG SnapshotDiscoveryPending;
  728. //
  729. // Remember whether or not the underlying volume is online.
  730. // Protect with 'Root->Semaphore'.
  731. //
  732. LONG IsOnline;
  733. //
  734. // Remember whether or not remove has been processed. Protect with
  735. // 'Root->Semaphore'.
  736. //
  737. BOOLEAN IsRemoved;
  738. //
  739. // Remember whether or not this volume is used for crashdump.
  740. // Protect with 'Root->Semaphore'.
  741. //
  742. BOOLEAN UsedForCrashdump;
  743. //
  744. // Protect with 'InterlockedExchange'.
  745. //
  746. LONG UsedForPaging;
  747. //
  748. // In the persistent snapshot case on the boot volume, keep a handle
  749. // to \SystemRoot\bootstat.dat and pin it. Protect with
  750. // 'InterlockedExchange'.
  751. //
  752. HANDLE BootStatHandle;
  753. //
  754. // Indicates that there is a hibernate action pending. Protect with
  755. // 'InterlockedExchange'.
  756. //
  757. LONG HibernatePending;
  758. //
  759. // Indicates that COPY DATA ioctls should be ignored. Protect with
  760. // 'InterlockedExchange'.
  761. //
  762. LONG IgnoreCopyData;
  763. //
  764. // Flag memory pressure to tweak commit and release error codes.
  765. //
  766. LONG LastReleaseDueToMemoryPressure;
  767. //
  768. // A bitmap that says, if a write comes here then delete all
  769. // snapshots using this volume. Set value with 'InterlockedExchange'
  770. // and protect with 'SpinLock'.
  771. //
  772. PRTL_BITMAP ProtectedBlocksBitmap;
  773. //
  774. // A list of copy on writes should be kept in non-paged pool
  775. // for a spell until the diff area volumes all arrive.
  776. // Protect 'FirstWriteProcessed' with 'SpinLock' and 'Interlocked'
  777. // Protect 'CopyOnWriteList' with 'SpinLock'.
  778. // Protect 'PnpWaitTimerContext' with 'SpinLock'.
  779. // Protect 'ActivateStarted' with 'SpinLock'.
  780. //
  781. LONG FirstWriteProcessed;
  782. LONG ActivateStarted;
  783. LIST_ENTRY CopyOnWriteList;
  784. PVSP_CONTEXT PnpWaitTimerContext;
  785. //
  786. // A ref count to keep track of pending file system operations
  787. // on this filter.
  788. //
  789. LONG FSRefCount;
  790. //
  791. // The delete diff area files timer. Protect with Critical.
  792. //
  793. PKTIMER DeleteTimer;
  794. //
  795. // Epic number to avoid queries
  796. //
  797. LONG EpicNumber;
  798. };
  799. typedef struct _VSP_WAIT_BLOCK {
  800. LONG RefCount;
  801. KEVENT Event;
  802. } VSP_WAIT_BLOCK, *PVSP_WAIT_BLOCK;
  803. #define BLOCK_SIZE (0x4000)
  804. #define BLOCK_SHIFT (14)
  805. #define MINIMUM_TABLE_HEAP_SIZE (0x20000)
  806. #define MEMORY_PRESSURE_CHECK_ALLOC_SIZE (0x40000)
  807. #define LARGEST_NTFS_CLUSTER (0x10000)
  808. #define SMALLEST_NTFS_CLUSTER (0x200)
  809. #define VSP_HIGH_PRIORITY (20)
  810. #define VSP_LOWER_PRIORITY (10)
  811. #define VSP_MAX_SNAPSHOTS (512)
  812. #define NOMINAL_DIFF_AREA_FILE_GROWTH (50*1024*1024)
  813. #define MAXIMUM_DIFF_AREA_FILE_GROWTH (1000*1024*1024)
  814. #define VSP_TRANSLATION_TABLE_ENTRY_FLAG_COPY_ENTRY (0x1)
  815. typedef struct _TRANSLATION_TABLE_ENTRY {
  816. LONGLONG VolumeOffset;
  817. PDEVICE_OBJECT TargetObject;
  818. ULONG Flags;
  819. LONGLONG TargetOffset;
  820. } TRANSLATION_TABLE_ENTRY, *PTRANSLATION_TABLE_ENTRY;
  821. //
  822. // The structure below is used in the non-paged temp table. 'IsComplete' and
  823. // 'WaitingQueueDpc' are protected with 'extension->SpinLock'.
  824. //
  825. struct _TEMP_TRANSLATION_TABLE_ENTRY {
  826. LONGLONG VolumeOffset;
  827. PVOLUME_EXTENSION Extension;
  828. PIRP WriteIrp;
  829. PIRP CopyIrp;
  830. PDEVICE_OBJECT TargetObject;
  831. LONGLONG TargetOffset;
  832. BOOLEAN IsComplete;
  833. BOOLEAN InTableUpdateQueue;
  834. BOOLEAN IsMoveEntry;
  835. PKEVENT WaitEvent;
  836. LIST_ENTRY WaitingQueueDpc; // These can run in arbitrary context.
  837. WORK_QUEUE_ITEM WorkItem;
  838. //
  839. // Fields used for the persistent implementation. Protect 'TableUpdate*'
  840. // with 'Extension->SpinLock'.
  841. //
  842. LIST_ENTRY TableUpdateListEntry;
  843. LONGLONG FileOffset;
  844. };
  845. //
  846. // The structure below is used in the persistent snapshot lookup table.
  847. // Protect everything with 'NonPagedResource'.
  848. // Protect 'SnapshotFilter', 'DiffAreaFilter' with 'Root->LookupTableMutex'.
  849. //
  850. typedef struct _VSP_LOOKUP_TABLE_ENTRY {
  851. GUID SnapshotGuid;
  852. PFILTER_EXTENSION SnapshotFilter;
  853. PFILTER_EXTENSION DiffAreaFilter;
  854. LIST_ENTRY SnapshotFilterListEntry;
  855. LIST_ENTRY DiffAreaFilterListEntry;
  856. LONGLONG VolumeSnapshotSize;
  857. LONGLONG SnapshotOrderNumber;
  858. ULONGLONG SnapshotControlItemFlags;
  859. LARGE_INTEGER SnapshotTime;
  860. LONGLONG DiffAreaStartingVolumeOffset;
  861. LONGLONG ApplicationInfoStartingVolumeOffset;
  862. LONGLONG DiffAreaLocationDescriptionVolumeOffset;
  863. LONGLONG InitialBitmapVolumeOffset;
  864. HANDLE DiffAreaHandle;
  865. } VSP_LOOKUP_TABLE_ENTRY, *PVSP_LOOKUP_TABLE_ENTRY;
  866. //
  867. // Write protect 'VolumeListEntry' with 'NonPagedResource' and
  868. // 'Root->Semaphore'.
  869. // Protect 'FilterListEntry*' with 'Root->Semaphore' and 'Filter->SpinLock'.
  870. // Protect 'NextAvailable' with 'NonPagedResource'
  871. // Write Protect 'AllocatedFileSize' with 'NonPagedResource' and
  872. // 'Root->Semaphore'.
  873. // Protect 'UnusedAllocationList' with 'NonPagedResource'.
  874. //
  875. struct _VSP_DIFF_AREA_FILE {
  876. LIST_ENTRY FilterListEntry;
  877. BOOLEAN FilterListEntryBeingUsed;
  878. PVOLUME_EXTENSION Extension;
  879. PFILTER_EXTENSION Filter;
  880. HANDLE FileHandle;
  881. LONGLONG NextAvailable;
  882. LONGLONG AllocatedFileSize;
  883. LIST_ENTRY UnusedAllocationList;
  884. LIST_ENTRY ListEntry;
  885. //
  886. // Fields used for the persistent implementation. Protect
  887. // 'TableUpdateQueue' and 'TableUpdateInProgress' with 'Extension->SpinLock'.
  888. // Whoever sets 'TableUpdateInProgress' to TRUE owns 'TableUpdateIrp',
  889. // 'NextFreeTableOffset', 'TableTargetOffset', and 'OldTableTargetOffset'.
  890. // Protect 'IrpNeeded' with 'Extension->SpinLock'.
  891. // Protect the initialization of 'IrpReady' with non-paged resource.
  892. // Protect 'ValidateHandleNeeded' with 'Root->Semaphore'.
  893. //
  894. PIRP TableUpdateIrp;
  895. ULONG NextFreeTableEntryOffset;
  896. LONGLONG ApplicationInfoTargetOffset;
  897. LONGLONG DiffAreaLocationDescriptionTargetOffset;
  898. LONGLONG InitialBitmapVolumeOffset;
  899. LONGLONG FirstTableTargetOffset;
  900. LONGLONG TableTargetOffset;
  901. LONGLONG NextTableTargetOffset;
  902. LONGLONG NextTableFileOffset;
  903. LIST_ENTRY TableUpdateQueue;
  904. BOOLEAN TableUpdateInProgress;
  905. BOOLEAN IrpNeeded;
  906. BOOLEAN ValidateHandleNeeded;
  907. BOOLEAN NextBlockAllocationInProgress;
  908. BOOLEAN NextBlockAllocationComplete;
  909. NTSTATUS StatusOfNextBlockAllocate;
  910. LIST_ENTRY TableUpdatesInProgress;
  911. WORK_QUEUE_ITEM WorkItem;
  912. KEVENT IrpReady;
  913. };
  914. typedef struct _DIFF_AREA_FILE_ALLOCATION {
  915. LIST_ENTRY ListEntry;
  916. LONGLONG Offset;
  917. LONGLONG NLength; // Negative values indicate that the length is unusable.
  918. } DIFF_AREA_FILE_ALLOCATION, *PDIFF_AREA_FILE_ALLOCATION;
  919. typedef struct _OLD_HEAP_ENTRY {
  920. LIST_ENTRY ListEntry;
  921. PVOID DiffAreaFileMap;
  922. } OLD_HEAP_ENTRY, *POLD_HEAP_ENTRY;
  923. //
  924. // {3808876B-C176-4e48-B7AE-04046E6CC752}
  925. // This GUID is used to decorate the names of the diff area files for
  926. // uniqueness. This GUID has been included in the list of files not to be
  927. // backed up by NTBACKUP. If this GUID is changed, or if other GUIDs are
  928. // added, then this change should also be reflected in the NTBACKUP file
  929. // not to be backed up.
  930. //
  931. DEFINE_GUID(VSP_DIFF_AREA_FILE_GUID, 0x3808876b, 0xc176, 0x4e48, 0xb7, 0xae, 0x4, 0x4, 0x6e, 0x6c, 0xc7, 0x52);
  932. //
  933. // The following definitions are for the persistent volume snapshot on disk
  934. // data structures.
  935. //
  936. #define VOLSNAP_PERSISTENT_VERSION (1)
  937. //
  938. // Block type definitions.
  939. //
  940. #define VSP_BLOCK_TYPE_START (1)
  941. #define VSP_BLOCK_TYPE_CONTROL (2)
  942. #define VSP_BLOCK_TYPE_DIFF_AREA (3)
  943. #define VSP_BLOCK_TYPE_APP_INFO (4)
  944. #define VSP_BLOCK_TYPE_DIFF_AREA_LOCATION_DESCRIPTION (5)
  945. #define VSP_BLOCK_TYPE_INITIAL_BITMAP (6)
  946. //
  947. // Common header for all block types.
  948. //
  949. typedef struct _VSP_BLOCK_HEADER {
  950. GUID Signature; // Equal to VSP_DIFF_AREA_FILE_GUID.
  951. ULONG Version; // Equal to VOLSNAP_PERSISTENT_VERSION.
  952. ULONG BlockType; // The type of block.
  953. LONGLONG ThisFileOffset; // The file offset of this block.
  954. LONGLONG ThisVolumeOffset; // The volume offset of this block.
  955. LONGLONG NextVolumeOffset; // The volume offset of the next block.
  956. } VSP_BLOCK_HEADER, *PVSP_BLOCK_HEADER;
  957. //
  958. // Start block definition. This will be stored in the last sector of the
  959. // NTFS boot file.
  960. //
  961. #define BYTES_IN_BOOT_AREA (0x2000)
  962. #define VSP_START_BLOCK_OFFSET (0x1E00)
  963. typedef struct _VSP_BLOCK_START {
  964. VSP_BLOCK_HEADER Header;
  965. LONGLONG FirstControlBlockVolumeOffset;
  966. LONGLONG MaximumDiffAreaSpace;
  967. } VSP_BLOCK_START, *PVSP_BLOCK_START;
  968. //
  969. // Control Item types definition.
  970. //
  971. #define VSP_CONTROL_ITEM_TYPE_END (0)
  972. #define VSP_CONTROL_ITEM_TYPE_FREE (1)
  973. #define VSP_CONTROL_ITEM_TYPE_SNAPSHOT (2)
  974. #define VSP_CONTROL_ITEM_TYPE_DIFF_AREA (3)
  975. //
  976. // Snapshot flags.
  977. //
  978. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_REVERT_MASTER (0x1)
  979. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_READ_WRITE (0x2)
  980. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_VISIBLE (0x4)
  981. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_DIRTY_CRASHDUMP (0x8)
  982. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_HIBERFIL_COPIED (0x10)
  983. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_PAGEFILE_COPIED (0x20)
  984. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_NO_DIFF_AREA_FILL (0x40)
  985. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_DIRTY_DETECTION (0x80)
  986. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_OFFLINE (0x100)
  987. #define VSP_SNAPSHOT_CONTROL_ITEM_FLAG_ALL (0x1FC)
  988. //
  989. // Control Item for snapshot.
  990. //
  991. typedef struct _VSP_CONTROL_ITEM_SNAPSHOT {
  992. ULONG ControlItemType; // Set to VSP_CONTROL_ITEM_TYPE_SNAPSHOT.
  993. ULONG Reserved;
  994. LONGLONG VolumeSnapshotSize;
  995. GUID SnapshotGuid;
  996. LONGLONG SnapshotOrderNumber;
  997. ULONGLONG SnapshotControlItemFlags;
  998. LARGE_INTEGER SnapshotTime;
  999. } VSP_CONTROL_ITEM_SNAPSHOT, *PVSP_CONTROL_ITEM_SNAPSHOT;
  1000. //
  1001. // Control Item for diff area file.
  1002. //
  1003. typedef struct _VSP_CONTROL_ITEM_DIFF_AREA {
  1004. ULONG ControlItemType; // Set to VSP_CONTROL_ITEM_TYPE_DIFF_AREA.
  1005. ULONG Reserved;
  1006. LONGLONG DiffAreaStartingVolumeOffset;
  1007. GUID SnapshotGuid;
  1008. LONGLONG ApplicationInfoStartingVolumeOffset;
  1009. LONGLONG DiffAreaLocationDescriptionVolumeOffset;
  1010. LONGLONG InitialBitmapVolumeOffset;
  1011. } VSP_CONTROL_ITEM_DIFF_AREA, *PVSP_CONTROL_ITEM_DIFF_AREA;
  1012. //
  1013. // Number of bytes per control information structure.
  1014. //
  1015. #define VSP_BYTES_PER_CONTROL_ITEM (0x80)
  1016. //
  1017. // Global snapshot flags.
  1018. //
  1019. #define VSP_CONTROL_BLOCK_FLAG_REVERT_IN_PROGRESS (0x1)
  1020. //
  1021. // Control block definition. These will stored consecutively
  1022. // as clusters in "\System Volume Information\{VSP_DIFF_AREA_FILE_GUID}".
  1023. //
  1024. typedef struct _VSP_BLOCK_CONTROL {
  1025. VSP_BLOCK_HEADER Header;
  1026. } VSP_BLOCK_CONTROL, *PVSP_BLOCK_CONTROL;
  1027. //
  1028. // The following is the persistent table definition within a diff area file.
  1029. //
  1030. #define VSP_DIFF_AREA_TABLE_ENTRY_FLAG_MOVE_ENTRY (0x1)
  1031. typedef struct _VSP_BLOCK_DIFF_AREA_TABLE_ENTRY {
  1032. LONGLONG SnapshotVolumeOffset;
  1033. LONGLONG DiffAreaFileOffset;
  1034. LONGLONG DiffAreaVolumeOffset;
  1035. ULONGLONG Flags;
  1036. } VSP_BLOCK_DIFF_AREA_TABLE_ENTRY, *PVSP_BLOCK_DIFF_AREA_TABLE_ENTRY;
  1037. //
  1038. // Diff area block structure. The first of these will be stored as the
  1039. // second block of the diff area file named
  1040. // "\System Volume Information\{SnapshotGuid}{VSP_DIFF_AREA_FILE_GUID}".
  1041. //
  1042. #define VSP_OFFSET_TO_FIRST_TABLE_ENTRY (0x80)
  1043. typedef struct _VSP_BLOCK_DIFF_AREA {
  1044. VSP_BLOCK_HEADER Header;
  1045. } VSP_BLOCK_DIFF_AREA, *PVSP_BLOCK_DIFF_AREA;
  1046. //
  1047. // App info block structure. This block will be stored as a block
  1048. // of the diff area file named
  1049. // "\System Volume Information\{SnapshotGuid}{VSP_DIFF_AREA_FILE_GUID}".
  1050. //
  1051. #define VSP_OFFSET_TO_APP_INFO (0x80)
  1052. #define VSP_MAX_APP_INFO_SIZE (BLOCK_SIZE - VSP_OFFSET_TO_APP_INFO)
  1053. typedef struct _VSP_BLOCK_APP_INFO {
  1054. VSP_BLOCK_HEADER Header;
  1055. ULONG AppInfoSize;
  1056. } VSP_BLOCK_APP_INFO, *PVSP_BLOCK_APP_INFO;
  1057. //
  1058. // The following is the definition of a Diff Area Location Descriptor.
  1059. //
  1060. typedef struct _VSP_DIFF_AREA_LOCATION_DESCRIPTOR {
  1061. LONGLONG VolumeOffset;
  1062. LONGLONG FileOffset;
  1063. LONGLONG Length;
  1064. } VSP_DIFF_AREA_LOCATION_DESCRIPTOR, *PVSP_DIFF_AREA_LOCATION_DESCRIPTOR;
  1065. //
  1066. // Diff Area File Location Description block structure. This block will
  1067. // be stored as a block of the diff area file named
  1068. // "\System Volume Information\{SnapshotGuid}{VSP_DIFF_AREA_FILE_GUID}".
  1069. //
  1070. #define VSP_OFFSET_TO_FIRST_LOCATION_DESCRIPTOR (0x80)
  1071. typedef struct _VSP_BLOCK_DIFF_AREA_LOCATION_DESCRIPTION {
  1072. VSP_BLOCK_HEADER Header;
  1073. } VSP_BLOCK_DIFF_AREA_LOCATION_DESCRIPTION, *PVSP_BLOCK_DIFF_AREA_LOCATION_DESCRIPTION;
  1074. //
  1075. // Initial Bitmap block structure. This block will be stored as a block of
  1076. // the diff area file named
  1077. // "\System Volume Information\{SnapshotGuid}{VSP_DIFF_AREA_FILE_GUID}".
  1078. //
  1079. #define VSP_OFFSET_TO_START_OF_BITMAP (0x80)
  1080. typedef struct _VSP_BLOCK_INITIAL_BITMAP {
  1081. VSP_BLOCK_HEADER Header;
  1082. } VSP_BLOCK_INITIAL_BITMAP, *PVSP_BLOCK_INITIAL_BITMAP;