Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1741 lines
53 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. srpriv.h
  5. Abstract:
  6. This is a local header file for sr private structures and macros
  7. Author:
  8. Paul McDaniel (paulmcd) 23-Jan-2000
  9. Revision History:
  10. --*/
  11. #ifndef _SRPRIV_H_
  12. #define _SRPRIV_H_
  13. //
  14. // If CONFIG_LOGGING_VIA_REGISTRY is enables, SR will read the LogBufferSize,
  15. // LogAllocationUnit and LogFlushFrequency from the registry. While this is
  16. // useful for performance tuning, we don't want this functionality in the
  17. // shipping filter, so this should NOT be defined for shipping code.
  18. //
  19. //#define CONFIG_LOGGING_VIA_REGISTRY
  20. #ifdef CONFIG_LOGGING_VIA_REGISTRY
  21. #define REGISTRY_LOG_BUFFER_SIZE L"LogBufferSize"
  22. #define REGISTRY_LOG_ALLOCATION_UNIT L"LogAllocationUnit"
  23. #define REGISTRY_LOG_FLUSH_FREQUENCY L"LogFlushFrequency"
  24. #endif
  25. //
  26. // If SYNC_LOG_WRITE is defined, the filter will write all log entries
  27. // synchronously to the change log file. This has a significant impact on the
  28. // performance of the driver, therefore we are NOT doing this. We buffer
  29. // the log entries and write them to disk periodically.
  30. //
  31. // #define SYNC_LOG_WRITE
  32. //
  33. // forward definitions for srlog.h
  34. //
  35. typedef struct _SR_LOG_CONTEXT * PSR_LOG_CONTEXT;
  36. typedef struct _SR_LOGGER_CONTEXT * PSR_LOGGER_CONTEXT;
  37. //
  38. // allocation utilities
  39. //
  40. #define SR_ALLOCATE_POOL( type, len, tag ) \
  41. ExAllocatePoolWithTag( \
  42. (type), \
  43. (len), \
  44. (tag)|PROTECTED_POOL )
  45. #define SR_FREE_POOL( ptr, tag ) \
  46. ExFreePoolWithTag(ptr, (tag)|PROTECTED_POOL)
  47. #define SR_FREE_POOL_WITH_SIG(a,t) \
  48. { \
  49. ASSERT((a)->Signature == (t)); \
  50. (a)->Signature = MAKE_FREE_TAG(t); \
  51. SR_FREE_POOL(a,t); \
  52. (a) = NULL; \
  53. }
  54. #define SR_ALLOCATE_STRUCT(pt,ot,t) \
  55. (ot *)(SR_ALLOCATE_POOL(pt,sizeof(ot),t))
  56. #define SR_ALLOCATE_ARRAY(pt,et,c,t) \
  57. (et *)(SR_ALLOCATE_POOL(pt,sizeof(et)*(c),t))
  58. // BUGBUG: ALIGN_UP(PVOID) won't work, it needs to be the type of the first entry of the
  59. // following data (paulmcd 4/29/99)
  60. #define SR_ALLOCATE_STRUCT_WITH_SPACE(pt,ot,cb,t) \
  61. (ot *)(SR_ALLOCATE_POOL(pt,ALIGN_UP(sizeof(ot),PVOID)+(cb),t))
  62. #define MAKE_FREE_TAG(Tag) (((Tag) & 0xffffff00) | (ULONG)'x')
  63. #define IS_VALID_TAG(Tag) (((Tag) & 0x0000ffff) == 'rS' )
  64. //
  65. // ISSUE-2001-05-01-mollybro Restore can only handle file paths of at most 1000 characters
  66. // Restore should be fixed to cope with this, but for now, the filter is just
  67. // going to treat operations on files with names that are longer than 1000
  68. // characters as uninteresting (where the 1000 characters includes the
  69. // terminating NULL that will be added when the name is logged).
  70. // When this limit is eventually removed, we should remove these checks by
  71. // the filter (search for the places that use this macro).
  72. //
  73. // SR will only log filenames where the full path is 1000 characters
  74. // or less. This macro tests to make sure a name is within our valid range.
  75. //
  76. #define IS_FILENAME_VALID_LENGTH( pExtension, pFileName, StreamLength ) \
  77. (((((pFileName)->Length + (StreamLength)) - (pExtension)->pNtVolumeName->Length) < \
  78. (SR_MAX_FILENAME_PATH * sizeof( WCHAR ))) ? \
  79. TRUE : \
  80. FALSE )
  81. //
  82. // This is an internal error code this is used when we detect that a
  83. // volume has been disabled. Note that this status should NEVER be
  84. // returned from a dispatch routine. This is designed to be an error
  85. // code.
  86. //
  87. #define SR_STATUS_VOLUME_DISABLED ((NTSTATUS)-1)
  88. #define SR_STATUS_CONTEXT_NOT_SUPPORTED ((NTSTATUS)-2)
  89. #define SR_STATUS_IGNORE_FILE ((NTSTATUS)-3)
  90. //
  91. // Local event type definitions
  92. //
  93. //
  94. // these are copied manually
  95. //
  96. #define SR_MANUAL_COPY_EVENTS \
  97. (SrEventStreamChange)
  98. //
  99. // these are logged and only cared about once
  100. //
  101. #define SR_ONLY_ONCE_EVENT_TYPES \
  102. (SrEventAclChange|SrEventAttribChange)
  103. //
  104. // this we ignore after any of the SR_FULL_BACKUP_EVENT_TYPES occur
  105. // note: SrEventFileCreate is added to this list to prevent recording
  106. // of stream creates if we have recorded the unnamed stream create
  107. // already.
  108. //
  109. #define SR_IGNORABLE_EVENT_TYPES \
  110. (SrEventStreamChange|SrEventAclChange|SrEventAttribChange \
  111. |SrEventFileDelete|SrEventStreamCreate)
  112. //
  113. // these cause us to start ignoring SR_IGNORABLE_EVENT_TYPES
  114. //
  115. #define SR_FULL_BACKUP_EVENT_TYPES \
  116. (SrEventStreamChange|SrEventFileCreate \
  117. |SrEventFileDelete|SrEventStreamCreate)
  118. //
  119. // these we always need to log, even if we are ignoring them
  120. //
  121. #define SR_ALWAYS_LOG_EVENT_TYPES \
  122. (SrEventFileDelete)
  123. //
  124. // Certain events are relevant to the entire file and not just
  125. // the current stream. Flag these types of events so that we know
  126. // to put the ignorable events in the backup history keyed by the file
  127. // name instead of by the file and stream name.
  128. //
  129. #define SR_FILE_LEVEL_EVENTS \
  130. (SrEventStreamChange|SrEventFileDelete|SrEventAclChange|SrEventAttribChange)
  131. /***************************************************************************++
  132. Routine Description:
  133. This macro determines from the bits set in the EventType whether to
  134. log the current operation against the file name with the stream component
  135. or without the stream component. It returns 0 if this operation should
  136. be logged against the file without the stream name, or the StreamNameLength
  137. otherwise.
  138. Arguments:
  139. EventType - the event that just occured
  140. StreamNameLength - the length of the stream component of the name
  141. Return Value:
  142. 0 - If the filename without the stream component is to be used.
  143. StreamNameLength - If the filename with the stream component is to be used.
  144. --***************************************************************************/
  145. #define RECORD_AGAINST_STREAM( EventType, StreamNameLength ) \
  146. (FlagOn( (EventType), SR_FILE_LEVEL_EVENTS ) ? \
  147. 0 : \
  148. (StreamNameLength) )
  149. //
  150. // pool tags (please keep this in alpha order - reading backwards)
  151. //
  152. #define SR_BACKUP_DIRECTORY_CONTEXT_TAG MAKE_TAG('CBrS')
  153. #define SR_BACKUP_FILE_CONTEXT_TAG MAKE_TAG('FBrS')
  154. #define SR_COPY_BUFFER_TAG MAKE_TAG('BCrS')
  155. #define SR_CREATE_COMPLETION_TAG MAKE_TAG('CCrS')
  156. #define SR_COUNTED_EVENT_TAG MAKE_TAG('ECrS')
  157. #define SR_CONTROL_OBJECT_TAG MAKE_TAG('OCrS')
  158. #define SR_STREAM_CONTEXT_TAG MAKE_TAG('CSrS')
  159. #define SR_DEBUG_BLOB_TAG MAKE_TAG('BDrS')
  160. #define SR_DEVICE_EXTENSION_TAG MAKE_TAG('EDrS')
  161. #define SR_DEVICE_LIST_TAG MAKE_TAG('LDrS')
  162. #define SR_EA_DATA_TAG MAKE_TAG('DErS')
  163. #define SR_EXTENSION_LIST_TAG MAKE_TAG('LErS')
  164. #define SR_EVENT_RECORD_TAG MAKE_TAG('RErS')
  165. #define SR_FILE_ENTRY_TAG MAKE_TAG('EFrS')
  166. #define SR_FILENAME_BUFFER_TAG MAKE_TAG('NFrS')
  167. #define SR_GLOBALS_TAG MAKE_TAG('LGrS')
  168. #define SR_GET_OBJECT_NAME_CONTEXT_TAG MAKE_TAG('OGrS')
  169. #define HASH_BUCKET_TAG MAKE_TAG('BHrS')
  170. #define SR_HOOKED_DRIVER_ENTRY_TAG MAKE_TAG('DHrS')
  171. #define HASH_HEADER_TAG MAKE_TAG('HHrS')
  172. #define HASH_KEY_TAG MAKE_TAG('KHrS')
  173. #define SR_LOG_ACLINFO_TAG MAKE_TAG('AIrS')
  174. #define SR_KEVENT_TAG MAKE_TAG('EKrS')
  175. #define SR_LOG_BUFFER_TAG MAKE_TAG('BLrS')
  176. #define SR_LOG_CONTEXT_TAG MAKE_TAG('CLrS')
  177. #define SR_LOG_ENTRY_TAG MAKE_TAG('ELrS')
  178. #define SR_LOOKUP_TABLE_TAG MAKE_TAG('TLrS')
  179. #define SR_MOUNT_POINTS_TAG MAKE_TAG('PMrS')
  180. #define SR_OVERWRITE_INFO_TAG MAKE_TAG('IOrS')
  181. #define SR_PERSISTENT_CONFIG_TAG MAKE_TAG('CPrS')
  182. #define SR_RENAME_BUFFER_TAG MAKE_TAG('BRrS')
  183. #define SR_LOGGER_CONTEXT_TAG MAKE_TAG('GRrS')
  184. #define SR_REPARSE_HEADER_TAG MAKE_TAG('HRrS')
  185. #define SR_REGISTRY_TAG MAKE_TAG('RRrS')
  186. #define SR_SECURITY_DATA_TAG MAKE_TAG('DSrS')
  187. #define SR_STREAM_DATA_TAG MAKE_TAG('TSrS')
  188. #define SR_TRIGGER_ITEM_TAG MAKE_TAG('ITrS')
  189. #define SR_VOLUME_INFO_TAG MAKE_TAG('IVrS')
  190. #define SR_VOLUME_NAME_TAG MAKE_TAG('NVrS')
  191. #define SR_WORK_ITEM_TAG MAKE_TAG('IWrS')
  192. #define SR_WORK_CONTEXT_TAG MAKE_TAG('CWrS')
  193. //
  194. // We use a "trick" of hiding the stream name in the unicode string
  195. // between the Length and MaximumLength of the buffer. We then track the
  196. // StreamName length separately. This macro checks to make sure that
  197. // all is still in sync.
  198. //
  199. #define IS_VALID_SR_STREAM_STRING( pFileName, StreamLength ) \
  200. ((((pFileName)->Length + (StreamLength)) <= (pFileName)->MaximumLength) && \
  201. (((StreamLength) > 0) ? \
  202. (((pFileName)->Length < (pFileName)->MaximumLength) && \
  203. ((pFileName)->Buffer[(pFileName)->Length/sizeof(WCHAR)] == ':')) : \
  204. TRUE ))
  205. #define SR_FILE_READ_ACCESS READ_CONTROL | \
  206. FILE_READ_DATA | \
  207. FILE_READ_ATTRIBUTES | \
  208. FILE_READ_EA
  209. #define SR_FILE_WRITE_ACCESS WRITE_DAC | \
  210. WRITE_OWNER | \
  211. FILE_WRITE_DATA | \
  212. FILE_APPEND_DATA | \
  213. FILE_WRITE_ATTRIBUTES | \
  214. FILE_WRITE_EA
  215. //
  216. // The maximum number of characters in a short name.
  217. //
  218. #define SR_SHORT_NAME_CHARS (8 + 1 + 3)
  219. //
  220. // Error handlers.
  221. //
  222. #if DBG
  223. NTSTATUS
  224. SrDbgStatus(
  225. IN NTSTATUS Status,
  226. IN PSTR pFileName,
  227. IN USHORT LineNumber
  228. );
  229. #define CHECK_STATUS(status) SrDbgStatus((status),__FILE__,__LINE__)
  230. #define RETURN(status) return CHECK_STATUS(status)
  231. //
  232. // in debug builds i want the chance to DbgBreak on an error encountered
  233. // from a lower level api call.
  234. //
  235. #undef NT_SUCCESS
  236. #define NT_SUCCESS(status) ((NTSTATUS)(CHECK_STATUS((status))) >= 0)
  237. #define NT_SUCCESS_NO_DBGBREAK(status) ((NTSTATUS)(status) >= 0)
  238. #else
  239. #define RETURN(status) return (status)
  240. #define CHECK_STATUS(status) ((void)0)
  241. #define NT_SUCCESS_NO_DBGBREAK(status) NT_SUCCESS((status))
  242. #endif // DBG
  243. #define DebugFlagSet(a)\
  244. (FlagOn(_globals.DebugControl, SR_DEBUG_ ## a))
  245. //
  246. // Debug spew control.
  247. //
  248. #define SR_DEBUG_FUNC_ENTRY 0x00000001
  249. #define SR_DEBUG_CANCEL 0x00000002
  250. #define SR_DEBUG_NOTIFY 0x00000004
  251. #define SR_DEBUG_LOG_EVENT 0x00000008
  252. #define SR_DEBUG_INIT 0x00000020
  253. #define SR_DEBUG_HASH 0x00000040
  254. #define SR_DEBUG_LOOKUP 0x00000080
  255. #define SR_DEBUG_LOG 0x00000100
  256. #define SR_DEBUG_RENAME 0x00000200
  257. #define SR_DEBUG_LOAD_UNLOAD 0x00000400
  258. #define SR_DEBUG_BYTES_WRITTEN 0x00000800
  259. #define SR_DEBUG_PNP 0x00001000
  260. #define SR_DEBUG_EXPAND_SHORT_NAMES 0x00002000
  261. #define SR_DEBUG_BLOB_VERIFICATION 0x00004000
  262. #define SR_DEBUG_IOCTL 0x00008000
  263. #define SR_DEBUG_BREAK_ON_ERROR 0x00010000
  264. #define SR_DEBUG_VERBOSE_ERRORS 0x00020000
  265. #define SR_DEBUG_BREAK_ON_LOAD 0x00040000
  266. #define SR_DEBUG_ENABLE_UNLOAD 0x00080000
  267. #define SR_DEBUG_ADD_DEBUG_INFO 0x00100000
  268. #define SR_DEBUG_DELAY_DPC 0x00200000
  269. #define SR_DEBUG_KEEP_CONTEXT_NAMES 0x10000000
  270. #define SR_DEBUG_CONTEXT_LOG 0x20000000
  271. #define SR_DEBUG_CONTEXT_LOG_DETAILED 0x40000000
  272. #define SR_DEBUG_DEFAULTS (SR_DEBUG_VERBOSE_ERRORS)
  273. //
  274. // config file structures (store in \_restore\_driver.cfg)
  275. //
  276. // these can't go in the registry and they need to survive a restore, and
  277. // the registry is reverted along with the system , during a restore
  278. //
  279. typedef struct _SR_PERSISTENT_CONFIG
  280. {
  281. //
  282. // = SR_PERSISTENT_CONFIG_TAG
  283. //
  284. ULONG Signature;
  285. //
  286. // the number to use for the next temp file name (e.g. A0000001.exe = 1)
  287. //
  288. ULONG FileNameNumber;
  289. //
  290. // the number to use for the next seq number
  291. //
  292. INT64 FileSeqNumber;
  293. //
  294. // the number for the current restore point subdirectory (e.g.
  295. // "\_restore\rp5" = 5)
  296. //
  297. ULONG CurrentRestoreNumber;
  298. } SR_PERSISTENT_CONFIG, * PSR_PERSISTENT_CONFIG;
  299. #define RESTORE_CONFIG_LOCATION RESTORE_LOCATION L"\\_driver.cfg"
  300. //
  301. // Tracing.
  302. //
  303. #if DBG
  304. #define SrTrace(a, _b_) \
  305. { \
  306. if (DebugFlagSet(##a)) \
  307. { \
  308. try { \
  309. KdPrint( _b_ ); \
  310. } except (EXCEPTION_EXECUTE_HANDLER) { \
  311. /* do nothing, just catch it and ignore. bug#177569 */ \
  312. /* long strings with non-english characters can trigger */ \
  313. /* an exception with KdPrint. */ \
  314. } \
  315. } \
  316. }
  317. //
  318. // a version of SrTrace that does not wrap KdPrint with try, so should
  319. // only be used in cases where it is certain there is no risk of exception.
  320. // this is needed in termination handlers which cannot nest exception
  321. // handling
  322. //
  323. #define SrTraceSafe(a, _b_) \
  324. (DebugFlagSet(##a) ? KdPrint( _b_ ) : TRUE)
  325. /* { \
  326. IF_DEBUG(##a) \
  327. { \
  328. KdPrint( _b_ ); \
  329. } \
  330. }
  331. */
  332. #else //DBG
  333. #define SrTrace(a, _b_)
  334. #define SrTraceSafe(a, _b_)
  335. #endif //DBG
  336. //
  337. // Object types exported by the kernel but not in any header file.
  338. //
  339. extern POBJECT_TYPE *IoDeviceObjectType;
  340. //
  341. // Macro to clear pointers only in the DEBUG version
  342. //
  343. #if DBG
  344. # define NULLPTR(_p) ((_p) = NULL)
  345. #else
  346. # define NULLPTR(_p)
  347. #endif
  348. /////////////////////////////////////////////////////////////////////////////
  349. //
  350. // Public globals.
  351. //
  352. /////////////////////////////////////////////////////////////////////////////
  353. //
  354. // e.g. "{64bdb2bb-d3b0-41d6-a28e-275057d7740d}" = 38 characters
  355. //
  356. #define SR_GUID_BUFFER_LENGTH (38 * sizeof(WCHAR))
  357. #define SR_GUID_BUFFER_COUNT 40
  358. #define IS_VALID_GLOBALS(pObject) \
  359. (((pObject) != NULL) && ((pObject)->Signature == SR_GLOBALS_TAG))
  360. typedef struct _SR_GLOBALS
  361. {
  362. //
  363. // NonPagedPool
  364. //
  365. //
  366. // = SR_GLOBALS_TAG
  367. //
  368. ULONG Signature;
  369. //
  370. // Offset of process name in PEPROCESS struct, set to default
  371. // in logfmt.h but can be overridden using registry
  372. //
  373. ULONG ProcNameOffset;
  374. //
  375. // For controlling debug functions (like SrTrace) at runtime
  376. //
  377. ULONG DebugControl;
  378. //
  379. // the global DRIVER_OBJECT
  380. //
  381. PDRIVER_OBJECT pDriverObject;
  382. //
  383. // the sr device that people can open to get a control object
  384. //
  385. PDEVICE_OBJECT pControlDevice;
  386. //
  387. // OPTIONAL: a control object if it is open on this system
  388. //
  389. struct _SR_CONTROL_OBJECT * pControlObject;
  390. //
  391. // Are we currently monitoring the system? This is TRUE when the registry
  392. // says to disable, or the filter has received the STOP_MONITORING_IOCTL.
  393. // It only gets cleared when the filter receives the START_MONITORING_IOCTL.
  394. //
  395. // NOTE: This is NOT used for errors that require the filter to shut off.
  396. // The following flag provides that.
  397. //
  398. BOOLEAN Disabled;
  399. //
  400. // If we hit an error reading the blob and generated a volume error
  401. // on the system volume. Set this flag to true so that we don't
  402. // continue to try to load the blob until all the volumes have
  403. // been disabled by the service.
  404. //
  405. BOOLEAN HitErrorLoadingBlob;
  406. //
  407. // have we loaded our disk based config values yet? we delay load these
  408. // as we load pretty early in the boot sequence so our DriverEntry could
  409. // not do this
  410. //
  411. BOOLEAN FileConfigLoaded;
  412. //
  413. // have we loaded the blob info (lookup.c)
  414. //
  415. BOOLEAN BlobInfoLoaded;
  416. //
  417. // a debug flag for doing all of the normal work except for backups.
  418. //
  419. BOOLEAN DontBackup;
  420. //
  421. // our persistent config values
  422. //
  423. SR_PERSISTENT_CONFIG FileConfig;
  424. //
  425. // this is the number we used for the last backup file
  426. //
  427. ULONG LastFileNameNumber;
  428. //
  429. // this is the seq number
  430. //
  431. INT64 LastSeqNumber;
  432. //
  433. // the location to read our registry our of (from DriverEntry)
  434. //
  435. PUNICODE_STRING pRegistryLocation;
  436. //
  437. // in-memory blob information
  438. //
  439. BLOB_INFO BlobInfo;
  440. //
  441. // these resources are always acquired in order if nested acquired.
  442. // the activity lock is outermost.
  443. //
  444. //
  445. // Blob synchronization stuff (acquired sometimes with the global lock held)
  446. //
  447. ERESOURCE BlobLock;
  448. //
  449. // This resource locks pControlObject + this global structure + hash lists
  450. //
  451. ERESOURCE GlobalLock;
  452. //
  453. // the registry configured machine guid as a string
  454. // (e.g. "{03e692d7-b392-4a01-babf-1efd2c11d449}" )
  455. //
  456. WCHAR MachineGuid[SR_GUID_BUFFER_COUNT];
  457. #ifdef USE_LOOKASIDE
  458. //
  459. // lookaside lists for speedy allocations
  460. //
  461. PAGED_LOOKASIDE_LIST FileNameBufferLookaside;
  462. #endif
  463. //
  464. // Logger Context
  465. //
  466. PSR_LOGGER_CONTEXT pLogger;
  467. //
  468. // FsRtl fast I/O call backs
  469. //
  470. FAST_IO_DISPATCH FastIoDispatch;
  471. //
  472. // anchors the list of all device extensions (attached volumes)
  473. //
  474. ERESOURCE DeviceExtensionListLock;
  475. LIST_ENTRY DeviceExtensionListHead;
  476. //
  477. // keeps track of whether or not we have already attached to the system
  478. // volume.
  479. //
  480. struct _SR_DEVICE_EXTENSION * pSystemVolumeExtension;
  481. #ifndef SYNC_LOG_WRITE
  482. //
  483. // SR log buffer size
  484. //
  485. ULONG LogBufferSize;
  486. //
  487. // The time interval at which the logs are flushed, in seconds.
  488. //
  489. ULONG LogFlushFrequency;
  490. //
  491. // This is the calculated value that translate the LogFlushFrequency
  492. // to the form of the time that the KeTimer apis need (100-nanosecond
  493. // intervals).
  494. //
  495. LARGE_INTEGER LogFlushDueTime;
  496. #endif
  497. //
  498. // The unit used to extend the log files.
  499. //
  500. ULONG LogAllocationUnit;
  501. } SR_GLOBALS, *PSR_GLOBALS;
  502. extern PSR_GLOBALS global;
  503. extern SR_GLOBALS _globals;
  504. //
  505. // used as a window for persisting our file numbers to the disk.
  506. // a large enough number is used so that we don't have a problem during
  507. // power failures even if there is a lot of activity. otherwise the
  508. // number chosen is random.
  509. //
  510. #define SR_SEQ_NUMBER_INCREMENT 1000
  511. #define SR_FILE_NUMBER_INCREMENT 1000
  512. /////////////////////////////////////////////////////////////////////////////
  513. //
  514. // File Context related information
  515. //
  516. /////////////////////////////////////////////////////////////////////////////
  517. //
  518. // Structure for tracking an individual stream context. Note that the buffer
  519. // for the FileName is allocated as part of this structure and follows
  520. // immediatly after it.
  521. //
  522. typedef struct _SR_STREAM_CONTEXT
  523. {
  524. //
  525. // OS Structure used to track contexts per stream. Note how we use
  526. // the following fields:
  527. // OwnerID -> Holds pointer to our DeviceExtension
  528. // InstanceId -> Holds Pointer to FsContext associated
  529. // with this structure
  530. // We use these values to get back to these structures
  531. //
  532. FSRTL_PER_STREAM_CONTEXT ContextCtrl;
  533. //
  534. // Linked list used to track contexts per device (in our device
  535. // extension).
  536. //
  537. LIST_ENTRY ExtensionLink;
  538. //
  539. // This is a counter of how many threads are currently using this
  540. // context. The count is used in this way:
  541. // - It is set to 1 when it is created.
  542. // - It is incremented every time it is returned to a thread
  543. // - It is decremented when the thread is done with it.
  544. // - It is decremented when the underlying stream that is using it is freed
  545. // - The context is deleted when this count goes to zero
  546. //
  547. LONG UseCount;
  548. //
  549. // Maintain the link count -- currently for debugging purposes only.
  550. //
  551. ULONG LinkCount;
  552. //
  553. // Holds the name of the file
  554. //
  555. UNICODE_STRING FileName;
  556. //
  557. // This holds the length of the stream name portion of the
  558. // FileName. Note that this length is not included in the
  559. // length inside the FileName string but the characters
  560. // are there during debug.
  561. //
  562. USHORT StreamNameLength;
  563. //
  564. // Flags for this context. All flags are set or cleared via
  565. // the interlocked bit routines except when the entry is being
  566. // created, at this time we know nobody is using this entry.
  567. //
  568. ULONG Flags;
  569. } SR_STREAM_CONTEXT, *PSR_STREAM_CONTEXT;
  570. //
  571. // If set, this entry is interesting to SR
  572. //
  573. #define CTXFL_IsInteresting 0x00000001
  574. //
  575. // If set, this entry is for a directory
  576. //
  577. #define CTXFL_IsDirectory 0x00000002
  578. //
  579. // If set, this entry is for a volume open. We will not have a name
  580. // and this object will not be interesting.
  581. //
  582. #define CTXFL_IsVolumeOpen 0x00000004
  583. //
  584. // If set, this is a temporary context and should not be linked into
  585. // any of the context lists. It will be freed as soom as the user is
  586. // done with this operation.
  587. //
  588. #define CTXFL_Temporary 0x00000010
  589. //
  590. // If set, we are performing a significant operation that affects the state
  591. // of this context so we should not use it. If someone tries to get this
  592. // context then create a temporary context and return it. Cases where this
  593. // occurs:
  594. // - Source file of a rename.
  595. // - Source file for the creation of a hardlink
  596. //
  597. #define CTXFL_DoNotUse 0x00000020
  598. //
  599. // If set, we need to query the link count before linking this context into
  600. // the filter contexts.
  601. //
  602. #define CTXFL_QueryLinkCount 0x00000040
  603. //
  604. // If set, then we are currently linked into the device extension linked
  605. // list.
  606. //
  607. #define CTXFL_InExtensionList 0x00000100
  608. //
  609. // If set, then we are linked into the stream list. Note that there is
  610. // a small period of time when we might be unlinked with this flag still
  611. // set (when the file system is calling SrpDeleteContextCallback). This is
  612. // fine because we still handle not being found in the list when we do
  613. // the search. This flag handles the case when the file has been completly
  614. // closed (and the memory freed) on us.
  615. //
  616. #define CTXFL_InStreamList 0x00000200
  617. //
  618. // Macro used to set the Renaming flag in an individual context. We use the
  619. // list lock in the extension to protect this. We can get away with this
  620. // because rename operations are rare.
  621. //
  622. //#define SrSetRenamingFlag(ext,ctx) \
  623. //{ \
  624. // SrAcquireContextLockExclusive((ext)); \
  625. // SetFlag((ctx)->Flags,CTXFL_Renaming); \
  626. // SrReleaseContextLock((ext)); \
  627. //}
  628. //
  629. // We use this structure to keep track of all contexts associated with this
  630. // device. This way one we unload or disable monitoring we can walk
  631. // through and free all contexts.
  632. //
  633. typedef struct _SR_CONTEXT_CTRL
  634. {
  635. //
  636. // Lock used for accessing the linked list. We also acquire this lock
  637. // shared as we look up contexts. This way they can't disappear until
  638. // we get the use count updated.
  639. //
  640. ERESOURCE Lock;
  641. //
  642. // The linked list of contexts.
  643. //
  644. LIST_ENTRY List;
  645. //
  646. // If this count is non-zero then all contexts become temporary.
  647. // This count is presently used to track how many pending directory
  648. // renames are in progress in the system. While this count is non-zero
  649. // any contexts that are created become temporary and are freed
  650. // when the current operation is completed.
  651. //
  652. ULONG AllContextsTemporary;
  653. } SR_CONTEXT_CTRL, *PSR_CONTEXT_CTRL;
  654. //
  655. // Macros for locking the context lock
  656. //
  657. #define SrAcquireContextLockShared(pExt) \
  658. SrAcquireResourceShared( &(pExt)->ContextCtrl.Lock, TRUE )
  659. #define SrAcquireContextLockExclusive(pExt) \
  660. SrAcquireResourceExclusive( &(pExt)->ContextCtrl.Lock, TRUE )
  661. #define SrReleaseContextLock(pExt) \
  662. SrReleaseResource( &(pExt)->ContextCtrl.Lock )
  663. /////////////////////////////////////////////////////////////////////////////
  664. //
  665. // Name Control Structure related fields
  666. //
  667. /////////////////////////////////////////////////////////////////////////////
  668. //
  669. // This structure is used to retrieve the name of a file object. To prevent
  670. // allocating memory every time we get a name this structure contains a small
  671. // buffer (which should handle 90+% of all names). If we do overflow this
  672. // buffer we will allocate a buffer big enough for the name.
  673. //
  674. typedef struct _SRP_NAME_CONTROL
  675. {
  676. UNICODE_STRING Name;
  677. ULONG BufferSize;
  678. PUCHAR AllocatedBuffer;
  679. USHORT StreamNameLength;
  680. CHAR SmallBuffer[254];
  681. } SRP_NAME_CONTROL, *PSRP_NAME_CONTROL;
  682. /////////////////////////////////////////////////////////////////////////////
  683. //
  684. // Device Extension related definitions
  685. //
  686. /////////////////////////////////////////////////////////////////////////////
  687. #define IS_VALID_SR_DEVICE_EXTENSION( _ext ) \
  688. (((_ext) != NULL) && \
  689. ((_ext)->Signature == SR_DEVICE_EXTENSION_TAG))
  690. #define IS_SR_DEVICE_OBJECT( _devObj ) \
  691. (((_devObj) != NULL) && \
  692. ((_devObj)->DriverObject == _globals.pDriverObject) && \
  693. (IS_VALID_SR_DEVICE_EXTENSION(((PSR_DEVICE_EXTENSION)(_devObj)->DeviceExtension))))
  694. #define DEVICE_NAME_SZ 64
  695. typedef enum _SR_FILESYSTEM_TYPE {
  696. SrNtfs = 0x01,
  697. SrFat = 0x02,
  698. // Flag to determine whether or not this is attached to the filesystem's
  699. // control device object.
  700. SrFsControlDeviceObject = 0x80000000
  701. } SR_FILESYSTEM_TYPE, *PSR_FILESYSTEM_TYPE;
  702. typedef struct _SR_DEVICE_EXTENSION {
  703. //
  704. // NonPagedPool
  705. //
  706. //
  707. // SR_DEVICE_EXTENSION_TAG
  708. //
  709. ULONG Signature;
  710. //
  711. // links all extensions to global->DeviceExtensionListHead
  712. //
  713. LIST_ENTRY ListEntry;
  714. //
  715. // Activity lock for this volume.
  716. //
  717. ERESOURCE ActivityLock;
  718. BOOLEAN ActivityLockHeldExclusive;
  719. //
  720. // the dyanamic unnamed device created by sr.sys used to attach
  721. // to the target device
  722. //
  723. PDEVICE_OBJECT pDeviceObject;
  724. //
  725. // the target device.. that device that we attached to in the attachment
  726. // chain, when we hooked into the file system driver. might not be the
  727. // actual file system device, but another filter in the chain.
  728. //
  729. PDEVICE_OBJECT pTargetDevice;
  730. //
  731. // NT volume name (needs to be free'd if non-null)
  732. //
  733. PUNICODE_STRING pNtVolumeName;
  734. //
  735. // This lock is to synchronize volumes the work needed to do
  736. // to setup a volume (get the volume GUID, create the restore
  737. // location, etc) for logging or actually log an operation.
  738. //
  739. // NOTE: When this lock is acquired, the volume's ActivityLock
  740. // **MUST** be acquired either shared or exclusive (the SrAcquireLogLock
  741. // macro tests for this in DBG builds). For this reason, there are times
  742. // when we access the logging structures when we just have the
  743. // ActivityLock exclusive since this will be sufficient to get exclusive
  744. // access to the logging structures. The main reason for doing this is
  745. // performance -- we can save a few instructions by not making the call to
  746. // acquire the LogLock. Since we have exclusive access to the volume,
  747. // there should be no wait to get the log lock at these times.
  748. //
  749. ERESOURCE LogLock;
  750. //
  751. // the string version of the nt volume guid (e.g. "{xxx}" ).
  752. //
  753. UNICODE_STRING VolumeGuid;
  754. WCHAR VolumeGuidBuffer[SR_GUID_BUFFER_COUNT];
  755. //
  756. // the amount of bytes written to this volume since the last
  757. // notification. this is reset after each notification or volume
  758. // dismount
  759. //
  760. ULONGLONG BytesWritten;
  761. //
  762. // this struct contains the logging context for this volume
  763. //
  764. PSR_LOG_CONTEXT pLogContext;
  765. //
  766. // Volume information
  767. //
  768. SR_FILESYSTEM_TYPE FsType;
  769. //
  770. // Used to manage Contexts for a given volume.
  771. //
  772. SR_CONTEXT_CTRL ContextCtrl;
  773. //
  774. // Cached Volume attributes: valid only if CachedFsAttributes == TRUE
  775. //
  776. ULONG FsAttributes;
  777. BOOLEAN CachedFsAttributes;
  778. //
  779. // this drive will be temporarily disabled by the filter if it runs
  780. // out of space. this is reset by SrReloadConfiguration.
  781. //
  782. BOOLEAN Disabled;
  783. //
  784. // do we need to check the restore store on this drive, this is reset
  785. // on a SrCreateRestorePoint
  786. //
  787. BOOLEAN DriveChecked;
  788. //
  789. // this is used by filelist.c to provide a backup histore to prevent
  790. // duplicate backups to a file that changes multiple times within the same
  791. // restore point. This list is flushed on restore point creation, and
  792. // can be trimmed due to resource constraints
  793. //
  794. PHASH_HEADER pBackupHistory;
  795. } SR_DEVICE_EXTENSION, *PSR_DEVICE_EXTENSION;
  796. //
  797. // Macro used to see if we should LOG on this device object
  798. //
  799. #define SR_LOGGING_ENABLED(_devExt) \
  800. (!global->Disabled && !(_devExt)->Disabled)
  801. //
  802. // We don't need to log IO that is directed at the control device object
  803. // of a file system in most cases. This macro does the quick check of the
  804. // flags in our device extension to see if this is the control device object
  805. // for a file system.
  806. //
  807. #define SR_IS_FS_CONTROL_DEVICE(_devExt) \
  808. (FlagOn((_devExt)->FsType, SrFsControlDeviceObject))
  809. //
  810. // Definitions for posting operations
  811. //
  812. typedef
  813. NTSTATUS
  814. (*PSR_SYNCOP_ROUTINE) (
  815. IN PVOID Parameter
  816. );
  817. typedef struct _SR_WORK_CONTEXT {
  818. //
  819. // Work item used to queue
  820. //
  821. WORK_QUEUE_ITEM WorkItem;
  822. //
  823. // Actual caller supplied work routine
  824. //
  825. PSR_SYNCOP_ROUTINE SyncOpRoutine;
  826. //
  827. // Parameter to the routine
  828. //
  829. PVOID Parameter;
  830. //
  831. // Return status of routine
  832. //
  833. NTSTATUS Status;
  834. //
  835. // Event to sync with main-line thread
  836. //
  837. KEVENT SyncEvent;
  838. } SR_WORK_CONTEXT, *PSR_WORK_CONTEXT;
  839. //
  840. // Op. posting routines
  841. //
  842. VOID
  843. SrSyncOpWorker(
  844. IN PSR_WORK_CONTEXT WorkContext
  845. );
  846. NTSTATUS
  847. SrPostSyncOperation(
  848. IN PSR_SYNCOP_ROUTINE SyncOpRoutine,
  849. IN PVOID Parameter
  850. );
  851. //
  852. // Other stuff
  853. //
  854. PDEVICE_OBJECT
  855. SrGetFilterDevice (
  856. PDEVICE_OBJECT pDeviceObject
  857. );
  858. NTSTATUS
  859. SrCreateAttachmentDevice (
  860. IN PDEVICE_OBJECT pRealDevice OPTIONAL,
  861. IN PDEVICE_OBJECT pDeviceObject,
  862. OUT PDEVICE_OBJECT *ppNewDeviceObject
  863. );
  864. VOID
  865. SrDeleteAttachmentDevice (
  866. IN PDEVICE_OBJECT pDeviceObject
  867. );
  868. NTSTATUS
  869. SrAttachToDevice (
  870. IN PDEVICE_OBJECT pRealDevice OPTIONAL,
  871. IN PDEVICE_OBJECT pDeviceObject,
  872. IN PDEVICE_OBJECT pNewDeviceObject OPTIONAL,
  873. OUT PSR_DEVICE_EXTENSION * ppExtension OPTIONAL
  874. );
  875. NTSTATUS
  876. SrAttachToVolumeByName (
  877. IN PUNICODE_STRING pVolumeName,
  878. OUT PSR_DEVICE_EXTENSION * ppExtension OPTIONAL
  879. );
  880. VOID
  881. SrDetachDevice(
  882. IN PDEVICE_OBJECT pDeviceObject,
  883. IN BOOLEAN RemoveFromDeviceList
  884. );
  885. #if DBG
  886. //
  887. // In DBG mode, define a SR_MUTEX as a RESOURCE so that we get the
  888. // benefit of the thread information stored in ERESOURCES for debugging
  889. // purposes.
  890. //
  891. #define SR_MUTEX ERESOURCE
  892. #define SrInitializeMutex( mutex ) \
  893. ExInitializeResourceLite( (mutex) );
  894. #define SrAcquireMutex( mutex ) \
  895. { \
  896. ASSERT( !ExIsResourceAcquiredExclusive( (mutex) ) && \
  897. !ExIsResourceAcquiredShared( (mutex) ) ); \
  898. KeEnterCriticalRegion(); \
  899. ExAcquireResourceExclusive( (mutex), TRUE ); \
  900. }
  901. #define SrReleaseMutex( mutex ) \
  902. { \
  903. ASSERT( ExIsResourceAcquiredExclusive( (mutex) ) ); \
  904. ExReleaseResourceEx( (mutex) ); \
  905. KeLeaveCriticalRegion(); \
  906. }
  907. #else
  908. //
  909. // In non-DBG mode, define a SR_MUTEX as a FAST_MUTEX so that it is more
  910. // efficient for what we use this synchronization for than ERESOURCES.
  911. //
  912. #define SR_MUTEX FAST_MUTEX
  913. #define SrInitializeMutex( mutex ) \
  914. ExInitializeFastMutex( (mutex) );
  915. #define SrAcquireMutex( mutex ) \
  916. ExAcquireFastMutex( (mutex) );
  917. #define SrReleaseMutex( mutex ) \
  918. ExReleaseFastMutex( (mutex) );
  919. #endif /* DBG */
  920. #define SR_RESOURCE ERESOURCE;
  921. #define SrAcquireResourceExclusive( resource, wait ) \
  922. { \
  923. ASSERT( ExIsResourceAcquiredExclusiveLite((resource)) || \
  924. !ExIsResourceAcquiredSharedLite((resource)) ); \
  925. KeEnterCriticalRegion(); \
  926. ExAcquireResourceExclusiveLite( (resource), (wait) ); \
  927. }
  928. #define SrAcquireResourceShared( resource, wait ) \
  929. { \
  930. KeEnterCriticalRegion(); \
  931. ExAcquireResourceSharedLite( (resource), (wait) ); \
  932. }
  933. #define SrReleaseResource( resource ) \
  934. { \
  935. ASSERT( ExIsResourceAcquiredSharedLite((resource)) || \
  936. ExIsResourceAcquiredExclusiveLite((resource)) ); \
  937. ExReleaseResourceLite( (resource) ); \
  938. KeLeaveCriticalRegion(); \
  939. }
  940. #define IS_RESOURCE_INITIALIZED( resource ) \
  941. ((resource)->SystemResourcesList.Flink != NULL)
  942. #define IS_LOOKASIDE_INITIALIZED( lookaside ) \
  943. ((lookaside)->L.ListEntry.Flink != NULL)
  944. //
  945. // macro that should probably be in ntos\inc\io.h.
  946. //
  947. #define SrUnmarkIrpPending( Irp ) ( \
  948. IoGetCurrentIrpStackLocation( (Irp) )->Control &= ~SL_PENDING_RETURNED )
  949. //
  950. // Miscellaneous validators.
  951. //
  952. #define IS_VALID_DEVICE_OBJECT( pDeviceObject ) \
  953. ( ((pDeviceObject) != NULL) && \
  954. ((pDeviceObject)->Type == IO_TYPE_DEVICE) )
  955. // ((pDeviceObject)->Size == sizeof(DEVICE_OBJECT)) )
  956. #define IS_VALID_FILE_OBJECT( pFileObject ) \
  957. ( ((pFileObject) != NULL) && \
  958. ((pFileObject)->Type == IO_TYPE_FILE) )
  959. // ((pFileObject)->Size == sizeof(FILE_OBJECT)) )
  960. #define IS_VALID_IRP( pIrp ) \
  961. ( ((pIrp) != NULL) && \
  962. ((pIrp)->Type == IO_TYPE_IRP) && \
  963. ((pIrp)->Size >= IoSizeOfIrp((pIrp)->StackCount)) )
  964. //
  965. // Calculate the dimension of an array.
  966. //
  967. #define DIMENSION(x) ( sizeof(x) / sizeof(x[0]) )
  968. //
  969. // The DIFF macro should be used around an expression involving pointer
  970. // subtraction. The expression passed to DIFF is cast to a size_t type,
  971. // allowing the result to be easily assigned to any 32-bit variable or
  972. // passed to a function expecting a 32-bit argument.
  973. //
  974. #define DIFF(x) ((size_t)(x))
  975. //
  976. // the wait is in 100 nanosecond units to 10,000,000 = 1 second
  977. //
  978. #define NANO_FULL_SECOND (10000000)
  979. //
  980. // The default buffer size we use to buffer the log entries.
  981. //
  982. #define SR_DEFAULT_LOG_BUFFER_SIZE (2 * 1024)
  983. //
  984. // The frequency with which we should fire the log flush timer, in seconds.
  985. //
  986. #define SR_DEFAULT_LOG_FLUSH_FREQUENCY 1
  987. //
  988. // By default, we will extend the log file 16K at a time.
  989. //
  990. #define SR_DEFAULT_LOG_ALLOCATION_UNIT (16 * 1024)
  991. //
  992. // Returns TRUE if the given device type matches one of the device types
  993. // we support. If not, it returns FALSE.
  994. //
  995. #define SR_IS_SUPPORTED_DEVICE(_do) \
  996. ((_do)->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM)
  997. #define SR_IS_SUPPORTED_REAL_DEVICE(_rd) \
  998. (((_rd)->Characteristics & FILE_REMOVABLE_MEDIA) == 0)
  999. #define SR_IS_SUPPORTED_VOLUME(_vpb) \
  1000. (((_vpb)->DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) && \
  1001. ((_vpb)->RealDevice->Characteristics & FILE_REMOVABLE_MEDIA) == 0)
  1002. #define IS_VALID_WORK_ITEM(pObject) \
  1003. (((pObject) != NULL) && ((pObject)->Signature == SR_WORK_ITEM_TAG))
  1004. typedef struct _SR_WORK_ITEM
  1005. {
  1006. //
  1007. // NonPagedPool
  1008. //
  1009. //
  1010. // = SR_WORK_ITEM_TAG
  1011. //
  1012. ULONG Signature;
  1013. WORK_QUEUE_ITEM WorkItem;
  1014. PVOID Parameter1;
  1015. PVOID Parameter2;
  1016. PVOID Parameter3;
  1017. //
  1018. // The event to signal when the work item has been completed.
  1019. //
  1020. KEVENT Event;
  1021. //
  1022. // For return a status code
  1023. //
  1024. NTSTATUS Status;
  1025. } SR_WORK_ITEM, * PSR_WORK_ITEM;
  1026. #define SR_COPY_BUFFER_LENGTH (64 * 1024)
  1027. //
  1028. // used for file entries for ZwQueryDirectory
  1029. #define SR_FILE_ENTRY_LENGTH (1024*4)
  1030. //
  1031. // used just in case we switch to dos volume names
  1032. //
  1033. #define VOLUME_FORMAT L"%wZ"
  1034. //
  1035. // used for exception detection in finally
  1036. //
  1037. #if DBG
  1038. #define FinallyUnwind(FuncName, StatusCode) \
  1039. (AbnormalTermination()) ? \
  1040. ( SrTraceSafe( VERBOSE_ERRORS, \
  1041. ("sr!%s failed due to an unhandled exception!\n", #FuncName)),\
  1042. ( ( (global == NULL || FlagOn(global->DebugControl, SR_DEBUG_BREAK_ON_ERROR)) ? \
  1043. RtlAssert("AbnormalTermination() == FALSE", __FILE__, __LINE__, NULL) : \
  1044. 0 ), \
  1045. STATUS_UNHANDLED_EXCEPTION ) ) \
  1046. : (StatusCode)
  1047. #else
  1048. #define FinallyUnwind(FuncName, StatusCode) \
  1049. (AbnormalTermination()) ? \
  1050. STATUS_UNHANDLED_EXCEPTION \
  1051. : (StatusCode)
  1052. #endif // DBG
  1053. //
  1054. // stolen from sertlp.h
  1055. //
  1056. #define LongAlignPtr(Ptr) ((PVOID)(((ULONG_PTR)(Ptr) + 3) & -4))
  1057. #define LongAlignSize(Size) (((ULONG)(Size) + 3) & -4)
  1058. //
  1059. // the number of characters the largest ULONG takes in base 10 .
  1060. // 4294967295 = 10 chars
  1061. //
  1062. #define MAX_ULONG_CHARS (10)
  1063. #define MAX_ULONG_LENGTH (MAX_ULONG_CHARS*sizeof(WCHAR))
  1064. //
  1065. // flags to check if we are in the middle of text mode setup
  1066. //
  1067. #define UPGRADE_SETUPDD_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Setupdd"
  1068. #define UPGRADE_SETUPDD_VALUE_NAME L"Start"
  1069. //
  1070. // flags to check if we are in the middle of gui mode setup
  1071. //
  1072. #define UPGRADE_CHECK_SETUP_KEY_NAME L"\\Registry\\Machine\\System\\Setup"
  1073. #define UPGRADE_CHECK_SETUP_VALUE_NAME L"SystemSetupInProgress"
  1074. //
  1075. // this is a filter as to what sort of errors cause volume error's to be
  1076. // triggered. If we get the error STATUS_VOLUME_DISMOUNTED, we have already
  1077. // shutdown everything correctly and we don't want to treat this as an error.
  1078. // Also, if we get STATUS_FILE_CORRUPT_ERROR, the user's operation is also
  1079. // going to fail, so don't treat this as a volume error.
  1080. //
  1081. #define CHECK_FOR_VOLUME_ERROR(Status) \
  1082. ((STATUS_VOLUME_DISMOUNTED != Status) && \
  1083. (STATUS_FILE_CORRUPT_ERROR != Status) && \
  1084. (SR_STATUS_VOLUME_DISABLED != Status) && \
  1085. (SR_STATUS_CONTEXT_NOT_SUPPORTED != Status) && \
  1086. (SR_STATUS_IGNORE_FILE != Status) && \
  1087. !NT_SUCCESS((Status)))
  1088. //
  1089. // Macro that defines what a "volume name" mount point is. This macro can
  1090. // be used to scan the result from QUERY_POINTS to discover which mount points
  1091. // are "volume name" mount points.
  1092. //
  1093. // stolen + modified from mountmgr.h
  1094. //
  1095. #define MOUNTMGR_VOLUME_NAME_PREFIX_COUNT (49)
  1096. #define MOUNTMGR_VOLUME_NAME_PREFIX_LENGTH (49*sizeof(WCHAR))
  1097. #define MOUNTMGR_IS_VOLUME_NAME_PREFIX(s) ( \
  1098. (s)->Length >= MOUNTMGR_VOLUME_NAME_PREFIX_LENGTH && \
  1099. (s)->Buffer[0] == '\\' && \
  1100. (s)->Buffer[1] == '?' && \
  1101. (s)->Buffer[2] == '?' && \
  1102. (s)->Buffer[3] == '\\' && \
  1103. (s)->Buffer[4] == 'V' && \
  1104. (s)->Buffer[5] == 'o' && \
  1105. (s)->Buffer[6] == 'l' && \
  1106. (s)->Buffer[7] == 'u' && \
  1107. (s)->Buffer[8] == 'm' && \
  1108. (s)->Buffer[9] == 'e' && \
  1109. (s)->Buffer[10] == '{' && \
  1110. (s)->Buffer[19] == '-' && \
  1111. (s)->Buffer[24] == '-' && \
  1112. (s)->Buffer[29] == '-' && \
  1113. (s)->Buffer[34] == '-' && \
  1114. (s)->Buffer[47] == '}' && \
  1115. (s)->Buffer[48] == '\\' )
  1116. #if DBG
  1117. #define SrAcquireActivityLockShared(pExtension) \
  1118. { \
  1119. if (ExIsResourceAcquiredShared(&(pExtension)->ActivityLock) == FALSE) \
  1120. { \
  1121. /* no other locks better be held. the activity lock is the */ \
  1122. /* outermost lock */ \
  1123. ASSERT(!ExIsResourceAcquiredShared(&global->GlobalLock)); \
  1124. ASSERT(!ExIsResourceAcquiredExclusive( &global->GlobalLock)); \
  1125. ASSERT(!ExIsResourceAcquiredShared(&global->BlobLock)); \
  1126. ASSERT(!ExIsResourceAcquiredExclusive( &global->BlobLock)); \
  1127. ASSERT(!ExIsResourceAcquiredShared(&(pExtension)->LogLock)); \
  1128. ASSERT(!ExIsResourceAcquiredExclusive( &(pExtension)->LogLock)); \
  1129. } \
  1130. KeEnterCriticalRegion(); \
  1131. ExAcquireSharedStarveExclusive(&(pExtension)->ActivityLock, TRUE); \
  1132. }
  1133. #define SrAcquireActivityLockExclusive(pExtension) \
  1134. { \
  1135. if (!ExIsResourceAcquiredExclusive(&(pExtension)->ActivityLock)) \
  1136. { \
  1137. /* no other locks better be held. the activity lock is the */ \
  1138. /* outermost lock */ \
  1139. ASSERT(!ExIsResourceAcquiredShared(&global->GlobalLock)); \
  1140. ASSERT(!ExIsResourceAcquiredExclusive( &global->GlobalLock)); \
  1141. ASSERT(!ExIsResourceAcquiredShared(&global->BlobLock)); \
  1142. ASSERT(!ExIsResourceAcquiredExclusive( &global->BlobLock)); \
  1143. ASSERT(!ExIsResourceAcquiredShared(&(pExtension)->LogLock)); \
  1144. ASSERT(!ExIsResourceAcquiredExclusive( &(pExtension)->LogLock)); \
  1145. } \
  1146. SrAcquireResourceExclusive(&(pExtension)->ActivityLock, TRUE); \
  1147. }
  1148. #define SrAcquireLogLockShared(pExtension) \
  1149. { \
  1150. ASSERT(ExIsResourceAcquiredShared(&(pExtension)->ActivityLock) || \
  1151. ExIsResourceAcquiredExclusive( &(pExtension)->ActivityLock )); \
  1152. SrAcquireResourceShared(&(pExtension)->LogLock, TRUE); \
  1153. }
  1154. #define SrAcquireLogLockExclusive(pExtension) \
  1155. { \
  1156. ASSERT(ExIsResourceAcquiredShared(&(pExtension)->ActivityLock) || \
  1157. ExIsResourceAcquiredExclusive( &(pExtension)->ActivityLock )); \
  1158. SrAcquireResourceExclusive(&(pExtension)->LogLock, TRUE); \
  1159. }
  1160. #else
  1161. #define SrAcquireActivityLockShared(pExtension) \
  1162. { \
  1163. KeEnterCriticalRegion(); \
  1164. ExAcquireSharedStarveExclusive(&(pExtension)->ActivityLock, TRUE); \
  1165. }
  1166. #define SrAcquireActivityLockExclusive(pExtension) \
  1167. SrAcquireResourceExclusive(&(pExtension)->ActivityLock, TRUE)
  1168. #define SrAcquireLogLockShared(pExtension) \
  1169. SrAcquireResourceShared(&((pExtension)->LogLock), TRUE)
  1170. #define SrAcquireLogLockExclusive(pExtension) \
  1171. SrAcquireResourceExclusive(&((pExtension)->LogLock), TRUE)
  1172. #endif // DBG
  1173. #define IS_ACTIVITY_LOCK_ACQUIRED_EXCLUSIVE( pExtension ) \
  1174. ExIsResourceAcquiredExclusiveLite( &(pExtension)->ActivityLock )
  1175. #define IS_ACTIVITY_LOCK_ACQUIRED_SHARED( pExtension ) \
  1176. ExIsResourceAcquiredSharedLite( &(pExtension)->ActivityLock )
  1177. #define IS_LOG_LOCK_ACQUIRED_EXCLUSIVE( pExtension ) \
  1178. ExIsResourceAcquiredExclusiveLite( &(pExtension)->LogLock )
  1179. #define IS_LOG_LOCK_ACQUIRED_SHARED( pExtension ) \
  1180. ExIsResourceAcquiredSharedLite( &(pExtension)->LogLock )
  1181. #define SrReleaseActivityLock(pExtension) \
  1182. SrReleaseResource(&(pExtension)->ActivityLock)
  1183. #define SrReleaseLogLock(pExtension) \
  1184. SrReleaseResource(&(pExtension)->LogLock)
  1185. #define IS_GLOBAL_LOCK_ACQUIRED() \
  1186. (ExIsResourceAcquiredExclusiveLite(&(global->GlobalLock)) || \
  1187. ExIsResourceAcquiredSharedLite( &(global->GlobalLock) ))
  1188. #define SrAcquireGlobalLockExclusive() \
  1189. SrAcquireResourceExclusive( &(global->GlobalLock), TRUE )
  1190. #define SrReleaseGlobalLock() \
  1191. SrReleaseResource( &(global->GlobalLock) )
  1192. #define IS_BLOB_LOCK_ACQUIRED_EXCLUSIVE() \
  1193. (ExIsResourceAcquiredExclusiveLite(&(global->BlobLock)))
  1194. #define IS_BLOB_LOCK_ACQUIRED() \
  1195. (ExIsResourceAcquiredExclusiveLite(&(global->BlobLock)) || \
  1196. ExIsResourceAcquiredSharedLite( &(global->BlobLock) ))
  1197. #define SrAcquireBlobLockExclusive() \
  1198. SrAcquireResourceExclusive( &(global->BlobLock), TRUE )
  1199. #define SrAcquireBlobLockShared() \
  1200. SrAcquireResourceShared( &(global->BlobLock), TRUE )
  1201. #define SrReleaseBlobLock() \
  1202. SrReleaseResource( &(global->BlobLock) )
  1203. #define IS_DEVICE_EXTENSION_LIST_LOCK_ACQUIRED() \
  1204. (ExIsResourceAcquiredExclusiveLite(&(global->DeviceExtensionListLock)) || \
  1205. ExIsResourceAcquiredSharedLite( &(global->DeviceExtensionListLock) ))
  1206. #define SrAcquireDeviceExtensionListLockExclusive() \
  1207. SrAcquireResourceExclusive( &(global->DeviceExtensionListLock), TRUE )
  1208. #define SrAcquireDeviceExtensionListLockShared() \
  1209. SrAcquireResourceShared( &(global->DeviceExtensionListLock), TRUE )
  1210. #define SrReleaseDeviceExtensionListLock() \
  1211. SrReleaseResource( &(global->DeviceExtensionListLock) )
  1212. #define SrAcquireBackupHistoryLockShared( pExtension ) \
  1213. SrAcquireResourceShared( &((pExtension)->pBackupHistory->Lock), TRUE )
  1214. #define SrAcquireBackupHistoryLockExclusive( pExtension ) \
  1215. SrAcquireResourceExclusive( &((pExtension)->pBackupHistory->Lock), TRUE )
  1216. #define SrReleaseBackupHistoryLock( pExtension ) \
  1217. SrReleaseResource( &((pExtension)->pBackupHistory->Lock) )
  1218. //
  1219. // we require 50mb free to function
  1220. //
  1221. #define SR_MIN_DISK_FREE_SPACE (50 * 1024 * 1024)
  1222. //
  1223. // the temp unique filename used in SrHandleFileOverwrite
  1224. //
  1225. #define SR_UNIQUE_TEMP_FILE L"\\4bf03598-d7dd-4fbe-98b3-9b70a23ee8d4"
  1226. #define SR_UNIQUE_TEMP_FILE_LENGTH (37 * sizeof(WCHAR))
  1227. #define VALID_FAST_IO_DISPATCH_HANDLER(FastIoDispatchPtr, FieldName) \
  1228. (((FastIoDispatchPtr) != NULL) && \
  1229. (((FastIoDispatchPtr)->SizeOfFastIoDispatch) >= \
  1230. (FIELD_OFFSET(FAST_IO_DISPATCH, FieldName) + sizeof(VOID *))) && \
  1231. ((FastIoDispatchPtr)->FieldName != NULL))
  1232. #define FILE_OBJECT_IS_NOT_POTENTIALLY_INTERESTING(FileObject) \
  1233. ((FileObject) == NULL || \
  1234. FlagOn((FileObject)->Flags, FO_STREAM_FILE))
  1235. #define FILE_OBJECT_DOES_NOT_HAVE_VPB(FileObject) \
  1236. (FileObject)->Vpb == NULL
  1237. #define USE_DO_HINT
  1238. #ifdef USE_DO_HINT
  1239. #define SrIoCreateFile( F, D, O, I, A, FA, SA, CD, CO, EB, EL, FL, DO ) \
  1240. IoCreateFileSpecifyDeviceObjectHint((F), \
  1241. (D), \
  1242. (O), \
  1243. (I), \
  1244. (A), \
  1245. (FA), \
  1246. (SA), \
  1247. (CD), \
  1248. (CO), \
  1249. (EB), \
  1250. (EL), \
  1251. CreateFileTypeNone, \
  1252. NULL, \
  1253. (FL), \
  1254. (DO) );
  1255. #else
  1256. #define SrIoCreateFile( F, D, O, I, A, FA, SA, CD, CO, EB, EL, FL, DO ) \
  1257. ZwCreateFile((F), \
  1258. (D), \
  1259. (O), \
  1260. (I), \
  1261. (A), \
  1262. (FA), \
  1263. (SA), \
  1264. (CD), \
  1265. (CO), \
  1266. (EB), \
  1267. (EL) );
  1268. #endif /* USE_DO_HINT */
  1269. //
  1270. // Macros so that we can check for expected errors in debug code.
  1271. //
  1272. #if DBG
  1273. #define DECLARE_EXPECT_ERROR_FLAG( _ErrorFlag ) \
  1274. BOOLEAN _ErrorFlag = FALSE
  1275. #define SET_EXPECT_ERROR_FLAG( _ErrorFlag ) \
  1276. ((_ErrorFlag) = TRUE)
  1277. #define CLEAR_EXPECT_ERROR_FLAG( _ErrorFlag ) \
  1278. ((_ErrorFlag) = FALSE)
  1279. #define CHECK_FOR_EXPECTED_ERROR( _ErrorFlag, _Status ) \
  1280. { \
  1281. if ((_ErrorFlag)) \
  1282. { \
  1283. ASSERT( !NT_SUCCESS_NO_DBGBREAK( (_Status) ) );\
  1284. } \
  1285. }
  1286. #else
  1287. #define DECLARE_EXPECT_ERROR_FLAG( _ErrorFlag )
  1288. #define SET_EXPECT_ERROR_FLAG( _ErrorFlag )
  1289. #define CLEAR_EXPECT_ERROR_FLAG( _ErrorFlag )
  1290. #define CHECK_FOR_EXPECTED_ERROR( _ErrorFlag, _Status )
  1291. #endif
  1292. #endif // _SRPRIV_H_