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
,
30 /* Call the W(ide) function */
31 ConvertWin32AnsiObjectApiToUnicodeApi(FileMapping
,
34 lpFileMappingAttributes
,
45 CreateFileMappingW(HANDLE hFile
,
46 LPSECURITY_ATTRIBUTES lpFileMappingAttributes
,
48 DWORD dwMaximumSizeHigh
,
49 DWORD dwMaximumSizeLow
,
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
;
62 /* Set default access */
63 DesiredAccess
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
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
;
69 /* If the caller didn't say anything, assume SEC_COMMIT */
70 if (!Attributes
) Attributes
= SEC_COMMIT
;
72 /* Now check if the caller wanted write access */
73 if (flProtect
== PAGE_READWRITE
)
76 DesiredAccess
|= SECTION_MAP_WRITE
;
78 else if (flProtect
== PAGE_EXECUTE_READWRITE
)
81 DesiredAccess
|= (SECTION_MAP_WRITE
| SECTION_MAP_EXECUTE
);
83 else if (flProtect
== PAGE_EXECUTE_READ
)
86 DesiredAccess
|= SECTION_MAP_EXECUTE
;
88 else if ((flProtect
!= PAGE_READONLY
) && (flProtect
!= PAGE_WRITECOPY
))
90 SetLastError(ERROR_INVALID_PARAMETER
);
94 /* Now check if we got a name */
95 if (lpName
) RtlInitUnicodeString(&SectionName
, lpName
);
97 /* Now convert the object attributes */
98 ObjectAttributes
= BaseFormatObjectAttributes(&LocalAttributes
,
99 lpFileMappingAttributes
,
100 lpName
? &SectionName
: NULL
);
102 /* Check if we got a size */
103 if (dwMaximumSizeLow
|| dwMaximumSizeHigh
)
105 /* Use a LARGE_INTEGER and convert */
106 SectionSize
= &LocalSize
;
107 SectionSize
->LowPart
= dwMaximumSizeLow
;
108 SectionSize
->HighPart
= dwMaximumSizeHigh
;
111 /* Make sure the handle is valid */
112 if (hFile
== INVALID_HANDLE_VALUE
)
114 /* It's not, we'll only go on if we have a size */
118 /* No size, so this isn't a valid non-mapped section */
119 SetLastError(ERROR_INVALID_PARAMETER
);
124 /* Now create the actual section */
125 Status
= NtCreateSection(&SectionHandle
,
132 if (!NT_SUCCESS(Status
))
135 BaseSetLastNTError(Status
);
138 else if (Status
== STATUS_OBJECT_NAME_EXISTS
)
140 SetLastError(ERROR_ALREADY_EXISTS
);
144 SetLastError(ERROR_SUCCESS
);
147 /* Return the section */
148 return SectionHandle
;
156 MapViewOfFileEx(HANDLE hFileMappingObject
,
157 DWORD dwDesiredAccess
,
158 DWORD dwFileOffsetHigh
,
159 DWORD dwFileOffsetLow
,
160 SIZE_T dwNumberOfBytesToMap
,
161 LPVOID lpBaseAddress
)
164 LARGE_INTEGER SectionOffset
;
169 /* Convert the offset */
170 SectionOffset
.LowPart
= dwFileOffsetLow
;
171 SectionOffset
.HighPart
= dwFileOffsetHigh
;
173 /* Save the size and base */
174 ViewBase
= lpBaseAddress
;
175 ViewSize
= dwNumberOfBytesToMap
;
177 /* Convert flags to NT Protection Attributes */
178 if (dwDesiredAccess
== FILE_MAP_COPY
)
180 Protect
= PAGE_WRITECOPY
;
182 else if (dwDesiredAccess
& FILE_MAP_WRITE
)
184 Protect
= (dwDesiredAccess
& FILE_MAP_EXECUTE
) ?
185 PAGE_EXECUTE_READWRITE
: PAGE_READWRITE
;
187 else if (dwDesiredAccess
& FILE_MAP_READ
)
189 Protect
= (dwDesiredAccess
& FILE_MAP_EXECUTE
) ?
190 PAGE_EXECUTE_READ
: PAGE_READONLY
;
194 Protect
= PAGE_NOACCESS
;
197 /* Map the section */
198 Status
= NtMapViewOfSection(hFileMappingObject
,
208 if (!NT_SUCCESS(Status
))
211 BaseSetLastNTError(Status
);
215 /* Return the base */
224 MapViewOfFile(HANDLE hFileMappingObject
,
225 DWORD dwDesiredAccess
,
226 DWORD dwFileOffsetHigh
,
227 DWORD dwFileOffsetLow
,
228 SIZE_T dwNumberOfBytesToMap
)
230 /* Call the extended API */
231 return MapViewOfFileEx(hFileMappingObject
,
235 dwNumberOfBytesToMap
,
244 UnmapViewOfFile(LPCVOID lpBaseAddress
)
248 /* Unmap the section */
249 Status
= NtUnmapViewOfSection(NtCurrentProcess(), (PVOID
)lpBaseAddress
);
250 if (!NT_SUCCESS(Status
))
252 /* Check if the pages were protected */
253 if (Status
== STATUS_INVALID_PAGE_PROTECTION
)
255 /* Flush the region if it was a "secure memory cache" */
256 if (RtlFlushSecureMemoryCache((PVOID
)lpBaseAddress
, 0))
258 /* Now try to unmap again */
259 Status
= NtUnmapViewOfSection(NtCurrentProcess(), (PVOID
)lpBaseAddress
);
260 if (NT_SUCCESS(Status
)) return TRUE
;
265 BaseSetLastNTError(Status
);
269 /* Otherwise, return sucess */
278 OpenFileMappingA(IN DWORD dwDesiredAccess
,
279 IN BOOL bInheritHandle
,
282 ConvertOpenWin32AnsiObjectApiToUnicodeApi(FileMapping
, dwDesiredAccess
, bInheritHandle
, lpName
);
288 /* FIXME: Convert to the new macros */
291 OpenFileMappingW(IN DWORD dwDesiredAccess
,
292 IN BOOL bInheritHandle
,
296 HANDLE SectionHandle
;
297 OBJECT_ATTRIBUTES ObjectAttributes
;
298 UNICODE_STRING UnicodeName
;
303 /* Otherwise, fail */
304 SetLastError(ERROR_INVALID_PARAMETER
);
308 /* Convert attributes */
309 RtlInitUnicodeString(&UnicodeName
, lpName
);
310 InitializeObjectAttributes(&ObjectAttributes
,
312 (bInheritHandle
? OBJ_INHERIT
: 0),
313 BaseGetNamedObjectDirectory(),
316 /* Convert COPY to READ */
317 if (dwDesiredAccess
== FILE_MAP_COPY
)
320 dwDesiredAccess
= SECTION_MAP_READ
;
322 else if (dwDesiredAccess
& FILE_MAP_EXECUTE
)
325 dwDesiredAccess
= (dwDesiredAccess
& ~FILE_MAP_EXECUTE
) | SECTION_MAP_EXECUTE
;
328 /* Open the section */
329 Status
= NtOpenSection(&SectionHandle
, dwDesiredAccess
, &ObjectAttributes
);
330 if (!NT_SUCCESS(Status
))
333 BaseSetLastNTError(Status
);
337 /* Otherwise, return the handle */
338 return SectionHandle
;
346 FlushViewOfFile(IN LPCVOID lpBaseAddress
,
347 IN SIZE_T dwNumberOfBytesToFlush
)
350 PVOID BaseAddress
= (PVOID
)lpBaseAddress
;
351 SIZE_T NumberOfBytesToFlush
= dwNumberOfBytesToFlush
;
352 IO_STATUS_BLOCK IoStatusBlock
;
355 Status
= NtFlushVirtualMemory(NtCurrentProcess(),
357 &NumberOfBytesToFlush
,
359 if (!NT_SUCCESS(Status
) && (Status
!= STATUS_NOT_MAPPED_DATA
))
362 BaseSetLastNTError(Status
);