Annotation of mstools/samples/sdktools/dlgedit/rwres.c, revision 1.1.1.1

1.1       root        1: 
                      2: /******************************************************************************\
                      3: *       This is a part of the Microsoft Source Code Samples. 
                      4: *       Copyright (C) 1993 Microsoft Corporation.
                      5: *       All rights reserved. 
                      6: *       This source code is only intended as a supplement to 
                      7: *       Microsoft Development Tools and/or WinHelp documentation.
                      8: *       See these sources for detailed information regarding the 
                      9: *       Microsoft samples programs.
                     10: \******************************************************************************/
                     11: 
                     12: /****************************** Module Header *******************************
                     13: * Module Name: rwres.c
                     14: *
                     15: * Does all the reading and writing of the .RES (resource) file.
                     16: *
                     17: * Functions:
                     18: *
                     19: *    OpenResFile()
                     20: *    WriteRes()
                     21: *    LoadResFile()
                     22: *    IsValidResFile()
                     23: *    SafeParseResHeader()
                     24: *    SafeNameOrdLen()
                     25: *    SafeDWordAlign()
                     26: *    WriteDlgIncludeRes()
                     27: *
                     28: * Comments:
                     29: *
                     30: ****************************************************************************/
                     31: 
                     32: #include "dlgedit.h"
                     33: #include "dlgfuncs.h"
                     34: #include "dlgextrn.h"
                     35: 
                     36: 
                     37: /*
                     38:  * The bytes in the special RT_RESOURCE32 type resource that is the
                     39:  * first resource in every Win32 format res file.  The first 8 bytes
                     40:  * in this resource's header were specially designed to be invalid
                     41:  * for a 16 bit format resource file, so that tools can determine
                     42:  * immediately if they are reading a 16 bit or a Win32 format res
                     43:  * file.
                     44:  */
                     45: static BYTE abResource32[] = {
                     46:     0x00, 0x00, 0x00, 0x00,                 // DataSize (0 bytes).
                     47:     0x20, 0x00, 0x00, 0x00,                 // HeaderSize (32 bytes).
                     48:     0xff, 0xff, 0x00, 0x00,                 // Type (RT_RESOURCE32).
                     49:     0xff, 0xff, 0x00, 0x00,                 // Name (ordinal 0).
                     50:     0x00, 0x00, 0x00, 0x00,                 // DataVersion
                     51:     0x00, 0x00,                             // MemoryFlags
                     52:     0x00, 0x00,                             // LanguageId
                     53:     0x00, 0x00, 0x00, 0x00,                 // Version
                     54:     0x00, 0x00, 0x00, 0x00                  // Characteristics
                     55: };
                     56: 
                     57: 
                     58: STATICFN BOOL LoadResFile(HANDLE hfRes, LPTSTR pszFullResFile,
                     59:     LPTSTR pszIncludeBuf);
                     60: STATICFN BOOL IsValidResFile(PRES pRes, INT cbFileSize);
                     61: STATICFN PRES SafeParseResHeader(PRES pRes, INT cbMaxSize);
                     62: STATICFN INT SafeNameOrdLen(LPTSTR psz, INT cbMaxLen);
                     63: STATICFN VOID SafeDWordAlign(PBYTE *ppb, PINT pcbMax);
                     64: STATICFN BOOL WriteDlgIncludeRes(HANDLE hfWrite, LPTSTR pszFullResFile);
                     65: 
                     66: 
                     67: 
                     68: /************************************************************************
                     69: * OpenResFile
                     70: *
                     71: * High level function to load the data in a resource file.  The
                     72: * function LoadResFile is called to do the actual work, after
                     73: * this code does some housekeeping.
                     74: *
                     75: * Arguments:
                     76: *     LPTSTR pszFullPath - The full path to the resource file.
                     77: *
                     78: * Returns:
                     79: *     TRUE if resource file was opened; otherwise, FALSE.
                     80: *
                     81: ************************************************************************/
                     82: 
                     83: BOOL OpenResFile(
                     84:     LPTSTR pszFullPath)
                     85: {
                     86:     HCURSOR hcurSave;
                     87:     PRESLINK prl;
                     88:     PRESLINK prlSave;
                     89:     BOOL fSuccess = FALSE;
                     90:     INT cDlg;
                     91:     HANDLE hfRes;
                     92:     TCHAR szInclude[CCHMAXPATH];
                     93:     TCHAR szFullInclude[CCHMAXPATH];
                     94:     BOOL fIncOpened = FALSE;
                     95: 
                     96:     hcurSave = SetCursor(hcurWait);
                     97: 
                     98:     /*
                     99:      * Close any existing resource and include file and free memory.
                    100:      * It is assumed that if either had been changed, the user was asked
                    101:      * if they wanted to save them, because it is too late now.
                    102:      */
                    103:     FreeRes();
                    104:     FreeInclude();
                    105: 
                    106:     if ((hfRes = CreateFile(pszFullPath, GENERIC_READ,
                    107:             FILE_SHARE_READ, NULL, OPEN_EXISTING,
                    108:             FILE_FLAG_SEQUENTIAL_SCAN, NULL)) != (HANDLE)-1 &&
                    109:             LoadResFile(hfRes, pszFullPath, szInclude)) {
                    110:         lstrcpy(szFullResFile, pszFullPath);
                    111:         pszResFile = FileInPath(szFullResFile);
                    112: 
                    113:         ShowFileStatus(TRUE);
                    114: 
                    115:         /*
                    116:          * If there was a DLGINCLUDE resource found, try and open the
                    117:          * specified include file, after making sure that it is a
                    118:          * fully formed path.
                    119:          */
                    120:         if (*szInclude) {
                    121:             /*
                    122:              * Does the include filespec from the res file appear to
                    123:              * be a simple filename without a path?  If so, look for
                    124:              * it in the same directory that the res file is in.
                    125:              * Otherwise, assume it has a fully qualified path.
                    126:              */
                    127:             if (!HasPath(szInclude)) {
                    128:                 lstrcpy(szFullInclude, szFullResFile);
                    129:                 lstrcpy(FileInPath(szFullInclude), szInclude);
                    130:             }
                    131:             else {
                    132:                 lstrcpy(szFullInclude, szInclude);
                    133:             }
                    134: 
                    135:             fIncOpened = OpenIncludeFile(szFullInclude);
                    136:         }
                    137: 
                    138:         /*
                    139:          * If there wasn't an include resource found, or there was
                    140:          * but it couldn't be opened, we want to ask the user for the
                    141:          * include file to use for this resource file.
                    142:          */
                    143:         if (!fIncOpened)
                    144:             Open(FILE_INCLUDE);
                    145: 
                    146:         /*
                    147:          * Start counting the dialogs in the resource, but stop at two.
                    148:          */
                    149:         cDlg = 0;
                    150:         for (cDlg = 0, prl = gprlHead; prl; prl = prl->prlNext) {
                    151:             if (prl->fDlgResource) {
                    152:                 if (++cDlg > 1)
                    153:                     break;
                    154: 
                    155:                 prlSave = prl;
                    156:             }
                    157:         }
                    158: 
                    159:         /*
                    160:          * If there are multiple dialogs, display the "Select Dialog"
                    161:          * dialog to ask the user which one they want to edit.  If
                    162:          * there is exactly one dialog, just go ahead and show it
                    163:          * initially.
                    164:          */
                    165:         if (cDlg == 1)
                    166:             ResLinkToDialog(prlSave);
                    167:         else if (cDlg > 1)
                    168:             SelectDialogDialog();
                    169: 
                    170:         fSuccess = TRUE;
                    171:     }
                    172: 
                    173:     if (hfRes != (HANDLE)-1)
                    174:         CloseHandle(hfRes);
                    175: 
                    176:     ShowFileStatus(TRUE);
                    177:     SetCursor(hcurSave);
                    178: 
                    179:     return fSuccess;
                    180: }
                    181: 
                    182: 
                    183: 
                    184: /************************************************************************
                    185: * LoadResFile
                    186: *
                    187: * Loads the resource file specified by the passed in file handle.
                    188: * This function first verifies that it is a valid resource file.
                    189: *
                    190: * Arguments:
                    191: *   HANDLE hfRes           - File handle to read from.
                    192: *   LPTSTR pszFullResFile  - Full name of resource file being loaded.
                    193: *   LPTSTR pszIncludeBuf   - Where to return the include file name, if
                    194: *                            a DLGINCLUDE resource is found in the res
                    195: *                            file.  If not, this buffer gets a null byte
                    196: *                            as its first character.
                    197: *
                    198: * Returns:
                    199: *   TRUE if load was successful; otherwise, FALSE is returned.
                    200: *
                    201: ************************************************************************/
                    202: 
                    203: STATICFN BOOL LoadResFile(
                    204:     HANDLE hfRes,
                    205:     LPTSTR pszFullResFile,
                    206:     LPTSTR pszIncludeBuf)
                    207: {
                    208:     HANDLE hAllRes;
                    209:     PRES pRes;
                    210:     PRES pResAll;
                    211:     PRESLINK prl;
                    212:     PRESLINK prlT;
                    213:     INT cbRead;
                    214:     LPTSTR pszResType;
                    215:     DWORD cbFileSize;
                    216: 
                    217:     cbFileSize = GetFileSize((HANDLE)hfRes, NULL);
                    218: 
                    219:     if (!(hAllRes = GlobalAlloc(GMEM_MOVEABLE, cbFileSize))) {
                    220:         Message(MSG_OUTOFMEMORY);
                    221:         return FALSE;
                    222:     }
                    223: 
                    224:     *pszIncludeBuf = CHAR_NULL;
                    225:     pRes = pResAll = (PRES)GlobalLock(hAllRes);
                    226:     if ((cbRead = _lread((HFILE)hfRes, (LPSTR)pResAll, cbFileSize)) != -1 &&
                    227:             cbRead == (INT)cbFileSize) {
                    228:         if (!IsValidResFile(pResAll, cbFileSize)) {
                    229:             Message(MSG_BADRESFILE, pszFullResFile);
                    230:         }
                    231:         else do {
                    232:             pszResType = ResourceType(pRes);
                    233: 
                    234:             if (IsOrd(pszResType) && OrdID(pszResType) == ORDID_RT_DLGINCLUDE) {
                    235:                 /*
                    236:                  * Pass back the include file name.  This resource
                    237:                  * will not be saved in the res list because it is
                    238:                  * going to be explicitly written out later if
                    239:                  * necessary.
                    240:                  */
                    241:                 NameOrdCpy(pszIncludeBuf, (LPTSTR)SkipResHeader(pRes));
                    242:             }
                    243:             else if (IsOrd(pszResType) &&
                    244:                     OrdID(pszResType) == ORDID_RT_RESOURCE32) {
                    245:                 /*
                    246:                  * This is the dummy resource that identifies a
                    247:                  * 32 bit resource file.  This resource should be
                    248:                  * skipped also.
                    249:                  */
                    250:             }
                    251:             else {
                    252:                 /*
                    253:                  * This is some other kind of a resource.
                    254:                  * Save it in the resource list.
                    255:                  */
                    256:                 if (!(prlT = AllocResLink(pRes))) {
                    257:                     FreeResList();
                    258:                     break;
                    259:                 }
                    260: 
                    261:                 if (!gprlHead) {
                    262:                     gprlHead = prl = prlT;
                    263:                 }
                    264:                 else {
                    265:                     prl->prlNext = prlT;
                    266:                     prl = prlT;
                    267:                 }
                    268:             }
                    269: 
                    270:             /*
                    271:              * Move to the next resource.
                    272:              */
                    273:             pRes = (PRES)((PBYTE)pRes + pRes->HeaderSize + pRes->DataSize);
                    274:             DWordAlign((PBYTE *)&pRes);
                    275:         } while (pRes < (PRES)((PBYTE)pResAll + cbFileSize));
                    276:     }
                    277: 
                    278:     GlobalUnlock(hAllRes);
                    279:     GlobalFree(hAllRes);
                    280: 
                    281:     return (gprlHead ? TRUE : FALSE);
                    282: }
                    283: 
                    284: 
                    285: 
                    286: /************************************************************************
                    287: * IsValidResFile
                    288: *
                    289: * This function does some basic checks on the resource file in memory
                    290: * pointed to by pbRes.  It does this by walking through the resource
                    291: * checking for the resource header info and lengths.
                    292: *
                    293: * Arguments:
                    294: *   PRES pRes      - Pointer to the first resource in the file.
                    295: *   INT cbFileSize - Size of the file in memory.
                    296: *
                    297: * Returns:
                    298: *   TRUE if it is a valid resource file, FALSE if not.
                    299: *
                    300: ************************************************************************/
                    301: 
                    302: STATICFN BOOL IsValidResFile(
                    303:     PRES pRes,
                    304:     INT cbFileSize)
                    305: {
                    306:     INT cbCurLoc = 0;
                    307:     PRES pResT;
                    308: 
                    309:     /*
                    310:      * The file is zero size.
                    311:      */
                    312:     if (!cbFileSize)
                    313:         return FALSE;
                    314: 
                    315:     pResT = pRes;
                    316:     while (cbCurLoc < cbFileSize) {
                    317:         /*
                    318:          * Check this resource for validity.
                    319:          */
                    320:         if (!(pResT = SafeParseResHeader(pResT, cbFileSize - cbCurLoc)))
                    321:             return FALSE;
                    322: 
                    323:         /*
                    324:          * Point just past the resource that was just checked.
                    325:          */
                    326:         cbCurLoc = (PBYTE)pResT - (PBYTE)pRes;
                    327:     }
                    328: 
                    329:     return (cbCurLoc == cbFileSize) ? TRUE : FALSE;
                    330: }
                    331: 
                    332: 
                    333: 
                    334: /************************************************************************
                    335: * SafeParseResHeader
                    336: *
                    337: * This function parses the specified resource header and returns a
                    338: * pointer to the next resource header in the resource file.  It does
                    339: * it in a safe manner, not touching memory beyond the maximum size
                    340: * specified.  If the resource header is somehow messed up and
                    341: * specifies a size that is larger than will fit in the given maximum
                    342: * size, NULL is returned.
                    343: *
                    344: * Arguments:
                    345: *   PRES pRes     - Pointer to the resource.
                    346: *   INT cbMaxSize - Maximum size the resource can be.
                    347: *
                    348: * Returns:
                    349: *   A pointer to just past this resource, or NULL if the resource
                    350: *   is larger than cbMaxSize.
                    351: *
                    352: ************************************************************************/
                    353: 
                    354: STATICFN PRES SafeParseResHeader(
                    355:     PRES pRes,
                    356:     INT cbMaxSize)
                    357: {
                    358:     INT cbLen;
                    359:     DWORD cbDataSize;
                    360:     PBYTE pb;
                    361: 
                    362:     pb = (PBYTE)pRes;
                    363: 
                    364:     /*
                    365:      * There must be room for the first part of the resource header.
                    366:      */
                    367:     if (sizeof(RES) > cbMaxSize)
                    368:         return FALSE;
                    369: 
                    370:     pb += sizeof(RES);
                    371:     cbMaxSize -= sizeof(RES);
                    372: 
                    373:     /*
                    374:      * Parse the type field then skip over it.
                    375:      */
                    376:     cbLen = SafeNameOrdLen((LPTSTR)pb, cbMaxSize);
                    377:     if (cbLen > cbMaxSize)
                    378:         return NULL;
                    379: 
                    380:     pb += cbLen;
                    381:     cbMaxSize -= cbLen;
                    382: 
                    383:     /*
                    384:      * Parse the name field then skip over it.
                    385:      */
                    386:     cbLen = SafeNameOrdLen((LPTSTR)pb, cbMaxSize);
                    387:     if (cbLen > cbMaxSize)
                    388:         return NULL;
                    389: 
                    390:     pb += cbLen;
                    391:     cbMaxSize -= cbLen;
                    392: 
                    393:     SafeDWordAlign(&pb, &cbMaxSize);
                    394: 
                    395:     /*
                    396:      * There must be room for the second part of the resource header.
                    397:      */
                    398:     if (sizeof(RES2) > cbMaxSize)
                    399:         return FALSE;
                    400: 
                    401:     pb += sizeof(RES2);
                    402:     cbMaxSize -= sizeof(RES2);
                    403: 
                    404:     /*
                    405:      * The header size field must be valid.
                    406:      */
                    407:     if (pRes->HeaderSize != (DWORD)(pb - (PBYTE)pRes))
                    408:         return FALSE;
                    409: 
                    410:     /*
                    411:      * Calculate the size of the data, taking into account any
                    412:      * padding that may be at the end to make it DWORD aligned.
                    413:      */
                    414:     cbDataSize = pRes->DataSize;
                    415:     DWordAlign((PBYTE *)&cbDataSize);
                    416: 
                    417:     /*
                    418:      * There must be room enough left for the data.
                    419:      */
                    420:     if (cbDataSize > (DWORD)cbMaxSize)
                    421:         return FALSE;
                    422: 
                    423:     return (PRES)(pb + cbDataSize);
                    424: }
                    425: 
                    426: 
                    427: 
                    428: /************************************************************************
                    429: * SafeNameOrdLen
                    430: *
                    431: * This function returns the size of the specified name/ordinal.  It
                    432: * does it in a safe manner, not touching memory beyond the specified
                    433: * maximum size.  If it is a string and the terminating null is not
                    434: * found within cbMaxLen bytes, then cbMaxLen plus one is returned.
                    435: *
                    436: * Arguments:
                    437: *   LPTSTR psz   - Pointer to the name/ordinal.
                    438: *   INT cbMaxLen - Maximum length to probe.
                    439: *
                    440: * Returns:
                    441: *   The length of the ordinal if it is an ordinal, or the length
                    442: *   of the string (plus the null terminator) if it is a string.
                    443: *
                    444: ************************************************************************/
                    445: 
                    446: STATICFN INT SafeNameOrdLen(
                    447:     LPTSTR psz,
                    448:     INT cbMaxLen)
                    449: {
                    450:     INT cbLen = 0;
                    451: 
                    452:     if (cbMaxLen == 0)
                    453:         return 1;
                    454: 
                    455:     if (IsOrd(psz))
                    456:         return sizeof(ORDINAL);
                    457: 
                    458:     for (cbLen = 0; cbLen < cbMaxLen && *psz; psz++, cbLen += sizeof(TCHAR))
                    459:         ;
                    460: 
                    461:     /*
                    462:      * Account for the null terminator.
                    463:      */
                    464:     cbLen += sizeof(TCHAR);
                    465: 
                    466:     return cbLen;
                    467: }
                    468: 
                    469: 
                    470: 
                    471: /************************************************************************
                    472: * SafeDWordAlign
                    473: *
                    474: * This function aligns the passed pointer to a DWORD boundary.  At the
                    475: * same time, it subtracts from the specified counter the amount that
                    476: * it had to add to the pointer, if any.
                    477: *
                    478: * Arguments:
                    479: *   PBYTE *ppb  - Points to the pointer to align.
                    480: *   PINT pcbMax - Points to the current count to decrement.
                    481: *
                    482: ************************************************************************/
                    483: 
                    484: STATICFN VOID SafeDWordAlign(
                    485:     PBYTE *ppb,
                    486:     PINT pcbMax)
                    487: {
                    488:     INT cbAlign;
                    489: 
                    490:     cbAlign = (4 - (((WORD)(DWORD)*ppb) & 3)) % 4;
                    491:     *ppb += cbAlign;
                    492:     *pcbMax -= cbAlign;
                    493: }
                    494: 
                    495: 
                    496: 
                    497: /************************************************************************
                    498: * WriteRes
                    499: *
                    500: * Worker routine that does the actual writing out of the resource data.
                    501: *
                    502: * Arguments:
                    503: *   HANDLE hfWrite         - Resource file to write to.
                    504: *   LPTSTR pszFullResFile  - Full pathname to the resource file that
                    505: *                            is being written.
                    506: *
                    507: * Returns:
                    508: *   TRUE if successful; otherwise, FALSE.
                    509: *
                    510: ************************************************************************/
                    511: 
                    512: BOOL WriteRes(
                    513:     HANDLE hfWrite,
                    514:     LPTSTR pszFullResFile)
                    515: {
                    516:     PRESLINK prl;
                    517:     PRES pRes;
                    518: 
                    519:     /*
                    520:      * Write the special RT_RESOURCE32 dummy resource to the beginning
                    521:      * of the resource file.  This resource is aligned, so no padding
                    522:      * needs to be done before writing the resource that follows it.
                    523:      */
                    524:     if (_lwrite((HFILE)hfWrite, abResource32, sizeof(abResource32)) == -1)
                    525:         return FALSE;
                    526: 
                    527:     /*
                    528:      * Write out any DLGINCLUDE resource there may be.
                    529:      */
                    530:     if (!WriteDlgIncludeRes(hfWrite, pszFullResFile))
                    531:         return FALSE;
                    532: 
                    533:     /*
                    534:      * Loop through all the resources.
                    535:      */
                    536:     for (prl = gprlHead; prl; prl = prl->prlNext) {
                    537:         if (!(pRes = (PRES)GlobalLock(prl->hRes)))
                    538:             return FALSE;
                    539: 
                    540:         /*
                    541:          * Write the actual data.
                    542:          */
                    543:         if (_lwrite((HFILE)hfWrite, (LPSTR)pRes, prl->cbRes) == -1)
                    544:             return FALSE;
                    545: 
                    546:         /*
                    547:          * Write pads out to the next DWORD boundary.
                    548:          */
                    549:         if (!WriteDWordPad(hfWrite, prl->cbRes))
                    550:             return FALSE;
                    551: 
                    552:         GlobalUnlock(prl->hRes);
                    553:     }
                    554: 
                    555:     return TRUE;
                    556: }
                    557: 
                    558: 
                    559: 
                    560: /************************************************************************
                    561: * WriteDlgIncludeRes
                    562: *
                    563: * Writes out a DLGINCLUDE resource to the specified resource file for
                    564: * the currently open include file.
                    565: *
                    566: * Arguments:
                    567: *   HANDLE hfWrite         - Resource file handle to write to.
                    568: *   LPTSTR pszFullResFile  - Full pathname to the resource file that
                    569: *                            is being written.
                    570: *
                    571: * Returns:
                    572: *   Number of characters written if the include resource was
                    573: *   written successfully (or there wasn't one to write) or -1
                    574: *   if an error occurred.
                    575: *
                    576: ************************************************************************/
                    577: 
                    578: STATICFN BOOL WriteDlgIncludeRes(
                    579:     HANDLE hfWrite,
                    580:     LPTSTR pszFullResFile)
                    581: {
                    582:     INT cbResSize;
                    583:     INT cbDataSize;
                    584:     PRES pResBegin;
                    585:     PBYTE pb;
                    586:     INT cbWritten;
                    587:     LPTSTR pszInc;
                    588:     ORDINAL ordDlgIncName;
                    589:     BOOL fSuccess = FALSE;
                    590: 
                    591:     /*
                    592:      * No include file.  Do nothing (return success).
                    593:      */
                    594:     if (!pszIncludeFile)
                    595:         return TRUE;
                    596: 
                    597:     /*
                    598:      * If the include file is in a different directory than the resource
                    599:      * file, write the full path to it.  Otherwise, we just write the
                    600:      * include file name.
                    601:      */
                    602:     if (DifferentDirs(pszFullResFile, szFullIncludeFile))
                    603:         pszInc = szFullIncludeFile;
                    604:     else
                    605:         pszInc = pszIncludeFile;
                    606: 
                    607:     /*
                    608:      * The DLGINCLUDE resource name always is the same (a value of 1).
                    609:      */
                    610:     WriteOrd(&ordDlgIncName, ORDID_DLGINCLUDE_NAME);
                    611: 
                    612:     /*
                    613:      * Determine the size of the resource data.
                    614:      */
                    615:     cbDataSize = NameOrdLen(pszInc);
                    616: 
                    617:     /*
                    618:      * Determine the resource size.  Note that there is no need for
                    619:      * DWORD padding after the res header, because the header will
                    620:      * be aligned (there are no strings in it).
                    621:      */
                    622:     cbResSize = sizeof(RES) +                       // First part of res header.
                    623:             sizeof(ORDINAL) +                       // Type ordinal.
                    624:             sizeof(ORDINAL) +                       // Name ordinal.
                    625:             sizeof(RES2) +                          // Second half of header.
                    626:             cbDataSize;                             // Size of data.
                    627: 
                    628:     if (!(pResBegin = (PRES)MyAlloc(cbResSize)))
                    629:         return FALSE;
                    630: 
                    631:     /*
                    632:      * Write the resource header.
                    633:      */
                    634:     pb = WriteResHeader(pResBegin, cbDataSize, ORDID_RT_DLGINCLUDE,
                    635:             (LPTSTR)&ordDlgIncName, MMF_MOVEABLE | MMF_PURE | MMF_DISCARDABLE,
                    636:             0, 0, 0, 0);
                    637: 
                    638:     /*
                    639:      * Write the resource data.  This is simply the name
                    640:      * of the include file.
                    641:      */
                    642:     NameOrdCpy((LPTSTR)pb, pszInc);
                    643: 
                    644:     /*
                    645:      * Write the resource to the file.
                    646:      */
                    647:     cbWritten = _lwrite((HFILE)hfWrite, (LPSTR)pResBegin, cbResSize);
                    648: 
                    649:     if (cbWritten == cbResSize) {
                    650:         /*
                    651:          * Write pads out to the next DWORD boundary.
                    652:          */
                    653:         if (WriteDWordPad(hfWrite, cbWritten))
                    654:             fSuccess = TRUE;
                    655:     }
                    656: 
                    657:     MyFree(pResBegin);
                    658: 
                    659:     return fSuccess;
                    660: }

unix.superglobalmegacorp.com

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