1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Kernel-Mode Test Suite CcCopyRead test user-mode part
5  * PROGRAMMER:      Pierre Schweitzer <pierre@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 START_TEST(CcCopyRead)
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, 1024);
18     UNICODE_STRING BigAlignmentTest = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyRead\\BigAlignmentTest");
19     UNICODE_STRING SmallAlignmentTest = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyRead\\SmallAlignmentTest");
20     UNICODE_STRING ReallySmallAlignmentTest = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyRead\\ReallySmallAlignmentTest");
21     UNICODE_STRING FileBig = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyRead\\FileBig");
22     UNICODE_STRING BehaviourTestFile = RTL_CONSTANT_STRING(L"\\Device\\Kmtest-CcCopyRead\\BehaviourTestFile");
23     DWORD Error;
24 
25     Error = KmtLoadAndOpenDriver(L"CcCopyRead", FALSE);
26     ok_eq_int(Error, ERROR_SUCCESS);
27     if (Error)
28         return;
29 
30     InitializeObjectAttributes(&ObjectAttributes, &SmallAlignmentTest, 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 = 3;
35     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 3, &ByteOffset, NULL);
36     ok_eq_hex(Status, STATUS_SUCCESS);
37     ok_eq_hex(((USHORT *)Buffer)[0], 0xBABA);
38 
39     ByteOffset.QuadPart = 514;
40     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 514, &ByteOffset, NULL);
41     ok_eq_hex(Status, STATUS_SUCCESS);
42     ok_eq_hex(((USHORT *)Buffer)[242], 0xBABA);
43     ok_eq_hex(((USHORT *)Buffer)[243], 0xFFFF);
44 
45     ByteOffset.QuadPart = 1000;
46     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 2, &ByteOffset, NULL);
47     ok_eq_hex(Status, STATUS_SUCCESS);
48     ok_eq_hex(((USHORT *)Buffer)[0], 0xFFFF);
49     ok_eq_hex(((USHORT *)Buffer)[1], 0xBABA);
50 
51     NtClose(Handle);
52 
53     InitializeObjectAttributes(&ObjectAttributes, &BigAlignmentTest, 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 = 3;
58     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 3, &ByteOffset, NULL);
59     ok_eq_hex(Status, STATUS_SUCCESS);
60     ok_eq_hex(((USHORT *)Buffer)[0], 0xBABA);
61 
62     ByteOffset.QuadPart = 514;
63     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 514, &ByteOffset, NULL);
64     ok_eq_hex(Status, STATUS_SUCCESS);
65     ok_eq_hex(((USHORT *)Buffer)[242], 0xBABA);
66     ok_eq_hex(((USHORT *)Buffer)[243], 0xFFFF);
67 
68     ByteOffset.QuadPart = 300000;
69     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 10, &ByteOffset, NULL);
70     ok_eq_hex(Status, STATUS_SUCCESS);
71     ok_eq_hex(((USHORT *)Buffer)[0], 0xBABA);
72 
73     ByteOffset.QuadPart = 999990;
74     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 10, &ByteOffset, NULL);
75     ok_eq_hex(Status, STATUS_SUCCESS);
76     ok_eq_hex(((USHORT *)Buffer)[0], 0xBABA);
77 
78     ByteOffset.QuadPart = 1000;
79     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 2, &ByteOffset, NULL);
80     ok_eq_hex(Status, STATUS_SUCCESS);
81     ok_eq_hex(((USHORT *)Buffer)[0], 0xFFFF);
82     ok_eq_hex(((USHORT *)Buffer)[1], 0xBABA);
83 
84     NtClose(Handle);
85 
86     InitializeObjectAttributes(&ObjectAttributes, &ReallySmallAlignmentTest, OBJ_CASE_INSENSITIVE, NULL, NULL);
87     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
88     ok_eq_hex(Status, STATUS_SUCCESS);
89 
90     ByteOffset.QuadPart = 1;
91     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 61, &ByteOffset, NULL);
92     ok_eq_hex(Status, STATUS_SUCCESS);
93     ok_eq_hex(((USHORT *)Buffer)[0], 0xBABA);
94 
95     NtClose(Handle);
96 
97     InitializeObjectAttributes(&ObjectAttributes, &FileBig, OBJ_CASE_INSENSITIVE, NULL, NULL);
98     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
99     ok_eq_hex(Status, STATUS_SUCCESS);
100 
101     ByteOffset.QuadPart = 0;
102     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 1024, &ByteOffset, NULL);
103     ok_eq_hex(Status, STATUS_SUCCESS);
104     ok_eq_hex(((USHORT *)Buffer)[0], 0xBABA);
105 
106     NtClose(Handle);
107 
108     InitializeObjectAttributes(&ObjectAttributes, &BehaviourTestFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
109     Status = NtOpenFile(&Handle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
110     ok_eq_hex(Status, STATUS_SUCCESS);
111 
112     ByteOffset.QuadPart = 0;
113     Status = NtReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, Buffer, 1024, &ByteOffset, NULL);
114 
115     NtClose(Handle);
116 
117     RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
118     KmtCloseDriver();
119     KmtUnloadDriver();
120 }
121