source: trunk/src/kernel32/oslibmisc.cpp@ 21462

Last change on this file since 21462 was 21462, checked in by dmik, 15 years ago

Fixed: CreateProcess could not start programs with national characters in names on systems where the OS/2 codepage is not equal to the Windows ANSI codepage (like the .ru locale). Continuation of r21461.

File size: 11.8 KB
Line 
1/* $Id: oslibmisc.cpp,v 1.19 2004-05-24 08:56:07 sandervl Exp $ */
2/*
3 * Misc OS/2 util. procedures
4 *
5 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1998 Peter FitzSimmons
7 * Copyright 1998 Patrick Haller
8 *
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13#define INCL_WIN
14#define INCL_BASE
15#define INCL_DOSPROCESS
16#define INCL_DOSERRORS
17#define INCL_DOSSEL
18#define INCL_DOSNLS /* National Language Support values */
19#include <os2wrap.h> //Odin32 OS/2 api wrappers
20#include <string.h>
21#include <stdlib.h>
22#include <stdio.h> /*PLF Wed 98-03-18 05:15:04*/
23#include <malloc.h> /*PLF Wed 98-03-18 05:15:04*/
24#include "oslibmisc.h"
25#include "win32api.h"
26#include <misc.h>
27#include <odincrt.h>
28
29#define DBG_LOCALLOG DBG_oslibmisc
30#include "dbglocal.h"
31
32typedef APIRET ( APIENTRY *PFN_IMSETMSGQUEUEPROPERTY )( HMQ, ULONG );
33
34PFN_IMSETMSGQUEUEPROPERTY pfnImSetMsgQueueProperty = NULL;
35
36//******************************************************************************
37//TODO: not reentrant!
38//******************************************************************************
39char *OSLibGetDllName(ULONG hModule)
40{
41 static char modname[CCHMAXPATH] = {0};
42
43 if(DosQueryModuleName(hModule, CCHMAXPATH, modname) != 0) {
44 return NULL;
45 }
46 return(modname);
47}
48//******************************************************************************
49//******************************************************************************
50BOOL OSLibGetDllName(ULONG hModule, char *name, int length)
51{
52 return DosQueryModuleName(hModule, length, name) == 0;
53}
54//******************************************************************************
55/******************************************************************************
56 * Name : ULONG OSLibiGetModuleHandleA
57 * Purpose : replacement for IBM Open32's GetModuleHandle
58 * Parameters: LPCTSTR lpszModule
59 * Variables :
60 * Result : HMODULE hModule or NULLHANDLE in case of error
61 * Remark :
62 * Status : REWRITTEN UNTESTED
63 *
64 * Author : Patrick Haller [Sun, 1998/04/04 01:55]
65 *****************************************************************************/
66
67ULONG OSLibiGetModuleHandleA(char * pszModule)
68{
69 HMODULE hModule; /* module handle */
70 APIRET rc; /* API returncode */
71 static HMODULE hModuleExe = 0; /* "cached" hModuleExe */
72 PTIB pTIB; /* parameters for DosGetInfoBlocks */
73 PPIB pPIB;
74
75 dprintf(("KERNEL32:GetModuleHandle(%x)\n",
76 pszModule));
77
78 /* @@@PH 98/04/04
79
80 this Open32 function is broken for pszModule == NULL
81 return(GetModuleHandle(pszModule));
82
83 Open32 always returns -1 here, however it should return the handle
84 of the current process. MFC30 crashes.
85
86 SvL, me thinks for PELDR support, you'll have to rewrite
87 this code anyway :)
88
89 */
90
91 if (NULL == pszModule) /* obtain handle to current executable */
92 {
93 if (hModuleExe != NULLHANDLE) /* do we have a cached handle ? */
94 return (hModuleExe);
95
96 rc = DosGetInfoBlocks(&pTIB, /* get the info blocks */
97 &pPIB);
98 if (rc != NO_ERROR) /* check for errors */
99 {
100 return (NULLHANDLE); /* signal failure */
101 }
102
103 hModuleExe = pPIB->pib_hmte; /* set cached module */
104 hModule = pPIB->pib_hmte; /* module table entry ID */
105 }
106 else
107 {
108 rc = DosQueryModuleHandleStrict(pszModule, /* query module handle */
109 &hModule);
110
111 if (rc != NO_ERROR) /* check for errors */
112 {
113 return (NULLHANDLE); /* signal failure */
114 }
115 }
116
117 return (hModule); /* return determined handle */
118}
119
120
121ULONG OSLibQueryModuleHandle(char *modname)
122{
123 HMODULE hModule;
124 APIRET rc;
125
126 rc = DosQueryModuleHandleStrict(modname, /* query module handle */
127 &hModule);
128 if(rc)
129 return(-1);
130
131 return(hModule);
132}
133
134void OSLibWait(ULONG msec)
135{
136 DosSleep(msec);
137}
138
139//******************************************************************************
140//Wrapper for Dos16AllocSeg
141//******************************************************************************
142ULONG OSLibAllocSel(ULONG size, USHORT *selector)
143{
144#if 1
145 PVOID pSelMem;
146 ULONG sel;
147 APIRET rc;
148
149 rc = DosAllocMem(&pSelMem, size, PAG_COMMIT|PAG_READ|PAG_WRITE|OBJ_TILE);
150 if(rc != NO_ERROR) {
151 dprintf(("OSLibAllocSel: DosAllocMem failed with %d", rc));
152 DebugInt3();
153 return FALSE;
154 }
155 *selector = (DosFlatToSel((ULONG)pSelMem) >> 16);
156 return *selector != 0;
157#else
158 return (Dos16AllocSeg(size, selector, SEG_NONSHARED) == 0);
159#endif
160}
161//******************************************************************************
162//Wrapper for Dos16FreeSeg
163//******************************************************************************
164ULONG OSLibFreeSel(USHORT selector)
165{
166#if 1
167 PVOID pSelMem;
168 APIRET rc;
169
170 pSelMem = (PVOID)DosSelToFlat(selector << 16);
171 rc = DosFreeMem(pSelMem);
172 return rc == NO_ERROR;
173#else
174 return (Dos16FreeSeg(selector) == 0);
175#endif
176}
177//******************************************************************************
178//Wrapper for Dos32SelToFlat
179//******************************************************************************
180PVOID OSLibSelToFlat(USHORT selector)
181{
182 return (PVOID)DosSelToFlat(selector << 16);
183}
184//******************************************************************************
185//Get TIB data
186//******************************************************************************
187ULONG OSLibGetTIB(int tiboff)
188{
189 PTIB ptib;
190 PPIB ppib;
191 APIRET rc;
192
193 rc = DosGetInfoBlocks(&ptib, &ppib);
194 if(rc) {
195 return 0;
196 }
197 switch(tiboff)
198 {
199 case TIB_STACKTOP:
200 return (ULONG)ptib->tib_pstacklimit;
201 case TIB_STACKLOW:
202 return (ULONG)ptib->tib_pstack;
203 default:
204 return 0;
205 }
206}
207
208/**
209 * Gets a PIB data.
210 * @returns Requested PIB data.
211 * 0 may indicate error or that the PIB data you requested actually is 0.
212 * @param iPIB PIB data index. (one of the PIB_* defines in oslibmisc.h)
213 * @author
214 * @remark Spooky error handling.
215 */
216ULONG OSLibGetPIB(int iPIB)
217{
218 PTIB ptib;
219 PPIB ppib;
220 APIRET rc;
221
222 rc = DosGetInfoBlocks(&ptib, &ppib);
223 if (rc)
224 {
225 dprintf(("KERNEL32: OSLibGetPIB(%d): DosGetInfoBlocks failed with rc=%d\n", iPIB, rc));
226 return 0;
227 }
228
229 switch(iPIB)
230 {
231 case PIB_TASKHNDL:
232 return ppib->pib_hmte;
233
234 case PIB_TASKTYPE:
235 return (ppib->pib_ultype == 3) ? TASKTYPE_PM : TASKTYPE_VIO;
236
237 case PIB_PCHCMD:
238 return (ULONG)ppib->pib_pchcmd;
239
240 default:
241 dprintf(("KERNEL32: OSLibGetPIB(%d): Invalid PIB data index\n.", iPIB));
242 DebugInt3();
243 return 0;
244 }
245}
246//******************************************************************************
247//Allocate local thread memory
248//******************************************************************************
249ULONG OSLibAllocThreadLocalMemory(int nrdwords)
250{
251 APIRET rc;
252 PULONG thrdaddr;
253
254 rc = DosAllocThreadLocalMemory(nrdwords, &thrdaddr);
255 if(rc) {
256 dprintf(("DosAllocThreadLocalMemory failed %d", rc));
257 return 0;
258 }
259 return (ULONG)thrdaddr;
260}
261//******************************************************************************
262//******************************************************************************
263char *OSLibStripPath(char *path)
264{
265 /* @@@PH what does this function do ? Strip the path from a FQFN name ? */
266 char *pszFilename;
267 char *pszFilename1;
268
269 pszFilename = strrchr(path, '\\'); /* find rightmost backslash */
270 pszFilename1 = strrchr(path, '/'); /* find rightmost slash */
271 if(pszFilename > pszFilename1 && pszFilename != NULL)
272 return (++pszFilename); /* return pointer to next character */
273
274 if (pszFilename1 != NULL)
275 return (++pszFilename1); /* return pointer to next character */
276
277 return (path); /* default return value */
278}
279//******************************************************************************
280//******************************************************************************
281ULONG OSLibWinInitialize()
282{
283 return (ULONG)WinInitialize(0);
284}
285//******************************************************************************
286//******************************************************************************
287ULONG OSLibWinQueryMsgQueue(ULONG hab)
288{
289 ULONG hmq;
290 APIRET rc;
291 PTIB ptib;
292 PPIB ppib;
293
294 rc = DosGetInfoBlocks(&ptib, &ppib);
295 if(rc != NO_ERROR) {
296 dprintf(("DosGetInfoBlocks failed with rc %d", rc));
297 DebugInt3();
298 return 0;
299 }
300 if(ppib->pib_ultype == 2) {
301 dprintf(("Warning: app type changed back to VIO!!"));
302 ppib->pib_ultype = 3;
303 }
304 hmq = WinQueueFromID(hab, ppib->pib_ulpid, ptib->tib_ptib2->tib2_ultid);
305
306 if(!hmq) {
307 dprintf(("WinQueueFromID %x %x %x proc type %x failed with error %x", hab, ppib->pib_ulpid, ptib->tib_ptib2->tib2_ultid, ppib->pib_ultype, WinGetLastError(hab)));
308
309 hmq = (ULONG)WinCreateMsgQueue((HAB)hab, 0);
310 if(!hmq) {
311 dprintf(("WinCreateMsgQueue failed with error %x", WinGetLastError(hab)));
312 }
313 }
314 return hmq;
315}
316//******************************************************************************
317//******************************************************************************
318ULONG OSLibWinSetCp(ULONG hmq, ULONG codepage)
319{
320 return WinSetCp(hmq, codepage);
321}
322//******************************************************************************
323//******************************************************************************
324ULONG OSLibQueryCountry()
325{
326 COUNTRYCODE Country = {0}; /* Country code info (0 = current country) */
327 COUNTRYINFO CtryInfo = {0}; /* Buffer for country-specific information */
328 ULONG ulInfoLen = 0;
329 APIRET rc = NO_ERROR; /* Return code */
330
331 rc = DosQueryCtryInfo(sizeof(CtryInfo), &Country,
332 &CtryInfo, &ulInfoLen);
333
334 if (rc != NO_ERROR) {
335 return -1;
336 }
337 return CtryInfo.country;
338}
339//******************************************************************************
340//******************************************************************************
341BOOL OSLibDisablePopups()
342{
343 return DosError(FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR) == NO_ERROR;
344}
345//******************************************************************************
346//******************************************************************************
347void OSLibSetBeginLibpath(char *lpszBeginlibpath)
348{
349 PSZ psz = NULL;
350 if (lpszBeginlibpath) {
351 psz = (PSZ)malloc(strlen(lpszBeginlibpath) + 1);
352 CharToOemA(lpszBeginlibpath, psz);
353 }
354 DosSetExtLIBPATH(psz, BEGIN_LIBPATH);
355 if (psz) {
356 free(psz);
357 }
358}
359//******************************************************************************
360//******************************************************************************
361void OSLibQueryBeginLibpath(char *lpszBeginlibpath, int size)
362{
363 DosQueryExtLIBPATH(lpszBeginlibpath, BEGIN_LIBPATH);
364 OemToCharA(lpszBeginlibpath, lpszBeginlibpath);
365}
366//******************************************************************************
367//******************************************************************************
368ULONG OSLibImSetMsgQueueProperty( ULONG hmq, ULONG ulFlag )
369{
370 USHORT sel;
371 APIRET rc;
372
373 if( !pfnImSetMsgQueueProperty )
374 return 1;
375
376 sel = RestoreOS2FS();
377 rc = pfnImSetMsgQueueProperty( hmq, ulFlag );
378 SetFS( sel );
379
380 return rc;
381}
382//******************************************************************************
383//******************************************************************************
384
Note: See TracBrowser for help on using the repository browser.