to Firejone:<br> 下面的两个函数分别对文件和共享资源添加访问权限,在 D6 + Win2kSvr 中通过。注意<br>AddFileAccessRights 也可对目录操作。<br><br>const<br> ACL_REVISION = 2;<br> ACL_REVISION2 = 2;<br> netapi32lib = 'Netapi32.dll';<br><br>Type<br> NET_API_STATUS = Integer;<br><br> PShare_Info_502 = ^TShare_Info_502;<br> TShare_Info_502 = record<br> shi502_netName: PWideChar;<br> shi502_type: DWORD;<br> shi502_remark: PWideChar;<br> shi502_permissions: DWORD;<br> shi502_max_uses: DWORD;<br> shi502_current_uses : DWORD;<br> shi502_path: PWideChar;<br> shi502_passwd: PWideChar;<br> shi502_reserved: DWORD;<br> shi502_security_descriptor: PSECURITY_DESCRIPTOR;<br> end;<br><br> ACE_HEADER = record<br> AceType: Byte;<br> AceFlags: Byte;<br> AceSize: Word;<br> end;<br><br> ACCESS_ALLOWED_ACE = record<br> Header:ACE_HEADER;<br> Mask:ACCESS_MASK;<br> SidStart
WORD;<br> end;<br><br> ACL_SIZE_INFORMATION = record<br> AceCount: DWORD;<br> AclBytesInUse: DWORD;<br> AclBytesFree: DWORD;<br> end;<br><br> PACE_HEADER = ^ACE_HEADER;<br><br>function NetApiBufferFree(Buffer: Pointer): NET_API_STATUS; stdcall external netapi32lib;<br>function NetShareGetInfo(servername: LPWSTR; netname: LPWSTR; level: DWORD;<br> var butptr: Pointer): NET_API_STATUS; stdcall; external netapi32lib;<br>function NetShareSetInfo(servername: LPWSTR; netname: LPWSTR; leve: DWORD;<br> const buf: Pointer; parm_err: PDWORD): NET_API_STATUS; stdcall; external netapi32lib;<br><br>//添加文件、目录访问权限,对应于对象属性页中"安全" 页中的设置<br>function AddFileAccesRights(const FileName, UserName: string;<br> dwAccessMask: DWORD): boolean;<br>var<br> // SID variables<br> snuType : SID_NAME_USE;<br> szDomain : PChar;<br> cbDomain: DWORD;<br> pUserSID: Pointer;<br> cbUserSID: DWORD;<br> // File SD variables.<br> pFileSD: PSECURITY_DESCRIPTOR;<br> cbFileSD: DWORD;<br> // New SD variables.<br> pNewSD: PSECURITY_DESCRIPTOR;<br> // ACL variables.<br> p_ACL : PACL;<br> fDaclPresent, fDaclDefaulted : LongBool;<br> AclInfo: ACL_SIZE_INFORMATION;<br> // New ACL variables.<br> pNewACL : PACL;<br> cbNewACL: DWORD;<br> // Temporary ACE.<br> pTempAce: Pointer;<br> CurrentAceIndex : Cardinal;<br>begin<br> szDomain := nil;<br> cbDomain := 0;<br> pUserSID := nil;<br> cbUserSID := 0;<br> pFileSD := nil;<br> cbFileSD := 0;<br> pNewSD := nil;<br> p_ACL := nil;<br> pNewACL := nil;<br> pTempAce := nil;<br><br> //<br> // STEP 1: Get SID for given user.<br> //<br> Result := LookupAccountName(nil, PChar(UserName),<br> pUserSID, cbUserSID, szDomain, cbDomain, snuType);<br><br> // API should have failed with insufficient buffer.<br> if (not Result) and (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then<br> RaiseLastWin32Error;<br><br> pUserSID := AllocMem(cbUserSID);<br> szDomain := AllocMem(cbDomain);<br> try<br> Result := LookupAccountName(nil, PChar(UserName),<br> pUserSID, cbUserSID, szDomain, cbDomain, snuType);<br><br> if (not Result) then<br> RaiseLastWin32Error;<br><br> // STEP 2: Get security descriptor (SD) for file.<br> Result := GetFileSecurity(PChar(FileName),<br> DACL_SECURITY_INFORMATION, pFileSD, 0, cbFileSD);<br><br> if (not Result) and (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then<br> RaiseLastWin32Error;<br><br> pFileSD := AllocMem(cbFileSD);<br><br> Result := GetFileSecurity(PChar(FileName),<br> DACL_SECURITY_INFORMATION, pFileSD, cbFileSD, cbFileSD);<br> if (not Result) then<br> RaiseLastWin32Error;<br><br> // STEP 3: Initialize new SD.<br> pNewSD := AllocMem(cbFileSD); // Should be same size as FileSD.<br><br> if (not InitializeSecurityDescriptor(pNewSD,<br> SECURITY_DESCRIPTOR_REVISION)) then<br> RaiseLastWin32Error;<br><br> // STEP 4: Get DACL from SD.<br> if (not GetSecurityDescriptorDacl(pFileSD, fDaclPresent, p_ACL,<br> fDaclDefaulted)) then<br> RaiseLastWin32Error;<br> // STEP 5: Get size information for DACL.<br> AclInfo.AceCount := 0; // Assume NULL DACL.<br> AclInfo.AclBytesFree := 0;<br> AclInfo.AclBytesInUse := SizeOf(ACL);<br><br> if (fDaclPresent and Assigned(p_ACL)) then<br> begin<br> if (not GetAclInformation(p_ACL^, @AclInfo,<br> SizeOf(ACL_SIZE_INFORMATION), AclSizeInformation)) then<br> RaiseLastWin32Error;<br><br> // STEP 6: Compute size needed for the new ACL.<br> cbNewACL := AclInfo.AclBytesInUse + SizeOf(ACCESS_ALLOWED_ACE)<br> + GetLengthSid(pUserSID) - SizeOf(DWORD);<br><br> // STEP 7: Allocate memory for new ACL.<br> pNewACL := AllocMem(cbNewACL);<br><br> // STEP 8: Initialize the new ACL.<br> if (not InitializeAcl(pNewACL^, cbNewACL, ACL_REVISION2)) then<br> RaiseLastWin32Error;<br> // STEP 9: If DACL is present, copy it to a new DACL.<br> if (fDaclPresent) then<br> begin<br> // STEP 10: Copy the file's ACEs to the new ACL.<br> if (AclInfo.AceCount > 0) then<br> begin<br> for CurrentAceIndex := 0 to AclInfo.AceCount - 1 do<br> begin<br> // STEP 11: Get an ACE.<br> if (not GetAce(p_ACL^, CurrentAceIndex, pTempAce)) then<br> RaiseLastWin32Error;<br> // STEP 12: Add the ACE to the new ACL.<br> if (not AddAce(pNewACL^, ACL_REVISION, MAXDWORD, pTempAce,<br> PACE_HEADER(pTempAce)^.AceSize)) then<br> RaiseLastWin32Error;<br> end<br> end<br> end;<br><br> // STEP 13: Add the access-allowed ACE to the new DACL.<br> if (not AddAccessAllowedAce(pNewACL^, ACL_REVISION2, dwAccessMask,<br> pUserSID)) then<br> RaiseLastWin32Error;<br><br> // STEP 14: Set the new DACL to the file SD.<br> if (not SetSecurityDescriptorDacl(pNewSD, True, pNewACL, False)) then<br> RaiseLastWin32Error;<br><br> // STEP 15: Set the SD to the File.<br> if (not SetFileSecurity(PChar(FileName), DACL_SECURITY_INFORMATION,<br> pNewSD)) then<br> RaiseLastWin32Error;<br> Result := True;<br> end;<br> finally<br> // STEP 16: Free allocated memory<br> if Assigned(pUserSID) then<br> FreeMem(pUserSID);<br> if Assigned(szDomain) then<br> FreeMem(szDomain);<br> if Assigned(pFileSD) then<br> FreeMem(pFileSD);<br> if Assigned(pNewSD) then<br> FreeMem(pNewSD);<br> if Assigned(pNewACL) then<br> FreeMem(pNewACL);<br> end;<br>end;<br>//添加共享资源的访问权限,对应于对象属性页中"共享" 页中的设置,注意 ShareName<br>//对应的资源应已被设置为共享。这可以通过 NetShareAdd API 设置<br>function AddShareAccesRights(const ShareName: WideString;<br> const UserName: string; dwAccessMask: DWORD): boolean;<br>var<br> // SID variables<br> snuType : SID_NAME_USE;<br> szDomain : PChar;<br> cbDomain: DWORD;<br> pUserSID: Pointer;<br> cbUserSID: DWORD;<br> // File SD variables.<br> pShareSD: PSECURITY_DESCRIPTOR;<br> // New SD variables.<br> pNewSD: PSECURITY_DESCRIPTOR;<br> // ACL variables.<br> p_ACL : PACL;<br> fDaclPresent, fDaclDefaulted : LongBool;<br> AclInfo: ACL_SIZE_INFORMATION;<br> //Share_Info variables<br> BufPtr: PShare_Info_502;<br> ShareInfo: TShare_Info_502;<br> // New ACL variables.<br> pNewACL : PACL;<br> cbNewACL: DWORD;<br> // Temporary ACE.<br> pTempAce: Pointer;<br> CurrentAceIndex : Cardinal;<br> parm_err: DWORD;<br>begin<br> szDomain := nil;<br> cbDomain := 0;<br> pUserSID := nil;<br> cbUserSID := 0;<br> pNewSD := nil;<br> p_ACL := nil;<br> pNewACL := nil;<br> pTempAce := nil;<br> BufPtr := nil;<br><br> // STEP 1: Get SID for given user.<br> Result := LookupAccountName(nil, PChar(UserName),<br> pUserSID, cbUserSID, szDomain, cbDomain, snuType);<br><br> // API should have failed with insufficient buffer.<br> if (not Result) and (GetLastError <> ERROR_INSUFFICIENT_BUFFER) then<br> RaiseLastWin32Error;<br><br> pUserSID := AllocMem(cbUserSID);<br> szDomain := AllocMem(cbDomain);<br> try<br> Result := LookupAccountName(nil, PChar(UserName),<br> pUserSID, cbUserSID, szDomain, cbDomain, snuType);<br><br> if (not Result) then<br> RaiseLastWin32Error;<br><br> // STEP 2: Get security descriptor (SD) for ShareRes.<br> if (NetShareGetInfo(nil, PWideChar(ShareName), 502, Pointer(BufPtr))<br> = ERROR_SUCCESS) then<br> begin<br> if not IsValidSecurityDescriptor(BufPtr^.shi502_security_descriptor) then<br> RaiseLastWin32Error;<br> end<br> else<br> RaiseLastWin32Error;<br><br> pShareSD := BufPtr^.shi502_security_descriptor;<br> // STEP 3: Initialize new SD.<br> pNewSD := AllocMem(GetSecurityDescriptorLength(pShareSD));<br><br> if (not InitializeSecurityDescriptor(pNewSD,<br> SECURITY_DESCRIPTOR_REVISION)) then<br> RaiseLastWin32Error;<br><br> // STEP 4: Get DACL from SD.<br> if (not GetSecurityDescriptorDacl(pShareSD, fDaclPresent, p_ACL,<br> fDaclDefaulted)) then<br> RaiseLastWin32Error;<br> //<br> // STEP 5: Get size information for DACL.<br> //<br> AclInfo.AceCount := 0; // Assume NULL DACL.<br> AclInfo.AclBytesFree := 0;<br> AclInfo.AclBytesInUse := SizeOf(ACL);<br><br> if (fDaclPresent and Assigned(p_ACL)) then<br> begin<br> if (not GetAclInformation(p_ACL^, @AclInfo,<br> SizeOf(ACL_SIZE_INFORMATION), AclSizeInformation)) then<br> RaiseLastWin32Error;<br><br> // STEP 6: Compute size needed for the new ACL.<br> cbNewACL := AclInfo.AclBytesInUse + SizeOf(ACCESS_ALLOWED_ACE)<br> + GetLengthSid(pUserSID) - SizeOf(DWORD);<br><br> // STEP 7: Allocate memory for new ACL.<br> pNewACL := AllocMem(cbNewACL);<br><br> // STEP 8: Initialize the new ACL.<br> if (not InitializeAcl(pNewACL^, cbNewACL, ACL_REVISION2)) then<br> RaiseLastWin32Error;<br> // STEP 9: If DACL is present, copy it to a new DACL.<br> if (fDaclPresent) then<br> begin<br> // STEP 10: Copy the file's ACEs to the new ACL.<br> if (AclInfo.AceCount > 0) then<br> begin<br> for CurrentAceIndex := 0 to AclInfo.AceCount - 1 do<br> begin<br> // STEP 11: Get an ACE.<br> if (not GetAce(p_ACL^, CurrentAceIndex, pTempAce)) then<br> RaiseLastWin32Error;<br> // STEP 12: Add the ACE to the new ACL.<br> if (not AddAce(pNewACL^, ACL_REVISION, MAXDWORD, pTempAce,<br> PACE_HEADER(pTempAce)^.AceSize)) then<br> RaiseLastWin32Error;<br> end<br> end<br> end;<br><br> // STEP 13: Add the access-allowed ACE to the new DACL.<br> if (not AddAccessAllowedAce(pNewACL^, ACL_REVISION2, dwAccessMask,<br> pUserSID)) then<br> RaiseLastWin32Error;<br><br> // STEP 14: Set the new DACL to the new Share SD.<br> if (not SetSecurityDescriptorDacl(pNewSD, True, pNewACL, False)) then<br> RaiseLastWin32Error;<br><br> // STEP 15: Set the new SD to the ShareRes.<br> Move(BufPtr^,ShareInfo, SizeOf(ShareInfo));<br> ShareInfo.shi502_security_descriptor := pNewSD;<br> if not (NetShareSetInfo(nil, PWideChar(ShareName), 502, @ShareInfo,<br> @parm_err) = ERROR_SUCCESS) then<br> RaiseLastWin32Error;<br><br> Result := True;<br> end;<br> finally<br> // STEP 16: Free allocated memory<br> if Assigned(pUserSID) then<br> FreeMem(pUserSID);<br> if Assigned(szDomain) then<br> FreeMem(szDomain);<br> if Assigned(pNewSD) then<br> FreeMem(pNewSD);<br> if Assigned(pNewACL) then<br> FreeMem(pNewACL);<br> if Assigned(BufPtr) then<br> NetApiBufferFree(BufPtr);<br> end;<br>end;<br>