2013-08-13 11 views
3

Powershell에서 GetFileSecurity를 ​​PInvoke를 통해 사용하려고합니다. 호출 자체는 작동하지만 System.Runtime.InteropServices.Marshal.GetLastWin32Error 및 GetLastError (테스트 용으로 가져온)는 잘못된 오류 코드를 반환합니다. 새 INVITCH 인스턴스를 시작한 후 스크립트가 처음 실행될 때부터 PInvoke 시그니처에 SetLastError = true이 전혀 영향을 미치지 않는 것으로 보입니다. 둘 다 203 (ERROR_ENVVAR_NOT_FOUND)을 반환하지만 동일한 스크립트를 다시 호출하면 모두 반환됩니다. 0.Powershell, PInvoke 및 GetLastError

빠른 테스트로서 필자는 동등한 C 프로그램을 작성했고 GetLastError는 예상 값 (122 == ERROR_INSUFFICIENT_BUFFER)을 반환합니다.

전 Powershell 및 .NET을 처음 접했으므로 명백한 가짜를 용서하십시오.

$signature = @' 
[DllImport("advapi32.dll", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool GetFileSecurity(
    string lpFileName, 
    int RequestedInformation, 
    byte [] pSecurityDescriptor, 
    uint nLength, 
    out int lpnLengthNeeded 
); 

[DllImport("Kernel32.dll")] 
public static extern uint GetLastError(); 
'@ 

$enum = @' 
namespace Win32 { 
    public enum SECURITY_INFORMATION : uint 
    { 
    OWNER_SECURITY_INFORMATION  = 0x00000001, 
    GROUP_SECURITY_INFORMATION  = 0x00000002, 
    DACL_SECURITY_INFORMATION   = 0x00000004, 
    SACL_SECURITY_INFORMATION   = 0x00000008, 
    UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000, 
    UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000, 
    PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000, 
    PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000 
    } 
} 
'@ 


Add-Type -TypeDefinition $enum 
Add-Type -MemberDefinition $signature -Name API -Namespace Win32 

$len = 0 
$sec = New-Object byte[] 0 
$info = new-object Win32.SECURITY_INFORMATION 
$info = [Win32.SECURITY_INFORMATION]::OWNER_SECURITY_INFORMATION -bor 
     [Win32.SECURITY_INFORMATION]::GROUP_SECURITY_INFORMATION -bor 
     [Win32.SECURITY_INFORMATION]::DACL_SECURITY_INFORMATION 
[Win32.API]::GetFileSecurity("c:\temp", $info, $sec, $sec.Length, [ref] $len) 
[System.Runtime.InteropServices.Marshal]::GetLastWin32Error() 
[Win32.API]::GetLastError() 

답변

2

대신에 직접적으로 꼬집어서, GetFileSecurity 호출을하고 오류를 가져 오는 래퍼 C# 클래스를 만듭니다. PowerShell이 ​​GetFileSecurity() pinvoke 호출과 GetLastWin32Error() pinvoke 호출 사이에서 Win32 API를 호출하면 Win32 오류 번호가 재설정 될 수 있습니다.

+0

감사합니다. 나는 C#으로 모든 것을 작성하는 것을 끝내었고, 훨씬 덜 미친 듯이 더 읽기 쉽도록 보인다. – leromarinvit