分类: WINDOWS
2005-10-17 16:00:42
第二节:枚举网络资源
要枚举一网络容器资源,应用程序应把NETRESOURCE结构的地址传递给函数WNetOpenEnum;
该函数建立一由结构NETRESOURCE描述的资源句柄,并把此句柄传递给函数WNetEnumResource,
它将用NETRESOURCE结构数组的方式返回关于资源的消息,当句柄不是长时间的需要时,应用程
序可调用WNetCloseEnum函数关闭它.
应用程序可继续枚举由NETRESOURCE结构数组描述的容器资源(记住:是容器)
如果结构的dwUsage成员是RESOURCEUSAGE_CONTAINER(容器),可发出结构的地址给WNetOpenEnum
函数来打开容器并继续枚举,如果dwUsage成员是RESOURCEUSAGE_CONNECTABLE,就可发送结构给
WNetAddConnection2函数
下面的例子详解了一个枚举出所有网络资源的应用程序.当调用此函数时,指定NULL指向NETRESOURCE结构
当WNetOpenEnum收到一NULL指针,他将收到网络ROOT的句柄,当WNetEnumResource函数得到的结构成员
dwUsage是RESOURCEUSAGE_CONTAINER时,枚举函数调用他本身
BOOL WINAPI EnumerateFunc(HWND hwnd,HDC hdc,LPNETRESOURCE lpnr)
//hwnd是窗口句柄,hdc是画板句柄,lpnr是枚举时要用的NETRESOURCE结构
{
DWORD dwResult, dwResultEnum;
HANDLE hEnum;
DWORD cbBuffer = 16384; // 16K 是一个比较理想的大小
DWORD cEntries = 0xFFFFFFFF; // 枚举所有可能的
LPNETRESOURCE lpnrLocal; // 指向被枚举的NETRESOURCE结构
DWORD i;
dwResult = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, lpnr, &hEnum);
// 枚举所有资源 ,第一次调用lpnr是为NULL
if (dwResult != NO_ERROR)
{
//出错处理
NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetOpenEnum");
return FALSE;
}
//分配一全局內存(16k)
lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer);
//开始枚举
do
{
ZeroMemory(lpnrLocal, cbBuffer);//结构清零
dwResultEnum = WNetEnumResource(hEnum, // WNetOpenEnum函数返回的句柄
&cEntries, // 定义最大数为0ffffffffh
lpnrLocal, // LPNETRESOURCE数据结构
&cbBuffer); // 缓冲的大小
if (dwResultEnum == NO_ERROR)
{
for(i = 0; i < cEntries; i++)
{
//i为函数调用后返回的NETRESOURCE数据结构的个数
DisplayStruct(hdc, &lpnrLocal[i]);
//如果NETRESOURCE是一容器,进入枚举
if(RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage
& RESOURCEUSAGE_CONTAINER))
if(!EnumerateFunc(hwnd, hdc, &lpnrLocal[i]))
TextOut(hdc, 10, 10, "EnumerateFunc returned FALSE.", 29);
}
}
else if (dwResultEnum != ERROR_NO_MORE_ITEMS)//如果不等于没有可枚举的项目
{
NetErrorHandler(hwnd, dwResultEnum, (LPSTR)"WNetEnumResource");
break;
}
}
while(dwResultEnum != ERROR_NO_MORE_ITEMS);//枚举结束
GlobalFree((HGLOBAL)lpnrLocal); //释放内存
dwResult = WNetCloseEnum(hEnum);//关闭枚举
if(dwResult != NO_ERROR)
{
NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetCloseEnum");
return FALSE;
}
return TRUE;
}
;====汇编语言描述(BY 谢小荣)=====
AsmEnumerateFunc PROTO :DWORD,:DWORD,:DWORD
.DATA
cbBuffer dw 16384
cEntries dd 0xffffffffh
.CODE
AsmEnumerateFunc PROC hwnd:DWORD,hdc:DWORD,cBuf:DWORD
LOCAL currentBuf :DWORD
LOCAL dwResultEnum :DWORD
LOCAL lpnrLocal :DWORD
LOCAL hEnum :DWORD
;cBuf指向一NETRESOURCE结构,在下一函数调用中因会进行枚举,所以要用传递进来的参数
invoke WNetOpenEnum,RESOURCE_GLOBALNET,RESOURCETYPE_ANY,0, cBuf, offset hEnum
.if eax!=NO_ERROR
MsgBox "错误","在枚举网络资源时出现错误",MB_OK
mov eax,FALSE ;枚举函数要用到返回值
.else
invoke GlobalAlloc,GPTR,cbBuffer ;分配一全局內存(16k)
mov currentBuf,eax ;保存句柄给释放内存使用
mov lpnrLocal,eax ;句柄也是起始地址,因为用的是GPTR,如用GMEM_MOVEABLE则要用GlobalLock定位
.DO
invoke ZeroMemory,lpnrlocal, cbBuffer ;结构清零
invoke WNetEnumResource,hEnum,cEntries,lpnrLocal,cEntries ;枚举资源
mov dwResultEnum,eax
.if eax==NO_ERROR
push cx
mov cx,0ffffh
startloop:
push esi
mov esi,lpnrLocal
assume esi:NETRESOURCE ;设置ESI指向NETRESOURCE结构
mov eax,[esi].dwUsage
assume esi:nothing
pop esi
and eax,RESOURCEUSAGE_CONTAINER
.if eax==RESOURCEUSAGE_CONTAINER ;如果为一资源容器则继续调用主函数进行枚举
invoke AsmEnumerateFunc,hwnd,hdc,lpnrLocal
.if eax!=TRUE
;有错误
.endif
.endif
mov DWORD ptr eax,sizeof NETRESOURCE
ADD lpnrLocal,eax ;指向下一个NETRESOURCE结构的指针
loop startloop ;cx减1,如果CX!=0,再循环
pop cx
.endif
.WHILE dwResultEnum!=ERROR_NO_MORE_ITEMS
invoke GlobalFree,currentBuf
invoke WNetCloseEnum,hEnum
.if eax!=NO_ERROR
MOV EAX,FALSE
.else
mov eax,TRUE
endif
.endif
ret
AsmEnumerateFunc endp