スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

--.--.-- | スポンサー広告

WMIプログラムC++編-2

進捗状況は……特になし

そういえばGoogleの提供するブログサービス「Blogger」と「BlogSpot」が
「スプログ」のせいでえらいことになっているようだが
日本のブログサイトは大丈夫なんだろうか……何も対策とられてない予感(;´Д`)
特にここはJavaScriptが使えるだけに不安……
ブログスパムの悪夢--「スプログ」でグーグルのBloggerが大混乱-CNET



WMIプログラムC++編-2
前回約束したので今回はドメインにぶら下がっている
PCのIPAddressを取得するプログラムを解説します。

<その1>
とにもかくにもドメインにぶら下がっているPC名を取得できなければ話になりません。
そこで WNET API を使用してPC名を取得します。

<その2>
その後前回の要領で IP Address を取得するのですが
当然ネットワーク越しなのでアカウントとパスワードが必要になります。
(IWbemLocator インターフェイスの ConnectServer の
 第2パラメータにアカウント名、第3パラメータにパスワードが入ります)

<その3>
今回使用している「Win32_NetworkAdapterConfiguration」は
全てのネットワークアダプタの情報を取得できるのですが、
今回必要なのは生きているネットワークアダプタ
IP Address なので WHERE 区の後に「IPEnabled='TRUE'」と書いています。
WMI では WHERE 区の後に条件をつけることによって情報を絞ることができます。

<その4>
今回取得したい IP Address の情報は"String Array"のため少々手間が必要です。
詳細はソースを参考にしてください。

※今回は"ドメイン"、"アカウント"、"パスワード"の入力が必要のため
  GUIアプリにしました。
※何10台ものPCの検索を行うとアプリがビジー状態になるため
  スレッド化する等の工夫が必要でしょう

※2005/10/27間違ってた個所があったので修正
リソース

IDD_IP_ADDRESS DIALOG DISCARDABLE 0, 0, 183, 225
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "IP Address の列挙"
FONT 9, "MS Pゴシック"
BEGIN
LTEXT "ドメイン",IDC_STATIC,5,10,22,8
LTEXT "ユーザー",IDC_STATIC,5,35,28,8
LTEXT "パスワード",IDC_STATIC,5,60,32,8
EDITTEXT IDC_DOMAIN,40,5,70,15,ES_AUTOHSCROLL
EDITTEXT IDC_USER,40,30,70,15,ES_AUTOHSCROLL
EDITTEXT IDC_PASSWORD,40,55,70,15,ES_PASSWORD |
ES_AUTOHSCROLL
EDITTEXT IDC_LIST,5,80,175,140,ES_MULTILINE |
ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL
PUSHBUTTON "取得",IDC_GET,135,5,40,15
PUSHBUTTON "閉じる",IDCANCEL,135,55,40,15
END

WinMain.cpp

#define _WIN32_DCOM
#include
#include
#include
#include "resource.h"
using namespace std;

#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "Mpr.lib")

// IP Address の列挙
void IPAddressEnumerator(HWND hWnd, char *domain,
char *user, char *password)
{
IWbemLocator *wbem_locator = NULL;

// 各種初期化
::CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);

::CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
reinterpret_cast(&wbem_locator));

NETRESOURCE net_resource;
LPNETRESOURCE enum_resoruce;
HANDLE enum_handle;
DWORD buffer_size = 1000;
DWORD count = 1;

::SecureZeroMemory(&net_resource, sizeof(NETRESOURCE));
net_resource.dwScope = RESOURCE_GLOBALNET;
net_resource.dwType = RESOURCETYPE_ANY;
net_resource.dwDisplayType = RESOURCEDISPLAYTYPE_DOMAIN;
net_resource.dwUsage = RESOURCEUSAGE_CONTAINER;
net_resource.lpRemoteName = domain;
net_resource.lpProvider = "Microsoft Windows Network";

enum_resoruce =
(LPNETRESOURCE)::GlobalAlloc(GMEM_FIXED, buffer_size);
// ネットワークリソースの取得
::WNetOpenEnum(RESOURCE_GLOBALNET,
RESOURCETYPE_ANY,
0, &net_resource, &enum_handle);

// 取得したネットワークリソースの列挙
string ip_list;
while(::WNetEnumResource(enum_handle, &count,
enum_resoruce,
&buffer_size) == NO_ERROR)
{
IWbemServices *wbem_services = NULL;
IEnumWbemClassObject *wbem_enumerator = NULL;
IWbemClassObject *wbem_object = NULL;

char pc_name[256] = "";
wsprintf(pc_name, "%s\\ROOT\\CIMV2",
enum_resoruce->lpRemoteName);
char domain_name[256] = "";
wsprintf(domain_name, "ntlmdomain:%s", domain);

// 接続開始
mbstowcs(buffer2, buffer, length);
if(wbem_locator->ConnectServer(_bstr_t(pc_name),
_bstr_t(user),
_bstr_t(password),
0, NULL, domain_name,
0, &wbem_services) != S_OK)
{
::SendDlgItemMessage(hWnd, IDC_LIST, WM_SETTEXT, 9,
reinterpret_cast("connect failed..."));
return continue;
}

::CoSetProxyBlanket(wbem_services,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE);

wbem_services->ExecQuery(_bstr_t("WQL"),
_bstr_t("SELECT * FROM
Win32_NetworkAdapterConfiguration
WHERE IPEnabled='TRUE'"),
WBEM_FLAG_RETURN_IMMEDIATELY |
WBEM_FLAG_FORWARD_ONLY,
NULL, &wbem_enumerator);

// プロパティ読み込み
ULONG returned = 0;
char cr[3] = {0x0d, 0x0a, 0x00};

while(wbem_enumerator)
{
wbem_enumerator->Next(WBEM_INFINITE, 1,
&wbem_object, &returned);

if(0 == returned) break;

VARIANT property_value;
_bstr_t display_name;
::VariantInit(&property_value);
wbem_object->Get(L"IPAddress", 0L,
&property_value, NULL, NULL);

ip_list += "IPAddress : ";
// SAFEARRAY データの取得
if(property_value.vt == (VT_ARRAY | VT_BSTR))
{
long lLower = 0, lUpper = 0;
::SAFEARRAY *property_array = property_value.parray;
::SafeArrayGetLBound(property_array, 1, &lLower);
::SafeArrayGetUBound(property_array, 1, &lUpper);

string property_string;
for(long i = lLower; i <= lUpper; ++i)
{
BSTR data;
if(::SafeArrayGetElement(property_array,
&i, &data) != S_OK)
{
if(property_array != NULL)
::SafeArrayDestroy(property_array);
}

char buffer[256] = "";
wcstombs(buffer, data, 255);
property_string += buffer;
}

if(property_array != NULL)
::SafeArrayDestroy(property_array);

ip_list += property_string;
ip_list += cr;
}

::VariantClear(&property_value);
}

// オブジェクトの開放
if(wbem_object != NULL)
wbem_object->Release();

if(wbem_enumerator != NULL)
wbem_enumerator->Release();

if(wbem_services != NULL)
wbem_services->Release();
}

::SendDlgItemMessage(hWnd, IDC_LIST, WM_SETTEXT,
ip_list.length(),
reinterpret_cast(ip_list.c_str()));

// 各種開放
::WNetCloseEnum(enum_handle);
::GlobalFree(enum_resoruce);
wbem_locator->Release();
}

/* ダイアログ プロシージャ */
INT_PTR CALLBACK IPDlgProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_GET:
{
char domain[256] = "";
char user[256] = "";
char password[256] = "";
::SendDlgItemMessage(hWnd, IDC_DOMAIN,
WM_GETTEXT, 255,
reinterpret_cast(domain));
::SendDlgItemMessage(hWnd, IDC_USER,
WM_GETTEXT, 255,
reinterpret_cast(user));
::SendDlgItemMessage(hWnd, IDC_PASSWORD,
WM_GETTEXT, 255,
reinterpret_cast(password));
IPAddressEnumerator(hWnd, domain, user, password);
break;
}

case IDCANCEL:
::EndDialog(hWnd, 0);
::PostQuitMessage(0);
break;
}

return 0;
}

return FALSE;
}


/* メイン */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
MSG msg;

::CoInitializeEx(0, COINIT_MULTITHREADED);
hWnd = ::CreateDialog(hInstance,
MAKEINTRESOURCE(IDD_IP_ADDRESS),
0, IPDlgProc);

::ShowWindow(hWnd, SW_SHOW);

while(::GetMessage(&msg, NULL, 0, 0))
{
if(hWnd == 0 || !::IsDialogMessage(hWnd, &msg)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

::CoUninitialize();
return TRUE;
}

今回は以上です。
次回はどうしようかな(;´Д`)
スポンサーサイト

テーマ:プログラミング - ジャンル:コンピュータ

2005.10.23 | Comments(0) | Trackback(0) | プログラム

コメント

コメントの投稿


秘密にする

«  | HOME |  »

ブロとも申請フォーム

この人とブロともになる

カウンター


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。