Getting a drive's Name from a FolderItem

Given that I have C:, D:, E:, H:, M:, and Q: drives on my Windows system, and all of them display in Explorer with names that have been assigned, is there a way to get this assigned name from a FolderItem? For example, if I get a FolderItem “F” for “H:” and then try to add F.DisplayName or F.name to a listbox, all I get is “H:”.

Nothing in the Xojo docs for FolderItem give any indication that anything special is required to get the drive’s name.

Any tips?

Maybe this thread could help you:
https://forum.xojo.com/18937-how-can-i-access-a-volume-by-name/

Thanks Alberto - looks like a feature request is in the works.

Here’s my modification for newer Xojo and using it as an extension to FolderItem:

[code]Function GetVolumeName(extends f As FolderItem) As String
#If TargetWin32
Soft Declare Function GetVolumeInformationA Lib “Kernel32” ( root As CString, _
volName As Ptr, volNameSize As Integer, ByRef volSer As Integer, ByRef _
maxCompLength As Integer, ByRef sysFlags As Integer, sysName As Ptr, _
sysNameSize As Integer ) As Boolean
Soft Declare Function GetVolumeInformationW Lib “Kernel32” ( root As WString, _
volName As Ptr, volNameSize As Integer, ByRef volSer As Integer, ByRef _
maxCompLength As Integer, ByRef sysFlags As Integer, sysName As Ptr, _
sysNameSize As Integer ) As Boolean

Dim volName As New MemoryBlock( 256 )
Dim sysName As New MemoryBlock( 256 )
Dim volSerial, maxCompLength, sysFlags As Integer

If System.IsFunctionAvailable( “GetVolumeInformationW”, “Kernel32” ) Then
Call GetVolumeInformationW( Left( f.NativePath, 3 ), volName, 256, volSerial, maxCompLength, _
sysFlags, sysName, 256 )

Return volName.WString( 0 )

Else
Call GetVolumeInformationA( Left( f.NativePath, 3 ), volName, 256, volSerial, maxCompLength, _
sysFlags, sysName, 256 )

Return volName.CString( 0 )

End If
#EndIf
End Function[/code]

It tooks me times to do it, and I may be wrong, but the code below returns me “C:”

[code] Dim VolFI As FolderItem
Dim LopIdx As Integer

VolFI = GetFolderItem("")

Do Until VolFI = Nil
If VolFI.Parent <> Nil Then
VolFI = VolFI.Parent

Else
  Exit
End If

If UserCancelled Then Exit

Loop

// Display the result
TFURL.Text = VolFI.NativePath[/code]

Xojo 2015r1 / Windows XP / MacBook Pro 13" / Virtual Box.

Is this what was asked ?

did you try Folderitem.DisplayName on the volume item?

[nit picky] This is more properly called a Volume (not “drive”, since a single physical “drive” can have many Volumes), and “Name” is more properly called a “Label”.

On Mac you might be able to get away with calling it a “Name”, but on Windows, it’s always called a
“Label”.

The “Name” is truly the drive letter and a colon, not only because of historical concerns but also to keep path logic consistent. It will always be “H:\Folder 1\Folder 2\File 1.ext”, never “My Drive\Folder 1\Folder 2\File 1.ext”.

No, but I will…

C:

It seems that I did not read correctly the question. Sorry.

PS: I checked the example in the Volume Class and I get the letters too…

As Garth mentions, I was after the Label, not the name. The code I posted above gives me that.

I’d put 512 in the memory block allocations to handle the call to GetVolumeInformationW because each character is twice as wide.

Here’s that change for posterity:

[code]Function GetVolumeName(extends f As FolderItem) As String
#If TargetWin32
Soft Declare Function GetVolumeInformationA Lib “Kernel32” ( root As CString, _
volName As Ptr, volNameSize As Integer, ByRef volSer As Integer, ByRef _
maxCompLength As Integer, ByRef sysFlags As Integer, sysName As Ptr, _
sysNameSize As Integer ) As Boolean
Soft Declare Function GetVolumeInformationW Lib “Kernel32” ( root As WString, _
volName As Ptr, volNameSize As Integer, ByRef volSer As Integer, ByRef _
maxCompLength As Integer, ByRef sysFlags As Integer, sysName As Ptr, _
sysNameSize As Integer ) As Boolean

Dim volName As New MemoryBlock( 512 )
Dim sysName As New MemoryBlock( 512 )
Dim volSerial, maxCompLength, sysFlags As Integer

If System.IsFunctionAvailable( “GetVolumeInformationW”, “Kernel32” ) Then
Call GetVolumeInformationW( Left( f.NativePath, 3 ), volName, 512, volSerial, maxCompLength, _
sysFlags, sysName, 512 )

Return volName.WString( 0 )

Else
Call GetVolumeInformationA( Left( f.NativePath, 3 ), volName, 512, volSerial, maxCompLength, _
sysFlags, sysName, 512 )

Return volName.CString( 0 )

End If
#EndIf
End Function[/code]

Doh! Keep the calls at 256, just bump the memoryblock to 512 :slight_smile:

Doh, actually calls at 261 and memoryblocks at 522

Hmmm, reviewing this page indicates that this is a potential can-o-worms:
File Naming

When the use case examples have more “If … Then” qualifiers than a 1985 GWBASIC app …

Love it when I misclick a post and hit delete instead of edit.

Julian:
I added some data to a database in a current project, yesterday, and loved when I clicked in “New Record” (clean the window) instead of “Add Record” (Save the Record)…
I retyped that Record data and stopped asap :frowning:

I think my post was something like:

hehe yes

https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-getvolumeinformationa

says we need MAX_PATH + 1 which is 260+1

but as we’re covering Unicode in the same function then we need to allocate the space and set things to *2 so 522

We don’t need to worry about longer filenames that are possible in windows 10 and later because the API we’re calling isn’t in the list of calls shown on the page you linked.

So this should be good:

[code]Function GetVolumeName(extends f As FolderItem) As String
#If TargetWin32
Soft Declare Function GetVolumeInformationA Lib “Kernel32” ( root As CString, _
volName As Ptr, volNameSize As Integer, ByRef volSer As Integer, ByRef _
maxCompLength As Integer, ByRef sysFlags As Integer, sysName As Ptr, _
sysNameSize As Integer ) As Boolean
Soft Declare Function GetVolumeInformationW Lib “Kernel32” ( root As WString, _
volName As Ptr, volNameSize As Integer, ByRef volSer As Integer, ByRef _
maxCompLength As Integer, ByRef sysFlags As Integer, sysName As Ptr, _
sysNameSize As Integer ) As Boolean

Dim volName As New MemoryBlock( 522 )
Dim sysName As New MemoryBlock( 522 )
Dim volSerial, maxCompLength, sysFlags As Integer

If System.IsFunctionAvailable( “GetVolumeInformationW”, “Kernel32” ) Then
Call GetVolumeInformationW( Left( f.NativePath, 3 ), volName, 261 , volSerial, maxCompLength, _
sysFlags, sysName, 261 )

Return volName.WString( 0 )

Else
Call GetVolumeInformationA( Left( f.NativePath, 3 ), volName, 261 , volSerial, maxCompLength, _
sysFlags, sysName, 261 )

Return volName.CString( 0 )

End If
#EndIf
End Function[/code]