Click here to Skip to main content
Click here to Skip to main content

Serve Customized .ISO files from ASP.NET

, 20 Dec 2008
Rate this:
Please Sign up or sign in to vote.
An article on embedding download-specific license information or configuration in customized ISO files.

Introduction

This article describes how, using the DiscUtils library from CodePlex, you can serve up customized ISO files from a website.

Background

I've been working on the DiscUtils library for a couple of months, and I thought it would be a good idea to show how it can be used in practice. CodeProject seemed like the ideal place to expose some of the capabilities of the DiscUtils library.

DiscUtils itself provides an Open Source library for creating, reading, and modifying various disk image formats, including .ISOs. The DiscUtils library is implemented in pure C# (no P/Invoke or COM Interop), and doesn't load the entire disk image into memory, so has a relatively small memory footprint. This makes it perfect for use in websites. This article describes one such use of the library, to create .ISO images on request using ASP.NET. Specifically, the code injects a mock license file into the ISOs - but any kind of image customization is possible.

Using the Code

The code is a very simple ASP.NET website, created in Visual Web Developer 2008 Express Edition. I've re-arranged the project files slightly, so they exist in a single directory hierarchy.

The interesting code is in CreateISO.ashx. There is a using statement to pull in the DiscUtils.Iso9660 namespace (the DLL itself is placed in the Bin folder of the solution). The ProcessRequest method creates the ISO file; first, the CD Builder is initialized:

CDBuilder builder = new CDBuilder();
builder.UseJoliet = true;
builder.VolumeIdentifier = "GENERATED_CD";

Enabling Joliet is recommended (permits long file names), and the Volume Identifier can be set to any string (subject to constraints of the ISO 9660 specification).

Next, the contents of the CD need to be specified. In this case, we include all files from the ~/App_Data/CDRoot folder:

DirectoryInfo di = new DirectoryInfo(context.Server.MapPath("~/App_Data/CDRoot"));
PopulateFromFolder(builder, di, di.FullName);

The PopulateFromFolder method is defined later in the file - it simply recurses through the directory structure, adding any files found to the ISO image:

public static void PopulateFromFolder(CDBuilder builder, 
                   DirectoryInfo di, string basePath)
{
    foreach (FileInfo file in di.GetFiles())
    {
        builder.AddFile(file.FullName.Substring(basePath.Length), file.FullName);
    }

    foreach (DirectoryInfo dir in di.GetDirectories())
    {
        PopulateFromFolder(builder, dir, basePath);
    }
}

After populating the ISO image with all of the 'normal' files from the disk, it's time to customize the image. Here, we're simply creating a new file 'LICENSE.LIC' that contains some dummy licensing information. You could customize the ISO image in any way you choose.

MemoryStream ms = new MemoryStream();
StreamWriter writer = new StreamWriter(ms, Encoding.ASCII);
writer.WriteLine("LICENSE FILE");
writer.WriteLine("Issued By: Acme, Inc.");
writer.WriteLine("Issued On: " + DateTime.UtcNow);
writer.Flush();
builder.AddFile("LICENSE.LIC", ms.GetBuffer());

Next, the HTTP headers are set. Since there is no registered Internet Media Type for ISO images, application/octet-stream is used. The Content-Disposition header instructs Internet Explorer to offer a 'Save As...' dialog box, and also provides the default file name for the ISO file.

context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("Content-Disposition", 
        "attachment; filename=newiso.iso");

Finally, the ISO image is finalized using Build(), and we simply pump the data from the resulting stream to the HTTP response stream.

Stream cdStream = builder.Build();
byte[] buffer = new byte[64 * 1024];
int numBytes = cdStream.Read(buffer, 0, buffer.Length);
while (numBytes != 0)
{
    context.Response.OutputStream.Write(buffer, 0, numBytes);
    numBytes = cdStream.Read(buffer, 0, buffer.Length);
}

Points of Interest

This article illustrates that you can create ISO images using the DiscUtils library either from existing files, or by providing a byte array. You can also supply a Stream instance.

The DiscUtils library doesn't currently support El Torito format, so it isn't suitable for projects where you need to provide a bootable CD.

If you find any bugs or problems with the code in this article, please post comments below. If the problem is with the DiscUtils library, please post an Issue on the CodePlex project.

History

None (yet).

License

This article, along with any associated source code and files, is licensed under The MIT License

About the Author

festive_ken
Software Developer (Senior)
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
GeneralGreat job PinmemberBill Seddon22-Dec-08 23:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 20 Dec 2008
Article Copyright 2008 by festive_ken
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid