private static byte[] GetBufferFromIStream(IStream comStream) { LARGE_INTEGER zeroPos; zeroPos.QuadPart = 0; ULARGE_INTEGER[] streamPosition = new ULARGE_INTEGER[1]; comStream.Seek(zeroPos, (uint)STREAM_SEEK.STREAM_SEEK_CUR, streamPosition); comStream.Seek(zeroPos, (uint)STREAM_SEEK.STREAM_SEEK_SET, null); Microsoft.VisualStudio.OLE.Interop.STATSTG[] stat = new Microsoft.VisualStudio.OLE.Interop.STATSTG[1]; comStream.Stat(stat, (uint)STATFLAG.STATFLAG_NONAME); int bufferLength = (int)stat[0].cbSize.QuadPart; byte[] buffer = new byte[bufferLength]; uint bytesRead = 0; comStream.Read(buffer, (uint)buffer.Length, out bytesRead); // return the stream to its previous location LARGE_INTEGER newPos; newPos.QuadPart = (long)streamPosition[0].QuadPart; comStream.Seek(newPos, (uint)STREAM_SEEK.STREAM_SEEK_SET, null); return(buffer); }
private static bool isPatch(VsInterop.IStorage storage) { Trace.Assert(storage != null); Guid CLSID_MsiPatch = new Guid(@"{000c1086-0000-0000-c000-000000000046}"); VsInterop.STATSTG[] stg = new VsInterop.STATSTG[1]; storage.Stat(stg, (uint)VsInterop.STATFLAG.STATFLAG_NONAME); return(stg[0].clsid == CLSID_MsiPatch); }
/// <summary> /// Returns true if the storage represents a patch (MSP) /// </summary> /// <param name="storage">The store to check.</param> /// <returns>true if the storage is an MSP, false otherwise.</returns> public static bool IsPatch(IStorage storage) { if (storage == null) { throw new ArgumentNullException("storage"); } STATSTG[] stg = new STATSTG[] { new STATSTG() }; storage.Stat(stg, (uint)STATFLAG.STATFLAG_NONAME); return(String.Equals(stg[0].clsid.ToString(), MSP_CLSID, StringComparison.OrdinalIgnoreCase)); }
private static byte[] GetBufferFromIStream(IStream comStream) { LARGE_INTEGER zeroPos; zeroPos.QuadPart = 0; ULARGE_INTEGER[] streamPosition = new ULARGE_INTEGER[1]; comStream.Seek(zeroPos, (uint)STREAM_SEEK.STREAM_SEEK_CUR, streamPosition); comStream.Seek(zeroPos, (uint)STREAM_SEEK.STREAM_SEEK_SET, null); Microsoft.VisualStudio.OLE.Interop.STATSTG[] stat = new Microsoft.VisualStudio.OLE.Interop.STATSTG[1]; comStream.Stat(stat, (uint)STATFLAG.STATFLAG_NONAME); int bufferLength = (int)stat[0].cbSize.QuadPart; byte[] buffer = new byte[bufferLength]; uint bytesRead = 0; comStream.Read(buffer, (uint)buffer.Length, out bytesRead); // return the stream to its previous location LARGE_INTEGER newPos; newPos.QuadPart = (long)streamPosition[0].QuadPart; comStream.Seek(newPos, (uint)STREAM_SEEK.STREAM_SEEK_SET, null); return buffer; }
public static void OpenAndExtractStorages(string filename, string dir) { IStorage rootStorage = null; int hresult = Ole32.StgOpenStorage(filename, null, STGM.STGM_READ | STGM.STGM_SHARE_EXCLUSIVE, IntPtr.Zero, 0, out rootStorage); if ((hresult == S_OK) && (rootStorage != null)) { if (IsPatch(rootStorage)) { try { IEnumSTATSTG rootStorageEnum = null; rootStorage.EnumElements(0, IntPtr.Zero, 0, out rootStorageEnum); STATSTG[] enumStg = new STATSTG[] { new STATSTG() }; uint numFetched = 0; rootStorageEnum.Next(1, enumStg, out numFetched); while (numFetched == 1) { if (enumStg[0].type == (uint)STGTY.STGTY_STORAGE) { // Save the nested transform storages with an .mst extension SaveStorage(rootStorage, dir, enumStg[0].pwcsName, ".mst"); } rootStorageEnum.Next(1, enumStg, out numFetched); } if (enumStg != null) { Marshal.ReleaseComObject(rootStorageEnum); } if (rootStorage != null) { Marshal.ReleaseComObject(rootStorage); } using (Database installDatabase = new Database(filename, DatabaseOpenMode.ReadOnly)) using (View view = installDatabase.OpenView("SELECT `Name`, `Data` FROM `_Streams`")) { view.Execute(); foreach (Record record in view) { SaveStream(record, dir); record.Close(); } } } finally { if (rootStorage != null) { Marshal.ReleaseComObject(rootStorage); } } } } }