Win Nt/2k/xp - информация о железе

Тема в разделе "MS Visual C++", создана пользователем corsair, 4 авг 2005.

Статус темы:
Закрыта.
  1. corsair

    corsair Гость

    Нужно узнать информацию о железе компьютера - серийник материнки, биоса, видюхи и т.п.
    Сразу говорю - не для защиты от копирования, так что на эту тему просьба не флудить.
    Информация о физических и логических дисках, MAC-адрес сетевухи - не надо.
    Перерыл весь инет - нифига толком не нашел.
    Когда юзаю WMI - то большинство информации о железе не выдается - вместо серийника материнки - пустая строка либо вообще вылетает эксепшн. Код для работы с WMI сам не писал - нашел в нете. Причем второй пример - с msdn.microsoft.com. Но оба примера работают одинаково. В общем задолбался уже с этим . Может кто скажет где глюк, или какой другой способ подскажете.

    1) //////////////////////////////////////////////////////////// /////////////////////////////////////////////////////

    //инициализация необходимых COM library для вызывающего потока
    HRESULT DoCoInitialize(DWORD dwCoInitApartModel)
    {
    //индикатор текущего состояния процесса
    HRESULT hres = S_FALSE;
    try
    {
    //инициализация необходимых COM library для вызывающего потока
    //с запросом организации необходимой модели аппартаментов
    //возможный возврат из функции - это указание на то что
    //The COM library is already initialized on the calling thread
    //или сообщение о том, что мы пытаемся поменять модель аппартаментов,
    //либо то что наш поток для которого мы вызываем CoInitializeEx принадлежит
    //к нейтральной модели. второе значение попадает в разряд FAILED
    hres = CoInitializeEx(0, dwCoInitApartModel);
    if (FAILED(hres)) throw _TEXT("failed to initialize COM library");

    //настройка защиты COM по умолчанию для всего процесса
    //если данная функция ни разу не вызвана, то берутся настройки по умолчанию из реестра
    //http://www.rsdn.ru/article/com/comsec.xml
    hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
    if (FAILED(hres)) throw _TEXT("failed to initialize security");
    }
    catch(...){}
    //function is completed successfully
    return hres;
    }

    //Windows Management Instrumentation (WMI) - технология, входящая в состав ядра Windows 2000
    //и предоставляющая доступ с помощью интерфейсов к объектам системы.
    //соединение с интересующим нас пространством имен WMI и получение интерфейса для доступа к его сервисам
    HRESULT DoConnectToWMINamespace(IN LPCTSTR _tcsMachineName, IN LPCTSTR _tcsUser, IN LPCTSTR _tcsPassword, OUT IWbemServices** ppSrvSvc)
    {
    //индикатор текущего состояния процесса
    HRESULT hres = E_NOINTERFACE;
    try
    {
    //проверка на отсутствие в необходимости дальнейших действий
    if(ppSrvSvc == NULL) throw _TEXT("bad pointer on the interface");
    //обнуляем значение указателя
    //того требует политика политкорректности и уважения к вызывающему
    *ppSrvSvc = NULL;

    //to create a connection to a WMI namespace
    //для того чтобы подсоединиться к интересующему нас пространству имён
    //необходимо получить интерфейс IWbemLocator
    //IWbemLocator со своим единственным единственный методом ConnectServer
    //позволит нашей клиентской программе получить с помощью интерфейса IWbemServices
    //доступ к объектам интересующего нас пространства имен WMI на необходимой нам машине
    CComPtr<IWbemLocator> pLoc;
    hres = CoCreateInstance(__uuidof(WbemLocator), 0, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pLoc);
    if (FAILED(hres)) throw _TEXT("failed to create IWbemLocator object");

    //формирование полного имени требуемого для подключения пространства имен
    _bstr_t bstrNetworkResource;
    if(_tcsMachineName != NULL) ((bstrNetworkResource += L"\\\\") += _tcsMachineName) += L"\\";
    bstrNetworkResource += L"root\\cimv2";

    //интерфейс, который предоставляет доступ к сервисам запрошенного протранства имен WMI
    //.......................................................... ........................
    //в контексте данной функции при данной организации кода не корректно напрямую работать
    //с переданным буффером под указатель, поэтому временный указатель здесь вполне оправдан
    CComPtr<IWbemServices> pSvc;

    //connect to WMI namespace through a call to the IWbemLocator::ConnectServer method
    //подключение к объектам интересующего нас пространства имен
    //.......................................................... ........................
    //strUser - A NULL value indicates the current security context.
    //If the user name is from a domain different from the current domain,
    //the string may contain the domain name and user name separated by a backslash.
    //.......................................................... ........................
    //strPassword - Pointer to a valid BSTR, which contains the user name you need for a connection.
    //A blank string "" specifies a valid zero-length password.
    //.......................................................... .......................
    //connect to the root\cimv2 namespace with the current user.
    if(_tcsUser == NULL || _tcsPassword == NULL)
    hres = pLoc->ConnectServer(bstrNetworkResource, NULL, NULL, 0, NULL, 0, 0, &pSvc);
    //connect to the root\cimv2 namespace using password and username.
    else
    hres = pLoc->ConnectServer(bstrNetworkResource, _bstr_t(_tcsUser), _bstr_t(_tcsPassword), 0, NULL, 0, 0, &pSvc);
    //could not connect
    if (FAILED(hres)) throw _TEXT("could not connect");

    //to set the security levels on a WMI connection
    //set the proxy so that impersonation of the client occurs.
    //http://www.rsdn.ru/article/com/comsec.xml
    //hres = CoSetProxyBlanket(*ppSrvSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
    //if (FAILED(hres)) throw _TEXT("could not set proxy blanket");

    //так будет правильнее даже с учетом того, что в дальнейшем мы здесь можем
    //напридумывать всего чего угодно и не хотелось бы при этом возвращаться к уже написанному
    //.......................................................... .......................
    //логическая передача прав использования объекта через указатель на его интерфейс
    (*ppSrvSvc) = pSvc;
    //мы знаем о существовании двух ситуаций развития событий:
    // - при исключительном развитии ситуации, мы должны быть уверены,
    // что освободим интерфейс, если не посщастливится использовать
    // его в дальнейшем и поэтому обертка для указателя здесь оправдана во всех отношениях
    // - при нормальном с нашей точки зрения развитии событий мы должны так сказать
    // передать права использования от одного указателя другому и зная что следует за деструктором
    // объекта из сгенерированного типа шаблоном class ATL::CComPtr<typename T>, после
    // непосредственной передачи адреса мы должны сказать COM что у нас появился еще один user pointer
    (*ppSrvSvc)->AddRef();
    }
    catch(...){}
    //function is completed successfully
    return hres;
    }

    //
    HRESULT GetBIOS_SerialNumber(OUT LPCTSTR _tcsSerial)
    {
    //индикатор текущего состояния процесса
    HRESULT hres = E_NOINTERFACE;
    try
    {
    //инициализация необходимых COM library для вызывающего потока
    hres = DoCoInitialize(COINIT_MULTITHREADED);
    if (FAILED(hres)) throw _TEXT("failed to initialize COM library");

    //интерфейс, который предоставит нам доступ
    //к сервисам интересующего нас протранства имен WMI
    CComPtr<IWbemServices> pSvc;

    //соединение с интересующим нас пространством имен WMI и получение интерфейса для доступа к его сервисам
    hres = DoConnectToWMINamespace(NULL, NULL, NULL, &pSvc);
    if (FAILED(hres)) throw _TEXT("could not connect");

    //дальше просто используем интерфейс IWbemServices для выполнения
    //необходимых нам запросов в пространстве имен WMI
    //................................................................................
    ......................

    //The IEnumWbemClassObject interface is used to enumerate
    //Common Information Model (CIM) objects and is similar to a standard COM enumerator
    CComPtr<IEnumWbemClassObject> penumClsObj;

    //формируем ассоциативный запрос основываясь на полученном DeviceID нашего LogicalDisk для получения
    //свойств объекта Win32_DiskPartition ассоциированным по так называемому ключу, cвойству объекта
    //к квалификацией key, c объектом Win32_LogicalDisk с помощью ассоциативного класса Win32_LogicalDiskToPartition

    _bstr_t bstrQuery = L"Win32_BIOS";

    //выполняем созданный нами запрос для получения интерфейса перечислителя полученных объектов
    hres = pSvc->CreateInstanceEnum(bstrQuery, WBEM_FLAG_SHALLOW|WBEM_FLAG_FORWARD_ONLY, NULL, &penumClsObj);
    if (FAILED(hres)) throw _TEXT("cannot be received class object enumerator");

    //интерфейс доступа к свойствам и методам
    //полученного в следствии запроса одиночного объекта
    CComPtr<IWbemClassObject> pClsObj;
    //количество объектов полученных вследствии запроса
    //которые можно перечислить с помощью интерфейса перечислителя
    unsigned long uNumOfInstances = 0;

    //получаем указатель на следующий объект с помощью метода IEnumWbemClassObject::Next
    //мы заранее знаем, что составляли запрос так, что у нас не может быть более одного объекта
    //поэтому вместо того, чтобы делать цикл для перечисления ограничимся одиночным вызовом
    if(WBEM_S_NO_ERROR != penumClsObj->Next(WBEM_INFINITE, 1, &pClsObj, &uNumOfInstances) || !uNumOfInstances)
    {throw _TEXT("attempt to receive object has failed");}

    //объект типа COM Variant для получения ключа DeviceID
    //используется для получения любых свойств объекта,
    //инкапсулирует идентификатор типа возвращаемого значения
    CComVariant _value;

    //метод для получения конечного свойства полученного объекта
    hres = pClsObj->Get(L"SerialNumber", 0, &_value, NULL, NULL);
    if (FAILED(hres) || (_value.vt != VT_BSTR))
    {throw _TEXT("attempt to receive access to properties of object has failed");}

    //освобождаем интерфейсы объекта и перечислителя
    //поскольку они уже не нужны и понадобятся нам далее
    //для выполнения последующих запросов
    pClsObj.Release();
    penumClsObj.Release();

    //копирование полученной информации в целевой буффер
    _tcscpy((TCHAR*)_tcsSerial, _bstr_t(_value.bstrVal));
    }
    catch(...){AfxMessageBox("ERRO R!");}

    //следующий шаг применим здесь только при одиночном использовании
    //приведенной выше функции. В остальных случаях инициализация и
    //и деининциализация COM выносятся в отдельные методы и применимы
    //к потокам а не в отдельности к каждой функции использующей механизмы COM

    //Closes the COM library on the current thread,
    //unloads all DLLs loaded by the thread, frees any
    //other resources that the thread maintains,
    //and forces all RPC connections on the thread to close.
    CoUninitialize();

    //function is completed successfully
    return hres;
    }

    //////////////////////////////////////////////////////////// /////////////////////////////////////////////////////

    2) // //////////////////////////////////////////////////////////// /////////////////////////////////////////////////////

    int GetWMIData()
    {
    HRESULT hres;

    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------

    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres))
    {
    //cout << "Failed to initialize COM library. Error code = 0x"
    // << hex << hres << endl;
    return 1; // Program has failed.
    }

    // Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------
    // Note: If you are using Windows 2000, you need to specify -
    // the default authentication credentials for a user by using
    // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
    // parameter of CoInitializeSecurity ------------------------

    hres = CoInitializeSecurity(
    NULL,
    -1, // COM authentication
    NULL, // Authentication services
    NULL, // Reserved
    RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
    RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
    NULL, // Authentication info
    EOAC_NONE, // Additional capabilities
    NULL // Reserved
    );


    if (FAILED(hres))
    {
    //cout << "Failed to initialize security. Error code = 0x"
    // << hex << hres << endl;
    CoUninitialize();
    return 1; // Program has failed.
    }

    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------

    IWbemLocator *pLoc = NULL;

    hres = CoCreateInstance(
    CLSID_WbemLocator,
    0,
    CLSCTX_INPROC_SERVER,
    IID_IWbemLocator, (LPVOID *) &pLoc);

    if (FAILED(hres))
    {
    //cout << "Failed to create IWbemLocator object."
    // << " Err code = 0x"
    // << hex << hres << endl;
    CoUninitialize();
    return 1; // Program has failed.
    }

    // Step 4: -----------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method

    IWbemServices *pSvc = NULL;

    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
    _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
    NULL, // User name. NULL = current user
    NULL, // User password. NULL = current
    0, // Locale. NULL indicates current
    NULL, // Security flags.
    0, // Authority (e.g. Kerberos)
    0, // Context object
    &pSvc // pointer to IWbemServices proxy
    );

    if (FAILED(hres))
    {
    //cout << "Could not connect. Error code = 0x"
    // << hex << hres << endl;
    pLoc->Release();
    CoUninitialize();
    return 1; &nbs p; // Program has failed.
    }

    //cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;


    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres = CoSetProxyBlanket(
    pSvc, // Indicates the proxy to set
    RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
    RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
    NULL, // Server principal name
    RPC_C_AUTHN_LEVEL_CALL, / / RPC_C_AUTHN_LEVEL_xxx
    RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
    NULL, // client identity
    EOAC_NONE // proxy capabilities
    );

    if (FAILED(hres))
    {
    //cout << "Could not set proxy blanket. Error code = 0x"
    // << hex << hres << endl;
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 1; &nbs p; // Program has failed.
    }

    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----

    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
    bstr_t("WQL"),
    bstr_t("SELECT * FROM Win32_BIOS"),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    NULL,
    &pEnumerator);

    if (FAILED(hres))
    {
    //cout << "Query for operating system name failed."
    // << " Error code = 0x"
    // << hex << hres << endl;
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 1; &nbs p; // Program has failed.
    }

    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------

    IWbemClassObject *pclsObj;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
    HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
    &pclsObj, &uReturn);

    if(0 == uReturn)
    {
    break;
    }

    VARIANT vtProp;
    VariantInit(&vtProp);

    // Get the value of the Name property
    hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
    //wcout << " OS Name : " << vtProp.bstrVal << endl;
    char str[200];
    _tcscpy((TCHAR*)str, _bstr_t(vtProp.bstrVal));
    //str.Format(_T(" OS Name %s"), _bstr_t(vtProp.bstrVal));
    VariantClear(&vtProp);
    }

    // Cleanup
    // ========

    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    pclsObj->Release();
    CoUninitialize();

    return 0; // Program successfully completed.

    }

    //////////////////////////////////////////////////////////// ////////////////////////////////////////////////////
     
  2. quest

    quest Гость

    Если через WMI взять не можешь , то больше ни как не возмешь. Могут взять только утилиты специально написанные под конкретную модель устройства , самим производителем или, нужно знать адреса и марку чип-глюка, что бы вообще с ними работать на низком уровне.
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей