C # - AdjustTokenPrivileges не работает на 32-битной версии

Я пытаюсь получить привилегию в своем приложении .NET 4 C #. Этот код работает и привилегия получена успешно, но только в 64-битных системах. Когда тот же код запускается в 32-битной системе, код в AdjustTokenPrivileges не работает с этим исключением:

Неверный доступ к ячейке памяти. (Исключение из HRESULT: 0x800703E6)

Я попытался изменить код, чтобы исправить эту проблему, но ничего не помогло, и я очень озадачен.

Любые идеи о том, почему это не работает в 32-битных системах? Он не работает как в Windows Vista, так и в 32-битной версии 7, так что это специфическая проблема для 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);

person Eaton    schedule 28.11.2012    source источник
comment
Вы проверили, что структура правильного размера в 32-битных системах? Что именно означает 256?   -  person Security Hound    schedule 29.11.2012
comment
Задает размер в байтах буфера, на который указывает параметр PreviousState. Этот параметр может быть равен нулю, если параметр PreviousState равен NULL. Но проблема не в этом. Если я установлю для всех этих необязательных параметров значение null / 0, та же проблема все равно возникнет.   -  person Eaton    schedule 29.11.2012


Ответы (1)


Исправлено, просто нужно было поставить ссылку перед 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);
person Eaton    schedule 29.11.2012