source: trunk/src/kernel32/oslibmem.cpp@ 8864

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

moved OS2 memory functions into seperate file

File size: 7.8 KB
Line 
1/* $Id: oslibmem.cpp,v 1.1 2002-07-13 15:58:21 sandervl Exp $ */
2/*
3 * Wrappers for OS/2 Dos* API
4 *
5 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12
13
14/*******************************************************************************
15* Header Files *
16*******************************************************************************/
17#define INCL_BASE
18#define INCL_DOSEXCEPTIONS
19#define INCL_DOSMEMMGR
20#define INCL_DOSPROCESS
21#define INCL_DOSFILEMGR
22#define INCL_DOSERRORS
23#define INCL_DOSDEVIOCTL
24#define INCL_DOSDEVICES
25#define INCL_NPIPES
26#include <os2wrap.h> //Odin32 OS/2 api wrappers
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include <ctype.h>
31#include <win32api.h>
32#include <winconst.h>
33#include <win\winioctl.h>
34#include <misc.h>
35#include "initterm.h"
36#include "oslibdos.h"
37#include "dosqss.h"
38#include "win32k.h"
39
40#define DBG_LOCALLOG DBG_oslibmem
41#include "dbglocal.h"
42
43//******************************************************************************
44//TODO: Assumes entire memory range has the same protection flags!
45//TODO: Check if this works for code aliases...
46//******************************************************************************
47DWORD OSLibDosAliasMem(LPVOID pb, ULONG cb, LPVOID *ppbAlias, ULONG fl)
48{
49 DWORD rc;
50 DWORD attr;
51 DWORD size = cb;
52
53 cb = (cb-1) & ~0xfff;
54 cb+= PAGE_SIZE;
55
56 rc = DosQueryMem(pb, &size, &attr);
57 if(rc) {
58 dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
59 return rc;
60 }
61 size = (size-1) & ~0xfff;
62 size+= PAGE_SIZE;
63 if(size != cb) {
64 dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
65 //ignore this and continue return 5;
66 attr = fl; //just use original protection flags (NOT CORRECT)
67 }
68 attr &= (PAG_READ|PAG_WRITE|PAG_EXECUTE|PAG_GUARD|PAG_DEFAULT);
69 if(attr != fl) {
70 rc = DosSetMem(pb, size, fl);
71 if(rc) {
72 dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
73 attr = fl;
74 //just continue for now
75 //return rc;
76 }
77 }
78 rc = DosAliasMem(pb, cb, ppbAlias, 2);
79 if(rc) {
80 dprintf(("OSLibDosAliasMem: DosAliasMem %x %x returned %d", pb, cb, rc));
81 return rc;
82 }
83 if(attr != fl) {
84 rc = DosSetMem(pb, size, attr);
85 if(rc) {
86 dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
87 return rc;
88 }
89 }
90 return 0;
91}
92//******************************************************************************
93//NT returns addresses aligned at 64k, so we do too.
94//******************************************************************************
95// tries to retrieve an aligned block recursivly
96APIRET OdinAlignMemR(LPVOID *lpMemAddr, DWORD size, DWORD offset, DWORD flags)
97{
98 LPVOID memaddr;
99 APIRET rc, rc2;
100
101 DosEnterCritSec();
102 DosFreeMem(*lpMemAddr);
103 rc2 = DosAllocMem(&memaddr, 64 * 1024 - offset, PAG_READ | flAllocMem);
104 rc = DosAllocMem(lpMemAddr, size, flags | flAllocMem);
105 DosExitCritSec();
106
107 dprintf2(("OdinAlignMem: DosAllocMem returned %d, %d and pointers %x, %x for size %x and offset %x", rc, rc2, *lpMemAddr, memaddr, size, offset ));
108
109 if(rc2) {
110 // giving up - return as received
111 return rc;
112 }
113
114 if(rc) {
115 // seems to be out of memory
116 DosFreeMem(memaddr);
117 return rc;
118 }
119
120 if((DWORD) *lpMemAddr & 0xFFFF)
121 rc = OdinAlignMemR(lpMemAddr, size, (DWORD) *lpMemAddr & 0xFFFF, flags);
122
123 DosFreeMem(memaddr);
124 return rc;
125}
126//******************************************************************************
127//******************************************************************************
128DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD cbSize, DWORD flFlags)
129{
130 PVOID pvMemAddr;
131 DWORD offset;
132 APIRET rc;
133
134 /*
135 * Let's try use the extended DosAllocMem API of Win32k.sys.
136 */
137 if (libWin32kInstalled())
138 {
139 rc = DosAllocMemEx(lplpMemAddr, cbSize, flFlags | flAllocMem | OBJ_ALIGN64K);
140 if (rc != ERROR_NOT_SUPPORTED) /* This call was stubbed until recently. */
141 return rc;
142 }
143
144 /*
145 * If no or old Win32k fall back to old method.
146 */
147
148 rc = DosAllocMem(&pvMemAddr, cbSize, flFlags | flAllocMem);
149 if(rc) {
150 return rc;
151 }
152
153 // already 64k aligned ?
154// if((DWORD) pvMemAddr & 0xFFFF)
155// rc = OdinAlignMemR(&pvMemAddr, cbSize, (DWORD) pvMemAddr & 0xFFFF, flFlags);
156
157 if(!rc)
158 *lplpMemAddr = pvMemAddr;
159
160 return rc;
161}
162//******************************************************************************
163//******************************************************************************
164DWORD OSLibDosFreeMem(LPVOID lpMemAddr)
165{
166 return DosFreeMem(lpMemAddr);
167}
168//******************************************************************************
169//NOTE: If name == NULL, allocated gettable unnamed shared memory
170//OS/2 returns error 123 (invalid name) if the shared memory name includes
171//colons. We need to replace them with underscores.
172//******************************************************************************
173DWORD OSLibDosAllocSharedMem(LPVOID *lplpMemAddr, DWORD size, DWORD flags, LPSTR name)
174{
175 APIRET rc;
176 char *sharedmemname = NULL, *tmp;
177
178 if(name) {
179 sharedmemname = (char *)malloc(strlen(name) + 16);
180 strcpy(sharedmemname, "\\SHAREMEM\\");
181 strcat(sharedmemname, name);
182 }
183 else flags |= OBJ_GETTABLE;
184
185 //SvL: Colons are unacceptable in shared memory names (for whatever reason)
186 tmp = sharedmemname;
187 while(*tmp != 0) {
188 if(*tmp == ':') {
189 *tmp = '_';
190 }
191 tmp++;
192 }
193
194 rc = DosAllocSharedMem(lplpMemAddr, sharedmemname, size, flags);
195 if(name) {
196 free(sharedmemname);
197 }
198 return rc;
199}
200//******************************************************************************
201//NOTE: If name == NULL, assume gettable unnamed shared memory
202//******************************************************************************
203DWORD OSLibDosGetNamedSharedMem(LPVOID *lplpMemAddr, LPSTR name)
204{
205 APIRET rc;
206 char *sharedmemname = NULL, *tmp;
207
208 if(name) {
209 sharedmemname = (char *)malloc(strlen(name) + 16);
210 strcpy(sharedmemname, "\\SHAREMEM\\");
211 strcat(sharedmemname, name);
212
213 //SvL: Colons are unacceptable in shared memory names (for whatever reason)
214 tmp = sharedmemname;
215 while(*tmp != 0) {
216 if(*tmp == ':') {
217 *tmp = '_';
218 }
219 tmp++;
220 }
221 rc = DosGetNamedSharedMem(lplpMemAddr, sharedmemname, PAG_READ|PAG_WRITE);
222 if(name) {
223 free(sharedmemname);
224 }
225 }
226 else rc = DosGetSharedMem((LPVOID)*(DWORD *)lplpMemAddr, PAG_READ|PAG_WRITE);
227
228 return rc;
229}
230//******************************************************************************
231//******************************************************************************
232DWORD OSLibDosQueryMem(LPVOID lpMemAddr, DWORD *lpRangeSize, DWORD *lpAttr)
233{
234 return DosQueryMem(lpMemAddr, lpRangeSize, lpAttr);
235}
236//******************************************************************************
237//******************************************************************************
238DWORD OSLibDosSetMem(LPVOID lpMemAddr, DWORD size, DWORD flags)
239{
240 APIRET rc;
241
242 rc = DosSetMem(lpMemAddr, size, flags);
243 switch(rc) {
244 case ERROR_INVALID_ADDRESS:
245 return OSLIB_ERROR_INVALID_ADDRESS;
246 case ERROR_ACCESS_DENIED:
247 return OSLIB_ERROR_ACCESS_DENIED;
248 default:
249 return rc;
250 }
251}
252//******************************************************************************
253//******************************************************************************
Note: See TracBrowser for help on using the repository browser.