source: trunk/src/kernel32/oslibmisc.cpp

Last change on this file was 22040, checked in by dmik, 13 years ago

kernel32: Fix Win32ImageBase::matchModName().

As opposed to the declared functionality, it was comparing the name part
of the argument with the full path of the stored module name and this would
obviously not work if the module name were a full path.

One of the failig cases was a frequent attempt to retrieve the resources of the
current executable by doing LoadLibraryEx() with the full executable name.

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