COM, ATL

메인보드 정보 알아보기

디버그정 2009. 10. 4. 07:16
레지스트리 뒤져도 안나온다 했더니.... 컴포넌트 사용해서 구한다. 인터넷서 돌아다니면서 찾은거~~~




--------------------------------------------------------------------
* a.cpp
*-----------------------------------------------------------------------------
*
*-----------------------------------------------------------------------------
* All rights reserved by Rho Yong Hwan (fixbrain@gmail.com, unsorted@msn.com)
*-----------------------------------------------------------------------------
* Revision History:
* Date Who What
* ---------------- ---------------- ----------------
* 28.09.2007 Rho Yong Hwan birth
**---------------------------------------------------------------------------*/
#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif//_WIN32_DCOM

#include "stdafx.h"
#include <windows.h>
#include <crtdbg.h>

#include <wbemidl.h>
#pragma comment (lib, "wbemuuid.lib")
#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
#include <strsafe.h>
#pragma comment(lib, "strsafe.lib")

//
// types
//

typedef struct _MAIN_BOARD_INFO
{
TCHAR Manufacture[255];
TCHAR Serial[255];
} MAIN_BOARD_INFO, *PMAIN_BOARD_INFO;

//
// functions
//

int GetMainBoardInfo(PMAIN_BOARD_INFO mbi);
LPTSTR BSTR_to_TCHAR(IN const BSTR bstr);


/** ---------------------------------------------------------------------------
\brief

\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
int _tmain(int argc, _TCHAR* argv[])
{
//
// main board information
//
MAIN_BOARD_INFO mbi;
RtlZeroMemory(&mbi, sizeof(mbi));
if (0 != GetMainBoardInfo(&mbi))
{
_ftprintf(stderr, _T("%s\n"), _T("[*] error > GetMainBoardInfo() failed"));
return -1;
}

_ftprintf(stdout, _T("[*] main board information\n"), mbi.Serial);
_ftprintf(stdout, _T("manufacturer: %s\n"), mbi.Manufacture);
_ftprintf(stdout, _T("serial : %s\n"), mbi.Serial);

return 0;
}

/** ---------------------------------------------------------------------------
\brief

\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
int GetMainBoardInfo(PMAIN_BOARD_INFO mbi)
{
_ASSERTE(NULL != mbi);
_ASSERTE(TRUE != IsBadWritePtr(mbi, sizeof(MAIN_BOARD_INFO)));
if ((NULL == mbi) || (TRUE == IsBadWritePtr(mbi, sizeof(MAIN_BOARD_INFO))))
{
return -1;
}

HRESULT hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres))
{
return -1;
}

hres = CoInitializeSecurity(NULL, // not server
-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))
{
CoUninitialize();
return -1; // Program has failed.
}

int ret = -1;
IWbemLocator* locator = NULL;
IEnumWbemClassObject* enumerator = NULL;
IWbemServices* service = NULL;
IWbemClassObject* clsObj = NULL;

hres = CoCreateInstance(CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID *)&locator);
if (FAILED(hres))
{
CoUninitialize();
return -1; // Program has failed.
}

hres = locator->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
&service); // pointer to IWbemServices proxy
if (FAILED(hres))
{
ret = -1;
goto clean_up;
}

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



//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; // Program has failed.
//}

hres = service->ExecQuery(bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_BaseBoard"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&enumerator);
if (FAILED(hres))
{
ret = -1;
goto clean_up;
}

ULONG uReturn = 0;
HRESULT hr = enumerator->Next(WBEM_INFINITE,
1,
&clsObj,
&uReturn);
if(0 == uReturn)
{
ret = -1;
goto clean_up;
}

LPTSTR c_str = NULL;
VARIANT vtProp;

hr = clsObj->Get(L"Manufacturer", 0, &vtProp, 0, 0);
c_str = BSTR_to_TCHAR(vtProp.bstrVal);
if (NULL == c_str)
{
VariantClear(&vtProp);
ret = -1;

goto clean_up;
}
if (! SUCCEEDED(StringCbPrintf(mbi->Manufacture,
sizeof(mbi->Manufacture),
_T("%s"),
c_str)))
{
VariantClear(&vtProp);
ret = -1;

goto clean_up;
}
free(c_str); c_str = NULL;

hr = clsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
c_str = BSTR_to_TCHAR(vtProp.bstrVal);
if (NULL == c_str)
{
VariantClear(&vtProp);
ret = -1;

goto clean_up;
}
if (! SUCCEEDED(StringCbPrintf(mbi->Serial,
sizeof(mbi->Serial),
_T("%s"),
c_str)))
{
VariantClear(&vtProp);
ret = -1;

goto clean_up;
}
free(c_str); c_str = NULL;

VariantClear(&vtProp);
ret = 0;

// Cleanup
//
clean_up:
if (NULL != locator)
{
locator->Release();
locator = NULL;
}

if (NULL != enumerator)
{
enumerator->Release(); enumerator = NULL;
}

if (NULL != service)
{
service->Release();
service = NULL;
}

if (NULL != clsObj)
{
clsObj->Release();
clsObj = NULL;
}

CoUninitialize();
return ret;
}


/** ---------------------------------------------------------------------------
\brief

#include <comutil.h>
#pragma comment(lib, "comsuppw.lib")
#include <strsafe.h>
#pragma comment(lib, "strsafe.lib")
\param
\return success : allocate null terminated TCHAR string and return pointer
(must free TCHAR string)
fail : return NULL
\code
\endcode
-----------------------------------------------------------------------------*/
LPTSTR BSTR_to_TCHAR(IN const BSTR bstr)
{
_ASSERTE(NULL != bstr);
if (NULL == bstr)
{
return NULL;
}

_bstr_t tmp(bstr);
DWORD CharCount = tmp.length();

#ifdef UNICODE
DWORD c_str_buf_len = (sizeof(TCHAR) * CharCount ) + sizeof(TCHAR);
#else
// unicode 가 아닌 경우 한글같은 wide char 는 2바이트를 사용함
// 그러나 _bstr_t::length() 는 문자의 갯수만 리턴하므로
// CharCount * sizeof(TCHAR) * 2 를 해 줘야 한다.
// 물론 unicode 인 경우는 아무 문제 없음
//
DWORD c_str_buf_len = (( sizeof(TCHAR) * CharCount ) * 2 ) + sizeof(TCHAR);
#endif
LPTSTR c_str = (LPTSTR) malloc(c_str_buf_len);
RtlZeroMemory(c_str, c_str_buf_len);
if (!SUCCEEDED(StringCbPrintf(c_str, c_str_buf_len, _T("%s"), (LPCTSTR)tmp)))
{
free(c_str);
c_str = NULL;
}

return c_str;
}