summaryrefslogblamecommitdiffstats
path: root/private/sdktools/imagehlp/bind.c
blob: 94c6d8262fd3dd31c4cd764ff53872ed9811b15f (plain) (tree)










































































































































































































































































































































































                                                                                                         
/*++

Copyright (c) 1992  Microsoft Corporation

Module Name:

    bind.c

Abstract:

Author:

Revision History:

--*/

#include <private.h>

BOOL
Match(
    char *Pattern,
    char *Text
    )
{
    switch (*Pattern) {
       case '\0':
            return *Text == '\0';

        case '?':
            return *Text != '\0' && Match( Pattern + 1, Text + 1 );

        case '*':
            do {
                if (Match( Pattern + 1, Text ))
                    return TRUE;
                    }
            while (*Text++);
            return FALSE;

        default:
            return toupper( *Text ) == toupper( *Pattern ) && Match( Pattern + 1, Text + 1 );
        }
}


BOOL
AnyMatches(
    char *Name,
    int  *NumList,
    int  Length,
    char **StringList
    )
{
    if (Length == 0) {
        return FALSE;
        }

    return (Match( StringList[ NumList[ 0 ] ], Name ) ||
            AnyMatches( Name, NumList + 1, Length - 1, StringList )
           );
}

BOOL
BindStatusRoutine(
    IMAGEHLP_STATUS_REASON Reason,
    LPSTR ImageName,
    LPSTR DllName,
    PVOID Va,
    ULONG Parameter
    );

#define BIND_ERR 99
#define BIND_OK  0

PCHAR SymbolPath;

BOOL fVerbose;
BOOL fNoUpdate = TRUE;
BOOL fDisableNewImports;
BOOL fBindSysImages;
DWORD BindFlags;

int _CRTAPI1
main(
    int argc,
    char *argv[],
    char *envp[]
    )
{
    char c, *p;
    int ExcludeList[256];
    int ExcludeListLength = 0;

    BOOL fUsage = FALSE;
    LPSTR DllPath;
    LPSTR CurrentImageName;

    int ArgNumber = argc;
    char **ArgList = argv;

    envp;

    DllPath = NULL;
    CurrentImageName = NULL;

    if (argc < 2) {
        goto usage;
        }

    while (--argc) {
        p = *++argv;
        if (*p == '/' || *p == '-') {
            while (c = *++p)
            switch (toupper( c )) {
                case '?':
                    fUsage = TRUE;
                    break;

                case 'P':
                    if (--argc) {
                        DllPath = *++argv;
                        }
                    else {
                        fprintf( stderr, "BIND: Parameter missing for /%c\n", c );
                        fUsage = TRUE;
                        }
                    break;

                case 'V':
                    fVerbose = TRUE;
                    break;

                case 'O':
                    fDisableNewImports = TRUE;
                    break;

                case 'S':
                    if (--argc) {
                        SymbolPath = *++argv;
                        }
                    else {
                        fprintf( stderr, "BIND: Parameter missing for /%c\n", c );
                        fUsage = TRUE;
                        }
                    break;

                case 'U':
                    fNoUpdate = FALSE;
                    break;

                case 'Y':
                    fBindSysImages = TRUE;
                    break;

                case 'X' :
                    if (--argc) {
                        ++argv;
                        ExcludeList[ExcludeListLength] = ArgNumber - argc;
                        ExcludeListLength++;
                        }
                    else {
                        fprintf( stderr, "BIND: Parameter missing for /%c\n", c );
                        fUsage = TRUE;
                        }
                    break;

                default:
                    fprintf( stderr, "BIND: Invalid switch - /%c\n", c );
                    fUsage = TRUE;
                    break;
                }
            if (fUsage) {
usage:
                fputs("usage: BIND [switches] image-names... \n"
                      "            [-?] display this message\n"
                      "            [-v] verbose output\n"
                      "            [-o] disable new import descriptors\n"
                      "            [-u] update the image\n"
                      "            [-s Symbol directory] update any associated .DBG file\n"
                      "            [-p dll search path]\n"
                      "            [-y] allow binding on images located above 2G",
                      stderr
                     );
                return BIND_ERR;
                }
            }
        else {
            CurrentImageName = p;
            if (fVerbose) {
                fprintf( stdout,
                         "BIND: binding %s using DllPath %s\n",
                         CurrentImageName,
                         DllPath ? DllPath : "Default"
                       );
                }

            if (AnyMatches( CurrentImageName, ExcludeList, ExcludeListLength, ArgList )) {
                if (fVerbose) {
                    fprintf( stdout, "BIND: skipping %s\n", CurrentImageName );
                    }
                }
            else {
                BindFlags = 0;
                if (fNoUpdate) {
                    BindFlags |= BIND_NO_UPDATE;
                }
                if (fDisableNewImports) {
                    BindFlags |= BIND_NO_BOUND_IMPORTS;
                }
                if (fBindSysImages) {
                    BindFlags |= BIND_ALL_IMAGES;
                }

                BindImageEx( BindFlags,
                             CurrentImageName,
                             DllPath,
                             SymbolPath,
                             (PIMAGEHLP_STATUS_ROUTINE)BindStatusRoutine
                           );
                }
            }
        }

    return BIND_OK;
}


BOOL
BindStatusRoutine(
    IMAGEHLP_STATUS_REASON Reason,
    LPSTR ImageName,
    LPSTR DllName,
    PVOID Va,
    ULONG Parameter
    )
{
    PIMAGE_BOUND_IMPORT_DESCRIPTOR NewImports, NewImport;
    PIMAGE_BOUND_FORWARDER_REF NewForwarder;
    UINT i;

    switch( Reason ) {
        case BindOutOfMemory:
            fprintf( stderr, "BIND: Out of memory - needed %u bytes.\n", Parameter );
            ExitProcess( 1 );

        case BindRvaToVaFailed:
            fprintf( stderr, "BIND: %s contains invalid Rva - %lx\n", ImageName, Va );
            break;

        case BindNoRoomInImage:
            fprintf( stderr,
                     "BIND: Not enough room for new format import table.  Defaulting to unbound image.\n"
                   );
            break;

        case BindImportModuleFailed:
            fprintf( stderr,"BIND: %s - Unable to find %s\n", ImageName, DllName );
            break;

        case BindImportProcedureFailed:
            fprintf( stderr,
                     "BIND: %s - %s entry point not found in %s\n",
                     ImageName,
                     Parameter,
                     DllName
                   );
            break;

        case BindImportModule:
            if (fVerbose) {
                fprintf( stderr,"BIND: %s - Imports from %s\n", ImageName, DllName );
                }
            break;

        case BindImportProcedure:
            if (fVerbose) {
                fprintf( stderr,
                         "BIND: %s - %s Bound to %lx\n",
                         ImageName,
                         Parameter,
                         Va
                       );
                }
            break;

        case BindForwarder:
            if (fVerbose) {
                fprintf( stderr, "BIND: %s - %s forwarded to %s [%x]\n",
                         ImageName,
                         DllName,
                         Parameter,
                         Va
                       );
                }
            break;

        case BindForwarderNOT:
            if (fVerbose) {
                fprintf( stderr,
                         "BIND: %s - Forwarder %s not snapped [%lx]\n",
                         ImageName,
                         Parameter,
                         Va
                       );
                }
            break;

        case BindImageModified:
            fprintf( stdout, "BIND: binding %s\n", ImageName );
            break;


        case BindExpandFileHeaders:
            if (fVerbose) {
                fprintf( stderr,
                         "    Expanded %s file headers to %x\n",
                         ImageName,
                         Parameter
                       );
                }
            break;

        case BindMismatchedSymbols:
            fprintf(stderr, "BIND: Warning: %s checksum did not match %s\n",
                            ImageName,
                            (LPSTR)Parameter);
            break;

        case BindSymbolsNotUpdated:
            fprintf(stderr, "BIND: Warning: symbol file %s not updated.\n",
                            (LPSTR)Parameter);
            break;

        case BindImageComplete:
            if (fVerbose) {
                fprintf(stderr, "BIND: Details of binding of %s\n", ImageName );
                NewImports = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)Va;
                NewImport = NewImports;
                while (NewImport->OffsetModuleName) {
                    fprintf( stderr, "    Import from %s [%x]",
                             (LPSTR)NewImports + NewImport->OffsetModuleName,
                             NewImport->TimeDateStamp
                           );
                    if (NewImport->NumberOfModuleForwarderRefs != 0) {
                        fprintf( stderr, " with %u forwarders", NewImport->NumberOfModuleForwarderRefs );
                        }
                    fprintf( stderr, "\n" );
                    NewForwarder = (PIMAGE_BOUND_FORWARDER_REF)(NewImport+1);
                    for ( i=0; i<NewImport->NumberOfModuleForwarderRefs; i++ ) {
                        fprintf( stderr, "        Forward to %s [%x]\n",
                                 (LPSTR)NewImports + NewForwarder->OffsetModuleName,
                                 NewForwarder->TimeDateStamp
                               );
                        NewForwarder += 1;
                        }
                    NewImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewForwarder;
                    }
                }
            break;
        }

    return TRUE;
}