home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / mm / admct / admcrest.c < prev    next >
C/C++ Source or Header  |  1999-05-11  |  26KB  |  842 lines

  1. /******************** START OF SPECIFICATIONS *********************
  2. *
  3. * SUBROUTINE NAME: MCIREST.c
  4. *
  5. * DESCRIPTIVE NAME: A couple of excess functions.
  6. *
  7. *
  8. *
  9. *              Copyright (c) IBM Corporation  1991, 1993
  10. *                        All Rights Reserved
  11. *
  12. * FUNCTION:
  13. *
  14. * NOTES: The following concepts are illustrated in the source file.
  15. *        C. How to pause/resume a stream
  16. *        D. Support stream transition tables.
  17. *        E. Processing INFO_PRODUCT + INFO_FILE
  18. *
  19. * ENTRY POINTS:
  20. *
  21. *********************** END OF SPECIFICATIONS **********************/
  22. #define INCL_DOSSEMAPHORES
  23. #define INCL_DOSPROCESS
  24. #define INCL_ERRORS
  25.  
  26. #include <os2.h>                        // OS2 defines.
  27. #include <string.h>                     // String functions.
  28. #include <os2medef.h>                   // MME includes files.
  29. #include <ssm.h>                        // SSM spi includes.
  30. #include <meerror.h>                    // MM Error Messages.
  31. #include <mmioos2.h>                    // MMIO Include.
  32. #include <mcios2.h>                     // MM System Include.
  33. #include <mmdrvos2.h>                     // MCI Driver Include.
  34. #include <mcd.h>                        // AudioIFDriverInterface.
  35. #include <hhpheap.h>                    // Heap Manager Definitions
  36. #include <qos.h>
  37. #include <audiomcd.h>                   // Component Definitions
  38. #include "admcfunc.h"                   // Function Prototypes
  39. #include <checkmem.h>
  40.  
  41.  
  42. /********************* START OF SPECIFICATIONS *********************
  43. *
  44. * SUBROUTINE NAME: MCISTOP.C
  45. *
  46. * DESCRIPTIVE
  47. *
  48. * FUNCTION:  Stop Playing/Recording.
  49. *  On a stop, a streaming MCD should perform the following commands:
  50. *
  51. *  A. Verify that the flags passed are valid.
  52. *  B. Stop any commands which are active on another thread.
  53. *  C. If a stream had previously been created, ensure that it is in
  54. *     stopped state.
  55. *  D. If it is a paused stream, then do a STOP_PAUSE to ensure that
  56. *     no data will be lost.
  57. *
  58. * NOTES:
  59. *
  60. * ENTRY POINTS:
  61. *
  62. * INPUT: MCI_STOP message.
  63. *
  64. * EXIT-NORMAL: MCIERR_SUCCESS
  65. *
  66. * EXIT_ERROR:  Error Code.
  67. *
  68. * EFFECTS:
  69. *
  70. * INTERNAL REFERENCES:  MCIERR ().
  71. *
  72. * EXTERNAL REFERENCES: spiStopStream ()   -   SSM Spi
  73. *
  74. *********************** END OF SPECIFICATIONS **********************/
  75. RC MCIStop ( FUNCTION_PARM_BLOCK *pFuncBlock)
  76. {
  77.    ULONG           ulrc;                   // MME Error Value Propogated
  78.    INSTANCE        *ulpInstance;           // Local Instance
  79.    ULONG           ulParam1;               // Incoming MCI Flags
  80.    ULONG           ulCnt;                  // Semaphore Posts Freq
  81.    ULONG           ulAbortNotify = FALSE;  // whether or not to abort a notify
  82.    ULONG           ulStopFlags;            // Mask for Incoming MCI Flags
  83.    ULONG           ulSpiFlags;
  84.  
  85.  
  86.    /*****************************
  87.    * Do Some Flag Checking
  88.    ******************************/
  89.    ulParam1 = pFuncBlock->ulParam1;
  90.  
  91.    /* Mask out illegal file */
  92.  
  93.    ulStopFlags = ulParam1;
  94.    ulStopFlags &= ~(MCI_WAIT + MCI_NOTIFY );
  95.  
  96.    /* If the caller passed in a flag we do not support--return an error */
  97.  
  98.    if (ulStopFlags > 0)
  99.        return (MCIERR_INVALID_FLAG);
  100.  
  101.    ulpInstance = (INSTANCE *)pFuncBlock->ulpInstance;
  102.  
  103.    /*****************************************
  104.    * To ensure proper syncronization, acquire
  105.    * the semaphore which is used to control
  106.    * who can check to see which processes are
  107.    * active. This function will also tell us
  108.    * if there is an operation to abort or
  109.    * supercede.
  110.    ******************************************/
  111.  
  112.    GetNotifyAbortAccess ( ulpInstance, &ulAbortNotify );
  113.  
  114.    /*******************************************
  115.    * If there is an operation active (i.e. a
  116.    * play, record or save) then post a message
  117.    * stating that the command has been
  118.    * aborted (record), superceded (play) or
  119.    * wait for completion (save).
  120.    ********************************************/
  121.  
  122.    if (ulAbortNotify == TRUE)
  123.      {
  124.      if ( ulpInstance->usNotPendingMsg == MCI_SAVE )
  125.         {
  126.         /*****************************************************
  127.         * Save cannot be interrupted or data will be lost, so
  128.         * if there is a save pending, wait for it to complete
  129.         ******************************************************/
  130.  
  131.         DosWaitEventSem( ulpInstance->hThreadSem, (ULONG ) -1 );
  132.  
  133.         }
  134.      else
  135.         {
  136.         PostMDMMessage ( MCI_NOTIFY_ABORTED,
  137.                          ulpInstance->usNotPendingMsg,
  138.                          pFuncBlock);
  139.  
  140.         DosResetEventSem (ulpInstance->hEventSem, &ulCnt);
  141.         DosResetEventSem (ulpInstance->hThreadSem, &ulCnt);
  142.  
  143.         /**********************************************
  144.         * If we are recording information, we must do
  145.         * a full stop so that no information will be
  146.         * lost.  However, if this is a play back stream
  147.         * do a pause so that the next play will resume
  148.         * without audible breakup of information.
  149.         ***********************************************/
  150.  
  151.  
  152.         if ( ulpInstance->ulOperation == MCIDRV_INPUT )
  153.           {
  154.           ulSpiFlags = SPI_STOP_FLUSH;
  155.           }
  156.         else
  157.           {
  158.           ulSpiFlags = SPI_STOP_STREAM;
  159.           }
  160.  
  161.         /***********************************
  162.         * Stop The Stream
  163.         ************************************/
  164.         ulrc = ADMCStopStream (ulpInstance, ulSpiFlags);
  165.  
  166.         if ( ulpInstance->ulOperation == MCIDRV_INPUT )
  167.           {
  168.           if (!ulrc)
  169.              {
  170.              /*****************************
  171.              * Wait for the stopped event
  172.              ******************************/
  173.              DosWaitEventSem (ulpInstance->hThreadSem, (ULONG) -1);
  174.              }
  175.  
  176.           /****************************************
  177.           * Record streams go into a stopped state
  178.           *****************************************/
  179.           STRMSTATE = MCI_STOP;
  180.  
  181.           }
  182.         else
  183.           {
  184.           /*****************************************
  185.           * Since a pause does not generate an event
  186.           * create a fake one so our play thread can
  187.           * clean up (if it is active).
  188.           *****************************************/
  189.  
  190.           ulpInstance->StreamEvent = EVENT_STREAM_STOPPED;
  191.           DosPostEventSem (ulpInstance->hEventSem);
  192.  
  193.           DosWaitEventSem (ulpInstance->hThreadSem, (ULONG) -1);
  194.  
  195.           /***************************************
  196.           * Play streams go into a stopped/paused state
  197.           ****************************************/
  198.  
  199.           STRMSTATE = STOP_PAUSED;
  200.           }
  201.  
  202.  
  203.         } /* if no pending save */
  204.  
  205.         ulpInstance->usNotifyPending = FALSE;
  206.  
  207.      } /* if notify pending */
  208.  
  209.  
  210.    if (STRMSTATE != MCI_STOP && STRMSTATE != STOP_PAUSED )
  211.       {
  212.       DosResetEventSem (ulpInstance->hEventSem, &ulCnt);
  213.       ADMCStopStream (ulpInstance, SPI_STOP_STREAM );
  214.       STRMSTATE = STOP_PAUSED;
  215.       }
  216.  
  217.    return (MCIERR_SUCCESS);
  218.  
  219. }
  220.  
  221.  
  222. /********************* START OF SPECIFICATIONS *********************
  223. *
  224. * SUBROUTINE NAME: MCIPAUS.C
  225. *
  226. * DESCRIPTIVE
  227. *
  228. * FUNCTION:  Waveform Pause.
  229. *
  230. * NOTES:
  231. *  On a MCI_PAUSE, a streaming MCD should perform the following commands:
  232. *
  233. *  A. Ensure that no flags are passed in.
  234. *  B. If we are currently streaming, pause the stream.
  235. *  C. Set flag indicating that we are in paused state.
  236. *
  237. * ENTRY POINTS:
  238. *
  239. * INPUT: MCI_PAUSE message.
  240. *
  241. * EXIT-NORMAL: Return Code 0.
  242. *
  243. * EXIT_ERROR:  Error Code.
  244. *
  245. * EFFECTS:
  246. *
  247. * INTERNAL REFERENCES:  MCIERR ().
  248. *
  249. * EXTERNAL REFERENCES: spiStopStream ()   -   SSM Spi
  250. *
  251. *********************** END OF SPECIFICATIONS **********************/
  252. RC MCIPaus (FUNCTION_PARM_BLOCK *pFuncBlock)
  253.  
  254. {
  255.     INSTANCE *      ulpInstance;
  256.     ULONG           ulPauseFlags;
  257.  
  258.     ulPauseFlags = pFuncBlock->ulParam1;
  259.     ulPauseFlags &= ~(MCI_WAIT + MCI_NOTIFY );
  260.  
  261.    /* If the caller passed in a flag we do not support--return an error */
  262.  
  263.     if (ulPauseFlags > 0 )
  264.        {
  265.        return MCIERR_INVALID_FLAG;
  266.        }
  267.  
  268.     ulpInstance = (INSTANCE *) pFuncBlock->ulpInstance;
  269.  
  270.     /****************************************************
  271.     * The default action on an spiStopstream is pause.
  272.     *****************************************************/
  273.     if ((STRMSTATE == MCI_PLAY ) || (STRMSTATE == MCI_RECORD) )
  274.        {
  275.  
  276.        ADMCStopStream (ulpInstance, SPI_STOP_STREAM);
  277.  
  278.        STRMSTATE = MCI_PAUSE;    /* update Instance */
  279.  
  280.        }
  281.  
  282.     return (MCIERR_SUCCESS);
  283.  
  284. } /* MCIPause */
  285.  
  286.  
  287.  
  288. /********************* START OF SPECIFICATIONS *********************
  289. *
  290. * SUBROUTINE NAME: MCIRESUME
  291. *
  292. * DESCRIPTIVE      Audio MCD Resume.
  293. *
  294. * FUNCTION:  Resume Playback/Record from Paused State.
  295. *
  296. * NOTES:
  297. * On a MCI_RESUME, a streaming MCD should perform the following commands:
  298. *
  299. * A. Ensure that no flags are passed in.
  300. * B. If we are paused, resume the stream.
  301. *
  302. * ENTRY POINTS:
  303. *
  304. * INPUT: MCI_RESUME message.
  305. *
  306. * EXIT-NORMAL: Return Code 0.
  307. *
  308. * EXIT_ERROR:  Error Code.
  309. *
  310. * EFFECTS:
  311. *
  312. * INTERNAL REFERENCES:  MCIERR ().
  313. *
  314. * EXTERNAL REFERENCES: SpiStartStream ()        -   SSM Spi
  315. *
  316. *********************** END OF SPECIFICATIONS **********************/
  317. RC  MCIResume (FUNCTION_PARM_BLOCK * pFuncBlock)
  318. {
  319.  
  320.    ULONG                  ulResumeFlags;   // Incoming MCI Flags
  321.  
  322.    INSTANCE               * ulpInstance;   // Local Instance
  323.  
  324.    /*********************************
  325.    * Check for invalid flags
  326.    *********************************/
  327.  
  328.    ulResumeFlags = pFuncBlock->ulParam1;
  329.  
  330.    /* Mask out legal flags */
  331.  
  332.    ulResumeFlags &= ~( MCI_WAIT + MCI_NOTIFY );
  333.  
  334.    /* If the caller passed in a flag we do not support--return an error */
  335.  
  336.    if (ulResumeFlags > 0 )
  337.            return ( MCIERR_INVALID_FLAG );
  338.  
  339.    /**********************************
  340.    * Derefernce pointers.
  341.    ***********************************/
  342.  
  343.    ulpInstance= (INSTANCE *) pFuncBlock->ulpInstance;
  344.  
  345.  
  346.    /**********************************************************
  347.    * No State Transition if already in States Play or Record
  348.    **********************************************************/
  349.  
  350.    if ( STRMSTATE == MCI_PAUSE )
  351.       {
  352. // CONNECTOR FEATURE--need to add resume
  353.  
  354.          StartStream( ulpInstance, MCIDRV_START_PLAYBACK ); // MCIDRV_RESUME not in spec
  355.  
  356. //       SpiStartStream (ulpInstance->StreamInfo.hStream, SPI_START_STREAM);
  357. // CONNECTOR FEATURE
  358.  
  359.        if ( ulpInstance->ulOperation == MCIDRV_OUTPUT )
  360.           {
  361.           STRMSTATE = MCI_PLAY;      // update Instance
  362.           }
  363.        else
  364.           {
  365.           STRMSTATE = MCI_RECORD;
  366.           }
  367.  
  368.       } /* if in paused state */
  369.  
  370.    return (MCIERR_SUCCESS);
  371.  
  372. } /* MCIResume */
  373.  
  374.  
  375.  
  376.  
  377. /********************* START OF SPECIFICATIONS *********************
  378. *
  379. * SUBROUTINE NAME: MCISTPA
  380. *
  381. * DESCRIPTIVE : Audio MCD Set Position Advice.
  382. *
  383. * FUNCTION: Create Media Position Advice Notification messages.
  384. *
  385. * NOTES:
  386. *  To a streaming MCD, a postion advise simply is a cuepoint which
  387. *  reoccurs every x time units.  To enable position advise, the following
  388. *  steps should be followed:
  389. .*
  390. .
  391. *  Check flags and validate and pointers.
  392. *  If the caller has asked for position advise to be turned on then
  393. *
  394. *    If a stream has been created, then enable the recurring cuepoint event.
  395. *    Else, set a flag and enable the event later.
  396. *  If position advise is to be turned off, then disable the recurring
  397. *  cuepoint event.
  398. *
  399. * ENTRY POINTS:
  400. *
  401. * INPUT: MCI_SET_POSITION_ADVISE message.
  402. *
  403. * EXIT-NORMAL: MCIERR_SUCCESS
  404. *
  405. * EXIT_ERROR:  Error Code.
  406. *
  407. * EFFECTS:
  408. *
  409. * INTERNAL REFERENCES:  MCIERR ().
  410. *
  411. * EXTERNAL REFERENCES: spiStartStream ()         -   SSM Spi
  412. *
  413. *********************** END OF SPECIFICATIONS **********************/
  414.  
  415. RC  MCISetPositionAdvise (FUNCTION_PARM_BLOCK * pFuncBlock)
  416. {
  417.   ULONG           ulrc;                      // Error Value
  418.   ULONG           ulParam1;                  // Incoming MCI Flags
  419.   ULONG           ulPosAdviseFlags;          // Mask For Incoming Flags
  420.   ULONG           ulMMTime;                  // Converted Time
  421.  
  422.   INSTANCE        *ulpInstance;              // Local Instance
  423.  
  424.   PID             pid;
  425.   TID             tid;
  426.   HWND            hWnd;
  427.  
  428.   PMCI_POSITION_PARMS pPositionParms;      // MCI Msg Data
  429.  
  430.   /***************************
  431.   * Intialize Pointers
  432.   ****************************/
  433.  
  434.   ulpInstance = (INSTANCE *)pFuncBlock->ulpInstance;
  435.   ulParam1 = pFuncBlock->ulParam1;
  436.   ulPosAdviseFlags = ulParam1;
  437.   pPositionParms = (PMCI_POSITION_PARMS) pFuncBlock->ulParam2;
  438.  
  439.   /**********************************
  440.   * Check for Validity of Flags
  441.   ***********************************/
  442.   ulPosAdviseFlags &= ~( MCI_NOTIFY  + MCI_WAIT     +
  443.                          MCI_SET_POSITION_ADVISE_ON +
  444.                          MCI_SET_POSITION_ADVISE_OFF);
  445.  
  446.   /*************************************
  447.   * Return error if flags are not
  448.   * appropriate for the message
  449.   *************************************/
  450.  
  451.   if (ulPosAdviseFlags > 0 )
  452.       return ( MCIERR_INVALID_FLAG );
  453.  
  454.   /********************************
  455.   * Null Parameter Conditions
  456.   *********************************/
  457.   ulrc = CheckMem (((PVOID)pPositionParms),
  458.                    sizeof (MCI_POSITION_PARMS),
  459.                    PAG_READ);
  460.  
  461.   if (ulrc != MCIERR_SUCCESS)
  462.      {
  463.      return (MCIERR_MISSING_PARAMETER);
  464.      }
  465.  
  466.  
  467.  
  468.   /******************************************************
  469.   * Check for Invalid Combination of Valid Flags
  470.   *******************************************************/
  471.   if ((ulParam1 & MCI_SET_POSITION_ADVISE_ON) &&
  472.       (ulParam1 & MCI_SET_POSITION_ADVISE_OFF))
  473.  
  474.       return (MCIERR_FLAGS_NOT_COMPATIBLE);
  475.  
  476.   /************************************************
  477.   * Check for Invalid Combination of Valid Flags
  478.   *************************************************/
  479.   if (!(ulParam1 & MCI_SET_POSITION_ADVISE_ON ||
  480.       ulParam1 & MCI_SET_POSITION_ADVISE_OFF))
  481.  
  482.       return (MCIERR_MISSING_FLAG);
  483.  
  484.  
  485.   /*---------------------------------------
  486.   * To enable position advise, a file or
  487.   * playlist must be loaded.
  488.   *---------------------------------------*/
  489.  
  490.   if (ulpInstance->fFileExists == FALSE )
  491.     return (MCIERR_FILE_NOT_FOUND);
  492.  
  493.   /******************************************
  494.   * Enable Position Advise
  495.   *******************************************/
  496.  
  497.   if (ulParam1 & MCI_SET_POSITION_ADVISE_ON)
  498.      {
  499.      /************************************
  500.      * Ensure that the callback handle that
  501.      * the caller specified is valid.  This case
  502.      * is somewhat special--MDM normally checks
  503.      * the callback handles when MCI_NOTIFY is
  504.      * specified.  However, callback handles can
  505.      * be passed on position advise with the
  506.      * MCI_WAIT flag.
  507.      ************************************/
  508.  
  509.      hWnd = pPositionParms->hwndCallback;
  510.  
  511.  
  512.      if (!WinQueryWindowProcess(hWnd, &pid, &tid))
  513.           return(MCIERR_INVALID_CALLBACK_HANDLE);
  514.  
  515.      ulpInstance->StreamInfo.PosAdvEvcb.hwndCallback = hWnd;
  516.  
  517.      ulpInstance->StreamInfo.PosAdvEvcb.usDeviceID = ulpInstance->usWaveDeviceID;
  518.  
  519.      /**************************************************
  520.      * If we have an existing stream and have already
  521.      * enabled a position advise cuepoint, then
  522.      * disable the previous position advise since the
  523.      * new one has precendence.
  524.      **************************************************/
  525.  
  526.      if ( ulpInstance->usPosAdvise == EVENT_ENABLED )
  527.  
  528.         {
  529.  
  530.         /* why don't we check ulrc? */
  531.  
  532.         ulrc = ADMCDisableEvent(ulpInstance->StreamInfo.hPosEvent);
  533.         }
  534.  
  535.      /***************************************
  536.      * Fill in Event Control Block to indicate
  537.      * that we want a recurring cue point.
  538.      ****************************************/
  539.      ulpInstance->StreamInfo.PosAdvEvcb.evcb.ulType = EVENT_CUE_TIME;
  540.      ulpInstance->StreamInfo.PosAdvEvcb.evcb.ulFlags = EVENT_RECURRING;
  541.      ulpInstance->StreamInfo.PosAdvEvcb.evcb.hstream = ulpInstance->StreamInfo.hStream;
  542.  
  543.      /************************************************
  544.      * Copy our instance into the position advise
  545.      * event control block.  The event routine will
  546.      * use this field to obtain a pointer to our
  547.      * instance.  Once it has this pointer, it can
  548.      * manipulate instance variables etc, necessary
  549.      * to inform the caller that the event has
  550.      * happened.  See the PlayEventProc in admcplay.c
  551.      * and the RecordEventProc in admcrecd.c
  552.      ***********************************************
  553.      **/
  554.      ulpInstance->StreamInfo.PosAdvEvcb.ulpInstance = (ULONG)ulpInstance;
  555.  
  556.      /********************************************
  557.      * Copy Position UserParm into instance.
  558.      * This User Parameter is returned on
  559.      * Position change messages to the user.
  560.      *********************************************/
  561.      ulpInstance->usPosUserParm = pPositionParms->usUserParm;
  562.  
  563.      ulrc = ConvertToMM ( ulpInstance,
  564.                           &ulMMTime,
  565.                           pPositionParms->ulUnits);
  566.  
  567.      /**********************************************
  568.      * Frequency of Position Change Messages
  569.      **********************************************/
  570.  
  571.      ulpInstance->StreamInfo.PosAdvEvcb.evcb.mmtimeStream = ulpInstance->StreamInfo.PosAdvEvcb.mmCuePt = ulMMTime;
  572.  
  573.      /*********************************************
  574.      * If ulUnits == 0 return MCIERR_OUTOFRANGE
  575.      *********************************************/
  576.  
  577.      if ( ulMMTime == 0)
  578.          return (MCIERR_OUTOFRANGE);
  579.  
  580.      /*********************************************
  581.      * Enable the recurring time event.  Note:
  582.      * We are utilizing an extended event control
  583.      * block which we modified to contain window
  584.      * handles, instance pointers etc.  In fact,
  585.      * you can modify the evcb to contain whatever
  586.      * data you wish.  Simply ensure the beginning
  587.      * fields of the structure are what SSM expects
  588.      * and the remainder can be used by the MCD.
  589.      * See admcplay.c or audiosub.c for more info
  590.      **********************************************/
  591.  
  592.      if (ulpInstance->ulCreateFlag == PREROLL_STATE)
  593.        {
  594.        ulrc = ADMCEnableEvent( (PEVCB) &ulpInstance->StreamInfo.PosAdvEvcb,
  595.                               (PHEVENT) &ulpInstance->StreamInfo.hPosEvent);
  596.  
  597.        ulpInstance->usPosAdvise = EVENT_ENABLED; // Set The Flag and Return
  598.        }
  599.      else
  600.        {
  601.        ulpInstance->usPosAdvise = TRUE; // Set The Flag and Return
  602.        }
  603.  
  604.      if (ulrc)
  605.          return (ulrc);
  606.      } /* Set Position Advise on */
  607.  
  608.   /*****************************************
  609.   * Disable Position Advise
  610.   ******************************************/
  611.  
  612.   if (ulParam1 & MCI_SET_POSITION_ADVISE_OFF)
  613.      {
  614.      /* Ensure that position advise has been turned on first */
  615.      if ( !ulpInstance->usPosAdvise )
  616.         {
  617.         return ( MCIERR_INVALID_CUEPOINT );
  618.         }
  619.      /* If an event has been enabled, remove it */
  620.  
  621.      if ( ulpInstance->usPosAdvise == EVENT_ENABLED )
  622.         {
  623.         ulrc = ADMCDisableEvent (ulpInstance->StreamInfo.hPosEvent);
  624.         }
  625.  
  626.      /* Set flag indicating that Position Advise is no longer in effect */
  627.  
  628.      ulpInstance->usPosAdvise = FALSE;
  629.  
  630.      } /* Set position advise off */
  631.  
  632.   return (ulrc);    // return RC
  633. } /* MCISetPositionAdvise */
  634.  
  635.  
  636. /********************* START OF SPECIFICATIONS *********************
  637. *
  638. * SUBROUTINE NAME: MCISYNC
  639. *
  640. * DESCRIPTIVE      Audio MCD Set Sync Offset.
  641. *
  642. * FUNCTION:  Set Synchronization offset.
  643. *
  644. * NOTES:
  645. *
  646. * ENTRY POINTS:
  647. *
  648. * INPUT: MCI_SET_SYNC_OFFSET message.
  649. *
  650. * EXIT-NORMAL: Return Code 0.
  651. *
  652. * EXIT_ERROR:  Error Code.
  653. *
  654. * EFFECTS:
  655. *
  656. * INTERNAL REFERENCES:  MCIERR ().
  657. *
  658. * EXTERNAL REFERENCES: spiStartStream ()         -   SSM Spi
  659. *
  660. *********************** END OF SPECIFICATIONS **********************/
  661. //RC MCISync (FUNCTION_PARM_BLOCK * pFuncBlock)
  662. //{
  663. //  INSTANCE             *pInstance;       // Local Instance
  664. //  PMCIDRV_SYNC_PARMS   pSyncParms;
  665. //
  666. //  pInstance = (INSTANCE *) pFuncBlock->ulpInstance;
  667. //  pSyncParms = ( PMCIDRV_SYNC_PARMS ) pFuncBlock->ulParam2;
  668. //
  669. //  pFuncBlock->ulParam1 &= ~(MCI_WAIT | MCI_NOTIFY );
  670. //
  671. //  switch ( pFuncBlock->ulParam1 )
  672. //     {
  673. //     case MCIDRV_SYNC_ENABLE  :
  674. //        if ( !pInstance->StreamInfo.hStream )
  675. //           {
  676. //           return ( MCIERR_UNSUPPORTED_FUNCTION );
  677. //           }
  678. //        pSyncParms->ulNumStreams = 1;
  679. //        pSyncParms->hStreams = &pInstance->StreamInfo.hStream;
  680. //        break;
  681. //     case MCIDRV_SYNC_DISABLE :
  682. //        break;
  683. //     default :
  684. //        return ( MCIERR_UNSUPPORTED_FUNCTION );
  685. //     }
  686. //  /***********************************************
  687. //  * Flag the offset condition as true.
  688. //  ***********************************************/
  689. //
  690. //  return (MCIERR_SUCCESS);
  691. //        // Forced RC
  692. //}
  693.  
  694.  
  695. /********************* START OF SPECIFICATIONS *********************
  696. *
  697. * SUBROUTINE NAME:              MCDINFO
  698. *
  699. * DESCRIPTIVE NAME: Information about Waveform Device.
  700. *
  701. * FUNCTION: Obtain Info about a  Waveform Device.
  702. *
  703. * NOTES:
  704. *
  705. * ENTRY POINTS:
  706. *     LINKAGE:   CALL FAR
  707. *
  708. * INPUT: MCI_INFO message.
  709. *
  710. * EXIT-NORMAL: MCIERR_SUCCESS.
  711. *
  712. * EXIT_ERROR:  Error Code.
  713. *
  714. * EFFECTS:
  715. *
  716. * INTERNAL REFERENCES:
  717. *
  718. * EXTERNAL REFERENCES:
  719. *
  720. *********************** END OF SPECIFICATIONS **********************/
  721.  
  722. RC MCIInfo (FUNCTION_PARM_BLOCK *pFuncBlock)
  723. {
  724.  
  725.   ULONG            ulrc;               // Propogated MME Error Value
  726.   ULONG            ulParam1;           // Incoming MCI Msg Flags
  727.   ULONG            ulInfoFlags;        // Mask for Incoming Flags
  728.   INSTANCE         *ulpInstance;       // Local Instance
  729.   PMCI_INFO_PARMS  pInfoParms;        // Msg Data Ptr
  730.  
  731.   ulParam1 = pFuncBlock->ulParam1 & NOTIFY_MASK;
  732.   pInfoParms = (PMCI_INFO_PARMS) pFuncBlock->ulParam2;
  733.  
  734.   ulInfoFlags = ulParam1;
  735.  
  736.   /*******************************************
  737.   * Turn off Expected Flags Bits
  738.   ********************************************/
  739.   ulInfoFlags &= ~( MCI_INFO_FILE + MCI_INFO_PRODUCT);
  740.  
  741.   /************************************************
  742.   * Return Error if any bits are still set
  743.   ************************************************/
  744.  
  745.   if (ulInfoFlags > 0 )
  746.       return (MCIERR_INVALID_FLAG);
  747.  
  748.   /****************************************************
  749.   * Check For Valid Flags but Invalid combination
  750.   *****************************************************/
  751.  
  752.   if (ulParam1 & MCI_INFO_FILE && ulParam1 & MCI_INFO_PRODUCT)
  753.       return (MCIERR_FLAGS_NOT_COMPATIBLE);
  754.  
  755.  
  756.   if (!(ulParam1 & MCI_INFO_FILE || ulParam1 & MCI_INFO_PRODUCT))
  757.       return (MCIERR_MISSING_FLAG);
  758.  
  759.   /******************************************************
  760.   * Derefernce Instance pointer from the function block
  761.   ******************************************************/
  762.   ulpInstance = (INSTANCE *) pFuncBlock->ulpInstance;
  763.  
  764.   /*************************************************
  765.   * Check For valid MCI Data Struct pointer
  766.   *************************************************/
  767.   if (ulrc = CheckMem ((PVOID)pInfoParms,
  768.                        sizeof (MCI_INFO_PARMS),
  769.                        PAG_READ | PAG_WRITE) )
  770.       {
  771.       return (MCIERR_MISSING_PARAMETER);
  772.       }
  773.  
  774.  
  775.   if (ulParam1 & MCI_INFO_FILE)
  776.       {
  777.       /* An element must be loaded before this is valid */
  778.  
  779.       if (ulpInstance->fFileExists == FALSE )
  780.           {
  781.           return ( MCIERR_FILE_NOT_FOUND );
  782.           }
  783.  
  784.       /************************************
  785.       * Ensure the size of the buffer the
  786.       * user passed is valid for the length
  787.       * the caller says it is (i.e. they may
  788.       * have said it's valid for 8 bytes).
  789.       *************************************/
  790.  
  791.        if (ulrc = CheckMem ((PVOID)pInfoParms->pszReturn,
  792.                             pInfoParms->ulRetSize,
  793.                             PAG_READ | PAG_WRITE) )
  794.  
  795.          {
  796.          return (MCIERR_INVALID_BUFFER);
  797.          }
  798.       /********************************************
  799.       * If the filename is longer that what the
  800.       * caller has allocated, return the length
  801.       * that they should have allocated for the next
  802.       * try.
  803.       ***********************************************/
  804.  
  805.       if (strlen(ulpInstance->pszAudioFile) > pInfoParms->ulRetSize)
  806.         {
  807.         pInfoParms->ulRetSize = strlen (ulpInstance->pszAudioFile);
  808.         return (MCIERR_INVALID_BUFFER);
  809.         }
  810.       else
  811.         {
  812.         /* return to the caller the filename */
  813.  
  814.         strcpy((PSZ)pInfoParms->pszReturn, ulpInstance->pszAudioFile);
  815.         }
  816.  
  817.       } /* If File Info was Requested */
  818.  
  819.   /**********************************
  820.   * Product Information
  821.   ***********************************/
  822.  
  823.   if (ulParam1 & MCI_INFO_PRODUCT)
  824.       {
  825.  
  826.       /*******************************
  827.       * Get Product Information
  828.       * From AudioIF which is the
  829.       * device specific component.
  830.       ********************************/
  831.  
  832.        ulrc = mciSendCommand ( ulpInstance->usAmpDeviceID,
  833.                                MCI_INFO,
  834.                                ulParam1,
  835.                                (PVOID) pInfoParms,
  836.                                pFuncBlock->usUserParm);
  837.  
  838.       }  /* INFO Product */
  839.  
  840.   return (ulrc);
  841. } /* MCIInfo */
  842.