MFC 修改文件或者文件夹的属性。

本文的程序需在管理员的权限下运行

原文参考:http://m.myexception.cn/vc-mfc/120522.html

可以修改指定文件的或者文件夹的属性

 TCHAR* lpFileName, TCHAR* lpAccountName, DWORD dw

lpFileName指定需要设置文件或者文件夹的路径,lpAccountName为需要设置的组的名字例如:Everyone,

dw为设置的属性的ACCESS_MASK具体的值有以下。参考:https://blogs.msdn.microsoft.com/openspecification/2010/04/01/about-the-access_mask-structure/

 

 

 

 

#define myHeapAlloc(x) (HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,x))

typedef BOOL(WINAPI *SetSecurityDescriptorControlFnPtr)(
	IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
	IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
	IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet);

typedef BOOL(WINAPI *AddAccessAllowedAceExFnPtr)(
	PACL pAcl,
	DWORD dwAceRevision,
	DWORD AceFlags,
	DWORD AccessMask,
	PSID pSid
	);
BOOL AddRights(TCHAR* lpFileName, TCHAR* lpAccountName, DWORD dw)
{
	//lookupAccountName相关变量
	PSID pUserID = NULL;
	DWORD dUserID = 0;
	TCHAR* pDomainName = NULL;
	DWORD dDomainName = 0;
	SID_NAME_USE snuType;

	//第一步,取得传入的用户或用户组的SID
	BOOL check1 = LookupAccountName(NULL, lpAccountName, pUserID, &dUserID, pDomainName, &dDomainName, &snuType);
	pUserID = (PSID)myHeapAlloc(dUserID);
	pDomainName = (TCHAR*)myHeapAlloc(dDomainName * sizeof(TCHAR));
	check1 = LookupAccountName(NULL, lpAccountName, pUserID, &dUserID, pDomainName, &dDomainName, &snuType);

	//第二步,取得文件的安全描述符(SD)
	PSECURITY_DESCRIPTOR pFileSD = NULL;
	DWORD dFileSD = 0;
	SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;

	check1 = GetFileSecurity(lpFileName, secInfo, pFileSD, 0, &dFileSD);
	pFileSD = (PSECURITY_DESCRIPTOR)myHeapAlloc(dFileSD);
	check1 = GetFileSecurity(lpFileName, secInfo, pFileSD, dFileSD, &dFileSD);

	//第三步,初始一个新的SD
	SECURITY_DESCRIPTOR newSD;
	InitializeSecurityDescriptor(&newSD, SECURITY_DESCRIPTOR_REVISION);

	//第四步,从SD中取出DACL
	BOOL bPresent;
	BOOL bDaclDefault;
	PACL pACL = NULL;
	GetSecurityDescriptorDacl(pFileSD, &bPresent, &pACL, &bDaclDefault);

	//第五步,取DACL的内存大小
	ACL_SIZE_INFORMATION aclInfo;
	aclInfo.AceCount = 0;
	aclInfo.AclBytesFree = 0;
	aclInfo.AclBytesInUse = sizeof(ACL);

	// 如果DACL不为空,则取其信息
	if (bPresent) {
		GetAclInformation(pACL, &aclInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation);
	}

	//第六步,计算新的ACL的size
	DWORD dNewAcl = aclInfo.AclBytesInUse + sizeof(ACL_SIZE_INFORMATION) + GetLengthSid(pUserID) - 2;

	//第七步,为新ACL分配内存
	PACL pNewAcl = (PACL)myHeapAlloc(dNewAcl);

	//第八步,初始化新的acl
	InitializeAcl(pNewAcl, dNewAcl, ACL_REVISION2);

	//第九步,如果文件(目录)的DACL有数据则拷贝数据到新的DACL
	UINT newAclIndex = 0;
	UINT curAclIndex = 0;
	LPVOID pTempAce = NULL;
	if (bPresent&&aclInfo.AceCount)
	{
		for (curAclIndex = 0; curAclIndex != aclInfo.AceCount; curAclIndex++)
		{
			GetAce(pACL, curAclIndex, &pTempAce);
			if (((ACCESS_ALLOWED_ACE*)pTempAce)->Header.AceFlags == INHERITED_ACE)
				break;

			if (EqualSid(pUserID, &(((ACCESS_ALLOWED_ACE*)pTempAce)->SidStart)))
			{
				printf("suc");
				continue;
			}

			AddAce(pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize);
			newAclIndex++;
		}
	}

	SetSecurityDescriptorControlFnPtr _SetSecurityDescriptorControl = NULL;
	AddAccessAllowedAceExFnPtr _AddAccessAllowedAceEx = NULL;
	//动态装载函数
	_AddAccessAllowedAceEx = (AddAccessAllowedAceExFnPtr)
		GetProcAddress(GetModuleHandle(TEXT("advapi32.dll")),
			"AddAccessAllowedAceEx");
	_AddAccessAllowedAceEx(pNewAcl, ACL_REVISION2,
		CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE,
		dw, pUserID);

	//拷贝继承的ACE
	if (bPresent&&aclInfo.AceCount)
	{
		for (; curAclIndex != aclInfo.AceCount; curAclIndex++)
		{
			GetAce(pACL, curAclIndex, &pTempAce);
			AddAce(pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize);
		}
	}

	//把新的acl设置到新的sd中
	check1 = SetSecurityDescriptorDacl(&newSD, TRUE, pNewAcl, FALSE);
	check1 = SetFileSecurity(lpFileName, secInfo, &newSD);
	DWORD err = GetLastError();

	return TRUE;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值