Ejemplo n.º 1
0
        private bool ReseatWIMXml(string wimFile)
        {
            try
            {
                using (var wimHandle = WimgApi.CreateFile(
                           wimFile,
                           WimFileAccess.Write,
                           WimCreationDisposition.OpenExisting,
                           WimCreateFileOptions.Chunked,
                           WimCompressionType.None))
                {
                    // Always set a temporary path
                    //
                    WimgApi.SetTemporaryPath(wimHandle, Environment.GetEnvironmentVariable("TEMP"));

                    string xmldata = WimgApi.GetImageInformationAsString(wimHandle);
                    var    xml     = WIMInformationXML.DeserializeWIM(xmldata);
                    xmldata = WIMInformationXML.SerializeWIM(xml);
                    WimgApi.SetImageInformation(wimHandle, xmldata);
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
Ejemplo n.º 2
0
        public static ObservableCollection <_WimImage> GetWIM(string filePath)
        {
            //Check registry first then return;


            var images = new ObservableCollection <_WimImage>();

            using (
                var handle = WimgApi.CreateFile(filePath, WimFileAccess.Read, WimCreationDisposition.OpenExisting,
                                                WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(handle, Environment.GetEnvironmentVariable("TEMP"));
                var result = WimgApi.GetImageInformation(handle);

                var xParent  = (XElement)result.FirstNode;
                var xElement = xParent.Element("TOTALBYTES");
                if (xElement == null)
                {
                    throw new Exception("Invalid WIM File.");
                }

                foreach (var xImage in xParent.Elements().Skip(1))
                {
                    var WI = new WimImage(xImage, filePath);
                    images.Add(WI);
                }
            }
            return(images);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
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);
                    }
                }
            }
        }
Ejemplo n.º 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);
                }
            }
        }
Ejemplo n.º 6
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);
        }
 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;
         }
     }
 }
Ejemplo n.º 8
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);
                }
            }
        }
Ejemplo n.º 9
0
        public void SetReferenceFileTest()
        {
            var splitWims = CreateSplitWim().ToArray();

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

                foreach (var referenceFile in splitWims.Skip(1))
                {
                    WimgApi.SetReferenceFile(wimHandle, referenceFile, WimSetReferenceMode.Append, WimSetReferenceOptions.None);
                }
            }
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
0
        public void ExportImageTest()
        {
            var exportWimPath = Path.Combine(TestContext.CurrentContext.WorkDirectory, "export.wim");

            using (var imageHandle = WimgApi.LoadImage(TestWimHandle, 1))
            {
                using (var 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);
        }
Ejemplo n.º 12
0
        private void ApplyImage()
        {
            using (var wimHandle = WimgApi.CreateFile(WimPath, WimFileAccess.Read, WimCreationDisposition.OpenExisting,
                                                      WimCreateFileOptions.None, WimCompressionType.None))
            {
                WimgApi.SetTemporaryPath(wimHandle, Path.GetTempPath());

                var loadImageIndex   = 1;
                var imageInformation = WimgApi.GetImageInformation(wimHandle).CreateNavigator();
                if (imageInformation == null)
                {
                    throw new NullReferenceException("Unable to get Image Information");
                }

                var imageCount = WimgApi.GetImageCount(wimHandle);
                if (imageCount > 1 && !string.IsNullOrWhiteSpace(Edition))
                {
                    loadImageIndex = 1;
                }

                var xpath         = string.Format("//WIM/IMAGE[@INDEX={0}]/NAME", loadImageIndex);
                var imageNameNode = imageInformation.SelectSingleNode(xpath);
                if (imageNameNode == null)
                {
                    throw new InvalidDataException("Unable to read WIM image name");
                }

                _progressRecord = new ProgressRecord(0, string.Format("Applying Windows Image - {0}", imageNameNode.TypedValue), "Starting");

                WimgApi.RegisterMessageCallback(wimHandle, MessageCallback);

                try
                {
                    using (var imageHandle = WimgApi.LoadImage(wimHandle, loadImageIndex))
                        WimgApi.ApplyImage(imageHandle, TargetPath, WimApplyImageOptions.None);
                }
                finally
                {
                    _autoResetEvent.Set();
                    WimgApi.UnregisterMessageCallback(wimHandle, MessageCallback);
                }
            }
        }
Ejemplo n.º 13
0
        public void ApplyImageTest_NoApply()
        {
            WimMessageCallback messageCallback = (messageType, message, userData) =>
            {
                if (messageType == WimMessageType.SetRange)
                {
                    _noApplyFileCount = ((WimMessageSetRange)message).FileCount;
                }

                return(WimMessageResult.Done);
            };

            var applyPath = Path.Combine(TestContext.CurrentContext.WorkDirectory, "Apply");

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

                WimgApi.RegisterMessageCallback(wimHandle, messageCallback);

                try
                {
                    using (var imageHandle = WimgApi.LoadImage(wimHandle, 1))
                    {
                        WimgApi.ApplyImage(imageHandle, applyPath, WimApplyImageOptions.NoApply);
                    }
                }
                finally
                {
                    WimgApi.UnregisterMessageCallback(wimHandle, messageCallback);
                }
            }

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

            fileCount.ShouldBe(0);

            _noApplyFileCount.ShouldBe(TestWimFileCount);
        }
Ejemplo n.º 14
0
        public bool GetWIMInformation(
            string wimFile,
            out WIMInformationXML.WIM wim)
        {
            wim = 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
                    {
                        var wiminfo = WimgApi.GetImageInformationAsString(wimHandle);
                        wim = WIMInformationXML.DeserializeWIM(wiminfo);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message + " - " + ex.ToString());
                    }
                    finally
                    {
                    }
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
Ejemplo n.º 15
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);
        }
Ejemplo n.º 16
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);
        }
Ejemplo n.º 17
0
        public bool MarkImageAsBootable(string wimFile, int imageIndex)
        {
            using (var wimHandle = WimgApi.CreateFile(
                       wimFile,
                       WimFileAccess.Write,
                       WimCreationDisposition.OpenExisting,
                       WimCreateFileOptions.None,
                       WimCompressionType.None))
            {
                // Always set a temporary path
                //
                WimgApi.SetTemporaryPath(wimHandle, Environment.GetEnvironmentVariable("TEMP"));

                try
                {
                    WimgApi.SetBootImage(wimHandle, imageIndex);
                }
                catch
                {
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 18
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;
        }
Ejemplo n.º 19
0
        public bool CaptureImage(
            string wimFile,
            string imageName,
            string imageDescription,
            string imageFlag,
            string InputDirectory,
            string imageDisplayName                    = null,
            string imageDisplayDescription             = null,
            WIMInformationXML.WINDOWS windows          = null,
            WimCompressionType compressionType         = WimCompressionType.Lzx,
            WimCaptureImageOptions addFlags            = WimCaptureImageOptions.None,
            IImaging.ProgressCallback progressCallback = null)
        {
            string title = $"Creating {imageName} ({wimFile.Split('\\').Last()})";

            try
            {
                int directoriesScanned = 0;
                int filesScanned       = 0;

                WimMessageResult callback2(WimMessageType messageType, object message, object userData)
                {
                    switch (messageType)
                    {
                    case WimMessageType.Process:
                    {
                        WimMessageProcess processMessage = (WimMessageProcess)message;
                        if (processMessage.Path.StartsWith(Path.Combine(InputDirectory.EndsWith(":") ? InputDirectory + @"\" : InputDirectory, @"System Volume Information"), StringComparison.InvariantCultureIgnoreCase))
                        {
                            processMessage.Process = false;
                        }
                        break;
                    }

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

                    case WimMessageType.Scanning:
                    {
                        WimMessageScanning scanningMessage = (WimMessageScanning)message;

                        switch (scanningMessage.CountType)
                        {
                        case WimMessageScanningType.Directories:
                        {
                            directoriesScanned = scanningMessage.Count;
                            break;
                        }

                        case WimMessageScanningType.Files:
                        {
                            filesScanned = scanningMessage.Count;
                            break;
                        }
                        }

                        progressCallback?.Invoke($"Scanning objects ({filesScanned} files, {directoriesScanned} directories scanned)", 0, true);
                        break;
                    }
                    }

                    return(WimMessageResult.Success);
                }

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

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

                    try
                    {
                        using (var imagehandle = WimgApi.CaptureImage(wimHandle, InputDirectory, addFlags))
                        {
                            var wiminfo      = WimgApi.GetImageInformationAsString(imagehandle);
                            var wiminfoclass = WIMInformationXML.DeserializeIMAGE(wiminfo);
                            if (!string.IsNullOrEmpty(imageFlag))
                            {
                                wiminfoclass.FLAGS = imageFlag;
                            }
                            if (!string.IsNullOrEmpty(imageName))
                            {
                                wiminfoclass.NAME = imageName;
                            }
                            if (!string.IsNullOrEmpty(imageDescription))
                            {
                                wiminfoclass.DESCRIPTION = imageDescription;
                            }
                            if (!string.IsNullOrEmpty(imageDisplayName))
                            {
                                wiminfoclass.DISPLAYNAME = imageDisplayName;
                            }
                            if (!string.IsNullOrEmpty(imageDisplayDescription))
                            {
                                wiminfoclass.DISPLAYDESCRIPTION = imageDisplayDescription;
                            }
                            if (windows != null)
                            {
                                wiminfoclass.WINDOWS = windows;
                            }

                            wiminfo = WIMInformationXML.SerializeIMAGE(wiminfoclass);
                            WimgApi.SetImageInformation(imagehandle, wiminfo);
                        }
                    }
                    finally
                    {
                        // Be sure to unregister the callback method
                        //
                        WimgApi.UnregisterMessageCallback(wimHandle, callback2);
                    }
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
Ejemplo n.º 20
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);
        }
Ejemplo n.º 21
0
 public void CreateFileTest_ThrowsArgumentNullException_path()
 {
     ShouldThrow <ArgumentNullException>("path", () =>
                                         WimgApi.CreateFile(null, WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None));
 }
Ejemplo n.º 22
0
 public void CreateFileTest(WimCompressionType compressionType)
 {
     using (WimHandle wimHandle = WimgApi.CreateFile(CreateWimPath, WimFileAccess.Write, WimCreationDisposition.CreateAlways, WimCreateFileOptions.None, compressionType))
     {
     }
 }
        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")));
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 25
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);
        }