Exemplo n.º 1
0
        static void Main(string[] args)
        {
            string extractDir       = @"D:\HotfixDB\lab";
            bool   includeExtension = true;

            string msiFilePath = @"D:\HotfixDB\lab\NDP45-KB3127229-x64\NDP45-KB3127229.msp";

            VsInterop.IStorage rootStorage = null;
            HRESULT            hr          = NativeMethods.StgOpenStorage(msiFilePath, null, STGM.STGM_READ | STGM.STGM_SHARE_EXCLUSIVE, null, 0, out rootStorage);

            if (HResultHelper.IsSucceeded(hr) && rootStorage != null)
            {
                //
                // A Database and Patch Example
                // https://msdn.microsoft.com/en-us/library/aa367813(v=vs.85).aspx
                //
                // http://www.pinvoke.net/default.aspx/msi.msirecordsetstring
                // http://blogs.msdn.com/b/heaths/archive/2006/03/31/566288.aspx
                //
                MsiDbOpenPersist msiDbOpenPersist = MsiDbOpenPersist.MSIDBOPEN_READONLY;
                if (isPatch(rootStorage))
                {
                    msiDbOpenPersist = MsiDbOpenPersist.MSIDBOPEN_READONLY | MsiDbOpenPersist.MSIDBOPEN_PATCHFILE;
                }

                // Release COM object of root storage.
                Marshal.ReleaseComObject(rootStorage);

                IntPtr msiDatabaseHandle = IntPtr.Zero;
                uint   err = NativeMethods.MsiOpenDatabase(msiFilePath, new IntPtr((uint)msiDbOpenPersist), out msiDatabaseHandle);
                if (err == WinError.ERROR_SUCCESS)
                {
                    IntPtr msiViewHandle = IntPtr.Zero;
                    //err = NativeMethods.MsiDatabaseOpenView(msiDatabaseHandle, @"SELECT Name, Data FROM _Streams", out msiViewHandle);
                    err = NativeMethods.MsiDatabaseOpenView(msiDatabaseHandle, @"SELECT Name, Data FROM _Storages", out msiViewHandle);
                    //err = NativeMethods.MsiDatabaseOpenView(msiDatabaseHandle, @"SELECT Name, Data FROM _Tables", out msiViewHandle);
                    if (err == WinError.ERROR_SUCCESS)
                    {
                        err = NativeMethods.MsiViewExecute(msiViewHandle, IntPtr.Zero);
                        if (err == WinError.ERROR_SUCCESS)
                        {
                            while (true)
                            {
                                IntPtr msiRecordHandle = IntPtr.Zero;
                                err = NativeMethods.MsiViewFetch(msiViewHandle, out msiRecordHandle);
                                if (err != WinError.ERROR_SUCCESS)
                                {
                                    break;
                                }

                                saveStream(msiRecordHandle, extractDir, includeExtension);

                                NativeMethods.MsiCloseHandle(msiRecordHandle);
                            }
                        }
                    }

                    // Close MSI view handle.
                    if (msiViewHandle != IntPtr.Zero)
                    {
                        NativeMethods.MsiCloseHandle(msiViewHandle);
                    }
                }

                // Close MSI database handle.
                if (msiDatabaseHandle != IntPtr.Zero)
                {
                    NativeMethods.MsiCloseHandle(msiDatabaseHandle);
                }
            }
            else
            {
                throw new Exception(string.Format(@"Failed: StgOpenStorage(): Failed to open root storage ""{0}""", msiFilePath));
            }
        }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            string extractDir       = @"F:\Takatano\Desktop\experiment\storages";
            bool   includeExtension = true;

            string msiFilePath = @"F:\Takatano\Projects\MsixEx\NDP45-KB3037581.msp";

            VsInterop.IStorage rootStorage = null;
            HRESULT            hr          = NativeMethods.StgOpenStorage(msiFilePath, null, STGM.STGM_READ | STGM.STGM_SHARE_EXCLUSIVE, null, 0, out rootStorage);

            if (HResultHelper.IsSucceeded(hr) && rootStorage != null)
            {
                //
                // もしかすると、この辺関係ないかも
                // (構造を維持して展開できれば、話は違うかも)
                //

                //VsInterop.IEnumSTATSTG enumStatStg = null;
                //rootStorage.EnumElements(0, IntPtr.Zero, 0, out enumStatStg);
                //if (enumStatStg != null)
                //{
                //    while (true)
                //    {
                //        VsInterop.STATSTG[] stg = new VsInterop.STATSTG[1];
                //        uint fetched;
                //        hr = (HRESULT)enumStatStg.Next(1, stg, out fetched);
                //        if (hr == HRESULT.S_FALSE)
                //        {
                //            break;
                //        }
                //        if (hr != HRESULT.S_OK)
                //        {
                //            throw new Exception(@"Failed: IEnumSTATSTG.Next(): Failed to enumerate next storage status");
                //        }

                //        Console.WriteLine(@"Name:{0}, Type:{1}", stg[0].pwcsName, stg[0].type);

                //        if ((VsInterop.STGTY)stg[0].type == VsInterop.STGTY.STGTY_STORAGE)
                //        {
                //            saveStorage(rootStorage, extractDir, stg[0].pwcsName, includeExtension ? @".mst" : null);
                //        }

                //        //if (stg.pwcsName)
                //        //{
                //        //    CoTaskMemFree(stg.pwcsName);    // これ必要なのかも, Marshal.FreeCoTaskMem(), string になっているし、不要かな。
                //        //    stg.pwcsName = NULL;
                //        //}
                //    }

                //    Marshal.ReleaseComObject(enumStatStg);
                //}

                //
                // A Database and Patch Example
                // https://msdn.microsoft.com/en-us/library/aa367813(v=vs.85).aspx
                //
                // http://www.pinvoke.net/default.aspx/msi.msirecordsetstring
                // http://blogs.msdn.com/b/heaths/archive/2006/03/31/566288.aspx
                //
                MsiDbOpenPersist msiDbOpenPersist = MsiDbOpenPersist.MSIDBOPEN_READONLY;
                if (isPatch(rootStorage))
                {
                    msiDbOpenPersist = MsiDbOpenPersist.MSIDBOPEN_READONLY | MsiDbOpenPersist.MSIDBOPEN_PATCHFILE;
                }

                // Release COM object of root storage.
                Marshal.ReleaseComObject(rootStorage);

                IntPtr msiDatabaseHandle = IntPtr.Zero;
                uint   err = NativeMethods.MsiOpenDatabase(msiFilePath, new IntPtr((uint)msiDbOpenPersist), out msiDatabaseHandle);
                if (err == WinError.ERROR_SUCCESS)
                {
                    IntPtr msiViewHandle = IntPtr.Zero;
                    err = NativeMethods.MsiDatabaseOpenView(msiDatabaseHandle, @"SELECT Name, Data FROM _Streams", out msiViewHandle);
                    if (err == WinError.ERROR_SUCCESS)
                    {
                        err = NativeMethods.MsiViewExecute(msiViewHandle, IntPtr.Zero);
                        if (err == WinError.ERROR_SUCCESS)
                        {
                            while (true)
                            {
                                IntPtr msiRecordHandle = IntPtr.Zero;
                                err = NativeMethods.MsiViewFetch(msiViewHandle, out msiRecordHandle);
                                if (err != WinError.ERROR_SUCCESS)
                                {
                                    break;
                                }

                                saveStream(msiRecordHandle, extractDir, includeExtension);

                                NativeMethods.MsiCloseHandle(msiRecordHandle);
                            }
                        }
                    }

                    // Close MSI view handle.
                    if (msiViewHandle != IntPtr.Zero)
                    {
                        NativeMethods.MsiCloseHandle(msiViewHandle);
                    }
                }

                // Close MSI database handle.
                if (msiDatabaseHandle != IntPtr.Zero)
                {
                    NativeMethods.MsiCloseHandle(msiDatabaseHandle);
                }
            }
            else
            {
                throw new Exception(string.Format(@"Failed: StgOpenStorage(): Failed to open root storage ""{0}""", msiFilePath));
            }
        }