mirror of https://github.com/lianthony/NT4.0
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
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);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|