Annotation of ntddk/src/print/lib/fontread.c, revision 1.1.1.1

1.1       root        1: /******************************* MODULE HEADER *******************************
                      2:  * fontread.c
                      3:  *      Functions to assist processing of the data in a common font
                      4:  *      installer file format.
                      5:  *
                      6:  * Copyright (C) 1992 - 1993   Microsoft Corporation.
                      7:  *
                      8:  *****************************************************************************/
                      9: 
                     10: #include        <stddef.h>
                     11: #include        <windows.h>
                     12: 
                     13: #include        "fontread.h"
                     14: #include        "libproto.h"            /* bWrite() proto */
                     15: 
                     16: #include        "fontfile.h"            /* File layout details */
                     17: 
                     18: 
                     19: 
                     20: /******************************** Function Header ****************************
                     21:  * iFIOpenRead
                     22:  *      Makes the font installer file accessible & memory mapped.  Called
                     23:  *      by a driver to gain access to the fonts in the font installer's
                     24:  *      output file.
                     25:  *
                     26:  * RETURNS:
                     27:  *      Number of records in the file;  0 for an empty/non-existant file.
                     28:  *
                     29:  * HISTORY:
                     30:  *  13:37 on Sat 12 Jun 1993    -by-    Lindsay Harris   [lindsayh]
                     31:  *      Stop using memory mapping as it is unsafe across the net.
                     32:  *
                     33:  *  13:45 on Thu 27 Feb 1992    -by-    Lindsay Harris   [lindsayh]
                     34:  *      First incarnation.
                     35:  *
                     36:  *****************************************************************************/
                     37: 
                     38: int
                     39: iFIOpenRead( pFIMem, hHeap, pwstrName )
                     40: FI_MEM  *pFIMem;                /* Output goes here */
                     41: HANDLE   hHeap;                 /* Need some storage for a short time */
                     42: PWSTR    pwstrName;             /* Name of printer data file */
                     43: {
                     44: 
                     45:     DWORD   dwSize;             /* Size of buffer needed for file name */
                     46:     PWSTR   pwstrLocal;
                     47: 
                     48: 
                     49: 
                     50:     pFIMem->hFont = INVALID_HANDLE_VALUE;      /* No data until we have it */
                     51:     pFIMem->pbBase = NULL;
                     52: 
                     53:     /*
                     54:      *   First map the file to memory.  However,  we do need firstly to
                     55:      * generate the file name of interest.  This is based on the data
                     56:      * file name for this type of printer.
                     57:      *   Allocate more storage than is indicated:  we MAY want to add
                     58:      * a prefix to the file name rather than replace the existing one.
                     59:      */
                     60: 
                     61: 
                     62:     dwSize = sizeof( WCHAR ) * (wcslen( pwstrName ) + 1 + 4);
                     63: 
                     64:     if( pwstrLocal = (PWSTR)HeapAlloc( hHeap, 0, dwSize ) )
                     65:     {
                     66:         /*  Got the memory,  so fiddle the file name to our standard */
                     67: 
                     68:         int    iPtOff;             /* Location of '.' */
                     69: 
                     70: 
                     71:         FF_HEADER  ffh;          /* Read in to determine memory size needed */
                     72: 
                     73: 
                     74: 
                     75:         wcscpy( pwstrLocal, pwstrName );
                     76: 
                     77:         /*
                     78:          *   Go looking for a '.' - if not found,  append to string.
                     79:          */
                     80: 
                     81:         iPtOff = wcslen( pwstrLocal );
                     82: 
                     83:         while( --iPtOff > 0 )
                     84:         {
                     85:             if( *(pwstrLocal + iPtOff) == (WCHAR)'.' )
                     86:                 break;
                     87:         }
                     88: 
                     89:         if( iPtOff <= 0 )
                     90:         {
                     91:             iPtOff = wcslen( pwstrLocal );              /* Presume none! */
                     92:             *(pwstrLocal + iPtOff) = L'.';
                     93:         }
                     94:         ++iPtOff;               /* Skip the period */
                     95: 
                     96: 
                     97:     
                     98:         /*  Generate the name and map the file */
                     99:         wcscpy( pwstrLocal + iPtOff, FILE_FONTS );
                    100: 
                    101: 
                    102:   
                    103:         pFIMem->hFont = CreateFileW( pwstrLocal, GENERIC_READ, FILE_SHARE_READ,
                    104:                                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                    105:                                                                    NULL );
                    106:   
                    107:         HeapFree( hHeap, 0, (LPSTR)pwstrLocal );        /* No longer needed */
                    108: 
                    109:         /*
                    110:          *   Now for the fun part.   The file header contains the size
                    111:          *  of the fixed part of the file.  This is the part containing
                    112:          *  the IFIMETRICS etc.  This is the part of the file that causes
                    113:          *  great distress to GDI if the network fails when we are mapping
                    114:          *  to a remote system.  SO,  we allocate storage for this data
                    115:          *  now,  and read the data in.  Then it is safe for ever after.
                    116:          */
                    117: 
                    118:         if( pFIMem->hFont == INVALID_HANDLE_VALUE )
                    119:             return  0;           /*  Probably no file there at all */
                    120: 
                    121:         if( !ReadFile( pFIMem->hFont, &ffh, sizeof( ffh ), &dwSize, NULL ) ||
                    122:             dwSize != sizeof( ffh ) )
                    123:         {
                    124:             /*
                    125:              *   Bad news on the read,  so fail the call now.
                    126:              */
                    127: 
                    128:             CloseHandle( pFIMem->hFont );
                    129:             pFIMem->hFont = INVALID_HANDLE_VALUE;
                    130: 
                    131:             return  0;
                    132:         }
                    133:         
                    134:         dwSize = ffh.ulFixSize + sizeof( ffh );
                    135: 
                    136:         pFIMem->pbBase = (BYTE *)GlobalAlloc( GMEM_FIXED, dwSize );
                    137: 
                    138: 
                    139:         if( pFIMem->pbBase == NULL )
                    140:         {
                    141:             /*  Could not get the memory,  so give up now */
                    142:             CloseHandle( pFIMem->hFont );
                    143:             pFIMem->hFont = INVALID_HANDLE_VALUE;
                    144: 
                    145:             return  0;
                    146:         }
                    147: 
                    148:         /*
                    149:          *   We want to read the file header again,  so rewind the file.
                    150:          */
                    151: 
                    152:         SetFilePointer( pFIMem->hFont,  0, NULL, FILE_BEGIN );
                    153: 
                    154:         if( !ReadFile( pFIMem->hFont, pFIMem->pbBase, dwSize, &dwSize, NULL ) ||
                    155:             dwSize != dwSize )
                    156:         {
                    157: 
                    158:             /*   Not good either - cannot read the file again.  */
                    159: 
                    160:             GlobalFree( pFIMem->pbBase );
                    161:             pFIMem->pbBase = NULL;
                    162: 
                    163:             CloseHandle( pFIMem->hFont );
                    164:             pFIMem->hFont = INVALID_HANDLE_VALUE;
                    165: 
                    166:             return  0;
                    167:         }
                    168: 
                    169: 
                    170:         return  iFIRewind( pFIMem );    
                    171:     }
                    172:     else
                    173:         return  0;              /* Too bad: oh well, no extra fonts */
                    174: }
                    175: 
                    176: /******************************** Function Header ****************************
                    177:  * bFINextRead()
                    178:  *      Updates pFIMem to the next entry in the font installer file.
                    179:  *      Returns TRUE if OK, and updates the pointers in pFIMem.
                    180:  *
                    181:  * RETURNS:
                    182:  *      TRUE/FALSE.   FALSE for EOF,  otherwise pFIMem updated.
                    183:  *
                    184:  * HISTORY:
                    185:  *  13:50 on Thu 27 Feb 1992    -by-    Lindsay Harris   [lindsayh]
                    186:  *      Numero Uno.
                    187:  *
                    188:  *****************************************************************************/
                    189: 
                    190: BOOL
                    191: bFINextRead( pFIMem )
                    192: FI_MEM   *pFIMem;
                    193: {
                    194:     FF_HEADER      *pFFH;               /* Overall file header */
                    195:     FF_REC_HEADER  *pFFRH;              /* Per record header */
                    196: 
                    197:     /*
                    198:      *  Validate that we have valid data.
                    199:      */
                    200: 
                    201: 
                    202:     if( pFIMem == 0 || pFIMem->hFont == INVALID_HANDLE_VALUE )
                    203:         return  FALSE;                          /* Empty file */
                    204: 
                    205:     pFFH = (FF_HEADER *)pFIMem->pbBase;
                    206: 
                    207:     if( pFFH->ulID != FF_ID )
                    208:     {
                    209:         DbgPrint( "Print!bFINextRead: FF_HEADER has invalid ID\n" );
                    210: 
                    211:         return  FALSE;
                    212:     }
                    213:     
                    214:     /*
                    215:      *   If pFIMem->pvFix == 0, we should return the data from the
                    216:      * first record.  Otherwise,  return the next record in the chain.
                    217:      * This is done to avoid the need to have a ReadFirst()/ReadNext()
                    218:      * pair of functions.
                    219:      */
                    220: 
                    221:     if( pFIMem->pvFix )
                    222:     {
                    223:         /*
                    224:          *   The header is located immediately before the data we last
                    225:          * returned for the fixed portion of the record.  SO,  we back
                    226:          * over it to get the header which then gives us the address
                    227:          * of the next header.
                    228:          */
                    229: 
                    230:         pFFRH = (FF_REC_HEADER *)((BYTE *)pFIMem->pvFix -
                    231:                                                  sizeof( FF_REC_HEADER ));
                    232: 
                    233:         if( pFFRH->ulRID != FR_ID )
                    234:         {
                    235:             DbgPrint( "Print!bFINextRead: Invalid FF_REC_HEADER ID\n" );
                    236: 
                    237:             return  FALSE;
                    238:         }
                    239: 
                    240:         /*
                    241:          *   We could check here for EOF on the existing structure, but this
                    242:          * is not required BECAUSE THE ulNextOff field will be 0, so when
                    243:          * it is added to our current address,  we don't move.  Hence, the
                    244:          * check for the NEW address is OK to detect EOF.
                    245:          */
                    246: 
                    247:         (BYTE *)pFFRH += pFFRH->ulNextOff;              /* Next entry */
                    248: 
                    249:     }
                    250:     else
                    251:     {
                    252:         /*   Point to the first record.  */
                    253:         pFFRH = (FF_REC_HEADER *)(pFIMem->pbBase + pFFH->ulFixData);
                    254:     }
                    255: 
                    256:     if( pFFRH->ulNextOff == 0 )
                    257:         return  FALSE;
                    258: 
                    259:     pFIMem->pvFix = (BYTE *)pFFRH + sizeof( FF_REC_HEADER );
                    260:     pFIMem->ulFixSize = pFFRH->ulSize;
                    261: 
                    262:     if( pFIMem->ulVarSize = pFFRH->ulVarSize )
                    263:         pFIMem->ulVarOff = pFFRH->ulVarOff + pFFH->ulVarData;
                    264:     else
                    265:         pFIMem->ulVarOff = 0;              /* None here */
                    266: 
                    267: 
                    268:     return  TRUE;
                    269: }
                    270: 
                    271: /******************************** Function Header ***************************
                    272:  * bFIRewind
                    273:  *      Reset pFIMem to the first font in the file.
                    274:  *
                    275:  * RETURNS:
                    276:  *      Number of entries in the file.
                    277:  *
                    278:  * HISTORY:
                    279:  *  13:54 on Thu 27 Feb 1992    -by-    Lindsay Harris   [lindsayh]
                    280:  *      Start.
                    281:  *
                    282:  *****************************************************************************/
                    283: 
                    284: int
                    285: iFIRewind( pFIMem )
                    286: FI_MEM   *pFIMem;               /* File of importance */
                    287: {
                    288:     /*
                    289:      *  Not hard!  The pFIMem contains the base address of the file, so we
                    290:      * use this to find the address of the first record,  and any variable
                    291:      * data that corresponds with it.
                    292:      */
                    293: 
                    294:     FF_HEADER      *pFFH;
                    295:     FF_REC_HEADER  *pFFRH;
                    296: 
                    297:     if( pFIMem == 0 || pFIMem->hFont == INVALID_HANDLE_VALUE )
                    298:         return  0;                              /* None! */
                    299: 
                    300: 
                    301:     /*
                    302:      *   The location of the first record is specified in the header.
                    303:      */
                    304: 
                    305:     pFFH = (FF_HEADER *)pFIMem->pbBase;
                    306:     if( pFFH->ulID != FF_ID )
                    307:     {
                    308:         DbgPrint( "Print!iFIRewind: FF_HEADER has invalid ID\n" );
                    309: 
                    310:         return  0;
                    311:     }
                    312: 
                    313:     pFFRH = (FF_REC_HEADER *)(pFIMem->pbBase + pFFH->ulFixData);
                    314: 
                    315:     if( pFFRH->ulRID != FR_ID )
                    316:     {
                    317:         DbgPrint( "Print!iFIRewind: Invalid FF_REC_HEADER ID\n" );
                    318: 
                    319:         return  0;
                    320:     }
                    321: 
                    322:     /*
                    323:      *   Set the pvFix field in the header to 0.  This is used in bFINextRead
                    324:      * to mean that the data for the first record should be supplied.
                    325:      */
                    326:     pFIMem->pvFix = 0;          /* MEANS USE FIRST NEXT READ */
                    327:     pFIMem->ulFixSize = 0;
                    328:     pFIMem->ulVarOff = 0;       /* None here */
                    329: 
                    330:     return  pFFH->ulRecCount;
                    331: }
                    332: 
                    333: 
                    334: /******************************* Function Header ***************************
                    335:  * bFICloseRead
                    336:  *      Called when finished with this font file.
                    337:  *
                    338:  * RETURNS:
                    339:  *      Nothing
                    340:  *
                    341:  * HISTORY:
                    342:  *  15:07 on Sat 12 Jun 1993    -by-    Lindsay Harris   [lindsayh]
                    343:  *      Can no longer use MapFile,  so free memory and close handles as needed.
                    344:  *
                    345:  *  13:56 on Thu 27 Feb 1992    -by-    Lindsay Harris   [lindsayh]
                    346:  *      Time t = 0
                    347:  *
                    348:  ***************************************************************************/
                    349: 
                    350: BOOL
                    351: bFICloseRead( pFIMem )
                    352: FI_MEM  *pFIMem;                /* File/memory we are finished with */
                    353: {
                    354:     /*
                    355:      *   Easy!  All we need do is unmap the file.  We have the address too!
                    356:      */
                    357: 
                    358:     BOOL   bRet;                /* Return code */
                    359: 
                    360: 
                    361:     if( pFIMem == 0 || pFIMem->hFont == INVALID_HANDLE_VALUE )
                    362:         return  TRUE;                   /* Nothing there! */
                    363:     
                    364:     bRet = CloseHandle( pFIMem->hFont );
                    365: 
                    366: 
                    367:     /*   Also free our chunk of memory  */
                    368: 
                    369:     if( pFIMem->pbBase )
                    370:     {
                    371:         /*   Address is valid,  so free it now  */
                    372: 
                    373:         GlobalFree( pFIMem->pbBase );
                    374:         
                    375:         pFIMem->pbBase = NULL;
                    376:     }
                    377: 
                    378: 
                    379:     if( bRet )
                    380:         pFIMem->hFont = INVALID_HANDLE_VALUE; /* Stops freeing more than once */
                    381: 
                    382: 
                    383:     return  bRet;
                    384: }

unix.superglobalmegacorp.com

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