hello all ...
I am trying to get the free and used disk space of a specific drive like D:\
This is form MSDN
Quote
BOOL GetDiskFreeSpaceEx(
LPCWSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailableToCaller,
PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes
);
The values obtained by this function are of type ULARGE_INTEGER. Be sure not to truncate these values to 32 bits.
how can i get free and used bytes ??
need 64-bit !!??
Hutch had a great llittle program for that a few months back
let me see if i can find it with the forum search tool...
here is the thread i was thinking of...
http://www.masm32.com/board/index.php?topic=12385.0
and a related one...
http://www.masm32.com/board/index.php?topic=12365.0
You might need to write a sticky note giving a detailed explanation with pictures Dave, its magic that the search button would yield results!!! o0
Sorry, i couldn't help that. Don't mind me, its all tongue in cheek.
HR,
Ghandi
Here is a working snippet (only the Print Str$ part requires the MB lib, replace with crt printf or similar if needed).
include \masm32\MasmBasic\MasmBasic.inc
.data
FreeBytesAvailableToCaller dq 0
TotalNumberOfBytes dq 0
TotalNumberOfFreeBytes dq 0
DirectoryName db "D:\", 0
OneGiga = 1024*1024*1024
.code
start: invoke GetDiskFreeSpaceEx,
offset DirectoryName,
offset FreeBytesAvailableToCaller,
offset TotalNumberOfBytes,
offset TotalNumberOfFreeBytes
Print Str$("FreeBytesAvailable:\t%4f GB\n", q:FreeBytesAvailableToCaller/OneGiga)
Print Str$("TotalNumberOfBytes:\t%4f GB\n", q:TotalNumberOfBytes/OneGiga)
Print Str$("TotalNumberOfFreeBytes:\t%4f GB\n", q:TotalNumberOfFreeBytes/OneGiga)
Inkey "bye"
Exit
end start
FreeBytesAvailable: 141.3 GB
TotalNumberOfBytes: 149.0 GB
TotalNumberOfFreeBytes: 141.3 GB
Trying to get the used space of drive K: ...
may b the subtraction operatio is wrong
it shows correct output for total and free space .
i am trying to calculate the used space by (total space - free space)
here is the code:
Quote
.data
freeSpace dd ?,? ;GetDiskFreeSpaceEx expects this to be 64-bits
totalSpace dd ?,? ;GetDiskFreeSpaceEx expects this to be 64-bits
usedSpace dd ?,?
outputbuffer db 256 dup(?)
totalbuffer db 256 dup(?)
usedbuffer db 256 dup(?)
freebuffer db 256 dup(?)
report db "Total Space ............ %s",13,10,"Used Space ............ %s",13,10,"Free Space ............ %s"
.code
start:
invoke GetDiskFreeSpaceEx, CTEXT("K:\"),addr freeSpace,addr totalSpace,0
invoke StrFormatByteSize64, totalSpace, totalSpace+4, ADDR totalbuffer, SIZEOF totalbuffer
invoke StrFormatByteSize64, freeSpace, freeSpace+4, ADDR freebuffer, SIZEOF freebuffer
mov eax , totalSpace
mov ebx , freeSpace
sub eax , ebx
mov usedSpace , eax
invoke StrFormatByteSize64, usedSpace, usedSpace+4, ADDR usedbuffer, SIZEOF usedbuffer
invoke wsprintf , addr outputbuffer , addr report , addr totalbuffer , addr usedbuffer , addr freebuffer
invoke MessageBox, NULL,addr outputbuffer,CTEXT("K:\ Drive Info"), MB_OK
invoke ExitProcess,NULL
end start
it also shows some extra character after last line ...
here is the output copied from MessageBox.
Quote
Total Space ......... 7.46 GB
Used Space ......... 502 MB
Free Space .......... 2.97 GBK:\
what is the solution ??
Quotereport db "Total Space ............ %s",13,10,"Used Space ............ %s",13,10,"Free Space ............ %s",0
...
mov eax,totalSpace
mov edx,totalSpace+4
sub eax,freeSpace
sbb edx,freeSpace+4
mov usedSpace,eax
mov usedSpace+4,edx
what is the reason for adding 4 ??
actually i didn't understand it :red
you need 64Bit arithmetic because file/directory sizes are 64 bit width. The '+4' is used to access the high order DWORD of a QWORD. (4 is added to the addres of variable, not to the content)
Ghandi
this is a case where i knew what to look for - i also knew who the author was, which helped me narrow it down a bit :P
to qWord:
what is the reason for using both sub and sbb??
sub eax,freeSpace
sbb edx,freeSpace+4
what is the reason for using 4 parameters in StrFormatByteSize64 ??
there should be three parameters ..
Quote from: maruf10 on April 10, 2010, 05:54:04 AM
to qWord:
what is the reason for using both sub and sbb??
sub eax,freeSpace
sbb edx,freeSpace+4
It is used to do 64 bit subtraction (subtract then subtract with borrow).
Quotewhat is the reason for using 4 parameters in StrFormatByteSize64 ??
there should be three parameters ..
Because you are pushing 32bit numbers and the first parameter is a 64 bit number, you have to push it in 2 parts hence the 4 parameters instead of 3.
Here is a Example from Florian Mücke
.data
lpRootPathName db "\",0
lpSPerClus dd 0
lpBPerSec dd 0
lpNOfFreeClus dd 0
lpTotalNClus dd 0
ConvertStr db "%lu kB available to caller",13,10,"%lu k total",0
String db 255 dup (0)
caption db "GetDiskFreeSpace",0
lpDir db "\",0
lpFBAvailableQ dq 0
lpTotalBytesQ dq 0
lpFBAvailableD dd 0
lpTotalBytesD dd 0
String1 db 255 dup (0)
OneK REAL10 1024.0
.code
start:
invoke GetDiskFreeSpaceEx, ADDR lpDir, ADDR lpFBAvailableQ, ADDR lpTotalBytesQ, NULL
finit ;initialisiert FPU
fld OneK ;laed eine Realzahl (1024,0) in den TOS
fild lpFBAvailableQ ;laed lpFB... in den TOS
fdiv ST(0),ST(1) ;dividiert zwei Realzahlen
fistp lpFBAvailableD ;speichert Integer aus dem TOS und poppt
fild lpTotalBytesQ
fdiv ST(0),ST(1)
fistp lpTotalBytesD
invoke wsprintf, ADDR String1, ADDR ConvertStr,lpFBAvailableD, lpTotalBytesD
invoke MessageBox,0,ADDR String1,ADDR caption,MB_OK
push 0
call ExitProcess
end start
mov eax,totalSpace
mov edx,totalSpace+4
shrd eax,edx,10 ;10 for KB, 20 for MB, eax has value
I prefer to see "4096 Meg" instead of "4294967296 bytes" (or even "4 Gig" but accuracy is lost with too many shifts (3.99 Gig will show as "3 Gig")).
Quote from: sinsi
I prefer to see "4096 Meg" instead of "4294967296 bytes" (or even "4 Gig" but accuracy is lost with too many shifts (3.99 Gig will show as "3 Gig")).
The trick of course it to display them in a magnitude appropriate manner, especially when the number may be a few thousand bytes, up to a couple of terabytes.
-Clive
(eq.1) minimum number of digits
Dmin = FLOOR((N-1) x LOG(2)) + 1
(eq.2) maximum number of digits
Dmax = FLOOR(N x LOG(2)) + 1
D = number of decimal digits
N = number of bits
figure out how many digits you want to see (4 to 5 seems adequate)
test the upper (64 - N) bits for all 0's
if any of those bits are non-zero, SHR,10, increment the magnitude counter, and test again
include \masm32\include\masm32rt.inc
include \masm32\include\debug.inc
include \masm32\include\shlwapi.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\debug.lib
includelib \masm32\lib\shlwapi.lib
.data
freeSpace dd ?,? ;GetDiskFreeSpaceEx expects this to be 64-bits
totalSpace dd ?,? ;GetDiskFreeSpaceEx expects this to be 64-bits
usedSpace dd ?,?
outputbuffer db 256 dup(?)
totalbuffer db 256 dup(?)
usedbuffer db 256 dup(?)
freebuffer db 256 dup(?)
report db "Total Space ............ %s",13,10,"Used Space ............ %s",13,10,"Free Space ............ %s",0
MAXPATH equ 512
driveName db MAXPATH dup (?)
colon db ":",0
slash db "/",0
_title db " ",0
space db " ",0
info db " Drive Information",0
info2 db "Submitte By Raisul",0
prompt1 db "ENTER DRIVE NAME : ",0
prompt2 db "DO YOU WANT TO CONTINUE(y/n)?? ",0
decision db MAXPATH dup (?)
Y db "y",0
N db "n",0
newline db 10,13,0
.code
start:
invoke ClearScreen
.repeat
invoke StdOut , addr prompt1
invoke StdIn , addr driveName , MAXPATH
MOV BYTE PTR [driveName+EAX-2],0
invoke lstrcat , addr driveName , addr colon
invoke lstrcat , addr driveName , addr slash
invoke GetDiskFreeSpaceEx, addr driveName,addr freeSpace,addr totalSpace,0
invoke StrFormatByteSize64, totalSpace, totalSpace+4, ADDR totalbuffer, SIZEOF totalbuffer
invoke StrFormatByteSize64, freeSpace, freeSpace+4, ADDR freebuffer, SIZEOF freebuffer
mov eax,totalSpace
mov edx,totalSpace+4
sub eax,freeSpace
sbb edx,freeSpace+4
mov usedSpace,eax
mov usedSpace+4,edx
invoke StrFormatByteSize64, usedSpace, usedSpace+4, ADDR usedbuffer, SIZEOF usedbuffer
invoke wsprintf , addr outputbuffer , addr report , addr totalbuffer , addr usedbuffer , addr freebuffer
invoke lstrcpy , addr _title , addr driveName
invoke lstrcat , addr _title , addr info
invoke lstrcat , addr _title , addr info2
invoke MessageBox, NULL,addr outputbuffer,addr _title, MB_OK
invoke StdOut , addr newline
.repeat
invoke StdOut , addr prompt2
invoke StdIn , addr decision , MAXPATH
MOV BYTE PTR [decision+EAX-2],0
invoke lstrcmp , addr decision , addr Y
mov ebx , eax
invoke lstrcmp , addr decision , addr N
mov ecx , eax
.until (ebx == 0 || ecx == 0)
.until ebx!=0
invoke ExitProcess,NULL
end start
>> give me some idea to add graphical interface with the above code
driveName db MAXPATH dup (?)
What is the use of MAXPATH
Quote from: CliveThe trick of course it to display them in a magnitude appropriate manner, especially when the number may be a few thousand bytes, up to a couple of terabytes.
Someone already worked out a procedure to do that, I wasn't able to find it though.
Quote from: Greg Lyon
Someone already worked out a procedure to do that, I wasn't able to find it though.
I wrote this many years ago for a disc media application, take it as a pseudo-code example.
-Clive
// KILO,MEGA,GIGA,TERA,PETA,EXA,ZETTA,YOTTA
char * MemSize(QWORD Size)
{
static const char Symbol[] = "KMGTPEZY?";
static char Str[32];
int Sym;
double Units;
double Capacity;
Sym = 0;
Units = 1024.0;
Capacity = (double)Size / Units;
while((Capacity > Units) || (Sym >= (sizeof(Symbol) - 1)))
{
Capacity = Capacity / Units;
Sym++;
}
sprintf(Str, "%6.2lf %cB", Capacity, Symbol[Sym]);
return(Str);
}
Quote from: raisul1
driveName db MAXPATH dup (?)
What is the use of MAXPATH
To allocate enough space for a fully described path. Seems overkill for "C:\", but better than allocating an insufficient one.
-Clive
How can i add background image in my asm code
Autoranging capacity conversion in assembler using 64-bit integers.
-Clive
.386
.MODEL FLAT,C
.CODE
; Convert 64-bit capacity number to form xxx.yyy KB, xxx.yyy GB, etc
AutoRange PROC num:QWORD, outstr:PTR BYTE
push esi
push ebx
mov esi,outstr ; C string output buffer
mov eax,dword ptr num[0] ; Low order 32-bits
mov edx,dword ptr num[4] ; High order
; Fixed point 10.10 bits, autoranging
xor ebx,ebx ; Clear size index
or edx,edx ; Test high order dword
jnz next
test eax,0FFF00000h ; Try to confine range to xxx.yyy ie 0.000 to 1023.999
jz done ; by checking upper 12 bits zero, and lower 20 bits the number
next: shrd eax,edx,10 ; edx:eax >> 10 -> eax
shr edx,10 ; edx >> 10 -> edx
inc ebx ; step magnitude index
or edx,edx ; Test high order dword
jnz next ; still non zero, shift again
test eax,0FFF00000h ; Check if lower 20 bits hold the number
jnz next ; if upper 12-bits non zero, shift again
done: push eax ; Save fractional portion
shr eax,10 ; align to integer portion
; convert binary to decimal for integer portion
push 0 ; Mark end of decimal with NULL
mov ecx,10 ; base 10
@@: xor edx,edx ; eax = edx:eax / 10, edx = edx:eax % 10
div ecx
add edx,030h ; += '0', convert digit to ASCII
push edx ; stack
or eax,eax ; until decimal fully decoded
jnz @B
pop eax ; unstack
@@: mov byte ptr [esi],al ; add ASCII digit
add esi,1
pop eax ; unstack
or eax,eax ; NULL marks end of digits
jnz @B
mov byte ptr [esi],'.' ; Add decimal point
pop eax ; Recover fractional portion
and eax,03FFh ; Mask fraction portion
mov ecx,1000 ; Convert 0..1023 to 0..999
mul ecx ; eax = (eax * 1000) >> 10
shr eax,10
; Convert to 3 decimal places for fractional portion
mov ecx,10 ; Base 10
xor edx,edx ; eax = edx:eax / 10, edx = edx:eax % 10
div ecx
add edx,030h ; += '0', convert digit to ASCII
mov byte ptr [esi+3],dl ; .--F
xor edx,edx ; eax = edx:eax / 10, edx = edx:eax % 10
div ecx
add edx,030h ; += '0', convert digit to ASCII
mov byte ptr [esi+2],dl ; .-F-
xor edx,edx ; eax = edx:eax / 10, edx = edx:eax % 10
div ecx
add edx,030h ; += '0', convert digit to ASCII
mov byte ptr [esi+1],dl ; .F--
mov byte ptr [esi+4],' ' ; space
mov al,mag[ebx]
mov byte ptr [esi+5],al ; xB<NUL>
mov byte ptr [esi+6],'B'
mov byte ptr [esi+7],0
pop ebx
pop esi
ret
; Magnitude conversion
mag db 'KMGTPE' ; KMGTPEZY, 64-bits gets to EXABYTES
AutoRange ENDP
END