home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mmpm21tk.zip / TK / CASECONV / CONVPROC.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  29KB  |  870 lines

  1. /*static char *SCCSID = "@(#)convproc.c    13.4 92/03/06";*/
  2. #pragma title ("CONVPROC.C - Case Convert I/O Procedure")
  3.  
  4. /********************** START OF SPECIFICATIONS *****************************/
  5. /*                                                                          */
  6. /* SOURCE FILE NAME: CONVPROC.C                                             */
  7. /*                                                                          */
  8. /* DESCRIPTIVE NAME: Multi-Media I/O Procedure                              */
  9. /*                                                                          */
  10. /* COPYRIGHT:                                                               */
  11. /*              Copyright (c) IBM Corporation  1992, 1993                   */
  12. /*                        All Rights Reserved                               */
  13. /*                                                                          */
  14. /* STATUS: MMPM/2 Release 1.10                                              */
  15. /*                                                                          */
  16. /* ABSTRACT:                                                                */
  17. /*                                                                          */
  18. /*********************** END OF SPECIFICATIONS ******************************/
  19.  
  20. #define INCL_NOPMAPI                   // no PM include files required
  21. #define INCL_DOSFILEMGR                // need for Dos File I/O API's
  22. #define INCL_CONVPROC                  // use only include CONV proc info
  23.  
  24. #include <os2.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <mmioos2.h>                   // public include files
  29. #include "hhpheap.h"                   // MMPM/2 Heap Manager
  30. #include "convproc.h"                  // header defs for this I/O proc
  31.  
  32. #pragma subtitle ("CONVPROC - Case Convert I/O procedure")
  33. #pragma page ()
  34.  
  35. /**************************************************************************
  36. **   CONVProc                                                            **
  37. ***************************************************************************
  38. *
  39. * ARGUMENTS:
  40. *
  41. *     PSZ pmmioStr - pointer to MMIOINFO block
  42. *     USHORT usMsg - MMIO message being sent
  43. *     LONG lParam1 - filename or other parameter depending on message
  44. *     LONG lParam2 - used with some messages as values
  45. *
  46. *
  47. * RETURN:
  48. *
  49. *     MMIOM_OPEN
  50. *         Success           - MMIO_SUCCESS     (0)
  51. *         Failure           - Return > 0
  52. *
  53. *     MMIOM_READ
  54. *         Success           - Return code of x for number of bytes read
  55. *                           - 0 if the end of the file was reached, or
  56. *         Failure           - MMIO_ERROR      (-1)
  57. *
  58. *     MMIOM_WRITE
  59. *         Success           - Return code of x for number of bytes written
  60. *         Failure           - MMIO_ERROR      (-1)
  61. *
  62. *     MMIOM_SEEK
  63. *         Success           - Return code of x indicates current file position
  64. *         Failure           - MMIO_ERROR      (-1)
  65. *
  66. *     MMIOM_CLOSE
  67. *         Success           - MMIO_SUCCESS     (0)
  68. *         Failure           - Return > 0
  69. *
  70. *     MMIOM_GETFORMATNAME
  71. *         Success           - Returns the number of bytes read into
  72. *                             the buffer (size of format name)
  73. *         Failure           - Return 0
  74. *
  75. *     MMIOM_GETFORMATINFO
  76. *         Success           - MMIO_SUCCESS     (0)
  77. *         Failure           - MMIO_ERROR      (-1)
  78. *
  79. *     MMIOM_QUERYHEADERLENGTH
  80. *         Success           - Returns the size of the header in bytes
  81. *         Failure           - Return 0
  82. *
  83. *     MMIOM_IDENTIFYFILE
  84. *         Success           - MMIO_SUCCESS     (0)
  85. *         Failure           - MMIO_ERROR      (-1)
  86. *
  87. *     MMIOM_GETHEADER
  88. *         Success           - Returns number of bytes copied into
  89. *                             the header structure.
  90. *         Failure           - Return 0
  91. *         Other             - If length passed in was not large
  92. *                             enough to hold header then,
  93. *                             MMIOERR_INVALID_BUFFER_LENGTH is set
  94. *                             in ulErrorRet.
  95. *                           - If header is bad,
  96. *                             MMIOERR_INVALID_STRUCTURE is set in
  97. *                             ulErrorRet
  98. *
  99. *     MMIOM_SETHEADER
  100. *         Success           - Returns number of bytes written
  101. *         Failure           - Return 0
  102. *         Other             - If header is bad,
  103. *                             MMIOERR_INVALID_STRUCTURE is set in
  104. *                             ulErrorRet
  105. *
  106. *     CONV_TOUPPER - Returns buffer of uppercase-converted characters.
  107. *     CONV_TOLOWER - Returns buffer of lowercase-converted characters.
  108. *
  109. * DESCRIPTION:
  110. *
  111. *     This routine will attempt I/O functions on a DOS type file, and
  112. *     allow custom messages to be sent that provide case conversion of text.
  113. *
  114. * GLOBAL VARS REFERENCED:
  115. *
  116. * GLOBAL VARS MODIFIED:
  117. *
  118. * NOTES:
  119. *
  120. * SIDE EFFECTS:
  121. *
  122. ***************************************************************************/
  123.  
  124. LONG APIENTRY CONVProc( PVOID pmmioStr,
  125.                         USHORT  usMsg,
  126.                         LONG lParam1,
  127.                         LONG lParam2 )
  128.  
  129. {
  130.    PCONVPROCINFO pInfo;             // Converter I/O Procedure Info Block
  131.    PMMIOINFO pmmioinfo;             // I/O information block
  132.    MMIOINFO mmioinfoSS;             // I/O info block for Storage System
  133.    PMMFORMATINFO pmmformatinfo;     // formatinfo for this ioproc.
  134.    PCONVHEADERINFO pconvHeaderInfo; // pointer to header struct for FFT files.
  135.    PSZ pszFileName;                 // file name passed in from caller
  136.    PSZ pszFormatString;             // format string to return.
  137.    PSZ pszData;
  138.    CHAR szHeaderLength[2];          // storage for header length (USHORT)
  139.    PCHAR pTemp;                     // temp pointer for use in Header manip.
  140.    HFILE hFileHandle;               // file handle created or passed in
  141.    HMMIO hmmioSS;                   // handle for Storage System
  142.    FOURCC fccStorageSystem;         // SS I/O Proc FOURCC
  143.    USHORT usReturnCode;             // return code from mmioClose
  144.    ULONG ulReturnCode;              // return code from mmio API calls
  145.    LONG lReturnCode;                // return code from mmio API calls
  146.    LONG lBytesCopied;               // num of bytes of format string.
  147.    LONG lBytesRead;                 // return from mmioRead
  148.    LONG lBytesWritten;              // return from mmioWrite
  149.    LONG lHeaderLength;              // storage for CONV header length input
  150.    LONG lFilePosition;              // return from mmioSeek
  151.    LONG lSavedFilePosition;         // saved LFP for the file.
  152.    ULONG ulTempFlags;               // temp flags for flags to be removed.
  153.  
  154.    /*
  155.     *  Initalize local file handle and Return Codes.
  156.     */
  157.  
  158.    hFileHandle = 0L;
  159.    ulReturnCode = 0L;
  160.    usReturnCode = 0;
  161.  
  162.    /*
  163.     * Clear the error return before anything happens to insure valid results.
  164.     */
  165.  
  166.    if (pmmioStr)
  167.       {
  168.       pmmioinfo = (PMMIOINFO) pmmioStr;
  169.       pInfo = (PCONVPROCINFO) &pmmioinfo->aulInfo;
  170.       pmmioinfo->ulErrorRet = MMIO_SUCCESS;
  171.       }
  172.    else
  173.       {
  174.       pmmioinfo = NULL;
  175.       pInfo = NULL;
  176.       }
  177.  
  178.    /*
  179.     *  Route the MMIO message to the proper code handler.
  180.     */
  181.  
  182.    switch( usMsg )
  183.       {
  184.       case MMIOM_OPEN:
  185.  
  186.          /*
  187.           * Get the filename from parameter. Then create a File Format header
  188.           * in memory since this message will use this structure.
  189.           */
  190.  
  191.          pszFileName = (CHAR *)lParam1;
  192.          pconvHeaderInfo =
  193.             (PCONVHEADERINFO)HhpAllocBuffer( sizeof(CONVHEADERINFO), 0);
  194.          if (!pconvHeaderInfo)
  195.             {
  196.             return (MMIO_ERROR);
  197.             }
  198.  
  199.          /*
  200.           * If no Storage System I/O proc was determined from mmioOpen,
  201.           * either determine the SS from the name (CREATE case) or
  202.           * search I/O proc list for SS type. If the file is being created
  203.           * and the storage system cannot be determined from the name,
  204.           * default the storage system to DOS.
  205.           */
  206.  
  207.          if (!pmmioinfo->fccChildIOProc)
  208.             {
  209.             /*
  210.              * Since no Storage system has been determined from mmioOpen, we
  211.              * need to determine the Storage system from the filename. If
  212.              * it cannot be determined from the name, since it's a create we
  213.              * will default the storage system to DOS.
  214.              */
  215.  
  216.             if (pmmioinfo->ulFlags & MMIO_CREATE)
  217.                {
  218.                if (mmioDetermineSSIOProc( pszFileName,
  219.                                           pmmioinfo,
  220.                                           &fccStorageSystem,
  221.                                           NULL ))
  222.                   {
  223.                   fccStorageSystem = FOURCC_DOS;
  224.                   }
  225.                }
  226.             else
  227.                {
  228.  
  229.                /*
  230.                 * The file already exists, so we need to determine the storage
  231.                 * system by looping through all the SS I/O procs until the SS
  232.                 * is determined or it is not. If it is not then this file
  233.                 * cannot be opened, so return an error.
  234.                 */
  235.  
  236.                if (mmioIdentifyStorageSystem( pszFileName,
  237.                                               pmmioinfo,
  238.                                               &fccStorageSystem ))
  239.                   {
  240.                   return (MMIO_ERROR);
  241.                   }
  242.                }
  243.  
  244.             /*
  245.              * Now we either have a SS, and if so assign it to the SS I/O
  246.              * proc field of the pmmioinfo sent in, or we don't so return.
  247.              */
  248.  
  249.             if (!fccStorageSystem)
  250.                {
  251.                return (MMIO_ERROR);
  252.                }
  253.             else
  254.                {
  255.                pmmioinfo->fccChildIOProc = fccStorageSystem;
  256.                }
  257.             }
  258.  
  259.          /*
  260.           * We have the Storage System FOURCC so open the SS.
  261.           * To set up the mmioOpen call to the storage system :
  262.           *
  263.           *  1. Initialize the mmioinfo passed in for the Storage System.
  264.           *  2. Set fccIOProc to the Storage System FOURCC.
  265.           *  3. Save the hmmcf handle in aulInfo[1] if sent in.
  266.           *  4. IMPORTANT: Use flags sent in EXCEPT Buffered I/O flags.
  267.           *     VERY IMPORTANT: Set the NOIDENTIFY flag before calling the
  268.           *     mmioOpen below to avoid and endless loop.
  269.           *  5. The open call will handle the DELETE flag.
  270.           *  6. Use the name passed in to this I/O proc for the open because
  271.           *     at this point the SS I/O proc will know how to deal with it.
  272.           */
  273.  
  274.          memset( &mmioinfoSS, '\0', sizeof(MMIOINFO));
  275.          mmioinfoSS.fccIOProc = pmmioinfo->fccChildIOProc;
  276.          memmove( &mmioinfoSS.aulInfo, pmmioinfo->aulInfo,(4*sizeof(ULONG)));
  277.          mmioinfoSS.ulFlags = pmmioinfo->ulFlags;
  278.  
  279.          ulTempFlags = (MMIO_CREATE|MMIO_READ|MMIO_WRITE|MMIO_READWRITE|
  280.                         MMIO_COMPAT|MMIO_EXCLUSIVE|MMIO_DENYWRITE|
  281.                         MMIO_DENYREAD|MMIO_DENYNONE|MMIO_DELETE|MMIO_VERTBAR|
  282.                         MMIO_APPEND|MMIO_USE_TEMP|MMIO_RWMODE|MMIO_SHAREMODE|
  283.                         MMIO_NOTRANSLATE|MMIO_TRANSLATEDATA|
  284.                         MMIO_TRANSLATEHEADER);
  285.  
  286.          mmioinfoSS.ulFlags &= ulTempFlags;
  287.          mmioinfoSS.ulFlags |= MMIO_NOIDENTIFY;
  288.  
  289.          hmmioSS = mmioOpen( pszFileName, &mmioinfoSS, mmioinfoSS.ulFlags );
  290.  
  291.          if (hmmioSS)
  292.             {
  293.             /*
  294.              * Handle a DELETE request for the file format by returning
  295.              * success if ( hmmio = TRUE = 1).
  296.              */
  297.  
  298.             if (pmmioinfo->ulFlags & MMIO_DELETE)
  299.                {
  300.                return (MMIO_SUCCESS);
  301.                }
  302.             pInfo->hmmioSS = hmmioSS;
  303.             }
  304.          else
  305.             {
  306.             return (mmioinfoSS.ulErrorRet);
  307.             }
  308.  
  309.          /*
  310.           * Get the header for the file if it already exists and
  311.           * store it with the MMIOINFO for the file.
  312.           */
  313.  
  314.          if (!(pmmioinfo->ulFlags & MMIO_CREATE))
  315.             {
  316.             /*
  317.              * Seek the file to the beginning to read in the header.
  318.              */
  319.  
  320.             lFilePosition = mmioSeek( hmmioSS,
  321.                                       0L,
  322.                                       SEEK_SET );
  323.  
  324.             if (lFilePosition < 0L)
  325.                {
  326.                mmioClose( hmmioSS, 0L );
  327.                return (MMIO_ERROR);
  328.                }
  329.  
  330.             /*
  331.              * Read the header of the file into the provided buffer for the
  332.              * given length.
  333.              */
  334.  
  335.             lBytesRead = mmioRead( hmmioSS,
  336.                                    (PSZ)pconvHeaderInfo,
  337.                                    sizeof(CONVHEADERINFO) );
  338.  
  339.             if (lBytesRead < 0L)
  340.                {
  341.                mmioClose( hmmioSS, 0L );
  342.                return (MMIO_ERROR);
  343.                }
  344.             }
  345.          else
  346.             {
  347.             /*
  348.              * Make a new header for the file and write it to the beginning.
  349.              */
  350.  
  351.             pconvHeaderInfo->ulHeaderLength = sizeof(CONVHEADERINFO);
  352.             strcpy( pconvHeaderInfo->szHeaderText, HEADER_STRING );
  353.  
  354.             lFilePosition = mmioSeek( hmmioSS,
  355.                                       0L,
  356.                                       SEEK_SET );
  357.  
  358.             if (lFilePosition < 0L)
  359.                {
  360.                mmioClose( hmmioSS, 0L );
  361.                return (MMIO_ERROR);
  362.                }
  363.  
  364.             /*
  365.              * Write the newly created header to the file.
  366.              */
  367.  
  368.             lBytesWritten = mmioWrite( hmmioSS,
  369.                                        (PSZ)pconvHeaderInfo,
  370.                                        sizeof(CONVHEADERINFO) );
  371.  
  372.             if (lBytesWritten < 0L)
  373.                {
  374.                mmioClose( hmmioSS, 0L );
  375.                return (MMIO_ERROR);
  376.                }
  377.             }
  378.  
  379.          pconvHeaderInfo->ulFlags = 0;
  380.          pmmioinfo->pExtraInfoStruct = (PVOID)pconvHeaderInfo;
  381.  
  382.          /*
  383.           * Seek the file past the header to allow reads/writes to occur
  384.           * at the first byte of non-header data if the file already exists.
  385.           */
  386.  
  387.          lReturnCode = mmioSeek( hmmioSS,
  388.                                  sizeof(CONVHEADERINFO),
  389.                                  SEEK_SET );
  390.  
  391.          if (lReturnCode >= 0L)
  392.             {
  393.             pmmioinfo->lLogicalFilePos = lReturnCode;
  394.             }
  395.          else
  396.             {
  397.             mmioClose( hmmioSS, 0L );
  398.             return (lReturnCode);
  399.             }
  400.  
  401.          return (0L);
  402.  
  403.          break;
  404.  
  405.       case MMIOM_READ:
  406.          /*
  407.           * Call the read API with the Storage System handle using the
  408.           * parameters that have been passed in to this I/O proc.
  409.           */
  410.  
  411.          lBytesRead = mmioRead( pInfo->hmmioSS,
  412.                                 (CHAR *) lParam1,
  413.                                 lParam2 );
  414.  
  415.          /*
  416.           *  Check the return code and determine if read was successful.
  417.           *  Read must return:
  418.           *    -1 - an error occurred with mmioRead or somewhere internally.
  419.           *     x - number of bytes actually read by mmioRead.
  420.           */
  421.  
  422.          if ( lBytesRead < 0L )
  423.             {
  424.             return( -1L );
  425.             }
  426.          else
  427.             {
  428.             return( lBytesRead );
  429.             }
  430.  
  431.          break;
  432.  
  433.       case MMIOM_WRITE:
  434.          /*
  435.           * Call the write API with the Storage System handle using the
  436.           * parameters that have been passed in to this I/O proc.
  437.           */
  438.  
  439.          lBytesWritten = mmioWrite( pInfo->hmmioSS,
  440.                                     (CHAR *) lParam1,
  441.                                     lParam2 );
  442.  
  443.          /*
  444.           *  Check the return code and determine if write was successful.
  445.           *  Write must return:
  446.           *    -1 - an error occurred with mmioWrite or somewhere internally.
  447.           *     x - number of bytes actually written by mmioWrite.
  448.           */
  449.  
  450.          if ( lBytesWritten < 0L )
  451.             {
  452.             return( -1L );
  453.             }
  454.          else if ( lBytesWritten != lParam2 )
  455.             {
  456.             pmmioinfo->ulErrorRet = MMIOERR_CANNOTWRITE;
  457.             return( lBytesWritten );
  458.             }
  459.          else
  460.             {
  461.  
  462.             /*
  463.              * Set the Flags field in the CONV header to show it was modified.
  464.              */
  465.  
  466.             pconvHeaderInfo = (PCONVHEADERINFO)pmmioinfo->pExtraInfoStruct;
  467.  
  468.             if (pconvHeaderInfo)
  469.                pconvHeaderInfo->ulFlags = CONV_MODIFIED_FILE;
  470.  
  471.             return( lBytesWritten );
  472.             }
  473.  
  474.          break;
  475.  
  476.       case MMIOM_SEEK:
  477.          /*
  478.           * Call the seek API with the Storage System handle using the
  479.           * parameters that have been passed in to this I/O proc.
  480.           */
  481.  
  482.          lReturnCode = mmioSeek( pInfo->hmmioSS,
  483.                                  lParam1,
  484.                                  lParam2 );
  485.  
  486.          /*
  487.           *  Check the return code and determine if seek was successful.
  488.           *  Seek must return:
  489.           *    -1 - an error occurred with mmioSeek or somewhere internally.
  490.           *     x - new current file postion from the beginning of the file.
  491.           */
  492.  
  493.          if ( lReturnCode < 0L )
  494.             {
  495.             return( -1L );
  496.             }
  497.  
  498.          return( lReturnCode );
  499.  
  500.          break;
  501.  
  502.       case MMIOM_CLOSE:
  503.             /*
  504.              * If the CONV header structure was maintained in pExtraInfoStruct,
  505.              * write it back to the beginning of the file.
  506.              */
  507.  
  508.             if (((pmmioinfo->ulFlags & MMIO_WRITE) ||
  509.                  (pmmioinfo->ulFlags & MMIO_READWRITE)) &&
  510.                  (pmmioinfo->pExtraInfoStruct))
  511.  
  512.                {
  513.                pconvHeaderInfo = (PCONVHEADERINFO)pmmioinfo->pExtraInfoStruct;
  514.  
  515.                lReturnCode = mmioSeek( pInfo->hmmioSS,
  516.                                        0L,
  517.                                        SEEK_SET );
  518.  
  519.                if (lReturnCode < 0L)
  520.                   {
  521.                   return (lReturnCode);
  522.                   }
  523.  
  524.                ulReturnCode = mmioSetHeader( pmmioinfo->hmmio,
  525.                                              (PVOID)pmmioinfo->pExtraInfoStruct,
  526.                                              sizeof(CONVHEADERINFO),
  527.                                              &lBytesWritten,
  528.                                              0L, 0L );
  529.                if (ulReturnCode)
  530.                   {
  531.                   return (ulReturnCode);
  532.                   }
  533.                }
  534.  
  535.             if (pmmioinfo->pExtraInfoStruct)
  536.                HhpFreeBuffer((PBYTE)pmmioinfo->pExtraInfoStruct);
  537.  
  538.             /*
  539.              * Call the close API with the Storage System handle using any
  540.              * parameters that have been passed in to this I/O proc.
  541.              */
  542.  
  543.             usReturnCode = mmioClose( pInfo->hmmioSS, 0L );
  544.             return ((ULONG)usReturnCode);
  545.  
  546.          break;
  547.  
  548.       case MMIOM_IDENTIFYFILE:
  549.          /*
  550.           * Get the filename from parameter. Then create a File Format header
  551.           * in memory since this message use this structure.
  552.           */
  553.  
  554.          pszFileName = (CHAR *)lParam1;  // get the filename from parameter.
  555.  
  556.          pconvHeaderInfo =
  557.             (PCONVHEADERINFO)HhpAllocBuffer( sizeof(CONVHEADERINFO), 0);
  558.  
  559.          if (!pconvHeaderInfo)
  560.             {
  561.             return (MMIO_ERROR);
  562.             }
  563.  
  564.          hmmioSS = (HMMIO)lParam2;       // get the SS handle to the file.
  565.  
  566.          if ( !hmmioSS )
  567.             {
  568.             HhpFreeBuffer((PBYTE)pconvHeaderInfo);
  569.             return (MMIO_ERROR);
  570.             }
  571.          else
  572.             {
  573.  
  574.             /*
  575.              * Seek the file to the beginning to read in the file header.
  576.              */
  577.  
  578.             lFilePosition = mmioSeek( hmmioSS,
  579.                                       0L,
  580.                                       SEEK_SET );
  581.  
  582.             if (lFilePosition < 0L)
  583.                {
  584.                HhpFreeBuffer((PBYTE)pconvHeaderInfo);
  585.                return (MMIO_ERROR);
  586.                }
  587.  
  588.             /*
  589.              * Compare convHeaderInfo.szHeaderText with text string defined
  590.              * in the convproc.h header file.
  591.              */
  592.  
  593.             lBytesRead = mmioRead( hmmioSS,
  594.                                    (PSZ)pconvHeaderInfo,
  595.                                    sizeof(CONVHEADERINFO) );
  596.  
  597.             if ( lBytesRead <= 0L )
  598.                {
  599.                HhpFreeBuffer((PBYTE)pconvHeaderInfo);
  600.                return( -1L );
  601.                }
  602.  
  603.             pTemp = (CHAR *)pconvHeaderInfo;
  604.             pTemp += 2 * sizeof(ULONG);
  605.  
  606.             if (!strncmp( pTemp, HEADER_STRING, strlen(HEADER_STRING) ))
  607.                {
  608.                HhpFreeBuffer((PBYTE)pconvHeaderInfo);
  609.                return( 0L );
  610.                }
  611.             else
  612.                {
  613.                HhpFreeBuffer((PBYTE)pconvHeaderInfo);
  614.                return( -1L );
  615.                }
  616.             }
  617.  
  618.          break;
  619.  
  620.       case MMIOM_GETFORMATINFO:
  621.  
  622.          /*
  623.           * Fill in the mmformatinfo for the CONVProc.
  624.           */
  625.  
  626.          pmmformatinfo = (PMMFORMATINFO)lParam1;
  627.  
  628.          if (pmmformatinfo == NULL)
  629.             {
  630.             return( -1L );
  631.             }
  632.  
  633.          pmmformatinfo->ulStructLen = sizeof(MMFORMATINFO);
  634.          pmmformatinfo->fccIOProc = FOURCC_FFT;
  635.          pmmformatinfo->ulIOProcType = MMIO_IOPROC_FILEFORMAT;
  636.          pmmformatinfo->ulMediaType = MMIO_MEDIATYPE_OTHER;
  637.          pmmformatinfo->ulFlags = MMIO_CANREADUNTRANSLATED      |
  638.                                   MMIO_CANWRITEUNTRANSLATED     |
  639.                                   MMIO_CANREADWRITEUNTRANSLATED |
  640.                                   MMIO_CANSEEKUNTRANSLATED;
  641.  
  642.          memset( pmmformatinfo->szDefaultFormatExt,  '\0',
  643.             sizeof(pmmformatinfo->szDefaultFormatExt)  );
  644.          strcpy( pmmformatinfo->szDefaultFormatExt,  "FFT" );
  645.  
  646.          if (convhlpGetNLSData( &pmmformatinfo->ulCodePage,
  647.                                 &pmmformatinfo->ulLanguage ))
  648.             {
  649.             return( -1L );
  650.             }
  651.  
  652.          if (convhlpGetFormatStringLength( FOURCC_FFT,
  653.                                            &(pmmformatinfo->lNameLength) ))
  654.             {
  655.             return( -1L );
  656.             }
  657.  
  658.          return( 0L );
  659.          break;
  660.  
  661.       case MMIOM_GETFORMATNAME:
  662.  
  663.          /*
  664.           * The string is in a resource file (CONVPROC.RC) for NLS purposes.
  665.           */
  666.  
  667.          pszFormatString = (CHAR *)lParam1;
  668.  
  669.          lBytesCopied = convhlpGetFormatString( FOURCC_FFT,
  670.                                                 pszFormatString,
  671.                                                 lParam2 );
  672.  
  673.          return( lBytesCopied );
  674.          break;
  675.  
  676.       case MMIOM_QUERYHEADERLENGTH:
  677.  
  678.          /*
  679.           * Save current file position for later restore. Then
  680.           * seek the file to the beginning to read in the header.
  681.           */
  682.  
  683.          lSavedFilePosition = pmmioinfo->lLogicalFilePos;
  684.  
  685.          lFilePosition = mmioSeek( pInfo->hmmioSS,
  686.                                    0L,
  687.                                    SEEK_SET );
  688.  
  689.          if (lFilePosition < 0L)
  690.             {
  691.             return (0L);
  692.             }
  693.  
  694.          /*
  695.           * Read in the header length for the file. It is the first 4 bytes.
  696.           */
  697.  
  698.          lBytesRead = mmioRead( pInfo->hmmioSS,
  699.                                 szHeaderLength,
  700.                                 sizeof(ULONG) );
  701.  
  702.          lReturnCode = mmioSeek( pInfo->hmmioSS,
  703.                                  lSavedFilePosition,
  704.                                  SEEK_SET );
  705.  
  706.          if (lReturnCode != lSavedFilePosition)
  707.             {
  708.             return (0L);
  709.             }
  710.  
  711.          if (lBytesRead <= 0L)
  712.             {
  713.             return (0L);
  714.             }
  715.          else
  716.             {
  717.             lHeaderLength = (LONG)(*((LONG *)szHeaderLength));
  718.             return (lHeaderLength);
  719.             }
  720.  
  721.          break;
  722.  
  723.       case MMIOM_GETHEADER:
  724.  
  725.          /*
  726.           * Save current file position for later restore. Then
  727.           * seek the file to the beginning to read in the header.
  728.           */
  729.  
  730.          lSavedFilePosition = pmmioinfo->lLogicalFilePos;
  731.  
  732.          lFilePosition = mmioSeek( pInfo->hmmioSS,
  733.                                    0L,
  734.                                    SEEK_SET );
  735.  
  736.          if (lFilePosition < 0L)
  737.             {
  738.             return (0L);
  739.             }
  740.  
  741.          /*
  742.           * Read the header of the file into the provided buffer for the
  743.           * given length. Then seek the file back to the saved position.
  744.           */
  745.  
  746.          lBytesRead = mmioRead( pInfo->hmmioSS,
  747.                                 (CHAR *)lParam1,
  748.                                 lParam2 );
  749.  
  750.          lReturnCode = mmioSeek( pInfo->hmmioSS,
  751.                                  lSavedFilePosition,
  752.                                  SEEK_SET );
  753.  
  754.          if (lReturnCode != lSavedFilePosition)
  755.             {
  756.             return (0L);
  757.             }
  758.  
  759.          if (lBytesRead <= 0L)
  760.             {
  761.             return (0L);
  762.             }
  763.          else
  764.             {
  765.             return (lBytesRead);
  766.             }
  767.  
  768.          break;
  769.  
  770.       case MMIOM_SETHEADER:
  771.  
  772.          /*
  773.           * Save current file position for later restore. Then
  774.           * seek the file to the beginning to read in the header.
  775.           */
  776.  
  777.          lSavedFilePosition = pmmioinfo->lLogicalFilePos;
  778.  
  779.          lFilePosition = mmioSeek( pInfo->hmmioSS,
  780.                                    0L,
  781.                                    SEEK_SET );
  782.  
  783.          if (lFilePosition < 0L)
  784.             {
  785.             return (0L);
  786.             }
  787.  
  788.          /*
  789.           * Write the entire header to the file. Then seek the file back
  790.           * to the saved file position.
  791.           */
  792.  
  793.          lBytesWritten = mmioWrite( pInfo->hmmioSS,
  794.                                     (CHAR *)lParam1,
  795.                                     lParam2 );
  796.  
  797.          lReturnCode = mmioSeek( pInfo->hmmioSS,
  798.                                  lSavedFilePosition,
  799.                                  SEEK_SET );
  800.  
  801.          if (lReturnCode != lSavedFilePosition)
  802.             {
  803.             return (0L);
  804.             }
  805.  
  806.          if (lBytesWritten <= 0L)
  807.             {
  808.             return (0L);
  809.             }
  810.          else
  811.             {
  812.             return (lBytesWritten);
  813.             }
  814.  
  815.          break;
  816.  
  817.       case CONVM_TOUPPER:
  818.  
  819.          pszData = (CHAR *)lParam1;
  820.          convhlpToUpper( (PUCHAR)pszData );
  821.          return (MMIO_SUCCESS);
  822.  
  823.          break;
  824.  
  825.       case CONVM_TOLOWER:
  826.  
  827.          pszData = (CHAR *)lParam1;
  828.          convhlpToLower( (PUCHAR)pszData );
  829.          return (MMIO_SUCCESS);
  830.  
  831.          break;
  832.  
  833.       default:
  834.  
  835.          /*
  836.           * If an IO Proc has a child IO Proc, then instead of
  837.           * returning UNSUPPORTED_MESSAGE, send the message to
  838.           * the child IO Proc to see if it can understand and
  839.           * process the message.
  840.           *
  841.           * Since message is unexpected, need to check for valid
  842.           * pointers.
  843.           */
  844.  
  845.          if (pInfo)
  846.             {
  847.             if (pInfo->hmmioSS)
  848.                {
  849.                lReturnCode = ( mmioSendMessage( pInfo->hmmioSS,
  850.                                                 usMsg,
  851.                                                 lParam1,
  852.                                                 lParam2 ));
  853.            
  854.                if (!lReturnCode)
  855.                    pmmioinfo->ulErrorRet = mmioGetLastError(pInfo->hmmioSS);
  856.                return (lReturnCode);
  857.                }
  858.             }
  859.           else
  860.             {
  861.             if (pmmioinfo)
  862.                 pmmioinfo->ulErrorRet = MMIOERR_UNSUPPORTED_MESSAGE;
  863.             }
  864.  
  865.           return (MMIOERR_UNSUPPORTED_MESSAGE);
  866.  
  867.       }
  868.  
  869. }
  870.