CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data 
Author Message
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

I need to write a procedure which will return the
correct "Bytes Per Allocation Unit (Cluster)" whether
running in native DOS or a DOS box under any flavor
of Windows.

I wrote the following procedure:

--------------begin code snippet--------------------

procedure GetDriveData( {Int21/1C}
 drive: char; {A, B, C etc}
 var SectorsPerCluster: byte; {returns $ff if call failed}
 var BytesPerSector: word;
 var Clusters: word
 );
var
reg: registers;
begin
with reg do begin
 ah:=$1c;
 dl:=ord(upcase(drive))-64;
 intr($21,reg);
 SectorsPerCluster:=al;
 BytesPerSector:=cx;
 Clusters:=dx;
 end;
end;

--------------end code snippet-------------------------

...and it returns the following answer when run in a DOS box
under Win NT 4:

127 SectorsPerCluster; 512 BytesPerSector; 15747 Clusters

...which is obviously not correct, since CHKDSK returns the
following information:

C:\>chkdsk
The type of the file system is NTFS.
Warning!  F parameter not specified
Running CHKDSK in read-only mode.

CHKDSK is verifying files...
File verification completed.
CHKDSK is verifying indexes...
Index verification completed.
CHKDSK is verifying security descriptors...
Security descriptor verification completed.

  6297448 kilobytes total disk space.
  3220167 kilobytes in 52724 user files.
    14718 kilobytes in 3501 indexes.
    80974 kilobytes in use by the system.
     4096 kilobytes occupied by the logfile.
  2981589 kilobytes available on disk.

      512 bytes in each allocation unit.
 12594896 total allocation units on disk.
  5963178 allocation units available on disk.



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

Quote:

>I need to write a procedure which will return the
>correct "Bytes Per Allocation Unit (Cluster)" whether
>running in native DOS or a DOS box under any flavor
>of Windows.

>I wrote the following procedure:

>--------------begin code snippet--------------------

>procedure GetDriveData( {Int21/1C}
> drive: char; {A, B, C etc}
> var SectorsPerCluster: byte; {returns $ff if call failed}
> var BytesPerSector: word;
> var Clusters: word
> );
>var
>reg: registers;
>begin
>with reg do begin
> ah:=$1c;
> dl:=ord(upcase(drive))-64;
> intr($21,reg);
> SectorsPerCluster:=al;
> BytesPerSector:=cx;
> Clusters:=dx;

Perhaps SectorsPerCluster and Clusters should be longints. You also
may want to check int 21, function 7303 (ax=7303h). IIRC, that returns
extended info for large drives.

Regards,
Jim Wilson
(Cheap spam protection in place: remove the 'SpamThis'
from my email ID to reply to me personally)



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data
I'm not sure how this function obtains it's infor-
mation, but if it is done through the Boot Sector,
then it will have trouble.

I would suspect that the Int21 functions would not
properly decode a boot sector of an NTFS volume.

Joe

Quote:

> I need to write a procedure which will return the
> correct "Bytes Per Allocation Unit (Cluster)" whether
> running in native DOS or a DOS box under any flavor
> of Windows.



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data
This is a much more difficult issue than meets the eye.

This old DOS interface has an effective limit of drive size <= 2G.  When a
drive is larger than 2G, the system has two choices: return values that
produce a sort of valid cluster size, number of clusters, and number of
available clusters; or simply lie.  OS/2 chose the first solution.  Windows
lies.  The first solution will result in math errors when using the
returned values to calculate the drive size, and can impact existing
programs.

For example, I wrote a little DOS program that returns the following
results for an HPFS drive in OS/2:

Information returned by DOS for drive I --
  total clusters = 34953
  available clusters = 5754
  sectors per cluster = 512
  bytes per sector = 512

Derived information --
  cluster size = 262144
  drive size = 8947968K

The program was carefully written to avoid math errors.

The OS/2 CHKDSK command returns the following output for the drive:

The current hard disk drive is: I:
The type of file system for the disk is HPFS.
The HPFS file system program has been started.
CHKDSK is searching for lost data.
CHKDSK has searched 100% of the disk.
   8948172 kilobytes total disk space.
     14640 kilobytes are in 4717 directories.
   7437717 kilobytes are in 62817 user files.
     16098 kilobytes are in extended attributes.
      2048 kilobytes are reserved for system use.
   1477668 kilobytes are available for use.

I also modified the DOS program to use the OS/2 native interface, and it
returned the following values --

Information returned by OS/2 for drive I --
  total clusters = 17896344
  available clusters = 2946215
  sectors per cluster = 1
  bytes per sector = 512

Derived information --
  drive size = 8947712K

OS/2 returns most of this information as unsigned long data; only the
sector size is returned as unsigned.

I do not know if there is any way for a 16-bit DOS program to obtain valid
drive information in WinNT, Win9x or WinME.

My system at work runs WinME with a 3 gig drive, and it also returns
useless information.

-- Steve Myers

Quote:

>I need to write a procedure which will return the
>correct "Bytes Per Allocation Unit (Cluster)" whether
>running in native DOS or a DOS box under any flavor
>of Windows.

>I wrote the following procedure:

>--------------begin code snippet--------------------

>procedure GetDriveData( {Int21/1C}
> drive: char; {A, B, C etc}
> var SectorsPerCluster: byte; {returns $ff if call failed}
> var BytesPerSector: word;
> var Clusters: word
> );
>var
>reg: registers;
>begin
>with reg do begin
> ah:=$1c;
> dl:=ord(upcase(drive))-64;
> intr($21,reg);
> SectorsPerCluster:=al;
> BytesPerSector:=cx;
> Clusters:=dx;
> end;
>end;

>--------------end code snippet-------------------------

>....and it returns the following answer when run in a DOS box
>under Win NT 4:

>127 SectorsPerCluster; 512 BytesPerSector; 15747 Clusters

>....which is obviously not correct, since CHKDSK returns the
>following information:

>C:\>chkdsk
>The type of the file system is NTFS.
>Warning!  F parameter not specified
>Running CHKDSK in read-only mode.

>CHKDSK is verifying files...
>File verification completed.
>CHKDSK is verifying indexes...
>Index verification completed.
>CHKDSK is verifying security descriptors...
>Security descriptor verification completed.

>  6297448 kilobytes total disk space.
>  3220167 kilobytes in 52724 user files.
>    14718 kilobytes in 3501 indexes.
>    80974 kilobytes in use by the system.
>     4096 kilobytes occupied by the logfile.
>  2981589 kilobytes available on disk.

>      512 bytes in each allocation unit.
> 12594896 total allocation units on disk.
>  5963178 allocation units available on disk.



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

Quote:

>I need to write a procedure which will return the
>correct "Bytes Per Allocation Unit (Cluster)" whether
>running in native DOS or a DOS box under any flavor
>of Windows.

>I wrote the following procedure:

>--------------begin code snippet--------------------

snip...
>--------------end code snippet-------------------------

>...and it returns the following answer when run in a DOS box
>under Win NT 4:

>127 SectorsPerCluster; 512 BytesPerSector; 15747 Clusters

>...which is obviously not correct, since CHKDSK returns the
>following information:

>C:\>chkdsk
>The type of the file system is NTFS.
>Warning!  F parameter not specified
>Running CHKDSK in read-only mode.

>CHKDSK is verifying files...
>File verification completed.
>CHKDSK is verifying indexes...
>Index verification completed.
>CHKDSK is verifying security descriptors...
>Security descriptor verification completed.

>  6297448 kilobytes total disk space.
>  3220167 kilobytes in 52724 user files.
>    14718 kilobytes in 3501 indexes.
>    80974 kilobytes in use by the system.
>     4096 kilobytes occupied by the logfile.
>  2981589 kilobytes available on disk.

>      512 bytes in each allocation unit.
> 12594896 total allocation units on disk.
>  5963178 allocation units available on disk.

The main problem with your code is that you assume that every file
system type has some kind of "cluster" information. But this is not
true. In the case of NTFS, CHKDSK just returns the sector size (which
is 512 bytes as some kind of standard independend from the operating
system, if someone has other informations, please let me know). The
same goes for other drives with non-FAT filesystems like CD-ROMs or
network drives.
The code you posted will only work for a FAT16 drive, for FAT32 or
no-FAT file systems it just can't show any thing "correct". CHKDSK
assumption to show the sector size is as close as it gets...

Ralf



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

[snip]

Quote:
>> SectorsPerCluster:=al;
>> BytesPerSector:=cx;
>> Clusters:=dx;

>Perhaps SectorsPerCluster and Clusters should be longints.

What good does it do to declare SectorsPerCluster as a longint,
if the result is being returned from the interrupt in an 8-bit register?


Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

Quote:

>I'm not sure how this function obtains it's infor-
>mation, but if it is done through the Boot Sector,
>then it will have trouble.

>I would suspect that the Int21 functions would not
>properly decode a boot sector of an NTFS volume.

I'm not talking about booting to plain DOS and then
using that function to query an NTFS disk.

I'm talking about booting to NT and then opening up a DOS
box and then calling the DOS function from within an app
running in that DOS box.  

I would have expected whoever wrote the DOS box code to know
how to ask NT for the information.

The whole point of operating system functions is to relieve the
application developer of such concerns.



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

Quote:


>>I need to write a procedure which will return the
>>correct "Bytes Per Allocation Unit (Cluster)" whether
>>running in native DOS or a DOS box under any flavor
>>of Windows.

>>I wrote the following procedure:

[snip]

Quote:
>The main problem with your code is that you assume that every file
>system type has some kind of "cluster" information.

Hi Ralf,

I really don't assume anything, except perhaps that whoever wrote the "DOS
box" interface for Win NT would make an attempt to return valid information
for the DOS API calls.

If Win NT with NTFS has no clusters - i.e. it allocates at sector
resolution - then one might reasonably expect the authors of the DOS box
under Win NT to make the DOS API return "1" as the answer for "Sectors per
Cluster".  

Quote:
>The code you posted will only work for a FAT16 drive, for FAT32 or
>no-FAT file systems it just can't show any thing "correct".

"can't" is the wrong word.  there's no reason why it couldn't show the
correct value for FAT32.


Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data
stI'm talking about booting to NT and then opening up a DOS

Quote:
> box and then calling the DOS function from within an app
> running in that DOS box.

> I would have expected whoever wrote the DOS box code to know
> how to ask NT for the information.

He didn't :-) NT doesn't support the extra (LFN/FAT32'ish) dos ints in
dosboxes. For me, this is one of the big problems of NT IMHO, at least
seen from the workstation (as opposed to server) side. We had a lot of
problems with that, each FPC release again (since the installer is then
unable to dezip zips with LFNs with them). As a solution we started
packing both a win32 and dos installer.

Win 2000 does support INT21 AH=7xxx however, and afaik also for NTFS.

Quote:
> The whole point of operating system functions is to relieve the
> application developer of such concerns.

Probably M$ though that Dos would be phased out much sooner, which is
not even that strange, but that turned out to be wrong.

--




Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

Quote:
> The main problem with your code is that you assume that every file
> system type has some kind of "cluster" information.

Sure it has, any block orientated device has a block size, and
everyfilesystem driver calls it differently (e.g. Ext2fs from Linux
calls it INODE size), but in the end it is all the same:

Clustersize in a broader sense is the amount of space the free space of
the drive decreases when you enlarge a zero byte file to a 1 byte file.

This definition is not perfect (some filesystems might allocate blocks
for 0 bytes files, and also compressed filesystems can act funny), but
quite adequate to grasp the concept.

Also this definition does not cover certain historical reasons. (like a
maximal  number of clusters on FAT16)

Quote:
> But this is not  true. In the case of NTFS, CHKDSK just returns the > sector size (which > is 512 bytes as some kind of standard independend from > the operating
> system, if someone has other informations, please let me know).

Hmm. IIRC the default clustersize of NTFS is much higher (which it is
good, it is already (relatively) slow enough already), so I think the
512 bytes size is too optimistic.

However it doesn't matter, since even if it was 512 bytes, that would be
the clustersize, only in that case it happens to be the same as the disk
size.

Quote:
> The
> same goes for other drives with non-FAT filesystems like CD-ROMs or
> network drives.
> The code you posted will only work for a FAT16 drive, for FAT32 or
> no-FAT file systems it just can't show any thing "correct". CHKDSK
> assumption to show the sector size is as close as it gets...

For cdroms, the minimal size is always 2048 afaik, except maybe for
Adaptec DirectCD stuff.

For other filesystems you can also do it, but not in a dosbox under NT.
However with a win32 call (getdiskfreespacea or so) you can get it even
under NT, but that is not possible from a dosprogram without certain
really heavy workarounds. (like loading VXDs that act as intermediate)

--




Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

schreibt:

Quote:
>I would have expected whoever wrote the DOS box code to know
>how to ask NT for the information.

That's not a matter of the DOS box, which only is the user interface for any 16
or 32 bit non-GUI program.

Since many interrupts do make sense only for old small disks and file systems,
how can you be sure that NT will even make drives visible and available to such
legacy programs, which obviously cannot correctly handle such drives?

When a child wants to add a picture to dad's business report, then a clever dad
will create a copy of *any* document, which can be discarded after the child
has finished painting. This way both are happy, the child could paint, and
daddy has not lost important information ;-)

Quote:
>The whole point of operating system functions is to relieve the
>application developer of such concerns.

That's correct, and therefore you can simply call the *appropriate* API
functions, which replace the old interrupts.

In order to get correct answers you always should use the appropriate
functions, otherwise you risk to get wrong answers on inappropriate questions.
So when you want your program to produce meaningful results "under any flavor
of Windows", then you should know about the restrictions of *any* flavor of
Windows, and accordingly use the appropriate functions to retrieve the desired
information from the *actual* flavor of Windows.

But in your case better substitute "Windows" by "DOS", since you are using DOS
functions. So when you use interrupts, specified for e.g. DOS 3.1, you first
should check that the running DOS version meets your expectations. It's *your*
responsibility, to check the environment of your program, and to use the
appropriate functions accordingly.

DoDi



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data
On Sat, 30 Sep 2000 20:23:55 +0200, Marco van de Voort

Quote:

>NT doesn't support the extra (LFN/FAT32'ish) dos ints in dosboxes.

Not out of the box, but check this:
  http://www.goof.com/pcg/djgpp/ntlfn.html

--
<O
( \   GNOME vs. KDE: the game!
 X    http://pineight.8m.com/nes.htm

This is McAfee VirusScan. Add these two lines to your signature to
prevent the spread of signature viruses.  http://www.mcafee.com/



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

Quote:


>(student) schreibt:

>>I would have expected whoever wrote the DOS box code to know
>>how to ask NT for the information.

>That's not a matter of the DOS box,

Of course it is.  The whole point of the DOS box is to run DOS programs.  
Whoever wrote the Win NT DOS box code COULD HAVE chosen to return more
meaningful information in response to that interrupt.  They chose not to.

Quote:
>Since many interrupts do make sense only for old small disks and file
>systems, how can you be sure that NT will even make drives visible and
>available to such legacy programs,

Have you ever used Win NT?  

NTFS-formatted disks under Win-NT are fully visible to DOS apps running in
the Win-NT DOS box.  That's the whole point of the DOS box.   Why have a
DOS box if DOS apps can't run in it?

Quote:
>which obviously cannot correctly
>handle such drives?

Huh?  DOS apps running in a DOS box under Win NT can read and write files
to an NTFS-formatted disk.  The DOS box code handles all the details.

Quote:
>When a child wants to add a picture to dad's business report, then a
>clever dad will create a copy of *any* document, which can be discarded
>after the child has finished painting. This way both are happy, the
>child could paint, and daddy has not lost important information ;-)

Once upon a time in a land far, far away there were three Blackbirds.  The
first bird flew off to the North in search of food and never returned.  The
second bird sat perched on a limb high in a tree until one day he was hit
by lighting.  The third bird is still trying to figure out what your
analogy is supposed to mean.

Quote:
>>The whole point of operating system functions is to relieve the
>>application developer of such concerns.

>That's correct, and therefore you can simply call the *appropriate* API
>functions, which replace the old interrupts.

There are no "appropriate API functions" in a Win-NT DOS box which "replace
the old interrupts".   The whole point of a DOS box is to make a DOS app
think it is running under DOS.  The designers of the DOS box COULD HAVE
chosen to return useful information for that interrupt.  For some reason,
they chose not to.

Quote:
>In order to get correct answers you always should use the appropriate
>functions,

... and in DOS, Get Drive Data *is* the appropriate function.  

Quote:
>So when you use interrupts, specified for e.g. DOS 3.1,

Get Drive Data works for DOS 6.2

One might reasonably have expected the designer(s) of the Win NT DOS box
code to make an effort to support the function calls of the then-current
version of DOS.

Quote:
>It's *your* responsibility, to check the environment of
>your program, and to use the appropriate functions accordingly.

So, back to original question:  Is there, or is there not, a DOS function
call which is properly supported in all flavors of Windows DOS boxes which
returns the size of the disk allocation units?  Yes or no?

If the answer is no, then it's because Microsoft either 1) chose not to.
for reasons which have not been articulated, or 2) was incompetent.



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

Quote:


>>>I need to write a procedure which will return the
>>>correct "Bytes Per Allocation Unit (Cluster)" whether
>>>running in native DOS or a DOS box under any flavor
>>>of Windows.

>>>I wrote the following procedure:

>[snip]

>>The main problem with your code is that you assume that every file
>>system type has some kind of "cluster" information.

>Hi Ralf,

>I really don't assume anything, except perhaps that whoever wrote the "DOS
>box" interface for Win NT would make an attempt to return valid information
>for the DOS API calls.

Well, i think it was omitted as in NT you don't have access to the
drive at a sector/cluster level. Direct disk read/writes are not
possible (at least without special drivers)

Quote:
>If Win NT with NTFS has no clusters - i.e. it allocates at sector
>resolution - then one might reasonably expect the authors of the DOS box
>under Win NT to make the DOS API return "1" as the answer for "Sectors per
>Cluster".  

That might have been a possible solution...
Quote:

>>The code you posted will only work for a FAT16 drive, for FAT32 or
>>no-FAT file systems it just can't show any thing "correct".

>"can't" is the wrong word.  there's no reason why it couldn't show the
>correct value for FAT32.

Because the INT21 function you used is limited to 64K clusters, while
a FAT32 drive usually has more than that (a 512MB partition, the
smallest size for a FAT32 partition has already 128K clusters, which
exceeds the maximum value of a 16bit register!)

Ralf



Wed, 18 Jun 1902 08:00:00 GMT  
 CHKDSK, Win NT, and DOS Int21 Function 1Ch Get Drive Data

Quote:

>On Sat, 30 Sep 2000 20:23:55 +0200, Marco van de Voort

>>NT doesn't support the extra (LFN/FAT32'ish) dos ints in dosboxes.

>Not out of the box, but check this:
>  http://www.goof.com/pcg/djgpp/ntlfn.html

After that, even a cd "LFN" doesn't work anymore.

Not stable enough :-)



Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 25 post ]  Go to page: [1] [2]

 Relevant Pages 

1. How do I know DOS program is under Win 95 or Win NT

2. Help getting Interbase to work on a web server (D2 Dev/Win NT 3.51/IIS 3.0)

3. Help: MS-DOS Screen Capture (in Full-Screen Mode) Under Win 95/98/NT

4. Getting Data from Screen in Win 95 with TurboPascal 6

5. DOS Function in BP/WIN 7.0

6. DUAL BOOT WIN NT WIN 98

7. SQL Server for Win 95 and Win NT?

8. Getting drive sizes larger than 2 gigs...

9. WIN API Help: Map Network Drive: WinFW 3.11

10. function to verify if a drive exists

11. Turbo Pascal 5.5 Large Drive Function/Procedure

12. Turbo Pascal gets 100% Windows NT CPU

 

 
Powered by phpBB® Forum Software