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.

456 lines
14 KiB

  1. /*++
  2. Copyright (c) 1989 - 1998 Microsoft Corporation
  3. Module Name:
  4. ifsuser.h
  5. Abstract:
  6. Ifsuser is a static lib that wraps a bunch of user-mode code
  7. needed for using the IFS. It is not necessary to use the APIs
  8. in this lib for availing the IFS functionality. However, using
  9. it will isolate clients from changes to IFS headers / data str.
  10. Applications that do not want to use NtXXX APIs should include
  11. this header file.
  12. Applications that directly use NtXXX APIs only need <exifs.h>
  13. Author:
  14. Rajeev Rajan [RajeevR] 7-Apr-1998
  15. Revision History:
  16. --*/
  17. #ifndef _IFSUSER_H_
  18. #define _IFSUSER_H_
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. #ifndef EXIFS_DEVICE_NAME
  23. #define EXIFS_DEVICE_NAME
  24. //////////////////////////////////////////////////////////////////////////////
  25. // The Devicename string required to access the exchange IFS device
  26. // from User-Mode. Clients should use DD_EXIFS_USERMODE_DEV_NAME_U.
  27. //////////////////////////////////////////////////////////////////////////////
  28. // Local store Device names
  29. #define DD_LSIFS_USERMODE_SHADOW_DEV_NAME_U L"\\??\\LocalStoreIfs"
  30. #define DD_LSIFS_USERMODE_DEV_NAME_U L"\\\\.\\LocalStoreIfs"
  31. //
  32. // WARNING The next two strings must be kept in sync. Change one and you must
  33. // change the other. These strings have been chosen such that they are
  34. // unlikely to coincide with names of other drivers.
  35. //
  36. // NOTE: These definitions MUST be synced with <exifs.h>
  37. //
  38. #define DD_EXIFS_USERMODE_SHADOW_DEV_NAME_U L"\\??\\ExchangeIfs"
  39. #define DD_EXIFS_USERMODE_DEV_NAME_U L"\\\\.\\ExchangeIfs"
  40. //
  41. // Prefix needed before <store-name>\<root-name>
  42. //
  43. #define DD_EXIFS_MINIRDR_PREFIX L"\\;E:"
  44. #endif // EXIFS_DEVICE_NAME
  45. //
  46. // Bit flags for PR_DOTSTUFF_STATE
  47. //
  48. // DOTSTUFF_STATE_HAS_BEEN_SCANNED - Has the content been scanned?
  49. // DOTSTUFF_STATE_NEEDS_STUFFING - If it has been scanned does
  50. // it need to be dot stuffed?
  51. #define DOTSTUFF_STATE_HAS_BEEN_SCANNED 0x1
  52. #define DOTSTUFF_STATE_NEEDS_STUFFING 0x2
  53. //////////////////////////////////////////////////////////////////////////////
  54. // LIST OF FUNCTIONS EXPORTED
  55. //
  56. // INBOUND =>
  57. // ==========
  58. // 1. IfsInitializeWrapper() :initializes a seed eg GUID for unique filenames.
  59. // 2. IfsTerminateWrapper() :cleanup if necessary.
  60. // *3. IfsCreateNewFileW() :given store prefix, return a HANDLE that can be
  61. // used for storing data in that store.
  62. // 4. IfsCacheInsertFile() :given an EA, insert filename in FH cache.
  63. // 4. IfsMarshallHandle() :given an IFS handle, will return context that
  64. // will aid in manifesting a new HANDLE in a
  65. // different process.
  66. // *5. IfsUnMarshallHandle() :given context from previous function, this will
  67. // manifest a new HANDLE in current process.
  68. //
  69. // OUTBOUND =>
  70. // ===========
  71. // *1. IfsCacheCreateFile() :given an EA, get a file handle from the FH cache.
  72. // if the file handle is not in FH cache, it will be
  73. // created and inserted in FH cache.
  74. // *2. IfsCreateFile() :given an EA, merely create a file handle -
  75. // no FH cache insert/search.
  76. // *3. IfsCreateFileRelative():given an EA, merely create a file handle -
  77. // no FH cache insert/search - relative open
  78. //
  79. // *NOTE: Functions with an asterisk next to them return file HANDLES.
  80. // It is expected that the caller will close these handles at an appropriate time !
  81. //
  82. //////////////////////////////////////////////////////////////////////////////
  83. //////////////////////////////////////////////////////////////////////////////
  84. // INBOUND functions
  85. //////////////////////////////////////////////////////////////////////////////
  86. //
  87. // This function sets up a seed GUID to aid generation of unique names !
  88. //
  89. BOOL __fastcall
  90. IfsInitializeWrapper();
  91. //
  92. // This function cleans up any state setup in Init()
  93. //
  94. VOID __fastcall
  95. IfsTerminateWrapper();
  96. //
  97. // Create a new IFS handle given a store prefix -
  98. // The handle is opened for read/write. Caller should close
  99. // handle after use. Closing the handle without committing the
  100. // bytes (via NtQueryEa) will cause the bytes to be reused by IFS.
  101. //
  102. // NB: A fully qualified IFS filename is of the form:
  103. // "\\??\\ExchangeIfs\\;E:\\<store-name>\\<root-name>\\<filename>"
  104. // Typically, <store-name> is a constant for the machine,
  105. // <root-name> is a function of a given MDB store and
  106. // <filename> is a specific message in the store
  107. //
  108. // This functions expects the StorePrefix to be <store-name>\\<root-name>.
  109. // The function will generate a unique <filename>
  110. //
  111. DWORD __fastcall
  112. IfsCreateNewFileW(
  113. IN LPWSTR StorePrefix,
  114. IN DWORD FlagsOverride,
  115. IN OUT PHANDLE phFile
  116. );
  117. #ifdef _USE_FHCACHE_
  118. //
  119. // Protocols should call this function to get an FIO_CONTEXT for
  120. // an inbound message. This replaces IfsCreateNewFileW() as the
  121. // preferred method of using the IFS/File Handle Cache.
  122. //
  123. FIO_CONTEXT*
  124. IfsCreateInboundMessageFile(
  125. IN LPWSTR StorePrefix,
  126. IN DWORD FlagsOverride,
  127. IN BOOL fScanForDots = TRUE
  128. );
  129. FIO_CONTEXT*
  130. IfsCreateInboundMessageFileEx(
  131. IN LPWSTR StorePrefix,
  132. IN DWORD FlagsOverride,
  133. IN BOOL fScanForDots = TRUE,
  134. IN BOOL fStoredWithTerminatingDot = FALSE
  135. );
  136. //
  137. // Given an FH cache FIO_CONTEXT and IFS EAs, insert file handle in
  138. // FH cache using filename !
  139. //
  140. BOOL
  141. IfsCacheInsertFile(
  142. IN FIO_CONTEXT* pContext,
  143. IN PVOID EaBuffer,
  144. IN DWORD EaLength,
  145. IN BOOL fKeepReference
  146. );
  147. //
  148. // Given an FH cache FIO_CONTEXT and IFS EAs, insert file handle in
  149. // FH cache using filename !
  150. // BINLIN - Caller of this function must ensure that EaBuffer has DotStuff state embedded!
  151. // This can be achieved by calling IfsMarshallStoreEA() and marshall the returned EA
  152. // buffer back to IIS, and use this EA buffer in IfsCacheInsertFileEx().
  153. //
  154. BOOL
  155. IfsCacheInsertFileEx(
  156. IN FIO_CONTEXT* pContext,
  157. IN LPWSTR StorePrefix,
  158. IN PVOID EaBuffer,
  159. IN DWORD EaLength,
  160. IN BOOL fKeepReference
  161. );
  162. BOOL IfsCacheWriteFile(
  163. IN PFIO_CONTEXT pfioContext,
  164. IN LPCVOID lpBuffer,
  165. IN DWORD BytesToWrite,
  166. IN FH_OVERLAPPED * lpo
  167. );
  168. BOOL IfsCacheReadFile(
  169. IN PFIO_CONTEXT pfioContext,
  170. IN LPCVOID lpBuffer,
  171. IN DWORD BytesToRead,
  172. IN FH_OVERLAPPED * lpo
  173. );
  174. DWORD IfsCacheGetFileSizeFromContext(
  175. IN FIO_CONTEXT* pContext,
  176. OUT DWORD* pcbFileSizeHigh
  177. );
  178. void IfsReleaseCacheContext( PFIO_CONTEXT pContext );
  179. #endif
  180. //
  181. // Given an IFS handle, return context to be used by IfsUnMarshallHandle()
  182. // in order to manifest a handle in another process !
  183. //
  184. // fUseEA should be used to decide whether marshalling is done via EAs
  185. // or DuplicateHandle(). This function expects a buffer and buffer size.
  186. // If the function return ERROR_SUCCESS, *pcbContext == size of data
  187. // If the function returns ERROR_MORE_DATA, *pcbContext == size
  188. // expected. Caller should allocate this size and make the request again !
  189. //
  190. DWORD
  191. IfsMarshallHandle(
  192. IN HANDLE hFile, // IFS file handle
  193. IN BOOL fUseEA, // If TRUE, use EA to marshall
  194. IN HANDLE hTargetProcess, // Handle to target process - optional
  195. IN OUT PVOID pbContext, // ptr to buffer for context
  196. IN OUT PDWORD pcbContext // IN - sizeof pbContext OUT - real size
  197. );
  198. #ifdef _USE_FHCACHE_
  199. //
  200. // This replaces IfsMarshallHandle() as the preferred way of marhalling
  201. // handles. The FIO_CONTEXT contains the IFS handle.
  202. //
  203. DWORD
  204. IfsMarshallHandleEx(
  205. IN FIO_CONTEXT* pContext, // FH cache FIO_CONTEXT
  206. IN BOOL fUseEA, // If TRUE, use EA to marshall
  207. IN HANDLE hTargetProcess, // Handle to target process - optional
  208. IN OUT PVOID pbContext, // ptr to buffer for context
  209. IN OUT PDWORD pcbContext // IN - sizeof pbContext OUT - real size
  210. );
  211. #endif
  212. //
  213. // Give a context from IfsMarshallHandle(), return a handle usable in
  214. // current process !
  215. //
  216. // Called in Store process only !
  217. // The HANDLE this returns will refer to an EA that has the DOT Stuff State embedded !
  218. //
  219. DWORD
  220. IfsUnMarshallHandle(
  221. IN LPWSTR StorePrefix,
  222. IN PVOID pbContext,
  223. IN DWORD cbContext,
  224. IN OUT PHANDLE phFile,
  225. OUT PULONG pulDotStuffState = NULL
  226. );
  227. //////////////////////////////////////////////////////////////////////////////
  228. // OUTBOUND functions
  229. //////////////////////////////////////////////////////////////////////////////
  230. #ifdef _USE_FHCACHE_
  231. //
  232. // Given an opaque EaBuffer and EaLength, return an FIO_CONTEXT from the
  233. // File Handle Cache. Typically, used on outbound.
  234. //
  235. FIO_CONTEXT*
  236. IfsCacheCreateFile(
  237. IN LPWSTR StorePrefix,
  238. IN PVOID EaBuffer,
  239. IN DWORD EaLength,
  240. IN BOOL fAsyncContext
  241. );
  242. //
  243. // Given an opaque EaBuffer and EaLength, return an FIO_CONTEXT from the
  244. // File Handle Cache. Typically, used on outbound.
  245. // This replaces IfsCacheCreateFile() as the preferred way to do outbound.
  246. // BINLIN - Caller of this function must ensure that EaBuffer has DotStuff state embedded.
  247. // This can be achieved by calling IfsMarshallStoreEA() and marshall the returned EA
  248. // buffer back to IIS, and use this EA buffer in IfsCacheInsertFileEx().
  249. //
  250. FIO_CONTEXT*
  251. IfsCacheCreateFileEx(
  252. IN LPWSTR StorePrefix,
  253. IN PVOID EaBuffer,
  254. IN DWORD EaLength,
  255. IN BOOL fAsyncContext,
  256. IN BOOL fWantItStuffed
  257. );
  258. #endif
  259. //
  260. // Create an IFS handle given an EaBuffer and EaLength -
  261. // The handle is opened for read-only. EaBuffer can be freed
  262. // after this call. Caller should close handle after use.
  263. //
  264. // NB: EaBuffer should have been obtained from a "trusted source"
  265. // ie. ESE or IFS.
  266. //
  267. DWORD
  268. IfsCreateFileRelative(
  269. IN HANDLE hRoot,
  270. IN PVOID EaBuffer,
  271. IN DWORD EaLength,
  272. IN OUT PHANDLE phFile
  273. );
  274. //
  275. // Create an IFS handle given an EaBuffer and EaLength -
  276. // The handle is opened for read-only. EaBuffer can be freed
  277. // after this call. Caller should close handle after use.
  278. //
  279. // NB: EaBuffer should have been obtained from a "trusted source"
  280. // ie. ESE or IFS.
  281. //
  282. DWORD
  283. IfsCreateFile(
  284. IN LPWSTR StorePrefix,
  285. IN PVOID EaBuffer,
  286. IN DWORD EaLength,
  287. IN OUT PHANDLE phFile
  288. );
  289. DWORD
  290. IfsCreateFileEx(
  291. IN LPWSTR StorePrefix,
  292. IN PVOID EaBuffer,
  293. IN DWORD EaLength,
  294. IN OUT PHANDLE phFile,
  295. IN BOOL fUniqueFileName,
  296. IN DWORD desiredAccess
  297. );
  298. DWORD
  299. IfsCreateFileEx2(
  300. IN LPWSTR StorePrefix,
  301. IN PVOID EaBuffer,
  302. IN DWORD EaLength,
  303. IN OUT PHANDLE phFile,
  304. IN BOOL fUniqueFileName,
  305. IN DWORD desiredAccess,
  306. IN DWORD shareAccess,
  307. IN DWORD createDisposition // see NT DDK
  308. );
  309. #ifdef _USE_FHCACHE_
  310. //
  311. // BINLIN - This function embeds the DotStuff state property into the real EA and
  312. // return the ptr to the new EA buffer. Used only during outbound and before marshalling
  313. // EA back to IIS for TransmitFile(), normally in the Store process.
  314. // Here is the call sequence:
  315. // 1) IIS request outbound message from Store
  316. // 2) Store driver calls EcGetProp() on PR_DOTSTUFF_STATE to get DotStuff state property
  317. // 3) Store driver calls EcGetFileHandleProp() to get real EA.
  318. // 4) IF EA is returned, Store driver calls IfsMarshallStoreEA() and obtain a new EA buffer
  319. // in pbMarshallEA, and marshall that to IIS.
  320. // 5) IF HANDLE is returned, Store driver may call IfsMarshallHandle() to obtain EA.
  321. // It then MUST CALL IfsMarshallStoreEA() to obtain new EA buffer pbMarshallEA.
  322. // In general, if EA is obtained from Store or through IfsMarshallHandle(), the returned
  323. // EA is not marshall-able until Store driver calls this function with DotStuff state to
  324. // obtain a new EA buffer. Only marshall this new EA buffer to IIS, not the EA returned from Store!!!
  325. //
  326. // General rule of marshalling EA with DotStuff state - EA buffer marshall back and forth
  327. // between IIS/Store always contain DotStuff state!
  328. //
  329. // NOTE:
  330. // 1) Passing in 0 (or use default) for DotStuff state if one doesn't exist/available.
  331. // 2) Caller must allocate memory for pbMarshallEA, and must be at least *pcbEA+sizeof(ulDotStuffState).
  332. // 3) It's ok to pass in same buffer ptr for pbStoreEA and pbMarshallEA, as long as 2) is true.
  333. //
  334. DWORD
  335. IfsMarshallStoreEA(
  336. IN PVOID pbStoreEA, // ptr to buffer for EA returned from Store
  337. IN OUT PDWORD pcbEA, // IN - sizeof pbStoreEA OUT - sizeof pbMarshallEA
  338. OUT PVOID pbMarshallEA, // ptr to buffer for new EA ready for marshall
  339. IN ULONG ulDotStuffState = 0 // Dotstuff state combined into pbMarshallEA with pbStoreEA
  340. );
  341. #endif
  342. //////////////////////////////////////////////////////////////////////////////
  343. // UTILITY functions - not meant to be used by clients of ifsuser.lib
  344. //////////////////////////////////////////////////////////////////////////////
  345. //
  346. // Get filename from handle
  347. //
  348. DWORD
  349. IfsGetFilenameFromHandle(
  350. IN HANDLE hFile,
  351. IN OUT LPSTR lpstrFilename
  352. );
  353. //
  354. // Get filename from EA
  355. //
  356. VOID
  357. IfsGetFilenameFromEaW(
  358. IN PVOID EaBuffer,
  359. IN OUT LPWSTR* ppwstrFilename
  360. );
  361. //
  362. // Open a file with no EA
  363. //
  364. DWORD
  365. IfsOpenFileNoEa(
  366. IN LPWSTR lpwstrName,
  367. IN OUT PHANDLE phFile
  368. );
  369. #ifdef NT_INCLUDED
  370. //
  371. // This is the function used by the I/O manager to check EA buffer
  372. // validity. This can be used to debug EA_LIST_INCONSISTENT errors.
  373. //
  374. DWORD
  375. CheckEaBufferValidity(
  376. IN PFILE_FULL_EA_INFORMATION EaBuffer,
  377. IN ULONG EaLength,
  378. OUT PULONG ErrorOffset
  379. );
  380. #endif
  381. #ifdef __cplusplus
  382. }
  383. #endif
  384. #endif // _IFSUSER_H_