Volume Type : Cocoa instead of Carbon

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.

[code] #if TargetCocoa then
// — Documentation:
// 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

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

#endif[/code]

Thanks… I will look more closely tomorrow

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.

Carlo, what it say for IsInternal (YES/NO)?

      // --- is the disk internal to the machine?
      if getResourceValue( disk, value, "NSURLVolumeIsInternalKey", error ) then listbox1.addrow "isInternal: " + if( boolvalue( value ), "YES", "NO" )

both USB drives return isInternal = “NO”.

What does it returns for a Locked Device like a SD Card ?

And Optical Devices can be Read/Write too (CD / DVD / BluRay).

I do not have a SD Card to test.

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.