source: trunk/src/kernel32/OS2NATIVE.c@ 4

Last change on this file since 4 was 4, checked in by ktk, 26 years ago

Import

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