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.
1140 lines
30 KiB
1140 lines
30 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
unilib.c
|
|
|
|
Abstract:
|
|
|
|
This file handles the shared KM and UM code for Unidrv
|
|
|
|
Environment:
|
|
|
|
Win32 subsystem, Unidrv driver
|
|
|
|
Revision History:
|
|
|
|
02/04/97 -davidx-
|
|
Devmode changes to support OEM plugins.
|
|
|
|
10/17/96 -amandan-
|
|
Created it.
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
#ifndef KERNEL_MODE
|
|
#include <winddiui.h>
|
|
#endif
|
|
|
|
#include <printoem.h>
|
|
#include "oemutil.h"
|
|
#include "gpd.h"
|
|
|
|
//
|
|
// Internal data structure
|
|
//
|
|
|
|
typedef union {
|
|
WORD w;
|
|
BYTE b[2];
|
|
} UW;
|
|
|
|
typedef union {
|
|
DWORD dw;
|
|
BYTE b[4];
|
|
} UDW;
|
|
|
|
#if !defined(DEVSTUDIO) // MDS doesn't need these
|
|
|
|
|
|
//
|
|
// Information about UniDriver private devmode
|
|
//
|
|
|
|
CONST DRIVER_DEVMODE_INFO gDriverDMInfo =
|
|
{
|
|
UNIDRIVER_VERSION, sizeof(UNIDRVEXTRA),
|
|
UNIDRIVER_VERSION_500, sizeof(UNIDRVEXTRA500),
|
|
UNIDRIVER_VERSION_400, sizeof(UNIDRVEXTRA400),
|
|
UNIDRIVER_VERSION_351, sizeof(UNIDRVEXTRA351),
|
|
};
|
|
|
|
CONST DWORD gdwDriverDMSignature = UNIDEVMODE_SIGNATURE;
|
|
CONST WORD gwDriverVersion = UNIDRIVER_VERSION;
|
|
|
|
|
|
//
|
|
// Functions
|
|
//
|
|
|
|
BOOL
|
|
BInitDriverDefaultDevmode(
|
|
OUT PDEVMODE pdm,
|
|
IN LPCTSTR pDeviceName,
|
|
IN PUIINFO pUIInfo,
|
|
IN PRAWBINARYDATA pRawData,
|
|
IN BOOL bMetric
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function intializes the devmode with
|
|
the UNIDRV default devmode
|
|
|
|
Arguments:
|
|
|
|
pdm pointer to Unidrv DEVMODE
|
|
pDeviceName pointer to device name
|
|
pUIInfo pointer to UIINFO
|
|
pRawData pointer to RAWBINARYDATA
|
|
bMetric indicates whether system is running in a metric country
|
|
|
|
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.
|
|
|
|
--*/
|
|
{
|
|
PDEVMODE pdmPublic;
|
|
PUNIDRVEXTRA pdmPrivate;
|
|
PWSTR pwstrFormName;
|
|
PFEATURE pFeature;
|
|
PGPDDRIVERINFO pDriverInfo;
|
|
|
|
pDriverInfo = GET_DRIVER_INFO_FROM_INFOHEADER(pUIInfo->pInfoHeader);
|
|
|
|
pdmPublic = pdm;
|
|
|
|
/*********************/
|
|
/* PUBLIC DEVMODE */
|
|
/*********************/
|
|
|
|
if (pDeviceName)
|
|
CopyStringW(pdmPublic->dmDeviceName, pDeviceName, CCHDEVICENAME);
|
|
|
|
pdmPublic->dmDriverVersion = UNIDRIVER_VERSION;
|
|
pdmPublic->dmSpecVersion = DM_SPECVERSION;
|
|
pdmPublic->dmSize = sizeof(DEVMODE);
|
|
pdmPublic->dmDriverExtra = sizeof(UNIDRVEXTRA);
|
|
|
|
pdmPublic->dmFields =
|
|
DM_COPIES | DM_ORIENTATION | DM_PAPERSIZE | DM_COLLATE | DM_DITHERTYPE |
|
|
DM_COLOR | DM_FORMNAME | DM_TTOPTION | DM_DEFAULTSOURCE |
|
|
#ifndef WINNT_40
|
|
DM_NUP |
|
|
#endif
|
|
DM_PRINTQUALITY;
|
|
|
|
pdmPublic->dmOrientation = DMORIENT_PORTRAIT;
|
|
pdmPublic->dmDuplex = DMDUP_SIMPLEX;
|
|
pdmPublic->dmCollate = DMCOLLATE_TRUE;
|
|
pdmPublic->dmMediaType = DMMEDIA_STANDARD;
|
|
pdmPublic->dmTTOption = DMTT_SUBDEV;
|
|
pdmPublic->dmColor = DMCOLOR_MONOCHROME;
|
|
pdmPublic->dmDefaultSource = DMBIN_FORMSOURCE;
|
|
pdmPublic->dmScale = 100;
|
|
pdmPublic->dmCopies = 1;
|
|
#ifndef WINNT_40
|
|
pdmPublic->dmNup = DMNUP_SYSTEM;
|
|
#endif
|
|
|
|
//
|
|
// We always set ICM off. The spooler will turn it on at install time
|
|
// if there are color profiles installed with this printer
|
|
//
|
|
|
|
pdmPublic->dmICMMethod = DMICMMETHOD_NONE;
|
|
pdmPublic->dmICMIntent = DMICM_CONTRAST;
|
|
pdmPublic->dmDitherType = pUIInfo->defaultQuality + QUALITY_MACRO_START;
|
|
|
|
if (pUIInfo->liBestQualitySettings == END_OF_LIST &&
|
|
pUIInfo->liBetterQualitySettings == END_OF_LIST &&
|
|
pUIInfo->liDraftQualitySettings == END_OF_LIST)
|
|
pdmPublic->dmDitherType = QUALITY_MACRO_CUSTOM;
|
|
|
|
#ifndef WINNT_40
|
|
|
|
pdmPublic->dmFields |= (DM_ICMMETHOD | DM_ICMINTENT);
|
|
|
|
#endif
|
|
|
|
if (pDriverInfo && pDriverInfo->Globals.bTTFSEnabled == FALSE)
|
|
pdmPublic->dmTTOption = DMTT_DOWNLOAD;
|
|
|
|
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))
|
|
{
|
|
pdmPublic->dmPrintQuality = (short)pRes->iXdpi;
|
|
pdmPublic->dmYResolution = (short)pRes->iYdpi;
|
|
}
|
|
}
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_DUPLEX))
|
|
{
|
|
PDUPLEX pDuplex;
|
|
|
|
//
|
|
// Use the default duplex option specified in the GPD file
|
|
//
|
|
|
|
pdmPublic->dmFields |= DM_DUPLEX;
|
|
|
|
if (pDuplex = PGetIndexedOption(pUIInfo, pFeature, pFeature->dwDefaultOptIndex))
|
|
pdmPublic->dmDuplex = (SHORT) pDuplex->dwDuplexID;
|
|
}
|
|
|
|
//
|
|
// Always set DM_COLLATE flag since we can simulate it if the
|
|
// device cannot.
|
|
//
|
|
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_MEDIATYPE))
|
|
{
|
|
PMEDIATYPE pMediaType;
|
|
|
|
//
|
|
// Use the default media type specified in the PPD file
|
|
//
|
|
|
|
pdmPublic->dmFields |= DM_MEDIATYPE;
|
|
|
|
if (pMediaType = PGetIndexedOption(pUIInfo, pFeature, pFeature->dwDefaultOptIndex))
|
|
pdmPublic->dmMediaType = (SHORT)pMediaType->dwMediaTypeID;
|
|
|
|
}
|
|
|
|
|
|
if (pUIInfo->dwFlags & FLAG_COLOR_DEVICE)
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_COLORMODE))
|
|
{
|
|
POPTION pColorMode;
|
|
PCOLORMODEEX pColorModeEx;
|
|
|
|
if ((pColorMode = PGetIndexedOption(pUIInfo, pFeature, pFeature->dwDefaultOptIndex)) &&
|
|
(pColorModeEx = OFFSET_TO_POINTER(pUIInfo->pInfoHeader, pColorMode->loRenderOffset)) &&
|
|
(pColorModeEx->bColor))
|
|
{
|
|
pdmPublic->dmColor = DMCOLOR_COLOR;
|
|
}
|
|
}
|
|
|
|
pdmPublic->dmFields |= DM_COLOR;
|
|
}
|
|
|
|
//
|
|
// Initialize form-related fields
|
|
//
|
|
|
|
VDefaultDevmodeFormFields(pUIInfo, pdmPublic, bMetric);
|
|
|
|
|
|
/*********************/
|
|
/* PRIVATE DEVMODE */
|
|
/*********************/
|
|
|
|
//
|
|
// Fill in the private portion of devmode
|
|
//
|
|
|
|
pdmPrivate = (PUNIDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdm);
|
|
pdmPrivate->wVer = UNIDRVEXTRA_VERSION ;
|
|
pdmPrivate->wSize = sizeof(UNIDRVEXTRA);
|
|
|
|
pdmPrivate->wOEMExtra = 0;
|
|
ZeroMemory(pdmPrivate->wReserved, sizeof(pdmPrivate->wReserved));
|
|
|
|
pdmPrivate->iLayout = ONE_UP;
|
|
pdmPrivate->bReversePrint = FALSE;
|
|
pdmPrivate->iQuality = pUIInfo->defaultQuality;
|
|
|
|
//
|
|
// Initialize default sFlags
|
|
//
|
|
|
|
if (pUIInfo->dwFlags & FLAG_FONT_DOWNLOADABLE)
|
|
pdmPrivate->dwFlags &= DXF_DOWNLOADTT;
|
|
|
|
pdmPrivate->dwSignature = UNIDEVMODE_SIGNATURE;
|
|
pdmPrivate->dwChecksum32 = pRawData->dwChecksum32;
|
|
pdmPrivate->dwOptions = pRawData->dwDocumentFeatures;
|
|
|
|
InitDefaultOptions(pRawData,
|
|
pdmPrivate->aOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
MODE_DOCUMENT_STICKY);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
VMergePublicDevmodeFields (
|
|
PDEVMODE pdmSrc,
|
|
PDEVMODE pdmDest,
|
|
PUIINFO pUIInfo,
|
|
PRAWBINARYDATA pRawData
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
This function merges the public devmode fields from SRC to DEST
|
|
It is assumed that the devmode has been converted to the current
|
|
version before this function is called
|
|
|
|
Arguments:
|
|
|
|
pdmSrc pointer to src DEVMODE
|
|
pdmDest pointer to destination DEVMODE
|
|
pUIInfo pointer to UIINFO
|
|
pRawData pointer to raw binary printer description data
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
{
|
|
PFEATURE pFeature;
|
|
|
|
#ifndef WINNT_40
|
|
if ( (pdmSrc->dmFields & DM_NUP) &&
|
|
(pdmSrc->dmNup == DMNUP_SYSTEM ||
|
|
pdmSrc->dmNup == DMNUP_ONEUP))
|
|
{
|
|
pdmDest->dmNup = pdmSrc->dmNup;
|
|
pdmDest->dmFields |= DM_NUP;
|
|
}
|
|
#endif
|
|
//
|
|
// Copy dmDefaultSource field
|
|
//
|
|
|
|
if ( pdmSrc->dmFields & DM_DEFAULTSOURCE &&
|
|
((pdmSrc->dmDefaultSource >= DMBIN_FIRST &&
|
|
pdmSrc->dmDefaultSource <= DMBIN_LAST) ||
|
|
pdmSrc->dmDefaultSource >= DMBIN_USER))
|
|
|
|
{
|
|
pdmDest->dmDefaultSource = pdmSrc->dmDefaultSource;
|
|
pdmDest->dmFields |= DM_DEFAULTSOURCE;
|
|
}
|
|
|
|
//
|
|
// Copy the dmDitherType field
|
|
//
|
|
|
|
if ((pdmSrc->dmFields & DM_DITHERTYPE) &&
|
|
((pdmSrc->dmDitherType >= QUALITY_MACRO_START &&
|
|
pdmSrc->dmDitherType < QUALITY_MACRO_END) ||
|
|
(pdmSrc->dmDitherType <= HT_PATSIZE_MAX_INDEX)))
|
|
{
|
|
pdmDest->dmFields |= DM_DITHERTYPE;
|
|
pdmDest->dmDitherType = pdmSrc->dmDitherType;
|
|
|
|
}
|
|
|
|
//
|
|
// Copy dmOrientation field
|
|
//
|
|
|
|
if ((pdmSrc->dmFields & DM_ORIENTATION) &&
|
|
(pdmSrc->dmOrientation == DMORIENT_PORTRAIT ||
|
|
pdmSrc->dmOrientation == DMORIENT_LANDSCAPE))
|
|
{
|
|
pdmDest->dmFields |= DM_ORIENTATION;
|
|
pdmDest->dmOrientation = pdmSrc->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 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 ((pdmSrc->dmFields & DM_PAPERWIDTH) &&
|
|
(pdmSrc->dmFields & DM_PAPERLENGTH) &&
|
|
(pdmSrc->dmPaperWidth > 0) &&
|
|
(pdmSrc->dmPaperLength > 0))
|
|
{
|
|
pdmDest->dmFields |= (DM_PAPERLENGTH | DM_PAPERWIDTH);
|
|
pdmDest->dmFields &= ~(DM_PAPERSIZE | DM_FORMNAME);
|
|
pdmDest->dmPaperWidth = pdmSrc->dmPaperWidth;
|
|
pdmDest->dmPaperLength = pdmSrc->dmPaperLength;
|
|
|
|
}
|
|
else if (pdmSrc->dmFields & DM_PAPERSIZE)
|
|
{
|
|
pdmDest->dmFields |= DM_PAPERSIZE;
|
|
pdmDest->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH | DM_FORMNAME);
|
|
pdmDest->dmPaperSize = pdmSrc->dmPaperSize;
|
|
|
|
}
|
|
else if (pdmSrc->dmFields & DM_FORMNAME)
|
|
{
|
|
|
|
pdmDest->dmFields |= DM_FORMNAME;
|
|
pdmDest->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH | DM_PAPERSIZE);
|
|
CopyString(pdmDest->dmFormName, pdmSrc->dmFormName, CCHFORMNAME);
|
|
}
|
|
|
|
//
|
|
// Copy dmScale field
|
|
//
|
|
|
|
if ((pdmSrc->dmFields & DM_SCALE) &&
|
|
(pdmSrc->dmScale >= MIN_SCALE) &&
|
|
(pdmSrc->dmScale <= MAX_SCALE))
|
|
{
|
|
//
|
|
// Unidrv can't have DM_SCALE flag set for app compat reasons. That is
|
|
// the same behavior we saw when testing other OEM PCL drivers.
|
|
// (See bug #35241 for details.)
|
|
//
|
|
// pdmDest->dmFields |= DM_SCALE;
|
|
//
|
|
|
|
pdmDest->dmScale = pdmSrc->dmScale;
|
|
}
|
|
|
|
//
|
|
// Copy dmCopies field
|
|
//
|
|
|
|
if ((pdmSrc->dmFields & DM_COPIES) &&
|
|
(pdmSrc->dmCopies >= 1) &&
|
|
(pdmSrc->dmCopies <= max(MAX_COPIES, (SHORT)pUIInfo->dwMaxCopies)))
|
|
{
|
|
pdmDest->dmFields |= DM_COPIES;
|
|
pdmDest->dmCopies = pdmSrc->dmCopies;
|
|
}
|
|
|
|
|
|
if ((pdmSrc->dmFields & DM_COLOR) &&
|
|
(pdmSrc->dmColor == DMCOLOR_COLOR ||
|
|
pdmSrc->dmColor == DMCOLOR_MONOCHROME))
|
|
{
|
|
pdmDest->dmFields |= DM_COLOR;
|
|
pdmDest->dmColor = pdmSrc->dmColor;
|
|
}
|
|
|
|
if ((pdmSrc->dmFields & DM_DUPLEX) &&
|
|
(GET_PREDEFINED_FEATURE(pUIInfo, GID_DUPLEX) != NULL) &&
|
|
(pdmSrc->dmDuplex == DMDUP_SIMPLEX ||
|
|
pdmSrc->dmDuplex == DMDUP_HORIZONTAL ||
|
|
pdmSrc->dmDuplex == DMDUP_VERTICAL))
|
|
{
|
|
pdmDest->dmFields |= DM_DUPLEX;
|
|
pdmDest->dmDuplex = pdmSrc->dmDuplex;
|
|
}
|
|
|
|
if ((pdmSrc->dmFields & DM_COLLATE) &&
|
|
(pdmSrc->dmCollate == DMCOLLATE_TRUE ||
|
|
pdmSrc->dmCollate == DMCOLLATE_FALSE))
|
|
{
|
|
pdmDest->dmFields |= DM_COLLATE;
|
|
pdmDest->dmCollate = pdmSrc->dmCollate;
|
|
}
|
|
|
|
//
|
|
// Copy dmTTOption field
|
|
//
|
|
|
|
if (pdmSrc->dmFields & DM_TTOPTION &&
|
|
(pdmSrc->dmTTOption == DMTT_BITMAP ||
|
|
pdmSrc->dmTTOption == DMTT_DOWNLOAD ||
|
|
pdmSrc->dmTTOption == DMTT_SUBDEV) )
|
|
{
|
|
pdmDest->dmTTOption = pdmSrc->dmTTOption;
|
|
pdmDest->dmFields |= DM_TTOPTION;
|
|
}
|
|
|
|
|
|
if ((pdmSrc->dmFields & DM_ICMMETHOD) &&
|
|
(pdmSrc->dmICMMethod == DMICMMETHOD_NONE ||
|
|
pdmSrc->dmICMMethod == DMICMMETHOD_SYSTEM ||
|
|
pdmSrc->dmICMMethod == DMICMMETHOD_DRIVER ||
|
|
pdmSrc->dmICMMethod == DMICMMETHOD_DEVICE))
|
|
{
|
|
pdmDest->dmFields |= DM_ICMMETHOD;
|
|
pdmDest->dmICMMethod = pdmSrc->dmICMMethod;
|
|
}
|
|
|
|
if ((pdmSrc->dmFields & DM_ICMINTENT) &&
|
|
(pdmSrc->dmICMIntent == DMICM_SATURATE ||
|
|
#ifndef WINNT_40
|
|
pdmSrc->dmICMIntent == DMICM_COLORIMETRIC ||
|
|
pdmSrc->dmICMIntent == DMICM_ABS_COLORIMETRIC ||
|
|
#endif
|
|
pdmSrc->dmICMIntent == DMICM_CONTRAST
|
|
))
|
|
|
|
{
|
|
pdmDest->dmFields |= DM_ICMINTENT;
|
|
pdmDest->dmICMIntent = pdmSrc->dmICMIntent;
|
|
}
|
|
|
|
|
|
//
|
|
// Resolution
|
|
//
|
|
|
|
if ((pdmSrc->dmFields & (DM_PRINTQUALITY|DM_YRESOLUTION)) &&
|
|
(pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_RESOLUTION)))
|
|
{
|
|
PRESOLUTION pRes;
|
|
DWORD dwIndex;
|
|
INT iXdpi, iYdpi;
|
|
|
|
switch (pdmSrc->dmFields & (DM_PRINTQUALITY|DM_YRESOLUTION))
|
|
{
|
|
case DM_PRINTQUALITY:
|
|
|
|
iXdpi = iYdpi = pdmSrc->dmPrintQuality;
|
|
break;
|
|
|
|
case DM_YRESOLUTION:
|
|
|
|
iXdpi = iYdpi = pdmSrc->dmYResolution;
|
|
break;
|
|
|
|
default:
|
|
|
|
iXdpi = pdmSrc->dmPrintQuality;
|
|
iYdpi = pdmSrc->dmYResolution;
|
|
break;
|
|
}
|
|
|
|
dwIndex = MapToDeviceOptIndex(pUIInfo->pInfoHeader, GID_RESOLUTION, iXdpi, iYdpi, NULL);
|
|
|
|
if (pRes = PGetIndexedOption(pUIInfo, pFeature, dwIndex))
|
|
{
|
|
pdmDest->dmFields |= (DM_PRINTQUALITY|DM_YRESOLUTION);
|
|
pdmDest->dmPrintQuality = GETQUALITY_X(pRes);
|
|
pdmDest->dmYResolution = GETQUALITY_Y(pRes);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Media type
|
|
//
|
|
|
|
if ((pdmSrc->dmFields & DM_MEDIATYPE) &&
|
|
(pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_MEDIATYPE)) &&
|
|
(pdmSrc->dmMediaType == DMMEDIA_STANDARD ||
|
|
pdmSrc->dmMediaType == DMMEDIA_TRANSPARENCY ||
|
|
pdmSrc->dmMediaType == DMMEDIA_GLOSSY ||
|
|
pdmSrc->dmMediaType >= DMMEDIA_USER) )
|
|
{
|
|
pdmDest->dmFields |= DM_MEDIATYPE;
|
|
pdmDest->dmMediaType = pdmSrc->dmMediaType;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
BMergeDriverDevmode(
|
|
IN OUT PDEVMODE pdmDest,
|
|
IN PUIINFO pUIInfo,
|
|
IN PRAWBINARYDATA pRawData,
|
|
IN PDEVMODE pdmSrc
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function validates the source devmode and
|
|
merge it with the destination devmode for UNIDRV
|
|
|
|
Arguments:
|
|
|
|
pdmDest pointer to destination Unidrv DEVMODE
|
|
pUIInfo pointer to UIINFO
|
|
pRawData pointer to RAWBINARYDATA
|
|
pdmSrc pointer to src 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.
|
|
|
|
--*/
|
|
{
|
|
|
|
PUNIDRVEXTRA pPrivDest, pPrivSrc;
|
|
|
|
ASSERT(pdmDest != NULL &&
|
|
pdmDest->dmSize == sizeof(DEVMODE) &&
|
|
pdmDest->dmDriverExtra >= sizeof(UNIDRVEXTRA) &&
|
|
pdmSrc != NULL &&
|
|
pdmSrc->dmSize == sizeof(DEVMODE) &&
|
|
pdmSrc->dmDriverExtra >= sizeof(UNIDRVEXTRA));
|
|
|
|
/**********************************/
|
|
/* TRANSFER PUBLIC DEVMODE FIELDS */
|
|
/**********************************/
|
|
|
|
VMergePublicDevmodeFields(pdmSrc, pdmDest, pUIInfo, pRawData);
|
|
|
|
|
|
/***************************/
|
|
/* GET PRIVATE DEVMODE */
|
|
/***************************/
|
|
|
|
//
|
|
// If the source devmode has a private portion, then check
|
|
// to see if belongs to us. Copy the private portion to
|
|
// the destination devmode if it does.
|
|
//
|
|
|
|
pPrivSrc = (PUNIDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdmSrc);
|
|
pPrivDest = (PUNIDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdmDest);
|
|
|
|
//
|
|
// Validate private portion of input devmode
|
|
// If it's not our private devmode, then return the default already in
|
|
// privDest
|
|
//
|
|
|
|
if (pPrivSrc->dwSignature == UNIDEVMODE_SIGNATURE)
|
|
{
|
|
memcpy(pPrivDest, pPrivSrc, sizeof(UNIDRVEXTRA));
|
|
|
|
if (pPrivDest->dwChecksum32 != pRawData->dwChecksum32)
|
|
{
|
|
WARNING(( "UNIDRV: Devmode checksum mismatch.\n"));
|
|
|
|
pPrivDest->dwChecksum32 = pRawData->dwChecksum32;
|
|
pPrivDest->dwOptions = pRawData->dwDocumentFeatures;
|
|
|
|
InitDefaultOptions(pRawData,
|
|
pPrivDest->aOptions,
|
|
MAX_PRINTER_OPTIONS,
|
|
MODE_DOCUMENT_STICKY);
|
|
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#endif // !defined(DEVSTUDIO)
|
|
|
|
//
|
|
// Alignment functions
|
|
//
|
|
|
|
WORD
|
|
DwAlign2(
|
|
IN PBYTE pubData)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts a non-aligned, big endian (e.g. 80386) value and returns
|
|
it as an integer, with the correct byte alignment.
|
|
|
|
Arguments:
|
|
|
|
pubData - a pointer to a data buffer to convert
|
|
|
|
Return Value:
|
|
|
|
The converted value.
|
|
|
|
--*/
|
|
{
|
|
static INT iType = 0;
|
|
UW Uw;
|
|
|
|
|
|
if( iType == 0 )
|
|
{
|
|
//
|
|
// Need to determine byte/word relationships
|
|
//
|
|
|
|
Uw.b[ 0 ] = 0x01;
|
|
Uw.b[ 1 ] = 0x02;
|
|
|
|
iType = Uw.w == 0x0102 ? 1 : 2;
|
|
}
|
|
|
|
if( iType == 2 )
|
|
{
|
|
Uw.b[ 0 ] = *pubData++;
|
|
Uw.b[ 1 ] = *pubData;
|
|
}
|
|
else
|
|
{
|
|
Uw.b[ 1 ] = *pubData++;
|
|
Uw.b[ 0 ] = *pubData;
|
|
}
|
|
|
|
return Uw.w;
|
|
}
|
|
|
|
DWORD
|
|
DwAlign4(
|
|
IN PBYTE pubData)
|
|
{
|
|
static INT iType = 0;
|
|
UDW Udw;
|
|
|
|
if( iType == 0 )
|
|
{
|
|
//
|
|
// Need to determine byte/word relationships
|
|
//
|
|
|
|
Udw.b[ 0 ] = 0x01;
|
|
Udw.b[ 1 ] = 0x02;
|
|
Udw.b[ 2 ] = 0x03;
|
|
Udw.b[ 3 ] = 0x04;
|
|
|
|
iType = Udw.dw == 0x01020304 ? 1 : 2;
|
|
}
|
|
|
|
if( iType == 2 )
|
|
{
|
|
Udw.b[ 0 ] = *pubData++;
|
|
Udw.b[ 1 ] = *pubData++;
|
|
Udw.b[ 2 ] = *pubData++;
|
|
Udw.b[ 3 ] = *pubData;
|
|
}
|
|
else
|
|
{
|
|
Udw.b[ 3 ] = *pubData++;
|
|
Udw.b[ 2 ] = *pubData++;
|
|
Udw.b[ 1 ] = *pubData++;
|
|
Udw.b[ 0 ] = *pubData;
|
|
}
|
|
|
|
return Udw.dw;
|
|
}
|
|
|
|
#if !defined(DEVSTUDIO) // Not necessary for MDS
|
|
|
|
|
|
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(UNIDRVEXTRA, field), sizeof(pdmPrivate->field) }
|
|
|
|
{
|
|
PUNIDRVEXTRA pdmPrivate;
|
|
INT i;
|
|
|
|
static const struct {
|
|
|
|
DWORD dwIndex;
|
|
DWORD dwOffset;
|
|
DWORD dwSize;
|
|
|
|
} aIndexMap[] = {
|
|
|
|
MAPPSDEVMODEFIELD(OEMGDS_UNIDM_GPDVER, wVer),
|
|
MAPPSDEVMODEFIELD(OEMGDS_UNIDM_FLAGS, dwFlags),
|
|
|
|
{ 0, 0, 0 }
|
|
};
|
|
|
|
pdmPrivate = (PUNIDRVEXTRA) 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 unidrv 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.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
VUpdatePrivatePrinterData(
|
|
IN HANDLE hPrinter,
|
|
IN OUT PPRINTERDATA pPrinterData,
|
|
IN DWORD dwMode,
|
|
IN PUIINFO pUIInfo,
|
|
IN POPTSELECT pCombinedOptions
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Update the registry with the keywords
|
|
|
|
Arguments:
|
|
|
|
hPrinter - Handle to the current printer
|
|
pPrinterData - Points to PRINTERDATA
|
|
dwMode - MODE_READ/MODE_WRITE
|
|
|
|
Return Value:
|
|
|
|
None
|
|
TRUE if conversion was successful, FALSE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// UniDriver read/write registry steps for point and print to NT4 drivers
|
|
// 1. Writes ModelName to registry if necessary
|
|
// 2. Upgrade PageProtection
|
|
// 3. Upgrade FreeMem
|
|
//
|
|
|
|
PTSTR ptstrModelName = NULL;
|
|
PPAGEPROTECT pPageProtect = NULL;
|
|
PMEMOPTION pMemOption = NULL;
|
|
PFEATURE pPPFeature, pMemFeature;
|
|
DWORD dwFeatureIndex,dwSelection,dwIndex,dwError;
|
|
DWORD dwFlag, dwType, cbNeeded;
|
|
|
|
if (!pUIInfo || !pCombinedOptions)
|
|
return;
|
|
|
|
if (pPPFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGEPROTECTION))
|
|
pPageProtect = PGetIndexedOption(pUIInfo, pPPFeature, 0);
|
|
|
|
if (pMemFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_MEMOPTION))
|
|
pMemOption = PGetIndexedOption(pUIInfo, pMemFeature, 0);
|
|
|
|
dwType = REG_BINARY;
|
|
|
|
if (pPageProtect)
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pUIInfo, pPPFeature);
|
|
dwError = GetPrinterData(hPrinter, REGVAL_PAGE_PROTECTION, &dwType,
|
|
(BYTE *)&dwFlag, sizeof(dwFlag), &cbNeeded);
|
|
|
|
if (dwMode == MODE_READ )
|
|
{
|
|
if (dwError == ERROR_SUCCESS)
|
|
{
|
|
if (dwFlag & DXF_PAGEPROT)
|
|
dwSelection = PAGEPRO_ON;
|
|
else
|
|
dwSelection = PAGEPRO_OFF;
|
|
|
|
for (dwIndex = 0; dwIndex < pPPFeature->Options.dwCount; dwIndex++, pPageProtect++)
|
|
{
|
|
if (dwSelection == pPageProtect->dwPageProtectID)
|
|
break;
|
|
}
|
|
|
|
if (dwIndex == pPPFeature->Options.dwCount)
|
|
dwIndex = pPPFeature->dwDefaultOptIndex;
|
|
|
|
pCombinedOptions[dwFeatureIndex].ubCurOptIndex = (BYTE)dwIndex;
|
|
}
|
|
}
|
|
else // MODE_WRITE
|
|
{
|
|
#ifndef KERNEL_MODE
|
|
|
|
SHORT sRasddFlag;
|
|
|
|
if (dwError != ERROR_SUCCESS)
|
|
sRasddFlag = 0;
|
|
else
|
|
sRasddFlag = (SHORT)dwFlag;
|
|
|
|
pPageProtect = PGetIndexedOption(pUIInfo,
|
|
pPPFeature,
|
|
pCombinedOptions[dwFeatureIndex].ubCurOptIndex);
|
|
|
|
if (pPageProtect && pPageProtect->dwPageProtectID == PAGEPRO_ON)
|
|
sRasddFlag |= DXF_PAGEPROT;
|
|
else
|
|
sRasddFlag &= ~DXF_PAGEPROT;
|
|
|
|
SetPrinterData(hPrinter,
|
|
REGVAL_PAGE_PROTECTION,
|
|
REG_BINARY,
|
|
(BYTE *)&sRasddFlag,
|
|
sizeof(sRasddFlag));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if ( pMemOption)
|
|
{
|
|
dwFeatureIndex = GET_INDEX_FROM_FEATURE(pUIInfo, pMemFeature);
|
|
dwError = GetPrinterData(hPrinter, REGVAL_RASDD_FREEMEM, &dwType,
|
|
(BYTE *)&dwFlag, sizeof(dwFlag), &cbNeeded);
|
|
|
|
if (dwMode == MODE_READ )
|
|
{
|
|
if (dwError == ERROR_SUCCESS)
|
|
{
|
|
|
|
for (dwIndex = 0; dwIndex < pMemFeature->Options.dwCount; dwIndex++, pMemOption++)
|
|
{
|
|
if (dwFlag == (pMemOption->dwInstalledMem/KBYTES))
|
|
break;
|
|
}
|
|
|
|
if (dwIndex == pMemFeature->Options.dwCount)
|
|
dwIndex = pMemFeature->dwDefaultOptIndex;
|
|
|
|
pCombinedOptions[dwFeatureIndex].ubCurOptIndex = (BYTE)dwIndex;
|
|
}
|
|
|
|
}
|
|
else // MODE_WRITE
|
|
{
|
|
#ifndef KERNEL_MODE
|
|
|
|
pMemOption = PGetIndexedOption(pUIInfo,
|
|
pMemFeature,
|
|
pCombinedOptions[dwFeatureIndex].ubCurOptIndex);
|
|
|
|
if (pMemOption)
|
|
dwFlag = (pMemOption->dwInstalledMem/KBYTES);
|
|
|
|
SetPrinterData(hPrinter,
|
|
REGVAL_RASDD_FREEMEM,
|
|
REG_BINARY,
|
|
(BYTE *)&dwFlag,
|
|
sizeof(dwFlag));
|
|
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//
|
|
// Rasdd requires ModelName, so check if it's there and write it if it's not.
|
|
//
|
|
if (!(ptstrModelName = PtstrGetPrinterDataString(hPrinter, REGVAL_MODELNAME, &dwFlag)))
|
|
{
|
|
#ifndef KERNEL_MODE
|
|
|
|
PGPDDRIVERINFO pDriverInfo;
|
|
|
|
pDriverInfo = OFFSET_TO_POINTER(pUIInfo->pInfoHeader,
|
|
pUIInfo->pInfoHeader->loDriverOffset);
|
|
|
|
BSetPrinterDataString(hPrinter,
|
|
REGVAL_MODELNAME,
|
|
pDriverInfo->Globals.pwstrModelName,
|
|
REG_SZ);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if (ptstrModelName)
|
|
MemFree(ptstrModelName);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
--*/
|
|
|
|
{
|
|
PFEATURE pFeature;
|
|
PPAGESIZE pPageSize;
|
|
|
|
if (bMetric && (pUIInfo->dwFlags & FLAG_A4_SIZE_EXISTS))
|
|
{
|
|
CopyString(pDevmode->dmFormName, A4_FORMNAME, CCHFORMNAME);
|
|
pDevmode->dmPaperSize = DMPAPER_A4;
|
|
pDevmode->dmPaperWidth = 2100; // 210mm measured in 0.1mm units
|
|
pDevmode->dmPaperLength = 2970; // 297mm
|
|
|
|
}
|
|
else if (!bMetric && (pUIInfo->dwFlags & FLAG_LETTER_SIZE_EXISTS))
|
|
{
|
|
CopyString(pDevmode->dmFormName, LETTER_FORMNAME, CCHFORMNAME);
|
|
pDevmode->dmPaperSize = DMPAPER_LETTER;
|
|
pDevmode->dmPaperWidth = 2159; // 8.5"
|
|
pDevmode->dmPaperLength = 2794; // 11"
|
|
}
|
|
else
|
|
{
|
|
if (pFeature = GET_PREDEFINED_FEATURE(pUIInfo, GID_PAGESIZE))
|
|
{
|
|
//
|
|
// Skip writing the dmFormName here because
|
|
// ValidateDevmodeFormField will take care of it.
|
|
//
|
|
|
|
pPageSize = PGetIndexedOption(pUIInfo, pFeature, pFeature->dwDefaultOptIndex);
|
|
if (pPageSize)
|
|
{
|
|
pDevmode->dmPaperSize = (SHORT)pPageSize->dwPaperSizeID;
|
|
pDevmode->dmPaperWidth = (SHORT)(MASTER_UNIT_TO_MICRON(pPageSize->szPaperSize.cx,
|
|
pUIInfo->ptMasterUnits.x)
|
|
/ DEVMODE_PAPER_UNIT);
|
|
pDevmode->dmPaperLength = (SHORT)(MASTER_UNIT_TO_MICRON(pPageSize->szPaperSize.cy,
|
|
pUIInfo->ptMasterUnits.y)
|
|
/ DEVMODE_PAPER_UNIT);
|
|
|
|
pDevmode->dmFields |= (DM_PAPERWIDTH | DM_PAPERLENGTH | DM_PAPERSIZE);
|
|
pDevmode->dmFields &= ~DM_FORMNAME;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
pDevmode->dmFields &= ~(DM_PAPERWIDTH | DM_PAPERLENGTH);
|
|
pDevmode->dmFields |= (DM_PAPERSIZE | DM_FORMNAME);
|
|
}
|
|
|
|
#endif // !defined(DEVSTUDIO)
|
|
|