操作系统环境:不使用简单文件共享,共享文件夹所在磁盘为NTFS 文件系统
(1)设置共享账户专用文件夹
创建一个共享文件夹,如果已经存在就不新建并设置为Everyone访问,并设置为指定用户访问
BOOL CWindowTaskHelper::CreateShareFolder(CString strFoldFullPath,CString strOwner,CString strPassword,CString strShareName)
{
BOOL bResult = FALSE;
CFileFind fileFind;
if (fileFind.FindFile(strFoldFullPath))
{
SetEveryoneAccessFolder(strFoldFullPath);
bResult = TRUE;
fileFind.Close();
}
else
{
bResult = CreateFolder(strFoldFullPath);
}
if (bResult)
{
HINSTANCE hInstance = NULL;
bResult = AdjustAndShareFolder(strFoldFullPath,strOwner,strPassword);
ASSERT(bResult);
}
if(!bResult)
{
VsControlTools::VsMessageBox(_T("创建共享文件夹失败!"),MB_OK,_T("提示"));
}
return bResult;
}
函数CreateFolder :新建一个Everyone访问的文件夹,如果已经存在就不新建
BOOL CWindowTaskHelper::CreateFolder(CString strFoldFullPath)
{
BOOL bResult = FALSE;
TCHAR tcChar[MAX_PATH];
memset(tcChar,0, MAX_PATH *(sizeof(TCHAR) ) );
CFileFind fileFind;
bResult = fileFind.FindFile(strFoldFullPath);
if(!bResult)
{
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor( & sd,SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl( & sd,TRUE,NULL,FALSE);
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = & sd;
bResult = CreateDirectory(strFoldFullPath,&sa);
}
else
{
fileFind.Close();
}
#ifdef _DEBUG
if (!bResult)
{
VsControlTools::VsMessageBox(_T("创建文件夹失败!"),MB_OK,_T("提示"));
}
#endif
return bResult;
}
函数 AdjustAndShareFolder //设置共享文件夹的用户权限,共享权限只为专用账户 以 CMD Cacls命令实现
BOOL CWindowTaskHelper::AdjustAndShareFolder(CString strFoldFullPath,CString strOwner,CString strPassword)
{
BOOL bResult = FALSE;
HINSTANCE hInstance = NULL;
CString strTmp = _T("");
//启用Everyone
strTmp.Format(_T("/c echo Y|CACLS %s /T /p Everyone:F"),strFoldFullPath);
#ifdef _DEBUG
::AfxMessageBox(strTmp);
#endif
ShellExecute(NULL,_T("open"),_T("cmd.exe"),strTmp,NULL,SW_HIDE);
//设置共享文件夹
bResult = ShareFolderForUser(strFoldFullPath,strOwner,strPassword);
ASSERT(bResult);
//设置指定的账户对文件夹的操作权限
strTmp.Format(_T("/c echo Y|CACLS %s /T /p %s:F"),strFoldFullPath,strOwner);
#ifdef _DEBUG
::AfxMessageBox(strTmp);
#endif
hInstance = ShellExecute(NULL,_T("open"),_T("cmd.exe"),strTmp,NULL,SW_HIDE);
//添加SYSTEM以便在服务中使用
strTmp.Format(_T("/c CACLS %s /T /e /g SYSTEM:F"),strFoldFullPath);
#ifdef _DEBUG
::AfxMessageBox(strTmp);
#endif
hInstance = ShellExecute(NULL,_T("open"),_T("cmd.exe"),strTmp,NULL,SW_HIDE);
bResult = ((int) hInstance > 32);
//设置管理员对文件夹的操作权限
strTmp.Format(_T("/c CACLS %s /T /e /g Administrators:F"),strFoldFullPath);
hInstance = ShellExecute(NULL,_T("open"),_T("cmd.exe"),strTmp,NULL,SW_HIDE);
bResult = ((int) hInstance > 32);
ASSERT(bResult);
//设置当前登录用户对文件夹的操作权限
CString strHostName = _T("");
CString strCurrentUser =_T("");
DWORD dwMax = MAX_PATH;
TCHAR tcChar[MAX_PATH];
memset(tcChar,0,MAX_PATH * (sizeof(TCHAR)));
::GetComputerName(tcChar,&dwMax);
strHostName = tcChar;
dwMax = MAX_PATH;
memset(tcChar,0,MAX_PATH * (sizeof(TCHAR)));
TCHAR *szLogName = NULL;
if ( WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,WTS_CURRENT_SESSION,WTSUserName,&szLogName,&dwMax) )
{
strCurrentUser = szLogName;
WTSFreeMemory(szLogName);
}
strTmp.Format(_T("/c CACLS %s /T /e /g %s//%s:F"),strFoldFullPath,strHostName,strCurrentUser);
hInstance = ShellExecute(NULL,_T("open"),_T("cmd.exe"),strTmp,NULL,SW_HIDE);
bResult = ((int) hInstance > 32);
ASSERT(bResult);
return bResult;
}
函数ShareFolderForUser://文件夹设置为共享并指定为指定用户访问
BOOL CWindowTaskHelper::ShareFolderForUser(CString strFoldFullPath,CString strUser,CString strPassword,CString strShareName)
{
BOOL bResult = FALSE;
SECURITY_DESCRIPTOR sd;
#ifdef _DEBUG
CString strTip = _T("");
strTip.Format(_T("path = %s ,User = %s , password = %s ,ready to Share !! "),strFoldFullPath,strUser,strPassword);
VsControlTools::VsMessageBox(strTip,MB_OK,_T("提示"));
#endif
if (SetNetUserAccessPower(strUser,&sd))
{
SHARE_INFO_502 p;
if (strShareName.IsEmpty())
{
strShareName = strFoldFullPath.Right(strFoldFullPath.GetLength() - strFoldFullPath.ReverseFind(_T('//')) - 1);
}
p.shi502_netname = strShareName.GetBuffer();
p.shi502_type = STYPE_DISKTREE; // disk drive
p.shi502_remark = NULL;
p.shi502_permissions = ACCESS_ALL;
p.shi502_max_uses = -1;
p.shi502_current_uses = 0;
p.shi502_path = strFoldFullPath.GetBuffer();
p.shi502_passwd = strPassword.GetBuffer();
p.shi502_reserved = 0;
p.shi502_security_descriptor = &sd;
DWORD parm_err = 0;
NET_API_STATUS res = NetShareAdd(NULL,502,(LPBYTE)&p,&parm_err);
if(res == NO_ERROR || res == 2118)//2118表示共享已经存在
{
#ifdef _DEBUG
CString strTip = _T("");
strTip.Format(_T("共享文件 %s 成功!"),strFoldFullPath);
VsControlTools::VsMessageBox(strTip,MB_OK,_T("提示"));
#endif
bResult = TRUE;
}
#ifdef _DEBUG
else
{
CString strTip = _T("");
strTip.Format(_T("res = %d ,共享文件 %s 失败!"),res,strFoldFullPath);
VsControlTools::VsMessageBox(strTip,MB_OK,_T("提示"));
}
#endif
}
return bResult;
}
函数SetNetUserAccessPower:将文件“属性”下“共享”中的权限只指定为专用账户,配置文件夹 “共享”的权限表
SECURITY_DESCRIPTOR->ACL->ACE->SID
BOOL CWindowTaskHelper::SetNetUserAccessPower(CString strUser,PSECURITY_DESCRIPTOR pSD,DWORD dwPower)
{
BYTE aclBuffer[1024];
PACL pacl=(PACL)&aclBuffer; //声明一个ACL,长度是1024
BYTE sidBuffer[100];
PSID psid=(PSID) &sidBuffer; //声明一个SID,长度是100
DWORD sidBufferSize = 100;
TCHAR domainBuffer[80];
DWORD domainBufferSize = 80; SID_NAME_USE snu;
//初始化一个SD
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
//初始化一个ACL
InitializeAcl(pacl, 1024, ACL_REVISION);
//查找用户,并取该用户的SID
BOOL bResult = LookupAccountName( 0,
strUser.GetBuffer(),
psid,
&sidBufferSize,
domainBuffer,
&domainBufferSize,
&snu);
if (bResult)
{
//设置该用户的Access-Allowed的ACE,其权限为“所有权限”
bResult = AddAccessAllowedAce(pacl, ACL_REVISION, dwPower, psid);
//sidBufferSize = 100;
//domainBufferSize = 80;
添加"SYSTEM"
//bResult = LookupAccountName(0,_T("SYSTEM"),psid,&sidBufferSize,domainBuffer,&domainBufferSize,&snu);
//ASSERT(bResult);
//bResult = AddAccessAllowedAce(pacl, ACL_REVISION, dwPower, psid);
//把ACL设置到SD中
if (bResult)
{
SetSecurityDescriptorDacl(pSD, TRUE, pacl, FALSE);
}
#ifdef _DEBUG
else
{
VsControlTools::VsMessageBox(_T("添加 ACE 失败!"),MB_OK,_T("提示"));
}
#endif
}
#ifdef _DEBUG
else
{
CString strTip = _T("");
strTip.Format(_T("系统中不存在用户 ‘%s’!"),strUser);
VsControlTools::VsMessageBox(strTip,MB_OK,_T("提示"));
}
#endif
return bResult
}
(2)取消共享文件夹
BOOL CWindowTaskHelper::DisableShareFolderForUser(CString strFoldFullPath,CString strShareName)
{
BOOL bResult = FALSE;
CFileFind fileFind;
if (fileFind.FindFile(strFoldFullPath))
{
if (strShareName.IsEmpty())
{
int iPos = strFoldFullPath.GetLength() - strFoldFullPath.ReverseFind(_T('//')) - 1;
strShareName = strFoldFullPath.Right(iPos);
}
NET_API_STATUS res;
res = NetShareDel(NULL, strShareName.GetBuffer(), 0);
if ( NERR_Success == res )
{
bResult = TRUE;
CString strTmp = _T("");
strTmp.Format(_T("/c echo Y|CACLS %s /T /p Everyone:F"),strFoldFullPath); //指定为Everyone访问
HINSTANCE hInstance = ShellExecute(NULL,_T("open"),_T("cmd.exe"),strTmp,NULL,SW_HIDE);
}
#ifdef _DEBUG
else
{
CString strTip =_T("");
strTip.Format(_T("删除共享 %s 失败"),strShareName);
VsControlTools::VsMessageBox(strTip,MB_OK,_T("提示"));
}
#endif
}
else
{
bResult = TRUE;
}
return bResult;
}
上面是以NetShareAdd()和NetShareDel()来实现共享和取消共享
另外一种方法是 以CMD net share 命令 但此种命令我还没找到可以去设置文件夹“共享”下“权限”的方法,并且此种方法是通过文件夹安全属性来限制共享访问,实际使用中会出现访问不了的情况,原因还没找到。建议使用第一中方法设置共享,因为可以设置文件属性中"共享"下的“权限”。
strTmp.Format(_T("/c net share %s=%s"),strShareName,strFoldFullPath);
strTmp.Format(_T("/c net share %s /DELETE"),strShareName);
hInstance = ShellExecute(NULL,_T("open"),_T("cmd.exe"),strTmp,NULL,SW_HIDE);