DEVESC_SETJOBPROPERTIES is used to set information in the printer's job properties structure. This structure is known only to the printer presentation driver and this escape is the only way for an application to set values inside the structure.
Since DEVESC_SETJOBPROPERTIES is new, applications will call GreEscape DEVESC_QUERYESCSUPPORT to determine if you support this DevEscape.
The DevEscape path has a handle to a device context (HDC) that should already have printer property information associated with the HDC. Job property information may change or may be dependent upon the printer property information in the HDC. In that case, if an application passes job properties for a different device or for a different spooler printer name, then misleading information will be returned.
You should test the input job properties to make sure that they are valid. This includes passing tests such as whether they contain your driver's signature string, whether the device name is yours, and whether the values are within proper ranges (only landscape or portrait). If these tests fail, then fail the call.
LONG ENGENTRY Escape (HDC hdc, LONG lEscape, LONG cInCount, PBYTE pInData, PLONG pcOutCount, PBYTE pOutData, PDDC pddc, ULONG ulFunction) { switch (lEscape) { case DEVESC_SETJOBPROPERTIES: { INT cbQueries = cInCount; PBYTE pbQueries = pInData; PDJP_ITEM pISet = (PDJP_ITEM)pbQueries; BOOL fError = FALSE; ULONG ulMaxSize; if (GRE_234 > globals.ulGreVersion) { assertstring ("Not supported on pre-DAX engine!\n"); lrc = DEVESC_NOTIMPLEMENTED; break; } pGoodDrivData = ReturnDriverData (pddc->pdb, pdi, pddc->pdb->hmcbHeap, pDrivData, pddc->pdb->pszPrinterName, TRUE, pDevice, pDriver); assertF (pGoodDrivData); /* Is the size of the input driver data is not the same as ** the size of our good data? */ if (pDrivData->cb != pGoodDrivData->cb) lrc = DEV_PROP_BUF_TOO_SMALL; /* Or, if the two don't compare, then fail the call. */ if (0 != memcmp (pDrivData, pGoodDrivData, pGoodDrivData->cb)) lrc = DEV_INV_INP_JOBPROPERTIES; // Update the job properties with the input set list do { DBPRINTF (("Set '%s'/%d. Query type '%s'/%d. Simple value = %d\n", pszProperty (pISet->ulProperty), pISet->ulProperty, pszType (pISet->lType), pISet->lType, pISet->ulValue)); switch (pISet->ulProperty) { case DJP_SJ_ORIENTATION: { if (pISet->ulValue == DJP_ORI_PORTRAIT) { pJobProp->ulOrientation = ORIENTATION_PORTRAIT; } else if (pISet->ulValue == DJP_ORI_LANDSCAPE) { pJobProp->ulOrientation = ORIENTATION_LANDSCAPE; } else { pISet->lType = DJP_ERROR_OUT_OF_RANGE; } break; } case DJP_CJ_RESOLUTION: { PDJPT_RESOLUTION pRes = DJP_ELEMENTP (*pISet, DJPT_RESOLUTION); PRESINFO pResInfo = pDriver->pRES; ULONG ulNumDefined = pDriver->ulNumRes; PULONG pulResDevice = pDevice->pulRES; ULONG ulNumDevice = pDevice->usNumRes; BOOL fFound = FALSE; register INT i, j; for (i = 0; !fFound && i < ulNumDevice; i++, pulResDevice++) { for (j = 0; j < ulNumDefined; j++) { if (pResInfo[j].ulResID == *pulResDevice) { if (pRes->usXResolution == pResInfo[j].ulXRes && pRes->usYResolution == pResInfo[j].ulYRes ) { fFound = TRUE; pJobProp->ulDefResID = *pulResDevice; break; } } } } if (!fFound) pISet->lType = DJP_ERROR_OUT_OF_RANGE; break; } case DJP_SJ_BITSPERPEL: case DJP_SJ_COLOR: { PPRINTMODE pPrintMode = pDriver->pPrintModes; ULONG ulNumDefined = pDriver->ulNumPrintModes; PULONG pulPrintModes = pDevice->pulPrintModes; ULONG ulNumDevice = pDevice->usNumPrintModes; PDJPT_BITSPERPEL pTmp = DJP_ELEMENTP (*pISet, DJPT_BITSPERPEL); BOOL fFound = FALSE; register INT i, j; for (i = 0; !fFound && i < ulNumDevice; i++, pulPrintModes++) { fFound = FALSE; for (j = 0; j < ulNumDefined; j++) { if (pPrintMode[j].ulPrintModeID == *pulPrintModes) { if (DJP_SJ_BITSPERPEL == pISet->ulProperty) { if (*pTmp == pPrintMode[j].usLogBitCount) { pJobProp->ulDefPrintModeID = *pulPrintModes; fFound = TRUE; break; } } else { if (((1 == pPrintMode[j].usBitsPerPel) && (*pTmp == DJP_CLR_MONOCHROME) ) || ((1 < pPrintMode[j].usBitsPerPel) && (*pTmp == DJP_CLR_COLOR) ) ) { pJobProp->ulDefPrintModeID = *pulPrintModes; fFound = TRUE; break; } } } } } if (!fFound) pISet->lType = DJP_ERROR_OUT_OF_RANGE; break; } case DJP_SJ_PAPERSIZE: { ULONG ulNumDefined = pDevice->ulNumForms; PFORMINFO2 pFormInfo = pDevice->pFORMS; PDJPT_PAPERSIZE pSize = DJP_ELEMENTP (*pISet, DJPT_PAPERSIZE); BOOL fFound = FALSE; LONG lRet; register INT i; for (i = 0; i < ulNumDefined; i++) { lRet = pFormInfo[i].ulDJPid; if (DJP_PSI_NONE != lRet && *pSize == lRet) { fFound = TRUE; break; } } if (fFound) { ULONG ulDefaultConnID = pJobProp->ulDefConnID, ulDefaultFormID = 0, ulDefaultTrayID = 0, ulDefaultMediaID = 0; BOOL bOK; // Ask for the current connection id bOK = GetIDsFromConnID (pDriver, pDevice, ulDefaultConnID, &ulDefaultTrayID, &ulDefaultFormID, &ulDefaultMediaID); if (bOK) // Get a new connection id bOK = NewConnection (pdb, pGoodDrivData->szDeviceName, &ulDefaultConnID, pFormInfo[i].ulFormID, // Override form ulDefaultTrayID, ulDefaultMediaID, FALSE); // Dont create a new one! // Set it! if (bOK) pJobProp->ulDefConnID = ulDefaultConnID; else pISet->lType = DJP_ERROR_OUT_OF_RANGE; } else { pISet->lType = DJP_ERROR_OUT_OF_RANGE; } break; } case DJP_CJ_FORM: { ULONG ulNumDefined; ULONG ulNumDevice; PDJPT_FORM pDJPForm = DJP_ELEMENTP (*pISet, DJPT_FORM); PFORMINFO2 pFormInfo = (PFORMINFO2)NULL; PTRAYINFO pTrayInfo = (PTRAYINFO)NULL; PMEDIAINFO pMediaInfo = (PMEDIAINFO)NULL; CHAR szTempName[32]; BOOL bOK; register INT i, j; ulNumDevice = pDevice->ulNumForms; for (i = 0; i < ulNumDevice; i++) { FormNameFromID (pDriver, pDevice, szTempName, pDevice->pFORMS[i].ulFormID); if (0 == strcmp (pDJPForm->szFormname, szTempName)) { pFormInfo = (PFORMINFO2) &pDevice->pFORMS[i]; break; } } if (pDJPForm->szTrayname[0]) { ulNumDevice = pDevice->usNumTrays; ulNumDefined = pDriver->ulNumTrays; for (i = 0; i < ulNumDefined && !pTrayInfo; i++) { for (j = 0; j < ulNumDevice; j++) { if (pDriver->pTRAYS[i].ulTrayID == pDevice->pulTRAYS[j]) { TrayNameFromID (pDriver, pDevice, szTempName, pDriver->pTRAYS[i].ulTrayID); if (0 == strcmp (pDJPForm->szTrayname, szTempName)) { pTrayInfo = (PTRAYINFO) &pDriver->pTRAYS[i]; break; } } } } } if (pDJPForm->szMedianame[0]) { ulNumDevice = pDevice->ulNumMedias; ulNumDefined = pDriver->ulNumMedias; for (i = 0; i < ulNumDefined && !pMediaInfo; i++) { for (j = 0; j < ulNumDevice; j++) { if (pDriver->pMEDIAS[i].ulMediaID == pDevice->pulMEDIAS[j]) { MediaNameFromID (pDriver, pDevice, szTempName, pDriver->pMEDIAS[i].ulMediaID); if (0 == strcmp (pDJPForm->szMedianame, pszTempName)) { pMediaInfo = (PMEDIAINFO) &pDriver->pMEDIAS[i]; break; } } } } } if (pFormInfo) { ULONG ulDefaultConnID = pJobProp->ulDefConnID, ulDefaultFormID = 0, ulDefaultTrayID = 0, ulDefaultMediaID = 0; // Ask for the current connection id bOK = GetIDsFromConnID (pDriver, pDevice, ulDefaultConnID, &ulDefaultTrayID, &ulDefaultFormID, &ulDefaultMediaID); ulDefaultFormID = pFormInfo->ulFormID; if (pTrayInfo) ulDefaultTrayID = pTrayInfo->ulTrayID; if (pMediaInfo) ulDefaultMediaID = pMediaInfo->ulMediaID; bOK = NewConnection (pdb, pGoodDrivData->szDeviceName, &ulDefaultConnID, ulDefaultFormID, ulDefaultTrayID, ulDefaultMediaID, FALSE); // Dont create a new one! } else bOK = FALSE; if (bOK) pJobProp->ulDefConnID = ulDefaultConnID; else pISet->lType = DJP_ERROR_OUT_OF_RANGE; break; } case DJP_SJ_COPIES: { if (0 < pISet->ulValue && pISet->ulValue < 100) pJobProp->ulCopies = pISet->ulValue; else pISet->lType = DJP_ERROR_OUT_OF_RANGE; break; } case DJP_SJ_PRINTQUALITY: case DJP_SJ_TRAYTYPE: case DJP_SJ_MEDIA: case DJP_SJ_MEDIA_COLOR: case DJP_CJ_MIXEDFORMS: case DJP_SJ_FONTDOWNLOADING: case DJP_SJ_DUPLEX: case DJP_SJ_COLLATE: case DJP_SJ_FEED: case DJP_SJ_SCALING: case DJP_SJ_FORMFEEDCONTROL: case DJP_SJ_N_UP: default: pISet->lType = DJP_ERROR_NOT_SUPPORTED; DBPRINTF (("Unknow set '%s' = %d!\n", pszProperty (pISet->ulProperty), pISet->ulProperty)); break; } // Move to the set item pISet = DJP_NEXT_STRUCTP (pISet); } while (pISet->ulProperty != DJP_NONE); cbDrivData = cbParm2; pDrivData = (PDRIVDATA)pbParm2; /* Copy the updated job properties onto the user's job properties */ ulMaxSize = min (pGoodDrivData->cb, cbDrivData); memcpy (pDrivData, pGoodDrivData, ulMaxSize); pDrivData->cb = ulMaxSize; if (fError) { GplErrSetWarning (PMERR_DATATYPE_ENTRY_INVALID); ulrc = DEV_ERROR; } else { ulrc = DEV_OK; } break; } } return lrc; }