Jump to content
Sign in to follow this  
kosamja

Checking is CD drive real or virtual?

Recommended Posts

How to check if CD drive is real or virtual, I tried this but I am not sure if it really works (only tested on 1 pc). Can someone test it?

#NoTrayIcon
#RequireAdmin
#include <Constants.au3>
#include <GUIConstants.au3>
#include <WinAPIFiles.au3>
#include <WinAPIHObj.au3>
#include <WinAPIMisc.au3>

Opt('WinWaitDelay', 0)
Opt('MouseClickDelay', 0)
Opt('MouseClickDownDelay', 0)
Opt('MouseClickDragDelay', 0)
Opt('SendKeyDelay', 0)
Opt('SendKeyDownDelay', 0)
Opt('WinTitleMatchMode', 3)

$DrivesList = DriveGetDrive('CDROM')
If IsArray($DrivesList) Then
   For $i = 1 to $DrivesList[0]
      If _IsVirtualCDRomDevice($DrivesList[$i]) = False Then MsgBox(0, '', StringUpper($DrivesList[$i]))
   Next
EndIf
Exit

Func _IsVirtualCDRomDevice($sDriveLetter)
   $sBusTypeVirtual = 0xE
   $sBusTypeFileBackedVirtual = 0xF
   $sCDRomDeviceIdentifiers = _GetCDRomDeviceIdentifiers($sDriveLetter)
   If IsArray($sCDRomDeviceIdentifiers) Then
      $sScsiStatus = $sCDRomDeviceIdentifiers[0]
      $sLun = $sCDRomDeviceIdentifiers[1]
      $sDataTransferLength = $sCDRomDeviceIdentifiers[2]
      If $sScsiStatus = 0 and $sLun = 0 and $sDataTransferLength = 8 Then
         $sDriveBusType = _WinAPI_GetDriveBusType($sDriveLetter)
         If $sDriveBusType <> $sBusTypeVirtual and $sDriveBusType <> $sBusTypeFileBackedVirtual Then
            $sDeviceIdentifiers = _GetDeviceIdentifiers($sDriveLetter)
            $sValue037 = $sDeviceIdentifiers[4]
            If $sValue037 = 0 Then Return False
         EndIf
      EndIf
   EndIf
   Return True
EndFunc

Func _GetCDRomDeviceIdentifiers($sDriveLetter)
   Local $sCDRomDeviceIdentifiers[3]
   $tag_SCSI_PASS_THROUGH_DIRECT = 'ushort Length;byte ScsiStatus;byte PathId;byte TargetId;byte Lun;byte CdbLength;byte SenseInfoLength;byte DataIn;byte Alignment[3];ulong DataTransferLength;ulong TimeOutValue;ulong_ptr DataBufferOffset;ulong SenseInfoOffset;byte Cdb[16]'
   $sDriveHandle = _WinAPI_CreateFile('\\.\' & $sDriveLetter, 2, 2+4, 2+4)
   If $sDriveHandle = 0 Then Return SetError(1, 0, '')
   If not @AutoItX64 Then
      $tScsiPassThroughDirect = DllStructCreate($tag_SCSI_PASS_THROUGH_DIRECT & ';byte Hdr[8]')
   Else
      $tScsiPassThroughDirect = DllStructCreate($tag_SCSI_PASS_THROUGH_DIRECT & ';byte[4];byte Hdr[8]')
   EndIf
   $tDataScsiCDB = DllStructCreate('byte;byte;byte[6];byte[2];byte;byte;byte[4]', DllStructGetPtr($tScsiPassThroughDirect, 'Cdb'))
   $sDataBufferLength = DllStructGetPtr($tScsiPassThroughDirect, 'Hdr') - DllStructGetPtr($tScsiPassThroughDirect)
   DllStructSetData($tDataScsiCDB, 4, 0, 1)
   DllStructSetData($tDataScsiCDB, 4, 8, 2)
   DllStructSetData($tDataScsiCDB, 1, 0xBD)
   DllStructSetData($tScsiPassThroughDirect, 'DataIn', 1)
   DllStructSetData($tScsiPassThroughDirect, 'CdbLength', 12)
   DllStructSetData($tScsiPassThroughDirect, 'TimeOutValue', 86400)
   DllStructSetData($tScsiPassThroughDirect, 'DataTransferLength', 8)
   DllStructSetData($tScsiPassThroughDirect, 'Length', $sDataBufferLength)
   DllStructSetData($tScsiPassThroughDirect, 'DataBufferOffset', $sDataBufferLength)
   $sResult = _WinAPI_DeviceIoControl($sDriveHandle, $IOCTL_SCSI_PASS_THROUGH, DllStructGetPtr($tScsiPassThroughDirect), $sDataBufferLength, DllStructGetPtr($tScsiPassThroughDirect), DllStructGetSize($tScsiPassThroughDirect))
   If $sResult = False Then Return SetError(2, 0, '')
   _WinAPI_CloseHandle($sDriveHandle)
   $sCDRomDeviceIdentifiers[0] = DllStructGetData($tScsiPassThroughDirect, 'ScsiStatus')
   $sCDRomDeviceIdentifiers[1] = DllStructGetData($tScsiPassThroughDirect, 'Lun')
   $sCDRomDeviceIdentifiers[2] = DllStructGetData($tScsiPassThroughDirect, 'DataTransferLength')
   Return $sCDRomDeviceIdentifiers
EndFunc

Func _GetDeviceIdentifiers($sDriveLetter)
   Local $sDeviceIdentifiers[6] = ['', 0, 0, 0, 0, 0]
   $tag_STORAGE_DESCRIPTOR_HEADER = 'dword Version;dword Size'
   $tag_STORAGE_PROPERTY_QUERY = 'ulong_ptr PropertyId;ulong_ptr QueryType;byte AdditionalParameters[4]'
   $tag_STORAGE_DEVICE_DESCRIPTOR = 'ulong Version;ulong Size;byte DeviceType;byte DeviceTypeModifier;byte RemovableMedia;byte CommandQueueing;ulong VendorIdOffset;ulong ProductIdOffset;ulong ProductRevisionOffset;ulong SerialNumberOffset;ulong BusType;ulong RawPropertiesLength'
   $tStoragePropertyQuery = DllStructCreate($tag_STORAGE_PROPERTY_QUERY)
   $sStorageDescriptorHeader = DllStructCreate($tag_STORAGE_DESCRIPTOR_HEADER)
   $sDriveHandle = _WinAPI_CreateFile('\\.\' & $sDriveLetter, 2, 2+4, 2+4)
   If $sDriveHandle = 0 Then Return SetError(1, 0, '')
   $sResult = _WinAPI_DeviceIoControl($sDriveHandle, $IOCTL_STORAGE_QUERY_PROPERTY, DllStructGetPtr($tStoragePropertyQuery), DllStructGetSize($tStoragePropertyQuery), DllStructGetPtr($sStorageDescriptorHeader), DllStructGetSize($sStorageDescriptorHeader))
   If $sResult = False or DllStructGetData($sStorageDescriptorHeader, 'Size') = 0 Then Return SetError(2, 0, '')
   $tStorageDeviceDescriptor = DllStructCreate($tag_STORAGE_DEVICE_DESCRIPTOR & ';byte RawDeviceProperties[' & DllStructGetData($sStorageDescriptorHeader, 'Size') & ']')
   $sResult = _WinAPI_DeviceIoControl($sDriveHandle, $IOCTL_STORAGE_QUERY_PROPERTY, DllStructGetPtr($tStoragePropertyQuery), DllStructGetSize($tStoragePropertyQuery), DllStructGetPtr($tStorageDeviceDescriptor), DllStructGetSize($tStorageDeviceDescriptor))
   If $sResult = False Then Return SetError(3, 0, '')
   If DllStructGetData($tStorageDeviceDescriptor, 'VendorIdOffset') <> 0 Then
      $sVendorIdPtr = DllStructGetPtr($tStorageDeviceDescriptor) + DllStructGetData($tStorageDeviceDescriptor, 'VendorIdOffset')
      $tVendorId = DllStructCreate('char VendorId[' & _WinAPI_StringLenA($sVendorIdPtr) & ']', $sVendorIdPtr)
      $sDeviceIdentifiers[0] = StringStripWS(DllStructGetData($tVendorId, 'VendorId'), $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES)
   EndIf
   If DllStructGetData($tStorageDeviceDescriptor, 'ProductIdOffset') <> 0 Then
      $sProductIdPtr = DllStructGetPtr($tStorageDeviceDescriptor) + DllStructGetData($tStorageDeviceDescriptor, 'ProductIdOffset')
      $tProductId = DllStructCreate('char ProductId[' & _WinAPI_StringLenA($sProductIdPtr) & ']', $sProductIdPtr)
      $sDeviceIdentifiers[0] = StringRegExpReplace($sDeviceIdentifiers[0], '\N+\K(?!.$)', ' ') & StringStripWS(DllStructGetData($tProductId, 'ProductId'), $STR_STRIPLEADING + $STR_STRIPTRAILING + $STR_STRIPSPACES)
   EndIf
   $sDeviceIdentifiers[1] = DllStructGetData($tStorageDeviceDescriptor, 'RawDeviceProperties', 3) ;value [039] in _WinAPI_DisplayStruct
   $sDeviceIdentifiers[2] = DllStructGetData($tStorageDeviceDescriptor, 'RawDeviceProperties', 4) ;value [040] in _WinAPI_DisplayStruct
   $sDeviceIdentifiers[3] = DllStructGetData($tStorageDeviceDescriptor, 'RawDeviceProperties', 6) ;value [042] in _WinAPI_DisplayStruct
   $sDeviceIdentifiers[4] = DllStructGetData($tStorageDeviceDescriptor, 'RawDeviceProperties', 1) ;value [037] in _WinAPI_DisplayStruct
   $sDeviceIdentifiers[5] = DllStructGetData($tStorageDeviceDescriptor, 'DeviceTypeModifier')
   _WinAPI_CloseHandle($sDriveHandle)
   Return $sDeviceIdentifiers
EndFunc

 

CD Check.au3

Edited by kosamja

Share this post


Link to post
Share on other sites

My system has no physical optical drive. Running Windows 10 v 1803.

If I mount an ISO image, it is seen in the $DrivesList array but your function _IsVirtualCDRomDevice does not detect it.

Edit: The LUN is detected as 1

Edited by ModemJunki

Always carry a towel.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...