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.
 
 
 
 
 
 

373 lines
8.4 KiB

#include "precomp.h"
#pragma hdrstop
/**************************************************************************
*
* Adds an entry to the UFI has table
*
* History
* 1-27-95 Gerrit van Wingerden [gerritv]
* Wrote it.
*
***************************************************************************/
BOOL bAddUFIEntry( PUFIHASH *ppHashBase, PUNIVERSAL_FONT_ID pufi )
{
PUFIHASH pBucket;
ULONG index;
index = UFI_HASH_VALUE(pufi) % UFI_HASH_SIZE;
pBucket = LOCALALLOC( sizeof( UFIHASH ) );
if( pBucket == NULL )
{
WARNING("bAddUFIEntry: out of memory\n");
return(FALSE);
}
pBucket->pNext = ppHashBase[index];
ppHashBase[index] = pBucket;
*((PUNIVERSAL_FONT_ID)&(pBucket->ufi)) = *pufi;
return(TRUE);
}
/**************************************************************************
*
* Checks to see if an entry is in the UFI table.
*
* History
* 1-27-95 Gerrit van Wingerden [gerritv]
* Wrote it.
*
***************************************************************************/
BOOL bFindUFIEntry( PUFIHASH *ppHashBase, PUNIVERSAL_FONT_ID pufi )
{
PUFIHASH pBucket;
ULONG index;
index = UFI_HASH_VALUE(pufi) % UFI_HASH_SIZE;
pBucket = ppHashBase[index];
if( pBucket == NULL )
{
return(FALSE);
}
do
{
if( UFI_SAME_FILE(&pBucket->ufi,pufi) )
{
return(TRUE);
}
pBucket = pBucket->pNext;
} while( pBucket != NULL );
return(FALSE);
}
/**************************************************************************
* VOID vFreeUFIHashTable( PUFIHASH *ppHashTable )
*
* Frees all the memory allocated for the UFI has table.
*
* History
* 1-27-95 Gerrit van Wingerden [gerritv]
* Wrote it.
*
***************************************************************************/
VOID vFreeUFIHashTable(
PUFIHASH *ppHashTable
)
{
PUFIHASH pBucket, *ppHashEnd, pBucketTmp, *ppTableBase;
if( ppHashTable == NULL )
{
return;
}
ppTableBase = ppHashTable; // save ptr to the base so we can free it later
// Next loop through the whole table looking for buckets lists
for( ppHashEnd = ppHashTable + UFI_HASH_SIZE;
ppHashTable < ppHashEnd;
ppHashTable += 1 )
{
pBucket = *ppHashTable;
while( pBucket != NULL )
{
pBucketTmp = pBucket;
pBucket = pBucket->pNext;
LOCALFREE( pBucketTmp );
}
}
LOCALFREE( ppTableBase );
}
/**************************************************************************
* BOOL GetUFIBits( PUNIVERSAL_FONT_ID, ULONG, ULONG, BYTE )
*
* Gets the raw bits for a font given a UFI.
*
* History
* 1-27-95 Gerrit van Wingerden [gerritv]
* Wrote it.
*
***************************************************************************/
BOOL GetUFIBits(
PUNIVERSAL_FONT_ID pufi,
ULONG *pulFileSize,
ULONG cjBufferSize,
BYTE *pjBuffer
)
{
return (NtGdiGetUFIBits(pufi, cjBufferSize, pjBuffer, pulFileSize));
}
/**************************************************************************
* BOOL GetUFI( HDC hdc, PUNIVERSAL_FONT_ID pufi )
*
* Gets the UFI for the font currently in the DC.
*
* History
* 1-27-95 Gerrit van Wingerden [gerritv]
* Wrote it.
*
***************************************************************************/
BOOL GetUFI(
HDC hdc,
PUNIVERSAL_FONT_ID pufi
)
{
return( NtGdiGetUFI(hdc, pufi) );
}
/**************************************************************************
* BOOL ForceUFIMapping( HDC hdc, PUNIVERSAL_FONT_ID pufi )
*
* Force the all font mapping on the DC to map to the font specified by
* a UFI
*
* History
* 1-27-95 Gerrit van Wingerden [gerritv]
* Wrote it.
*
***************************************************************************/
BOOL ForceUFIMapping( HDC hdc, UNIVERSAL_FONT_ID *pufi)
{
return( NtGdiForceUFIMapping(hdc, pufi) );
}
/**************************************************************************
* BOOL bDoFontChange( HDC hdc )
*
* Called everytime the font changes in the DC. This routines checks to
* see if the font has already been packaged in the spool file and if not
* gets the raw bits for it and packages it into the spool file.
*
* History
* 1-27-95 Gerrit van Wingerden [gerritv]
* Wrote it.
*
***************************************************************************/
BOOL bDoFontChange( HDC hdc )
{
PLDC pldc;
PUFIHASH pBucket;
BOOL bRet = FALSE;
UNIVERSAL_FONT_ID ufi;
PBYTE pjBuffer;
pldc = GET_PLDC( hdc );
pldc->fl &= ~LDC_FONT_CHANGE;
if( !GetUFI( hdc, &ufi ) )
{
WARNING("bDoFontChange: call to GetUFI failed\n");
return(FALSE);
}
// if the UFI to which we are forcing mapping does not match the new UFI then
// set forced mapping to the new UFI
if( ( pldc->fl & LDC_FORCE_MAPPING ) &&
(!UFI_SAME_FACE(&pldc->ufi,&ufi)))
{
if( !MF_ForceUFIMapping( hdc, &ufi ) )
{
WARNING("bDoFontChange: call to MF_ForceUFIMapping failed\n");
return(FALSE);
}
pldc->ufi = ufi;
}
if( UFI_DEVICE_FONT(&ufi) ||
!(pldc->fl & LDC_DOWNLOAD_FONTS) )
{
return(TRUE);
}
pjBuffer = NULL;
if( !bFindUFIEntry( pldc->ppUFIHash, &ufi ) )
{
EMFITEMHEADER emfi;
ULONG Dummy;
emfi.ulID = UFI_TYPE1_FONT(&ufi) ? EMRI_TYPE1_FONT : EMRI_ENGINE_FONT;
bAddUFIEntry( pldc->ppUFIHash, &ufi );
if( !GetUFIBits( &ufi, &emfi.cjSize, 0, NULL ) )
{
WARNING("bDonFontChange GetUFIBits failed\n");
goto ERROREXIT;
}
pjBuffer = LocalAlloc( LMEM_FIXED, emfi.cjSize );
if( pjBuffer == NULL )
{
WARNING("bDonFontChange unable to allocate memory\n");
goto ERROREXIT;
}
if( !GetUFIBits( &ufi, &emfi.cjSize, emfi.cjSize, pjBuffer ) )
{
WARNING("bDonFontChange GetUFIBits failed\n");
goto ERROREXIT;
}
if( !(*fpWritePrinter)( pldc->hSpooler, (PBYTE) &emfi, sizeof(emfi), &Dummy ) ||
!(*fpWritePrinter)( pldc->hSpooler, (PBYTE) pjBuffer, emfi.cjSize, &Dummy ))
{
WARNING("bDonFontChange error writing to printer\n");
goto ERROREXIT;
}
MFD1("Done writing UFI to printer\n");
}
bRet = TRUE;
ERROREXIT:
if( pjBuffer != NULL )
{
LocalFree(pjBuffer);
}
return(bRet);
}
/**************************************************************************
* BOOL RemoteRasterizerCompatible()
*
* This routine is used if we are about to print using remote EMF. If a
* Type 1 font rasterizer has been installed on the client machine, we need
* to query the remote machine to make sure that it has a rasterizer that is
* compatable with the local version. If it isn't, we will return false
* telling the caller that we should go RAW.
*
* History
* 6-4-96 Gerrit van Wingerden [gerritv]
* Wrote it.
*
***************************************************************************/
BOOL gbQueriedRasterizerVersion = FALSE;
UNIVERSAL_FONT_ID gufiLocalType1Rasterizer;
BOOL RemoteRasterizerCompatible(HANDLE hSpooler)
{
// if we haven't queried the rasterizer for the version yet do so first
UNIVERSAL_FONT_ID ufi;
LARGE_INTEGER TimeStamp;
if(!gbQueriedRasterizerVersion)
{
// we have a contract with NtGdiQueryFonts (the routine called by the spooler
// on the remote machine) that if a Type1 rasterizer is installed, the UFI
// for it will always be first in the UFI list returned. So we can call
// NtGdiQueryFonts
if(!NtGdiQueryFonts(&gufiLocalType1Rasterizer, 1, &TimeStamp))
{
WARNING("Unable to get local Type1 information\n");
return(FALSE);
}
gbQueriedRasterizerVersion = TRUE;
}
if(!UFI_TYPE1_RASTERIZER(&gufiLocalType1Rasterizer))
{
// no need to disable remote printing if there is no ATM driver installed
return(TRUE);
}
// Since we made it this far there must be a Type1 rasterizer on the local machine.
// Let's find out the version number of the Type1 rasterizer (if one is installed)
// on the print server.
if((*fpQueryRemoteFonts)(hSpooler, &ufi, 1 ) &&
(UFI_SAME_RASTERIZER_VERSION(&gufiLocalType1Rasterizer,&ufi)))
{
return(TRUE);
}
else
{
WARNING("Remote Type1 rasterizer missing or wrong version. Going RAW\n");
return(FALSE);
}
}