Back to index

lightning-sunbird  0.9+nobinonly
Classes | Typedefs | Functions
macdll.c File Reference
#include <string.h>
#include <Files.h>
#include <Errors.h>
#include <Folders.h>
#include <CodeFragments.h>
#include <Aliases.h>
#include <Resources.h>
#include "IterateDirectory.h"
#include "MacErrorHandling.h"
#include "macdll.h"
#include "mdmac.h"
#include "macio.h"
#include "primpl.h"
#include "plstr.h"

Go to the source code of this file.

Classes

struct  GetSharedLibraryFilterProcData

Typedefs

typedef struct GetSharedLibraryFilterProcData

Functions

static pascal void GetSharedLibraryFilterProc (const CInfoPBRec *const inCpb, Boolean *inWantQuit, void *inFilterData)
OSErr NSGetSharedLibrary (Str255 inLibName, CFragConnectionID *outID, Ptr *outMainAddr)
static Boolean LibInPefContainer (const FSSpec *inSpec, StringPtr inName, UInt32 *outCodeOffset, UInt32 *outCodeLength)
OSErr NSFindSymbol (CFragConnectionID inID, Str255 inSymName, Ptr *outMainAddr, CFragSymbolClass *outSymClass)
OSErr GetNamedFragmentOffsets (const FSSpec *fileSpec, const char *fragmentName, UInt32 *outOffset, UInt32 *outLength)
OSErr GetIndexedFragmentOffsets (const FSSpec *fileSpec, UInt32 fragmentIndex, UInt32 *outOffset, UInt32 *outLength, char **outFragmentName)
OSErr NSLoadNamedFragment (const FSSpec *fileSpec, const char *fragmentName, CFragConnectionID *outConnectionID)
OSErr NSLoadIndexedFragment (const FSSpec *fileSpec, PRUint32 fragmentIndex, char **outFragName, CFragConnectionID *outConnectionID)

Class Documentation

struct GetSharedLibraryFilterProcData

Definition at line 62 of file macdll.c.

Class Members
StringPtr inName
Boolean inRecursive
Ptr outAddress
OSErr outError
Boolean outFound
CFragConnectionID outID

Typedef Documentation

Definition at line 72 of file macdll.c.


Function Documentation

OSErr GetIndexedFragmentOffsets ( const FSSpec fileSpec,
UInt32  fragmentIndex,
UInt32 outOffset,
UInt32 outLength,
char **  outFragmentName 
)

Definition at line 432 of file macdll.c.

{
       CFragResourceHandle         cFragHandle;
       short                                                          fileRefNum;
       OSErr                                                          err = noErr;
       
       fileRefNum = FSpOpenResFile(fileSpec, fsRdPerm);
       err = ResError();
       if (err != noErr) return err;

       cFragHandle = (CFragResourceHandle)Get1Resource(kCFragResourceType, kCFragResourceID);     
       if (!cFragHandle)
       {
              err = resNotFound;
              goto done;
       }
              
       err = cfragNoLibraryErr;                  /* in case of failure */
       *outOffset = 0;
       *outLength = 0;
       *outFragmentName = NULL;
       
       /* the CStrFromPStr mallocs, so might move memory */
       HLock((Handle)cFragHandle);
       
       /* Now look for the named fragment */
       if ((**cFragHandle).memberCount > 0)
       {
              CFragResourceMemberPtr      memberPtr;
              UInt16                                                         i;
              
              for (  i = 0, memberPtr = &(**cFragHandle).firstMember;
                                   i < (**cFragHandle).memberCount;
                                   i ++, memberPtr = (CFragResourceMemberPtr)((char *)memberPtr + memberPtr->memberSize))
              {
                     
                     if (i == fragmentIndex)
                     {
                            char   *fragmentStr;
                            CStrFromPStr(memberPtr->name, &fragmentStr);
                            if (!fragmentStr)           /* test for allocation failure */
                            {
                                   err = memFullErr;
                                   break;
                            }
                            
                            *outFragmentName = fragmentStr;
                            *outOffset = memberPtr->offset;
                            *outLength = memberPtr->length;
                            err = noErr;
                            break;
                     }
              }
       }
       
       HUnlock((Handle)cFragHandle);
       
       /* Resource handle will go away when the res fork is closed */
       
done:
       CloseResFile(fileRefNum);
       return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

OSErr GetNamedFragmentOffsets ( const FSSpec fileSpec,
const char *  fragmentName,
UInt32 outOffset,
UInt32 outLength 
)

Definition at line 364 of file macdll.c.

{
       CFragResourceHandle         cFragHandle;
       short                                                          fileRefNum;
       OSErr                                                          err = noErr;
       
       fileRefNum = FSpOpenResFile(fileSpec, fsRdPerm);
       err = ResError();
       if (err != noErr) return err;

       cFragHandle = (CFragResourceHandle)Get1Resource(kCFragResourceType, kCFragResourceID);     
       if (!cFragHandle)
       {
              err = resNotFound;
              goto done;
       }
       
       /* nothing here moves memory, so no need to lock the handle */
       
       err = cfragNoLibraryErr;                  /* in case of failure */
       *outOffset = 0;
       *outLength = 0;
       
       /* Now look for the named fragment */
       if ((**cFragHandle).memberCount > 0)
       {
              CFragResourceMemberPtr      memberPtr;
              UInt16                                                         i;
              
              for (  i = 0, memberPtr = &(**cFragHandle).firstMember;
                                   i < (**cFragHandle).memberCount;
                                   i ++, memberPtr = (CFragResourceMemberPtr)((char *)memberPtr + memberPtr->memberSize))
              {
                     char          memberName[256];
                     UInt16 nameLen = PR_MIN(memberPtr->name[0], 255);
              
                     // avoid malloc here for speed
                     strncpy(memberName, (char *)&memberPtr->name[1], nameLen);
                     memberName[nameLen] = '\0';
              
                     // fragment names are case insensitive, so act like the system
                     if (PL_strcasecmp(memberName, fragmentName) == 0)
                     {
                            *outOffset = memberPtr->offset;
                            *outLength = memberPtr->length;
                            err = noErr;
                            break;
                     }
              }
       }
       
       /* Resource handle will go away when the res fork is closed */
       
done:
       CloseResFile(fileRefNum);
       return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static pascal void GetSharedLibraryFilterProc ( const CInfoPBRec *const  inCpb,
Boolean inWantQuit,
void inFilterData 
) [static]

Definition at line 179 of file macdll.c.

{
       GetSharedLibraryFilterProcData* pFilterData = (GetSharedLibraryFilterProcData*) inFilterData;

       if ((inCpb->hFileInfo.ioFlAttrib & (1 << ioDirFlg)) == 0)
       {
              FSSpec fragSpec;
              OSErr  tempErr;
              Str255 errName;
              Boolean       crap;
              UInt32 codeOffset;
              UInt32 codeLength;
              
              // it's a file
              
              //  fix-me do we really want to allow all 'APPL's' for in which to find this library?
              switch (inCpb->hFileInfo.ioFlFndrInfo.fdType)
              {
                     case kCFragLibraryFileType:
                     case 'APPL':
                            tempErr = FSMakeFSSpec(inCpb->hFileInfo.ioVRefNum, inCpb->hFileInfo.ioFlParID, inCpb->hFileInfo.ioNamePtr, &fragSpec);

                            // this shouldn't fail
                            if (noErr != tempErr)
                            {
                                   return;
                            }
                            
                            // resolve an alias if this was one
                            tempErr = ResolveAliasFile(&fragSpec, true, &crap, &crap);

                            // if got here we have a shlb (or app-like shlb)
                            if (noErr != tempErr)
                            {
                                   // probably couldn't resolve an alias
                                   return;
                            }
              
                            break;
                     default:
                            return;
              }
       
              // see if this symbol is in this fragment
              if (LibInPefContainer(&fragSpec, pFilterData->inName, &codeOffset, &codeLength))
                     tempErr = GetDiskFragment(&fragSpec, codeOffset, codeLength, fragSpec.name, kLoadCFrag, &pFilterData->outID, &pFilterData->outAddress, errName);
              else
                     return;
                            
              // stop if we found a library by that name
              if (noErr == tempErr)
              {                    
                     *inWantQuit = true;
                     pFilterData->outFound = true;
                     pFilterData->outError = tempErr;
              }
       }
       // FSpIterateDirectory will automagically call us for subsequent sub-dirs if necessary
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Boolean LibInPefContainer ( const FSSpec inSpec,
StringPtr  inName,
UInt32 outCodeOffset,
UInt32 outCodeLength 
) [static]

Definition at line 249 of file macdll.c.

{
       short                              refNum;
       CFragResourceHandle         hCfrg;
       CFragResourceMember* pCurItem;
       UInt32                             curLibIndex;
       Boolean                                   found;
       
       // asume we didn't find it
       found = false;
       
       // open the resource fork, if we can't bail
       refNum = FSpOpenResFile(inSpec, fsRdPerm);
       require(-1 != refNum, Exit);
       
       // grab out the alias record, if it's not there bail
       hCfrg = (CFragResourceHandle) Get1Resource(kCFragResourceType, kCFragResourceID);
       require(NULL != hCfrg, CloseResourceAndExit);
       
       HLock((Handle)hCfrg);
       
       // get ptr to first item
       pCurItem = &(*hCfrg)->firstMember;
       for (curLibIndex = 0; curLibIndex < (*hCfrg)->memberCount; curLibIndex++)
       {
              // is this our library?
              if ((pCurItem->name[0] == inName[0]) &&
                     (strncmp((char*) inName + 1, (char*) pCurItem->name + 1, PR_MIN(pCurItem->name[0], inName[0])) == 0))
              {
                     *outCodeOffset = pCurItem->offset;
                     *outCodeLength = pCurItem->length;
                     found = true;
              }
              
              // skip to next one
              pCurItem = (CFragResourceMember*) ((char*) pCurItem + pCurItem->memberSize);                                    
       }
       
       HUnlock((Handle)hCfrg);
       
CloseResourceAndExit:
       CloseResFile(refNum);
Exit:
       return (found);

}

Here is the call graph for this function:

Here is the caller graph for this function:

OSErr NSFindSymbol ( CFragConnectionID  inID,
Str255  inSymName,
Ptr *  outMainAddr,
CFragSymbolClass *  outSymClass 
)

Definition at line 306 of file macdll.c.

{
       OSErr  err;
       
       if (inSymName[0] > 63)
       {
              /* 
                     if there are greater than 63 characters in the
                     name, CFM FindSymbol fails, so let's iterate through all
                     of the symbols in the fragment and grab it 
                     that way.
              */
              long   symbolCount;
              Str255 curSymName;
              long   curIndex;
              Boolean found;
              
              found = false;
              err = CountSymbols(inID, &symbolCount);
              if (noErr == err)
              {
                     /* now iterate through all the symbols in the library */
                     /* per DTS the indices apparently go 0 to n-1 */
                     for (curIndex = 0; (curIndex <= symbolCount - 1 && !found); curIndex++)
                     {
                            err = GetIndSymbol(inID, curIndex, curSymName, outMainAddr, outSymClass);
                            if (noErr == err && curSymName[0] == inSymName[0] && !strncmp((char*)curSymName + 1, (char*)inSymName + 1, curSymName[0]))
                            {
                                   /* found our symbol */
                                   found = true;
                            }
                     }
                     
                     /* if we didn't find it set the error code so below it won't take this symbol */
                     if (!found)
                            err = cfragNoSymbolErr;
              }      
       }
       else
       {      
              err = FindSymbol(inID, inSymName, outMainAddr, outSymClass);
       }
       
       return (err);
}

Here is the call graph for this function:

OSErr NSGetSharedLibrary ( Str255  inLibName,
CFragConnectionID *  outID,
Ptr *  outMainAddr 
)

Definition at line 87 of file macdll.c.

{
       char*         curLibPath;
       char*         freeCurLibPath;
       OSErr         tempErr;
       Boolean              recursive;
       FSSpec        curFolder;    
       GetSharedLibraryFilterProcData filterData;
       char          *endCurLibPath;
       Boolean              done;
       
       filterData.outFound = false;
       filterData.outID = (CFragConnectionID)(-1);
       filterData.outAddress = NULL;
       filterData.inName = inLibName;
              
       freeCurLibPath = curLibPath = PR_GetLibraryPath();
       
       if (curLibPath == NULL)
              return (cfragNoLibraryErr);
       
       tempErr = cfragNoLibraryErr;
       
       do
       {
              endCurLibPath = PL_strchr(curLibPath, PR_PATH_SEPARATOR);
              done = (endCurLibPath == NULL);

#if 0
              // we overload the first character of a path if it's :
              // then we want to recursively search that path
              // see if path should be recursive
              if (*curLibPath == ':')
              {
                     // ':' is an illegal character in the name of a file
                     // if we start any path with this, we want to allow 
                     // search recursively
                     curLibPath++;
                     recursive = true;
              }
              else
#endif
              {
                     recursive = false;
              }
              
              if (!done)
                     *endCurLibPath = '\0';      // NULL terminate the string
              
              // convert to FSSpec
              tempErr = ConvertUnixPathToFSSpec(curLibPath, &curFolder);     

              // now look in this directory
              if (noErr == tempErr)
              {
                     filterData.inRecursive = recursive;
                     FSpIterateDirectory(&curFolder, recursive ? 0 : 1, &GetSharedLibraryFilterProc, &filterData);
                     
                     if (filterData.outFound)
                     {
                            *outID = filterData.outID;
                            *outMainAddr = filterData.outAddress;
                            tempErr = noErr;
                            break;
                     }
                     else 
                     {
                            tempErr = cfragNoLibraryErr;
                     }
              }
              
              curLibPath = endCurLibPath + 1;    // skip to next path (past the '\0');
       } while (!done);

       free(freeCurLibPath);
       return (tempErr);
}

Here is the call graph for this function:

OSErr NSLoadIndexedFragment ( const FSSpec fileSpec,
PRUint32  fragmentIndex,
char **  outFragName,
CFragConnectionID *  outConnectionID 
)

Definition at line 548 of file macdll.c.

{
    UInt32      fragOffset, fragLength;
    char        *fragNameBlock = NULL;
    Ptr         main;
    Str255      fragName = "\p";
    Str255      errName;
    OSErr       err;

    *outFragName = NULL;
    
    err = GetIndexedFragmentOffsets(fileSpec, fragmentIndex, &fragOffset, &fragLength, &fragNameBlock);
    if (err != noErr) return err;
                
    if (fragNameBlock)
    {
        UInt32 nameLen = strlen(fragNameBlock);
        if (nameLen > 63)
            nameLen = 63;
        BlockMoveData(fragNameBlock, &fragName[1], nameLen);
        fragName[0] = nameLen;
    }

    // Note that we pass the fragment name as the 4th param to GetDiskFragment.
    // This value affects the ability of debuggers, and the Talkback system,
    // to match code fragments with symbol files
    err = GetDiskFragment(fileSpec, fragOffset, fragLength, fragName, 
                    kLoadCFrag, outConnectionID, &main, errName);
    if (err != noErr)
    {
        free(fragNameBlock);
        return err;
    }

    *outFragName = fragNameBlock;
    return noErr;
}

Here is the call graph for this function:

OSErr NSLoadNamedFragment ( const FSSpec fileSpec,
const char *  fragmentName,
CFragConnectionID *  outConnectionID 
)

Definition at line 507 of file macdll.c.

{
    UInt32      fragOffset, fragLength;
    short       fragNameLength;
    Ptr             main;
    Str255      fragName;
    Str255      errName;
    OSErr           err;
    
    err = GetNamedFragmentOffsets(fileSpec, fragmentName, &fragOffset, &fragLength);
    if (err != noErr) return err;
    
    // convert fragment name to pascal string
    fragNameLength = strlen(fragmentName);
    if (fragNameLength > 255)
        fragNameLength = 255;
    BlockMoveData(fragmentName, &fragName[1], fragNameLength);
    fragName[0] = fragNameLength;
    
    // Note that we pass the fragment name as the 4th param to GetDiskFragment.
    // This value affects the ability of debuggers, and the Talkback system,
    // to match code fragments with symbol files
    err = GetDiskFragment(fileSpec, fragOffset, fragLength, fragName, 
                    kLoadCFrag, outConnectionID, &main, errName);

    return err;
}

Here is the call graph for this function: