OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 06 Октябрь, 2024 23:41

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
 Заголовок сообщения: Как узнать серийный номер диска?
СообщениеДобавлено: Суббота, 07 Сентябрь, 2024 06:39 

Зарегистрирован: Воскресенье, 06 Август, 2017 19:33
Сообщения: 95
Доброго времени суток. Подскажите, как при помощи WinApi.DeviceIoControl узнать серийный номер диска?

Получаю дескриптор устройства
Код:
VAR
   hDevice, procHeap3: WinApi.HANDLE;
   lpFileName: WinApi.PtrWSTR;
   p3: WinApi.PtrVoid;
   myType1, myType2: MyType;
BEGIN
   procHeap3 := WinApi.GetProcessHeap();
   p3 := WinApi.HeapAlloc (procHeap3, {}, 19* SIZE(CHAR));
   SYSTEM.PUT (SYSTEM.ADR (lpFileName), p3);
   lpFileName[0] := "\";
   lpFileName[1] := "\";
   lpFileName[2] := ".";
   lpFileName[3] := "\";
   lpFileName[4] := "P";
   lpFileName[5] := "h";
   lpFileName[6] := "y";
   lpFileName[7] := "s";
   lpFileName[8] := "i";
   lpFileName[9] := "c";
   lpFileName[10] := "a";
   lpFileName[11] := "l";
   lpFileName[12] := "D";
   lpFileName[13] := "r";
   lpFileName[14] := "i";
   lpFileName[15] := "v";
   lpFileName[16] := "e";
   lpFileName[17] := "0";
   lpFileName[18] := 0X;
   hDevice := WinApi.CreateFileW (lpFileName, {}, WinApi.FILE_SHARE_WRITE, NIL,  WinApi.OPEN_EXISTING, {}, 0);
   IF hDevice # WinApi.INVALID_HANDLE_VALUE THEN
      ???
   ELSE
      StdLog.String ("Ошибка при получении дескриптора файла")
   END

Вроде не ругается, а как дальше применить WinApi.DeviceIoControl - не знаю, а именно: что указать в коде управления операции (dwIoControlCode) и как работать с lpInBuffer, lpOutBuffer: PtrVoid?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 07 Сентябрь, 2024 15:36 
Аватара пользователя

Зарегистрирован: Воскресенье, 09 Декабрь, 2018 15:14
Сообщения: 124
Откуда: Equestria
1. Особенности использования winapi не совсем по тематике форума. Надо гуглить самому.
Первая попавшаяся ссылка в гугуле https://stackoverflow.com/questions/48250004/how-to-get-a-serial-number-of-a-windows-disk

2. Биндинги к winapi в блэкбоке устаревшие и/или не полные. Всякую экзотику надо самому расковыривать из заголовков для сишки.
Иногда константы в заголовках очень запутано объявляются. Можно на godbolt побыстрому посмотреть что там на выходе.
Для надёжности лучше использовать компилятор x86 msvc (32 бит).
Код:
#include <windows.h>

void y(void) {
  int x = IOCTL_STORAGE_QUERY_PROPERTY;
}
Код:
        push    ebp
        mov     ebp, esp
        push    ecx
        mov     DWORD PTR _x$[ebp], 2954240             ; 002d1400H
        mov     esp, ebp
        pop     ebp
        ret     0
2954240 - интересующее нас число.

3. Пример программы.
Не уверен, правда, серийный номер чего оно выдаёт. Но какой-то выдаёт.
Обращаю внимание что используются структуры переменной размерности, возможно именно поэтому их нету в биндингах.
Код:
MODULE TestDisk;

   IMPORT SYSTEM, WinApi, StdLog;

   PROCEDURE Do*;
      CONST
         IOCTL_STORAGE_QUERY_PROPERTY = 2954240;
         StorageDeviceProperty = 0;
         PropertyStandardQuery = 0;

      TYPE
         STORAGE_PROPERTY_QUERY = RECORD [untagged]
            PropertyID, QueryType: INTEGER;
            AdditionalParameters: ARRAY 4 OF BYTE; (*variadic*)
         END;

         STORAGE_DEVICE_DESCRIPTOR = RECORD [untagged]
            Version, Size: INTEGER;
            DeviceType, DeviceTypeModifier: BYTE;
            RemovableMedia, CommandQueueing: BYTE;
            VendorIDOffset, ProductIDOffset, ProductRevisionOffset, SerialNumberOffset: INTEGER;
            BusType: INTEGER;
            RawPropertiesLength: INTEGER;
            RawDeviceProperties: ARRAY 4096 OF BYTE; (*variadic*)
         END;

      VAR
         handle: WinApi.HANDLE;
         spq: STORAGE_PROPERTY_QUERY;
         buf: STORAGE_DEVICE_DESCRIPTOR;
         str: WinApi.PtrSTR;
         ok: WinApi.BOOL;
         i, n: INTEGER;
   BEGIN
      handle := WinApi.CreateFileW ("\\.\C:", {}, WinApi.FILE_SHARE_WRITE, NIL, WinApi.OPEN_EXISTING, {}, 0);
      IF handle # WinApi.INVALID_HANDLE_VALUE THEN
         spq.PropertyID := StorageDeviceProperty;
         spq.QueryType := PropertyStandardQuery;
         FOR i := 0 TO LEN(spq.AdditionalParameters) - 1 DO (*clear just in case*)
            spq.AdditionalParameters[i] := 0;
         END;
         IF WinApi.DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, SYSTEM.ADR(spq), SIZE(STORAGE_PROPERTY_QUERY), SYSTEM.ADR(buf), SIZE(STORAGE_DEVICE_DESCRIPTOR), n, NIL) = WinApi.TRUE THEN
            IF buf.Version >= 40 THEN
               IF buf.Size <= SIZE(STORAGE_DEVICE_DESCRIPTOR) THEN
                  IF buf.SerialNumberOffset > 0 THEN
                     str := SYSTEM.VAL(WinApi.PtrSTR, SYSTEM.ADR(buf) + buf.SerialNumberOffset)
                  ELSE str := "<NOT AVAILABLE>"
                  END;
                  StdLog.String("Serial: "); StdLog.String(str$); StdLog.Ln
               ELSE StdLog.String("buffer too small"); StdLog.Ln
               END
            ELSE StdLog.String("unsupported version"); StdLog.Ln
            END
         ELSE StdLog.String("fail to get device properties"); StdLog.Ln
         END;
         ok := WinApi.CloseHandle(handle)
      ELSE StdLog.String("fail to open device"); StdLog.Ln
      END
   END Do;

END TestDisk.

^Q DevCompiler.CompileAndUnload
^Q TestDisk.Do


PS: Динамические строки и структуры, которые не сохраняются где-то внутри winapi, вполне можно передавать через обычный POINTER. А кучу (heap) процесса лучше не использовать - она используется самим блэкбоксом и однажды может стать плохо и не понятно отчего, по возможности лучше использовать статические объекты на стеке.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 08 Сентябрь, 2024 05:21 

Зарегистрирован: Воскресенье, 06 Август, 2017 19:33
Сообщения: 95
Очень благодарен за ответ.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 3 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB