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

  • Автор темы corsair
  • Дата начала
Статус
Закрыто для дальнейших ответов.
C

corsair

Гость
#1
Нужно узнать информацию о железе компьютера - серийник материнки, биоса, видюхи и т.п.
Сразу говорю - не для защиты от копирования, так что на эту тему просьба не флудить.
Информация о физических и логических дисках, 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.

}

//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////
 
Q

quest

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