现在的位置: 首页 > 综合 > 正文

转:设置指定账户的网络共享文件夹(VC++)

2012年05月08日 ⁄ 综合 ⁄ 共 7298字 ⁄ 字号 评论关闭

操作系统环境:不使用简单文件共享,共享文件夹所在磁盘为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);

 

抱歉!评论已关闭.