diff --git a/tst/passthrough-dotnet/Program.cs b/tst/passthrough-dotnet/Program.cs index 3b6c98b9..2b7a2ea9 100644 --- a/tst/passthrough-dotnet/Program.cs +++ b/tst/passthrough-dotnet/Program.cs @@ -771,7 +771,7 @@ namespace passthrough if (null == PassThrough || null == MountPoint) throw new CommandLineUsageException(); - //EnableBackupRestorePrivileges(); + EnableBackupRestorePrivileges(); if (null != DebugLogFile) if (0 > FileSystem.SetDebugLogFile(DebugLogFile)) @@ -840,43 +840,73 @@ namespace passthrough throw new CommandLineUsageException(); } -#if false /* * Turns out there is no managed way to adjust privileges. * So we have to write our own using P/Invoke. Joy! + * + * NOTE: The P/Invoke definitions below are not for general use. */ - static NTSTATUS EnableBackupRestorePrivileges(VOID) + private struct LUID_AND_ATTRIBUTES { - union - { - TOKEN_PRIVILEGES P; - UINT8 B[sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)]; - } Privileges; - HANDLE Token; + public UInt64 Luid; + public UInt32 Attributes; + } + [StructLayout(LayoutKind.Sequential)] + private struct TOKEN_PRIVILEGES + { + public UInt32 PrivilegeCount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public LUID_AND_ATTRIBUTES[] Privileges; + } + [DllImport("advapi32.dll", SetLastError = true)] + private static extern Boolean OpenProcessToken( + IntPtr ProcessHandle, + UInt32 DesiredAccess, + out IntPtr TokenHandle); + [DllImport("kernel32.dll", SetLastError = true)] + private static extern Boolean CloseHandle( + IntPtr hObject); + [DllImport("advapi32.dll", SetLastError = true)] + private static extern Boolean LookupPrivilegeValueW( + [MarshalAs(UnmanagedType.LPWStr)] String lpSystemName, + [MarshalAs(UnmanagedType.LPWStr)] String lpName, + out UInt64 lpLuid); + [DllImport("advapi32.dll", SetLastError = true)] + private static extern Boolean AdjustTokenPrivileges( + IntPtr TokenHandle, + Boolean DisableAllPrivileges, + ref TOKEN_PRIVILEGES NewState, + UInt32 BufferLength, + IntPtr PreviousState, + IntPtr ReturnLength); + private static Int32 EnableBackupRestorePrivileges() + { + TOKEN_PRIVILEGES Privileges; + IntPtr Token; - Privileges.P.PrivilegeCount = 2; - Privileges.P.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - Privileges.P.Privileges[1].Attributes = SE_PRIVILEGE_ENABLED; + Privileges = default(TOKEN_PRIVILEGES); + Privileges.PrivilegeCount = 2; + Privileges.Privileges = new LUID_AND_ATTRIBUTES[2]; + Privileges.Privileges[0].Attributes = 2/*SE_PRIVILEGE_ENABLED*/; + Privileges.Privileges[1].Attributes = 2/*SE_PRIVILEGE_ENABLED*/; - if (!LookupPrivilegeValueW(0, SE_BACKUP_NAME, &Privileges.P.Privileges[0].Luid) || - !LookupPrivilegeValueW(0, SE_RESTORE_NAME, &Privileges.P.Privileges[1].Luid)) - return NtStatusFromWin32(GetLastError()); + if (!LookupPrivilegeValueW(null, "SeBackupPrivilege", out Privileges.Privileges[0].Luid) || + !LookupPrivilegeValueW(null, "SeRestorePrivilege", out Privileges.Privileges[1].Luid)) + return Marshal.GetLastWin32Error(); - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &Token)) - return NtStatusFromWin32(GetLastError()); + if (!OpenProcessToken((IntPtr)(-1), 0x0020/*TOKEN_ADJUST_PRIVILEGES*/, out Token)) + return Marshal.GetLastWin32Error(); - if (!AdjustTokenPrivileges(Token, FALSE, &Privileges.P, 0, 0, 0)) + if (!AdjustTokenPrivileges(Token, false, ref Privileges, 0, IntPtr.Zero, IntPtr.Zero)) { CloseHandle(Token); - return NtStatusFromWin32(GetLastError()); + return Marshal.GetLastWin32Error(); } CloseHandle(Token); - return STATUS_SUCCESS; + return 0; } -#endif private Ptfs _Ptfs; }