static VOID TestPrivateFunctions(VOID) { UNICODE_STRING ExAllocateCallBackName = RTL_CONSTANT_STRING(L"ExAllocateCallBack"); UNICODE_STRING ExFreeCallBackName = RTL_CONSTANT_STRING(L"ExFreeCallBack"); PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock; INT CallbackContext; if (!ExAllocateCallBack) ExAllocateCallBack = MmGetSystemRoutineAddress(&ExAllocateCallBackName); if (!ExFreeCallBack) ExFreeCallBack = MmGetSystemRoutineAddress(&ExFreeCallBackName); if (skip(ExAllocateCallBack && ExFreeCallBack, "ExAllocateCallBack and/or ExFreeCallBack unavailable\n")) return; CallbackBlock = ExAllocateCallBack(ExCallbackFunction, &CallbackContext); ok(CallbackBlock != NULL, "CallbackBlock = NULL\n"); if (skip(CallbackBlock != NULL, "Allocating callback failed\n")) return; ok_eq_pointer(CallbackBlock->Function, ExCallbackFunction); ok_eq_pointer(CallbackBlock->Context, &CallbackContext); ok_eq_hex(KmtGetPoolTag(CallbackBlock), 'brbC'); ExFreeCallBack(CallbackBlock); }
/** * @name TestIrpHandler * * Test IRP handler routine * * @param DeviceObject * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler * @param Irp * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler, except for passing it to * IoGetCurrentStackLocation * @param IoStackLocation * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler * * @return Status */ static NTSTATUS TestIrpHandler( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION IoStackLocation) { NTSTATUS Status = STATUS_SUCCESS; DPRINT("IRP!\n"); ok_irql(PASSIVE_LEVEL); ok_eq_pointer(DeviceObject->DriverObject, TestDriverObject); if (IoStackLocation->MajorFunction == IRP_MJ_CREATE) trace("Got IRP_MJ_CREATE!\n"); else if (IoStackLocation->MajorFunction == IRP_MJ_CLOSE) trace("Got IRP_MJ_CLOSE!\n"); else trace("Got an IRP!\n"); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
static NTSTATUS NTAPI NotificationCallback( _In_ PVOID NotificationStructure, _Inout_opt_ PVOID Context) { PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notification = NotificationStructure; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE Handle; ok_irql(PASSIVE_LEVEL); ok_eq_pointer(Context, &NotificationContext); ok_eq_uint(Notification->Version, 1); ok_eq_uint(Notification->Size, sizeof(*Notification)); /* symbolic link must exist */ trace("Interface change: %wZ\n", Notification->SymbolicLinkName); InitializeObjectAttributes(&ObjectAttributes, Notification->SymbolicLinkName, OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenSymbolicLinkObject(&Handle, GENERIC_READ, &ObjectAttributes); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status), "No symbolic link\n")) { Status = ObCloseHandle(Handle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); } return STATUS_SUCCESS; }
static VOID NTAPI CallbackFunction( IN PVOID CallbackContext, IN PVOID Argument1, IN PVOID Argument2) { INT *InvocationCount = CallbackContext; ok_irql(PASSIVE_LEVEL); (*InvocationCount)++; ok_eq_pointer(Argument1, &CallbackArgument1); ok_eq_pointer(Argument2, &CallbackArgument2); }
/** * @name TestUnload * * Test unload routine. * This is called by the driver's Unload routine as early as possible, with * ResultBuffer and the test device object still valid, so that test macros * work correctly * * @param DriverObject * Driver Object. * This is guaranteed not to have been touched by Unload before the call * to TestEntry * * @return Status */ VOID TestUnload( IN PDRIVER_OBJECT DriverObject) { PAGED_CODE(); DPRINT("Unload!\n"); ok_irql(PASSIVE_LEVEL); ok_eq_pointer(DriverObject, TestDriverObject); trace("Unloading example driver\n"); }
static VOID NTAPI KernelModeTest(IN PVOID Context) { NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ParentHandle, SystemRootHandle, TargetHandle; PFILE_OBJECT ParentFileObject, TargetFileObject, SystemRootFileObject; UNREFERENCED_PARAMETER(Context); /* Kernelmode mandatory for IoCreateFile */ ok(ExGetPreviousMode() == KernelMode, "UserMode returned!\n"); /* First of all, open \\SystemRoot * We're interested in 3 pieces of information about it: * -> Its target (it's a symlink): \Windows or \ReactOS * -> Its associated File Object * -> Its associated FCB */ TargetFileObject = NULL; IoStatusBlock.Status = 0xFFFFFFFF; TargetHandle = INVALID_HANDLE_VALUE; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&TargetHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(TargetHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&TargetFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); } ok(TargetFileObject != NULL, "Not target to continue!\n"); if (TargetFileObject == NULL) { if (TargetHandle != INVALID_HANDLE_VALUE) { ObCloseHandle(TargetHandle, KernelMode); } return; } /* Open target directory of \SystemRoot\Regedit.exe * This must lead to \SystemRoot opening */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRootRegedit, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(ParentHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&ParentFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { /* At that point, file object must point to \SystemRoot * But must not be the same FO than target (diverted file object) * This means FCB & FileName are equal * But CCB & FO are different * CCB must be != NULL, otherwise it means open failed */ ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n"); ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL); ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext); ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n"); ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n"); ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0); ObDereferenceObject(ParentFileObject); } /* Because target exists FSD must signal it */ ok_eq_long(IoStatusBlock.Information, FILE_EXISTS); ObCloseHandle(ParentHandle, KernelMode); } /* Do the same with relative open */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&SystemRootHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &Regedit, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, SystemRootHandle, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(ParentHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&ParentFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n"); ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext); ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n"); ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n"); ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0); Status = ObReferenceObjectByHandle(SystemRootHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&SystemRootFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject); ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n"); ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n"); ObDereferenceObject(SystemRootFileObject); } ObDereferenceObject(ParentFileObject); } ok_eq_long(IoStatusBlock.Information, FILE_EXISTS); ObCloseHandle(ParentHandle, KernelMode); } ObCloseHandle(SystemRootHandle, KernelMode); } /* *** */ /* Now redo the same scheme, but using a target that doesn't exist * The difference will be in IoStatusBlock.Information, the FSD will * inform that the target doesn't exist. * Clear for rename :-) */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRootFoobar, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(ParentHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&ParentFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n"); ok_eq_pointer(ParentFileObject->RelatedFileObject, NULL); ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext); ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n"); ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n"); ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0); ObDereferenceObject(ParentFileObject); } ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST); ObCloseHandle(ParentHandle, KernelMode); } IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&SystemRootHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &Foobar, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, SystemRootHandle, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { Status = ObReferenceObjectByHandle(ParentHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&ParentFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok(ParentFileObject != TargetFileObject, "Diverted file object must be different\n"); ok_eq_pointer(ParentFileObject->FsContext, TargetFileObject->FsContext); ok(ParentFileObject->FsContext2 != 0x0, "Parent must be open!\n"); ok(ParentFileObject->FsContext2 != TargetFileObject->FsContext2, "Parent open must have its own context!\n"); ok_eq_long(RtlCompareUnicodeString(&ParentFileObject->FileName, &TargetFileObject->FileName, FALSE), 0); Status = ObReferenceObjectByHandle(SystemRootHandle, FILE_READ_DATA, *IoFileObjectType, KernelMode, (PVOID *)&SystemRootFileObject, NULL); ok_eq_hex(Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { ok_eq_pointer(ParentFileObject->RelatedFileObject, SystemRootFileObject); ok(ParentFileObject->RelatedFileObject != TargetFileObject, "File objects must be different\n"); ok(SystemRootFileObject != TargetFileObject, "File objects must be different\n"); ObDereferenceObject(SystemRootFileObject); } ObDereferenceObject(ParentFileObject); } ok_eq_long(IoStatusBlock.Information, FILE_DOES_NOT_EXIST); ObCloseHandle(ParentHandle, KernelMode); } ObCloseHandle(SystemRootHandle, KernelMode); } ObDereferenceObject(TargetFileObject); ObCloseHandle(TargetHandle, KernelMode); /* *** */ /* Direct target open of something that doesn't exist */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRootFoobarFoobar, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND); ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF); if (Status == STATUS_SUCCESS) { ObCloseHandle(ParentHandle, KernelMode); } /* Relative target open of something that doesn't exist */ IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &SystemRoot, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwOpenFile(&SystemRootHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_hex(IoStatusBlock.Status, STATUS_SUCCESS); if (Status == STATUS_SUCCESS) { IoStatusBlock.Status = 0xFFFFFFFF; IoStatusBlock.Information = 0xFFFFFFFF; InitializeObjectAttributes(&ObjectAttributes, &FoobarFoobar, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, SystemRootHandle, NULL); Status = IoCreateFile(&ParentHandle, GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0, CreateFileTypeNone, NULL, IO_OPEN_TARGET_DIRECTORY); ok_eq_hex(Status, STATUS_OBJECT_PATH_NOT_FOUND); ok_eq_hex(IoStatusBlock.Status, 0xFFFFFFFF); if (Status == STATUS_SUCCESS) { ObCloseHandle(ParentHandle, KernelMode); } ObCloseHandle(SystemRootHandle, KernelMode); } }
/** * @name TestMessageHandler * * Test message handler routine * * @param DeviceObject * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler * @param Irp * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler, except for passing it to * IoGetCurrentStackLocation * @param IoStackLocation * Device Object. * This is guaranteed not to have been touched by the dispatch function * before the call to the IRP handler * * @return Status */ static NTSTATUS TestMessageHandler( IN PDEVICE_OBJECT DeviceObject, IN ULONG ControlCode, IN PVOID Buffer OPTIONAL, IN SIZE_T InLength, IN OUT PSIZE_T OutLength) { NTSTATUS Status = STATUS_SUCCESS; switch (ControlCode) { case IOCTL_NOTIFY: { static int TimesReceived = 0; ++TimesReceived; ok(TimesReceived == 1, "Received control code 1 %d times\n", TimesReceived); ok_eq_pointer(Buffer, NULL); ok_eq_ulong((ULONG)InLength, 0LU); ok_eq_ulong((ULONG)*OutLength, 0LU); break; } case IOCTL_SEND_STRING: { static int TimesReceived = 0; ANSI_STRING ExpectedString = RTL_CONSTANT_STRING("yay"); ANSI_STRING ReceivedString; ++TimesReceived; ok(TimesReceived == 1, "Received control code 2 %d times\n", TimesReceived); ok(Buffer != NULL, "Buffer is NULL\n"); ok_eq_ulong((ULONG)InLength, (ULONG)ExpectedString.Length); ok_eq_ulong((ULONG)*OutLength, 0LU); ReceivedString.MaximumLength = ReceivedString.Length = (USHORT)InLength; ReceivedString.Buffer = Buffer; ok(RtlCompareString(&ExpectedString, &ReceivedString, FALSE) == 0, "Received string: %Z\n", &ReceivedString); break; } case IOCTL_SEND_MYSTRUCT: { static int TimesReceived = 0; MY_STRUCT ExpectedStruct = { 123, ":D" }; MY_STRUCT ResultStruct = { 456, "!!!" }; ++TimesReceived; ok(TimesReceived == 1, "Received control code 3 %d times\n", TimesReceived); ok(Buffer != NULL, "Buffer is NULL\n"); ok_eq_ulong((ULONG)InLength, (ULONG)sizeof ExpectedStruct); ok_eq_ulong((ULONG)*OutLength, 2LU * sizeof ExpectedStruct); if (!skip(Buffer && InLength >= sizeof ExpectedStruct, "Cannot read from buffer!\n")) ok(RtlCompareMemory(&ExpectedStruct, Buffer, sizeof ExpectedStruct) == sizeof ExpectedStruct, "Buffer does not contain expected values\n"); if (!skip(Buffer && *OutLength >= 2 * sizeof ExpectedStruct, "Cannot write to buffer!\n")) { RtlCopyMemory((PCHAR)Buffer + sizeof ExpectedStruct, &ResultStruct, sizeof ResultStruct); *OutLength = 2 * sizeof ExpectedStruct; } break; } default: ok(0, "Got an unknown message! DeviceObject=%p, ControlCode=%lu, Buffer=%p, In=%lu, Out=%lu bytes\n", DeviceObject, ControlCode, Buffer, InLength, *OutLength); break; } return Status; }
static VOID TestCreateSection( IN HANDLE FileHandle1, IN PFILE_OBJECT FileObject1, IN HANDLE FileHandle2, IN PFILE_OBJECT FileObject2) { NTSTATUS Status = STATUS_SUCCESS; PVOID SectionObject; LARGE_INTEGER MaximumSize; ULONG PointerCount1, PointerCount2; KmtStartSeh() Status = MmCreateSection(NULL, 0, NULL, NULL, 0, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_INVALID_PAGE_PROTECTION); if (!KmtIsCheckedBuild) { /* PAGE_NOACCESS and missing SEC_RESERVE/SEC_COMMIT/SEC_IMAGE assert */ KmtStartSeh() Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_NOACCESS, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_ACCESS_VIOLATION); KmtStartSeh() Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_NOACCESS, 0, NULL, NULL); KmtEndSeh(STATUS_ACCESS_VIOLATION); } SectionObject = KmtInvalidPointer; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, NULL, 0, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_INVALID_PAGE_PROTECTION); ok_eq_pointer(SectionObject, KmtInvalidPointer); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); KmtStartSeh() Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_READONLY, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_ACCESS_VIOLATION); SectionObject = KmtInvalidPointer; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, NULL, PAGE_READONLY, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_ACCESS_VIOLATION); ok_eq_pointer(SectionObject, KmtInvalidPointer); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 0; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_INVALID_FILE_FOR_SECTION); ok_eq_longlong(MaximumSize.QuadPart, 0LL); ok_eq_pointer(SectionObject, KmtInvalidPointer); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); MaximumSize.QuadPart = 0; KmtStartSeh() Status = MmCreateSection(NULL, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_INVALID_PARAMETER_4); ok_eq_longlong(MaximumSize.QuadPart, 0LL); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(NULL, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_ACCESS_VIOLATION); ok_eq_longlong(MaximumSize.QuadPart, 1LL); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 0; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_INVALID_PARAMETER_4); ok_eq_longlong(MaximumSize.QuadPart, 0LL); ok_eq_pointer(SectionObject, KmtInvalidPointer); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); /* page file section */ SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); if (!skip(FileHandle1 != NULL && FileObject1 != NULL && FileHandle2 != NULL && FileObject2 != NULL, "No file handle or object\n")) { PointerCount1 = 3; PointerCount2 = 3; /* image section */ CheckObject(FileHandle2, PointerCount2, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); CheckObject(FileHandle2, PointerCount2, 1L); CheckSection(SectionObject, SEC_IMAGE); TestMapView(SectionObject, FALSE, TRUE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); CheckObject(FileHandle2, PointerCount2, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, FileObject2); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); ++PointerCount2; CheckObject(FileHandle2, PointerCount2, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, TRUE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); //--PointerCount2; // ???? CheckObject(FileHandle2, PointerCount2, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, FileObject2); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); CheckObject(FileHandle2, PointerCount2, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, TRUE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); /* image section with inappropriate file */ CheckObject(FileHandle1, PointerCount1, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_INVALID_IMAGE_NOT_MZ); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok_eq_pointer(SectionObject, KmtInvalidPointer); CheckObject(FileHandle1, PointerCount1, 1L); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); CheckObject(FileHandle1, PointerCount1, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, FileObject1); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); ++PointerCount1; CheckObject(FileHandle1, PointerCount1, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, FALSE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); //--PointerCount1; // ???? CheckObject(FileHandle1, PointerCount1, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, FileObject1); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); CheckObject(FileHandle1, PointerCount1, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, FALSE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); /* image section with two different files */ CheckObject(FileHandle1, PointerCount1, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, FileObject2); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); CheckObject(FileHandle1, PointerCount1, 1L); CheckObject(FileHandle2, PointerCount2, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, TRUE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); CheckObject(FileHandle1, PointerCount1, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, FileObject1); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); CheckObject(FileHandle1, PointerCount1, 1L); CheckObject(FileHandle2, PointerCount2, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, FALSE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); /* data file section */ CheckObject(FileHandle1, PointerCount1, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, FileHandle1, NULL); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); CheckObject(FileHandle1, PointerCount1, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, FALSE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); CheckObject(FileHandle1, PointerCount1, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, FileObject1); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); CheckObject(FileHandle1, PointerCount1, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, FALSE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); CheckObject(FileHandle1, PointerCount1, 1L); SectionObject = KmtInvalidPointer; MaximumSize.QuadPart = 1; KmtStartSeh() Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, FileHandle1, FileObject1); KmtEndSeh(STATUS_SUCCESS); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_longlong(MaximumSize.QuadPart, 1LL); ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n"); ok(SectionObject != NULL, "Section object pointer NULL\n"); CheckObject(FileHandle1, PointerCount1, 1L); CheckSection(SectionObject, 0); TestMapView(SectionObject, TRUE, FALSE); if (SectionObject && SectionObject != KmtInvalidPointer) ObDereferenceObject(SectionObject); CheckObject(FileHandle1, PointerCount1, 1L); } }
static VOID TestQueryLink( _In_ HANDLE LinkHandle, _In_ PCUNICODE_STRING ExpectedTarget) { NTSTATUS Status; WCHAR QueriedTargetBuffer[32]; UNICODE_STRING QueriedTarget; ULONG ResultLength; PULONG pResultLength; ULONG i; for (i = 0; i < 2; i++) { if (i == 0) { pResultLength = &ResultLength; } else { pResultLength = NULL; } /* Query with NULL Buffer just gives us the length */ RtlInitEmptyUnicodeString(&QueriedTarget, NULL, 0); if (pResultLength) ResultLength = 0x55555555; Status = ZwQuerySymbolicLinkObject(LinkHandle, &QueriedTarget, pResultLength); ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); ok_eq_uint(QueriedTarget.Length, 0); ok_eq_uint(QueriedTarget.MaximumLength, 0); ok_eq_pointer(QueriedTarget.Buffer, NULL); if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); /* Query with Length-1 buffer */ RtlInitEmptyUnicodeString(&QueriedTarget, QueriedTargetBuffer, ExpectedTarget->Length - 1); RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); if (pResultLength) ResultLength = 0x55555555; Status = ZwQuerySymbolicLinkObject(LinkHandle, &QueriedTarget, pResultLength); ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); ok_eq_uint(QueriedTarget.Length, 0); ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length - 1); ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); ok_eq_uint(QueriedTarget.Buffer[0], 0x5555); if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); /* Query with Length buffer */ RtlInitEmptyUnicodeString(&QueriedTarget, QueriedTargetBuffer, ExpectedTarget->Length); RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); if (pResultLength) ResultLength = 0x55555555; Status = ZwQuerySymbolicLinkObject(LinkHandle, &QueriedTarget, pResultLength); ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length); ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); if (pResultLength && QueriedTarget.MaximumLength < ExpectedTarget->MaximumLength) { ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); ok_eq_uint(QueriedTarget.Length, 0); ok_eq_uint(QueriedTarget.Buffer[0], 0x5555); if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); } else { ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length); ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget); ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555); } /* Query with Length+1 buffer */ RtlInitEmptyUnicodeString(&QueriedTarget, QueriedTargetBuffer, ExpectedTarget->Length + 1); RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); if (pResultLength) ResultLength = 0x55555555; Status = ZwQuerySymbolicLinkObject(LinkHandle, &QueriedTarget, pResultLength); ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length + 1); ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); if (pResultLength && QueriedTarget.MaximumLength < ExpectedTarget->MaximumLength) { ok_eq_hex(Status, STATUS_BUFFER_TOO_SMALL); ok_eq_uint(QueriedTarget.Length, 0); ok_eq_uint(QueriedTarget.Buffer[0], 0x5555); if (pResultLength) ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); } else { ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length); ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget); ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555); } /* Query with Length+2 buffer */ RtlInitEmptyUnicodeString(&QueriedTarget, QueriedTargetBuffer, ExpectedTarget->Length + sizeof(WCHAR)); RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); if (pResultLength) ResultLength = 0x55555555; Status = ZwQuerySymbolicLinkObject(LinkHandle, &QueriedTarget, pResultLength); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length); ok_eq_uint(QueriedTarget.MaximumLength, ExpectedTarget->Length + sizeof(WCHAR)); ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget); if (pResultLength) { if (ExpectedTarget->MaximumLength >= ExpectedTarget->Length + sizeof(UNICODE_NULL)) ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0); ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); } else { ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555); } /* Query with full-sized buffer */ RtlInitEmptyUnicodeString(&QueriedTarget, QueriedTargetBuffer, sizeof(QueriedTargetBuffer)); RtlFillMemory(&QueriedTargetBuffer, sizeof(QueriedTargetBuffer), 0x55); if (pResultLength) ResultLength = 0x55555555; Status = ZwQuerySymbolicLinkObject(LinkHandle, &QueriedTarget, pResultLength); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_uint(QueriedTarget.Length, ExpectedTarget->Length); ok_eq_uint(QueriedTarget.MaximumLength, sizeof(QueriedTargetBuffer)); ok_eq_pointer(QueriedTarget.Buffer, QueriedTargetBuffer); ok(RtlEqualUnicodeString(&QueriedTarget, ExpectedTarget, FALSE), "%wZ != %wZ\n", &QueriedTarget, ExpectedTarget); if (pResultLength) { if (ExpectedTarget->MaximumLength >= ExpectedTarget->Length + sizeof(UNICODE_NULL)) ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0); ok_eq_ulong(ResultLength, ExpectedTarget->MaximumLength); } else { ok_eq_uint(QueriedTarget.Buffer[QueriedTarget.Length / sizeof(WCHAR)], 0x5555); } } }
static VOID TestDriverObject( IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING RegistryPath OPTIONAL, IN DRIVER_STATUS DriverStatus) { BOOLEAN CheckThisDispatchRoutine; PVOID FirstMajorFunc; int i; UNICODE_STRING HardwareDatabase = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM"); UNICODE_STRING RegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Services\\Kmtest-IoDeviceObject"); UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"\\Driver\\Kmtest-IoDeviceObject"); UNICODE_STRING ServiceKeyName = RTL_CONSTANT_STRING(L"Kmtest-IoDeviceObject"); BOOLEAN Equal; ok(DriverObject->Size == sizeof(DRIVER_OBJECT), "Size does not match, got %x\n",DriverObject->Size); ok(DriverObject->Type == 4, "Type does not match 4. got %d\n", DriverObject->Type); if (DriverStatus == DriverStatusEntry) { ok(DriverObject->DeviceObject == NULL, "Expected DeviceObject pointer to be 0, got %p\n", DriverObject->DeviceObject); ok (DriverObject->Flags == DRVO_LEGACY_DRIVER, "Expected Flags to be DRVO_LEGACY_DRIVER, got %lu\n", DriverObject->Flags); ok(DriverObject->DriverStart < (PVOID)TestEntry, "DriverStart is %p, expected < %p\n", DriverObject->DriverStart, (PVOID)TestEntry); ok(DriverObject->DriverSize > 0x2000, "DriverSize 0x%lx\n", DriverObject->DriverSize); ok_eq_pointer(DriverObject->DriverExtension, (PDRIVER_EXTENSION)(DriverObject + 1)); ok_eq_pointer(DriverObject->DriverExtension->DriverObject, DriverObject); ok_eq_pointer(DriverObject->DriverExtension->AddDevice, NULL); ok_eq_ulong(DriverObject->DriverExtension->Count, 0UL); Equal = RtlEqualUnicodeString(RegistryPath, &RegPath, FALSE); ok(Equal, "RegistryPath is '%wZ'\n", RegistryPath); ok((ULONG_PTR)RegistryPath % PAGE_SIZE == 0, "RegistryPath %p not page-aligned\n", RegistryPath); ok_eq_pointer(RegistryPath->Buffer, (PWCHAR)(RegistryPath + 1)); ok_eq_uint(RegistryPath->MaximumLength, RegistryPath->Length); Equal = RtlEqualUnicodeString(&DriverObject->DriverExtension->ServiceKeyName, &ServiceKeyName, FALSE); ok(Equal, "ServiceKeyName is '%wZ'\n", &DriverObject->DriverExtension->ServiceKeyName); ok_eq_tag(KmtGetPoolTag(DriverObject->DriverExtension->ServiceKeyName.Buffer), ' oI'); ok_eq_uint((KmtGetPoolType(DriverObject->DriverExtension->ServiceKeyName.Buffer) - 1) & BASE_POOL_TYPE_MASK, NonPagedPool); ok_eq_uint(DriverObject->DriverExtension->ServiceKeyName.MaximumLength, DriverObject->DriverExtension->ServiceKeyName.Length + sizeof(UNICODE_NULL)); ok_eq_uint(DriverObject->DriverExtension->ServiceKeyName.Buffer[DriverObject->DriverExtension->ServiceKeyName.Length / sizeof(WCHAR)], UNICODE_NULL); Equal = RtlEqualUnicodeString(&DriverObject->DriverName, &DriverName, FALSE); ok(Equal, "DriverName is '%wZ'\n", &DriverObject->DriverName); ok_eq_tag(KmtGetPoolTag(DriverObject->DriverName.Buffer), ' oI'); ok_eq_uint((KmtGetPoolType(DriverObject->DriverName.Buffer) - 1) & BASE_POOL_TYPE_MASK, PagedPool); ok_eq_uint(DriverObject->DriverName.MaximumLength, DriverObject->DriverName.Length); // TODO: show that both string and buffer are constants inside ntos Equal = RtlEqualUnicodeString(DriverObject->HardwareDatabase, &HardwareDatabase, FALSE); ok(Equal, "HardwareDatabase is '%wZ'\n", DriverObject->HardwareDatabase); ok_eq_uint(DriverObject->HardwareDatabase->MaximumLength, DriverObject->HardwareDatabase->Length + sizeof(UNICODE_NULL)); ok_eq_uint(DriverObject->HardwareDatabase->Buffer[DriverObject->HardwareDatabase->Length / sizeof(WCHAR)], UNICODE_NULL); ok(DriverObject->DriverInit == DriverEntry, "DriverInit is %p, expected %p\n", (PVOID)DriverObject->DriverInit, (PVOID)DriverEntry); } else if (DriverStatus == DriverStatusIrp) { ok(DriverObject->DeviceObject != NULL, "Expected DeviceObject pointer to non null\n"); ok (DriverObject->Flags == (DRVO_LEGACY_DRIVER | DRVO_INITIALIZED), "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED, got %lu\n", DriverObject->Flags); } else if (DriverStatus == DriverStatusUnload) { ok(DriverObject->DeviceObject != NULL, "Expected DeviceObject pointer to non null\n"); ok (DriverObject->Flags == (DRVO_LEGACY_DRIVER | DRVO_INITIALIZED | DRVO_UNLOAD_INVOKED), "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED | DRVO_UNLOAD_INVOKED, got %lu\n", DriverObject->Flags); } else ASSERT(FALSE); /* Select a routine that was not changed */ FirstMajorFunc = DriverObject->MajorFunction[1]; ok(FirstMajorFunc != 0, "Expected MajorFunction[1] to be non NULL\n"); if (!skip(FirstMajorFunc != NULL, "First major function not set!\n")) { for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { if (DriverStatus > 0) CheckThisDispatchRoutine = (i > 3) && (i != 14); else CheckThisDispatchRoutine = TRUE; if (CheckThisDispatchRoutine) { ok(DriverObject->MajorFunction[i] == FirstMajorFunc, "Expected MajorFunction[%d] to match %p\n", i, FirstMajorFunc); } } } }
static VOID TestResourceUndocumentedShortcuts( IN PERESOURCE Res, IN BOOLEAN AreApcsDisabled) { PVOID Ret; LONG Count = 0; ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_uint(KeAreAllApcsDisabled(), AreApcsDisabled); /* ExEnterCriticalRegionAndAcquireResourceShared, ExEnterCriticalRegionAndAcquireSharedWaitForExclusive */ Count = 0; Ret = ExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count; ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread); ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU); Ret = ExEnterCriticalRegionAndAcquireResourceShared(Res); ++Count; ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread); ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU); ExEnterCriticalRegionAndAcquireSharedWaitForExclusive(Res); ++Count; ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread); ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU); while (Count-- > 1) { ExReleaseResourceAndLeaveCriticalRegion(Res); ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU); } ExReleaseResourceAndLeaveCriticalRegion(Res); ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU); /* ExEnterCriticalRegionAndAcquireResourceExclusive */ Count = 0; ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); Ret = ExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count; ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread); ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU); Ret = ExEnterCriticalRegionAndAcquireResourceExclusive(Res); ++Count; ok_eq_pointer(Ret, KeGetCurrentThread()->Win32Thread); ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU); ExReleaseResourceAndLeaveCriticalRegion(Res); --Count; ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_bool(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, TRUE, Count, 0LU, 0LU); ExReleaseResourceAndLeaveCriticalRegion(Res); --Count; ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); ok_eq_uint(KeAreAllApcsDisabled(), AreApcsDisabled); CheckResourceStatus(Res, FALSE, Count, 0LU, 0LU); }
static VOID NTAPI DpcHandler( IN PRKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { PKPRCB Prcb = KeGetCurrentPrcb(); ok_irql(DISPATCH_LEVEL); InterlockedIncrement(&DpcCount); ok(DeferredContext == Dpc, "DeferredContext = %p, Dpc = %p, expected equal\n", DeferredContext, Dpc); ok_eq_pointer(SystemArgument1, (PVOID)0xabc123); ok_eq_pointer(SystemArgument2, (PVOID)0x5678); /* KDPC object contents */ ok_eq_uint(Dpc->Type, DpcObject); ok_eq_uint(Dpc->Importance, DpcImportance); ok_eq_uint(Dpc->Number, 0); ok(Dpc->DpcListEntry.Blink != NULL, "\n"); ok(Dpc->DpcListEntry.Blink != &Dpc->DpcListEntry, "\n"); if (!skip(Dpc->DpcListEntry.Blink != NULL, "DpcListEntry.Blink == NULL\n")) ok_eq_pointer(Dpc->DpcListEntry.Flink, Dpc->DpcListEntry.Blink->Flink); ok(Dpc->DpcListEntry.Flink != NULL, "\n"); ok(Dpc->DpcListEntry.Flink != &Dpc->DpcListEntry, "\n"); if (!skip(Dpc->DpcListEntry.Flink != NULL, "DpcListEntry.Flink == NULL\n")) ok_eq_pointer(Dpc->DpcListEntry.Blink, Dpc->DpcListEntry.Flink->Blink); ok_eq_pointer(Dpc->DeferredRoutine, DpcHandler); ok_eq_pointer(Dpc->DeferredContext, DeferredContext); ok_eq_pointer(Dpc->SystemArgument1, SystemArgument1); ok_eq_pointer(Dpc->SystemArgument2, SystemArgument2); ok_eq_pointer(Dpc->DpcData, NULL); ok_eq_uint(Prcb->DpcRoutineActive, 1); /* this DPC is not in the list anymore, but it was at the head! */ ok_eq_pointer(Prcb->DpcData[DPC_NORMAL].DpcListHead.Flink, Dpc->DpcListEntry.Flink); ok_eq_pointer(Prcb->DpcData[DPC_NORMAL].DpcListHead.Blink, Dpc->DpcListEntry.Blink); }
static NTSTATUS TestIrpHandler( _In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PIO_STACK_LOCATION IoStack) { NTSTATUS Status; PTEST_FCB Fcb; CACHE_UNINITIALIZE_EVENT CacheUninitEvent; PAGED_CODE(); DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction); ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP || IoStack->MajorFunction == IRP_MJ_CREATE || IoStack->MajorFunction == IRP_MJ_READ); Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; if (IoStack->MajorFunction == IRP_MJ_CREATE) { if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR)) { TestDeviceObject = DeviceObject; TestFileObject = IoStack->FileObject; } Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI'); RtlZeroMemory(Fcb, sizeof(*Fcb)); ExInitializeFastMutex(&Fcb->HeaderMutex); FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex); if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) && IoStack->FileObject->FileName.Buffer[1] == 'B') { Fcb->Header.AllocationSize.QuadPart = 1000000; Fcb->Header.FileSize.QuadPart = 1000000; Fcb->Header.ValidDataLength.QuadPart = 1000000; } else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) && IoStack->FileObject->FileName.Buffer[1] == 'S') { Fcb->Header.AllocationSize.QuadPart = 3000; Fcb->Header.FileSize.QuadPart = 3000; Fcb->Header.ValidDataLength.QuadPart = 3000; } else { Fcb->Header.AllocationSize.QuadPart = 512; Fcb->Header.FileSize.QuadPart = 512; Fcb->Header.ValidDataLength.QuadPart = 512; } Fcb->Header.IsFastIoPossible = FALSE; IoStack->FileObject->FsContext = Fcb; IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers; CcInitializeCacheMap(IoStack->FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize, FALSE, &Callbacks, NULL); Irp->IoStatus.Information = FILE_OPENED; Status = STATUS_SUCCESS; } else if (IoStack->MajorFunction == IRP_MJ_READ) { BOOLEAN Ret; ULONG Length; PVOID Buffer; LARGE_INTEGER Offset; Offset = IoStack->Parameters.Read.ByteOffset; Length = IoStack->Parameters.Read.Length; Fcb = IoStack->FileObject->FsContext; ok_eq_pointer(DeviceObject, TestDeviceObject); ok_eq_pointer(IoStack->FileObject, TestFileObject); if (!FlagOn(Irp->Flags, IRP_NOCACHE)) { ok(Offset.QuadPart % 512 != 0, "Offset is aligned: %I64i\n", Offset.QuadPart); ok(Length % 512 != 0, "Length is aligned: %I64i\n", Length); Buffer = MapUserBuffer(Irp); ok(Buffer != NULL, "Null pointer!\n"); _SEH2_TRY { Ret = CcCopyRead(IoStack->FileObject, &Offset, Length, TRUE, Buffer, &Irp->IoStatus); ok_bool_true(Ret, "CcCopyRead"); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Irp->IoStatus.Status = _SEH2_GetExceptionCode(); } _SEH2_END; Status = Irp->IoStatus.Status; }
static VOID TestObjectTypes(VOID) { ULONG Index; ObpTypeObjectType = GetObjectType(L"\\ObjectTypes\\Type"); if (skip(ObpTypeObjectType != NULL, "No Type object type\n")) return; ObpDefaultObject = ObpTypeObjectType->DefaultObject; ok(ObpDefaultObject != NULL, "No ObpDefaultObject\n"); SeDefaultObjectMethod = ObpTypeObjectType->TypeInfo.SecurityProcedure; ok(SeDefaultObjectMethod != NULL, "No SeDefaultObjectMethod\n"); #ifdef _PROPER_NT_NDK_EXPORTS #define ObpTypeObjectType *ObpTypeObjectType #define ObpDirectoryObjectType *ObpDirectoryObjectType #define ObpSymbolicLinkObjectType *ObpSymbolicLinkObjectType #define PsJobType *PsJobType #define DbgkDebugObjectType *DbgkDebugObjectType #define ExEventPairObjectType *ExEventPairObjectType #define ExMutantObjectType *ExMutantObjectType #define ExCallbackObjectType *ExCallbackObjectType #define ExTimerObjectType *ExTimerObjectType #define ExProfileObjectType *ExProfileObjectType #define ExpKeyedEventObjectType *ExpKeyedEventObjectType #define ExWindowStationObjectType *ExWindowStationObjectType #define ExDesktopObjectType *ExDesktopObjectType #define MmSectionObjectType *MmSectionObjectType #define CmpKeyObjectType *CmpKeyObjectType #define LpcPortObjectType *LpcPortObjectType #define LpcWaitablePortObjectType *LpcWaitablePortObjectType #define IoAdapterObjectType *IoAdapterObjectType #define IoControllerObjectType *IoControllerObjectType #define IoDeviceObjectType *IoDeviceObjectType #define IoDriverObjectType *IoDriverObjectType #define IoCompletionObjectType *IoCompletionObjectType #define WmipGuidObjectType *WmipGuidObjectType #endif Index = 1; CheckObjectType(Type, ObpTypeObjectType, OBT_MAINTAIN_TYPE_LIST | OBT_CUSTOM_KEY, 0x100, 0x020000, 0x020000, 0x020000, 0x0f0001, 0x1f0001); ok_eq_hex(ObpTypeObjectType->Key, TAG('ObjT')); CheckObjectType(Directory, ObpDirectoryObjectType, OBT_CASE_INSENSITIVE | OBT_PAGED_POOL, 0x100, 0x020003, 0x02000c, 0x020003, 0x0f000f, 0x0f000f); CheckObjectType(SymbolicLink, ObpSymbolicLinkObjectType, OBT_CASE_INSENSITIVE | OBT_PAGED_POOL, 0x100, 0x020001, 0x020000, 0x020001, 0x0f0001, 0x0f0001); CheckObjectType(Token, *SeTokenObjectType, OBT_SECURITY_REQUIRED | OBT_PAGED_POOL, 0x100, 0x020008, 0x0200e0, 0x020000, 0x0f01ff, 0x1f01ff); CheckObjectType(Process, *PsProcessType, OBT_NO_DEFAULT | OBT_SECURITY_REQUIRED, 0x0b0, 0x020410, 0x020beb, 0x120000, 0x1f0fff, 0x1f0fff); CheckObjectType(Thread, *PsThreadType, OBT_NO_DEFAULT | OBT_SECURITY_REQUIRED, 0x0b0, 0x020048, 0x020037, 0x120000, 0x1f03ff, 0x1f03ff); CheckObjectType(Job, PsJobType, OBT_NO_DEFAULT | OBT_SECURITY_REQUIRED, 0x000, 0x020004, 0x02000b, 0x120000, 0x1f03ff, 0x1f001f); CheckObjectType(DebugObject, DbgkDebugObjectType, OBT_NO_DEFAULT | OBT_SECURITY_REQUIRED, 0x000, 0x020001, 0x020002, 0x120000, 0x1f000f, 0x1f000f); CheckObjectType(Event, *ExEventObjectType, OBT_NO_DEFAULT, 0x100, 0x020001, 0x020002, 0x120000, 0x1f0003, 0x1f0003); CheckObjectType(EventPair, ExEventPairObjectType, 0, 0x100, 0x120000, 0x120000, 0x120000, 0x1f0000, 0x1f0000); CheckObjectType(Mutant, ExMutantObjectType, OBT_NO_DEFAULT, 0x100, 0x020001, 0x020000, 0x120000, 0x1f0001, 0x1f0001); CheckObjectType(Callback, ExCallbackObjectType, OBT_NO_DEFAULT, 0x100, 0x020000, 0x020001, 0x120000, 0x1f0001, 0x1f0001); CheckObjectType(Semaphore, *ExSemaphoreObjectType, OBT_NO_DEFAULT, 0x100, 0x020001, 0x020002, 0x120000, 0x1f0003, 0x1f0003); CheckObjectType(Timer, ExTimerObjectType, OBT_NO_DEFAULT, 0x100, 0x020001, 0x020002, 0x120000, 0x1f0003, 0x1f0003); CheckObjectType(Profile, ExProfileObjectType, OBT_NO_DEFAULT, 0x100, 0x020001, 0x020001, 0x020001, 0x0f0001, 0x0f0001); CheckObjectType(KeyedEvent, ExpKeyedEventObjectType, OBT_PAGED_POOL, 0x000, 0x020001, 0x020002, 0x020000, 0x0f0003, 0x1f0003); CheckObjectType(WindowStation, ExWindowStationObjectType, OBT_NO_DEFAULT | OBT_SECURITY_REQUIRED | OBT_MAINTAIN_HANDLE_COUNT, 0x130, 0x020303, 0x02001c, 0x020060, 0x0f037f, 0x0f037f); CheckObjectType(Desktop, ExDesktopObjectType, OBT_NO_DEFAULT | OBT_SECURITY_REQUIRED | OBT_MAINTAIN_HANDLE_COUNT, 0x130, 0x020041, 0x0200be, 0x020100, 0x0f01ff, 0x0f01ff); CheckObjectType(Section, MmSectionObjectType, OBT_PAGED_POOL, 0x100, 0x020005, 0x020002, 0x020008, 0x0f001f, 0x1f001f); CheckObjectType(Key, CmpKeyObjectType, OBT_CUSTOM_SECURITY_PROC | OBT_SECURITY_REQUIRED | OBT_PAGED_POOL, 0x030, 0x020019, 0x020006, 0x020019, 0x0f003f, 0x1f003f); CheckObjectType(Port, LpcPortObjectType, OBT_PAGED_POOL, 0x7b2, 0x020001, 0x010001, 0x000000, 0x1f0001, 0x1f0001); CheckObjectType(WaitablePort, LpcWaitablePortObjectType, OBT_NO_DEFAULT, 0x7b2, 0x020001, 0x010001, 0x000000, 0x1f0001, 0x1f0001); CheckObjectType(Adapter, IoAdapterObjectType, 0, 0x100, 0x120089, 0x120116, 0x1200a0, 0x1f01ff, 0x1f01ff); CheckObjectType(Controller, IoControllerObjectType, 0, 0x100, 0x120089, 0x120116, 0x1200a0, 0x1f01ff, 0x1f01ff); CheckObjectType(Device, IoDeviceObjectType, OBT_CUSTOM_SECURITY_PROC | OBT_CASE_INSENSITIVE, 0x100, 0x120089, 0x120116, 0x1200a0, 0x1f01ff, 0x1f01ff); CheckObjectType(Driver, IoDriverObjectType, OBT_CASE_INSENSITIVE, 0x100, 0x120089, 0x120116, 0x1200a0, 0x1f01ff, 0x1f01ff); CheckObjectType(IoCompletion, IoCompletionObjectType, OBT_CASE_INSENSITIVE, 0x110, 0x020001, 0x020002, 0x120000, 0x1f0003, 0x1f0003); CheckObjectType(File, *IoFileObjectType, OBT_NO_DEFAULT | OBT_CUSTOM_SECURITY_PROC | OBT_CASE_INSENSITIVE | OBT_MAINTAIN_HANDLE_COUNT, 0x130, 0x120089, 0x120116, 0x1200a0, 0x1f01ff, 0x1f01ff); CheckObjectType(WmiGuid, WmipGuidObjectType, OBT_NO_DEFAULT | OBT_CUSTOM_SECURITY_PROC | OBT_SECURITY_REQUIRED, 0x100, 0x000001, 0x000002, 0x000010, 0x120fff, 0x1f0fff); CheckObjectType(FilterConnectionPort, NULL, OBT_NO_DEFAULT | OBT_SECURITY_REQUIRED, 0x100, 0x020001, 0x010001, 0x000000, 0x1f0001, 0x1f0001); CheckObjectType(FilterCommunicationPort, NULL, OBT_NO_DEFAULT, 0x100, 0x020001, 0x010001, 0x000000, 0x1f0001, 0x1f0001); // exported but not created ok_eq_pointer(IoDeviceHandlerObjectType, NULL); // my Win7/x64 additionally has: // ALPC Port // EtwConsumer // EtwRegistration // IoCompletionReserve // PcwObject // PowerRequest // Session // TmEn // TmRm // TmTm // TmTx // TpWorkerFactory // UserApcReserve // ... and does not have: // Port // WaitablePort ObDereferenceObject(ObpTypeObjectType); }