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

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

pre-commit

File size: 29.4 KB
Line 
1/* $Id: api.cpp,v 1.4 2001-01-22 08:06:38 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_ALL
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <os2.h>
23
24#include "devSegDf.h"
25#include "rmalloc.h"
26#include "new.h"
27
28#include <memory.h>
29#include <stdlib.h>
30#include <stddef.h>
31#include <string.h>
32
33#include "log.h"
34#include "OS2Krnl.h"
35#include "ldrCalls.h"
36#include "dev32.h"
37#include "api.h"
38#include "options.h"
39#include "locks.h"
40#include "sprintf.h"
41
42
43/*******************************************************************************
44* Defined Constants And Macros *
45*******************************************************************************/
46#if 1//ndef RING0
47#include <stdio.h>
48#define IOSftClose(hFile) DosClose(hFile)
49#define rmalloc malloc
50#define realloc realloc
51#define rfree free
52#undef kprintf
53#define kprintf(a) printf a
54#endif
55
56
57/*******************************************************************************
58* Structures and Typedefs *
59*******************************************************************************/
60typedef struct _MaskArray
61{
62 int cMasks; /* Number of elements in papszMasks. */
63 PSZ * papszMasks; /* Array of module/process masks. */
64} MASKARRAY, *PMASKARRAY;
65
66typedef struct _ApiDataEntry
67{
68 BOOL fEnabled; /* Only enabled if data was found in .INI file! */
69 MASKARRAY ProcessInc; /* Process inclusion rules. */
70 MASKARRAY ProcessExc; /* Process exclusion rules. */
71 MASKARRAY ModuleInc; /* Module inclusion rules. */
72 MASKARRAY ModuleExc; /* Module exclusion rules. */
73} APIDATAENTRY, *PAPIDATAENTRY;
74
75
76/*******************************************************************************
77* Global Variables *
78*******************************************************************************/
79APIDATAENTRY aApiData[API_CENTRIES]; /* Array of api info. */
80PSZ pszFile; /* Pointer to entire file mapping. */
81RWLOCK ApiInfoRWLock; /* Read/Write lock for api data. */
82
83
84/*******************************************************************************
85* Internal Functions *
86*******************************************************************************/
87APIRET apiReadIniFile(PSZ pszIniFile);
88APIRET apiParseIniFile(PSZ pszFile);
89PSZ apiStripIniLine(PSZ pszFile, PSZ * ppszFile);
90int apiInterpretApiNo(PSZ pszSection);
91void apiFreeApiData(PAPIDATAENTRY paNewApiData);
92void apiSortApiData(PAPIDATAENTRY paApiData);
93void apiSortMaskArray(PMASKARRAY pMasks);
94BOOL apiFindNameInMaskArray(PSZ pszName, PMASKARRAY pMasks);
95APIRET apiGetProccessName(PSZ pszName);
96APIRET apiGetModuleName(PSZ pszName, USHORT usCS, ULONG ulEIP);
97#if 1 //ndef RING0
98APIRET apiWriteIniFile(PSZ pszIniFile);
99APIRET apiWriteMasks(SFN sfn, PULONG poff, PMASKARRAY pMasks, PSZ pszType, BOOL fEnabled);
100APIRET apiWriteLine(SFN sfn, PULONG poff, PSZ pszString);
101#endif
102
103
104/**
105 * This function will read the ini file from a give disklocation.
106 * @returns OS/2 return code.
107 * @param pszIniFile Full path to the inifile.
108 * @sketch Open the file.
109 * Determin file size.
110 * Allocate memory for the file.
111 * Read the entire file.
112 * Parse the file
113 * Close the file.
114 * @status completely implemented.
115 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
116 * @remark Must hold the loader semaphore before calling this function!
117 */
118APIRET apiReadIniFile(PSZ pszIniFile)
119{
120 SFN sfn;
121 APIRET rc;
122
123 rc = IOSftOpen(pszIniFile,
124 OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
125 OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY,
126 (PSFN)SSToDS(&sfn),
127 NULL);
128 if (rc == NO_ERROR)
129 {
130 ULONG cbFile = 0;
131
132 rc = SftFileSize(sfn, &cbFile);
133 if (rc == NO_ERROR)
134 {
135 if (cbFile > 256*1024) /* Max size if 256 KB! */
136 {
137 rc = ERROR_NOT_ENOUGH_MEMORY;
138 kprintf(("apiReadIniFile: Files %s is too large (%d).\n", pszIniFile, cbFile));
139 }
140 else
141 {
142 PSZ pszNewFile = (PSZ)rmalloc((size_t) cbFile + 1);
143 if (pszNewFile)
144 {
145 ULONG cbRead = cbFile;
146
147 rc = IOSftReadAt(sfn, &cbRead, pszNewFile, 0UL, 0UL);
148 if (rc == NO_ERROR)
149 {
150 memset(pszNewFile + cbRead, 0, (size_t)(cbFile + 1 - cbRead)); /* terminate the file. */
151 rc = apiParseIniFile(pszNewFile);
152 }
153 else
154 kprintf(("apiReadIniFile: Failed to read %s into memory, rc=%d. (size %d)\n", pszIniFile, rc, cbFile));
155
156 if (rc != NO_ERROR)
157 rfree(pszNewFile);
158 }
159 else
160 {
161 rc = ERROR_NOT_ENOUGH_MEMORY;
162 kprintf(("apiReadIniFile: Failed to allocate %d of resident memory.\n", cbFile));
163 }
164 }
165 }
166 else
167 kprintf(("apiReadIniFile: Failed to determin size of %s, rc=%d\n", pszIniFile, rc));
168
169 IOSftClose(sfn);
170 }
171 else
172 kprintf(("apiReadIniFile: Failed to open file %s, rc=%d\n", pszIniFile, rc));
173
174 return rc;
175}
176
177
178/**
179 * Parse the inifile.
180 * @returns OS/2 return code.
181 * @param pszFile Pointer to file mapping.
182 * @sketch
183 * @status completely implemented.
184 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
185 * @remark
186 */
187APIRET apiParseIniFile(PSZ pszFile)
188{
189 PAPIDATAENTRY paNewApiData;
190 PSZ * ppszFile = (PSZ*)SSToDS(&pszFile);
191 PSZ pszLine;
192 APIRET rc;
193
194 /*
195 * Allocate and zero temporary api data structure.
196 */
197 paNewApiData = (PAPIDATAENTRY)rmalloc(sizeof(aApiData));
198 if (paNewApiData == NULL)
199 {
200 kprintf(("apiParseIniFile: failed to allocate temporary struct.\n"));
201 return ERROR_NOT_ENOUGH_MEMORY;
202 }
203 memset(paNewApiData, 0, sizeof(aApiData));
204
205 /*
206 * We'll loop until end of file.
207 * This is a double loop. Outer loop on section level. Inner loop
208 * on Type level.
209 */
210 rc = NO_ERROR;
211 pszLine = apiStripIniLine(pszFile, ppszFile);
212 while (pszLine != NULL && rc == NO_ERROR)
213 {
214 char ch;
215
216 if ((ch = *pszLine) != '\0')
217 {
218 if (ch == '[')
219 {
220 int iApi = apiInterpretApiNo(pszLine);
221 if (iApi >= 0 && iApi < API_CENTRIES)
222 {
223 PMASKARRAY pMaskArray = &paNewApiData[iApi].ModuleExc;
224
225 /*
226 * Enable api data entry.
227 * Get a line.
228 * Check for end-of-file and new section.
229 * Skip empty lines.
230 * Uppercase the line.
231 * If "Type=" line Then Change type entry.
232 * Else Add line to current type entry (default to module exclude).
233 */
234 paNewApiData[iApi].fEnabled = TRUE;
235 while ((pszLine = apiStripIniLine(pszFile, ppszFile)) != NULL
236 && *pszLine != '[')
237 {
238 if (*pszLine == '\0')
239 continue;
240 strupr(pszLine);
241 if (strcmp("TYPE=", pszLine) == 0)
242 {
243 pszLine += 5;
244 if (strstr(pszLine, "PROC"))
245 pMaskArray = strstr(pszLine, "INC")
246 ? &paNewApiData[iApi].ProcessInc
247 : &paNewApiData[iApi].ProcessExc; /* default */
248 else
249 pMaskArray = strstr(pszLine, "INC")
250 ? &paNewApiData[iApi].ModuleInc
251 : &paNewApiData[iApi].ModuleExc; /* default */
252 if (strstr(pszLine, "DIS"))
253 paNewApiData[iApi].fEnabled = FALSE;
254 }
255 else
256 {
257 if (pMaskArray->cMasks % 8 == 0)
258 {
259 void *pv = rrealloc(pMaskArray->papszMasks, 8 + pMaskArray->cMasks);
260 if (pv == NULL)
261 {
262 rc = ERROR_NOT_ENOUGH_MEMORY;
263 kprintf(("apiParseIniFile: Failed to allocate more mask array memory. %c masks\n", pMaskArray->cMasks));
264 break;
265 }
266 pMaskArray->papszMasks = (PSZ*)pv;
267 }
268 pMaskArray->papszMasks[pMaskArray->cMasks++] = pszLine;
269 }
270 } /* inner loop */
271 }
272 else
273 {
274 kprintf(("apiParseIniFile: bogus api no.%d (%s)\n", iApi, pszLine));
275 pszLine = apiStripIniLine(pszFile, ppszFile);
276 }
277 }
278 else
279 {
280 kprintf(("apiParseIniFile: bogus line encountered: %s\n", pszLine));
281 pszLine = apiStripIniLine(pszFile, ppszFile);
282 }
283 }
284 else
285 pszLine = apiStripIniLine(pszFile, ppszFile);
286 } /* outer loop */
287
288
289 /*
290 * If we were successfull we'll replace the existing api data with
291 * the data we've just read.
292 * If not we'll free any used memory before returning failure.
293 */
294 if (rc == NO_ERROR)
295 {
296 apiSortApiData(paNewApiData);
297 RWLockAcquireWrite(&ApiInfoRWLock);
298 apiFreeApiData(&aApiData[0]);
299 memcpy(&aApiData[0], paNewApiData, sizeof(aApiData));
300 RWLockReleaseWrite(&ApiInfoRWLock);
301 }
302 else
303 apiFreeApiData(paNewApiData);
304 rfree(paNewApiData);
305
306 return rc;
307}
308
309
310
311/**
312 * Strips and extract a line advancing the *ppszFile pointer to
313 * the next line. Comments are also stripped.
314 * @returns Pointer to line. NULL if end of file.
315 * @param pszFile Pointer to line.
316 * @param ppszFile Pointer to pointer variable.
317 * @sketch
318 * @status completly implemented.
319 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
320 */
321PSZ apiStripIniLine(PSZ pszFile, PSZ * ppszFile)
322{
323 PSZ pszComment;
324 PSZ pszLine;
325 char ch;
326
327 /*
328 * If end of file Then return NULL.
329 */
330 if (*pszFile)
331 return NULL;
332
333 /*
334 * Strip start of line.
335 */
336 while ((ch = *pszFile) == ' ' || ch == '\t')
337 pszFile++;
338 pszLine = pszFile;
339
340 /*
341 * Look for the line end and any evt. comment (starts with a ';').
342 */
343 pszComment = NULL;
344 while ((ch = *pszFile) != '\r' && ch != '\n' && ch != '\0')
345 {
346 if (ch == ';')
347 pszComment = pszFile;
348 pszFile++;
349 }
350
351 /*
352 * Update pszComment with the line end if not already set (we'll
353 * use this pointer to right strip the line).
354 * If not last line, then terminate the line.
355 * Skip return and newline characters to position the *ppszFile pointer
356 * at the next line.
357 * Update the next line pointer.
358 */
359 if (pszComment == NULL)
360 pszComment = pszFile;
361 if (ch != '\0')
362 {
363 *pszFile = '\0';
364 while ((ch = *pszFile) == '\r' || ch == '\n')
365 pszFile++;
366 }
367 *ppszFile = pszFile;
368
369 /*
370 * Right strip the line (starts with pszComment).
371 */
372 pszComment--;
373 while ((ch = *pszComment) == ' ' || ch == '\t')
374 pszComment--;
375 pszComment[1] = '\0';
376
377 return pszLine;
378}
379
380
381/**
382 * Reads the section header '[<ApiNbr]' and translates it into an
383 * api index (into aApiData). Range is not checked.
384 * @returns API index. -1 on error. Check range!
385 * @param pszSection Pointer to the section header string.
386 * Assumes that it's pointing to the '['.
387 * @sketch Skip '['.
388 * Skip blanks.
389 * Convert decimal number string and return it.
390 * @status completely implemented.
391 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
392 * @remark Layz, we only read '[n' no checking for the ending ']'.
393 */
394int apiInterpretApiNo(PSZ pszSection)
395{
396 int iApi = 0;
397
398 pszSection++; /* skip '[' */
399 if (*pszSection < '0' || *pszSection > '9')
400 return -1;
401
402 while (*pszSection == ' ' || *pszSection == '\t')
403 pszSection++;
404
405 while (*pszSection >= '0' || *pszSection <= '9')
406 {
407 iApi = (iApi * 10) + *pszSection - '0';
408 pszSection++;
409 }
410
411 return iApi;
412}
413
414
415/**
416 * Sort the entire api data structure.
417 * @param paApiData Pointer to api data to sort.
418 * @sketch Loop thru all entries and sort all four mask arrays.
419 * @status completely implemented.
420 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
421 * @remark See apiSortMaskArray.
422 */
423void apiSortApiData(PAPIDATAENTRY paApiData)
424{
425 int i;
426
427 for (i = 0; i < API_CENTRIES; i++)
428 {
429 apiSortMaskArray(&paApiData[i].ProcessInc);
430 apiSortMaskArray(&paApiData[i].ProcessExc);
431 apiSortMaskArray(&paApiData[i].ModuleInc);
432 apiSortMaskArray(&paApiData[i].ModuleExc);
433 }
434}
435
436
437/**
438 * Sorts the content of an mask array.
439 * Duplicates are removed.
440 * @param pMasks Pointer to a mask array structure.
441 * @sketch Use bouble sort.
442 * @status partially implemented.
443 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
444 * @remark Duplicate submasks aren't tested for.
445 * example: "DOSCALL1.DLL" is equal to "DOS*"
446 */
447void apiSortMaskArray(PMASKARRAY pMasks)
448{
449 int i;
450 PSZ pszTmp;
451
452 do
453 {
454 for (i = 1, pszTmp = NULL; i < pMasks->cMasks; i++)
455 {
456 int iDiff = strcmp(pMasks->papszMasks[i], pMasks->papszMasks[i-1]);
457 if (iDiff == 0)
458 { /* remove entry */
459 memmove(&pMasks->papszMasks[i], &pMasks->papszMasks[i+1],
460 (pMasks->cMasks - i - 1) * sizeof(pMasks->papszMasks[0]));
461 i--;
462 }
463 else if (iDiff < 0)
464 { /* Swap entries. */
465 PSZ pszTmp = pMasks->papszMasks[i];
466 pMasks->papszMasks[i] = pMasks->papszMasks[i-1];
467 pMasks->papszMasks[i-1] = pszTmp;
468 }
469 }
470 } while (pszTmp != NULL);
471}
472
473
474/**
475 * Frees internal data in a api data structure.
476 * @param paApiData Pointer to api data table.
477 * @sketch Loop thru all api entries and free mask array pointers.
478 * @status Completely implemented.
479 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
480 * @remark Any serialization is not my problem.
481 */
482void apiFreeApiData(PAPIDATAENTRY paApiData)
483{
484 int i;
485
486 for (i = 0; i < API_CENTRIES; i++)
487 {
488 if (paApiData[i].ProcessInc.cMasks)
489 rfree(paApiData[i].ProcessInc.papszMasks);
490 if (paApiData[i].ProcessExc.cMasks)
491 rfree(paApiData[i].ProcessExc.papszMasks);
492 if (paApiData[i].ModuleInc.cMasks)
493 rfree(paApiData[i].ModuleInc.papszMasks);
494 if (paApiData[i].ModuleExc.cMasks)
495 rfree(paApiData[i].ModuleExc.papszMasks);
496 }
497}
498
499#if 1 //ndef RING0
500/**
501 * Write the internal data to a fresh ini file.
502 * This is a service routine used by the configuration program.
503 * @returns OS/2 return code.
504 * @param pszIniFile Pointer to the name of the ini file.
505 * @sketch
506 * @status
507 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
508 * @remark
509 */
510APIRET apiWriteIniFile(PSZ pszIniFile)
511{
512 SFN sfn;
513 APIRET rc;
514
515
516 rc = IOSftOpen(pszIniFile,
517 OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS,
518 OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_WRITEONLY,
519 (PSFN)SSToDS(&sfn),
520 NULL);
521 if (rc == NO_ERROR)
522 {
523 int i;
524 ULONG off = 0;
525 PULONG poff = (PULONG)SSToDS(&off);
526 char sz[80];
527 PSZ psz = (PSZ)SSToDS(&sz[0]);
528
529 for (i = 0; i < API_CENTRIES; i++)
530 {
531 sprintf(psz, "[%d]", i);
532 if ((rc = apiWriteLine(sfn, poff, psz)) != NO_ERROR)
533 break;
534
535 rc = apiWriteMasks(sfn, poff, &aApiData[i].ProcessExc, "Process Exclude", aApiData[i].fEnabled);
536 if (rc != NO_ERROR)
537 break;
538
539 if (aApiData[i].ProcessInc.cMasks)
540 {
541 rc = apiWriteMasks(sfn, poff, &aApiData[i].ProcessInc, "Process Include", TRUE);
542 if (rc != NO_ERROR)
543 break;
544 }
545
546 if (aApiData[i].ModuleExc.cMasks)
547 {
548 rc = apiWriteMasks(sfn, poff, &aApiData[i].ModuleExc, "Module Exclude", TRUE);
549 if (rc != NO_ERROR)
550 break;
551 }
552
553 if (aApiData[i].ModuleInc.cMasks)
554 {
555 rc = apiWriteMasks(sfn, poff, &aApiData[i].ModuleInc, "Module Include", TRUE);
556 if (rc != NO_ERROR)
557 break;
558 }
559 rc = apiWriteLine(sfn, poff, "");
560 }
561
562 IOSftClose(sfn);
563 }
564 else
565 kprintf(("apiWriteIniFile: Failed open %s for write. rc=%d\n", pszIniFile, rc));
566
567 return rc;
568}
569
570
571/**
572 * Writes the content of a mask array to the ini file.
573 * @returns OS/2 return code.
574 * @param sfn File handle. (sfn = System File Number)
575 * @param poff Pointer to the file offset variable.
576 * (We're required to keep track of the current offset due to
577 * the IOSftWriteAt function.)
578 * @param pMasks Pointer to the mask array struct to be written to file.
579 * @param pszType Type string for these masks.
580 * @param fEnabled If the api entry is enabled or not.
581 * @status completely implemented.
582 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
583 */
584APIRET apiWriteMasks(SFN sfn, PULONG poff, PMASKARRAY pMasks, PSZ pszType, BOOL fEnabled)
585{
586 char sz[48];
587 PSZ psz = (PSZ)SSToDS(&sz[0]);
588 APIRET rc = NO_ERROR;
589 int i;
590
591 if (fEnabled)
592 sprintf(psz, "Type=%s", pszType);
593 else
594 sprintf(psz, "Type=%s Disabled", pszType);
595 rc = apiWriteLine(sfn, poff, psz);
596 if (rc != NO_ERROR)
597 return rc;
598
599 for (i = 0, rc = NO_ERROR; rc == NO_ERROR && i < pMasks->cMasks; i++)
600 rc = apiWriteLine(sfn, poff, pMasks->papszMasks[i]);
601
602 return rc;
603}
604
605
606/**
607 * Writes a string to the file and advances to the next line.
608 * @returns OS/2 return code.
609 * @param sfn File handle. (sfn = System File Number)
610 * @param poff Pointer to the file offset variable.
611 * (We're required to keep track of the current offset due to
612 * the IOSftWriteAt function.)
613 * @param pszString String to be written.
614 * @status completely implemented.
615 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
616 */
617APIRET apiWriteLine(SFN sfn, PULONG poff, PSZ pszString)
618{
619 ULONG cb = strlen(pszString);
620 APIRET rc;
621
622 rc = IOSftWriteAt(sfn, &cb, pszString, 0UL, *poff);
623 if (rc == NO_ERROR)
624 {
625 *poff += cb;
626 cb = 2;
627 rc = IOSftWriteAt(sfn, &cb, "\r\n", 0UL, *poff);
628 if (rc == NO_ERROR)
629 *poff += cb;
630 }
631
632 return rc;
633}
634
635
636/**
637 * Opens a given file.
638 * @returns NO_ERROR on success. OS/2 error code on error.
639 * @param pszFilename Pointer to filename.
640 * @param flOpenFlags Open flags. (similar to DosOpen)
641 * @param flOpenMode Open mode flags. (similar to DosOpen)
642 * @param phFile Pointer to filehandle.
643 * @param pulsomething 16-bit near (?) pointer to a variable - unknown. NULL is allowed. EA?
644 */
645APIRET KRNLCALL IOSftOpen(
646 PSZ pszFilename,
647 ULONG flOpenFlags,
648 ULONG flOpenMode,
649 PSFN phFile,
650 PULONG pulsomething
651 )
652{
653 APIRET rc;
654 ULONG ulAction = 0;
655
656 rc = DosOpen(pszFilename, phFile, &ulAction, 0, 0, flOpenFlags, flOpenMode, NULL);
657
658 pulsomething = pulsomething;
659 return rc;
660}
661
662/**
663 * Read at a given offset in the a file.
664 * @returns NO_ERROR on success. OS/2 error code on error.
665 * @param hFile File handle - System File Number.
666 * @param pcbActual Pointer to variable which upon input holds the number
667 * of bytes to read, on output the actual number of bytes read.
668 * @param pvBuffer Pointer to the read buffer.
669 * @param flFlags Read flags?
670 * @param ulOffset File offset to read from. (0=start of file)
671 */
672APIRET KRNLCALL IOSftReadAt(
673 SFN hFile,
674 PULONG pcbActual,
675 PVOID pvBuffer,
676 ULONG flFlags,
677 ULONG ulOffset)
678{
679 APIRET rc;
680 ULONG ul;
681 rc = DosSetFilePtr(hFile, ulOffset, FILE_BEGIN, &ul);
682 if (rc == NO_ERROR)
683 rc = DosRead(hFile, pvBuffer, *pcbActual, pcbActual);
684 flFlags = flFlags;
685 return rc;
686}
687
688
689/**
690 * Write at a given offset in the a file.
691 * @returns NO_ERROR on success. OS/2 error code on error.
692 * @param hFile File handle - System File Number.
693 * @param pcbActual Pointer to variable which upon input holds the number
694 * of bytes to write, on output the actual number of bytes write.
695 * @param pvBuffer Pointer to the write buffer.
696 * @param flFlags Read flags?
697 * @param ulOffset File offset to write from. (0=start of file)
698 */
699APIRET KRNLCALL IOSftWriteAt(
700 SFN hFile,
701 PULONG pcbActual,
702 PVOID pvBuffer,
703 ULONG flFlags,
704 ULONG ulOffset)
705{
706 APIRET rc;
707 ULONG ul;
708 rc = DosSetFilePtr(hFile, ulOffset, FILE_BEGIN, &ul);
709 if (rc == NO_ERROR)
710 rc = DosWrite(hFile, pvBuffer, *pcbActual, pcbActual);
711 flFlags = flFlags;
712 return rc;
713}
714
715/**
716 * Gets the filesize.
717 * @returns NO_ERROR on success; OS/2 error code on error.
718 * @param hFile File handle - System File Number.
719 * @param pcbFile Pointer to ULONG which will hold the file size upon return.
720 */
721APIRET KRNLCALL SftFileSize(
722 SFN hFile,
723 PULONG pcbFile)
724{
725 FILESTATUS3 fsts3;
726 APIRET rc;
727
728 rc = DosQueryFileInfo(hFile, FIL_STANDARD, &fsts3, sizeof(fsts3));
729 if (rc == NO_ERROR)
730 *pcbFile = fsts3.cbFile;
731 return rc;
732}
733
734#endif
735
736/**
737 * Searches a mask array if there is any match for the given name.
738 * @returns TRUE if found.
739 * FALSE if not found.
740 * @param pszName Pointer to name.
741 * @param pMasks Pointer to mask array.
742 * @sketch
743 * @status
744 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
745 * @remark
746 */
747BOOL apiFindNameInMaskArray(PSZ pszName, PMASKARRAY pMasks)
748{
749 return FALSE;
750}
751
752
753#ifdef RING0
754/**
755 * Get the current process executable name.
756 * @returns OS/2 return code.
757 * @param pszName Pointer to output name buffer.
758 * @sketch Get current ptda.
759 * Get module handle (hmte) from current ptda.
760 * Get pmte and smte from the hmte.
761 * Check if there is any path (full filename).
762 * Parse out filename+ext from full filename and copy it to pszName.
763 * return.
764 * @status completely implemented.
765 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
766 */
767APIRET apiGetProccessName(PSZ pszName)
768{
769 PPTDA pPTDA = ptdaGetCur();
770 if (pPTDA)
771 {
772 HMTE hmte = ptdaGet_ptda_module(pPTDA);
773 if (hmte)
774 {
775 PMTE pmte = ldrASMpMTEFromHandle(hmte);
776 PSMTE psmte;
777 if ( pmte
778 && (psmte = pmte->mte_swapmte)
779 && psmte->smte_path
780 && *psmte->smte_path)
781 {
782 /*
783 * Get executable name from swap mte.
784 * We parse out the filename+ext and copies it to the output buffer.
785 */
786 PCHAR psz;
787 PCHAR pszExt;
788 ldrGetFileName2(psmte->smte_path, (PCHAR*)SSToDS(&psz), (PCHAR*)SSToDS(&pszExt));
789 if (!psz) psz = psmte->smte_path;
790 strcpy(pszName, psz);
791 return NO_ERROR;
792 }
793 else
794 kprintf(("apiGetProcessName: failed to get pmte(0x%08x) from hmte(0x%04x) or no path.\n", pmte, hmte));
795 }
796 else
797 kprintf(("apiGetProcessName: This PTDA has no module handle. (pptda=0x%08x, hptda=0x%04)\n", pPTDA, ptdaGet_ptda_handle(pPTDA)));
798 }
799 else
800 kprintf(("apiGetProcessName: No current PTDA!\n"));
801
802 return ERROR_INVALID_PARAMETER;
803}
804
805/**
806 * Gets the module name from a given CS:EIP pair.
807 * @returns OS/2 return code.
808 * @param pszName Output buffer.
809 * @param usCS CS (code segment).
810 * @param ulEIP EIP (Extended Instruction Pointer).
811 * @sketch Get hmte from cs:eip.
812 * Get pmte and smte from the hmte.
813 * Check if there is any path (full filename).
814 * Parse out filename+ext from full filename and copy it to pszName.
815 * return.
816 * @status completely implemented.
817 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
818 */
819APIRET apiGetModuleName(PSZ pszName, USHORT usCS, ULONG ulEIP)
820{
821 HMTE hmte = VMGetOwner(usCS, ulEIP);
822 if (hmte)
823 {
824 PMTE pmte = ldrASMpMTEFromHandle(hmte);
825 PSMTE psmte;
826 if ( pmte
827 && (psmte = pmte->mte_swapmte)
828 && psmte->smte_path
829 && *psmte->smte_path)
830 {
831 /*
832 * Get executable name from swap mte.
833 * We parse out the filename+ext and copies it to the output buffer.
834 */
835 PCHAR psz;
836 PCHAR pszExt;
837 ldrGetFileName2(psmte->smte_path, (PCHAR*)SSToDS(&psz), (PCHAR*)SSToDS(&pszExt));
838 if (!psz) psz = psmte->smte_path;
839 strcpy(pszName, psz);
840 return NO_ERROR;
841 }
842 else
843 kprintf(("apiGetModuleName: failed to get pmte(0x%08x) from hmte(0x%04x) or no path.\n", pmte, hmte));
844 }
845 else
846 kprintf(("apiGetModuleName: failed to get hmte from cs=%04x eip=%08x\n", usCS, ulEIP));
847
848 /*
849 * We failed.
850 */
851 return ERROR_INVALID_PARAMETER;
852}
853
854
855
856/**
857 * Checks if an api enhancement is enabled for this process or/and module.
858 * Exclusion lists rulez over inclusion.
859 * Excluded processes rulez over included modules.
860 * @returns TRUE (!0) if it's enabled.
861 * FALSE (0) if it's disabled.
862 * @param iApi Api data id/index.
863 * @param usCS CS of the API caller.
864 * @param ulEIP EIP of the API caller.
865 * @sketch
866 * @status
867 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
868 * @remark
869 */
870BOOL _Optlink APIQueryEnabled(int iApi, USHORT usCS, LONG ulEIP)
871{
872 PAPIDATAENTRY pEntry;
873
874 /*
875 * Check if these enhancements are switched off globally.
876 */
877 if (isApiEnhDisabled())
878 return FALSE;
879
880 /*
881 * Aquire read lock.
882 */
883 RWLockAcquireRead(&ApiInfoRWLock);
884
885 /*
886 * Get data entry pointer.
887 * Check if entry is enabled.
888 */
889 BOOL fRet = FALSE;
890 pEntry = &aApiData[iApi];
891 if (pEntry->fEnabled)
892 {
893 CHAR szName[CCHMAXPATH];
894 PSZ pszName = (PSZ)SSToDS(&szName[0]);
895
896 if (pEntry->ProcessExc.cMasks > 0 || pEntry->ProcessInc.cMasks > 0)
897 {
898 if (!apiGetProccessName(pszName))
899 { /* TODO - fix this priority - it's probably wrong */
900 if (pEntry->ProcessExc.cMasks)
901 fRet = !apiFindNameInMaskArray(pszName, &pEntry->ProcessExc);
902 else if (pEntry->ProcessInc.cMasks)
903 fRet = apiFindNameInMaskArray(pszName, &pEntry->ProcessInc);
904 }
905 }
906
907 if ( !pEntry->ProcessExc.cMasks
908 && !fRet
909 && (pEntry->ModuleExc.cMasks > 0 || pEntry->ModuleInc.cMasks > 0))
910 {
911 if (!apiGetModuleName(pszName, usCS, ulEIP))
912 { /* TODO - fix this priority - it's probably wrong */
913 if (pEntry->ModuleExc.cMasks)
914 fRet = !apiFindNameInMaskArray(pszName, &pEntry->ModuleExc);
915 else if (pEntry->ProcessInc.cMasks)
916 fRet = apiFindNameInMaskArray(pszName, &pEntry->ModuleInc);
917 }
918 }
919 }
920
921
922 /*
923 * Release read lock.
924 */
925 RWLockReleaseRead(&ApiInfoRWLock);
926
927 return fRet;
928}
929
930
931/**
932 * Init The Api Overloading SubSystem.
933 * @returns OS/2 return code.
934 * @sketch Find Ini file location.
935 * Read the inifile and there by initiate the aApiData strcut.
936 * @status completly implemented.
937 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
938 */
939APIRET _Optlink APIInit(void)
940{
941 APIRET rc;
942
943 rc = apiReadIniFile(&szWin32kIni[0]);
944
945 return rc;
946}
947#endif
948
Note: See TracBrowser for help on using the repository browser.