home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mmpm21tk.zip / TK / ADMCT / ADMCCLOS.C < prev    next >
C/C++ Source or Header  |  1993-04-12  |  10KB  |  288 lines

  1. /********************* START OF SPECIFICATIONS *********************
  2. *
  3. * SUBROU1TINE NAME:  MCICLOS.C
  4. *
  5. * DESCRIPTIVE NAME: Close Waveform Device.
  6. *
  7. *
  8. *
  9. *              Copyright (c) IBM Corporation  1991, 1993
  10. *                        All Rights Reserved
  11. *
  12. * FUNCTION:  A streaming MCD should do the following on a close.
  13. *
  14. *  A. Stop all commands which are active on another thread(s).
  15. *  B. Destroy all active streams.
  16. *  C. Close all open files.
  17. *  D. Delete any temporary files.
  18. *  E. Close any connected devices (such as an amp-mixer).
  19. *  F. If MCI_NOTIFY was used, notify the caller of completion.
  20. *
  21. * NOTES: When The Process is killed all threads Die.  Thus
  22. *        we check if the MCI_CLOSE_EXIT flag is passed in.  If this
  23. *        flag is passed, then will NOT do a stop before destroying
  24. *        the stream.   A stop in this scenario will cause a hang since
  25. *        the streaming subsystem has lost necessary threads.
  26. *
  27. * ENTRY POINTS:
  28. *
  29. * INPUT: MCI_CLOSE message.
  30. *
  31. * EXIT-NORMAL: Instance deleted, Device released.
  32. *
  33. * EXIT_ERROR:  Error Code.
  34. *
  35. * EFFECTS: None.
  36. *
  37. * INTERNAL REFERENCES: PostMDMMessage(), DestroyStream().
  38. *
  39. * EXTERNAL REFERENCES: SpiDestroyStream ()    - SSM SPI.
  40. *                      mdmDriverNotify  ()    - MDM API.
  41. *                      mciSendCommand   ()    - MDM API.
  42. *                      mciConnection    ()    - MDM API.
  43. *                      mmioClose        ()    - MMIO API.
  44. *                      HhpFreeMem       ()    - Heap Manager.
  45. *                      DosCloseEventSem ()    - OS/2 API.
  46. *                      DosCloseMutexSem ()    - OS/2 API.
  47. *                      DosFreeModule    ()    - OS/2 API.
  48. *
  49. *********************** END OF SPECIFICATIONS **********************/
  50.  
  51. #define INCL_BASE
  52. #define INCL_DOSMODULEMGR
  53. #define INCL_DOSSEMAPHORES
  54.  
  55. #include <os2.h>                        // OS2 defines.
  56. #include <string.h>
  57. #include <os2medef.h>                   // MME includes files.
  58. #include <stdlib.h>                     // Math functions
  59. #include <audio.h>                      // Audio Device defines
  60. #include <ssm.h>                        // SSM Spi includes.
  61. #include <meerror.h>                    // MM Error Messages.
  62. #include <mmioos2.h>                    // MMIO Include.
  63. #include <mcios2.h>                     // MM System Include.
  64. #include <mcipriv.h>                    // MCI Connection stuff
  65. #include <mmdrvos2.h>                   // MCI Driver include.
  66. #include <mcd.h>                        // AudioIFDriverInterface.
  67. #include <hhpheap.h>                    // Heap Manager Definitions
  68. #include <qos.h>
  69. #include <audiomcd.h>                   // Component Definitions.
  70. #include "admcfunc.h"                   // Function Prototypes.
  71.  
  72. RC MCIClos (FUNCTION_PARM_BLOCK *pFuncBlock)
  73. {
  74.   ULONG               ulrc;           // RC
  75.   ULONG               ulParam1;       // Incoming MCI Flags
  76.   ULONG               ulAbortNotify = FALSE; // whether to abort play/record operation
  77.   ULONG               ulCount;
  78.   INSTANCE            *ulpInstance;   // Active Instance
  79.   ULONG               ulCloseFlags;   // Mask for MCI Flags
  80.  
  81.   MTIME_EVCB           *pCuePoint;
  82.   MTIME_EVCB           *pTempCuePoint;
  83.  
  84.   /*******************************************
  85.   * Dererence Pointers From Thread Block
  86.   ********************************************/
  87.  
  88.   ulParam1 =   pFuncBlock->ulParam1;
  89.   ulpInstance = (INSTANCE *)pFuncBlock->ulpInstance;
  90.  
  91.   /***************************
  92.   * Intialize Variables
  93.   ***************************/
  94.   ulCloseFlags = ulParam1;
  95.  
  96.   /************************************
  97.   * Check for Illegal Flags
  98.   *************************************/
  99.  
  100.   ulCloseFlags &= ~(MCI_WAIT + MCI_NOTIFY + MCI_CLOSE_EXIT) ;
  101.  
  102.   if (ulCloseFlags > 0)
  103.       return MCIERR_INVALID_FLAG;
  104.  
  105.   /****************************************
  106.   * If There are any Pending Notifies
  107.   * Post Abort Message for Those Operations
  108.   *****************************************/
  109.  
  110.   GetNotifyAbortAccess( ulpInstance, &ulAbortNotify );
  111.  
  112.   /******************************************************
  113.   * Fix for MMPM/2 AVC--they do repeated close and after
  114.   * approximately 80 closes, due to some OS/2 scheduling
  115.   * quirk, close would free the instance before the thread
  116.   * finished processing.  Therefore, require close to
  117.   * acquire the exclusive semaphore before freeing
  118.   * instance.
  119.   ********************************************************/
  120.  
  121.  
  122.    DosRequestMutexSem( ulpInstance->hmtxCloseAccess, -1 );
  123.  
  124.    /* Release semaphore since this will be the last command for this instance */
  125.  
  126.    DosReleaseMutexSem( ulpInstance->hmtxCloseAccess );
  127.  
  128.  
  129.  
  130.   if ( ulAbortNotify == TRUE)
  131.      {
  132.  
  133.      /* Stop the command on another thread */
  134.  
  135.      GenericThreadAbort( ulpInstance, pFuncBlock, ulParam1  );
  136.  
  137.  
  138. //     if ( ulpInstance->usNotPendingMsg == MCI_SAVE )
  139. //        {
  140. //        /******************************************
  141. //        * Save is a non-interruptible operation
  142. //        * wait for completion
  143. //        ******************************************/
  144. //
  145. //        DosWaitEventSem( ulpInstance->hThreadSem, (ULONG ) -1 );
  146. //
  147. //        }
  148. //      else
  149. //        {
  150. //        /******************************************
  151. //        * If any other operation is processing, then
  152. //        * terminate them (i.e. even if we are
  153. //        * recording, the user does not want to save
  154. //        * the file so just send the aborted message
  155. //        ******************************************/
  156. //
  157. //        PostMDMMessage (MCI_NOTIFY_ABORTED,
  158. //                        ulpInstance->usNotPendingMsg,
  159. //                        pFuncBlock);
  160. //
  161. //        /***********************************************
  162. //        * Both play and record will create a thread.
  163. //        * We need to ensure that the thread will be
  164. //        * removed on a close.
  165. //        * If this is an exit list, a stop will cause a
  166. //        * hang since some necessary threads will not
  167. //        * exist anymore.
  168. //        ************************************************/
  169. //
  170. //      if (  !(ulParam1 & MCI_CLOSE_EXIT)  )
  171. //         {
  172. //         /* Stop the command on another thread */
  173. //
  174. //         ThreadedStop( ulpInstance );
  175. //         }
  176. //
  177. //        ulpInstance->usNotifyPending = FALSE;
  178. //
  179. //        }
  180.      } /* Pending Notifies */
  181.  
  182.   /***************************************
  183.   * Destroy the Stream if we have
  184.   * created one
  185.   ***************************************/
  186.  
  187.   if (ulpInstance->StreamInfo.hStream != (ULONG) NULL)
  188.      {
  189.      ulrc = DestroyStream ( &ulpInstance->StreamInfo.hStream);
  190.      }
  191.  
  192.  
  193.   /************************************************
  194.   * If a file was previously opened then close it
  195.   * (however, if it was opened with the OPEN_MMIO
  196.   * flag, then don't close it.  That is the
  197.   * applications responsibility).
  198.   ************************************************/
  199.  
  200.   ulrc = CloseFile( ulpInstance );
  201.  
  202.   if ( ulrc )
  203.      {
  204.      return ( ulrc );
  205.      }
  206.  
  207.   /*------------------------------------------
  208.   * Free the memory of any cuepoints we have
  209.   * created.
  210.   *------------------------------------------*/
  211.  
  212.   if ( (ulpInstance->usCuePt == TRUE) ||
  213.        (ulpInstance->usCuePt == EVENT_ENABLED))
  214.      {
  215.      pCuePoint = CUEPOINT;
  216.  
  217.      while ( pCuePoint )
  218.         {
  219.         pTempCuePoint = pCuePoint;
  220.         pCuePoint = pCuePoint->pNextEVCB;
  221.         CleanUp ((PVOID) pTempCuePoint);
  222.         } /* while there are cue points to remove */
  223.  
  224.      } /* if we have cue points in use */
  225.  
  226.   /* Remove any undo nodes if they were allocated */
  227.  
  228.   RemoveUndoNodes( ulpInstance );
  229.  
  230.  
  231.  
  232.   /*******************************************
  233.   * Break The Default Amp/Mixer Connection
  234.   * The connected device will not allow a close
  235.   * before the connection is broken.
  236.   ********************************************/
  237.  
  238.   ulrc = mciConnection (ulpInstance->usWaveDeviceID,
  239.                         1,
  240.                         ulpInstance->usAmpDeviceID,
  241.                         1,
  242.                         MCI_BREAKCONNECTION);
  243.  
  244.   /****************************************
  245.   * Close The what we are connected to.
  246.   * Most often this will be the amp/mixer.
  247.   * However, if we are connected to another
  248.   * device, close it.  This call will remove
  249.   * any ability to talk to the audio device.
  250.   *****************************************/
  251.  
  252.   ulrc = mciSendCommand ((WORD)ulpInstance->usAmpDeviceID,
  253.                          MCI_CLOSE,
  254.                          MCI_WAIT,
  255.                          0,
  256.                          0);
  257.  
  258.   /*******************************************
  259.   * Close Internal Semaphores
  260.   *******************************************/
  261.   DosCloseEventSem (ulpInstance->hEventSem);
  262.   DosCloseEventSem (ulpInstance->hThreadSem);
  263.   DosCloseMutexSem (ulpInstance->hmtxDataAccess);
  264.   DosCloseMutexSem (ulpInstance->hmtxNotifyAccess);
  265.  
  266. // avc
  267.   DosCloseMutexSem (ulpInstance->hmtxCloseAccess);
  268.  
  269.  
  270.   /*****************************************
  271.   * Post Close Complete message If needed
  272.   *****************************************/
  273.  
  274.   if (ulParam1 & MCI_NOTIFY)
  275.      {
  276.       PostMDMMessage ( MCI_NOTIFY_SUCCESSFUL, MCI_CLOSE, pFuncBlock);
  277.      }
  278.  
  279.   /*******************************************
  280.   * Free Thread Parm Block & Assoc Pointers
  281.   *******************************************/
  282.  
  283.   CleanUp ((PVOID) pFuncBlock->pInstance);
  284.  
  285.   return (MCIERR_SUCCESS);     // Return Success
  286. } /* MCIClose */
  287.  
  288.