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.

780 lines
32 KiB

  1. //
  2. // MODULE: MSITStg.h
  3. //
  4. // PURPOSE: Interface declaration for IMSITStorage
  5. //
  6. // COMPANY: This file was created by Microsoft and should not be changed by Saltmine
  7. // except for comments
  8. //
  9. // ORIGINAL DATE: unknown.
  10. //
  11. // NOTES:
  12. //
  13. // Version Date By Comments
  14. //--------------------------------------------------------------------
  15. // V3.1 01-18-99 JM This header added.
  16. //
  17. // MSITStg.h -- Interface declaration for IMSITStorage
  18. #ifndef __MSITSTG_H__
  19. #define __MSITSTG_H__
  20. // Class ID for the ITSS File System:
  21. DEFINE_GUID(CLSID_ITStorage,
  22. 0x5d02926a, 0x212e, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  23. // Inteface ID for the IITStorage interface:
  24. DEFINE_GUID(IID_ITStorage,
  25. 0x88cc31de, 0x27ab, 0x11d0, 0x9d, 0xf9, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  26. // Interface ID for the IITStorageEx interface:
  27. DEFINE_GUID(IID_ITStorageEx,
  28. 0xe74097b0, 0x292d, 0x11d1, 0xb6, 0x7e, 0x0, 0x0, 0xf8, 0x1, 0x49, 0xf6);
  29. // Class ID for the FSStorage wrapper for the Win32 file system:
  30. // {D54EEE56-AAAB-11d0-9E1D-00A0C922E6EC}
  31. DEFINE_GUID(CLSID_IFSStorage,
  32. 0xd54eee56, 0xaaab, 0x11d0, 0x9e, 0x1d, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  33. // Interface ID for the IFSStorage interface:
  34. // {8BB2438A-A70C-11d0-9E1C-00A0C922E6EC}
  35. DEFINE_GUID(IID_IFSStorage,
  36. 0x8bb2438a, 0xa70c, 0x11d0, 0x9e, 0x1c, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  37. // Interface ID for the extended IStream interface
  38. DEFINE_GUID(IID_IStreamITEx,
  39. 0xeb19b681, 0x9360, 0x11d0, 0x9e, 0x16, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  40. // Interface ID for the extended IStorage interface
  41. DEFINE_GUID(IID_IStorageITEx,
  42. 0xeb19b680, 0x9360, 0x11d0, 0x9e, 0x16, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  43. // Interface IDs for the Data Space Manager used within an ITStorage object:
  44. DEFINE_GUID(IID_IDataSpaceManager,
  45. 0x7c01fd0f, 0x7baa, 0x11d0, 0x9e, 0xc, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  46. DEFINE_GUID(IID_IDataSpace,
  47. 0x7c01fd0e, 0x7baa, 0x11d0, 0x9e, 0xc, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  48. DEFINE_GUID(IID_ITransformServices,
  49. 0xa55895fc, 0x89e1, 0x11d0, 0x9e, 0x14, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  50. DEFINE_GUID(IID_IKeyInstance,
  51. 0x96af35ce, 0x88ec, 0x11d0, 0x9e, 0x14, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  52. // Interface IDs for the plug-in data transforms:
  53. DEFINE_GUID(IID_ITransformFactory,
  54. 0x7c01fd0c, 0x7baa, 0x11d0, 0x9e, 0xc, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  55. DEFINE_GUID(IID_ITransformInstance,
  56. 0xeb19b67e, 0x9360, 0x11d0, 0x9e, 0x16, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  57. // Interface ID for the File Finder interface (used with URLs):
  58. DEFINE_GUID(IID_IITFileFinder,
  59. 0x77231260, 0x19c0, 0x11d1, 0xb6, 0x6e, 0x0, 0x0, 0xf8, 0x1, 0x49, 0xf6);
  60. /*
  61. The IITStorage interface parallels the API's defined for creating and
  62. opening Docfiles. So if you have code that currently uses Docfiles for
  63. your storage mechanism, you can easily convert over to using ITS files
  64. instead.
  65. ITS files use a different on-disk structure to optimize them for very
  66. fast stream access and very low overhead. ITS files can manage thousands
  67. or millions of streams with very good access performance and very small
  68. directory space requirements. This makes ITS files ideal for CD-Roms and
  69. for data collections that you'll download across the Internet.
  70. To make the conversion to ITS files you'll need to call CoCreateInstance
  71. with the class-id CLSID_ITStorage and the interface-id IID_ITStorage. You'll
  72. get back an interface pointer, say pItStg. Then you'll need to adjust the
  73. places where your code creates or opens Docfiles. Instead of StgCreateDocfile
  74. you'll call pItStg->StgCreateDocfile, and instead of StgOpenStorage, you'll
  75. call pItStg->StgOpenStorage. In both cases you'll get back an IStorage
  76. interface pointer, say pIStg, which you can use just as you did before.
  77. That's it. In general the rest of your code shouldn't have to change. There
  78. are some functional difference between ITS files and Docfiles -- ITS files
  79. don't support STGM_TRANSACTED, for example. So if you have to have transacted
  80. file operations, you can't use ITS files -- at least for now. However in
  81. almost all other respects ITS files interfaces can directly replace Docfile
  82. interfaces.
  83. Converting your data is also easy. Just open one of your Docfiles using
  84. StgOpenStorage, create a new ITS file via pItStg->StgCreateDocfile, and then
  85. use the CopyTo interface to copy your data objects and their storage heirarchy
  86. over to the ITS file:
  87. pStgDocfile->CopyTo(0, NULL, NULL, pStgITS);
  88. In some cases you may want to exercise some control over the internal parameters
  89. kept in an ITS file. You do this by calling SetControlData to give the IITStorage
  90. interface a block of ITS control data. Then each subsequent call to StgCreateDocfile
  91. will use that control data. The ITS control data determines, among other things,
  92. the tradeoff between efficient random access to the stream data and minimizing the
  93. size of an ITS file.
  94. The actual structure and interpretation of ITS control data is documented below.
  95. (See the ITSFS_Control_Data data type). You can get default control data via the
  96. DefaultControlData fuction. Note that DefaultControlData allocates the control
  97. structure using IMalloc::Alloc as provided by CoGetMalloc and expects that your code will
  98. deallocate the structure using the IMalloc::Free.
  99. */
  100. // IID_IStreamITEx interface declaration:
  101. DECLARE_INTERFACE_(IStreamITEx, IStream)
  102. {
  103. // IStreamITEx methods
  104. STDMETHOD(SetDataSpaceName)(const WCHAR * pwcsDataSpaceName) PURE;
  105. STDMETHOD(GetDataSpaceName)( WCHAR **ppwcsDataSpaceName) PURE;
  106. STDMETHOD(Flush)() = 0;
  107. };
  108. // IID_IStorageITEx interface declaration:
  109. DECLARE_INTERFACE_(IStorageITEx, IStorage)
  110. {
  111. // IStorageITEx methods:
  112. STDMETHOD(GetCheckSum)(ULARGE_INTEGER *puli) PURE;
  113. STDMETHOD(CreateStreamITEx)(const WCHAR * pwcsName, const WCHAR *pwcsDataSpaceName,
  114. DWORD grfMode, DWORD reserved1, DWORD reserved2,
  115. IStreamITEx ** ppstm
  116. ) PURE;
  117. STDMETHOD(OpenStreamITEx)(const WCHAR * pwcsName, void * reserved1, DWORD grfMode,
  118. DWORD reserved2, IStreamITEx ** ppstm) PURE;
  119. };
  120. // IStorageITEx::CreateStream lets you specify the data space in which a stream
  121. // is to be created. Currently two dataspaces are supported:
  122. //
  123. // L"Uncompressed" -- This dataspace applies no compression.
  124. // L"MSCompressed" -- This dataspace applies a default compression transform.
  125. #pragma warning( disable : 4200)
  126. // ITS_Control_Data is the generic structure of control data passed to the
  127. // IITStorage::SetControlData method or returned by the IITStorage::DefaultControlData
  128. // method.
  129. typedef struct _ITS_Control_Data
  130. {
  131. UINT cdwControlData; // Number of DWords to follow.
  132. UINT adwControlData[0]; // Actually this will be adwControlData[cdwControlData]
  133. } ITS_Control_Data, *PITS_Control_Data;
  134. // ITSFS_Control_Data is the actual prefix structure of control data for IITStorage.
  135. typedef struct _ITSFS_Control_Data
  136. {
  137. UINT cdwFollowing; // Must be 6 or 13
  138. DWORD cdwITFS_Control; // Must be 5
  139. DWORD dwMagic; // Must be MAGIC_ITSFS_CONTROL (see below)
  140. DWORD dwVersion; // Must be 1
  141. DWORD cbDirectoryBlock;// Size in bytes of directory blocks (Default is 8192)
  142. DWORD cMinCacheEntries;// Least upper bound on the number of directory blocks
  143. // which we'll cache in memory. (Default is 20)
  144. DWORD fFlags; // Control bit flags (see below).
  145. // Default value is fDefaultIsCompression.
  146. } ITSFS_Control_Data, *PITSFS_Control_Data;
  147. // Signature value for ITSFS_Control_Data
  148. const DWORD MAGIC_ITSFS_CONTROL = 'I' | ('T' << 8) | ('S' << 16) | ('C' << 24);
  149. // Bit flag definitions for ITSFS_Control_Data::fFlags
  150. const DWORD fDefaultIsCompression = 0x00000001;
  151. const DWORD fDefaultIsUncompressed = 0x00000000;
  152. // Note all other fFlags bits positions are reserved for future releases and should be
  153. // set to zero.
  154. // When ITSFS_Control_Data::cdwFollowing is > 6, we assume that LZX_Control_Data follows
  155. // immediately after. (See the XformControlData type below) LZX_Control_Data defines
  156. // parameters which control the default compressed data space.
  157. //
  158. // If ITSFS_Control_Data::cdwFollowing is 6, we use default values for the LZX
  159. // control data.
  160. typedef struct _LZX_Control_Data
  161. {
  162. UINT cdwControlData; // Must be 6
  163. DWORD dwLZXMagic; // Must be LZX_MAGIC (see below)
  164. DWORD dwVersion; // Must be 2
  165. DWORD dwMulResetBlock;// Number of blocks between compression resets. (Default: 4)
  166. DWORD dwMulWindowSize;// Maximum number of blocks kept in data history (Default: 4)
  167. DWORD dwMulSecondPartition; // Granularity in blocks of sliding history(Default: 2)
  168. DWORD dwOptions; // Option flags (Default: fOptimizeCodeStreams)
  169. } LZX_Control_Data, *PLZX_Control_Data;
  170. // Note: The block size for LZX compression is 32768 bytes.
  171. const DWORD LZX_MAGIC = 'L' | ('Z' << 8 ) | ('X' << 16) | ('C' << 24);
  172. // Values for LZX_Control_Data::dwOptions
  173. const DWORD fOptimizeCodeStreams = 0x00000001;
  174. // Note that all other flag bit positions are reserved for future releases and should be
  175. // set to zero.
  176. // The second parameter for the IITStorage::Compact method below is an enueration
  177. // which defines the level of compaction to do.
  178. typedef enum ECompactionLev {COMPACT_DATA=0, COMPACT_DATA_AND_PATH} ;
  179. DECLARE_INTERFACE_(IITStorage, IUnknown)
  180. {
  181. // IITStorage methods
  182. STDMETHOD(StgCreateDocfile)(const WCHAR * pwcsName, DWORD grfMode,
  183. DWORD reserved, IStorage ** ppstgOpen
  184. ) PURE;
  185. STDMETHOD(StgCreateDocfileOnILockBytes)(ILockBytes * plkbyt, DWORD grfMode,
  186. DWORD reserved, IStorage ** ppstgOpen
  187. ) PURE;
  188. STDMETHOD(StgIsStorageFile)(const WCHAR * pwcsName) PURE;
  189. STDMETHOD(StgIsStorageILockBytes)(ILockBytes * plkbyt) PURE;
  190. STDMETHOD(StgOpenStorage)(const WCHAR * pwcsName, IStorage * pstgPriority,
  191. DWORD grfMode, SNB snbExclude, DWORD reserved,
  192. IStorage ** ppstgOpen
  193. ) PURE;
  194. STDMETHOD(StgOpenStorageOnILockBytes)
  195. (ILockBytes * plkbyt, IStorage * pStgPriority, DWORD grfMode,
  196. SNB snbExclude, DWORD reserved, IStorage ** ppstgOpen
  197. ) PURE;
  198. STDMETHOD(StgSetTimes)(WCHAR const * lpszName, FILETIME const * pctime,
  199. FILETIME const * patime, FILETIME const * pmtime
  200. ) PURE;
  201. STDMETHOD(SetControlData)(PITS_Control_Data pControlData) PURE;
  202. STDMETHOD(DefaultControlData)(PITS_Control_Data *ppControlData) PURE;
  203. STDMETHOD(Compact)(const WCHAR * pwcsName, ECompactionLev iLev) PURE;
  204. };
  205. DECLARE_INTERFACE_(IITStorageEx, IITStorage)
  206. {
  207. STDMETHOD(StgCreateDocfileForLocale)
  208. (const WCHAR * pwcsName, DWORD grfMode, DWORD reserved, LCID lcid,
  209. IStorage ** ppstgOpen
  210. ) PURE;
  211. STDMETHOD(StgCreateDocfileForLocaleOnILockBytes)
  212. (ILockBytes * plkbyt, DWORD grfMode, DWORD reserved, LCID lcid,
  213. IStorage ** ppstgOpen
  214. ) PURE;
  215. STDMETHOD(QueryFileStampAndLocale)(const WCHAR *pwcsName, DWORD *pFileStamp,
  216. DWORD *pFileLocale) PURE;
  217. STDMETHOD(QueryLockByteStampAndLocale)(ILockBytes * plkbyt, DWORD *pFileStamp,
  218. DWORD *pFileLocale) PURE;
  219. };
  220. typedef IITStorage *PIITStorage;
  221. DECLARE_INTERFACE_(IFSStorage, IUnknown)
  222. {
  223. // IUnknown methods
  224. STDMETHOD(QueryInterface) (THIS_ REFIID, VOID **) PURE;
  225. STDMETHOD_(ULONG, AddRef) (THIS) PURE;
  226. STDMETHOD_(ULONG, Release) (THIS) PURE;
  227. // IFSStorage methods
  228. STDMETHOD(FSCreateStorage)(const WCHAR * pwcsName, DWORD grfMode, IStorage **ppstgOpen) PURE;
  229. STDMETHOD(FSOpenStorage)(const WCHAR * pwcsName, DWORD grfMode, IStorage **ppstgOpen) PURE;
  230. STDMETHOD(FSCreateStream)(const WCHAR *pwcsName, DWORD grfMode, IStream **ppStrm) PURE;
  231. STDMETHOD(FSCreateTemporaryStream)(IStream **ppStrm) PURE;
  232. STDMETHOD(FSOpenStream )(const WCHAR *pwcsName, DWORD grfMode, IStream **ppStrm) PURE;
  233. STDMETHOD(FSCreateLockBytes)(const WCHAR *pwcsName, DWORD grfMode, ILockBytes **ppLkb) PURE;
  234. STDMETHOD(FSCreateTemporaryLockBytes)(ILockBytes **ppLkb) PURE;
  235. STDMETHOD(FSOpenLockBytes )(const WCHAR *pwcsName, DWORD grfMode, ILockBytes **ppLkb) PURE;
  236. STDMETHOD(FSStgSetTimes)(WCHAR const * lpszName, FILETIME const * pctime,
  237. FILETIME const * patime, FILETIME const * pmtime
  238. ) PURE;
  239. };
  240. typedef IFSStorage *PIFSStorage;
  241. /*
  242. ** Data Spaces -- What they are.
  243. Within an ITS file we store information in one or more data spaces. A data space
  244. is a container which holds the bits which represent a collection of streams. Each
  245. data space has a name and an associated collection of transforms.
  246. Those transforms take the raw data which you write to an ITS stream and map it into
  247. a representation stream. When you read from an ITS stream they do the reverse mapping
  248. to reconstruct your original data from the representation.
  249. When you first create an ITS file, it contains one data space named "Default_Space"
  250. which applies the LZX data compression transform. By default all of the streams you
  251. create will have their data representations stored in the default data space.
  252. If LZX compression meets your needs, and you're not concerned about data enciphering,
  253. you can skip over the following discussion. If, on the other hand, you want to
  254. create additional data spaces or transforms, read on.
  255. To create a data space, you must first get a pointer to the IDataSpaceManager interface.
  256. Just do a QueryInterface for IID_DataSpaceManager from any storage created by the
  257. IITStorage interface. Then you can call the CreateDataSpace function to define a new
  258. data space.
  259. When you're defining a collection of data spaces, be sure that their names are distinct.
  260. Defining two data spaces with the same name is an error. Data space names follow the
  261. rules for stream names. That is, they must be less than 260 characters long, and may
  262. not contain the characters '/'. '\', '|', ':', or any character less than 0x0020.
  263. Data spaces are kept in a separate name space. So you don't have to worry about
  264. colliding with a stream name or a storage name. As noted above, we have defined one
  265. special data space ("Default_Space") where all data resides if you take no action.
  266. You can redefine that default space simply by creating a new data space with the
  267. name "Default_Space". This is the one case where a name collision is allowed. If
  268. you do redefine the default data space, any data in the old space will automatically
  269. be transformed appropriately and moved into the new default data space.
  270. ** Importing Items
  271. If you have defined additional data spaces, the next step is to define which streams
  272. and storages you want to move into the new data spaces. You do that by means of the
  273. IDataSpace::Import function. For example suppose you've defined the dataspace
  274. *pMyDataSpace and you want to import the stream "Alpha" contained in the storage
  275. *pThatStorage:
  276. pMyDataSpace->Import(pThatStorage, "Alpha");
  277. Similarly if you want to import the storage "HTML_Pages" from pThisStorage:
  278. pMyDataSpace->Import(pThisStorage, "HTML_Pages");
  279. That will recursively import the "HTML_Pages" storage and all of the streams and
  280. storages contained within it. It also conditions those storages so that anything
  281. you create within them will be automatically imported into pMyDataSpace. Note that
  282. subsequent Import operations may alter that conditioning.
  283. If you later decide that you want to move "Alpha" back into the default data
  284. space:
  285. hr = pDataSpaceManager->OpenDataSpace(L"Default_Space", &pDefaultDataSpace);
  286. pDefaultDataSpace->Import(pThatStorage, "Alpha");
  287. ** Data Space Transform Sets
  288. When you define a data space, you must specify a set of transforms to apply to
  289. the items you import into the space. A transform is an interface that converts
  290. data to some other representation. For example the LZX transform converts your
  291. imported data into a more compact, compressed representation. Other transforms
  292. might implement word or phrase based dictionary compression, or they might encipher
  293. your data, or they might just convert from one data format to another. You could,
  294. for example, construct a transform to store HTML data as a Rich Text stream.
  295. When you define a data space with more than one transform, they are applied in
  296. order. For example let's suppose that your transform set consists of these three:
  297. 1. A Dictionary compression transform
  298. 2. The LXZ transform
  299. 3. An data encryption transform
  300. Whenever you write data into this space, it will first be compressed using the
  301. dictionary compression methods, then LZX compression will be applied, and finally
  302. your information will be encrypted. When you read data the process is reversed so
  303. that the encryption transform supplies data to the LZX transform which in turn
  304. provides data for the dictionary compression transform.
  305. You define the transform set via a vector of class ids (paclsidXform). Each class id
  306. defines a location where an implementation of IID_Transform can be found. In addition
  307. you'll supply corresponding control data for each transform (papxfcd). The number of
  308. transforms is defined by the cXforms parameter.
  309. Note that it is legal to define a space with zero transforms. This is useful when
  310. you've got items which are already compressed and which won't benefit from an
  311. additional layer of compression overhead.
  312. The control data for a transform defines how it will operate in a particular
  313. data space. For example the control data for the LZX transform defines how
  314. aggressively it will pursue compression, and it controls the tradeoff between
  315. random access performance and the level of compression.
  316. The actual structure and content of the control data is documented above.
  317. (See the LZX_Control_Data data type.)
  318. ** Transform Factories -- How they are organized; What they do
  319. Transforms have two functional capabilities. They can return default
  320. control data (DefaultControlData), and they can create
  321. transform instances (CreateTransformInstance). When the ITSS code calls your
  322. CreateTransformInstance function, it will supply a storage medium (pXFSpan_Base)
  323. where transformed data is to be stored along with the control data for the
  324. instance and several other useful pieces of information.
  325. The CreateTransformInstance function has several parameters that you can use
  326. when you need to access global and/or instance data streams. They also support
  327. the construction of encryption transforms. You can ignore those parameters if your
  328. transform doesn't do encryption, uses only a single pass over the data, and doesn't
  329. rely on any data beyond the data in the stream being transformed.
  330. -- The rclsidXForm and pwszDataSpace parameters, respectively, tell you the Class ID
  331. by which your code was located, and the name of the data space in which your instance
  332. will be working. These values are used with the ITransformServices interface.
  333. -- The pXformServices parameter points to an instance of the ITranformServices interface.
  334. That interface gives you access to a couple of storages where you can keep global and
  335. instance data for your transform. It also gives you a way to contruct a temporary
  336. stream that is automatically deleted when you release it. That's very handy when
  337. you get a seek operation into the middle of the transformed data followed by a write
  338. operation.
  339. If you're implementing a multipass strategy, you can get access to those storages
  340. from code outside the transform by doing a QueryInterface from any ITS storage for
  341. the interface IID_ITransformServices. You identify the storage in question by the
  342. transform's class id and possibly the name of the data space instance.
  343. The per-transform-instance storage is also a convenient place to put the navigation
  344. data necessary to support fast seek operations.
  345. -- The pKeyManager parameter is an interface pointer used with encryption transforms.
  346. It supplies the read and write keys to use with your encryption transform. Those keys
  347. are set by the SetKeys interface of the ITransformServices interface. This allows you
  348. to separate your user interface code where people will enter passwords from the
  349. transform implementations. This can be useful when you want the same keys to be used
  350. for several different data spaces.
  351. ** Transform Instances -- How they are organized; What they do
  352. A Transform Instance is an object which simulates a data medium which can be
  353. suballocated. Suballocated items are managed as data spans (ITransformedSpan).
  354. You must supply a function to create a data span (CreateTransformedSpan), and
  355. a function to open a data span (OpenTransformedSpan). Both of those functions
  356. return an ITransformedSpan interface when they succeed. In addition you must
  357. supply the function SpaceSize to return the size of the entire untransformed
  358. data image. That is, SpaceSize returns the highest limit offset (offset + size)
  359. of any data span created within the instance.
  360. A span is identified by an ImageSpan structure which defines an offset and a size
  361. for the span. Both values are defined in untransformed space. For the Create function
  362. this is an output parameter, while it is an input parameter for the Open function.
  363. Note the interaction between the ImageSpan and the WriteAt member function of the
  364. ITransformedSpan interface.
  365. ** Transformed Data Spans -- How they are organized; What they do
  366. A transformed Data Span (ITransformedSpan) has two member functions -- ReadAt and
  367. WriteAt. Those functions are very similar to the ReadAt and WriteAt functions of
  368. the ILockBytes interface. The difference is that WriteAt includes an extra output
  369. parameter (pImageSpan) for recording the current span parameters. The ReadAt function
  370. doesn't include that parameter because read operations can never change the span's
  371. size or move it to a different offset.
  372. ** Implementation Strategies
  373. This section describes a few scenarios that you may encounter as you construct a
  374. transform along with strategies for those situations. This is an open ended list
  375. which will expand as we gain more experience with transforms.
  376. Many compression and encryption transforms are designed around sequential I/O. That is,
  377. they expect to get the raw data from a sequence of write opeations with no intervening
  378. seek operations. In many cases such transforms also write out the transformed data to
  379. the base stream in ascending order. Similarly they expect read requests to come to them
  380. with no intervening seek operations.
  381. The key issue for those transforms is how do you implement random access and interleaved
  382. read, write, and seek operations.
  383. Leaving aside write operations for the moment, let's consider a random sequence of reads
  384. interleaved with seek operations. One solution might be to construct a table to map from
  385. raw data offsets to transformed data offsets. You can store such a table in the instance
  386. storage for the current data space.
  387. One complication is that many compression transforms use the raw data as a dictionary.
  388. That is, you can only start reading from the beginning of the transformed data. You can
  389. deal with those transforms telling them to reset themselves periodically. That gives
  390. you a collection of starting points spread fairly evenly throught the transformed
  391. data. When you do this you'll need to supply a control data parameter to control the
  392. frequency of those reset points so that your clients can make an appropriate tradeoff
  393. between compression efficiency and random access performance.
  394. Now what about adding random write operations to the mix? The short answer here is that
  395. you can't do this in the middle of transformed data. One strategy would be to reconstruct
  396. the entire raw data into a temporary stream and do all your I/O to that stream until
  397. release time. Then at release time you can transform the revised data sequentially.
  398. A variation on that strategy is to keep track of which reset spans are modified and
  399. write the modified versions of those transformed spans to the end of the base stream.
  400. This leaves a certain amount of dead space in your transformed data, but it allows
  401. you to defer the sequential reconstruction work to a more convenient time. The down
  402. side is that it requires you to manage yet more navigation data in the instance
  403. storage for the data space.
  404. */
  405. interface IDataSpaceManager;
  406. interface IDataSpace;
  407. interface ITransformServices;
  408. interface IKeyInstance;
  409. interface ITransformFactory;
  410. interface ITransformInstance;
  411. typedef struct _XformControlData
  412. {
  413. UINT cdwControlData; // Size of this structure in DWords
  414. UINT adwControlData[0]; // Actually this will be UINT adwData[cdwData];
  415. } XformControlData, *PXformControlData;
  416. /*
  417. // {7C01FD0F-7BAA-11d0-9E0C-00A0C922E6EC}
  418. DEFINE_GUID(IID_IDataSpaceManager,
  419. 0x7c01fd0f, 0x7baa, 0x11d0, 0x9e, 0xc, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  420. */
  421. interface IDataSpaceManager : public IUnknown
  422. {
  423. public:
  424. virtual HRESULT STDMETHODCALLTYPE CreateDataSpace
  425. (const WCHAR *pwszDataSpace, UINT cXforms,
  426. const CLSID *paclsidXform, PXformControlData paxfcd,
  427. IDataSpace *pITDataSpace
  428. ) = 0;
  429. virtual HRESULT STDMETHODCALLTYPE OpenDataSpace
  430. (const WCHAR *pwszDataSpace,
  431. IDataSpace *pITDataSpace
  432. ) = 0;
  433. virtual HRESULT STDMETHODCALLTYPE DiscardDataSpace
  434. (const WCHAR *pwszDataSpace) = 0;
  435. virtual HRESULT STDMETHODCALLTYPE EnumDataSpaces
  436. (IEnumSTATSTG ** ppenum) = 0;
  437. };
  438. /*
  439. // {7C01FD0E-7BAA-11d0-9E0C-00A0C922E6EC}
  440. DEFINE_GUID(IID_IDataSpace,
  441. 0x7c01fd0e, 0x7baa, 0x11d0, 0x9e, 0xc, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  442. */
  443. interface IDataSpace : public IUnknown
  444. {
  445. public:
  446. virtual HRESULT STDMETHODCALLTYPE GetTransformInfo
  447. (PUINT pcXforms, PUINT pcdwXformControlData,
  448. CLSID *paclsid, PXformControlData pxfcd
  449. ) = 0;
  450. virtual HRESULT STDMETHODCALLTYPE Import
  451. (IStorage *pStg, const WCHAR * pwszElementName) = 0;
  452. virtual HRESULT STDMETHODCALLTYPE ImportSpace(IStorage **ppStg) = 0;
  453. };
  454. /*
  455. // {7C01FD0C-7BAA-11d0-9E0C-00A0C922E6EC}
  456. DEFINE_GUID(IID_ITransformFactory,
  457. 0x7c01fd0c, 0x7baa, 0x11d0, 0x9e, 0xc, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  458. */
  459. interface ITransformFactory : public IUnknown
  460. {
  461. public:
  462. virtual HRESULT STDMETHODCALLTYPE DefaultControlData
  463. (XformControlData **ppXFCD) = 0;
  464. virtual HRESULT STDMETHODCALLTYPE CreateTransformInstance
  465. (ITransformInstance *pXFormMedium, // Container data span for transformed data
  466. ULARGE_INTEGER cbUntransformedSize, // Untransformed size of data
  467. PXformControlData pXFCD, // Control data for this instance
  468. const CLSID *rclsidXForm, // Transform Class ID
  469. const WCHAR *pwszDataSpaceName, // Data space name for this instance
  470. ITransformServices *pXformServices, // Utility routines
  471. IKeyInstance *pKeyManager, // Interface to get enciphering keys
  472. ITransformInstance **ppTransformInstance // Out: Instance transform interface
  473. ) = 0;
  474. };
  475. typedef struct _ImageSpan
  476. {
  477. ULARGE_INTEGER uliHandle;
  478. ULARGE_INTEGER uliSize;
  479. } ImageSpan;
  480. /*
  481. // {EB19B67E-9360-11d0-9E16-00A0C922E6EC}
  482. DEFINE_GUID(IID_ITransformInstance,
  483. 0xeb19b67e, 0x9360, 0x11d0, 0x9e, 0x16, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  484. */
  485. interface ITransformInstance : public IUnknown
  486. {
  487. public:
  488. virtual HRESULT STDMETHODCALLTYPE ReadAt
  489. (ULARGE_INTEGER ulOffset, void *pv, ULONG cb, ULONG *pcbRead,
  490. ImageSpan *pSpan
  491. ) = 0;
  492. virtual HRESULT STDMETHODCALLTYPE WriteAt
  493. (ULARGE_INTEGER ulOffset, const void *pv, ULONG cb, ULONG *pcbWritten,
  494. ImageSpan *pSpan
  495. ) = 0;
  496. virtual HRESULT STDMETHODCALLTYPE Flush() = 0;
  497. virtual HRESULT STDMETHODCALLTYPE SpaceSize(ULARGE_INTEGER *puliSize) = 0;
  498. // Note: SpaceSize returns the high water mark for the space. That is, the largest
  499. // limit value (uliOffset + uliSize) for any transformed lockbytes created within
  500. // the base (*pXLKB).
  501. };
  502. /*
  503. // {A55895FC-89E1-11d0-9E14-00A0C922E6EC}
  504. DEFINE_GUID(IID_ITransformServices,
  505. 0xa55895fc, 0x89e1, 0x11d0, 0x9e, 0x14, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  506. */
  507. interface ITransformServices : public IUnknown
  508. {
  509. public:
  510. virtual HRESULT STDMETHODCALLTYPE PerTransformStorage
  511. (REFCLSID rclsidXForm, IStorage **ppStg) = 0;
  512. virtual HRESULT STDMETHODCALLTYPE PerTransformInstanceStorage
  513. (REFCLSID rclsidXForm, const WCHAR *pwszDataSpace, IStorage **ppStg) = 0;
  514. virtual HRESULT STDMETHODCALLTYPE SetKeys
  515. (REFCLSID rclsidXForm, const WCHAR *pwszDataSpace,
  516. PBYTE pbReadKey, UINT cbReadKey,
  517. PBYTE pbWriteKey, UINT cbWriteKey
  518. ) = 0;
  519. virtual HRESULT STDMETHODCALLTYPE CreateTemporaryStream(IStream **ppStrm) = 0;
  520. };
  521. /*
  522. // {96AF35CE-88EC-11d0-9E14-00A0C922E6EC}
  523. DEFINE_GUID(IID_IKeyInstance,
  524. 0x96af35ce, 0x88ec, 0x11d0, 0x9e, 0x14, 0x0, 0xa0, 0xc9, 0x22, 0xe6, 0xec);
  525. */
  526. interface IKeyInstance : public IUnknown
  527. {
  528. public:
  529. virtual HRESULT STDMETHODCALLTYPE GetKeys
  530. (PBYTE *pbReadKey, PUINT pcbReadKey,
  531. PBYTE *pbWriteKey, PUINT pcbWriteKey
  532. ) = 0;
  533. };
  534. /*
  535. Streams stored in an ITS file may be accessed through URLs with
  536. the form:
  537. its: <File Path> :: <Stream Path>
  538. where <File Path> may be either a Win32 file path or a URL, and
  539. <Stream Path> is the path to a stream stored in the ITS file.
  540. Each <Stream Path> must begin with '/'.
  541. This means that you can copy a Win32 directory tree of HTML files
  542. and associated files into an ITS file and get to them through ITS
  543. URLs. If all the URL references within those HTML files are
  544. relative, they will be resolved within the containing ITS file.
  545. The <File Path> portion of the URL may either be a complete path
  546. to the ITS file, or it may be just the file name. In the later case
  547. you may need to install auxillary information in the registry to
  548. help the ITSS code locate the file. Here are the rules:
  549. 1. If you don't supply a complete path, ITSS looks in the current
  550. working directory for the file.
  551. 2. If the file isn't found in step 1. ITSS looks for a registry
  552. value in the ITSS_MAP section of HKEY_LOCAL_MACHINE. The value
  553. name must match the file name, and the value will be a string
  554. giving the complete file path to be used.
  555. 3. If the file isn't found in steps 1 and 2, ITSS isolates the file's
  556. extension (beginning with the last '.' character) and looks
  557. for a corresponding class id value in the ITSS_FINDER section
  558. of HKEY_LOCAL_MACHINE. The name for the value will match the
  559. extension, and the value will be the class id for an object
  560. which implements the IID_IITFileFinder interface.
  561. 4. If the file isn't found in steps 1 through 3, the URL reference
  562. fails.
  563. */
  564. #define ITSS_MAP "Software\\Microsoft\\Windows\\ITStorage\\Maps"
  565. #define ITSS_FINDER "Software\\Microsoft\\Windows\\ITStorage\\Finders"
  566. interface IITFileFinder : public IUnknown
  567. {
  568. public:
  569. virtual HRESULT STDMETHODCALLTYPE FindThisFile(const WCHAR *pFileName, WCHAR **ppFullPath,
  570. BOOL *pfRecordPathInRegistry
  571. ) = 0;
  572. // The FindThisFile method maps a file name into a complete file path. The file name
  573. // is defined by *pFileName, and a pointer to the complete path is returned in
  574. // *ppFullPath. The returned path will be a string allocated in the IMalloc heap.
  575. // The *pfRecordPathInRegistry result should be TRUE when we should record this mapping
  576. // in the ITSS_MAP registry section and FALSE otherwise.
  577. };
  578. #endif // __MSITSTG_H__