- Revert r52573
[reactos.git] / 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 | SEC_LARGE_PAGES);
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
142 if (Status == STATUS_OBJECT_NAME_EXISTS)
143 {
144 SetLastError(ERROR_ALREADY_EXISTS);
145 return SectionHandle;
146 }
147
148 if (!NT_SUCCESS(Status))
149 {
150 /* We failed */
151 SetLastErrorByStatus(Status);
152 return NULL;
153 }
154
155 SetLastError(ERROR_SUCCESS);
156 /* Return the section */
157 return SectionHandle;
158 }
159
160 /*
161 * @implemented
162 */
163 LPVOID
164 NTAPI
165 MapViewOfFileEx(HANDLE hFileMappingObject,
166 DWORD dwDesiredAccess,
167 DWORD dwFileOffsetHigh,
168 DWORD dwFileOffsetLow,
169 SIZE_T dwNumberOfBytesToMap,
170 LPVOID lpBaseAddress)
171 {
172 NTSTATUS Status;
173 LARGE_INTEGER SectionOffset;
174 SIZE_T ViewSize;
175 ULONG Protect;
176 LPVOID ViewBase;
177
178 /* Convert the offset */
179 SectionOffset.LowPart = dwFileOffsetLow;
180 SectionOffset.HighPart = dwFileOffsetHigh;
181
182 /* Save the size and base */
183 ViewBase = lpBaseAddress;
184 ViewSize = dwNumberOfBytesToMap;
185
186 /* Convert flags to NT Protection Attributes */
187 if (dwDesiredAccess & FILE_MAP_WRITE)
188 {
189 Protect = PAGE_READWRITE;
190 }
191 else if (dwDesiredAccess & FILE_MAP_READ)
192 {
193 Protect = PAGE_READONLY;
194 }
195 else if (dwDesiredAccess & FILE_MAP_COPY)
196 {
197 Protect = PAGE_WRITECOPY;
198 }
199 else
200 {
201 Protect = PAGE_NOACCESS;
202 }
203
204 /* Map the section */
205 Status = ZwMapViewOfSection(hFileMappingObject,
206 NtCurrentProcess(),
207 &ViewBase,
208 0,
209 0,
210 &SectionOffset,
211 &ViewSize,
212 ViewShare,
213 0,
214 Protect);
215 if (!NT_SUCCESS(Status))
216 {
217 /* We failed */
218 SetLastErrorByStatus(Status);
219 return NULL;
220 }
221
222 /* Return the base */
223 return ViewBase;
224 }
225
226 /*
227 * @implemented
228 */
229 LPVOID
230 NTAPI
231 MapViewOfFile(HANDLE hFileMappingObject,
232 DWORD dwDesiredAccess,
233 DWORD dwFileOffsetHigh,
234 DWORD dwFileOffsetLow,
235 SIZE_T dwNumberOfBytesToMap)
236 {
237 /* Call the extended API */
238 return MapViewOfFileEx(hFileMappingObject,
239 dwDesiredAccess,
240 dwFileOffsetHigh,
241 dwFileOffsetLow,
242 dwNumberOfBytesToMap,
243 NULL);
244 }
245
246 /*
247 * @implemented
248 */
249 BOOL
250 NTAPI
251 UnmapViewOfFile(LPCVOID lpBaseAddress)
252 {
253 NTSTATUS Status;
254
255 /* Unmap the section */
256 Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
257 if (!NT_SUCCESS(Status))
258 {
259 /* We failed */
260 SetLastErrorByStatus(Status);
261 return FALSE;
262 }
263
264 /* Otherwise, return sucess */
265 return TRUE;
266 }
267
268 /*
269 * @implemented
270 */
271 HANDLE
272 NTAPI
273 OpenFileMappingA(DWORD dwDesiredAccess,
274 BOOL bInheritHandle,
275 LPCSTR lpName)
276 {
277 NTSTATUS Status;
278 ANSI_STRING AnsiName;
279 PUNICODE_STRING UnicodeCache;
280
281 /* Check for a name */
282 if (lpName)
283 {
284 /* Use TEB Cache */
285 UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
286
287 /* Convert to unicode */
288 RtlInitAnsiString(&AnsiName, lpName);
289 Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
290 if (!NT_SUCCESS(Status))
291 {
292 /* Conversion failed */
293 SetLastErrorByStatus(Status);
294 return NULL;
295 }
296 }
297 else
298 {
299 /* We need a name */
300 SetLastError(ERROR_INVALID_PARAMETER);
301 return NULL;
302 }
303
304 /* Call the Unicode version */
305 return OpenFileMappingW(dwDesiredAccess,
306 bInheritHandle,
307 (LPCWSTR)UnicodeCache->Buffer);
308 }
309
310 /*
311 * @implemented
312 */
313 HANDLE
314 NTAPI
315 OpenFileMappingW(DWORD dwDesiredAccess,
316 BOOL bInheritHandle,
317 LPCWSTR lpName)
318 {
319 NTSTATUS Status;
320 HANDLE SectionHandle;
321 OBJECT_ATTRIBUTES ObjectAttributes;
322 UNICODE_STRING UnicodeName;
323
324 /* We need a name */
325 if (!lpName)
326 {
327 /* Otherwise, fail */
328 SetLastError(ERROR_INVALID_PARAMETER);
329 return NULL;
330 }
331
332 /* Convert attributes */
333 RtlInitUnicodeString(&UnicodeName, lpName);
334 InitializeObjectAttributes(&ObjectAttributes,
335 &UnicodeName,
336 (bInheritHandle ? OBJ_INHERIT : 0),
337 hBaseDir,
338 NULL);
339
340 /* Convert COPY to READ */
341 if (dwDesiredAccess == FILE_MAP_COPY) dwDesiredAccess = FILE_MAP_READ;
342
343 /* Open the section */
344 Status = ZwOpenSection(&SectionHandle,
345 dwDesiredAccess,
346 &ObjectAttributes);
347 if (!NT_SUCCESS(Status))
348 {
349 /* We failed */
350 SetLastErrorByStatus(Status);
351 return NULL;
352 }
353
354 SetLastError(ERROR_SUCCESS);
355 /* Otherwise, return the handle */
356 return SectionHandle;
357 }
358
359 /*
360 * @implemented
361 */
362 BOOL
363 NTAPI
364 FlushViewOfFile(LPCVOID lpBaseAddress,
365 SIZE_T dwNumberOfBytesToFlush)
366 {
367 SIZE_T NumberOfBytesToFlush;
368 NTSTATUS Status;
369 IO_STATUS_BLOCK IoStatusBlock;
370
371 /* Save amount of bytes to flush to a local var */
372 NumberOfBytesToFlush = dwNumberOfBytesToFlush;
373
374 /* Flush the view */
375 Status = NtFlushVirtualMemory(NtCurrentProcess(),
376 (LPVOID)lpBaseAddress,
377 &NumberOfBytesToFlush,
378 &IoStatusBlock);
379 if (!NT_SUCCESS(Status))
380 {
381 /* We failed */
382 SetLastErrorByStatus(Status);
383 return FALSE;
384 }
385
386 /* Return success */
387 return TRUE;
388 }
389
390 /* EOF */