private unsafe void UnsafeEnableDisablePrivileges(TokenPrivileges privileges) { var privBytes = privileges.GetNativeTokenPrivileges(); fixed (byte* priv = privBytes) { uint cbLength; Win32.SetLastError(Win32.SUCCESS); var rc = Win32.AdjustTokenPrivileges( _handle, Win32.FALSE, (IntPtr)priv, 0, IntPtr.Zero, out cbLength); Win32.CheckCall(rc); // Additional check: privilege can't be added, and in that case, // rc indicates a success, but GetLastError() has a specific meaning. if (Marshal.GetLastWin32Error() == Win32.ERROR_NOT_ALL_ASSIGNED) Win32.ThrowLastError(); } }
/// <summary> /// Enable a single privilege on the process. /// </summary> /// <param name="privilege"></param> /// <exception cref=""> /// Throws an exception if the privilege is not present /// in the privilege list of the process /// </exception> public void EnablePrivilege(TokenPrivilege privilege) { var privs = new TokenPrivileges { privilege }; EnableDisablePrivileges(privs); }
private void EnableDisablePrivileges(TokenPrivileges privileges) { UnsafeEnableDisablePrivileges(privileges); }
/// <summary> /// Gets the absolute path of the target of a symlink of junction /// </summary> /// <param name="linkPath">The path to the symlink or junction</param> /// <returns>The absolute path to the target of <paramref name="linkPath"/></returns> /// <exception cref="Exception">Some generic error</exception> public static string GetTarget(string linkPath) { // We need to get backup privileges IntPtr tokenHandle; var tokenPrivileges = new TokenPrivileges { privileges = new LuidAndAttributes[1] }; var success = OpenProcessToken(Process.GetCurrentProcess().Handle, DesiredAccessToken, out tokenHandle); if (!success) throw new Exception("Couldn't get all the privileges to do this"); success = LookupPrivilegeValue(null, DesiredAccessName, out tokenPrivileges.privileges[0].luid); if(!success) throw new Exception("Couldn't get all the privileges to do this"); tokenPrivileges.privilegeCount = 1; tokenPrivileges.privileges[0].attributes = DesiredAccessEnabled; success = AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivileges, Marshal.SizeOf(tokenPrivileges), IntPtr.Zero, IntPtr.Zero); CloseHandle(tokenHandle); if (!success) throw new Exception("Couldn't get all the privileges to do this"); // Open the file and do stuff var fileHandle = CreateFile(linkPath, FileAccess.Read, FileShare.ReadWrite, 0, FileMode.Open, FileFlagOpenReparsePoint | FileFlagBackupSemantics, IntPtr.Zero); if(fileHandle.ToInt32() < 0) throw new Exception("Could not open the location"); ReparseDataBuffer buffer; uint bytesReturned; success = DeviceIoControl(fileHandle, ControlCode, IntPtr.Zero, 0, out buffer, (16 * 1024), out bytesReturned, IntPtr.Zero); if (!success) { CloseHandle(fileHandle); throw new Exception("Could not open the location"); } // Get data from buffer string relativeString, absoluteString; var subsString = ""; var printString = ""; if (buffer.reparseTag == ReparseTagSymlink) { subsString = new string(buffer.reparseTarget, (buffer.subsNameOffset / 2 + 2), buffer.subsNameLength /2); printString = new string(buffer.reparseTarget, (buffer.printNameOffset / 2 + 2), buffer.printNameLength / 2); } else if (buffer.reparseTag == ReparseTagMountpoint) { subsString = new string(buffer.reparseTarget, buffer.subsNameOffset / 2, buffer.subsNameLength / 2); printString = new string(buffer.reparseTarget, buffer.printNameOffset / 2, buffer.printNameLength / 2); } if (!string.IsNullOrEmpty(printString)) { relativeString = printString; } else { relativeString = subsString; if (relativeString.StartsWith(@"\??\")) { relativeString = relativeString.Substring(4); } } // Fix relative paths if (buffer.reparseTag == ReparseTagSymlink && (relativeString.Length < 2 || relativeString[1] != ':')) { absoluteString = Path.Combine(linkPath, @"..\" + relativeString); } else { absoluteString = relativeString; } if (absoluteString.EndsWith("\\")) { absoluteString = absoluteString.Substring(0, absoluteString.Length - 1); } CloseHandle(fileHandle); return absoluteString; }
private static extern bool AdjustTokenPrivileges(IntPtr tokenHandle, [MarshalAs(UnmanagedType.Bool)] bool disableAllPrivileges, ref TokenPrivileges newState, Int32 bufferLength, IntPtr previousState, IntPtr returnLength);
/// <summary> /// Gets the absolute path of the target of a symlink of junction /// </summary> /// <param name="linkPath">The path to the symlink or junction</param> /// <returns>The absolute path to the target of <paramref name="linkPath"/></returns> /// <exception cref="Exception">Some generic error</exception> public static string GetTarget(string linkPath) { // We need to get backup privileges IntPtr tokenHandle; var tokenPrivileges = new TokenPrivileges { privileges = new LuidAndAttributes[1] }; var success = OpenProcessToken(Process.GetCurrentProcess().Handle, DesiredAccessToken, out tokenHandle); if (!success) { throw new Exception("Couldn't get all the privileges to do this"); } success = LookupPrivilegeValue(null, DesiredAccessName, out tokenPrivileges.privileges[0].luid); if (!success) { throw new Exception("Couldn't get all the privileges to do this"); } tokenPrivileges.privilegeCount = 1; tokenPrivileges.privileges[0].attributes = DesiredAccessEnabled; success = AdjustTokenPrivileges(tokenHandle, false, ref tokenPrivileges, Marshal.SizeOf(tokenPrivileges), IntPtr.Zero, IntPtr.Zero); CloseHandle(tokenHandle); if (!success) { throw new Exception("Couldn't get all the privileges to do this"); } // Open the file and do stuff var fileHandle = CreateFile(linkPath, FileAccess.Read, FileShare.ReadWrite, 0, FileMode.Open, FileFlagOpenReparsePoint | FileFlagBackupSemantics, IntPtr.Zero); if (fileHandle.ToInt32() < 0) { throw new Exception("Could not open the location"); } ReparseDataBuffer buffer; uint bytesReturned; success = DeviceIoControl(fileHandle, ControlCode, IntPtr.Zero, 0, out buffer, (16 * 1024), out bytesReturned, IntPtr.Zero); if (!success) { CloseHandle(fileHandle); throw new Exception("Could not open the location"); } // Get data from buffer string relativeString, absoluteString; var subsString = ""; var printString = ""; if (buffer.reparseTag == ReparseTagSymlink) { subsString = new string(buffer.reparseTarget, (buffer.subsNameOffset / 2 + 2), buffer.subsNameLength / 2); printString = new string(buffer.reparseTarget, (buffer.printNameOffset / 2 + 2), buffer.printNameLength / 2); } else if (buffer.reparseTag == ReparseTagMountpoint) { subsString = new string(buffer.reparseTarget, buffer.subsNameOffset / 2, buffer.subsNameLength / 2); printString = new string(buffer.reparseTarget, buffer.printNameOffset / 2, buffer.printNameLength / 2); } if (!string.IsNullOrEmpty(printString)) { relativeString = printString; } else { relativeString = subsString; if (relativeString.StartsWith(@"\??\")) { relativeString = relativeString.Substring(4); } } // Fix relative paths if (buffer.reparseTag == ReparseTagSymlink && (relativeString.Length < 2 || relativeString[1] != ':')) { absoluteString = Path.Combine(linkPath, @"..\" + relativeString); } else { absoluteString = relativeString; } if (absoluteString.EndsWith("\\")) { absoluteString = absoluteString.Substring(0, absoluteString.Length - 1); } CloseHandle(fileHandle); return(absoluteString); }