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.

1483 lines
36 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. // filterId for last completion
  438. //
  439. ULONGLONG lastRecallCompletionFilterId;
  440. //
  441. // Volume serial number
  442. //
  443. ULONG serial;
  444. //
  445. // If the recall is complete this is the status
  446. //
  447. NTSTATUS recallStatus;
  448. //
  449. // Recall state
  450. //
  451. RP_RECALL_STATE state;
  452. //
  453. // Flags (see below for description)
  454. //
  455. ULONG flags;
  456. //
  457. // Reference count for the file context
  458. //
  459. ULONG refCount;
  460. //
  461. // Usn of the file
  462. //
  463. USN usn;
  464. //
  465. // Tracks create section lock
  466. //
  467. LONG createSectionLock;
  468. //
  469. // Reparse point data
  470. //
  471. RP_DATA rpData;
  472. } RP_FILE_CONTEXT, *PRP_FILE_CONTEXT;
  473. //
  474. // RP_FILE_CONTEXT Flags
  475. //
  476. // We have seen a write to this file
  477. #define RP_FILE_WAS_WRITTEN 1
  478. #define RP_FILE_INITIALIZED 2
  479. #define RP_FILE_REPARSE_POINT_DELETED 4
  480. /*++
  481. VOID
  482. RsInitializeFileContextQueueLock()
  483. Routine Description
  484. Initializes lock guarding the file context queue
  485. Arguments
  486. none
  487. Return Value
  488. none
  489. --*/
  490. #define RsInitializeFileContextQueueLock() { \
  491. DebugTrace((DPFLTR_RSFILTER_ID, DBG_LOCK,"RsFilter: RsInitializeFileContextQueueLock.\n"));\
  492. ExInitializeFastMutex(&RsFileContextQueueLock); \
  493. }
  494. /*++
  495. VOID
  496. RsAcquireFileContextQueueLock()
  497. Routine Description
  498. Acquire lock guarding the file context queue
  499. Arguments
  500. none
  501. Return Value
  502. none
  503. --*/
  504. #define RsAcquireFileContextQueueLock() { \
  505. ExAcquireFastMutex(&RsFileContextQueueLock); \
  506. DebugTrace((DPFLTR_RSFILTER_ID, DBG_LOCK, "RsFilter: RsAcquireFileContextQueueLock.\n"));\
  507. }
  508. /*++
  509. VOID
  510. RsReleaseFileContextQueueLock()
  511. Routine Description
  512. Release lock guarding the file context queue
  513. Arguments
  514. none
  515. Return Value
  516. none
  517. --*/
  518. #define RsReleaseFileContextQueueLock() { \
  519. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsReleaseFileContextQueueLock.\n"));\
  520. ExReleaseFastMutex(&RsFileContextQueueLock); \
  521. }
  522. /*++
  523. VOID
  524. RsAcquireFileObjectLockExclusive()
  525. Routine Description
  526. Acquire lock guarding a file object entry
  527. Arguments
  528. none
  529. Return Value
  530. none
  531. --*/
  532. #define RsAcquireFileObjectEntryLockExclusive(entry) { \
  533. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileObjectEntryLockExclusive Waiting (%x).\n", entry));\
  534. FsRtlEnterFileSystem(); \
  535. ExAcquireResourceExclusiveLite(&(entry)->resource, TRUE); \
  536. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileObjectEntryLockExclusive Owned (%x).\n", entry));\
  537. }
  538. /*++
  539. VOID
  540. RsAcquireFileObjectEntryLockShared()
  541. Routine Description
  542. Acquire lock guarding a file object entry
  543. Arguments
  544. none
  545. Return Value
  546. none
  547. --*/
  548. #define RsAcquireFileObjectEntryLockShared(entry) { \
  549. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileObjectEntryLockShared Waiting (%x).\n", entry));\
  550. FsRtlEnterFileSystem(); \
  551. ExAcquireResourceSharedLite(&(entry)->resource, TRUE); \
  552. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileObjectEntryLockShared Owned (%x).\n", entry));\
  553. }
  554. /*++
  555. VOID
  556. RsReleaseFileObjectEntryLock()
  557. Routine Description
  558. Release lock guarding a file object entry
  559. Arguments
  560. none
  561. Return Value
  562. none
  563. --*/
  564. #define RsReleaseFileObjectEntryLock(entry) { \
  565. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsReleaseFileObjectEntryLock (%x).\n", entry));\
  566. ExReleaseResourceLite(&(entry)->resource); \
  567. FsRtlExitFileSystem(); \
  568. }
  569. /*++
  570. VOID
  571. RsAcquireFileContextEntryLockExclusive()
  572. Routine Description
  573. Acquire lock guarding a file context entry
  574. Arguments
  575. none
  576. Return Value
  577. none
  578. --*/
  579. #define RsAcquireFileContextEntryLockExclusive(entry) { \
  580. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileContextEntryLockExclusive Waiting (%x).\n", entry));\
  581. FsRtlEnterFileSystem(); \
  582. ExAcquireResourceExclusiveLite(&(entry)->resource, TRUE); \
  583. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileContextEntryLockExclusive Owned (%x).\n", entry));\
  584. }
  585. /*++
  586. VOID
  587. RsAcquireFileContextEntryLockShared()
  588. Routine Description
  589. Acquire lock guarding a file context entry
  590. Arguments
  591. none
  592. Return Value
  593. none
  594. --*/
  595. #define RsAcquireFileContextEntryLockShared(entry) { \
  596. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileContextEntryLockShared Waiting (%x).\n", entry));\
  597. FsRtlEnterFileSystem(); \
  598. ExAcquireResourceSharedLite(&(entry)->resource, TRUE); \
  599. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsAcquireFileContextEntryLockShared Owned (%x).\n", entry));\
  600. }
  601. /*++
  602. VOID
  603. RsReleaseFileContextEntryLock()
  604. Routine Description
  605. Release lock guarding a file context entry
  606. Arguments
  607. none
  608. Return Value
  609. none
  610. --*/
  611. #define RsReleaseFileContextEntryLock(entry) { \
  612. DebugTrace((DPFLTR_RSFILTER_ID,DBG_LOCK, "RsFilter: RsReleaseFileContextEntryLock. (%x)\n", entry));\
  613. ExReleaseResourceLite(&(entry)->resource); \
  614. FsRtlExitFileSystem(); \
  615. }
  616. /*++
  617. VOID
  618. RsGetValidateLock(PKIRQL irql)
  619. Routine Description:
  620. Get a lock on the validate queue
  621. Arguments:
  622. Place to save irql
  623. Return Value:
  624. None
  625. --*/
  626. #define RsGetValidateLock(irql) ExAcquireSpinLock(&RsValidateQueueLock, irql)
  627. /*++
  628. VOID
  629. RsPutValidateLock(KIRQL oldIrql)
  630. Routine Description:
  631. Free a lock on the validate queue
  632. Arguments:
  633. Saved irql
  634. Return Value:
  635. None
  636. --*/
  637. #define RsPutValidateLock(oldIrql) ExReleaseSpinLock(&RsValidateQueueLock, oldIrql)
  638. /*++
  639. VOID
  640. RsGetIoLock(PKIRQL irql)
  641. Routine Description:
  642. Lock the IO queue
  643. Arguments:
  644. Variable to receive current irql
  645. Return Value:
  646. 0
  647. Note:
  648. --*/
  649. #define RsGetIoLock(irql) ExAcquireSpinLock(&RsIoQueueLock, irql)
  650. /*++
  651. VOID
  652. RsPutIoLock(KIRQL oldIrql)
  653. Routine Description:
  654. Unlock the IO queue
  655. Arguments:
  656. oldIrql - Saved irql
  657. Return Value:
  658. 0
  659. Note:
  660. --*/
  661. #define RsPutIoLock(oldIrql) ExReleaseSpinLock(&RsIoQueueLock, oldIrql)
  662. #define RP_IS_NO_RECALL_OPTION(OpenOptions) \
  663. (RsNoRecallDefault?!((OpenOptions) & FILE_OPEN_NO_RECALL) : ((OpenOptions) & FILE_OPEN_NO_RECALL))
  664. #define RP_SET_NO_RECALL_OPTION(OpenOptions) \
  665. (RsNoRecallDefault ? ((OpenOptions) &= ~FILE_OPEN_NO_RECALL):((OpenOptions) |= FILE_OPEN_NO_RECALL))
  666. #define RP_RESET_NO_RECALL_OPTION(OpenOptions) \
  667. (RsNoRecallDefault ?((OpenOptions) |= FILE_OPEN_NO_RECALL) : ((OpenOptions) &= ~FILE_OPEN_NO_RECALL))
  668. #define RP_IS_NO_RECALL(Entry) \
  669. (RP_IS_NO_RECALL_OPTION((Entry)->openOptions) && !(((PRP_FILE_CONTEXT) (Entry)->fsContext)->flags & RP_FILE_WAS_WRITTEN))
  670. #define RP_SET_NO_RECALL(Entry) \
  671. RP_SET_NO_RECALL_OPTION((Entry)->openOptions)
  672. #define RP_RESET_NO_RECALL(Entry) \
  673. RP_RESET_NO_RECALL_OPTION(Entry->openOptions)
  674. typedef struct _RP_VALIDATE_INFO {
  675. LIST_ENTRY list;
  676. LARGE_INTEGER lastSetTime; // Last time a RP was set.
  677. ULONG serial; // Volume serial number
  678. } RP_VALIDATE_INFO, *PRP_VALIDATE_INFO;
  679. typedef struct _AV_ERR {
  680. ULONG line;
  681. ULONG file;
  682. ULONG code;
  683. WCHAR string[1]; /* Actual size will vary */
  684. } AV_ERR, *PAV_ERR;
  685. //
  686. // Possible create flags:
  687. //
  688. #define SF_FILE_CREATE_PATH 1
  689. #define SF_FILE_CREATE_ID 2
  690. #define SF_FILE_READ 3
  691. typedef enum _RP_FILE_BUF_STATE {
  692. RP_FILE_BUF_INVALID=0,
  693. RP_FILE_BUF_IO,
  694. RP_FILE_BUF_VALID,
  695. RP_FILE_BUF_ERROR
  696. } RP_FILE_BUF_STATE, *PRP_FILE_BUF_STATE;
  697. //
  698. // Define the cache buffer structure
  699. //
  700. typedef struct _RP_FILE_BUF {
  701. //
  702. // IRPs waiting on this block
  703. //
  704. LIST_ENTRY WaitQueue;
  705. //
  706. // Volume serial number for the volume on which the file
  707. // this block maps to resides
  708. //
  709. ULONG VolumeSerial;
  710. //
  711. // File id uniquely indicating which file this block
  712. // belongs to
  713. //
  714. ULONGLONG FileId;
  715. //
  716. // Block number this buffer maps to
  717. //
  718. ULONGLONG Block;
  719. //
  720. // Lock for the buffer
  721. //
  722. ERESOURCE Lock;
  723. //
  724. // Links in the hash queue this buffer belongs
  725. //
  726. LIST_ENTRY BucketLinks;
  727. //
  728. // Links in the lru list
  729. //
  730. LIST_ENTRY LruLinks;
  731. //
  732. // Indicates the current buffer state
  733. //
  734. RP_FILE_BUF_STATE State;
  735. //
  736. // If i/o completed with errors, this is useful
  737. //
  738. NTSTATUS IoStatus;
  739. //
  740. // Actual buffer contents themselves
  741. //
  742. PUCHAR Data;
  743. //
  744. // Usn used to validate block
  745. //
  746. LONGLONG Usn;
  747. } RP_FILE_BUF, *PRP_FILE_BUF;
  748. //
  749. // The hash bucket structure
  750. //
  751. typedef struct _RP_CACHE_BUCKET {
  752. //
  753. // Link to the head of the entries in this bucket
  754. //
  755. LIST_ENTRY FileBufHead;
  756. } RP_CACHE_BUCKET, *PRP_CACHE_BUCKET;
  757. //
  758. // Cache LRU structure
  759. //
  760. typedef struct _RP_CACHE_LRU {
  761. //
  762. // Pointer to head of LRU
  763. //
  764. LIST_ENTRY FileBufHead;
  765. //
  766. // Lock structure for protecting the LRU
  767. //
  768. FAST_MUTEX Lock;
  769. //
  770. // Total number of buffers in the cache
  771. //
  772. //
  773. ULONG TotalCount;
  774. //
  775. // Number of buffers in LRU (just for bookkeeping)
  776. //
  777. ULONG LruCount;
  778. //
  779. // Counting semaphore used to signal availability (and number)
  780. // of buffers in LRU
  781. //
  782. KSEMAPHORE AvailableSemaphore;
  783. } RP_CACHE_LRU, *PRP_CACHE_LRU;
  784. //
  785. // Completion Context used by Mount and LoadFs completion routines.
  786. //
  787. typedef struct _RP_COMPLETION_CONTEXT {
  788. LIST_ENTRY leQueueHead;
  789. PIO_WORKITEM pIoWorkItem;
  790. PIRP pIrp;
  791. PIO_WORKITEM_ROUTINE prtnWorkItemRoutine;
  792. union {
  793. struct {
  794. PVPB pvpbOriginalVpb;
  795. PDEVICE_OBJECT pdoRealDevice;
  796. PDEVICE_OBJECT pdoNewFilterDevice;
  797. } Mount;
  798. struct {
  799. PVOID pvDummy;
  800. } LoadFs;
  801. } Parameters;
  802. } RP_COMPLETION_CONTEXT, *PRP_COMPLETION_CONTEXT;
  803. //
  804. // Some utility macros
  805. //
  806. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  807. #define MIN(a,b) ((a) > (b) ? (b) : (a))
  808. //
  809. // Debug support
  810. //
  811. #define DBG_INFO DPFLTR_INFO_LEVEL
  812. #define DBG_ERROR DPFLTR_ERROR_LEVEL
  813. #define DBG_VERBOSE DPFLTR_TRACE_LEVEL
  814. #define DBG_LOCK DPFLTR_TRACE_LEVEL
  815. #define DebugTrace(MSG) DbgPrintEx MSG
  816. //
  817. // Function prototypes
  818. //
  819. NTSTATUS
  820. RsAddQueue(IN ULONG Serial,
  821. OUT PULONGLONG RecallId,
  822. IN ULONG OpenOption,
  823. IN PFILE_OBJECT FileObject,
  824. IN PDEVICE_OBJECT DevObj,
  825. IN PDEVICE_OBJECT FilterDeviceObject,
  826. IN PRP_DATA PhData,
  827. IN LARGE_INTEGER RecallStart,
  828. IN LARGE_INTEGER RecallSize,
  829. IN LONGLONG FileId,
  830. IN LONGLONG ObjIdHi,
  831. IN LONGLONG ObjIdLo,
  832. IN ULONG DesiredAccess,
  833. IN PRP_USER_SECURITY_INFO UserSecurityInfo);
  834. NTSTATUS
  835. RsAddFileObj(IN PFILE_OBJECT fileObj,
  836. IN PDEVICE_OBJECT FilterDeviceObject,
  837. IN RP_DATA *phData,
  838. IN ULONG openOption);
  839. NTSTATUS
  840. RsQueueCancel(IN ULONGLONG filterId);
  841. NTSTATUS
  842. RsMakeContext(IN PFILE_OBJECT fileObj,
  843. OUT PRP_FILE_CONTEXT *context);
  844. NTSTATUS
  845. RsReleaseFileContext(IN PRP_FILE_CONTEXT context);
  846. NTSTATUS
  847. RsFreeFileObject(IN PLIST_ENTRY FilterContext);
  848. PRP_FILE_CONTEXT
  849. RsAcquireFileContext(IN ULONGLONG FilterId,
  850. IN BOOLEAN Exclusive);
  851. VOID
  852. RsReleaseFileObject(IN PRP_FILE_OBJ entry);
  853. NTSTATUS
  854. RsGenerateDevicePath(IN PDEVICE_OBJECT deviceObject,
  855. OUT POBJECT_NAME_INFORMATION *nameInfo
  856. );
  857. NTSTATUS
  858. RsGenerateFullPath(IN POBJECT_NAME_INFORMATION fileName,
  859. IN PDEVICE_OBJECT deviceObject,
  860. OUT POBJECT_NAME_INFORMATION *nameInfo
  861. );
  862. ULONG
  863. RsRemoveQueue(IN PFILE_OBJECT fileObj);
  864. NTSTATUS
  865. RsCompleteRecall(IN PDEVICE_OBJECT DeviceObject,
  866. IN ULONGLONG FilterId,
  867. IN NTSTATUS Status,
  868. IN ULONG RecallAction,
  869. IN BOOLEAN CancellableRead);
  870. NTSTATUS
  871. RsCompleteReads(IN PRP_FILE_CONTEXT Context);
  872. NTSTATUS
  873. RsPreserveDates(IN PRP_FILE_CONTEXT Context);
  874. NTSTATUS
  875. RsMarkUsn(IN PRP_FILE_CONTEXT Context);
  876. NTSTATUS
  877. RsOpenTarget(IN PRP_FILE_CONTEXT Context,
  878. IN ULONG OpenAccess,
  879. IN ULONG AdditionalAccess,
  880. OUT HANDLE *Handle,
  881. OUT PFILE_OBJECT *FileObject);
  882. ULONG
  883. RsIsNoRecall(IN PFILE_OBJECT fileObj,
  884. OUT PRP_DATA *rpData);
  885. NTSTATUS
  886. RsPartialData(IN PDEVICE_OBJECT DeviceObject,
  887. IN ULONGLONG filterId,
  888. IN NTSTATUS status,
  889. IN CHAR *buffer,
  890. IN ULONG bytesRead,
  891. IN ULONGLONG offset);
  892. NTSTATUS
  893. RsPartialWrite(IN PDEVICE_OBJECT DeviceObject,
  894. IN PRP_FILE_CONTEXT Context,
  895. IN CHAR *Buffer,
  896. IN ULONG BufLen,
  897. IN ULONGLONG Offset);
  898. NTSTATUS
  899. RsDoWrite(IN PDEVICE_OBJECT DeviceObject,
  900. IN PRP_FILE_CONTEXT Context);
  901. NTSTATUS
  902. RsQueueRecall(IN ULONGLONG filterId,
  903. IN ULONGLONG recallStart,
  904. IN ULONGLONG recallSize);
  905. NTSTATUS
  906. RsQueueNoRecall(IN PFILE_OBJECT FileObject,
  907. IN PIRP Irp,
  908. IN ULONGLONG RecallStart,
  909. IN ULONGLONG RecallSize,
  910. IN ULONG BufferOffset,
  911. IN ULONG BufferLength,
  912. IN PRP_FILE_BUF CacheBuffer,
  913. IN PVOID UserBuffer);
  914. NTSTATUS
  915. RsQueueNoRecallOpen(IN PRP_FILE_OBJ entry,
  916. IN ULONGLONG filterId,
  917. IN ULONGLONG offset,
  918. IN ULONGLONG size);
  919. NTSTATUS
  920. RsQueueRecallOpen(IN PRP_FILE_CONTEXT Context,
  921. IN PRP_FILE_OBJ Entry,
  922. IN ULONGLONG FilterId,
  923. IN ULONGLONG Offset,
  924. IN ULONGLONG Size,
  925. IN ULONG Command);
  926. NTSTATUS
  927. RsGetFileInfo(IN PRP_FILE_OBJ Entry,
  928. IN PDEVICE_OBJECT DeviceObject);
  929. NTSTATUS
  930. RsGetFileId(IN PRP_FILE_OBJ entry,
  931. IN PDEVICE_OBJECT DeviceObject);
  932. NTSTATUS
  933. RsGetFileName(IN PRP_FILE_OBJ entry,
  934. IN PDEVICE_OBJECT DeviceObject);
  935. NTSTATUS
  936. RsCloseFile(IN ULONGLONG filterId);
  937. NTSTATUS
  938. RsCleanupFileObject(IN ULONGLONG filterId);
  939. NTSTATUS
  940. RsCompleteIrp(
  941. IN PDEVICE_OBJECT DeviceObject,
  942. IN PIRP Irp,
  943. IN PVOID Context);
  944. NTSTATUS
  945. RsCheckRead(IN PIRP irp,
  946. IN PFILE_OBJECT fileObject,
  947. IN PDEVICE_EXTENSION deviceExtension);
  948. NTSTATUS
  949. RsCheckWrite(IN PIRP irp,
  950. IN PFILE_OBJECT fileObject,
  951. IN PDEVICE_EXTENSION deviceExtension);
  952. NTSTATUS
  953. RsFailAllRequests(IN PRP_FILE_CONTEXT Context,
  954. IN BOOLEAN Norecall);
  955. NTSTATUS
  956. RsCompleteAllRequests(
  957. IN PRP_FILE_CONTEXT Context,
  958. IN PRP_FILE_OBJ Entry,
  959. IN NTSTATUS Status
  960. );
  961. NTSTATUS
  962. RsWriteReparsePointData(IN PRP_FILE_CONTEXT Context);
  963. NTSTATUS
  964. RsTruncateFile(IN PRP_FILE_CONTEXT Context);
  965. NTSTATUS
  966. RsSetEndOfFile(IN PRP_FILE_CONTEXT Context,
  967. IN ULONGLONG size);
  968. BOOLEAN
  969. RsIsFastIoPossible(IN PFILE_OBJECT fileObj);
  970. PIRP
  971. RsGetFsaRequest(VOID);
  972. PRP_FILE_OBJ
  973. RsFindQueue(IN ULONGLONG filterId);
  974. NTSTATUS
  975. RsAddIo(IN PIRP irp);
  976. PIRP
  977. RsRemoveIo(VOID);
  978. VOID
  979. RsCompleteRead(IN PRP_IRP_QUEUE Irp,
  980. IN BOOLEAN unlock);
  981. BOOLEAN
  982. RsIsFileObj(IN PFILE_OBJECT fileObj,
  983. IN BOOLEAN returnContextData,
  984. OUT PRP_DATA *rpData,
  985. OUT POBJECT_NAME_INFORMATION *str,
  986. OUT LONGLONG *fileId,
  987. OUT LONGLONG *objIdHi,
  988. OUT LONGLONG *objIdLo,
  989. OUT ULONG *options,
  990. OUT ULONGLONG *filterId,
  991. OUT USN *usn);
  992. VOID
  993. RsCancelRecalls(VOID);
  994. VOID
  995. RsCancelIo(VOID);
  996. VOID
  997. RsLogValidateNeeded(IN ULONG serial);
  998. BOOLEAN
  999. RsAddValidateObj(IN ULONG serial,
  1000. IN LARGE_INTEGER cTime);
  1001. BOOLEAN
  1002. RsRemoveValidateObj(IN ULONG serial);
  1003. NTSTATUS
  1004. RsQueueValidate(IN ULONG serial);
  1005. ULONG
  1006. RsTerminate(VOID);
  1007. NTSTATUS
  1008. RsGetRecallInfo(IN OUT PRP_MSG Msg,
  1009. OUT PULONG_PTR InfoSize,
  1010. IN KPROCESSOR_MODE RequestorMode);
  1011. VOID
  1012. RsCancelReadRecall(IN PDEVICE_OBJECT DeviceObject,
  1013. IN PIRP Irp);
  1014. VOID
  1015. RsCancelWriteRecall(IN PDEVICE_OBJECT DeviceObject,
  1016. IN PIRP Irp);
  1017. VOID
  1018. RsLogError(IN ULONG line,
  1019. IN ULONG file,
  1020. IN ULONG code,
  1021. IN NTSTATUS ioError,
  1022. IN PIO_STACK_LOCATION irpSp,
  1023. IN WCHAR *msgString);
  1024. ULONG
  1025. RsGetReparseData(IN PFILE_OBJECT fileObject,
  1026. IN PDEVICE_OBJECT deviceObject,
  1027. OUT PRP_DATA rpData);
  1028. NTSTATUS
  1029. RsCheckVolumeReadOnly (IN PDEVICE_OBJECT FilterDeviceObject,
  1030. IN OUT PBOOLEAN pbReturnedFlagReadOnly);
  1031. NTSTATUS
  1032. RsQueryValueKey (
  1033. IN PUNICODE_STRING KeyName,
  1034. IN PUNICODE_STRING ValueName,
  1035. IN OUT PULONG ValueLength,
  1036. IN OUT PKEY_VALUE_FULL_INFORMATION *KeyValueInformation,
  1037. IN OUT PBOOLEAN DeallocateKeyValue);
  1038. NTSTATUS
  1039. RsCacheInitialize(
  1040. VOID
  1041. );
  1042. VOID
  1043. RsCacheFsaPartialData(
  1044. IN PRP_IRP_QUEUE ReadIo,
  1045. IN PUCHAR Buffer,
  1046. IN ULONGLONG Offset,
  1047. IN ULONG Length,
  1048. IN NTSTATUS Status
  1049. );
  1050. VOID
  1051. RsCacheFsaIoComplete(
  1052. IN PRP_IRP_QUEUE ReadIo,
  1053. IN NTSTATUS Status
  1054. );
  1055. NTSTATUS
  1056. RsGetNoRecallData(
  1057. IN PFILE_OBJECT FileObject,
  1058. IN PIRP Irp,
  1059. IN USN Usn,
  1060. IN LONGLONG FileOffset,
  1061. IN LONGLONG Length,
  1062. IN PUCHAR UserBuffer
  1063. );
  1064. LONG
  1065. RsExceptionFilter(
  1066. IN WCHAR *FunctionName,
  1067. IN PEXCEPTION_POINTERS ExceptionPointer);
  1068. NTSTATUS
  1069. RsTruncateOnClose(
  1070. IN PRP_FILE_CONTEXT Context
  1071. );
  1072. NTSTATUS
  1073. RsSetPremigratedState(IN PRP_FILE_CONTEXT Context);
  1074. NTSTATUS
  1075. RsDeleteReparsePoint(IN PRP_FILE_CONTEXT Context);
  1076. NTSTATUS
  1077. RsSetResetAttributes(IN PFILE_OBJECT FileObject,
  1078. IN ULONG SetAttributes,
  1079. IN ULONG ResetAttributes);
  1080. BOOLEAN
  1081. RsSetCancelRoutine(IN PIRP Irp,
  1082. IN PDRIVER_CANCEL CancelRoutine);
  1083. BOOLEAN
  1084. RsClearCancelRoutine (
  1085. IN PIRP Irp
  1086. );
  1087. NTSTATUS
  1088. RsGetFileUsn(IN PRP_FILE_CONTEXT Context,
  1089. IN PFILE_OBJECT FileObject,
  1090. IN PDEVICE_OBJECT FilterDeviceObject);
  1091. VOID
  1092. RsInterlockedRemoveEntryList(PLIST_ENTRY Entry,
  1093. PKSPIN_LOCK Lock);
  1094. VOID
  1095. RsGetUserInfo(
  1096. IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
  1097. OUT PRP_USER_SECURITY_INFO UserSecurityInfo);
  1098. typedef enum _RpModuleCode
  1099. {
  1100. ModRpFilter = 100
  1101. ,ModRpFilfun
  1102. ,ModRpCache
  1103. ,ModRpzw
  1104. ,ModRpSec
  1105. } RpModuleCode;
  1106. typedef struct _RP_TRACE_ENTRY
  1107. {
  1108. RpModuleCode ModuleCode;
  1109. USHORT usLineNumber;
  1110. USHORT usIrql;
  1111. LARGE_INTEGER Timestamp;
  1112. ULONG_PTR Value1;
  1113. ULONG_PTR Value2;
  1114. ULONG_PTR Value3;
  1115. ULONG_PTR Value4;
  1116. } RP_TRACE_ENTRY, *PRP_TRACE_ENTRY;
  1117. typedef struct _RP_TRACE_CONTROL_BLOCK
  1118. {
  1119. KSPIN_LOCK Lock;
  1120. PRP_TRACE_ENTRY EntryBuffer;
  1121. ULONG EntryMaximum;
  1122. ULONG EntryNext;
  1123. } RP_TRACE_CONTROL_BLOCK, *PRP_TRACE_CONTROL_BLOCK;
  1124. #define RsTrace0(_ModuleCode) RsTrace4 ((_ModuleCode), 0, 0, 0, 0)
  1125. #define RsTrace1(_ModuleCode, _Value1) RsTrace4 ((_ModuleCode), (_Value1), 0, 0, 0)
  1126. #define RsTrace2(_ModuleCode, _Value1, _Value2) RsTrace4 ((_ModuleCode), (_Value1), (_Value2), 0, 0)
  1127. #define RsTrace3(_ModuleCode, _Value1, _Value2, _Value3) RsTrace4 ((_ModuleCode), (_Value1), (_Value2), (_Value3), 0)
  1128. #if DBG
  1129. #define RsTrace4(_ModuleCode, _Value1, _Value2, _Value3, _Value4) RsTraceAddEntry ((_ModuleCode), \
  1130. ((USHORT)(__LINE__)), \
  1131. ((ULONG_PTR)(_Value1)), \
  1132. ((ULONG_PTR)(_Value2)), \
  1133. ((ULONG_PTR)(_Value3)), \
  1134. ((ULONG_PTR)(_Value4)))
  1135. #else
  1136. #define RsTrace4(_ModuleCode, _Value1, _Value2, _Value3, _Value4)
  1137. #endif
  1138. #if DBG
  1139. #define DEFAULT_TRACE_ENTRIES (0x4000)
  1140. #else
  1141. #define DEFAULT_TRACE_ENTRIES (0)
  1142. #endif
  1143. VOID RsTraceAddEntry (RpModuleCode ModuleCode,
  1144. USHORT usLineNumber,
  1145. ULONG_PTR Value1,
  1146. ULONG_PTR Value2,
  1147. ULONG_PTR Value3,
  1148. ULONG_PTR Value4);
  1149. NTSTATUS RsTraceInitialize (ULONG ulRequestedTraceEntries);
  1150. extern PRP_TRACE_CONTROL_BLOCK RsTraceControlBlock;
  1151. extern ULONG RsDefaultTraceEntries;
  1152. NTSTATUS RsLookupContext (PFILE_OBJECT pFileObject,
  1153. PRP_FILE_OBJ *pReturnedRpFileObject,
  1154. PRP_FILE_CONTEXT *pReturnedRpFileContext);