News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Comparing drive sizes

Started by shadow, July 08, 2005, 02:56:47 AM

Previous topic - Next topic

shadow

Ok so i used GetDiskFreeSpaceEx and StrFormatByteSize64 to get a drive size.  Then I used StrTrim to cut off the space and the GB/MB/KB ending.  Now I am left with a number like 3.02 .  Now I want to compare this with a number so that I can prevent a file from being installed on a drive that's too small.  lstrcmp doesn't seem to function properly for this.  What can I do to make sure when mainbuffer1 is less than minsize, it gives an error?  Minsize is in GB.



.data
minsize db "18.00",0
kb db " K",0
mb db " M",0
gb db " GB",0

.data?
mainbuffer db 4000 DUP (?)
mainbuffer1 db 4000 DUP (?)

.code

invoke GetDiskFreeSpaceEx,addr mainbuffer,addr size1,NULL,NULL
invoke StrFormatByteSize64, size1, size1+4, ADDR mainbuffer1, SIZEOF size1
invoke SetDlgItemText,hWin,IDC_EDT2,addr mainbuffer1
invoke StrTrim,addr mainbuffer1,addr kb ;*****if StrFormatByteSize64 outputs in KB, the drive is too small*****
.if eax==1
invoke MessageBox,hWin,addr smallt,addr smallc,MB_OK+MB_ICONERROR
ret
.endif
invoke StrTrim,addr mainbuffer1,addr mb ;*****if StrFormatByteSize64 outputs in MB, the drive is too small*****
.if eax==1
invoke MessageBox,hWin,addr smallt,addr smallc,MB_OK+MB_ICONERROR
ret
.endif
invoke StrTrim,addr mainbuffer1,addr gb
.if eax==1 ; *****StrFormatByteSize64 Gives us a GB output..*****
invoke lstrcmp,addr mainbuffer1,addr minsize ;*****"<space>GB" is now cut out of mainbuffer1... compare it with minsize*****
.if eax==-1 ;####PROBLEM  eax is always positive no matter what size mainbuffer1 is or minsize####
invoke MessageBox,hWin,addr smallt,addr smallc,MB_OK+MB_ICONERROR
ret
.else
jmp sizeok
.endif
invoke MessageBox,hWin,addr smallt,addr smallc,MB_OK+MB_ICONERROR
.endif
sizeok:
; and out...


I have a feeling lstrcmp doesn't like decimal points. 
hmm... thanks in advance folks!  :wink

Rifleman

shadow,
Convert the number to a string then do your compare and all will work well.

PBrennick

shadow

how do I convert it to a string?

farrier

shadow,

Unless you need to compare the strings, compare the raw numbers:


struct DISKSIZE
.dwLowSize dd ?
.dwHighSize dd ?
ends

avail_bytes DISKSIZE
total_bytes DISKSIZE
free_bytes DISKSIZE
file_bytes DISKSIZE


invoke GetDiskFreeSpaceEx, [edi], avail_bytes, total_bytes, free_bytes
invoke GetFileSizeEx, [hYourFile], file_bytes
mov eax, [avail_bytes.dwHighSize]
cmp eax, [file_bytes.dwHighSize] ;avail - file
ja .enough_room
jb .not_enough
mov eax, [avail_bytes.swLowSize]
cmp eax, [avail_bytes.dwLowSize] ;avail - file
jae .enough_room
.not_enough:


hth,

farrier

ps. Don't you wish we all had 64 bit registers!
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

shadow

I have never used struct before.  where does

avail_bytes  DISKSIZE
total_bytes DISKSIZE
free_bytes DISKSIZE
file_bytes DISKSIZE
go? hmmm that totally confused me  :red  I'll bet i have a few juicy 64 bit registers in this AMD 3500 here...  If only  I could use them :(.

farrier

shadow,

Use:

DISKSIZE struc
   dwLowSize dd ?
   dwHighSize dd ?
DISKSIZE ends


instead!  I posted FASM code by mistake.

farrier
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

shadow

hehe i got that one from the MASM documentation on STRUCT... Now that I've gotten some sleep... did you mean
avail_bytes dd DISKSIZE
total_bytes dd DISKSIZE
free_bytes dd DISKSIZE
file_bytes dd DISKSIZE

?

Mark Jones

No Shadow,


DISKSIZE struc
   dwLowSize dd ?
   dwHighSize dd ?
DISKSIZE ends

.data?
avail_bytes DISKSIZE<>
total_bytes DISKSIZE<>
free_bytes DISKSIZE<>
file_bytes DISKSIZE<>

.code
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

farrier

It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

shadow

I'm understanding the idea behind this now, the high and low parts of the 64 bit qword value are 32bits each.  :U   The size I want to compare with the drive size is 19330000000 bytes; the sum of 30 seperate files. 19330000000 doesn't fit into any 32 bit registers.  How do I get 19330000000 into file_bytes?  :'(

Jeff

#10
theres a number of ways to approach this.  the size would require about 10 bytes.  for starters, you could use the TBYTE (10 byte) type..data?
avail_bytes TBYTE ?
total_bytes TBYTE ?
free_bytes TBYTE ?
file_bytes TBYTE ?

to make things a wee bit easier for you, you could make a few adjustments to the structure:DISKSIZE struc
   dwLowSize dd ?
   dwHighSize dd ?
   wHighHighSize word ?       ;doubleword might be wise
DISKSIZE ends

.data?
avail_bytes DISKSIZE <>
total_bytes DISKSIZE <>
free_bytes DISKSIZE <>
file_bytes DISKSIZE <>

.code
same size but easier to get at the numbers a bit

it can be as large as you want, its just a matter of coding the manipulation (80bit addition, multiplication, etc)

sorry, bad advice, please ignore

shadow

hmm I think it has more to do with how I am actually moving the data into file_bytes.



.data
size12 db "19330000000",0

.data?
DISKSIZE struc
   dwLowSize dd ?
   dwHighSize dd ?
   dwHighHighSize dword ?
DISKSIZE ends


.data?
avail_bytes DISKSIZE <>
total_bytes DISKSIZE <>
free_bytes DISKSIZE <>
file_bytes DISKSIZE <>

mainbuffer db 4000 DUP (?)
mainbuffer1 db 4000 DUP (?)

.code
invoke GetDiskFreeSpaceEx,addr mainbuffer,addr avail_bytes,addr total_bytes,addr free_bytes

;--

invoke lstrcpy,addr file_bytes,addr size12 ;doesn't seem to work...
;I tried mov too, but registers aren't big enough.

;--

mov eax, [avail_bytes.dwHighSize]
cmp eax, [file_bytes.dwHighSize] ;avail - file
ja enough_room
jb not_enough
mov eax, [avail_bytes.dwLowSize]
cmp eax, [avail_bytes.dwLowSize] ;avail - file
jae enough_room



not_enough:
invoke MessageBox,hWin,addr smallt,addr smallc,MB_OK+MB_ICONERROR
ret

enough_room:

ret


Jeff

oh im sorry, the API was coded specifically using ULARGE_INTEGER structures.  i thought you were going to code the changes.

[edit]
whoa i really screwed up really sorry.  the structure that you had was sufficient.  take out the dwHighHighSize part.  if you want to manipulate the numbers for avail_bytes, total_bytes, etc, you have to work with them 32bits at a time.

shadow

It's alright!  Everyone makes mistakes  :red  Do I have to split 19330000000 into 32 bit chunks to copy it to avail_bytes?  How would I do that?  Hmmm... I never thought writing an installer program would be so difficult!  I'm leanring a lot though!  thanks folks!

Jeff

so sorry again.  :)  let me try this again.

Quote from: shadow on July 12, 2005, 01:38:55 AM
I'm understanding the idea behind this now, the high and low parts of the 64 bit qword value are 32bits each. :U The size I want to compare with the drive size is 19330000000 bytes; the sum of 30 seperate files. 19330000000 doesn't fit into any 32 bit registers. How do I get 19330000000 into file_bytes? :'(

size12 is a number string.  to make things easier, you should convert this to a "DISKSIZE number".  i dont know what API functions to use but you can always use the windows calculator (one of our best friends).  ;)

according to the calculator, 19330000000 is 00000004 80286480 in hex. so in code, you could use this:
.data
size12 DISKSIZE <80286480h,00000004h>    ;low 32bits first since little endian, then high 32bits


i hope ive redeemed myself.  :)