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

nilo 2007-07-27 06: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的参数怎么就不正确了,哪为大哥帮帮忙,小弟十分感谢,调试了好长时间都无法成功,郁闷死了,哎
...全文
904 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wenyang 2011-05-26
  • 打赏
  • 举报
回复
学习了
  • 打赏
  • 举报
回复
加上这句话就好了。
netres.lpProvider="Microsoft Windows Network";
[Quote=引用楼主 nilo 的回复:]
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <Winnetwk.h>
#pragma comment(lib, "Mpr.lib ")

int gongxiang(NETRESOURCE netres)
{

NETRESOURCE *pNetres;
HANDLE ……
[/Quote]
hustpanda 2008-01-30
  • 打赏
  • 举报
回复
楼主怎么搞定的? 可否赐教
hjh5303 2007-08-01
  • 打赏
  • 举报
回复
学习,收藏

play100 2007-08-01
  • 打赏
  • 举报
回复
可以查看本机或局域网共享的文件夹
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();
}
rand0941 2007-08-01
  • 打赏
  • 举报
回复
楼主怎么搞定的,学习下,
play100(坐天观井) 好像不行,不能搜索共享
tomtom123 2007-07-30
  • 打赏
  • 举报
回复
MARK
nilo 2007-07-28
  • 打赏
  • 举报
回复
可以这么说,微软MSDN里的例子都行不同,不知道有没有人用WNetOpenEnum、WNetEnumResource遍历成功过,麻烦用过的发言,没用过的、没自己测试过的,请不要google或baidu搜的代码贴上来
nilo 2007-07-28
  • 打赏
  • 举报
回复
我确定没错啊,而且FindFirstFile和FindNextFile是不能遍历共享文件、文件夹的,楼上的代码也不行
emptyness 2007-07-28
  • 打赏
  • 举报
回复
看完下面的文字 ,再确定你的 递归函数没写错 就应该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,
   ¢ries, // 返回尽可能多的结果
   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
}





nilo 2007-07-28
  • 打赏
  • 举报
回复
没人知道怎么回事吗?到底该用什么参数啊,帮帮忙,谢谢
顶起来
nilo 2007-07-28
  • 打赏
  • 举报
回复
问题已经解决,嘿嘿,开心!
nilo 2007-07-27
  • 打赏
  • 举报
回复
如何能使用nets \\192.168.1.88\c也可以枚举出c盘下的目录,小弟真的各种参数都换了,但是就是不行,请各位大哥帮帮忙,是我参数哪里错了,实在不知啊,哎

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧