flat assembler
Message board for the users of flat assembler.
Index
> DOS > GetDiskFreeSpaceEx |
Is this useful ? | |||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||
Total Votes : 12 |
Author |
|
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 ) ; ; 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 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 !!! 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 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 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" ',0 tx11: db 'Call failed, drive does not exist ',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 sseol: mov al,13 call sscharout mov al,10 ; pass 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 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 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 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. 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 |
|||
13 Jan 2008, 03:45 |
|
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.
|
|||
13 Jan 2008, 15:24 |
|
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.
|
|||
13 Jan 2008, 16:19 |
|
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.
|
|||
25 Jan 2008, 04:10 |
|
DOS386 18 Jun 2009, 11:51
WARNING: bumped almost 2 years old topic
I wrote: Quote:
Fixed in 2038 kernel: http://sf.net/project/showfiles.php?group_id=5109&package_id=5152 |
|||
18 Jun 2009, 11:51 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.