Пример #1
0
        public void RegisterClass_UnregisterClassName()
        {
            WindowClass myClass = new WindowClass
            {
                ClassName       = "RegisterClass_UnregisterClassName",
                Style           = ClassStyle.HorizontalRedraw,
                WindowProcedure = CallDefaultProcedure
            };

            Atom atom = WindowMethods.RegisterClass(ref myClass);

            atom.IsValid.Should().BeTrue();

            try
            {
                var info = WindowMethods.GetClassInfo(ModuleMethods.GetModuleHandle(null), "RegisterClass_UnregisterClassName");
                info.ClassName.Should().Be("RegisterClass_UnregisterClassName");
                info.ClassAtom.Should().Be(Atom.Null);
                info.Style.Should().Be(ClassStyle.HorizontalRedraw);
            }
            finally
            {
                WindowMethods.UnregisterClass("RegisterClass_UnregisterClassName", null);
                Action action =
                    () => WindowMethods.GetClassInfo(ModuleMethods.GetModuleHandle(null), "RegisterClass_UnregisterClassName");
                action.ShouldThrow <IOException>().And
                .HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_CLASS_DOES_NOT_EXIST));
            }
        }
Пример #2
0
        public void RegisterClass_UnregisterActiveWindow()
        {
            WindowClass myClass = new WindowClass
            {
                ClassName       = "RegisterClass_UnregisterActiveWindow",
                WindowProcedure = CallDefaultProcedure,
            };

            Atom atom = WindowMethods.RegisterClass(ref myClass);

            atom.IsValid.Should().BeTrue();

            try
            {
                WindowHandle window = WindowMethods.CreateWindow(atom,
                                                                 "RegisterClass_UnregisterActiveWindow", WindowStyles.Diabled | WindowStyles.Minimize);
                window.IsValid.Should().BeTrue();

                try
                {
                    Action action = () => WindowMethods.UnregisterClass(atom, null);
                    action.ShouldThrow <IOException>().And
                    .HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_CLASS_HAS_WINDOWS));
                }
                finally
                {
                    WindowMethods.DestroyWindow(window);
                }
            }
            finally
            {
                WindowMethods.UnregisterClass(atom, null);
            }
        }
Пример #3
0
        public void GetClassInfo_NotRegistered()
        {
            Action action = () => WindowMethods.GetClassInfo(null, Path.GetRandomFileName());

            action.ShouldThrow <IOException>().And
            .HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_CLASS_DOES_NOT_EXIST));
        }
Пример #4
0
        /// <summary>
        /// Get the type name of the given object.
        /// </summary>
        public static string GetObjectType(SafeHandle handle)
        {
            using (HeapBuffer buffer = new HeapBuffer())
            {
                NTSTATUS status = NTSTATUS.STATUS_BUFFER_OVERFLOW;

                // We'll initially give room for 50 characters for the type name
                uint returnLength = (uint)Marshal.SizeOf <OBJECT_TYPE_INFORMATION>() + 50 * sizeof(char);

                while (status == NTSTATUS.STATUS_BUFFER_OVERFLOW || status == NTSTATUS.STATUS_BUFFER_TOO_SMALL || status == NTSTATUS.STATUS_INFO_LENGTH_MISMATCH)
                {
                    buffer.EnsureByteCapacity(returnLength);

                    status = Direct.NtQueryObject(
                        Handle: handle,
                        ObjectInformationClass: OBJECT_INFORMATION_CLASS.ObjectTypeInformation,
                        ObjectInformation: buffer.DangerousGetHandle(),
                        ObjectInformationLength: checked ((uint)buffer.ByteCapacity),
                        ReturnLength: out returnLength);
                }

                if (!ErrorMacros.NT_SUCCESS(status))
                {
                    throw ErrorHelper.GetIoExceptionForNTStatus(status);
                }

                return(new CheckedReader(buffer).ReadStruct <OBJECT_TYPE_INFORMATION>().TypeName.ToString());
            }
        }
Пример #5
0
        public static unsafe void ToUpperInvariant(ref UNICODE_STRING value)
        {
            NTSTATUS status = Imports.RtlUpcaseUnicodeString(
                (UNICODE_STRING *)Structs.AddressOf(ref value), (UNICODE_STRING *)Structs.AddressOf(ref value), false);

            if (!ErrorMacros.NT_SUCCESS(status))
            {
                ErrorMethods.GetIoExceptionForNTStatus(status);
            }
        }
 public void QuerySuggestedLinkName()
 {
     // Need to open the handle with no rights (desiredAccess: 0) to avoid needing to run as admin
     using (var handle = FileMethods.CreateFile(@"\\.\C:", CreationDisposition.OpenExisting, desiredAccess: 0))
     {
         Action action = () => DeviceMethods.QuerySuggestedLinkName(handle);
         action.ShouldThrow <WInteropIOException>("this is an optional query, not aware of which drivers support this").
         And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_NOT_FOUND));
     }
 }
Пример #7
0
        public void CopyFile_NotOverExisting(bool useCreateFile)
        {
            using (var cleaner = new TestFileCleaner())
            {
                string source      = cleaner.CreateTestFile(CompressedFile2);
                string destination = cleaner.CreateTestFile($"CopyFile_NotOverExisting({useCreateFile})");

                Action action = () => CompressionMethods.LzCopyFile(source, destination, overwrite: false, useCreateFile: useCreateFile);
                action.ShouldThrow <IOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_FILE_EXISTS));
            }
        }
Пример #8
0
        /// <summary>
        /// CopyFile2 wrapper. Only available on Windows8 and above.
        /// </summary>
        public static void CopyFile2(string source, string destination, bool overwrite = false)
        {
            unsafe
            {
                int cancel = 0;
                COPYFILE2_EXTENDED_PARAMETERS parameters = new COPYFILE2_EXTENDED_PARAMETERS();
                parameters.dwSize      = (uint)Marshal.SizeOf <COPYFILE2_EXTENDED_PARAMETERS>();
                parameters.pfCanel     = &cancel;
                parameters.dwCopyFlags = overwrite ? 0 : CopyFileFlags.COPY_FILE_FAIL_IF_EXISTS;

                HRESULT hr = Direct.CopyFile2(source, destination, &parameters);
                if (ErrorMacros.FAILED(hr))
                {
                    throw ErrorHelper.GetIoExceptionForHResult(hr, source);
                }
            }
        }
Пример #9
0
        /// <summary>
        /// CopyFile2 wrapper. Only available on Windows8 and above.
        /// </summary>
        public static void CopyFile2(string source, string destination, bool overwrite = false)
        {
            unsafe
            {
                int cancel = 0;
                COPYFILE2_EXTENDED_PARAMETERS parameters = new COPYFILE2_EXTENDED_PARAMETERS()
                {
                    dwSize      = (uint)sizeof(COPYFILE2_EXTENDED_PARAMETERS),
                    pfCanel     = &cancel,
                    dwCopyFlags = overwrite ? 0 : CopyFileFlags.COPY_FILE_FAIL_IF_EXISTS
                };

                HRESULT hr = Imports.CopyFile2(source, destination, &parameters);
                if (ErrorMacros.FAILED(hr))
                {
                    throw Errors.GetIoExceptionForHResult(hr, source);
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Get the name fot he given handle. This is typically the NT path of the object.
        /// </summary>
        public static string GetObjectName(SafeHandle handle)
        {
            // IoQueryFileDosDeviceName wraps this for file handles, but requires calling ExFreePool to free the allocated memory
            // https://msdn.microsoft.com/en-us/library/windows/hardware/ff548474.aspx
            //
            // http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FNT%20Objects%2FType%20independed%2FOBJECT_NAME_INFORMATION.html
            //
            //  typedef struct _OBJECT_NAME_INFORMATION
            //  {
            //       UNICODE_STRING Name;
            //       WCHAR NameBuffer[0];
            //  } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
            //
            // The above definition means the API expects a buffer where it can stick a UNICODE_STRING with the buffer immediately following.

            using (HeapBuffer buffer = new HeapBuffer())
            {
                NTSTATUS status       = NTSTATUS.STATUS_BUFFER_OVERFLOW;
                uint     returnLength = 260 * sizeof(char);

                while (status == NTSTATUS.STATUS_BUFFER_OVERFLOW || status == NTSTATUS.STATUS_BUFFER_TOO_SMALL)
                {
                    buffer.EnsureByteCapacity(returnLength);

                    status = Direct.NtQueryObject(
                        Handle: handle,
                        ObjectInformationClass: OBJECT_INFORMATION_CLASS.ObjectNameInformation,
                        ObjectInformation: buffer.DangerousGetHandle(),
                        ObjectInformationLength: checked ((uint)buffer.ByteCapacity),
                        ReturnLength: out returnLength);
                }

                if (!ErrorMacros.NT_SUCCESS(status))
                {
                    throw ErrorHelper.GetIoExceptionForNTStatus(status);
                }

                return(new CheckedReader(buffer).ReadStruct <UNICODE_STRING>().ToString());
            }
        }
Пример #11
0
 public DriveNotReadyException(string message, Exception innerException)
     : base(message, innerException)
 {
     HResult = (int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_NOT_READY);
 }
Пример #12
0
 public DriveNotReadyException()
     : base()
 {
     HResult = (int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_NOT_READY);
 }
        public void OpenFileWithTrailingSeparator()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string testFile = cleaner.CreateTestFile(nameof(OpenFileWithTrailingSeparator));

                string fullName = FileMethods.GetFullPathName(Paths.AddTrailingSeparator(testFile));

                FindOperation <string> find = new FindOperation <string>(testFile);
                Action action = () => find.FirstOrDefault();
                action.ShouldThrow <ArgumentException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_INVALID_PARAMETER));

                action = () => FileMethods.CreateFile(Paths.AddTrailingSeparator(testFile), CreationDisposition.OpenExisting, DesiredAccess.ReadAttributes);
                action.ShouldThrow <WInteropIOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_INVALID_NAME));
            }
        }
Пример #14
0
        public void CreateSymbolicLinkToFile()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string filePath     = cleaner.CreateTestFile("CreateSymbolicLinkToFile");
                string symbolicLink = cleaner.GetTestPath();
                Action action       = () => FileMethods.CreateSymbolicLink(symbolicLink, filePath);

                if (CanCreateSymbolicLinks())
                {
                    action();
                    var attributes = FileMethods.GetFileAttributes(symbolicLink);
                    attributes.Should().HaveFlag(FileAttributes.ReparsePoint);

                    using (var handle = FileMethods.CreateFile(symbolicLink, CreationDisposition.OpenExisting, DesiredAccess.ReadExtendedAttributes,
                                                               ShareModes.All, fileFlags: FileFlags.OpenReparsePoint))
                    {
                        handle.IsInvalid.Should().BeFalse();
                        var(printName, substituteName, tag) = DeviceMethods.GetReparsePointNames(handle);
                        tag.Should().Be(ReparseTag.SymbolicLink);
                        printName.Should().Be(filePath);
                        substituteName.Should().Be(@"\??\" + filePath);
                    }
                }
                else
                {
                    // Can't create links unless you have admin rights SE_CREATE_SYMBOLIC_LINK_NAME SeCreateSymbolicLinkPrivilege
                    action.ShouldThrow <System.IO.IOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_PRIVILEGE_NOT_HELD));
                }
            }
        }
Пример #15
0
        public void WindowsErrorToHresultMappings(WindowsError error, HRESULT expected)
        {
            HRESULT result = ErrorMacros.HRESULT_FROM_WIN32(error);

            result.Should().Be(expected);
        }
        public void LockedFileDirectoryDeletion()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string directory = cleaner.GetTestPath();
                DirectoryMethods.CreateDirectory(directory);
                FileMethods.DirectoryExists(directory).Should().BeTrue();
                string file = cleaner.CreateTestFile(nameof(LockedFileDirectoryDeletion), directory);
                using (var handle = FileMethods.CreateFile(file, CreationDisposition.OpenExisting, DesiredAccess.GenericRead, ShareModes.ReadWrite | ShareModes.Delete))
                {
                    handle.IsInvalid.Should().BeFalse();

                    // Mark the file for deletion
                    FileMethods.DeleteFile(file);

                    // RemoveDirectory API call will throw
                    Action action = () => DirectoryMethods.RemoveDirectory(directory);
                    action.ShouldThrow <WInteropIOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_DIR_NOT_EMPTY));

                    // Opening the directory for deletion will succeed, but have no impact
                    using (var directoryHandle = FileMethods.CreateFile(
                               directory,
                               CreationDisposition.OpenExisting,
                               DesiredAccess.ListDirectory | DesiredAccess.Delete,
                               ShareModes.ReadWrite | ShareModes.Delete,
                               FileAttributes.None,
                               FileFlags.BackupSemantics | FileFlags.DeleteOnClose))
                    {
                        directoryHandle.IsInvalid.Should().BeFalse();
                    }
                }

                // File will be gone now that the handle is closed
                FileMethods.FileExists(file).Should().BeFalse();

                // But the directory will still exist as it doesn't respect DeleteOnClose with an open handle when it is closed
                FileMethods.DirectoryExists(directory).Should().BeTrue();

                // Create a handle to the directory again with DeleteOnClose and it will actually delete the directory
                using (var directoryHandle = FileMethods.CreateFile(
                           directory,
                           CreationDisposition.OpenExisting,
                           DesiredAccess.ListDirectory | DesiredAccess.Delete,
                           ShareModes.ReadWrite | ShareModes.Delete,
                           FileAttributes.None,
                           FileFlags.BackupSemantics | FileFlags.DeleteOnClose))
                {
                    directoryHandle.IsInvalid.Should().BeFalse();
                }
                FileMethods.DirectoryExists(directory).Should().BeFalse();
            }
        }
Пример #17
0
        public void CreateSymbolicLinkToLongPathFile()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string longPath = @"\\?\" + PathGenerator.CreatePathOfLength(cleaner.TempFolder, 500);
                FileHelper.CreateDirectoryRecursive(longPath);
                string filePath = cleaner.CreateTestFile("CreateSymbolicLinkToLongPathFile", longPath);

                string symbolicLink = cleaner.GetTestPath();
                Action action       = () => FileDesktopMethods.CreateSymbolicLink(symbolicLink, filePath);

                if (CanCreateSymbolicLinks())
                {
                    action();
                    var attributes = FileDesktopMethods.GetFileAttributes(symbolicLink);
                    attributes.Should().HaveFlag(FileAttributes.FILE_ATTRIBUTE_REPARSE_POINT);
                }
                else
                {
                    action.ShouldThrow <System.IO.IOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_PRIVILEGE_NOT_HELD));
                }
            }
        }
Пример #18
0
        public void CreateSymbolicLinkToFile()
        {
            using (var cleaner = new TestFileCleaner())
            {
                string filePath     = cleaner.CreateTestFile("CreateSymbolicLinkToFile");
                string symbolicLink = cleaner.GetTestPath();
                Action action       = () => FileDesktopMethods.CreateSymbolicLink(symbolicLink, filePath);

                if (CanCreateSymbolicLinks())
                {
                    action();
                    var attributes = FileDesktopMethods.GetFileAttributes(symbolicLink);
                    attributes.Should().HaveFlag(FileAttributes.FILE_ATTRIBUTE_REPARSE_POINT);
                }
                else
                {
                    // Can't create links unless you have admin rights SE_CREATE_SYMBOLIC_LINK_NAME SeCreateSymbolicLinkPrivilege
                    action.ShouldThrow <System.IO.IOException>().And.HResult.Should().Be((int)ErrorMacros.HRESULT_FROM_WIN32(WindowsError.ERROR_PRIVILEGE_NOT_HELD));
                }
            }
        }