2025-04-27 07:49:33 -04:00

591 lines
16 KiB
C

/*++
Copyright (c) 1996-1997 Microsoft Corporation
Module Name:
mkuff.c
Abstract:
Environment:
Windows NT PostScript driver
Revision History:
--*/
#include "precomp.h"
//
// Macros
//
DWORD gdwOutputFlags;
//
// Local function prototypes
//
BOOL
BiArgcheck(
IN INT iArgc,
IN CHAR **ppArgv,
IN OUT PWSTR pwstrInFileName,
IN OUT PWSTR pwstrOutFileName);
PBYTE
PCreateUFFFileHeader(
HANDLE hHeap,
PFILELIST pFileList,
PDWORD pdwUFFSize);
//
// Globals
//
BYTE gcstrError1[] = "Usage: mkuff [-v] [Input Text file] [Output UFF file]\n";
BYTE gcstrError2[] = "mkuff: HeapCreate() failed\n.";
BYTE gcstrError3[] = "BGetInfo failed.\n";
BYTE gcstrError4[] = "Cannot create output file '%ws'.\n";
BYTE gcstrError5[] = "PCreateUFFFileHeader failed\n";
BYTE gcstrError6[] = "WriteFile fails: writes %ld bytes\n";
BYTE gcstrError8[] = "Cannot open file \"%ws\".\n";
INT __cdecl
main(
IN INT iArgc,
IN CHAR **ppArgv)
/*++
Routine Description:
main
Arguments:
iArgc - Number of parameters in the following
ppArgv - The parameters, starting with our name
Return Value:
Return error code
Note:
--*/
{
HANDLE hHeap, hInFile, hOutput;
PBYTE pInFile, pUFFFile;
DWORD dwInFileSize, dwI, dwUFFHeaderSize, dwWrittenSize, dwFileSize;
PWSTR wstrInFileName[FILENAME_SIZE];
PWSTR wstrOutFileName[FILENAME_SIZE];
FILELIST FileList;
DATA_HEADER DataHeader;
PCARTLIST pCartList;
PDATAFILE pDataTmp;
PDATAFILE pFontFile;
HANDLE hFontFile;
PBYTE pFontData;
if (gdwOutputFlags & OUTPUT_VERBOSE)
{
fprintf( stdout, "Start mkuff\n");
}
if (!BiArgcheck(iArgc, ppArgv, (PWSTR)wstrInFileName, (PWSTR)wstrOutFileName))
{
fprintf( stderr, gcstrError1);
return -1;
}
if (gdwOutputFlags & OUTPUT_VERBOSE)
{
fprintf( stdout, "InFile: %ws\nOutFile: %ws\n", wstrInFileName, wstrOutFileName);
}
//
// Heap Creation
//
if (!(hHeap = HeapCreate( HEAP_NO_SERIALIZE, 0x10000, 0x10000)))
{
fprintf( stderr, gcstrError2);
ERR(("CreateHeap failed: %d\n", GetLastError()));
return -2;
}
hInFile = MapFileIntoMemory((PWSTR)wstrInFileName,
(PVOID)&pInFile,
&dwInFileSize );
ZeroMemory(&FileList, sizeof(FILELIST));
if (!BGetInfo(hHeap, pInFile, dwInFileSize, &FileList))
{
fprintf( stderr, gcstrError3);
ERR(("CreateHeap failed: %d\n", GetLastError()));
return -3;
}
if (gdwOutputFlags & OUTPUT_VERBOSE)
{
PDATAFILE pFontFile;
PDATAFILE pTransFile;
PCARTLIST pCartList;
printf("\n");
printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("FileList\n");
pCartList = FileList.pCartList;
for (dwI = 0; dwI < FileList.dwCartridgeNum; dwI ++, pCartList = pCartList->pNext)
{
if (pCartList->pwstrCartName)
fprintf( stdout, "CartRidge(%d): ""%ws""\n", dwI, pCartList->pwstrCartName);
pFontFile = pCartList->pFontFile;
while( pFontFile )
{
fprintf( stdout, "FontFile(%d): %ws, FontName:%ws\n", pFontFile->rcID, pFontFile->pwstrFileName, pFontFile->pwstrDataName);
pFontFile = pFontFile->pNext;
}
pTransFile = pCartList->pTransFile;
while( pTransFile )
{
fprintf( stdout, "TransFile(%d): %ws\n", pTransFile->rcID, pTransFile->pwstrFileName);
pTransFile = pTransFile->pNext;
}
}
}
UnmapFileFromMemory(hInFile);
pUFFFile = PCreateUFFFileHeader(hHeap, &FileList, &dwUFFHeaderSize);
if (pUFFFile == NULL)
{
fprintf( stderr, gcstrError5);
return -5;
}
hOutput = CreateFile((PWSTR)wstrOutFileName,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( hOutput == INVALID_HANDLE_VALUE )
{
fprintf( stderr, gcstrError4, wstrOutFileName);
return -4;
}
WriteFile( hOutput,
pUFFFile,
dwUFFHeaderSize,
&dwWrittenSize,
NULL );
if( dwWrittenSize != dwUFFHeaderSize)
{
fprintf( stderr, gcstrError6, dwWrittenSize);
return -6;
}
//
// Open font file and write data
//
pCartList = FileList.pCartList;
while (pCartList)
{
pDataTmp = pCartList->pFontFile;
while (pDataTmp)
{
hFontFile = MapFileIntoMemory(pDataTmp->pwstrFileName,
(PVOID)&pFontData,
&dwFileSize );
DataHeader.dwSignature = pDataTmp->dwSignature;
DataHeader.wSize = sizeof(DATA_HEADER);
DataHeader.wDataID = (WORD)pDataTmp->rcID;
DataHeader.dwDataSize = (WORD)dwFileSize;
DataHeader.dwReserved = 0;
if (hFontFile)
{
WriteFile( hOutput,
&DataHeader,
sizeof(DATA_HEADER),
&dwWrittenSize,
NULL);
if( dwWrittenSize != sizeof(DATA_HEADER))
{
fprintf( stderr, gcstrError6, dwWrittenSize);
return -6;
}
WriteFile( hOutput,
pFontData,
dwFileSize,
&dwWrittenSize,
NULL);
if( dwWrittenSize != dwFileSize)
{
fprintf( stderr, gcstrError6, dwWrittenSize);
return -6;
}
UnmapFileFromMemory(hFontFile);
}
else
break;
pDataTmp = pDataTmp->pNext;
}
pDataTmp = pCartList->pTransFile;
while (pDataTmp)
{
hFontFile = MapFileIntoMemory(pDataTmp->pwstrFileName,
(PVOID)&pFontData,
&dwFileSize );
DataHeader.dwSignature = pDataTmp->dwSignature;
DataHeader.wSize = sizeof(DATA_HEADER);
DataHeader.wDataID = (WORD)pDataTmp->rcID;
DataHeader.dwDataSize = (WORD)dwFileSize;
DataHeader.dwReserved = 0;
if (hFontFile)
{
WriteFile( hOutput,
&DataHeader,
sizeof(DATA_HEADER),
&dwWrittenSize,
NULL);
if( dwWrittenSize != sizeof(DATA_HEADER))
{
fprintf( stderr, gcstrError6, dwWrittenSize);
return -6;
}
WriteFile( hOutput,
pFontData,
dwFileSize,
&dwWrittenSize,
NULL);
if( dwWrittenSize != dwFileSize)
{
fprintf( stderr, gcstrError6, dwWrittenSize);
return -6;
}
UnmapFileFromMemory(hFontFile);
}
else
break;
pDataTmp = pDataTmp->pNext;
}
pCartList = pCartList->pNext;
}
CloseHandle(hOutput);
HeapDestroy(hHeap);
return 0;
}
BOOL
BiArgcheck(
IN INT iArgc,
IN CHAR **ppArgv,
IN OUT PWSTR pwstrInFileName,
IN OUT PWSTR pwstrOutFileName)
/*++
Routine Description:
iArgcheck
Arguments:
iArgc - Number of parameters in the following
ppArgv - The parameters, starting with our name
pwstrInFileName -
pwstrOutFileName -
Return Value:
If TRUE, function succeeded. Othewise FALSE.
Note:
--*/
{
INT iI;
INT iRet;
if (iArgc > 4 || iArgc < 3)
{
return FALSE;
}
if (iArgc == 4)
{
gdwOutputFlags |= OUTPUT_VERBOSE;
ppArgv++;
}
ppArgv++;
iRet = MultiByteToWideChar(CP_ACP, 0, *ppArgv, strlen(*ppArgv), pwstrInFileName, FILENAME_SIZE);
*(pwstrInFileName + iRet) = (WCHAR)NULL;
ppArgv++;
iRet = MultiByteToWideChar(CP_ACP, 0, *ppArgv, strlen(*ppArgv), pwstrOutFileName, FILENAME_SIZE);
*(pwstrOutFileName + iRet) = (WCHAR)NULL;
return TRUE;
}
PBYTE
PCreateUFFFileHeader(
HANDLE hHeap,
PFILELIST pFileList,
PDWORD pdwUFFHeaderSize)
{
HANDLE hFontFile;
PDATAFILE pFontFile, pTransFile;
PCARTLIST pCartList;
PDATAFILE pDataTmp;
PUFF_FILEHEADER pUFFHeader;
PUFF_FONTDIRECTORY pUFFFontDir, pFirstFontDir;
PBYTE pFontData;
DWORD dwNumOfFontNameChars, dwNumOfData, dwNumOfFonts, dwNumOfTrans, dwUFFHeaderSize, dwFileSize, dwNumOfCartNameChars, dwI;
DWORD dwOffset, offCartridgeName;
PWSTR pwstrCartNameBuf, pwstrFontNameBuf;
*pdwUFFHeaderSize = 0;
dwNumOfFontNameChars = dwNumOfCartNameChars = dwNumOfFonts = dwNumOfTrans = 0;
pCartList = pFileList->pCartList;
while (pCartList)
{
pDataTmp = pCartList->pFontFile;
while (pDataTmp)
{
dwNumOfFontNameChars += 1 + wcslen(pDataTmp->pwstrDataName);
pDataTmp = pDataTmp->pNext;
dwNumOfFonts ++;
}
pDataTmp = pCartList->pTransFile;
while (pDataTmp)
{
pDataTmp = pDataTmp->pNext;
dwNumOfTrans ++;
}
if (pCartList->pwstrCartName)
dwNumOfCartNameChars += 1 + wcslen(pCartList->pwstrCartName);
pCartList = pCartList->pNext;
}
dwNumOfData = dwNumOfFonts + dwNumOfTrans;
dwUFFHeaderSize = sizeof(UFF_FILEHEADER) +
sizeof(UFF_FONTDIRECTORY) * dwNumOfFonts +
dwNumOfCartNameChars * sizeof(WCHAR) +
dwNumOfFontNameChars * sizeof(WCHAR);
pUFFHeader = (PUFF_FILEHEADER)HeapAlloc(hHeap, 0, dwUFFHeaderSize);
if (pUFFHeader == NULL)
{
return NULL;
}
//
// Fill in header.
//
pUFFHeader->dwSignature = UFF_FILE_MAGIC;
pUFFHeader->dwVersion = UFF_VERSION_NUMBER;
pUFFHeader->dwSize = sizeof(UFF_FILEHEADER);
pUFFHeader->nFonts = dwNumOfFonts;
pUFFHeader->nGlyphSets = dwNumOfTrans;
pUFFHeader->nVarData = 0;
pUFFHeader->offFontDir = sizeof(UFF_FILEHEADER);
pUFFHeader->dwFlags = 0;
pUFFHeader->dwReserved[0] = 0;
pUFFHeader->dwReserved[1] = 0;
pUFFHeader->dwReserved[2] = 0;
pUFFHeader->dwReserved[3] = 0;
//
// Fill in UFF_FONTDIRECTORY
//
// ------------------
// UFF_FONTHEADER
// ------------------
// UFF_FONTDIRECTORY * (Number of fonts)
// ------------------
// Cartridge name
// ------------------
// Font name
// ------------------
// First cartridge font data
// ------------------
// First cartridge glyph data
// ------------------
// Second cartridge font data
// ------------------
// Second cartridge glyph data
// ------------------
//
pUFFFontDir = (PUFF_FONTDIRECTORY)(pUFFHeader + 1);
pwstrCartNameBuf = (PWSTR)(pUFFFontDir + dwNumOfFonts);
pwstrFontNameBuf = pwstrCartNameBuf + dwNumOfCartNameChars;
pCartList = pFileList->pCartList;
dwOffset = sizeof(UFF_FILEHEADER) +
sizeof(UFF_FONTDIRECTORY) * dwNumOfFonts +
dwNumOfCartNameChars * sizeof(WCHAR) +
dwNumOfFontNameChars * sizeof(WCHAR);
while(pCartList)
{
pFontFile = pCartList->pFontFile;
pTransFile = pCartList->pTransFile;
pFirstFontDir = pUFFFontDir;
if (pCartList->pwstrCartName)
{
offCartridgeName = (PBYTE)pwstrCartNameBuf - (PBYTE)pUFFHeader;
wcscpy(pwstrCartNameBuf, pCartList->pwstrCartName);
pwstrCartNameBuf += wcslen(pCartList->pwstrCartName) + 1;
}
else
offCartridgeName = (DWORD)NULL;
while (pFontFile)
{
hFontFile = MapFileIntoMemory(pFontFile->pwstrFileName,
(PVOID)&pFontData,
&dwFileSize );
if (hFontFile)
{
pFontFile->dwSize = dwFileSize;
if (1)
{
pFontFile->dwSignature = DATA_IFI_SIG;
pFontFile->rcTrans = ((FI_DATA_HEADER*)pFontData)->u.sCTTid;
}
else
{
pFontFile->dwSignature = DATA_UFM_SIG;
pFontFile->rcTrans = (SHORT)((UNIFM_HDR*)pFontData)->lGlyphSetDataRCID;
}
UnmapFileFromMemory(hFontFile);
}
else
return NULL;
pUFFFontDir->dwSignature = FONT_REC_SIG;
pUFFFontDir->wSize = sizeof(UFF_FONTDIRECTORY);
pUFFFontDir->wFontID = (WORD)pFontFile->rcID;
pUFFFontDir->sGlyphID = (SHORT)pFontFile->rcTrans;
pUFFFontDir->wFlags = 0;
pUFFFontDir->dwInstallerSig = WINNT_INSTALLER_SIG;
if (pFontFile->pwstrDataName)
{
pUFFFontDir->offFontName = (PBYTE)pwstrFontNameBuf - (PBYTE)pUFFHeader;
wcscpy(pwstrFontNameBuf, pFontFile->pwstrDataName);
pwstrFontNameBuf += wcslen(pFontFile->pwstrDataName) + 1;
}
else
pUFFFontDir->offFontName = (DWORD)NULL;
pUFFFontDir->offCartridgeName = offCartridgeName;
pUFFFontDir->offFontData = dwOffset;
pUFFFontDir->offGlyphData = 0;
pUFFFontDir->offVarData = 0;
pUFFFontDir++;
dwOffset += pFontFile->dwSize + sizeof(DATA_HEADER);
pFontFile = pFontFile->pNext;
}
while (pTransFile)
{
hFontFile = MapFileIntoMemory(pTransFile->pwstrFileName,
(PVOID)&pFontData,
&dwFileSize );
if (1)
{
pTransFile->dwSignature = DATA_RLE_SIG;
}
else
pTransFile->dwSignature = DATA_GTT_SIG;
if (hFontFile)
{
pTransFile->dwSize = dwFileSize;
while (pFirstFontDir < pUFFFontDir)
{
if (pFirstFontDir->sGlyphID == (SHORT)pTransFile->rcID)
pFirstFontDir->offGlyphData = dwOffset;
pFirstFontDir ++;
}
dwOffset += dwFileSize + sizeof(DATA_HEADER);
UnmapFileFromMemory(hFontFile);
}
else
return NULL;
pTransFile = pTransFile->pNext;
}
pCartList = pCartList->pNext;
}
if (gdwOutputFlags & OUTPUT_VERBOSE)
{
BDumpUFF(pUFFHeader);
}
*pdwUFFHeaderSize = dwUFFHeaderSize;
return (PBYTE)pUFFHeader;
}