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

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

Moved ldrCalls.h into the OS2Krnl.h tree as OS2KLDR.h.
Also moved the Ldr definitions from OS2Krnl.h and into OS2KLDR.h.

File size: 29.4 KB
Line 
1/* $Id: api.cpp,v 1.5 2001-02-10 11:11:41 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 rrealloc 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.