Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.01.2019, 07:02   #11
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от falsebegin Посмотреть сообщение
может кто нить поможет нубу написать функцию
так есть-же у тебя имена разделов в реестре - выводи их и всё.
RegQueryValueEx() выводит ключи внутри раздела, а твоя задача перебрать имена вложенных разделов внутри ветки ..Enum\IDE, для чего применяем другую функцию RegEnumKey() - она возвращает в буфер строку с именем раздела.

Все разделы внутри IDE перебираешь циклом, для чего функция имеет "индекс". Его нужно увеличивать на 1 на каждом шаге. Как-только функция вернёт ошибку (не нуль в EAX), значит все подразделы просканировал.

Не знаю как на Дельфях, а на ассемблере это выглядит так..
В параметрах функции, всё-что в кв.скобках - это значения из памяти,
а что без скобок - это адрес переменных (указатели).
Последний параметр 128 - это размер буфера:
Код:
format  PE  gui
include 'win32ax.inc'
;---------------------
.data
subKey  db   'SYSTEM\CurrentControlSet\Enum\IDE',0   ; ветка реестра
buff    db   128 dup(0)             ; буфер для строки с именем
hndl    dd   0                      ; место под хэндл ветки реестра
indx    dd   0                      ; индекс для поиска (начинаешь с нуля)
;---------------------
.code
start:
; Открываем раздел реестра Key
       invoke   RegOpenKey,HKEY_LOCAL_MACHINE,subKey,hndl

; Перебираем имена всех подразделов раздела Key
@01:   invoke   RegEnumKey,[hndl],[indx],buff,128  ;<<--------<<--------+
       or       eax,eax                       ; проверим eax            |
       jnz      @stop                         ;   ..выйти, если ошибка  |
       inc      [indx]                        ; увеличим индекс на 1    |
       invoke   MessageBox,0,buff,0,0         ; боксим строку с именем  |
       jmp      @01                           ;--------->>--------------+

@stop: invoke   RegCloseKey,[hndl]            ; прибьём хэндл реестра
       invoke   ExitProcess, 0
.end start
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 13.01.2019, 15:45   #12
Комиссар Катани
Пользователь
 
Регистрация: 29.12.2012
Сообщений: 21
По умолчанию

Вот код, как получить модель жесткого диска без всяких реестров.

Код:
function GetIdeModelNumber(HDDIndx: Byte) : String;

const IDENTIFY_BUFFER_SIZE = 512;
type
  TIDERegs = packed record
    bFeaturesReg     : BYTE; // Used for specifying SMART "commands".
    bSectorCountReg  : BYTE; // IDE sector count register
    bSectorNumberReg : BYTE; // IDE sector number register
    bCylLowReg       : BYTE; // IDE low order cylinder value
    bCylHighReg      : BYTE; // IDE high order cylinder value
    bDriveHeadReg    : BYTE; // IDE drive/head register
    bCommandReg      : BYTE; // Actual IDE command.
    bReserved        : BYTE; // reserved for future use.  Must be zero.
  end;
  TSendCmdInParams = packed record  // Buffer size in bytes
    cBufferSize  : DWORD;
    // Structure with drive register values.
    irDriveRegs  : TIDERegs;
    // Physical drive number to send command to (0,1,2,3).
    bDriveNumber : BYTE;
    bReserved    : Array[0..2] of Byte;
    dwReserved   : Array[0..3] of DWORD;
    bBuffer      : Array[0..0] of Byte;  // Input buffer.
  end;
  TIdSector = packed record
    wGenConfig                 : Word;
    wNumCyls                   : Word;
    wReserved                  : Word;
    wNumHeads                  : Word;
    wBytesPerTrack             : Word;
    wBytesPerSector            : Word;
    wSectorsPerTrack           : Word;
    wVendorUnique              : Array[0..2] of Word;
    sSerialNumber              : Array[0..19] of CHAR;
    wBufferType                : Word;
    wBufferSize                : Word;
    wECCSize                   : Word;
    sFirmwareRev               : Array[0..7] of Char;
    sModelNumber               : Array[0..39] of Char;
    wMoreVendorUnique          : Word;
    wDoubleWordIO              : Word;
    wCapabilities              : Word;
    wReserved1                 : Word;
    wPIOTiming                 : Word;
    wDMATiming                 : Word;
    wBS                        : Word;
    wNumCurrentCyls            : Word;
    wNumCurrentHeads           : Word;
    wNumCurrentSectorsPerTrack : Word;
    ulCurrentSectorCapacity    : DWORD;
    wMultSectorStuff           : Word;
    ulTotalAddressableSectors  : DWORD;
    wSingleWordDMA             : Word;
    wMultiWordDMA              : Word;
    bReserved                  : Array[0..127] of BYTE;
  end;
  PIdSector = ^TIdSector;
  TDriverStatus = packed record
    // Error code from driver, or 0 if no error.
    bDriverError : Byte;
    // Contents of IDE Error register. Only valid when bDriverError is SMART_IDE_ERROR.
    bIDEStatus   : Byte;
    bReserved    : Array[0..1] of Byte;
    dwReserved   : Array[0..1] of DWORD;
  end;
  TSendCmdOutParams = packed record
    // Size of bBuffer in bytes
    cBufferSize  : DWORD;
    // Driver status structure.
    DriverStatus : TDriverStatus;
    // Buffer of arbitrary length in which to store the data read from the drive.
    bBuffer      : Array[0..0] of BYTE;
  end;

  var
    hDevice : THandle;
    cbBytesReturned : DWORD;
    ptr : PChar;
    SCIP : TSendCmdInParams;
    aIdOutCmd : Array [0..(SizeOf(TSendCmdOutParams)+IDENTIFY_BUFFER_SIZE-1)-1] of Byte;
    IdOutCmd  : TSendCmdOutParams absolute aIdOutCmd;

  procedure ChangeByteOrder( var Data; Size : Integer );
  var
    ptr : PChar;
    i : Integer;
    c : Char;
  begin
    ptr := @Data;
    for i := 0 to (Size shr 1)-1 do
    begin
      c := ptr^;
      ptr^ := (ptr+1)^;
      (ptr+1)^ := c;
      Inc(ptr,2);
    end;
  end;

begin
  if SysUtils.Win32Platform=VER_PLATFORM_WIN32_NT then // Windows NT, Windows 2000
    begin
      // warning! change name for other drives: ex.: second drive '\\.\PhysicalDrive1\'
      hDevice := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(HDDIndx)), GENERIC_READ or GENERIC_WRITE,
        FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );
    end
  else // Version Windows 95 OSR2, Windows 98
    hDevice := CreateFile( '\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 );
  if hDevice=INVALID_HANDLE_VALUE then Exit;
  try
    FillChar(SCIP,SizeOf(TSendCmdInParams)-1,#0);
    FillChar(aIdOutCmd,SizeOf(aIdOutCmd),#0);
    cbBytesReturned := 0;
    // Set up data structures for IDENTIFY command.
    with SCIP do
    begin
      cBufferSize  := IDENTIFY_BUFFER_SIZE;
//      bDriveNumber := 0;
      with irDriveRegs do
      begin
        bSectorCountReg  := 1;
        bSectorNumberReg := 1;
//      if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0
//      else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
        bDriveHeadReg    := $A0;
        bCommandReg      := $EC;
      end;
    end;
    if not DeviceIoControl( hDevice, $0007c088, @SCIP, SizeOf(TSendCmdInParams)-1,
      @aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil ) then Exit;
  finally
    CloseHandle(hDevice);
  end;
  with PIdSector(@IdOutCmd.bBuffer)^ do
  begin
    ChangeByteOrder(sModelNumber, SizeOf(sModelNumber) );
    (PChar(@sModelNumber)+SizeOf(sModelNumber))^ := #0;
    Result := PChar(@sModelNumber);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption:=GetIdeModelNumber(0);
end;
P.S. Код прекрасно работает на всех операционных 32/64-разрядных системах архитектуры NT - Windows XP, Windows 7, Windows 10. Не требует драйвера. Эксплуатирую данный код уже более десяти лет.

Последний раз редактировалось Комиссар Катани; 13.01.2019 в 16:09. Причина: Добавлен P.S.
Комиссар Катани вне форума Ответить с цитированием
Старый 13.01.2019, 16:01   #13
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от R71MT Посмотреть сообщение
IDE
Скорее всего у автора в HKEY_LOCAL_MACHINE\SYSTEM\CurrentCo ntrolSet\Enum\SCSI если не сильно древнее.



И 1 USB HDD у меня там же (причем он отключен сейчас). А другой и флешки нет.

В общем самый простой и надежный вариант — WMI.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 13.01.2019 в 16:06.
Alex11223 вне форума Ответить с цитированием
Старый 13.01.2019, 18:29   #14
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
В общем самый простой и надежный вариант — WMI.
согласен, ..ведь зачем метровые портянки кода,
когда можно просто вызвать такой батник, и он сам скинет в txt-файл любые данные о диске (здесь только имя и кол-во разделов):
Код:
@echo off
wmic  /Output:DiskName.txt DiskDrive get caption,partitions /format:list
Цитата:
Сообщение от Комиссар Катани Посмотреть сообщение
Не требует драйвера.
..а только запрашивает у этого драйвера CTL_code SMART_RCV_DRIVE_DATA
под номером 0x0007c088. Тоже вариант.. только громоздкий-уж слишком.
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 13.01.2019, 19:32   #15
NetSpace
Участник клуба
 
Аватар для NetSpace
 
Регистрация: 03.06.2009
Сообщений: 1,792
По умолчанию

вот тут проект консольного приложения. выводит информацию о ваших дисках
Вложения
Тип файла: txt Новый текстовый документ.txt (13.6 Кб, 125 просмотров)
Программирование - это единственный способ заставить компьютер делать то, что тебе хочется, а не то, что приходится.
NetSpace вне форума Ответить с цитированием
Старый 14.01.2019, 01:42   #16
falsebegin
Форумчанин
 
Регистрация: 23.11.2016
Сообщений: 100
По умолчанию

пытался поставить эту функицию function GetIdeModelNumber(HDDIndx: Byte) : String; и ругается может что то надо ставить в uses? и статье я пользуюсь Embarcadero RAD Studio XE7


Код:
begin
 if SysUtils.Win32Platform=VER_PLATFORM_WIN32_NT then // Windows NT, Windows 2000
    begin
      // warning! change name for other drives: ex.: second drive '\\.\PhysicalDrive1\'

Последний раз редактировалось falsebegin; 14.01.2019 в 01:45.
falsebegin вне форума Ответить с цитированием
Старый 14.01.2019, 01:49   #17
falsebegin
Форумчанин
 
Регистрация: 23.11.2016
Сообщений: 100
По умолчанию

а вот за батник спасибо если не найду другое решение то ставлю его
falsebegin вне форума Ответить с цитированием
Старый 14.01.2019, 05:30   #18
falsebegin
Форумчанин
 
Регистрация: 23.11.2016
Сообщений: 100
По умолчанию

вопрос насчет батника можно ли убрать или как то скрыть Caption= и Partitions=1 ?

Код:
Caption=ATA WDC WD10PURX-64E SCSI Disk Device
Partitions=1
falsebegin вне форума Ответить с цитированием
Старый 14.01.2019, 08:56   #19
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от falsebegin Посмотреть сообщение
можно ли убрать или как то скрыть
вместо /format:list задай /format:table, т.е.
Код:
@echo off
wmic  /Output:DiskName.txt DiskDrive get caption,partitions /format:table
если вывести справку по "DiskDrive", то можно получить список свойств,
которые выводит WMI о диске (помимо имени и кол-ва разделов).
указывай их в батнике через запятую, после GET:
Код:
c:\wmic
wmic:root\cli>diskdrive get/?
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 14.01.2019, 19:47   #20
Комиссар Катани
Пользователь
 
Регистрация: 29.12.2012
Сообщений: 21
По умолчанию

Цитата:
Сообщение от falsebegin Посмотреть сообщение
пытался поставить эту функицию function GetIdeModelNumber(HDDIndx: Byte) : String; и ругается может что то надо ставить в uses? и статье я пользуюсь Embarcadero RAD XE7
Это проверка платформы Windows. Удалите условие if then else и просто вставьте
Код:
hDevice := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(HDDIndx)), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );
Комиссар Катани вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как в ubuntu отключить авто монтирование жестких дисков? youknow Linux (Ubuntu, Debian, Red Hat, CentOS, Mint) 3 17.07.2017 13:54
ребята, может кто делал, или знает как описать унимодальную фукнцию Alenka63 Microsoft Office Excel 2 14.10.2016 15:25
Как получить список жестких дисков? Glaciuse Win Api 10 06.02.2014 15:07
Получить имена физических дисков. Ant-kul C# (си шарп) 2 16.12.2012 15:08
Как извлечь музыку из файла или может кто знает, что играет? Marsel737 Свободное общение 13 16.08.2011 20:53