1 /*
2  * PROJECT:     ReactOS api tests
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Test for CAtlFileMapping
5  * COPYRIGHT:   Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
6  */
7 
8 #include <atlfile.h>
9 
10 #ifdef HAVE_APITEST
11     #include <apitest.h>
12 #else
13     #include "atltest.h"
14 #endif
15 
16 struct TestData
17 {
18     int data[4];
19 };
20 
21 
22 static void test_SharedMem()
23 {
24     CAtlFileMapping<TestData> test1, test2;
25     CAtlFileMappingBase test3;
26     BOOL bAlreadyExisted;
27     HRESULT hr;
28 
29     ok(test1.GetData() == NULL, "Expected NULL, got %p\n", test1.GetData());
30     ok(test3.GetData() == NULL, "Expected NULL, got %p\n", test3.GetData());
31     ok(test1.GetHandle() == NULL, "Expected NULL, got %p\n", test1.GetHandle());
32     ok(test3.GetHandle() == NULL, "Expected NULL, got %p\n", test3.GetHandle());
33     ok(test1.GetMappingSize() == 0, "Expected 0, got %lu\n", test1.GetMappingSize());
34     ok(test3.GetMappingSize() == 0, "Expected 0, got %lu\n", test3.GetMappingSize());
35 
36     test1 = test1;
37     //test1 = test2;  // Asserts on orig.m_pData != NULL, same with CopyFrom
38     //test1 = test3;  // does not compile
39     hr = test1.Unmap();
40     ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
41 
42     // Asserts on name == NULL
43     hr = test1.OpenMapping(_T("TEST_MAPPING"), 123, 0, FILE_MAP_ALL_ACCESS);
44     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%lx\n", hr);
45     ok(test1.GetData() == NULL, "Expected NULL, got %p\n", test1.GetData());
46     ok(test1.GetHandle() == NULL, "Expected NULL, got %p\n", test1.GetHandle());
47     ok(test1.GetMappingSize() == 123, "Expected 123, got %lu\n", test1.GetMappingSize());
48 
49     hr = test1.Unmap();
50     ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
51     ok(test1.GetData() == NULL, "Expected NULL, got %p\n", test1.GetData());
52     ok(test1.GetHandle() == NULL, "Expected NULL, got %p\n", test1.GetHandle());
53     ok(test1.GetMappingSize() == 123, "Expected 123, got %lu\n", test1.GetMappingSize());
54 
55     bAlreadyExisted = 123;
56     hr = test1.MapSharedMem(sizeof(TestData), _T("TEST_MAPPING"), &bAlreadyExisted, (LPSECURITY_ATTRIBUTES)0, PAGE_READWRITE, FILE_MAP_ALL_ACCESS);
57     ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
58     ok(test1.GetData() != NULL, "Expected ptr, got %p\n", test1.GetData());
59     ok(test1.GetHandle() != NULL, "Expected handle, got %p\n", test1.GetHandle());
60     ok(test1.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test1.GetMappingSize());
61     ok(bAlreadyExisted == FALSE, "Expected FALSE, got %u\n", bAlreadyExisted);
62 
63     if (test1.GetData())
64     {
65         memset(test1.GetData(), 0x35, sizeof(TestData));
66     }
67 
68     hr = test2.CopyFrom(test1);
69     ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
70     ok(test2.GetData() != NULL, "Expected ptr, got %p\n", test2.GetData());
71     ok(test2.GetHandle() != NULL, "Expected handle, got %p\n", test2.GetHandle());
72     ok(test2.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test2.GetMappingSize());
73 
74     // test1 is not closed:
75     ok(test1.GetData() != NULL, "Expected ptr, got %p\n", test1.GetData());
76     ok(test1.GetHandle() != NULL, "Expected handle, got %p\n", test1.GetHandle());
77     ok(test1.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test1.GetMappingSize());
78 
79     // test2 does not equal test1
80     ok(test1.GetData() != test2.GetData(), "Expected different ptrs\n");
81     ok(test1.GetHandle() != test2.GetHandle(), "Expected different handles\n");
82 
83     TestData* t1 = test1;
84     TestData* t2 = test2;
85     if (t1 && t2)
86     {
87         ok(t1->data[0] == 0x35353535, "Expected 0x35353535, got 0x%x\n", t1->data[0]);
88         ok(t2->data[0] == 0x35353535, "Expected 0x35353535, got 0x%x\n", t2->data[0]);
89 
90         t1->data[0] = 0xbeefbeef;
91         ok(t1->data[0] == (int)0xbeefbeef, "Expected 0xbeefbeef, got 0x%x\n", t1->data[0]);
92         ok(t2->data[0] == (int)0xbeefbeef, "Expected 0xbeefbeef, got 0x%x\n", t2->data[0]);
93     }
94 
95     hr = test3.OpenMapping(_T("TEST_MAPPING"), sizeof(TestData), offsetof(TestData, data[1]));
96     ok(hr == HRESULT_FROM_WIN32(ERROR_MAPPED_ALIGNMENT), "Expected HRESULT_FROM_WIN32(ERROR_MAPPED_ALIGNMENT), got 0x%lx\n", hr);
97     ok(test3.GetData() == NULL, "Expected NULL, got %p\n", test3.GetData());
98     ok(test3.GetHandle() == NULL, "Expected NULL, got %p\n", test3.GetHandle());
99     ok(test3.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test3.GetMappingSize());
100 
101     hr = test2.Unmap();
102     ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
103     ok(test2.GetData() == NULL, "Expected NULL, got %p\n", test2.GetData());
104     ok(test2.GetHandle() == NULL, "Expected NULL, got %p\n", test2.GetHandle());
105     ok(test2.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test2.GetMappingSize());
106 
107     bAlreadyExisted = 123;
108     // Wrong access flag
109     hr = test2.MapSharedMem(sizeof(TestData), _T("TEST_MAPPING"), &bAlreadyExisted, (LPSECURITY_ATTRIBUTES)0, PAGE_EXECUTE_READ, FILE_MAP_ALL_ACCESS);
110     ok(hr == E_ACCESSDENIED, "Expected E_ACCESSDENIED, got 0x%lx\n", hr);
111     ok(test2.GetData() == NULL, "Expected NULL, got %p\n", test2.GetData());
112     ok(test2.GetHandle() == NULL, "Expected NULL, got %p\n", test2.GetHandle());
113     ok(test2.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test2.GetMappingSize());
114     ok(bAlreadyExisted == TRUE, "Expected TRUE, got %u\n", bAlreadyExisted);
115 
116     bAlreadyExisted = 123;
117     hr = test2.MapSharedMem(sizeof(TestData), _T("TEST_MAPPING"), &bAlreadyExisted, (LPSECURITY_ATTRIBUTES)0, PAGE_READWRITE, FILE_MAP_ALL_ACCESS);
118     ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
119     ok(test2.GetData() != NULL, "Expected ptr, got %p\n", test2.GetData());
120     ok(test2.GetHandle() != NULL, "Expected handle, got %p\n", test2.GetHandle());
121     ok(test2.GetMappingSize() == sizeof(TestData), "Expected sizeof(TestData), got %lu\n", test2.GetMappingSize());
122     ok(bAlreadyExisted == TRUE, "Expected TRUE, got %u\n", bAlreadyExisted);
123 
124     // test2 does not equal test1
125     ok(test1.GetData() != test2.GetData(), "Expected different ptrs\n");
126     ok(test1.GetHandle() != test2.GetHandle(), "Expected different handles\n");
127 
128     t2 = test2;
129     if (t1 && t2)
130     {
131         ok(t1->data[0] == (int)0xbeefbeef, "Expected 0xbeefbeef, got 0x%x\n", t1->data[0]);
132         ok(t2->data[0] == (int)0xbeefbeef, "Expected 0xbeefbeef, got 0x%x\n", t2->data[0]);
133 
134         t1->data[0] = 0xdeaddead;
135         ok(t1->data[0] == (int)0xdeaddead, "Expected 0xdeaddead, got 0x%x\n", t1->data[0]);
136         ok(t2->data[0] == (int)0xdeaddead, "Expected 0xdeaddead, got 0x%x\n", t2->data[0]);
137     }
138 }
139 
140 static void test_FileMapping()
141 {
142     WCHAR Buf[MAX_PATH] = {0};
143     ULARGE_INTEGER FileSize;
144 
145     GetModuleFileNameW(NULL, Buf, _countof(Buf));
146 
147     CAtlFileMapping<IMAGE_DOS_HEADER> test1, test2;
148     HRESULT hr;
149 
150     {
151         CHandle hFile(CreateFileW(Buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL));
152         ok(hFile != INVALID_HANDLE_VALUE, "Could not open %S, aborting test\n", Buf);
153         if (hFile == INVALID_HANDLE_VALUE)
154             return;
155 
156         FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
157 
158         hr = test1.MapFile(hFile, 0, 0, PAGE_READONLY, FILE_MAP_READ);
159         ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
160         ok(test1.GetData() != NULL, "Expected ptr, got %p\n", test1.GetData());
161         ok(test1.GetHandle() != NULL, "Expected handle, got %p\n", test1.GetHandle());
162         ok(test1.GetMappingSize() == FileSize.LowPart, "Expected %lu, got %lu\n", FileSize.LowPart, test1.GetMappingSize());
163 
164         hr = test2.MapFile(hFile, 0, 0x10000, PAGE_READONLY, FILE_MAP_READ);
165         ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
166         ok(test2.GetData() != NULL, "Expected ptr, got %p\n", test2.GetData());
167         ok(test2.GetHandle() != NULL, "Expected handle, got %p\n", test2.GetHandle());
168         // Offset is subtracted
169         ok(test2.GetMappingSize() == FileSize.LowPart - 0x10000, "Expected %lu, got %lu\n", FileSize.LowPart-0x10000, test2.GetMappingSize());
170 
171         hr = test1.Unmap();
172         ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
173         ok(test1.GetData() == NULL, "Expected NULL, got %p\n", test1.GetData());
174         ok(test1.GetHandle() == NULL, "Expected NULL, got %p\n", test1.GetHandle());
175         ok(test1.GetMappingSize() == FileSize.LowPart, "Expected %lu, got %lu\n", FileSize.LowPart, test1.GetMappingSize());
176 
177         hr = test1.MapFile(hFile, 0x1000);
178         ok(hr == S_OK, "Expected S_OK, got 0x%lx\n", hr);
179         ok(test1.GetData() != NULL, "Expected ptr, got %p\n", test1.GetData());
180         ok(test1.GetHandle() != NULL, "Expected handle, got %p\n", test1.GetHandle());
181         ok(test1.GetMappingSize() == 0x1000, "Expected 0x1000, got %lu\n", test1.GetMappingSize());
182     }
183 
184     // We can still access it after the file is closed
185     PIMAGE_DOS_HEADER dos = test1;
186     if (dos)
187     {
188         ok(dos->e_magic == IMAGE_DOS_SIGNATURE, "Expected IMAGE_DOS_SIGNATURE, got 0x%x\n", dos->e_magic);
189     }
190 }
191 
192 
193 START_TEST(CAtlFileMapping)
194 {
195     test_SharedMem();
196     test_FileMapping();
197 }
198