Как узнать адрес PnP девайса

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Как узнать адрес PnP девайса

Сообщение claymen » 22.09.2008 (Пн) 13:59

Здравстуйте!
Мне необходимо узнавать адрес, который присвоила система PnP девайсу "Звуковая карта". Для однократного применения, это можно сделать с помощью многих системных утилит, но для постоянного использования, такие утилиты необходимо сначало установить в систему. Это долго и не всегда приемлемо. Скажите пож. можно ли узнавать адреса "Звуковой карты" с помощью API функций или msinfo.dll ? Я наю лишь то, что этих адресов 256 (например AC00-ACFF) Другие девайсы звуковой карты (Игровой порт и т.д.) меня не интересуют.
и начинали мы все чайниками, но потом...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как узнать адрес PnP девайса

Сообщение Хакер » 22.09.2008 (Пн) 14:09

Эээ... И что ты будешь с ними делать?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Re: Как узнать адрес PnP девайса

Сообщение claymen » 22.09.2008 (Пн) 14:16

Моя программа ничего с ними делать не будет. Она лишь передаст их другой программе в качестве параметра комм.строки
Мне интересно, способен бейсик на такие возможности или нет. Судя по тому, что MSINFO.EXE это делать умеет, а в VB есть MSINFO.DLL
я и предположил, что такое возможно. Но я не знаю как.
и начинали мы все чайниками, но потом...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как узнать адрес PnP девайса

Сообщение Хакер » 22.09.2008 (Пн) 14:29

Мне интересно, способен бейсик на такие возможности или нет.

Чертовски глупое предположение/утверждение. С какого такого язык должен иметь такие возможности? Ни один язык в мире таких возможностей не имеет.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Re: Как узнать адрес PnP девайса

Сообщение claymen » 22.09.2008 (Пн) 14:39

Не спорю. Но такое вообще возможно с помощью API или других средств ?
Если нет, то где в системе лежит эта информация о адресах, присвоенных PnP девайсам (реестр, фал) ?
Ведь MSINFO.EXE , ЭВЕРЕСТ и т.п. ее где-то берут...
и начинали мы все чайниками, но потом...

claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Re: Как узнать адрес PnP девайса

Сообщение claymen » 22.09.2008 (Пн) 17:17

Ладно. Кто может сказать мне точное название раздела MSInfo32, отвечающего за адрес PnP девайса "Звуковая карта" ?
Судя по дереву, предоставляемому программой MSInfo32, раздел называется "Память", но при попытке экспорта содержимого этого раздела
в файл результатов, сохраняется только раздел "Сведения о системе".
Экспорт делаю следующим образом:
Код: Выделить всё
    Dim obj As MSINFO32Lib.MSInfo
    Set obj = New MSINFO32Lib.MSInfo
    DoEvents
    obj.SaveFile "c:\results.txt", "myPCname", "Память"
    Set obj = Nothing

Что я делаю не так ?
и начинали мы все чайниками, но потом...

claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Re: Как узнать адрес PnP девайса

Сообщение claymen » 23.09.2008 (Вт) 3:52

Ладно. Я нашел ветку реестра, отвечающую за это, но не знаю как прочитать от туда нужное.
Вот пример на С. Помогите пож-то переделать его на VB:
Код: Выделить всё
#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 );
}
и начинали мы все чайниками, но потом...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как узнать адрес PnP девайса

Сообщение Хакер » 23.09.2008 (Вт) 16:18

Чего тут переводить-то? Здесь нет ничего Си-специфичного, всё прозрачно переводится на VB.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Re: Как узнать адрес PnP девайса

Сообщение claymen » 23.09.2008 (Вт) 17:28

Если бы это было для меня не так "Си специфично" - я бы не просил о помощи.
Если тебе так хочется показать свое знание языка Си, то делай это не таким образом.
Я не сомневаюсь в твоей компитенции и профессионализмне, но это все же раздел соответствующий, а не "Для проффи".

Обращаюсь к другим пользователям этого форума. Помогите пож-то переделать этот код под VB!
и начинали мы все чайниками, но потом...

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Как узнать адрес PnP девайса

Сообщение Antonariy » 23.09.2008 (Вт) 21:02

Здесь нет ничего Си-специфичного

А это? По-моему вполне специфичненько. Такой конструкции я даже пока не встречал в сишных исходниках.
Код: Выделить всё
typedef struct _IDDATA
{
   unsigned char Type; // тип возвращаемых данных
   …
   // общая область памяти
   union
   {
      struct // обработка портов ввода-вывода
      {
         …
      } Port;
      struct // обработка номера прерывания
      {
         …
      } IRQ;
      struct // обработка адресов в памяти
      {
         …
      } Memory;
      …
   } u;
} IDDATA, *PIDDATA;

Хотя логически поразмыслив, можно предположить, что оно переведется так:
Код: Выделить всё
Type Port
Type IRQ
Type Memory

Type IDDATA
    Type As Byte
    …
    Port As Port
    IRQ As IRQ
    Memory As Memory
    …
End Type
Лучший способ понять что-то самому — объяснить это другому.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как узнать адрес PnP девайса

Сообщение Хакер » 23.09.2008 (Вт) 21:13

Мне хочется показать тебе, что крайне глупо просить сделать перевод, который можно сделать банальным Replace-ом по рягулярному выраждению.

Не нужно быть профессионалом, чтобы догадаться заменить if(a) b(c) на if a then b(c). У программиста должна быть, как бы это скахать, инженерная находчивость, что-ли. Если тебе не очевидно, что все if-ы можно заменить таким же образом, что все for-ы и все while и все switch-и можно заменить на аналогичные VB-шные конструкции.

Допустим, я соглашусь, что в VB нет альтернативы #define. Но ведь абсолютно везде здесь #define служит для определения констант. Которые можно объявить как константы в VB. В чём проблема, я не понимаю? Часто бывает куча макросов, которые нужно расскрывать ручками, что вызывает кучу проблем при переводе. Но здесь-то этого нет?

А причина проста — лень напрячь мозг чуть-чуть силнее, чем обычно. Хочется, чтобы кто-нибудь сам потратил свое время на неителлектуальный перевод.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Как узнать адрес PnP девайса

Сообщение ANDLL » 23.09.2008 (Вт) 21:13

Antonariy писал(а):Хотя логически поразмыслив, можно предположить, что оно переведется так:
Нет
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как узнать адрес PnP девайса

Сообщение Хакер » 23.09.2008 (Вт) 21:15

Antonariy
Нет, надо просто объявить N разных вариантов UDT, раскрыв в каждом UDT свой член юниона. Или объявить универсальный UDT.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Re: Как узнать адрес PnP девайса

Сообщение Antonariy » 23.09.2008 (Вт) 21:16

ANDLL писал(а):
Antonariy писал(а):Хотя логически поразмыслив, можно предположить, что оно переведется так:
Нет
Значит это не просто специфичненько, а вполне так себе уверенно специфично. :wink:
Лучший способ понять что-то самому — объяснить это другому.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Как узнать адрес PnP девайса

Сообщение ANDLL » 23.09.2008 (Вт) 21:35

Antonariy писал(а):
ANDLL писал(а):
Antonariy писал(а):Хотя логически поразмыслив, можно предположить, что оно переведется так:
Нет
Значит это не просто специфичненько, а вполне так себе уверенно специфично. :wink:
Ясное дело, что специфично. А ты хакеру поверил?)
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как узнать адрес PnP девайса

Сообщение Хакер » 23.09.2008 (Вт) 22:24

Просто ты странно как-то логически поразмыслил — у тебя, получается, структура будет одинаковой что с юнионом, что без него.

Юнион, конечно, более Си-спефифичен, но вполне переводим.

А есть действительно Си-специфичные вещи, например циклы for, не совпадающие по смыслу с примитивными vb-шными For-ами, например такой:
Код: Выделить всё
for(PTOKENRECORD i = TkSq.Begin; i != TkSq.End+1 ; ((i->TokenID == T_TRANSITION) ? i = (PTOKENRECORD)i->TokenDataBegin : i++))


Или, автор бы умер от горя, если бы ему встретился такой макрос:
Код: Выделить всё
#define X86_DEF_OPCODE(fist_byte, second_byte) (WORD)(0x##fist_byte + (((sizeof(""#second_byte"")-1) == 0 ? 0: 0x0##second_byte) << 8)), (BYTE)((sizeof(""#second_byte"")-1) == 0)
#define X86_DEF_INSTRUCTION(mnemo,               \
                     opcode_first,         \
                     opcode_second,         \
                     opcode_extension,      \
                     operand1,            \
                     operand2,            \
                     operand3)            \
                     {                  \
                        X86_I_##mnemo,      \
                        X86_DEF_OPCODE(opcode_first, opcode_second), \
                        ((sizeof(""#opcode_extension"")-1) == 0 ? 0xFF : (BYTE)0##opcode_extension),\
                        0,               \
                        ((sizeof(""#operand1"")-1) != 0) + ((sizeof(""#operand2"")-1) != 0) + ((sizeof(""#operand3"")-1) != 0), \
                        #mnemo, \
                        {((sizeof(""#operand1"")-1) != 0 ? X86_ASM_OPERAND_TYPEMASK_##operand1 : 0),\
                         ((sizeof(""#operand2"")-1) != 0 ? X86_ASM_OPERAND_TYPEMASK_##operand2 : 0),\
                         ((sizeof(""#operand3"")-1) != 0 ? X86_ASM_OPERAND_TYPEMASK_##operand3 : 0)\
                        }                  \
                     }


который бы использовался для прединициализации глобального массива структур.

Никакой прединициализации в VB нет, поэтому пришлось бы как-то заполнять всю структуру в рантайме, при том, фигурно-скобочной записи представления структуры тоже нет, так что пришлось бы присваивать значение каждому члену струткруы в отдельности. При этом, макросов у нас тоже нет. Здесь фишка в том, что у макроса некоторые параметры могут быть неуказаны. Макрос сам как-бы подсчитывает, сколько из последних трёх его параметров указано, и заносит это число в структуру. В VB об этом даже мечтать не стоит. Макрос сам превращает последовательность байтов (может быть из одного байта, а может быть из двух) в правильное WORD-значение, записав которое в нужное место там окажется нужная последовательность. Одновременно макрос записывает в структуру длину последовательности байтов. Макрос сам превратит ABCD в строчку "ABCD" и засунет её в некоторое поле структуры. А вдругое поле структуры подставит значение константы FOO_FOO_FOO_ABCD. В VB это немыслимо, для того чтобы получить в памяти нужный массив надо написать огромный инициализирующий код, кроме того, поскольку таких элементов в массиве около 800, то нужно перед этим написать автоматический конвертор, раскрывающий макрос, а затем превращающий всё это в VB-шный код.

Вот это сложно, и если бы появился такой код с пометкой "Помогите перевести", я бы слова ни сказал и помог перевести. А здесь — всё элементарно, и проблема только с одним — с ленью автора.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Re: Как узнать адрес PnP девайса

Сообщение claymen » 24.09.2008 (Ср) 3:50

Тупик ... Одни дебаты о Си :(
и начинали мы все чайниками, но потом...

mc-colins
Начинающий
Начинающий
 
Сообщения: 13
Зарегистрирован: 04.10.2008 (Сб) 20:12

Re: Как узнать адрес PnP девайса

Сообщение mc-colins » 08.10.2008 (Ср) 22:01

Используй WMI
Код: Выделить всё
On Error Resume Next
Set objService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
If Err.Number <> 0 Then
    End
End If
For Each pnpObject In objService.ExecQuery("SELECT * FROM Win32_DeviceMemoryAddress")
    pnpObject.Caption 'Описание 1
    pnpObject.Description 'Описание 2
    pnpObject.StartingAddress 'Начальный адрес
    pnpObject.EndingAddress 'Конечный адрес
Next

claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Re: Как узнать адрес PnP девайса

Сообщение claymen » 09.10.2008 (Чт) 13:55

и как я должен распознать среди идентификаторов, нужные мне диапазоны адресов ?
и начинали мы все чайниками, но потом...

claymen
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 159
Зарегистрирован: 14.04.2006 (Пт) 16:07
Откуда: КЫРГЫЗСТАН г.Бишкек

Re: Как узнать адрес PnP девайса

Сообщение claymen » 09.10.2008 (Чт) 14:47

загрузил я инфу о всех аудио девайсах и адресах pnp, а толку то ?
все девайсы идут под идентификаторами, а какой из них соотвествует нужному адресу ?
Код: Выделить всё
Devices.Nodes.Clear
Devices.Nodes.Add , 0, "Devices", "Звуковые устройства"
Devices.Nodes.Add , 0, "PnP", "PnP устройства"
Set objService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
AudVol = 1
For Each objSound In objService.ExecQuery("SELECT * FROM Win32_SoundDevice")
    DoEvents
    nodeDo = Devices.Nodes.Add("Devices", 4, "SoundDev" + Trim(Str(AudVol)), objSound.Caption)
    Devices.Nodes.Item("Devices").Expanded = True
    nodeDo = Devices.Nodes.Add("SoundDev" + Trim(Str(AudVol)), 4, "SoundInfo" + Trim(Str(AudVol)), "Наименование: " & objSound.Description)
    nodeDo = Devices.Nodes.Add("SoundDev" + Trim(Str(AudVol)), 4, "SoundAuthor" + Trim(Str(AudVol)), "Производитель: " & objSound.Manufacturer)
    nodeDo = Devices.Nodes.Add("SoundDev" + Trim(Str(AudVol)), 4, "SoundIdent" + Trim(Str(AudVol)), "Идентификатор: " & objSound.DeviceID)
    AudVol = AudVol + 1
Next
PnPVol = 1
For Each objSound In objService.ExecQuery("SELECT * FROM Win32_DeviceMemoryAddress")
    DoEvents
    nodeDo = Devices.Nodes.Add("PnP", 4, "PnPDev" + Trim(Str(PnPVol)), objSound.Caption)
    Devices.Nodes.Item("PnP").Expanded = True
    nodeDo = Devices.Nodes.Add("PnPDev" + Trim(Str(PnPVol)), 4, "PnPInfo" + Trim(Str(PnPVol)), "Описание: " & objSound.Description)
    nodeDo = Devices.Nodes.Add("PnPDev" + Trim(Str(PnPVol)), 4, "PnPAddressBegin" + Trim(Str(PnPVol)), "Начальный адрес: " & objSound.StartingAddress)
    nodeDo = Devices.Nodes.Add("PnPDev" + Trim(Str(PnPVol)), 4, "PnPAddressEnd" + Trim(Str(PnPVol)), "Конечный адрес: " & objSound.EndingAddress)
    PnPVol = PnPVol + 1
Next

моя звуковая имеет адресацию "0xDCF8000-0xDCFBFFF", а ее идентификатор "PCI\VEN_8086&DEV_27D8&SUBSYS_817F1043&REV_01\3&11583659&0&D8"
и как мне выбрать из 2 десятков адресаций мою звуковую карту ?
в ее описание входит только следующее:
Код: Выделить всё
Описание: 0xDCF8000-0xDCFBFFF
Начальный адрес: 3721363456
Конечный адрес: 3721379839

судя по описателю, то это адреса из ресурсов, выделенных под звуковую карту. а что делать с начальным и конечным адресами
да и вообще, как их отыскать из двух десятков других описателей ?
и начинали мы все чайниками, но потом...


Вернуться в Visual Basic 1–6

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22

    TopList