/*++
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;
}