Byte order in Volume Serial Number

G

Gutek

Hello,

I have noticed that the Volume Serial Number of the same CD is displayed
in different byte order on machines with XP and Win 98 - either using
"dir e:" command or by GetVolumeInformation() function from Win32 API.
But the VSN of a floppy disk is identical on both machines.
I have written an application that relies on this number so it is
important that the bytes are properly ordered. How to verify what is the
actual byte order, so that the Serial number of the same volume is
always the same?

regards,

Piotr
 
B

Bob I

Suggest your application determines what platform it is running on to
resolve this issue.
 
G

Gutek

Bob I napisał(a):
Suggest your application determines what platform it is running on to
resolve this issue.

This could be a solution provided that I am sure that Volume Serial
Numbers are ALWAYS reversed on Win 98 with respect to XP. But this is
not true for floppy disk, for example, as they appear to obey the same
byte order. Can somebody verify this for any CD, please?

regards,
Gutek
 
E

Eric P.

Years ago when Windows 98 still was the greatest I studied Volume Serial
Number and wrote little assembler programs to change the VSN when required.
You can change the VSN to anything as long as it is a valid HEX value.
On one of my old old computers with Windows 98SE the C: partition still
has ABCD-ABCD as VSN.
MicroSoft used Volume Tracking to distinguish volumes an not VSN.
If not able to do Volume Tracking Windows would use other methods.
The VSN didn't have any use anymore to check volumes.

I discovered Format and Diskcopy differ in the way they create a VSN.
Below I wrote at the time:

<QUOTE>
A VSN is generated by Format.COM and DiskCopy.Com from Dos date and Dos
time.
It is a double word (4 bytes) value stored in reverse notation on disk.
The VSN is stored at offset 0027h (FAT12 and FAT16) or 0043h (FAT32) in the
bootsector.

The routines used to generate a VSN stayed the same from Dos 5.0 - Dos 7.1

Routines in Format.Com and DiskCopy differ slightly.
Compared with Format.COM the High and Low word have changed place
Format: [Seconds/Hundredth] + [Month/Day of mo] = High word of VSN
[Hour/Minutes] + [Year] = Low word of VSN

DiskCopy: [Seconds/Hundredth] + [Month/Day of mo] = Low word of VSN
[Hour/Minutes] + [Year] = High word of VSN
</QUOTE>
 
G

Gutek

Thanks for reply.

My problem, however, is related to VSN of CDs - and those I believe you
cannot change easily. I would like to distribute a number of CDs among
people and I create a database, where people register their CDs, so that
I knew who's got a particular copy. This process requires that all users
send me VSN of their CDs - it is prompted to them using
GetVolumeInformation() from API.
Now, on my old machine with Win 98, the VSN of the CD is prompted in
reverse byte order. If the user sends me the VSN in this order - the
database, which stores all numbers of distributed CDs, will not
recognize it. I can implement a mechanism which automatically restores
the proper order of bytes when needed, but I must know whether it is
normal or reversed. Is there a way, possibly using API, to check which
rule is used? And why the VSN of CD is reversed, but not of the floppy?

regards,

Gutek
 
E

Eric P.

I think I understood your problem but wanted to make clear the VSN is a
very old Dos relic MS didn't do much with in the later nineties.
And it was originally created for a different purpose, to check the same
disk was still in place, but replaced by Volume Tracking.
 
G

Gutek

Eric P. napisał(a):
I think I understood your problem but wanted to make clear the VSN is a
very old Dos relic MS didn't do much with in the later nineties.
And it was originally created for a different purpose, to check the same
disk was still in place, but replaced by Volume Tracking.

Is VSN deprecated or not, it is still the best method for me. I checked
what MSDN tells about this "Volume Tracking", but i doesn't seem to be
of any use to me. I need sth that uniquely identifies the CD, is
accessible through Win API, is independent among Windows versions and is
automatically added to a CD when burned. Could you please suggest some
other API function that meets these requirements?

If this is not a problem, can you (or anybody) check VSN of any CD on
your old Win 98 machine and then on XP, please? And if confirmed, can
you explain this, please?

Kind regards,

Gutek
 
G

Gutek

Eric P. napisał(a):
I think I understood your problem but wanted to make clear the VSN is a
very old Dos relic MS didn't do much with in the later nineties.
And it was originally created for a different purpose, to check the same
disk was still in place, but replaced by Volume Tracking.

Could you give me some example source code of how to read directly the
bytes of the CD which store the VSN, please? I did some assembler before
so maybe I'll manage to figure it out somehow...

regards,

Gutek
 
G

Gutek

dg1261 napisa³(a):
Gutek,

I just checked a random data DVD, and got the following results from a "dir"
command:

Win98se: F001-5C78
Win2000-sp4: 785C-01F0
WinXP-sp2: 785C-01F0

Thanks,
Seems that this is a rule for Win9x systems. I think that one might
check the lpFileSystemNameBuffer variable from:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getvolumeinformation.asp

and apply GetVersion() to determine the win version. When the file
system is CDFS (or for any other than FAT, FAT32, NTFS) and GetVersion
indicates Win9x family we can switch the bytes. Am I right?

regards,
Gutek
 
D

dg1261

Eric P. said:
Format: [Seconds/Hundredth] + [Month/Day of mo] = High word
[Hour/Minutes] + [Year] = Low word

Eric,

Could you clarify what you mean by "format"? For example, is [Hour/Minutes]
and [Year] separate bytes of a word? Or is [Hour/Minutes] converted and
arithmetically added with [Year] to form a very large number that is
converted to a hexadecimal word? Perhaps a brief example of the conversion
would help illustrate the formula.

What I'm wondering here, is whether Gutek might be able to determine which
form of the VSN is being used by assuming the year 2005 is in there
somewhere.
 
D

dg1261

Gutek said:
...can you (or anybody) check VSN of any CD on
your old Win 98 machine and then on XP, please?

Gutek,

I just checked a random data DVD, and got the following results from a "dir"
command:

Win98se: F001-5C78
Win2000-sp4: 785C-01F0
WinXP-sp2: 785C-01F0
 
E

Eric P.

This I wrote down in 1998 while still playing with VSN.
I had created a little assembler program to change the VSN on harddisks
in the early 90's but adapted it later for FAT32.
Never did anything with the VSN on CD's!

<QUOTE>
The Volume Serial Number appeared first in MS-Dos 5.0 (Not counting 4.x)
It is used by MS-Dos to identify removable media.

In Windows 95/98 Volume Tracking is used instead, unless the removable media
is write protected or Volume Tracking has been switched off in the Registry.

Volume Tracking writes a different string to the OEM field in the bootsector
each time the removable media is inserted and assessed.
Identification of removable media change is therefore much more reliable
with
Volume Tracking than using the Volume Serial Number.

When Volume Tracking has been switched off the disk's label, serial
number and
BPB will be used by Windows to identify the disk.

See Article ID: Q148637 in MicroSoft Knowledge Base
Windows 95/98 Overwrites Boot-Sector Field on Floppy Disks.

A VSN is generated by Format.COM and DiskCopy.Com from Dos date and Dos
time.
It is a double word (4 bytes) value stored in reverse notation on disk.
The VSN is stored at offset 0027h (FAT12 and FAT16) or 0043h (FAT32) in the
bootsector.

The routines used to generate a VSN stayed the same from Dos 5.0 - Dos 7.1

Routines in Format.Com and DiskCopy differ slightly.
Compared with Format.COM the High and Low word have changed place
Format: [Seconds/Hundredth] + [Month/Day of mo] = High word of VSN
[Hour/Minutes] + [Year] = Low word of VSN
DiskCopy: [Seconds/Hundredth] + [Month/Day of mo] = Low word of VSN
[Hour/Minutes] + [Year] = High word of VSN

Create Volume Serial Number
Dos 5.0 Format.Com
0DA4:4B84 B42A MOV AH,2A ;Get date
0DA4:4B86 CD21 INT 21
0DA4:4B88 51 PUSH CX ;Year
0DA4:4B89 52 PUSH DX ;DH=month, DL=day of month
0DA4:4B8A B42C MOV AH,2C ;Get time
0DA4:4B8C CD21 INT 21
0DA4:4B8E 8BC2 MOV AX,DX ;AH=seconds, AL=hundredths/sec
0DA4:4B90 5A POP DX ;DH=month, DL=day of month
0DA4:4B91 03C2 ADD AX,DX ;Get High word of VSN
0DA4:4B93 A3A815 MOV [15A8],AX
0DA4:4B96 A37E0F MOV [0F7E],AX
0DA4:4B99 8BC1 MOV AX,CX ;AH=hour, AL=minutes
0DA4:4B9B 59 POP CX ;Year
0DA4:4B9C 03C1 ADD AX,CX ;Get Low word of VSN
0DA4:4B9E A3A615 MOV [15A6],AX
0DA4:4BA1 A3800F MOV [0F80],AX
0DA4:4BA4 C3 RET

Dos 7.1 Format.Com (Windows 98)
0DA7:83E4 B42A MOV AH,2A ;Get date
0DA7:83E6 CD21 INT 21
0DA7:83E8 51 PUSH CX ;Year
0DA7:83E9 52 PUSH DX ;DH=month, DL=day of month
0DA7:83EA B42C MOV AH,2C ;Get time
0DA7:83EC CD21 INT 21
0DA7:83EE 8BC2 MOV AX,DX ;AH=seconds, AL=hundredths/sec
0DA7:83F0 5A POP DX ;DH=month, DL=day of month
0DA7:83F1 03C2 ADD AX,DX ;Get High word of VSN
0DA7:83F3 A3014B MOV [4B01],AX
0DA7:83F6 A3C632 MOV [32C6],AX
0DA7:83F9 8BC1 MOV AX,CX ;AH=hour, AL=minutes
0DA7:83FB 59 POP CX ;Year
0DA7:83FC 03C1 ADD AX,CX ;Get Low word of VSN
0DA7:83FE A3FF4A MOV [4AFF],AX
0DA7:8401 A3C832 MOV [32C8],AX
0DA7:8404 C3 RET

Dos 5.0 DiskCopy.Com
0DA4:0B21 B42A MOV AH,2A ;Get date
0DA4:0B23 CD21 INT 21
0DA4:0B25 51 PUSH CX ;Year
0DA4:0B26 52 PUSH DX ;DH=month, DL=day of month
0DA4:0B27 B42C MOV AH,2C ;Get time
0DA4:0B29 CD21 INT 21 ;DH=seconds, DL=hundredths/sec
0DA4:0B2B 58 POP AX ;AH=month, AL=day of month
0DA4:0B2C 03C2 ADD AX,DX ;Get Low word of VSN
0DA4:0B2E A35603 MOV [0356],AX
0DA4:0B31 26 ES:
0DA4:0B32 894727 MOV [BX+27],AX
0DA4:0B35 58 POP AX ;Year
0DA4:0B36 03C1 ADD AX,CX ;CH=hour, CL=minutes
0DA4:0B38 A35803 MOV [0358],AX ;Hi word of VSN
0DA4:0B3B 26 ES:
0DA4:0B3C 894729 MOV [BX+29],AX
0DA4:0B3F C606550301 MOV BYTE PTR [0355],01
0DA4:0B44 5E POP SI
0DA4:0B45 5B POP BX
0DA4:0B46 07 POP ES
0DA4:0B47 C3 RET

Dos 7.1 DiskCopy.Com (Windows 98)
0DA7:0B7E B42A MOV AH,2A ;Get date
0DA7:0B80 CD21 INT 21
0DA7:0B82 51 PUSH CX ;Year
0DA7:0B83 52 PUSH DX ;DH=month, DL=day of month
0DA7:0B84 B42C MOV AH,2C ;Get time
0DA7:0B86 CD21 INT 21 ;DH=seconds, DL=hundredths/sec
0DA7:0B88 58 POP AX ;AH=month, AL=day of month
0DA7:0B89 03C2 ADD AX,DX ;Get Low word of VSN
0DA7:0B8B A35703 MOV [0357],AX
0DA7:0B8E 26 ES:
0DA7:0B8F 894727 MOV [BX+27],AX
0DA7:0B92 58 POP AX ;Year
0DA7:0B93 03C1 ADD AX,CX ;CH=hour, CL=minutes
0DA7:0B95 A35903 MOV [0359],AX ;Hi word of VSN
0DA7:0B98 26 ES:
0DA7:0B99 894729 MOV [BX+29],AX
0DA7:0B9C C606560301 MOV BYTE PTR [0356],01
0DA7:0BA1 5E POP SI
0DA7:0BA2 5B POP BX
0DA7:0BA3 07 POP ES
0DA7:0BA4 C3 RET
</QUOTE>
Eric P. said:
Format: [Seconds/Hundredth] + [Month/Day of mo] = High word
[Hour/Minutes] + [Year] = Low word


Eric,

Could you clarify what you mean by "format"? For example, is [Hour/Minutes]
and [Year] separate bytes of a word? Or is [Hour/Minutes] converted and
arithmetically added with [Year] to form a very large number that is
converted to a hexadecimal word? Perhaps a brief example of the conversion
would help illustrate the formula.

What I'm wondering here, is whether Gutek might be able to determine which
form of the VSN is being used by assuming the year 2005 is in there
somewhere.
 
D

dg1261

Eric P. said:
MOV AH,2A ;Get date
INT 21
PUSH CX ;Year
PUSH DX ;DH=month, DL=day of month
MOV AH,2C ;Get time
INT 21 ;DH=seconds, DL=hundredths/sec
POP AX ;AH=month, AL=day of month
ADD AX,DX ;Get Low word of VSN
...(snipped)...
POP AX ;Year
ADD AX,CX ;CH=hour, CL=minutes

Thanks for the details, Eric. Looks like my idea won't help Gutek much.

Decimal 2005 = hex 07D5, so the high byte of the word containing the year
(after adding the hour) would have to be in the range 7-31 decimal. The
high byte of the other word (month plus seconds) would be in the range 1-72
decimal. Gutek would have to compare two bytes to try and determine which
one included the year, and if one of the two fell outside the range 7-31,
then that one would be the one that did *not* contain the year. But alas,
7-31 is too broad a range and you could have both bytes within that range a
substantial percentage of the time.
 
D

dg1261

Gutek said:
Seems that this is a rule for Win9x systems. I think that one
might check the lpFileSystemNameBuffer variable from:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/getvolumeinformation.asp

and apply GetVersion() to determine the win version. When
the file system is CDFS (or for any other than FAT, FAT32,
NTFS) and GetVersion indicates Win9x family we can switch
the bytes. Am I right?

Well, based on a sample size of two (you and me), it sounds like it should
work. <g>
 
G

Gutek

dg1261 napisa³(a):
Well, based on a sample size of two (you and me), it sounds like it should
work. <g>

My friend has also confirmed this, so it makes it three :)

Regards,

Gutek
 
W

wooly.bully

Missed the beginning of this discussion.

Try Ralf Brown's Interrupt List at

http://www.ctyme.com/cgi-swish/intr.cgi

and search for the string

volume serial number

From there I found the statement

The serial number is computed from the current date and time when
the disk is created; the first part is the sum of the
seconds/hundredths and month/day, the second part is the sum of the
hours/minutes and year.

Which probably means you cannot retrieve the year value because of the
unknown hours/minutes value.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top