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 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); }
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(); } } }); }
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); }
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)); } }
public void ExtractImagePathTest_ThrowsArgumentNullException_destinationFile() { using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1)) { WimHandle imageHandleCopy = imageHandle; ShouldThrow <ArgumentNullException>("destinationFile", () => WimgApi.ExtractImagePath(imageHandleCopy, "", null)); } }
public void MountImageHandleTest_ThrowsArgumentNullException_mountPath() { using (WimHandle imageHandle = WimgApi.LoadImage(TestWimHandle, 1)) { WimHandle imageHandleCopy = imageHandle; ShouldThrow <ArgumentNullException>("mountPath", () => WimgApi.MountImage(imageHandleCopy, null, WimMountImageOptions.None)); } }
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)); } }
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; } } }
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 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 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); }
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 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); } } }
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); }
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 void CreateFileTest(WimCompressionType compressionType) { using (WimHandle wimHandle = WimgApi.CreateFile(CreateWimPath, WimFileAccess.Write, WimCreationDisposition.CreateAlways, WimCreateFileOptions.None, compressionType)) { } }
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"))); }
private void VerifyMountState(WimHandle imageHandle, WimMountPointState expectedMountPointState) { WimMountInfo mountedImageInfo = WimgApi.GetMountedImageInfoFromHandle(imageHandle); (mountedImageInfo.State | expectedMountPointState).ShouldBe(expectedMountPointState); }
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 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); }