Skip to content

Instantly share code, notes, and snippets.

@sayurin
Last active September 21, 2022 07:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sayurin/ea78ece46350214f8773 to your computer and use it in GitHub Desktop.
Save sayurin/ea78ece46350214f8773 to your computer and use it in GitHub Desktop.
ISO image creator
using System;
using System.Runtime.InteropServices;
using IMAPI2FS; // COM reference: Microsoft IMAPI2 File System Image Creator
using IStream = System.Runtime.InteropServices.ComTypes.IStream;
class IsoImage {
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
static extern void SHCreateStreamOnFile(string pszFile, uint grfMode, out IStream ppstm);
static void Main(string[] args) {
var isoPath = args[0];
var volumeName= args[1];
var path = args[2];
// same as Activator.CreateInstance(Type.GetTypeFromProgID("IMAPI2FS.MsftFileSystemImage"))
var image = (IFileSystemImage)new MsftFileSystemImage();
image.ChooseImageDefaultsForMediaType(IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK);
image.FileSystemsToCreate = FsiFileSystems.FsiFileSystemJoliet | FsiFileSystems.FsiFileSystemISO9660;
image.VolumeName = volumeName;
image.Root.AddTree(path, false);
var resultImage = image.CreateResultImage();
var inStream = (IStream)resultImage.ImageStream;
SHCreateStreamOnFile(isoPath, 0x00001001, out var outStream);
inStream.CopyTo(outStream, (long)resultImage.TotalBlocks * resultImage.BlockSize, IntPtr.Zero, IntPtr.Zero);
outStream.Commit(0);
}
}
open System
open System.IO
open System.Runtime.InteropServices
open System.Runtime.InteropServices.ComTypes
type IMAPI_MEDIA_PHYSICAL_TYPE =
| IMAPI_MEDIA_TYPE_UNKNOWN = 0x00
| IMAPI_MEDIA_TYPE_CDROM = 0x01
| IMAPI_MEDIA_TYPE_CDR = 0x02
| IMAPI_MEDIA_TYPE_CDRW = 0x03
| IMAPI_MEDIA_TYPE_DVDROM = 0x04
| IMAPI_MEDIA_TYPE_DVDRAM = 0x05
| IMAPI_MEDIA_TYPE_DVDPLUSR = 0x06
| IMAPI_MEDIA_TYPE_DVDPLUSRW = 0x07
| IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER = 0x08
| IMAPI_MEDIA_TYPE_DVDDASHR = 0x09
| IMAPI_MEDIA_TYPE_DVDDASHRW = 0x0A
| IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER = 0x0B
| IMAPI_MEDIA_TYPE_DISK = 0x0C
| IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER = 0x0D
| IMAPI_MEDIA_TYPE_HDDVDROM = 0x0E
| IMAPI_MEDIA_TYPE_HDDVDR = 0x0F
| IMAPI_MEDIA_TYPE_HDDVDRAM = 0x10
| IMAPI_MEDIA_TYPE_BDROM = 0x11
| IMAPI_MEDIA_TYPE_BDR = 0x12
| IMAPI_MEDIA_TYPE_BDRE = 0x13
| IMAPI_MEDIA_TYPE_MAX = 0x13
type FsiFileSystems =
| FsiFileSystemNone = 0
| FsiFileSystemISO9660 = 1
| FsiFileSystemJoliet = 2
| FsiFileSystemUDF = 4
| FsiFileSystemUnknown = 0x40000000
[<ComImport; Guid "2C941FDC-975B-59BE-A960-9A2A262853A5"; InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>]
type IFsiDirectoryItem =
// inherit IFsiItem
// IFsiDirectoryItem
[<DispId 32>] abstract member AddTree : sourceDirectory : string * includeBaseDirectory : bool -> unit
[<ComImport; Guid "2C941FD8-975B-59BE-A960-9A2A262853A5"; InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>]
type IFileSystemImageResult =
[<DispId 1>] abstract member ImageStream : IStream
[<DispId 3>] abstract member TotalBlocks : int
[<DispId 4>] abstract member BlockSize : int
[<ComImport; Guid "2C941FE1-975B-59BE-A960-9A2A262853A5"; InterfaceType(ComInterfaceType.InterfaceIsIDispatch)>]
type IFileSystemImage =
[<DispId 0>] abstract member Root : IFsiDirectoryItem
[<DispId 4>] abstract member VolumeName : string with get, set
[<DispId 13>] abstract member FileSystemsToCreate : FsiFileSystems with get, set
[<DispId 15>] abstract member CreateResultImage : [<Out>] resultStream : IFileSystemImageResult byref -> unit
[<DispId 33>] abstract member ChooseImageDefaultsForMediaType : value : IMAPI_MEDIA_PHYSICAL_TYPE -> unit
[<DllImport("shlwapi.dll", CharSet = CharSet.Unicode, PreserveSig = true)>]
extern void SHCreateStreamOnFile(string pszFile, uint32 grfMode, [<Out>] IStream& ppstm);
let isoPath, volumeName, path = fsi.CommandLineArgs.[1], fsi.CommandLineArgs.[2], fsi.CommandLineArgs.[3]
let image = Activator.CreateInstance(Type.GetTypeFromProgID "IMAPI2FS.MsftFileSystemImage") :?> IFileSystemImage
image.ChooseImageDefaultsForMediaType IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK
image.FileSystemsToCreate <- FsiFileSystems.FsiFileSystemJoliet ||| FsiFileSystems.FsiFileSystemISO9660
image.VolumeName <- volumeName
image.Root.AddTree(path, false)
let resultImage = image.CreateResultImage()
let mutable outStream = null
SHCreateStreamOnFile(isoPath, 0x00001001u, &outStream)
resultImage.ImageStream.CopyTo(outStream, int64 resultImage.TotalBlocks * int64 resultImage.BlockSize, 0n, 0n)
outStream.Commit 0
using System;
using System.Runtime.InteropServices;
using IStream = System.Runtime.InteropServices.ComTypes.IStream;
class IsoImage {
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
static extern void SHCreateStreamOnFile(string pszFile, uint grfMode, out IStream ppstm);
static void Main(string[] args) {
var isoPath = args[0];
var volumeName= args[1];
var path = args[2];
dynamic image = Activator.CreateInstance(Type.GetTypeFromProgID("IMAPI2FS.MsftFileSystemImage"));
image.ChooseImageDefaultsForMediaType(12/*IMAPI_MEDIA_TYPE_DISK*/);
image.FileSystemsToCreate = 3/*FsiFileSystemJoliet | FsiFileSystemISO9660*/;
image.VolumeName = volumeName;
image.Root.AddTree(path, false);
var resultImage = image.CreateResultImage();
IStream inStream = resultImage.ImageStream;
SHCreateStreamOnFile(isoPath, 0x00001001, out var outStream);
inStream.CopyTo(outStream, (long)resultImage.TotalBlocks * (long)resultImage.BlockSize, IntPtr.Zero, IntPtr.Zero);
outStream.Commit(0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment