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