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.

1185 lines
31 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. webdav.h
  5. Abstract:
  6. This module defines the data structures and functions related to the
  7. WebDav protocol.
  8. Author:
  9. Rohan Kumar [rohank] 17-Mar-1999
  10. Revision History:
  11. --*/
  12. #ifndef _WEBDAV_H
  13. #define _WEBDAV_H
  14. #ifdef RX_PRIVATE_BUILD
  15. #undef IoGetTopLevelIrp
  16. #undef IoSetTopLevelIrp
  17. #endif
  18. //
  19. // The miniredir dipatch vector used by RDBSS.
  20. //
  21. extern struct _MINIRDR_DISPATCH MRxDAVDispatch;
  22. //
  23. // A serialization mutex used for various things.
  24. //
  25. extern FAST_MUTEX MRxDAVSerializationMutex;
  26. //
  27. // A pointer to the process that the RDBSS posts to. This is a non disappearing
  28. // process!
  29. //
  30. extern PEPROCESS MRxDAVSystemProcess;
  31. //
  32. // The DavWinInetCachePath which is used in satisfying volume related queries.
  33. //
  34. extern WCHAR DavWinInetCachePath[MAX_PATH];
  35. //
  36. // The ProcessId of the svchost.exe process that loads the webclnt.dll.
  37. //
  38. extern ULONG DavSvcHostProcessId;
  39. //
  40. // The exchange device name will be stored in this KEY_VALUE_PARTIAL_INFORMATION
  41. // structure.
  42. //
  43. extern PBYTE DavExchangeDeviceName;
  44. //
  45. // Name cache stuff. These values are read from the registry during init time.
  46. //
  47. extern ULONG FileInformationCacheLifeTimeInSec;
  48. extern ULONG FileNotFoundCacheLifeTimeInSec;
  49. extern ULONG NameCacheMaxEntries;
  50. //
  51. // The timeout values for various operations used by the MiniRedir. If an
  52. // operation is not completed within the timeout value specified for it, is
  53. // cancelled. The user can set the value to 0xffffffff to disable the
  54. // timeout/cancel logic. In other words, if the timeout value is 0xffffffff,
  55. // the requests will never timeout.
  56. //
  57. extern ULONG CreateRequestTimeoutValueInSec;
  58. extern ULONG CreateVNetRootRequestTimeoutValueInSec;
  59. extern ULONG QueryDirectoryRequestTimeoutValueInSec;
  60. extern ULONG CloseRequestTimeoutValueInSec;
  61. extern ULONG CreateSrvCallRequestTimeoutValueInSec;
  62. extern ULONG FinalizeSrvCallRequestTimeoutValueInSec;
  63. extern ULONG FinalizeFobxRequestTimeoutValueInSec;
  64. extern ULONG FinalizeVNetRootRequestTimeoutValueInSec;
  65. extern ULONG ReNameRequestTimeoutValueInSec;
  66. extern ULONG SetFileInfoRequestTimeoutValueInSec;
  67. extern ULONG QueryFileInfoRequestTimeoutValueInSec;
  68. extern ULONG QueryVolumeInfoRequestTimeoutValueInSec;
  69. extern ULONG LockRefreshRequestTimeoutValueInSec;
  70. //
  71. // The timer thread wakes up every "TimerThreadSleepTimeInSec" and cancels all
  72. // the requests which haven't completed in their specified timeout value. This
  73. // value is set to the min of the timeout values of all the requests mentioned
  74. // above.
  75. //
  76. extern ULONG TimerThreadSleepTimeInSec;
  77. //
  78. // The timer object used by the timer thread that cancels the requests which
  79. // have not completed in a specified time.
  80. //
  81. extern KTIMER DavTimerObject;
  82. //
  83. // This is used to indicate the timer thread to shutdown. When the system is
  84. // being shutdown this is set to TRUE. MRxDAVTimerThreadLock is the resource
  85. // used to gain access to this variable.
  86. //
  87. extern BOOL TimerThreadShutDown;
  88. extern ERESOURCE MRxDAVTimerThreadLock;
  89. //
  90. // The handle of the timer thread that is created using PsCreateSystemThread
  91. // is stored this global.
  92. //
  93. extern HANDLE TimerThreadHandle;
  94. //
  95. // This event is signalled by the timer thread right before its going to
  96. // terminate itself.
  97. //
  98. extern KEVENT TimerThreadEvent;
  99. //
  100. // If QueueLockRefreshWorkItem is TRUE, the TimerThread (which cancels all the
  101. // AsyncEngineContexts that haven't completed in a specified time) queues a
  102. // WorkItem to refresh the locks. After the WorkItem has been queued the value
  103. // of QueueLockRefreshWorkItem is set to FALSE. Once the worker thread is
  104. // done refreshing all the locks, it resets this value to TRUE. We have a
  105. // corresponding lock QueueLockRefreshWorkItemLock to synchronize access to
  106. // QueueLockRefreshWorkItem.
  107. //
  108. extern BOOL QueueLockRefreshWorkItem;
  109. extern ERESOURCE QueueLockRefreshWorkItemLock;
  110. //
  111. // The WorkQueueItem used in the MRxDAVContextTimerThread function to refresh
  112. // the LOCKs taken by this client.
  113. //
  114. extern RX_WORK_QUEUE_ITEM LockRefreshWorkQueueItem;
  115. #define DAV_MJ_READ 0
  116. #define DAV_MJ_WRITE 1
  117. //
  118. // Pool tags used by the reflector library. All the DAV MiniRedir pool tags
  119. // have "DV" as the first two characters.
  120. //
  121. #define DAV_SRVCALL_POOLTAG ('cSVD')
  122. #define DAV_NETROOT_POOLTAG ('tNVD')
  123. #define DAV_FILEINFO_POOLTAG ('iFVD')
  124. #define DAV_FILENAME_POOLTAG ('nFVD')
  125. #define DAV_EXCHANGE_POOLTAG ('xEVD')
  126. #define DAV_READWRITE_POOLTAG ('wRVD')
  127. #define DAV_QUERYDIR_POOLTAG ('dQVD')
  128. #define DAV_SRVOPEN_POOLTAG ('oSVD')
  129. #define DAV_LOCKTOKENENTRY_POOLTAG ('tLVD')
  130. #define DAV_LOCKCONFLICTENTRY_POOLTAG ('cLVD')
  131. //
  132. // Use the DavDbgTrace macro for logging Mini-Redir stuff in the kernel
  133. // debugger.
  134. //
  135. #if DBG
  136. extern ULONG MRxDavDebugVector;
  137. #define DAV_TRACE_ERROR 0x00000001
  138. #define DAV_TRACE_DEBUG 0x00000002
  139. #define DAV_TRACE_CONTEXT 0x00000004
  140. #define DAV_TRACE_DETAIL 0x00000008
  141. #define DAV_TRACE_ENTRYEXIT 0x00000010
  142. #define DAV_TRACE_QUERYDIR 0x00000020
  143. #define DAV_TRACE_OPENCLOSE 0x00000040
  144. #define DAV_TRACE_READ 0x00000080
  145. #define DAV_TRACE_WRITE 0x00000100
  146. #define DAV_TRACE_SRVCALL 0x00000200
  147. #define DAV_TRACE_FCBFOBX 0x00000400
  148. #define DAV_TRACE_DAVNETROOT 0x00000800
  149. #define DAV_TRACE_INFOCACHE 0x00001000
  150. #define DAV_TRACE_ALL 0xffffffff
  151. #define DavDbgTrace(_x_, _y_) { \
  152. if (_x_ & MRxDavDebugVector) { \
  153. DbgPrint _y_; \
  154. } \
  155. }
  156. #else
  157. #define DavDbgTrace(_x_, _y_)
  158. #endif
  159. //
  160. // The initialization states of the miniredir.
  161. //
  162. typedef enum _WEBDAV_INIT_STATES {
  163. MRxDAVINIT_START,
  164. MRxDAVINIT_MINIRDR_REGISTERED
  165. } WEBDAV_INIT_STATES;
  166. //
  167. // These are used by the entry point routines to specify what entrypoint was
  168. // called. This facilitates common continuation routines.
  169. //
  170. typedef enum _WEBDAV_MINIRDR_ENTRYPOINTS {
  171. DAV_MINIRDR_ENTRY_FROM_CREATE = 0,
  172. DAV_MINIRDR_ENTRY_FROM_CLEANUPFOBX,
  173. DAV_MINIRDR_ENTRY_FROM_CREATESRVCALL,
  174. DAV_MINIRDR_ENTRY_FROM_CREATEVNETROOT,
  175. DAV_MINIRDR_ENTRY_FROM_FINALIZESRVCALL,
  176. DAV_MINIRDR_ENTRY_FROM_FINALIZEVNETROOT,
  177. DAV_MINIRDR_ENTRY_FROM_CLOSESRVOPEN,
  178. DAV_MINIRDR_ENTRY_FROM_RENAME,
  179. DAV_MINIRDR_ENTRY_FROM_READ,
  180. DAV_MINIRDR_ENTRY_FROM_WRITE,
  181. DAV_MINIRDR_ENTRY_FROM_QUERYDIR,
  182. DAV_MINIRDR_ENTRY_FROM_SETFILEINFORMATION,
  183. DAV_MINIRDR_ENTRY_FROM_QUERYFILEINFORMATION,
  184. DAV_MINIRDR_ENTRY_FROM_QUERYVOLUMEINFORMATION,
  185. DAV_MINIRDR_ENTRY_FROM_REFRESHTHELOCK,
  186. DAV_MINIRDR_ENTRY_FROM_MAXIMUM
  187. } WEBDAV_MINIRDR_ENTRYPOINTS;
  188. //
  189. // The states of the I/O operation(s).
  190. //
  191. typedef enum _WEBDAV_INNERIO_STATE {
  192. MRxDAVInnerIoStates_Initial = 0,
  193. MRxDAVInnerIoStates_ReadyToSend,
  194. MRxDAVInnerIoStates_OperationOutstanding
  195. } WEBDAV_INNERIO_STATE;
  196. //
  197. // The WebDav context structure that encapsulates the AsyncEngineCtx structure
  198. // and has the miniredir specific fields.
  199. //
  200. typedef struct _WEBDAV_CONTEXT {
  201. //
  202. // The AsyncEngineCtx Structure used by the Reflector library.
  203. //
  204. union {
  205. UMRX_ASYNCENGINE_CONTEXT;
  206. UMRX_ASYNCENGINE_CONTEXT AsyncEngineContext;
  207. };
  208. //
  209. // This is used by the entry point routines to specify what entrypoint was
  210. // called. This facilitates common continuation routines.
  211. //
  212. WEBDAV_MINIRDR_ENTRYPOINTS EntryPoint;
  213. //
  214. // These describe the inner state of the I/O operation. These states are
  215. // described in the MRxDAV_INNERIO_STATE data structure.
  216. //
  217. UCHAR OpSpecificState;
  218. //
  219. // Pointer to the information strucutre for the Create request.
  220. //
  221. PDAV_USERMODE_CREATE_RETURNED_FILEINFO CreateReturnedFileInfo;
  222. //
  223. // This is used in the Continuation functions for the read, write and
  224. // querydir calls. It keeps track of the number of times the Continuation
  225. // routine has been called.
  226. //
  227. ULONG ContinueEntryCount;
  228. } WEBDAV_CONTEXT, *PWEBDAV_CONTEXT;
  229. //
  230. // While creating the AsyncEngineContext, the extra space needed for the
  231. // miniredir specific fields is also allocated. Thus, one doesn't need to
  232. // allocate twice.
  233. //
  234. #define SIZEOF_DAV_SPECIFIC_CONTEXT \
  235. sizeof(WEBDAV_CONTEXT) - sizeof(UMRX_ASYNCENGINE_CONTEXT)
  236. //
  237. // The WebDav device object structure that encapsulates the UMRX_DEVICE_OBJECT
  238. // structure and has the miniredir specific fields.
  239. //
  240. typedef struct _WEBDAV_DEVICE_OBJECT {
  241. //
  242. // The UMRX_DEVICE_OBJECT structure.
  243. //
  244. union {
  245. UMRX_DEVICE_OBJECT;
  246. UMRX_DEVICE_OBJECT UMRefDeviceObject;
  247. };
  248. //
  249. // TRUE => miniredir has been started.
  250. //
  251. BOOLEAN IsStarted;
  252. //
  253. // The FCB of the device object.
  254. //
  255. PVOID CachedRxDeviceFcb;
  256. //
  257. // The process registering this device object.
  258. //
  259. PEPROCESS RegisteringProcess;
  260. } WEBDAV_DEVICE_OBJECT, *PWEBDAV_DEVICE_OBJECT;
  261. //
  262. // The Dav device object.
  263. //
  264. extern PWEBDAV_DEVICE_OBJECT MRxDAVDeviceObject;
  265. //
  266. // The extra number of bytes needed for the device object. This info is used
  267. // when the device object gets created.
  268. //
  269. #define WEBDAV_DEVICE_OBJECT_EXTENSION_SIZE \
  270. (sizeof(WEBDAV_DEVICE_OBJECT) - sizeof(RDBSS_DEVICE_OBJECT))
  271. //
  272. // For every LOCK that is taken for a file, the following entry is created and
  273. // added to the global LockTokenEntryList.
  274. //
  275. typedef struct _WEBDAV_LOCK_TOKEN_ENTRY {
  276. LIST_ENTRY listEntry;
  277. //
  278. // The LockToken that was returned by the server on a successful LOCK
  279. // request.
  280. //
  281. PWCHAR OpaqueLockToken;
  282. //
  283. // The server on which the file is shared.
  284. //
  285. PWCHAR ServerName;
  286. //
  287. // The path of the file on the server.
  288. //
  289. PWCHAR PathName;
  290. //
  291. // The ServerHashTable ServerId of this server.
  292. //
  293. ULONG ServerID;
  294. //
  295. // The LogonId of this user.
  296. //
  297. LUID LogonID;
  298. //
  299. // If this is set to FALSE, this LockEntry is not refreshed.
  300. //
  301. BOOL ShouldThisEntryBeRefreshed;
  302. //
  303. // The SecurityClientContext of the client in whose context the LOCK was
  304. // taken. This is needed to impersonate the client when refreshing the
  305. // LOCK.
  306. //
  307. PSECURITY_CLIENT_CONTEXT SecurityClientContext;
  308. //
  309. // The timeout value of the LOCK taken on the server. If the client wants
  310. // to hold the LOCK beyond this timeout then it needs to refresh the LOCK
  311. // before the timeout expires.
  312. //
  313. ULONG LockTimeOutValueInSec;
  314. //
  315. // The system tick count when this LOCK entry was created. This value is
  316. // used in sending out LOCK refresh requests.
  317. //
  318. LARGE_INTEGER CreationTimeInTickCount;
  319. } WEBDAV_LOCK_TOKEN_ENTRY, *PWEBDAV_LOCK_TOKEN_ENTRY;
  320. //
  321. // The global list of all the active LOCK tokens (one for every LOCK taken) and
  322. // the resource that is used to synchronize access to it.
  323. //
  324. extern LIST_ENTRY LockTokenEntryList;
  325. extern ERESOURCE LockTokenEntryListLock;
  326. #define WEBDAV_LOCKCONFLICTENTRY_LIFETIMEINSEC 10
  327. //
  328. // For every LOCK request that fails, we create an entry below and add it to
  329. // the global LockConflictEntryList.
  330. //
  331. typedef struct _WEBDAV_LOCK_CONFLICT_ENTRY {
  332. LIST_ENTRY listEntry;
  333. //
  334. // The complete path name of the file that has already been locked on the
  335. // server.
  336. //
  337. PWCHAR CompletePathName;
  338. //
  339. // The owner of the LOCK on the file as returned by the server.
  340. //
  341. PWCHAR LockOwner;
  342. //
  343. // The system tick count when this entry was created. This entry is kept
  344. // alive for WEBDAV_LOCKCONFLICTENTRY_LIFETIMEINSEC seconds.
  345. //
  346. LARGE_INTEGER CreationTimeInTickCount;
  347. } WEBDAV_LOCK_CONFLICT_ENTRY, *PWEBDAV_LOCK_CONFLICT_ENTRY;
  348. //
  349. // The global list of all the LOCK conflict entries and the resource that is
  350. // used to synchronize access to it.
  351. //
  352. extern LIST_ENTRY LockConflictEntryList;
  353. extern ERESOURCE LockConflictEntryListLock;
  354. //
  355. // The WEBDAV specific FOBX structure.
  356. //
  357. typedef struct _WEBDAV_FOBX {
  358. //
  359. // The pointer to the DavFileAttribute list for this directory. This list
  360. // is created on the first call to Enumerate files in the directory.
  361. //
  362. PDAV_FILE_ATTRIBUTES DavFileAttributes;
  363. //
  364. // Number of DavFileAttribute entries.
  365. //
  366. ULONG NumOfFileEntries;
  367. //
  368. // The index of the next file to be returned to the user. The file index
  369. // starts from zero, hence file index = 0 => the first file entry etc.
  370. //
  371. ULONG CurrentFileIndex;
  372. //
  373. // Pointer to the next entry.
  374. //
  375. PLIST_ENTRY listEntry;
  376. } WEBDAV_FOBX, *PWEBDAV_FOBX;
  377. //
  378. // A pointer to an instance of WEBDAV_SRV_OPEN is stored in the context field
  379. // of MRX_SRV_OPEN strucutre.
  380. //
  381. #define MRxDAVGetFobxExtension(pFobx) \
  382. (((pFobx) == NULL) ? NULL : (PWEBDAV_FOBX)((pFobx)->Context))
  383. //
  384. // The WEBDAV specific SRV_OPEN structure.
  385. //
  386. typedef struct _WEBDAV_SRV_OPEN {
  387. //
  388. // The file handle associated with this SrvOpen.
  389. //
  390. HANDLE UnderlyingHandle;
  391. //
  392. // This also is the handle got from the usermode. Its used for debugging
  393. // purposes.
  394. //
  395. PVOID UserModeKey;
  396. //
  397. // Pointer to the file object associated with the handle. This is set
  398. // after the handle is successfully created in the usermode.
  399. //
  400. PFILE_OBJECT UnderlyingFileObject;
  401. //
  402. // Pointer to the device object represented by the file object mentioned
  403. // above.
  404. //
  405. PDEVICE_OBJECT UnderlyingDeviceObject;
  406. //
  407. // This indicates whether we need to call IoRaiseInformationalHardError
  408. // when the close fails. We need to do this if the PUT or DELETE failed and
  409. // the operation which the user expects has succeeded actually failed.
  410. //
  411. BOOL RaiseHardErrorIfCloseFails;
  412. //
  413. // Created In Kernel.
  414. //
  415. BOOL createdInKernel;
  416. //
  417. // The OpaqueLockToken returned by the server if the file was LOCKed on
  418. // Create. This token has to be sent with every request that modifies the
  419. // data or the properties of this file.
  420. //
  421. PWCHAR OpaqueLockToken;
  422. //
  423. // The LockTokenEntry created for the OpaqueLockToken above.
  424. //
  425. PWEBDAV_LOCK_TOKEN_ENTRY LockTokenEntry;
  426. } WEBDAV_SRV_OPEN, *PWEBDAV_SRV_OPEN;
  427. //
  428. // A pointer to an instance of WEBDAV_SRV_OPEN is stored in the context field
  429. // of MRX_SRV_OPEN strucutre.
  430. //
  431. #define MRxDAVGetSrvOpenExtension(pSrvOpen) \
  432. (((pSrvOpen) == NULL) ? NULL : (PWEBDAV_SRV_OPEN)((pSrvOpen)->Context))
  433. //
  434. // The WEBDAV specific FCB structure.
  435. //
  436. typedef struct _WEBDAV_FCB {
  437. //
  438. // Is this FCB for a directory ?
  439. //
  440. BOOL isDirectory;
  441. //
  442. // Does the File exist in the WinInet cache ??
  443. //
  444. BOOL isFileCached;
  445. //
  446. // Should this file be deleted on Close ?
  447. //
  448. BOOL DeleteOnClose;
  449. //
  450. // Was this file written to ?
  451. //
  452. ULONG FileWasModified;
  453. //
  454. // Did we reset the FileWasModified in the DavFcb to FALSE? If we did and
  455. // the PUT failed, we need to reset the FileWasModified field in the FCB to
  456. // TRUE.
  457. //
  458. BOOL FileModifiedBitReset;
  459. //
  460. // If we happen to LOCK the file on the server on Create we set this to
  461. // TRUE. On CloseSrvOpen we check if this value is TRUE. If it is and the
  462. // file has been modified, we only go to the usermode to do the PUT, DELETE,
  463. // PROPPATCH etc, if the SrvOpen contains the OpaqueLockToken. If it does
  464. // not then any request that modifies the file is going to fail with a
  465. // 423.
  466. //
  467. BOOL FileIsLockedOnTheServer;
  468. //
  469. // On Close, if the file has been modified, we PROPPATCH the time values
  470. // as well. We take the current time as the value of the "Last Modified Time"
  471. // (LMT). If the SetFileInformation of the LMT happens after the file has
  472. // been modifed, then we should use what ever LMT is already in the FCB as
  473. // the LMT. For example,
  474. // Create, Write, Close - Use the CurrentTime in close as the LMT.
  475. // Create, Write, SetFileInfo(LMT), Close - Use the LMT in the FCB.
  476. //
  477. BOOL DoNotTakeTheCurrentTimeAsLMT;
  478. //
  479. // This resource is used to synchronize the "Read-Modify-Write" routine
  480. // in the Write path of the DAV Redir. This is because when we get non-cached
  481. // writes to the MiniRedir which do not extend the VaildDataLength, RDBSS,
  482. // acquires the FCB resource shared. This means that multiple threads could
  483. // be writing data to the local file (in the DAV Redir case) in which case
  484. // they can overwrite each others changes since we do Read-Modify-Write.
  485. // Hence we need to protect this code using a resource which we acqiure
  486. // in an exclusive fashion when we do these writes. We allocate memory for
  487. // this resource and initialize it the first time we need to acquire the
  488. // lock. If allocated and initialized, it will be uninitialized and
  489. // deallocated when the FCB is being deallocated.
  490. //
  491. PERESOURCE DavReadModifyWriteLock;
  492. //
  493. // We store the file name information on create. This is used if the delayed
  494. // write failed to pop up the dialogue box and write an eventlog entry.
  495. //
  496. UNICODE_STRING FileNameInfo;
  497. BOOL FileNameInfoAllocated;
  498. //
  499. // Changes in directory entry.
  500. //
  501. BOOLEAN fCreationTimeChanged;
  502. BOOLEAN fLastAccessTimeChanged;
  503. BOOLEAN fLastModifiedTimeChanged;
  504. BOOLEAN fFileAttributesChanged;
  505. //
  506. // Was this file renamed ?
  507. //
  508. BOOL FileWasRenamed;
  509. BOOL LocalFileIsEncrypted;
  510. SECURITY_CLIENT_CONTEXT SecurityClientContext;
  511. //
  512. // If the file gets renamed, the new name is copied into this buffer.
  513. //
  514. WCHAR NewFileName[MAX_PATH];
  515. //
  516. // Length of the new file name.
  517. //
  518. ULONG NewFileNameLength;
  519. //
  520. // The file name of the local file that represents the file on the DAV
  521. // server which has been created.
  522. //
  523. WCHAR FileName[MAX_PATH];
  524. WCHAR Url[MAX_PATH * 2];
  525. } WEBDAV_FCB, *PWEBDAV_FCB;
  526. //
  527. // A pointer to an instance of WEBDAV_FCB is stored in the context field
  528. // of MRX_FCB strucutre.
  529. //
  530. #define MRxDAVGetFcbExtension(pFcb) \
  531. (((pFcb) == NULL) ? NULL : (PWEBDAV_FCB)((pFcb)->Context))
  532. //
  533. // The WEBDAV specific V_NET_ROOT structure.
  534. //
  535. typedef struct _WEBDAV_V_NET_ROOT {
  536. //
  537. // The client's security context. This is set during the create call.
  538. //
  539. SECURITY_CLIENT_CONTEXT SecurityClientContext;
  540. //
  541. // Is set to true after the above context is set. This is used to avoid
  542. // initialization of the SecurityContext.
  543. //
  544. BOOLEAN SCAlreadyInitialized;
  545. //
  546. // Has the LogonID of this V_NET_ROOT been set ?
  547. //
  548. BOOL LogonIDSet;
  549. //
  550. // The LogonID for this session.
  551. //
  552. LUID LogonID;
  553. //
  554. // Is this an Office Web Server share?
  555. //
  556. BOOL isOfficeShare;
  557. //
  558. // Is this a TAHOE share?
  559. //
  560. BOOL isTahoeShare;
  561. //
  562. // Is PROPATCH method allowed?
  563. //
  564. BOOL fAllowsProppatch;
  565. //
  566. // Was this VNetRoot "NOT" created successfully in the usermode? We keep this
  567. // info because when a finalize VNetRoot request comes, we need to know
  568. // whether need to go upto the usermode to finalize the PerUserEntry. If the
  569. // create failed then this BOOL is set to TRUE. If this is TRUE, then we
  570. // don't go to the usermode to finalize the PerUserEntry.
  571. //
  572. BOOL createVNetRootUnSuccessful;
  573. // does he report available space?
  574. BOOL fReportsAvailableSpace;
  575. } WEBDAV_V_NET_ROOT, *PWEBDAV_V_NET_ROOT;
  576. //
  577. // The WEBDAV specific V_NET_ROOT structure.
  578. //
  579. typedef struct _WEBDAV_NET_ROOT {
  580. ULONG RefCount;
  581. PMRX_NET_ROOT pRdbssNetRoot; // The Rdbss NetRoot it belongs to
  582. NAME_CACHE_CONTROL NameCacheCtlGFABasic; // The basic file information name cache control.
  583. NAME_CACHE_CONTROL NameCacheCtlGFAStandard; // The standard file information name cache control.
  584. NAME_CACHE_CONTROL NameCacheCtlFNF; // The File not found name cache control.
  585. } WEBDAV_NET_ROOT, *PWEBDAV_NET_ROOT;
  586. //
  587. // A pointer to an instance of WEBDAV_V_NET_ROOT is stored in the context field
  588. // of MRX_V_NET_ROOT strucutre.
  589. //
  590. #define MRxDAVGetVNetRootExtension(pVNetRoot) \
  591. (((pVNetRoot) == NULL) ? NULL : (PWEBDAV_V_NET_ROOT)((pVNetRoot)->Context))
  592. //
  593. // The WEBDAV specific V_NET_ROOT structure.
  594. //
  595. typedef struct _WEBDAV_SRV_CALL {
  596. //
  597. // The Unique ServerID.
  598. //
  599. ULONG ServerID;
  600. //
  601. // Is set to true after the above context is set. Used to check whether we
  602. // need to delete the SecurityClientContext when we are completing the
  603. // request.
  604. //
  605. BOOLEAN SCAlreadyInitialized;
  606. } WEBDAV_SRV_CALL, *PWEBDAV_SRV_CALL;
  607. //
  608. // A pointer to an instance of WEBDAV_SRV_CALL is stored in the context field
  609. // of MRX_SRV_CALL strucutre.
  610. //
  611. #define MRxDAVGetSrvCallExtension(pSrvCall) \
  612. (((pSrvCall) == NULL) ? NULL : (PWEBDAV_SRV_CALL)((pSrvCall)->Context))
  613. //
  614. // Get the Security client context associated with this request.
  615. //
  616. #define MRxDAVGetSecurityClientContext() { \
  617. if (RxContext != NULL && RxContext->pRelevantSrvOpen != NULL) { \
  618. if (RxContext->pRelevantSrvOpen->pVNetRoot != NULL) { \
  619. if (RxContext->pRelevantSrvOpen->pVNetRoot->Context != NULL) { \
  620. DavVNetRoot = (PWEBDAV_V_NET_ROOT) \
  621. RxContext->pRelevantSrvOpen->pVNetRoot->Context; \
  622. SecurityClientContext = &(DavVNetRoot->SecurityClientContext); \
  623. } \
  624. } \
  625. } \
  626. }
  627. //
  628. // We turn away async operations that are not wait by posting. If we can wait
  629. // then we turn off the sync flag so that things will just act synchronous.
  630. //
  631. #define TURN_BACK_ASYNCHRONOUS_OPERATIONS() { \
  632. if (FlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION)) { \
  633. if (FlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT)) { \
  634. ClearFlag(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION) \
  635. } else { \
  636. RxContext->PostRequest = TRUE; \
  637. return STATUS_PENDING; \
  638. } \
  639. } \
  640. }
  641. //
  642. // Global locking variables and macros.
  643. //
  644. extern RX_SPIN_LOCK MRxDAVGlobalSpinLock;
  645. extern KIRQL MRxDAVGlobalSpinLockSavedIrql;
  646. extern BOOLEAN MRxDAVGlobalSpinLockAcquired;
  647. #define MRxDAVAcquireGlobalSpinLock() \
  648. KeAcquireSpinLock(&MRxDAVGlobalSpinLock,&MRxDAVGlobalSpinLockSavedIrql); \
  649. MRxDAVGlobalSpinLockAcquired = TRUE
  650. #define MRxDAVReleaseGlobalSpinLock() \
  651. MRxDAVGlobalSpinLockAcquired = FALSE; \
  652. KeReleaseSpinLock(&MRxDAVGlobalSpinLock,MRxDAVGlobalSpinLockSavedIrql)
  653. #define MRxDAVGlobalSpinLockAcquired() \
  654. (MRxDAVGlobalSpinLockAcquired == TRUE)
  655. //
  656. // The IrpCompletionContext structure that is used in the read/write operations.
  657. // All we need is an event on which we will wait till the underlying file system
  658. // completes the request. This event gets signalled in the Completion routine
  659. // that we specify.
  660. //
  661. typedef struct _WEBDAV_READ_WRITE_IRP_COMPLETION_CONTEXT {
  662. //
  663. // The event which is signalled in the Completion routine that is passed
  664. // to IoCallDriver in the read and write requests.
  665. //
  666. KEVENT DavReadWriteEvent;
  667. } WEBDAV_READ_WRITE_IRP_COMPLETION_CONTEXT, *PWEBDAV_READ_WRITE_IRP_COMPLETION_CONTEXT;
  668. //
  669. // The prototypes of functions defined for various I/O requests by the DAV
  670. // miniredir are mentioned below.
  671. //
  672. //
  673. // Create/Open/Cleanup/Close Request function prototypes.
  674. //
  675. NTSTATUS
  676. MRxDAVCreate(
  677. IN PRX_CONTEXT RxContext
  678. );
  679. NTSTATUS
  680. MRxDAVCleanupFobx (
  681. IN OUT PRX_CONTEXT RxContext
  682. );
  683. NTSTATUS
  684. MRxDAVCloseSrvOpen (
  685. IN OUT PRX_CONTEXT RxContext
  686. );
  687. NTSTATUS
  688. MRxDAVCollapseOpen (
  689. IN OUT PRX_CONTEXT RxContext
  690. );
  691. NTSTATUS
  692. MRxDAVComputeNewBufferingState(
  693. IN OUT PMRX_SRV_OPEN pSrvOpen,
  694. IN PVOID pMRxContext,
  695. OUT ULONG *pNewBufferingState
  696. );
  697. NTSTATUS
  698. MRxDAVForcedClose (
  699. IN OUT PMRX_SRV_OPEN SrvOpen
  700. );
  701. NTSTATUS
  702. MRxDAVShouldTryToCollapseThisOpen (
  703. IN PRX_CONTEXT RxContext
  704. );
  705. NTSTATUS
  706. MRxDAVTruncate (
  707. IN OUT PRX_CONTEXT RxContext
  708. );
  709. VOID
  710. MRxDAVSetLoud(
  711. IN PBYTE Msg,
  712. IN PRX_CONTEXT RxContext,
  713. IN PUNICODE_STRING s
  714. );
  715. NTSTATUS
  716. MRxDAVFlush (
  717. IN OUT PRX_CONTEXT RxContext
  718. );
  719. //
  720. // Read prototypes.
  721. //
  722. NTSTATUS
  723. MRxDAVRead (
  724. IN OUT PRX_CONTEXT RxContext
  725. );
  726. //
  727. // Write prototypes.
  728. //
  729. NTSTATUS
  730. MRxDAVWrite(
  731. IN PRX_CONTEXT RxContext
  732. );
  733. ULONG
  734. MRxDAVExtendForCache(
  735. IN OUT PRX_CONTEXT RxContext,
  736. IN OUT PLARGE_INTEGER NewFileSize,
  737. OUT PLARGE_INTEGER NewAllocationSize
  738. );
  739. ULONG
  740. MRxDAVExtendForNonCache(
  741. IN OUT PRX_CONTEXT RxContext,
  742. IN OUT PLARGE_INTEGER NewFileSize,
  743. OUT PLARGE_INTEGER NewAllocationSize
  744. );
  745. //
  746. // SrvCall function prototypes.
  747. //
  748. NTSTATUS
  749. MRxDAVCreateSrvCall(
  750. PMRX_SRV_CALL pSrvCall,
  751. PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext
  752. );
  753. NTSTATUS
  754. MRxDAVFinalizeSrvCall(
  755. PMRX_SRV_CALL pSrvCall,
  756. BOOLEAN Force
  757. );
  758. NTSTATUS
  759. MRxDAVSrvCallWinnerNotify(
  760. IN PMRX_SRV_CALL pSrvCall,
  761. IN BOOLEAN ThisMinirdrIsTheWinner,
  762. IN OUT PVOID pSrvCallContext
  763. );
  764. //
  765. // NetRoot/VNetRoot function prototypes.
  766. //
  767. NTSTATUS
  768. MRxDAVUpdateNetRootState(
  769. IN OUT PMRX_NET_ROOT pNetRoot
  770. );
  771. NTSTATUS
  772. MRxDAVCreateVNetRoot(
  773. IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext
  774. );
  775. NTSTATUS
  776. MRxDAVFinalizeVNetRoot(
  777. IN PMRX_V_NET_ROOT pVNetRoot,
  778. IN PBOOLEAN ForceDisconnect
  779. );
  780. NTSTATUS
  781. MRxDAVFinalizeNetRoot(
  782. IN PMRX_NET_ROOT pNetRoot,
  783. IN PBOOLEAN ForceDisconnect
  784. );
  785. VOID
  786. MRxDAVExtractNetRootName(
  787. IN PUNICODE_STRING FilePathName,
  788. IN PMRX_SRV_CALL SrvCall,
  789. OUT PUNICODE_STRING NetRootName,
  790. OUT PUNICODE_STRING RestOfName OPTIONAL
  791. );
  792. //
  793. // Query Directory prototypes.
  794. //
  795. NTSTATUS
  796. MRxDAVQueryDirectory(
  797. IN PRX_CONTEXT RxContext
  798. );
  799. //
  800. // Query volume.
  801. //
  802. NTSTATUS
  803. MRxDAVQueryVolumeInformation(
  804. IN PRX_CONTEXT RxContext
  805. );
  806. //
  807. // File Information.
  808. //
  809. NTSTATUS
  810. MRxDAVQueryFileInformation(
  811. IN PRX_CONTEXT RxContext
  812. );
  813. NTSTATUS
  814. MRxDAVSetFileInformation(
  815. IN PRX_CONTEXT RxContext
  816. );
  817. //
  818. // DevFcb prototypes.
  819. //
  820. NTSTATUS
  821. MRxDAVDevFcbXXXControlFile (
  822. IN OUT PRX_CONTEXT RxContext
  823. );
  824. NTSTATUS
  825. MRxDAVStart (
  826. IN OUT struct _RX_CONTEXT * RxContext,
  827. IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject
  828. );
  829. NTSTATUS
  830. MRxDAVStop (
  831. IN OUT struct _RX_CONTEXT * RxContext,
  832. IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject
  833. );
  834. BOOLEAN
  835. MRxDAVFastIoDeviceControl (
  836. IN struct _FILE_OBJECT *FileObject,
  837. IN BOOLEAN Wait,
  838. IN PVOID InputBuffer OPTIONAL,
  839. IN ULONG InputBufferLength,
  840. OUT PVOID OutputBuffer OPTIONAL,
  841. IN ULONG OutputBufferLength,
  842. IN ULONG IoControlCode,
  843. OUT PIO_STATUS_BLOCK IoStatus,
  844. IN struct _DEVICE_OBJECT *DeviceObject
  845. );
  846. BOOLEAN
  847. MRxDAVFastIoRead(
  848. IN PFILE_OBJECT FileObject,
  849. IN PLARGE_INTEGER FileOffset,
  850. IN ULONG Length,
  851. IN BOOLEAN Wait,
  852. IN ULONG LockKey,
  853. OUT PVOID Buffer,
  854. OUT PIO_STATUS_BLOCK IoStatus,
  855. IN PDEVICE_OBJECT DeviceObject
  856. );
  857. BOOLEAN
  858. MRxDAVFastIoWrite(
  859. IN PFILE_OBJECT FileObject,
  860. IN PLARGE_INTEGER FileOffset,
  861. IN ULONG Length,
  862. IN BOOLEAN Wait,
  863. IN ULONG LockKey,
  864. OUT PVOID Buffer,
  865. OUT PIO_STATUS_BLOCK IoStatus,
  866. IN PDEVICE_OBJECT DeviceObject
  867. );
  868. //
  869. // Other Misc prototypes.
  870. //
  871. NTSTATUS
  872. MRxDAVSyncXxxInformation(
  873. IN OUT PRX_CONTEXT RxContext,
  874. IN UCHAR MajorFunction,
  875. IN PFILE_OBJECT FileObject,
  876. IN ULONG InformationClass,
  877. IN ULONG Length,
  878. OUT PVOID Information,
  879. OUT PULONG_PTR ReturnedLength OPTIONAL
  880. );
  881. NTSTATUS
  882. MRxDAVDeallocateForFcb (
  883. IN OUT PMRX_FCB pFcb
  884. );
  885. NTSTATUS
  886. MRxDAVDeallocateForFobx (
  887. IN OUT PMRX_FOBX pFobx
  888. );
  889. //
  890. // The prototype of the routine that formats the DAV specific portion of the
  891. // context.
  892. //
  893. NTSTATUS
  894. MRxDAVFormatTheDAVContext(
  895. PUMRX_ASYNCENGINE_CONTEXT AsyncEngineContext,
  896. USHORT EntryPoint
  897. );
  898. NTSTATUS
  899. DavXxxInformation(
  900. IN const int xMajorFunction,
  901. IN PFILE_OBJECT FileObject,
  902. IN ULONG InformationClass,
  903. IN ULONG Length,
  904. OUT PVOID Information,
  905. OUT PULONG ReturnedLength
  906. );
  907. ULONG
  908. DavReadWriteFileEx(
  909. IN USHORT Operation,
  910. IN BOOL NonPagedBuffer,
  911. IN BOOL UseOriginalIrpsMDL,
  912. IN PMDL OriginalIrpsMdl,
  913. IN PDEVICE_OBJECT DeviceObject,
  914. IN PFILE_OBJECT FileObject,
  915. IN ULONGLONG FileOffset,
  916. IN OUT PVOID DataBuffer,
  917. IN ULONG SizeInBytes,
  918. OUT PIO_STATUS_BLOCK IoStatusBlock
  919. );
  920. NTSTATUS
  921. DavReadWriteIrpCompletionRoutine(
  922. IN PDEVICE_OBJECT DeviceObject,
  923. IN PIRP CalldownIrp,
  924. IN PVOID Context
  925. );
  926. NTSTATUS
  927. MRxDAVProbeForReadWrite(
  928. IN PBYTE BufferToBeValidated,
  929. IN DWORD BufferSize,
  930. IN BOOL doProbeForRead,
  931. IN BOOL doProbeForWrite
  932. );
  933. NTSTATUS
  934. MRxDAVFsCtl(
  935. IN OUT PRX_CONTEXT RxContext
  936. );
  937. NTSTATUS
  938. MRxDAVIsValidDirectory(
  939. IN OUT PRX_CONTEXT RxContext,
  940. IN PUNICODE_STRING DirectoryName
  941. );
  942. NTSTATUS
  943. MRxDAVCancelRoutine(
  944. PRX_CONTEXT RxContext
  945. );
  946. VOID
  947. MRxDAVTimeOutTheContexts(
  948. BOOL WindDownAllContexts
  949. );
  950. VOID
  951. MRxDAVContextTimerThread(
  952. PVOID DummyContext
  953. );
  954. NTSTATUS
  955. MRxDAVQueryEaInformation (
  956. IN OUT PRX_CONTEXT RxContext
  957. );
  958. NTSTATUS
  959. MRxDAVSetEaInformation (
  960. IN OUT PRX_CONTEXT RxContext
  961. );
  962. NTSTATUS
  963. MRxDAVGetFullParentDirectoryPath(
  964. PRX_CONTEXT RxContext,
  965. PUNICODE_STRING ParentDirName
  966. );
  967. NTSTATUS
  968. MRxDAVGetFullDirectoryPath(
  969. PRX_CONTEXT RxContext,
  970. PUNICODE_STRING FileName,
  971. PUNICODE_STRING DirName
  972. );
  973. NTSTATUS
  974. MRxDAVCreateEncryptedDirectoryKey(
  975. PUNICODE_STRING DirName
  976. );
  977. NTSTATUS
  978. MRxDAVRemoveEncryptedDirectoryKey(
  979. PUNICODE_STRING DirName
  980. );
  981. NTSTATUS
  982. MRxDAVQueryEncryptedDirectoryKey(
  983. PUNICODE_STRING DirName
  984. );
  985. VOID
  986. MRxDAVCleanUpTheLockConflictList(
  987. BOOL CleanUpAllEntries
  988. );
  989. #endif //_WEBDAV_H