is drive a usb drive?

Windows specific forum
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

is drive a usb drive?

Post by jassing »

Is there a way to detect if a drive is physically part of the machine (sata/ide) or connected via a USB / Firewire hub? (or internal/external)

Another related -- is there a way to tell if a drive is a solid state drive (vs mechanical)?
(bonus if there's a way to reliably read the drive's actual serial # (not volume id).

I would like to avoid using wsh for speed and possible policy conflicts; but if that's the only way; I will make adjustments.

Thanks.
-josh
User avatar
RSBasic
Moderator
Moderator
Posts: 1228
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: is drive a usb drive?

Post by RSBasic »

Image
Image
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: is drive a usb drive?

Post by jassing »

RSBasic wrote:USB drive check: http://www.rsbasic.de/aktualisierung/wi ... e%20ist.pb
[/qoute]
I ran that as x86 & x64, unicode and not. Nothing was identified as a usb drive.
that's the volume id, not the drive's serial #.
Marc56us
Addict
Addict
Posts: 1600
Joined: Sat Feb 08, 2014 3:26 pm

Re: is drive a usb drive?

Post by Marc56us »

jassing wrote:Is there a way to detect if a drive is physically part of the machine (sata/ide) or connected via a USB / Firewire hub? (or internal/external)
GetDriveType function
Determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.

https://msdn.microsoft.com/fr-fr/librar ... s.85).aspx
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: is drive a usb drive?

Post by DontTalkToMe »

jassing wrote: (bonus if there's a way to reliably read the drive's actual serial # (not volume id).
MS says

https://msdn.microsoft.com/en-us/librar ... 2147217396
This function returns the volume serial number that the operating system assigns when a hard disk is formatted. To programmatically obtain the hard disk's serial number that the manufacturer assigns, use the Windows Management Instrumentation (WMI) Win32_PhysicalMedia property SerialNumber.
User avatar
blueb
Addict
Addict
Posts: 1118
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: is drive a usb drive?

Post by blueb »

Will this help?

Code: Select all

; German forum: http://www.purebasic.fr/german/viewtopic.php?t=1895&highlight=
; Author: DataMiner (updated for PB 4.00 by Andre)
; Date: 05. February 2005
; OS: Windows
; Demo: No


Define.l Serial, type, i 
Define.s Lfwrk, FileSystem, VolName 

For i=65 To 90 
  Lfwrk=Chr(i)+":\" 
  type =GetDriveType_(Lfwrk) 
  FileSystem = Space(256) 
  VolName= Space(256) 
  GetVolumeInformation_(@Lfwrk, @VolName, 255, @Serial, 0, 0, @FileSystem, 255) 
  Select type 
    Case 0 
      Debug Lfwrk+" The drive type cannot be determined." 
    Case 2 
      Debug Lfwrk+" = DRIVE_REMOVABLE, "+VolName+", "+FileSystem+", "+  Hex(Serial) 
    Case 3 
      Debug Lfwrk+" = DRIVE_FIXED, "+VolName+", "+FileSystem+", "+  Hex(Serial) 
    Case 4 
      Debug Lfwrk+" = DRIVE_REMOTE, "+VolName+", "+FileSystem+", "+  Hex(Serial) 
    Case 5 
      Debug Lfwrk+" = DRIVE_CDROM, "+VolName+", "+FileSystem+", "+  Hex(Serial) 
    Case 6 
      Debug Lfwrk+" =  DRIVE_RAMDISK,   "+VolName+", "+FileSystem+", "+  Hex(Serial) 
  EndSelect 
Next 
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: is drive a usb drive?

Post by jassing »

thanks; I'll use wmi... not ideal; but it'll work. thanks.
I'll poke around that too, to see if I can find a internal/external disk identifier too.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: is drive a usb drive?

Post by Thunder93 »

jassing wrote:Another related -- is there a way to tell if a drive is a solid state drive (vs mechanical)?
There is, I've thrown something together and is incomplete. Unfortunately I'm heading out for a few so here it is.

Code: Select all

#StorageDeviceTrimProperty = 8

Structure DEVICE_TRIM_DESCRIPTOR Align #PB_Structure_AlignC
  Version.l
  Size.l
  TrimEnabled.b
EndStructure

#StorageDeviceSeekPenaltyProperty = 7

Structure DEVICE_SEEK_PENALTY_DESCRIPTOR Align #PB_Structure_AlignC
  Version.l
  Size.l
  IncursSeekPenalty.b
EndStructure

Structure ATA_PASS_THROUGH_EX Align #PB_Structure_AlignC
  length.w
  AtaFlags.w
  PathId.c
  TargetId.c
  Lun.c
  ReservedAsUchar.c
  DataTransferLength.l
  TimeOutValue.l
  ReservedAsUlong.l
  DataBufferOffset.i
  PreviousTaskFile.c[8]
  CurrentTaskFile.c[8]
EndStructure

Structure ATAIdentifyDeviceQuery Align #PB_Structure_AlignC
  header.ATA_PASS_THROUGH_EX
  Data.w[256]
EndStructure

Structure STORAGE_PROPERTY_QUERY Align #PB_Structure_AlignC
  PropertyId.l ;STORAGE_PROPERTY_ID
  QueryType.l  ;STORAGE_QUERY_TYPE
  AdditionalParameters.l
EndStructure

#IOCTL_STORAGE_QUERY_PROPERTY  = $2D1400
#IOCTL_ATA_PASS_THROUGH = $4D02C
#PropertyStandardQuery = 0

#ATA_FLAGS_DATA_IN  = $02


bytesReturned.l

sDrive.s = "\\.\PhysicalDrive0"

hDevice = CreateFile_(sDrive,
                      0,  ; No access To drive needed.
                      #FILE_SHARE_READ | #FILE_SHARE_WRITE, #Null,
                      #OPEN_EXISTING,  0, #Null)

If hDevice <> #INVALID_HANDLE_VALUE
  Debug sDrive
  
  ;Check TRIM -- should be Y for SSD  
  spqTrim.STORAGE_PROPERTY_QUERY
  spqTrim\PropertyId = #StorageDeviceTrimProperty
  spqTrim\QueryType = #PropertyStandardQuery
  
  bytesReturned = 0
  dtd.DEVICE_TRIM_DESCRIPTOR
  If DeviceIoControl_(hDevice, #IOCTL_STORAGE_QUERY_PROPERTY,
                      @spqTrim, SizeOf(spqTrim), @dtd, SizeOf(dtd), @bytesReturned, #Null) And bytesReturned = SizeOf(dtd)  
    
    Debug "Retrieving TRIM"
    If dtd\TrimEnabled = 1      
      Debug "  Disk is SSD"
    Else
      Debug "  Disk is non-SSD"
    EndIf
    
    
  Else
    Debug "DeviceIoControl #1 failed: Error-Code: "+GetLastError_()
  EndIf
  
  ;Check the seek-penalty value -- should be N For SSD  
  spqSeekP.STORAGE_PROPERTY_QUERY
  spqSeekP\PropertyId = #StorageDeviceSeekPenaltyProperty
  spqSeekP\QueryType = #PropertyStandardQuery
  
  bytesReturned = 0
  dspd.DEVICE_SEEK_PENALTY_DESCRIPTOR
  If DeviceIoControl_(hDevice, #IOCTL_STORAGE_QUERY_PROPERTY,
                      @spqSeekP, SizeOf(spqSeekP), @dspd, SizeOf(dspd), @bytesReturned, #Null) And bytesReturned = SizeOf(dspd)
    
    Debug "Retrieving SeekPenalty"
    If dspd\IncursSeekPenalty = 0
      Debug "  Disk is SSD"
    Else
      Debug "  Disk is non-SSD"
    EndIf
    
  Else
    Debug #CRLF$+"DeviceIoControl #2 failed: Error-Code: "+GetLastError_()
  EndIf
  
  CloseHandle_(hDevice)
EndIf


; Administrative privileges required for the below code

hDevice = CreateFile_(sDrive,
                      #GENERIC_READ | #GENERIC_WRITE, ; Administrative privileges is required
                      #FILE_SHARE_READ | #FILE_SHARE_WRITE, #Null,
                      #OPEN_EXISTING,  0, #Null)

If hDevice = -1 : Debug #CRLF$+"Requires Administrator Privileges for drive RPM reading." : End : EndIf

If hDevice <> #INVALID_HANDLE_VALUE
  ;Get drive's RPMs reading -- should be 1 for SSD
  ;CODE SOURCE: https://emoacht.wordpress.com/2012/11/06/csharp-ssd/
  
  id_query.ATAIdentifyDeviceQuery
  
  With id_query\header
    \length = SizeOf(id_query\header)   
    \AtaFlags = #ATA_FLAGS_DATA_IN
    \DataTransferLength = SizeOf(id_query\Data) * 2 ;Size of "data" in bytes    
    
    \TimeOutValue = 5 ;secs
    \DataBufferOffset = OffsetOf(ATAIdentifyDeviceQuery\Data)
    ;     \PreviousTaskFile = 0
    ;     \CurrentTaskFile  = 0
    \CurrentTaskFile[6] = $EC ; ATA IDENTIFY DEVICE    
  EndWith 
  
    
  bytesReturned = 0 : dbsize.l = SizeOf(id_query)
  If DeviceIoControl_(hDevice, #IOCTL_ATA_PASS_THROUGH,
                      @id_query, dbsize, @id_query, dbsize, @bytesReturned, #Null) ;And bytesReturned = SizeOf(id_query)
    
    
    kNominalMediaRotRateWordIndex = 217
    
    Debug "Retrieving Nominal media rotation rate"
    If id_query\Data[kNominalMediaRotRateWordIndex] = 1
      Debug "Disk is SSD"
    Else
      Debug "Disk is non-SSD"
    EndIf    
    
  Else
    Debug #CRLF$+"DeviceIoControl #3 failed: Error-Code: "+GetLastError_()
  EndIf  
  
  CloseHandle_(hDevice)
EndIf
Last edited by Thunder93 on Fri Apr 22, 2016 10:05 pm, edited 2 times in total.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: is drive a usb drive?

Post by jassing »

Thunder93 wrote:[I've thrown something together and is incomplete. Unfortunately I'm heading out for a few so here it is.
Thanks; I'll have a look at it tonight.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: is drive a usb drive?

Post by Thunder93 »

I've updated it. Administrator privileges isn't requirement for the first two methods. Third method, even though incomplete, does require Admin privileges.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: is drive a usb drive?

Post by Thunder93 »

You want drive serials not volume Ids. You want to detect type of device (like USB or Firewire), and if its Solid-State drive. WMI isn't often appealing, so without WMI usage. Requires no administrator privileges.

GetDrivesINFO.pb - Revised on 2016-04-23 | #1

Code: Select all

IncludeFile "IsSSD.pbi"

Structure STORAGE_DEVICE_DESCRIPTOR ;Align #PB_Structure_AlignC
  Version.l
  Size.l
  DeviceType.b
  DeviceTypeModifier.b
  RemovableMedia.b
  CommandQueueing.b
  VendorIdOffset.l
  ProductIdOffset.l
  ProductRevisionOffset.l
  SerialNumberOffset.l
  BusType.w
  RawPropertiesLength.l
  RawDeviceProperties.b
  Reserved.b[1024]
EndStructure

#BusTypeUnknown      = $00
#BusTypeScsi         = $01
#BusTypeAtapi        = $02
#BusTypeAta          = $03
#BusType1394         = $04
#BusTypeSsa          = $05
#BusTypeFibre        = $06
#BusTypeUsb          = $07
#BusTypeRAID         = $08
#BusTypeiSCSI        = $09
#BusTypeSas          = $0A
#BusTypeSata         = $0B
#BusTypeMaxReserved  = $7F

#IOCTL_STORAGE_QUERY_PROPERTY          = $2D1400
#IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER = $2D0C10

strDrive.s
udtQuery.STORAGE_PROPERTY_QUERY
udtOut.STORAGE_DEVICE_DESCRIPTOR

OpenConsole()
PrintN("Enumerate devices")

For Drives=1 To 26
  
  strDrive="\\.\" + Chr(64+Drives) + ":"
  
  hDrive = CreateFile_(strDrive, 0,#FILE_SHARE_READ | #FILE_SHARE_WRITE, 0, #OPEN_EXISTING, 0, 0)
  If hDrive <> #INVALID_HANDLE_VALUE
    
    PrintN("--------------------------------------------------")
    
    lngResult = DeviceIoControl_(hDrive, #IOCTL_STORAGE_QUERY_PROPERTY, udtQuery,SizeOf(udtQuery), @udtOut, SizeOf(udtOut), @dwOutBytes, 0)
    If lngResult 
      PrintN("Drive " + Chr(64+Drives) + ": is a ")
      
      Select(udtOut\Bustype) 
        Case #BusTypeUnknown
          PrintN("Bustype: Unknown bus type")
          
        Case #BusTypeScsi
          PrintN("Bustype: SCSI bus")
          
        Case #BusTypeAtapi
          PrintN("Bustype:  Atapi bus")
          
        Case #BusTypeAta
          PrintN("Bustype:  Ata Device")
          
        Case #BusType1394
          PrintN("Bustype: IEEE-1394 bus")
          
        Case #BusTypeSsa
          PrintN("Bustype: SSA bus")
          
        Case #BusTypeFibre
          PrintN("Bustype: Fibre Channel bus")
          
        Case #BusTypeUsb          
          PrintN("Bustype: USB bus")
      
        Case #BusTypeRAID
          PrintN("Bustype: RAID bus")         

        Case #BusTypeiSCSI
          PrintN("Bustype: iSCSI bus")
          
        Case #BusTypeSas
          PrintN("Bustype: Sas bus")
          
        Case #BusTypeSata
          PrintN("Bustype: SATA bus")
          
        Case #BusTypeMaxReserved
          PrintN("Bustype: iSCSI bus")
          
        Default
          PrintN("Bustype = " + Str(udtOut\BusType))
      EndSelect
      
      If IsSSD(strDrive)
        PrintN("Device is Solid-State Drive (SSD)")
      EndIf      
      
      If udtout\RemovableMedia
        PrintN("Device is Removable Media")
      EndIf
      
      If udtOut\ProductIdOffset > 0
        PrintN("ProductID = " + PeekS(@udtOut + udtOut\ProductIdOffset, -1, #PB_Ascii))
      EndIf
      
      If udtOut\ProductRevisionOffset > 0
        PrintN("ProductRevision = " + PeekS(@udtOut + udtOut\ProductRevisionOffset, -1, #PB_Ascii))
      EndIf
      
      If udtOut\VendorIdOffset  > 0
        PrintN("VendorID = " + PeekS(@udtOut + udtOut\VendorIdOffset, -1, #PB_Ascii))
      EndIf
      
      If udtOut\SerialNumberOffset  > 0       
        Serial$ = Trim(PeekS(@udtOut + udtOut\SerialNumberOffset, -1, #PB_Ascii))        
        PrintN("Serial = " + Serial$)        
      EndIf         
      
    Else
      PrintN("No Device-IO info available.. for "+Chr(64+Drives) + ":")
      
    EndIf    
    
    ClearStructure(@udtQuery, STORAGE_PROPERTY_QUERY)
    ClearStructure(@udtOut, STORAGE_DEVICE_DESCRIPTOR)
  EndIf
  CloseHandle_(hDrive)
  
  
Next Drives

wait.s=Input()
CloseConsole()
IsSSD.pbi

Code: Select all

#StorageDeviceSeekPenaltyProperty   = 7
#StorageDeviceTrimProperty          = 8

Structure DEVICE_TRIM_DESCRIPTOR Align #PB_Structure_AlignC
  Version.l
  Size.l
  TrimEnabled.b
EndStructure

Structure DEVICE_SEEK_PENALTY_DESCRIPTOR Align #PB_Structure_AlignC
  Version.l
  Size.l
  IncursSeekPenalty.b
EndStructure

Structure STORAGE_PROPERTY_QUERY Align #PB_Structure_AlignC
  PropertyId.l ;STORAGE_PROPERTY_ID
  QueryType.l  ;STORAGE_QUERY_TYPE
  AdditionalParameters.l
EndStructure

#IOCTL_STORAGE_QUERY_PROPERTY  = $2D1400
#IOCTL_ATA_PASS_THROUGH        = $4D02C
#PropertyStandardQuery         = 0

Procedure.b IsSSD(sDrive.s)  
  Protected hDevice.i, bytesReturned.l, IsSSD.b 
  
  If sDrive = "" : ProcedureReturn 0 : EndIf
  
  hDevice = CreateFile_(sDrive,
                        0,  ; No access To drive needed.
                        #FILE_SHARE_READ | #FILE_SHARE_WRITE, #Null,
                        #OPEN_EXISTING,  0, #Null)
  
  If hDevice <> #INVALID_HANDLE_VALUE
    
    ;Check TRIM -- should be Y for SSD  
    Protected spqTrim.STORAGE_PROPERTY_QUERY
    spqTrim\PropertyId = #StorageDeviceTrimProperty
    spqTrim\QueryType = #PropertyStandardQuery
    
    bytesReturned = 0
    Protected dtd.DEVICE_TRIM_DESCRIPTOR
    If DeviceIoControl_(hDevice, #IOCTL_STORAGE_QUERY_PROPERTY,
                        @spqTrim, SizeOf(spqTrim), @dtd, SizeOf(dtd), @bytesReturned, #Null) And bytesReturned = SizeOf(dtd)  
      
      If dtd\TrimEnabled = 1 : IsSSD+1 : EndIf
    EndIf
    
    ;Check the seek-penalty value -- should be N For SSD  
    Protected spqSeekP.STORAGE_PROPERTY_QUERY
    spqSeekP\PropertyId = #StorageDeviceSeekPenaltyProperty
    spqSeekP\QueryType = #PropertyStandardQuery
    
    bytesReturned = 0
    Protected dspd.DEVICE_SEEK_PENALTY_DESCRIPTOR
    If DeviceIoControl_(hDevice, #IOCTL_STORAGE_QUERY_PROPERTY,
                        @spqSeekP, SizeOf(spqSeekP), @dspd, SizeOf(dspd), @bytesReturned, #Null) And bytesReturned = SizeOf(dspd)
      
      If dspd\IncursSeekPenalty = 0 : IsSSD+2 : EndIf
    EndIf
    
    CloseHandle_(hDevice)
  EndIf
  
  ProcedureReturn IsSSD ; 0 = Non-SSD, 1 = SSD-byTRIM, 2 = SSD-bySEEKPENTALTY, 3 = SSD-byBOTH
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  Debug IsSSD("\\.\C:")
CompilerEndIf
Last edited by Thunder93 on Sat Apr 23, 2016 4:06 am, edited 4 times in total.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: is drive a usb drive?

Post by jassing »

... AWESOME!!!!

Thank you!!! That worked perfectly!!!!
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: is drive a usb drive?

Post by Thunder93 »

You're certainly welcome. :mrgreen:
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
Post Reply