source: trunk/src/kernel32/hmmmap.cpp@ 9824

Last change on this file since 9824 was 9824, checked in by sandervl, 23 years ago

Cleaned up memory map code

File size: 9.3 KB
Line 
1/* $Id: hmmmap.cpp,v 1.21 2003-02-18 18:48:54 sandervl Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 * Win32 Unified Handle Manager for OS/2
6 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
7 */
8
9#undef DEBUG_LOCAL
10//#define DEBUG_LOCAL
11
12
13/*****************************************************************************
14 * Remark *
15 *****************************************************************************
16
17 */
18
19
20/*****************************************************************************
21 * Includes *
22 *****************************************************************************/
23
24#include <os2win.h>
25#include <stdlib.h>
26#include <string.h>
27#include "unicode.h"
28#include "misc.h"
29
30#include "HandleManager.H"
31#include "HMMMap.h"
32#include "mmap.h"
33#include "heapshared.h"
34
35#define DBG_LOCALLOG DBG_hmmmap
36#include "dbglocal.h"
37
38/*****************************************************************************
39 * Defines *
40 *****************************************************************************/
41
42/*****************************************************************************
43 * Structures *
44 *****************************************************************************/
45
46/*****************************************************************************
47 * Local Prototypes *
48 *****************************************************************************/
49
50//******************************************************************************
51//******************************************************************************
52DWORD HMDeviceMemMapClass::CreateFileMapping(PHMHANDLEDATA pHMHandleData,
53 HFILE hFile,
54 SECURITY_ATTRIBUTES *sa, /* [in] Optional security attributes*/
55 DWORD protect, /* [in] Protection for mapping object */
56 DWORD size_high, /* [in] High-order 32 bits of object size */
57 DWORD size_low, /* [in] Low-order 32 bits of object size */
58 LPCSTR name) /* [in] Name of file-mapping object */
59{
60 Win32MemMap *map;
61
62 if((hFile == -1 && size_low == 0) || size_high ||
63 protect & ~(PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY|SEC_COMMIT|SEC_IMAGE|SEC_RESERVE|SEC_NOCACHE) ||
64 (protect & (PAGE_READONLY|PAGE_READWRITE|PAGE_WRITECOPY)) == 0 ||
65// (hFile == -1 && (protect & SEC_COMMIT)) ||
66 ((protect & SEC_COMMIT) && (protect & SEC_RESERVE)))
67 {
68
69 dprintf(("CreateFileMappingA: invalid parameter (combination)!"));
70 dprintf(("Parameters: %x %x %x %x %s", hFile, protect, size_high, size_low, name));
71 return ERROR_INVALID_PARAMETER;
72 }
73
74 map = Win32MemMap::findMap((LPSTR)name);
75 if(map != NULL) {
76 dprintf(("CreateFileMappingA: duplicating map %s!", name));
77
78 DWORD protflags = map->getProtFlags();
79 switch(protect) {
80 case FILE_MAP_WRITE:
81 if(!(protflags & PAGE_WRITECOPY))
82 dprintf(("Different flags for duplicate!"));
83 break;
84 case FILE_MAP_READ:
85 if(!(protflags & (PAGE_READWRITE | PAGE_READONLY)))
86 dprintf(("Different flags for duplicate!"));
87 break;
88 case FILE_MAP_COPY:
89 if(!(protflags & PAGE_WRITECOPY))
90 dprintf(("Different flags for duplicate!"));
91 break;
92 }
93 //TODO:
94 //Is it allowed to open an existing view with different flags?
95 //(i.e. write access to readonly object)
96 // -> for the same file handle, yes
97
98 //if map already exists, we must create a new handle to the existing
99 //map object and return ERROR_ALREADY_EXISTS
100 pHMHandleData->dwUserData = (ULONG)map;
101 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
102
103 //findMap already incremented the reference count, so we simply don't
104 //release it here
105 return ERROR_ALREADY_EXISTS;
106 }
107
108#if 0
109 //We reuse the original memory map object if another one is created for
110 //the same file handle
111 //TODO: different file handles can exist for the same file (DuplicateHandle)
112 map = Win32MemMap::findMapByFile(hFile);
113 if(map) {
114 dprintf(("CreateFileMappingA: duplicating map with file %x!", hFile));
115
116 //if map already exists, we must create a new handle to the existing
117 //map object
118 pHMHandleData->dwUserData = (ULONG)map;
119 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
120
121 //findMap already incremented the reference count, so we simply don't
122 //release it here
123 return ERROR_SUCCESS;
124 }
125#endif
126 else {
127 map = new Win32MemMap(hFile, size_low, protect, (LPSTR)name);
128
129 if(map == NULL) {
130 dprintf(("CreateFileMappingA: can't create Win32MemMap object!"));
131 return ERROR_OUTOFMEMORY;
132 }
133
134 if(map->Init(size_low) == FALSE) {
135 dprintf(("CreateFileMappingA: init failed!"));
136 delete map;
137 return ERROR_GEN_FAILURE;
138 }
139 }
140 map->AddRef();
141 pHMHandleData->dwUserData = (ULONG)map;
142 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
143 return NO_ERROR;
144}
145//******************************************************************************
146//******************************************************************************
147DWORD HMDeviceMemMapClass::OpenFileMapping(PHMHANDLEDATA pHMHandleData,
148 DWORD access, /* [in] Access mode */
149 BOOL inherit, /* [in] Inherit flag */
150 LPCSTR name ) /* [in] Name of file-mapping object */
151{
152 Win32MemMap *map;
153 DWORD protflags;
154 DWORD ret;
155
156 if(name == NULL)
157 return ERROR_INVALID_PARAMETER;
158
159 map = Win32MemMap::findMap((LPSTR)name);
160 if(map == NULL) {
161 dprintf(("OpenFileMapping: mapping %s not found", name));
162 return ERROR_FILE_NOT_FOUND;
163 }
164 protflags = map->getProtFlags();
165 switch(access) {
166 case FILE_MAP_WRITE:
167 case FILE_MAP_ALL_ACCESS:
168 if(!(protflags & (PAGE_WRITECOPY|PAGE_READWRITE))) {
169 ret = ERROR_INVALID_PARAMETER;
170 goto fail;
171 }
172 break;
173 case FILE_MAP_READ:
174 if(!(protflags & (PAGE_READWRITE | PAGE_READONLY))) {
175 ret = ERROR_INVALID_PARAMETER;
176 goto fail;
177 }
178 break;
179 case FILE_MAP_COPY:
180 if(!(protflags & PAGE_WRITECOPY)) {
181 ret = ERROR_INVALID_PARAMETER;
182 goto fail;
183 }
184 break;
185 }
186 //findMap already incremented the reference count, so we simply don't
187 //release it here
188 pHMHandleData->dwUserData = (ULONG)map;
189 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
190 return NO_ERROR;
191
192fail:
193 map->Release();
194 return ret;
195}
196//******************************************************************************
197//******************************************************************************
198LPVOID HMDeviceMemMapClass::MapViewOfFileEx(PHMHANDLEDATA pHMHandleData,
199 DWORD dwDesiredAccess,
200 DWORD dwFileOffsetHigh,
201 DWORD dwFileOffsetLow,
202 DWORD dwNumberOfBytesToMap,
203 LPVOID lpBaseAddress)
204{
205 Win32MemMap *map;
206
207 dprintf(("KERNEL32: HMDeviceMemMapClass::MapViewOfFileEx(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh)\n",
208 pHMHandleData->hHMHandle,
209 dwDesiredAccess,
210 dwFileOffsetHigh,
211 dwFileOffsetLow,
212 dwNumberOfBytesToMap,
213 lpBaseAddress));
214
215 if(lpBaseAddress != NULL)
216 {
217#if 0
218 //No can do. Let us choose the address
219 dprintf(("Can't create view to virtual address %x", lpBaseAddress));
220 SetLastError(ERROR_OUTOFMEMORY);
221 return NULL;
222#else
223 // PH 2000/05/24 IBM VAJ3 uses this function.
224 // I don't think we'll ever succeed in EXACTLY copying the original
225 // behaviour of the function. Maybe ignoring the base address helps?
226 dprintf(("WARNING: suggested virtual address %x IGNORED! (experimental API violation)",
227 lpBaseAddress));
228#endif
229 }
230
231 if(pHMHandleData->dwUserData == NULL || pHMHandleData->dwInternalType != HMTYPE_MEMMAP) {
232 dprintf(("MapViewOfFileEx: invalid handle data!"));
233 SetLastError(ERROR_INVALID_HANDLE);
234 return NULL;
235 }
236 map = (Win32MemMap *)pHMHandleData->dwUserData;
237
238 return map->mapViewOfFile(dwNumberOfBytesToMap, dwFileOffsetLow, dwDesiredAccess);
239}
240//******************************************************************************
241//******************************************************************************
242BOOL HMDeviceMemMapClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
243{
244 Win32MemMap *map;
245
246 dprintf(("HMDeviceMemMapClass::CloseHandle %x", pHMHandleData->dwUserData));
247 if(pHMHandleData->dwUserData == NULL || pHMHandleData->dwInternalType != HMTYPE_MEMMAP) {
248 dprintf(("HMDeviceMemMapClass::CloseHandle: invalid handle data!"));
249 return FALSE;
250 }
251 //Although an application may close the file handle used to create a file
252 //mapping object, the system keeps the corresponding file open until the last
253 //view of the file is unmapped.
254 map = (Win32MemMap *)pHMHandleData->dwUserData;
255 map->Release();
256
257 return TRUE;
258}
259//******************************************************************************
260//******************************************************************************
Note: See TracBrowser for help on using the repository browser.