您的位置:程序门 -> vc/mfc -> 网络编程



遍历共享文件的问题,请高手帮忙(wnetopenenum)


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


遍历共享文件的问题,请高手帮忙(wnetopenenum)
发表于:2007-07-27 18:20:53 楼主
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winnetwk.h>
#pragma   comment(lib, "mpr.lib ")

int   gongxiang(netresource   netres)
{

netresource   *pnetres;
handle   hfile;
dword   i,a,b,c=100;

i=wnetopenenum(resource_globalnet,resourcetype_any,0,&netres,&hfile);
if(i   !=   no_error)
{
printf( "wnetopenenum   error   is:%d\n ",i);
return   0;
}

b=sizeof(netresource)*4*100000;
pnetres=(netresource   *)globalalloc(gptr,   b   );
i=wnetenumresource(hfile,&a,(void   *)pnetres,(dword   *)&b);
if(i   !=   no_error)
{
printf( "wnetenumresource   error   is:%d\n ",i);
return   0;
}

for(i=0;i <a;i++)
{
printf( "name   is:%s\n ",pnetres[i].lpremotename);
if(   (pnetres[i].dwusage   &   resourceusage_container)   ¦ ¦   (pnetres[i].dwtype   &   resourcetype_disk)   )
gongxiang(pnetres[i]);
}
return   0;
}
int   main(int   argv,char   *argc[])
{
netresource   netres;

netres.dwscope=resource_connected   ¦   resource_globalnet   ¦   resource_remembered;
netres.dwtype=resourcetype_any   ¦   resourcetype_disk   ¦   resourcetype_print;
netres.dwdisplaytype=resourcedisplaytype_domain   ¦   resourcedisplaytype_server   ¦   resourcedisplaytype_share   ¦   resourcedisplaytype_generic;
netres.dwusage=resourceusage_connectable   ¦   resourceusage_container;
netres.lplocalname=0;
netres.lpremotename=argc[1];
netres.lpcomment=0;
netres.lpprovider=0;

gongxiang(netres);
return   0;
}

编译出来的文件名为nets.exe,输入nets   \\192.168.1.88,这个ip已经共享了c、d、e、f盘,成功是成功了,但是只列出了如下:
name   is:\\192.168.1.88\c
wnetopenenum   error   is:87
name   is:\\192.168.1.88\d
wnetopenenum   error   is:87
name   is:\\192.168.1.88\e
wnetopenenum   error   is:87
name   is:\\192.168.1.88\f
wnetopenenum   error   is:87

又试了下在cmd下输入了:
nets   \\192.168.1.88\c

还是wnetopenenum   error   is:87,87是参数不正确,但是wnetopenenum的参数怎么就不正确了,哪为大哥帮帮忙,小弟十分感谢,调试了好长时间都无法成功,郁闷死了,哎
发表于:2007-07-27 18:26:551楼 得分:0
如何能使用nets   \\192.168.1.88\c也可以枚举出c盘下的目录,小弟真的各种参数都换了,但是就是不行,请各位大哥帮帮忙,是我参数哪里错了,实在不知啊,哎
发表于:2007-07-28 10:38:502楼 得分:0
没人知道怎么回事吗?到底该用什么参数啊,帮帮忙,谢谢
顶起来
发表于:2007-07-28 11:27:533楼 得分:0
看完下面的文字   ,再确定你的   递归函数没写错     就应该ok了..  


天气热,,不多说了..粘贴了..

------------------------------------------------------------------------------------


网络共享资源也是按树状组织的,非叶节点称为容器(container),对容器需要进一步搜索直到到达叶子节点为止,叶子节点才是共享资源的根路径。共享资源一般分成两种:共享打印设备和共享文件夹。对于网络共享文件的搜索,采用wnetopenenum和wnetenumresource(由   mpr.dll导出)进行递归枚举。其函数原型及参数含义请参阅msdn,使用如下代码enumshare.cpp将显示所有的网络驱动器共享文件夹的路径:
  
  #include
  #include
  #pragma   comment(lib, "mpr.lib ")
  
  int   enum_netshare(lpnetresource   lpnr);
  
  void   __cdecl   main(int   argc,char   *argv[])
  {
           enum_netshare(0);
  }
  
  
  int   enum_netshare(lpnetresource   lpnr)
  {
           dword   r,   renum,usage;
           handle   henum;
           dword   cbbuffer   =   16384;          
           dword   centries   =   -1;                
           lpnetresource   lpnrlocal;         //   netresource数组结构的指针
           dword   i;
  
  
           r   =   wnetopenenum(resource_globalnet,         //   范围:所有网络资源
                                                       resourcetype_disk,//   类型:仅枚举可存储介质
                                                       resourceusage_all,//   使用状态:所有
                                                       lpnr,                           //   初次调用时为null
                                                       &henum);                     //   成功后返回的网络资源句柄
  
           if   (r   !=   no_error)   {
                   printf( "wnetopenenum   error....\n ");
                   return   false;
           }
        
           lpnrlocal   =   (lpnetresource)   malloc(cbbuffer);
           if   (lpnrlocal   ==   null)
                   return   false;
  
           do
           {
                   zeromemory(lpnrlocal,   cbbuffer);      
  
                   renum   =   wnetenumresource(henum,                        
                                                                               &centries,         //   返回尽可能多的结果
                                                                               lpnrlocal,         //   lpnetresource
                                                                               &cbbuffer);       //   buffer大小
                   if   (renum   ==   no_error)   {
  
                           for(i   =   0;   i   <   centries;   i++)   {
                                
                                   usage   =   lpnrlocal.dwusage;
                                
                                   if(usage   &   resourceusage_container)   {
                                      
                                           if(!enum_netshare(&lpnrlocal))
                                                   printf( "errors   detected   in   enum   process...\n ");                              
                                   }else{
  
                                           //   这里病毒可调用遍历函数遍历该共享文件夹下的所有文件
             //   enum_path(lpnrlocal.lpremotename);
                                           printf( "find   %s   -->   %s\n ",lpnrlocal.lplocalname,
                                                                                                   lpnrlocal.lpremotename);
                                   }
                           }
                   }else   if   (renum   !=   error_no_more_items)   {
                           printf( "wnetenumresource   error...\n ");
                           break;
                   }
           }while(renum   !=   error_no_more_items);
  
           free((void*)lpnrlocal);
  
           r   =   wnetcloseenum(henum);
            
           if(r   !=   no_error)   {
                   printf( "wnetcloseenum   error....\n ");
                   return   false;
           }
  
           return   true;
  }

  遍历开始时wnetopenenum第4形参为0,在发现共享容器进行递归调用时候,该参数将为共享容器的netresource结构指针。从   netresource结构中可以找到我们感兴趣的lpremotename,该指针不为0则表示是有效的共享容器或共享文件夹。
  
typedef   struct   _netresource   {
    dword   dwscope;
    dword   dwtype;
    dword   dwdisplaytype;
    dword   dwusage;
    lptstr   lplocalname;
    lptstr   lpremotename;
    lptstr   lpcomment;
    lptstr   lpprovider;
}   netresource;

                在解决了起始目录的问题之后,就可以从这些起始目录开始使用findfirstfile和findnextfile开始遍历其下以及其子目录下的所有文件和目录了,遍历方法可采用深度优先或广度优先搜索算法,较常用的还是深度优先算法。具体实现方式可采用递归搜索或非递归搜索两种实现方式。递归搜索需要占用栈空间,有可能造成栈空间耗竭而产生异常,不过在现实应用中这种情况很少出现,而非递归搜索则不存在此问题,但代码实现略复杂。在现实应用中,应用最多的还是递归遍历搜索。搜索时,可指定findfirstfile的第一形参为*.*以搜索所有文件,根据搜索结果win32_find_data结构的   dwfileattributes成员判断是否为目录,若为目录则需要继续遍历该子目录,根据win32_find_data的cfilename中的文件名成员判断是否具有要感染的文件后缀以采取修改感染动作,以下代码实现了递归搜索某个目录及其下所有子目录的功能:

void   enum_path(char   *cpath){

        win32_find_data   wfd;
        handle   hfd;
        char   cdir[max_path];
        char   subdir[max_path];

        int   r;

        getcurrentdirectory(max_path,cdir);
        setcurrentdirectory(cpath);

        hfd   =   findfirstfile( "*.* ",&wfd);

        if(hfd!=invalid_handle_value)   {
                do{
                        if(wfd.dwfileattributes   &   file_attribute_directory)   {
                                if(wfd.cfilename[0]   !=   '. ')   {
                                        //合成完整路径名
                                        sprintf(subdir, "%s\\%s ",cpath,wfd.cfilename);    
                                        //递归枚举子目录
                                        enum_path(subdir);                              
                                }
                        }else{

                                printf( "%s\\%s\n ",cpath,wfd.cfilename);
                                //   病毒可根据后缀名判断是否要感染相应的文件            
                        }
                     
                }while(r=findnextfile(hfd,&wfd),r!=0);      
        }
        setcurrentdirectory(cdir);
}

                  短短20多行c代码就实现了文件遍历的功能,win32   api的强大功能不仅为开发者提供了便利,同时也为病毒敞开了方便之门。用汇编实现则稍微复杂一些,感兴趣的读者可参阅elkern中的   enum_path部分,原理是一样的,限于篇幅这里不再给出相应的汇编代码。
非递归搜索不使用堆栈存储相关的信息,而使用显式分配的链表或栈等结构存储相关的信息,应用一个迭代循环完成递归遍历同样的功能,下面是使用链表以栈方式处理子目录列表的一个简单实现:

void   nr_enum_path(char   *cpath){

        list   dir_list;
        string   cdir,subdir;
        win32_find_data   wfd;
        handle   hfd;      
        int   r;

        dir_list.push_back(string(cpath));

        while(dir_list.size())   {
                cdir   =   dir_list.back();
                dir_list.pop_back();
           
                setcurrentdirectory(cdir.c_str());

                hfd   =   findfirstfile( "*.* ",&wfd);

                if(hfd!=invalid_handle_value)   {
                        do{
                                if(wfd.dwfileattributes   &   file_attribute_directory)   {
                                        if(wfd.cfilename[0]   !=   '. ')   {
                                                //合成完整路径名
                                                subdir=cdir+ "\\ "+wfd.cfilename;
                                                cout < < "push   subdir:   " < <
                                                //递归枚举子目录
                                                dir_list.push_back(string(subdir));                              
                                        }
                                }else{

                                        printf( "%s\\%s\n ",cpath,wfd.cfilename);
                                        //   病毒可根据后缀名判断是否要感染相应的文件            
                                }
                             
                        }while(r=findnextfile(hfd,&wfd),r!=0);      
                }      
        }//end   while
}


发表于:2007-07-28 12:08:154楼 得分:0
我确定没错啊,而且findfirstfile和findnextfile是不能遍历共享文件、文件夹的,楼上的代码也不行
发表于:2007-07-28 12:11:535楼 得分:0
可以这么说,微软msdn里的例子都行不同,不知道有没有人用wnetopenenum、wnetenumresource遍历成功过,麻烦用过的发言,没用过的、没自己测试过的,请不要google或baidu搜的代码贴上来
发表于:2007-07-28 18:00:156楼 得分:0
问题已经解决,嘿嘿,开心!
发表于:2007-07-30 19:09:357楼 得分:0
mark
发表于:2007-08-01 10:12:488楼 得分:0
可以查看本机或局域网共享的文件夹
void   fcontext::findfiles(cstring   filepath,   bool   hassub,cstringarray   &arrays){
//   去掉回收站
cstring   temp   =   filepath;
temp.makeupper();
if   (temp.find(_t( ":\\recycler "))   > =   0)
return;
if   (temp.find(_t( ":\\recycled "))   > =   0)
return;
//
cfilefind   cfind;
bool   isworking   =   false;
isworking   =   cfind.findfile(filepath);
while(isworking){
isworking   =   cfind.findnextfilew();
if   (cfind.isdots())
continue;
if   (cfind.isdirectory()){   //处理目录
if   (!hassub)   //不包含子文件夹
continue;
cstring   cs   =   cfind.getfilepath()   +   _t( "\\*.* ");
findfiles(cs,hassub,arrays);
continue;
}
arrays.add(cfind.getfilepath());
}
cfind.close();
}
发表于:2007-08-01 11:14:299楼 得分:0
学习,收藏

发表于:2007-08-01 16:21:5910楼 得分:0
楼主怎么搞定的,学习下,
play100(坐天观井)   好像不行,不能搜索共享


快速检索

最新资讯
热门点击