mirror of https://github.com/lianthony/NT4.0
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.
355 lines
8.0 KiB
355 lines
8.0 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
quryprnt.c
|
|
|
|
Abstract:
|
|
|
|
Implementation of DrvQueryPrint
|
|
|
|
[Environment:]
|
|
|
|
Win32 subsystem, PostScript driver, user mode
|
|
|
|
Revision History:
|
|
|
|
06/22/95 -davidx-
|
|
Ported from Daytona.
|
|
|
|
mm/dd/yy -author-
|
|
description
|
|
|
|
--*/
|
|
|
|
|
|
#include "psui.h"
|
|
#include "regdata.h"
|
|
#include "..\..\lib\um\dqpfunc.c"
|
|
|
|
|
|
BOOL QueryPrintForm(PDEVQUERYPRINT_INFO, HPPD, PDEVMODE);
|
|
BOOL QueryPrinterFeatures(PDEVQUERYPRINT_INFO, HPPD, PSDEVMODE *);
|
|
|
|
|
|
|
|
BOOL
|
|
DevQueryPrintEx(
|
|
PDEVQUERYPRINT_INFO pDQPInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine determines whether or not the driver can print the job
|
|
described by pDevMode on the printer described by hPrinter.
|
|
|
|
Arguments:
|
|
|
|
pDQPInfo - Points to a DEVQUERYPRINT_INFO structure
|
|
|
|
Return Value:
|
|
|
|
TRUE if there is no conflict, FALSE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
HPPD hppd = NULL;
|
|
PDEVMODE pdm = NULL;
|
|
INT errID = 0;
|
|
BOOL result = TRUE;
|
|
|
|
//
|
|
// If no devmode is specified, default will be used
|
|
//
|
|
|
|
Assert(pDQPInfo && pDQPInfo->Level >= 1);
|
|
|
|
if (pDQPInfo->pDevMode == NULL)
|
|
return TRUE;
|
|
|
|
//
|
|
// Load printer description file and verify devmode information
|
|
//
|
|
|
|
if ((hppd = LoadPpdFile(pDQPInfo->hPrinter, TRUE)) == NULL) {
|
|
|
|
errID = IDS_DQPERR_PPD;
|
|
|
|
} if ((pdm = MEMALLOC(sizeof(PSDEVMODE))) == NULL) {
|
|
|
|
errID = IDS_DQPERR_MEMORY;
|
|
|
|
} else if (!SetDefaultDevMode(pdm, NULL, hppd, IsMetricCountry()) ||
|
|
!ValidateSetDevMode(pdm, pDQPInfo->pDevMode, hppd))
|
|
{
|
|
errID = IDS_INVALID_DEVMODE;
|
|
|
|
} else if (!QueryPrintForm(pDQPInfo, hppd, pdm)) {
|
|
|
|
result = FALSE;
|
|
|
|
} else if (!QueryPrinterFeatures(pDQPInfo, hppd, (PSDEVMODE *) pdm)) {
|
|
|
|
errID = IDS_FEATURE_CONFLICT;
|
|
|
|
} else if (!PpdFindResolution(hppd, pdm->dmPrintQuality) &&
|
|
PpdDefaultResolution(hppd) != pdm->dmPrintQuality)
|
|
{
|
|
errID = IDS_INVALID_RESOLUTION;
|
|
}
|
|
|
|
if (result && errID) {
|
|
|
|
DQPsprintf(ghInstance,
|
|
pDQPInfo->pszErrorStr,
|
|
pDQPInfo->cchErrorStr,
|
|
&pDQPInfo->cchNeeded,
|
|
TEXT("%!"),
|
|
errID);
|
|
|
|
result = FALSE;
|
|
}
|
|
|
|
//
|
|
// Clean up before returning
|
|
//
|
|
|
|
if (hppd)
|
|
UnloadPpdFile(hppd);
|
|
|
|
if (pdm)
|
|
MEMFREE(pdm);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
QueryPrintForm(
|
|
PDEVQUERYPRINT_INFO pDQPInfo,
|
|
HPPD hppd,
|
|
PDEVMODE pDevMode
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Verify specified paper/form option is supported by printer
|
|
|
|
Arguments:
|
|
|
|
pDQPInfo - Points to a DEVQUERYPRINT_INFO structure
|
|
hppd - Handle to printer PPD object
|
|
pDevMode - Pointer to DEVMODE data
|
|
|
|
Return Value:
|
|
|
|
TRUE if there is no conflict, FALSE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
FORM_TRAY_TABLE FormTrayTable;
|
|
LOGFORM logForm;
|
|
WCHAR SlotName[MAX_OPTION_NAME];
|
|
BOOL result = TRUE;
|
|
INT errID = 0;
|
|
|
|
switch (ValidateDevModeForm(pDQPInfo->hPrinter, pDQPInfo->pDevMode, &logForm)) {
|
|
|
|
case CUSTOM_FORM:
|
|
|
|
//
|
|
// Paper size is specified using paper width and paper length
|
|
//
|
|
|
|
if (!FormSupportedOnPrinter(hppd, (PFORM_INFO_1) &logForm, NULL, FALSE))
|
|
errID = IDS_INVALID_CUSTOM_SIZE;
|
|
break;
|
|
|
|
case VALID_FORM:
|
|
|
|
SlotName[0] = NUL;
|
|
|
|
//
|
|
// Check if an input slot is specifically requested
|
|
//
|
|
|
|
if ((pDevMode->dmFields & DM_DEFAULTSOURCE) &&
|
|
(pDevMode->dmDefaultSource != DMBIN_FORMSOURCE))
|
|
{
|
|
LONG SlotNum = (LONG) pDevMode->dmDefaultSource;
|
|
|
|
if (SlotNum == DMBIN_MANUAL || SlotNum == DMBIN_ENVMANUAL) {
|
|
|
|
//
|
|
// Don't really make sense to assign a form to manual-feed slot
|
|
// Let it through if the paper size is supported on the printer
|
|
// and ignore whatever that's assigned to manual-feed slot.
|
|
//
|
|
|
|
if (!FormSupportedOnPrinter(hppd, (PFORM_INFO_1) &logForm, NULL, FALSE))
|
|
errID = IDS_INVALID_PAPER_SIZE;
|
|
|
|
break;
|
|
|
|
} else if (hppd->pInputSlots != NULL && SlotNum >= DMBIN_USER) {
|
|
|
|
PINPUTSLOT pInputSlot;
|
|
|
|
pInputSlot = (PINPUTSLOT)
|
|
LISTOBJ_FindIndexed((PLISTOBJ) hppd->pInputSlots->pUiOptions,
|
|
SlotNum - DMBIN_USER);
|
|
|
|
if (pInputSlot != NULL)
|
|
CopyStr2Unicode(SlotName, GetXlatedName(pInputSlot), MAX_OPTION_NAME);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Retrieve form-to-tray assignment table
|
|
//
|
|
|
|
if (FormTrayTable = CurrentFormTrayTable(pDQPInfo->hPrinter)) {
|
|
|
|
PWSTR pNextEntry = FormTrayTable;
|
|
PWSTR pSlotName, pFormName, pPrinterForm;
|
|
BOOL IsDefaultTray;
|
|
|
|
//
|
|
// Check if there is an entry in the table matching the specified form name
|
|
//
|
|
|
|
result = FALSE;
|
|
|
|
while (*pNextEntry != NUL) {
|
|
|
|
pNextEntry = EnumFormTrayTable(pNextEntry,
|
|
&pSlotName,
|
|
&pFormName,
|
|
&pPrinterForm,
|
|
&IsDefaultTray);
|
|
|
|
if (wcscmp(pFormName, logForm.name) == EQUAL_STRING &&
|
|
(SlotName[0] == NUL || wcscmp(pSlotName, SlotName) == EQUAL_STRING))
|
|
{
|
|
result = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
FreeFormTrayTable(FormTrayTable);
|
|
|
|
if (!result) {
|
|
|
|
WCHAR formatStr[MAX_OPTION_NAME];
|
|
|
|
LoadString(ghInstance, IDS_DQPERR_PAPER_NOT_LOADED, formatStr, MAX_OPTION_NAME);
|
|
|
|
DQPsprintf(ghInstance,
|
|
pDQPInfo->pszErrorStr,
|
|
pDQPInfo->cchErrorStr,
|
|
&pDQPInfo->cchNeeded,
|
|
formatStr,
|
|
logForm.name,
|
|
SlotName);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
errID = IDS_INVALID_FORM;
|
|
break;
|
|
}
|
|
|
|
if (result && errID) {
|
|
|
|
DQPsprintf(ghInstance,
|
|
pDQPInfo->pszErrorStr,
|
|
pDQPInfo->cchErrorStr,
|
|
&pDQPInfo->cchNeeded,
|
|
TEXT("%!"),
|
|
errID);
|
|
|
|
result = FALSE;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
QueryPrinterFeatures(
|
|
PDEVQUERYPRINT_INFO pDQPInfo,
|
|
HPPD hppd,
|
|
PSDEVMODE *pdm
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Look for conflicting printer-feature selections
|
|
|
|
Arguments:
|
|
|
|
pDQPInfo - Points to a DEVQUERYPRINT_INFO structure
|
|
hppd - Handle to PPD object
|
|
pdm - Pointer to a PSDEVMODE structure
|
|
|
|
Return Value:
|
|
|
|
TRUE if there is no conflict, FALSE otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
PPRINTERDATA pPrinterData;
|
|
WORD index;
|
|
BOOL result = TRUE;
|
|
|
|
//
|
|
// Get printer property data from registry
|
|
//
|
|
|
|
if (pPrinterData = GetPrinterProperties(pDQPInfo->hPrinter, hppd)) {
|
|
|
|
//
|
|
// Convert public devmode fields to printer feature selections
|
|
//
|
|
|
|
DevModeFieldsToOptions(pdm, pdm->dmPublic.dmFields, hppd);
|
|
|
|
//
|
|
// Check if any of the doc-sticky features are constrained
|
|
//
|
|
|
|
for (index=0; index < hppd->cDocumentStickyFeatures; index++) {
|
|
|
|
if (PpdFeatureConstrained(hppd,
|
|
pPrinterData->options,
|
|
pdm->dmPrivate.options,
|
|
index,
|
|
pdm->dmPrivate.options[index]))
|
|
{
|
|
result = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
MEMFREE(pPrinterData);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|