flat assembler
Message board for the users of flat assembler.

Index > DOS > GetDiskFreeSpaceEx


Is this useful ?
YES, very much :-)
16%
 16%  [ 2 ]
Acceptable
41%
 41%  [ 5 ]
Stop polluting this serious developers forum with old DOS crap
8%
 8%  [ 1 ]
Stop polluting this DOS subforum with Windows crap
0%
 0%  [ 0 ]
NO idea, I'm drunk, just want to submit a vote :-D
33%
 33%  [ 4 ]
Total Votes : 12

Author
Thread Post new topic Reply to topic
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 13 Jan 2008, 03:45
Code:
;
; DOS "GetDiskFreeSpaceEx" INT $21/$7303 test
; (CL) Copyleft 2008-01-13 Public Domain - ABUSE at YOUR own risk !!!
; http://board.flatassembler.net/topic.php?t=8139
; Compile with FASM
; Results in .COM of 1067 bytes (sorry, not even 1 GibiByte filled Very Happy )
;
; Usage:
;
; GDFSEX drive [C] optional "C" will set Carry flag before call
; GDFSEX C:
; GDFSEX C:\ C
;
; !!! 80386 Required !!!
;
; INT $21 / $7303 "GetDiskFreeSpaceEx"
; FreeDOS,EDR-DOS - FAT32 - GET EXTENDED FREE SPACE ON DRIVE
; Call:   AX = $7303
;         DS:DX -> ASCIZ string for drive ("C:\" or "\\SERVER\Share")
;         ES:DI -> buffer for extended free space structure
;         CX = length of buffer for extended free space
; Return: CF clear if successful
;            ES:DI buffer filled
;         CF set on error
;            AX = error code
;
; 00   WORD    (ret) size of returned structure
; 02   WORD    (call) structure version (0)
;              (ret) actual structure version (0)
;
; 04   DWORD   sectors per cluster
; 08   DWORD   bytes per sector
;
; 0C   DWORD   free clusters
; 10   DWORD   total clusters
; 14   DWORD   free sectors phys
; 18   DWORD   total sectors phys
; 1C   DWORD   free clusters "alloc"
; 20   DWORD   total clusters "alloc"
;
; ToDo/Bugs:
; - Remove messy vars from code
; - Decimal > 4 GiB

format binary as "COM"
use16
org $0100

;[8086]
   push  cs
   pop   es

   mov   dx,tx1
   call  ssdxprint  ; Welcome message
   jmp   @f
;----------

tx1: db 3,'DOS "GetDiskFreeSpaceEx" INT $21/$7303 test',3
     db '(CL) 2008-01-13 Public Domain - ABUSE at YOUR own risk !!',3
     db 'Syntax: GDFSEX drive [C]',2

xdrive:  db 8  dup (0)
xbuff:   db 64 dup (0)
xcf:     db 0
xax:     db 0,0
xeax:    db 0,0,0,0

@@:   mov   ah,[$80]
      cmp   ah,3          ; !!! cmd string length + 1
      jb    qq2           ; <3, no drive, default to current, and no "C" flag

      mov   cl,7          ; Max lenght
      mov   si,$82
      mov   di,xdrive
@@:   lodsb               ; Pick
      cmp   al,32
      jbe   qq3           ; End
      stosb
      dec   cl
      jnz   @b            ; Loop until 7 chars or bad char

qq3:  lodsb               ; "C" flag ?
      cmp   al,67
      jne   qq1           ; NO
      inc   byte [xcf]    ; YES
      jmp   short qq1
;--------------------

qq2:  mov  ah,$19         ; DOS 1+ - GET CURRENT DEFAULT DRIVE
      int  $21            ; Return: AL = drive (0 = A: , 1 = B: , etc)
      add  al,65
      mov  ah,58
      mov  [xdrive],ax

qq1:  mov   dx,tx2
      call  ssdxprint
      mov   dx,xdrive
      call  ssdxprint
      mov   al,124
      call  sscharout
      call  sseol
      mov   dx,tx3
      call  ssdxprint
      mov   al,[xcf]
      add   al,48
      call  sscharout
      call  ssdeol
      jmp   @f
;-------------

tx2: db 'Checking drive: |',0
tx3: db 'Calling INT $21 with AX=$7303 and flag(C)=',0

@@:   mov   ax,$7303
      mov   cx,48
      mov   dx,xdrive
      mov   di,xbuff
      mov   bl,[xcf]
      add   bl,255
      int   $21            ; !!! HOT !!!
      mov   bl,0
      adc   bl,0
      mov   [xcf],bl
      mov   [xax],ax
      mov   al,[xbuff]
      cmp   al,49
      jae   qiq3           ; Faulty, we asked for 48 bytes only
      cmp   al,36          ; Minimum
      jae   qiq4           ; Good
qiq3: mov   byte [xbuff],0 ; Bad Sad

qiq4: mov   dx,tx4
      call  ssdxprint
      mov   al,[xcf]
      add   al,48
      call  sscharout      ; Flag(C)
      call  sseol
      mov   dx,tx5
      call  ssdxprint
      mov   ax,[xax]
      call  sshexd16       ; AX
      mov   dx,tx6
      call  ssdxprint
      cmp   byte [xbuff],0
      jne   @f             ; GOOD
      mov   dx,tx7
      call  ssdxprint
@@:   mov   dx,tx8
      call  ssdxprint
      jmp   @f
;-------------

tx4:  db 'Results:',3
      db 'Flag(C)=',0
tx5:  db 'AX=',0
tx6:  db 3,'Buffer ',0
tx7:  db 'NOT ',0
tx8:  db 'filled',2

@@:   cmp   byte [xcf],0
      je    @f            ; Flag(C)=0

      mov   dx,tx11
      call  ssdxprint     ; Call failed
      jmp   qq5           ; Done
;--------------

@@:   cmp   byte [xbuff],0
      jne   @f            ; GOOD, we had success

      mov   dx,tx10
      call  ssdxprint     ; Unsupported
      jmp   qq5           ; Done
;--------------

@@:   mov   dx,tx12
      call  ssdxprint     ; 9 x desc

;[80386]
      xor   ecx,ecx
@@:   mov   eax,[xbuff+ecx]
      push  ecx
      push  ax
      shr   eax,16
      call  sshexd16
      call  ssapo
      pop   ax
      call  sshex16
      mov   al,32
      call  sscharout
      pop   ecx
      add   ecx,4
      cmp   ecx,36
      jne   @b
      call  ssdeol

      mov   dx,tx9
      call  ssdxprint       ; Free

      mov   eax,[xbuff+4]   ; s/c
      mov   ebx,[xbuff+8]   ; b/s
      mul   ebx
      test  edx,edx
      jz    @f              ; Must be 0, otherwise >= 4 GiB cluster !!! Shocked
      xor   eax,eax
@@:   mov   ebx,[xbuff+$0C] ; Free clusters
      mul   ebx             ; Now we have final result in EDX:EAX
      mov   [xeax],eax      ; Save lower 32 bits it here
      test  edx,edx
      jz    @f              ; < 4 GiB, also dec result Smile

      mov   ax,dx           ; Would work up to 2^48 bytes = 16 TiB
      call  sshexd16        ; Here we get full result but only in HEX, no dec Sad
      call  ssapo
      mov   ax,[xeax+2]
      call  sshex16
      call  ssapo
      mov   ax,[xeax]
      call  sshex16
      jmp   qq5            ; Done
;--------------

@@:   mov   ax,[xeax+2]
      call  sshexd16
      call  ssapo
      mov   ax,[xeax]
      call  sshex16
      mov   al,32
      call  sscharout
      mov   eax,[xeax]
      call  ssdec32

qq5:  call  ssdeol
      mov   ax,$4C00
      int   $21
;--------------

tx9:  db 'Free: ',0
tx10: db 'This faulty DOS/DOG seems not to support "GetDiskFreeSpaceEx" Sad',0
tx11: db 'Call failed, drive does not exist Very Happy',0
tx12: db 'ver...size ..sec/clus bytes/sect '
      db 'free.clust total.clus free.sects total.secs free.clust total.clus',1

; SUB Write HEXD16 | input in AX | trashes all | pritns "$" also

sshexd16:
      push  ax
      mov   al,36
      call  sscharout
      pop   ax
      ; pass

; SUB Write HEX16 | input in AX | trashes all

sshex16: mov   cl,4
qq6:     mov   dl,ah       ; DL <- AH
         shl   ax,4
         shr   dl,4
         add   dl,$30
         cmp   dl,$3A
         jb    @f          ; "b" : below unsigned | OK, a number
         add   dl,7
@@:      push  ax
         push  cx
         mov   al,dl
         call  sscharout
         pop   cx
         pop   ax
         dec   cl
         jnz   qq6
         ret
;-----------

ssapo:  mov  al,39
        jmp  short sscharout
;---------------------------

ssdeol: call sseol
; pass Very Happy

sseol: mov al,13
       call sscharout
       mov al,10
; pass Very Happy

sscharout: push  ax    ; In: AL
           push  bx
           push  dx
           cmp   al,10
           jb    @f    ; Skip crap "characters"
           mov   ah,2
           mov   dl,al
           int   $21
@@:        pop   dx
           pop   bx
           pop   ax
           ret
;-------------

ssdxprint:
         push ax   ; IN: DX ||| ASCIIZ: 0 instead of "$" !!!
         push bx   ; 0:END 1:EOL+END 2:DEOL+END 3:EOL
         push dx

         mov  bx,dx

llprlop:
         mov   al,[bx]
         cmp   al,0
         jz    qq7
         cmp   al,1
         jnz   @f
         call  sseol
         jmp   short qq7
;-----------------------
@@:      cmp   al,2
         jnz   @f
         call  ssdeol
         jmp   short qq7
;-----------------------
@@:      cmp   al,3
         jnz   @f
         call  sseol
         mov   al,0
@@:      call  sscharout
         inc   bx
         jmp   short llprlop
;---------------------------
qq7:     pop  dx
         pop  bx
         pop  ax
         ret
;-----------

; EXDEC.ASM written by MAD for use with the Assembly Tutorial Chapter 4
; Upgraded to 32 bits Wink In : EAX
; Converts a number in EAX to decimal format and outputs it to the screen

ssdec32:
    mov   cl,0                          ; POP counter - preset to 0
    mov   ebx,10                        ; Divisor: divide by 10
deciloop:
    xor   edx,edx                       ; High 32 bits zero.
    div   ebx                           ; Remainder in EDX, quotient in EAX
    inc   cl                            ; Increase POP counter
    push  dx                            ; And PUSH , no BYTE PUSH exists Sad
    test  eax,eax                       ; Is quotient zero?
    jnz   deciloop                      ; If not, get one more number

popeloop:
    pop   ax                            ; Get number
    add   al,48                         ; Add ASCII base (48="0")
    call  sscharout
    dec   cx
    jnz   popeloop
    ret
;------

;END.
    


Download now : http://board.flatassembler.net/download.php?id=3529 ( 7 KiB )

Enjoy Very Happy

The goal of this code is, besides providing an example of DOS development with FASM, testing bugs in DOS kernels.

Following bugs or non-optimal behavior occurs:

FreeDOS
- Call fails if no slash in drive string: "C:\" works, "C:" fails. EDR-DOS doesn't have this bug.

EDR-DOS
- Call returns with AX=0 and thus AL=0. According to (moronious) last "official" version of RBIL from 2000, "AL=0 and flag(C)=0" is the evidence of non-supported call. According to Udo (not registered here (yet)), his implementation is 100% correct (maybe he is somewhat right - I don't have the final evidence of opposite, because of AH=0 also), and it's 100% safe (here I have to oppose, it's NOT safe, because of (moronious) RBIL at least). Fix is easy - just set AL to 1 (or any other non-ZERO value before returning. Wink FreeDOS doesn't have this problem.
- Call does not fail if drive string is garbage, it uses default drive. FreeDOS doesn't have this problem, it correctly fails. Both do correctly fail on a valid-looking non-existent drive like "P:\" if you have no "P". Fix: accept "\" and maybe "." as default drive, "C:" or "C:\" or any other letter to test a given drive, but fail otherwise.

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 13 Jan 2008, 03:45
View user's profile Send private message Reply with quote
Picnic



Joined: 05 May 2007
Posts: 1403
Location: Piraeus, Greece
Picnic 13 Jan 2008, 13:35
Ι will run it as soon as I find change, i guess i need pure Dos or FreeDos, old versions of Windows is out of the question ?

> Stop polluting this serious developers forum with old DOS crap

Oh no, please keep posting, Dos is still alive in nowdays, at least for some of us DOS386.
I'm planning to buy an old PC sooner or later to install Dos again.
Post 13 Jan 2008, 13:35
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 13 Jan 2008, 15:24
I don't like DOS because if I want commandline, I'll use Linux or CMD.exe. If I want graphics, I'll use Linux or Windows. I don't find DOS as appealing as in the 90's.
Post 13 Jan 2008, 15:24
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Vov4ik



Joined: 20 May 2007
Posts: 28
Location: USSR, Moscow Region
Vov4ik 13 Jan 2008, 16:19
If i want speed, reliability and all potential of PC, i'll use DOS. Graphics is implemented slowly in windows, everybody knows this, linux is faster, but runs in protected mode and too highly abstracted from hardware. Of course, much of "multimedia" hardware is vendor-specific and undocumented, so, without windoze drivers, we have to be content with basic capabilities.
Post 13 Jan 2008, 16:19
View user's profile Send private message ICQ Number Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo 25 Jan 2008, 04:10
Madis, use the right tool for the job. Or at least make sure it's fun (else why bother?). You can always dual boot or run something like DOSBox or DOSEMU, if necessary. Smile
Post 25 Jan 2008, 04:10
View user's profile Send private message Visit poster's website Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1905
DOS386 18 Jun 2009, 11:51
WARNING: bumped almost 2 years old topic

I wrote:

Quote:

FreeDOS

- Call fails if no slash in drive string: "C:\" works, "C:" fails. EDR-DOS doesn't have this bug.


Fixed in 2038 kernel: http://sf.net/project/showfiles.php?group_id=5109&package_id=5152 Smile
Post 18 Jun 2009, 11:51
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.