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); }
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); }
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); }
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); } } } }
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 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; } } }
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); } } }
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); } } }
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); }
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); }
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); } } }
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); }
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); }
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); }
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); }
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); }
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; }
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); }
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 CreateFileTest_ThrowsArgumentNullException_path() { ShouldThrow <ArgumentNullException>("path", () => WimgApi.CreateFile(null, WimFileAccess.Read, WimCreationDisposition.OpenExisting, WimCreateFileOptions.None, WimCompressionType.None)); }
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"))); }
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); }
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); }