Detecting media type of mounted volume

When I insert an SD card I want to know what the mediatype is. I played around with CarbonApplicationEventsMBS, which works great. I can see when a volume is mounted. I just don’t know how to check the media type can be determined: External drive, SD card, CF card, USB Thumbrive, or whatever kind of media I can feed my computer.

I need to know if a card is a USB thumb drive, CompatcFlash card, SD card or Memorystick(Duo).
And even SxS media, or XQD media, or an XD-CAM disc, if that’s even possible.
I know on the OS-X desktop, the appropriate icon appears for each different type of media. So, somewhere it must be on the volume info.

Well I knew I had code to do this… but unfortuntly is was CARBON code…

  Dim x as integer
  Dim y as integer
  if f Is nil then
    return 0//false
  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"... but all my drives show 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 // Set to Unknown as both Internal and External bits are set
    if infoBuffer.long(10)<>0 then y=volumeNETWORK
    if Bitwise.BitAnd(x,pow(2,24))>0 then y=-1 ' do not display
    return y
  'enum {
  '/* vMExtendedAttributes (GetVolParms) bit position constants */
  'bIsEjectable                  = 0,    /* volume is in an ejectable disk drive */
  'bSupportsHFSPlusAPIs          = 1,    /* volume supports HFS Plus APIs directly (not through compatibility layer) */
  'bSupportsFSCatalogSearch      = 2,    /* volume supports FSCatalogSearch */
  'bSupportsFSExchangeObjects    = 3,    /* volume supports FSExchangeObjects */
  'bSupports2TBFiles             = 4,    /* volume supports supports 2 terabyte files */
  'bSupportsLongNames            = 5,    /* volume supports file/directory/volume names longer than 31 characters */
  'bSupportsMultiScriptNames     = 6,    /* volume supports file/directory/volume names with characters from multiple script systems */
  'bSupportsNamedForks           = 7,    /* volume supports forks beyond the data and resource forks */
  'bSupportsSubtreeIterators     = 8,    /* volume supports recursive iterators not at the volume root */
  'bL2PCanMapFileBlocks          = 9,    /* volume supports Lg2Phys SPI correctly */
  'bParentModDateChanges         = 10,   /* Changing a file or folder causes its parent's mod date to change */
  'bAncestorModDateChanges       = 11,   /* Changing a file or folder causes all ancestor mod dates to change */
  'bSupportsSymbolicLinks        = 13,   /* volume supports the creation and use of symbolic links (Mac OS X only) */
  'bIsAutoMounted                = 14,   /* volume was mounted automatically (Mac OS X only) */
  'bAllowCDiDataHandler          = 17,   /* allow QuickTime's CDi data handler to examine this volume */
  'bSupportsExclusiveLocks       = 18,   /* volume supports exclusive opens for writing */
  'bSupportsJournaling           = 19,   /* volume supports journal (journal may not be active) */
  'bNoVolumeSizes                = 20,   /* volume is unable to report volume size or free space */
  'bIsOnInternalBus              = 21,   /* device is on an internal bus - see note below */
  'bIsCaseSensitive              = 22,   /* volume is case sensitive */
  'bIsCasePreserving             = 23,   /* volume is case preserving */
  'bDoNotDisplay                 = 24,   /* volume should not be displayed in UI */
  'bIsRemovable                  = 25,   /* device is removable according to IOKit */
  'bNoRootTimes                  = 26,   /* volume does not set reliable times for its root directory */
  'bIsOnExternalBus              = 27,   /* device is on an external bus -- see note below */
  'bSupportsExtendedFileSecurity = 28    /* volume supports FSFileSecurity objects */
  '/*    Note: A volume can return one of four states via the bIsInternal and bIsExternal bits.  A volume known
  'to be on an internal bus will set bIsInternal and clear bIsExternal.  A volume known to
  'be on an external bus will clear bIsInternal and set bIsExternal.  A volume on a bus that
  'is indeterminate (could be either) will set both bits.  A volume not on a local bus will, such
  'as a network volume, will leave both bits clear. */

A lot of info can be garnered from NSURL, instead of Carbon APIs, but as far as I’m aware the disk types is very limited.

IOKit probably exposes what you need

 dim info as CFDictionaryMBS = volume(VolumeCount-1).DarwinMediaInfoMBS

this tells you details like this:

“BSD Major” = 1;
“BSD Minor” = 9;
“BSD Name” = disk4;
“BSD Unit” = 4;
Content = “FDisk_partition_scheme”;
“Content Hint” = “”;
Ejectable = 1;
IOBusyInterest = “IOCommand is not serializable”;
IOGeneralInterest = “IOCommand is not serializable”;
IOMediaIcon = {
CFBundleIdentifier = “”;
IOBundleResourceFile = “Removable.icns”;
Leaf = 0;
Open = 1;
“Preferred Block Size” = 512;
Removable = 1;
Size = 4043309056;
Whole = 1;
Writable = 1;

dim session as new DASessionMBS dim d as DADiskMBS = DADiskMBS.CreateFromVolume(session, volume(volumecount-1)) dim dic as Dictionary = d.Description

For my USB Stick the DAMediaKind is IOMedia, DAMediaContent is DOS_FAT_32, removable and ejectable are true. DABusName is XHC1 and DADeviceProtocol is USB. So you know it’s USB at least.

Of course we also have WindowsVolumeInformationMBS and VolumeInformationMBS classes.

Which is the same information you can get from NSURL.

I think you have to go deeper…