I have an ongoing problem with file paths, I touched on this subject sometime back & still haven't found a satisfactory answer. The problem is when a program & it's data files are on a drive or partition other than C:. In 16 bit code you could use function 19h of Int 21 which returned the number of the current drive in the AL register, where 0 = A, 1 = B etc. You could then use XLAT to find the drive letter from a lookup table & insert it into the start of the path string. What I need is a way of doing this in 32 bit, or there might be another method I haven't found yet. Any thoughts & ideas will be appreciated.
GetLogicalDriveStrings, GetVolumeInformation, GetDriveType
win32.hlp
.686
.model flat,stdcall
option casemap:none
include windows.inc
include stdio.inc
include asmlib.inc
.code
main proc C uses esi edi ebx argc:dword,argv:ptr dword
LOCAL volsn:dword, maxcomp:dword, sysf:dword
LOCAL drivestr[4*MAXBYTE]:byte
LOCAL volname[MAX_PATH]:byte, sysname[MAX_PATH]:byte
LOCAL diskfree:LARGE_INTEGER,L1:LARGE_INTEGER,disktotal:LARGE_INTEGER
; invoke GetLogicalDrives
; mov edi,eax
; bt edi,X
invoke GetLogicalDriveStrings,sizeof drivestr,addr drivestr
lea esi,drivestr
lea ebx,[esi+eax]
.while esi < ebx
invoke printf,T(CRLF,"Volume: %s",CRLF),esi
invoke memset,addr volname,0,sizeof volname
mov eax,[esi]
and eax,0FFFFh
mov dword ptr sysname,eax
invoke QueryDosDevice,addr sysname,addr volname,sizeof volname
.if eax
invoke printf,T("Device: ")
invoke puts,addr volname
.endif
invoke GetDiskFreeSpaceEx,esi,addr L1,addr disktotal,addr diskfree
.if eax
mov eax,diskfree.LowPart
mov edx,diskfree.HighPart
shrd eax,edx,3*10;/1024=2^10;/1024=2^10;/1024=2^10
shr edx,3*10; KiB; MiB; GiB
mov ecx,eax
mov eax,disktotal.LowPart
mov edx,disktotal.HighPart
shrd eax,edx,3*10;/1024=2^10;/1024=2^10;/1024=2^10
shr edx,3*10; KiB; MiB; GiB
invoke printf,T("%u of %u GiB free"),ecx,eax
.endif
invoke GetDriveType,esi
.if eax == DRIVE_FIXED
invoke puts,T("Type: HDD")
.elseif eax == DRIVE_CDROM
invoke puts,T("Type: CDROM")
.elseif eax == DRIVE_REMOVABLE
invoke puts,T("Type: REM")
.endif
invoke GetVolumeInformation,esi,addr volname,sizeof volname,addr volsn,\
addr maxcomp,addr sysf,addr sysname,sizeof sysname
.if eax
invoke printf,T("Name: %s",CRLF,"SN: %.8X",CRLF,"FS: %s",CRLF),\
addr volname,volsn,addr sysname
.endif
invoke strlen,esi
lea esi,[esi+eax+1]
.endw
invoke getchar
return 0
main endp
end
Of course, there are more complicated ways to get it :wink
include \masm32\include\masm32rt.inc
.data?
buffer db MAX_PATH dup (?)
.code
start:
mov esi, offset buffer
invoke GetCurrentDirectory, sizeof buffer, offset buffer
mov byte ptr [esi+2], ah
MsgBox 0, esi, "Current drive:", MB_OK
exit
end start
Thanks for your suggestions, I'll give them a try :U
Beware of little traps. This exe launched via a shortcut from C:\temp, with no start folder specified:
GetCurrentDirectory: C:\temp
Current drive: C:
GetModuleFileName: D:\masm32\RichMasm\RES\CurrentDrive.exe
Current drive: D:
include \masm32\include\masm32rt.inc
.code
start:
sub esp, MAX_PATH ; create a buffer
print "GetCurrentDirectory:", 9
invoke GetCurrentDirectory, MAX_PATH, esp
print esp, 13, 10
mov byte ptr [esp+2], 0
print "Current drive: ", 9
print esp, 13, 10
print "GetModuleFileName:", 9
mov eax, esp
invoke GetModuleFileName, 0, eax, MAX_PATH
print esp, 13, 10
mov byte ptr [esp+2], 0
print "Current drive: ", 9
print esp, 13, 10
add esp, MAX_PATH ; release the buffer (not really needed before ExitProcess...)
getkey
exit
end start
Thanks jj, I'll bear that in mind.
oops, it seems I ignored the word "current" when reading your post
No problem drizz, it was an interesting and very informative post, gave me a lot to think about.
Thanks jj, this, too, has helped me.
Quote from: Neil on December 06, 2009, 04:27:07 PM
No problem drizz, it was an interesting and very informative post, gave me a lot to think about.
I agree :U