https://git.reactos.org/?p=reactos.git;a=commitdiff;h=98972036d9aa7cfbdb3d3c9c6cf1d9c15472fa34

commit 98972036d9aa7cfbdb3d3c9c6cf1d9c15472fa34
Author:     Pierre Schweitzer <[email protected]>
AuthorDate: Tue Apr 16 08:25:09 2019 +0200
Commit:     Pierre Schweitzer <[email protected]>
CommitDate: Tue Apr 16 19:50:27 2019 +0200

    [KMTESTS:CC] Add tests for CcCopyWrite
    
    CORE-15384
---
 modules/rostests/kmtests/CMakeLists.txt            |   1 +
 modules/rostests/kmtests/kmtest/testlist.c         |   2 +
 modules/rostests/kmtests/ntos_cc/CMakeLists.txt    |  15 +
 modules/rostests/kmtests/ntos_cc/CcCopyWrite_drv.c | 373 +++++++++++++++++++++
 .../rostests/kmtests/ntos_cc/CcCopyWrite_user.c    |  94 ++++++
 5 files changed, 485 insertions(+)

diff --git a/modules/rostests/kmtests/CMakeLists.txt 
b/modules/rostests/kmtests/CMakeLists.txt
index ddfde9600d..b7cf7093ad 100644
--- a/modules/rostests/kmtests/CMakeLists.txt
+++ b/modules/rostests/kmtests/CMakeLists.txt
@@ -138,6 +138,7 @@ list(APPEND KMTEST_SOURCE
     kernel32/FileAttributes_user.c
     kernel32/FindFile_user.c
     ntos_cc/CcCopyRead_user.c
+    ntos_cc/CcCopyWrite_user.c
     ntos_cc/CcMapData_user.c
     ntos_cc/CcPinMappedData_user.c
     ntos_cc/CcPinRead_user.c
diff --git a/modules/rostests/kmtests/kmtest/testlist.c 
b/modules/rostests/kmtests/kmtest/testlist.c
index 0c5e2010d6..5375d04cde 100644
--- a/modules/rostests/kmtests/kmtest/testlist.c
+++ b/modules/rostests/kmtests/kmtest/testlist.c
@@ -7,6 +7,7 @@
 #include <kmt_test.h>
 
 KMT_TESTFUNC Test_CcCopyRead;
+KMT_TESTFUNC Test_CcCopyWrite;
 KMT_TESTFUNC Test_CcMapData;
 KMT_TESTFUNC Test_CcPinMappedData;
 KMT_TESTFUNC Test_CcPinRead;
@@ -39,6 +40,7 @@ KMT_TESTFUNC Test_TcpIpConnect;
 const KMT_TEST TestList[] =
 {
     { "CcCopyRead",                   Test_CcCopyRead },
+    { "CcCopyWrite",                  Test_CcCopyWrite },
     { "CcMapData",                    Test_CcMapData },
     { "CcPinMappedData",              Test_CcPinMappedData },
     { "CcPinRead",                    Test_CcPinRead },
diff --git a/modules/rostests/kmtests/ntos_cc/CMakeLists.txt 
b/modules/rostests/kmtests/ntos_cc/CMakeLists.txt
index 60912ad1cc..b31a1e5058 100644
--- a/modules/rostests/kmtests/ntos_cc/CMakeLists.txt
+++ b/modules/rostests/kmtests/ntos_cc/CMakeLists.txt
@@ -16,6 +16,21 @@ add_target_compile_definitions(cccopyread_drv 
KMT_STANDALONE_DRIVER)
 #add_pch(cccopyread_drv ../include/kmt_test.h)
 add_rostests_file(TARGET cccopyread_drv)
 
+#
+# CcCopyWrite
+#
+list(APPEND CCCOPYWRITE_DRV_SOURCE
+    ../kmtest_drv/kmtest_standalone.c
+    CcCopyWrite_drv.c)
+
+add_library(cccopywrite_drv MODULE ${CCCOPYWRITE_DRV_SOURCE})
+set_module_type(cccopywrite_drv kernelmodedriver)
+target_link_libraries(cccopywrite_drv kmtest_printf ${PSEH_LIB})
+add_importlibs(cccopywrite_drv ntoskrnl hal)
+add_target_compile_definitions(cccopywrite_drv KMT_STANDALONE_DRIVER)
+#add_pch(cccopyread_drv ../include/kmt_test.h)
+add_rostests_file(TARGET cccopywrite_drv)
+
 #
 # CcMapData
 #
diff --git a/modules/rostests/kmtests/ntos_cc/CcCopyWrite_drv.c 
b/modules/rostests/kmtests/ntos_cc/CcCopyWrite_drv.c
new file mode 100644
index 0000000000..9404be1c14
--- /dev/null
+++ b/modules/rostests/kmtests/ntos_cc/CcCopyWrite_drv.c
@@ -0,0 +1,373 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE:         Test driver for CcCopyWrite function
+ * PROGRAMMER:      Pierre Schweitzer <[email protected]>
+ */
+
+#include <kmt_test.h>
+
+#define NDEBUG
+#include <debug.h>
+
+typedef struct _TEST_FCB
+{
+    FSRTL_ADVANCED_FCB_HEADER Header;
+    SECTION_OBJECT_POINTERS SectionObjectPointers;
+    FAST_MUTEX HeaderMutex;
+    ULONG WriteLength;
+} TEST_FCB, *PTEST_FCB;
+
+static PFILE_OBJECT TestFileObject;
+static PDEVICE_OBJECT TestDeviceObject;
+static KMT_IRP_HANDLER TestIrpHandler;
+static FAST_IO_DISPATCH TestFastIoDispatch;
+
+static
+BOOLEAN
+NTAPI
+FastIoRead(
+    _In_ PFILE_OBJECT FileObject,
+    _In_ PLARGE_INTEGER FileOffset,
+    _In_ ULONG Length,
+    _In_ BOOLEAN Wait,
+    _In_ ULONG LockKey,
+    _Out_ PVOID Buffer,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject)
+{
+    IoStatus->Status = STATUS_NOT_SUPPORTED;
+    return FALSE;
+}
+
+static
+BOOLEAN
+NTAPI
+FastIoWrite(
+    _In_ PFILE_OBJECT FileObject,
+    _In_ PLARGE_INTEGER FileOffset,
+    _In_ ULONG Length,
+    _In_ BOOLEAN Wait,
+    _In_ ULONG LockKey,
+    _Out_ PVOID Buffer,
+    _Out_ PIO_STATUS_BLOCK IoStatus,
+    _In_ PDEVICE_OBJECT DeviceObject)
+{
+    IoStatus->Status = STATUS_NOT_SUPPORTED;
+    return FALSE;
+}
+
+NTSTATUS
+TestEntry(
+    _In_ PDRIVER_OBJECT DriverObject,
+    _In_ PCUNICODE_STRING RegistryPath,
+    _Out_ PCWSTR *DeviceName,
+    _Inout_ INT *Flags)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+
+    UNREFERENCED_PARAMETER(RegistryPath);
+
+    *DeviceName = L"CcCopyWrite";
+    *Flags = TESTENTRY_NO_EXCLUSIVE_DEVICE |
+             TESTENTRY_BUFFERED_IO_DEVICE |
+             TESTENTRY_NO_READONLY_DEVICE;
+
+    KmtRegisterIrpHandler(IRP_MJ_CLEANUP, NULL, TestIrpHandler);
+    KmtRegisterIrpHandler(IRP_MJ_CREATE, NULL, TestIrpHandler);
+    KmtRegisterIrpHandler(IRP_MJ_READ, NULL, TestIrpHandler);
+    KmtRegisterIrpHandler(IRP_MJ_WRITE, NULL, TestIrpHandler);
+    KmtRegisterIrpHandler(IRP_MJ_FLUSH_BUFFERS, NULL, TestIrpHandler);
+
+    TestFastIoDispatch.FastIoRead = FastIoRead;
+    TestFastIoDispatch.FastIoWrite = FastIoWrite;
+    DriverObject->FastIoDispatch = &TestFastIoDispatch;
+
+
+    return Status;
+}
+
+VOID
+TestUnload(
+    _In_ PDRIVER_OBJECT DriverObject)
+{
+    PAGED_CODE();
+}
+
+BOOLEAN
+NTAPI
+AcquireForLazyWrite(
+    _In_ PVOID Context,
+    _In_ BOOLEAN Wait)
+{
+    return TRUE;
+}
+
+VOID
+NTAPI
+ReleaseFromLazyWrite(
+    _In_ PVOID Context)
+{
+    return;
+}
+
+BOOLEAN
+NTAPI
+AcquireForReadAhead(
+    _In_ PVOID Context,
+    _In_ BOOLEAN Wait)
+{
+    return TRUE;
+}
+
+VOID
+NTAPI
+ReleaseFromReadAhead(
+    _In_ PVOID Context)
+{
+    return;
+}
+
+static CACHE_MANAGER_CALLBACKS Callbacks = {
+    AcquireForLazyWrite,
+    ReleaseFromLazyWrite,
+    AcquireForReadAhead,
+    ReleaseFromReadAhead,
+};
+
+static
+PVOID
+MapAndLockUserBuffer(
+    _In_ _Out_ PIRP Irp,
+    _In_ ULONG BufferLength)
+{
+    PMDL Mdl;
+
+    if (Irp->MdlAddress == NULL)
+    {
+        Mdl = IoAllocateMdl(Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp);
+        if (Mdl == NULL)
+        {
+            return NULL;
+        }
+
+        _SEH2_TRY
+        {
+            MmProbeAndLockPages(Mdl, Irp->RequestorMode, IoWriteAccess);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            IoFreeMdl(Mdl);
+            Irp->MdlAddress = NULL;
+            _SEH2_YIELD(return NULL);
+        }
+        _SEH2_END;
+    }
+
+    return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
+}
+
+
+static
+NTSTATUS
+TestIrpHandler(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _In_ PIRP Irp,
+    _In_ PIO_STACK_LOCATION IoStack)
+{
+    LARGE_INTEGER Zero = RTL_CONSTANT_LARGE_INTEGER(0LL);
+    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 ||
+           IoStack->MajorFunction == IRP_MJ_WRITE ||
+           IoStack->MajorFunction == IRP_MJ_FLUSH_BUFFERS);
+
+    Status = STATUS_NOT_SUPPORTED;
+    Irp->IoStatus.Information = 0;
+
+    if (IoStack->MajorFunction == IRP_MJ_CREATE)
+    {
+        ok_irql(PASSIVE_LEVEL);
+
+        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 = 512;
+            Fcb->Header.FileSize.QuadPart = 512;
+            Fcb->Header.ValidDataLength.QuadPart = 512;
+        }
+        else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
+                 IoStack->FileObject->FileName.Buffer[1] == 'V')
+        {
+            Fcb->Header.AllocationSize.QuadPart = 62;
+            Fcb->Header.FileSize.QuadPart = 62;
+            Fcb->Header.ValidDataLength.QuadPart = 62;
+        }
+        else
+        {
+            Fcb->Header.AllocationSize.QuadPart = 1004;
+            Fcb->Header.FileSize.QuadPart = 1004;
+            Fcb->Header.ValidDataLength.QuadPart = 1004;
+        }
+        Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
+        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)
+    {
+        PMDL Mdl;
+        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);
+
+        ok(BooleanFlagOn(Irp->Flags, IRP_NOCACHE), "IRP not coming from 
Cc!\n");
+        ok_irql(APC_LEVEL);
+        ok((Offset.QuadPart == 0 || Offset.QuadPart == 4096 || Offset.QuadPart 
== 8192), "Unexpected offset: %I64i\n", Offset.QuadPart);
+        ok(Length % PAGE_SIZE == 0, "Length is not aligned: %I64i\n", Length);
+
+        ok(Irp->AssociatedIrp.SystemBuffer == NULL, "A SystemBuffer was 
allocated!\n");
+        Buffer = MapAndLockUserBuffer(Irp, Length);
+        ok(Buffer != NULL, "Null pointer!\n");
+        RtlFillMemory(Buffer, Length, 0xBA);
+
+        Status = STATUS_SUCCESS;
+
+        Mdl = Irp->MdlAddress;
+        ok(Mdl != NULL, "Null pointer for MDL!\n");
+        ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0, "MDL not locked\n");
+        ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non 
paged\n");
+        ok((Mdl->MdlFlags & MDL_IO_PAGE_READ) != 0, "Non paging IO\n");
+        ok((Irp->Flags & IRP_PAGING_IO) != 0, "Non paging IO\n");
+
+        Irp->IoStatus.Information = Length;
+        IoStack->FileObject->CurrentByteOffset.QuadPart = Offset.QuadPart + 
Length;
+    }
+    else if (IoStack->MajorFunction == IRP_MJ_WRITE)
+    {
+        PMDL Mdl;
+        ULONG Length;
+        PVOID Buffer;
+        LARGE_INTEGER Offset;
+
+        Offset = IoStack->Parameters.Read.ByteOffset;
+        Length = IoStack->Parameters.Read.Length;
+        Fcb = IoStack->FileObject->FsContext;
+
+        if (!FlagOn(Irp->Flags, IRP_NOCACHE))
+        {
+            BOOLEAN Ret;
+
+            ok_irql(PASSIVE_LEVEL);
+
+            Buffer = Irp->AssociatedIrp.SystemBuffer;
+            ok(Buffer != NULL, "Null pointer!\n");
+
+            Fcb->WriteLength = Length;
+
+            _SEH2_TRY
+            {
+                Ret = CcCopyWrite(IoStack->FileObject, &Offset, Length, TRUE, 
Buffer);
+                ok_bool_true(Ret, "CcCopyWrite");
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                Irp->IoStatus.Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+
+            Status = Irp->IoStatus.Status;
+        }
+        else
+        {
+            ok_irql(PASSIVE_LEVEL);
+            ok((Offset.QuadPart == 0 || Offset.QuadPart == 4096), "Unexpected 
offset: %I64i\n", Offset.QuadPart);
+            ok_eq_ulong(Length, ROUND_TO_PAGES(Fcb->WriteLength));
+
+            ok(Irp->AssociatedIrp.SystemBuffer == NULL, "A SystemBuffer was 
allocated!\n");
+            Buffer = MapAndLockUserBuffer(Irp, Length);
+            ok(Buffer != NULL, "Null pointer!\n");
+
+            Status = STATUS_SUCCESS;
+
+            Mdl = Irp->MdlAddress;
+            ok(Mdl != NULL, "Null pointer for MDL!\n");
+            ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0, "MDL not locked\n");
+            ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from 
non paged\n");
+            ok((Mdl->MdlFlags & MDL_IO_PAGE_READ) == 0, "MDL for read paging 
IO\n");
+            ok((Irp->Flags & IRP_PAGING_IO) != 0, "Non paging IO\n");
+        }
+    }
+    else if (IoStack->MajorFunction == IRP_MJ_FLUSH_BUFFERS)
+    {
+        IO_STATUS_BLOCK IoStatus;
+
+        Fcb = IoStack->FileObject->FsContext;
+        CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus);
+
+        Status = STATUS_SUCCESS;
+    }
+    else if (IoStack->MajorFunction == IRP_MJ_CLEANUP)
+    {
+        ok_irql(PASSIVE_LEVEL);
+        KeInitializeEvent(&CacheUninitEvent.Event, NotificationEvent, FALSE);
+        CcUninitializeCacheMap(IoStack->FileObject, &Zero, &CacheUninitEvent);
+        KeWaitForSingleObject(&CacheUninitEvent.Event, Executive, KernelMode, 
FALSE, NULL);
+        Fcb = IoStack->FileObject->FsContext;
+        ExFreePoolWithTag(Fcb, 'FwrI');
+        IoStack->FileObject->FsContext = NULL;
+        Status = STATUS_SUCCESS;
+    }
+
+    if (Status == STATUS_PENDING)
+    {
+        IoMarkIrpPending(Irp);
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        Status = STATUS_PENDING;
+    }
+    else
+    {
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+
+    return Status;
+}
diff --git a/modules/rostests/kmtests/ntos_cc/CcCopyWrite_user.c 
b/modules/rostests/kmtests/ntos_cc/CcCopyWrite_user.c
new file mode 100644
index 0000000000..1b5f8d6187
--- /dev/null
+++ b/modules/rostests/kmtests/ntos_cc/CcCopyWrite_user.c
@@ -0,0 +1,94 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite CcCopyWrite test user-mode part
+ * PROGRAMMER:      Pierre Schweitzer <[email protected]>
+ */
+
+#include <kmt_test.h>
+
+START_TEST(CcCopyWrite)
+{
+    HANDLE Handle;
+    NTSTATUS Status;
+    LARGE_INTEGER ByteOffset;
+    IO_STATUS_BLOCK IoStatusBlock;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    PVOID Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, 4097);
+    UNICODE_STRING BigFile = 
RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\BigFile");
+    UNICODE_STRING SmallFile = 
RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\SmallFile");
+    UNICODE_STRING VerySmallFile = 
RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\VerySmallFile");
+    UNICODE_STRING NormalFile = 
RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\NormalFile");
+    
+    KmtLoadDriver(L"CcCopyWrite", FALSE);
+    KmtOpenDriver();
+
+    InitializeObjectAttributes(&ObjectAttributes, &VerySmallFile, 
OBJ_CASE_INSENSITIVE, NULL, NULL);
+    Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, 
&IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    ByteOffset.QuadPart = 0;
+    Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 62, 
&ByteOffset, NULL);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    NtClose(Handle);
+
+    InitializeObjectAttributes(&ObjectAttributes, &SmallFile, 
OBJ_CASE_INSENSITIVE, NULL, NULL);
+    Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, 
&IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    ByteOffset.QuadPart = 0;
+    Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 
512, &ByteOffset, NULL);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    NtClose(Handle);
+
+    InitializeObjectAttributes(&ObjectAttributes, &NormalFile, 
OBJ_CASE_INSENSITIVE, NULL, NULL);
+    Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, 
&IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    ByteOffset.QuadPart = 0;
+    Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 
1004, &ByteOffset, NULL);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    NtClose(Handle);
+
+    InitializeObjectAttributes(&ObjectAttributes, &BigFile, 
OBJ_CASE_INSENSITIVE, NULL, NULL);
+    Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, 
&IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    ByteOffset.QuadPart = 0;
+    Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 
4097, &ByteOffset, NULL);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    NtClose(Handle);
+
+    InitializeObjectAttributes(&ObjectAttributes, &BigFile, 
OBJ_CASE_INSENSITIVE, NULL, NULL);
+    Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, 
&IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    ByteOffset.QuadPart = 4097;
+    Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 
4097, &ByteOffset, NULL);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
+    ok_eq_hex(Status, STATUS_SUCCESS);
+
+    NtClose(Handle);
+
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+    KmtCloseDriver();
+    KmtUnloadDriver();
+}

Reply via email to