home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional Developers Kit 1992 November / Disc01 / Disc01.mdf / mmpm2tk / mmpmtlk2 / admct / admcload.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-06  |  36.4 KB  |  1,127 lines

  1. /*static char *SCCSID = "@(#)admcload.c    13.17 92/05/01";*/
  2. /********************* START OF SPECIFICATIONS *********************
  3. *
  4. * SUBROUTINE NAME: MCILOAD.C
  5. *
  6. * DESCRIPTIVE NAME: Audio MCD Load Element Routine.
  7. *
  8. * FUNCTION:Load an Waveform Element.
  9. *
  10. * NOTES:
  11. *
  12. * ENTRY POINTS:
  13. *     LINKAGE:   CALL FAR
  14. *
  15. * INPUT: MCI_PLAY message.
  16. *
  17. * EXIT-NORMAL: Return Code 0.
  18. *
  19. * EXIT_ERROR:  Error Code.
  20. *
  21. * EFFECTS:
  22. *
  23. * INTERNAL REFERENCES:    CreateNAssocStream ().
  24. *                         DestroyStream().
  25. *                         SetAudioDevice().
  26. *                         VSDInstToWaveSetParms().
  27. *                         PostMDMMessage ().
  28. *                         OpenFile().
  29. *
  30. * EXTERNAL REFERENCES:    SpiStopStream  ().
  31. *                         SpiAssociate   ().
  32. *                         SpiDisableEvent().
  33. *                         SpiSeekStream  ().
  34. *                         mmioSendMessage().
  35. *                         mmioClose ().
  36. *
  37. *********************** END OF SPECIFICATIONS **********************/
  38. #define INCL_BASE
  39. #define INCL_DOSMODULEMGR
  40. #define INCL_DOSSEMAPHORES
  41.  
  42. #include <os2.h>
  43. #include <string.h>
  44. #include <os2medef.h>                   // MME includes files.
  45. #include <audio.h>                      // Audio Device defines
  46. #include <ssm.h>                        // SSM spi includes.
  47. #include <meerror.h>                    // MM Error Messages.
  48. #include <mmsystem.h>                   // MM System Include.
  49. #include <mcidrv.h>                     // Mci Driver Include.
  50. #include <mmio.h>                       // MMIO Include.
  51. #include <mcd.h>                        // VSDIDriverInterface.
  52. #include <hhpheap.h>                    // Heap Manager Definitions
  53. #include <audiomcd.h>                   // Component Definitions.
  54. #include "admcfunc.h"                   // Function Prototypes
  55.  
  56. /********************* START OF SPECIFICATIONS *********************
  57. *
  58. * SUBROUTINE NAME: MCILOAD.C
  59. *
  60. * DESCRIPTIVE NAME: Audio MCD Load Element Routine.
  61. *
  62. * FUNCTION:Load an Waveform Element.
  63. *
  64. * NOTES:
  65. *
  66. * ENTRY POINTS:
  67. *     LINKAGE:   CALL FAR
  68. *
  69. * INPUT: MCI_PLAY message.
  70. *
  71. * EXIT-NORMAL: Return Code 0.
  72. *
  73. * EXIT_ERROR:  Error Code.
  74. *
  75. * EFFECTS:
  76. *
  77. * INTERNAL REFERENCES:DestroyStream(), ReadRIFFWaveHeaderInfo()
  78. *                     SetAmpDefaults(), SetWaveDeviceDefaults().
  79. *                     SetAudioDevice().
  80. *
  81. * EXTERNAL REFERENCES:
  82. *
  83. *********************** END OF SPECIFICATIONS **********************/
  84.  
  85.  
  86. RC MCILoad ( FUNCTION_PARM_BLOCK *pFuncBlock)
  87. {
  88.  
  89.   ULONG                ulPathLength;        // length of path that we generated
  90.  
  91.   LONG                 lReturnCode;         // return code for mmio functions
  92.  
  93.   ULONG                ulrc;                // MME Propogated Error RC
  94.   ULONG                ulParam1;            // Incoming MCI Flags
  95.   ULONG                lCnt;                // Semaphore Posting Freq
  96.   ULONG                ulErr1;              // Internal Error Conditions
  97.   ULONG                ulAbortNotify = FALSE;// indicates whether to abort a previous
  98.                                             // operation
  99.   DWORD                dwLoadFlags;         // Incoming Flags Mask
  100.   DWORD                dwSpiFlags;
  101.   DWORD                dwSetAll;            //  Reinit AudioIF
  102.  
  103.   USHORT               usEvcbIndex;         // Evcb Counter
  104.  
  105.   INSTANCE *           ulpInstance;         // Local Instance//
  106.  
  107.   LPMCI_LOAD_PARMS     lpLoadParms;         // App MCI Data Struct
  108.   MCI_WAVE_SET_PARMS   SetParms;            // App MCI Data Struct
  109.  
  110.   PBYTE                pDBCSName;           // pointer to the name of the file
  111.  
  112.   extern HHUGEHEAP     heap;                // Global MCD Heap
  113.   CHAR                 TempPath[ CCHMAXPATH ]; // holds path for temp files
  114.  
  115.   /*********************************
  116.   * Intialize Variables
  117.   **********************************/
  118.   ulrc = MCIERR_SUCCESS;
  119.   ulErr1 = MCIERR_SUCCESS;
  120.   dwLoadFlags = 0;
  121.   /**************************************
  122.   * Dereference Pointers
  123.   **************************************/
  124.   ulpInstance = (INSTANCE *)pFuncBlock->ulpInstance;
  125.   ulParam1 = pFuncBlock->ulParam1;
  126.   ulParam1 &= ~MCI_OPEN_ELEMENT;
  127.   dwLoadFlags = ulParam1;
  128.   /**************************************
  129.   * Mask UnWanted Bits
  130.   **************************************/
  131.   dwLoadFlags &= ~MCI_NOTIFY;
  132.   dwLoadFlags &= ~MCI_WAIT;
  133.   dwLoadFlags &= ~MCI_OPEN_MMIO;
  134.   dwLoadFlags &= ~MCI_READONLY;
  135.   dwLoadFlags &= ~MCI_OPEN_ELEMENT;
  136.  
  137.   dwSetAll = MCI_WAVE_SET_BITSPERSAMPLE|MCI_WAVE_SET_FORMATTAG|
  138.              MCI_WAVE_SET_CHANNELS | MCI_WAVE_SET_SAMPLESPERSEC;
  139.  
  140.  
  141.   if (dwLoadFlags > 0 )
  142.      {
  143.  
  144.      if ( ulParam1 & MCI_OPEN_PLAYLIST)
  145.         {
  146.         return MCIERR_UNSUPPORTED_FLAG;
  147.         }
  148.  
  149.      return MCIERR_INVALID_FLAG;
  150.      }
  151.  
  152.   /****************************************
  153.   * Check For Valid Parameters
  154.   ****************************************/
  155.   ulrc = CheckMem ((PVOID)pFuncBlock->ulParam2,
  156.                    sizeof (MCI_LOAD_PARMS), PAG_READ);
  157.  
  158.   if (ulrc != MCIERR_SUCCESS)
  159.           return MCIERR_MISSING_PARAMETER;
  160.  
  161.   /***************************************
  162.   * Initialize values
  163.   ****************************************/
  164.  
  165.   ulpInstance->ulCanSave   = TRUE;
  166.   ulpInstance->ulCanInsert = TRUE;
  167.   ulpInstance->ulCanRecord = TRUE;
  168.  
  169.   lpLoadParms = (LPMCI_LOAD_PARMS)pFuncBlock->ulParam2;
  170.  
  171.   DosRequestMutexSem( ulpInstance->hmtxNotifyAccess, -1 );
  172.   if (ulpInstance->usNotifyPending == TRUE)
  173.      {
  174.      ulpInstance->ulNotifyAborted = TRUE;
  175.      ulpInstance->usNotifyPending = FALSE;
  176.      ulAbortNotify = TRUE;
  177.      }
  178.   DosReleaseMutexSem( ulpInstance->hmtxNotifyAccess );
  179.  
  180.   if ( ulAbortNotify == TRUE)
  181.      {
  182.  
  183.      // if there is a save pending, wait for it to complete
  184.  
  185.      if ( ulpInstance->usNotPendingMsg == MCI_SAVE )
  186.         {
  187.         // Save is a non-interruptible operation
  188.         // wait for completion
  189.  
  190.         DosWaitEventSem( ulpInstance->hThreadSem, (ULONG ) -1 );
  191.  
  192.         }
  193.       else
  194.         {
  195.         /****************************
  196.         * Post Aborted Message
  197.         *****************************/
  198.         PostMDMMessage ( MCI_NOTIFY_ABORTED,
  199.                          ulpInstance->usNotPendingMsg,
  200.                          pFuncBlock);
  201.  
  202.         /***************************************
  203.         * Reset Internal semaphores
  204.         ****************************************/
  205.         DosResetEventSem (ulpInstance->hEventSem, &lCnt);
  206.         DosResetEventSem (ulpInstance->hThreadSem, &lCnt);
  207.  
  208.         /**********************************
  209.         * Stop Streaming
  210.         **********************************/
  211.         ulrc = SpiStopStream (STREAM.hStream, SPI_STOP_DISCARD);
  212.  
  213.         if (!ulrc)
  214.           {
  215.           DosWaitEventSem (ulpInstance->hThreadSem, (ULONG) -1 );
  216.           }
  217.  
  218.  
  219.         STRMSTATE = MCI_STOP;
  220.  
  221.         } /* if pending message not save */
  222.  
  223.  
  224.      } /* notify pending is true */
  225.  
  226.   else
  227.  
  228.      {
  229.      // stop may have done a stop pause, so ensure that another stop is done
  230.  
  231.      if ( STRMSTATE == STOP_PAUSED )
  232.         {
  233.  
  234.         /***************************************
  235.         * Reset Internal semaphores
  236.         ****************************************/
  237.         DosResetEventSem (ulpInstance->hEventSem, &lCnt);
  238.         DosResetEventSem (ulpInstance->hThreadSem, &lCnt);
  239.  
  240.         if ( AMPMIX.ulOperation == OPERATION_RECORD )
  241.            {
  242.            dwSpiFlags = SPI_STOP_FLUSH;
  243.            }
  244.         else
  245.            {
  246.            dwSpiFlags = SPI_STOP_DISCARD;
  247.            }
  248.  
  249.         /**********************************
  250.         * Stop Streaming
  251.         **********************************/
  252.         ulrc = SpiStopStream (STREAM.hStream, dwSpiFlags );
  253.         if (!ulrc)
  254.            DosWaitEventSem (ulpInstance->hEventSem, (ULONG) -1 );
  255.         }
  256.  
  257.      }
  258.  
  259.   ulpInstance->ulOldStreamPos  = 0;
  260.  
  261.   /********************************************
  262.   * Discard CuePoints since Element Changed
  263.   ********************************************/
  264.   if ((ulpInstance->usCuePt == TRUE) || (ulpInstance->usCuePt == EVENT_ENABLED)) {
  265.      for (usEvcbIndex = 0; usEvcbIndex < STREAM.usCuePtIndex; usEvcbIndex++) {
  266.           STREAM.MCuePtEvcb[usEvcbIndex].mmCuePt = 0;
  267.           if (ulpInstance->ulCreateFlag == PREROLL_STATE)
  268.               SpiDisableEvent (STREAM.HCuePtHndl[usEvcbIndex]);
  269.  
  270.      }
  271.      ulpInstance->usCuePt = FALSE;
  272.  
  273.      /***************************
  274.      * Reset CuePt Index to 0
  275.      ***************************/
  276.      STREAM.usCuePtIndex = 0;
  277.   } /* There Were CuePoints */
  278.  
  279.   /*******************************************/
  280.   // Disable Position Advise
  281.   /*******************************************/
  282.  
  283.   if ((ulpInstance->usPosAdvise == TRUE) || (ulpInstance->usPosAdvise == EVENT_ENABLED)) {
  284.       if (ulpInstance->ulCreateFlag == PREROLL_STATE)
  285.  
  286.           SpiDisableEvent (STREAM.hPosEvent);
  287.  
  288.       ulpInstance->usPosAdvise = FALSE;
  289.   }
  290.  
  291.  
  292.  
  293.   /*****************************
  294.   * Close Previous Element
  295.   *****************************/
  296.   if (ulpInstance->hmmio != (ULONG)NULL) {
  297.  
  298.       ulrc = mmioClose (ulpInstance->hmmio, 0);
  299.  
  300.       if ( ulpInstance->ulCreatedName )
  301.          {
  302.          DosDelete( ( PSZ ) ulpInstance->lpstrAudioFile );
  303.          }
  304.  
  305.       ulpInstance->ulCreatedName = FALSE;
  306.  
  307.       ulpInstance->hmmio = (ULONG)NULL;
  308.  
  309.   } /* hmmio not Null */
  310.  
  311.  
  312.   /***************************************
  313.   * Check for valid element names
  314.   ****************************************/
  315.  
  316.   if ( !( ulParam1 & MCI_OPEN_MMIO )  )
  317.      {
  318.      if ( lpLoadParms->lpstrElementName )
  319.         {
  320.         if (ulrc = CheckMem ( (PVOID)lpLoadParms->lpstrElementName,
  321.                               1, PAG_WRITE))
  322.            {
  323.            return MCIERR_MISSING_PARAMETER;
  324.            }
  325.         ulpInstance->ulCreatedName = FALSE;
  326.         }
  327.       else
  328.         {
  329.         /**************************************
  330.         * if the user requests a read only file
  331.         * and we must create it, return error
  332.         **************************************/
  333.  
  334.         if ( ulParam1 & MCI_READONLY )
  335.            {
  336.            return MCIERR_FILE_NOT_FOUND;
  337.            }
  338.  
  339.         if (!( pDBCSName = HhpAllocMem (heap, CCHMAXPATH )))
  340.            {
  341.            return MCIERR_OUT_OF_MEMORY;
  342.            }
  343.  
  344.         /**********************************************
  345.         * Query the default path to place temp files and
  346.         * generate a temporary file name
  347.         **********************************************/
  348.  
  349.         ulrc = mciQuerySysValue( MSV_WORKPATH, pDBCSName );
  350.  
  351.         if ( !ulrc )
  352.            {
  353.            return MCIERR_INI_FILE;
  354.            }
  355.  
  356.         ulPathLength = CCHMAXPATH;
  357.  
  358.         lReturnCode = GenerateUniqueFile( pDBCSName,
  359.                                           &ulPathLength,
  360.                                           &ulpInstance->hTempFile );
  361.  
  362.         if ( lReturnCode != MMIO_SUCCESS )
  363.            {
  364.            return MCIERR_FILE_NOT_FOUND;
  365.            }
  366.  
  367.         ulpInstance->ulCreatedName = TRUE;
  368.  
  369.  
  370.         } /* else the user did not pass in a name */
  371.  
  372.      } /* if the open mmio flag was not passed in */
  373.  
  374.  
  375.   /*************************************************************
  376.   * Destroy Previous Stream. (can be modified to just re assoc)
  377.   *************************************************************/
  378.   if (ulpInstance->ulCreateFlag == PREROLL_STATE)
  379.      {
  380.  
  381.      /************************************
  382.      * Destroy The Stream
  383.      *************************************/
  384.      DestroyStream (STREAM.hStream);
  385.  
  386.      /*************************************
  387.      * Set Stream Creation Flag
  388.      **************************************/
  389.  
  390.      ulpInstance->ulCreateFlag = CREATE_STATE;
  391.      }  /* PreRoll State */
  392.  
  393.   /******************************************************
  394.   * If hmmio is passed in just update instance copy of
  395.   * hmmio, reset filexists flag and return success
  396.   *****************************************************/
  397.   if (ulParam1 & MCI_OPEN_MMIO) {
  398.       ulpInstance->hmmio = (HMMIO)lpLoadParms->lpstrElementName;
  399.       ulpInstance->mmioHndlPrvd = TRUE;
  400.       ulpInstance->dwmmioOpenFlag = MMIO_READWRITE | MMIO_EXCLUSIVE;
  401.  
  402.       ulrc = OpenFile (ulpInstance, ulpInstance->dwmmioOpenFlag);
  403.       if (ulrc)
  404.           return (ulrc);
  405.  
  406.       ulrc = InitAudioDevice (ulpInstance, OPERATION_PLAY);
  407.       if (ulrc)
  408.           return ulrc;
  409.  
  410.       ulpInstance->usFileExists = TRUE;
  411.       /*******************************************
  412.       * Copy audio device attributes into MCI
  413.       * Wave Set structure
  414.       ********************************************/
  415.       VSDInstToWaveSetParms ( &SetParms, ulpInstance);
  416.  
  417.       /**********************************************
  418.       * Set the Audio device attributes.
  419.       * dwSetAll is a flag set to waveaudio extensions
  420.       *************************************************/
  421.       ulrc = SetAudioDevice (ulpInstance, &SetParms, dwSetAll);
  422.  
  423.       if (ulrc)
  424.            return (ulrc);
  425.  
  426.   }
  427.  
  428.   /***********************************
  429.   * Temporary File creation Flags
  430.   ************************************/
  431.  
  432.   if ( (ulParam1 & MCI_READONLY) || !ulpInstance->ulCanSave )
  433.      {
  434.      ulpInstance->ulOpenTemp = MCI_FALSE;
  435.      }
  436.   else
  437.      {
  438.      ulpInstance->ulOpenTemp = MCI_TRUE;
  439.      }
  440.  
  441.   ulpInstance->ulUsingTemp = MCI_FALSE;
  442.  
  443.  
  444.   if ( !( ulParam1 & MCI_OPEN_MMIO ) )
  445.  
  446.       {
  447.        /********************************************
  448.        *  Flag Media Present  as true
  449.        **********************************************/
  450.        ulpInstance->usMediaPresent = MCI_TRUE;
  451.  
  452.        /********************************************
  453.        *  Copy the file to load, and check to see if
  454.        *  we should copy the name passed in or copy
  455.        *  the one the one we generated if the name
  456.        *  was null
  457.        **********************************************/
  458.  
  459.        if ( lpLoadParms->lpstrElementName )
  460.           {
  461.           strcpy ( (PSZ)ulpInstance->lpstrAudioFile,
  462.                    (PSZ)lpLoadParms->lpstrElementName);
  463.           }
  464.        else
  465.           {
  466.           strcpy ( (PSZ)ulpInstance->lpstrAudioFile,
  467.                    pDBCSName );
  468.  
  469.           }
  470.        /***********************************************
  471.        * Find out if the File Exists.
  472.        ***************************************************/
  473.        ulpInstance->dwmmioOpenFlag = MMIO_READ | MMIO_DENYNONE;
  474.  
  475.         /******************************************************
  476.         * If the user wants to open temp, then modify the flags
  477.         ******************************************************/
  478.         if ( ulpInstance->ulOpenTemp )
  479.            {
  480.            ulpInstance->dwmmioOpenFlag |= MMIO_READWRITE | MMIO_EXCLUSIVE;
  481.            ulpInstance->dwmmioOpenFlag &= ~MMIO_DENYNONE;
  482.            ulpInstance->dwmmioOpenFlag &= ~MMIO_READ;
  483.            }
  484.  
  485.  
  486.        ulrc = OpenFile( ulpInstance, ulpInstance->dwmmioOpenFlag );
  487.  
  488.  
  489.        if ( !ulrc )
  490.          {
  491.          if ( ulpInstance->ulCreatedName )
  492.             {
  493.             AMPMIX.ulOperation = OPERATION_RECORD;
  494.             }
  495.          else
  496.             {
  497.             AMPMIX.ulOperation = OPERATION_PLAY;
  498.             }
  499.  
  500.          ulpInstance->usFileExists = TRUE;
  501.          }
  502.        else
  503.          {
  504.          if (ulrc == ERROR_FILE_NOT_FOUND)
  505.             {
  506.             /********************************
  507.             * if this is a read only file then
  508.             * we cannot create a new one
  509.             *********************************/
  510.  
  511.             if ( ulParam1 & MCI_READONLY )
  512.                {
  513.                ulpInstance->usFileExists = FALSE;
  514.                return MCIERR_FILE_NOT_FOUND;
  515.                }
  516.  
  517.             AMPMIX.ulOperation = OPERATION_RECORD;
  518.             ulpInstance->ulCreateFlag = CREATE_STATE;
  519.             ulrc = MCIERR_SUCCESS;
  520.             ulpInstance->dwmmioOpenFlag = MMIO_CREATE | MMIO_READWRITE | MMIO_EXCLUSIVE;
  521.  
  522.             /********************************
  523.             * Open The Element
  524.             *******************************/
  525.  
  526.             ulrc = OpenFile ( ulpInstance,
  527.                               ulpInstance->dwmmioOpenFlag);
  528.  
  529.             if (ulrc)
  530.                {
  531.                ulpInstance->usFileExists = FALSE;
  532.  
  533.                if ( ulrc == ERROR_FILE_NOT_FOUND )
  534.                   {
  535.                   return MCIERR_FILE_NOT_FOUND;
  536.                   }
  537.                else
  538.                   {
  539.                   return (ulrc);
  540.                   }
  541.                } /* if an error occurred */
  542.  
  543.  
  544.  
  545.             ulpInstance->usFileExists = TRUE;
  546.             SetWaveDeviceDefaults (ulpInstance, OPERATION_RECORD);
  547.             ulrc = MCIERR_SUCCESS;
  548.  
  549.             }
  550.          else
  551.             {
  552.             ulpInstance->usFileExists = FALSE;
  553.  
  554.             // copy back the name we had before
  555.  
  556.  
  557.             return (ulrc);
  558.             }
  559.  
  560.          } /* else there was an error on the load open */
  561.  
  562.       // ensure that the mode and other actions are set
  563.  
  564.       /*************************************
  565.       * Since we did not create the file
  566.       *  the open file routines are not smart
  567.       * enough to figure out how to set the
  568.       * defaults
  569.       *************************************/
  570.       if ( ulpInstance->ulCreatedName )
  571.          {
  572.          AMPMIX.sChannels =    NOT_INTIALIZED;
  573.          AMPMIX.sMode =        NOT_INTIALIZED;
  574.          AMPMIX.lSRate =       NOT_INTIALIZED;
  575.          AMPMIX.lBitsPerSRate = 0;
  576.  
  577.          ulpInstance->ulAverageBytesPerSec = NOT_INTIALIZED;
  578.          }
  579.  
  580.       ulrc = InitAudioDevice (ulpInstance, AMPMIX.ulOperation );
  581.       if (ulrc)
  582.           return ulrc;
  583.  
  584.        VSDInstToWaveSetParms ( &SetParms, ulpInstance);
  585.  
  586.        ulrc = SetAudioDevice (ulpInstance, &SetParms, dwSetAll);
  587.  
  588.        if (ulrc)
  589.            return (ulrc);
  590.  
  591.        }       /* Element Specified on Load */
  592.  
  593.  
  594.   /***********************************************************
  595.   * perform this after the open because open file will modify
  596.   * the state of the following flags
  597.   ***********************************************************/
  598.  
  599.   if ( ulParam1 & MCI_READONLY )
  600.      {
  601.      ulpInstance->ulCanSave = MCI_FALSE;
  602.      ulpInstance->ulCanRecord = MCI_FALSE;
  603.      }
  604.  
  605.  
  606.   /*****************************************************
  607.   * Currently return true if a playlst strm was created
  608.   *****************************************************/
  609.   if (ulpInstance->usPlayLstStrm == TRUE) {
  610.       if (ulrc = SpiGetHandler((PSZ)"FSSH", &(STREAM.hidASource),
  611.                                &(STREAM.hidATarget)))
  612.           return ulrc;
  613.  
  614.       ulpInstance->usPlayLstStrm = FALSE;
  615.  
  616.   }  /* Trash the old Stream Handler Handles */
  617.  
  618.   /*************************************************
  619.   * Reassociate The Stream Handlers with the new
  620.   * stream object
  621.   *************************************************/
  622.   if (ulpInstance->ulCreateFlag == PREROLL_STATE) {
  623.  
  624.       /*********************************************
  625.       * Fill in Associate Control Block Info
  626.       *********************************************/
  627.       STREAM.acbmmio.ulObjType = ACBTYPE_MMIO;
  628.       STREAM.acbmmio.ulACBLen = sizeof (ACB_MMIO);
  629.       STREAM.acbmmio.hmmio = ulpInstance->hmmio;
  630.  
  631.       /***********************************************
  632.       * Associate FileSystem as source if Playing
  633.       ***********************************************/
  634.       if (AMPMIX.ulOperation == OPERATION_PLAY)
  635.          {
  636.          if (ulrc = SpiAssociate ((HSTREAM)STREAM.hStream,
  637.                                    STREAM.hidASource,
  638.                                    (PVOID) &(STREAM.acbmmio)))
  639.               return ulrc;
  640.       /******************************************************************
  641.       * We need to seek to 0 to reset the target stream handlers position
  642.       *******************************************************************/
  643.          ulrc = ( STREAM.hStream,
  644.                                 SPI_SEEK_ABSOLUTE,
  645.                                 0L );
  646.          if (ulrc)
  647.             return (ulrc);
  648.  
  649.  
  650.          }
  651.  
  652.       /***********************************************
  653.       * Associate FileSystem as Target if Recording
  654.       ***********************************************/
  655.       if (AMPMIX.ulOperation == OPERATION_RECORD) {
  656.           if (ulrc = SpiAssociate ((HSTREAM)STREAM.hStream,
  657.                                    STREAM.hidATarget,
  658.                                    (PVOID) &(STREAM.acbmmio)))
  659.             return ulrc;
  660.       } /* Record */
  661.   } /* Preoll State Flag */
  662.  
  663.   // ulpInstance->usFileExists = TRUE;
  664.  
  665.   /**********************************************
  666.   * If the temp flag has sent, open the temp file
  667.   **********************************************/
  668.  
  669.   if ( ulpInstance->ulOpenTemp )
  670.     {
  671.  
  672.     /**********************************************
  673.     * Query the default path to place temp files and
  674.     * pass it on to the IO Proc
  675.     **********************************************/
  676.  
  677.     ulrc = mciQuerySysValue( MSV_WORKPATH, TempPath );
  678.  
  679.     if ( !ulrc )
  680.        {
  681.        return MCIERR_INI_FILE;
  682.        }
  683.  
  684.     ulrc = mmioSendMessage( ulpInstance->hmmio,
  685.                             MMIOM_TEMPCHANGE,
  686.                             ( LONG ) TempPath,
  687.                             0 );
  688.     if ( ulrc )
  689.       {
  690.       ulrc = mmioGetLastError( ulpInstance->hmmio );
  691.       if ( ulrc == MMIOERR_CANNOTWRITE )
  692.          {
  693.  
  694.          mmioClose( ulpInstance->hmmio, 0 );
  695.          ulpInstance->usFileExists = FALSE;
  696.  
  697.          return MCIERR_TARGET_DEVICE_FULL;
  698.          }
  699.       else
  700.          {
  701.          return ulrc;
  702.          }
  703.       }
  704.     ulpInstance->ulUsingTemp = MCI_TRUE;
  705.  
  706.     } /* if ulOpenTemp */
  707.  
  708.  
  709.   STRMSTATE = MCI_STOP;
  710.  
  711.   return (ULONG)(ulrc);
  712.  
  713. }
  714.  
  715.  
  716. /********************* START OF SPECIFICATIONS *********************
  717. *
  718. * SUBROUTINE NAME: MCICNCT.c
  719. *
  720. * DESCRIPTIVE NAME: Audio MCD Connections.
  721. *
  722. * FUNCTION:Process Connector Message.
  723. *
  724. * NOTES:
  725. *
  726. * ENTRY POINTS:
  727. *     LINKAGE:   CALL FAR
  728. *
  729. * INPUT: MCI_PLAY message.
  730. *
  731. * EXIT-NORMAL: Return Code 0.
  732. *
  733. * EXIT_ERROR:  Error Code.
  734. *
  735. * EFFECTS:
  736. *
  737. * INTERNAL REFERENCES:
  738. *                     DestroyStream(),
  739. *                     SetAmpDefaults(),
  740. *                     SetWaveDeviceDefaults().
  741. *
  742. * EXTERNAL REFERENCES:
  743. *
  744. *********************** END OF SPECIFICATIONS **********************/
  745. RC MCICnct ( FUNCTION_PARM_BLOCK *pFuncBlock)
  746. {
  747.    ULONG            ulrc;              // RC
  748.    ULONG            ulParam1;          // Incoming MCI Flags
  749.    ULONG            ulConnectorType;   // Struct to hold connector flag
  750.    ULONG            ulHoldConFlag;     // flag to hold enable/disable etc.
  751.    ULONG            ulFlagCount;
  752.    INSTANCE *       ulpInstance;        // Local Instance
  753.  
  754.    LPMCI_CONNECTOR_PARMS lpConParms;   // MCI Msg Data
  755.  
  756.    ulrc = MCIERR_SUCCESS;
  757.    ulpInstance = (INSTANCE *)pFuncBlock->ulpInstance;
  758.    ulParam1 = pFuncBlock->ulParam1;
  759.  
  760.    lpConParms = (LPMCI_CONNECTOR_PARMS)pFuncBlock->ulParam2;
  761.  
  762.  
  763.    /****************************************
  764.    * Check For Valid Parameters
  765.    *****************************************/
  766.  
  767.    ulrc = CheckMem ( (PVOID) lpConParms,
  768.                      sizeof (MCI_CONNECTOR_PARMS),
  769.                      PAG_READ);
  770.  
  771.    if ( ulrc != MCIERR_SUCCESS )
  772.      {
  773.      return MCIERR_MISSING_PARAMETER;
  774.      }
  775.  
  776.    if ( ( ulParam1 & MCI_NOTIFY ) && ( ulParam1 & MCI_WAIT ) )
  777.       {
  778.       return MCIERR_INVALID_FLAG;
  779.       }
  780.  
  781.    /****************************************
  782.    * Remember if we have to notify
  783.    *****************************************/
  784.    ulParam1 &= ~( MCI_NOTIFY + MCI_WAIT );
  785.  
  786.    /****************************************
  787.    * Ensure a command flag was sent
  788.    *****************************************/
  789.  
  790.    if ( !ulParam1 )
  791.      {
  792.      return MCIERR_MISSING_FLAG;
  793.      }
  794.  
  795.    ulConnectorType = ( ulParam1 & MCI_CONNECTOR_TYPE ) ? 1 : 0;
  796.  
  797.    ulHoldConFlag = ulParam1 & ~( MCI_CONNECTOR_TYPE| MCI_CONNECTOR_INDEX);
  798.  
  799.    ulFlagCount = ( ulParam1 & MCI_ENABLE_CONNECTOR ) ? 1 : 0;
  800.    ulFlagCount += ( ulParam1 & MCI_DISABLE_CONNECTOR ) ? 1 : 0;
  801.    ulFlagCount += ( ulParam1 & MCI_QUERY_CONNECTOR_STATUS ) ? 1 : 0;
  802.  
  803.    if ( ulFlagCount > 1 )
  804.       return MCIERR_FLAGS_NOT_COMPATIBLE;
  805.  
  806.    // if they want to set a type
  807.  
  808.    if ( ulConnectorType )
  809.          {
  810.          if ( ulParam1 & MCI_CONNECTOR_INDEX && ( lpConParms->dwConnectorIndex != 1) )
  811.               {
  812.               if ( lpConParms->dwConnectorType != MCI_SPEAKERS_CONNECTOR )
  813.                  {
  814.                  return MCIERR_INVALID_CONNECTOR_INDEX;
  815.                 }
  816.                else
  817.                  {
  818.                  if ( lpConParms->dwConnectorIndex != 2 )
  819.                     {
  820.                     return MCIERR_INVALID_CONNECTOR_INDEX;
  821.                     }
  822.                  }
  823.               }
  824.  
  825.           if ( ulHoldConFlag & ~( MCI_ENABLE_CONNECTOR  |
  826.                                   MCI_DISABLE_CONNECTOR |
  827.                                   MCI_QUERY_CONNECTOR_STATUS ) )
  828.              {
  829.              return MCIERR_INVALID_FLAG;
  830.              }
  831.          switch( ulHoldConFlag )
  832.                  {
  833.                  /*-------------------------------------------------------------*
  834.                  * Enable connector
  835.                  *-------------------------------------------------------------*/
  836.  
  837.                  case MCI_ENABLE_CONNECTOR:
  838.                        if ( ulConnectorType )
  839.                          {
  840.                          switch( lpConParms->dwConnectorType )
  841.                                  {
  842.                                  // since we know that we are connected to an amp/mixer
  843.                                  // we can pass the command on
  844.  
  845.                                  case MCI_LINE_IN_CONNECTOR:
  846.                                  case MCI_AUDIO_IN_CONNECTOR   :
  847.                                  case MCI_MICROPHONE_CONNECTOR:
  848.                                  case MCI_LINE_OUT_CONNECTOR:
  849.                                  case MCI_AUDIO_OUT_CONNECTOR  :
  850.                                  case MCI_SPEAKERS_CONNECTOR:
  851.                                  case MCI_HEADPHONES_CONNECTOR:
  852.  
  853.                                     ulrc = mciSendCommand ( ulpInstance->wAmpDeviceID,
  854.                                                            (USHORT) MCI_CONNECTOR,
  855.                                                            ulParam1,
  856.                                                            (DWORD) lpConParms,
  857.                                                            pFuncBlock->usUserParm );
  858.                                     break;
  859.                                  case MCI_WAVE_STREAM_CONNECTOR:
  860.  
  861.                                     ulrc = MCIERR_CANNOT_MODIFY_CONNECTOR;
  862.                                     break;
  863.                                  case MCI_MIDI_STREAM_CONNECTOR:
  864.                                  case MCI_AMP_STREAM_CONNECTOR:
  865.                                  case MCI_CD_STREAM_CONNECTOR  :
  866.                                  case MCI_VIDEO_IN_CONNECTOR   :
  867.                                  case MCI_VIDEO_OUT_CONNECTOR  :
  868.                                  case MCI_PHONE_SET_CONNECTOR  :
  869.                                  case MCI_PHONE_LINE_CONNECTOR :
  870.                                  case MCI_UNIVERSAL_CONNECTOR  :
  871.  
  872.                                     ulrc = MCIERR_UNSUPPORTED_CONN_TYPE;
  873.                                     break;
  874.                                  default:
  875.                                          ulrc = MCIERR_INVALID_CONNECTOR_TYPE;
  876.                                          break;
  877.                                  }
  878.                          }
  879.                        break;
  880.  
  881.                  /*-------------------------------------------------------------*
  882.                  * Disable connector
  883.                  *-------------------------------------------------------------*/
  884.  
  885.                  case MCI_DISABLE_CONNECTOR:
  886.                        if ( ulConnectorType )
  887.                          {
  888.                          switch( lpConParms->dwConnectorType )
  889.                                  {
  890.                                  case MCI_LINE_IN_CONNECTOR:
  891.                                  case MCI_AUDIO_IN_CONNECTOR   :
  892.                                  case MCI_MICROPHONE_CONNECTOR:
  893.                                  case MCI_LINE_OUT_CONNECTOR:
  894.                                  case MCI_AUDIO_OUT_CONNECTOR  :
  895.                                  case MCI_SPEAKERS_CONNECTOR:
  896.                                  case MCI_HEADPHONES_CONNECTOR:
  897.  
  898.                                     ulrc = mciSendCommand ( ulpInstance->wAmpDeviceID,
  899.                                                            (USHORT) MCI_CONNECTOR,
  900.                                                            ulParam1,
  901.                                                            (DWORD) lpConParms,
  902.                                                            pFuncBlock->usUserParm );
  903.                                          break;
  904.                                  case MCI_WAVE_STREAM_CONNECTOR:
  905.  
  906.                                     ulrc = MCIERR_CANNOT_MODIFY_CONNECTOR;
  907.                                     break;
  908.                                  case MCI_MIDI_STREAM_CONNECTOR:
  909.                                  case MCI_AMP_STREAM_CONNECTOR:
  910.                                  case MCI_CD_STREAM_CONNECTOR  :
  911.                                  case MCI_VIDEO_IN_CONNECTOR   :
  912.                                  case MCI_VIDEO_OUT_CONNECTOR  :
  913.                                  case MCI_PHONE_SET_CONNECTOR  :
  914.                                  case MCI_PHONE_LINE_CONNECTOR :
  915.                                  case MCI_UNIVERSAL_CONNECTOR  :
  916.  
  917.                                     ulrc = MCIERR_UNSUPPORTED_CONN_TYPE;
  918.                                     break;
  919.  
  920.                                  default:
  921.                                          ulrc = MCIERR_INVALID_CONNECTOR_TYPE;
  922.                                          break;
  923.                                  } /* switch the connector type */
  924.  
  925.  
  926.                          } /* if caller wants to know the type */
  927.                        break;
  928.                  /*-------------------------------------------------------------*
  929.                  * QUERY conn     ector
  930.                  *-------------------------------------------------------------*/
  931.  
  932.                  case MCI_QUERY_CONNECTOR_STATUS :
  933.                        if ( ulConnectorType )
  934.                          {
  935.  
  936.                          switch( lpConParms->dwConnectorType )
  937.                                  {
  938.                                  case MCI_LINE_IN_CONNECTOR:
  939.                                  case MCI_AUDIO_IN_CONNECTOR   :
  940.                                  case MCI_MICROPHONE_CONNECTOR:
  941.                                  case MCI_LINE_OUT_CONNECTOR:
  942.                                  case MCI_AUDIO_OUT_CONNECTOR  :
  943.                                  case MCI_SPEAKERS_CONNECTOR:
  944.                                  case MCI_HEADPHONES_CONNECTOR:
  945.  
  946.                                     ulrc = mciSendCommand ( ulpInstance->wAmpDeviceID,
  947.                                                            (USHORT) MCI_CONNECTOR,
  948.                                                            ulParam1,
  949.                                                            (DWORD) lpConParms,
  950.                                                            pFuncBlock->usUserParm );
  951.                                     break;
  952.  
  953.                                  case MCI_WAVE_STREAM_CONNECTOR:
  954.                                    if ( ulParam1 & MCI_CONNECTOR_INDEX )
  955.                                      {
  956.                                      if (lpConParms->dwConnectorIndex != 1)
  957.  
  958.                                         {
  959.                                         return MCIERR_INVALID_CONNECTOR_INDEX;
  960.                                         }
  961.                                    }
  962.                                    lpConParms->dwReturn = TRUE;
  963.                                    ulrc = MAKEULONG( MCIERR_SUCCESS, MCI_TRUE_FALSE_RETURN );
  964.                                    break;
  965.                                  case MCI_MIDI_STREAM_CONNECTOR:
  966.                                  case MCI_AMP_STREAM_CONNECTOR:
  967.                                  case MCI_CD_STREAM_CONNECTOR  :
  968.                                  case MCI_VIDEO_IN_CONNECTOR   :
  969.                                  case MCI_VIDEO_OUT_CONNECTOR  :
  970.                                  case MCI_PHONE_SET_CONNECTOR  :
  971.                                  case MCI_PHONE_LINE_CONNECTOR :
  972.                                  case MCI_UNIVERSAL_CONNECTOR  :
  973.  
  974.                                     ulrc = MCIERR_UNSUPPORTED_CONN_TYPE;
  975.                                     break;
  976.  
  977.                                  default:
  978.                                          ulrc = MCIERR_INVALID_CONNECTOR_TYPE;
  979.                                          break;
  980.                                  }
  981.  
  982.                          }
  983.  
  984.                        break;
  985.  
  986.                  /*-------------------------------------------------------------*
  987.                  * Unknown request
  988.                  *-------------------------------------------------------------*/
  989.  
  990.                  default:
  991.                          ulrc = MCIERR_MISSING_FLAG;
  992.                          break;
  993.                  } /* switch the connector type */
  994.  
  995.          } /* if !ulrc */
  996.   else if ( ulParam1 & MCI_CONNECTOR_INDEX )
  997.      {
  998.      if (lpConParms->dwConnectorIndex != 1)
  999.  
  1000.         {
  1001.         return MCIERR_INVALID_CONNECTOR_INDEX;
  1002.         }
  1003.  
  1004.      if (  ( ulParam1 & ~( MCI_CONNECTOR_INDEX + MCI_QUERY_CONNECTOR_STATUS) ) > 0  )
  1005.        {
  1006.        return MCIERR_INVALID_FLAG;
  1007.        }
  1008.  
  1009.  
  1010.      if ( !(ulParam1 & MCI_QUERY_CONNECTOR_STATUS)  )
  1011.         {
  1012.         return MCIERR_MISSING_FLAG;
  1013.         }
  1014.  
  1015.      lpConParms->dwReturn = TRUE;
  1016.      ulrc = MAKEULONG( MCIERR_SUCCESS, MCI_TRUE_FALSE_RETURN );
  1017.  
  1018.      } /* see if the index only flag is set */
  1019.   else
  1020.      // else there was neither a connector index nor a connector type
  1021.      // must be one or both
  1022.      {
  1023.      if ( !(ulParam1 & MCI_QUERY_CONNECTOR_STATUS)  )
  1024.         {
  1025.         return MCIERR_MISSING_FLAG;
  1026.         }
  1027.  
  1028.      lpConParms->dwReturn = TRUE;
  1029.      ulrc = MAKEULONG( MCIERR_SUCCESS, MCI_TRUE_FALSE_RETURN );
  1030.      }
  1031.  
  1032.  
  1033.    return (ulrc);
  1034. }
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051. /********************* START OF SPECIFICATIONS *******************************
  1052. *
  1053. * SUBROUTINE NAME: AllocMessageParmMem
  1054. *
  1055. * DESCRIPTIVE NAME:
  1056. *
  1057. * FUNCTION: Allocate Memory for MCI Message parameter when MCI_NOTIFY
  1058. *           Flag is On..
  1059. *
  1060. *
  1061. * NOTES:
  1062. * ENTRY POINTS:
  1063. *     LINKAGE:   CALL FAR
  1064. *
  1065. * INPUT:
  1066. *
  1067. * EXIT-NORMAL: Return Code 0.
  1068. *
  1069. * EXIT_ERROR:  Error Code.
  1070. *
  1071. * EFFECTS:
  1072. *
  1073. * INTERNAL REFERENCES: HhpAllocMem().
  1074. *
  1075. * EXTERNAL REFERENCES:
  1076. *
  1077. *********************** END OF SPECIFICATIONS *******************************/
  1078. ULONG   AllocNCopyMessageParmMem (USHORT usMessage, FUNCTION_PARM_BLOCK * pFuncBlock, ULONG ulCopyFrom, USHORT usUserParm)
  1079. {
  1080.  
  1081.   extern HHUGEHEAP        heap;      // Global Heap
  1082.   LPMCI_PLAY_PARMS        prPLY;     // MCI Play Params Pointer
  1083.   LPMCI_RECORD_PARMS      prREC;     // MCI Record Parms Pointer
  1084.  
  1085.  
  1086.   /******************************************************/
  1087.   // Based on message Allocate the appropriate structure
  1088.   /*****************************************************/
  1089.  
  1090.   pFuncBlock->ulNotify = TRUE;
  1091.   usUserParm = usUserParm;
  1092.  
  1093.  
  1094.   switch (usMessage) {
  1095.  
  1096.   case MCI_PLAY:
  1097.           {
  1098.                   if (!(prPLY = HhpAllocMem (heap, sizeof (MCI_PLAY_PARMS))))
  1099.                           return MCIERR_OUT_OF_MEMORY;
  1100.  
  1101.  
  1102.                   /***************************************************/
  1103.                   // Copy DriverEntry Parms into Prvt Strct
  1104.                   /***************************************************/
  1105.                   memcpy (prPLY, (LPMCI_PLAY_PARMS)ulCopyFrom, sizeof (MCI_PLAY_PARMS));
  1106.                   pFuncBlock->ulParam2 = (ULONG)prPLY;
  1107.  
  1108.           }
  1109.           break;
  1110.  
  1111.   case MCI_RECORD:
  1112.           {
  1113.                   if (!(prREC = HhpAllocMem (heap,sizeof (MCI_RECORD_PARMS))))
  1114.                           return MCIERR_OUT_OF_MEMORY;
  1115.                   /***************************************************/
  1116.                   // Copy DriverEntry Parms into Prvt Strct
  1117.                   /***************************************************/
  1118.                   memcpy (prREC, (LPMCI_RECORD_PARMS)ulCopyFrom, sizeof (MCI_RECORD_PARMS));
  1119.                   pFuncBlock->ulParam2 = (ULONG)prREC;
  1120.           }
  1121.           break;
  1122.  
  1123.   } /* of Switch */
  1124.  
  1125.   return (ULONG)(MCIERR_SUCCESS);
  1126. }
  1127.