作業系統環境:不使用簡單檔案分享權限設定,共用資料夾所在磁碟為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);