예제 #1
0
파일: prnprop.c 프로젝트: Gaikokujin/WinNT4
PVOID
GetPrinterRegistryData(
    HANDLE  hPrinter,
    PWSTR   pRegKey
    )

/*++

Routine Description:

    Retrieve printer data from the registry

Arguments:

    hPrinter - Handle to the printer object
    pRegKey - Specifies the registry key name

Return Value:

    Pointer to the printer data, NULL if there is an error

Note:

    We assume the first WORD of the printer data contains the size information.

--*/

{
    DWORD   cbNeeded, type;
    PVOID   pData = NULL;

    if (GetPrinterData(hPrinter, pRegKey, &type, NULL, 0, &cbNeeded) == ERROR_MORE_DATA &&
        (pData = MemAlloc(cbNeeded)) != NULL &&
        GetPrinterData(hPrinter, pRegKey, &type, pData, cbNeeded, &cbNeeded) == ERROR_SUCCESS &&
        cbNeeded > sizeof(WORD) && cbNeeded == *((PWORD) pData))
    {
        return pData;
    }

    Error(("Couldn't get printer data: %ws\n", pRegKey));
    MemFree(pData);
    return NULL;
}
예제 #2
0
파일: formbox.c 프로젝트: kcrazy/winekit
BOOL
AddFormsToDataBase(
    PPRINTERINFO    pPI,
    BOOL            DeleteFirst
    )

/*++

Routine Description:

    This function add driver supports forms to the data base

Arguments:

    pPI - Pointer to the PRINTERINFO


Return Value:

    BOOLEAN


Author:

    09-Dec-1993 Thu 22:38:27 created  

    27-Apr-1994 Wed 19:18:58 updated  
        Fixed bug# 13592 which printman/spooler did not call ptrprop first but
        docprop so let us into unknown form database state,

Revision History:


--*/

{
    WCHAR       wName[CCHFORMNAME + 2];
    BOOL        bRet;
    LONG        i;
    DWORD       Type;


    Type = REG_SZ;

    if ((GetPrinterData(pPI->hPrinter,
                        wszModel,
                        &Type,
                        (LPBYTE)wName,
                        sizeof(wName),
                        &i) == ERROR_SUCCESS) &&
        (wcscmp(pPI->PlotDM.dm.dmDeviceName, wName))) {

        PLOTDBG(DBG_FORMS, ("Already added forms to the data base for %s",
                                                pPI->PlotDM.dm.dmDeviceName));
        return(TRUE);
    }

    //
    // Find out if we have permission to do this
    //

    if (SetPrinterData(pPI->hPrinter,
                       wszModel,
                       REG_SZ,
                       (LPBYTE)pPI->PlotDM.dm.dmDeviceName,
                       (wcslen(pPI->PlotDM.dm.dmDeviceName) + 1) *
                                            sizeof(WCHAR)) == ERROR_SUCCESS) {

        PFORMSRC    pFS;
        FORM_INFO_1 FI1;

        //
        // We have permission to update the registry so do it now
        //

        pPI->Flags |= PIF_UPDATE_PERMISSION;

        PLOTDBG(DBG_PERMISSION,
                ("!!! MODEL NAME: '%s' not Match, Re-installed Form Database",
                                            pPI->PlotDM.dm.dmDeviceName));

        //
        // Add the driver supportes forms to the system spooler data base if
        // not yet done so
        //

        FI1.pName = wName;

        for (i = 0, pFS = (PFORMSRC)pPI->pPlotGPC->Forms.pData;
             i < (LONG)pPI->pPlotGPC->Forms.Count;
             i++, pFS++) {

            //
            // We will only add the non-roll paper forms
            //

            if (pFS->Size.cy) {

                str2Wstr(wName, CCHOF(wName), pFS->Name);

                //
                // Firstable we will delete the same name form in the data
                // base first, this will ensure we have our curent user defined
                // form can be installed
                //

                if (DeleteFirst) {

                    DeleteForm(pPI->hPrinter, wName);
                }

                FI1.Size                 = pFS->Size;
                FI1.ImageableArea.left   = pFS->Margin.left;
                FI1.ImageableArea.top    = pFS->Margin.top;
                FI1.ImageableArea.right  = FI1.Size.cx - pFS->Margin.right;
                FI1.ImageableArea.bottom = FI1.Size.cy - pFS->Margin.bottom;

                PLOTDBG(DBG_FORMS, (
                        "AddForm: %s-[%ld x %ld] (%ld, %ld)-(%ld, %ld)",
                        FI1.pName, FI1.Size.cx, FI1.Size.cy,
                        FI1.ImageableArea.left, FI1.ImageableArea.top,
                        FI1.ImageableArea.right,FI1.ImageableArea.bottom));

                FI1.Flags = FORM_PRINTER;

                if ((!AddForm(pPI->hPrinter, 1, (LPBYTE)&FI1))  &&
                    (GetLastError() != ERROR_FILE_EXISTS)       &&
                    (GetLastError() != ERROR_ALREADY_EXISTS)) {

                    bRet = FALSE;
                    PLOTERR(("AddFormsToDataBase: AddForm(%s) failed, [%ld]",
                                        wName, GetLastError()));
                }
            }
        }

        return(TRUE);

    } else {

        pPI->Flags &= ~PIF_UPDATE_PERMISSION;

        PLOTDBG(DBG_PERMISSION, ("AddFormsToDataBase(): NO UPDATE PERMISSION"));

        return(FALSE);
    }
}
예제 #3
0
파일: upgrade.c 프로젝트: Gaikokujin/WinNT4
BOOL
AddDriverForms(
    HANDLE  hPrinter,
    PMPD    pmpd
    )

/*++

Routine Description:

    Add printer-specific forms to the global forms database

Arguments:

    hPrinter - Identifies the printer being upgraded
    pmpd - Points to printer description data

Return Value:

    TRUE if successful, FALSE if there is an error

--*/

{
    PFEATURE    pFeature;
    PPAPERSIZE  pPaperSize;
    WORD        index;
    DWORD       type, value, cbNeeded;
    FORM_INFO_1 formInfo;

    //
    // Check if we've added printer-specific forms already
    //

    if (GetPrinterData(hPrinter,
                       REGSTR_FORMSADDED,
                       &type,
                       (PBYTE) &value,
                       sizeof(value),
                       &cbNeeded) == ERROR_SUCCESS)
    {
        return TRUE;
    }

    Verbose(("Adding printer-specific forms\n"));

    //
    // Call AddForm for every printer specific form
    //

    formInfo.Flags = 0;
    pFeature = MpdPaperSizes(pmpd);
    
    for (index=0; index < pFeature->count; index++) {

        pPaperSize = FindIndexedSelection(pFeature, index);

        //
        // Form name, size, and imageable area
        //

        formInfo.pName = GetXlatedName(pPaperSize);
        formInfo.Size = pPaperSize->size;

        formInfo.ImageableArea.left = formInfo.ImageableArea.top = 0;
        formInfo.ImageableArea.right = formInfo.Size.cx;
        formInfo.ImageableArea.bottom = formInfo.Size.cy;

        AddForm(hPrinter, 1, (PBYTE) &formInfo);
    }

    //
    // Indicate we have successfully added printer specific forms
    //

    value = 1;
    SetPrinterData(hPrinter, REGSTR_FORMSADDED, REG_DWORD, (PBYTE) &value, sizeof(value));
    
    return TRUE;
}
예제 #4
0
파일: oemui.cpp 프로젝트: Realhram/wdk81
////////////////////////////////////////////////////////////////////////////////
//
// Initializes OptItems to display OEM printer property UI.
//
static HRESULT hrPrinterPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
{
    UNREFERENCED_PARAMETER(dwMode);

    if(NULL == pOEMUIParam->pOEMOptItems)
    {
        // Fill in the number of OptItems to create for OEM printer property UI.
        pOEMUIParam->cOEMOptItems = 1;
    }
    else
    {
        //
        //This is the second time we are called Now setup the optional items.
        //
        DWORD   dwError;
        DWORD   dwDeviceValue;
        DWORD   dwType;
        DWORD   dwNeeded;

        // Get device settings value from printer.
        dwError = GetPrinterData(pOEMUIParam->hPrinter, OEMUI_VALUE, &dwType, (PBYTE) &dwDeviceValue,
                                   sizeof(dwDeviceValue), &dwNeeded);
        if( (ERROR_SUCCESS != dwError)
            ||
            (dwDeviceValue > 100)
          )
        {
            // Failed to get the device value or value is invalid, just use the default.
            dwDeviceValue = 0;
        }

        // Init UI Callback reference.
        pOEMUIParam->OEMCUIPCallback = OEMPrinterUICallBack;

        // Init OEMOptItmes.
        InitOptItems(pOEMUIParam->pOEMOptItems, pOEMUIParam->cOEMOptItems);

        // Fill out tree view items.

        // New section.
        pOEMUIParam->pOEMOptItems[0].Level = 1;
        pOEMUIParam->pOEMOptItems[0].Flags = OPTIF_COLLAPSE;
        pOEMUIParam->pOEMOptItems[0].pName = GetStringResource(pOEMUIParam->hOEMHeap, pOEMUIParam->hModule, IDS_DEV_SECTION);
        pOEMUIParam->pOEMOptItems[0].Sel = dwDeviceValue;

        pOEMUIParam->pOEMOptItems[0].pOptType = CreateOptType(pOEMUIParam->hOEMHeap, 2);

        //
        //Setup the Optional Item
        //
        pOEMUIParam->pOEMOptItems[0].pOptType->Type = TVOT_UDARROW;
        pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].IconID = 0;
        pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].lParam = 100;

        //
        //Allows You to apply Customised help to this Control
        //
        AddCustomUIHelp (pOEMUIParam->hPrinter,
                         pOEMUIParam->hOEMHeap,
                         pOEMUIParam->hModule,
                         &(pOEMUIParam->pOEMOptItems[0]),
                         CUSDRV_HELPTOPIC_1,
                         IDS_HELPFILE);
    }
    return S_OK;
}
예제 #5
0
파일: text.cpp 프로젝트: kcrazy/winekit
/*++
*******************************************************************
    P r i n t T e x t J o b

    Routine Description:
        Prints a text data job.

    Arguments:
        pData           => Data structure for this job
        pDocumentName   => Name of this document

    Return Value:
        TRUE  if successful
        FALSE if failed - GetLastError() will return reason.
*******************************************************************
--*/
BOOL
PrintTextJob(
         IN PPRINTPROCESSORDATA pData,
    __in IN LPWSTR pDocumentName)
{
    DOCINFO     DocInfo;
    LOGFONT     LogFont;
    CHARSETINFO CharSetInfo;
    HFONT       hOldFont, hFont = NULL;
    DWORD       Copies;
    BOOL        rc;
    DWORD       NoRead;
    DWORD       CurrentLine;
    DWORD       CurrentCol;
    HANDLE      hPrinter = NULL;
    BYTE        *ReadBufferStart = NULL;
    PBYTE       pLineBuffer = NULL;
    PBYTE       pReadBuffer = NULL;
    PBYTE       pReadBufferEnd = NULL;
    ULONG       CharHeight, CharWidth, CharsPerLine, LinesPerPage;
    ULONG       PageWidth, PageHeight;
    ULONG       Length, TabBase;
    BOOL        ReadAll;
    TEXTMETRIC  tm;
    DWORD       fdwFlags;
    DWORD       Encoding;
    DWORD       SplitSize;
    BOOL        ReturnValue = FALSE;
    BOOL        bAbortDoc   = FALSE;

    DWORD       dwNeeded;
    DWORD       dwNoTranslate = 0;
    DWORD       dwNoTranslateCR = 0;
    DWORD       dwTransparent = 0;
    INT         iBkMode = OPAQUE;

    DocInfo.lpszDocName = pData->pDocument;  /* Document name */
    DocInfo.lpszOutput  = NULL;              /* Output file */
    DocInfo.lpszDatatype = NULL;             /* Datatype */
    DocInfo.cbSize = sizeof(DOCINFO);        /* Size of the structure */



    //
    // Go figure out the size of the form on the printer.  We do this
    // by calling GetTextMetrics, which gives us the font size of the
    // printer font, then getting the form size and calculating the
    // number of characters that will fit. In other cases we treat it as ANSI text.
    // Currently the codepage context is fixed to the system default codepage.
    //

    Encoding = GetACP();

    //
    // Create FIXED PITCH font and select
    //

    hOldFont = 0;
    ZeroMemory(&CharSetInfo, sizeof(CHARSETINFO));
    if (TranslateCharsetInfo((PDWORD)UIntToPtr(Encoding), &CharSetInfo, TCI_SRCCODEPAGE))
    {
        ZeroMemory(&LogFont, sizeof(LOGFONT));

        LogFont.lfWeight = 400;
        LogFont.lfCharSet = (BYTE)CharSetInfo.ciCharset;
        LogFont.lfPitchAndFamily = FIXED_PITCH;

        hFont = CreateFontIndirect(&LogFont);
        hOldFont = (HFONT) SelectObject(pData->hDC, hFont);
    }

    if (!GetTextMetrics(pData->hDC, &tm)) {
        // Essential text processing computation failed
        goto Done;
    }

    CharHeight = tm.tmHeight + tm.tmExternalLeading;
    CharWidth  = tm.tmAveCharWidth;

    if (!CharWidth || !CharHeight) {
        // Essential text processing computation failed
        goto Done;
    }

    //
    // Calculate most fittable characters' number to one line.
    //

    PageWidth = GetDeviceCaps(pData->hDC, DESKTOPHORZRES);
    PageHeight = GetDeviceCaps(pData->hDC, DESKTOPVERTRES);

    CharsPerLine = PageWidth / CharWidth;
    LinesPerPage = PageHeight / CharHeight;

    if (!CharsPerLine || !LinesPerPage) {
        // Essential text processing computation failed
        goto Done;
    }

    /** Allocate a buffer for one line of text **/

    pLineBuffer = (PBYTE)AllocSplMem(CharsPerLine + 5);

    if (!pLineBuffer) {
        goto Done;
    }

    /** Let the printer know we are starting a new document **/

    if (!StartDoc(pData->hDC, (LPDOCINFO)&DocInfo)) {

        goto Done;
    }

    ReadBufferStart = (BYTE *)AllocSplMem(READ_BUFFER_SIZE);

    if (!ReadBufferStart) {

        goto Done;
    }

    /** Print the data pData->Copies times **/

    Copies = pData->Copies;

    while (Copies--) {

        /**
            Loop, getting data and sending it to the printer.  This also
            takes care of pausing and cancelling print jobs by checking
            the processor's status flags while printing.  The way we do
            this is to read in some data from the printer.  We will then
            pull data, one tabbed line at a time from there and print
            it.  If the last bit of data in the buffer does not make up
            a whole line, we call GetTabbedLineFromBuffer() with a non-
            zero Length, which indicates that there are chars left
            from the previous read.
        **/

        TabBase = 0;
        Length = 0;
        fdwFlags = FLAG_TRANSLATE_CR | FLAG_TRANSLATE_LF;

        CurrentLine = 0;
        CurrentCol = 0;

        /**
            Open the printer.  If it fails, return.  This also sets up the
            pointer for the ReadPrinter calls.
        **/

        if (!OpenPrinter(pDocumentName, &hPrinter, NULL)) {

            hPrinter = NULL;
            bAbortDoc = TRUE;
            goto Done;
        }

        //
        // Call GetPrinterData to see if the queue wants no LF/CR processing.
        //
        if( GetPrinterData( hPrinter,
                            (LPWSTR)gszNoTranslateCRLF,
                            NULL,
                            (PBYTE)&dwNoTranslate,
                            sizeof( dwNoTranslate ),
                            &dwNeeded ) == ERROR_SUCCESS ){

            if( dwNoTranslate ){
                fdwFlags &= ~( FLAG_TRANSLATE_CR | FLAG_TRANSLATE_LF );
            }
        }

        //
        // Call GetPrinterData to see if the queue wants no CR processing.
        //
        if( GetPrinterData( hPrinter,
                            (LPWSTR)gszNoTranslateCR,
                            NULL,
                            (PBYTE)&dwNoTranslateCR,
                            sizeof( dwNoTranslateCR ),
                            &dwNeeded ) == ERROR_SUCCESS ){

            if( dwNoTranslateCR ){

                fdwFlags &= ~FLAG_TRANSLATE_CR;

                if( GetPrinterData( hPrinter,
                                (LPWSTR)gszTransparency,
                                NULL,
                                (PBYTE)&dwTransparent,
                                sizeof( dwTransparent ),
                                &dwNeeded ) == ERROR_SUCCESS ){

                    if( dwTransparent ){
                        iBkMode = SetBkMode( pData->hDC, TRANSPARENT );
                    }
                }
            }
        }

        if (StartPage(pData->hDC) == SP_ERROR) {

            bAbortDoc = TRUE;
            goto Done;
        }

        /** ReadAll indicates if we are on the last line of the file **/

        ReadAll = FALSE;

        /**
            This next do loop continues until we have read all of the
            data for the print job.
        **/

        do {

            if (fdwFlags & FLAG_DBCS_SPLIT) {
                SplitSize = (DWORD)(pReadBufferEnd - pReadBuffer);
                memcpy(ReadBufferStart, pReadBuffer, SplitSize);
                fdwFlags &= ~FLAG_DBCS_SPLIT;
            }
            else {
                SplitSize = 0;
            }

            rc = ReadPrinter(hPrinter,
                             (ReadBufferStart + SplitSize),
                             (READ_BUFFER_SIZE - SplitSize),
                             &NoRead);

            if (!rc || !NoRead) {

                ReadAll = TRUE;

            } else {

                /** Pick up a pointer to the end of the data **/

                pReadBuffer    = ReadBufferStart;
                pReadBufferEnd = ReadBufferStart + SplitSize + NoRead;
            }

            /**
                This loop will process all the data that we have
                just read from the printer.
            **/

            do {

                if (!ReadAll) {

                    /**
                        Length on entry holds the length of any
                        residual chars from the last line that we couldn't
                        print out because we ran out of characters on
                        the ReadPrinter buffer.
                    **/

                    pReadBuffer = GetTabbedLineFromBuffer(
                                      pReadBuffer,
                                      pReadBufferEnd,
                                      pLineBuffer,
                                      CharsPerLine - CurrentCol,
                                      pData->TabSize,
                                      Encoding,
                                      &Length,
                                      &TabBase,
                                      &fdwFlags );

                    /**

                        If pReadBuffer == NULL, then we have
                        exhausted the read buffer and we need to ReadPrinter
                        again and save the last line chars.  Length holds
                        the number of characters on this partial line,
                        so the next time we call ReadPrinter we will
                        pickup where we left off.

                        The only time we'll get residual chars is if:

                        1. The last line ends w/o ff/lf/cr ("Hello\EOF")
                           In this case we should TextOutA the last line
                           and then quit.

                           (In this case, don't break here; go ahead and
                           print, then we'll break out below in the do..while.)


                        2. The ReadPrinter last byte is in the middle of a line.
                           Here we should read the next chunk and add the
                           new characters at the end of the chars we just read.

                           (In this case, we should break and leave Length
                           as it is so we will read again and append to the
                           buffer, beginning at Length.)
                    **/

                    if (!pReadBuffer || (fdwFlags & FLAG_DBCS_SPLIT))
                        break;
                }


                /** If the print processor is paused, wait for it to be resumed **/

                if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
                    WaitForSingleObject(pData->semPaused, INFINITE);
                }

                /** If the job has been aborted, clean up and leave **/

                if (pData->fsStatus & PRINTPROCESSOR_ABORTED) {

                    ReturnValue = TRUE;

                    bAbortDoc = TRUE;
                    goto Done;
                }

                /** Write the data to the printer **/

                /** Make sure Length is not zero  **/
                /** TextOut will fail if Length == 0 **/

                if (Length) {

                    /**
                        We may have a number of newlines pending, that
                        may push us to the next page (or even next-next
                        page).
                    **/

                    while (CurrentLine >= LinesPerPage) {

                        /**
                            We need a new page; always defer this to the
                            last second to prevent extra pages from coming out.
                        **/

                        if (EndPage(pData->hDC) == SP_ERROR ||
                            StartPage(pData->hDC) == SP_ERROR) {

                            bAbortDoc = TRUE;
                            goto Done;
                        }

                        CurrentLine -= LinesPerPage;
                    }

#pragma prefast(suppress:__WARNING_ANSI_APICALL, "By design. This function is inherently handling only ANSI text print jobs.")
                    if (TextOutA(pData->hDC,
                                 CurrentCol * CharWidth,
                                 CurrentLine * CharHeight,
                                 (LPCSTR)pLineBuffer,
                                 Length) == FALSE) {

                        ODS(("TextOut() failed\n"));

                        bAbortDoc = TRUE;
                        goto Done;
                    }

                    CurrentCol += Length;
                }

                /**
                    Even if the length is zero, increment the line.
                    Should happen when the character is only 0x0D or 0x0A.
                **/

                if (fdwFlags & FLAG_CR) {
                    CurrentCol=0;
                    fdwFlags &= ~FLAG_CR;
                }

                if (fdwFlags & FLAG_LF) {
                    CurrentLine++;
                    fdwFlags &= ~FLAG_LF;
                }

                /**
                    We need a new page.  Set the current line to the
                    end of the page.  We could do a End/StartPage
                    sequence, but this may cause a blank page to get
                    ejected.

                    Note: this code will avoid printing out pages that
                    consist of formfeeds only (if you have a page with a
                    space in it, that counts as text).
                **/

                if (fdwFlags & FLAG_FF) {

                    CurrentLine = LinesPerPage;
                    CurrentCol = 0;
                    fdwFlags &= ~FLAG_FF;
                }

                /**
                    We have done the text out, so these characters have
                    been successfully printed.  Zero out Length
                    so these characters won't be printed again
                **/

                Length = 0;

                /**
                    We only terminate this loop if we run out of chars
                    or we run out of read buffer.
                **/

            } while (pReadBuffer && pReadBuffer != pReadBufferEnd);

            /** Keep going until we get the last line **/

        } while (!ReadAll);

        if (EndPage(pData->hDC) == SP_ERROR) {

            bAbortDoc = TRUE;
            goto Done;
        }

        /**
            Close the printer - we open/close the printer for each
            copy so the data pointer will rewind.
        **/

        ClosePrinter(hPrinter);
        hPrinter = NULL;

    } /* While copies to print */

    /** Let the printer know that we are done printing **/

    EndDoc(pData->hDC);

    ReturnValue = TRUE;

Done:

    if (dwTransparent)
        SetBkMode( pData->hDC, iBkMode  );

    if (hPrinter)
        ClosePrinter(hPrinter);

    if (bAbortDoc)
        AbortDoc(pData->hDC);

    if (pLineBuffer)
        FreeSplMem(pLineBuffer);

    if (hOldFont)
    {
        SelectObject(pData->hDC, hOldFont);
        DeleteObject(hFont);
    }

    if (ReadBufferStart) 
    {
        FreeSplMem(ReadBufferStart);
    }

    return ReturnValue;
}
예제 #6
0
파일: regdata.c 프로젝트: Gaikokujin/WinNT4
BOOL
bGetRegData(
    HANDLE       hPrinter,          /* Handle for access to printer data */
    EXTDEVMODE  *pEDM,              /* EXTDEVMODE to fill in. */
    PWSTR        pwstrModel,        /* Model name, for validation */
    PRASDDUIINFO pRasdduiInfo       /* Rasddui common data */
)
{

    int     iI;                 /* Loop index */
    int     cForms;             /* Count number of forms we found */

    DWORD   dwType;             /* Registry access information */
    DWORD   cbNeeded;           /* Extra parameter to GetPrinterData */

    BOOL    bRet = TRUE;               /* Return code */

    FORM_DATA  *pForms;

    WCHAR   achBuf[ BF_NM_SZ ]; /* Read the form name from registry */


    dwType = REG_SZ;

    if( GetPrinterData( hPrinter, PP_MODELNAME, &dwType, (BYTE *)achBuf,
                                            sizeof( achBuf ), &cbNeeded ) ||
        wcscmp( achBuf, pwstrModel ) )
    {
        /*
         *   Bad news:  either there is no model name, or it is wrong!
         *  Either way,  drop this data and start from scratch.
         */

        vDXDefault( &pEDM->dx, pdh, iModelNum );

        return   FALSE;
    }


    /*
     *   Obtain the what forms are in what bin information.  The registry
     *  stores the form name of the form installed in each bin.  So read
     *  the name,  then match it to the forms data we have acquired
     *  from the spooler.  Fill in the pfdForm array with the address
     *  of the FORM_DATA array for this particular form.
     */

    // Read the old Keys only in case of Upgrade

    if (( !bNewkeys(hPrinter) ) && ( gdwPrinterUpgrade == PPUPGRADE_OLD_DRIVER ) )
    {

        cForms = 0;                             /* Count them as we go */

        for( iI = 0; iI < NumPaperBins; ++iI )
        {
            WCHAR   achName[ 32 ];


            wsprintf( achName, PP_PAP_SRC, iI );

            achBuf[ 0 ] = '\0';

            if( !GetPrinterData( hPrinter, achName, &dwType, (BYTE *)achBuf,
                                                    sizeof( achBuf ), &cbNeeded ) )
            {
                /*   Got a name,  so scan the forms data for this one. */

                if( achBuf[ 0 ] )
                {
                    /*   Something there,  so go look for it!  */
                    for( pForms = pFD; pForms->pFI; ++pForms )
                    {
                        if( wcscmp( pForms->pFI->pName, achBuf ) == 0 )
                        {
                            /*   Bingo!   Remember it & skip the rest */
                            aFMBin[ iI ].pfd = pForms;
                            ++cForms;
                            break;
                        }
                    }
                }

            }
        }

        /*   If no forms, return FALSE, as being not setup */

        bRet = cForms != 0;

        /*
         *   The bulk of the data is stored in the EXTDEVMODE data which
         * is stored in the registry.  So,  all we need to is retrieve
         * it,  and we have what we need.  Of course,  we need to verify
         * that it is still legitimate for the driver!
         */


        dwType = REG_BINARY;                /* EXTDEVMODE is binary data */

        if( GetPrinterData( hPrinter, PP_MAIN, &dwType,
                                  (BYTE *)pEDM, sizeof( EXTDEVMODE ), &cbNeeded) ||
            cbNeeded < sizeof( EXTDEVMODE ) )
        {
            /*
             *   Failed,  so generate the default values for this particular
             * printer.
             */


            vDXDefault( &pEDM->dx, pdh, iModelNum );
            bRet = FALSE;
        }
        else
        {
            /*   Verify that the data is reasonable:  set defaults if NBG */
            if( pEDM->dx.sVer != DXF_VER )
            {
                vDXDefault( &pEDM->dx, pdh, iModelNum );
                bRet = FALSE;
            }
        }

    }
    else if ( !bNewkeys(hPrinter) )   /* New Keys not present, generate default */
    {

        /*
         *   Failed,  so generate the default values for this particular
         * printer.
         */


        vDXDefault( &pEDM->dx, pdh, iModelNum );
        bRet = FALSE;
    }
    else  /* New Keys Present */
    {
                /* Read Memory, Rasdd Flags and  Font Carts */
        if ( (bRet = ( bRegReadTrayFormTable (hPrinter, pRasdduiInfo) &&
                       bRegReadMemory (hPrinter, pEDM, pdh,pModel ) &&
                       bRegReadRasddFlags (hPrinter, pEDM) &&
                       bRegReadFontCarts (hPrinter, pEDM, UIHEAP(pRasdduiInfo), NumAllCartridges,
                                          pFontCartMap) ) ) )
            ;


        /* If any of the above calls return false setdefaults and return false */
        if (!bRet)
        {
            vDXDefault( &pEDM->dx, pdh, iModelNum );
        }

    }

    return  bRet;

}