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.
329 lines
9.5 KiB
329 lines
9.5 KiB
/*++
|
|
|
|
Copyright (c) 1996-1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
gpc2gpd.c
|
|
|
|
Abstract:
|
|
|
|
GPC-to-GPD conversion program
|
|
|
|
Environment:
|
|
|
|
User-mode, stand-alone utility tool
|
|
|
|
Revision History:
|
|
|
|
10/16/96 -zhanw-
|
|
Created it.
|
|
|
|
--*/
|
|
|
|
#include "gpc2gpd.h"
|
|
|
|
#if !defined(DEVSTUDIO) // MDT only uses onre routine
|
|
|
|
VOID
|
|
VUsage(
|
|
PSTR pstrProgName
|
|
)
|
|
|
|
{
|
|
printf("usage: gpc2gpd -I<GPC file>\r\n");
|
|
printf(" -M<model index>\r\n");
|
|
printf(" -R<resource DLL>\r\n");
|
|
printf(" -O<GPD file>\r\n");
|
|
printf(" -N<Model Name>\r\n");
|
|
printf(" -S<0> -- output display strings directly \r\n");
|
|
printf(" <1> -- output display strings as value macros\r\n");
|
|
printf(" (see stdnames.gpd) \r\n");
|
|
printf(" <2> -- output display strings as RC id's (see common.rc)\r\n");
|
|
printf(" -P -- if present, use spooler names for standard papersizes\r\n");
|
|
}
|
|
|
|
#endif //!defined(DEVSTUDIO)
|
|
|
|
void
|
|
VOutputGlobalEntries(
|
|
IN OUT PCONVINFO pci,
|
|
IN PSTR pstrModelName,
|
|
IN PSTR pstrResourceDLLName,
|
|
IN PSTR pstrGPDFileName)
|
|
{
|
|
VOut(pci, "*GPDSpecVersion: \"1.0\"\r\n");
|
|
|
|
|
|
//
|
|
// *CodePage should be defined in the included GPD file
|
|
//
|
|
if (pci->dwStrType == STR_MACRO)
|
|
VOut(pci, "*Include: \"StdNames.gpd\"\r\n");
|
|
else
|
|
VOut(pci, "*CodePage: 1252\r\n");
|
|
|
|
VOut(pci, "*GPDFileVersion: \"1.0\"\r\n");
|
|
VOut(pci, "*GPDFileName: \"%s\"\r\n", pstrGPDFileName);
|
|
|
|
VOut(pci, "*ModelName: \"%s\"\r\n", pstrModelName);
|
|
VOut(pci, "*MasterUnits: PAIR(%d, %d)\r\n", pci->pdh->ptMaster.x, pci->pdh->ptMaster.y);
|
|
VOut(pci, "*ResourceDLL: \"%s\"\r\n", pstrResourceDLLName);
|
|
|
|
if (pci->pdh->fTechnology == GPC_TECH_TTY)
|
|
VOut(pci, "*PrinterType: TTY\r\n");
|
|
else if (pci->pmd->fGeneral & MD_SERIAL)
|
|
VOut(pci, "*PrinterType: SERIAL\r\n");
|
|
else
|
|
VOut(pci, "*PrinterType: PAGE\r\n");
|
|
|
|
if ((pci->pmd->fGeneral & MD_COPIES) && pci->ppc->sMaxCopyCount > 1)
|
|
VOut(pci, "*MaxCopies: %d\r\n", pci->ppc->sMaxCopyCount);
|
|
if (pci->pmd->sCartSlots > 0)
|
|
VOut(pci, "*FontCartSlots: %d\r\n", pci->pmd->sCartSlots);
|
|
|
|
if (pci->pmd->fGeneral & MD_CMD_CALLBACK)
|
|
pci->dwErrorCode |= ERR_MD_CMD_CALLBACK;
|
|
}
|
|
|
|
#if !defined(DEVSTUDIO) // MDT only uses the above code
|
|
|
|
void
|
|
VPrintErrors(
|
|
IN HANDLE hLogFile,
|
|
IN DWORD dwError)
|
|
{
|
|
DWORD dwNumBytesWritten;
|
|
DWORD i, len;
|
|
|
|
for (i = 0; i < NUM_ERRS; i++)
|
|
{
|
|
if (dwError & gdwErrFlag[i])
|
|
{
|
|
len = strlen(gpstrErrMsg[i]);
|
|
|
|
if (!WriteFile(hLogFile, gpstrErrMsg[i], len, &dwNumBytesWritten, NULL) ||
|
|
dwNumBytesWritten != len)
|
|
return; // abort
|
|
}
|
|
}
|
|
}
|
|
|
|
INT _cdecl
|
|
main(
|
|
INT argc,
|
|
CHAR **argv
|
|
)
|
|
/*++
|
|
|
|
Routine Desscription:
|
|
|
|
This routine parses the command line parameters, maps the GPC file into memory
|
|
and creates the output GPD file. It then starts converting GPC data by calling
|
|
various sub-routines. If any error occurs, it reports errors and tries to
|
|
continue if possible.
|
|
|
|
The following command line parameters are supported:
|
|
-I<GPC_file> : the file name does not need double quotes. Ex. -Icanon330.gpc
|
|
-M<model_id>: an integer, such as 1, which is the string resource id of the
|
|
the model name in the .rc file that comes with the given GPC
|
|
file.
|
|
-N<model_name>: a string, such as "HP LaserJet 4L".
|
|
-R<resource_dll>: the resource dll to be associated with the generated GPD
|
|
file. Ex. -Rcanon330.dll
|
|
-O<GPD_file>: the output GPD file name. Ex. -Ohplj4l.gpd
|
|
-S<style>: the string style used in generating the GPD file for standard names.
|
|
-S0 means using the direct strings for *Name entries.
|
|
-S1 means using string value macros for *Name entries. This is
|
|
mainly used for on-the-fly conversion. The value macros are
|
|
defined in printer5\inc\stdnames.gpd.
|
|
-S2 means using RC string id's. These strings are defined in
|
|
printer5\inc\common.rc.
|
|
-P rcNameID: 0x7fffffff for standard papersizes.
|
|
|
|
Arguments:
|
|
argc - number of arguments
|
|
**argv - pointer to an array of strings
|
|
|
|
Return value:
|
|
0
|
|
|
|
--*/
|
|
{
|
|
PSTR pstrProgName;
|
|
PSTR pstrGPCFileName = NULL;
|
|
WCHAR wstrGPCFile[MAX_PATH];
|
|
PSTR pstrGPDFileName = NULL;
|
|
WCHAR wstrGPDFile[MAX_PATH];
|
|
PSTR pstrResourceDLLName = NULL;
|
|
PSTR pstrModelName = NULL;
|
|
HFILEMAP hGPCFileMap;
|
|
CONVINFO ci; // structure to keep track conversion information
|
|
DWORD dwStrType = STR_MACRO; // default
|
|
WORD wModelIndex;
|
|
BOOL bUseSystemPaperNames = FALSE;
|
|
|
|
|
|
//
|
|
// Go through the command line arguments
|
|
//
|
|
|
|
pstrProgName = *argv++;
|
|
argc--;
|
|
|
|
if (argc == 0)
|
|
goto error_exit;
|
|
|
|
for ( ; argc--; argv++)
|
|
{
|
|
PSTR pArg = *argv;
|
|
|
|
if (*pArg == '-' || *pArg == '/')
|
|
{
|
|
switch (*++pArg)
|
|
{
|
|
case 'I':
|
|
pstrGPCFileName = ++pArg;
|
|
break;
|
|
|
|
case 'M':
|
|
wModelIndex = (WORD)atoi(++pArg);
|
|
break;
|
|
|
|
case 'R':
|
|
pstrResourceDLLName = ++pArg;
|
|
break;
|
|
|
|
case 'O':
|
|
pstrGPDFileName = ++pArg;
|
|
break;
|
|
|
|
case 'N':
|
|
pstrModelName = ++pArg;
|
|
break;
|
|
|
|
case 'S':
|
|
dwStrType = atoi(++pArg);
|
|
break;
|
|
|
|
case 'P':
|
|
bUseSystemPaperNames = TRUE;
|
|
break;
|
|
|
|
default:
|
|
goto error_exit;
|
|
}
|
|
}
|
|
else
|
|
goto error_exit;
|
|
}
|
|
|
|
//
|
|
// check if we have all the arguments needed
|
|
//
|
|
if (!pstrGPCFileName || !pstrGPDFileName || !pstrResourceDLLName ||
|
|
!wModelIndex || !pstrModelName)
|
|
goto error_exit;
|
|
|
|
ZeroMemory((PVOID)&ci, sizeof(CONVINFO));
|
|
|
|
//
|
|
// Open the GPC file and map it into memory.
|
|
//
|
|
MultiByteToWideChar(CP_ACP, 0, pstrGPCFileName, -1, wstrGPCFile, MAX_PATH);
|
|
hGPCFileMap = MapFileIntoMemory((LPCTSTR)wstrGPCFile, (PVOID *)&(ci.pdh), NULL);
|
|
if (!hGPCFileMap)
|
|
{
|
|
ERR(("Couldn't open file: %ws\r\n", pstrGPCFileName));
|
|
return (-1);
|
|
}
|
|
//
|
|
// create the output GPD file. If the given file already exists,
|
|
// overwrite it.
|
|
//
|
|
MultiByteToWideChar(CP_ACP, 0, pstrGPDFileName, -1, wstrGPDFile, MAX_PATH);
|
|
ci.hGPDFile = CreateFile((PCTSTR)wstrGPDFile, GENERIC_WRITE, 0, NULL,
|
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (ci.hGPDFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
ERR(("Couldn't create file: %ws\r\n", pstrGPDFileName));
|
|
UnmapFileFromMemory(hGPCFileMap);
|
|
return (-1);
|
|
}
|
|
|
|
//
|
|
// GPC file sanity check
|
|
//
|
|
if (ci.pdh->sMagic != 0x7F00 ||
|
|
!(ci.pmd = (PMODELDATA)GetTableInfo(ci.pdh, HE_MODELDATA, wModelIndex-1)) ||
|
|
!(ci.ppc = (PPAGECONTROL)GetTableInfo(ci.pdh, HE_PAGECONTROL,
|
|
ci.pmd->rgi[MD_I_PAGECONTROL])))
|
|
{
|
|
ci.dwErrorCode |= ERR_BAD_GPCDATA;
|
|
goto exit;
|
|
}
|
|
//
|
|
// allocate dynamic buffers needed for conversion
|
|
//
|
|
if (!(ci.ppiSize=(PPAPERINFO)MemAllocZ(ci.pdh->rghe[HE_PAPERSIZE].sCount*sizeof(PAPERINFO))) ||
|
|
!(ci.ppiSrc=(PPAPERINFO)MemAllocZ(ci.pdh->rghe[HE_PAPERSOURCE].sCount*sizeof(PAPERINFO))) ||
|
|
!(ci.presinfo=(PRESINFO)MemAllocZ(ci.pdh->rghe[HE_RESOLUTION].sCount*sizeof(RESINFO))))
|
|
{
|
|
ci.dwErrorCode |= ERR_OUT_OF_MEMORY;
|
|
goto exit;
|
|
}
|
|
|
|
ci.dwStrType = dwStrType;
|
|
ci.bUseSystemPaperNames = bUseSystemPaperNames ;
|
|
|
|
//
|
|
// generate GPD data
|
|
//
|
|
VOutputGlobalEntries(&ci, pstrModelName, pstrResourceDLLName, pstrGPDFileName);
|
|
VOutputUIEntries(&ci);
|
|
VOutputPrintingEntries(&ci);
|
|
|
|
exit:
|
|
UnmapFileFromMemory(hGPCFileMap);
|
|
CloseHandle(ci.hGPDFile);
|
|
if (ci.ppiSize)
|
|
MemFree(ci.ppiSize);
|
|
if (ci.ppiSrc)
|
|
MemFree(ci.ppiSrc);
|
|
if (ci.presinfo)
|
|
MemFree(ci.presinfo);
|
|
if (ci.dwErrorCode)
|
|
{
|
|
PWSTR pwstrLogFileName;
|
|
INT i;
|
|
HANDLE hLogFile;
|
|
|
|
//
|
|
// Open the log file and print out errors/warnings.
|
|
// Borrow the GPD file name buffer.
|
|
//
|
|
pwstrLogFileName = wstrGPDFile;
|
|
i = _tcslen((PTSTR)pwstrLogFileName);
|
|
if (_tcsrchr((PTSTR)pwstrLogFileName, TEXT('.')) != NULL)
|
|
i = i - 4; // there is a .GPD extension
|
|
StringCchCopyW((PTSTR)pwstrLogFileName + i, CCHOF(wstrGPDFile) - i, TEXT(".log"));
|
|
|
|
hLogFile = CreateFile((PCTSTR)pwstrLogFileName, GENERIC_WRITE, 0, NULL,
|
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (hLogFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
ERR(("Couldn't create the log file\r\n"));
|
|
return (-1);
|
|
}
|
|
VPrintErrors(hLogFile, ci.dwErrorCode);
|
|
CloseHandle(hLogFile);
|
|
}
|
|
|
|
return 0;
|
|
|
|
error_exit:
|
|
VUsage(pstrProgName);
|
|
return (-1);
|
|
}
|
|
|
|
#endif // !defined(DEVSTUDIO)
|