Quote: "Windows throws up a series of error messages - one for each drive which does not exist. You can't even run checks on Path Exist("A:"), as the same error appears."
You mean windows crashes DB with an error and won't let you go on? What errors are you getting?
BN2's method should work.
We could try the same thing BN2 is doing except use the win32 api for all of the calls. Maybe using the win api directly in windows mode will circumvent the problems. The following example retrieves the root drive letters and loads them into a memblock. Each byte=0 in the memblock indicates the end of a string. The returned size of all the drive strings combined is returned by the win api call. Using this value and dividing it by 4 (the length of each drive string) I can determine the number of drives. I dimension a string array to copy the memblock string into.
I test each drive in the array by calling SetCurrentDirectory to that drive letter through the win api. If it returns a 0 (fail), I check for an error code (I know error 21 = device not ready) and display a message. This error check could be used to deactivate a drive from your drive list in your file browser. The errors are returned as codes to your app so windows or db shouldn't quit on an exception. A list of the system error codes can be found on the msdn site.
rem retrieve drive list using winapi
rem by latch
rem 04/12/2009
rem returns the list of logical drives on the current system
rem and tests if the drive is ready for use
set window on
sync on
kernel32=1
load dll "kernel32.dll",kernel32
rem make a memblock large enough to hold 26 drives (a to z)
rem with a ':' '\' and 'null'. Adjust this to whatever size you want
make memblock 1,(26*4)+1
drivestring=get memblock ptr(1)
nsize=get memblock size(1)
size=call dll(kernel32,"GetLogicalDriveStringsA",nsize,drivestring)
print "the size of the returned string = ";size
d=size/4
print "4 bytes per drive; number of drives = ";d
dim drives$(d)
rem if the buffer wasn't large enough to hold all of the drives,
rem we retrieve the size from the function call and use that to
rem resize the buffer
if size > nsize
undim drives$(d)
delete memblock 1
make memblock 1,size+1
drivestring=get memblock ptr(1)
nsize=get memblock size(1)
size=call dll(kernel32,"GetLogicalDriveStringsA",nsize,drivestring)
print "the size of the returned string = ";size
d=size/4
print "4 bytes per drive; number of drives = ";d
dim drives$(d)
endif
count=0
for n=0 to size-1
byte=memblock byte(1,n)
if byte <> 0
drives$(count)=drives$(count)+chr$(byte)
else
inc count
endif
next n
rem retrieve the current directory so we can test other paths
curdir$=get dir$()
rem list the drives and determine if they are "ready" for use
for n=0 to d
print drives$(n)
rem use the win api to set the current directory to test it
test$=drives$(n)
result=call dll(kernel32,"SetCurrentDirectoryA",test$)
if result ! 1
error=call dll(kernel32,"GetLastError")
if error = 21
print "Drive ";drives$(n);" is not ready"
endif
endif
next n
rem switch back to original directory
call dll kernel32,"SetCurrentDirectoryA",curdir$
print
print
print get dir$()
sync
Enjoy your day.