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     DWORD Error;
24 
25     Error = KmtLoadAndOpenDriver(L"CcCopyWrite", FALSE);
26     ok_eq_int(Error, ERROR_SUCCESS);
27     if (Error)
28         return;
29 
30     InitializeObjectAttributes(&ObjectAttributes, &VerySmallFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
31     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
32     ok_eq_hex(Status, STATUS_SUCCESS);
33 
34     ByteOffset.QuadPart = 0;
35     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 62, &ByteOffset, NULL);
36     ok_eq_hex(Status, STATUS_SUCCESS);
37 
38     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
39     ok_eq_hex(Status, STATUS_SUCCESS);
40 
41     NtClose(Handle);
42 
43     InitializeObjectAttributes(&ObjectAttributes, &SmallFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
44     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
45     ok_eq_hex(Status, STATUS_SUCCESS);
46 
47     ByteOffset.QuadPart = 0;
48     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 512, &ByteOffset, NULL);
49     ok_eq_hex(Status, STATUS_SUCCESS);
50 
51     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
52     ok_eq_hex(Status, STATUS_SUCCESS);
53 
54     NtClose(Handle);
55 
56     InitializeObjectAttributes(&ObjectAttributes, &NormalFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
57     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
58     ok_eq_hex(Status, STATUS_SUCCESS);
59 
60     ByteOffset.QuadPart = 0;
61     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 1004, &ByteOffset, NULL);
62     ok_eq_hex(Status, STATUS_SUCCESS);
63 
64     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
65     ok_eq_hex(Status, STATUS_SUCCESS);
66 
67     NtClose(Handle);
68 
69     InitializeObjectAttributes(&ObjectAttributes, &BigFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
70     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
71     ok_eq_hex(Status, STATUS_SUCCESS);
72 
73     ByteOffset.QuadPart = 0;
74     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 4097, &ByteOffset, NULL);
75     ok_eq_hex(Status, STATUS_SUCCESS);
76 
77     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
78     ok_eq_hex(Status, STATUS_SUCCESS);
79 
80     NtClose(Handle);
81 
82     InitializeObjectAttributes(&ObjectAttributes, &BigFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
83     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
84     ok_eq_hex(Status, STATUS_SUCCESS);
85 
86     ByteOffset.QuadPart = 4097;
87     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 4097, &ByteOffset, NULL);
88     ok_eq_hex(Status, STATUS_SUCCESS);
89 
90     Status = NtFlushBuffersFile(Handle, &IoStatusBlock);
91     ok_eq_hex(Status, STATUS_SUCCESS);
92 
93     NtClose(Handle);
94 
95     InitializeObjectAttributes(&ObjectAttributes, &BehaviourTestFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
96     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
97     ok_eq_hex(Status, STATUS_SUCCESS);
98 
99     ByteOffset.QuadPart = 4097;
100     Status = NtWriteFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 4097, &ByteOffset, NULL);
101     ok_eq_hex(Status, STATUS_SUCCESS);
102 
103     NtClose(Handle);
104 
105     RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
106     KmtCloseDriver();
107     KmtUnloadDriver();
108 }
109