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.
1565 lines
41 KiB
1565 lines
41 KiB
/*++
|
|
|
|
Copyright (c) 1996-1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
psutil.c
|
|
|
|
Abstract:
|
|
|
|
PostScript utility functions
|
|
BInitDriverDefaultDevmode
|
|
BMergeDriverDevmode
|
|
VCopyUnicodeStringToAnsi
|
|
PGetAndConvertOldVersionFormTrayTable
|
|
BSaveAsOldVersionFormTrayTable
|
|
|
|
Environment:
|
|
|
|
Windows NT printer drivers
|
|
|
|
Revision History:
|
|
|
|
12/03/97 -fengy-
|
|
Added VUpdatePrivatePrinterData to split fixed fields in PrinterData
|
|
into Keyword/Value pairs in Registry.
|
|
|
|
04/17/97 -davidx-
|
|
Provide OEM plugins access to driver private devmode settings.
|
|
|
|
02/04/97 -davidx-
|
|
Devmode changes to support OEM plugins.
|
|
|
|
10/02/96 -davidx-
|
|
Implement BPSMergeDevmode.
|
|
|
|
09/26/96 -davidx-
|
|
Created it.
|
|
|
|
--*/
|
|
|
|
#include "lib.h"
|
|
#include "ppd.h"
|
|
#include "pslib.h"
|
|
#include "oemutil.h"
|
|
|
|
//
|
|
// Information about PostScript driver private devmode
|
|
//
|
|
|
|
CONST DRIVER_DEVMODE_INFO gDriverDMInfo =
|
|
{
|
|
PSDRIVER_VERSION, sizeof(PSDRVEXTRA),
|
|
PSDRIVER_VERSION_500, sizeof(PSDRVEXTRA500),
|
|
PSDRIVER_VERSION_400, sizeof(PSDRVEXTRA400),
|
|
PSDRIVER_VERSION_351, sizeof(PSDRVEXTRA351),
|
|
};
|
|
|
|
CONST DWORD gdwDriverDMSignature = PSDEVMODE_SIGNATURE;
|
|
CONST WORD gwDriverVersion = PSDRIVER_VERSION;
|
|
|
|
|
|
|
|
static VOID
|
|
VInitNewPrivateFields(
|
|
PRAWBINARYDATA pRawData,
|
|
PUIINFO pUIInfo,
|
|
PPSDRVEXTRA pdmPrivate,
|
|
BOOL bInitAllFields
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Intialize the new private devmode fields for PS 5.0
|
|
|
|
Arguments:
|
|
|
|
pUIInfo - Points to a UIINFO structure
|
|
pRawData - Points to raw binary printer description data
|
|
pdmPrivate - Points to the private devmode fields to be initialized
|
|
bInitAllFields - Whether to initialize all new private fields or
|
|
initialize the options array only
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
if (bInitAllFields)
|
|
{
|
|
pdmPrivate->wReserved1 = 0;
|
|
pdmPrivate->wSize = sizeof(PSDRVEXTRA);
|
|
|
|
pdmPrivate->fxScrFreq = 0;
|
|
pdmPrivate->fxScrAngle = 0;
|
|
pdmPrivate->iDialect = SPEED;
|
|
pdmPrivate->iTTDLFmt = TT_DEFAULT;
|
|
pdmPrivate->bReversePrint = FALSE;
|
|
pdmPrivate->iLayout = ONE_UP;
|
|
pdmPrivate->iPSLevel = pUIInfo->dwLangLevel;
|
|
|
|
pdmPrivate->wOEMExtra = 0;
|
|
pdmPrivate->wVer = PSDRVEXTRA_VERSION;
|
|
|
|
pdmPrivate->dwReserved2 = 0;
|
|
ZeroMemory(pdmPrivate->dwReserved3, sizeof(pdmPrivate->dwReserved3));
|
|
}
|
|
|
|
InitDefaultOptions(pRawData,
|
|
pdmPrivate->aOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
MODE_DOCUMENT_STICKY);
|
|
|
|
pdmPrivate->dwOptions = pRawData->dwDocumentFeatures;
|
|
pdmPrivate->dwChecksum32 = pRawData->dwChecksum32;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
BInitDriverDefaultDevmode(
|
|
OUT PDEVMODE pdmOut,
|
|
IN LPCTSTR ptstrPrinterName,
|
|
IN PUIINFO pUIInfo,
|
|
IN PRAWBINARYDATA pRawData,
|
|
IN BOOL bMetric
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Return the driver default devmode
|
|
|
|
Arguments:
|
|
|
|
pdmOut - Points to the output devmode to be initialized
|
|
ptstrPrinterName - Specifies the name of the printer
|
|
pUIInfo - Points to a UIINFO structure
|
|
pRawData - Points to raw binary printer description data
|
|
bMetric - Whether the system is running in metric mode
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
Note:
|
|
|
|
This function should initialize both public devmode fields
|
|
and driver private devmode fields. It's also assumed that
|
|
output buffer has already been zero initialized by the caller.
|
|
|
|
--*/
|
|
|
|
{
|
|
PPSDRVEXTRA pdmPrivate;
|
|
PFEATURE pFeature;
|
|
PPPDDATA pPpdData;
|
|
|
|
//
|
|
// Initialize public devmode fields
|
|
//
|
|
|
|
pPpdData = GET_DRIVER_INFO_FROM_INFOHEADER((PINFOHEADER) pRawData);
|
|
|
|
ASSERT(pPpdData != NULL);
|
|
|
|
pdmOut->dmDriverVersion = PSDRIVER_VERSION;
|
|
pdmOut->dmSpecVersion = DM_SPECVERSION;
|
|
pdmOut->dmSize = sizeof(DEVMODE);
|
|
pdmOut->dmDriverExtra = sizeof(PSDRVEXTRA);
|
|
|
|
pdmOut->dmFields = DM_ORIENTATION |
|
|
DM_SCALE |
|
|
DM_COPIES |
|
|
DM_PRINTQUALITY |
|
|
DM_YRESOLUTION |
|
|
DM_TTOPTION |
|
|
#ifndef WINNT_40
|
|
DM_NUP |
|
|
#endif
|
|
DM_COLOR |
|
|
DM_DEFAULTSOURCE;
|
|
|
|
pdmOut->dmOrientation = DMORIENT_PORTRAIT;
|
|
pdmOut->dmDuplex = DMDUP_SIMPLEX;
|
|
pdmOut->dmCollate = DMCOLLATE_FALSE;
|
|
pdmOut->dmMediaType = DMMEDIA_STANDARD;
|
|
pdmOut->dmTTOption = DMTT_SUBDEV;
|
|
pdmOut->dmColor = DMCOLOR_MONOCHROME;
|
|
pdmOut->dmDefaultSource = DMBIN_FORMSOURCE;
|
|
pdmOut->dmScale = 100;
|
|
pdmOut->dmCopies = 1;
|
|
pdmOut->dmPrintQuality =
|
|
pdmOut->dmYResolution = DEFAULT_RESOLUTION;
|
|
#ifndef WINNT_40
|
|
pdmOut->dmNup = DMNUP_SYSTEM;
|
|
#endif
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_RESOLUTION))
|
|
{
|
|
PRESOLUTION pRes;
|
|
|
|
//
|
|
// Use the default resolution specified in the PPD file
|
|
//
|
|
|
|
if (pRes = PGetIndexedOption(pUIInfo, pFeature, pFeature->dwDefaultOptIndex))
|
|
{
|
|
pdmOut->dmPrintQuality = (short)pRes->iXdpi;
|
|
pdmOut->dmYResolution = (short)pRes->iYdpi;
|
|
}
|
|
}
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_DUPLEX))
|
|
{
|
|
PDUPLEX pDuplex;
|
|
|
|
//
|
|
// Use the default duplex option specified in the PPD file
|
|
//
|
|
|
|
pdmOut->dmFields |= DM_DUPLEX;
|
|
|
|
if (pDuplex = PGetIndexedOption(pUIInfo, pFeature, pFeature->dwDefaultOptIndex))
|
|
pdmOut->dmDuplex = (SHORT) pDuplex->dwDuplexID;
|
|
}
|
|
|
|
#ifdef WINNT_40
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_COLLATE))
|
|
{
|
|
PCOLLATE pCollate;
|
|
|
|
pdmOut->dmFields |= DM_COLLATE;
|
|
|
|
if (pCollate = PGetIndexedOption(pUIInfo, pFeature, pFeature->dwDefaultOptIndex))
|
|
pdmOut->dmCollate = (SHORT) pCollate->dwCollateID;
|
|
}
|
|
|
|
#else // !WINNT_40
|
|
|
|
pdmOut->dmFields |= DM_COLLATE;
|
|
pdmOut->dmCollate = DMCOLLATE_TRUE;
|
|
|
|
#endif // !WINNT_40
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_MEDIATYPE))
|
|
{
|
|
//
|
|
// Use the default media type specified in the PPD file
|
|
//
|
|
|
|
pdmOut->dmFields |= DM_MEDIATYPE;
|
|
|
|
if (pFeature->dwDefaultOptIndex != OPTION_INDEX_ANY)
|
|
pdmOut->dmMediaType = DMMEDIA_USER + pFeature->dwDefaultOptIndex;
|
|
}
|
|
|
|
//
|
|
// Adobe wants to preserve the color information even for b/w printers.
|
|
// So for both b/w and color printers, turn color on by default for Adobe.
|
|
//
|
|
|
|
#ifndef ADOBE
|
|
|
|
if (IS_COLOR_DEVICE(pUIInfo))
|
|
{
|
|
|
|
#endif // !ADOBE
|
|
|
|
//
|
|
// Turn color on by default
|
|
//
|
|
|
|
pdmOut->dmColor = DMCOLOR_COLOR;
|
|
pdmOut->dmFields |= DM_COLOR;
|
|
|
|
#ifndef ADOBE
|
|
|
|
}
|
|
|
|
#endif // !ADOBE
|
|
|
|
//
|
|
// We always set ICM off. The spooler will turn it on at install time
|
|
// if there are color profiles installed with this printer
|
|
//
|
|
|
|
pdmOut->dmICMMethod = DMICMMETHOD_NONE;
|
|
pdmOut->dmICMIntent = DMICM_CONTRAST;
|
|
|
|
#ifndef WINNT_40
|
|
|
|
#ifndef ADOBE
|
|
|
|
if (IS_COLOR_DEVICE(pUIInfo))
|
|
{
|
|
|
|
#endif // !ADOBE
|
|
|
|
pdmOut->dmFields |= (DM_ICMMETHOD | DM_ICMINTENT);
|
|
|
|
#ifndef ADOBE
|
|
|
|
}
|
|
|
|
#endif // !ADOBE
|
|
|
|
#endif // !WINNT_40
|
|
|
|
//
|
|
// dmDeviceName field will be filled elsewhere.
|
|
// Use an arbitrary default value if the input parameter is NULL.
|
|
//
|
|
|
|
CopyString(pdmOut->dmDeviceName,
|
|
ptstrPrinterName ? ptstrPrinterName : TEXT("PostScript"),
|
|
CCHDEVICENAME);
|
|
|
|
//
|
|
// Initialize form-related fields
|
|
//
|
|
|
|
VDefaultDevmodeFormFields(pUIInfo, pdmOut, bMetric);
|
|
|
|
//
|
|
// Private devmode fields
|
|
//
|
|
|
|
pdmPrivate = (PPSDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdmOut);
|
|
pdmPrivate->dwSignature = PSDEVMODE_SIGNATURE;
|
|
pdmPrivate->coloradj = gDefaultHTColorAdjustment;
|
|
|
|
#ifndef WINNT_40
|
|
pdmPrivate->dwFlags = PSDEVMODE_METAFILE_SPOOL;
|
|
#endif
|
|
|
|
if (pPpdData->dwFlags & PPDFLAG_PRINTPSERROR)
|
|
pdmPrivate->dwFlags |= PSDEVMODE_EHANDLER;
|
|
|
|
if (pUIInfo->dwLangLevel > 1)
|
|
pdmPrivate->dwFlags |= PSDEVMODE_COMPRESSBMP;
|
|
|
|
#ifndef KERNEL_MODE
|
|
|
|
//
|
|
// Set up some private devmode flag bits for compatibility
|
|
// with previous versions of the driver.
|
|
//
|
|
|
|
pdmPrivate->dwFlags |= PSDEVMODE_CTRLD_AFTER;
|
|
|
|
if (GetACP() == 1252)
|
|
pdmPrivate->dwFlags |= (PSDEVMODE_FONTSUBST|PSDEVMODE_ENUMPRINTERFONTS);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Intialize the new private devmode fields for PS 5.0
|
|
//
|
|
|
|
VInitNewPrivateFields(pRawData, pUIInfo, pdmPrivate, TRUE);
|
|
|
|
if (SUPPORT_CUSTOMSIZE(pUIInfo))
|
|
{
|
|
VFillDefaultCustomPageSizeData(pRawData, &pdmPrivate->csdata, bMetric);
|
|
}
|
|
else
|
|
{
|
|
ZeroMemory(&pdmPrivate->csdata, sizeof(pdmPrivate->csdata));
|
|
pdmPrivate->csdata.dwX = pdmOut->dmPaperWidth * DEVMODE_PAPER_UNIT;
|
|
pdmPrivate->csdata.dwY = pdmOut->dmPaperLength * DEVMODE_PAPER_UNIT;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
BMergeDriverDevmode(
|
|
IN OUT PDEVMODE pdmOut,
|
|
IN PUIINFO pUIInfo,
|
|
IN PRAWBINARYDATA pRawData,
|
|
IN PDEVMODE pdmIn
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Merge the input devmode with an existing devmode.
|
|
|
|
Arguments:
|
|
|
|
pdmOut - Points to a valid output devmode
|
|
pUIInfo - Points to a UIINFO structure
|
|
pRawData - Points to raw binary printer description data
|
|
pdmIn - Points to the input devmode
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is a fatal error
|
|
|
|
Note:
|
|
|
|
This function should take care of both public devmode fields
|
|
and driver private devmode fields. It can assume the input
|
|
devmode has already been convert to the current size.
|
|
|
|
--*/
|
|
|
|
{
|
|
PPSDRVEXTRA pdmPrivateIn, pdmPrivateOut;
|
|
PFEATURE pFeature;
|
|
PPPDDATA pPpdData;
|
|
|
|
ASSERT(pdmOut != NULL &&
|
|
pdmOut->dmSize == sizeof(DEVMODE) &&
|
|
pdmOut->dmDriverExtra >= sizeof(PSDRVEXTRA) &&
|
|
pdmIn != NULL &&
|
|
pdmIn->dmSize == sizeof(DEVMODE) &&
|
|
pdmIn->dmDriverExtra >= sizeof(PSDRVEXTRA));
|
|
|
|
pdmPrivateIn = (PPSDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdmIn);
|
|
pdmPrivateOut = (PPSDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdmOut);
|
|
pPpdData = GET_DRIVER_INFO_FROM_INFOHEADER((PINFOHEADER) pRawData);
|
|
|
|
ASSERT(pPpdData != NULL);
|
|
|
|
//
|
|
// Merge the public devmode fields
|
|
//
|
|
#ifndef WINNT_40
|
|
if ( (pdmIn->dmFields & DM_NUP) &&
|
|
(pdmIn->dmNup == DMNUP_SYSTEM ||
|
|
pdmIn->dmNup == DMNUP_ONEUP))
|
|
{
|
|
pdmOut->dmNup = pdmIn->dmNup;
|
|
pdmOut->dmFields |= DM_NUP;
|
|
}
|
|
|
|
#endif // #ifndef WINNT_40
|
|
|
|
if (pdmIn->dmFields & DM_DEFAULTSOURCE &&
|
|
((pdmIn->dmDefaultSource >= DMBIN_FIRST &&
|
|
pdmIn->dmDefaultSource <= DMBIN_LAST) ||
|
|
pdmIn->dmDefaultSource >= DMBIN_USER))
|
|
{
|
|
pdmOut->dmFields |= DM_DEFAULTSOURCE;
|
|
pdmOut->dmDefaultSource = pdmIn->dmDefaultSource;
|
|
}
|
|
|
|
if ((pdmIn->dmFields & DM_ORIENTATION) &&
|
|
(pdmIn->dmOrientation == DMORIENT_PORTRAIT ||
|
|
pdmIn->dmOrientation == DMORIENT_LANDSCAPE))
|
|
{
|
|
pdmOut->dmFields |= DM_ORIENTATION;
|
|
pdmOut->dmOrientation = pdmIn->dmOrientation;
|
|
}
|
|
|
|
//
|
|
// If both DM_PAPERLENGTH and DM_PAPERWIDTH are set, copy
|
|
// dmPaperLength and dmPaperWidth fields. If DM_PAPERSIZE
|
|
// is set, copy dmPaperSize field. Otherwise, if DM_FORMNAME
|
|
// is set, copy dmFormName field.
|
|
//
|
|
|
|
if ((pdmIn->dmFields & DM_PAPERWIDTH) &&
|
|
(pdmIn->dmFields & DM_PAPERLENGTH) &&
|
|
(pdmIn->dmPaperWidth > 0) &&
|
|
(pdmIn->dmPaperLength > 0))
|
|
{
|
|
pdmOut->dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH);
|
|
pdmOut->dmFields &= ~(DM_PAPERSIZE | DM_FORMNAME);
|
|
pdmOut->dmPaperWidth = pdmIn->dmPaperWidth;
|
|
pdmOut->dmPaperLength = pdmIn->dmPaperLength;
|
|
}
|
|
else if (pdmIn->dmFields & DM_PAPERSIZE)
|
|
{
|
|
if ((pdmIn->dmPaperSize != DMPAPER_CUSTOMSIZE) ||
|
|
SUPPORT_CUSTOMSIZE(pUIInfo) &&
|
|
SUPPORT_FULL_CUSTOMSIZE_FEATURES(pUIInfo, pPpdData))
|
|
{
|
|
pdmOut->dmFields |= DM_PAPERSIZE;
|
|
pdmOut->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH | DM_FORMNAME);
|
|
pdmOut->dmPaperSize = pdmIn->dmPaperSize;
|
|
}
|
|
}
|
|
else if (pdmIn->dmFields & DM_FORMNAME)
|
|
{
|
|
pdmOut->dmFields |= DM_FORMNAME;
|
|
pdmOut->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH | DM_PAPERSIZE);
|
|
CopyString(pdmOut->dmFormName, pdmIn->dmFormName, CCHFORMNAME);
|
|
}
|
|
|
|
if ((pdmIn->dmFields & DM_SCALE) &&
|
|
(pdmIn->dmScale >= MIN_SCALE) &&
|
|
(pdmIn->dmScale <= MAX_SCALE))
|
|
{
|
|
pdmOut->dmFields |= DM_SCALE;
|
|
pdmOut->dmScale = pdmIn->dmScale;
|
|
}
|
|
|
|
if ((pdmIn->dmFields & DM_COPIES) &&
|
|
(pdmIn->dmCopies >= 1) &&
|
|
(pdmIn->dmCopies <= (SHORT) pUIInfo->dwMaxCopies))
|
|
{
|
|
pdmOut->dmFields |= DM_COPIES;
|
|
pdmOut->dmCopies = pdmIn->dmCopies;
|
|
}
|
|
|
|
if ((pdmIn->dmFields & DM_DUPLEX) &&
|
|
(GET_PREDEFINED_FEATURE(pUIInfo, GID_DUPLEX) != NULL) &&
|
|
(pdmIn->dmDuplex == DMDUP_SIMPLEX ||
|
|
pdmIn->dmDuplex == DMDUP_HORIZONTAL ||
|
|
pdmIn->dmDuplex == DMDUP_VERTICAL))
|
|
{
|
|
pdmOut->dmFields |= DM_DUPLEX;
|
|
pdmOut->dmDuplex = pdmIn->dmDuplex;
|
|
}
|
|
|
|
if ((pdmIn->dmFields & DM_COLLATE) &&
|
|
|
|
#ifdef WINNT_40
|
|
GET_PREDEFINED_FEATURE(pUIInfo, GID_COLLATE) != NULL &&
|
|
#endif
|
|
|
|
(pdmIn->dmCollate == DMCOLLATE_TRUE ||
|
|
pdmIn->dmCollate == DMCOLLATE_FALSE))
|
|
{
|
|
pdmOut->dmFields |= DM_COLLATE;
|
|
pdmOut->dmCollate = pdmIn->dmCollate;
|
|
}
|
|
|
|
if ((pdmIn->dmFields & DM_TTOPTION) &&
|
|
(pdmIn->dmTTOption == DMTT_BITMAP ||
|
|
pdmIn->dmTTOption == DMTT_DOWNLOAD ||
|
|
pdmIn->dmTTOption == DMTT_SUBDEV))
|
|
{
|
|
pdmOut->dmFields |= DM_TTOPTION;
|
|
pdmOut->dmTTOption = (pdmIn->dmTTOption == DMTT_SUBDEV) ? DMTT_SUBDEV : DMTT_DOWNLOAD;
|
|
}
|
|
|
|
//
|
|
// Merge color and ICM fields.
|
|
//
|
|
|
|
#ifndef ADOBE
|
|
|
|
if (IS_COLOR_DEVICE(pUIInfo))
|
|
{
|
|
|
|
#endif // !ADOBE
|
|
|
|
if ((pdmIn->dmFields & DM_COLOR) &&
|
|
(pdmIn->dmColor == DMCOLOR_COLOR ||
|
|
pdmIn->dmColor == DMCOLOR_MONOCHROME))
|
|
{
|
|
pdmOut->dmFields |= DM_COLOR;
|
|
pdmOut->dmColor = pdmIn->dmColor;
|
|
}
|
|
|
|
#ifndef WINNT_40
|
|
|
|
if ((pdmIn->dmFields & DM_ICMMETHOD) &&
|
|
(pdmIn->dmICMMethod == DMICMMETHOD_NONE ||
|
|
pdmIn->dmICMMethod == DMICMMETHOD_SYSTEM ||
|
|
pdmIn->dmICMMethod == DMICMMETHOD_DRIVER ||
|
|
pdmIn->dmICMMethod == DMICMMETHOD_DEVICE))
|
|
{
|
|
pdmOut->dmFields |= DM_ICMMETHOD;
|
|
pdmOut->dmICMMethod = pdmIn->dmICMMethod;
|
|
}
|
|
|
|
if ((pdmIn->dmFields & DM_ICMINTENT) &&
|
|
(pdmIn->dmICMIntent == DMICM_SATURATE ||
|
|
pdmIn->dmICMIntent == DMICM_CONTRAST ||
|
|
pdmIn->dmICMIntent == DMICM_COLORIMETRIC ||
|
|
pdmIn->dmICMIntent == DMICM_ABS_COLORIMETRIC))
|
|
{
|
|
pdmOut->dmFields |= DM_ICMINTENT;
|
|
pdmOut->dmICMIntent = pdmIn->dmICMIntent;
|
|
}
|
|
|
|
#endif // !WINNT_40
|
|
|
|
#ifndef ADOBE
|
|
|
|
}
|
|
|
|
#endif // !ADOBE
|
|
|
|
//
|
|
// Resolution
|
|
//
|
|
|
|
if ((pdmIn->dmFields & (DM_PRINTQUALITY|DM_YRESOLUTION)) &&
|
|
(pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_RESOLUTION)))
|
|
{
|
|
PRESOLUTION pRes;
|
|
DWORD dwIndex;
|
|
INT iXdpi, iYdpi;
|
|
|
|
switch (pdmIn->dmFields & (DM_PRINTQUALITY|DM_YRESOLUTION))
|
|
{
|
|
case DM_PRINTQUALITY:
|
|
|
|
iXdpi = iYdpi = pdmIn->dmPrintQuality;
|
|
break;
|
|
|
|
case DM_YRESOLUTION:
|
|
|
|
iXdpi = iYdpi = pdmIn->dmYResolution;
|
|
break;
|
|
|
|
default:
|
|
|
|
iXdpi = pdmIn->dmPrintQuality;
|
|
iYdpi = pdmIn->dmYResolution;
|
|
break;
|
|
}
|
|
|
|
dwIndex = MapToDeviceOptIndex(pUIInfo->pInfoHeader,
|
|
GID_RESOLUTION,
|
|
iXdpi,
|
|
iYdpi,
|
|
NULL);
|
|
|
|
if (pRes = PGetIndexedOption(pUIInfo, pFeature, dwIndex))
|
|
{
|
|
pdmOut->dmFields |= (DM_PRINTQUALITY|DM_YRESOLUTION);
|
|
pdmOut->dmPrintQuality = (short)pRes->iXdpi;
|
|
pdmOut->dmYResolution = (short)pRes->iYdpi;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Media type
|
|
//
|
|
|
|
if ((pdmIn->dmFields & DM_MEDIATYPE) &&
|
|
(pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_MEDIATYPE)) &&
|
|
(pdmIn->dmMediaType == DMMEDIA_STANDARD ||
|
|
pdmIn->dmMediaType == DMMEDIA_TRANSPARENCY ||
|
|
pdmIn->dmMediaType == DMMEDIA_GLOSSY ||
|
|
((pdmIn->dmMediaType >= DMMEDIA_USER) &&
|
|
(pdmIn->dmMediaType < DMMEDIA_USER + pFeature->Options.dwCount))))
|
|
{
|
|
pdmOut->dmFields |= DM_MEDIATYPE;
|
|
pdmOut->dmMediaType = pdmIn->dmMediaType;
|
|
}
|
|
|
|
//
|
|
// Merge the private devmode fields
|
|
//
|
|
|
|
if (pdmPrivateIn->dwSignature == PSDEVMODE_SIGNATURE)
|
|
{
|
|
CopyMemory(pdmPrivateOut, pdmPrivateIn, sizeof(PSDRVEXTRA));
|
|
|
|
if (pdmPrivateOut->dwChecksum32 != pRawData->dwChecksum32)
|
|
{
|
|
WARNING(("PSCRIPT5: Devmode checksum mismatch.\n"));
|
|
|
|
//
|
|
// Intialize the new private devmode fields for PS 5.0.
|
|
// If wReserved1 field is not 0, then the devmode is of
|
|
// a previous version. In that case, we should initialize
|
|
// all new private fields instead of just the options array.
|
|
//
|
|
|
|
VInitNewPrivateFields(pRawData,
|
|
pUIInfo,
|
|
pdmPrivateOut,
|
|
pdmPrivateOut->wReserved1 != 0);
|
|
|
|
|
|
//
|
|
// Convert PS4 feature/option selections to PS4 format
|
|
//
|
|
|
|
if (pdmPrivateIn->wReserved1 == pPpdData->dwNt4Checksum)
|
|
{
|
|
VConvertOptSelectArray(pRawData,
|
|
pdmPrivateOut->aOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
((PSDRVEXTRA400 *) pdmPrivateIn)->aubOptions,
|
|
64,
|
|
MODE_DOCUMENT_STICKY);
|
|
}
|
|
}
|
|
|
|
if (pdmPrivateOut->iPSLevel == 0 ||
|
|
pdmPrivateOut->iPSLevel > (INT) pUIInfo->dwLangLevel)
|
|
{
|
|
pdmPrivateOut->iPSLevel = pUIInfo->dwLangLevel;
|
|
}
|
|
|
|
if (pdmPrivateOut->iTTDLFmt == TYPE_42 && pUIInfo->dwTTRasterizer != TTRAS_TYPE42)
|
|
pdmPrivateOut->iTTDLFmt = TT_DEFAULT;
|
|
|
|
if (IS_COLOR_DEVICE(pUIInfo))
|
|
{
|
|
pdmPrivateOut->dwFlags &= ~PSDEVMODE_NEG;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If custom page size is supported, make sure the custom page
|
|
// size parameters are valid.
|
|
//
|
|
|
|
if (SUPPORT_CUSTOMSIZE(pUIInfo))
|
|
(VOID) BValidateCustomPageSizeData(pRawData, &pdmPrivateOut->csdata);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
BValidateDevmodeCustomPageSizeFields(
|
|
PRAWBINARYDATA pRawData,
|
|
PUIINFO pUIInfo,
|
|
PDEVMODE pdm,
|
|
PRECTL prclImageArea
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check if the devmode form fields are specifying PostScript custom page size
|
|
|
|
Arguments:
|
|
|
|
pRawData - Points to raw printer description data
|
|
pUIInfo - Points to UIINFO structure
|
|
pdm - Points to input devmode
|
|
prclImageArea - Returns imageable area of the custom page size
|
|
|
|
Return Value:
|
|
|
|
TRUE if the devmode specifies PostScript custom page size
|
|
FALSE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
PPPDDATA pPpdData;
|
|
PPSDRVEXTRA pdmPrivate;
|
|
|
|
pPpdData = GET_DRIVER_INFO_FROM_INFOHEADER((PINFOHEADER) pRawData);
|
|
|
|
ASSERT(pPpdData != NULL);
|
|
|
|
if ((pdm->dmFields & DM_PAPERSIZE) &&
|
|
pdm->dmPaperSize == DMPAPER_CUSTOMSIZE &&
|
|
SUPPORT_CUSTOMSIZE(pUIInfo) &&
|
|
SUPPORT_FULL_CUSTOMSIZE_FEATURES(pUIInfo, pPpdData))
|
|
{
|
|
pdmPrivate = (PPSDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdm);
|
|
|
|
pdm->dmFields &= ~(DM_PAPERWIDTH|DM_PAPERLENGTH|DM_FORMNAME);
|
|
pdm->dmPaperWidth = (SHORT) (pdmPrivate->csdata.dwX / DEVMODE_PAPER_UNIT);
|
|
pdm->dmPaperLength = (SHORT) (pdmPrivate->csdata.dwY / DEVMODE_PAPER_UNIT);
|
|
ZeroMemory(pdm->dmFormName, sizeof(pdm->dmFormName));
|
|
|
|
if (prclImageArea)
|
|
{
|
|
prclImageArea->left =
|
|
prclImageArea->top = 0;
|
|
prclImageArea->right = pdmPrivate->csdata.dwX;
|
|
prclImageArea->bottom = pdmPrivate->csdata.dwY;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
VCopyUnicodeStringToAnsi(
|
|
PSTR pstr,
|
|
PCWSTR pwstr,
|
|
INT iMaxChars
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert an ANSI string to a UNICODE string (using the current ANSI codepage)
|
|
|
|
Arguments:
|
|
|
|
pstr - Pointer to buffer for holding ANSI string
|
|
pwstr - Pointer to Unicode string
|
|
iMaxChars - Maximum number of ANSI characters to copy
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
Note:
|
|
|
|
If iMaxChars is 0 or negative, we assume the caller has provided
|
|
an ANSI buffer that's sufficiently large to do the conversion.
|
|
|
|
--*/
|
|
|
|
{
|
|
INT iLen = wcslen(pwstr) + 1;
|
|
|
|
if (iMaxChars <= 0)
|
|
iMaxChars = iLen;
|
|
|
|
#ifdef KERNEL_MODE
|
|
|
|
(VOID) EngUnicodeToMultiByteN(pstr, iMaxChars, NULL, (PWSTR) pwstr, iLen*sizeof(WCHAR));
|
|
|
|
#else // !KERNEL_MODE
|
|
|
|
(VOID) WideCharToMultiByte(CP_ACP, 0, pwstr, iLen, pstr, iMaxChars, NULL, NULL);
|
|
|
|
#endif
|
|
|
|
pstr[iMaxChars - 1] = NUL;
|
|
}
|
|
|
|
|
|
|
|
FORM_TRAY_TABLE
|
|
PGetAndConvertOldVersionFormTrayTable(
|
|
IN HANDLE hPrinter,
|
|
OUT PDWORD pdwSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve the old form-to-tray assignment table from registry and convert
|
|
it to the new format for the caller.
|
|
|
|
Arguments:
|
|
|
|
hPrinter - Handle to the printer object
|
|
pdwSize - Returns the form-to-tray assignment table size
|
|
|
|
Return Value:
|
|
|
|
Pointer to form-to-tray assignment table read from the registry
|
|
NULL if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
PTSTR ptstrNewTable;
|
|
PTSTR ptstrOld, ptstrEnd, ptstrNew, ptstrSave;
|
|
DWORD dwTableSize, dwNewTableSize;
|
|
FORM_TRAY_TABLE pFormTrayTable;
|
|
|
|
//
|
|
// Retrieve the form-to-tray assignment information from registry
|
|
//
|
|
|
|
pFormTrayTable = PvGetPrinterDataBinary(hPrinter,
|
|
REGVAL_TRAY_FORM_SIZE_PS40,
|
|
REGVAL_TRAY_FORM_TABLE_PS40,
|
|
&dwTableSize);
|
|
|
|
if (pFormTrayTable == NULL)
|
|
return NULL;
|
|
|
|
//
|
|
// Simple validation to make sure the information is valid
|
|
// Old format contains the table size as the first field in table
|
|
//
|
|
|
|
if (dwTableSize != *pFormTrayTable)
|
|
{
|
|
ERR(("Corrupted form-to-tray assignment table!\n"));
|
|
SetLastError(ERROR_INVALID_DATA);
|
|
|
|
MemFree(pFormTrayTable);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Convert the old format form-to-tray assignment table to new format
|
|
// OLD NEW
|
|
// Tray Name Tray Name
|
|
// Form Name Form Name
|
|
// Printer Form
|
|
// IsDefaultTray
|
|
//
|
|
|
|
//
|
|
// The first WCHAR hold the size of the table
|
|
//
|
|
|
|
dwTableSize -= sizeof(WCHAR);
|
|
ptstrOld = pFormTrayTable + 1;
|
|
ptstrEnd = ptstrOld + (dwTableSize / sizeof(WCHAR) - 1);
|
|
|
|
//
|
|
// Figuring out the size of new table, the last entry in the table
|
|
// is always a NUL so add the count for it here first
|
|
//
|
|
|
|
dwNewTableSize = 1;
|
|
|
|
while (ptstrOld < ptstrEnd && *ptstrOld != NUL)
|
|
{
|
|
ptstrSave = ptstrOld;
|
|
ptstrOld += _tcslen(ptstrOld) + 1;
|
|
ptstrOld += _tcslen(ptstrOld) + 1;
|
|
|
|
//
|
|
// New format contain only TrayName and FormName
|
|
//
|
|
|
|
dwNewTableSize += (DWORD)(ptstrOld - ptstrSave);
|
|
|
|
//
|
|
// Skip printer form and IsDefaultTray flag
|
|
//
|
|
|
|
ptstrOld += _tcslen(ptstrOld) + 2;
|
|
}
|
|
|
|
dwNewTableSize *= sizeof(WCHAR);
|
|
|
|
if ((ptstrOld != ptstrEnd) ||
|
|
(*ptstrOld != NUL) ||
|
|
(ptstrNewTable = MemAlloc(dwNewTableSize)) == NULL)
|
|
{
|
|
ERR(( "Couldn't convert form-to-tray assignment table.\n"));
|
|
MemFree(pFormTrayTable);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// The first WCHAR contains the table size
|
|
//
|
|
|
|
ptstrOld = pFormTrayTable + 1;
|
|
ptstrNew = ptstrNewTable;
|
|
|
|
while (*ptstrOld != NUL)
|
|
{
|
|
//
|
|
// Copy slot name, form name
|
|
//
|
|
|
|
ptstrSave = ptstrOld;
|
|
ptstrOld += _tcslen(ptstrOld) + 1;
|
|
ptstrOld += _tcslen(ptstrOld) + 1;
|
|
|
|
CopyMemory(ptstrNew, ptstrSave, (ptstrOld - ptstrSave) * sizeof(WCHAR));
|
|
ptstrNew += (ptstrOld - ptstrSave);
|
|
|
|
//
|
|
// skip printer form and IsDefaultTray flag
|
|
//
|
|
|
|
ptstrOld += _tcslen(ptstrOld) + 2;
|
|
}
|
|
|
|
//
|
|
// The last WCHAR is a NUL-terminator
|
|
//
|
|
|
|
*ptstrNew = NUL;
|
|
|
|
if (pdwSize)
|
|
*pdwSize = dwNewTableSize;
|
|
|
|
MemFree(pFormTrayTable);
|
|
|
|
ASSERT(BVerifyMultiSZPair(ptstrNewTable, dwNewTableSize));
|
|
return(ptstrNewTable);
|
|
}
|
|
|
|
|
|
|
|
#ifndef KERNEL_MODE
|
|
|
|
BOOL
|
|
BSaveAsOldVersionFormTrayTable(
|
|
IN HANDLE hPrinter,
|
|
IN FORM_TRAY_TABLE pFormTrayTable,
|
|
IN DWORD dwSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Save form-to-tray assignment table in NT 4.0 compatible format
|
|
|
|
Arguments:
|
|
|
|
hPrinter - Handle to the current printer
|
|
pFormTrayTable - Points to new format form-tray table
|
|
dwSize - Size of form-tray table to be saved, in bytes
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD dwOldTableSize;
|
|
PTSTR ptstrNew, ptstrOld, ptstrOldTable;
|
|
BOOL bResult;
|
|
|
|
//
|
|
// Find out how much memory to allocate for old format table
|
|
// Old format table has size as its very first character
|
|
//
|
|
|
|
ASSERT((dwSize % sizeof(TCHAR)) == 0 && dwSize >= sizeof(TCHAR));
|
|
dwOldTableSize = dwSize + sizeof(WCHAR);
|
|
ptstrNew = pFormTrayTable;
|
|
|
|
while (*ptstrNew != NUL)
|
|
{
|
|
//
|
|
// Skip tray name and form name
|
|
//
|
|
|
|
ptstrNew += _tcslen(ptstrNew) + 1;
|
|
ptstrNew += _tcslen(ptstrNew) + 1;
|
|
|
|
//
|
|
// Old format has two extra characters per entry
|
|
// one for the empty PrinterForm field
|
|
// another for IsDefaultTray flag
|
|
//
|
|
|
|
dwOldTableSize += 2 * sizeof(TCHAR);
|
|
}
|
|
|
|
if ((ptstrOldTable = MemAlloc(dwOldTableSize)) == NULL)
|
|
{
|
|
ERR(("Memory allocation failed\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Convert new format table to old format
|
|
// Be careful about the IsDefaultTray flag
|
|
//
|
|
|
|
ptstrNew = pFormTrayTable;
|
|
ptstrOld = ptstrOldTable;
|
|
*ptstrOld++ = (TCHAR) dwOldTableSize;
|
|
|
|
while (*ptstrNew != NUL)
|
|
{
|
|
//
|
|
// Copy slot name and form name
|
|
//
|
|
|
|
FINDFORMTRAY FindData;
|
|
DWORD dwCount;
|
|
PTSTR ptstrTrayName, ptstrFormName;
|
|
|
|
ptstrTrayName = ptstrNew;
|
|
ptstrNew += _tcslen(ptstrNew) + 1;
|
|
ptstrFormName = ptstrNew;
|
|
ptstrNew += _tcslen(ptstrNew) + 1;
|
|
|
|
CopyMemory(ptstrOld, ptstrTrayName, (ptstrNew - ptstrTrayName) * sizeof(TCHAR));
|
|
ptstrOld += (ptstrNew - ptstrTrayName);
|
|
|
|
//
|
|
// Set PrinterForm field to NUL
|
|
//
|
|
|
|
*ptstrOld++ = NUL;
|
|
|
|
//
|
|
// Set IsDefaultTray flag appropriately
|
|
//
|
|
|
|
dwCount = 0;
|
|
RESET_FINDFORMTRAY(pFormTrayTable, &FindData);
|
|
|
|
while (BSearchFormTrayTable(pFormTrayTable, NULL, ptstrFormName, &FindData))
|
|
dwCount++;
|
|
|
|
*ptstrOld++ = (dwCount == 1) ? TRUE : FALSE;
|
|
}
|
|
|
|
//
|
|
// The last character is a NUL-terminator
|
|
//
|
|
|
|
*ptstrOld = NUL;
|
|
|
|
bResult = BSetPrinterDataBinary(
|
|
hPrinter,
|
|
REGVAL_TRAY_FORM_SIZE_PS40,
|
|
REGVAL_TRAY_FORM_TABLE_PS40,
|
|
ptstrOldTable,
|
|
dwOldTableSize);
|
|
|
|
MemFree(ptstrOldTable);
|
|
return bResult;
|
|
}
|
|
|
|
#endif // !KERNEL_MODE
|
|
|
|
|
|
|
|
BOOL
|
|
BGetDevmodeSettingForOEM(
|
|
IN PDEVMODE pdm,
|
|
IN DWORD dwIndex,
|
|
OUT PVOID pOutput,
|
|
IN DWORD cbSize,
|
|
OUT PDWORD pcbNeeded
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Function to provide OEM plugins access to driver private devmode settings
|
|
|
|
Arguments:
|
|
|
|
pdm - Points to the devmode to be access
|
|
dwIndex - Predefined index to specify which devmode the caller is interested in
|
|
pOutput - Points to output buffer
|
|
cbSize - Size of output buffer
|
|
pcbNeeded - Returns the expected size of output buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
#define MAPPSDEVMODEFIELD(index, field) \
|
|
{ index, offsetof(PSDRVEXTRA, field), sizeof(pdmPrivate->field) }
|
|
|
|
{
|
|
PPSDRVEXTRA pdmPrivate;
|
|
INT i;
|
|
|
|
static const struct {
|
|
|
|
DWORD dwIndex;
|
|
DWORD dwOffset;
|
|
DWORD dwSize;
|
|
|
|
} aIndexMap[] = {
|
|
|
|
MAPPSDEVMODEFIELD(OEMGDS_PSDM_FLAGS, dwFlags),
|
|
MAPPSDEVMODEFIELD(OEMGDS_PSDM_DIALECT, iDialect),
|
|
MAPPSDEVMODEFIELD(OEMGDS_PSDM_TTDLFMT, iTTDLFmt),
|
|
MAPPSDEVMODEFIELD(OEMGDS_PSDM_NUP, iLayout),
|
|
MAPPSDEVMODEFIELD(OEMGDS_PSDM_PSLEVEL, iPSLevel),
|
|
MAPPSDEVMODEFIELD(OEMGDS_PSDM_CUSTOMSIZE, csdata),
|
|
|
|
{ 0, 0, 0 }
|
|
};
|
|
|
|
pdmPrivate = (PPSDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdm);
|
|
i = 0;
|
|
|
|
while (aIndexMap[i].dwSize != 0)
|
|
{
|
|
if (aIndexMap[i].dwIndex == dwIndex)
|
|
{
|
|
*pcbNeeded = aIndexMap[i].dwSize;
|
|
|
|
if (cbSize < aIndexMap[i].dwSize || pOutput == NULL)
|
|
{
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
return FALSE;
|
|
}
|
|
|
|
CopyMemory(pOutput, (PBYTE) pdmPrivate + aIndexMap[i].dwOffset, aIndexMap[i].dwSize);
|
|
return TRUE;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
WARNING(("Unknown pscript devmode index: %d\n", dwIndex));
|
|
SetLastError(ERROR_NOT_SUPPORTED);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
BConvertPrinterPropertiesData(
|
|
IN HANDLE hPrinter,
|
|
IN PRAWBINARYDATA pRawData,
|
|
OUT PPRINTERDATA pPrinterData,
|
|
IN PVOID pvSrcData,
|
|
IN DWORD dwSrcSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert an older or newer version PRINTERDATA structure to current version
|
|
|
|
Arguments:
|
|
|
|
hPrinter - Handle to the current printer
|
|
pRawData - Points to raw printer description data
|
|
pPrinterData - Points to destination buffer
|
|
pvSrcData - Points to source data to be converted
|
|
dwSrcSize - Size of the source data in bytes
|
|
|
|
Return Value:
|
|
|
|
TRUE if conversion was successful, FALSE otherwise
|
|
|
|
Note:
|
|
|
|
This function is called after the library function has already
|
|
done a generic conversion.
|
|
|
|
--*/
|
|
|
|
{
|
|
PPS4_PRINTERDATA pSrc = pvSrcData;
|
|
PPPDDATA pPpdData;
|
|
|
|
//
|
|
// Check if the source PRINTERDATA was from NT4 PS driver
|
|
//
|
|
|
|
pPpdData = GET_DRIVER_INFO_FROM_INFOHEADER((PINFOHEADER) pRawData);
|
|
|
|
ASSERT(pPpdData != NULL);
|
|
|
|
if (dwSrcSize != sizeof(PS4_PRINTERDATA) ||
|
|
dwSrcSize != pSrc->wSize ||
|
|
pSrc->wDriverVersion != PSDRIVER_VERSION_400 ||
|
|
pSrc->wChecksum != pPpdData->dwNt4Checksum)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Convert PS4 feature/option selections to PS4 format
|
|
//
|
|
|
|
VConvertOptSelectArray(pRawData,
|
|
pPrinterData->aOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
pSrc->options,
|
|
64,
|
|
MODE_PRINTER_STICKY);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
VUpdatePrivatePrinterData(
|
|
IN HANDLE hPrinter,
|
|
IN OUT PPRINTERDATA pPrinterData,
|
|
IN DWORD dwMode,
|
|
IN PUIINFO pUIInfo,
|
|
IN POPTSELECT pCombineOptions
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Update the Registry with the keyword/value pairs
|
|
of PRINTERDATA's fixed fields.
|
|
|
|
Arguments:
|
|
|
|
hPrinter - Handle to the current printer
|
|
pPrinterData - Points to PRINTERDATA
|
|
dwMode - MODE_READ/MODE_WRITE
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD dwValue, dwMinFreeMem;
|
|
|
|
#ifdef KERNEL_MODE
|
|
|
|
ASSERT(dwMode == MODE_READ);
|
|
|
|
#endif
|
|
|
|
//
|
|
// read/write PRINTERDATA fields from/to registry
|
|
//
|
|
|
|
if (dwMode == MODE_READ)
|
|
{
|
|
if (BGetPrinterDataDWord(hPrinter, REGVAL_FREEMEM, &dwValue))
|
|
{
|
|
//
|
|
// REGVAL_FREEMEM is in unit of Kbyte, we need to convert it to byte.
|
|
// Also make sure the value is not less than the minimum value we required.
|
|
//
|
|
|
|
dwMinFreeMem = pUIInfo->dwLangLevel < 2 ? MIN_FREEMEM_L1: MIN_FREEMEM_L2;
|
|
|
|
pPrinterData->dwFreeMem = max(dwValue * KBYTES, dwMinFreeMem);
|
|
}
|
|
|
|
if (BGetPrinterDataDWord(hPrinter, REGVAL_JOBTIMEOUT, &dwValue))
|
|
{
|
|
pPrinterData->dwJobTimeout = dwValue;
|
|
}
|
|
|
|
if (BGetPrinterDataDWord(hPrinter, REGVAL_PROTOCOL, &dwValue))
|
|
{
|
|
pPrinterData->wProtocol = (WORD)dwValue;
|
|
|
|
if (pPrinterData->wProtocol != PROTOCOL_ASCII &&
|
|
pPrinterData->wProtocol != PROTOCOL_BCP &&
|
|
pPrinterData->wProtocol != PROTOCOL_TBCP &&
|
|
pPrinterData->wProtocol != PROTOCOL_BINARY)
|
|
{
|
|
pPrinterData->wProtocol = PROTOCOL_ASCII;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifndef KERNEL_MODE
|
|
|
|
else
|
|
{
|
|
ASSERT(dwMode == MODE_WRITE);
|
|
|
|
//
|
|
// Remember to convert byte to Kbyte for REGVAL_FREEMEM
|
|
//
|
|
|
|
(VOID) BSetPrinterDataDWord(hPrinter, REGVAL_FREEMEM, pPrinterData->dwFreeMem / KBYTES);
|
|
(VOID) BSetPrinterDataDWord(hPrinter, REGVAL_JOBTIMEOUT, pPrinterData->dwJobTimeout);
|
|
(VOID) BSetPrinterDataDWord(hPrinter, REGVAL_PROTOCOL, (DWORD)pPrinterData->wProtocol);
|
|
}
|
|
|
|
#endif // !KERNEL_MODE
|
|
}
|
|
|
|
|
|
VOID
|
|
VDefaultDevmodeFormFields(
|
|
PUIINFO pUIInfo,
|
|
PDEVMODE pDevmode,
|
|
BOOL bMetric
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialized the form-related devmode fields with their default values
|
|
|
|
Arguments:
|
|
|
|
pUIInfo - Points for UIINFO
|
|
pDevmode - Points to the DEVMODE whose form-related fields are to be initialized
|
|
bMetric - Specifies whether the system is running in metric mode
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
ASSERT(pUIInfo);
|
|
|
|
if (!(bMetric && (pUIInfo->dwFlags & FLAG_A4_SIZE_EXISTS)) &&
|
|
!(!bMetric && (pUIInfo->dwFlags & FLAG_LETTER_SIZE_EXISTS)))
|
|
{
|
|
PFEATURE pFeature;
|
|
PPAGESIZE pPageSize;
|
|
PCWSTR pDisplayName;
|
|
|
|
//
|
|
// A4 or Letter not available. Use the printer's default paper size.
|
|
//
|
|
|
|
if ((pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGESIZE)) &&
|
|
(pPageSize = PGetIndexedOption(pUIInfo, pFeature, pFeature->dwDefaultOptIndex)) &&
|
|
(pDisplayName = OFFSET_TO_POINTER(pUIInfo->pubResourceData, pPageSize->GenericOption.loDisplayName)))
|
|
{
|
|
CopyString(pDevmode->dmFormName, pDisplayName, CCHFORMNAME);
|
|
pDevmode->dmPaperSize = (short)(pPageSize->dwPaperSizeID);
|
|
pDevmode->dmPaperWidth = (short)(pPageSize->szPaperSize.cx / DEVMODE_PAPER_UNIT);
|
|
pDevmode->dmPaperLength = (short)(pPageSize->szPaperSize.cy / DEVMODE_PAPER_UNIT);
|
|
|
|
//
|
|
// PPD parser always assigns custom paper size values to dwPaperSizeID (see ppdparse.c), including for
|
|
// standard page sizes, so we need to use dmPaperSize/dmPaperWidth in devmode instead of dmPaperSize.
|
|
//
|
|
|
|
pDevmode->dmFields |= (DM_FORMNAME | DM_PAPERWIDTH | DM_PAPERLENGTH);
|
|
pDevmode->dmFields &= ~DM_PAPERSIZE;
|
|
|
|
//
|
|
// return when we succeeded, otherwise we will fall into the default A4 or Letter case
|
|
//
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
ERR(("Failed to get default paper size from PPD\n"));
|
|
}
|
|
}
|
|
|
|
if (bMetric)
|
|
{
|
|
CopyString(pDevmode->dmFormName, A4_FORMNAME, CCHFORMNAME);
|
|
pDevmode->dmPaperSize = DMPAPER_A4;
|
|
pDevmode->dmPaperWidth = 2100; // 210mm measured in 0.1mm units
|
|
pDevmode->dmPaperLength = 2970; // 297mm
|
|
}
|
|
else
|
|
{
|
|
CopyString(pDevmode->dmFormName, LETTER_FORMNAME, CCHFORMNAME);
|
|
pDevmode->dmPaperSize = DMPAPER_LETTER;
|
|
pDevmode->dmPaperWidth = 2159; // 8.5"
|
|
pDevmode->dmPaperLength = 2794; // 11"
|
|
}
|
|
|
|
pDevmode->dmFields &= ~(DM_PAPERWIDTH | DM_PAPERLENGTH);
|
|
pDevmode->dmFields |= (DM_PAPERSIZE | DM_FORMNAME);
|
|
}
|
|
|
|
|
|
#if !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
|
|
|
|
typedef struct _VMERRMSGIDTBL
|
|
{
|
|
LANGID lgid; // Language ID
|
|
DWORD resid; // VM error handler resource ID
|
|
}
|
|
VMERRMSGIDTBL, *PVMERRMSGIDTBL;
|
|
|
|
VMERRMSGIDTBL VMErrMsgIDTbl[] =
|
|
{
|
|
// Lang. ID Res. ID
|
|
|
|
{ LANG_CHINESE, 0 }, // Chinense: use sub table below
|
|
{ LANG_DANISH, PSPROC_vmerr_Danish_ps }, // Danish Adobe bug#342407
|
|
{ LANG_DUTCH, PSPROC_vmerr_Dutch_ps }, // Dutch
|
|
{ LANG_FINNISH, PSPROC_vmerr_Finnish_ps }, // Finnish Adobe bug#342407
|
|
{ LANG_FRENCH, PSPROC_vmerr_French_ps }, // French
|
|
{ LANG_GERMAN, PSPROC_vmerr_German_ps }, // German
|
|
{ LANG_ITALIAN, PSPROC_vmerr_Italian_ps }, // Italian
|
|
{ LANG_JAPANESE, PSPROC_vmerr_Japanese_ps }, // Japanese
|
|
{ LANG_KOREAN, PSPROC_vmerr_Korean_ps }, // Korean
|
|
{ LANG_NORWEGIAN, PSPROC_vmerr_Norwegian_ps }, // Norwegian Adobe bug#342407
|
|
{ LANG_PORTUGUESE, PSPROC_vmerr_Portuguese_ps }, // Portuguese
|
|
{ LANG_SPANISH, PSPROC_vmerr_Spanish_ps }, // Spanish
|
|
{ LANG_SWEDISH, PSPROC_vmerr_Swedish_ps }, // Swedish
|
|
|
|
{ 0, 0 } // Stopper. Don't remove this.
|
|
};
|
|
|
|
VMERRMSGIDTBL VMErrMsgIDTbl2[] =
|
|
{
|
|
// Sub lang. ID Res. ID
|
|
|
|
{ SUBLANG_CHINESE_TRADITIONAL, PSPROC_vmerr_TraditionalChinese_ps }, // Taiwan
|
|
{ SUBLANG_CHINESE_SIMPLIFIED, PSPROC_vmerr_SimplifiedChinese_ps }, // PRC
|
|
{ SUBLANG_CHINESE_HONGKONG, PSPROC_vmerr_TraditionalChinese_ps }, // Hong Kong
|
|
{ SUBLANG_CHINESE_SINGAPORE, PSPROC_vmerr_SimplifiedChinese_ps }, // Singapore
|
|
|
|
{ 0, 0 } // Stopper. Don't remove this.
|
|
};
|
|
|
|
DWORD
|
|
DWGetVMErrorMessageID(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get the VM Error message ID calculated from the current user's locale.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
The VM Error message ID.
|
|
|
|
--*/
|
|
|
|
{
|
|
LANGID lgid;
|
|
WORD wPrim, wSub;
|
|
DWORD dwVMErrorMessageID;
|
|
PVMERRMSGIDTBL pTbl, pTbl2;
|
|
|
|
dwVMErrorMessageID = 0;
|
|
|
|
lgid = GetSystemDefaultLangID();
|
|
|
|
wPrim = PRIMARYLANGID(lgid);
|
|
|
|
for (pTbl = VMErrMsgIDTbl; pTbl->lgid && !dwVMErrorMessageID; pTbl++)
|
|
{
|
|
if (pTbl->lgid == wPrim)
|
|
{
|
|
if (pTbl->resid)
|
|
{
|
|
dwVMErrorMessageID = pTbl->resid;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
wSub = SUBLANGID(lgid);
|
|
|
|
for (pTbl2 = VMErrMsgIDTbl2; pTbl2->lgid; pTbl2++)
|
|
{
|
|
if (pTbl2->lgid == wSub)
|
|
{
|
|
dwVMErrorMessageID = pTbl2->resid;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return dwVMErrorMessageID;
|
|
}
|
|
|
|
#endif // !defined(KERNEL_MODE) || defined(USERMODE_DRIVER)
|