Здравствуйте! Подскажите пож-то, где в системе Windows хранятся адреса PnP девайсов назначенных системой. Пробовал отследить обращения к реестру программы MSInfo32.exe , но безуспешно. А ведь программа где-то их берет.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum стр34, 42... Несвижский 2-е изд вот пример оттуда (1_14.cpp) Code (Text): // Определение основных параметров устройств в Windows NT/2000/XP/SR3/Vista #include "stdafx.h" // путь к разделу в реестре, описывающему установленное оборудование #define HKLM_ENUM_NT "SYSTEM\\CurrentControlSet\\Enum" #define MAX_DEVICES 200 // возможное количество устройств в системе // дополнительные флаги #define PORT_MEMORY 0x0000 // адрес порта в памяти #define PORT_IO 0x0001 // адрес порта ввода-вывода #define MEMORY_READ_WRITE 0x0000 // память для записи и чтения #define MEMORY_READ_ONLY 0x0001 // память только для чтения #define MEMORY_WRITE_ONLY 0x0002 // память только для записи // тип канала DMA #define DMA_8 0x0000 #define DMA_16 0x0001 #define DMA_32 0x0002 // типы данных enum DataTypesNT { Port_Type = 1, // адрес порта ввода-вывода IRQ_Type = 2, // номер прерывания Memory_Type = 3, // адрес в памяти DMA_Type = 4, // номер канала DMA BusNumber_Type = 6 // номер шины }; // определяем тип значения для хранения адресов typedef LARGE_INTEGER PHYSICAL_ADDRESS; // определяем структуры для описания данных #pragma pack ( 4 ) typedef struct _IDDATA { unsigned char Type; // тип возвращаемых данных unsigned char Share; // общий доступ к данным unsigned short Flags; // дополнительный флаг описания // общая область памяти union { struct // обработка портов ввода-вывода { PHYSICAL_ADDRESS Start; // базовый адрес unsigned long Length; // ширина порта } Port; struct // обработка номера прерывания { unsigned long Level; // уровень доступа unsigned long Number; // номер выделенного прерывания unsigned long Reserved; // резерв } IRQ; struct // обработка адресов в памяти { PHYSICAL_ADDRESS Start; // базовый адрес unsigned long Length; // ширина адресного пространства } Memory; struct { unsigned long Channel; // номер выделенного канала DMA unsigned long Port; // номер порта unsigned long Reserved; // резерв } DMA; struct // обработка номера шины { unsigned long Start; // базовый адрес шины unsigned long Length; // ширина адресного пространства unsigned long Reserved; // резерв } BusNumber; } u; } IDDATA, *PIDDATA; #pragma pack ( ) typedef struct _DATA_LIST { unsigned short Version; // номер версии unsigned short Revision; // дополнительный номер версии unsigned long Count; // полное количество данных об устройстве IDDATA Id[16]; // массив структур для получения данных } DATA_LIST, *PDATA_LIST; typedef struct _DATA_LIST_ALL { DWORD Reserved; // резерв unsigned long Reserved2; // резерв DATA_LIST DataList; // структура DATA_LIST } DATA_LIST_ALL, *PDATA_LIST_ALL; typedef struct _DATA { unsigned long Count; // количество найденных описателей устройства DATA_LIST_ALL All_List[2]; // массив структур DATA_LIST_ALL } DATA, *PDATA; // основная структура описателя устройства typedef struct _DeviceParamNT { char DeviceDesc[100]; // текстовое описание устройства char FriendlyName[80]; // дополнительное описание устройства char Class[50]; // имя класса устройства PHYSICAL_ADDRESS Base_Memory[16]; // базовые адреса в памяти PHYSICAL_ADDRESS End_Memory[16]; // завершающие адреса в памяти unsigned short TypeBaseMemory[16]; // тип адреса в памяти PHYSICAL_ADDRESS Base_Port[16]; // базовый порт ввода-вывода PHYSICAL_ADDRESS End_Port[16]; // завершающий порт ввода-вывода unsigned short TypeBasePort[16]; // тип порта ввода-вывода BYTE DMA_Channel[8]; // номер выделенного канала DMA unsigned short TypeDMA[8]; // тип канала DMA BYTE IRQ_Number[16]; // номер выделенного прерывания unsigned int BusNumber[8]; // номер шины для некоторых типов устройств } DEVICEPARAMSNT, *PDEVICEPARAMSNT; // определяем функцию поиска устройств в реестре void GetDevicesConfig_NT ( ); // массив структур DEVICEPARAMSNT для описания устройств DEVICEPARAMSNT devices_NT[MAX_DEVICES]; // реализация функции void GetDevicesConfig_NT ( ) { // объявляем переменные HKEY phKey = NULL, phKey2 = NULL, phKey3 = NULL, phKey4 = NULL, phKey5 = NULL; // дескрипторы разделов реестра // счетчики разделов и размеры значений параметров в реестре DWORD dwKey = 0, dwKey2 = 0, dwKey3 = 0, dwSize = 0, cbName = 256; // счетчики данных unsigned int uPort_index = 0, uIRQ_index = 0, uMemory_index = 0, uDMA_index = 0, uBus_index = 0; // счетчик найденных устройств unsigned int uIndex = 0; // различные пути в реестре char section_name[513]; char new_path[MAX_PATH]; char new_path2[MAX_PATH]; char new_path3[MAX_PATH]; char new_path4[MAX_PATH]; char new_path5[MAX_PATH]; // буфер для данных char hard_key[150]; // структура для получения данных об устройстве DATA cfg; // обнуляем структуру перед использованием for ( i = 0; i < 200; i++ ) ZeroMemory ( &devicesNT[i], sizeof ( DEVICEPARAMSNT ) ); // открываем раздел реестра для перечисления подразделов if ( !RegOpenKeyEx ( HKEY_LOCAL_MACHINE, HKLM_ENUM_NT, 0, KEY_READ, &phKey ) == ERROR_SUCCESS ) return; while ( 1 ) { // определяем размер значения cbName = 256; // перечисляем подразделы в открытом разделе if ( RegEnumKeyEx ( phKey, dwKey, section_name, &cbName, NULL, NULL, NULL, NULL ) == ERROR_NO_MORE_ITEMS ) break; // выходим из цикла, если все подразделы получены // собираем путь для доступа к вложенному разделу strcpy ( new_path, "" ); strcpy ( new_path, HKLM_ENUM_NT ); strcat ( new_path, "\\" ); strcat ( new_path, section_name ); // открываем вложенный раздел if ( RegOpenKeyEx ( HKEY_LOCAL_MACHINE, new_path, 0, KEY_READ, &phKey2 ) == ERROR_SUCCESS ) { // сбрасываем счетчик dwKey2 = 0; while ( 1 ) { // определяем размер значения cbName = 256; // перечисляем подразделы в открытом разделе if ( RegEnumKeyEx ( phKey2, dwKey2, new_path2, &cbName, NULL, NULL, NULL, NULL ) == ERROR_NO_MORE_ITEMS ) break; // выходим из цикла, если все подразделы получены // собираем путь для доступа к вложенному разделу strcpy ( new_path3, "" ); strcpy ( new_path3, new_path ); strcat ( new_path3, "\\" ); strcat ( new_path3, new_path2 ); // открываем вложенный раздел if ( RegOpenKeyEx ( HKEY_LOCAL_MACHINE, new_path3, 0, KEY_READ, &phKey3 ) == ERROR_SUCCESS ) { // сбрасываем счетчик dwKey3 = 0; while ( 1 ) { // определяем размер значения cbName = 256; if ( RegEnumKeyEx ( phKey3, dwKey3, new_path4, &cbName, NULL, NULL, NULL, NULL ) == ERROR_NO_MORE_ITEMS ) break; // выходим из цикла // собираем путь для доступа к вложенному разделу strcpy ( new_path5, "" ); strcpy ( new_path5, new_path3 ); strcat ( new_path5, "\\" ); strcat ( new_path5, new_path4 ); // открываем вложенный раздел if(RegOpenKeyEx ( HKEY_LOCAL_MACHINE, new_path5, 0, KEY_READ, &phKey4 ) == ERROR_SUCCESS ) { dwSize = 150; // размер данных // получаем описание устройства RegQueryValueEx ( phKey4, "DeviceDesc", NULL, NULL, ( LPBYTE ) hard_key, &dwSize ); // сохраняем в основную структуру strcpy ( devicesNT[uIndex].DeviceDesc, hard_key ); strcpy ( hard_key, "" ); // получаем имя класса устройства dwSize = 50; RegQueryValueEx ( phKey4, "Class", NULL, NULL, ( LPBYTE ) hard_key, &dwSize ); strcpy ( devicesNT[uIndex].Class, hard_key ); strcpy ( hard_key, "" ); // получаем дополнительное описание устройства dwSize = 80; RegQueryValueEx ( phKey4, "FriendlyName", NULL, NULL, ( LPBYTE ) hard_key, &dwSize ); strcpy ( devicesNT[uIndex].FriendlyName , hard_key ); strcpy ( hard_key, "" ); // собираем путь для доступа // основным параметрам устройства strcat ( new_path5, "\\Control" ); // Windows 2000/XP/SR3 // strcat ( new_path5, "\\LogConf" ); // Windows NT // открываем раздел реестра if ( RegOpenKeyEx ( HKEY_LOCAL_MACHINE, new_path5, 0, KEY_READ, &phKey5 ) == ERROR_SUCCESS ) { dwSize = sizeof ( DATA ); // определяем размер данных // обнуляем структуру данных ZeroMemory ( &cfg, sizeof ( DATA ) ); // получаем данные из реестра RegQueryValueEx ( phKey5, "AllocConfig", NULL, NULL, ( LPBYTE ) &cfg, &dwSize ); // определяем количество описателей устройства for ( int i = 0; i < cfg.Count; i++ ) { for ( int j = 0; j < cfg.All_List[i].DataList.Count; j++ ) { // определяем тип данных switch ( cfg.All_List[i].DataList.Id[j].Type ) { case Port_Type: // порт ввода-вывода // получаем базовый порт devicesNT[uIndex].Base_Port[uPort_index] = cfg.All_List[i].DataList.Id[j].u.Port.Start; // получаем завершающий порт devicesNT[uIndex].End_Port[uPort_index].LowPart = cfg.All_List[i].DataList.Id[j].u.Port.Start.LowPart + cfg.All_List[i].DataList.Id[j].u.Port.Length - 1; // получаем тип порта ввода-вывода if ( cfg.All_List[i].DataList.Id[j].Flags & PORT_MEMORY ) devicesNT[uIndex].TypeBasePort[uPort_index] = PORT_MEMORY; else if ( cfg.All_List[i].DataList.Id[j].Flags & PORT_IO ) devicesNT[uIndex].TypeBasePort[uPort_index] = PORT_IO; // увеличиваем счетчик uPort_index++; break; case IRQ_Type: // номер прерывания devicesNT[uIndex].IRQ_Number[uIRQ_index] = cfg.All_List[i].DataList.Id[j].u.IRQ.Number; uIRQ_index++; break; case Memory_Type: // адреса в памяти // получаем базовый адрес devicesNT[uIndex].Base_Memory[uMemory_index] = cfg.All_List[i].DataList.Id[j].u.Memory.Start; // получаем завершающий адрес devicesNT[uIndex].End_Memory[uMemory_index].LowPart = cfg.All_List[i].DataList.Id[j].u.Memory.Start.LowPart + cfg.All_List[i].DataList.Id[j].u.Memory.Length - 1; // определяем тип памяти if ( cfg.All_List[i].DataList.Id[j].Flags & MEMORY_READ_WRITE ) devicesNT[uIndex].TypeBaseMemory[uPort_index] = MEMORY_READ_WRITE; else if ( cfg.All_List[i].DataList.Id[j].Flags & MEMORY_READ_ONLY ) devicesNT[uIndex].TypeBaseMemory[uPort_index] = MEMORY_READ_ONLY; devicesNT[uIndex].TypeBaseMemory[uPort_index] = MEMORY_READ_ONLY; devicesNT[uIndex].TypeBaseMemory[uPort_index] = MEMORY_WRITE_ONLY; uMemory_index++; break; case DMA_Type: // номер канала DMA // получаем номер канала devicesNT[uIndex].DMA_Channel[uDMA_index] = cfg.All_List[i].DataList.Id[j].u.DMA.Channel; // определяем тип канала if ( cfg.All_List[i].DataList.Id[j].Flags & DMA_8 ) devicesNT[uIndex].TypeDMA[uPort_index] = DMA_8; else if ( cfg.All_List[i].DataList.Id[j].Flags & DMA_16 ) devicesNT[uIndex].TypeDMA[uPort_index] = DMA_16; else if ( cfg.All_List[i].DataList.Id[j].Flags & DMA_32 ) devicesNT[uIndex].TypeDMA[uPort_index] = DMA_32; uDMA_index++; break; case BusNumber_Type: // тип шины devicesNT[uIndex].BusNumber[uBus_index] = cfg.All_List[i].DataList.Id[j].u.BusNumber.Start; break; } } } // закрываем раздел и обнуляем счетчики if ( phKey5 ) RegCloseKey ( phKey5 ); uPort_index = 0; uIRQ_index = 0; uMemory_index = 0; uDMA_index = 0; uBus_index = 0; } // закрываем вложенный раздел if ( phKey4 ) RegCloseKey ( phKey4 ); // увеличиваем счетчик найденных устройств uIndex++; } // увеличиваем счетчик для поиска следующего подраздела dwKey3++; } // закрываем вложенный раздел if ( phKey3 ) RegCloseKey ( phKey3 ); } // увеличиваем счетчик для поиска следующего подраздела dwKey2++; } // закрываем вложенный раздел if ( phKey2 ) RegCloseKey ( phKey2 ); } // увеличиваем счетчик для получения следующего подраздела dwKey++; } // закрываем корневой раздел и выходим из функции if ( phKey ) RegCloseKey ( phKey ); }