Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details

If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.

Automatic mounting of multisegmented ISO files

If you have a question or need help, this is the place to be.
Post Reply
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Automatic mounting of multisegmented ISO files

Post by Bitmonster »

I just want to show you something neat you can do with EventGhost. Since I have many DVDs that don't fit on a single layer DVD-Rs and I don't want to shrink them down, I developed a way to backup such DVDs with two DVD-R. The trick is to use Daemon-Tools to mount two DVD-Rs filled with splitted ISO files as a single virtual drive.

You first have to create splitted ISO-files of course. To do this, you can create a single ISO files with a tool of your choice and then use one of the nifty file splitter tools (there are millions out there) to split this ISO down to a suitable size. Make sure the parts size is a multiple of 2048 bytes. Also make sure the ending of the parts contains an incrementing number. For example my parts look like this:
MY_IMAGE.ISO.001
MY_IMAGE.ISO.002
MY_IMAGE.ISO.003
and so on.

Now you can burn these parts on DVD-Rs as you want. I have written a tool to make this process somewhat easier, that I might post later.

To mount these parts you would normally have to use a tool to create a so called .MDS file. These files Daemon-Tools can use to mount an ISO consisting of multiple parts. You can manually create such file with DVDDecrypter for example, but this is not very convenient of course. So here is the moment EventGhost kicks in. Everytime a media is changed EG will trigger a script. If this script finds a splitted ISO on one of the monitored drives, it creates an MDS file on the fly and mounts it with Daemon-Tools. This also works, if one DVD has parts of two different ISOs (sometimes I copy two original DVDs to three DVD-Rs).

So no more user-interaction is needed: just insert the two DVDs and you can directly play them with the software you want.

To install it:
1. Copy the following macro code and paste it to your configuration somewhere:

Code: Select all

<?xml version="1.0" encoding="UTF-8" ?>
<EventGhost Version="895">
    <Macro Name="ISO-Mounter" Expanded="True">
        <Event Name="DriveMounted.E">
        </Event>
        <Event Name="DriveMounted.F">
        </Event>
        <Event Name="DriveMounted.H">
        </Event>
        <Action>
            EventGhost.PythonScript(u'searchPathes = [\n    "E:\\\\", \n    "F:\\\\", \n    "H:\\\\", \n    "C:\\\\data", \n    "D:\\\\data",\n]\noutFile = "C:\\\\MULTISEGMENT.MDS"\ndaemonProgPath =  eg.PROGRAMFILES + "\\\\D-Tools\\\\daemon.exe"\n\n\nfrom os.path import split, isfile\nfrom os import listdir, stat\nfrom struct import pack\nfrom win32api import WinExec\n\n\ndef MountISO(pathes, mds_filename, d_drivenum, d_path):  \n    # get a list for every wanted path with all filenames in it\n    pathnum = 0\n    fileTable = []\n    for path in pathes:\n        fileTable.append([])\n        try:\n            files = listdir(path)\n        except WindowsError:\n            files = []\n        \n        for file in files:\n            if isfile(path + \'//\' + file):\n                fileTable[pathnum].append(file)\n        pathnum = pathnum + 1\n\n    # find a part that is at least in two pathes\n    def compareDrives():\n        for i in range(0, len(fileTable) - 1):\n            for j in range (i + 1, len(fileTable)):\n                for k in range(len(fileTable[i])):\n                    for l in range(len(fileTable[j])):\n                        if fileTable[i][k][:-4] == fileTable[j][l][:-4]: \n                            return fileTable[i][k][:-4]\n        return None\n\n    found = compareDrives()\n    if not found:\n        return      # if no parts found take a quick exit\n\n    # stuff needed files into a list\n    files = []\n    for i in range(len(fileTable)):\n        for j in range(len(fileTable[i])):\n            if fileTable[i][j][:-4] == found:\n                files.append((fileTable[i][j], pathes[i]))\n           \n    #sort list\n    files.sort()\n\n    #remove duplicate files\n    i = 0\n    while i < len(files) - 1:\n        if files[i][0] == files[i+1][0]:\n            del files[i]\n        else:\n             i = i + 1\n\n    #merge path and filename and also calculate the image size\n    iso_size = 0\n    for i in range(len(files)):\n        files[i] = files[i][1] + \'\\\\\' + files[i][0]\n        iso_size = iso_size + stat(files[i]).st_size\n\n    # create the MDS data\n    fd = open(mds_filename, \'wb\')\n    fd.write("MEDIA DESCRIPTOR\\x01\\x03\\x10\\x00\\x01\\x00\\x02")\n    fd.write(41 * "\\x00" + "\\xC0" + 15 * "\\x00" + "\\x58" + 11 * "\\x00")\n    fd.write(pack("<L", iso_size / 2048))  # number of sectors\n    fd.write("\\x01\\x00\\x01\\x03\\x01\\x00\\x01\\x00\\x00\\x00\\x00\\x00")\n    fd.write("\\x70\\x00\\x00\\x00\\x02\\x00\\x14\\x00\\x01" + 7 * "\\x00")\n    fd.write(pack("<L", iso_size / 2048))  # number of sectors\n    fd.write("\\x00\\x08" + 30 * "\\x00")\n    fd.write(pack("b", len(files)))        # number of parts\n    fd.write("\\x00\\x00\\x00\\xC4\\x10" + 2078 * "\\x00")\n    fd.write("\\x01\\x02\\x01\\x10\\x00\\x03\\x00\\x00")\n    # last sector of program area in physical sectors\n    # = (number of sectors) + 0x30000 - 1\n    fd.write(pack(">L", (iso_size / 2048) + 196607))\n    fd.write(2036 * "\\x00")\n\n    # the table with the offsets to the filenames and sector-sizes of \n    # the parts\n    offset = 4292 + len(files) * 16\n    for filename in files:\n       fd.write(pack("<L", offset))\n       fd.write(4 * "\\x00")\n       fd.write(pack("<L", stat(filename).st_size / 2048)) # number of sectors of this part\n       fd.write(4 * "\\x00")\n       offset = offset + len(filename) + 1\n\n    # the filenames with full path as c-strings\n    for filename in files:\n        fd.write(filename + "\\x00")\n\n    fd.close()\n\n    # call Daemon-Tools to mount the MDS file    \n    WinExec(\'"\' + d_path + \'" -mount \' + d_drivenum + \',"\' + mds_filename + \'"\') \n\n\n    \nMountISO(searchPathes, outFile, "0", daemonProgPath)\n')
        </Action>
    </Macro>
</EventGhost>
2. Change the "DriveMounted" events to the real DVD-ROM drive letters your system has. The chunk above uses the drives E:, F: and H:. Don't put any virtual Daemon-Tools drive there.

3. Open up the PythonScript item and edit the locations to monitor. The example looks like this:

Code: Select all

searchPathes = [
    "E:\\", 
    "F:\\", 
    "H:\\", 
    "C:\\data", 
    "D:\\data",
]
So here it monitors the root of the drives E:, F: and H: and also two locations on my HDDs, that also might contain splitted parts. This way I can copy one DVD-R back to HDD and then insert the second one to get my full ISO back. Keep in mind, that you have to escape backslashes in Python with two backslashes.

By default the script creates an .MDS file in the root of your C: drive. If you want another location, you can edit the "outFile" line.
Please post software-related questions in the forum - PMs will only be answered, if really private, thanks!
Post Reply