Leaked source code of windows server 2003
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.
 
 
 
 
 
 

562 lines
14 KiB

/*++
Copyright (c) 1996-1999 Microsoft Corporation
Module Name:
data.h
Abstract:
Interface to PPD/GPD parsers and deals with getting binary data.
Environment:
Windows NT Unidrv driver
Revision History:
10/15/96 -amandan-
Created
--*/
#include "unidrv.h"
PGPDDRIVERINFO
PGetDefaultDriverInfo(
IN HANDLE hPrinter,
IN PRAWBINARYDATA pRawData
)
/*++
Routine Description:
This function just need to get default driverinfo
Arguments:
hPrinter - Handle to printer.
pRawData - Pointer to RAWBINARYDATA
Return Value:
Returns pUIInfo
Note:
--*/
{
PINFOHEADER pInfoHeader;
//
// Set the current driver version
//
pInfoHeader = InitBinaryData(pRawData, NULL, NULL);
//
// Get GPDDRIVERINFO
//
if (pInfoHeader == NULL)
return NULL;
else
return(OFFSET_TO_POINTER(pInfoHeader, pInfoHeader->loDriverOffset));
}
PGPDDRIVERINFO
PGetUpdateDriverInfo (
IN PDEV * pPDev,
IN HANDLE hPrinter,
IN PINFOHEADER pInfoHeader,
IN POPTSELECT pOptionsArray,
IN PRAWBINARYDATA pRawData,
IN WORD wMaxOptions,
IN PDEVMODE pdmInput,
IN PPRINTERDATA pPrinterData
)
/*++
Routine Description:
This function calls the parser to get the updated INFOHEADER
for the binary data.
Arguments:
hPrinter Handle to printer
pOptionsArray pointer to optionsarray
pRawData Pointer to RAWBINARYDATA
wMaxOptions max count for optionsarray
pdmInput Pointer to input DEVMODE
pPrinterData Pointer to PRINTERDATA
Return Value:
PINFOHEADER , NULL if failure.
Note:
At this point the input devmode have been validated. And its option
array is either the default or its own valid array. Don't need to check
again in this function.
Once completed, this function should have filled out the pOptionsArray with
1. Combined array from PRINTERDATA and DEVMODE
2. Resolve UI Conflicts
--*/
{
PUNIDRVEXTRA pdmPrivate;
POPTSELECT pDocOptions, pPrinterOptions;
RECTL rcFormImageArea;
OPTSELECT DocOptions[MAX_PRINTER_OPTIONS];
OPTSELECT PrinterOptions[MAX_PRINTER_OPTIONS];
//
// Check for PRINTERDATA.dwChecksum32, If matches with current binary data,
// Use it to combine PRINTERDATA.aOptions to combined array
//
pPrinterOptions = pPrinterData->dwChecksum32 == pRawData->dwChecksum32 ?
pPrinterData->aOptions : NULL;
if (pdmInput)
{
pdmPrivate = (PUNIDRVEXTRA) GET_DRIVER_PRIVATE_DEVMODE(pdmInput);
pDocOptions = pdmPrivate->aOptions;
}
else
pDocOptions = NULL;
//
// Combine the option arrays to pOptionsArray
// Note: pDocOptions and pPrinterOptions cannot be NULL when combining
// options array to get snapshot.
//
if (pDocOptions == NULL)
{
if (! InitDefaultOptions(pRawData,
DocOptions,
MAX_PRINTER_OPTIONS,
MODE_DOCUMENT_STICKY))
{
return FALSE;
}
pDocOptions = DocOptions;
}
if (pPrinterOptions == NULL)
{
if (! InitDefaultOptions(pRawData,
PrinterOptions,
MAX_PRINTER_OPTIONS,
MODE_PRINTER_STICKY))
{
return FALSE;
}
pPrinterOptions = PrinterOptions;
}
CombineOptionArray(pRawData, pOptionsArray, wMaxOptions, pDocOptions, pPrinterOptions);
if (! BMergeFormToTrayAssignments(pPDev))
{
ERR(("BMergeFormToTrayAssignments failed"));
}
//
// Resolve any UI conflicts.
//
if (!ResolveUIConflicts( pRawData,
pOptionsArray,
MAX_PRINTER_OPTIONS,
MODE_DOCANDPRINTER_STICKY))
{
VERBOSE(("Resolved conflicting printer feature selections.\n"));
}
//
// We are here means pOptionsArray is valid. Call parser to UpdateBinaryData
//
pInfoHeader = InitBinaryData(pRawData,
pInfoHeader,
pOptionsArray);
//
// Get GPDDRIVERINFO
//
if (pInfoHeader == NULL)
return NULL;
else
return(OFFSET_TO_POINTER(pInfoHeader, pInfoHeader->loDriverOffset));
}
VOID
VFixOptionsArray(
PDEV *pPDev,
PRECTL prcFormImageArea
)
/*++
Routine Description:
This functions is called to propagate public devmode settings
to the combined option array.
Arguments:
hPrinter Handle to printer
pInfoHeader Pointer to INFOHEADER
pOptionsArray Pointer to the options array
pdmInput Pointer to input devmode
bMetric Flag to indicate running in metric system
prcImageArea Returns the logical imageable area associated with the requested form
Return Value:
None
Note:
--*/
{
WORD wGID, wOptID, wOption;
HANDLE hPrinter = pPDev->devobj.hPrinter ;
PINFOHEADER pInfoHeader = pPDev->pInfoHeader ;
POPTSELECT pOptionsArray = pPDev->pOptionsArray ;
PDEVMODE pdmInput = pPDev->pdm ;
BOOL bMetric = pPDev->PrinterData.dwFlags & PFLAGS_METRIC ;
//
// Validate the form-related fields in the input devmode and
// make sure they're consistent with each other.
//
if (BValidateDevmodeFormFields(hPrinter, pdmInput, prcFormImageArea, NULL, 0) == FALSE)
{
//
// If failed to validate the form fields, ask parser to
// use the default
//
VDefaultDevmodeFormFields(pPDev->pUIInfo, pdmInput, bMetric );
prcFormImageArea->top = prcFormImageArea->left = 0;
prcFormImageArea->right = pdmInput->dmPaperWidth * DEVMODE_PAPER_UNIT;
prcFormImageArea->bottom = pdmInput->dmPaperLength * DEVMODE_PAPER_UNIT;
}
for (wOption = 0; wOption < MAX_GID; wOption++)
{
switch(wOption)
{
case 0:
wGID = GID_PAGESIZE;
VFixOptionsArrayWithPaperSizeID(pPDev) ;
continue;
break;
case 1:
wGID = GID_DUPLEX;
break;
case 2:
wGID = GID_INPUTSLOT;
break;
case 3:
wGID = GID_MEDIATYPE;
break;
case 4:
wGID = GID_COLORMODE;
break;
case 5:
wGID = GID_COLLATE;
break;
case 6:
wGID = GID_RESOLUTION;
break;
case 7:
wGID = GID_ORIENTATION;
break;
default:
continue;
}
ChangeOptionsViaID(pInfoHeader, pOptionsArray, wGID, pdmInput);
}
}
PWSTR
PGetROnlyDisplayName(
PDEV *pPDev,
PTRREF loOffset,
PWSTR wstrBuf,
WORD wsize
)
/*++
revised capabilities:
caller must pass in a local buffer to
hold the string, the local buffer
shall be of fixed size say
WCHAR wchbuf[MAX_DISPLAY_NAME];
The return value shall be either the passed
in ptr or a ptr pointing directly to the buds
binary data.
Routine Description:
Get a read-only copy of a display name:
1) if the display name is in the binary printer description data,
then we simply return a pointer to that data.
2) otherwise, the display name is in the resource DLL.
we allocate memory out of the driver's heap and
load the string.
Caller should NOT attempt to free the returned pointer unless
that pointer is one he allocated.
Arguments:
pci - Points to basic printer info
loOffset - Display name string offset
Return Value:
Pointer to the requested display name string
NULL if there is an error or string not found in resource.dll
--*/
{
if (loOffset & GET_RESOURCE_FROM_DLL)
{
//
// loOffset specifies a string resource ID
// in the resource DLL
//
INT iLength;
//
// First ensure the resource DLL has been loaded
// and a heap has already been created
//
// nah, just look here!
// pPDev->WinResData.hModule ;
//
// Load string resource into a temporary buffer
// and allocate enough memory to hold the string
//
// #ifdef RCSTRINGSUPPORT
#if 0
if(((loOffset & ~GET_RESOURCE_FROM_DLL) >= RESERVED_STRINGID_START)
&& ((loOffset & ~GET_RESOURCE_FROM_DLL) <= RESERVED_STRINGID_END))
{
iLength = ILoadStringW( &pPDev->localWinResData,
(int)( loOffset & ~GET_RESOURCE_FROM_DLL),
wstrBuf, wsize );
}
else
#endif
{
iLength = ILoadStringW( &pPDev->WinResData,
(int)( loOffset & ~GET_RESOURCE_FROM_DLL),
wstrBuf, wsize );
}
if( iLength)
return (wstrBuf); // debug check that buffer is null terminated.
return(NULL); // no string was found!
}
else
{
//
// loOffset is a byte offset from the beginning of
// the resource data block
//
return OFFSET_TO_POINTER(pPDev->pUIInfo->pubResourceData, loOffset);
// note wchbuf is ignored in this case.
}
}
VOID
VFixOptionsArrayWithPaperSizeID(
PDEV *pPDev
)
/*++
Routine Description:
Fix up combined options array with paper size information from public devmode fields
Arguments:
pci - Points to basic printer info
Return Value:
NONE
function uses:
UImodule Render Module equiv
pci->pUIInfo pPDev->pUIInfo
pci->pInfoHeader pPDev->pInfoHeader
pci->pdm pPDev->pdm
pci->pRawData pPDev->pRawData
pci->pCombinedOptions pPDev->pOptionsArray
MapToDeviceOptIndex
PGetIndexedOption
PGetReadOnlyDisplayName
ReconstructOptionArray
--*/
{
PFEATURE pFeature = GET_PREDEFINED_FEATURE(pPDev->pUIInfo, GID_PAGESIZE);
BOOL abEnabledOptions[MAX_PRINTER_OPTIONS];
PDWORD pdwPaperIndex = (PDWORD)abEnabledOptions;
DWORD dwCount, dwOptionIndex, i;
if (pFeature == NULL)
return;
dwCount = MapToDeviceOptIndex(pPDev->pInfoHeader,
GID_PAGESIZE,
pPDev->pdm->dmPaperWidth * DEVMODE_PAPER_UNIT,
pPDev->pdm->dmPaperLength * DEVMODE_PAPER_UNIT,
pdwPaperIndex);
if (dwCount == 0 )
return;
dwOptionIndex = pdwPaperIndex[0];
if (dwCount > 1 )
{
POPTION pOption;
PCWSTR pDisplayName;
WCHAR wchBuf[MAX_DISPLAY_NAME];
for (i = 0; i < dwCount; i++)
{
if (pOption = PGetIndexedOption(pPDev->pUIInfo, pFeature, pdwPaperIndex[i]))
{
if(pOption->loDisplayName == 0xffffffff) //use papername from EnumForms()
{
PFORM_INFO_1 pForms;
DWORD dwFormIndex ;
// temp hack!!! possibly needed for NT40 ?
// dwOptionIndex = pdwPaperIndex[i];
// break;
// end hack.
// ----- the fix ------ //
if (pPDev->pSplForms == NULL)
pPDev->pSplForms = MyEnumForms(pPDev->devobj.hPrinter, 1, &pPDev->dwSplForms);
if (pPDev->pSplForms == NULL)
{
// ERR(("No spooler forms.\n")); just a heads up.
// dwOptionIndex already set to safe default
break;
}
pForms = pPDev->pSplForms ;
dwFormIndex = ((PPAGESIZE)pOption)->dwPaperSizeID - 1 ;
if ( (dwFormIndex < pPDev->dwSplForms) &&
(pDisplayName = (pForms[dwFormIndex]).pName) &&
(_wcsicmp(pPDev->pdm->dmFormName, pDisplayName) == EQUAL_STRING) )
{
dwOptionIndex = pdwPaperIndex[i];
break;
}
}
else if ( (pDisplayName = PGetROnlyDisplayName(pPDev, pOption->loDisplayName,
wchBuf, MAX_DISPLAY_NAME )) &&
(_wcsicmp(pPDev->pdm->dmFormName, pDisplayName) == EQUAL_STRING) )
{
dwOptionIndex = pdwPaperIndex[i];
break;
}
}
} // if name doesn't match we default to the first candidate.
}
ZeroMemory(abEnabledOptions, sizeof(abEnabledOptions));
abEnabledOptions[dwOptionIndex] = TRUE;
ReconstructOptionArray(pPDev->pRawData,
pPDev->pOptionsArray,
MAX_COMBINED_OPTIONS,
GET_INDEX_FROM_FEATURE(pPDev->pUIInfo, pFeature),
abEnabledOptions);
}