- Sync to trunk 36919.
[reactos.git] / reactos / dll / win32 / kernel32 / mem / section.c
1 /*
2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/mem/section.c
5 * PURPOSE: Handles virtual memory APIs
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <k32.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 /*
19 * @implemented
20 */
21 HANDLE
22 NTAPI
23 CreateFileMappingA(IN HANDLE hFile,
24 IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
25 IN DWORD flProtect,
26 IN DWORD dwMaximumSizeHigh,
27 IN DWORD dwMaximumSizeLow,
28 IN LPCSTR lpName)
29 {
30 NTSTATUS Status;
31 ANSI_STRING AnsiName;
32 PUNICODE_STRING UnicodeCache;
33 LPCWSTR UnicodeName = NULL;
34
35 /* Check for a name */
36 if (lpName)
37 {
38 /* Use TEB Cache */
39 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
40
41 /* Convert to unicode */
42 RtlInitAnsiString(&AnsiName, lpName);
43 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
44 if (!NT_SUCCESS(Status))
45 {
46 /* Conversion failed */
47 SetLastErrorByStatus(Status);
48 return NULL;
49 }
50
51 /* Otherwise, save the buffer */
52 UnicodeName = (LPCWSTR)UnicodeCache->Buffer;
53 }
54
55 /* Call the Unicode version */
56 return CreateFileMappingW(hFile,
57 lpFileMappingAttributes,
58 flProtect,
59 dwMaximumSizeHigh,
60 dwMaximumSizeLow,
61 UnicodeName);
62 }
63
64 /*
65 * @implemented
66 */
67 HANDLE
68 NTAPI
69 CreateFileMappingW(HANDLE hFile,
70 LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
71 DWORD flProtect,
72 DWORD dwMaximumSizeHigh,
73 DWORD dwMaximumSizeLow,
74 LPCWSTR lpName)
75 {
76 NTSTATUS Status;
77 HANDLE SectionHandle;
78 OBJECT_ATTRIBUTES LocalAttributes;
79 POBJECT_ATTRIBUTES ObjectAttributes;
80 UNICODE_STRING SectionName;
81 ACCESS_MASK DesiredAccess;
82 LARGE_INTEGER LocalSize;
83 PLARGE_INTEGER SectionSize = NULL;
84 ULONG Attributes;
85
86 /* Set default access */
87 DesiredAccess = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ;
88
89 /* Get the attributes for the actual allocation and cleanup flProtect */
90 Attributes = flProtect & (SEC_FILE | SEC_IMAGE | SEC_RESERVE | SEC_NOCACHE | SEC_COMMIT);
91 flProtect ^= Attributes;
92
93 /* If the caller didn't say anything, assume SEC_COMMIT */
94 if (!Attributes) Attributes = SEC_COMMIT;
95
96 /* Now check if the caller wanted write access */
97 if (flProtect == PAGE_READWRITE)
98 {
99 /* Give it */
100 DesiredAccess |= (SECTION_MAP_WRITE | SECTION_MAP_READ);
101 }
102
103 /* Now check if we got a name */
104 if (lpName) RtlInitUnicodeString(&SectionName, lpName);
105
106 /* Now convert the object attributes */
107 ObjectAttributes = BasepConvertObjectAttributes(&LocalAttributes,
108 lpFileMappingAttributes,
109 lpName ? &SectionName : NULL);
110
111 /* Check if we got a size */
112 if (dwMaximumSizeLow || dwMaximumSizeHigh)
113 {
114 /* Use a LARGE_INTEGER and convert */
115 SectionSize = &LocalSize;
116 SectionSize->LowPart = dwMaximumSizeLow;
117 SectionSize->HighPart = dwMaximumSizeHigh;
118 }
119
120 /* Make sure the handle is valid */
121 if (hFile == INVALID_HANDLE_VALUE)
122 {
123 /* It's not, we'll only go on if we have a size */
124 hFile = NULL;
125 if (!SectionSize)
126 {
127 /* No size, so this isn't a valid non-mapped section */
128 SetLastError(ERROR_INVALID_PARAMETER);
129 return NULL;
130 }
131 }
132
133 /* Now create the actual section */
134 Status = NtCreateSection(&SectionHandle,
135 DesiredAccess,
136 ObjectAttributes,
137 SectionSize,
138 flProtect,
139 Attributes,
140 hFile);
141 if (!NT_SUCCESS(Status))
142 {
143 /* We failed */
144 SetLastErrorByStatus(Status);
145 return NULL;
146 }
147
148 /* Return the section */
149 return SectionHandle;
150 }
151
152 /*
153 * @implemented
154 */
155 LPVOID
156 NTAPI
157 MapViewOfFileEx(HANDLE hFileMappingObject,
158 DWORD dwDesiredAccess,
159 DWORD dwFileOffsetHigh,
160 DWORD dwFileOffsetLow,
161 SIZE_T dwNumberOfBytesToMap,
162 LPVOID lpBaseAddress)
163 {
164 NTSTATUS Status;
165 LARGE_INTEGER SectionOffset;
166 SIZE_T ViewSize;
167 ULONG Protect;
168 LPVOID ViewBase;
169
170 /* Convert the offset */
171 SectionOffset.LowPart = dwFileOffsetLow;
172 SectionOffset.HighPart = dwFileOffsetHigh;
173
174 /* Save the size and base */
175 ViewBase = lpBaseAddress;
176 ViewSize = dwNumberOfBytesToMap;
177
178 /* Convert flags to NT Protection Attributes */
179 if (dwDesiredAccess & FILE_MAP_WRITE)
180 {
181 Protect = PAGE_READWRITE;
182 }
183 else if (dwDesiredAccess & FILE_MAP_READ)
184 {
185 Protect = PAGE_READONLY;
186 }
187 else if (dwDesiredAccess & FILE_MAP_COPY)
188 {
189 Protect = PAGE_WRITECOPY;
190 }
191 else
192 {
193 Protect = PAGE_NOACCESS;
194 }
195
196 /* Map the section */
197 Status = ZwMapViewOfSection(hFileMappingObject,
198 NtCurrentProcess(),
199 &ViewBase,
200 0,
201 0,
202 &SectionOffset,
203 &ViewSize,
204 ViewShare,
205 0,
206 Protect);
207 if (!NT_SUCCESS(Status))
208 {
209 /* We failed */
210 SetLastErrorByStatus(Status);
211 return NULL;
212 }
213
214 /* Return the base */
215 return ViewBase;
216 }
217
218 /*
219 * @implemented
220 */
221 LPVOID
222 NTAPI
223 MapViewOfFile(HANDLE hFileMappingObject,
224 DWORD dwDesiredAccess,
225 DWORD dwFileOffsetHigh,
226 DWORD dwFileOffsetLow,
227 SIZE_T dwNumberOfBytesToMap)
228 {
229 /* Call the extended API */
230 return MapViewOfFileEx(hFileMappingObject,
231 dwDesiredAccess,
232 dwFileOffsetHigh,
233 dwFileOffsetLow,
234 dwNumberOfBytesToMap,
235 NULL);
236 }
237
238 /*
239 * @implemented
240 */
241 BOOL
242 NTAPI
243 UnmapViewOfFile(LPCVOID lpBaseAddress)
244 {
245 NTSTATUS Status;
246
247 /* Unmap the section */
248 Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
249 if (!NT_SUCCESS(Status))
250 {
251 /* We failed */
252 SetLastErrorByStatus(Status);
253 return FALSE;
254 }
255
256 /* Otherwise, return sucess */
257 return TRUE;
258 }
259
260 /*
261 * @implemented
262 */
263 HANDLE
264 NTAPI
265 OpenFileMappingA(DWORD dwDesiredAccess,
266 BOOL bInheritHandle,
267 LPCSTR lpName)
268 {
269 NTSTATUS Status;
270 ANSI_STRING AnsiName;
271 PUNICODE_STRING UnicodeCache;
272
273 /* Check for a name */
274 if (lpName)
275 {
276 /* Use TEB Cache */
277 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
278
279 /* Convert to unicode */
280 RtlInitAnsiString(&AnsiName, lpName);
281 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
282 if (!NT_SUCCESS(Status))
283 {
284 /* Conversion failed */
285 SetLastErrorByStatus(Status);
286 return NULL;
287 }
288 }
289 else
290 {
291 /* We need a name */
292 SetLastError(ERROR_INVALID_PARAMETER);
293 return NULL;
294 }
295
296 /* Call the Unicode version */
297 return OpenFileMappingW(dwDesiredAccess,
298 bInheritHandle,
299 (LPCWSTR)UnicodeCache->Buffer);
300 }
301
302 /*
303 * @implemented
304 */
305 HANDLE
306 NTAPI
307 OpenFileMappingW(DWORD dwDesiredAccess,
308 BOOL bInheritHandle,
309 LPCWSTR lpName)
310 {
311 NTSTATUS Status;
312 HANDLE SectionHandle;
313 OBJECT_ATTRIBUTES ObjectAttributes;
314 UNICODE_STRING UnicodeName;
315
316 /* We need a name */
317 if (!lpName)
318 {
319 /* Otherwise, fail */
320 SetLastError(ERROR_INVALID_PARAMETER);
321 return NULL;
322 }
323
324 /* Convert attributes */
325 RtlInitUnicodeString(&UnicodeName, lpName);
326 InitializeObjectAttributes(&ObjectAttributes,
327 &UnicodeName,
328 (bInheritHandle ? OBJ_INHERIT : 0),
329 hBaseDir,
330 NULL);
331
332 /* Convert COPY to READ */
333 if (dwDesiredAccess == FILE_MAP_COPY) dwDesiredAccess = FILE_MAP_READ;
334
335 /* Open the section */
336 Status = ZwOpenSection(&SectionHandle,
337 dwDesiredAccess,
338 &ObjectAttributes);
339 if (!NT_SUCCESS(Status))
340 {
341 /* We failed */
342 SetLastErrorByStatus(Status);
343 return NULL;
344 }
345
346 /* Otherwise, return the handle */
347 return SectionHandle;
348 }
349
350 /*
351 * @implemented
352 */
353 BOOL
354 NTAPI
355 FlushViewOfFile(LPCVOID lpBaseAddress,
356 SIZE_T dwNumberOfBytesToFlush)
357 {
358 SIZE_T NumberOfBytesToFlush;
359 NTSTATUS Status;
360 IO_STATUS_BLOCK IoStatusBlock;
361
362 /* Save amount of bytes to flush to a local var */
363 NumberOfBytesToFlush = dwNumberOfBytesToFlush;
364
365 /* Flush the view */
366 Status = NtFlushVirtualMemory(NtCurrentProcess(),
367 (LPVOID)lpBaseAddress,
368 &NumberOfBytesToFlush,
369 &IoStatusBlock);
370 if (!NT_SUCCESS(Status))
371 {
372 /* We failed */
373 SetLastErrorByStatus(Status);
374 return FALSE;
375 }
376
377 /* Return success */
378 return TRUE;
379 }
380
381 /* EOF */