2012-11-28 41 views
3

我想在我的.NET 4 C#應用程序中獲得一個特權。此代碼有效並且成功獲得特權,但僅限於64位系統。當在32位系統上運行相同的代碼時,代碼在AdjustTokenPrivileges上出現此異常將失敗:C# - AdjustTokenPrivileges 32位不工作

對內存位置的訪問無效。 (異常來自HRESULT:0x800703E6)

我試着修改代碼來解決問題,但沒有任何工作,我很難過。

有關爲什麼在32位系統上失敗的任何想法?它在Windows Vista和7 32位上都失敗了,所以它是一個32位的特定問題。

的方法:

 public static void EnableDisablePrivilege(string PrivilegeName, bool EnableDisable) 
    { 
     var htok = IntPtr.Zero; 
     if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TokenAccessLevels.AdjustPrivileges | TokenAccessLevels.Query, out htok)) 
     { 
      Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); 
      return; 
     } 
     var tkp = new TOKEN_PRIVILEGES { PrivilegeCount = 1, Privileges = new LUID_AND_ATTRIBUTES[1] }; 
     LUID luid; 
     if (!LookupPrivilegeValue(null, PrivilegeName, out luid)) 
     { 
      Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); 
      return; 
     } 
     tkp.Privileges[0].LUID = luid; 
     tkp.Privileges[0].Attributes = (uint)(EnableDisable ? 2 : 0); 
     TOKEN_PRIVILEGES prv; 
     uint rb; 
     if (!AdjustTokenPrivileges(htok, false, tkp, 256, out prv, out rb)) 
     { 
      Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); 
      return; 
     } 
    } 

實現:

EnableDisablePrivilege("SeManageVolumePrivilege", true); 

PInvoke的聲明:

 [StructLayout(LayoutKind.Sequential)] 
    public struct LUID 
    { 
     private uint lp; 
     private int hp; 

     public uint LowPart 
     { 
      get { return lp; } 
      set { lp = value; } 
     } 

     public int HighPart 
     { 
      get { return hp; } 
      set { hp = value; } 
     } 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct LUID_AND_ATTRIBUTES 
    { 
     private LUID luid; 
     private uint attributes; 

     public LUID LUID 
     { 
      get { return luid; } 
      set { luid = value; } 
     } 

     public uint Attributes 
     { 
      get { return attributes; } 
      set { attributes = value; } 
     } 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct TOKEN_PRIVILEGES 
    { 
     private uint prvct; 
     [MarshalAs(UnmanagedType.SafeArray, SizeConst = 1)] 
     private LUID_AND_ATTRIBUTES[] privileges; 

     public uint PrivilegeCount 
     { 
      get { return prvct; } 
      set { prvct = value; } 
     } 

     public LUID_AND_ATTRIBUTES[] Privileges 
     { 
      get { return privileges; } 
      set { privileges = value; } 
     } 
    } 

    [DllImport("advapi32", SetLastError = true)] 
    public static extern bool OpenProcessToken(IntPtr ProcessHandle, TokenAccessLevels DesiredAccess, out IntPtr TokenHandle); 

    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, TOKEN_PRIVILEGES NewState, uint BufferLength, out TOKEN_PRIVILEGES PreviousState, out uint ReturnLength); 

    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid); 
+0

您是否驗證過32位系統上的結構是否正確? 256代表什麼? –

+0

「指定PreviousState參數指向的緩衝區的大小(以字節爲單位)。如果PreviousState參數爲NULL,則此參數可以爲零。」但這不是問題。如果我將所有這些可選參數設置爲null/0,仍會發生同樣的問題。 – Eaton

回答

2

固定的,只是不得不把NewState前裁判:

[DllImport("advapi32.dll", SetLastError = true)] 
    public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, uint Bufferlength, IntPtr PreviousState, IntPtr ReturnLength);