blog

枪手亨利

博客园 首页 新随笔 联系 订阅 管理
在Windows中建立一个共享目录,通常是使用NetShareAdd函数.但是在Win2k和Win9x下,这个函数分别是包含在Netapi32.dll和Svrapi.dll中.

那么如果直接在程序中使用Netapi32.lib或Svrapi.lib,在不同的操作系统下运行时会发生找不到xxx函数的输出错误. 解决的办法就是通过GetProcAddress动态获取NetShareAdd.正好ccrun在csdn回答一位网友的问题,顺便写了些代码,在这里贴出来.



注:

1. 以下代码已在Win2k ADV Server和Win9x SE中通过测试.编译时不需要包含lm.h或Svrapi.h,如果包含的话,会引起数据类型重名的错误.

2. 请使用Borland C Builder编译器.如果您用VC,个别参数需要改动



代码如下:



typedef DWORD (WINAPI *NETSHAREADD2K)(LPWSTR, DWORD, LPBYTE, LPDWORD);

typedef DWORD (WINAPI *NETSHAREADD9X)(const char FAR*, short, const char FAR*, unsigned short);

NETSHAREADD2K NetShareAdd2k;

NETSHAREADD9X NetShareAdd9x;



bool bWinNT; // 操作系统标志

HINSTANCE hDll; // DLL文件句柄



#define NNLEN80// 共享名的长度

#define LM20_NNLEN12// LM 2.0 共享名的长度

#define SHPWLEN8// 共享密码的长度

#define STYPE_DISKTREE0// 磁盘共享

#define SHI50F_FULL0x0002

#define NERR_Success0// 操作成功



#define NERR_BASE2100

#define NERR_DuplicateShare(NERR_BASE 18)// 共享名称已经存在

#define NERR_RedirectedPath(NERR_BASE 17)// 重定向资源的操作非法

#define NERR_UnknownDevDir(NERR_BASE 16)// 设备或目录不存在



typedef struct _share_info_50 // 用于Win9x

{

charshi50_netname[LM20_NNLEN 1];// 共享名

unsigned charshi50_type;//

unsigned shortshi50_flags;//

char FAR *shi50_remark;// ANSI 备注

char FAR *shi50_path;// 共享的资源,也就是共享的目录

charshi50_rw_password[SHPWLEN 1]; // 可读写的密码

charshi50_ro_password[SHPWLEN 1]; // 只读密码

}share_info_50;



typedef struct _SHARE_INFO_2 // 用于Win2k

{

LPWSTRshi2_netname;

DWORDshi2_type;

LPWSTRshi2_remark;

DWORDshi2_permissions;

DWORDshi2_max_uses;

DWORDshi2_current_uses;

LPWSTRshi2_path;

LPWSTRshi2_passwd;

}SHARE_INFO_2, *PSHARE_INFO_2, *LPSHARE_INFO_2;



//---------------------------------------------------------------------------

bool __fastcall InitApi() // 根据操作系统的不同,从Dll中获取API

{

// 判断系统平台

OSVERSIONINFO info;

info.dwOSVersionInfoSize = sizeof(info);

GetVersionEx(#amp;info);

bWinNT = (info.dwPlatformId == VER_PLATFORM_WIN32_NT)? true: false;



if(bWinNT)

{

hDll = LoadLibrary(Netapi32.dll); // win2k

if(hDll)

{

NetShareAdd2k = (NETSHAREADD2K)GetProcAddress(hDll, NetShareAdd);

return (NetShareAdd2k != NULL);

}

else

return false;

}

else

{

hDll = LoadLibrary(Svrapi.dll); // win9x

if(hDll)

{

NetShareAdd9x = (NETSHAREADD9X)GetProcAddress(hDll, NetShareAdd);

return NetShareAdd9x != NULL;

}

else

return false;

}

}

//---------------------------------------------------------------------------

String __fastcall MyPathToNetShare(

String strPath,// 共享目录

String strNetName,// 共享名

String strPassword,// 密码

String strRemark)// 共享目录的注释

{

if(!InitApi())

return 函数获取错误!;



// 文档标题:如何在Win9x/2k下建立共享目录

// 作者:ccrun(老妖) 信箱:info@ccrun.com

// 为防止不负责任的转载者遗漏作者信息,故在此插入此信息,请见谅.

// 欢迎访问C Builder 研究 http://www.ccrun.com



if(!bWinNT)// 操作系统是win9x

{

char FAR *pszServerName = NULL;

short nLevel = 50;

struct share_info_50* pBuf = NULL;

unsigned short cbBuffer;

DWORD nStatus;

cbBuffer = sizeof(struct share_info_50);

pBuf = (share_info_50 *)malloc(cbBuffer);

if(pBuf == NULL)

return 内存分配失败!;



// Assign values to the share_info_50 structure.

strcpy(pBuf->shi50_netname, strNetName.c_str());

pBuf->shi50_type = STYPE_DISKTREE;

pBuf->shi50_flags = SHI50F_FULL;

pBuf->shi50_remark = strRemark.c_str();

pBuf->shi50_path = strPath.c_str();

strcpy(pBuf->shi50_rw_password, strPassword.c_str()); // No password

strcpy(pBuf->shi50_ro_password, strPassword.c_str()); // No password



// Call the NetShareAdd function specifying information level 50.

nStatus = NetShareAdd9x(pszServerName,

nLevel,

(char FAR *)pBuf,

cbBuffer);



// 释放分配的内存

if(pBuf != NULL)

free(pBuf);

//

FreeLibrary(hDll);



if(nStatus == NERR_Success)

return(添加成功!);

else

return String(有错误发生,返回码: String(nStatus));

}

else// 操作系统是Win2k

{

HANDLE hToken;

TOKEN_PRIVILEGES tk;



// 首先提升本进程的调试级别

OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, #amp;hToken);

LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, #amp;tk.Privileges[0].Luid);

tk.PrivilegeCount = 1;

tk.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges(hToken, FALSE, #amp;tk, 0, (PTOKEN_PRIVILEGES)NULL, 0);



DWORDnas;

SHARE_INFO_2p;

DWORDdwParamErr = NULL;

p.shi2_path= StringToOleStr(strPath);

p.shi2_remark= StringToOleStr(strRemark);

p.shi2_netname= StringToOleStr(strNetName);

p.shi2_passwd= StringToOleStr(strPassword);

p.shi2_type= STYPE_DISKTREE; // disk drive

p.shi2_permissions= 0;

p.shi2_max_uses= -1;

p.shi2_current_uses= 0;

nas = NetShareAdd2k(NULL, 2, (LPBYTE)#amp;p, #amp;dwParamErr);



FreeLibrary(hDll);



switch(nas)

{

case NERR_Success:return 设置成功!;

case ERROR_ACCESS_DENIED:return 拒绝访问!;

case ERROR_INVALID_LEVEL:return 非法的级别!;

case ERROR_INVALID_NAME:return 非法的名称!;

case ERROR_INVALID_PARAMETER:return 参数非法!;

case NERR_DuplicateShare:return 共享重名!;

case NERR_RedirectedPath:return 重定向路径!;

case NERR_UnknownDevDir:return 未知的驱动路径!;

default:return 未知错误!;

}

}

}

// 调用举例

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)

{

ShowMessage(MyPathToNetShare(C:\ccrun\123, MyShare, , 共享目录的注释));

}

//---------------------------------------------------------------------------
posted on 2005-12-08 15:54  henry  阅读(1876)  评论(0)    收藏  举报