source: trunk/src/win32k/api/api.cpp@ 4996

Last change on this file since 4996 was 4996, checked in by bird, 25 years ago

pre-commit

File size: 14.3 KB
Line 
1/* $Id: api.cpp,v 1.2 2001-01-20 23:51:06 bird Exp $
2 *
3 * API Overload Init and Helper Function.
4 *
5 * Copyright (c) 2001 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define INCL_DOSERRORS
15#define INCL_NOPMAPI
16#define INCL_OS2KRNL_SEM
17#define INCL_OS2KRNL_PTDA
18#define INCL_OS2KRNL_IO
19
20
21/*******************************************************************************
22* Header Files *
23*******************************************************************************/
24#include <os2.h>
25
26#include "devSegDf.h"
27#include "rmalloc.h"
28#include "new.h"
29
30#include <memory.h>
31#include <stdlib.h>
32#include <stddef.h>
33#include <string.h>
34
35#include "log.h"
36#include "OS2Krnl.h"
37#include "dev32.h"
38#include "api.h"
39#include "options.h"
40
41
42
43
44/*******************************************************************************
45* Structures and Typedefs *
46*******************************************************************************/
47typedef struct _MaskArray
48{
49 int cMasks; /* Number of elements in papszMasks. */
50 PSZ * papszMasks; /* Array of module/process masks. */
51} MASKARRAY, *PMASKARRAY;
52
53typedef struct _ApiDataEntry
54{
55 BOOL fEnabled; /* Only enabled if data was found in .INI file! */
56 MASKARRAY ProcessInc; /* Process inclusion rules. */
57 MASKARRAY ProcessExc; /* Process exclusion rules. */
58 MASKARRAY ModuleInc; /* Module inclusion rules. */
59 MASKARRAY ModuleExc; /* Module exclusion rules. */
60} APIDATAENTRY, *PAPIDATAENTRY;
61
62
63/*******************************************************************************
64* Global Variables *
65*******************************************************************************/
66APIDATAENTRY aApiData[API_MAX]; /* Array of api info. */
67PSZ pszFile; /* Pointer to entire file mapping. */
68
69
70/*******************************************************************************
71* Internal Functions *
72*******************************************************************************/
73APIRET apiReadIniFile(PSZ pszIniFile);
74APIRET apiParseIniFile(PSZ pszFile);
75PSZ apiStripIniLine(PSZ pszFile, PSZ * ppszFile);
76int apiInterpretApiNo(PSZ pszSection);
77void apiFreeApiData(PAPIDATAENTRY paNewApiData);
78
79
80
81
82/**
83 * This function will read the ini file from a give disklocation.
84 * @returns OS/2 return code.
85 * @param pszIniFile Full path to the inifile.
86 * @sketch Open the file.
87 * Determin file size.
88 * Allocate memory for the file.
89 * Read the entire file.
90 * Parse the file
91 * Close the file.
92 * @status completely implemented.
93 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
94 * @remark Must hold the loader semaphore before calling this function!
95 */
96APIRET apiReadIniFile(PSZ pszIniFile)
97{
98 SFN sfn;
99 APIRET rc;
100
101 rc = IOSftOpen(pszIniFile,
102 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
103 OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY,
104 (PSFN)SSToDS(&sfn),
105 NULL);
106 if (rc == NO_ERROR)
107 {
108 ULONG cbFile = 0;
109
110 rc = SftFileSize(sfn, &cbFile);
111 if (rc == NO_ERROR)
112 {
113 if (cbFile > 256*1024) /* Max size if 256 KB! */
114 {
115 rc = ERROR_NOT_ENOUGH_MEMORY;
116 kprintf(("apiReadIniFile: Files %s is too large (%d).\n", pszIniFile, cbFile));
117 }
118 else
119 {
120 PSZ pszNewFile = (PSZ)rmalloc((size_t) cbFile + 1);
121 if (pszNewFile)
122 {
123 ULONG cbRead;
124
125 rc = IOSftReadAt(sfn, &cbRead, pszNewFile, 0UL, 0UL);
126 if (rc == NO_ERROR)
127 {
128 memset(pszNewFile + cbRead, 0, (size_t)(cbFile + 1 - cbRead)); /* terminate the file. */
129 rc = apiParseIniFile(pszNewFile);
130 }
131 else
132 kprintf(("apiReadIniFile: Failed to read %s into memory, rc=%d. (size %d)\n", pszIniFile, rc, cbFile));
133
134 if (rc != NO_ERROR)
135 rfree(pszNewFile);
136 }
137 else
138 {
139 rc = ERROR_NOT_ENOUGH_MEMORY;
140 kprintf(("apiReadIniFile: Failed to allocate %d of resident memory.\n", cbFile));
141 }
142 }
143 }
144 else
145 kprintf(("apiReadIniFile: Failed to determin size of %s, rc=%d\n", pszIniFile, rc));
146
147 IOSftClose(sfn);
148 }
149 else
150 kprintf(("apiReadIniFile: Failed to open file %s, rc=%d\n", pszIniFile, rc));
151
152 return rc;
153}
154
155
156/**
157 * Parse the inifile.
158 * @returns OS/2 return code.
159 * @param pszFile Pointer to file mapping.
160 * @sketch
161 * @status completely implemented.
162 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
163 * @remark
164 */
165APIRET apiParseIniFile(PSZ pszFile)
166{
167 PAPIDATAENTRY paNewApiData;
168 PSZ * ppszFile = (PSZ*)SSToDS(&pszFile);
169 PSZ pszLine;
170 APIRET rc;
171
172 /*
173 * Allocate and zero temporary api data structure.
174 */
175 paNewApiData = (PAPIDATAENTRY)rmalloc(sizeof(aApiData));
176 if (paNewApiData == NULL)
177 {
178 kprintf(("apiParseIniFile: failed to allocate temporary struct.\n"));
179 return ERROR_NOT_ENOUGH_MEMORY;
180 }
181 memset(paNewApiData, 0, sizeof(aApiData));
182
183 /*
184 * We'll loop until end of file.
185 * This is a double loop. Outer loop on section level. Inner loop
186 * on Type level.
187 */
188 rc = NO_ERROR;
189 pszLine = apiStripIniLine(pszFile, ppszFile);
190 while (pszLine != NULL && rc == NO_ERROR)
191 {
192 char ch;
193
194 if ((ch = *pszLine) != '\0')
195 {
196 if (ch == '[')
197 {
198 int iApi = apiInterpretApiNo(pszLine);
199 if (iApi >= 0 && iApi < API_MAX)
200 {
201 PMASKARRAY pMaskArray = &paNewApiData[iApi].ModuleExc;
202
203 /*
204 * Enable api data entry.
205 * Get a line.
206 * Check for end-of-file and new section.
207 * Skip empty lines.
208 * Uppercase the line.
209 * If "Type=" line Then Change type entry.
210 * Else Add line to current type entry (default to module exclude).
211 */
212 paNewApiData[iApi].fEnabled = TRUE;
213 while ((pszLine = apiStripIniLine(pszFile, ppszFile)) != NULL
214 && *pszLine != '[')
215 {
216 if (*pszLine == '\0')
217 continue;
218 strupr(pszLine);
219 if (strcmp("TYPE=", pszLine) == 0)
220 {
221 pszLine += 5;
222 if (strstr(pszLine, "PROC"))
223 pMaskArray = strstr(pszLine, "INC")
224 ? &paNewApiData[iApi].ProcessInc
225 : &paNewApiData[iApi].ProcessExc; /* default */
226 else
227 pMaskArray = strstr(pszLine, "INC")
228 ? &paNewApiData[iApi].ModuleInc
229 : &paNewApiData[iApi].ModuleExc; /* default */
230 }
231 else
232 {
233 if (pMaskArray->cMasks % 8 == 0)
234 {
235 void *pv = rrealloc(pMaskArray->papszMasks, 8 + pMaskArray->cMasks);
236 if (pv == NULL)
237 {
238 rc = ERROR_NOT_ENOUGH_MEMORY;
239 kprintf(("apiParseIniFile: Failed to allocate more mask array memory. %c masks\n", pMaskArray->cMasks));
240 break;
241 }
242 pMaskArray->papszMasks = (PSZ*)pv;
243 }
244 pMaskArray->papszMasks[pMaskArray->cMasks++] = pszLine;
245 }
246 } /* inner loop */
247 }
248 else
249 {
250 kprintf(("apiParseIniFile: bogus api no.%d (%s)\n", iApi, pszLine));
251 pszLine = apiStripIniLine(pszFile, ppszFile);
252 }
253 }
254 else
255 {
256 kprintf(("apiParseIniFile: bogus line encountered: %s\n", pszLine));
257 pszLine = apiStripIniLine(pszFile, ppszFile);
258 }
259 }
260 else
261 pszLine = apiStripIniLine(pszFile, ppszFile);
262 } /* outer loop */
263
264
265 /*
266 * If we were successfull we'll replace the existing api data with
267 * the data we've just read.
268 * (TODO: Not sure (ie. quite sure) if we need some kind of serialization here...)
269 * If not we'll free any used memory before returning failure.
270 */
271 if (rc == NO_ERROR)
272 {
273 /* add spin lock */
274 apiFreeApiData(&aApiData[0]);
275 memcpy(&aApiData[0], paNewApiData, sizeof(aApiData));
276 /* remove spin lock */
277 }
278 else
279 apiFreeApiData(paNewApiData);
280 rfree(paNewApiData);
281
282 return rc;
283}
284
285
286
287/**
288 * Strips and extract a line advancing the *ppszFile pointer to
289 * the next line. Comments are also stripped.
290 * @returns Pointer to line. NULL if end of file.
291 * @param pszFile Pointer to line.
292 * @param ppszFile Pointer to pointer variable.
293 * @sketch
294 * @status completly implemented.
295 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
296 */
297PSZ apiStripIniLine(PSZ pszFile, PSZ * ppszFile)
298{
299 PSZ pszComment;
300 PSZ pszLine;
301 char ch;
302
303 /*
304 * If end of file Then return NULL.
305 */
306 if (*pszFile)
307 return NULL;
308
309 /*
310 * Strip start of line.
311 */
312 while ((ch = *pszFile) == ' ' || ch == '\t')
313 pszFile++;
314 pszLine = pszFile;
315
316 /*
317 * Look for the line end and any evt. comment (starts with a ';').
318 */
319 pszComment = NULL;
320 while ((ch = *pszFile) != '\r' && ch != '\n' && ch != '\0')
321 {
322 if (ch == ';')
323 pszComment = pszFile;
324 pszFile++;
325 }
326
327 /*
328 * Update pszComment with the line end if not already set (we'll
329 * use this pointer to right strip the line).
330 * If not last line, then terminate the line.
331 * Skip return and newline characters to position the *ppszFile pointer
332 * at the next line.
333 * Update the next line pointer.
334 */
335 if (pszComment == NULL)
336 pszComment = pszFile;
337 if (ch != '\0')
338 {
339 *pszFile = '\0';
340 while ((ch = *pszFile) == '\r' || ch == '\n')
341 pszFile++;
342 }
343 *ppszFile = pszFile;
344
345 /*
346 * Right strip the line (starts with pszComment).
347 */
348 pszComment--;
349 while ((ch = *pszComment) == ' ' || ch == '\t')
350 pszComment--;
351 pszComment[1] = '\0';
352
353 return pszLine;
354}
355
356
357/**
358 * Reads the section header '[<ApiNbr]' and translates it into an
359 * api index (into aApiData). Range is not checked.
360 * @returns API index. -1 on error. Check range!
361 * @param pszSection Pointer to the section header string.
362 * Assumes that it's pointing to the '['.
363 * @sketch Skip '['.
364 * Skip blanks.
365 * Convert decimal number string and return it.
366 * @status completely implemented.
367 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
368 * @remark Layz, we only read '[n' no checking for the ending ']'.
369 */
370int apiInterpretApiNo(PSZ pszSection)
371{
372 int iApi = 0;
373
374 pszSection++; /* skip '[' */
375 if (*pszSection < '0' || *pszSection > '9')
376 return -1;
377
378 while (*pszSection == ' ' || *pszSection == '\t')
379 pszSection++;
380
381 while (*pszSection >= '0' || *pszSection <= '9')
382 {
383 iApi = (iApi * 10) + *pszSection - '0';
384 pszSection++;
385 }
386
387 return iApi;
388}
389
390
391/**
392 * Frees internal data in a api data structure.
393 * @param paNewApiData Pointer to api data table.
394 * @sketch Loop thru all api entries and free mask array pointers.
395 * @status Completely implemented.
396 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
397 * @remark Any serialization is not my problem.
398 */
399void apiFreeApiData(PAPIDATAENTRY paNewApiData)
400{
401 int i;
402
403 for (i = 0; i < API_MAX; i++)
404 {
405 if (paNewApiData[i].ProcessInc.cMasks)
406 rfree(paNewApiData[i].ProcessInc.papszMasks);
407 if (paNewApiData[i].ProcessExc.cMasks)
408 rfree(paNewApiData[i].ProcessExc.papszMasks);
409 if (paNewApiData[i].ModuleInc.cMasks)
410 rfree(paNewApiData[i].ModuleInc.papszMasks);
411 if (paNewApiData[i].ModuleExc.cMasks)
412 rfree(paNewApiData[i].ModuleExc.papszMasks);
413 }
414}
415
416
417
418BOOL _Optlink APIQueryEnabled(int iApi, USHORT usCS, LONG ulEIP)
419{
420 PAPIDATAENTRY pEntry;
421
422 /*
423 * Check if these enhancements are switched off globally.
424 */
425 if (isApiEnhDisabled())
426 return FALSE;
427
428 /*
429 * Aquire read lock - TODO.
430 */
431
432
433 /*
434 * Get data entry pointer.
435 * Check if entry is enabled.
436 */
437 pEntry = &aApiInfo[iApi];
438 if (pEntry->fEnabled)
439 {
440 CHAR szName[CCHMAXPATH];
441
442 }
443 else
444 fRet = FALSE;
445
446
447 /*
448 * Release read lock - TODO.
449 */
450
451
452 return fRet;
453}
454
455
456
457/**
458 * Init The Api Overloading SubSystem.
459 * @returns OS/2 return code.
460 * @sketch Find Ini file location.
461 * Read the inifile and there by initiate the aApiData strcut.
462 * @status completly implemented.
463 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
464 */
465APIRET _Optlink APIInit(void)
466{
467 APIRET rc;
468
469 rc = apiReadIniFile(&szWin32kIni[0]);
470
471 return rc;
472}
473
Note: See TracBrowser for help on using the repository browser.