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.

1760 lines
55 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. // Mutex for synchronizing the multiple paths through which we can
  384. // attach to a volume so that we don't attach more than once.
  385. //
  386. FAST_MUTEX AttachToVolumeLock;
  387. //
  388. // the sr device that people can open to get a control object
  389. //
  390. PDEVICE_OBJECT pControlDevice;
  391. //
  392. // OPTIONAL: a control object if it is open on this system
  393. //
  394. struct _SR_CONTROL_OBJECT * pControlObject;
  395. //
  396. // Are we currently monitoring the system? This is TRUE when the registry
  397. // says to disable, or the filter has received the STOP_MONITORING_IOCTL.
  398. // It only gets cleared when the filter receives the START_MONITORING_IOCTL.
  399. //
  400. // NOTE: This is NOT used for errors that require the filter to shut off.
  401. // The following flag provides that.
  402. //
  403. BOOLEAN Disabled;
  404. //
  405. // If we hit an error reading the blob and generated a volume error
  406. // on the system volume. Set this flag to true so that we don't
  407. // continue to try to load the blob until all the volumes have
  408. // been disabled by the service.
  409. //
  410. BOOLEAN HitErrorLoadingBlob;
  411. //
  412. // have we loaded our disk based config values yet? we delay load these
  413. // as we load pretty early in the boot sequence so our DriverEntry could
  414. // not do this
  415. //
  416. BOOLEAN FileConfigLoaded;
  417. //
  418. // have we loaded the blob info (lookup.c)
  419. //
  420. BOOLEAN BlobInfoLoaded;
  421. //
  422. // a debug flag for doing all of the normal work except for backups.
  423. //
  424. BOOLEAN DontBackup;
  425. //
  426. // our persistent config values
  427. //
  428. SR_PERSISTENT_CONFIG FileConfig;
  429. //
  430. // this is the number we used for the last backup file
  431. //
  432. ULONG LastFileNameNumber;
  433. //
  434. // this is the seq number
  435. //
  436. INT64 LastSeqNumber;
  437. //
  438. // the location to read our registry our of (from DriverEntry)
  439. //
  440. PUNICODE_STRING pRegistryLocation;
  441. //
  442. // in-memory blob information
  443. //
  444. BLOB_INFO BlobInfo;
  445. //
  446. // these resources are always acquired in order if nested acquired.
  447. // the activity lock is outermost.
  448. //
  449. //
  450. // Blob synchronization stuff (acquired sometimes with the global lock held)
  451. //
  452. ERESOURCE BlobLock;
  453. //
  454. // This resource locks pControlObject + this global structure + hash lists
  455. //
  456. ERESOURCE GlobalLock;
  457. //
  458. // the registry configured machine guid as a string
  459. // (e.g. "{03e692d7-b392-4a01-babf-1efd2c11d449}" )
  460. //
  461. WCHAR MachineGuid[SR_GUID_BUFFER_COUNT];
  462. #ifdef USE_LOOKASIDE
  463. //
  464. // lookaside lists for speedy allocations
  465. //
  466. PAGED_LOOKASIDE_LIST FileNameBufferLookaside;
  467. #endif
  468. //
  469. // Logger Context
  470. //
  471. PSR_LOGGER_CONTEXT pLogger;
  472. //
  473. // FsRtl fast I/O call backs
  474. //
  475. FAST_IO_DISPATCH FastIoDispatch;
  476. //
  477. // anchors the list of all device extensions (attached volumes)
  478. //
  479. ERESOURCE DeviceExtensionListLock;
  480. LIST_ENTRY DeviceExtensionListHead;
  481. //
  482. // a pointer to the system process (there is no api to get this)
  483. //
  484. PEPROCESS pSystemProcess;
  485. //
  486. // keeps track of whether or not we have already attached to the system
  487. // volume.
  488. //
  489. struct _SR_DEVICE_EXTENSION * pSystemVolumeExtension;
  490. #ifndef SYNC_LOG_WRITE
  491. //
  492. // SR log buffer size
  493. //
  494. ULONG LogBufferSize;
  495. //
  496. // The time interval at which the logs are flushed, in seconds.
  497. //
  498. ULONG LogFlushFrequency;
  499. //
  500. // This is the calculated value that translate the LogFlushFrequency
  501. // to the form of the time that the KeTimer apis need (100-nanosecond
  502. // intervals).
  503. //
  504. LARGE_INTEGER LogFlushDueTime;
  505. #endif
  506. //
  507. // The unit used to extend the log files.
  508. //
  509. ULONG LogAllocationUnit;
  510. } SR_GLOBALS, *PSR_GLOBALS;
  511. extern PSR_GLOBALS global;
  512. extern SR_GLOBALS _globals;
  513. //
  514. // used as a window for persisting our file numbers to the disk.
  515. // a large enough number is used so that we don't have a problem during
  516. // power failures even if there is a lot of activity. otherwise the
  517. // number chosen is random.
  518. //
  519. #define SR_SEQ_NUMBER_INCREMENT 1000
  520. #define SR_FILE_NUMBER_INCREMENT 1000
  521. /////////////////////////////////////////////////////////////////////////////
  522. //
  523. // File Context related information
  524. //
  525. /////////////////////////////////////////////////////////////////////////////
  526. //
  527. // Structure for tracking an individual stream context. Note that the buffer
  528. // for the FileName is allocated as part of this structure and follows
  529. // immediatly after it.
  530. //
  531. typedef struct _SR_STREAM_CONTEXT
  532. {
  533. //
  534. // OS Structure used to track contexts per stream. Note how we use
  535. // the following fields:
  536. // OwnerID -> Holds pointer to our DeviceExtension
  537. // InstanceId -> Holds Pointer to FsContext associated
  538. // with this structure
  539. // We use these values to get back to these structures
  540. //
  541. FSRTL_PER_STREAM_CONTEXT ContextCtrl;
  542. //
  543. // Linked list used to track contexts per device (in our device
  544. // extension).
  545. //
  546. LIST_ENTRY ExtensionLink;
  547. //
  548. // This is a counter of how many threads are currently using this
  549. // context. The count is used in this way:
  550. // - It is set to 1 when it is created.
  551. // - It is incremented every time it is returned to a thread
  552. // - It is decremented when the thread is done with it.
  553. // - It is decremented when the underlying stream that is using it is freed
  554. // - The context is deleted when this count goes to zero
  555. //
  556. LONG UseCount;
  557. //
  558. // Maintain the link count -- currently for debugging purposes only.
  559. //
  560. ULONG LinkCount;
  561. //
  562. // Holds the name of the file
  563. //
  564. UNICODE_STRING FileName;
  565. //
  566. // This holds the length of the stream name portion of the
  567. // FileName. Note that this length is not included in the
  568. // length inside the FileName string but the characters
  569. // are there during debug.
  570. //
  571. USHORT StreamNameLength;
  572. //
  573. // Flags for this context. All flags are set or cleared via
  574. // the interlocked bit routines except when the entry is being
  575. // created, at this time we know nobody is using this entry.
  576. //
  577. ULONG Flags;
  578. } SR_STREAM_CONTEXT, *PSR_STREAM_CONTEXT;
  579. //
  580. // If set, this entry is interesting to SR
  581. //
  582. #define CTXFL_IsInteresting 0x00000001
  583. //
  584. // If set, this entry is for a directory
  585. //
  586. #define CTXFL_IsDirectory 0x00000002
  587. //
  588. // If set, this entry is for a volume open. We will not have a name
  589. // and this object will not be interesting.
  590. //
  591. #define CTXFL_IsVolumeOpen 0x00000004
  592. //
  593. // If set, this is a temporary context and should not be linked into
  594. // any of the context lists. It will be freed as soom as the user is
  595. // done with this operation.
  596. //
  597. #define CTXFL_Temporary 0x00000010
  598. //
  599. // If set, we are performing a significant operation that affects the state
  600. // of this context so we should not use it. If someone tries to get this
  601. // context then create a temporary context and return it. Cases where this
  602. // occurs:
  603. // - Source file of a rename.
  604. // - Source file for the creation of a hardlink
  605. //
  606. #define CTXFL_DoNotUse 0x00000020
  607. //
  608. // If set, we need to query the link count before linking this context into
  609. // the filter contexts.
  610. //
  611. #define CTXFL_QueryLinkCount 0x00000040
  612. //
  613. // If set, then we are currently linked into the device extension linked
  614. // list.
  615. //
  616. #define CTXFL_InExtensionList 0x00000100
  617. //
  618. // If set, then we are linked into the stream list. Note that there is
  619. // a small period of time when we might be unlinked with this flag still
  620. // set (when the file system is calling SrpDeleteContextCallback). This is
  621. // fine because we still handle not being found in the list when we do
  622. // the search. This flag handles the case when the file has been completly
  623. // closed (and the memory freed) on us.
  624. //
  625. #define CTXFL_InStreamList 0x00000200
  626. //
  627. // Macro used to set the Renaming flag in an individual context. We use the
  628. // list lock in the extension to protect this. We can get away with this
  629. // because rename operations are rare.
  630. //
  631. //#define SrSetRenamingFlag(ext,ctx) \
  632. //{ \
  633. // SrAcquireContextLockExclusive((ext)); \
  634. // SetFlag((ctx)->Flags,CTXFL_Renaming); \
  635. // SrReleaseContextLock((ext)); \
  636. //}
  637. //
  638. // We use this structure to keep track of all contexts associated with this
  639. // device. This way one we unload or disable monitoring we can walk
  640. // through and free all contexts.
  641. //
  642. typedef struct _SR_CONTEXT_CTRL
  643. {
  644. //
  645. // Lock used for accessing the linked list. We also acquire this lock
  646. // shared as we look up contexts. This way they can't disappear until
  647. // we get the use count updated.
  648. //
  649. ERESOURCE Lock;
  650. //
  651. // The linked list of contexts.
  652. //
  653. LIST_ENTRY List;
  654. //
  655. // If this count is non-zero then all contexts become temporary.
  656. // This count is presently used to track how many pending directory
  657. // renames are in progress in the system. While this count is non-zero
  658. // any contexts that are created become temporary and are freed
  659. // when the current operation is completed.
  660. //
  661. ULONG AllContextsTemporary;
  662. } SR_CONTEXT_CTRL, *PSR_CONTEXT_CTRL;
  663. //
  664. // Macros for locking the context lock
  665. //
  666. #define SrAcquireContextLockShared(pExt) \
  667. SrAcquireResourceShared( &(pExt)->ContextCtrl.Lock, TRUE )
  668. #define SrAcquireContextLockExclusive(pExt) \
  669. SrAcquireResourceExclusive( &(pExt)->ContextCtrl.Lock, TRUE )
  670. #define SrReleaseContextLock(pExt) \
  671. SrReleaseResource( &(pExt)->ContextCtrl.Lock )
  672. /////////////////////////////////////////////////////////////////////////////
  673. //
  674. // Name Control Structure related fields
  675. //
  676. /////////////////////////////////////////////////////////////////////////////
  677. //
  678. // This structure is used to retrieve the name of a file object. To prevent
  679. // allocating memory every time we get a name this structure contains a small
  680. // buffer (which should handle 90+% of all names). If we do overflow this
  681. // buffer we will allocate a buffer big enough for the name.
  682. //
  683. typedef struct _SRP_NAME_CONTROL
  684. {
  685. UNICODE_STRING Name;
  686. ULONG BufferSize;
  687. PUCHAR AllocatedBuffer;
  688. USHORT StreamNameLength;
  689. CHAR SmallBuffer[254];
  690. } SRP_NAME_CONTROL, *PSRP_NAME_CONTROL;
  691. /////////////////////////////////////////////////////////////////////////////
  692. //
  693. // Device Extension related definitions
  694. //
  695. /////////////////////////////////////////////////////////////////////////////
  696. #define IS_VALID_SR_DEVICE_EXTENSION( _ext ) \
  697. (((_ext) != NULL) && \
  698. ((_ext)->Signature == SR_DEVICE_EXTENSION_TAG))
  699. #define IS_SR_DEVICE_OBJECT( _devObj ) \
  700. (((_devObj) != NULL) && \
  701. ((_devObj)->DriverObject == _globals.pDriverObject) && \
  702. (IS_VALID_SR_DEVICE_EXTENSION(((PSR_DEVICE_EXTENSION)(_devObj)->DeviceExtension))))
  703. #define DEVICE_NAME_SZ 64
  704. typedef enum _SR_FILESYSTEM_TYPE {
  705. SrNtfs = 0x01,
  706. SrFat = 0x02,
  707. // Flag to determine whether or not this is attached to the filesystem's
  708. // control device object.
  709. SrFsControlDeviceObject = 0x80000000
  710. } SR_FILESYSTEM_TYPE, *PSR_FILESYSTEM_TYPE;
  711. typedef struct _SR_DEVICE_EXTENSION {
  712. //
  713. // NonPagedPool
  714. //
  715. //
  716. // SR_DEVICE_EXTENSION_TAG
  717. //
  718. ULONG Signature;
  719. //
  720. // links all extensions to global->DeviceExtensionListHead
  721. //
  722. LIST_ENTRY ListEntry;
  723. //
  724. // Activity lock for this volume.
  725. //
  726. ERESOURCE ActivityLock;
  727. BOOLEAN ActivityLockHeldExclusive;
  728. //
  729. // the dyanamic unnamed device created by sr.sys used to attach
  730. // to the target device
  731. //
  732. PDEVICE_OBJECT pDeviceObject;
  733. //
  734. // the target device.. that device that we attached to in the attachment
  735. // chain, when we hooked into the file system driver. might not be the
  736. // actual file system device, but another filter in the chain.
  737. //
  738. PDEVICE_OBJECT pTargetDevice;
  739. //
  740. // NT volume name (needs to be free'd if non-null)
  741. //
  742. PUNICODE_STRING pNtVolumeName;
  743. //
  744. // This lock is to synchronize volumes the work needed to do
  745. // to setup a volume (get the volume GUID, create the restore
  746. // location, etc) for logging or actually log an operation.
  747. //
  748. // NOTE: When this lock is acquired, the volume's ActivityLock
  749. // **MUST** be acquired either shared or exclusive (the SrAcquireLogLock
  750. // macro tests for this in DBG builds). For this reason, there are times
  751. // when we access the logging structures when we just have the
  752. // ActivityLock exclusive since this will be sufficient to get exclusive
  753. // access to the logging structures. The main reason for doing this is
  754. // performance -- we can save a few instructions by not making the call to
  755. // acquire the LogLock. Since we have exclusive access to the volume,
  756. // there should be no wait to get the log lock at these times.
  757. //
  758. ERESOURCE LogLock;
  759. //
  760. // the string version of the nt volume guid (e.g. "{xxx}" ).
  761. //
  762. UNICODE_STRING VolumeGuid;
  763. WCHAR VolumeGuidBuffer[SR_GUID_BUFFER_COUNT];
  764. //
  765. // the amount of bytes written to this volume since the last
  766. // notification. this is reset after each notification or volume
  767. // dismount
  768. //
  769. ULONGLONG BytesWritten;
  770. //
  771. // this struct contains the logging context for this volume
  772. //
  773. PSR_LOG_CONTEXT pLogContext;
  774. //
  775. // Volume information
  776. //
  777. SR_FILESYSTEM_TYPE FsType;
  778. //
  779. // Used to manage Contexts for a given volume.
  780. //
  781. SR_CONTEXT_CTRL ContextCtrl;
  782. //
  783. // Cached Volume attributes: valid only if CachedFsAttributes == TRUE
  784. //
  785. ULONG FsAttributes;
  786. BOOLEAN CachedFsAttributes;
  787. //
  788. // this drive will be temporarily disabled by the filter if it runs
  789. // out of space. this is reset by SrReloadConfiguration.
  790. //
  791. BOOLEAN Disabled;
  792. //
  793. // do we need to check the restore store on this drive, this is reset
  794. // on a SrCreateRestorePoint
  795. //
  796. BOOLEAN DriveChecked;
  797. //
  798. // this is used by filelist.c to provide a backup histore to prevent
  799. // duplicate backups to a file that changes multiple times within the same
  800. // restore point. This list is flushed on restore point creation, and
  801. // can be trimmed due to resource constraints
  802. //
  803. PHASH_HEADER pBackupHistory;
  804. } SR_DEVICE_EXTENSION, *PSR_DEVICE_EXTENSION;
  805. //
  806. // Macro used to see if we should LOG on this device object
  807. //
  808. #define SR_LOGGING_ENABLED(_devExt) \
  809. (!global->Disabled && !(_devExt)->Disabled)
  810. //
  811. // We don't need to log IO that is directed at the control device object
  812. // of a file system in most cases. This macro does the quick check of the
  813. // flags in our device extension to see if this is the control device object
  814. // for a file system.
  815. //
  816. #define SR_IS_FS_CONTROL_DEVICE(_devExt) \
  817. (FlagOn((_devExt)->FsType, SrFsControlDeviceObject))
  818. //
  819. // Definitions for posting operations
  820. //
  821. typedef
  822. NTSTATUS
  823. (*PSR_SYNCOP_ROUTINE) (
  824. IN PVOID Parameter
  825. );
  826. typedef struct _SR_WORK_CONTEXT {
  827. //
  828. // Work item used to queue
  829. //
  830. WORK_QUEUE_ITEM WorkItem;
  831. //
  832. // Actual caller supplied work routine
  833. //
  834. PSR_SYNCOP_ROUTINE SyncOpRoutine;
  835. //
  836. // Parameter to the routine
  837. //
  838. PVOID Parameter;
  839. //
  840. // Return status of routine
  841. //
  842. NTSTATUS Status;
  843. //
  844. // Event to sync with main-line thread
  845. //
  846. KEVENT SyncEvent;
  847. } SR_WORK_CONTEXT, *PSR_WORK_CONTEXT;
  848. //
  849. // Op. posting routines
  850. //
  851. VOID
  852. SrSyncOpWorker(
  853. IN PSR_WORK_CONTEXT WorkContext
  854. );
  855. NTSTATUS
  856. SrPostSyncOperation(
  857. IN PSR_SYNCOP_ROUTINE SyncOpRoutine,
  858. IN PVOID Parameter
  859. );
  860. //
  861. // Other stuff
  862. //
  863. PDEVICE_OBJECT
  864. SrGetFilterDevice (
  865. PDEVICE_OBJECT pDeviceObject
  866. );
  867. NTSTATUS
  868. SrCreateAttachmentDevice (
  869. IN PDEVICE_OBJECT pRealDevice OPTIONAL,
  870. IN PDEVICE_OBJECT pDeviceObject,
  871. OUT PDEVICE_OBJECT *ppNewDeviceObject
  872. );
  873. VOID
  874. SrDeleteAttachmentDevice (
  875. IN PDEVICE_OBJECT pDeviceObject
  876. );
  877. NTSTATUS
  878. SrAttachToDevice (
  879. IN PDEVICE_OBJECT pRealDevice OPTIONAL,
  880. IN PDEVICE_OBJECT pDeviceObject,
  881. IN PDEVICE_OBJECT pNewDeviceObject OPTIONAL,
  882. OUT PSR_DEVICE_EXTENSION * ppExtension OPTIONAL
  883. );
  884. NTSTATUS
  885. SrAttachToVolumeByName (
  886. IN PUNICODE_STRING pVolumeName,
  887. OUT PSR_DEVICE_EXTENSION * ppExtension OPTIONAL
  888. );
  889. VOID
  890. SrDetachDevice(
  891. IN PDEVICE_OBJECT pDeviceObject,
  892. IN BOOLEAN RemoveFromDeviceList
  893. );
  894. #if DBG
  895. //
  896. // In DBG mode, define a SR_MUTEX as a RESOURCE so that we get the
  897. // benefit of the thread information stored in ERESOURCES for debugging
  898. // purposes.
  899. //
  900. #define SR_MUTEX ERESOURCE
  901. #define SrInitializeMutex( mutex ) \
  902. ExInitializeResourceLite( (mutex) );
  903. #define SrAcquireMutex( mutex ) \
  904. { \
  905. ASSERT( !ExIsResourceAcquiredExclusive( (mutex) ) && \
  906. !ExIsResourceAcquiredShared( (mutex) ) ); \
  907. KeEnterCriticalRegion(); \
  908. ExAcquireResourceExclusive( (mutex), TRUE ); \
  909. }
  910. #define SrReleaseMutex( mutex ) \
  911. { \
  912. ASSERT( ExIsResourceAcquiredExclusive( (mutex) ) ); \
  913. ExReleaseResourceEx( (mutex) ); \
  914. KeLeaveCriticalRegion(); \
  915. }
  916. #else
  917. //
  918. // In non-DBG mode, define a SR_MUTEX as a FAST_MUTEX so that it is more
  919. // efficient for what we use this synchronization for than ERESOURCES.
  920. //
  921. #define SR_MUTEX FAST_MUTEX
  922. #define SrInitializeMutex( mutex ) \
  923. ExInitializeFastMutex( (mutex) );
  924. #define SrAcquireMutex( mutex ) \
  925. ExAcquireFastMutex( (mutex) );
  926. #define SrReleaseMutex( mutex ) \
  927. ExReleaseFastMutex( (mutex) );
  928. #endif /* DBG */
  929. #define SR_RESOURCE ERESOURCE;
  930. #define SrAcquireResourceExclusive( resource, wait ) \
  931. { \
  932. ASSERT( ExIsResourceAcquiredExclusiveLite((resource)) || \
  933. !ExIsResourceAcquiredSharedLite((resource)) ); \
  934. KeEnterCriticalRegion(); \
  935. ExAcquireResourceExclusiveLite( (resource), (wait) ); \
  936. }
  937. #define SrAcquireResourceShared( resource, wait ) \
  938. { \
  939. KeEnterCriticalRegion(); \
  940. ExAcquireResourceSharedLite( (resource), (wait) ); \
  941. }
  942. #define SrReleaseResource( resource ) \
  943. { \
  944. ASSERT( ExIsResourceAcquiredSharedLite((resource)) || \
  945. ExIsResourceAcquiredExclusiveLite((resource)) ); \
  946. ExReleaseResourceLite( (resource) ); \
  947. KeLeaveCriticalRegion(); \
  948. }
  949. #define IS_RESOURCE_INITIALIZED( resource ) \
  950. ((resource)->SystemResourcesList.Flink != NULL)
  951. #define IS_LOOKASIDE_INITIALIZED( lookaside ) \
  952. ((lookaside)->L.ListEntry.Flink != NULL)
  953. //
  954. // macro that should probably be in ntos\inc\io.h.
  955. //
  956. #define SrUnmarkIrpPending( Irp ) ( \
  957. IoGetCurrentIrpStackLocation( (Irp) )->Control &= ~SL_PENDING_RETURNED )
  958. //
  959. // Miscellaneous validators.
  960. //
  961. #define IS_VALID_DEVICE_OBJECT( pDeviceObject ) \
  962. ( ((pDeviceObject) != NULL) && \
  963. ((pDeviceObject)->Type == IO_TYPE_DEVICE) )
  964. // ((pDeviceObject)->Size == sizeof(DEVICE_OBJECT)) )
  965. #define IS_VALID_FILE_OBJECT( pFileObject ) \
  966. ( ((pFileObject) != NULL) && \
  967. ((pFileObject)->Type == IO_TYPE_FILE) )
  968. // ((pFileObject)->Size == sizeof(FILE_OBJECT)) )
  969. #define IS_VALID_IRP( pIrp ) \
  970. ( ((pIrp) != NULL) && \
  971. ((pIrp)->Type == IO_TYPE_IRP) && \
  972. ((pIrp)->Size >= IoSizeOfIrp((pIrp)->StackCount)) )
  973. //
  974. // Calculate the dimension of an array.
  975. //
  976. #define DIMENSION(x) ( sizeof(x) / sizeof(x[0]) )
  977. //
  978. // The DIFF macro should be used around an expression involving pointer
  979. // subtraction. The expression passed to DIFF is cast to a size_t type,
  980. // allowing the result to be easily assigned to any 32-bit variable or
  981. // passed to a function expecting a 32-bit argument.
  982. //
  983. #define DIFF(x) ((size_t)(x))
  984. //
  985. // the wait is in 100 nanosecond units to 10,000,000 = 1 second
  986. //
  987. #define NANO_FULL_SECOND (10000000)
  988. //
  989. // The default buffer size we use to buffer the log entries.
  990. //
  991. #define SR_DEFAULT_LOG_BUFFER_SIZE (2 * 1024)
  992. //
  993. // The frequency with which we should fire the log flush timer, in seconds.
  994. //
  995. #define SR_DEFAULT_LOG_FLUSH_FREQUENCY 1
  996. //
  997. // By default, we will extend the log file 16K at a time.
  998. //
  999. #define SR_DEFAULT_LOG_ALLOCATION_UNIT (16 * 1024)
  1000. //
  1001. // Returns TRUE if the given device type matches one of the device types
  1002. // we support. If not, it returns FALSE.
  1003. //
  1004. #define SR_IS_SUPPORTED_DEVICE(_do) \
  1005. ((_do)->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM)
  1006. #define SR_IS_SUPPORTED_REAL_DEVICE(_rd) \
  1007. (((_rd)->Characteristics & FILE_REMOVABLE_MEDIA) == 0)
  1008. #define SR_IS_SUPPORTED_VOLUME(_vpb) \
  1009. (((_vpb)->DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM) && \
  1010. ((_vpb)->RealDevice->Characteristics & FILE_REMOVABLE_MEDIA) == 0)
  1011. #define IS_VALID_WORK_ITEM(pObject) \
  1012. (((pObject) != NULL) && ((pObject)->Signature == SR_WORK_ITEM_TAG))
  1013. typedef struct _SR_WORK_ITEM
  1014. {
  1015. //
  1016. // NonPagedPool
  1017. //
  1018. //
  1019. // = SR_WORK_ITEM_TAG
  1020. //
  1021. ULONG Signature;
  1022. WORK_QUEUE_ITEM WorkItem;
  1023. BOOLEAN FreeBuffer;
  1024. PVOID Parameter1;
  1025. //
  1026. // for synchronizing OPTIONAL
  1027. //
  1028. KEVENT Event;
  1029. //
  1030. // for return a status code
  1031. //
  1032. NTSTATUS Status;
  1033. } SR_WORK_ITEM, * PSR_WORK_ITEM;
  1034. #define SR_COPY_BUFFER_LENGTH (64 * 1024)
  1035. //
  1036. // used for file entries for ZwQueryDirectory
  1037. #define SR_FILE_ENTRY_LENGTH (1024*4)
  1038. //
  1039. // used just in case we switch to dos volume names
  1040. //
  1041. #define VOLUME_FORMAT L"%wZ"
  1042. //
  1043. // used for exception detection in finally
  1044. //
  1045. #if DBG
  1046. #define FinallyUnwind(FuncName, StatusCode) \
  1047. (AbnormalTermination()) ? \
  1048. ( SrTraceSafe( VERBOSE_ERRORS, \
  1049. ("sr!%s failed due to an unhandled exception!\n", #FuncName)),\
  1050. ( ( (global == NULL || FlagOn(global->DebugControl, SR_DEBUG_BREAK_ON_ERROR)) ? \
  1051. RtlAssert("AbnormalTermination() == FALSE", __FILE__, __LINE__, NULL) : \
  1052. 0 ), \
  1053. STATUS_UNHANDLED_EXCEPTION ) ) \
  1054. : (StatusCode)
  1055. #else
  1056. #define FinallyUnwind(FuncName, StatusCode) \
  1057. (AbnormalTermination()) ? \
  1058. STATUS_UNHANDLED_EXCEPTION \
  1059. : (StatusCode)
  1060. #endif // DBG
  1061. //
  1062. // stolen from sertlp.h
  1063. //
  1064. #define LongAlignPtr(Ptr) ((PVOID)(((ULONG_PTR)(Ptr) + 3) & -4))
  1065. #define LongAlignSize(Size) (((ULONG)(Size) + 3) & -4)
  1066. //
  1067. // the number of characters the largest ULONG takes in base 10 .
  1068. // 4294967295 = 10 chars
  1069. //
  1070. #define MAX_ULONG_CHARS (10)
  1071. #define MAX_ULONG_LENGTH (MAX_ULONG_CHARS*sizeof(WCHAR))
  1072. //
  1073. // flags to check if we are in the middle of text mode setup
  1074. //
  1075. #define UPGRADE_SETUPDD_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Setupdd"
  1076. #define UPGRADE_SETUPDD_VALUE_NAME L"Start"
  1077. //
  1078. // flags to check if we are in the middle of gui mode setup
  1079. //
  1080. #define UPGRADE_CHECK_SETUP_KEY_NAME L"\\Registry\\Machine\\System\\Setup"
  1081. #define UPGRADE_CHECK_SETUP_VALUE_NAME L"SystemSetupInProgress"
  1082. //
  1083. // this is a filter as to what sort of errors cause volume error's to be
  1084. // triggered. If we get the error STATUS_VOLUME_DISMOUNTED, we have already
  1085. // shutdown everything correctly and we don't want to treat this as an error.
  1086. // Also, if we get STATUS_FILE_CORRUPT_ERROR, the user's operation is also
  1087. // going to fail, so don't treat this as a volume error.
  1088. //
  1089. #define CHECK_FOR_VOLUME_ERROR(Status) \
  1090. ((STATUS_VOLUME_DISMOUNTED != Status) && \
  1091. (STATUS_FILE_CORRUPT_ERROR != Status) && \
  1092. (SR_STATUS_VOLUME_DISABLED != Status) && \
  1093. (SR_STATUS_CONTEXT_NOT_SUPPORTED != Status) && \
  1094. (SR_STATUS_IGNORE_FILE != Status) && \
  1095. !NT_SUCCESS((Status)))
  1096. //
  1097. // Macro that defines what a "volume name" mount point is. This macro can
  1098. // be used to scan the result from QUERY_POINTS to discover which mount points
  1099. // are "volume name" mount points.
  1100. //
  1101. // stolen + modified from mountmgr.h
  1102. //
  1103. #define MOUNTMGR_VOLUME_NAME_PREFIX_COUNT (49)
  1104. #define MOUNTMGR_VOLUME_NAME_PREFIX_LENGTH (49*sizeof(WCHAR))
  1105. #define MOUNTMGR_IS_VOLUME_NAME_PREFIX(s) ( \
  1106. (s)->Length >= MOUNTMGR_VOLUME_NAME_PREFIX_LENGTH && \
  1107. (s)->Buffer[0] == '\\' && \
  1108. (s)->Buffer[1] == '?' && \
  1109. (s)->Buffer[2] == '?' && \
  1110. (s)->Buffer[3] == '\\' && \
  1111. (s)->Buffer[4] == 'V' && \
  1112. (s)->Buffer[5] == 'o' && \
  1113. (s)->Buffer[6] == 'l' && \
  1114. (s)->Buffer[7] == 'u' && \
  1115. (s)->Buffer[8] == 'm' && \
  1116. (s)->Buffer[9] == 'e' && \
  1117. (s)->Buffer[10] == '{' && \
  1118. (s)->Buffer[19] == '-' && \
  1119. (s)->Buffer[24] == '-' && \
  1120. (s)->Buffer[29] == '-' && \
  1121. (s)->Buffer[34] == '-' && \
  1122. (s)->Buffer[47] == '}' && \
  1123. (s)->Buffer[48] == '\\' )
  1124. #if DBG
  1125. #define SrAcquireActivityLockShared(pExtension) \
  1126. { \
  1127. if (ExIsResourceAcquiredShared(&(pExtension)->ActivityLock) == FALSE) \
  1128. { \
  1129. /* no other locks better be held. the activity lock is the */ \
  1130. /* outermost lock */ \
  1131. ASSERT(!ExIsResourceAcquiredShared(&global->GlobalLock)); \
  1132. ASSERT(!ExIsResourceAcquiredExclusive( &global->GlobalLock)); \
  1133. ASSERT(!ExIsResourceAcquiredShared(&global->BlobLock)); \
  1134. ASSERT(!ExIsResourceAcquiredExclusive( &global->BlobLock)); \
  1135. ASSERT(!ExIsResourceAcquiredShared(&(pExtension)->LogLock)); \
  1136. ASSERT(!ExIsResourceAcquiredExclusive( &(pExtension)->LogLock)); \
  1137. } \
  1138. KeEnterCriticalRegion(); \
  1139. ExAcquireSharedStarveExclusive(&(pExtension)->ActivityLock, TRUE); \
  1140. }
  1141. #define SrAcquireActivityLockExclusive(pExtension) \
  1142. { \
  1143. if (!ExIsResourceAcquiredExclusive(&(pExtension)->ActivityLock)) \
  1144. { \
  1145. /* no other locks better be held. the activity lock is the */ \
  1146. /* outermost lock */ \
  1147. ASSERT(!ExIsResourceAcquiredShared(&global->GlobalLock)); \
  1148. ASSERT(!ExIsResourceAcquiredExclusive( &global->GlobalLock)); \
  1149. ASSERT(!ExIsResourceAcquiredShared(&global->BlobLock)); \
  1150. ASSERT(!ExIsResourceAcquiredExclusive( &global->BlobLock)); \
  1151. ASSERT(!ExIsResourceAcquiredShared(&(pExtension)->LogLock)); \
  1152. ASSERT(!ExIsResourceAcquiredExclusive( &(pExtension)->LogLock)); \
  1153. } \
  1154. SrAcquireResourceExclusive(&(pExtension)->ActivityLock, TRUE); \
  1155. }
  1156. #define SrAcquireLogLockShared(pExtension) \
  1157. { \
  1158. ASSERT(ExIsResourceAcquiredShared(&(pExtension)->ActivityLock) || \
  1159. ExIsResourceAcquiredExclusive( &(pExtension)->ActivityLock )); \
  1160. SrAcquireResourceShared(&(pExtension)->LogLock, TRUE); \
  1161. }
  1162. #define SrAcquireLogLockExclusive(pExtension) \
  1163. { \
  1164. ASSERT(ExIsResourceAcquiredShared(&(pExtension)->ActivityLock) || \
  1165. ExIsResourceAcquiredExclusive( &(pExtension)->ActivityLock )); \
  1166. SrAcquireResourceExclusive(&(pExtension)->LogLock, TRUE); \
  1167. }
  1168. #else
  1169. #define SrAcquireActivityLockShared(pExtension) \
  1170. { \
  1171. KeEnterCriticalRegion(); \
  1172. ExAcquireSharedStarveExclusive(&(pExtension)->ActivityLock, TRUE); \
  1173. }
  1174. #define SrAcquireActivityLockExclusive(pExtension) \
  1175. SrAcquireResourceExclusive(&(pExtension)->ActivityLock, TRUE)
  1176. #define SrAcquireLogLockShared(pExtension) \
  1177. SrAcquireResourceShared(&((pExtension)->LogLock), TRUE)
  1178. #define SrAcquireLogLockExclusive(pExtension) \
  1179. SrAcquireResourceExclusive(&((pExtension)->LogLock), TRUE)
  1180. #endif // DBG
  1181. #define IS_ACTIVITY_LOCK_ACQUIRED_EXCLUSIVE( pExtension ) \
  1182. ExIsResourceAcquiredExclusiveLite( &(pExtension)->ActivityLock )
  1183. #define IS_ACTIVITY_LOCK_ACQUIRED_SHARED( pExtension ) \
  1184. ExIsResourceAcquiredSharedLite( &(pExtension)->ActivityLock )
  1185. #define IS_LOG_LOCK_ACQUIRED_EXCLUSIVE( pExtension ) \
  1186. ExIsResourceAcquiredExclusiveLite( &(pExtension)->LogLock )
  1187. #define IS_LOG_LOCK_ACQUIRED_SHARED( pExtension ) \
  1188. ExIsResourceAcquiredSharedLite( &(pExtension)->LogLock )
  1189. #define SrReleaseActivityLock(pExtension) \
  1190. SrReleaseResource(&(pExtension)->ActivityLock)
  1191. #define SrReleaseLogLock(pExtension) \
  1192. SrReleaseResource(&(pExtension)->LogLock)
  1193. #define IS_GLOBAL_LOCK_ACQUIRED() \
  1194. (ExIsResourceAcquiredExclusiveLite(&(global->GlobalLock)) || \
  1195. ExIsResourceAcquiredSharedLite( &(global->GlobalLock) ))
  1196. #define SrAcquireGlobalLockExclusive() \
  1197. SrAcquireResourceExclusive( &(global->GlobalLock), TRUE )
  1198. #define SrReleaseGlobalLock() \
  1199. SrReleaseResource( &(global->GlobalLock) )
  1200. #define IS_BLOB_LOCK_ACQUIRED_EXCLUSIVE() \
  1201. (ExIsResourceAcquiredExclusiveLite(&(global->BlobLock)))
  1202. #define IS_BLOB_LOCK_ACQUIRED() \
  1203. (ExIsResourceAcquiredExclusiveLite(&(global->BlobLock)) || \
  1204. ExIsResourceAcquiredSharedLite( &(global->BlobLock) ))
  1205. #define SrAcquireBlobLockExclusive() \
  1206. SrAcquireResourceExclusive( &(global->BlobLock), TRUE )
  1207. #define SrAcquireBlobLockShared() \
  1208. SrAcquireResourceShared( &(global->BlobLock), TRUE )
  1209. #define SrReleaseBlobLock() \
  1210. SrReleaseResource( &(global->BlobLock) )
  1211. #define IS_DEVICE_EXTENSION_LIST_LOCK_ACQUIRED() \
  1212. (ExIsResourceAcquiredExclusiveLite(&(global->DeviceExtensionListLock)) || \
  1213. ExIsResourceAcquiredSharedLite( &(global->DeviceExtensionListLock) ))
  1214. #define SrAcquireDeviceExtensionListLockExclusive() \
  1215. SrAcquireResourceExclusive( &(global->DeviceExtensionListLock), TRUE )
  1216. #define SrAcquireDeviceExtensionListLockShared() \
  1217. SrAcquireResourceShared( &(global->DeviceExtensionListLock), TRUE )
  1218. #define SrReleaseDeviceExtensionListLock() \
  1219. SrReleaseResource( &(global->DeviceExtensionListLock) )
  1220. #define SrAcquireBackupHistoryLockShared( pExtension ) \
  1221. SrAcquireResourceShared( &((pExtension)->pBackupHistory->Lock), TRUE )
  1222. #define SrAcquireBackupHistoryLockExclusive( pExtension ) \
  1223. SrAcquireResourceExclusive( &((pExtension)->pBackupHistory->Lock), TRUE )
  1224. #define SrReleaseBackupHistoryLock( pExtension ) \
  1225. SrReleaseResource( &((pExtension)->pBackupHistory->Lock) )
  1226. #define SrAcquireAttachToVolumeLock() \
  1227. ExAcquireFastMutex( &_globals.AttachToVolumeLock )
  1228. #define SrReleaseAttachToVolumeLock() \
  1229. ExReleaseFastMutex( &_globals.AttachToVolumeLock )
  1230. //
  1231. // we require 50mb free to function
  1232. //
  1233. #define SR_MIN_DISK_FREE_SPACE (50 * 1024 * 1024)
  1234. //
  1235. // the temp unique filename used in SrHandleFileOverwrite
  1236. //
  1237. #define SR_UNIQUE_TEMP_FILE L"\\4bf03598-d7dd-4fbe-98b3-9b70a23ee8d4"
  1238. #define SR_UNIQUE_TEMP_FILE_LENGTH (37 * sizeof(WCHAR))
  1239. #define VALID_FAST_IO_DISPATCH_HANDLER(FastIoDispatchPtr, FieldName) \
  1240. (((FastIoDispatchPtr) != NULL) && \
  1241. (((FastIoDispatchPtr)->SizeOfFastIoDispatch) >= \
  1242. (FIELD_OFFSET(FAST_IO_DISPATCH, FieldName) + sizeof(VOID *))) && \
  1243. ((FastIoDispatchPtr)->FieldName != NULL))
  1244. #define FILE_OBJECT_IS_NOT_POTENTIALLY_INTERESTING(FileObject) \
  1245. ((FileObject) == NULL || \
  1246. FlagOn((FileObject)->Flags, FO_STREAM_FILE))
  1247. #define FILE_OBJECT_DOES_NOT_HAVE_VPB(FileObject) \
  1248. (FileObject)->Vpb == NULL
  1249. #define USE_DO_HINT
  1250. #ifdef USE_DO_HINT
  1251. #define SrIoCreateFile( F, D, O, I, A, FA, SA, CD, CO, EB, EL, FL, DO ) \
  1252. IoCreateFileSpecifyDeviceObjectHint((F), \
  1253. (D), \
  1254. (O), \
  1255. (I), \
  1256. (A), \
  1257. (FA), \
  1258. (SA), \
  1259. (CD), \
  1260. (CO), \
  1261. (EB), \
  1262. (EL), \
  1263. CreateFileTypeNone, \
  1264. NULL, \
  1265. (FL), \
  1266. (DO) );
  1267. #else
  1268. #define SrIoCreateFile( F, D, O, I, A, FA, SA, CD, CO, EB, EL, FL, DO ) \
  1269. ZwCreateFile((F), \
  1270. (D), \
  1271. (O), \
  1272. (I), \
  1273. (A), \
  1274. (FA), \
  1275. (SA), \
  1276. (CD), \
  1277. (CO), \
  1278. (EB), \
  1279. (EL) );
  1280. #endif /* USE_DO_HINT */
  1281. //
  1282. // Macros so that we can check for expected errors in debug code.
  1283. //
  1284. #if DBG
  1285. #define DECLARE_EXPECT_ERROR_FLAG( _ErrorFlag ) \
  1286. BOOLEAN _ErrorFlag = FALSE
  1287. #define SET_EXPECT_ERROR_FLAG( _ErrorFlag ) \
  1288. ((_ErrorFlag) = TRUE)
  1289. #define CLEAR_EXPECT_ERROR_FLAG( _ErrorFlag ) \
  1290. ((_ErrorFlag) = FALSE)
  1291. #define CHECK_FOR_EXPECTED_ERROR( _ErrorFlag, _Status ) \
  1292. { \
  1293. if ((_ErrorFlag)) \
  1294. { \
  1295. ASSERT( !NT_SUCCESS_NO_DBGBREAK( (_Status) ) );\
  1296. } \
  1297. }
  1298. #else
  1299. #define DECLARE_EXPECT_ERROR_FLAG( _ErrorFlag )
  1300. #define SET_EXPECT_ERROR_FLAG( _ErrorFlag )
  1301. #define CLEAR_EXPECT_ERROR_FLAG( _ErrorFlag )
  1302. #define CHECK_FOR_EXPECTED_ERROR( _ErrorFlag, _Status )
  1303. #endif
  1304. #endif // _SRPRIV_H_