Resize() 공개 메소드

Resizes the buffer.
Be careful with the pointer returned, because it may become invalid after the next Resize function call and after the ResizableBuffer instance is disposed.
Buffer is already disposed. is lesser or equal to zero or greater than the maximum size allowed.
public Resize ( int newSize ) : void
newSize int The desired buffer size.
리턴 void
        /// <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));
                }
        }
예제 #2
0
        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)));
                }
            }
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
        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;
        }