diff options
Diffstat (limited to 'src/WixToolset.Core.Native/Ole32/Storage.cs')
-rw-r--r-- | src/WixToolset.Core.Native/Ole32/Storage.cs | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/src/WixToolset.Core.Native/Ole32/Storage.cs b/src/WixToolset.Core.Native/Ole32/Storage.cs new file mode 100644 index 00000000..3e4c6af2 --- /dev/null +++ b/src/WixToolset.Core.Native/Ole32/Storage.cs | |||
@@ -0,0 +1,377 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixToolset.Core.Native.Ole32 | ||
4 | { | ||
5 | using System; | ||
6 | using System.Runtime.InteropServices; | ||
7 | using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; | ||
8 | using STATSTG = System.Runtime.InteropServices.ComTypes.STATSTG; | ||
9 | |||
10 | /// <summary> | ||
11 | /// Wrapper for the compound storage file APIs. | ||
12 | /// </summary> | ||
13 | internal class Storage : IDisposable | ||
14 | { | ||
15 | private readonly IStorage storage; | ||
16 | private bool disposed; | ||
17 | |||
18 | /// <summary> | ||
19 | /// Instantiate a new Storage. | ||
20 | /// </summary> | ||
21 | /// <param name="storage">The native storage interface.</param> | ||
22 | private Storage(IStorage storage) | ||
23 | { | ||
24 | this.storage = storage; | ||
25 | } | ||
26 | |||
27 | /// <summary> | ||
28 | /// Storage destructor. | ||
29 | /// </summary> | ||
30 | ~Storage() | ||
31 | { | ||
32 | this.Dispose(); | ||
33 | } | ||
34 | |||
35 | /// <summary> | ||
36 | /// The IEnumSTATSTG interface enumerates an array of STATSTG structures. | ||
37 | /// </summary> | ||
38 | [ComImport, Guid("0000000d-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | ||
39 | private interface IEnumSTATSTG | ||
40 | { | ||
41 | /// <summary> | ||
42 | /// Gets a specified number of STATSTG structures. | ||
43 | /// </summary> | ||
44 | /// <param name="celt">The number of STATSTG structures requested.</param> | ||
45 | /// <param name="rgelt">An array of STATSTG structures returned.</param> | ||
46 | /// <param name="pceltFetched">The number of STATSTG structures retrieved in the rgelt parameter.</param> | ||
47 | /// <returns>The error code.</returns> | ||
48 | [PreserveSig] | ||
49 | uint Next(uint celt, [MarshalAs(UnmanagedType.LPArray), Out] STATSTG[] rgelt, out uint pceltFetched); | ||
50 | |||
51 | /// <summary> | ||
52 | /// Skips a specified number of STATSTG structures in the enumeration sequence. | ||
53 | /// </summary> | ||
54 | /// <param name="celt">The number of STATSTG structures to skip.</param> | ||
55 | void Skip(uint celt); | ||
56 | |||
57 | /// <summary> | ||
58 | /// Resets the enumeration sequence to the beginning of the STATSTG structure array. | ||
59 | /// </summary> | ||
60 | void Reset(); | ||
61 | |||
62 | /// <summary> | ||
63 | /// Creates a new enumerator that contains the same enumeration state as the current STATSTG structure enumerator. | ||
64 | /// </summary> | ||
65 | /// <returns>The cloned IEnumSTATSTG interface.</returns> | ||
66 | [return: MarshalAs(UnmanagedType.Interface)] | ||
67 | IEnumSTATSTG Clone(); | ||
68 | } | ||
69 | |||
70 | /// <summary> | ||
71 | /// The IStorage interface supports the creation and management of structured storage objects. | ||
72 | /// </summary> | ||
73 | [ComImport, Guid("0000000b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | ||
74 | private interface IStorage | ||
75 | { | ||
76 | /// <summary> | ||
77 | /// Creates and opens a stream object with the specified name contained in this storage object. | ||
78 | /// </summary> | ||
79 | /// <param name="pwcsName">The name of the newly created stream.</param> | ||
80 | /// <param name="grfMode">Specifies the access mode to use when opening the newly created stream.</param> | ||
81 | /// <param name="reserved1">Reserved for future use; must be zero.</param> | ||
82 | /// <param name="reserved2">Reserved for future use; must be zero.</param> | ||
83 | /// <param name="ppstm">On return, pointer to the location of the new IStream interface pointer.</param> | ||
84 | void CreateStream(string pwcsName, uint grfMode, uint reserved1, uint reserved2, out IStream ppstm); | ||
85 | |||
86 | /// <summary> | ||
87 | /// Opens an existing stream object within this storage object using the specified access permissions in grfMode. | ||
88 | /// </summary> | ||
89 | /// <param name="pwcsName">The name of the stream to open.</param> | ||
90 | /// <param name="reserved1">Reserved for future use; must be NULL.</param> | ||
91 | /// <param name="grfMode">Specifies the access mode to be assigned to the open stream.</param> | ||
92 | /// <param name="reserved2">Reserved for future use; must be zero.</param> | ||
93 | /// <param name="ppstm">A pointer to IStream pointer variable that receives the interface pointer to the newly opened stream object.</param> | ||
94 | void OpenStream(string pwcsName, IntPtr reserved1, uint grfMode, uint reserved2, out IStream ppstm); | ||
95 | |||
96 | /// <summary> | ||
97 | /// Creates and opens a new storage object nested within this storage object with the specified name in the specified access mode. | ||
98 | /// </summary> | ||
99 | /// <param name="pwcsName">The name of the newly created storage object.</param> | ||
100 | /// <param name="grfMode">A value that specifies the access mode to use when opening the newly created storage object.</param> | ||
101 | /// <param name="reserved1">Reserved for future use; must be zero.</param> | ||
102 | /// <param name="reserved2">Reserved for future use; must be zero.</param> | ||
103 | /// <param name="ppstg">A pointer, when successful, to the location of the IStorage pointer to the newly created storage object.</param> | ||
104 | void CreateStorage(string pwcsName, uint grfMode, uint reserved1, uint reserved2, out IStorage ppstg); | ||
105 | |||
106 | /// <summary> | ||
107 | /// Opens an existing storage object with the specified name in the specified access mode. | ||
108 | /// </summary> | ||
109 | /// <param name="pwcsName">The name of the storage object to open.</param> | ||
110 | /// <param name="pstgPriority">Must be NULL.</param> | ||
111 | /// <param name="grfMode">Specifies the access mode to use when opening the storage object.</param> | ||
112 | /// <param name="snbExclude">Must be NULL.</param> | ||
113 | /// <param name="reserved">Reserved for future use; must be zero.</param> | ||
114 | /// <param name="ppstg">When successful, pointer to the location of an IStorage pointer to the opened storage object.</param> | ||
115 | void OpenStorage(string pwcsName, IStorage pstgPriority, uint grfMode, IntPtr snbExclude, uint reserved, out IStorage ppstg); | ||
116 | |||
117 | /// <summary> | ||
118 | /// Copies the entire contents of an open storage object to another storage object. | ||
119 | /// </summary> | ||
120 | /// <param name="ciidExclude">The number of elements in the array pointed to by rgiidExclude.</param> | ||
121 | /// <param name="rgiidExclude">An array of interface identifiers (IIDs) that either the caller knows about and does not want | ||
122 | /// copied or that the storage object does not support, but whose state the caller will later explicitly copy.</param> | ||
123 | /// <param name="snbExclude">A string name block (refer to SNB) that specifies a block of storage or stream objects that are not to be copied to the destination.</param> | ||
124 | /// <param name="pstgDest">A pointer to the open storage object into which this storage object is to be copied.</param> | ||
125 | void CopyTo(uint ciidExclude, IntPtr rgiidExclude, IntPtr snbExclude, IStorage pstgDest); | ||
126 | |||
127 | /// <summary> | ||
128 | /// Copies or moves a substorage or stream from this storage object to another storage object. | ||
129 | /// </summary> | ||
130 | /// <param name="pwcsName">The name of the element in this storage object to be moved or copied.</param> | ||
131 | /// <param name="pstgDest">IStorage pointer to the destination storage object.</param> | ||
132 | /// <param name="pwcsNewName">The new name for the element in its new storage object.</param> | ||
133 | /// <param name="grfFlags">Specifies whether the operation should be a move (STGMOVE_MOVE) or a copy (STGMOVE_COPY).</param> | ||
134 | void MoveElementTo(string pwcsName, IStorage pstgDest, string pwcsNewName, uint grfFlags); | ||
135 | |||
136 | /// <summary> | ||
137 | /// Reflects changes for a transacted storage object to the parent level. | ||
138 | /// </summary> | ||
139 | /// <param name="grfCommitFlags">Controls how the changes are committed to the storage object.</param> | ||
140 | void Commit(uint grfCommitFlags); | ||
141 | |||
142 | /// <summary> | ||
143 | /// Discards all changes that have been made to the storage object since the last commit operation. | ||
144 | /// </summary> | ||
145 | void Revert(); | ||
146 | |||
147 | /// <summary> | ||
148 | /// Returns an enumerator object that can be used to enumerate the storage and stream objects contained within this storage object. | ||
149 | /// </summary> | ||
150 | /// <param name="reserved1">Reserved for future use; must be zero.</param> | ||
151 | /// <param name="reserved2">Reserved for future use; must be NULL.</param> | ||
152 | /// <param name="reserved3">Reserved for future use; must be zero.</param> | ||
153 | /// <param name="ppenum">Pointer to IEnumSTATSTG* pointer variable that receives the interface pointer to the new enumerator object.</param> | ||
154 | void EnumElements(uint reserved1, IntPtr reserved2, uint reserved3, out IEnumSTATSTG ppenum); | ||
155 | |||
156 | /// <summary> | ||
157 | /// Removes the specified storage or stream from this storage object. | ||
158 | /// </summary> | ||
159 | /// <param name="pwcsName">The name of the storage or stream to be removed.</param> | ||
160 | void DestroyElement(string pwcsName); | ||
161 | |||
162 | /// <summary> | ||
163 | /// Renames the specified storage or stream in this storage object. | ||
164 | /// </summary> | ||
165 | /// <param name="pwcsOldName">The name of the substorage or stream to be changed.</param> | ||
166 | /// <param name="pwcsNewName">The new name for the specified substorage or stream.</param> | ||
167 | void RenameElement(string pwcsOldName, string pwcsNewName); | ||
168 | |||
169 | /// <summary> | ||
170 | /// Sets the modification, access, and creation times of the indicated storage element, if supported by the underlying file system. | ||
171 | /// </summary> | ||
172 | /// <param name="pwcsName">The name of the storage object element whose times are to be modified.</param> | ||
173 | /// <param name="pctime">Either the new creation time for the element or NULL if the creation time is not to be modified.</param> | ||
174 | /// <param name="patime">Either the new access time for the element or NULL if the access time is not to be modified.</param> | ||
175 | /// <param name="pmtime">Either the new modification time for the element or NULL if the modification time is not to be modified.</param> | ||
176 | void SetElementTimes(string pwcsName, FILETIME pctime, FILETIME patime, FILETIME pmtime); | ||
177 | |||
178 | /// <summary> | ||
179 | /// Assigns the specified CLSID to this storage object. | ||
180 | /// </summary> | ||
181 | /// <param name="clsid">The CLSID that is to be associated with the storage object.</param> | ||
182 | void SetClass(Guid clsid); | ||
183 | |||
184 | /// <summary> | ||
185 | /// Stores up to 32 bits of state information in this storage object. | ||
186 | /// </summary> | ||
187 | /// <param name="grfStateBits">Specifies the new values of the bits to set.</param> | ||
188 | /// <param name="grfMask">A binary mask indicating which bits in grfStateBits are significant in this call.</param> | ||
189 | void SetStateBits(uint grfStateBits, uint grfMask); | ||
190 | |||
191 | /// <summary> | ||
192 | /// Returns the STATSTG structure for this open storage object. | ||
193 | /// </summary> | ||
194 | /// <param name="pstatstg">On return, pointer to a STATSTG structure where this method places information about the open storage object.</param> | ||
195 | /// <param name="grfStatFlag">Specifies that some of the members in the STATSTG structure are not returned, thus saving a memory allocation operation.</param> | ||
196 | void Stat(out STATSTG pstatstg, uint grfStatFlag); | ||
197 | } | ||
198 | |||
199 | /// <summary> | ||
200 | /// The IStream interface lets you read and write data to stream objects. | ||
201 | /// </summary> | ||
202 | [ComImport, Guid("0000000c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | ||
203 | private interface IStream | ||
204 | { | ||
205 | /// <summary> | ||
206 | /// Reads a specified number of bytes from the stream object into memory starting at the current seek pointer. | ||
207 | /// </summary> | ||
208 | /// <param name="pv">A pointer to the buffer which the stream data is read into.</param> | ||
209 | /// <param name="cb">The number of bytes of data to read from the stream object.</param> | ||
210 | /// <param name="pcbRead">A pointer to a ULONG variable that receives the actual number of bytes read from the stream object.</param> | ||
211 | void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, int cb, IntPtr pcbRead); | ||
212 | |||
213 | /// <summary> | ||
214 | /// Writes a specified number of bytes into the stream object starting at the current seek pointer. | ||
215 | /// </summary> | ||
216 | /// <param name="pv">A pointer to the buffer that contains the data that is to be written to the stream.</param> | ||
217 | /// <param name="cb">The number of bytes of data to attempt to write into the stream.</param> | ||
218 | /// <param name="pcbWritten">A pointer to a ULONG variable where this method writes the actual number of bytes written to the stream object.</param> | ||
219 | void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, int cb, IntPtr pcbWritten); | ||
220 | |||
221 | /// <summary> | ||
222 | /// Changes the seek pointer to a new location relative to the beginning of the stream, the end of the stream, or the current seek pointer. | ||
223 | /// </summary> | ||
224 | /// <param name="dlibMove">The displacement to be added to the location indicated by the dwOrigin parameter.</param> | ||
225 | /// <param name="dwOrigin">The origin for the displacement specified in dlibMove.</param> | ||
226 | /// <param name="plibNewPosition">A pointer to the location where this method writes the value of the new seek pointer from the beginning of the stream.</param> | ||
227 | void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition); | ||
228 | |||
229 | /// <summary> | ||
230 | /// Changes the size of the stream object. | ||
231 | /// </summary> | ||
232 | /// <param name="libNewSize">Specifies the new size of the stream as a number of bytes.</param> | ||
233 | void SetSize(long libNewSize); | ||
234 | |||
235 | /// <summary> | ||
236 | /// Copies a specified number of bytes from the current seek pointer in the stream to the current seek pointer in another stream. | ||
237 | /// </summary> | ||
238 | /// <param name="pstm">A pointer to the destination stream.</param> | ||
239 | /// <param name="cb">The number of bytes to copy from the source stream.</param> | ||
240 | /// <param name="pcbRead">A pointer to the location where this method writes the actual number of bytes read from the source.</param> | ||
241 | /// <param name="pcbWritten">A pointer to the location where this method writes the actual number of bytes written to the destination.</param> | ||
242 | void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten); | ||
243 | |||
244 | /// <summary> | ||
245 | /// Ensures that any changes made to a stream object open in transacted mode are reflected in the parent storage object. | ||
246 | /// </summary> | ||
247 | /// <param name="grfCommitFlags">Controls how the changes for the stream object are committed.</param> | ||
248 | void Commit(int grfCommitFlags); | ||
249 | |||
250 | /// <summary> | ||
251 | /// Discards all changes that have been made to a transacted stream since the last call to IStream::Commit. | ||
252 | /// </summary> | ||
253 | void Revert(); | ||
254 | |||
255 | /// <summary> | ||
256 | /// Restricts access to a specified range of bytes in the stream. | ||
257 | /// </summary> | ||
258 | /// <param name="libOffset">Integer that specifies the byte offset for the beginning of the range.</param> | ||
259 | /// <param name="cb">Integer that specifies the length of the range, in bytes, to be restricted.</param> | ||
260 | /// <param name="dwLockType">Specifies the restrictions being requested on accessing the range.</param> | ||
261 | void LockRegion(long libOffset, long cb, int dwLockType); | ||
262 | |||
263 | /// <summary> | ||
264 | /// Removes the access restriction on a range of bytes previously restricted with IStream::LockRegion. | ||
265 | /// </summary> | ||
266 | /// <param name="libOffset">Specifies the byte offset for the beginning of the range.</param> | ||
267 | /// <param name="cb">Specifies, in bytes, the length of the range to be restricted.</param> | ||
268 | /// <param name="dwLockType">Specifies the access restrictions previously placed on the range.</param> | ||
269 | void UnlockRegion(long libOffset, long cb, int dwLockType); | ||
270 | |||
271 | /// <summary> | ||
272 | /// Retrieves the STATSTG structure for this stream. | ||
273 | /// </summary> | ||
274 | /// <param name="pstatstg">Pointer to a STATSTG structure where this method places information about this stream object.</param> | ||
275 | /// <param name="grfStatFlag">Specifies that this method does not return some of the members in the STATSTG structure, thus saving a memory allocation operation.</param> | ||
276 | void Stat(out STATSTG pstatstg, int grfStatFlag); | ||
277 | |||
278 | /// <summary> | ||
279 | /// Creates a new stream object that references the same bytes as the original stream but provides a separate seek pointer to those bytes. | ||
280 | /// </summary> | ||
281 | /// <param name="ppstm">When successful, pointer to the location of an IStream pointer to the new stream object.</param> | ||
282 | void Clone(out IStream ppstm); | ||
283 | } | ||
284 | |||
285 | /// <summary> | ||
286 | /// Creates a new compound file storage object. | ||
287 | /// </summary> | ||
288 | /// <param name="storageFile">The compound file being created.</param> | ||
289 | /// <param name="mode">Specifies the access mode to use when opening the new storage object.</param> | ||
290 | /// <returns>The created Storage object.</returns> | ||
291 | public static Storage CreateDocFile(string storageFile, StorageMode mode) | ||
292 | { | ||
293 | var storage = NativeMethods.StgCreateDocfile(storageFile, (uint)mode, 0); | ||
294 | |||
295 | return new Storage(storage); | ||
296 | } | ||
297 | |||
298 | /// <summary> | ||
299 | /// Opens an existing root storage object in the file system. | ||
300 | /// </summary> | ||
301 | /// <param name="storageFile">The file that contains the storage object to open.</param> | ||
302 | /// <param name="mode">Specifies the access mode to use to open the storage object.</param> | ||
303 | /// <returns>The created Storage object.</returns> | ||
304 | public static Storage Open(string storageFile, StorageMode mode) | ||
305 | { | ||
306 | var storage = NativeMethods.StgOpenStorage(storageFile, IntPtr.Zero, (uint)mode, IntPtr.Zero, 0); | ||
307 | |||
308 | return new Storage(storage); | ||
309 | } | ||
310 | |||
311 | /// <summary> | ||
312 | /// Copies the entire contents of this open storage object into another Storage object. | ||
313 | /// </summary> | ||
314 | /// <param name="destinationStorage">The destination Storage object.</param> | ||
315 | public void CopyTo(Storage destinationStorage) | ||
316 | { | ||
317 | this.storage.CopyTo(0, IntPtr.Zero, IntPtr.Zero, destinationStorage.storage); | ||
318 | } | ||
319 | |||
320 | /// <summary> | ||
321 | /// Opens an existing Storage object with the specified name according to the specified access mode. | ||
322 | /// </summary> | ||
323 | /// <param name="name">The name of the Storage object.</param> | ||
324 | /// <returns>The opened Storage object.</returns> | ||
325 | public Storage OpenStorage(string name) | ||
326 | { | ||
327 | this.storage.OpenStorage(name, null, (uint)(StorageMode.Read | StorageMode.ShareExclusive), IntPtr.Zero, 0, out var subStorage); | ||
328 | |||
329 | return new Storage(subStorage); | ||
330 | } | ||
331 | |||
332 | /// <summary> | ||
333 | /// Disposes the managed and unmanaged objects in this object. | ||
334 | /// </summary> | ||
335 | public void Dispose() | ||
336 | { | ||
337 | if (!this.disposed) | ||
338 | { | ||
339 | Marshal.ReleaseComObject(this.storage); | ||
340 | |||
341 | this.disposed = true; | ||
342 | } | ||
343 | |||
344 | GC.SuppressFinalize(this); | ||
345 | } | ||
346 | |||
347 | /// <summary> | ||
348 | /// The native methods. | ||
349 | /// </summary> | ||
350 | private static class NativeMethods | ||
351 | { | ||
352 | /// <summary> | ||
353 | /// Creates a new compound file storage object. | ||
354 | /// </summary> | ||
355 | /// <param name="pwcsName">The name for the compound file being created.</param> | ||
356 | /// <param name="grfMode">Specifies the access mode to use when opening the new storage object.</param> | ||
357 | /// <param name="reserved">Reserved for future use; must be zero.</param> | ||
358 | /// <returns>A pointer to the location of the IStorage pointer to the new storage object.</returns> | ||
359 | [DllImport("ole32.dll", PreserveSig = false)] | ||
360 | [return: MarshalAs(UnmanagedType.Interface)] | ||
361 | internal static extern IStorage StgCreateDocfile([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, uint grfMode, uint reserved); | ||
362 | |||
363 | /// <summary> | ||
364 | /// Opens an existing root storage object in the file system. | ||
365 | /// </summary> | ||
366 | /// <param name="pwcsName">The file that contains the storage object to open.</param> | ||
367 | /// <param name="pstgPriority">Most often NULL.</param> | ||
368 | /// <param name="grfMode">Specifies the access mode to use to open the storage object.</param> | ||
369 | /// <param name="snbExclude">If not NULL, pointer to a block of elements in the storage to be excluded as the storage object is opened.</param> | ||
370 | /// <param name="reserved">Indicates reserved for future use; must be zero.</param> | ||
371 | /// <returns>A pointer to a IStorage* pointer variable that receives the interface pointer to the opened storage.</returns> | ||
372 | [DllImport("ole32.dll", PreserveSig = false)] | ||
373 | [return: MarshalAs(UnmanagedType.Interface)] | ||
374 | internal static extern IStorage StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)] string pwcsName, IntPtr pstgPriority, uint grfMode, IntPtr snbExclude, uint reserved); | ||
375 | } | ||
376 | } | ||
377 | } | ||