none
How to create .ISO image file

    Question

  • I want to create an .ISO file instead of burning an image to disc.  These are the steps I'm assuming I should take:

    1. CoCreateInstance to obtain an IFileSystemImage object
    2. Add files/folders to the image using IFsiDirectoryItem and IFsiFileItem
    3. Call IFileSystemImage::CreateResultImage to obtain an IFileSystemImageResult object
    4. Call IFileSystemImageResult::get_ImageStream to obtain an IStream object
    5. Call ::SHCreateStreamOnFile to create the new .ISO file, and obtain a second IStream object
    6. Use IStream::CopyTo to copy data from the stream obtained in step 4 to the stream obtained in step 5

    Are there any problems with these steps?  Any potential pitfalls I should be aware of?  The Win32 documentation states that the IStream interface defines 64-bit stream sizes, but the COM implementation only supports streams up to 4 GB  (32-bit).  If this is the case, is there another recommended method?

    Friday, August 18, 2006 9:00 PM

Answers

  • Hi Caliendo,

    I think I see the confusion.  The MSDN article you point to refers to a specific implementation of the IStream interface, namely that implemented by the compound storage stuff.  I don't know too much about that implementation, but since IMAPIv2 streams are not structured storage, please accept my assurances that >4GB is no problem with streams created via IMAPIv2.

    I just re-checked the source; Sure enough, the File System stream does support the CopyTo() method.  As long as you don't mind the API call taking a significant time (4GB is a lot to copy) without progress notifications, then you absolultely can use this API.

    Please note that, although the FSI object's resulting IStream does implement this function, the MsftStreamConcatenate, MsftStreamInterleave, MsftStreamPrng001, and MsftStreamZero classes do not implement the CopyTo() function.

    Special suggestions for creating an ISO image:

    * Don't call FSI->ImportFileSystem() nor FSI->put_SessionStartBlock() -- they don't make sense for ISO images.

    * DO call FSI->ChooseImageDefaultsForMediaType() and FSI->put_FreeMediaBlocks() if you want to target a specific type of media (i.e. CD-R media).

    * DO call FSI->put_StageFiles(VARIANT_TRUE) if you can ensure the source files won't change.  This is currently E_NOTIMPL, but will eventually result in one less copy of the data.

    That's all the special bits I'd suggest.  Others might have additional suggestions.

    Let us know how you like it overall....

     

    Henry Gabryjelski

    Tuesday, August 22, 2006 4:10 PM

All replies

  • Hi Caliendo,

    Yes!  IMAPIv2's design is specifically intended to allow creation of ISO images!  Your steps are theoretically correct, but they require that CopyTo() is implemented.  However, IMAPIv2 does not implement the CopyTo() method on any of the IStream objects it creates. Steps 1-5 need not change, but you would need to manually implement a CopyTo() style method.

    Can you help me understand why you think the COM implementation only supports stream sizes up to 4GB in size?  From my looking at this, the Stat() method of IStream reports a 64-bit stream size.  Each individual Read() call is limited in size, but given that you can Seek() to any point in many streams (and Read() forward for sequential streams), I don't understand what limitation exists to limit IStreams to 4GB.

    I hope this helps,

    Henry Gabryjelski

    Monday, August 21, 2006 4:11 PM
  • Since I couldn't find a method for creating an ISO image specifically described in the online documentation, I tried to fabricate one using the IMAPIv2 interfaces.  The steps outlined in my original post was what I came up with.  However, when I read the following article about a 4GB stream limit, I thought my solution could not be correct, since .ISO images could easily exceed 4GB:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/stg/stg/istream_compound_file_implementation.asp

    So I thought certainly there must be another way to accomplish this using IMAPIv2.  Hence my post.

    I'm not sure why you say that IMAPIv2 does not implement the CopyTo method on any of the IStream objects it creates.  Following the steps I outlined in my original post, I was able to successfully create an ISO image greater than 4GB using the CopyTo method off the IStream pointer returned from IFileSystemImageResult::get_ImageStream.  (I obtained the target stream from SHCreateStreamOnFile). I also copied all the data with a single call to CopyTo, specifiying the size obtained from IStream::Stat.  (So the MSDN documentation is either incorrect or obsolete).  The image burned to disc successfully.

    For now, can you offer any special instructions or caveats when creating the .ISO image?

    Monday, August 21, 2006 8:29 PM
  • Hi Caliendo,

    I think I see the confusion.  The MSDN article you point to refers to a specific implementation of the IStream interface, namely that implemented by the compound storage stuff.  I don't know too much about that implementation, but since IMAPIv2 streams are not structured storage, please accept my assurances that >4GB is no problem with streams created via IMAPIv2.

    I just re-checked the source; Sure enough, the File System stream does support the CopyTo() method.  As long as you don't mind the API call taking a significant time (4GB is a lot to copy) without progress notifications, then you absolultely can use this API.

    Please note that, although the FSI object's resulting IStream does implement this function, the MsftStreamConcatenate, MsftStreamInterleave, MsftStreamPrng001, and MsftStreamZero classes do not implement the CopyTo() function.

    Special suggestions for creating an ISO image:

    * Don't call FSI->ImportFileSystem() nor FSI->put_SessionStartBlock() -- they don't make sense for ISO images.

    * DO call FSI->ChooseImageDefaultsForMediaType() and FSI->put_FreeMediaBlocks() if you want to target a specific type of media (i.e. CD-R media).

    * DO call FSI->put_StageFiles(VARIANT_TRUE) if you can ensure the source files won't change.  This is currently E_NOTIMPL, but will eventually result in one less copy of the data.

    That's all the special bits I'd suggest.  Others might have additional suggestions.

    Let us know how you like it overall....

     

    Henry Gabryjelski

    Tuesday, August 22, 2006 4:10 PM
  • I'm confused about FSI->put_StageFiles.  It currently returns E_NOTIMPL, regardless whether you pass VARIANT_TRUE or VARIANT_FALSE as a parameter.  What do you mean when you say it will eventually result in one less copy of the data?  Are you planning on implementing this method before RTM?

    Currently, it looks like IMAPI stages everything, so there's always a copy of the image in the staging folder.  In order to create an .ISO file, I am currently copying the data from the IFileSystemImageResult stream to a file stream using multiple calls to CopyTo (only so I can implement my own progress bar).  The problem with this method is I ultimately have two images taking up space on the hard drive at the same time (the temporary one created by IFileSystemImage and the keeper in my .ISO file), and it takes twice as long to create the image.  It would be nice if I could somehow take the stage file created by IFileSystemImage and rename it to .ISO (assuming it is an .ISO image).  Is there any way to accomplish this?

    Maybe if I explain what I'm trying to do, it will help:

    I have a list of files (and an optional boot image) that I want to record to disc.  Instead of burning directly to disc, however, I want to create an .ISO file first, then later record the .ISO image to disc (end result should be the same).  I am currently using a third-party recording SDK to accomplish this.  The only thing I'm doing prior to saving the image is setting the file system to UDF for DVD images and Joliet for other media types.  Other than whether the target media is DVD, I don't know what specific media type the .ISO image will be recorded to.  (I'm assuming the caller worries about disc capacity, and won't try to create an .ISO image that is too large to fit on the intended media).

    So now I want to leverage the native recording capabilities provided by Vista via IMAPIv2 to accomplish the same task.  I can't simply call FSI->ChooseImageDefaultsForMedia, because there is no media in the drive.  So I have to manually call the individual methods to set the appropriate settings.  My goal, of course, is to produce an .ISO image that will record correctly to the intended media, even though I don't know what media that is.  What are the minimum bits of information I need to know about the media to produce a valid image?  Is it sufficient simply to know whether the media is DVD so I can set the correct file system, or are there other settings I need to be concerned with?  (Again, assume the caller worries about disc capacity).

    P.S.  I am assured that the files won't change.

    • Proposed as answer by Vasant12 Tuesday, April 05, 2011 7:30 PM
    Tuesday, August 22, 2006 7:38 PM
  • Hello Caliendo,

    Please see my other thread for a more complete answer to the StageFiles property.  We realize this double copying is a problem and that was why we chose to include this interface in our initial release even though we don't support the functionality yet.  This way, clients can use the interface properly and when IMAPI begins to support the feature, it will "just work".  Unfortunately, it will not make it into the product in the RTM timeframe, but we would like to include it in a future release.

    As for the minimum bits needed to product a valid image: you are correct.  If you are not worried about disc capacity, you just want to (a) set the image size to be large (so the filesystem doesn't reject files inappropriately) and (b) select the correct filesystems.

    Please let me know if you have any further questions!

    thanks,

    Garrett Jacobson
    SDE, Optical Platform Group

    Tuesday, August 29, 2006 12:30 AM
  • hi i wish i get help it's been days searching and i got no clue
    i'm doin a simple program at the end of it i get a simple list of file paths all i want is to make a button that writes these file paths in( someway ) to an iso or nrg or any image file so that whenever i want to burn them i do it ...

    it's like when you are using nero and u want to skip burning for someother day u just save the project ...

    so please help me
    Thursday, August 30, 2007 6:31 PM
  •  

    Dear ismail-marmoush,

     

    Please refrain from posting the same message in multiple threads! I will clean-up the other thread, but do not repeat this.

     

    This forum will help you investigate detailed issues or respond generic conceptual questions, but we will not code for you.

     

    This thread and other on the forum already explain in detail how to achieve the creation of an .iso file. You need to read them and try the solutions discussed first.


     

    Friday, August 31, 2007 5:24 PM
  • Hi Caliendo

    could you pleas share snippet  of Step 6 .
    to
    Use IStream::CopyTo to copy data from the stream obtained in step 4 to the stream obtained in step 5

    It would be a great help.

    Thank in advance
    satbir soni
    Monday, November 17, 2008 10:01 AM
  • Thanks,

    I have solved that step.
    Tuesday, November 25, 2008 5:00 AM