Annotation of pmsdk/samples/linefrac/lffile.c, revision 1.1

1.1     ! root        1: /************************************************************************
        !             2: *
        !             3: *   lffile.c -- File handling subroutines for LineFrac.
        !             4: *
        !             5: *   Created by Microsoft Corporation, 1989
        !             6: *
        !             7: ************************************************************************/
        !             8: 
        !             9: #define INCL_WIN
        !            10: #define INCL_GPI
        !            11: #define INCL_DOSMEMMGR
        !            12: #define INCL_DOSFILEMGR
        !            13: #define INCL_BITMAPFILEFORMAT
        !            14: #include <os2.h>
        !            15: 
        !            16: #include <stdio.h>
        !            17: 
        !            18: #include "opendlg.h"
        !            19: 
        !            20: #define INCL_GLOBALS
        !            21: #define INCL_THREADS
        !            22: #include "linefrac.h"
        !            23: 
        !            24: #define INCL_LFFILE
        !            25: #define INCL_LFPS
        !            26: #define INCL_LFUTIL
        !            27: #include "lffuncs.h"
        !            28: 
        !            29: 
        !            30: 
        !            31: 
        !            32: /*
        !            33:  * this is the bitmap resource file format structure
        !            34:  */
        !            35: typedef struct {
        !            36:     USHORT    wType;
        !            37:     ULONG     dwSize;
        !            38:     int       xHotspot;
        !            39:     int       yHotspot;
        !            40:     ULONG     dwBitsOffset;
        !            41:     USHORT    bmWidth;       /* from here this is a BitmapInfo table */
        !            42:     USHORT    bmHeight;
        !            43:     USHORT    bmPlanes;
        !            44:     USHORT    bmBitcount;
        !            45: } RCBITMAP;
        !            46: typedef RCBITMAP FAR *PRCBITMAP;
        !            47: 
        !            48: 
        !            49: 
        !            50: 
        !            51: /************************************************************************
        !            52: *
        !            53: *   Global Variables
        !            54: *
        !            55: ************************************************************************/
        !            56: 
        !            57: extern GLOBALDATA global;
        !            58: 
        !            59: 
        !            60: 
        !            61: 
        !            62: /************************************************************************
        !            63: *
        !            64: *   LfReadFile
        !            65: *
        !            66: *   Calls the OpenDlg function to ask the user what file name to
        !            67: *   read from.
        !            68: *
        !            69: ************************************************************************/
        !            70: 
        !            71: VOID
        !            72: LfReadFile(hwnd, pthr)
        !            73: HWND hwnd;
        !            74: PTHR pthr;
        !            75: {
        !            76:     HFILE hFile;
        !            77:     DLF dlf;
        !            78: 
        !            79:     dlf.rgbAction      = DLG_OPENDLG;
        !            80:     dlf.rgbFlags       = ATTRDIRLIST;
        !            81:     dlf.phFile         = &hFile;
        !            82:     dlf.pszExt         = (PSZ)"\\*.bmp";
        !            83:     dlf.pszAppName     = "LineFrac";
        !            84:     dlf.pszTitle       = "Load Bitmap";
        !            85:     dlf.pszInstructions = NULL;
        !            86:     dlf.szFileName[0]  = '\0';
        !            87:     dlf.szOpenFile[0]  = '\0';
        !            88: 
        !            89:     switch (DlgFile(hwnd,&dlf))
        !            90:     {
        !            91:     case TDF_ERRMEM:
        !            92:     case TDF_INVALID:
        !            93:        MyMessageBox(hwnd, "Error reading file.");
        !            94:        break;
        !            95: 
        !            96:     case TDF_NOOPEN:
        !            97:        break;
        !            98: 
        !            99:     default:
        !           100:        if (!LfReadBMP(pthr, &dlf))
        !           101:            MyMessageBox(hwnd, "Error reading file.\nIs AutoResize enabled?");
        !           102:     }
        !           103: }
        !           104: 
        !           105: 
        !           106: 
        !           107: 
        !           108: /************************************************************************
        !           109: *
        !           110: *   LfReadBMP
        !           111: *
        !           112: *   Read a bitmap in from a BMP format file.  Prepare the DC for the
        !           113: *   given thread to accept it. The user can have the DC resized to
        !           114: *   fit exactly the bitmap, or fit the bits in as best as we can.
        !           115: *   If we're not resizing and the bitmap is larger than the thread's
        !           116: *   DC, then load the bits flush with the lower left.
        !           117: *
        !           118: *   Both old-style (PRCBITMAP) and new-style (PBITMAPFILEHEADER)
        !           119: *   bitmaps can be read.
        !           120: *
        !           121: *   Free up memory and close the file before leaving.  The file
        !           122: *   will have been opened by the time this function is called,
        !           123: *   and the file handle will be in the *pdlf structure.
        !           124: *
        !           125: ************************************************************************/
        !           126: 
        !           127: BOOL
        !           128: LfReadBMP(pthr, pdlf)
        !           129: PTHR pthr;
        !           130: PDLF pdlf;             /* File information filled by DlgFile. */
        !           131: {
        !           132:     HFILE hfile;
        !           133:     ULONG cScans;
        !           134:     ULONG ulSize;       /* Number of bytes occupied by bitmap bits.         */
        !           135:     USHORT cSegs;       /* Number of 64K segments in ulSize.                */
        !           136:     USHORT cbExtra;     /* Bytes in last segment of ulSize.                 */
        !           137:     SEL sel;            /* Base selector to file data.                      */
        !           138:     USHORT hugeshift;   /* Segment index shift value.                       */
        !           139:     USHORT cbRead1;     /* Number of bytes to read first call to DosRead    */
        !           140:     USHORT cbRead2;     /* Number of bytes to read second call to DosRead   */
        !           141:     USHORT cbRead;      /* Number of bytes read by DosRead.                 */
        !           142:     BOOL fRet = FALSE;  /* Function return code.                            */
        !           143:     int i;              /* Generic loop index.                              */
        !           144:     FILESTATUS fsts;
        !           145:     PBITMAPFILEHEADER pbfh;
        !           146:     PRCBITMAP  rb;
        !           147:     PBYTE pImage;
        !           148: 
        !           149: 
        !           150:     /*******************************************************************
        !           151:     * Find out how big the file is so we can read the whole thing in.
        !           152:     *******************************************************************/
        !           153: 
        !           154:     hfile = *(pdlf->phFile);
        !           155:     if( DosQFileInfo( hfile, 1, &fsts, sizeof(FILESTATUS)) != 0)
        !           156:        goto lfread_error_close_file;
        !           157: 
        !           158:     ulSize  = fsts.cbFile;
        !           159:     cSegs   = (USHORT)(ulSize/0x10000L);
        !           160:     cbExtra = (USHORT)(ulSize%0x10000L);
        !           161:     if (DosAllocHuge(cSegs, cbExtra, (PSEL)&sel, 0, 0))
        !           162:        goto lfread_error_close_file;
        !           163:     if (DosGetHugeShift(&hugeshift))
        !           164:        goto lfread_error_free_bits;
        !           165: 
        !           166:     pImage = (PBYTE)MAKEP(sel, 0);
        !           167:     rb    = (PRCBITMAP)pImage;
        !           168:     pbfh   = (PBITMAPFILEHEADER)pImage;
        !           169: 
        !           170: 
        !           171:     /*******************************************************************
        !           172:     * Read the bits in from the file. The DosRead function allows a
        !           173:     * maximum of 64K-1 bytes read at a time.  We get around this
        !           174:     * by reading two 32K chunks for each 64K segment, and reading the
        !           175:     * last segment in one piece.
        !           176:     *******************************************************************/
        !           177: 
        !           178:     for (i = 0; i <= cSegs; ++i)
        !           179:     {
        !           180:        if (i < cSegs)
        !           181:        {
        !           182:            /* This segment is 64K bytes long, so split it up. */
        !           183:            cbRead1 = 0x8000;
        !           184:            cbRead2 = 0x8000;
        !           185:        }
        !           186:        else
        !           187:        {
        !           188:            /* This segment is less than 64K bytes long, so read it all. */
        !           189:            cbRead1 = cbExtra;
        !           190:            cbRead2 = 0;
        !           191:        }
        !           192: 
        !           193:        /* There's a possibility that cbExtra will be 0, so check
        !           194:         * to avoid an unnecessary system call.
        !           195:         */
        !           196:        if (cbRead1 > 0)
        !           197:        {
        !           198:            if (DosRead( hfile
        !           199:                       , (PVOID)MAKEP(sel+(i<<hugeshift), 0)
        !           200:                       , cbRead1
        !           201:                       , &cbRead))
        !           202:                goto lfread_error_free_bits;
        !           203:            if (cbRead1 != cbRead)
        !           204:                goto lfread_error_free_bits;
        !           205:        }
        !           206: 
        !           207:        /* This will always be skipped on the last partial segment. */
        !           208:        if (cbRead2 > 0)
        !           209:        {
        !           210:            if (DosRead( hfile
        !           211:                       , (PVOID)MAKEP(sel+(i<<hugeshift), cbRead1)
        !           212:                       , cbRead2
        !           213:                       , &cbRead))
        !           214:                goto lfread_error_free_bits;
        !           215:            if (cbRead2 != cbRead)
        !           216:                goto lfread_error_free_bits;
        !           217:        }
        !           218:     }
        !           219: 
        !           220: 
        !           221:     /*******************************************************************
        !           222:     * At this point we have the bitmap completely in memory.  Now we
        !           223:     * look at how the user wants them set into the thread's PS.  If
        !           224:     * the thread has fAutoResizePS set, then make the PS fit the size
        !           225:     * of the bitmap (the easy case).  If the flag is not set, then
        !           226:     * figure out how to place it.
        !           227:     *******************************************************************/
        !           228: 
        !           229:     if (pthr->fAutoSizePS)
        !           230:     {
        !           231:        if (pbfh->bmp.cbFix != sizeof(BITMAPINFOHEADER))
        !           232:        {
        !           233:            global.bm.cx        = rb->bmWidth;
        !           234:            global.bm.cy        = rb->bmHeight;
        !           235:            global.bm.cPlanes   = rb->bmPlanes;
        !           236:            global.bm.cBitCount = rb->bmBitcount;
        !           237:        }
        !           238:        else
        !           239:        {
        !           240:            global.bm.cx        = pbfh->bmp.cx;
        !           241:            global.bm.cy        = pbfh->bmp.cy;
        !           242:            global.bm.cPlanes   = pbfh->bmp.cPlanes;
        !           243:            global.bm.cBitCount = pbfh->bmp.cBitCount;
        !           244:        }
        !           245: 
        !           246:        LfResizePS(pthr);
        !           247:     }
        !           248:     else
        !           249:        goto lfread_error_free_bits;
        !           250: 
        !           251: 
        !           252:     /*******************************************************************
        !           253:     * Tell GPI to put the bits into the thread's PS. The function returns
        !           254:     * the number of scan lines of the bitmap that were copied. We want
        !           255:     * all of them at once.
        !           256:     *******************************************************************/
        !           257: 
        !           258:     if (pbfh->bmp.cbFix != sizeof(BITMAPINFOHEADER))
        !           259:     {
        !           260:         pImage += rb->dwBitsOffset;
        !           261:         rb->dwBitsOffset = sizeof(BITMAPINFOHEADER);
        !           262:        cScans = GpiSetBitmapBits( pthr->hps
        !           263:                                 , 0L
        !           264:                                 , (LONG)rb->bmHeight
        !           265:                                 , pImage
        !           266:                                 , (PBITMAPINFO)&(rb->dwBitsOffset));
        !           267:        if (cScans != (LONG)rb->bmHeight)  /* compare with original number of scans */
        !           268:            goto lfread_error_free_bits;
        !           269:     }
        !           270:     else
        !           271:     {
        !           272:        cScans = GpiSetBitmapBits( pthr->hps
        !           273:                                 , 0L
        !           274:                                 , (LONG)pbfh->bmp.cy
        !           275:                                 , pImage + pbfh->offBits
        !           276:                                 , (PBITMAPINFO)&(pbfh->bmp));
        !           277:        if (cScans != (LONG)pbfh->bmp.cy)  /* compare with original number of scans */
        !           278:            goto lfread_error_free_bits;
        !           279:     }
        !           280:     fRet = TRUE;     /* We made it!  The bits are in the thread's PS. */
        !           281: 
        !           282: 
        !           283:     /*******************************************************************
        !           284:     * Close the file, free the buffer space and leave. This is a
        !           285:     * common exit point from the function.  Since the same cleanup
        !           286:     * operations need to be performed for such a large number of
        !           287:     * possible error conditions, this is a concise way to do the right
        !           288:     * thing.
        !           289:     *******************************************************************/
        !           290: 
        !           291: lfread_error_free_bits:
        !           292:     DosFreeSeg(sel);
        !           293: lfread_error_close_file:
        !           294:     DosClose(hfile);
        !           295:     return fRet;
        !           296: }
        !           297: 
        !           298: 
        !           299: 
        !           300: 
        !           301: /************************************************************************
        !           302: *
        !           303: *   LfWriteFile
        !           304: *
        !           305: *   Calls the OpenDlg function to ask the user what file name to
        !           306: *   save under.
        !           307: *
        !           308: ************************************************************************/
        !           309: 
        !           310: VOID
        !           311: LfWriteFile(hwnd, pthr)
        !           312: HWND hwnd;
        !           313: PTHR pthr;
        !           314: {
        !           315:     HFILE hFile;
        !           316:     DLF dlf;
        !           317:     BITMAPINFOHEADER bmih;
        !           318: 
        !           319: 
        !           320:     SetUpDLF( &dlf
        !           321:            , DLG_SAVEDLG
        !           322:            , &hFile
        !           323:            , (PSZ)"\\*.BMP"
        !           324:            , (PSZ)"LineFrac"
        !           325:            , (PSZ)"Save Bitmap"
        !           326:            , NULL );
        !           327:     dlf.szFileName[0] = '\0';
        !           328:     dlf.szOpenFile[0] = '\0';
        !           329: 
        !           330:     switch (DlgFile(hwnd,&dlf))
        !           331:     {
        !           332:     case TDF_ERRMEM:
        !           333:     case TDF_INVALID:
        !           334:        MyMessageBox(hwnd, "Error opening file.");
        !           335:        break;
        !           336: 
        !           337:     case TDF_NOSAVE:
        !           338:        break;
        !           339: 
        !           340:     default:
        !           341:        bmih.cbFix     = sizeof(BITMAPINFOHEADER);
        !           342:        bmih.cx        = (USHORT) pthr->rcl.xRight;
        !           343:        bmih.cy        = (USHORT) pthr->rcl.yTop;
        !           344:        bmih.cPlanes   = pthr->cPlanes;
        !           345:        bmih.cBitCount = pthr->cBitCount;
        !           346: 
        !           347:        if (!LfWriteBMP(pthr->hps, &bmih, &dlf))
        !           348:            MyMessageBox(hwnd, "Error writing file.");
        !           349:     }
        !           350: }
        !           351: 
        !           352: 
        !           353: 
        !           354: 
        !           355: /************************************************************************
        !           356: *
        !           357: *   LfWriteBMP
        !           358: *
        !           359: *   Write the bitmap out to a BMP format file. Write the file
        !           360: *   header first, then the bitmap bits.  Space for the header
        !           361: *   and the bits is allocated. Huge bitmaps are supported.
        !           362: *   Free up memory and close the file before leaving.  The file
        !           363: *   will have been opened by the time this function is called,
        !           364: *   and the file handle will be in the *pdlf structure.
        !           365: *
        !           366: ************************************************************************/
        !           367: 
        !           368: BOOL
        !           369: LfWriteBMP(hPS, pbmih, pdlf)
        !           370: HPS hPS;               /* hPS from which to get bitmap bits.     */
        !           371: PBITMAPINFOHEADER pbmih;/* Bitmap information.                   */
        !           372: PDLF pdlf;             /* File information filled by DlgFile. */
        !           373: {
        !           374:     HFILE hfile;
        !           375:     ULONG cScans;
        !           376:     ULONG ulSize;       /* Number of bytes occupied by bitmap bits.         */
        !           377:     USHORT cSegs;       /* Number of 64K segments in ulSize.                */
        !           378:     USHORT cbExtra;     /* Bytes in last segment of ulSize.                 */
        !           379:     SEL selBits;        /* Base selector to bitmap bits.                    */
        !           380:     USHORT hugeshift;   /* Segment index shift value.                       */
        !           381:     USHORT cbBMHdr;     /* Size of bitmap header.                           */
        !           382:     PBITMAPFILEHEADER pbfh; /* Pointer to private copy of bitmap info data.    */
        !           383:     USHORT cbWrite1;    /* Number of bytes to write first call to DosWrite  */
        !           384:     USHORT cbWrite2;    /* Number of bytes to write second call to DosWrite */
        !           385:     USHORT cbWritten;   /* Number of bytes written by DosWrite.             */
        !           386:     BOOL fRet = FALSE;  /* Function return code.                            */
        !           387:     int i;              /* Generic loop index.                              */
        !           388:     struct
        !           389:     {
        !           390:        LONG cPlanes;
        !           391:        LONG cBitCount;
        !           392:     } bmFmt;
        !           393: 
        !           394: 
        !           395:     hfile = *(pdlf->phFile);
        !           396: 
        !           397:     /*******************************************************************
        !           398:     * If the bitmap was created with either 0 planes or 0 bits per
        !           399:     * pixel, then query the format to write with.  By asking for just
        !           400:     * one format (two LONGs, or one instance of structure of bmFmt),
        !           401:     * we'll get the device's favored format.
        !           402:     *******************************************************************/
        !           403: 
        !           404:     if ((pbmih->cPlanes == 0) || (pbmih->cBitCount))
        !           405:     {
        !           406:        if (!GpiQueryDeviceBitmapFormats(hPS, 2L, (PLONG)&bmFmt))
        !           407:            goto lfwrite_error_close_file;
        !           408:     }
        !           409:     else
        !           410:     {
        !           411:        bmFmt.cPlanes   = pbmih->cPlanes;
        !           412:        bmFmt.cBitCount = pbmih->cBitCount;
        !           413:     }
        !           414: 
        !           415: 
        !           416:     /*******************************************************************
        !           417:     * Determine size of bitmap header. The header consists of a
        !           418:     * a fixed-size part and a variable-length color table.  The
        !           419:     * latter has  2^cBitCount  entries, each of which is sizeof(RGB)
        !           420:     * bytes long.  The exception is when cBitCount is 24, in which
        !           421:     * case the color table is omitted because the pixels are direct
        !           422:     * rgb values.
        !           423:     *******************************************************************/
        !           424: 
        !           425:     i = (int) bmFmt.cBitCount;
        !           426:     if (i == 24)
        !           427:        cbBMHdr = 0;
        !           428:     else
        !           429:        for (cbBMHdr = sizeof(RGB); i > 0; --i)
        !           430:            cbBMHdr *= 2;
        !           431:     cbBMHdr += sizeof(BITMAPFILEHEADER);
        !           432: 
        !           433: 
        !           434:     /*******************************************************************
        !           435:     * Copy structure from input to work buffer.  The call to
        !           436:     * GpiQueryBitmapBits will have write-access to this, so we won't
        !           437:     * let it have the user's data.
        !           438:     *******************************************************************/
        !           439: 
        !           440:     pbfh = 0;
        !           441:     if (DosAllocSeg(cbBMHdr, ((PUSHORT)&pbfh)+1, 0))
        !           442:        goto lfwrite_error_close_file;
        !           443:     pbfh->bmp = *pbmih;
        !           444:     if ((pbmih->cPlanes == 0) || (pbmih->cBitCount))
        !           445:     {
        !           446:        pbfh->bmp.cPlanes   = (USHORT) bmFmt.cPlanes;
        !           447:        pbfh->bmp.cBitCount = (USHORT) bmFmt.cBitCount;
        !           448:     }
        !           449: 
        !           450: 
        !           451:     /*******************************************************************
        !           452:     * Allocate space for the bitmap bits -- all of them at once.
        !           453:     * The extra ULONG casts are there to force all the arithmetic
        !           454:     * to be done in 32 bits.
        !           455:     *******************************************************************/
        !           456: 
        !           457:     ulSize = (
        !           458:               (
        !           459:                 (
        !           460:                   (ULONG)pbfh->bmp.cBitCount
        !           461:                   * (ULONG)pbfh->bmp.cx
        !           462:                   + 31L
        !           463:                 ) / 32L
        !           464:               ) * (ULONG)pbfh->bmp.cPlanes * 4L
        !           465:             ) * (ULONG)pbfh->bmp.cy;
        !           466: 
        !           467:     cSegs   = (USHORT)(ulSize/0x10000L);
        !           468:     cbExtra = (USHORT)(ulSize%0x10000L);
        !           469:     if (DosAllocHuge(cSegs, cbExtra, (PSEL)&selBits, 0, 0))
        !           470:        goto lfwrite_error_free_header;
        !           471:     if (DosGetHugeShift(&hugeshift))
        !           472:        goto lfwrite_error_free_bits;
        !           473: 
        !           474: 
        !           475:     /*******************************************************************
        !           476:     * Tell GPI to give us the bits. The function returns the number
        !           477:     * of scan lines of the bitmap that were copied.  We want all of
        !           478:     * them at once.
        !           479:     *******************************************************************/
        !           480: 
        !           481:     cScans = GpiQueryBitmapBits( hPS
        !           482:                               , 0L
        !           483:                               , (ULONG)pbfh->bmp.cy
        !           484:                               , (PBYTE)MAKEP(selBits, 0)
        !           485:                               , (PBITMAPINFO)&pbfh->bmp);
        !           486:     if (cScans != pbfh->bmp.cy)  /* compare with original number of scans */
        !           487:        goto lfwrite_error_free_bits;
        !           488: 
        !           489: 
        !           490:     /*******************************************************************
        !           491:     * Fill in the extra header fields and write the header out to
        !           492:     * the file.
        !           493:     *******************************************************************/
        !           494: 
        !           495:     pbfh->usType    = 0x4D42;            /* 'MB' */
        !           496:     pbfh->cbSize    = ulSize + cbBMHdr;
        !           497:     pbfh->xHotspot  = pbfh->bmp.cx / 2;    /* why bother ? */
        !           498:     pbfh->yHotspot  = pbfh->bmp.cy / 2;
        !           499:     pbfh->offBits   = cbBMHdr;
        !           500: 
        !           501:     if (DosWrite( hfile
        !           502:                , (PVOID)pbfh
        !           503:                , cbBMHdr
        !           504:                , &cbWritten))
        !           505:        goto lfwrite_error_free_bits;
        !           506:     if (cbWritten != cbBMHdr)
        !           507:        goto lfwrite_error_free_bits;
        !           508: 
        !           509: 
        !           510:     /*******************************************************************
        !           511:     * Write the bits out to the file. The DosWrite function allows a
        !           512:     * maximum of 64K-1 bytes written at a time.  We get around this
        !           513:     * by writing two 32K chunks for each 64K segment, and writing the
        !           514:     * last segment in one piece.
        !           515:     *******************************************************************/
        !           516: 
        !           517:     for (i = 0; i <= cSegs; ++i)
        !           518:     {
        !           519:        if (i < cSegs)
        !           520:        {
        !           521:            /* This segment is 64K bytes long, so split it up. */
        !           522:            cbWrite1 = 0x8000;
        !           523:            cbWrite2 = 0x8000;
        !           524:        }
        !           525:        else
        !           526:        {
        !           527:            /* This segment is less than 64K bytes long, so write it all. */
        !           528:            cbWrite1 = cbExtra;
        !           529:            cbWrite2 = 0;
        !           530:        }
        !           531: 
        !           532:        /* There's a possibility that cbExtra will be 0, so check
        !           533:         * to avoid an unnecessary system call.
        !           534:         */
        !           535:        if (cbWrite1 > 0)
        !           536:        {
        !           537:            if (DosWrite( hfile
        !           538:                        , (PVOID)MAKEP(selBits+(i<<hugeshift), 0)
        !           539:                        , cbWrite1
        !           540:                        , &cbWritten))
        !           541:                goto lfwrite_error_free_bits;
        !           542:            if (cbWrite1 != cbWritten)
        !           543:                goto lfwrite_error_free_bits;
        !           544:        }
        !           545: 
        !           546:        /* This will always be skipped on the last partial segment. */
        !           547:        if (cbWrite2 > 0)
        !           548:        {
        !           549:            if (DosWrite( hfile
        !           550:                        , (PVOID)MAKEP(selBits+(i<<hugeshift), cbWrite1)
        !           551:                        , cbWrite2
        !           552:                        , &cbWritten))
        !           553:                goto lfwrite_error_free_bits;
        !           554:            if (cbWrite2 != cbWritten)
        !           555:                goto lfwrite_error_free_bits;
        !           556:        }
        !           557:     }
        !           558: 
        !           559:     fRet = TRUE;     /* We made it!  The bits are on the disk. */
        !           560: 
        !           561: 
        !           562:     /*******************************************************************
        !           563:     * Close the file, free the buffer space and leave. This is a
        !           564:     * common exit point from the function.  Since the same cleanup
        !           565:     * operations need to be performed for such a large number of
        !           566:     * possible error conditions, this is concise way to do the right
        !           567:     * thing.
        !           568:     *******************************************************************/
        !           569: 
        !           570: lfwrite_error_free_bits:
        !           571:     DosFreeSeg(selBits);
        !           572: lfwrite_error_free_header:
        !           573:     DosFreeSeg(*((PUSHORT)&pbfh+1));
        !           574: lfwrite_error_close_file:
        !           575:     DosClose(hfile);
        !           576:     return fRet;
        !           577: }

unix.superglobalmegacorp.com

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