/* * PROJECT: ReactOS Win32 Base API * LICENSE: GPL - See COPYING in the top level directory * FILE: dll/win32/kernel32/mem/section.c * PURPOSE: Handles virtual memory APIs * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES ******************************************************************/ #include #define NDEBUG #include /* FUNCTIONS *****************************************************************/ /* * @implemented */ HANDLE NTAPI CreateFileMappingA(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, IN DWORD dwMaximumSizeHigh, IN DWORD dwMaximumSizeLow, IN LPCSTR lpName) { NTSTATUS Status; ANSI_STRING AnsiName; PUNICODE_STRING UnicodeCache; LPCWSTR UnicodeName = NULL; /* Check for a name */ if (lpName) { /* Use TEB Cache */ UnicodeCache = &NtCurrentTeb()->StaticUnicodeString; /* Convert to unicode */ RtlInitAnsiString(&AnsiName, lpName); Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE); if (!NT_SUCCESS(Status)) { /* Conversion failed */ SetLastErrorByStatus(Status); return NULL; } /* Otherwise, save the buffer */ UnicodeName = (LPCWSTR)UnicodeCache->Buffer; } /* Call the Unicode version */ return CreateFileMappingW(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, UnicodeName); } /* * @implemented */ HANDLE NTAPI CreateFileMappingW(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCWSTR lpName) { NTSTATUS Status; HANDLE SectionHandle; OBJECT_ATTRIBUTES LocalAttributes; POBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING SectionName; ACCESS_MASK DesiredAccess; LARGE_INTEGER LocalSize; PLARGE_INTEGER SectionSize = NULL; ULONG Attributes; /* Set default access */ DesiredAccess = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ; /* Get the attributes for the actual allocation and cleanup flProtect */ Attributes = flProtect & (SEC_FILE | SEC_IMAGE | SEC_RESERVE | SEC_NOCACHE | SEC_COMMIT); flProtect ^= Attributes; /* If the caller didn't say anything, assume SEC_COMMIT */ if (!Attributes) Attributes = SEC_COMMIT; /* Now check if the caller wanted write access */ if (flProtect == PAGE_READWRITE) { /* Give it */ DesiredAccess |= (SECTION_MAP_WRITE | SECTION_MAP_READ); } /* Now check if we got a name */ if (lpName) RtlInitUnicodeString(&SectionName, lpName); /* Now convert the object attributes */ ObjectAttributes = BasepConvertObjectAttributes(&LocalAttributes, lpFileMappingAttributes, lpName ? &SectionName : NULL); /* Check if we got a size */ if (dwMaximumSizeLow || dwMaximumSizeHigh) { /* Use a LARGE_INTEGER and convert */ SectionSize = &LocalSize; SectionSize->LowPart = dwMaximumSizeLow; SectionSize->HighPart = dwMaximumSizeHigh; } /* Make sure the handle is valid */ if (hFile == INVALID_HANDLE_VALUE) { /* It's not, we'll only go on if we have a size */ hFile = NULL; if (!SectionSize) { /* No size, so this isn't a valid non-mapped section */ SetLastError(ERROR_INVALID_PARAMETER); return NULL; } } /* Now create the actual section */ Status = NtCreateSection(&SectionHandle, DesiredAccess, ObjectAttributes, SectionSize, flProtect, Attributes, hFile); if (Status == STATUS_OBJECT_NAME_EXISTS) { SetLastError(ERROR_ALREADY_EXISTS); return SectionHandle; } if (!NT_SUCCESS(Status)) { /* We failed */ SetLastErrorByStatus(Status); return NULL; } SetLastError(ERROR_SUCCESS); /* Return the section */ return SectionHandle; } /* * @implemented */ LPVOID NTAPI MapViewOfFileEx(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, LPVOID lpBaseAddress) { NTSTATUS Status; LARGE_INTEGER SectionOffset; SIZE_T ViewSize; ULONG Protect; LPVOID ViewBase; /* Convert the offset */ SectionOffset.LowPart = dwFileOffsetLow; SectionOffset.HighPart = dwFileOffsetHigh; /* Save the size and base */ ViewBase = lpBaseAddress; ViewSize = dwNumberOfBytesToMap; /* Convert flags to NT Protection Attributes */ if (dwDesiredAccess & FILE_MAP_WRITE) { Protect = PAGE_READWRITE; } else if (dwDesiredAccess & FILE_MAP_READ) { Protect = PAGE_READONLY; } else if (dwDesiredAccess & FILE_MAP_COPY) { Protect = PAGE_WRITECOPY; } else { Protect = PAGE_NOACCESS; } /* Map the section */ Status = ZwMapViewOfSection(hFileMappingObject, NtCurrentProcess(), &ViewBase, 0, 0, &SectionOffset, &ViewSize, ViewShare, 0, Protect); if (!NT_SUCCESS(Status)) { /* We failed */ SetLastErrorByStatus(Status); return NULL; } /* Return the base */ return ViewBase; } /* * @implemented */ LPVOID NTAPI MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) { /* Call the extended API */ return MapViewOfFileEx(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap, NULL); } /* * @implemented */ BOOL NTAPI UnmapViewOfFile(LPCVOID lpBaseAddress) { NTSTATUS Status; /* Unmap the section */ Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress); if (!NT_SUCCESS(Status)) { /* We failed */ SetLastErrorByStatus(Status); return FALSE; } /* Otherwise, return sucess */ return TRUE; } /* * @implemented */ HANDLE NTAPI OpenFileMappingA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName) { NTSTATUS Status; ANSI_STRING AnsiName; PUNICODE_STRING UnicodeCache; /* Check for a name */ if (lpName) { /* Use TEB Cache */ UnicodeCache = &NtCurrentTeb()->StaticUnicodeString; /* Convert to unicode */ RtlInitAnsiString(&AnsiName, lpName); Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE); if (!NT_SUCCESS(Status)) { /* Conversion failed */ SetLastErrorByStatus(Status); return NULL; } } else { /* We need a name */ SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Call the Unicode version */ return OpenFileMappingW(dwDesiredAccess, bInheritHandle, (LPCWSTR)UnicodeCache->Buffer); } /* * @implemented */ HANDLE NTAPI OpenFileMappingW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName) { NTSTATUS Status; HANDLE SectionHandle; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING UnicodeName; /* We need a name */ if (!lpName) { /* Otherwise, fail */ SetLastError(ERROR_INVALID_PARAMETER); return NULL; } /* Convert attributes */ RtlInitUnicodeString(&UnicodeName, lpName); InitializeObjectAttributes(&ObjectAttributes, &UnicodeName, (bInheritHandle ? OBJ_INHERIT : 0), hBaseDir, NULL); /* Convert COPY to READ */ if (dwDesiredAccess == FILE_MAP_COPY) dwDesiredAccess = FILE_MAP_READ; /* Open the section */ Status = ZwOpenSection(&SectionHandle, dwDesiredAccess, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* We failed */ SetLastErrorByStatus(Status); return NULL; } SetLastError(ERROR_SUCCESS); /* Otherwise, return the handle */ return SectionHandle; } /* * @implemented */ BOOL NTAPI FlushViewOfFile(LPCVOID lpBaseAddress, SIZE_T dwNumberOfBytesToFlush) { SIZE_T NumberOfBytesToFlush; NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; /* Save amount of bytes to flush to a local var */ NumberOfBytesToFlush = dwNumberOfBytesToFlush; /* Flush the view */ Status = NtFlushVirtualMemory(NtCurrentProcess(), (LPVOID)lpBaseAddress, &NumberOfBytesToFlush, &IoStatusBlock); if (!NT_SUCCESS(Status)) { /* We failed */ SetLastErrorByStatus(Status); return FALSE; } /* Return success */ return TRUE; } /* EOF */