转贴:)<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;