source: trunk/src/kernel32/os2native.cpp@ 617

Last change on this file since 617 was 617, checked in by sandervl, 26 years ago

Exception handler changes

File size: 12.2 KB
Line 
1/* $Id: os2native.cpp,v 1.5 1999-08-22 11:11:10 sandervl Exp $ */
2
3/*
4 * Misc procedures
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Knut St. Osmundsen
8 * Copyright 1998 Peter FitzSimmons
9 *
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14#define INCL_BASE
15#define INCL_DOSEXCEPTIONS
16#define INCL_DOSMEMMGR
17#define INCL_DOSPROCESS
18#include <os2wrap.h> //Odin32 OS/2 api wrappers
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22#ifdef __IBMC__
23#include <builtin.h>
24#endif
25#include <win32type.h>
26#include "misc.h"
27#include "exceptions.h"
28
29#define PAGE_NOACCESS 0x01
30#define PAGE_READONLY 0x02
31#define PAGE_READWRITE 0x04
32#define PAGE_WRITECOPY 0x08
33#define PAGE_EXECUTE 0x10
34#define PAGE_EXECUTE_READ 0x20
35#define PAGE_EXECUTE_READWRITE 0x40
36#define PAGE_EXECUTE_WRITECOPY 0x80
37#define PAGE_GUARD 0x100
38#define PAGE_NOCACHE 0x200
39#define MEM_COMMIT 0x1000
40#define MEM_RESERVE 0x2000
41#define MEM_DECOMMIT 0x4000
42#define MEM_RELEASE 0x8000
43#define MEM_TOP_DOWN 0x100000 //Ignored
44
45extern ULONG flAllocMem; /* Tue 03.03.1998: knut */
46
47#ifdef DEBUG
48ULONG commit = 0, reserve = 0;
49#endif
50
51//******************************************************************************
52//******************************************************************************
53LPVOID WIN32API VirtualAlloc(LPVOID lpvAddress, DWORD cbSize, DWORD fdwAllocationType,
54 DWORD fdwProtect)
55{
56 PVOID Address = lpvAddress;
57 ULONG flag = 0, base;
58 APIRET rc;
59
60 dprintf(("VirtualAlloc at %X; %d bytes, fAlloc %d, fProtect %d\n", (int)lpvAddress, cbSize, fdwAllocationType, fdwProtect));
61
62 if (cbSize > 0x7fc00000) /* 2Gb - 4Mb */
63 {
64 dprintf(("VirtualAlloc: size too large"));
65// SetLastError( ERROR_OUTOFMEMORY );
66 return NULL;
67 }
68
69 if (!(fdwAllocationType & (MEM_COMMIT | MEM_RESERVE)) ||
70 (fdwAllocationType & ~(MEM_COMMIT | MEM_RESERVE)))
71 {
72 dprintf(("VirtualAlloc: Invalid parameter"));
73// SetLastError( ERROR_INVALID_PARAMETER );
74 return NULL;
75 }
76
77 if(fdwAllocationType & MEM_COMMIT) {
78 dprintf(("VirtualAlloc: commit\n"));
79 flag = PAG_COMMIT;
80 }
81 if(fdwProtect & PAGE_READONLY) flag |= PAG_READ;
82 if(fdwProtect & PAGE_READWRITE) flag |= (PAG_READ | PAG_WRITE);
83 if(fdwProtect & PAGE_EXECUTE_READ) flag |= PAG_EXECUTE;
84 if(fdwProtect & PAGE_GUARD) flag |= PAG_GUARD;
85
86 //just do this if other options are used
87 if(!(flag & (PAG_READ | PAG_WRITE | PAG_EXECUTE)) || flag == 0)
88 flag |= PAG_READ | PAG_WRITE;
89
90 if(fdwAllocationType & MEM_COMMIT && lpvAddress != NULL) {
91 Address = lpvAddress;
92
93 rc = DosSetMem(lpvAddress, cbSize, flag);
94 //might try to commit larger part with same base address
95 if(rc == ERROR_ACCESS_DENIED && cbSize > 4096 ) {//knut: AND more than one page
96 char *newbase = (char *)lpvAddress + ((cbSize-1) & 0xFFFFF000); //knut: lets not start after the last page!
97 ULONG size, os2flags;
98
99 while(newbase >= (char *)lpvAddress) { //knut: should check first page to!!
100 size = 4096;
101 os2flags = 0;
102 rc = DosQueryMem(newbase, &size, &os2flags);
103 if(rc) break;
104 if(os2flags & PAG_COMMIT) {
105 newbase += 4096;
106 break;
107 }
108 newbase -= 4096;
109 }
110 if(rc == 0) {
111 //In case it wants to commit bytes that fall into the last
112 //page of the previous commit command
113 if(cbSize > ((int)newbase - (int)lpvAddress)) {
114 rc = DosSetMem(newbase, cbSize - ((int)newbase - (int)lpvAddress), flag);
115 }
116 }
117 else return(NULL);
118 }
119 else
120 {
121 if(rc == ERROR_INVALID_ADDRESS)
122 {
123 rc = DosAllocMem(&Address, cbSize, flag | flAllocMem );
124 }
125 else
126 if(rc) dprintf(("Unexpected DosSetMem error %x", rc));
127 }
128 }
129 else {
130 /*knut: flAllocMem */
131 rc = DosAllocMem(&Address, cbSize, flag | flAllocMem );
132 }
133
134 //TODO: Set last error in case rc != 0
135 if(rc) {
136 dprintf(("DosSetMem returned %d\n", rc));
137// SetLastError( ERROR_OUTOFMEMORY );
138 return(NULL);
139 }
140
141 dprintf(("VirtualAlloc returned %X\n", Address));
142 return(Address);
143}
144//******************************************************************************
145//******************************************************************************
146BOOL WIN32API VirtualFree(LPVOID lpvAddress, DWORD cbSize, DWORD FreeType)
147{
148 APIRET rc;
149
150 dprintf(("VirtualFree at %d; %d bytes, freetype %d\n", (int)lpvAddress, cbSize, FreeType));
151
152 if(FreeType & MEM_DECOMMIT) {
153 rc = DosSetMem(lpvAddress, cbSize, PAG_DECOMMIT);
154 }
155 else rc = DosFreeMem(lpvAddress); //MEM_RELEASE, cbSize == 0 (or should be)
156
157//TODO: Set last error in case rc != 0
158 if(rc) return(FALSE);
159 return(TRUE);
160}
161//******************************************************************************
162//LPVOID lpvAddress; /* address of region of committed pages */
163//DWORD cbSize; /* size of the region */
164//DWORD fdwNewProtect; /* desired access protection */
165//PDWORD pfdwOldProtect; /* address of variable to get old protection */
166//TODO: Not 100% complete
167//TODO: SetLastError on failure
168//******************************************************************************
169BOOL WIN32API VirtualProtect(LPVOID lpvAddress, DWORD cbSize, DWORD fdwNewProtect,
170 DWORD *pfdwOldProtect)
171{
172 APIRET rc;
173 ULONG pageFlags = 0;
174 int npages;
175
176 dprintf(("VirtualProtect %X; %d bytes, new flags %X (%X)\n", (int)lpvAddress, cbSize, fdwNewProtect, pfdwOldProtect));
177// _interrupt(3);
178 if(pfdwOldProtect == NULL)
179 return(FALSE);
180
181 rc = DosQueryMem(lpvAddress, &cbSize, &pageFlags);
182 if(rc) {
183 dprintf(("DosQueryMem returned %d\n", rc));
184 return(FALSE);
185 }
186 dprintf(("Old memory flags %X\n", pageFlags));
187 *pfdwOldProtect = 0;
188 if(pageFlags & PAG_READ && !(pageFlags & PAG_WRITE))
189 *pfdwOldProtect |= PAGE_READONLY;
190 if(pageFlags & (PAG_READ | PAG_WRITE))
191 *pfdwOldProtect |= PAGE_READWRITE;
192 if(pageFlags & PAG_EXECUTE)
193 *pfdwOldProtect |= PAGE_EXECUTE_READ;
194 if(pageFlags & PAG_GUARD)
195 *pfdwOldProtect |= PAGE_GUARD;
196 pageFlags = 0;
197
198 if(fdwNewProtect & PAGE_READONLY) pageFlags |= PAG_READ;
199 if(fdwNewProtect & PAGE_READWRITE) pageFlags |= (PAG_READ | PAG_WRITE);
200 if(fdwNewProtect & PAGE_EXECUTE_READ) pageFlags |= PAG_EXECUTE;
201 if(fdwNewProtect & PAGE_EXECUTE_READWRITE)
202 pageFlags |= (PAG_EXECUTE | PAG_WRITE);
203 if(fdwNewProtect & PAGE_GUARD) pageFlags |= PAG_GUARD;
204//Not supported in OS/2??
205// if(fdwNewProtect & PAGE_NOACCESS)
206
207 dprintf(("New memory flags %X\n", pageFlags));
208 if(pageFlags == 0) {
209 dprintf(("pageFlags == 0\n"));
210 return(TRUE); //nothing to do
211 }
212 npages = ((int)lpvAddress + cbSize >> 12) - ((int)lpvAddress >> 12) + 1;
213
214 lpvAddress = (LPVOID)((int)lpvAddress & ~0xFFF);
215 cbSize = npages*4096;
216 dprintf(("lpvAddress = %X, cbSize = %d\n", lpvAddress, cbSize));
217
218 rc = DosSetMem(lpvAddress, cbSize, pageFlags);
219 if(rc) {
220 dprintf(("DosSetMem returned %d\n", rc));
221 return(FALSE);
222 }
223 return(TRUE);
224}
225//******************************************************************************
226#define PMEMORY_BASIC_INFORMATION void *
227//******************************************************************************
228DWORD WIN32API VirtualQuery(LPVOID lpvAddress, PMEMORY_BASIC_INFORMATION pmbiBuffer,
229 DWORD cbLength)
230{
231 dprintf(("VirtualQuery - stub\n"));
232 return(0);
233}
234//******************************************************************************
235//******************************************************************************
236#ifdef __WATCOMC__ /*PLF Sat 97-06-21 17:12:36*/
237 extern void interrupt3( void );
238 #pragma aux interrupt3= \
239 "int 3"
240#endif
241void WIN32API DebugBreak()
242{
243 dprintf(("DebugBreak\n"));
244#ifdef __WATCOMC__
245 interrupt3();
246#else
247 _interrupt(3);
248#endif
249}
250//******************************************************************************
251//TODO: Implement this??
252//******************************************************************************
253BOOL WIN32API GetThreadContext(HANDLE hThread, LPWINCONTEXT lpContext)
254{
255 dprintf(("GetThreadContext NOT IMPLEMENTED!! (TRUE)\n"));
256 memset(lpContext, 0, sizeof(WINCONTEXT));
257 return TRUE;
258}
259//******************************************************************************
260//TODO: Implement this??
261//******************************************************************************
262BOOL WIN32API SetThreadContext(HANDLE hThread, LPWINCONTEXT lpContext)
263{
264 dprintf(("SetThreadContext NOT IMPLEMENTED!!\n"));
265
266 return FALSE;
267}
268//******************************************************************************
269//******************************************************************************
270BOOL WIN32API VirtualLock( LPVOID lpAddress, DWORD dwSize )
271{
272 dprintf(("VirtualLock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
273 return TRUE;
274}
275
276//******************************************************************************
277BOOL WIN32API VirtualUnlock( LPVOID lpAddress, DWORD dwSize )
278{
279 dprintf(("VirtualUnlock at %d; %d bytes - stub (TRUE)\n", (int)lpAddress, dwSize));
280 return TRUE;
281}
282
283
284/*****************************************************************************
285 * Name : BOOL VirtualProtectEx
286 * Purpose : The VirtualProtectEx function changes the access protection on
287 * a region of committed pages in the virtual address space of a specified
288 * process. Note that this function differs from VirtualProtect,
289 * which changes the access protection on the calling process only.
290 * Parameters: HANDLE hProcess handle of process
291 * LPVOID lpvAddress address of region of committed pages
292 * DWORD cbSize size of region
293 * DWORD fdwNewProtect desired access protection
294 * PDWORD pfdwOldProtect address of variable to get old protection
295 * Variables :
296 * Result : size of target buffer
297 * Remark :
298 * Status : UNTESTED STUB
299 *
300 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
301 *****************************************************************************/
302
303BOOL WIN32API VirtualProtectEx(HANDLE hProcess,
304 LPVOID lpvAddress,
305 DWORD cbSize,
306 DWORD fdwNewProtect,
307 LPDWORD pfdwOldProtect)
308{
309 dprintf(("KERNEL32: VirtualProtectEx(%08x,%08xh,%08xh,%08xh,%08xh) not implemented.\n",
310 hProcess,
311 lpvAddress,
312 cbSize,
313 fdwNewProtect,
314 pfdwOldProtect));
315
316 return (FALSE);
317}
318
319
320/*****************************************************************************
321 * Name : DWORD VirtualQueryEx
322 * Purpose : The VirtualQueryEx function provides information about a range
323 * of pages within the virtual address space of a specified process.
324 * Parameters: HANDLE hProcess handle of process
325 * LPCVOID lpvAddress address of region
326 * PMEMORY_BASIC_INFORMATION pmbiBuffer address of information buffer
327 * DWORD cbLength size of buffer
328 * Variables :
329 * Result : number of bytes returned in buffer
330 * Remark :
331 * Status : UNTESTED STUB
332 *
333 * Author : Patrick Haller [Mon, 1998/06/15 08:00]
334 *****************************************************************************/
335
336DWORD WIN32API VirtualQueryEx(HANDLE hProcess,
337 LPVOID lpvAddress,
338 PMEMORY_BASIC_INFORMATION pmbiBuffer,
339 DWORD cbLength)
340{
341 dprintf(("KERNEL32: VirtualQueryEx(%08x,%08xh,%08xh,%08xh) not implemented.\n",
342 hProcess,
343 lpvAddress,
344 pmbiBuffer,
345 cbLength));
346
347 return (0);
348}
349
Note: See TracBrowser for help on using the repository browser.