Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can’t mount CD image of Win95 game

42 views
Skip to first unread message

Yvan Masson

unread,
Dec 19, 2022, 7:00:06 AM12/19/22
to
Hi list,

I have a CD image of an old Win 95 game. I can mount it from dosbox with
the `imgmount` command (`imgmount D cdimage.iso -t iso`), but could not
mount it with Debian:

$ file cdimage.iso
cdimage.iso: data

$ sudo mount cdimage.iso /mnt -o loop
mount: /mnt/sshfs: wrong fs type, bad option, bad superblock on
/dev/loop0, missing codepage or helper program, or other error.
dmesg(1) may have more information after failed mount system call.

The corresponding kernel logs:
loop0: detected capacity change from 0 to 542921

Any idea of the reason and how I could mount this ISO from Debian?

Regards,
Yvan




OpenPGP_signature

Thomas Schmitt

unread,
Dec 19, 2022, 7:30:06 AM12/19/22
to
Hi,

Yvan Masson wrote:
> I have a CD image of an old Win 95 game. [...]
> $ file cdimage.iso
> cdimage.iso: data

So the cdimage.iso is not an ISO 9660 filesystem or somehow defaced.
(Does the image file perhaps begin by "RIFF....CDXA" ?)

What do you get from the following runs ?

dd if=cdimage.iso bs=1 count=64 | od -t c

strings cdimage.iso | head -10


Have a nice day :)

Thomas

Yvan Masson

unread,
Dec 19, 2022, 8:30:05 AM12/19/22
to
Hi Thomas,

Le 19/12/2022 à 13:28, Thomas Schmitt a écrit :
> Hi,
>
> Yvan Masson wrote:
>> I have a CD image of an old Win 95 game. [...]
>> $ file cdimage.iso
>> cdimage.iso: data
>
> So the cdimage.iso is not an ISO 9660 filesystem or somehow defaced.
> (Does the image file perhaps begin by "RIFF....CDXA" ?)
>
> What do you get from the following runs ?
>
> dd if=cdimage.iso bs=1 count=64 | od -t c
64+0 records in
64+0 records out
64 bytes copied, 0.000147839 s, 433 kB/s
0000000 \0 377 377 377 377 377 377 377 377 377 377 \0 \0 002 \0 001
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0000100
>
> strings cdimage.iso | head -10
E<Su3+%b
bV)[
MI$
CD001
MSBSOLAR



WCD




1995082311483300
1995082312010100
0000000000000000
0000000000000000
GK2xexxxxxxxxxxxx
>
>
> Have a nice day :)
You too :-)
>
> Thomas
>
OpenPGP_signature

Kamil Jońca

unread,
Dec 19, 2022, 9:50:05 AM12/19/22
to
Yvan Masson <yv...@masson-informatique.fr> writes:

> Hi list,
>
> I have a CD image of an old Win 95 game. I can mount it from dosbox
> with the `imgmount` command (`imgmount D cdimage.iso -t iso`), but
> could not mount it with Debian:
>
> $ file cdimage.iso
> cdimage.iso: data
>
> $ sudo mount cdimage.iso /mnt -o loop
> mount: /mnt/sshfs: wrong fs type, bad option, bad superblock on
> /dev/loop0, missing codepage or helper program, or other error.
> dmesg(1) may have more information after failed mount system call.
>
> The corresponding kernel logs:
> loop0: detected capacity change from 0 to 542921
>
> Any idea of the reason and how I could mount this ISO from Debian?

What if you issue:
--8<---------------cut here---------------start------------->8---
sudo mount -o loop -t iso9660 cdimage.iso /mnt
--8<---------------cut here---------------end--------------->8---

KJ

--
http://wolnelektury.pl/wesprzyj/teraz/

Thomas Schmitt

unread,
Dec 19, 2022, 10:40:06 AM12/19/22
to
Hi,

i wrote:
> > dd if=cdimage.iso bs=1 count=64 | od -t c

Yvan Masson wrote:
> 0000000 \0 377 377 377 377 377 377 377 377 377 377 \0 \0 002 \0 001
> 0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0

This does not give me ideas.


> > strings cdimage.iso | head -10

> ...
> CD001
> MSBSOLAR
> WCD
> 1995082311483300
> 1995082312010100

But this looks like from a ISO 9660 Primary Volume Descriptor.

The text "CD001" is probably preceeded by a binary 1, which should be at
byte address 32768 of the ISO 9660 filesystem.
I assume that this byte and the string are displaced in cdimage.iso.

"MSBSOLAR" is probably the Volume Id (Label) of the ISO filesystem.
"WCD" could be the program which made the ISO.
"1995082311483300" as Creation Time would mean: 1995 August 23 11:48:33

Assuming that you cope with some prepended header and an ISO 9660
filesystem, the next step would be to find out how much "\001CD001"
is displaced from its normal byte position 32768.
2048 bytes later would come "\002CD001", which would be the Joliet Volume
Descriptor.
Again 2048 bytes later is probably the Descriptor Set Terminator with
a leading byte of value 255: "\377CD001".

If they are displaced by the same offset as "\001CD001", then consider to
cut off the surplus bytes from the start of a copy of the image and try
to mount that shortened copy. At least the signature of ISO 9660 should
then be recognizable for the Linux kernel.

It might of course be more complicated than just a prepended header.
The inner weaving of ISO 9660 could be broken by further inserted
meta-data.
In that case we would need to inspect the image in more detail, which
will be difficult by forth-and-back mail.


Have a nice day :)

Thomas

Yvan Masson

unread,
Dec 19, 2022, 10:40:06 AM12/19/22
to
Hi,

Thanks for the suggestion but I have the same error. Unsurprisingly, I
also have `ISOFS: Unable to identify CD-ROM format.` in kernel log.
OpenPGP_signature

Yvan Masson

unread,
Dec 19, 2022, 3:22:58 PM12/19/22
to
Thanks Thomas for these very clear and detailed explanations! I am
really not at ease using tools like hexdump, but I will try to dig into
it, this is a good exercise.

Yvan
OpenPGP_signature

Thomas Schmitt

unread,
Dec 19, 2022, 4:10:09 PM12/19/22
to
Hi,

Yvan Masson wrote:
> I am really not at ease using tools like hexdump,

I pondered a bit more. If it's an ISO filesystem wrapped into some header
and maybe a footer, then mount option -o offset= could help.

To obtain the offset of the first occurence of "CD001", do

offst=$( expr \
$( grep -a -o -b -m 1 CD001 cdimage.iso \
| sed -e 's/:/ /' \
| awk '{ print $1 }' ) - 32769 )

(It's the binary 1 before "CD001" which is normally at 32768. So grep will
report byte position 32769 for "CD001" if offset is 0.)

Then use the resulting number with the mount command

mount -t iso9660 -o offset="$offst" cdimage.iso /mnt

It might be that you get errors when mounting or when accessing the files
in the mounted image. Check your kernel logs even if all looks good.

---

(Do the year 1995 and the volume id "MSBSOLAR" mean that the game is
"The Magic School Bus Explores the Solar System" ?)

The Wanderer

unread,
Dec 19, 2022, 5:22:53 PM12/19/22
to
On 2022-12-19 at 16:07, Thomas Schmitt wrote:

> Hi,
>
> Yvan Masson wrote:
>> I am really not at ease using tools like hexdump,
>
> I pondered a bit more. If it's an ISO filesystem wrapped into some header
> and maybe a footer, then mount option -o offset= could help.
>
> To obtain the offset of the first occurence of "CD001", do
>
> offst=$( expr \
> $( grep -a -o -b -m 1 CD001 cdimage.iso \
> | sed -e 's/:/ /' \
> | awk '{ print $1 }' ) - 32769 )
>
> (It's the binary 1 before "CD001" which is normally at 32768. So grep will
> report byte position 32769 for "CD001" if offset is 0.)

This apparently isn't universally reliable. When I tested it with a
random ISO I happen to have lying around (a bullseye netinst from
2021-04-15), I got an error from expr about unexpected arguments.

Cutting down the command line led me to discover that even with '-m 1',
four different numbers are printed by the grep-pipeline subshell.
(Without '-m 1', seven are printed.)

I'm not entirely sure why this may happen, but it's what I've observed.

Inserting '| head -n 1 ' into the pipeline, right after grep, got this
to produce the expected first-occurrence-only information.

--
The Wanderer

The reasonable man adapts himself to the world; the unreasonable one
persists in trying to adapt the world to himself. Therefore all
progress depends on the unreasonable man. -- George Bernard Shaw

signature.asc

Thomas Schmitt

unread,
Dec 20, 2022, 3:00:05 AM12/20/22
to
Hi,

i wrote:
> > To obtain the offset of the first occurence of "CD001", do
> >
> > offst=$( expr \
> > $( grep -a -o -b -m 1 CD001 cdimage.iso \
> > | sed -e 's/:/ /' \
> > | awk '{ print $1 }' ) - 32769 )

The Wanderer wrote:
> Cutting down the command line led me to discover that even with '-m 1',
> four different numbers are printed by the grep-pipeline subshell.
> (Without '-m 1', seven are printed.)

This contradicts the promises of man grep about option -m.


> Inserting '| head -n 1 ' into the pipeline, right after grep, got this
> to produce the expected first-occurrence-only information.

So the new safer proposal is:

offst=$( expr \
$( grep -a -o -b -m 1 CD001 cdimage.iso \
| head -1 \
| sed -e 's/:/ /' \
| awk '{ print $1 }' ) - 32769 )

Afterwards $offst should hold a number > 0, which may be used with mount
option -o offset=.

---

About the occurences of CD001 in debian-11.5.0-amd64-netinst.iso :

32769:CD001 ... Primary Volume Descriptor (preceeded by \001)
34817:CD001 ... El Torito Boot Record (preceeded by \000)
36865:CD001 ... Joliet Volume Descrriptor (preceeded by \002)
38913:CD001 ... Volume Descriptor Set Terminator (preceeded by \377)

3935025:CD001 ... is inside data file /boot/grub/efi.img
(which serves as EFI boot partition)
7176356:CD001 ... is inside data file /boot/grub/x86_64-efi/udf.mod
11657521:CD001 ... is inside data file /EFI/boot/grubx64.efi
(which serves as boot stage after the Secure Boot shim)

The file paths of the latter three were determined by

xorriso -indev debian-11.5.0-amd64-netinst.iso \
-find / -lba_range "$blockadr" 1 -exec report_lba --

with block_adr = floor(3935025/2048) = 1921, or 3504, or 5692.

Each of the files probably contains code which wants to identify ISO 9660.

Yvan Masson

unread,
Dec 20, 2022, 3:52:52 AM12/20/22
to
>
> So the new safer proposal is:
>
> offst=$( expr \
> $( grep -a -o -b -m 1 CD001 cdimage.iso \
> | head -1 \
> | sed -e 's/:/ /' \
> | awk '{ print $1 }' ) - 32769 )
>
> Afterwards $offst should hold a number > 0, which may be used with mount
> option -o offset=.
>
I confirm that with this command I get the same result that what I had
done manually with hexdump. Unfortunately, mount still does not work
with "can't read superblock on /dev/loop0". Kernel logs say
"isofs_fill_super: get root inode failed".

I really appreciate the help on this very specific and technical issue,
but I am not sure it is worth the effort. As I said, it can be mounted
with dosbox.

And indeed, the game is the french version of "The Magic School Bus
Explores the Solar System". For those interested, it can be easily found
a popular french website specialized on "abandonware". It is not legal
but the website has the following rules that:
- game must be older than 2004
- game must not be sold anymore, at least in its french version
- beneficiaries must not have say that they don’t want the game freely
available

Regards,
Yvan
OpenPGP_signature

The Wanderer

unread,
Dec 20, 2022, 5:20:06 AM12/20/22
to
On 2022-12-20 at 02:51, Thomas Schmitt wrote:

> Hi,
>
> i wrote:

>>> To obtain the offset of the first occurence of "CD001", do
>>>
>>> offst=$( expr \
>>> $( grep -a -o -b -m 1 CD001 cdimage.iso \
>>> | sed -e 's/:/ /' \
>>> | awk '{ print $1 }' ) - 32769 )
>
> The Wanderer wrote:
>> Cutting down the command line led me to discover that even with '-m 1',
>> four different numbers are printed by the grep-pipeline subshell.
>> (Without '-m 1', seven are printed.)
>
> This contradicts the promises of man grep about option -m.

It does seem to, at least at a glance - but I think I've figured out
what's going on, and it's actually consistent with the option set you
gave.

If I pass the same ISO through 'strings' before piping to grep, I find
that there are four occurrences of 'CD001' in the first 25 lines that
strings printed, and the next doesn't happen until line 20290.

My guess would be that grep is treating a "line" as ending with a
newline, and that there isn't a newline character in the ISO in question
until after all four of those occurrences.

With the '-o' option, grep prints only the parts of the line that were
matched - but the plural here is very relevant. If that guess is
correct, then the "line" in question has *four* occurrences, so grep
prints them all - each on a separate line of output.

The key to realizing how this interaction is consistent with the
documentation is that the man page for '-m' doesn't promise that it will
stop processing after the first match, but rather the first matched
*line*. And since a "line" in a binary input file can be very long (a
fact I know from lengthy and painful experience), it's entirely possible
for the first matched line to contain multiple matches - each of which
will then get printed.
signature.asc

David

unread,
Dec 20, 2022, 5:40:06 AM12/20/22
to
On Tue, 20 Dec 2022 at 21:10, The Wanderer <wand...@fastmail.fm> wrote:
> On 2022-12-20 at 02:51, Thomas Schmitt wrote:

> >>> offst=$( expr \
> >>> $( grep -a -o -b -m 1 CD001 cdimage.iso \
> >>> | sed -e 's/:/ /' \
> >>> | awk '{ print $1 }' ) - 32769 )
> >
> > The Wanderer wrote:
> >> Cutting down the command line led me to discover that even with '-m 1',
> >> four different numbers are printed by the grep-pipeline subshell.
> >> (Without '-m 1', seven are printed.)
> >
> > This contradicts the promises of man grep about option -m.
>
> It does seem to, at least at a glance - but I think I've figured out
> what's going on, and it's actually consistent with the option set you
> gave.

[...]

Hi,

Slightly offtopic rambling ...

I haven't looked at the 'grep' part of the above expression, but
I assume that its output lines look something like:
100:CD001

If that is the case, then awk does not need any assistance
from 'expr' or 'sed' (and even not from 'grep' if we were not
searching a binary file).

Short demo:
$ echo 100:CD001 | awk 'BEGIN { FS=":" } /CD001/ { print $1 - 50 }'
50

I only write this because I just magine how poor old 'awk' feels:
"don't embed me in this pipelines and subshells and unnecessary
commands, I can do all that stuff myself without any help!!".

The Wanderer

unread,
Dec 20, 2022, 6:00:07 AM12/20/22
to
On 2022-12-20 at 05:37, David wrote:

> On Tue, 20 Dec 2022 at 21:10, The Wanderer <wand...@fastmail.fm>
> wrote:
>
>> On 2022-12-20 at 02:51, Thomas Schmitt wrote:

>>> This contradicts the promises of man grep about option -m.
>>
>> It does seem to, at least at a glance - but I think I've figured
>> out what's going on, and it's actually consistent with the option
>> set you gave.
>
> [...]
>
> Hi,
>
> Slightly offtopic rambling ...
>
> I haven't looked at the 'grep' part of the above expression, but
> I assume that its output lines look something like:
> 100:CD001
>
> If that is the case, then awk does not need any assistance
> from 'expr' or 'sed' (and even not from 'grep' if we were not
> searching a binary file).
>
> Short demo:
> $ echo 100:CD001 | awk 'BEGIN { FS=":" } /CD001/ { print $1 - 50 }'
> 50

If you replace the "echo 100:CD001" with "echo -e
'100:CD001\n200:CD001'" (not sure if that syntax is portable to all
shells, but it works in my version of bash), this does print '50' and
'150' on consecutive lines - which (if I'm not mistaken) matches the
behavior of the original pipeline, but is not what is actually desired
here.

> I only write this because I just magine how poor old 'awk' feels:
> "don't embed me in this pipelines and subshells and unnecessary
> commands, I can do all that stuff myself without any help!!".

Because of the above, it looks like a pipeline may still be necessary
here, to filter it down to just the first number being output. Unless
awk has another feature that would let us do that limiting internally too?
signature.asc

Thomas Schmitt

unread,
Dec 20, 2022, 6:10:05 AM12/20/22
to
Hi,

Yvan Masson wrote:
> Kernel logs say "isofs_fill_super: get root inode failed".

So there is more stuff inserted between the volume descriptor and the
root directory of the ISO.
(The descriptor contains a minimal directory record which points to
the content of the root directory. All attributes and properties of the
root directory are read from the "." directory record in there.
But obviously the pointer, a block address, leads to other data.)


> I really appreciate the help on this very specific and technical issue, but
> I am not sure it is worth the effort. As I said, it can be mounted with
> dosbox.

I would investigate further if i had the image file.
But my guessing of the french word for "abandonware" yields no success
on Google. :))

Well, for now the endeavor stops at the insight that there is probably
some meta-data interleaved between parts of the ISO image.

David

unread,
Dec 20, 2022, 6:10:06 AM12/20/22
to
On Tue, 20 Dec 2022 at 22:02, David <bounci...@gmail.com> wrote:

> $ echo -e '100:CD001\n200:CD001' | awk 'BEGIN { FS=":" } /CD001/ &&
> NR==1 { print $1 - 50 }'
> 50

Oops, my mistake, that's not the solution. Give me another minute and I
will post a better one one.

David

unread,
Dec 20, 2022, 6:10:06 AM12/20/22
to
Fair point. Thanks for noticing my laziness. :)

But 'awk' does indeed have vast powers, that are sadly very overlooked
in modern times:

$ echo -e '100:CD001\n200:CD001' | awk 'BEGIN { FS=":" } /CD001/ &&
NR==1 { print $1 - 50 }'
50

And I'm not anything like an 'awk' expert.

I just like to share what little knowledge I have because it is a bit
sad when cool tools fall out of fashion.

David

unread,
Dec 20, 2022, 6:20:05 AM12/20/22
to
The below does a better job:
(command should be all on one line)

$ echo -e '100:CD001\nXXX\n200:CD001' | awk 'BEGIN { FS=":" ; done=0 }
/CD001/ && done==0 { print $1 - 50 ; done=1 }'
50

Still quite clean and obvious for a one liner (for folks who know how 'awk'
works), and it will be significantly faster than pipelines and
subshell collections.

Not that that is always important. But I just commented today
because so often 'awk' is ignored as if its only capability is 'print $1'
when in fact it is actually very powerful but neglected.

Thomas Schmitt

unread,
Dec 20, 2022, 6:20:05 AM12/20/22
to
Hi,

The Wanderer wrote:
> With the '-o' option, grep prints only the parts of the line that were
> matched - but the plural here is very relevant. If that guess is
> correct, then the "line" in question has *four* occurrences, so grep
> prints them all - each on a separate line of output.

The man page agrees:

-o, --only-matching
Print only the matched (non-empty) parts of a matching line,
with each such part on a separate output line.

So -o is probably inapproriate in my pipe.
(It seems to be a development remnant. I got the pipe from a similar one
in an older mail of mine about hacking ISO images as stress test for
GRUB's ISO 9660 reader.)
On the other hand it curbs the length of the output.


David wrote:
> Short demo:
> $ echo 100:CD001 | awk 'BEGIN { FS=":" } /CD001/ { print $1 - 50 }'
> 50

Looks like a good alternative to sed and expr.
(I keep in memory the gesture "awk '{print $1}'" for picking words out of
lines. New stuff does not fit easy into that memory.)


> I only write this because I just magine how poor old 'awk' feels:
> "don't embed me in this pipelines and subshells and unnecessary
> commands, I can do all that stuff myself without any help!!".

My apologies to the venerable Awk Programming Language from an old
procedural programmer.

Stefan Monnier

unread,
Dec 20, 2022, 11:00:05 AM12/20/22
to
> Not that that is always important. But I just commented today
> because so often 'awk' is ignored as if its only capability is 'print $1'
> when in fact it is actually very powerful but neglected.

FWIW, `sed` can also do that job. Tho the subtraction part would take
a lot more work (`sed` doesn't know how to subtract, so you'd have to
write a chunk of `sed` code which implements subtraction by hand.
A fun exercise for the masochists out there who like to write code for
Turing machines).


Stefan

Lee

unread,
Dec 20, 2022, 12:20:20 PM12/20/22
to
On 12/20/22, David <bounci...@gmail.com> wrote:
> On Tue, 20 Dec 2022 at 22:04, David <bounci...@gmail.com> wrote:
>> On Tue, 20 Dec 2022 at 22:02, David <bounci...@gmail.com> wrote:
>
>> > $ echo -e '100:CD001\n200:CD001' | awk 'BEGIN { FS=":" } /CD001/ &&
>> > NR==1 { print $1 - 50 }'
>> > 50
>>
>> Oops, my mistake, that's not the solution. Give me another minute and I
>> will post a better one one.
>
> The below does a better job:
> (command should be all on one line)
>
> $ echo -e '100:CD001\nXXX\n200:CD001' | awk 'BEGIN { FS=":" ; done=0 }
> /CD001/ && done==0 { print $1 - 50 ; done=1 }'
> 50

You can do it without flags:

$ echo -e '100:CD001\nXXX\n200:CD001' | awk -F: '/CD001/ { print $1 -
50 ; exit }'
50

Thomas Schmitt

unread,
Dec 20, 2022, 4:20:06 PM12/20/22
to
Hi,

i meanwhile had a chance to inspect the image file and found that it
shows a repeating pattern of bytes with value 255 every 2352 bytes.
This corresponds to the size of medium level CD sectors, as can be obtained
by SCSI command "READ CD" (e.g. via Linux ioctl CDROMREADRAW).

CD-DA audio sectors have this whole size filled with audio payload.
Data sectors consist of meta-data and payload data. There are various forms
of data sectors. See
https://en.wikipedia.org/wiki/CD-ROM#Sector_structure

The magic number of ISO 9660 which in the data payload world is at byte
position 16 * 2048 is in the image file at position 16 * 2352 + 16.
This means that the header size of the data sector format is 16.
I expect a payload size of 2048 bytes.
(These parameters match the format "CD-ROM Mode 1". The remaining 288 bytes
of the sector are error correcting data.)

So i wrote a little C program which reads chunks of 2352 bytes from standard
input and writes 2048 bytes from offset 16 to standard output.
Filtering the image file through this program yielded a new image file
which can be mounted as ISO 9660 filesystem.

The program has 55 lines, including rudimentary error handling. I am sure
that the ongoing awk programming contest can provide a shorter solution.

David

unread,
Dec 20, 2022, 9:20:05 PM12/20/22
to
That's better indeed. Thanks for sharing those improvements!
It really is worthwhile to know some basics of 'awk'.
0 new messages