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)
9 /* INCLUDES ******************************************************************/
16 /* FUNCTIONS *****************************************************************/
23 CreateFileMappingA(IN HANDLE hFile
,
24 IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes
,
26 IN DWORD dwMaximumSizeHigh
,
27 IN DWORD dwMaximumSizeLow
,
32 PUNICODE_STRING UnicodeCache
;
33 LPCWSTR UnicodeName
= NULL
;
35 /* Check for a name */
39 UnicodeCache
= &NtCurrentTeb()->StaticUnicodeString
;
41 /* Convert to unicode */
42 RtlInitAnsiString(&AnsiName
, lpName
);
43 Status
= RtlAnsiStringToUnicodeString(UnicodeCache
, &AnsiName
, FALSE
);
44 if (!NT_SUCCESS(Status
))
46 /* Conversion failed */
47 SetLastErrorByStatus(Status
);
51 /* Otherwise, save the buffer */
52 UnicodeName
= (LPCWSTR
)UnicodeCache
->Buffer
;
55 /* Call the Unicode version */
56 return CreateFileMappingW(hFile
,
57 lpFileMappingAttributes
,
69 CreateFileMappingW(HANDLE hFile
,
70 LPSECURITY_ATTRIBUTES lpFileMappingAttributes
,
72 DWORD dwMaximumSizeHigh
,
73 DWORD dwMaximumSizeLow
,
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
;
86 /* Set default access */
87 DesiredAccess
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
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
;
93 /* If the caller didn't say anything, assume SEC_COMMIT */
94 if (!Attributes
) Attributes
= SEC_COMMIT
;
96 /* Now check if the caller wanted write access */
97 if (flProtect
== PAGE_READWRITE
)
100 DesiredAccess
|= (SECTION_MAP_WRITE
| SECTION_MAP_READ
);
103 /* Now check if we got a name */
104 if (lpName
) RtlInitUnicodeString(&SectionName
, lpName
);
106 /* Now convert the object attributes */
107 ObjectAttributes
= BasepConvertObjectAttributes(&LocalAttributes
,
108 lpFileMappingAttributes
,
109 lpName
? &SectionName
: NULL
);
111 /* Check if we got a size */
112 if (dwMaximumSizeLow
|| dwMaximumSizeHigh
)
114 /* Use a LARGE_INTEGER and convert */
115 SectionSize
= &LocalSize
;
116 SectionSize
->LowPart
= dwMaximumSizeLow
;
117 SectionSize
->HighPart
= dwMaximumSizeHigh
;
120 /* Make sure the handle is valid */
121 if (hFile
== INVALID_HANDLE_VALUE
)
123 /* It's not, we'll only go on if we have a size */
127 /* No size, so this isn't a valid non-mapped section */
128 SetLastError(ERROR_INVALID_PARAMETER
);
133 /* Now create the actual section */
134 Status
= NtCreateSection(&SectionHandle
,
142 if (Status
== STATUS_OBJECT_NAME_EXISTS
)
144 SetLastError(ERROR_ALREADY_EXISTS
);
145 return SectionHandle
;
148 if (!NT_SUCCESS(Status
))
151 SetLastErrorByStatus(Status
);
155 SetLastError(ERROR_SUCCESS
);
156 /* Return the section */
157 return SectionHandle
;
165 MapViewOfFileEx(HANDLE hFileMappingObject
,
166 DWORD dwDesiredAccess
,
167 DWORD dwFileOffsetHigh
,
168 DWORD dwFileOffsetLow
,
169 SIZE_T dwNumberOfBytesToMap
,
170 LPVOID lpBaseAddress
)
173 LARGE_INTEGER SectionOffset
;
178 /* Convert the offset */
179 SectionOffset
.LowPart
= dwFileOffsetLow
;
180 SectionOffset
.HighPart
= dwFileOffsetHigh
;
182 /* Save the size and base */
183 ViewBase
= lpBaseAddress
;
184 ViewSize
= dwNumberOfBytesToMap
;
186 /* Convert flags to NT Protection Attributes */
187 if (dwDesiredAccess
& FILE_MAP_WRITE
)
189 Protect
= PAGE_READWRITE
;
191 else if (dwDesiredAccess
& FILE_MAP_READ
)
193 Protect
= PAGE_READONLY
;
195 else if (dwDesiredAccess
& FILE_MAP_COPY
)
197 Protect
= PAGE_WRITECOPY
;
201 Protect
= PAGE_NOACCESS
;
204 /* Map the section */
205 Status
= ZwMapViewOfSection(hFileMappingObject
,
215 if (!NT_SUCCESS(Status
))
218 SetLastErrorByStatus(Status
);
222 /* Return the base */
231 MapViewOfFile(HANDLE hFileMappingObject
,
232 DWORD dwDesiredAccess
,
233 DWORD dwFileOffsetHigh
,
234 DWORD dwFileOffsetLow
,
235 SIZE_T dwNumberOfBytesToMap
)
237 /* Call the extended API */
238 return MapViewOfFileEx(hFileMappingObject
,
242 dwNumberOfBytesToMap
,
251 UnmapViewOfFile(LPCVOID lpBaseAddress
)
255 /* Unmap the section */
256 Status
= NtUnmapViewOfSection(NtCurrentProcess(), (PVOID
)lpBaseAddress
);
257 if (!NT_SUCCESS(Status
))
260 SetLastErrorByStatus(Status
);
264 /* Otherwise, return sucess */
273 OpenFileMappingA(DWORD dwDesiredAccess
,
278 ANSI_STRING AnsiName
;
279 PUNICODE_STRING UnicodeCache
;
281 /* Check for a name */
285 UnicodeCache
= &NtCurrentTeb()->StaticUnicodeString
;
287 /* Convert to unicode */
288 RtlInitAnsiString(&AnsiName
, lpName
);
289 Status
= RtlAnsiStringToUnicodeString(UnicodeCache
, &AnsiName
, FALSE
);
290 if (!NT_SUCCESS(Status
))
292 /* Conversion failed */
293 SetLastErrorByStatus(Status
);
300 SetLastError(ERROR_INVALID_PARAMETER
);
304 /* Call the Unicode version */
305 return OpenFileMappingW(dwDesiredAccess
,
307 (LPCWSTR
)UnicodeCache
->Buffer
);
315 OpenFileMappingW(DWORD dwDesiredAccess
,
320 HANDLE SectionHandle
;
321 OBJECT_ATTRIBUTES ObjectAttributes
;
322 UNICODE_STRING UnicodeName
;
327 /* Otherwise, fail */
328 SetLastError(ERROR_INVALID_PARAMETER
);
332 /* Convert attributes */
333 RtlInitUnicodeString(&UnicodeName
, lpName
);
334 InitializeObjectAttributes(&ObjectAttributes
,
336 (bInheritHandle
? OBJ_INHERIT
: 0),
340 /* Convert COPY to READ */
341 if (dwDesiredAccess
== FILE_MAP_COPY
) dwDesiredAccess
= FILE_MAP_READ
;
343 /* Open the section */
344 Status
= ZwOpenSection(&SectionHandle
,
347 if (!NT_SUCCESS(Status
))
350 SetLastErrorByStatus(Status
);
354 SetLastError(ERROR_SUCCESS
);
355 /* Otherwise, return the handle */
356 return SectionHandle
;
364 FlushViewOfFile(LPCVOID lpBaseAddress
,
365 SIZE_T dwNumberOfBytesToFlush
)
367 SIZE_T NumberOfBytesToFlush
;
369 IO_STATUS_BLOCK IoStatusBlock
;
371 /* Save amount of bytes to flush to a local var */
372 NumberOfBytesToFlush
= dwNumberOfBytesToFlush
;
375 Status
= NtFlushVirtualMemory(NtCurrentProcess(),
376 (LPVOID
)lpBaseAddress
,
377 &NumberOfBytesToFlush
,
379 if (!NT_SUCCESS(Status
))
382 SetLastErrorByStatus(Status
);