Before using WinExec, I wan't to check if there is actually a disk inserted in the drive I'm aiming to run something at.
I'm trying to avoid the "There is no disk in the drive X. Please insert a disk in to the drive X." error.
Does anybody know the proper API call?
tekhead009,
BroadcastSystemMessage is the API that sends the message and you can start there.
Paul
Quick and dirty.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.IF FUNC( exist, chr$("a:\nul") )
print "disk in drive",13,10
.ELSE
print "no disk in drive",13,10
.ENDIF
mov eax, input( 13,10,"Press enter to exit..." )
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
I'm not having much luck with BroadcastSystemMessage. Mostly because I don't see a way of targeting a specific drive, or even reading which drives received the message. It looks like that call is aimed at detecting drivers; but I'm not very experienced with API calls, and the W32 reference is pretty cryptic about it.
Michael, that code looks good, but I don't have, or use the functions that you're referring to. Can you give me a link to download them, so I can dig in and see how they're being done?
Alternatively, I'm able to obtain a handle to the drive using CreateFile; isn't there something I could do with the handle to test? I've tried creating a directory, or reading the exact file that I'm attempting to execute, but both still trigger the operating sytem to give me the "Please insert a disk into drive X" message.
I'm so excited; I got it!
I was on the right track opening the drive using CreateFile, I was opening the drive letter using //./x
--Instead, I should open the PHYSICAL DRIVE using //./PHYSICALDRIVE<n>
My problem was that when I put in my Compact Flash card in the reader it gets detected and appears in the system as drive A:, but then drive X and Y also appear because they're part of the same card reader. My problem was that I was unable to tell if a drive actually has media in it. I am able to get a handle to any of the drives letters A:, X:, or Y: using CreateFile and the drive letter. However, if I use the PHYSICALDRIVE number, I am only able to connect to a drive that has media inserted! (anybody have any explination why?)
I'm going to post my code for the archives, that and I'd like some feedback. Is there anything that stands out as clearly wrong or ineffecient? It works, but that doesn't mean I'm doing things right! Thanks everybody for the help!
The code picks up after detecting a device arrival. I've put the drive mask in EAX, and I'm now testing each bit for what drive has been detected:
.data
szPath BYTE "X:\autorun.exe",0
szDrive BYTE "\\.\PHYSICALDRIVEx",0
.code
;(... snip ...)
Deturmination_Loop:
test EAX,00000001h ;See if we've found the drive yet
jnz Found_Drive
shr EAX,1 ;Shift sha-bang right, check if it was the next drive.
loop Deturmination_Loop
invoke MessageBox,hWndo,OFFSET szNoDrive,\
OFFSET szCaption,MB_OK
jmp _end ;If nothings been found, warn and quit (something's wonkey, though)
Found_Drive:
mov EBX,26 ;Number of possible drives (from ECX eariler)
sub EBX,ECX ;Subtract to get the drive number in human-think.
add EBX,30h ;Add 30 (ascii 0) to PHYSICALDRIVE number.
mov ESI,OFFSET szDrive
mov BYTE PTR [ESI+17],BL ;Place drive number in the string..
add EBX,11h ;Now add 11h to get ASCII A-Z
mov ESI,OFFSET szPath
mov BYTE PTR [ESI], BL ;Replace drive letter with currently inserted drive.
Confirm_Disk_Inserted: ;More coffee.
invoke CreateFile,OFFSET szDrive,GENERIC_READ+GENERIC_WRITE,\
FILE_SHARE_READ+FILE_SHARE_WRITE,0,OPEN_EXISTING,\
FILE_FLAG_BACKUP_SEMANTICS,0 ;Try to open the physical drive.
cmp EAX,INVALID_HANDLE_VALUE ;Make certain the drive has been opened
je _end ;If can't open PHYSICALDRIVE, quit.
Drive_Opened:
mov hDrive,EAX ;Rember to save the handle before loosing it!
invoke CloseHandle,hDrive ;Close those handles.
invoke WinExec,OFFSET szPath,SW_SHOWNORMAL ;Use WinExec rather than ShellExecute.
invoke ShowWindow,hWndo,SW_MINIMIZE
invoke ShowWindow,hWndo,SW_HIDE
Looks nice. :bg
Just remember to close each handle in all cases.
Stolen directly from:
http://www.delphi3000.com/articles/article_1599.asp?SK=
invoke SetErrorMode, SEM_FAILCRITICALERRORS
mov [OldErrorMode], eax
invoke GetDiskFreeSpace, Drive, SectPerClus, BytesPerSector, TotNumClusters
invoke SetErrorMode, [OldErrorMode]
GetDiskFreeSpace witl return 1 with success and will return 0 "ERROR_NOT_READY" if no disk is in, and "ERROR_PATH_NOT_FOUND" if ThumbDrive not installed.
farrier
Quote from: farrier on July 15, 2005, 12:38:15 AM
Stolen directly from:
http://www.delphi3000.com/articles/article_1599.asp?SK=
invoke SetErrorMode, SEM_FAILCRITICALERRORS
mov [OldErrorMode], eax
invoke GetDiskFreeSpace, Drive, SectPerClus, BytesPerSector, TotNumClusters
invoke SetErrorMode, [OldErrorMode]
GetDiskFreeSpace witl return 1 with success and will return 0 "ERROR_NOT_READY" if no disk is in, and "ERROR_PATH_NOT_FOUND" if ThumbDrive not installed.
farrier
That's it. It works, and I understand exactly what's happening. I've modified my code to use this detection, rather than opening the physical drive. I feel much better now knowing how it works, rather then just relying on it working. I had tried GetDiskFreeSpace, but I was still getting the errors, and didn't know I could surpress them using the SetErrorMode API call.
Thanks again everyone!