Posts: 65
Threads: 22
Joined: Apr 2022
Reputation:
2
I'm looking for a reliable way to determine if a drive letter is in use but I'm running into some difficulties.
Take the following small clip as an example:
A$ = "F:\"
If _DirExists(A$) Then
Print A$; " Exists"
Else
Print A$; "Does not exist"
End If
Normally, this works fine and indicates if the drive letter contained in A$ exists. But now consider these two exceptions:
1) Suppose I have a thumbdrive attached to the system that has been wiped clean. By wiped clean, I mean you open DISKPART, select the thumbdrive, and perform a "CLEAN" on that drive. In this instance, there will be no partitions on the drive, but in File Explorer, the drive still shows up with a drive letter. However, the clip above will indicate that this drive letter does NOT exist. As a result, if I try to assign that drive letter to another drive, it will fail because it is already in use.
2) The same thing happens if I connect a drive that has BitLocker encryption but has not yet been unlocked. The QB64PE code will indicate that the drive letter does not exist even though it is already in use.
Any suggestions on a better way to determine if a drive letter is in use?
Posts: 3,972
Threads: 177
Joined: Apr 2022
Reputation:
219
Are we allowed to attempt to write onto the drive for our test?
b = b + ...
Posts: 1,272
Threads: 119
Joined: Apr 2022
Reputation:
100
(05-08-2023, 03:46 PM)hanness Wrote: I'm looking for a reliable way to determine if a drive letter is in use but I'm running into some difficulties.
Take the following small clip as an example:
A$ = "F:\"
If _DirExists(A$) Then
Print A$; " Exists"
Else
Print A$; "Does not exist"
End If
Normally, this works fine and indicates if the drive letter contained in A$ exists. But now consider these two exceptions:
1) Suppose I have a thumbdrive attached to the system that has been wiped clean. By wiped clean, I mean you open DISKPART, select the thumbdrive, and perform a "CLEAN" on that drive. In this instance, there will be no partitions on the drive, but in File Explorer, the drive still shows up with a drive letter. However, the clip above will indicate that this drive letter does NOT exist. As a result, if I try to assign that drive letter to another drive, it will fail because it is already in use.
2) The same thing happens if I connect a drive that has BitLocker encryption but has not yet been unlocked. The QB64PE code will indicate that the drive letter does not exist even though it is already in use.
Any suggestions on a better way to determine if a drive letter is in use?
Just off the top of my head perhaps:
A$ = "F:\."
The period added will force a root directory check maybe?
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 78
Threads: 2
Joined: Apr 2023
Reputation:
2
I can't remember the WinAPI way of doing this but it is far more accurate.
Schuwatch!
Yes, it's me. Now shut up.
Posts: 78
Threads: 2
Joined: Apr 2023
Reputation:
2
05-08-2023, 03:55 PM
(This post was last modified: 05-08-2023, 03:58 PM by Ultraman.)
Looks like you'd use GetLogicalDrives()
So,
Code: (Select All) Declare CustomType Library
Function GetLogicalDrives~&()
End Declare
Dim As Unsigned Long currentLetters: currentLetters = GetLogicalDrives
'do something to figure out the bitmask using AND
Schuwatch!
Yes, it's me. Now shut up.
Posts: 1,272
Threads: 119
Joined: Apr 2022
Reputation:
100
05-08-2023, 04:02 PM
(This post was last modified: 05-08-2023, 04:02 PM by TerryRitchie.)
(05-08-2023, 03:55 PM)Ultraman Wrote: Looks like you'd use GetLogicalDrives()
So,
Code: (Select All) Declare CustomType Library
Function GetLogicalDrives~&()
End Declare
Dim As Unsigned Long currentLetters: currentLetters = GetLogicalDrives
'do something to figure out the bitmask using AND
It looks like GetDriveTypeA may be more appropriate:
https://learn.microsoft.com/en-us/window...drivetypea
It can report that a drive exists but no volume has been mounted.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 78
Threads: 2
Joined: Apr 2023
Reputation:
2
Well GetDriveTypeA would require that you call it multiple times with a different letter each time, whereas the other would be called only once and then you'd process the returned value.
Schuwatch!
Yes, it's me. Now shut up.
Posts: 1,272
Threads: 119
Joined: Apr 2022
Reputation:
100
05-08-2023, 04:15 PM
(This post was last modified: 05-08-2023, 04:17 PM by TerryRitchie.)
(05-08-2023, 04:05 PM)Ultraman Wrote: Well GetDriveTypeA would require that you call it multiple times with a different letter each time, whereas the other would be called only once and then you'd process the returned value.
It appears that GetLogicalDrives only sets a bit for the existence of a drive. His issue is he needs to know if a volume is mounted as well. Perhaps use GetLogicalDrives first to identify existing drives then use GetDriveTypeA on each detected drive for the existence of a volume.
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 1,586
Threads: 59
Joined: Jul 2022
Reputation:
52
05-08-2023, 04:53 PM
(This post was last modified: 05-08-2023, 04:55 PM by mnrvovrfc.)
On Linux this is ridiculously easy:
On Debian/Ubuntu check in "/media/(user)" for additional subdirectories.
On almost other Linux OS check in "/run/media/(user)".
Use _DIREXISTS for it.
There are no drive letters to worry about. However this depends whether or not the pluggable disk was given a volume label. If not then it becomes harder to track down an UUID to identify that disk. That UUID doesn't change if the disk is plugged into a different Linux OS or a different computer into a Linux OS.
Fiddling with certain programs (which require administrative privileges anyway) could do something about it. On most systems, however, GNOME Disk Utility does not require the "root" password to delete partitions and reformat disks! Be careful out there.
What is the result of "vol F:" on the terminal on Windows?
Posts: 73
Threads: 3
Joined: Apr 2022
Reputation:
14
I found something else in my hodgepodge, maybe that can help.
Code: (Select All) 'LETTER_OF_USB_DEVICE 'program by Euklides
'Working with files on USB devices
'When you write a program using files located on USB drives, you don't be
'sure that the letter of this drive is always the same.
'You cannot write for instance:
' OPEN "F:\MYFILE\info.txt" FOR INPUT AS #1
' ...
'If your drive has a new letter, for instance "E", you must go into your program
' and change the letter
'So what you can do is this:
'1) ' find the serial of your drive
' Use below:
' GOSUB SERIALSSHOW
' and you will see all the serials of then actuel connected drives
' For instance, the good drive has the serial "<9911-447E>
'2) Now write your program so:
' fic$ = "<9911-447E>:\MYFILE\info.txt"
' GOSUB DRIVELETTERFIND: IF _CLIPBOARD$ = "" THEN PRINT "USB unit is not connected for using " + fic$: END
' fic$ = _CLIPBOARD$:OPEN fic$ FOR INPUT AS #1
' ...
'End
'=====================================================================
Declare Dynamic Library "kernel32"
FUNCTION GetVolumeInformationA& (lpRootPathName$, lpVolumeNameBuffer$, BYVAL nVolumeNameSize~&, _
lpVolumeSerialNumber~&, lpMaximumComponentLength~&, lpFileSystemFlags~&, lpFileSystemNameBuffer$, BYVAL nFileSystemNameSize&)
End Declare
Declare Library: Function GetDriveType& (d$): End Declare
Dim Shared DriveType As String, SERIALFOUND As String
'---
SERIALSSHOW:
For q = 1 To 26: X = GetFileInfo(q): If SERIALFOUND <> "<!!!-!!!>" Then Print " "; Chr$(64 + q) + ": "; SERIALFOUND
Next q
End
'---
DRIVELETTERFIND: 'in-->fic$ like' "<SER-IAL>ficname" out--> like "D:\ficname"
_Clipboard$ = "": K$ = UCase$(Left$(fic$, 2))
If Right$(K$, 1) = ":" And Left$(K$, 1) >= "A" And Left$(K$, 1) <= "Z" And DRIVEEXISTS(Asc(K$) - 64) = 1 Then _Clipboard$ = fic$: Return
J1 = InStr(fic$, "<"): J2 = InStr(J1, fic$, ">")
If J1 = 0 Or J2 = 0 Then Print fic$; " must be written like: <serial>\ficmame...": End
Serialsearch$ = Mid$(fic$, J1, J2 - J1 + 1): q = 0
For q = 1 To 26: X = GetFileInfo(q)
If SERIALFOUND = Serialsearch$ Then
fic$ = Right$(fic$, Len(fic$) - J2): If Left$(fic$, 1) <> ":" Then fic$ = ":" + fic$
fic$ = Chr$(64 + q) + fic$: _Clipboard$ = fic$
End If
Next q
Return
'---
Function GetFileInfo (D)
SERIALFOUND = "<!!!-!!!>":
If DRIVEEXISTS(D) <> 1 Then GetFileInfo = 0: Exit Function
Dname$ = Chr$(D + 64) + ":\": Sname$ = Space$(260)
R = GetVolumeInformationA(Dname$ + Chr$(0), Vname$, 260, serial~&, empty1~&, empty2~&, Sname$, 260)
If R = 0 Then Exit Function
Sname$ = Left$(Hex$(serial~&), 4) + "-" + Right$(Hex$(serial~&), 4)
SERIALFOUND = "<" + Sname$ + ">"
GetFileInfo = -1
End Function
'---
Function DRIVEEXISTS (V)
DRIVEEXISTS = 0: varX$ = Chr$(V + 64) + ":\" + Chr$(0): VarX = GetDriveType(varX$): If VarX > 1 Then DRIVEEXISTS = 1
End Function
'=====================================================================
My Pc Drives
C: is a Drive
D: Partition on C:
E: Partition on F:
F: is a Drive
G: is a USB Stick
|