Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

894 lines
23 KiB

/*
** AutoWrap.C
**
** The AutoWrap tool.
**
** Copyright(C) 1994 Microsoft Corporation
** All rights reserved.
**
** 091694 -- JHSimon @ IBM modified for PPC
**
**
*/
#include <windows.h>
#include <stdio.h>
#include "autowrap.h"
#include "scan.h"
/*
** prototypes
*/
BOOL GenerateDirectoryTree(void) ; // Dir Tree (OBJ, i386,MIPS,ALPHA,PPC)
BOOL GenerateAPIFiles(void) ; // WAPI.H, ZAPI.ASM(.S), Z*.LST, z*.def
BOOL GenerateInternals(void) ; // wrapper.c,h; wapi.C, readme.txt
BOOL GenerateBuildFiles(void) ; // Sources; makefile
BOOL ExpandTo( HANDLE hFile, PCHAR pText, PCHAR pReplacement ) ;
/*
** Global data
*/
BOOL fOverWrite = FALSE ;
CHAR *pBaseFileName = NULL ;
CHAR *pFileNameExt = NULL ;
CHAR *pFileStub = NULL ;
WORD fMachine = 0 ; // This is set in Scan.C
TEMPLATEDATA aTemplates[] =
{
{
#include "wapic.tpl"
, "z%.c", TPL_CONDITIONAL },
{
#include "wapidef.tpl"
, "z%.def", TPL_ALWAYS | TPL_MACHINE_SPECIFIC | TPL_EXPAND },
{
#include "wapih1.tpl"
, "wapi.h", TPL_ALWAYS | TPL_MACHINE_SPECIFIC| TPL_EXPAND },
{
#include "wrapi386.tpl"
, "wrapem.asm", TPL_INTERNAL | TPL_MACHINE_SPECIFIC | TPL_I386 | TPL_EXPAND },
{
#include "wrapmips.tpl"
, "wrapem.s", TPL_INTERNAL | TPL_MACHINE_SPECIFIC | TPL_MIPS | TPL_EXPAND },
{
#include "wrapaxp.tpl"
, "wrapem.s", TPL_INTERNAL | TPL_MACHINE_SPECIFIC | TPL_AXP | TPL_EXPAND },
{
#include "wrapppc.tpl"
, "wrapem.s", TPL_INTERNAL | TPL_MACHINE_SPECIFIC | TPL_PPC | TPL_EXPAND },
{
#include "wrapperh.tpl"
, "wrapper.h", TPL_INTERNAL },
{
#include "wrapprc1.tpl"
, "wrapper.c", TPL_INTERNAL },
{
#include "wrapprc2.tpl"
, "wrapper.c", TPL_APPEND },
{
#include "wrapprc3.tpl"
, "wrapper.c", TPL_APPEND },
{
#include "readme.tpl"
, "readme.txt", TPL_INTERNAL },
{
#include "sources.tpl"
, "Sources", TPL_CONDITIONAL | TPL_EXPAND},
{
#include "makefile.tpl"
, "Makefile", TPL_INTERNAL }
} ;
#define TEMPLATES (sizeof(aTemplates)/sizeof(TEMPLATEDATA))
typedef struct _apidata
{
PCHAR pName ;
DWORD dwOrdinal ;
} APIDATA, PAPIDATA ;
APIDATA *apAPI = NULL ;
APIDATA *apData = NULL ;
HGLOBAL hAPINameData = NULL ;
HGLOBAL hDataNameData = NULL ;
PCHAR pAPINameData = NULL ;
PCHAR pDataNameData = NULL ;
DWORD dwSizeAPINameData = 0 ;
DWORD dwOffsetAPINameData = 0 ;
DWORD dwSizeDataNameData = 0 ;
DWORD dwOffsetDataNameData = 0 ;
#define DATABLOCKSIZE 40000
HGLOBAL hAPINamePointers = NULL ;
HGLOBAL hDataNamePointers = NULL ;
DWORD dwAPIMaxIndex = 0 ;
DWORD dwDataMaxIndex = 0 ;
DWORD dwData = 0 ;
DWORD dwAPI = 0 ;
#define INCREMENT 1024
/*
** DoScan
**
** Callback function for enumeratoin of API and Data names in DLL
**
*/
void DoScan(char *pcEntry,int iOrd,int fData, void *pv)
{
int i;
if (fData)
{
if ((dwSizeDataNameData - dwOffsetDataNameData) < (strlen(pcEntry)+1))
{
if ( hDataNameData != NULL )
{
GlobalUnlock( hDataNameData ) ;
// realloc
hDataNameData = GlobalReAlloc( hDataNameData,
dwSizeDataNameData + DATABLOCKSIZE,
GMEM_ZEROINIT ) ;
}
else
{
// not yet allocated
hDataNameData = GlobalAlloc( GHND, DATABLOCKSIZE ) ;
}
if ( hDataNameData != NULL )
{
dwSizeDataNameData = GlobalSize( hDataNameData ) ;
pDataNameData = GlobalLock( hDataNameData) ;
}
}
if ( 0 == (dwDataMaxIndex - dwData) )
{
if ( hDataNamePointers != NULL )
{
// realloc
GlobalUnlock( hDataNamePointers) ;
hDataNamePointers = GlobalReAlloc( hDataNamePointers,
((dwDataMaxIndex + INCREMENT) * sizeof(APIDATA)),
GMEM_ZEROINIT ) ;
}
else
{
// not yet allocated
hDataNamePointers = GlobalAlloc( GHND, (INCREMENT * sizeof(APIDATA))) ;
}
if ( hDataNamePointers != NULL )
{
dwDataMaxIndex = GlobalSize(hDataNamePointers)/sizeof(APIDATA) ;
apData = GlobalLock(hDataNamePointers) ;
}
}
// add to list?
if (apData != NULL && pDataNameData != NULL && dwData < dwDataMaxIndex )
{
apData[dwData].dwOrdinal = (DWORD)iOrd ;
apData[dwData].pName = (PCHAR)(pDataNameData+dwOffsetDataNameData) ;
memcpy( apData[dwData].pName, pcEntry, strlen(pcEntry)+1 ) ;
dwData++ ;
dwOffsetDataNameData += strlen(pcEntry)+1 ;
}
}
else
{
if ((dwSizeAPINameData - dwOffsetAPINameData) < (strlen(pcEntry)+1))
{
if ( hAPINameData != NULL )
{
// realloc
GlobalUnlock( hAPINameData) ;
hAPINameData = GlobalReAlloc( hAPINameData,
dwSizeAPINameData + DATABLOCKSIZE,
GMEM_ZEROINIT ) ;
}
else
{
// not yet allocated
hAPINameData = GlobalAlloc( GHND, DATABLOCKSIZE ) ;
}
if ( hAPINameData != NULL )
{
dwSizeAPINameData = GlobalSize( hAPINameData ) ;
pAPINameData = GlobalLock( hAPINameData) ;
}
}
if ( 0 == (dwAPIMaxIndex - dwAPI) )
{
if ( hAPINamePointers != NULL )
{
// realloc
GlobalUnlock( hAPINamePointers) ;
hAPINamePointers = GlobalReAlloc( hAPINamePointers,
((dwAPIMaxIndex + INCREMENT) * sizeof(APIDATA)),
GMEM_ZEROINIT ) ;
}
else
{
// not yet allocated
hAPINamePointers = GlobalAlloc( GHND, (INCREMENT * sizeof(APIDATA))) ;
}
if ( hAPINamePointers != NULL )
{
dwAPIMaxIndex = GlobalSize(hAPINamePointers)/sizeof(APIDATA) ;
apAPI = GlobalLock(hAPINamePointers) ;
}
}
// add to list?
if (apAPI != NULL && pAPINameData != NULL && dwAPI < dwAPIMaxIndex)
{
apAPI[dwAPI].dwOrdinal = (DWORD)iOrd ;
apAPI[dwAPI].pName = (PCHAR)(pAPINameData+dwOffsetAPINameData) ;
memcpy( apAPI[dwAPI].pName, pcEntry, strlen(pcEntry)+1 ) ;
dwAPI++ ;
dwOffsetAPINameData += strlen(pcEntry)+1 ;
}
}
return;
}
/*
** main
**
*/
int _CRTAPI1 main( int argc, char *argv[] )
{
int iLibraryName = 1 ;
CHAR achDLLName[256] ;
CHAR *pDLLName = achDLLName ;
int i,j ;
DWORD dwOpenFlags = 0L ;
HANDLE hFile ;
DWORD dwWritten ;
if ( argc < 2 || argc > 3 )
{
// Dump helpful message
printf( "\nAUTOWRAP [-f] dll-name\n-f\tUpdate: Overwrite WAPI.C.") ;
printf( "\ndll-name\tThis is the name of the DLL that you wish to wrap.\n") ;
return(1) ;
}
// Parse cmd line
if ( argc == 3 && '-' == *argv[1] &&
('f' == *(argv[1]+1) || 'f' == *(argv[1]+1) ) )
{
fOverWrite = TRUE ;
iLibraryName++ ;
}
strcpy( pDLLName, argv[iLibraryName] ) ;
// Read API and DATA from the DLL
if( !ScanDLL (argv[1], DoScan, NULL) )
{fprintf(stderr,"ScanDLL error\n");
return 1 ;}
// find base name
for( i=strlen(achDLLName), pBaseFileName = &achDLLName[i-1];
i >= 0 && *pBaseFileName != '\\';
pBaseFileName--, i-- )
/* NULL BODY */ ;
if( i < 0 )
pBaseFileName++ ;
pBaseFileName++ ;
for( i=0; pBaseFileName[i] != '.'; i++ )
/* NULL BODY */ ;
pBaseFileName[i] = '\0' ;
pFileStub = pBaseFileName+1 ;
pFileNameExt = pFileStub+i ;
if( !GenerateDirectoryTree() )
{
printf( "AutoWrap: Failed to create directory structure.\n" ) ;
return 0 ;
}
for ( i=0; i < TEMPLATES; i++ )
{
CHAR achFilename[256] ;
PCHAR pFilename = achFilename ; // no fear of running off...
PCHAR pOrgFilename = aTemplates[i].pFilename ;
PCHAR pText = aTemplates[i].pText ;
// If this file is machine specific and we are looking at a binary
// of the wrong machine type then skip this file
if( PROCESSOR_SPECIFIC(aTemplates[i].wFlags) &&
!(aTemplates[i].wFlags & fMachine) )
continue ;
// if this file is machine specific then we need to pre-pend the
// the machine directory name to the filename
if ( MACHINE_SPECIFIC(aTemplates[i].wFlags ) )
{
char *ptr = NULL ;;
switch( fMachine )
{
case TPL_I386:
ptr = I386_DIR ;
break ;
case TPL_MIPS:
ptr = MIPS_DIR ;
break ;
case TPL_AXP:
ptr = AXP_DIR ;
break ;
case TPL_PPC:
ptr = PPC_DIR ;
break ;
}
if( ptr )
{
strcpy( pFilename, ptr ) ;
pFilename += strlen(pFilename) ;
}
}
// expand file name
while ( *pOrgFilename )
{
if ( '%' == *pOrgFilename )
{
*pFilename = '\0' ;
strcat( achFilename, pFileStub ) ;
pFilename += strlen(pFileStub) ;
}
else
{
*pFilename = *pOrgFilename ;
pFilename ++ ;
}
pOrgFilename++ ;
}
*pFilename = '\0' ;
// Open the file properly
if ( aTemplates[i].wFlags & TPL_ALWAYS )
{
dwOpenFlags = CREATE_ALWAYS ;
}
if ( aTemplates[i].wFlags & TPL_CONDITIONAL )
{
if ( fOverWrite )
dwOpenFlags = CREATE_ALWAYS ;
else
dwOpenFlags = CREATE_NEW ;
}
if ( aTemplates[i].wFlags & TPL_APPEND )
{
dwOpenFlags = OPEN_EXISTING ;
}
hFile = CreateFile( achFilename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
dwOpenFlags,
FILE_ATTRIBUTE_NORMAL,
(HANDLE)NULL ) ;
if ( hFile != INVALID_HANDLE_VALUE )
{
// if appending then seek to EOF
if ( aTemplates[i].wFlags & TPL_APPEND )
{
SetFilePointer( hFile, 0, NULL, FILE_END ) ;
}
if ( aTemplates[i].wFlags & TPL_EXPAND )
{
// Expand the template
if ( !ExpandTo( hFile, pText, pFileStub) )
{
printf( "AutoWrap: Failed to expand template for %s.\n",
aTemplates[i].pFilename ) ;
}
}
else
{
CHAR achBuffer[1024] ;
j = 0 ;
// just copy it to out
while ( *pText )
{
if (sizeof(achBuffer) == j)
{
WriteFile( hFile, achBuffer, sizeof(achBuffer),
&dwWritten, NULL ) ;
j = 0 ;
if( sizeof(achBuffer) != dwWritten )
{
printf( "AutoWrap: Failed to copy template to %s.\n",
aTemplates[i].pFilename ) ;
break ;
}
}
achBuffer[j] = *pText ;
j++ ;
pText++ ;
}
// left overs?
if (0 != j)
{
WriteFile( hFile, achBuffer, j,
&dwWritten, NULL ) ;
if( j != (int)dwWritten )
{
printf( "AutoWrap: Failed to copy template to %s.\n",
aTemplates[i].pFilename ) ;
}
}
}
FlushFileBuffers(hFile) ;
CloseHandle( hFile ) ;
}
else
{
if ( !(aTemplates[i].wFlags & TPL_CONDITIONAL) )
printf( "AutoWrap: Unable to open %s.\n", achFilename ) ;
}
}
return 0 ;
}
DWORD dwBuffered = 0 ;
char achBuffer[BUFFER_SIZE] ;
char *pBuffer = achBuffer ;
void FlushBuff( HANDLE hFile )
{
DWORD dwWritten ;
if ( dwBuffered != 0 )
if( hFile != INVALID_HANDLE_VALUE )
{
WriteFile( hFile, achBuffer, dwBuffered, &dwWritten, NULL ) ;
dwBuffered = 0 ;
pBuffer = achBuffer ;
}
}
void WriteString( HANDLE hFile, LPSTR lpText )
{
while ( '\0' != *lpText )
{
if ( BUFFER_SIZE == dwBuffered )
FlushBuff(hFile);
*pBuffer++ = *lpText++ ;
dwBuffered++;
}
}
void WriteChar( HANDLE hFile, LPSTR lpText, int count )
{
char ch;
while ( count-- )
{
if ( BUFFER_SIZE == dwBuffered )
FlushBuff(hFile);
*pBuffer++ = *lpText++;
dwBuffered++;
}
}
/*
** ExpandLineTo
**
** Template expansions
**
** %s filename stub
** %l Basename of library
** %e Extension of library
** %a real apiname
** %d real dataname
** %A modified apiname
** %D modified dataname
**
** modified names are '?' and '@' replaced with '_'. This is because
** the alpha assembler can't handle these characters in names... :-(
**
** %i index
** %c count of API names
** %o ordinal of API
** %O ordinal of Data
*/
BOOL ExpandLineTo( HANDLE hFile, PCHAR pText, PCHAR pReplacement, DWORD dwIndex )
{
// printf("ExpandLineTo: %s \n",pText);
while( *pText )
{
if( '%' == *pText )
{
pText++ ;
switch( *pText )
{
default:
printf( "AutoWrap: Syntax error in repeated template line.\n" ) ;
break ;
case 'a':
WriteString( hFile, apAPI[dwIndex].pName ) ;
break ;
case 'A':
{
char temp[50], *ptemp = temp ;
char *pname = apAPI[dwIndex].pName ;
while( *pname )
{
switch( *pname )
{
case '?':
case '@':
*ptemp = '_' ;
break ;
default:
*ptemp = *pname ;
break ;
}
ptemp++ ;
pname++ ;
}
*ptemp = '\0' ;
WriteString( hFile, temp ) ;
}
break ;
case 'd':
WriteString( hFile, apData[dwIndex].pName ) ;
break ;
case 'D':
{
char temp[50], *ptemp = temp ;
char *pname = apData[dwIndex].pName ;
while( *pname )
{
switch( *pname )
{
case '?':
case '@':
*ptemp = '_' ;
break ;
default:
*ptemp = *pname ;
break ;
}
ptemp++ ;
pname++ ;
}
*ptemp = '\0' ;
WriteString( hFile, temp ) ;
}
break ;
case 'l':
WriteString( hFile, pBaseFileName ) ;
break ;
case 'e':
WriteString( hFile, pFileNameExt ) ;
break ;
case 's':
WriteString( hFile, pReplacement ) ;
break ;
case 'c':
{
char achText[12] ;
sprintf( achText, "%ld", dwAPI ) ;
WriteString( hFile, achText ) ;
}
break ;
case 'i':
{
char achText[12] ;
sprintf( achText, "%ld", dwIndex ) ;
WriteString( hFile, achText ) ;
}
break ;
case 'o':
{
char achText[12] ;
sprintf( achText, "%ld", apAPI[dwIndex].dwOrdinal ) ;
WriteString( hFile, achText ) ;
}
break ;
case 'O':
{
char achText[12] ;
sprintf( achText, "%ld", apData[dwIndex].dwOrdinal ) ;
WriteString( hFile, achText ) ;
}
break ;
}
}
else
WriteChar( hFile, pText, 1 ) ;
pText++ ;
}
return TRUE ; ;
}
/*
** ExpandTo
**
** Template expansions
**
** %s filename stub
** %l Basename of library
** %e Extension of library
** %a apiname
** %c count of API names
** %a...\n take and expand rest of line repeatedly for each API available
** So %a"%a",\n would be used to create apinames list.
** %d...\n take and expand rest of line repeatedly for each API available
** So %d"%d",\n would be used to create data names list.
** %ifilename\n
** Appends the given file to the current one.
**
*/
BOOL ExpandTo( HANDLE hFile, PCHAR pText, PCHAR pReplacement )
{
// printf("ExpandTo: %s %s\n",pText,pReplacement);
while( *pText )
{
if( '%' == *pText )
{
pText++ ;
switch( *pText )
{
default:
printf( "AutoWrap: Syntax error in template.\n" ) ;
break ;
case 's':
WriteString( hFile, pReplacement ) ;
break ;
case 'l':
WriteString( hFile, pBaseFileName ) ;
break ;
case 'e':
WriteString( hFile, pFileNameExt) ;
break ;
case 'c':
{
char achText[12] ;
sprintf( achText, "%ld", dwAPI ) ;
WriteString( hFile, achText ) ;
}
break ;
case 'd':
case 'a':
{
char achNewTemp[256] ;
PCHAR p = achNewTemp ;
DWORD dwIndex ;
DWORD dwCnt = ('a' == *pText) ? dwAPI : dwData ;
// Copy to '\n' into achNewTemp
pText++ ;
while( '\n' != *pText )
{
*p = *pText ;
pText++ ;
p++ ;
}
*p++ = '\r' ;
*p++ = '\n' ;
*p++ = '\0' ;
for( dwIndex = 0; dwIndex < dwCnt; dwIndex++ )
{
ExpandLineTo( hFile, achNewTemp, pReplacement, dwIndex ) ;
}
}
break ;
case 'i':
{
char achNewTemp[256] ;
PCHAR p = achNewTemp ;
DWORD dwRead, dwTemp ;
HANDLE hAppendFile ;
// Flush write buffer first
FlushBuff(hFile) ;
// Copy to '\n' into achNewTemp
pText++ ;
while( '\n' != *pText )
{
*p = *pText ;
pText++ ;
p++ ;
}
*p++ = '\0' ;
// achNewTemp is the filename to open
hAppendFile = CreateFile( achNewTemp,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE)NULL ) ;
if ( hFile != INVALID_HANDLE_VALUE )
{
dwRead = 1 ;
// copy the file
while( dwRead )
{
ReadFile( hAppendFile, achNewTemp, sizeof(achNewTemp), &dwRead, NULL) ;
WriteFile( hFile, achNewTemp, dwRead, &dwTemp, NULL ) ;
}
CloseHandle(hAppendFile) ;
}
}
break ;
}
}
else
{
WriteChar( hFile, pText, 1) ;
}
pText++ ;
}
FlushBuff( hFile ) ;
return TRUE ; ;
}
/*
** GenerateDirectoryTree
**
** Makes sure that the following directory structure exists off of current
** directory.
**
** Current ----- OBJ
** |
** --- I386
** |
** --- MIPS
** |
** --- ALPHA
** |
** --- PPC
**
*/
BOOL GenerateDirectoryTree()
{
BOOL bRet = TRUE ;
if( !CreateDirectory( "obj", NULL ) )
{
// already exist?
if( ERROR_ALREADY_EXISTS == GetLastError() )
bRet = TRUE ;
else
bRet = FALSE ;
}
if( !CreateDirectory( "i386", NULL ) )
{
// already exist?
if( ERROR_ALREADY_EXISTS == GetLastError() )
bRet &= TRUE ;
else
bRet = FALSE ;
}
if( !CreateDirectory( "Mips", NULL ) )
{
// already exist?
if( ERROR_ALREADY_EXISTS == GetLastError() )
bRet &= TRUE ;
else
bRet = FALSE ;
}
if( !CreateDirectory( "Alpha", NULL ) )
{
// already exist?
if( ERROR_ALREADY_EXISTS == GetLastError() )
bRet &= TRUE ;
else
bRet = FALSE ;
}
if( !CreateDirectory( "ppc", NULL ) )
{
// already exist?
if( ERROR_ALREADY_EXISTS == GetLastError() )
bRet &= TRUE ;
else
bRet = FALSE ;
}
return bRet ; ;
}