Chinaunix首页 | 论坛 | 博客
  • 博客访问: 194442
  • 博文数量: 29
  • 博客积分: 1280
  • 博客等级: 中尉
  • 技术积分: 320
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-22 16:23
文章分类

全部博文(29)

文章存档

2009年(3)

2008年(1)

2007年(1)

2006年(3)

2005年(21)

我的朋友

分类: 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

阅读(2944) | 评论(0) | 转发(0) |
0

上一篇:WNET协议

下一篇:WNET协议应用

给主人留下些什么吧!~~