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

Last change on this file since 9971 was 9971, checked in by sandervl, 22 years ago

PF: Corrected HFILE definition as it is in Wine and in Win2k

File size: 9.8 KB
Line 
1/* $Id: hmmmap.cpp,v 1.24 2003-04-02 11:03:31 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 HANDLE 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 //It's not allowed to map a file of length 0 according to MSDN. This time
75 //the docs are correct. (verified in NT4 SP6)
76 //TODO: also need to verify access rights of the file handle (write maps need
77 // write access obviously)
78 if(hFile != -1) {
79 DWORD dwFileSizeLow = 0, dwFileSizeHigh = 0;
80
81 dwFileSizeLow = ::GetFileSize(hFile, &dwFileSizeHigh);
82 if(dwFileSizeHigh == 0 && dwFileSizeLow == 0) {
83 dprintf(("CreateFileMappingA: not allowed to map a file with length 0!!"));
84 return ERROR_FILE_INVALID;
85 }
86 }
87
88 map = Win32MemMap::findMap((LPSTR)name);
89 if(map != NULL) {
90 dprintf(("CreateFileMappingA: duplicating map %s!", name));
91
92 DWORD protflags = map->getProtFlags();
93 switch(protect) {
94 case FILE_MAP_WRITE:
95 if(!(protflags & PAGE_WRITECOPY))
96 dprintf(("Different flags for duplicate!"));
97 break;
98 case FILE_MAP_READ:
99 if(!(protflags & (PAGE_READWRITE | PAGE_READONLY)))
100 dprintf(("Different flags for duplicate!"));
101 break;
102 case FILE_MAP_COPY:
103 if(!(protflags & PAGE_WRITECOPY))
104 dprintf(("Different flags for duplicate!"));
105 break;
106 }
107 //TODO:
108 //Is it allowed to open an existing view with different flags?
109 //(i.e. write access to readonly object)
110 // -> for the same file handle, yes
111
112 //if map already exists, we must create a new handle to the existing
113 //map object and return ERROR_ALREADY_EXISTS
114 pHMHandleData->dwUserData = (ULONG)map;
115 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
116
117 //findMap already incremented the reference count, so we simply don't
118 //release it here
119 return ERROR_ALREADY_EXISTS;
120 }
121
122 //We reuse the original memory map object if another one is created for
123 //the same file handle
124 //TODO: different file handles can exist for the same file (DuplicateHandle)
125 map = Win32MemMap::findMapByFile(hFile);
126 if(map) {
127 Win32MemMapDup *dupmap;
128
129 dprintf(("CreateFileMappingA: duplicating map with file %x!", hFile));
130
131 dupmap = new Win32MemMapDup(map, hFile, size_low, protect, (LPSTR)name);
132
133 if(dupmap == NULL) {
134 dprintf(("CreateFileMappingA: can't create Win32MemMap object!"));
135 return ERROR_OUTOFMEMORY;
136 }
137 map->Release(); //findMapByFile increases the refcount, so decrease it here
138 map = dupmap;
139 }
140 else {
141 map = new Win32MemMap(hFile, size_low, protect, (LPSTR)name);
142
143 if(map == NULL) {
144 dprintf(("CreateFileMappingA: can't create Win32MemMap object!"));
145 return ERROR_OUTOFMEMORY;
146 }
147 }
148 if(map->Init(size_low) == FALSE) {
149 dprintf(("CreateFileMappingA: init failed!"));
150 delete map;
151 return ERROR_GEN_FAILURE;
152 }
153 pHMHandleData->dwUserData = (ULONG)map;
154 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
155 return NO_ERROR;
156}
157//******************************************************************************
158//******************************************************************************
159DWORD HMDeviceMemMapClass::OpenFileMapping(PHMHANDLEDATA pHMHandleData,
160 DWORD access, /* [in] Access mode */
161 BOOL inherit, /* [in] Inherit flag */
162 LPCSTR name ) /* [in] Name of file-mapping object */
163{
164 Win32MemMap *map;
165 DWORD protflags;
166 DWORD ret;
167
168 if(name == NULL)
169 return ERROR_INVALID_PARAMETER;
170
171 map = Win32MemMap::findMap((LPSTR)name);
172 if(map == NULL) {
173 dprintf(("OpenFileMapping: mapping %s not found", name));
174 return ERROR_FILE_NOT_FOUND;
175 }
176 protflags = map->getProtFlags();
177 switch(access) {
178 case FILE_MAP_WRITE:
179 case FILE_MAP_ALL_ACCESS:
180 if(!(protflags & (PAGE_WRITECOPY|PAGE_READWRITE))) {
181 ret = ERROR_INVALID_PARAMETER;
182 goto fail;
183 }
184 break;
185 case FILE_MAP_READ:
186 if(!(protflags & (PAGE_READWRITE | PAGE_READONLY))) {
187 ret = ERROR_INVALID_PARAMETER;
188 goto fail;
189 }
190 break;
191 case FILE_MAP_COPY:
192 if(!(protflags & PAGE_WRITECOPY)) {
193 ret = ERROR_INVALID_PARAMETER;
194 goto fail;
195 }
196 break;
197 }
198 //findMap already incremented the reference count, so we simply don't
199 //release it here
200 pHMHandleData->dwUserData = (ULONG)map;
201 pHMHandleData->dwInternalType = HMTYPE_MEMMAP;
202 return NO_ERROR;
203
204fail:
205 map->Release();
206 return ret;
207}
208//******************************************************************************
209//******************************************************************************
210LPVOID HMDeviceMemMapClass::MapViewOfFileEx(PHMHANDLEDATA pHMHandleData,
211 DWORD dwDesiredAccess,
212 DWORD dwFileOffsetHigh,
213 DWORD dwFileOffsetLow,
214 DWORD dwNumberOfBytesToMap,
215 LPVOID lpBaseAddress)
216{
217 Win32MemMap *map;
218
219 dprintf(("KERNEL32: HMDeviceMemMapClass::MapViewOfFileEx(%08xh,%08xh,%08xh,%08xh,%08xh,%08xh)\n",
220 pHMHandleData->hHMHandle,
221 dwDesiredAccess,
222 dwFileOffsetHigh,
223 dwFileOffsetLow,
224 dwNumberOfBytesToMap,
225 lpBaseAddress));
226
227 if(lpBaseAddress != NULL)
228 {
229#if 0
230 //No can do. Let us choose the address
231 dprintf(("Can't create view to virtual address %x", lpBaseAddress));
232 SetLastError(ERROR_OUTOFMEMORY);
233 return NULL;
234#else
235 // PH 2000/05/24 IBM VAJ3 uses this function.
236 // I don't think we'll ever succeed in EXACTLY copying the original
237 // behaviour of the function. Maybe ignoring the base address helps?
238 dprintf(("WARNING: suggested virtual address %x IGNORED! (experimental API violation)",
239 lpBaseAddress));
240#endif
241 }
242
243 if(pHMHandleData->dwUserData == NULL || pHMHandleData->dwInternalType != HMTYPE_MEMMAP) {
244 dprintf(("MapViewOfFileEx: invalid handle data!"));
245 SetLastError(ERROR_INVALID_HANDLE);
246 return NULL;
247 }
248 map = (Win32MemMap *)pHMHandleData->dwUserData;
249
250 return map->mapViewOfFile(dwNumberOfBytesToMap, dwFileOffsetLow, dwDesiredAccess);
251}
252//******************************************************************************
253//******************************************************************************
254BOOL HMDeviceMemMapClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
255{
256 Win32MemMap *map;
257
258 dprintf(("HMDeviceMemMapClass::CloseHandle %x", pHMHandleData->dwUserData));
259 if(pHMHandleData->dwUserData == NULL || pHMHandleData->dwInternalType != HMTYPE_MEMMAP) {
260 dprintf(("HMDeviceMemMapClass::CloseHandle: invalid handle data!"));
261 return FALSE;
262 }
263 //Although an application may close the file handle used to create a file
264 //mapping object, the system keeps the corresponding file open until the last
265 //view of the file is unmapped.
266 map = (Win32MemMap *)pHMHandleData->dwUserData;
267 map->Release();
268
269 return TRUE;
270}
271//******************************************************************************
272//******************************************************************************
Note: See TracBrowser for help on using the repository browser.