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.

1479 lines
35 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 2001
  3. (c) 1998 Seagate Software, Inc. All rights reserved.
  4. Module Name:
  5. RpFsa.h
  6. Abstract:
  7. Contains function declarations and structures for the File System Filter for Remote Storage
  8. Author:
  9. Rick Winter
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. X-13 108353 Michael C. Johnson 3-May-2001
  14. When checking a file to determine the type of recall also
  15. check a the potential target disk to see whether or not
  16. it is writable. This is necessary now that we have read-only
  17. NTFS volumes.
  18. X-12 365077 Michael C. Johnson 1-May-2001
  19. Revert to previous form of RsOpenTarget() with extra access
  20. parameter to allow us to apply the desired access bypassing
  21. the access check.
  22. X-11 194325 Michael C. Johnson 1-Mar-2001
  23. Clean up RsMountCompletion() and RsLoadFsCompletion() to
  24. ensure they don't call routines such as IoDeleteDevice()
  25. if not running at PASSIVE_LEVEL.
  26. Add in memory trace mechanism in preparation for attempts
  27. to flush out lingering reparse point deletion troubles.
  28. X-10 326345 Michael C. Johnson 26-Feb-2001
  29. Only send a single RP_RECALL_WAITING to the fsa on any one
  30. file object. Use the new flag RP_NOTIFICATION_SENT to record
  31. when notification has been done.
  32. --*/
  33. /* Defines */
  34. // memory allocation Tags for debug usage
  35. #define RP_RQ_TAG 'SFSR' // Recall queue
  36. #define RP_FN_TAG 'NFSR' // File name cache
  37. #define RP_SE_TAG 'ESSR' // Security info
  38. #define RP_WQ_TAG 'QWSR' // Work queue
  39. #define RP_QI_TAG 'IQSR' // Work Q info
  40. #define RP_LT_TAG 'TLSR' // Long term memory
  41. #define RP_IO_TAG 'OISR' // IOCTL queue
  42. #define RP_FO_TAG 'OFSR' // File Object Queue
  43. #define RP_VO_TAG 'OVSR' // Validate Queue
  44. #define RP_ER_TAG 'RESR' // Error log data
  45. #define RP_CC_TAG 'CCSR' // Cache buffers
  46. #define RP_US_TAG 'SUSR' // Usn record
  47. #define RP_CX_TAG 'CCSR' // Completion context
  48. #define RP_TC_TAG 'CTSR' // Trace control block
  49. #define RP_TE_TAG 'ETSR' // Trace entry buffer
  50. #define RP_RD_TAG 'DRSR' // Root directory path
  51. //
  52. // Device extension for the RsFilter device object
  53. //
  54. typedef enum _RP_VOLUME_WRITE_STATUS {
  55. RsVolumeStatusUnknown = 0, // No attempt has been made to determine volume writeability
  56. // or attempt to determine volume writeability failed
  57. RsVolumeStatusReadOnly, // volume is readonly
  58. RsVolumeStatusReadWrite // Volume is writeable
  59. } RP_VOLUME_WRITE_STATUS;
  60. typedef struct _DEVICE_EXTENSION {
  61. CSHORT Type;
  62. CSHORT Size;
  63. PDEVICE_OBJECT FileSystemDeviceObject;
  64. PDEVICE_OBJECT RealDeviceObject;
  65. BOOLEAN Attached;
  66. BOOLEAN AttachedToNtfsControlDevice;
  67. volatile RP_VOLUME_WRITE_STATUS WriteStatus;
  68. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  69. #define RSFILTER_PARAMS_KEY L"RsFilter\\Parameters"
  70. #define RS_TRACE_LEVEL_VALUE_NAME L"TraceLevel"
  71. #define RS_TRACE_LEVEL_DEFAULT 0
  72. extern PDEVICE_OBJECT FsDeviceObject;
  73. // Fsa validate job registry entry location
  74. #define FSA_VALIDATE_LOG_KEY_NAME L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\Remote_Storage_File_System_Agent\\Validate"
  75. #define FT_VOL_LEN 32
  76. /* First guess at device name length */
  77. #define AV_DEV_OBJ_NAME_SIZE (40 * sizeof(wchar_t))
  78. /* Space for a NULL and a delimiter */
  79. #define AV_NAME_OVERHEAD (2 * sizeof(wchar_t))
  80. #define RP_NTFS_NAME L"\\FileSystem\\NTFS"
  81. // FILE_HSM_ACTION_ACCESS is any access that requires HSM action (delete or recall or both)
  82. #ifdef WHEN_WE_HANDLE_DELETE
  83. #define FILE_HSM_ACTION_ACCESS (FILE_READ_DATA | FILE_WRITE_DATA | FILE_EXECUTE | DELETE)
  84. #else
  85. #define FILE_HSM_ACTION_ACCESS (FILE_READ_DATA | FILE_WRITE_DATA | FILE_EXECUTE)
  86. #endif
  87. /* FILE_HSM_RECALL_ACCESS is any access that allows the data to be read. */
  88. #define FILE_HSM_RECALL_ACCESS (FILE_READ_DATA | FILE_WRITE_DATA | FILE_EXECUTE)
  89. //
  90. // Timeout and retry values when waiting for the FSA to issue an IOCTL
  91. // Represents the amount of time - under multiple concurrent recall situations -
  92. // that an app will have to wait before the i/o it issued completes with
  93. // STATUS_FILE_IS_OFFLINE because RsFilter couldn't get any IOCTLs to
  94. // communicate with the FSA
  95. //
  96. #define RP_WAIT_FOR_FSA_IO_TIMEOUT -((LONGLONG) 4800000000) // 8 minutes
  97. /* Module ID defines for error/event logging */
  98. #define AV_MODULE_RPFILTER 1
  99. #define AV_MODULE_RPFILFUN 2
  100. #define AV_MODULE_RPSEC 3
  101. #define AV_MODULE_RPZW 4
  102. #define AV_MODULE_RPCACHE 5
  103. #define AV_BUFFER_SIZE 1024
  104. #ifndef BooleanFlagOn
  105. #define BooleanFlagOn(F,SF) ( (BOOLEAN)(((F) & (SF)) != 0) )
  106. #endif
  107. #define AV_FT_TICKS_PER_SECOND ((LONGLONG) 10000000)
  108. #define AV_FT_TICKS_PER_MINUTE ((LONGLONG) ((LONGLONG) 60 * AV_FT_TICKS_PER_SECOND))
  109. #define AV_FT_TICKS_PER_HOUR ((LONGLONG) ((LONGLONG) 60 * AV_FT_TICKS_PER_MINUTE))
  110. //
  111. // The filter ID tracks recalls and no-recalls as follows:
  112. // The id is a longlong where the highest order bit identifies the type of recall
  113. // (no-recall or recall). The remaining part of the high order long identifies the
  114. // read RP_IRP_QUEUE entry (for no-recall) or the file object entry (for recall).
  115. // The lower long identifies the file context entry.
  116. //
  117. #define RP_TYPE_RECALL (ULONGLONG) 0x8000000000000000
  118. #define RP_CONTEXT_MASK (ULONGLONG) 0x00000000ffffffff
  119. #define RP_READ_MASK 0x7fffffff
  120. #define RP_FILE_MASK (ULONGLONG) 0xffffffff00000000
  121. typedef struct _RP_CREATE_INFO {
  122. PIRP irp;
  123. PIO_STACK_LOCATION irpSp;
  124. POBJECT_NAME_INFORMATION str;
  125. ULONG options;
  126. //
  127. // Reparse point data
  128. //
  129. RP_DATA rpData;
  130. LONGLONG fileId;
  131. LONGLONG objIdHi;
  132. LONGLONG objIdLo;
  133. ULONG serial;
  134. ULONG action;
  135. ULONG desiredAccess;
  136. } RP_CREATE_INFO, *PRP_CREATE_INFO;
  137. typedef struct _RP_PENDING_CREATE {
  138. //
  139. // Filter id
  140. //
  141. ULONGLONG filterId;
  142. //
  143. //
  144. //
  145. PRP_CREATE_INFO qInfo;
  146. //
  147. // Event used to signal irp completion
  148. //
  149. KEVENT irpCompleteEvent;
  150. //
  151. // File object for irp
  152. //
  153. PFILE_OBJECT fileObject;
  154. //
  155. // Device object for irp
  156. //
  157. PDEVICE_OBJECT deviceObject;
  158. //
  159. // Open options
  160. //
  161. ULONG options;
  162. //
  163. // Indicates if oplocks should not be granted (to CI for instance..)
  164. //
  165. #define RP_PENDING_NO_OPLOCK 0x1
  166. //
  167. // Indicates if IRP should be sent down again
  168. //
  169. #define RP_PENDING_RESEND_IRP 0x2
  170. //
  171. // Indicates if we should wait for irp to complete
  172. //
  173. #define RP_PENDING_WAIT_FOR_EVENT 0x4
  174. //
  175. // Indicates if this is a recall
  176. //
  177. #define RP_PENDING_IS_RECALL 0x8
  178. //
  179. // Indicates if we should reset the offline attribute of the file
  180. //
  181. #define RP_PENDING_RESET_OFFLINE 0x10
  182. ULONG flags;
  183. } RP_PENDING_CREATE, *PRP_PENDING_CREATE;
  184. #define RP_IRP_NO_RECALL 1
  185. typedef struct _RP_IRP_QUEUE {
  186. LIST_ENTRY list;
  187. PIRP irp;
  188. PDEVICE_EXTENSION deviceExtension;
  189. ULONG flags;
  190. //
  191. // For regular read and write, offset and length
  192. // denote the offset and length within the file
  193. // For no-recall reads, offset and length would
  194. // denote the offset/length within the cacheBuffer
  195. //
  196. ULONGLONG offset;
  197. ULONGLONG length;
  198. //
  199. // These fields are used only for no-recall reads
  200. // filterId for no-recall (see filterid description)
  201. ULONGLONG readId;
  202. ULONGLONG recallOffset;
  203. ULONGLONG recallLength;
  204. //
  205. // User buffer for data from read-no-recall
  206. //
  207. PVOID userBuffer;
  208. //
  209. // Cache block buffer for no recall data
  210. //
  211. PVOID cacheBuffer;
  212. } RP_IRP_QUEUE, *PRP_IRP_QUEUE;
  213. //
  214. // Structure tracking the no-recall master IRP and associated irps
  215. //
  216. typedef struct _RP_NO_RECALL_MASTER_IRP {
  217. LIST_ENTRY AssocIrps;
  218. PIRP MasterIrp;
  219. } RP_NO_RECALL_MASTER_IRP, *PRP_NO_RECALL_MASTER_IRP;
  220. //
  221. // User security info structure: this is required for HSM
  222. // to do the pop-up for clients indicating the file is being recalled
  223. //
  224. typedef struct _RP_USER_SECURITY_INFO {
  225. //
  226. // Sid info
  227. //
  228. PCHAR userInfo;
  229. ULONG userInfoLen;
  230. LUID userAuthentication;
  231. LUID userInstance;
  232. LUID tokenSourceId;
  233. //
  234. // Token source info for user
  235. //
  236. CHAR tokenSource[TOKEN_SOURCE_LENGTH];
  237. //
  238. // Indicates if this was opened by user with admin privileges
  239. //
  240. BOOLEAN isAdmin;
  241. //
  242. // Indicates if this is a local proc
  243. //
  244. BOOLEAN localProc;
  245. } RP_USER_SECURITY_INFO, *PRP_USER_SECURITY_INFO;
  246. //
  247. // Associated macro for above
  248. //
  249. #define RsFreeUserSecurityInfo(UserSecurityInfo) { \
  250. if (UserSecurityInfo) { \
  251. if (UserSecurityInfo->userInfo) { \
  252. ExFreePool(UserSecurityInfo->userInfo); \
  253. } \
  254. ExFreePool(UserSecurityInfo); \
  255. } \
  256. }
  257. //
  258. // The file object entry keeps track of an open instance of a file.
  259. // For each NTFS file object there is one of these (if the file has an HSM tag)
  260. // This structure points to a FS_CONTEXT entry for which there is one for each file.
  261. // For instance if 3 clients open \\server\share\foo there will be 3 file object
  262. // structures and they will all point to the same FS_CONTEXT structure.
  263. //
  264. // The file objects we are tracking will have a pointer to one of there structures attached via
  265. // FsRtlInsertFilterContext. From there one can find the file context entry via the pointer to it.
  266. //
  267. typedef struct _RP_FILE_OBJ {
  268. //
  269. // Link to next file object
  270. //
  271. LIST_ENTRY list;
  272. //
  273. // File object itself
  274. //
  275. PFILE_OBJECT fileObj;
  276. //
  277. // Device object
  278. //
  279. PDEVICE_OBJECT devObj;
  280. //
  281. // Pointer to the RP_FILE_CONTEXT entry - there's one such entry for every *file*
  282. //
  283. PVOID fsContext;
  284. //
  285. // Resource protecting this entry
  286. //
  287. ERESOURCE resource;
  288. //
  289. // Spin lock protecting read/write IRP queues
  290. //
  291. KSPIN_LOCK qLock;
  292. //
  293. // Pending read IRP queue
  294. //
  295. LIST_ENTRY readQueue;
  296. //
  297. // Pending write IRP queue
  298. //
  299. LIST_ENTRY writeQueue;
  300. //
  301. // File create options specified when opening it
  302. //
  303. ULONG openOptions;
  304. //
  305. // File desired access spcecified when opening it
  306. //
  307. ULONG desiredAccess;
  308. //
  309. // Flags (descriptions below)
  310. //
  311. ULONG flags;
  312. //
  313. // Object id
  314. //
  315. LONGLONG objIdHi;
  316. LONGLONG objIdLo;
  317. //
  318. // File Id if available
  319. //
  320. LONGLONG fileId;
  321. //
  322. // Unique ID we generate for the file object
  323. //
  324. ULONGLONG filterId;
  325. //
  326. // Recall action flags (see rpio.h - RP_RECALL_ACTION..)
  327. //
  328. ULONG recallAction;
  329. PRP_USER_SECURITY_INFO userSecurityInfo;
  330. } RP_FILE_OBJ, *PRP_FILE_OBJ;
  331. //
  332. // RP_FILE_OBJ Flags
  333. //
  334. //
  335. // File was not opened for read or write access
  336. //
  337. #define RP_NO_DATA_ACCESS 1
  338. //
  339. // Opener is admin equivalent
  340. //
  341. #define RP_OPEN_BY_ADMIN 2
  342. //
  343. // Opened by local process
  344. //
  345. #define RP_OPEN_LOCAL 4
  346. //
  347. // Recall waiting notification already sent
  348. //
  349. #define RP_NOTIFICATION_SENT 8
  350. //
  351. // Recall state
  352. //
  353. typedef enum _RP_RECALL_STATE {
  354. RP_RECALL_INVALID = -1,
  355. RP_RECALL_NOT_RECALLED,
  356. RP_RECALL_STARTED,
  357. RP_RECALL_COMPLETED
  358. } RP_RECALL_STATE, *PRP_RECALL_STATE;
  359. //
  360. // Filter context for RsFilter:
  361. // Since filter contexts are attached to the SCB (stream control block) we need to use
  362. // the instance ID to indicate which file object we are interested in. We attach this
  363. // structure to and use myFileObjEntry to point to the RP_FILE_OBJ struct that
  364. // represents this file object.
  365. //
  366. typedef struct _RP_FILTER_CONTEXT {
  367. FSRTL_PER_STREAM_CONTEXT context;
  368. PVOID myFileObjEntry;
  369. } RP_FILTER_CONTEXT, *PRP_FILTER_CONTEXT;
  370. //
  371. // File context: one per *file*
  372. //
  373. typedef struct _RP_FILE_CONTEXT {
  374. //
  375. // Links to next/prev file (hanging off RsFileObjQHead)
  376. //
  377. LIST_ENTRY list;
  378. //
  379. // Lock protecting file object queue
  380. //
  381. KSPIN_LOCK qLock;
  382. //
  383. // Queue of all related file object entries
  384. //
  385. LIST_ENTRY fileObjects;
  386. //
  387. // Recalled data is written using this file object
  388. //
  389. PFILE_OBJECT fileObjectToWrite;
  390. //
  391. // Handle for the file object we use to write to
  392. //
  393. HANDLE handle;
  394. PDEVICE_OBJECT devObj;
  395. PDEVICE_OBJECT FilterDeviceObject;
  396. //
  397. // Unicode name of file
  398. //
  399. POBJECT_NAME_INFORMATION uniName;
  400. //
  401. // From the file object - unique file identifier
  402. //
  403. PVOID fsContext;
  404. //
  405. // Buffer to write out to file
  406. //
  407. PVOID nextWriteBuffer;
  408. //
  409. // Size of next write to the file (of recall data)
  410. //
  411. ULONG nextWriteSize;
  412. //
  413. // Lock protecting this entry
  414. //
  415. ERESOURCE resource;
  416. //
  417. // This notification event is signalled when recall completes for this file
  418. //
  419. KEVENT recallCompletedEvent;
  420. //
  421. // File id if available
  422. //
  423. LONGLONG fileId;
  424. //
  425. // Size in bytes of recall needed
  426. //
  427. LARGE_INTEGER recallSize;
  428. //
  429. // All bytes up to this offset have been recalled
  430. //
  431. LARGE_INTEGER currentOffset;
  432. //
  433. // Lower half of filter id (unique per file)
  434. //
  435. ULONGLONG filterId;
  436. //
  437. // Volume serial number
  438. //
  439. ULONG serial;
  440. //
  441. // If the recall is complete this is the status
  442. //
  443. NTSTATUS recallStatus;
  444. //
  445. // Recall state
  446. //
  447. RP_RECALL_STATE state;
  448. //
  449. // Flags (see below for description)
  450. //
  451. ULONG flags;
  452. //
  453. // Reference count for the file context
  454. //
  455. ULONG refCount;
  456. //
  457. // Usn of the file
  458. //
  459. USN usn;
  460. //
  461. // Tracks create section lock
  462. //
  463. LONG createSectionLock;
  464. //
  465. // Reparse point data
  466. //
  467. RP_DATA rpData;
  468. } RP_FILE_CONTEXT, *PRP_FILE_CONTEXT;
  469. //
  470. // RP_FILE_CONTEXT Flags
  471. //
  472. // We have seen a write to this file
  473. #define RP_FILE_WAS_WRITTEN 1
  474. #define RP_FILE_INITIALIZED 2
  475. #define RP_FILE_REPARSE_POINT_DELETED 4
  476. /*++
  477. VOID
  478. RsInitializeFileContextQueueLock()
  479. Routine Description
  480. Initializes lock guarding the file context queue
  481. Arguments
  482. none
  483. Return Value
  484. none
  485. --*/
  486. #define RsInitializeFileContextQueueLock() { \
  487. DebugTrace((DPFLTR_RSFILTER_ID, DBG_LOCK,"RsFilter: RsInitializeFileContextQueueLock.\n"));\
  488. ExInitializeFastMutex(&RsFileContextQueueLock); \
  489. }
  490. /*++
  491. VOID
  492. RsAcquireFileContextQueueLock()
  493. Routine Description
  494. Acquire lock guarding the file context queue
  495. Arguments
  496. none
  497. Return Value
  498. none
  499. --*/
  500. #define RsAcquireFileContextQueueLock() { \
  501. ExAcquireFastMutex(&RsFileContextQueueLock); \
  502. DebugTrace((DPFLTR_RSFILTER_ID, DBG_LOCK, "RsFilter: RsAcquireFileContextQueueLock.\n"));\
  503. }
  504. /*++
  505. VOID
  506. RsReleaseFileContextQueueLock()
  507. Routine Description
  508. Release lock guarding the file context queue
  509. Arguments
  510. none
  511. Return Value
  512. none
  513. --*/
  514. #define RsReleaseFileContextQueueLock() { \
  515. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsReleaseFileContextQueueLock.\n"));\
  516. ExReleaseFastMutex(&RsFileContextQueueLock); \
  517. }
  518. /*++
  519. VOID
  520. RsAcquireFileObjectLockExclusive()
  521. Routine Description
  522. Acquire lock guarding a file object entry
  523. Arguments
  524. none
  525. Return Value
  526. none
  527. --*/
  528. #define RsAcquireFileObjectEntryLockExclusive(entry) { \
  529. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileObjectEntryLockExclusive Waiting (%x).\n", entry));\
  530. FsRtlEnterFileSystem(); \
  531. ExAcquireResourceExclusiveLite(&(entry)->resource, TRUE); \
  532. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileObjectEntryLockExclusive Owned (%x).\n", entry));\
  533. }
  534. /*++
  535. VOID
  536. RsAcquireFileObjectEntryLockShared()
  537. Routine Description
  538. Acquire lock guarding a file object entry
  539. Arguments
  540. none
  541. Return Value
  542. none
  543. --*/
  544. #define RsAcquireFileObjectEntryLockShared(entry) { \
  545. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileObjectEntryLockShared Waiting (%x).\n", entry));\
  546. FsRtlEnterFileSystem(); \
  547. ExAcquireResourceSharedLite(&(entry)->resource, TRUE); \
  548. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileObjectEntryLockShared Owned (%x).\n", entry));\
  549. }
  550. /*++
  551. VOID
  552. RsReleaseFileObjectEntryLock()
  553. Routine Description
  554. Release lock guarding a file object entry
  555. Arguments
  556. none
  557. Return Value
  558. none
  559. --*/
  560. #define RsReleaseFileObjectEntryLock(entry) { \
  561. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsReleaseFileObjectEntryLock (%x).\n", entry));\
  562. ExReleaseResourceLite(&(entry)->resource); \
  563. FsRtlExitFileSystem(); \
  564. }
  565. /*++
  566. VOID
  567. RsAcquireFileContextEntryLockExclusive()
  568. Routine Description
  569. Acquire lock guarding a file context entry
  570. Arguments
  571. none
  572. Return Value
  573. none
  574. --*/
  575. #define RsAcquireFileContextEntryLockExclusive(entry) { \
  576. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileContextEntryLockExclusive Waiting (%x).\n", entry));\
  577. FsRtlEnterFileSystem(); \
  578. ExAcquireResourceExclusiveLite(&(entry)->resource, TRUE); \
  579. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileContextEntryLockExclusive Owned (%x).\n", entry));\
  580. }
  581. /*++
  582. VOID
  583. RsAcquireFileContextEntryLockShared()
  584. Routine Description
  585. Acquire lock guarding a file context entry
  586. Arguments
  587. none
  588. Return Value
  589. none
  590. --*/
  591. #define RsAcquireFileContextEntryLockShared(entry) { \
  592. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileContextEntryLockShared Waiting (%x).\n", entry));\
  593. FsRtlEnterFileSystem(); \
  594. ExAcquireResourceSharedLite(&(entry)->resource, TRUE); \
  595. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileContextEntryLockShared Owned (%x).\n", entry));\
  596. }
  597. /*++
  598. VOID
  599. RsReleaseFileContextEntryLock()
  600. Routine Description
  601. Release lock guarding a file context entry
  602. Arguments
  603. none
  604. Return Value
  605. none
  606. --*/
  607. #define RsReleaseFileContextEntryLock(entry) { \
  608. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsReleaseFileContextEntryLock. (%x)\n", entry));\
  609. ExReleaseResourceLite(&(entry)->resource); \
  610. FsRtlExitFileSystem(); \
  611. }
  612. /*++
  613. VOID
  614. RsGetValidateLock(PKIRQL irql)
  615. Routine Description:
  616. Get a lock on the validate queue
  617. Arguments:
  618. Place to save irql
  619. Return Value:
  620. None
  621. --*/
  622. #define RsGetValidateLock(irql) ExAcquireSpinLock(&RsValidateQueueLock, irql)
  623. /*++
  624. VOID
  625. RsPutValidateLock(KIRQL oldIrql)
  626. Routine Description:
  627. Free a lock on the validate queue
  628. Arguments:
  629. Saved irql
  630. Return Value:
  631. None
  632. --*/
  633. #define RsPutValidateLock(oldIrql) ExReleaseSpinLock(&RsValidateQueueLock, oldIrql)
  634. /*++
  635. VOID
  636. RsGetIoLock(PKIRQL irql)
  637. Routine Description:
  638. Lock the IO queue
  639. Arguments:
  640. Variable to receive current irql
  641. Return Value:
  642. 0
  643. Note:
  644. --*/
  645. #define RsGetIoLock(irql) ExAcquireSpinLock(&RsIoQueueLock, irql)
  646. /*++
  647. VOID
  648. RsPutIoLock(KIRQL oldIrql)
  649. Routine Description:
  650. Unlock the IO queue
  651. Arguments:
  652. oldIrql - Saved irql
  653. Return Value:
  654. 0
  655. Note:
  656. --*/
  657. #define RsPutIoLock(oldIrql) ExReleaseSpinLock(&RsIoQueueLock, oldIrql)
  658. #define RP_IS_NO_RECALL_OPTION(OpenOptions) \
  659. (RsNoRecallDefault?!((OpenOptions) & FILE_OPEN_NO_RECALL) : ((OpenOptions) & FILE_OPEN_NO_RECALL))
  660. #define RP_SET_NO_RECALL_OPTION(OpenOptions) \
  661. (RsNoRecallDefault ? ((OpenOptions) &= ~FILE_OPEN_NO_RECALL):((OpenOptions) |= FILE_OPEN_NO_RECALL))
  662. #define RP_RESET_NO_RECALL_OPTION(OpenOptions) \
  663. (RsNoRecallDefault ?((OpenOptions) |= FILE_OPEN_NO_RECALL) : ((OpenOptions) &= ~FILE_OPEN_NO_RECALL))
  664. #define RP_IS_NO_RECALL(Entry) \
  665. (RP_IS_NO_RECALL_OPTION((Entry)->openOptions) && !(((PRP_FILE_CONTEXT) (Entry)->fsContext)->flags & RP_FILE_WAS_WRITTEN))
  666. #define RP_SET_NO_RECALL(Entry) \
  667. RP_SET_NO_RECALL_OPTION((Entry)->openOptions)
  668. #define RP_RESET_NO_RECALL(Entry) \
  669. RP_RESET_NO_RECALL_OPTION(Entry->openOptions)
  670. typedef struct _RP_VALIDATE_INFO {
  671. LIST_ENTRY list;
  672. LARGE_INTEGER lastSetTime; // Last time a RP was set.
  673. ULONG serial; // Volume serial number
  674. } RP_VALIDATE_INFO, *PRP_VALIDATE_INFO;
  675. typedef struct _AV_ERR {
  676. ULONG line;
  677. ULONG file;
  678. ULONG code;
  679. WCHAR string[1]; /* Actual size will vary */
  680. } AV_ERR, *PAV_ERR;
  681. //
  682. // Possible create flags:
  683. //
  684. #define SF_FILE_CREATE_PATH 1
  685. #define SF_FILE_CREATE_ID 2
  686. #define SF_FILE_READ 3
  687. typedef enum _RP_FILE_BUF_STATE {
  688. RP_FILE_BUF_INVALID=0,
  689. RP_FILE_BUF_IO,
  690. RP_FILE_BUF_VALID,
  691. RP_FILE_BUF_ERROR
  692. } RP_FILE_BUF_STATE, *PRP_FILE_BUF_STATE;
  693. //
  694. // Define the cache buffer structure
  695. //
  696. typedef struct _RP_FILE_BUF {
  697. //
  698. // IRPs waiting on this block
  699. //
  700. LIST_ENTRY WaitQueue;
  701. //
  702. // Volume serial number for the volume on which the file
  703. // this block maps to resides
  704. //
  705. ULONG VolumeSerial;
  706. //
  707. // File id uniquely indicating which file this block
  708. // belongs to
  709. //
  710. ULONGLONG FileId;
  711. //
  712. // Block number this buffer maps to
  713. //
  714. ULONGLONG Block;
  715. //
  716. // Lock for the buffer
  717. //
  718. ERESOURCE Lock;
  719. //
  720. // Links in the hash queue this buffer belongs
  721. //
  722. LIST_ENTRY BucketLinks;
  723. //
  724. // Links in the lru list
  725. //
  726. LIST_ENTRY LruLinks;
  727. //
  728. // Indicates the current buffer state
  729. //
  730. RP_FILE_BUF_STATE State;
  731. //
  732. // If i/o completed with errors, this is useful
  733. //
  734. NTSTATUS IoStatus;
  735. //
  736. // Actual buffer contents themselves
  737. //
  738. PUCHAR Data;
  739. //
  740. // Usn used to validate block
  741. //
  742. LONGLONG Usn;
  743. } RP_FILE_BUF, *PRP_FILE_BUF;
  744. //
  745. // The hash bucket structure
  746. //
  747. typedef struct _RP_CACHE_BUCKET {
  748. //
  749. // Link to the head of the entries in this bucket
  750. //
  751. LIST_ENTRY FileBufHead;
  752. } RP_CACHE_BUCKET, *PRP_CACHE_BUCKET;
  753. //
  754. // Cache LRU structure
  755. //
  756. typedef struct _RP_CACHE_LRU {
  757. //
  758. // Pointer to head of LRU
  759. //
  760. LIST_ENTRY FileBufHead;
  761. //
  762. // Lock structure for protecting the LRU
  763. //
  764. FAST_MUTEX Lock;
  765. //
  766. // Total number of buffers in the cache
  767. //
  768. //
  769. ULONG TotalCount;
  770. //
  771. // Number of buffers in LRU (just for bookkeeping)
  772. //
  773. ULONG LruCount;
  774. //
  775. // Counting semaphore used to signal availability (and number)
  776. // of buffers in LRU
  777. //
  778. KSEMAPHORE AvailableSemaphore;
  779. } RP_CACHE_LRU, *PRP_CACHE_LRU;
  780. //
  781. // Completion Context used by Mount and LoadFs completion routines.
  782. //
  783. typedef struct _RP_COMPLETION_CONTEXT {
  784. LIST_ENTRY leQueueHead;
  785. PIO_WORKITEM pIoWorkItem;
  786. PIRP pIrp;
  787. PIO_WORKITEM_ROUTINE prtnWorkItemRoutine;
  788. union {
  789. struct {
  790. PVPB pvpbOriginalVpb;
  791. PDEVICE_OBJECT pdoRealDevice;
  792. PDEVICE_OBJECT pdoNewFilterDevice;
  793. } Mount;
  794. struct {
  795. PVOID pvDummy;
  796. } LoadFs;
  797. } Parameters;
  798. } RP_COMPLETION_CONTEXT, *PRP_COMPLETION_CONTEXT;
  799. //
  800. // Some utility macros
  801. //
  802. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  803. #define MIN(a,b) ((a) > (b) ? (b) : (a))
  804. //
  805. // Debug support
  806. //
  807. #define DBG_INFO DPFLTR_INFO_LEVEL
  808. #define DBG_ERROR DPFLTR_ERROR_LEVEL
  809. #define DBG_VERBOSE DPFLTR_TRACE_LEVEL
  810. #define DBG_LOCK DPFLTR_TRACE_LEVEL
  811. #define DebugTrace(MSG) DbgPrintEx MSG
  812. //
  813. // Function prototypes
  814. //
  815. NTSTATUS
  816. RsAddQueue(IN ULONG Serial,
  817. OUT PULONGLONG RecallId,
  818. IN ULONG OpenOption,
  819. IN PFILE_OBJECT FileObject,
  820. IN PDEVICE_OBJECT DevObj,
  821. IN PDEVICE_OBJECT FilterDeviceObject,
  822. IN PRP_DATA PhData,
  823. IN LARGE_INTEGER RecallStart,
  824. IN LARGE_INTEGER RecallSize,
  825. IN LONGLONG FileId,
  826. IN LONGLONG ObjIdHi,
  827. IN LONGLONG ObjIdLo,
  828. IN ULONG DesiredAccess,
  829. IN PRP_USER_SECURITY_INFO UserSecurityInfo);
  830. NTSTATUS
  831. RsAddFileObj(IN PFILE_OBJECT fileObj,
  832. IN PDEVICE_OBJECT FilterDeviceObject,
  833. IN RP_DATA *phData,
  834. IN ULONG openOption);
  835. NTSTATUS
  836. RsQueueCancel(IN ULONGLONG filterId);
  837. NTSTATUS
  838. RsMakeContext(IN PFILE_OBJECT fileObj,
  839. OUT PRP_FILE_CONTEXT *context);
  840. NTSTATUS
  841. RsReleaseFileContext(IN PRP_FILE_CONTEXT context);
  842. NTSTATUS
  843. RsFreeFileObject(IN PLIST_ENTRY FilterContext);
  844. PRP_FILE_CONTEXT
  845. RsAcquireFileContext(IN ULONGLONG FilterId,
  846. IN BOOLEAN Exclusive);
  847. VOID
  848. RsReleaseFileObject(IN PRP_FILE_OBJ entry);
  849. NTSTATUS
  850. RsGenerateDevicePath(IN PDEVICE_OBJECT deviceObject,
  851. OUT POBJECT_NAME_INFORMATION *nameInfo
  852. );
  853. NTSTATUS
  854. RsGenerateFullPath(IN POBJECT_NAME_INFORMATION fileName,
  855. IN PDEVICE_OBJECT deviceObject,
  856. OUT POBJECT_NAME_INFORMATION *nameInfo
  857. );
  858. ULONG
  859. RsRemoveQueue(IN PFILE_OBJECT fileObj);
  860. NTSTATUS
  861. RsCompleteRecall(IN PDEVICE_OBJECT DeviceObject,
  862. IN ULONGLONG FilterId,
  863. IN NTSTATUS Status,
  864. IN ULONG RecallAction,
  865. IN BOOLEAN CancellableRead);
  866. NTSTATUS
  867. RsCompleteReads(IN PRP_FILE_CONTEXT Context);
  868. NTSTATUS
  869. RsPreserveDates(IN PRP_FILE_CONTEXT Context);
  870. NTSTATUS
  871. RsMarkUsn(IN PRP_FILE_CONTEXT Context);
  872. NTSTATUS
  873. RsOpenTarget(IN PRP_FILE_CONTEXT Context,
  874. IN ULONG OpenAccess,
  875. IN ULONG AdditionalAccess,
  876. OUT HANDLE *Handle,
  877. OUT PFILE_OBJECT *FileObject);
  878. ULONG
  879. RsIsNoRecall(IN PFILE_OBJECT fileObj,
  880. OUT PRP_DATA *rpData);
  881. NTSTATUS
  882. RsPartialData(IN PDEVICE_OBJECT DeviceObject,
  883. IN ULONGLONG filterId,
  884. IN NTSTATUS status,
  885. IN CHAR *buffer,
  886. IN ULONG bytesRead,
  887. IN ULONGLONG offset);
  888. NTSTATUS
  889. RsPartialWrite(IN PDEVICE_OBJECT DeviceObject,
  890. IN PRP_FILE_CONTEXT Context,
  891. IN CHAR *Buffer,
  892. IN ULONG BufLen,
  893. IN ULONGLONG Offset);
  894. NTSTATUS
  895. RsDoWrite(IN PDEVICE_OBJECT DeviceObject,
  896. IN PRP_FILE_CONTEXT Context);
  897. NTSTATUS
  898. RsQueueRecall(IN ULONGLONG filterId,
  899. IN ULONGLONG recallStart,
  900. IN ULONGLONG recallSize);
  901. NTSTATUS
  902. RsQueueNoRecall(IN PFILE_OBJECT FileObject,
  903. IN PIRP Irp,
  904. IN ULONGLONG RecallStart,
  905. IN ULONGLONG RecallSize,
  906. IN ULONG BufferOffset,
  907. IN ULONG BufferLength,
  908. IN PRP_FILE_BUF CacheBuffer,
  909. IN PVOID UserBuffer);
  910. NTSTATUS
  911. RsQueueNoRecallOpen(IN PRP_FILE_OBJ entry,
  912. IN ULONGLONG filterId,
  913. IN ULONGLONG offset,
  914. IN ULONGLONG size);
  915. NTSTATUS
  916. RsQueueRecallOpen(IN PRP_FILE_CONTEXT Context,
  917. IN PRP_FILE_OBJ Entry,
  918. IN ULONGLONG FilterId,
  919. IN ULONGLONG Offset,
  920. IN ULONGLONG Size,
  921. IN ULONG Command);
  922. NTSTATUS
  923. RsGetFileInfo(IN PRP_FILE_OBJ Entry,
  924. IN PDEVICE_OBJECT DeviceObject);
  925. NTSTATUS
  926. RsGetFileId(IN PRP_FILE_OBJ entry,
  927. IN PDEVICE_OBJECT DeviceObject);
  928. NTSTATUS
  929. RsGetFileName(IN PRP_FILE_OBJ entry,
  930. IN PDEVICE_OBJECT DeviceObject);
  931. NTSTATUS
  932. RsCloseFile(IN ULONGLONG filterId);
  933. NTSTATUS
  934. RsCleanupFileObject(IN ULONGLONG filterId);
  935. NTSTATUS
  936. RsCompleteIrp(
  937. IN PDEVICE_OBJECT DeviceObject,
  938. IN PIRP Irp,
  939. IN PVOID Context);
  940. NTSTATUS
  941. RsCheckRead(IN PIRP irp,
  942. IN PFILE_OBJECT fileObject,
  943. IN PDEVICE_EXTENSION deviceExtension);
  944. NTSTATUS
  945. RsCheckWrite(IN PIRP irp,
  946. IN PFILE_OBJECT fileObject,
  947. IN PDEVICE_EXTENSION deviceExtension);
  948. NTSTATUS
  949. RsFailAllRequests(IN PRP_FILE_CONTEXT Context,
  950. IN BOOLEAN Norecall);
  951. NTSTATUS
  952. RsCompleteAllRequests(
  953. IN PRP_FILE_CONTEXT Context,
  954. IN PRP_FILE_OBJ Entry,
  955. IN NTSTATUS Status
  956. );
  957. NTSTATUS
  958. RsWriteReparsePointData(IN PRP_FILE_CONTEXT Context);
  959. NTSTATUS
  960. RsTruncateFile(IN PRP_FILE_CONTEXT Context);
  961. NTSTATUS
  962. RsSetEndOfFile(IN PRP_FILE_CONTEXT Context,
  963. IN ULONGLONG size);
  964. BOOLEAN
  965. RsIsFastIoPossible(IN PFILE_OBJECT fileObj);
  966. PIRP
  967. RsGetFsaRequest(VOID);
  968. PRP_FILE_OBJ
  969. RsFindQueue(IN ULONGLONG filterId);
  970. NTSTATUS
  971. RsAddIo(IN PIRP irp);
  972. PIRP
  973. RsRemoveIo(VOID);
  974. VOID
  975. RsCompleteRead(IN PRP_IRP_QUEUE Irp,
  976. IN BOOLEAN unlock);
  977. BOOLEAN
  978. RsIsFileObj(IN PFILE_OBJECT fileObj,
  979. IN BOOLEAN returnContextData,
  980. OUT PRP_DATA *rpData,
  981. OUT POBJECT_NAME_INFORMATION *str,
  982. OUT LONGLONG *fileId,
  983. OUT LONGLONG *objIdHi,
  984. OUT LONGLONG *objIdLo,
  985. OUT ULONG *options,
  986. OUT ULONGLONG *filterId,
  987. OUT USN *usn);
  988. VOID
  989. RsCancelRecalls(VOID);
  990. VOID
  991. RsCancelIo(VOID);
  992. VOID
  993. RsLogValidateNeeded(IN ULONG serial);
  994. BOOLEAN
  995. RsAddValidateObj(IN ULONG serial,
  996. IN LARGE_INTEGER cTime);
  997. BOOLEAN
  998. RsRemoveValidateObj(IN ULONG serial);
  999. NTSTATUS
  1000. RsQueueValidate(IN ULONG serial);
  1001. ULONG
  1002. RsTerminate(VOID);
  1003. NTSTATUS
  1004. RsGetRecallInfo(IN OUT PRP_MSG Msg,
  1005. OUT PULONG_PTR InfoSize,
  1006. IN KPROCESSOR_MODE RequestorMode);
  1007. VOID
  1008. RsCancelReadRecall(IN PDEVICE_OBJECT DeviceObject,
  1009. IN PIRP Irp);
  1010. VOID
  1011. RsCancelWriteRecall(IN PDEVICE_OBJECT DeviceObject,
  1012. IN PIRP Irp);
  1013. VOID
  1014. RsLogError(IN ULONG line,
  1015. IN ULONG file,
  1016. IN ULONG code,
  1017. IN NTSTATUS ioError,
  1018. IN PIO_STACK_LOCATION irpSp,
  1019. IN WCHAR *msgString);
  1020. ULONG
  1021. RsGetReparseData(IN PFILE_OBJECT fileObject,
  1022. IN PDEVICE_OBJECT deviceObject,
  1023. OUT PRP_DATA rpData);
  1024. NTSTATUS
  1025. RsCheckVolumeReadOnly (IN PDEVICE_OBJECT FilterDeviceObject,
  1026. IN OUT PBOOLEAN pbReturnedFlagReadOnly);
  1027. NTSTATUS
  1028. RsQueryValueKey (
  1029. IN PUNICODE_STRING KeyName,
  1030. IN PUNICODE_STRING ValueName,
  1031. IN OUT PULONG ValueLength,
  1032. IN OUT PKEY_VALUE_FULL_INFORMATION *KeyValueInformation,
  1033. IN OUT PBOOLEAN DeallocateKeyValue);
  1034. NTSTATUS
  1035. RsCacheInitialize(
  1036. VOID
  1037. );
  1038. VOID
  1039. RsCacheFsaPartialData(
  1040. IN PRP_IRP_QUEUE ReadIo,
  1041. IN PUCHAR Buffer,
  1042. IN ULONGLONG Offset,
  1043. IN ULONG Length,
  1044. IN NTSTATUS Status
  1045. );
  1046. VOID
  1047. RsCacheFsaIoComplete(
  1048. IN PRP_IRP_QUEUE ReadIo,
  1049. IN NTSTATUS Status
  1050. );
  1051. NTSTATUS
  1052. RsGetNoRecallData(
  1053. IN PFILE_OBJECT FileObject,
  1054. IN PIRP Irp,
  1055. IN USN Usn,
  1056. IN LONGLONG FileOffset,
  1057. IN LONGLONG Length,
  1058. IN PUCHAR UserBuffer
  1059. );
  1060. LONG
  1061. RsExceptionFilter(
  1062. IN WCHAR *FunctionName,
  1063. IN PEXCEPTION_POINTERS ExceptionPointer);
  1064. NTSTATUS
  1065. RsTruncateOnClose(
  1066. IN PRP_FILE_CONTEXT Context
  1067. );
  1068. NTSTATUS
  1069. RsSetPremigratedState(IN PRP_FILE_CONTEXT Context);
  1070. NTSTATUS
  1071. RsDeleteReparsePoint(IN PRP_FILE_CONTEXT Context);
  1072. NTSTATUS
  1073. RsSetResetAttributes(IN PFILE_OBJECT FileObject,
  1074. IN ULONG SetAttributes,
  1075. IN ULONG ResetAttributes);
  1076. BOOLEAN
  1077. RsSetCancelRoutine(IN PIRP Irp,
  1078. IN PDRIVER_CANCEL CancelRoutine);
  1079. BOOLEAN
  1080. RsClearCancelRoutine (
  1081. IN PIRP Irp
  1082. );
  1083. NTSTATUS
  1084. RsGetFileUsn(IN PRP_FILE_CONTEXT Context,
  1085. IN PFILE_OBJECT FileObject,
  1086. IN PDEVICE_OBJECT FilterDeviceObject);
  1087. VOID
  1088. RsInterlockedRemoveEntryList(PLIST_ENTRY Entry,
  1089. PKSPIN_LOCK Lock);
  1090. VOID
  1091. RsGetUserInfo(
  1092. IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
  1093. OUT PRP_USER_SECURITY_INFO UserSecurityInfo);
  1094. typedef enum _RpModuleCode
  1095. {
  1096. ModRpFilter = 100
  1097. ,ModRpFilfun
  1098. ,ModRpCache
  1099. ,ModRpzw
  1100. ,ModRpSec
  1101. } RpModuleCode;
  1102. typedef struct _RP_TRACE_ENTRY
  1103. {
  1104. RpModuleCode ModuleCode;
  1105. USHORT usLineNumber;
  1106. USHORT usIrql;
  1107. LARGE_INTEGER Timestamp;
  1108. ULONG_PTR Value1;
  1109. ULONG_PTR Value2;
  1110. ULONG_PTR Value3;
  1111. ULONG_PTR Value4;
  1112. } RP_TRACE_ENTRY, *PRP_TRACE_ENTRY;
  1113. typedef struct _RP_TRACE_CONTROL_BLOCK
  1114. {
  1115. KSPIN_LOCK Lock;
  1116. PRP_TRACE_ENTRY EntryBuffer;
  1117. ULONG EntryMaximum;
  1118. ULONG EntryNext;
  1119. } RP_TRACE_CONTROL_BLOCK, *PRP_TRACE_CONTROL_BLOCK;
  1120. #define RsTrace0(_ModuleCode) RsTrace4 ((_ModuleCode), 0, 0, 0, 0)
  1121. #define RsTrace1(_ModuleCode, _Value1) RsTrace4 ((_ModuleCode), (_Value1), 0, 0, 0)
  1122. #define RsTrace2(_ModuleCode, _Value1, _Value2) RsTrace4 ((_ModuleCode), (_Value1), (_Value2), 0, 0)
  1123. #define RsTrace3(_ModuleCode, _Value1, _Value2, _Value3) RsTrace4 ((_ModuleCode), (_Value1), (_Value2), (_Value3), 0)
  1124. #if DBG
  1125. #define RsTrace4(_ModuleCode, _Value1, _Value2, _Value3, _Value4) RsTraceAddEntry ((_ModuleCode), \
  1126. ((USHORT)(__LINE__)), \
  1127. ((ULONG_PTR)(_Value1)), \
  1128. ((ULONG_PTR)(_Value2)), \
  1129. ((ULONG_PTR)(_Value3)), \
  1130. ((ULONG_PTR)(_Value4)))
  1131. #else
  1132. #define RsTrace4(_ModuleCode, _Value1, _Value2, _Value3, _Value4)
  1133. #endif
  1134. #if DBG
  1135. #define DEFAULT_TRACE_ENTRIES (0x4000)
  1136. #else
  1137. #define DEFAULT_TRACE_ENTRIES (0)
  1138. #endif
  1139. VOID RsTraceAddEntry (RpModuleCode ModuleCode,
  1140. USHORT usLineNumber,
  1141. ULONG_PTR Value1,
  1142. ULONG_PTR Value2,
  1143. ULONG_PTR Value3,
  1144. ULONG_PTR Value4);
  1145. NTSTATUS RsTraceInitialize (ULONG ulRequestedTraceEntries);
  1146. extern PRP_TRACE_CONTROL_BLOCK RsTraceControlBlock;
  1147. extern ULONG RsDefaultTraceEntries;
  1148. NTSTATUS RsLookupContext (PFILE_OBJECT pFileObject,
  1149. PRP_FILE_OBJ *pReturnedRpFileObject,
  1150. PRP_FILE_CONTEXT *pReturnedRpFileContext);