Annotation of ntddk/src/print/pscrptui/quryprnt.c, revision 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.