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