使用 NetShareEnum 遍历本地共享目录需要注意的问题

来源:互联网 发布:淘宝怎么打开旺旺 编辑:程序博客网 时间:2024/06/03 14:52

1 简介

Windows提供了NetShareEnum函数用于实现遍历服务器的共享目录,但在实现该功能时发现一个有关UNICODE和ANSI字符串的问题。


2. 函数原型简介

该函数原型如下:

NET_API_STATUS NetShareEnum(  LPWSTR servername,  DWORD level,  LPBYTE* bufptr,  DWORD prefmaxlen,  LPDWORD entriesread,  LPDWORD totalentries,  LPDWORD resume_handle);
通过第二个参数 level 用来选择使用哪种级别的信息提取,可取值分别为0,1,2,50,502,。不同的level决定了bufptr所指向的结构体不同。以502 Level为例,bufptr需要指向SHARE_INFO_502的结构体。其定义如下所示:

typedef struct _SHARE_INFO_502 {  LPWSTR shi502_netname;  DWORD shi502_type;  LPWSTR shi502_remark;  DWORD shi502_permissions;  DWORD shi502_max_uses;  DWORD shi502_current_uses;  LPWSTR shi502_path;  LPWSTR shi502_passwd;  DWORD shi502_reserved;  PSECURITY_DESCRIPTOR shi502_security_descriptor;} SHARE_INFO_502, *PSHARE_INFO_502, *LPSHARE_INFO_502;

3. 实现方式


//定义一个简单的结构体,用于存放一个共享目录的目录名和所在的路径。
struct SHARE_FOLDER{SHARE_FOLDER(): wsNetName(L""), wsPath(L""){}std::wstring wsNetName;std::wstring wsPath;};


//遍历本地共享文件目录,结果存放至resShareFolders容器中
bool  EnumLocalShareFolders(std::vector<SHARE_FOLDER>& resShareFolders){resShareFolders.clear();PSHARE_INFO_502 pBuf=NULL;NET_API_STATUS  res;DWORD er=0, tr=0, resume=0;do{res = NetShareEnum(NULL, 502, (LPBYTE*) &pBuf,  MAX_PREFERRED_LENGTH,&er, &tr, &resume);if( NULL == pBuf){return false;}if( ERROR_SUCCESS == res || ERROR_MORE_DATA == res ){PSHARE_INFO_502  pPos = pBuf;for(DWORD i=1; i<=er; ++i){SHARE_FOLDER folder;folder.wsNetName = (wchar_t*)(pPos->shi502_netname);  //[1]folder.wsPath = (wchar_t*)(pPos->shi502_path);      //[2]resShareFolders.push_back(folder);++pPos;}NetApiBufferFree(pBuf);}}while(ERROR_MORE_DATA==res);return true;}

4. 存在问题

由MSDN提供的函数原型可以看出,用于存储返回信息的结构体 SHARE_INFO_502的字符串类型的成员变量都是宽字符类型 LPWSTR, 例如shi502_netname和shi502_path。事实上,通过系统的调用所提取出的字符串信息也是UNICODE字符串。但是在编译器的头文件中,该类型的字符串被定义成了LPSTR,也就是ANSI字符串,这就导致了两者的不一致。因此需要进行强制的类型转换,如上例代码中[1] [2]标记的的部分。如果不进行转换而直接将路径值和共享文件名赋值给std::wstring编译器报错。如果直接将

shi502_netname和shi502_path赋值给std::string类型,则只会赋值第一个字母。

例如,假设提取出的信息 shi502_netname 值为"ADMIN$",实际上,该值是以UNICODE编码, std::string name = shi502_netname 的赋值结果是,name=="A"。因为由于对字母高位补0,因此将后面的字符串截断。


5. 疑问

不知道是我个人理解问题,还是微软在这方面的实现有问题,笔者使用的平台是 Win7+vs2005 。 还没有在其它平台和IDE上验证。希望各位能够给出点意见和建议。

原创粉丝点击