/// <summary> /// Gets the name of the user for the <paramref name="process"/> given. /// </summary> /// <param name="process">Process to get username for.</param> /// <returns>Name of the user for the <paramref name="process"/> in the <c>DOMAIN\username</c> format.</returns> /// <exception cref="ArgumentNullException"><paramref name="process"/> is <see langword="null"/>.</exception> /// <exception cref="InvalidOperationException"> /// Process token cannot be obtained. /// <para>-or-</para> /// Process token information cannot be retrieved. /// <para>-or-</para> /// Account information cannot be found. /// </exception> public static string GetUserNameForProcess(Process process) { if (process == null) { throw new ArgumentNullException(nameof(process)); } SafeTokenHandle tokenHandle; if (!NativeMethods.OpenProcessToken(process.Handle, TokenAccessRights.TokenQuery, out tokenHandle)) { int hr = Marshal.GetHRForLastWin32Error(); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to open process token: 0x{0:X8}", hr), Marshal.GetExceptionForHR(hr)); } using (tokenHandle) using (ResizableBuffer buffer = new ResizableBuffer(ProcessHelper.DefaultBufferSize)) { int actualSize; if (!NativeMethods.GetTokenInformation(tokenHandle, TokenInformationClass.TokenUser, buffer.DangerousGetPointer(), buffer.ByteLength, out actualSize)) { int hr = Marshal.GetHRForLastWin32Error(); if (hr != NativeMethods.ErrorInsufficientBuffer) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to get token information: 0x{0:X8}", hr), Marshal.GetExceptionForHR(hr)); } // Resize and retry. buffer.Resize(actualSize); if (!NativeMethods.GetTokenInformation(tokenHandle, TokenInformationClass.TokenUser, buffer.DangerousGetPointer(), buffer.ByteLength, out actualSize)) { hr = Marshal.GetHRForLastWin32Error(); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to get token information: 0x{0:X8}", hr), Marshal.GetExceptionForHR(hr)); } } TokenUser tokenUser = (TokenUser)Marshal.PtrToStructure(buffer.DangerousGetPointer(), typeof(TokenUser)); return(ProcessHelper.GetUserNameForSid(tokenUser.User.Sid)); } }
private void ProcessNotification(ResizableBuffer resizableBuffer) { IntPtr bufferPointer = resizableBuffer.DangerousGetPointer(); // Marshal the notification received. DriverNotificationHeader header = (DriverNotificationHeader)Marshal.PtrToStructure(bufferPointer, typeof(DriverNotificationHeader)); DriverNotification notification = new DriverNotification { Type = header.Type, DataLength = header.DataLength, Data = bufferPointer + this.notificationHeaderSize }; // Get the reply object from the user-defined handler. object reply = null; int handlerResult = (int)NativeMethods.Ok; try { reply = this.handler(notification); } catch (Exception e) { handlerResult = Marshal.GetHRForException(e); NotificationsMonitor.Logger.Error(e, "Notification handler threw an exception."); } // Driver is not expecting any reply. if (header.ReplyLength == 0) { if (reply != null) { NotificationsMonitor.Logger.Warn(CultureInfo.InvariantCulture, "Driver is not expecting any reply, but reply object is returned from handler: {0}", reply.GetType()); } return; } int replySize = this.replyHeaderSize + MarshalingHelper.GetObjectSize(reply); if (replySize > header.ReplyLength) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Reply ({0} bytes) is bigger than the one expected by the driver ({1} bytes).", replySize, header.ReplyLength)); } DriverReplyHeader replyHeader = new DriverReplyHeader { MessageId = header.MessageId, // Notify driver about the exception thrown, if any. Status = handlerResult }; // Adjust the buffer to fit the reply. resizableBuffer.Resize(replySize); bufferPointer = resizableBuffer.DangerousGetPointer(); // Marshal reply to the output buffer. MarshalingHelper.MarshalObjectsToPointer(bufferPointer, replySize, replyHeader, reply); // And send it to the driver. uint hr = NativeMethods.FilterReplyMessage(this.filterPortHandle, bufferPointer, (uint)replySize); if (hr != NativeMethods.Ok) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to send reply: 0x{0:X8}", hr), Marshal.GetExceptionForHR(unchecked((int)hr))); } }
/// <summary> /// Gets the reparse point data from the <paramref name="path"/> given. /// </summary> /// <typeparam name="T"> /// Reparse point buffer data type. /// It should not contain reparse point data header information, because this function handles it separately. /// </typeparam> /// <param name="path">Path to the reparse point to get data from.</param> /// <param name="reparseTag">Reparse point tag.</param> /// <param name="reparseGuid">Reparse point <see cref="Guid"/>. Must be specified, if the <paramref name="reparseTag"/> is a non-Microsoft tag.</param> /// <returns>Reparse point data found.</returns> /// <exception cref="ArgumentNullException"><paramref name="path"/> is <see langword="null"/> or empty.</exception> /// <exception cref="ArgumentException"> /// <paramref name="reparseTag"/> is a Microsoft tag, but the <paramref name="reparseGuid"/> is not <see langword="null"/>. /// <para>-or-</para> /// <paramref name="reparseTag"/> is a non-Microsoft tag, but the <paramref name="reparseGuid"/> is <see langword="null"/>. /// </exception> /// <exception cref="InvalidOperationException"> /// <paramref name="path"/> cannot be found. /// <para>-or-</para> /// <paramref name="path"/> is not a reparse point. /// <para>-or-</para> /// <paramref name="path"/> reparse point cannot be opened. /// <para>-or-</para> /// <paramref name="path"/> reparse point data cannot be retrieved. /// <para>-or-</para> /// <paramref name="path"/> reparse point tag or GUID is invalid. /// </exception> /// <remarks> /// See <c>http://msdn.microsoft.com/en-us/library/windows/desktop/aa365511(v=vs.85).aspx</c> for more details about reparse point tags. /// </remarks> public static T GetReparsePointData <T>(string path, int reparseTag, Guid?reparseGuid) where T : struct { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } ReparsePointHelper.ValidateTagAndGuid(reparseTag, reparseGuid); bool isMicrosoftTag = ReparsePointHelper.IsMicrosoftTag(reparseTag); string normalizedPath = LongPathCommon.NormalizePath(path); bool isDirectory; if (!LongPathCommon.Exists(normalizedPath, out isDirectory)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Path does not exist: {0}", path)); } // Check, whether the path given is a reparse point. FileAttributes attributes = isDirectory ? new LongPathDirectoryInfo(normalizedPath).Attributes : LongPathFile.GetAttributes(normalizedPath); if (!attributes.HasFlag(FileAttributes.ReparsePoint)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Path given is not a reparse point: {0}", path)); } using (SafeFileHandle handle = NativeMethods.CreateFile( normalizedPath, AccessRights.GenericRead, FileShare.Read, IntPtr.Zero, FileMode.Open, EFileAttributes.OpenReparsePoint | EFileAttributes.BackupSemantics, IntPtr.Zero)) { if (handle.IsInvalid) { Exception nativeException = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to open reparse point: {0}", path), nativeException); } // Make sure that the buffer will be large enough to hold reparse point data. int initialBufferSize = Math.Max(ReparsePointHelper.BufferSize, Marshal.SizeOf(typeof(ReparseGuidDataBufferHeader)) + Marshal.SizeOf(typeof(T))); using (ResizableBuffer buffer = new ResizableBuffer(initialBufferSize)) { // Query the reparse point data. int bytesReturned; bool success = NativeMethods.DeviceIoControl( handle, ReparsePointHelper.GetReparsePointControlCode, IntPtr.Zero, 0, buffer.DangerousGetPointer(), buffer.ByteLength, out bytesReturned, IntPtr.Zero); int headerSize = isMicrosoftTag ? Marshal.SizeOf(typeof(ReparseDataBufferHeader)) : Marshal.SizeOf(typeof(ReparseGuidDataBufferHeader)); if (!success) { int hr = Marshal.GetHRForLastWin32Error(); if (hr != NativeMethods.ErrorMoreData) { Exception nativeException = Marshal.GetExceptionForHR(hr); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to get the reparse point data: {0}", path), nativeException); } // Read the ReparseDataLength value, and resize buffer to fit the data. int dataSize = headerSize + Marshal.ReadInt16(buffer.DangerousGetPointer(), 4 /* sizeof(uint) */); buffer.Resize(dataSize); success = NativeMethods.DeviceIoControl( handle, ReparsePointHelper.GetReparsePointControlCode, IntPtr.Zero, 0, buffer.DangerousGetPointer(), buffer.ByteLength, out bytesReturned, IntPtr.Zero); if (!success) { Exception nativeException = Marshal.GetExceptionForHR(hr); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to get the reparse point data: {0}", path), nativeException); } } // Make sure that the reparse tag is correct. uint tag = unchecked ((uint)Marshal.ReadInt32(buffer.DangerousGetPointer())); if (tag != unchecked ((uint)reparseTag)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Reparse point tag is invalid. Path has 0x{0:X8}, but 0x{1:X8} is specified.", tag, reparseTag)); } // Make sure that the reparse point GUID is correct, if needed. if (!isMicrosoftTag) { ReparseGuidDataBufferHeader header = (ReparseGuidDataBufferHeader)Marshal.PtrToStructure(buffer.DangerousGetPointer(), typeof(ReparseGuidDataBufferHeader)); if (header.ReparseGuid != reparseGuid) { throw new InvalidOperationException(string.Format( CultureInfo.InvariantCulture, "Reparse point GUID is invalid. Path has {0}, but {1} is specified.", header.ReparseGuid.ToString("N"), reparseGuid.Value.ToString("N"))); } } return((T)Marshal.PtrToStructure(buffer.DangerousGetPointer() + headerSize, typeof(T))); } } }
/// <summary> /// Gets the name of the user for the <paramref name="process"/> given. /// </summary> /// <param name="process">Process to get username for.</param> /// <returns>Name of the user for the <paramref name="process"/> in the <c>DOMAIN\username</c> format.</returns> /// <exception cref="ArgumentNullException"><paramref name="process"/> is <see langword="null"/>.</exception> /// <exception cref="InvalidOperationException"> /// Process token cannot be obtained. /// <para>-or-</para> /// Process token information cannot be retrieved. /// <para>-or-</para> /// Account information cannot be found. /// </exception> public static string GetUserNameForProcess(Process process) { if (process == null) { throw new ArgumentNullException(nameof(process)); } SafeTokenHandle tokenHandle; if (!NativeMethods.OpenProcessToken(process.Handle, TokenAccessRights.TokenQuery, out tokenHandle)) { int hr = Marshal.GetHRForLastWin32Error(); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to open process token: 0x{0:X8}", hr), Marshal.GetExceptionForHR(hr)); } using (tokenHandle) using (ResizableBuffer buffer = new ResizableBuffer(ProcessHelper.DefaultBufferSize)) { int actualSize; if (!NativeMethods.GetTokenInformation(tokenHandle, TokenInformationClass.TokenUser, buffer.DangerousGetPointer(), buffer.ByteLength, out actualSize)) { int hr = Marshal.GetHRForLastWin32Error(); if (hr != NativeMethods.ErrorInsufficientBuffer) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to get token information: 0x{0:X8}", hr), Marshal.GetExceptionForHR(hr)); } // Resize and retry. buffer.Resize(actualSize); if (!NativeMethods.GetTokenInformation(tokenHandle, TokenInformationClass.TokenUser, buffer.DangerousGetPointer(), buffer.ByteLength, out actualSize)) { hr = Marshal.GetHRForLastWin32Error(); throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Unable to get token information: 0x{0:X8}", hr), Marshal.GetExceptionForHR(hr)); } } TokenUser tokenUser = (TokenUser)Marshal.PtrToStructure(buffer.DangerousGetPointer(), typeof(TokenUser)); return ProcessHelper.GetUserNameForSid(tokenUser.User.Sid); } }
public IEnumerable<FilterInfo> GetFiltersInformation() { List<FilterInfo> result = new List<FilterInfo>(); lock (this.syncRoot) { using (ResizableBuffer buffer = new ResizableBuffer(1024)) { IntPtr filterFindHandle = IntPtr.Zero; uint hr = 0; try { uint bytesReturned; hr = NativeMethods.FilterFindFirst(NativeMethods.FilterInformationClass.FilterAggregateStandardInformation, buffer.DangerousGetPointer(), (uint)buffer.ByteLength, out bytesReturned, out filterFindHandle); // If the buffer allocated is not large enough to hold all data returned, resize it and try again. if (hr == NativeMethods.ErrorInsufficientBuffer) { buffer.Resize(unchecked((int)bytesReturned)); hr = NativeMethods.FilterFindFirst(NativeMethods.FilterInformationClass.FilterAggregateStandardInformation, buffer.DangerousGetPointer(), (uint)buffer.ByteLength, out bytesReturned, out filterFindHandle); } if (hr != NativeMethods.Ok) { // There are no filters available. if (hr == NativeMethods.ErrorNoMoreItems) { return result; } throw Marshal.GetExceptionForHR(unchecked((int)hr)); } result.AddRange(FltmcManager.MarshalFilterInfo(buffer.DangerousGetPointer())); while (true) { hr = NativeMethods.FilterFindNext(filterFindHandle, NativeMethods.FilterInformationClass.FilterAggregateStandardInformation, buffer.DangerousGetPointer(), (uint)buffer.ByteLength, out bytesReturned); if (hr == NativeMethods.ErrorInsufficientBuffer) { buffer.Resize(unchecked((int)bytesReturned)); hr = NativeMethods.FilterFindNext(filterFindHandle, NativeMethods.FilterInformationClass.FilterAggregateStandardInformation, buffer.DangerousGetPointer(), (uint)buffer.ByteLength, out bytesReturned); } if (hr != NativeMethods.Ok) { if (hr == NativeMethods.ErrorNoMoreItems) { break; } throw Marshal.GetExceptionForHR(unchecked((int)hr)); } result.AddRange(FltmcManager.MarshalFilterInfo(buffer.DangerousGetPointer())); } } catch (Exception e) { string message = string.Format(CultureInfo.InvariantCulture, "Unable to get the filter driver information: 0x{0:X8}", hr); FltmcManager.Logger.Error(e, message); throw new InvalidOperationException(message, e); } finally { if (filterFindHandle != IntPtr.Zero) { NativeMethods.FilterFindClose(filterFindHandle); } } } } return result; }