Пример #1
0
        internal static void ExecuteAgainstMountedImage(string imagePath, string mountPath, string tempPath, bool readOnly, Action <WimHandle, WimHandle> action)
        {
            using (WimHandle wimHandle = WimgApi.CreateFile(imagePath, WimFileAccess.Read | WimFileAccess.Write | WimFileAccess.Mount, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(wimHandle, tempPath);

                using (WimHandle imageHandle = WimgApi.LoadImage(wimHandle, 1))
                {
                    WimMountImageOptions flags = WimMountImageOptions.Fast | WimMountImageOptions.DisableDirectoryAcl | WimMountImageOptions.DisableFileAcl | WimMountImageOptions.DisableRPFix;

                    if (readOnly)
                    {
                        flags |= WimMountImageOptions.ReadOnly;
                    }

                    WimgApi.MountImage(imageHandle, mountPath, flags);

                    try
                    {
                        action?.Invoke(wimHandle, imageHandle);
                    }
                    finally
                    {
                        WimgApi.UnmountImage(imageHandle);
                    }
                }
            }
        }
Пример #2
0
        public bool ExtractFileFromImage(string wimFile, int imageIndex, string fileToExtract, string destination)
        {
            return(WIMLibImaging.ExtractFileFromImage(wimFile, imageIndex, fileToExtract, destination));

            using (var wimHandle = WimgApi.CreateFile(
                       wimFile,
                       WimFileAccess.Read,
                       WimCreationDisposition.OpenExisting,
                       WimCreateFileOptions.Chunked,
                       WimCompressionType.None))
            {
                // Always set a temporary path
                //
                WimgApi.SetTemporaryPath(wimHandle, Environment.GetEnvironmentVariable("TEMP"));

                try
                {
                    using (WimHandle imageHandle = WimgApi.LoadImage(wimHandle, imageIndex))
                    {
                        WimgApi.ExtractImagePath(imageHandle, fileToExtract, destination);
                    }
                }
                catch (Exception ex)
                {
                    // A priv is not held by the client
                    if (ex.HResult == -2147467259)
                    {
                        return(WIMLibImaging.ExtractFileFromImage(wimFile, imageIndex, fileToExtract, destination));
                    }

                    return(false);
                }
            }
            return(true);
        }
Пример #3
0
        public void GetMountedImageHandleTest_ReadWrite()
        {
            ExecuteAgainstMountedImage((wimHandle, imageHandle) =>
            {
                using (WimHandle actualWimHandle = WimgApi.GetMountedImageHandle(MountPath, false, out WimHandle actualImageHandle))
                {
                    try
                    {
                        actualWimHandle.ShouldNotBeNull();

                        actualImageHandle.ShouldNotBeNull();

                        WimMountInfo wimMountInfo = WimgApi.GetMountedImageInfoFromHandle(actualImageHandle);

                        wimMountInfo.ShouldNotBeNull();

                        wimMountInfo.ImageIndex.ShouldBe(1);
                        wimMountInfo.MountPath.ShouldBe(MountPath, StringCompareShould.IgnoreCase);
                        wimMountInfo.Path.ShouldBe(TestWimPath);
                        wimMountInfo.ReadOnly.ShouldBeTrue();
                        wimMountInfo.State.ShouldBe(WimMountPointState.Mounted);
                    }
                    finally
                    {
                        actualImageHandle.Dispose();
                    }
                }
            });
        }
Пример #4
0
        public void CaptureImageWithCallbackTest()
        {
            CallbackObject userData = new CallbackObject();

            using (WimHandle wimHandle = WimgApi.CreateFile(CaptureWimPath, WimFileAccess.Write, WimCreationDisposition.CreateAlways, WimCreateFileOptions.None, WimCompressionType.Xpress))
            {
                WimgApi.SetTemporaryPath(wimHandle, TempPath);

                WimgApi.RegisterMessageCallback(wimHandle, CaptureImageWithCallbackTestCallback, userData);
                try
                {
                    using (WimHandle imageHandle = WimgApi.CaptureImage(wimHandle, CapturePath, WimCaptureImageOptions.None))
                    {
                    }
                }
                finally
                {
                    WimgApi.UnregisterMessageCallback(wimHandle, CaptureImageWithCallbackTestCallback);
                }
            }
            _captureWithCallbackCalled.ShouldBe(true, "The callback should have been called");

            userData.WasCalled.ShouldBe(true, "The callback should have set user data");

            _captureWithCallbackFileCount.ShouldBe(TestWimTemplate.FileCount);
        }
Пример #5
0
        public void ApplyImageTest_Abort()
        {
            using (WimHandle wimHandle = WimgApi.CreateFile(TestWimPath, WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(wimHandle, TempPath);

                WimMessageResult MessageCallback(WimMessageType messageType, object message, object userData) => messageType == WimMessageType.Process ? WimMessageResult.Abort : WimMessageResult.Done;

                WimgApi.RegisterMessageCallback(wimHandle, MessageCallback);

                try
                {
                    using (WimHandle imageHandle = WimgApi.LoadImage(wimHandle, 1))
                    {
                        WimHandle imageHandleCopy = imageHandle;

                        Should.Throw <OperationCanceledException>(() =>
                                                                  WimgApi.ApplyImage(imageHandleCopy, ApplyPath, WimApplyImageOptions.NoApply));
                    }
                }
                finally
                {
                    WimgApi.UnregisterMessageCallback(wimHandle, MessageCallback);
                }
            }
        }
        public void ExportImageTest_ThrowsArgumentNullException_wimHandle()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                WimHandle imageHandleCopy = imageHandle;

                ShouldThrow <ArgumentNullException>("wimHandle", () =>
                                                    WimgApi.ExportImage(imageHandleCopy, null, WimExportImageOptions.None));
            }
        }
        public void ExtractImagePathTest_ThrowsArgumentNullException_sourceFile()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                WimHandle imageHandleCopy = imageHandle;

                ShouldThrow <ArgumentNullException>("sourceFile", () =>
                                                    WimgApi.ExtractImagePath(imageHandleCopy, null, string.Empty));
            }
        }
Пример #8
0
        public void ExtractImagePathTest_ThrowsArgumentNullException_destinationFile()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                WimHandle imageHandleCopy = imageHandle;

                ShouldThrow <ArgumentNullException>("destinationFile", () =>
                                                    WimgApi.ExtractImagePath(imageHandleCopy, "", null));
            }
        }
Пример #9
0
        public void MountImageHandleTest_ThrowsArgumentNullException_mountPath()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                WimHandle imageHandleCopy = imageHandle;

                ShouldThrow <ArgumentNullException>("mountPath", () =>
                                                    WimgApi.MountImage(imageHandleCopy, null, WimMountImageOptions.None));
            }
        }
Пример #10
0
        public void MountImageHandleTest_ThrowsDirectoryNotFoundException_mountPath()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                WimHandle imageHandleCopy = imageHandle;

                Should.Throw <DirectoryNotFoundException>(() =>
                                                          WimgApi.MountImage(imageHandleCopy, Path.Combine(TestDirectory, Guid.NewGuid().ToString()), WimMountImageOptions.None));
            }
        }
Пример #11
0
        public void LoadImageTest()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                imageHandle.ShouldNotBeNull();

                imageHandle.IsInvalid.ShouldBeFalse();

                imageHandle.IsClosed.ShouldBeFalse();
            }
        }
 private void InitializeWIM()
 {
     using (WimHandle fullWIM = WimgApi.CreateFile(SourceWIM, WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.Chunked, WimCompressionType.None))
     {
         XPathNodeIterator iterator = WimgApi.GetImageInformation(fullWIM).CreateNavigator().Select("/WIM/IMAGE/NAME");
         AvailableEditions = new string[iterator.Count];
         while (iterator.MoveNext())
         {
             AvailableEditions[iterator.CurrentPosition - 1] = "[" + iterator.Current.SelectSingleNode("../@INDEX").Value + "] " + iterator.Current.Value;
         }
     }
 }
Пример #13
0
        public void CaptureImageTest()
        {
            using (WimHandle wimHandle = WimgApi.CreateFile(CaptureWimPath, WimFileAccess.Write, WimCreationDisposition.CreateAlways, WimCreateFileOptions.None, WimCompressionType.Xpress))
            {
                WimgApi.SetTemporaryPath(wimHandle, TempPath);

                using (WimHandle imageHandle = WimgApi.CaptureImage(wimHandle, CapturePath, WimCaptureImageOptions.None))
                {
                    int imageCount = WimgApi.GetImageCount(wimHandle);

                    imageCount.ShouldBe(1);
                }
            }
        }
Пример #14
0
        public void ApplyImageTest()
        {
            using (WimHandle wimHandle = WimgApi.CreateFile(TestWimPath, WimFileAccess.Read | WimFileAccess.Write | WimFileAccess.Mount, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(wimHandle, TempPath);

                using (WimHandle imageHandle = WimgApi.LoadImage(wimHandle, 1))
                {
                    WimgApi.ApplyImage(imageHandle, ApplyPath, WimApplyImageOptions.Index | WimApplyImageOptions.DisableDirectoryAcl | WimApplyImageOptions.DisableFileAcl | WimApplyImageOptions.DisableRPFix);
                }
            }

            Directory.EnumerateFiles(ApplyPath).Count().ShouldBe(TestWimTemplate.FileCount);
        }
Пример #15
0
        public void SetReferenceFileTest()
        {
            string[] splitWims = CreateSplitWim().ToArray();

            using (WimHandle wimHandle = WimgApi.CreateFile(splitWims[0], WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(wimHandle, TempPath);

                foreach (string referenceFile in splitWims.Skip(1))
                {
                    WimgApi.SetReferenceFile(wimHandle, referenceFile, WimSetReferenceMode.Append, WimSetReferenceOptions.None);
                }
            }
        }
        public void ExportImageTest()
        {
            string exportWimPath = Path.Combine(TestDirectory, "export.wim");

            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                using (WimHandle wimHandle = WimgApi.CreateFile(exportWimPath, WimFileAccess.Write, WimCreationDisposition.CreateAlways, WimCreateFileOptions.None, WimCompressionType.Lzx))
                {
                    WimgApi.SetTemporaryPath(wimHandle, TempPath);

                    WimgApi.ExportImage(imageHandle, wimHandle, WimExportImageOptions.None);
                }
            }

            File.Exists(exportWimPath).ShouldBeTrue();

            new FileInfo(exportWimPath).Length.ShouldNotBe(0);
        }
        public void CommitImageHandleTest_Append()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                WimgApi.MountImage(imageHandle, MountPath, WimMountImageOptions.Fast | WimMountImageOptions.DisableDirectoryAcl | WimMountImageOptions.DisableFileAcl | WimMountImageOptions.DisableRPFix);

                try
                {
                    using (WimgApi.CommitImageHandle(imageHandle, true, WimCommitImageOptions.DisableDirectoryAcl | WimCommitImageOptions.DisableFileAcl | WimCommitImageOptions.DisableRPFix))
                    {
                        WimgApi.GetImageCount(TestWimHandle).ShouldBe(TestWimTemplate.ImageCount + 1);
                    }
                }
                finally
                {
                    WimgApi.UnmountImage(imageHandle);
                }
            }
        }
        public void ExtractImagePathTest()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                foreach (string file in GetImageFiles(imageHandle).Take(10))
                {
                    string fileName = Path.GetFileName(file);

                    fileName.ShouldNotBeNull();

                    // ReSharper disable once AssignNullToNotNullAttribute
                    string destinationPath = Path.Combine(TestDirectory, fileName);

                    WimgApi.ExtractImagePath(imageHandle, file, destinationPath);

                    File.Exists(destinationPath).ShouldBeTrue();
                }
            }
        }
        private IEnumerable <string> GetImageFiles(WimHandle imageHandle)
        {
            List <string> files = new List <String>();

            WimMessageResult MessageCallback(WimMessageType messageType, object message, object userData)
            {
                if (messageType == WimMessageType.FileInfo)
                {
                    WimMessageFileInfo messageFileInfo = (WimMessageFileInfo)message;

                    if ((messageFileInfo.FileInfo.Attributes | FileAttributes.Directory) != FileAttributes.Directory)
                    {
                        ((List <String>)userData).Add(messageFileInfo.Path.Replace(ApplyPath, string.Empty));
                    }
                }

                return(WimMessageResult.Done);
            }

            WimgApi.RegisterMessageCallback(TestWimHandle, MessageCallback, files);

            try
            {
                WimgApi.ApplyImage(imageHandle, ApplyPath, WimApplyImageOptions.NoApply | WimApplyImageOptions.FileInfo);
            }
            catch (Win32Exception win32Exception)
            {
                if (win32Exception.NativeErrorCode != 1235)
                {
                    throw;
                }
            }
            finally
            {
                WimgApi.UnregisterMessageCallback(TestWimHandle, MessageCallback);
            }

            return(files);
        }
Пример #20
0
        public bool GetWIMImageInformation(
            string wimFile,
            int imageIndex,
            out WIMInformationXML.IMAGE image)
        {
            image = null;
            try
            {
                using (var wimHandle = WimgApi.CreateFile(
                           wimFile,
                           WimFileAccess.Read,
                           WimCreationDisposition.OpenExisting,
                           WimCreateFileOptions.Chunked,
                           WimCompressionType.None))
                {
                    // Always set a temporary path
                    //
                    WimgApi.SetTemporaryPath(wimHandle, Environment.GetEnvironmentVariable("TEMP"));

                    try
                    {
                        using (WimHandle imageHandle = WimgApi.LoadImage(wimHandle, imageIndex))
                        {
                            var wiminfo = WimgApi.GetImageInformationAsString(imageHandle);
                            image = WIMInformationXML.DeserializeIMAGE(wiminfo);
                        }
                    }
                    finally
                    {
                    }
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
Пример #21
0
        public void ApplyImageTest_NoApply()
        {
            WimMessageResult MessageCallback(WimMessageType messageType, object message, object userData)
            {
                if (messageType == WimMessageType.SetRange)
                {
                    _noApplyFileCount = ((WimMessageSetRange)message).FileCount;
                }

                return(WimMessageResult.Done);
            }

            using (WimHandle wimHandle = WimgApi.CreateFile(TestWimPath, WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(wimHandle, TempPath);

                WimgApi.RegisterMessageCallback(wimHandle, MessageCallback);

                try
                {
                    using (WimHandle imageHandle = WimgApi.LoadImage(wimHandle, 1))
                    {
                        WimgApi.ApplyImage(imageHandle, ApplyPath, WimApplyImageOptions.NoApply);
                    }
                }
                finally
                {
                    WimgApi.UnregisterMessageCallback(wimHandle, MessageCallback);
                }
            }

            int fileCount = Directory.EnumerateFiles(ApplyPath).Count();

            fileCount.ShouldBe(0);

            _noApplyFileCount.ShouldBe(TestWimTemplate.FileCount);
        }
Пример #22
0
        public void RemountImageTest()
        {
            using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                WimgApi.MountImage(imageHandle, MountPath, WimMountImageOptions.Fast | WimMountImageOptions.DisableDirectoryAcl | WimMountImageOptions.DisableFileAcl | WimMountImageOptions.DisableRPFix | WimMountImageOptions.ReadOnly);

                try
                {
                    VerifyMountState(imageHandle, WimMountPointState.Mounted);

                    KillWimServ();

                    VerifyMountState(imageHandle, WimMountPointState.Remountable);

                    WimgApi.RemountImage(MountPath);

                    VerifyMountState(imageHandle, WimMountPointState.Mounted);
                }
                finally
                {
                    WimgApi.UnmountImage(imageHandle);
                }
            }
        }
Пример #23
0
        public static List <LogInfo> WimUnmount(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>(1);

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_WimUnmount));
            CodeInfo_WimUnmount info = cmd.Info as CodeInfo_WimUnmount;

            string mountDir = StringEscaper.Preprocess(s, info.MountDir);

            // Check MountDir
            if (!Directory.Exists(mountDir))
            {
                logs.Add(new LogInfo(LogState.Error, $"Directory [{mountDir}] does not exist"));
                return(logs);
            }

            // Unmount Wim
            // https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd834953.aspx
            WimHandle hWim   = null;
            WimHandle hImage = null;

            try
            {
                hWim = WimgApi.GetMountedImageHandle(mountDir, true, out hImage);

                WimMountInfo wimInfo = WimgApi.GetMountedImageInfoFromHandle(hImage);
                Debug.Assert(wimInfo.MountPath.Equals(mountDir, StringComparison.OrdinalIgnoreCase));

                // Prepare Command Progress Report
                WimgApi.RegisterMessageCallback(hWim, WimgApiCallback);
                s.MainViewModel.BuildCommandProgressTitle = "WimUnmount Progress";
                s.MainViewModel.BuildCommandProgressText  = string.Empty;
                s.MainViewModel.BuildCommandProgressMax   = 100;
                s.MainViewModel.BuildCommandProgressShow  = true;

                try
                { // Unmount
                    WimgApi.UnmountImage(hImage);
                    logs.Add(new LogInfo(LogState.Success, $"Unmounted [{wimInfo.Path}]'s image [{wimInfo.ImageIndex}] from [{mountDir}]"));
                }
                finally
                { // Finalize Command Progress Report
                    s.MainViewModel.BuildCommandProgressShow  = false;
                    s.MainViewModel.BuildCommandProgressTitle = "Progress";
                    s.MainViewModel.BuildCommandProgressText  = string.Empty;
                    s.MainViewModel.BuildCommandProgressValue = 0;
                    WimgApi.UnregisterMessageCallback(hWim, WimgApiCallback);
                }
            }
            catch (Win32Exception e)
            {
                logs.Add(new LogInfo(LogState.Error, $"Unable to unmount [{mountDir}]\r\nError Code [0x{e.ErrorCode:X8}]\r\nNative Error Code [0x{e.NativeErrorCode:X8}]\r\n"));
                return(logs);
            }
            finally
            {
                hWim?.Close();
                hImage?.Close();
            }

            return(logs);
        }
Пример #24
0
        private string CaptureTemplateImage(string capturePath)
        {
            string imagePath = Path.Combine(_testWimTemplateDirectory, TestWimTemplateFilename);

            if (!Directory.Exists(capturePath))
            {
                throw new DirectoryNotFoundException(String.Format(CultureInfo.CurrentCulture, "Could not find part of the path '{0}'", capturePath));
            }

            XmlDocument xmlDocument = new XmlDocument
            {
                XmlResolver = null,
            };

            using (WimHandle wimHandle = WimgApi.CreateFile(imagePath, WimFileAccess.Write, WimCreationDisposition.CreateNew, WimCreateFileOptions.None, WimCompressionType.Lzx))
            {
                WimgApi.SetTemporaryPath(wimHandle, _testWimTempPath);

                for (int i = 0; i < ImageCount; i++)
                {
                    // ReSharper disable once UnusedVariable
                    using (WimHandle imageHandle = WimgApi.CaptureImage(wimHandle, capturePath, WimCaptureImageOptions.DisableDirectoryAcl | WimCaptureImageOptions.DisableFileAcl | WimCaptureImageOptions.DisableRPFix))
                    {
                    }
                }

                XPathNavigator xml = WimgApi.GetImageInformation(wimHandle).CreateNavigator();

                xml.ShouldNotBeNull();

                using (StringReader stringReader = new StringReader(xml.OuterXml))
                    using (XmlTextReader reader = new XmlTextReader(stringReader)
                    {
                        DtdProcessing = DtdProcessing.Prohibit,
                    })
                    {
                        xmlDocument.Load(reader);
                    }

                XmlNodeList imageNodes = xmlDocument.SelectNodes("//WIM/IMAGE");

                imageNodes.ShouldNotBeNull();

                // ReSharper disable once PossibleNullReferenceException
                foreach (XmlElement imageNode in imageNodes)
                {
                    XmlDocumentFragment fragment = xmlDocument.CreateDocumentFragment();

                    fragment.InnerXml =
                        $@"<WINDOWS>
                              <ARCH>{Architecture:D}</ARCH>
                              <PRODUCTNAME>{ProductName}</PRODUCTNAME>
                              <EDITIONID>{EditionId}</EDITIONID>
                              <INSTALLATIONTYPE>{InstallationType}</INSTALLATIONTYPE>
                              <PRODUCTTYPE>{ProductType}</PRODUCTTYPE>
                              <PRODUCTSUITE></PRODUCTSUITE>
                              <LANGUAGES>
                                <LANGUAGE>{Language}</LANGUAGE>
                                <DEFAULT>{DefaultLangauge}</DEFAULT>
                              </LANGUAGES>
                              <VERSION>
                                <MAJOR>{ProductVersion.Major}</MAJOR>
                                <MINOR>{ProductVersion.Minor}</MINOR>
                                <BUILD>{ProductVersion.Build}</BUILD>
                                <SPBUILD>{ProductVersion.Revision}</SPBUILD>
                                <SPLEVEL>{SpLevel}</SPLEVEL>
                              </VERSION>
                              <SYSTEMROOT>{SystemRoot}</SYSTEMROOT>
                            </WINDOWS>";

                    imageNode.AppendChild(fragment);

                    fragment.InnerXml = $@"<NAME>{ImageNamePrefix}{imageNode.Attributes["INDEX"].Value}</NAME>";

                    imageNode.AppendChild(fragment);

                    fragment.InnerXml = $@"<DESCRIPTION>{ImageNamePrefix}{imageNode.Attributes["INDEX"].Value}</DESCRIPTION>";

                    imageNode.AppendChild(fragment);

                    WimgApi.SetImageInformation(wimHandle, xmlDocument);
                }
            }

            return(imagePath);
        }
Пример #25
0
 public void CreateFileTest(WimCompressionType compressionType)
 {
     using (WimHandle wimHandle = WimgApi.CreateFile(CreateWimPath, WimFileAccess.Write, WimCreationDisposition.CreateAlways, WimCreateFileOptions.None, compressionType))
     {
     }
 }
Пример #26
0
        public bool ExportImage(
            string wimFile,
            string destinationWimFile,
            int imageIndex,
            IEnumerable <string> referenceWIMs         = null,
            WimCompressionType compressionType         = WimCompressionType.Lzx,
            IImaging.ProgressCallback progressCallback = null)
        {
            return(WIMLibImaging.ExportImage(wimFile,
                                             destinationWimFile,
                                             imageIndex,
                                             referenceWIMs,
                                             compressionType,
                                             progressCallback));

            string title = $"Exporting {wimFile.Split('\\').Last()} - Index {imageIndex}";

            try
            {
                WimMessageResult callback2(WimMessageType messageType, object message, object userData)
                {
                    switch (messageType)
                    {
                    case WimMessageType.Progress:
                    {
                        WimMessageProgress progressMessage = (WimMessageProgress)message;
                        progressCallback?.Invoke($"{title} (Estimated time remaining: {progressMessage.EstimatedTimeRemaining})", progressMessage.PercentComplete, false);
                        break;
                    }
                    }

                    return(WimMessageResult.Success);
                }

                using (var wimHandle = WimgApi.CreateFile(
                           wimFile,
                           WimFileAccess.Read,
                           WimCreationDisposition.OpenExisting,
                           WimCreateFileOptions.Chunked,
                           WimCompressionType.None))
                {
                    // Always set a temporary path
                    //
                    WimgApi.SetTemporaryPath(wimHandle, Environment.GetEnvironmentVariable("TEMP"));

                    if (referenceWIMs != null)
                    {
                        foreach (var referenceFile in referenceWIMs)
                        {
                            WimgApi.SetReferenceFile(wimHandle, referenceFile, WimSetReferenceMode.Append, WimSetReferenceOptions.Chunked);
                        }
                    }

                    // Register a method to be called while actions are performed by WIMGAPi for this .wim file
                    //
                    WimgApi.RegisterMessageCallback(wimHandle, callback2);

                    using (var newWimHandle = WimgApi.CreateFile(
                               destinationWimFile,
                               WimFileAccess.Write,
                               WimCreationDisposition.OpenAlways,
                               compressionType == WimCompressionType.Lzms ? WimCreateFileOptions.Chunked : WimCreateFileOptions.None,
                               compressionType))
                    {
                        // Always set a temporary path
                        //
                        WimgApi.SetTemporaryPath(newWimHandle, Environment.GetEnvironmentVariable("TEMP"));

                        // Register a method to be called while actions are performed by WIMGAPi for this .wim file
                        //
                        WimgApi.RegisterMessageCallback(newWimHandle, callback2);

                        try
                        {
                            using (WimHandle imageHandle = WimgApi.LoadImage(wimHandle, imageIndex))
                            {
                                var    wiminfo      = WimgApi.GetImageInformationAsString(imageHandle);
                                var    wiminfoclass = WIMInformationXML.DeserializeIMAGE(wiminfo);
                                string imagename    = wiminfoclass.DISPLAYNAME == null ? wiminfoclass.NAME : wiminfoclass.DISPLAYNAME;

                                title = $"Exporting {imagename} ({wimFile.Split('\\').Last()} - Index {imageIndex})";

                                // Export the image contents
                                // This call is blocking but WIMGAPI will be calling MyCallbackMethod() during the process
                                //
                                WimgApi.ExportImage(imageHandle, newWimHandle, WimExportImageOptions.AllowDuplicates);
                            }
                        }
                        finally
                        {
                            // Be sure to unregister the callback method
                            //
                            WimgApi.UnregisterMessageCallback(wimHandle, callback2);

                            // Be sure to unregister the callback method
                            //
                            WimgApi.UnregisterMessageCallback(newWimHandle, callback2);
                        }
                    }
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
        public void SelectEdition(string editionName)
        {
            if (SourceFile == "(use existing file)")
            {
                return;
            }
            if (SourceWIMMountPoint != null)
            {
                UnmountWIM();
            }
            if (SourceWIM != null)
            {
                int pos   = editionName.IndexOf("] ");
                int index = int.Parse(editionName.Substring(1, pos - 1));
                editionName = editionName.Substring(pos + 2);
                string wimTempFile = Path.GetTempFileName();
                SourceWIMMountPoint = wimTempFile + ".mountdir";
                Directory.CreateDirectory(wimTempFile + ".tempdir");
                Directory.CreateDirectory(SourceWIMMountPoint + @"\Windows\System32\Recovery");
                Directory.CreateDirectory(SourceWIMMountPoint + @"\Windows\Boot\resources");
                Directory.CreateDirectory(SourceWIMMountPoint + @"\Windows\Boot\fonts");
                Directory.CreateDirectory(SourceWIMMountPoint + @"\Windows\Boot\DVD\PCAT");
                Directory.CreateDirectory(SourceWIMMountPoint + @"\Windows\Boot\DVD\EFI");
                Directory.CreateDirectory(SourceWIMMountPoint + @"\Windows\Boot\PCAT");
                Directory.CreateDirectory(SourceWIMMountPoint + @"\Windows\Boot\EFI");
                using (WimHandle fullWIM = WimgApi.CreateFile(SourceWIM, WimFileAccess.Read | WimFileAccess.Mount, WimCreationDisposition.OpenExisting, WimCreateFileOptions.Chunked, WimCompressionType.None))
                {
                    WimgApi.SetTemporaryPath(fullWIM, wimTempFile + ".tempdir");
                    using (WimHandle singleWIM = WimgApi.LoadImage(fullWIM, index))
                    {
                        foreach (string filename in FILES_TO_COPY_FROM_WIM)
                        {
                            WimgApi.ExtractImagePath(singleWIM, filename, Path.Combine(SourceWIMMountPoint, filename));
                        }
                        foreach (string font in Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), @"Boot\fonts")))
                        {
                            try
                            {
                                WimgApi.ExtractImagePath(singleWIM, Path.Combine(@"Windows\Boot\fonts", Path.GetFileName(font)), Path.Combine(SourceWIMMountPoint, @"Windows\Boot\fonts", Path.GetFileName(font)));
                            }
                            catch { }
                        }
                        BootloaderSourceDirectory = Path.Combine(SourceWIMMountPoint, @"Windows\Boot");
                        SourceFile = Path.Combine(SourceWIMMountPoint, @"Windows\System32\Recovery\Winre.wim");
                    }
                }
            }

            // extract ntoskrnl.exe information
            bool            is64bit;
            FileVersionInfo kernelVersion;
            string          tempFile = Path.GetTempFileName();

            Directory.CreateDirectory(tempFile + ".tempdir");
            try
            {
                System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
                using (WimHandle fullWIM = WimgApi.CreateFile(SourceFile, WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.Chunked, WimCompressionType.None))
                {
                    WimgApi.SetTemporaryPath(fullWIM, tempFile + ".tempdir");
                    using (WimHandle singleWIM = WimgApi.LoadImage(fullWIM, 1))
                    {
                        WimgApi.ExtractImagePath(singleWIM, @"Windows\System32\ntoskrnl.exe", tempFile);
                        kernelVersion = FileVersionInfo.GetVersionInfo(tempFile);
                        try
                        {
                            WimgApi.ExtractImagePath(singleWIM, @"Program Files (x86)\desktop.ini", tempFile);
                            is64bit = true;
                        }
                        catch
                        {
                            is64bit = false;
                        }
                    }
                }
            }
            finally
            {
                Directory.Delete(tempFile + ".tempdir");
                File.Delete(tempFile);
            }

            // fill attributes
            int    buildVersion = kernelVersion.FileBuildPart, revisionVersion = kernelVersion.FilePrivatePart;
            string bitness = is64bit ? "64-Bit" : "32-Bit";

            BootMenuEntryName   = editionName + " Recovery " + buildVersion + "." + revisionVersion + " " + bitness + (SourceWIM == null ? " for " + Environment.MachineName : "");
            DestinationFileName = "recovery" + buildVersion + "." + revisionVersion + (is64bit ? "x64" : "x86") + (SourceWIM == null ? "_" + Environment.MachineName : "") + ".wim";
            VersionInfo         = buildVersion + "." + revisionVersion + " (" + bitness + ")";
            EfiSupported        = EfiUsed = is64bit &&
                                            (OverwriteBCD || File.Exists(Path.Combine(Drive.Name, @"efi\microsoft\boot\BCD"))) &&
                                            (OverwriteBootloader || File.Exists(Path.Combine(Drive.Name, @"efi\microsoft\boot\resources\bootres.dll")));
        }
Пример #28
0
        private void VerifyMountState(WimHandle imageHandle, WimMountPointState expectedMountPointState)
        {
            WimMountInfo mountedImageInfo = WimgApi.GetMountedImageInfoFromHandle(imageHandle);

            (mountedImageInfo.State | expectedMountPointState).ShouldBe(expectedMountPointState);
        }
Пример #29
0
        private string CaptureTemplateImage(string capturePath)
        {
            string imagePath = Path.Combine(_testWimTemplateDirectory, TestWimTemplateFilename);

            if (!Directory.Exists(capturePath))
            {
                throw new DirectoryNotFoundException(String.Format(CultureInfo.CurrentCulture, "Could not find part of the path '{0}'", capturePath));
            }

            XmlDocument xmlDocument = new XmlDocument();

            using (WimHandle wimHandle = WimgApi.CreateFile(imagePath, WimFileAccess.Write, WimCreationDisposition.CreateNew, WimCreateFileOptions.None, WimCompressionType.Lzx))
            {
                WimgApi.SetTemporaryPath(wimHandle, _testWimTempPath);

                for (int i = 0; i < ImageCount; i++)
                {
                    // ReSharper disable once UnusedVariable
                    using (WimHandle imageHandle = WimgApi.CaptureImage(wimHandle, capturePath, WimCaptureImageOptions.DisableDirectoryAcl | WimCaptureImageOptions.DisableFileAcl | WimCaptureImageOptions.DisableRPFix))
                    {
                    }
                }

                XPathNavigator xml = WimgApi.GetImageInformation(wimHandle).CreateNavigator();

                xml.ShouldNotBeNull();

                // ReSharper disable once PossibleNullReferenceException
                xmlDocument.LoadXml(xml.OuterXml);

                XmlNodeList imageNodes = xmlDocument.SelectNodes("//WIM/IMAGE");

                imageNodes.ShouldNotBeNull();

                // ReSharper disable once PossibleNullReferenceException
                foreach (XmlElement imageNode in imageNodes)
                {
                    XmlDocumentFragment fragment = xmlDocument.CreateDocumentFragment();

                    fragment.InnerXml =
                        @"<WINDOWS>
                              <ARCH>0</ARCH>
                              <PRODUCTNAME>Microsoft® Windows® Operating System</PRODUCTNAME>
                              <EDITIONID>WindowsPE</EDITIONID>
                              <INSTALLATIONTYPE>WindowsPE</INSTALLATIONTYPE>
                              <PRODUCTTYPE>WinNT</PRODUCTTYPE>
                              <PRODUCTSUITE></PRODUCTSUITE>
                              <LANGUAGES>
                                <LANGUAGE>en-US</LANGUAGE>
                                <DEFAULT>en-US</DEFAULT>
                              </LANGUAGES>
                              <VERSION>
                                <MAJOR>6</MAJOR>
                                <MINOR>3</MINOR>
                                <BUILD>9600</BUILD>
                                <SPBUILD>16384</SPBUILD>
                                <SPLEVEL>0</SPLEVEL>
                              </VERSION>
                              <SYSTEMROOT>WINDOWS</SYSTEMROOT>
                            </WINDOWS>";

                    imageNode.AppendChild(fragment);

                    fragment.InnerXml = $@"<NAME>Test Image {imageNode.Attributes["INDEX"].Value}</NAME>";

                    imageNode.AppendChild(fragment);

                    fragment.InnerXml = $@"<DESCRIPTION>Test Image {imageNode.Attributes["INDEX"].Value}</DESCRIPTION>";

                    imageNode.AppendChild(fragment);

                    WimgApi.SetImageInformation(wimHandle, xmlDocument);
                }
            }

            return imagePath;
        }
Пример #30
0
        public static List <LogInfo> WimMount(EngineState s, CodeCommand cmd)
        {
            List <LogInfo> logs = new List <LogInfo>(1);

            Debug.Assert(cmd.Info.GetType() == typeof(CodeInfo_WimMount));
            CodeInfo_WimMount info = cmd.Info as CodeInfo_WimMount;

            string srcWim        = StringEscaper.Preprocess(s, info.SrcWim);
            string imageIndexStr = StringEscaper.Preprocess(s, info.ImageIndex);
            string mountDir      = StringEscaper.Preprocess(s, info.MountDir);

            // Check srcWim
            if (!File.Exists(srcWim))
            {
                logs.Add(new LogInfo(LogState.Error, $"File [{srcWim}] does not exist"));
                return(logs);
            }

            // Check MountDir
            if (StringEscaper.PathSecurityCheck(mountDir, out string errorMsg) == false)
            {
                logs.Add(new LogInfo(LogState.Error, errorMsg));
                return(logs);
            }

            if (!Directory.Exists(mountDir))
            {
                logs.Add(new LogInfo(LogState.Error, $"Directory [{mountDir}] does not exist"));
                return(logs);
            }

            // Check imageIndex
            int imageCount = 0;

            try
            {
                using (WimHandle hWim = WimgApi.CreateFile(srcWim,
                                                           WimFileAccess.Query,
                                                           WimCreationDisposition.OpenExisting,
                                                           WimCreateFileOptions.None,
                                                           WimCompressionType.None))
                {
                    WimgApi.SetTemporaryPath(hWim, Path.GetTempPath());
                    imageCount = WimgApi.GetImageCount(hWim);
                }
            }
            catch (Win32Exception e)
            {
                logs.Add(new LogInfo(LogState.Error, $"Unable to get information of [{srcWim}]\r\nError Code [0x{e.ErrorCode:X8}]\r\nNative Error Code [0x{e.NativeErrorCode:X8}]\r\n"));
                return(logs);
            }

            if (!NumberHelper.ParseInt32(imageIndexStr, out int imageIndex))
            {
                logs.Add(new LogInfo(LogState.Error, $"[{imageIndexStr}] is not a valid a positive integer"));
                return(logs);
            }

            if (!(1 <= imageIndex && imageIndex <= imageCount))
            {
                logs.Add(new LogInfo(LogState.Error, $"[{imageIndexStr}] must be [1] ~ [{imageCount}]"));
                return(logs);
            }

            // Mount Wim
            try
            {
                using (WimHandle hWim = WimgApi.CreateFile(srcWim,
                                                           WimFileAccess.Mount | WimFileAccess.Read,
                                                           WimCreationDisposition.OpenExisting,
                                                           WimCreateFileOptions.None,
                                                           WimCompressionType.None))
                {
                    WimgApi.SetTemporaryPath(hWim, Path.GetTempPath());
                    WimgApi.RegisterMessageCallback(hWim, WimgApiCallback);
                    try
                    {
                        using (WimHandle hImage = WimgApi.LoadImage(hWim, imageIndex))
                        {
                            s.MainViewModel.BuildCommandProgressTitle = "WimMount Progress";
                            s.MainViewModel.BuildCommandProgressText  = string.Empty;
                            s.MainViewModel.BuildCommandProgressMax   = 100;
                            s.MainViewModel.BuildCommandProgressShow  = true;

                            // Mount Wim
                            WimgApi.MountImage(hImage, mountDir, WimMountImageOptions.ReadOnly);
                        }
                    }
                    finally
                    {
                        s.MainViewModel.BuildCommandProgressShow  = false;
                        s.MainViewModel.BuildCommandProgressTitle = "Progress";
                        s.MainViewModel.BuildCommandProgressText  = string.Empty;
                        s.MainViewModel.BuildCommandProgressValue = 0;
                        WimgApi.UnregisterMessageCallback(hWim, WimgApiCallback);
                    }
                }
            }
            catch (Win32Exception e)
            {
                logs.Add(new LogInfo(LogState.Error, $"Unable to mount [{srcWim}]\r\nError Code [0x{e.ErrorCode:X8}]\r\nNative Error Code [0x{e.NativeErrorCode:X8}]\r\n"));
                return(logs);
            }

            logs.Add(new LogInfo(LogState.Success, $"[{srcWim}]'s image [{imageIndex}] mounted to [{mountDir}]"));
            return(logs);
        }