VC下获取远程主机共享信息的一些方法

VC下获取远程主机共享信息的一些方法

工程需要,要求就是在拥有了远程主机的IP地址、用户名和密码后列出远程主机上所有的共享资源。综合网上的资料和MSDN中的相关内容后,发现大概有WNetNetAPIWMI这么几种方式,感觉WMI是最强大的。下面就把各种方法大概说一下。

利用WMI获取远程主机的共享信息

1、  初始化操作

这部分我之前说过,参照以前WMI连接远程主机的文章就可以了,必须要能够正确得到IWbemServices对象,并为其设置了访问权限。

 

2、  枚举远程主机上的共享资源

共享资源对应的WMI类名是Win32_Share,我们只要用IWbemServices对象的CreateInstanceEnum()方法就可以得到所有的共享资源了。

HRESULT hr = S_OK;

IEnumWbemClassObject* pEnumObj = NULL;

Hr = pIWbemServices->CreateInstanceEnum(L"Win32_Share", 0, NULL, &pEnumObj);

Hr = CoSetProxyBlanket(

            pEnumObj,                        // 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

            pCID,               // 这个需要设置用户信息,见之前WMI连接远程主机的文章

            EOAC_NONE                    // proxy capabilities

            );

ULONG uReturned = 1;

while(uReturned == 1)

{

    IWbemClassObject *pStorageDev = NULL;

    hr = pEnumObj->Next(

    2000,           // timeout in two seconds

    1,              // return just one storage device

    &pStorageDev,   // pointer to storage device

    &uReturned);    // number obtained: one or zero

if (SUCCEEDED(hr) && (uReturned == 1))

{

        VARIANT pVal;

        VariantInit(&pVal);

        hr = pStorageDev->Get(L"__RELPATH", 0L, &pVal, NULL, NULL);

        GetShareInfo(pIWbemServices, pVal.bstrVal);//得到共享信息,pVal就是类标识

        VariantClear(&pVal);

        pStorageDev->Release();

    }

}

CHECK_AND_RELEASE(pEnumAdapters);

这里需要注意下,我们得到了枚举对象后,如果不是操作本机,而是要得到远程主机的共享资源是必须要为枚举对象设置访问权限的,也就是CoSetProxyBlanket()是不能少的

 

3、  得到共享信息

这里说下GetShareInfo()方法的实现,我们通过枚举得到了每个共享对象Win32_Share的类的字符标识,这样我们就可以使用IWbemServices对象的GetObject()方法得到具体的Win32_Share对象,其中bstrPathName就是之前得到的pVal.bstrVal

HRESULT hr = -1;

SAFEARRAY *psaNames = NULL;

IWbemClassObject* pClass = NULL;

long lLower, lUpper;

 

pIWbemServices->GetObject(bstrPathName, 0, NULL, &pClass, NULL);

if((hr = pClass->GetNames(NULL, WBEM_FLAG_ALWAYS|WBEM_FLAG_NONSYSTEM_ONLY, NULL, &psaNames)) == S_OK)

{

    if((hr = SafeArrayGetLBound(psaNames, 1, &lLower)) != S_OK)

    {

        SafeArrayDestroy(psaNames);

        CHECK_AND_RELEASE(pClass);

            return;

    }

    if((hr = SafeArrayGetUBound(psaNames, 1, &lUpper)) != S_OK)

    {

        SafeArrayDestroy(psaNames);

        CHECK_AND_RELEASE(pClass);

        return;

    }

    for (long lCount=lLower; lCount<=lUpper; lCount++)

    {

        BSTR PropName = NULL;

        VARIANT varString;

        VariantInit(&varString);

 

        if(SafeArrayGetElement(psaNames, &lCount, &PropName)==S_OK

            && pClass->Get(PropName, 0L, &varString, NULL, NULL)==S_OK)

        {

            if ((wcsicmp(PropName,L"Type")==0) && varString.vt!=VT_NULL)

            {

                UINT tmp_type = varString.uintVal;//0表示是共享文件夹

            }

            else if ((wcsicmp(PropName,L"Name")==0) && varString.vt!=VT_NULL)

            {

                CString tmp_name = varString.bstrVal;//共享名称

            }

            else if ((wcsicmp(PropName,L"Path")==0) && varString.vt!=VT_NULL)

            {

                CString tmp_path = varString.bstrVal;//共享在主机上的路径

            }

        }

        VariantClear(&varString);

        if (PropName != NULL)

        {

            SysFreeString(PropName);

        }

        if (bRes)

        {

            break;

        }

    }

    SafeArrayDestroy(psaNames);

}

CHECK_AND_RELEASE(pClass);

 

好了,到此WMI就已经得到所有的共享资源了。

 

利用WNet获取远程主机的共享信息

1、  连接远程主机

NETRESOURCE   nr;

memset(&nr, 0, sizeof(nr));

nr.dwScope=RESOURCE_CONNECTED; 

nr.dwType=RESOURCETYPE_DISK;

nr.dwDisplayType=RESOURCEDISPLAYTYPE_GENERIC; 

nr.dwUsage=RESOURCEUSAGE_CONNECTABLE;

nr.lpRemoteName = (LPTSTR)lpRemoteName;//远程主机名或IP://192.168.1.11

WNetAddConnection2(&nr, lpPw/*密码*/, lpUser/*用户名*/, CONNECT_UPDATE_PROFILE);

 

2、  利用WNetOpenEnum枚举共享信息

DWORD dwResult, dwResultEnum;

HANDLE hEnum;

BYTE buf[16384];

DWORD cbBuffer = 16384;     // 16K is a good size

LPNETRESOURCE lpnrLocal = (LPNETRESOURCE)buf;

DWORD cEntries = -1; 

dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, // all network resources

    RESOURCETYPE_DISK,   //只枚举共享文件夹

    0,  // enumerate all resources

    &nr,       // NULL first time the function is called

    &hEnum);    // handle to the resource

if (dwResult != NO_ERROR)

{

    return;

}

do

{

    cbBuffer = 16384;

    memset(lpnrLocal, 0, 16384);

    dwResultEnum = WNetEnumResource(hEnum,  // resource handle

        &cEntries,      // defined locally as -1

        lpnrLocal,      // LPNETRESOURCE

        &cbBuffer);     // buffer size

    if (dwResultEnum == NO_ERROR)

    {

        for (DWORD i=0; i<cEntries; i++)

        {

            CString str_remote = lpnrLocal[i].lpRemoteName;//得到共享名称

        }

    }

    else if (dwResultEnum != ERROR_NO_MORE_ITEMS)

    {

        break;

    }

}

while (dwResultEnum != ERROR_NO_MORE_ITEMS);

WNetCloseEnum(hEnum);

WNet方式枚举共享资源的时候好像无法的共享名以$结尾的隐藏共享。

Wnet需要导入的头文件是:Winnetwk.h.

库文件是:#pragma comment(lib, "Mpr.lib")

 

利用NetAPI获取远程主机的共享信息

1、  连接远程主机

这和WNet方式完全一样

 

2、  枚举共享资源

PSHARE_INFO_1 BufPtr, pInfo;

NET_API_STATUS res;

DWORD er=0,tr=0,resume=0, i;

do

{

    res = NetShareEnum ((LPTSTR)lpRemoteName, 1, (LPBYTE *) &BufPtr, -1, &er, &tr, &resume);

    if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA)

    {

        pInfo = BufPtr;

        for(i=1;i<=er;i++)

        {

            if (pInfo->shi1_type == STYPE_DISKTREE/*取文件夹共享*/

|| pInfo->shi1_type == STYPE_SPECIAL)

            {

                //pInfo->shi1_netname就是共享名称

            }

            pInfo++;

        }

        NetApiBufferFree(BufPtr);

    }

}

while (res==ERROR_MORE_DATA);

NetAPI需要导入的头文件和库文件

#include <lm.h>

#pragma comment(lib, "Netapi32.lib")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值