PFILEOBJ FILEOBJ_Create( PCWSTR pwstrFilename, WORD *pwChecksum ) /*++ Routine Description: Create a file object Arguments: pwstrFilename - Pointer to fully qualified Unicode filename pwChecksum - Pointer to a 16-bit crc checksum variable Return Value: Pointer to newly created file object NULL if an error occured --*/ { PFILEOBJ pFileObj; // Allocate space for a file object pFileObj = (PFILEOBJ) MEMALLOC(sizeof(FILEOBJ)); if (pFileObj != NULL) { // Save the pointer to checksum variable pFileObj->pwChecksum = pwChecksum; // Map the file into memory if (! MAPFILE( pwstrFilename, &pFileObj->hModule, (PBYTE*) &pFileObj->pNextChar, &pFileObj->cbAvailable)) { DBGERRMSG("MAPFILE"); MEMFREE(pFileObj); pFileObj = NULL; } } else { // Failed to allocate memory DBGERRMSG("MEMALLOC"); } return pFileObj; }
BOOL NeedPageSetupSection( PDEVDATA pdev ) /*++ Routine Description: Determine whether we need to have a PageSetup section to support device specific features. Arguments: pdev - Pointer to our DEVDATA structure Return Value: TRUE if a PageSetup section is needed. FALSE if not. --*/ { WORD index; // Prepare data for handling printer specific feature // if it's not done already. if (pdev->pFeatureData == NULL) { if (! PrepareFeatureData(pdev)) { DBGERRMSG("PrepareFeatureData"); return FALSE; } } // Check if any of the requested features should appear in // PageSetup section. for (index=0; index < pdev->cSelectedFeature; index++) { if (pdev->pFeatureData[index].section == ODS_PAGESETUP) return TRUE; } return FALSE; }
BOOL bSendPSProcSet( PDEVDATA pdev, ULONG ulPSid ) /*++ Routine Description: Load the specified procset from the resource file and then output it to printer. Arguments: pdev Pointer to DEVDATA structure ulPSid Resource ID of the procset Return Value: TRUE if successful. FALSE otherwise. --*/ { PVOID pres; ULONG size; if (pdev->dwFlags & PDEV_CANCELDOC) return FALSE; // Retrieve the specified procset from resource file pres = EngFindResource(pdev->hModule, ulPSid, PSPROC, &size); if (pres == NULL || size == 0) { DBGERRMSG("EngFindResource"); pdev->dwFlags |= PDEV_CANCELDOC; return FALSE; } // Output the procset to printer return pswrite(pdev, pres, size); }
PPDERROR PARSEROBJ_ParseValue( PPARSEROBJ pParserObj, PFILEOBJ pFileObj, PSTR pCh ) /*++ Routine Description: Parse the entry value. Arguments: pParserObj - pointer to the parser object pFileObj - pointer to input file object pCh - placeholder for returning the entry value terminating character Return Value: PPDERR_NONE - entry value was parsed successfully PPDERR_xxx - an error occured --*/ { PPDERROR err; BOOL bQuoted; PBUFOBJ pBufObj = & pParserObj->value; // Skip over any leading spaces do { err = FILEOBJ_GetChar(pFileObj, pCh); if (err != PPDERR_NONE) return err; } while (IsSpace(*pCh)); // Check to see if the first character is a '"'. // If it's a '"', then parse a quoted value (which // can span multiple lines) until the matching quote // is found. If the first character is not a quote, // the parse a normal string value until a newline // is found. if (*pCh == QUOTE_CHAR) { bQuoted = TRUE; pParserObj->valueType = QUOTED_VALUE; err = FILEOBJ_GetChar(pFileObj, pCh); } else { bQuoted = FALSE; pParserObj->valueType = STRING_VALUE; } for ( ; ; ) { // Read characters from the file until one of the // following condition is true: // an error occured // found a '"' when parsing a quoted value // found a newline or '/' when parsing a normal value if ((err != PPDERR_NONE) || (bQuoted && *pCh == QUOTE_CHAR) || (!bQuoted && (IsNewline(*pCh) || *pCh == XLATION_CHAR))) { break; } // Add the character to the buffer if (BUFOBJ_AddChar(pBufObj, *pCh) != PPDERR_NONE) { PSTR pNewBuffer; // The value string is longer than what our // buffer can hold. Expand the buffer by // DefaultValueLen. pNewBuffer = (PSTR) MEMALLOC(pBufObj->maxlen + 1 + DefaultValueLen); if (pNewBuffer == NULL) { DBGERRMSG("MEMALLOC"); return PPDERR_MEM; } else { memset(pNewBuffer, 0, pBufObj->maxlen + 1 + DefaultValueLen); } // Copy over the previous buffer contents memcpy(pNewBuffer, pBufObj->pBuffer, pBufObj->curlen); // Free the previous buffer MEMFREE(pBufObj->pBuffer); // Switch to the new buffer and update the buffer length. pBufObj->pBuffer = pNewBuffer; pBufObj->maxlen += DefaultValueLen; // Try adding the character to the buffer again. err = BUFOBJ_AddChar(pBufObj, *pCh); ASSERT(err == PPDERR_NONE); } // Read the next character from the file err = FILEOBJ_GetChar(pFileObj, pCh); } // Null-terminate the value string pBufObj->pBuffer[pBufObj->curlen] = '\0'; // Skip the remaining characters on the line // (which should be a translation string). if (err == PPDERR_NONE && ! IsNewline(*pCh)) err = PARSEROBJ_SkipLine(pParserObj, pFileObj); // Handle symbol value if (pParserObj->valueType == STRING_VALUE && *(pBufObj->pBuffer) == SYMBOL_CHAR) pParserObj->valueType = SYMBOL_VALUE; return err; }
PPARSEROBJ PARSEROBJ_Create( VOID ) /*++ Routine Description: Create a parser object Arguments: NONE Return Value: Pointer to newly recreated parser object NULL if an error occured --*/ { PPARSEROBJ pParserObj; // Allocate memory space and initialize its content to zero pParserObj = (PPARSEROBJ) MEMALLOC(sizeof(PARSEROBJ)); if (pParserObj == NULL) { DBGERRMSG("MEMALLOC"); } else { PSTR pBuffer; // Allocate memory to for holding the value. // Since the value can be very long, we start out // from a default sized buffer. When we run // out of room during parsing, we will grow // the buffer through GlobalReAlloc. pBuffer = (PSTR) MEMALLOC(DefaultValueLen+1); if (pBuffer == NULL) { DBGERRMSG("MEMALLOC"); MEMFREE(pParserObj); pParserObj = NULL; } else { memset(pParserObj, 0, sizeof(PARSEROBJ)); memset(pBuffer, 0, DefaultValueLen+1); // Initialize the buffer objects. BUFOBJ_Initialize( & pParserObj->keyword, pParserObj->mainKeyword, MaxKeywordLen); BUFOBJ_Initialize( & pParserObj->option, pParserObj->optionKeyword, MaxKeywordLen); BUFOBJ_Initialize( & pParserObj->xlation, pParserObj->translation, MaxXlationLen); BUFOBJ_Initialize( & pParserObj->value, pBuffer, DefaultValueLen); } } return pParserObj; }
VOID PsSelectPrinterFeatures( PDEVDATA pdev, WORD section ) /*++ Routine Description: Select printer specific feature to appear in a given section. Arguments: pdev - Pointer to our DEVDATA structure section - DSC section we're currently in Return Value: NONE --*/ { WORD index; PFEATUREDATA pFeatureData; PUIGROUP pUiGroup; PUIOPTION pUiOption; // // Prepare data for handling printer specific feature if it's not done already. // if (!pdev->pFeatureData && !PrepareFeatureData(pdev)) { DBGERRMSG("PrepareFeatureData"); return; } // // For each requested feature, check if it should be sent to // the printer in the current DSC section. // for (index = 0, pFeatureData = pdev->pFeatureData; index < pdev->cSelectedFeature; index ++, pFeatureData++) { // // Find the UIOPTION object corresponding to the requested feature/selection. // // HACK: PageSize feature is handled differently here because it involves // lots of legacy stuff which we don't want to touch at this point. // if (! (pFeatureData->section & section)) continue; if (pdev->hppd->pPageSizes && pdev->hppd->pPageSizes->featureIndex == pFeatureData->feature) { PsSelectFormAndTray(pdev); } else if (PpdFindFeatureSelection( pdev->hppd, pFeatureData->feature, pFeatureData->option, &pUiGroup, &pUiOption)) { DBGMSG1(DBG_LEVEL_VERBOSE, "Feature: %s\n", pUiGroup->pName); DBGMSG1(DBG_LEVEL_VERBOSE, "Selection: %s\n", pUiOption->pName); // // If we're not in JCLSetup section, then enclose the feature // invocation in a mark/cleartomark pair. // if (section != ODS_JCLSETUP) { DscBeginFeature(pdev, pUiGroup->pName); psprintf(pdev, " %s\n", pUiOption->pName); } if (pUiOption->pInvocation) psputs(pdev, pUiOption->pInvocation); if (section != ODS_JCLSETUP) DscEndFeature(pdev); } } }
BOOL PrepareFeatureData( PDEVDATA pdev ) /*++ Routine Description: Prepare data for handling printer specific feature Arguments: pdev - Pointer to our DEVDATA structure Return Value: TRUE if successful, FALSE otherwise --*/ { PPACKEDORDERDEP pOrderDep; PFEATUREDATA pFeatureData; BYTE options[MAX_PRINTER_OPTIONS]; WORD index, cOptions; HPPD hppd; ASSERT(pdev->cSelectedFeature == 0 && pdev->pFeatureData == NULL); // Allocate memory to hold printer specific feature data memset(options, OPTION_INDEX_ANY, sizeof(options)); hppd = pdev->hppd; cOptions = hppd->cDocumentStickyFeatures + hppd->cPrinterStickyFeatures; ASSERT(cOptions <= MAX_PRINTER_OPTIONS) if (hppd->cDocumentStickyFeatures != pdev->dm.dmPrivate.wOptionCount && hppd->cPrinterStickyFeatures != pdev->pPrinterData->wOptionCount) { DBGMSG(DBG_LEVEL_ERROR, "Invalid option count.\n"); } memcpy(options, pdev->dm.dmPrivate.options, hppd->cDocumentStickyFeatures); memcpy(&options[hppd->cDocumentStickyFeatures], pdev->pPrinterData->options, hppd->cPrinterStickyFeatures); pdev->pFeatureData = HEAPALLOC(pdev->hheap, cOptions * sizeof(FEATUREDATA)); if (pdev->pFeatureData == NULL) { DBGERRMSG("MEMALLOC"); return FALSE; } // Collect printer specific feature data pFeatureData = pdev->pFeatureData; for (index=0; index < cOptions; index++) { if (options[index] != OPTION_INDEX_ANY) { pOrderDep = PpdFindOrderDep(hppd, index, options[index]); if (pOrderDep != NULL && (pOrderDep->section & (ODS_PROLOG | ODS_EXITSERVER))) { // Prolog and ExitServer are treated the same as DocSetup DBGMSG(DBG_LEVEL_WARNING, "Prolog and ExitServer section encountered.\n"); pFeatureData->section = ODS_DOCSETUP; pFeatureData->order = pOrderDep->order; } else if (pOrderDep == NULL) { // If a feature has no corresponding OrderDependency entry, // assume it goes to the end of DocumentSetup section. pFeatureData->section = ODS_DOCSETUP; pFeatureData->order = MAXPSREAL; } else { pFeatureData->section = pOrderDep->section; pFeatureData->order = pOrderDep->order; } pFeatureData->feature = index; pFeatureData->option = options[index]; pFeatureData++; } } // Sort printer specific feature data using OrderDependency. // Since the number of features is very small (usually less // than a handful), we don't have to be too concerned with // sorting speed here. if (pdev->cSelectedFeature = (WORD) (pFeatureData - pdev->pFeatureData)) { cOptions = pdev->cSelectedFeature; pFeatureData = pdev->pFeatureData; for (index=0; index < cOptions-1; index++) { WORD n, m = index; for (n=index+1; n < cOptions; n++) { if (pFeatureData[n].order < pFeatureData[m].order) m = n; } if (m != index) { FEATUREDATA featureData; featureData = pFeatureData[index]; pFeatureData[index] = pFeatureData[m]; pFeatureData[m] = featureData; } } } return TRUE; }