Annotation of ntddk/src/print/pscrptui/quryprnt.c, revision 1.1.1.1

1.1       root        1: //--------------------------------------------------------------------------
                      2: //
                      3: // Module Name:  QURYPRNT.C
                      4: //
                      5: // Brief Description:  This module contains the PSCRIPT driver's
                      6: // DevQueryPrint routine.
                      7: //
                      8: // Author:  Kent Settle (kentse)
                      9: // Created: 01-Apr-1992
                     10: //
                     11: // Copyright (c) 1992 Microsoft Corporation
                     12: //
                     13: //--------------------------------------------------------------------------
                     14: 
                     15: #include "pscript.h"
                     16: #include "enable.h"
                     17: #include "pscrptui.h"
                     18: #include <winspool.h>
                     19: 
                     20: extern PNTPD UIGetNTPD(PWSTR);
                     21: 
                     22: PFORM_INFO_1 GetFormsDataBase(HANDLE, DWORD *, PNTPD);
                     23: 
                     24: //--------------------------------------------------------------------------
                     25: // BOOL DevQueryPrint(hPrinter, pDevMode, pResID)
                     26: // HANDLE      hPrinter;
                     27: // DEVMODE    *pDevMode;
                     28: // DWORD      *pResID;
                     29: //
                     30: // This routine determines whether or not the driver can print the
                     31: // job described by pDevMode on the printer described by hPrinter.
                     32: // If if can, it puts zero into pResID.  If it cannot, it puts the
                     33: // resource id of the string describing why it could not.
                     34: //
                     35: // This routine returns TRUE for success, FALSE for failure.
                     36: //
                     37: // History:
                     38: //   01-Apr-1992     -by-     Kent Settle     (kentse)
                     39: //  Wrote it.
                     40: //--------------------------------------------------------------------------
                     41: 
                     42: BOOL DevQueryPrint(hPrinter, pDevMode, pResID)
                     43: HANDLE      hPrinter;
                     44: DEVMODE    *pDevMode;
                     45: DWORD      *pResID;
                     46: {
                     47:     DWORD               count;
                     48:     PNTPD               pntpd;
                     49:     DWORD               i;
                     50:     PSRESOLUTION       *pRes;
                     51:     BOOL                bFound;
                     52:     FORM_INFO_1        *pdbForms, *pdbForm;
                     53:     PWSTR               pwstrFormName;
                     54: #if DBG
                     55:     DWORD              *pID;
                     56: #endif
                     57: 
                     58:     // if we have a NULL pDevMode, then we have nothing to do.
                     59:     // the printer will just use defaults.
                     60: 
                     61:     if (pDevMode == NULL)
                     62:         return(TRUE);
                     63: 
                     64:     // assume everything will work.
                     65: 
                     66:     *pResID = 0;
                     67: 
                     68:     if (!(pntpd = MapPrinter(hPrinter)))
                     69:     {
                     70:         RIP("PSCRPTUI!DevQueryPrinter: MapPrinter failed.\n");
                     71:         return(FALSE);
                     72:     }
                     73: 
                     74:     // verify a bunch of stuff in the DEVMODE structure.
                     75: 
                     76: //!!! we should do some kind of version checking, once it has
                     77: //!!! been defined what we should check for.
                     78: #if 0
                     79:     if ((pDevMode->dmSpecVersion != DM_SPECVERSION) ||
                     80:         (pDevMode->dmDriverVersion != DRIVER_VERSION))
                     81:     {
                     82:         *pResID = STRING_BASE + IDS_INVALID_VERSION;
                     83:         GlobalFree((HGLOBAL)pntpd);
                     84:         return(TRUE);
                     85:     }
                     86: #endif
                     87: 
                     88:     // check the size of the DEVMODE.
                     89: 
                     90:     if (pDevMode->dmSize != sizeof(DEVMODE))
                     91:     {
                     92:         *pResID = STRING_BASE + IDS_INVALID_DEVMODE_SIZE;
                     93:         GlobalFree((HGLOBAL)pntpd);
                     94:         return(TRUE);
                     95:     }
                     96: 
                     97:     // make sure the user provided a valid orientation.
                     98: 
                     99:     if ((pDevMode->dmOrientation != DMORIENT_PORTRAIT) &&
                    100:         (pDevMode->dmOrientation != DMORIENT_LANDSCAPE))
                    101:     {
                    102:         *pResID = STRING_BASE + IDS_INVALID_ORIENTATION;
                    103:         GlobalFree((HGLOBAL)pntpd);
                    104:         return(TRUE);
                    105:     }
                    106: 
                    107:     // when a form is specified in the DEVMODE structure, first search
                    108:     // to see if it can be found in the forms database.  if it is not
                    109:     // found, return that fact to the caller.  if it is found, then
                    110:     // check to see if the current printer can print on the form.
                    111: 
                    112:     bFound = FALSE;
                    113: 
                    114:     // get a pointer to the form name supported by the user.
                    115: 
                    116:     pwstrFormName = pDevMode->dmFormName;
                    117: 
                    118:     // now enumerate the forms in the forms database.
                    119: 
                    120:     if (!(pdbForms = GetFormsDataBase(hPrinter, &count, pntpd)))
                    121:     {
                    122:         *pResID = STRING_BASE + IDS_INVALID_FORM;
                    123:         GlobalFree((HGLOBAL)pntpd);
                    124:         return(TRUE);
                    125:     }
                    126:     else
                    127:     {
                    128:         // search each form in the database for a matching name,
                    129:         // when it has been found, then search the forms supported
                    130:         // by the printer to make sure the printer can print it.
                    131: 
                    132:         pdbForm = pdbForms;
                    133: 
                    134:         for (i = 0; i < count; i++)
                    135:         {
                    136:             if (!(wcscmp(pdbForm->pName, pwstrFormName)))
                    137:             {
                    138:                 // we have found the form in the database,
                    139:                 // now make sure the printer can print it.
                    140: 
                    141:                 if (pdbForm->Flags & PSCRIPT_VALID_FORM)
                    142:                 {
                    143:                     bFound = TRUE;
                    144:                     break;
                    145:                 }
                    146:             }
                    147: 
                    148:             // search the next form in the database.
                    149: 
                    150:             pdbForm++;
                    151:         }
                    152: 
                    153:         GlobalFree((HGLOBAL)pdbForms);
                    154: 
                    155:         if (!bFound)
                    156:         {
                    157:             *pResID = STRING_BASE + IDS_INVALID_FORM;
                    158:             GlobalFree((HGLOBAL)pntpd);
                    159:             return(TRUE);
                    160:         }
                    161:     }
                    162: 
                    163:     // override the paper size if both the paper length and width
                    164:     // fields are set, and the corresponding values are valid.
                    165: 
                    166:     if ((pDevMode->dmFields & DM_PAPERLENGTH) &&
                    167:         (pDevMode->dmFields & DM_PAPERWIDTH))
                    168:     {
                    169:        if (!pDevMode->dmPaperLength || !pDevMode->dmPaperWidth)
                    170:         {
                    171:            RIP("PSCRIPT!bValidateSetDEVMODE: invalid scale.\n");
                    172:             SetLastError(ERROR_INVALID_PARAMETER);
                    173:             GlobalFree((HGLOBAL)pntpd);
                    174:            return(FALSE);
                    175:        }
                    176:     }
                    177: 
                    178:     if ((pDevMode->dmScale < MIN_SCALE) || (pDevMode->dmScale > MAX_SCALE))
                    179:     {
                    180:         *pResID = STRING_BASE + IDS_INVALID_SCALE;
                    181:         GlobalFree((HGLOBAL)pntpd);
                    182:         return(TRUE);
                    183:     }
                    184: 
                    185:     // how 'bout a valid number of copies.
                    186: 
                    187:     if ((pDevMode->dmCopies < MIN_COPIES) || (pDevMode->dmCopies > MAX_COPIES))
                    188:     {
                    189:         *pResID = STRING_BASE + IDS_INVALID_NUMBER_OF_COPIES;
                    190:         GlobalFree((HGLOBAL)pntpd);
                    191:         return(TRUE);
                    192:     }
                    193: 
                    194:     // make sure the user supplied a valid resolution to print with.
                    195: 
                    196:     // if cResolutions == 0, then only the default resolutions is valid.
                    197: 
                    198:     bFound = FALSE;
                    199: 
                    200:     if (pntpd->cResolutions == 0)
                    201:     {
                    202:         if (pDevMode->dmPrintQuality == (SHORT)pntpd->iDefResolution)
                    203:             bFound = TRUE;
                    204:     }
                    205:     else
                    206:     {
                    207:         // the current device supports multiple resolutions, so make
                    208:         // sure that the user has selected one of them.
                    209: 
                    210:         pRes = (PSRESOLUTION *)((CHAR *)pntpd + pntpd->loResolution);
                    211: 
                    212:         for (i = 0; i < pntpd->cResolutions; i++)
                    213:         {
                    214:             if ((pDevMode->dmPrintQuality == (SHORT)pRes++->iValue))
                    215:             {
                    216:                 bFound = TRUE;
                    217:                 break;
                    218:             }
                    219:         }
                    220: 
                    221:     }
                    222: 
                    223:     if (!bFound)
                    224:     {
                    225:         *pResID = STRING_BASE + IDS_INVALID_RESOLUTION;
                    226:         GlobalFree((HGLOBAL)pntpd);
                    227:         return(TRUE);
                    228:     }
                    229: 
                    230:     // make sure we have a valid color mode.
                    231: 
                    232:     if ((pDevMode->dmColor != DMCOLOR_COLOR) &&
                    233:         (pDevMode->dmColor != DMCOLOR_MONOCHROME))
                    234:     {
                    235:         *pResID = STRING_BASE + IDS_INVALID_COLOR;
                    236:         GlobalFree((HGLOBAL)pntpd);
                    237:         return(TRUE);
                    238:     }
                    239: 
                    240:     // if the user is trying to print color to a b/w
                    241:     // printer, let them know.
                    242: 
                    243:     if ((pDevMode->dmColor == DMCOLOR_COLOR) &&
                    244:         (!(pntpd->flFlags & COLOR_DEVICE)))
                    245:     {
                    246:         *pResID = STRING_BASE + IDS_COLOR_ON_BW;
                    247:         GlobalFree((HGLOBAL)pntpd);
                    248:         return(TRUE);
                    249:     }
                    250: 
                    251:     // make sure we have a valid duplex mode.
                    252: 
                    253:     if ((pDevMode->dmDuplex != DMDUP_SIMPLEX) &&
                    254:         (pDevMode->dmDuplex != DMDUP_HORIZONTAL) &&
                    255:         (pDevMode->dmDuplex != DMDUP_VERTICAL))
                    256:     {
                    257:         *pResID = STRING_BASE + IDS_INVALID_DUPLEX;
                    258:         GlobalFree((HGLOBAL)pntpd);
                    259:         return(TRUE);
                    260:     }
                    261: 
                    262:     // handle the driver specific data.  make sure it is ours.
                    263: 
                    264:     if (pDevMode->dmDriverExtra != 0)
                    265:     {
                    266:         if (pDevMode->dmDriverExtra != (sizeof(PSDEVMODE) - pDevMode->dmSize))
                    267:         {
                    268:             *pResID = STRING_BASE + IDS_INVALID_DRIVER_EXTRA_SIZE;
                    269:             GlobalFree((HGLOBAL)pntpd);
                    270:             return(TRUE);
                    271:        }
                    272:     }
                    273: 
                    274:     // free up the NTPD resource.
                    275: 
                    276: #if DBG
                    277:     // do a little sanity checking.
                    278: 
                    279:     pID = (DWORD *)((CHAR *)pntpd + pntpd->cjThis);
                    280: 
                    281:     ASSERTPS((*pID != DRIVER_ID),
                    282:              "PSCRPTUI!NTPD structure overran buffer!!!\n");
                    283: #endif
                    284: 
                    285:     GlobalFree((HGLOBAL)pntpd);
                    286: 
                    287:     return(TRUE);
                    288: }
                    289: 
                    290: 
                    291: //--------------------------------------------------------------------------
                    292: // PNTPD MapPrinter(hPrinter)
                    293: // HANDLE  hPrinter;
                    294: //
                    295: // This routine takes a handle to a printer and returns a pointer
                    296: // to the memory mapped for the corresponding NTPD structure.
                    297: //
                    298: // This routine returns NULL for failure.
                    299: //
                    300: // History:
                    301: //   15-Apr-1992     -by-     Kent Settle     (kentse)
                    302: //  Wrote it.
                    303: //--------------------------------------------------------------------------
                    304: 
                    305: PNTPD MapPrinter(hPrinter)
                    306: HANDLE  hPrinter;
                    307: {
                    308:     LPDRIVER_INFO_2 pDriverInfo;
                    309:     DWORD           cbNeeded;
                    310:     PNTPD           pntpd;
                    311: 
                    312:     // Call Winspool to get information on PrinterAlias, such as fully
                    313:     // qualified pathname to printer data file. call it once to find
                    314:     // how big the DRIVERINFO is for this printer. call it again to
                    315:     // fill in the structure.
                    316: 
                    317:     GetPrinterDriver (hPrinter, NULL, 2, NULL, 0, &cbNeeded);
                    318: 
                    319:     if (!(pDriverInfo = (LPDRIVER_INFO_2)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, cbNeeded)))
                    320:     {
                    321:         RIP("PSCRPTUI!MapPrinter: GlobalAlloc for pDriverInfo failed.\n");
                    322:         return((PNTPD)NULL);
                    323:     }
                    324: 
                    325:     if (!GetPrinterDriver (hPrinter, NULL, 2, (LPBYTE)pDriverInfo,
                    326:                            cbNeeded, &cbNeeded))
                    327:     {
                    328:         RIP("PSCRPTUI!MapPrinter: GetPrinterDriver failed.\n");
                    329:         GlobalFree ((HGLOBAL)pDriverInfo);
                    330:         return((PNTPD)NULL);
                    331:     }
                    332: 
                    333:     // pDriverInfo now contains everything we need to know about our
                    334:     // device, or at least how to get it.  the first thing to do is
                    335:     // open the .PPD file for the current device.
                    336: 
                    337:     if (!(pntpd = UIGetNTPD(pDriverInfo->pDataFile)))
                    338:     {
                    339:         RIP("PSCRPTUI!MapPrinter: MapFile failed.\n");
                    340:         GlobalFree((HGLOBAL)pDriverInfo);
                    341:         return((PNTPD)NULL);
                    342:     }
                    343: 
                    344:     // free up memory allocated above.
                    345: 
                    346:     GlobalFree((HGLOBAL)pDriverInfo);
                    347: 
                    348:     return(pntpd);
                    349: }
                    350: 
                    351: 
                    352: //--------------------------------------------------------------------------
                    353: // PFORM_INFO_1 GetFormsDataBase(hPrinter, pcount, pntpd)
                    354: // HANDLE      hPrinter;
                    355: // DWORD      *pcount;
                    356: // PNTPD       pntpd;
                    357: //
                    358: // This routine takes a handle to a printer, enumerates the forms
                    359: // database, determines which forms are valid for the specified printer,
                    360: // and returns a pointer to an array of PFORM_INFO_1 structures.
                    361: // It also fills in the count of the forms enumerated.
                    362: //
                    363: // This routine returns NULL for failure.
                    364: //
                    365: // History:
                    366: //   21-Apr-1993     -by-     Kent Settle     (kentse)
                    367: //  Made a seperate routine.
                    368: //--------------------------------------------------------------------------
                    369: 
                    370: PFORM_INFO_1 GetFormsDataBase(hPrinter, pcount, pntpd)
                    371: HANDLE      hPrinter;
                    372: DWORD      *pcount;
                    373: PNTPD       pntpd;
                    374: {
                    375:     DWORD           cbNeeded, count;
                    376:     DWORD           i, j;
                    377:     PFORM_INFO_1    pdbForms, pdbForm;
                    378:     PSFORM         *pPSForm;
                    379:     SIZEL           sizlForm, sizlPSForm;
                    380: 
                    381:     // enumerate all the forms in the forms database.  first, pass in a
                    382:     // NULL buffer pointer, to get the size of buffer needed.
                    383: 
                    384:     if (!EnumForms(hPrinter, 1, NULL, 0, &cbNeeded, &count))
                    385:     {
                    386:         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
                    387:         {
                    388:             RIP("PSCRPTUI!GetFormsDataBase: 1st EnumForms failed.\n");
                    389:             return((PFORM_INFO_1)NULL);
                    390:         }
                    391:     }
                    392: 
                    393:     // now allocate the buffer needed to enumerate all the forms.
                    394: 
                    395:     if (!(pdbForms = (PFORM_INFO_1)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
                    396:                                              cbNeeded)))
                    397:     {
                    398:         RIP("PSCRPTUI!GetFormsDataBase: GlobalAlloc failed.\n");
                    399:         return((PFORM_INFO_1)NULL);
                    400:     }
                    401: 
                    402:     // now get all the forms.
                    403: 
                    404:     if (!EnumForms(hPrinter, 1, (LPBYTE)pdbForms, cbNeeded,
                    405:                    &cbNeeded, &count))
                    406:     {
                    407:         // something went wrong.  let the caller know the enumeration failed.
                    408: 
                    409:         *pcount = 0;
                    410:         GlobalFree((HGLOBAL)pdbForms);
                    411:         return((PFORM_INFO_1)NULL);
                    412:     }
                    413: 
                    414:     // we now have a list of all the forms in the database.  now determine
                    415:     // which are valid for the current printer.
                    416: 
                    417:     // enumerate each form name.  check to see if it is
                    418:     // valid for the current printer.  mark the high bit of the
                    419:     // Flags element of the FORM_INFO_1 structure.
                    420: 
                    421:     pdbForm = pdbForms;
                    422: 
                    423:     for (i = 0; i < count; i++)
                    424:     {
                    425:         sizlForm = pdbForm->Size;
                    426: 
                    427:         pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);
                    428: 
                    429:         // clear the valid form bit.
                    430: 
                    431:         pdbForm->Flags &= ~PSCRIPT_VALID_FORM;
                    432: 
                    433:         for (j = 0; j < pntpd->cPSForms; j++)
                    434:         {
                    435:             // convert the PSFORM sizlPaper from USER to
                    436:             // .001mm coordinates.
                    437: 
                    438:             sizlPSForm.cx = USERTO001MM(pPSForm->sizlPaper.cx);
                    439:             sizlPSForm.cy = USERTO001MM(pPSForm->sizlPaper.cy);
                    440: 
                    441:             // look for each form which matches in size.
                    442:             // (within one mm).
                    443: 
                    444:             if ((sizlForm.cx <= sizlPSForm.cx + 1000) &&
                    445:                 (sizlForm.cx >= sizlPSForm.cx - 1000) &&
                    446:                 (sizlForm.cy <= sizlPSForm.cy + 1000) &&
                    447:                 (sizlForm.cy >= sizlPSForm.cy - 1000))
                    448:             {
                    449:                 // mark the form as valid for this printer, and update the
                    450:                 // valid form counter.
                    451: 
                    452:                 pdbForm->Flags |= PSCRIPT_VALID_FORM;
                    453:                 break;
                    454:             }
                    455: 
                    456:             // point to the next PSFORM.
                    457: 
                    458:             pPSForm++;
                    459:         }
                    460: 
                    461:         pdbForm++;
                    462:     }
                    463: 
                    464:     // everything must have worked.
                    465: 
                    466:     *pcount = count;
                    467:     return(pdbForms);
                    468: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.