1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Kernel-Mode Test Suite CcCopyWrite test user-mode part
5  * PROGRAMMER:      Pierre Schweitzer <pierre@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 START_TEST(CcCopyWrite)
11 {
12     HANDLE Handle;
13     NTSTATUS Status;
14     LARGE_INTEGER ByteOffset;
15     IO_STATUS_BLOCK IoStatusBlock;
16     OBJECT_ATTRIBUTES ObjectAttributes;
17     PVOID Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, 4097);
18     UNICODE_STRING BigFile = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\BigFile");
19     UNICODE_STRING SmallFile = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\SmallFile");
20     UNICODE_STRING VerySmallFile = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\VerySmallFile");
21     UNICODE_STRING NormalFile = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\NormalFile");
22     UNICODE_STRING BehaviourTestFile = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyWrite\\BehaviourTestFile");
23 
24     KmtLoadDriver(L"CcCopyWrite", FALSE);
25     KmtOpenDriver();
26 
27     InitializeObjectAttributes(&ObjectAttributes, &VerySmallFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
28     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
29     ok_eq_hex(Status, STATUS_SUCCESS);
30 
31     ByteOffset.QuadPart = 0;
32     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 62, &ByteOffset, NULL);
33     ok_eq_hex(Status, STATUS_SUCCESS);
34 
35     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
36     ok_eq_hex(Status, STATUS_SUCCESS);
37 
38     NtClose(Handle);
39 
40     InitializeObjectAttributes(&ObjectAttributes, &SmallFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
41     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
42     ok_eq_hex(Status, STATUS_SUCCESS);
43 
44     ByteOffset.QuadPart = 0;
45     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 512, &ByteOffset, NULL);
46     ok_eq_hex(Status, STATUS_SUCCESS);
47 
48     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
49     ok_eq_hex(Status, STATUS_SUCCESS);
50 
51     NtClose(Handle);
52 
53     InitializeObjectAttributes(&ObjectAttributes, &NormalFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
54     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
55     ok_eq_hex(Status, STATUS_SUCCESS);
56 
57     ByteOffset.QuadPart = 0;
58     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 1004, &ByteOffset, NULL);
59     ok_eq_hex(Status, STATUS_SUCCESS);
60 
61     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
62     ok_eq_hex(Status, STATUS_SUCCESS);
63 
64     NtClose(Handle);
65 
66     InitializeObjectAttributes(&ObjectAttributes, &BigFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
67     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
68     ok_eq_hex(Status, STATUS_SUCCESS);
69 
70     ByteOffset.QuadPart = 0;
71     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 4097, &ByteOffset, NULL);
72     ok_eq_hex(Status, STATUS_SUCCESS);
73 
74     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
75     ok_eq_hex(Status, STATUS_SUCCESS);
76 
77     NtClose(Handle);
78 
79     InitializeObjectAttributes(&ObjectAttributes, &BigFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
80     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
81     ok_eq_hex(Status, STATUS_SUCCESS);
82 
83     ByteOffset.QuadPart = 4097;
84     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 4097, &ByteOffset, NULL);
85     ok_eq_hex(Status, STATUS_SUCCESS);
86 
87     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
88     ok_eq_hex(Status, STATUS_SUCCESS);
89 
90     NtClose(Handle);
91 
92     InitializeObjectAttributes(&ObjectAttributes, &BehaviourTestFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
93     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
94     ok_eq_hex(Status, STATUS_SUCCESS);
95 
96     ByteOffset.QuadPart = 4097;
97     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 4097, &ByteOffset, NULL);
98     ok_eq_hex(Status, STATUS_SUCCESS);
99 
100     NtClose(Handle);
101 
102     RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
103     KmtCloseDriver();
104     KmtUnloadDriver();
105 }
106