Changeset 159 for trunk/nom/src


Ignore:
Timestamp:
Dec 31, 2006, 10:46:48 AM (19 years ago)
Author:
cinc
Message:

Added functions to register DLLs with the garbage collector.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/nom/src/nomgc.c

    r158 r159  
    4242#include <os2.h>
    4343
    44 #include <stdarg.h>
    4544#include <stdio.h>
    4645#include <string.h>
     46#include <stdlib.h>
    4747
    4848/* For nomToken etc. */
     
    103103}
    104104
     105
     106/*
     107  Find a library record in the buffer filled by DosQuerySysState().
     108 */
     109static qsLrec_t* qsFindModuleRec(const HREGDLL hRegisterDLL,  USHORT hMod){
     110  qsLrec_t *       pModRec;
     111  int a=0;
     112
     113  pModRec=hRegisterDLL->pLibRec;
     114  while(NULL!=pModRec)
     115    {
     116      a++;
     117      //            printf("%d Checking: %x -> %04X (%s)\n", a, pModRec, pModRec->hmte, pModRec->pName);
     118
     119      if (NULLHANDLE==pModRec->pObjInfo   && pModRec->ctObj > 0)
     120        {
     121          pModRec->pObjInfo = (qsLObjrec_t*)((char*)pModRec
     122                                             + ((sizeof(qsLrec_t)
     123                                             + pModRec->ctImpMod * sizeof(short)
     124                                             + strlen((char*)pModRec->pName) + 1    /* filename */
     125                                             + 3) & ~3));
     126          pModRec->pNextRec = (void*)((char*)pModRec->pObjInfo
     127                                    + sizeof(qsLObjrec_t) * pModRec->ctObj);
     128        }
     129      if(pModRec->hmte==hMod)
     130        break;
     131
     132      pModRec=(qsLrec_t *)pModRec->pNextRec;
     133    }
     134  return pModRec;
     135}
     136
     137
     138#define BUFSIZE 1024*1024
     139NOMEXTERN HREGDLL NOMLINK nomBeginRegisterDLLWithGC(void)
     140{
     141  ULONG rc;
     142  HREGDLL hReg=NULLHANDLE;
     143  PTIB     ptib;
     144  PPIB     ppib;
     145  char *  buf;
     146
     147  rc = DosGetInfoBlocks(&ptib, &ppib);
     148  if (rc!=NO_ERROR)
     149    return NULLHANDLE;
     150
     151  buf = malloc(BUFSIZE);
     152  if(!buf)
     153    return NULLHANDLE;
     154
     155  memset(buf,0,BUFSIZE);
     156
     157  rc = DosQuerySysState(QS_PROCESS | QS_SEMAPHORE | QS_MTE | QS_FILESYS | QS_SHMEMORY ,
     158                        QS_MTE, /*0x96*/ ppib->pib_ulpid , 1UL, (PCHAR)buf, BUFSIZE);
     159  if (rc==NO_ERROR) {
     160    hReg=(qsPtrRec_t*) buf;
     161  }
     162  else
     163    free(buf);
     164
     165  return hReg;
     166}
     167
     168NOMEXTERN void NOMLINK nomEndRegisterDLLWithGC(const HREGDLL hRegisterDLL )
     169{
     170  free((char*)hRegisterDLL);
     171}
     172
     173
     174/*
     175  FIXME:
     176
     177  This function will not find every given DLL because it doesn't follow every import of
     178  each DLL.
     179  It's only meant for registering the GTK+, GLIB and friends DLLs. This works because GTK2.DLL
     180  is directly loaded by the exe and all the friends DLLs are imported by it.
     181
     182  Feel free to make this function really useful...
     183
     184  Oh, and some refactoring would be nice, too.
     185
     186 */
     187#define OBJREAD         0x0001L
     188#define OBJWRITE        0x0002L
     189#define OBJINVALID      0x0080L
     190NOMEXTERN BOOL NOMLINK nomRegisterDLLByName(const HREGDLL hRegisterDLL, const char* chrDLLName)
     191{
     192  qsPrec_t * p;
     193  int a=0;
     194
     195  printf("Trying to register DLL %s\n", chrDLLName);
     196
     197  p=hRegisterDLL->pProcRec;
     198  while(p && p->RecType == 1)
     199    {
     200      a++;
     201      if (p->cLib) {
     202        int i;
     203
     204        for (i=0; i<p->cLib; i++){
     205          qsLrec_t * pModRec;
     206
     207          //printf("%d %04X (p: %04x %04X, %04X) ",i, p->pLibRec[i], p, &p->pLibRec[i], &p->pLibRec);
     208
     209          pModRec=qsFindModuleRec(hRegisterDLL,  p->pLibRec[i]);
     210          if(pModRec){
     211            //  printf("DLL name: %s\n", pModRec->pName);
     212            if(NULLHANDLE!=strstr( pModRec->pName, chrDLLName))
     213              {
     214                qsLObjrec_t  *pObjInfo;
     215                printf("    --> Found DLL %s\n", pModRec->pName);
     216                pObjInfo=pModRec->pObjInfo;
     217                if(NULLHANDLE!=pObjInfo)
     218                  {
     219                    int iObj;
     220                    for(iObj=0; iObj<pModRec->ctObj ;iObj++)
     221                      {
     222                        if (!(pObjInfo[iObj].oflags & OBJWRITE)) continue;
     223                        if (!(pObjInfo[iObj].oflags & OBJREAD)) continue;
     224                        if ((pObjInfo[iObj].oflags & OBJINVALID)) continue;
     225                        printf("    #%d: %04lX, size: %04lX %04lX\n",
     226                               iObj, pObjInfo[iObj].oaddr, pObjInfo[iObj].osize, pObjInfo[iObj].oflags);
     227                        nomRegisterDataAreaForGC((char*)pObjInfo[iObj].oaddr,
     228                                                 (char*)(pObjInfo[iObj].oaddr+pObjInfo[iObj].osize));
     229
     230                      }
     231                  }
     232                return TRUE;
     233              }
     234            /* Check the imports of this DLL if any */
     235            if(pModRec->ctImpMod >0)
     236              {
     237                int iImps;
     238                PUSHORT   pImpHmte;
     239
     240                pImpHmte=(PUSHORT)((void*)pModRec + sizeof(qsLrec_t));
     241
     242                for(iImps=0; iImps < pModRec->ctImpMod; iImps++)
     243                  {
     244                    qsLrec_t * pModImp;
     245                    // printf("  Trying import #%d (%04X)\n", iImps, pImpHmte[iImps]);
     246                    pModImp=qsFindModuleRec(hRegisterDLL,  pImpHmte[iImps]);
     247                    if(pModImp){
     248                      //printf("  DLL name: %s\n", pModImp->pName);
     249                      if(NULLHANDLE!=strstr( pModImp->pName, chrDLLName))
     250                        {
     251                          qsLObjrec_t  *pObjInfo;
     252                          printf("    --> Found DLL %s\n", pModImp->pName);
     253                          pObjInfo=pModImp->pObjInfo;
     254                          if(NULLHANDLE!=pObjInfo)
     255                            {
     256                              int iObj;
     257                              for(iObj=0; iObj<pModImp->ctObj ;iObj++)
     258                                {
     259                                  if (!(pObjInfo[iObj].oflags & OBJWRITE)) continue;
     260                                  if (!(pObjInfo[iObj].oflags & OBJREAD)) continue;
     261                                  if ((pObjInfo[iObj].oflags & OBJINVALID)) continue;
     262                                 
     263                                  printf("    #%d: %04lX, size: %04lX %04lX\n",
     264                                         iObj, pObjInfo[iObj].oaddr, pObjInfo[iObj].osize, pObjInfo[iObj].oflags);
     265                                  nomRegisterDataAreaForGC((char*)pObjInfo[iObj].oaddr,
     266                                                           (char*)(pObjInfo[iObj].oaddr+pObjInfo[iObj].osize));
     267                                }
     268                            }
     269                          return TRUE;
     270                        }
     271                    }/* for() */
     272                  }/* for()*/
     273              }/* if() */
     274          }
     275        }/* For() */
     276      }
     277      break;
     278    }
     279  return NULLHANDLE;
     280}
Note: See TracChangeset for help on using the changeset viewer.