Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Название физического устройства


Автор: MetalFan 8.5.2007, 20:25
как по букве логического диска получить название физического устройства.
спасибо!

Автор: Snowy 8.5.2007, 20:47
Посмотри в DRKB GetIdeDiskSerialNumber.

Автор: MetalFan 8.5.2007, 20:58
хм... там пример получения серийного номера hdd...
а мне хотелось бы название физического устройства... например так, как Nero показывает список пишущих приводов... 
т.е. что-то типа: "F: Optaric DVD-RW NEC 3950"

Автор: Snowy 8.5.2007, 21:19
ну так посмотри код глазками.
он получает информацию о диске, берёт из неё номер и возвращает.
что мешает переделать код, чтобы из этой информации возвращалось название, а не серийние?

Автор: MetalFan 8.5.2007, 22:14
угу.разобрался) только там про то, что это название, ни слова

Автор: Snowy 8.5.2007, 22:17
русские программисты не пишут комментариев smile

Автор: Yanis 8.5.2007, 22:17
Цитата(Snowy @  8.5.2007,  23:17 Найти цитируемый пост)
русские программисты не пишут комментариев

Они и код то сами редко пишут.

Автор: MetalFan 9.5.2007, 10:30
Цитата(Yanis @  8.5.2007,  22:17 Найти цитируемый пост)
Они и код то сами редко пишут. 

 smile 
з.ы. вот на всякий случай переделанный мной код, выполняющий поставленную в топике задачу, а именно - получение имени физического устройства по букве логического диска.
для CD/DVD приводов вроде работает. для hdd не проверял)
Код

   {$ALIGN ON}
    type
    TScsiBusData = record  // warning! dword alignment
          NumberOfLogicalUnits : Byte;
          InitiatorBusId       : Byte;
          InquiryDataOffset    : ULONG;
    end;
    SCSI_BUS_DATA = TScsiBusData;
    PScsiBusData = ^TScsiBusData;

    // Define SCSI adapter bus information structure..
    TScsiAdapterBusInfo = record // warning! dword alignment
          NumberOfBuses : Byte;
          BusData : Array[0..0] of SCSI_BUS_DATA;
    end;
    SCSI_ADAPTER_BUS_INFO = TScsiAdapterBusInfo;
    PScsiAdapterBusInfo = ^TScsiAdapterBusInfo;

    TScsiInquiryData = record // warning! dword alignment
          PathId                : Byte;
          TargetId              : Byte;
          Lun                   : Byte;
          DeviceClaimed         : Boolean;
          InquiryDataLength     : ULONG;
          NextInquiryDataOffset : ULONG;
          InquiryData           : Array[0..0] of Byte;
    end;
    PScsiInquiryData = ^TScsiInquiryData;
   {$ALIGN OFF}
   const
    FILE_DEVICE_CONTROLLER          = $00000004;
    IOCTL_SCSI_BASE    = FILE_DEVICE_CONTROLLER;
    IOCTL_SCSI_GET_INQUIRY_DATA = (IOCTL_SCSI_BASE shl 16) or ($0403 shl 2);

   function GetDeviceName( ADriveLetter: Char; var AName: string ): Boolean;
   const
     C_BufSize = 2048;
   var
     hDevice : THandle;
     lAdaptBusInfo: PScsiAdapterBusInfo;
     lInqData: PScsiInquiryData;
     lSz: DWORD;
     lBuff: array[0..C_BufSize-1] of Byte;
     lSrc: Pointer;
   begin
      Result := False;
      hDevice := CreateFile( PChar( '\\.\'+ADriveLetter+':'),
                                      GENERIC_READ,
                                      FILE_SHARE_READ or FILE_SHARE_WRITE,
                                      nil,
                                      OPEN_EXISTING,
                                      FILE_ATTRIBUTE_NORMAL, 0 );
      if hDevice <> INVALID_HANDLE_VALUE then
      begin
        try
          lSz := C_BufSize;
          ZeroMemory( @lBuff, C_BufSize );
          Result := DeviceIoControl( hDevice, IOCTL_SCSI_GET_INQUIRY_DATA, nil, 0, @lBuff, lSz, lSz, nil );
          if not Result then Exit;
          lAdaptBusInfo := @lBuff;
          Result := lAdaptBusInfo^.NumberOfBuses > 0;
          if not Result then Exit;
          lInqData := PScsiInquiryData( Integer(lAdaptBusInfo) + lAdaptBusInfo^.BusData[0].InquiryDataOffset );
          lSz := lInqData^.InquiryDataLength - 8;
          Result := lSz > 0;
          if not Result then Exit;
          SetLength( AName, lSz);
          lSrc := PChar(@lInqData^.InquiryData[0]) + 8;
          Move( lSrc^, AName[1], lSz );
        finally
          CloseHandle( hDevice );
        end;
     end;
   end;

что скажете?

Автор: Snowy 9.5.2007, 14:55
Если работает, то скажу "хорошо" smile
А для удобства плагиата можно ещё и описание структур в функцию загнать. smile

Автор: MetalFan 16.5.2007, 13:00
ай блин... если на шлейфе 2 устройства, то получает только название первого((((

Автор: MetalFan 16.5.2007, 17:44
разобрался... сначала надо получить его адрес.
вот вроде бы работающий код:
Код

   {$ALIGN ON}
    type
    TScsiBusData = record  // warning! dword alignment
          NumberOfLogicalUnits : Byte;
          InitiatorBusId       : Byte;
          InquiryDataOffset    : ULONG;
    end;
    SCSI_BUS_DATA = TScsiBusData;
    PScsiBusData = ^TScsiBusData;

    // Define SCSI adapter bus information structure..
    TScsiAdapterBusInfo = record // warning! dword alignment
          NumberOfBuses : Byte;
          BusData : Array[0..0] of SCSI_BUS_DATA;
    end;
    SCSI_ADAPTER_BUS_INFO = TScsiAdapterBusInfo;
    PScsiAdapterBusInfo = ^TScsiAdapterBusInfo;

    TScsiInquiryData = record // warning! dword alignment
          PathId                : Byte;
          TargetId              : Byte;
          Lun                   : Byte;
          DeviceClaimed         : Boolean;
          InquiryDataLength     : ULONG;
          NextInquiryDataOffset : ULONG;
          InquiryData           : Array[0..0] of Byte;
    end;
    PScsiInquiryData = ^TScsiInquiryData;

    _SCSI_ADDRESS = record
      Length: ULONG;
      PortNumber: UCHAR;
      PathId: UCHAR;
      TargetId: UCHAR;
      Lun: UCHAR;
    end;
    PScsiAddress = ^TScsiAddress;
    TScsiAddress = _SCSI_ADDRESS;
   {$ALIGN OFF}
   
   const
    FILE_DEVICE_CONTROLLER          = $00000004;
    IOCTL_SCSI_BASE    = FILE_DEVICE_CONTROLLER;
    IOCTL_SCSI_GET_INQUIRY_DATA = (IOCTL_SCSI_BASE shl 16) or ($0403 shl 2);
    IOCTL_SCSI_GET_ADDRESS      = (IOCTL_SCSI_BASE shl 16) or ($0406 shl 2);


   function GetDeviceName( ADriveLetter: Char; var AName: string ): Boolean;
   const
     C_BufSize = 2048;
   var
     hDevice : THandle;
     lScsiAddress: TScsiAddress;

     i: Integer;
     lAdaptBusInfo: PScsiAdapterBusInfo;
     lInqData: PScsiInquiryData;
     lSz: DWORD;
     lBuff: array[0..C_BufSize-1] of Byte;
     lSrc: Pointer;
   begin
      Result := False;
      AName := '';
      hDevice := CreateFile( PChar( '\\.\'+ADriveLetter+':'),
                                      GENERIC_READ,
                                      FILE_SHARE_READ or FILE_SHARE_WRITE,
                                      nil,
                                      OPEN_EXISTING,
                                      FILE_ATTRIBUTE_NORMAL, 0 );
      if hDevice <> INVALID_HANDLE_VALUE then
      begin
        try
          lSz := SizeOf( TScsiAddress );
          ZeroMemory( @lScsiAddress, SizeOf( TScsiAddress ) );
          lScsiAddress.Length := lSz;

          Result := DeviceIoControl( hDevice, IOCTL_SCSI_GET_ADDRESS, nil, 0, @lScsiAddress, lSz, lSz, nil );
          if not Result then Exit;

          lSz := C_BufSize;
          ZeroMemory( @lBuff, C_BufSize );
          Result := DeviceIoControl( hDevice, IOCTL_SCSI_GET_INQUIRY_DATA, nil, 0, @lBuff, lSz, lSz, nil );
          if not Result then Exit;
          lAdaptBusInfo := @lBuff;
          Result := lAdaptBusInfo^.NumberOfBuses > 0;
          if not Result then Exit;
          lInqData := nil;

          Result := False;
          repeat
            if lInqData = nil then
              lInqData := PScsiInquiryData( Integer(lAdaptBusInfo) + lAdaptBusInfo^.BusData[0].InquiryDataOffset )
            else
              lInqData := Pointer(Integer(lAdaptBusInfo) + lInqData^.NextInquiryDataOffset);
            lSz := lInqData^.InquiryDataLength - 8;
            if (lInqData^.PathId = lScsiAddress.PathId) and
               (lInqData^.TargetId = lScsiAddress.TargetId ) and
               (lInqData^.Lun = lScsiAddress.Lun) and
               (lSz > 0) then
            begin
              SetLength( AName, lSz);
              lSrc := PChar(@lInqData^.InquiryData[0]) + 8;
              Move( lSrc^, AName[1], lSz );
              Result := True;
              Break;
            end;
          until lInqData^.NextInquiryDataOffset = 0;
        finally
          CloseHandle( hDevice );
        end;
     end;
   end;


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)