I have this OLD Carbon code… does anyone have a COCOA and Windows version that can replace this?
I need to insure that ONLY a USB external drive is available and selected as part of an App.
FUNCTION volumeInfo(f as folderitem,byref isEjectetable as boolean) as Integer
Dim x As Integer
Dim y As Integer
if f Is nil then
return volumeUNKNOWN
end if
// refer to files.h for details on other bit flags
#if TargetMacOS
Soft Declare Function PBHGetVolParmsSync lib CarbonFramework (ByRef paramBlock As HIOParam) As Short
Dim paramBlock As HIOParam
paramBlock.ioVRefNum = f.MacVRefNum
//the following line is a trick to work around the inability to assign a pointer to a structure
//to a field of type Ptr.
Dim infoBuffer As new MemoryBlock(GetVolParmsInfoBuffer.Size)
paramBlock.ioBuffer = infoBuffer
paramBlock.ioReqCount = infoBuffer.Size
Dim OSError As Integer = PBHGetVolParmsSync(paramBlock)
if OSError <> 0 then
return 0//false
end if
// Note : bit 0 is "supposed" to be "isEjectable".[ie. Flash Drive]
x=infoBuffer.long(20)
isEjectable=((x and 1)>0)
y=0
if Bitwise.BitAnd(x,pow(2,21))>0 then y=y+volumeINTERNAL
if Bitwise.BitAnd(x,pow(2,27))>0 then y=y+volumeEXTERNAL
if y=volumeNETWORK then y=volumeUNKNOWN // Switch these
if y=volumeUnknown and infoBuffer.long(10)<>0 then y=volumeNETWORK
return y
#endif
I have Cocoa code, it’s used in Backup To Go. With Cocoa you use NSURL and it’s resources to obtain the volume NSURL, from there you can then test various properties.
It will be quite a large chunk of code as you’ll need to convert the various NSObjects to Xojo equivalents. I’m not at my development machine at the moment, but when I get there, I’ll dig out the code for you.
Declare Function NSClassFromString Lib "Foundation" ( className as CFStringRef ) As Ptr
declare function fileURLWithPath lib "Foundation" selector "fileURLWithPath:" ( NSURLClassRef as Ptr, filePath as CFStringRef ) as Ptr
Dim URLRef as Ptr = fileURLWithPath( NSClassFromString( "NSURL" ), inFile.nativePath )
declare function getResourceValue lib "Foundation" selector "getResourceValue:forKey:error:" ( URLRef as Ptr, _
byRef value as Ptr, key as CFStringRef, byRef error as Ptr ) as boolean
declare function boolValue lib "Foundation" selector "boolValue" ( ref as Ptr ) as boolean // for converting NSNumber boolean to Xojo
declare function stringValue lib "Foundation" selector "stringWithString:" ( classRef as Ptr, instanceRef as Ptr ) as CFStringRef
Dim error, value, disk as ptr
// --- Find the disk.
if GetResourceValue( URLRef, disk, "NSURLVolumeURLKey", error ) = false then
// --- We failed to get this information
listBox1.addRow "Can't get the disk for the file " + infile.name
else
listbox1.addrow "Found the volume"
end if
if disk <> nil then
// --- Get the disk name
if getResourceValue( disk, value, "NSURLVolumeLocalizedNameKey", error ) then listBox1.addrow "Disk Name: " + stringValue( NSClassFromString( "NSString" ), value )
// --- is the disk ejectable?
if getResourceValue( disk, value, "NSURLVolumeIsEjectableKey", error ) then listBox1.addrow "isEjectable: " + if( boolValue( value ), "YES", "NO" )
// --- is the disk removable?
if getResourceValue( disk, value, "NSURLVolumeIsRemovableKey", error ) then listbox1.addrow "isRemovable: " + if( boolvalue( value ), "YES", "NO" )
// --- is the disk internal to the machine?
if getResourceValue( disk, value, "NSURLVolumeIsInternalKey", error ) then listbox1.addrow "isInternal: " + if( boolvalue( value ), "YES", "NO" )
end if
I only provided what I thought was necessary (otherwise you need a lot of code for converting all the various possible objects, and not all can be converted).
Sam,
I have been testing the code you provided above (thanks).
I notice that when I select a USB flash-drive, I get the right results (ejectable = YES, removable = YES),
yet when I select an external USB HD (Transcend), both ejectable and removable = NO.
Any idea for this discrepancy?
After accessing the Apple docs (https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/index.html#//apple_ref/doc/constant_group/Common_File_System_Resource_Keys),
I was looking if it were possible to determine if an external drive was an optical one (CD/DVD), but I could not find any reference to it. What I found (and added to the existing tests in your code) is “isReadOnly”:
if getResourceValue( disk, value, “volumeIsReadOnlyKey”, error ) then listbox1.addrow "IsReadOnly: " + if( boolvalue( value ), “YES”, “NO” )
From a quick test, it works OK, but I’d appreciate your opinion: is a combination of isReadOnly and isEjectable the right and best way to detect if the drive is a CD/DVD?
Thanks again.
// --- is the disk internal to the machine?
if getResourceValue( disk, value, "NSURLVolumeIsInternalKey", error ) then listbox1.addrow "isInternal: " + if( boolvalue( value ), "YES", "NO" )
Shows up as electable and removable. I suspect there’s either another property I am not aware of or the OS has a different system, because it clearly knows what the media is.