example/Example_user.c
hidparse/HidP_user.c
+ kernel32/FileAttributes_user.c
kernel32/FindFile_user.c
ntos_cc/CcCopyRead_user.c
ntos_io/IoCreateFile_user.c
DWORD KmtSendToDriver(IN DWORD ControlCode);
DWORD KmtSendStringToDriver(IN DWORD ControlCode, IN PCSTR String);
DWORD KmtSendWStringToDriver(IN DWORD ControlCode, IN PCWSTR String);
+DWORD KmtSendUlongToDriver(IN DWORD ControlCode, IN DWORD Value);
DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer OPTIONAL, IN DWORD InLength, IN OUT PDWORD OutLength);
#else /* if !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */
#error either KMT_KERNEL_MODE or KMT_USER_MODE must be defined
--- /dev/null
+/*
+ * PROJECT: ReactOS kernel-mode tests
+ * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE: Test for GetFileAttributes/SetFileAttributes
+ * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
+ */
+
+#include <kmt_test.h>
+
+#include "kernel32_test.h"
+
+START_TEST(FileAttributes)
+{
+ PCWSTR FileName = L"\\\\.\\Global\\GLOBALROOT\\Device\\Kmtest-kernel32\\Somefile";
+ BOOL Ret;
+ DWORD Attributes;
+
+ KmtLoadDriver(L"kernel32", FALSE);
+ KmtOpenDriver();
+
+ /* Set read-only attribute */
+ KmtSendUlongToDriver(IOCTL_EXPECT_SET_ATTRIBUTES, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_NORMAL);
+ Ret = SetFileAttributesW(FileName, FILE_ATTRIBUTE_READONLY);
+ ok(Ret == TRUE, "SetFileAttributesW returned %d, error %lu\n", Ret, GetLastError());
+
+ /* Set normal attribute */
+ KmtSendUlongToDriver(IOCTL_EXPECT_SET_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL);
+ Ret = SetFileAttributesW(FileName, FILE_ATTRIBUTE_NORMAL);
+ ok(Ret == TRUE, "SetFileAttributesW returned %d, error %lu\n", Ret, GetLastError());
+
+ /* Set 0 attribute (driver should receive normal) */
+ KmtSendUlongToDriver(IOCTL_EXPECT_SET_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL);
+ Ret = SetFileAttributesW(FileName, 0);
+ ok(Ret == TRUE, "SetFileAttributesW returned %d, error %lu\n", Ret, GetLastError());
+
+ /* Query read-only attribute */
+ KmtSendUlongToDriver(IOCTL_RETURN_QUERY_ATTRIBUTES, FILE_ATTRIBUTE_READONLY);
+ Attributes = GetFileAttributesW(FileName);
+ ok_eq_hex(Attributes, FILE_ATTRIBUTE_READONLY);
+
+ /* Query read-only + normal attribute */
+ KmtSendUlongToDriver(IOCTL_RETURN_QUERY_ATTRIBUTES, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_NORMAL);
+ Attributes = GetFileAttributesW(FileName);
+ ok_eq_hex(Attributes, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_NORMAL);
+
+ /* Query normal attribute */
+ KmtSendUlongToDriver(IOCTL_RETURN_QUERY_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL);
+ Attributes = GetFileAttributesW(FileName);
+ ok_eq_hex(Attributes, FILE_ATTRIBUTE_NORMAL);
+
+ /* Query 0 attribute */
+ KmtSendUlongToDriver(IOCTL_RETURN_QUERY_ATTRIBUTES, 0);
+ Attributes = GetFileAttributesW(FileName);
+ ok_eq_hex(Attributes, 0);
+
+ KmtCloseDriver();
+ KmtUnloadDriver();
+}
static KMT_MESSAGE_HANDLER TestMessageHandler;
static KMT_IRP_HANDLER TestDirectoryControl;
+static KMT_IRP_HANDLER TestQueryInformation;
+static KMT_IRP_HANDLER TestSetInformation;
static UNICODE_STRING ExpectedExpression = RTL_CONSTANT_STRING(L"<not set>");
static WCHAR ExpressionBuffer[MAX_PATH];
+static ULONG ExpectedSetAttributes = -1;
+static ULONG ReturnQueryAttributes = -1;
NTSTATUS
TestEntry(
*Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE;
KmtRegisterIrpHandler(IRP_MJ_DIRECTORY_CONTROL, NULL, TestDirectoryControl);
+ KmtRegisterIrpHandler(IRP_MJ_QUERY_INFORMATION, NULL, TestQueryInformation);
+ KmtRegisterIrpHandler(IRP_MJ_SET_INFORMATION, NULL, TestSetInformation);
KmtRegisterMessageHandler(0, NULL, TestMessageHandler);
return Status;
break;
}
+ case IOCTL_RETURN_QUERY_ATTRIBUTES:
+ {
+ DPRINT("IOCTL_RETURN_QUERY_ATTRIBUTES, InLength = %lu\n", InLength);
+ if (InLength != sizeof(ULONG))
+ return STATUS_INVALID_PARAMETER;
+
+ ReturnQueryAttributes = *(PULONG)Buffer;
+ DPRINT("IOCTL_RETURN_QUERY_ATTRIBUTES: %lu\n", ReturnQueryAttributes);
+ break;
+ }
+ case IOCTL_EXPECT_SET_ATTRIBUTES:
+ {
+ DPRINT("IOCTL_EXPECT_SET_ATTRIBUTES, InLength = %lu\n", InLength);
+ if (InLength != sizeof(ULONG))
+ return STATUS_INVALID_PARAMETER;
+
+ ExpectedSetAttributes = *(PULONG)Buffer;
+ DPRINT("IOCTL_EXPECT_SET_ATTRIBUTES: %lu\n", ExpectedSetAttributes);
+ break;
+ }
default:
return STATUS_NOT_SUPPORTED;
}
return Status;
}
+
+static
+NTSTATUS
+TestQueryInformation(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation)
+{
+ NTSTATUS Status = STATUS_NOT_SUPPORTED;
+ PFILE_BASIC_INFORMATION BasicInfo;
+
+ PAGED_CODE();
+
+ DPRINT("IRP %x/%x\n", IoStackLocation->MajorFunction, IoStackLocation->MinorFunction);
+ ASSERT(IoStackLocation->MajorFunction == IRP_MJ_QUERY_INFORMATION);
+
+ Irp->IoStatus.Information = 0;
+
+ ok_eq_ulong(IoStackLocation->Parameters.QueryFile.FileInformationClass, FileBasicInformation);
+ if (IoStackLocation->Parameters.QueryFile.FileInformationClass == FileBasicInformation)
+ {
+ ok(ReturnQueryAttributes != (ULONG)-1, "Unexpected QUERY_INFORMATION call\n");
+ BasicInfo = Irp->AssociatedIrp.SystemBuffer;
+ BasicInfo->CreationTime.QuadPart = 126011664000000000;
+ BasicInfo->LastAccessTime.QuadPart = 130899112800000000;
+ BasicInfo->LastWriteTime.QuadPart = 130899112800000000;
+ BasicInfo->ChangeTime.QuadPart = 130899112800000000;
+ BasicInfo->FileAttributes = ReturnQueryAttributes;
+ ReturnQueryAttributes = -1;
+ Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(*BasicInfo);
+ }
+
+ Irp->IoStatus.Status = Status;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+static
+NTSTATUS
+TestSetInformation(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation)
+{
+ NTSTATUS Status = STATUS_NOT_SUPPORTED;
+ PFILE_BASIC_INFORMATION BasicInfo;
+
+ PAGED_CODE();
+
+ DPRINT("IRP %x/%x\n", IoStackLocation->MajorFunction, IoStackLocation->MinorFunction);
+ ASSERT(IoStackLocation->MajorFunction == IRP_MJ_SET_INFORMATION);
+
+ ok_eq_ulong(IoStackLocation->Parameters.SetFile.FileInformationClass, FileBasicInformation);
+ if (IoStackLocation->Parameters.SetFile.FileInformationClass == FileBasicInformation)
+ {
+ ok(ExpectedSetAttributes != (ULONG)-1, "Unexpected SET_INFORMATION call\n");
+ BasicInfo = Irp->AssociatedIrp.SystemBuffer;
+ ok_eq_longlong(BasicInfo->CreationTime.QuadPart, 0LL);
+ ok_eq_longlong(BasicInfo->LastAccessTime.QuadPart, 0LL);
+ ok_eq_longlong(BasicInfo->LastWriteTime.QuadPart, 0LL);
+ ok_eq_longlong(BasicInfo->ChangeTime.QuadPart, 0LL);
+ ok_eq_ulong(BasicInfo->FileAttributes, ExpectedSetAttributes);
+ ExpectedSetAttributes = -1;
+ Status = STATUS_SUCCESS;
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
#define _KMTEST_FINDFILE_H_
#define IOCTL_EXPECT_EXPRESSION 1
+#define IOCTL_RETURN_QUERY_ATTRIBUTES 2
+#define IOCTL_EXPECT_SET_ATTRIBUTES 3
#endif /* !defined _KMTEST_FINDFILE_H_ */
/**
* @name KmtSendToDriver
*
- * Unload special-purpose driver (stop the service)
+ * Send an I/O control message with no arguments to the driver opened with KmtOpenDriver
*
* @param ControlCode
*
/**
* @name KmtSendStringToDriver
*
- * Unload special-purpose driver (stop the service)
+ * Send an I/O control message with a string argument to the driver opened with KmtOpenDriver
*
* @param ControlCode
* @param String
}
/**
- * @name KmtSendStringToDriver
+ * @name KmtSendWStringToDriver
*
- * Unload special-purpose driver (stop the service)
+ * Send an I/O control message with a wide string argument to the driver opened with KmtOpenDriver
*
* @param ControlCode
* @param String
return ERROR_SUCCESS;
}
+/**
+ * @name KmtSendUlongToDriver
+ *
+ * Send an I/O control message with an integer argument to the driver opened with KmtOpenDriver
+ *
+ * @param ControlCode
+ * @param Value
+ *
+ * @return Win32 error code as returned by DeviceIoControl
+ */
+DWORD
+KmtSendUlongToDriver(
+ IN DWORD ControlCode,
+ IN DWORD Value)
+{
+ DWORD BytesRead;
+
+ assert(ControlCode < 0x400);
+
+ if (!DeviceIoControl(TestDeviceHandle, KMT_MAKE_CODE(ControlCode), &Value, sizeof(Value), NULL, 0, &BytesRead, NULL))
+ return GetLastError();
+
+ return ERROR_SUCCESS;
+}
+
/**
* @name KmtSendBufferToDriver
*
+ * Send an I/O control message with the specified arguments to the driver opened with KmtOpenDriver
+ *
* @param ControlCode
* @param Buffer
* @param InLength
return GetLastError();
return ERROR_SUCCESS;
-}
\ No newline at end of file
+}
KMT_TESTFUNC Test_CcCopyRead;
KMT_TESTFUNC Test_Example;
+KMT_TESTFUNC Test_FileAttributes;
KMT_TESTFUNC Test_FindFile;
KMT_TESTFUNC Test_HidPDescription;
KMT_TESTFUNC Test_IoCreateFile;
{
{ "CcCopyRead", Test_CcCopyRead },
{ "-Example", Test_Example },
+ { "FileAttributes", Test_FileAttributes },
{ "FindFile", Test_FindFile },
{ "HidPDescription", Test_HidPDescription },
{ "IoCreateFile", Test_IoCreateFile },