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

    技术2022-05-20  40

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

     


    最新回复(0)