home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* */
- /* SOURCE FILE NAME: CDAUDPRO.C */
- /* */
- /* DESCRIPTIVE NAME: CD AUDIO MCI DRIVER PROCESS COMMANDS */
- /* */
- /* COPYRIGHT: (c) IBM Corp. 1991 - 1993 */
- /* */
- /* FUNCTION: This file contains the hardware independent code that */
- /* PROCESS commands for the CD Audio MCI Driver uses. */
- /* The entry point to the DLL is CDAUDIO.C */
- /* */
- /* NOTES: The hardware dependent code is found in file IBMCDROM.C. */
- /* */
- /* OTHER FUNCTIONS: */
- /* ProcClose - process MCI_CLOSE command. */
- /* ProcConnector - process MCI_CONNECTOR command. */
- /* ProcCue - process MCI_CUE command. */
- /* ProcCuePoint - process MCI_SET_CUEPOINT command. */
- /* ProcGeneral - process pass through MCI commands. */
- /* ProcCaps - process MCI_GETDEVCAPS command. */
- /* ProcInfo - process MCI_INFO command. */
- /* ProcMAudio - process MCI_MASTERAUDIO command. */
- /* ProcOpen - process MCI_OPEN command. */
- /* ProcPause - process MCI_PAUSE command. */
- /* ProcPlay - process MCI_PLAY command. */
- /* ProcPosAdvise - process MCI_SET_POSITION_ADVISE command. */
- /* ProcRestore - process MCIDRV_RESTORE command. */
- /* ProcResume - process MCI_RESUME command. */
- /* ProcSave - process MCIDRV_SAVE command. */
- /* ProcSeek - process MCI_SEEK command. */
- /* ProcSet - process MCI_SET command. */
- /* ProcSetSync - process MCI_SET_SYNC_OFFSET command. */
- /* ProcStatus - process MCI_STATUS command. */
- /* ProcStop - process MCI_STOP command. */
- /* ProcSync - process MCIDRV_SYNC command. */
- /* */
- /* */
- /****************************************************************************/
-
- #define INCL_DOSERRORS
- #define INCL_DOSPROCESS
- #define INCL_DOSMEMMGR
- #define INCL_DOSMODULEMGR
- #define INCL_DOSSEMAPHORES
- #include <os2.h>
- #include <string.h>
- #define INCL_MCIOS2
- #include <os2me.h>
- #include <cdaudos2.h>
- #include "cdaudibm.h"
- #include <ctype.h>
- #include "hhpheap.h"
-
- extern PVOID CDMC_hHeap;
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcClose */
- /* */
- /* DESCRIPTIVE NAME: Process Close. */
- /* */
- /* FUNCTION: Process MCI_CLOSE command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG *pulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* USHORT usUserParm -- User Parameter for mciDriverNotify. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcClose(PINST pInst, ULONG *pulParam1, PVOID pParam2, USHORT usUserParm)
- {
- ULONG rc, ulP1Temp;
-
- /* send close command to VSD, remove non-VSD flags */
- ulP1Temp = (*pulParam1 & ~(MCI_NOTIFY | MCI_CLOSE_EXIT)) | MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_CLOSE, &ulP1Temp, pParam2, 0);
-
- if (!rc)
- {
- pInst->valid[0] = ' '; //invalidate instance
-
- /* free up memory */
- DosCloseMutexSem(pInst->hInstSem);
-
- if (pInst->ulTrackInfoSize)
- HhpFreeMem(CDMC_hHeap, pInst->pTrackInfo);
-
- /* send notification before destroying device context information */
- if (*pulParam1 & MCI_NOTIFY)
- {
- *pulParam1 ^= MCI_NOTIFY;
- *pulParam1 |= MCI_WAIT;
- mdmDriverNotify(pInst->usDeviceID,
- ((MCI_GENERIC_PARMS *)pParam2)->hwndCallback, MM_MCINOTIFY,
- usUserParm, MAKEULONG(MCI_CLOSE, MCI_NOTIFY_SUCCESSFUL));
- } /* of if notify */
-
- HhpFreeMem(CDMC_hHeap, pInst);
- } /* of if no error from VSD */
-
- return(rc);
-
- } /* of ProcClose() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcConnector */
- /* */
- /* DESCRIPTIVE NAME: Process Connector. */
- /* */
- /* FUNCTION: Process MCI_CONNECTOR command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_INVALID_CONNECTOR_INDEX -- Invalid connector specified. */
- /* MCIERR_INVALID_CONNECTOR_TYPE -- Invalid connector specified. */
- /* MCIERR_UNSUPPORTED_CONN_TYPE -- Unsupported connector specified. */
- /* MCIERR_FLAGS_NOT_COMPATIBLE -- Invalid flag combinations. */
- /* MCIERR_INVALID_FLAG -- Unknown or unsupported flag. */
- /* MCIERR_MISSING_FLAG -- Flag is needed. */
- /* MCIERR_CANNOT_LOAD_DRIVER -- Unable to load VSD. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcConnector(PINST pInst, ULONG ulParam1, MCI_CONNECTOR_PARMS *pParam2)
- {
- ULONG rc;
- USHORT cnt = 0;
- ULONG ulType, ulIndex;
-
- rc = ValState(pInst);
- if ((rc != MCIERR_INSTANCE_INACTIVE) &&
- (ulParam1 & MCI_DISABLE_CONNECTOR ||
- ulParam1 & MCI_QUERY_CONNECTOR_STATUS))
- rc = MCIERR_SUCCESS;
-
- /********* check flags **********/
- if (!rc)
- {
- /* check exclusive flags */
- if (ulParam1 & MCI_ENABLE_CONNECTOR)
- cnt++;
- if (ulParam1 & MCI_DISABLE_CONNECTOR)
- cnt++;
- if (ulParam1 & MCI_QUERY_CONNECTOR_STATUS)
- cnt++;
-
- /* validate flags */
- if (!cnt)
- rc = MCIERR_MISSING_FLAG;
- else if (cnt > 1)
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
- else
- {
- ulType = ulParam1 & WAIT_NOTIFY_MASK;
- if (ulType & (0xFFFFFFFF ^
- (MCI_ENABLE_CONNECTOR | MCI_DISABLE_CONNECTOR |
- MCI_QUERY_CONNECTOR_STATUS |
- MCI_CONNECTOR_TYPE | MCI_CONNECTOR_INDEX)))
- rc = MCIERR_INVALID_FLAG;
- }
- } /* of if no error */
-
- /********* get connector index **********/
- if (!rc)
- {
- if (ulType & MCI_CONNECTOR_INDEX)
- ulIndex = pParam2->ulConnectorIndex;
- else
- ulIndex = 1; // set default
-
- /* get type of channel */
- /* This example assumes that there is only one connector, */
- /* the internal DAC or headphone. */
- if (ulParam1 & MCI_CONNECTOR_TYPE)
- if (pParam2->ulConnectorType == MCI_HEADPHONES_CONNECTOR)
- {
- if (ulIndex != 1)
- rc = MCIERR_INVALID_CONNECTOR_INDEX;
- }
- else
- if (pParam2->ulConnectorType > MCI_UNIVERSAL_CONNECTOR)
- rc = MCIERR_INVALID_CONNECTOR_TYPE;
- else
- rc = MCIERR_UNSUPPORTED_CONN_TYPE;
- else /* no type is declared, use absolute numbers */
- if (ulIndex != 1)
- rc = MCIERR_INVALID_CONNECTOR_INDEX;
- } /* of if no error */
-
- /****** process request ********/
- if (!rc)
- {
- if (ulType & MCI_QUERY_CONNECTOR_STATUS)
- {
- if (pInst->ulMode & CDMC_INTDAC)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- ULONG_HIWD(rc) = MCI_TRUE_FALSE_RETURN; // Adjust rc type
- }
- else
- rc = SetConnector(pInst, ulType);
- } /* of if no error */
-
- return(rc);
-
- } /* of ProcConnector() */
-
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcCue */
- /* */
- /* DESCRIPTIVE NAME: Process Cue. */
- /* */
- /* FUNCTION: Process MCI_CUE command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_PARAM_OVERFLOW -- Invalid PARMS pointer. */
- /* MCIERR_INVALID_FLAG -- Unknown flag. */
- /* MCIERR_UNSUPPORTED_FLAG -- Flag not supported by this MCD. */
- /* MCIERR_FLAGS_NOT_COMPATIBLE -- Invalid flag combinations. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcCue(PINST pInst, ULONG ulParam1)
- {
- ULONG rc, ulFlags;
-
- rc = ValState(pInst);
-
- if (!rc)
- {
- /* The CD Audio MCI Driver does not support MCI_RECORD */
-
- ulFlags = ulParam1 & WAIT_NOTIFY_MASK;
-
- switch (ulFlags)
- {
- case MCI_CUE_OUTPUT :
- /* call VSD (Vendor Specific Driver), *
- * the hardware specific MCI Driver */
- pInst->usStatus = STOPPED;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_CUE, 0L, 0L, 0);
- if (rc)
- rc = vsdResponse(pInst, rc);
-
- break;
- case MCI_CUE_OUTPUT | MCI_CUE_INPUT :
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
- break;
- case MCI_CUE_INPUT : // CD MCI Driver doesn't support MCI_RECORD
- rc = MCIERR_UNSUPPORTED_FLAG;
- break;
- case 0 :
- rc = MCIERR_MISSING_FLAG;
- break;
- default :
- rc = MCIERR_INVALID_FLAG;
-
- } /* of switch */
- } /* if drive is ready for command */
-
- return(rc);
-
- } /* of ProcCue() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcCuePoint */
- /* */
- /* DESCRIPTIVE NAME: Process Cue Point */
- /* */
- /* FUNCTION: Process MCI_SET_CUEPOINT command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_OUTOFRANGE -- event does not exist. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_FLAGS_NOT_COMPATIBLE -- Invalid flag combinations. */
- /* MCIERR_INVALID_FLAG -- Unknown or unsupported flag. */
- /* MCIERR_INVALID_CUEPOINT -- unable to locate event. */
- /* MCIERR_CUEPOINT_LIMIT_REACHED -- no more room to add events. */
- /* MCIERR_DUPLICATE_CUEPOINT -- duplicate cuepoint. */
- /* MCIERR_INVALID_CALLBACK_HANDLE -- invalid call back handle. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcCuePoint(PINST pInst, ULONG ulParam1, MCI_CUEPOINT_PARMS *pParam2)
- {
- ULONG rc, ulTime, ulFlags;
- MCI_CUEPOINT_PARMS recCuePoint;
- MCI_STATUS_PARMS recStatus;
- int i;
- PID pid;
- TID tid;
-
- rc = ValState(pInst);
-
- /* Make sure disc is present before you rely on cache */
- if (!rc)
- {
- recStatus.ulItem = MCI_STATUS_POSITION;
- ulFlags = MCI_STATUS_ITEM | MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_STATUS,
- &ulFlags, &recStatus, 0);
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc);
- } /* of if no error */
-
- /* if flag doesn't require an active/ready state, process it */
- if (!(ulParam1 & MCI_SET_CUEPOINT_ON) && rc != MCIERR_INSTANCE_INACTIVE)
- rc = MCIERR_SUCCESS;
-
- /* validate callback handle */
- if (!rc && !(ulParam1 & MCI_NOTIFY))
- if (!WinQueryWindowProcess(pParam2->hwndCallback, &pid, &tid))
- rc = MCIERR_INVALID_CALLBACK_HANDLE;
-
- if (!ULONG_LOWD(rc))
- {
- ulParam1 &= WAIT_NOTIFY_MASK;
- memcpy(&recCuePoint, pParam2, sizeof(MCI_CUEPOINT_PARMS));
-
- switch(ulParam1)
- {
- case MCI_SET_CUEPOINT_ON :
- rc = SetCuePoint(pInst, &recCuePoint);
- break;
- case MCI_SET_CUEPOINT_OFF :
- /* get time */
- ulTime = GetTimeAddr(pInst, pParam2->ulCuepoint, TRUE);
- if (ulTime == (ULONG) -1L)
- rc = MCIERR_OUTOFRANGE; // invalid track number
- else
- {
- ulTime += pInst->ulOffset;
-
- /* find requested cuepoint and disable */
- for (i=0; i < CDMCD_CUEPOINT_MAX; i++)
- if (pInst->arrCuePoint[i] == ulTime)
- break;
-
- if (i == CDMCD_CUEPOINT_MAX)
- rc = MCIERR_INVALID_CUEPOINT;
- else
- {
- pInst->arrCuePoint[i] = (ULONG) -1L;
- recCuePoint.ulCuepoint = ulTime;
- ulFlags = MCI_SET_CUEPOINT_OFF | MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_SET_CUEPOINT,
- &ulFlags, &recCuePoint, 0);
-
- } /* of else found cuepoint */
- } /* of else no error, find cuepoint */
- break;
- case MCI_SET_CUEPOINT_ON | MCI_SET_CUEPOINT_OFF :
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
- break;
- case 0 :
- rc = MCIERR_MISSING_FLAG;
- break;
- default :
- rc = MCIERR_INVALID_FLAG;
-
- } /* of switch */
- } /* of if no error */
-
- if (rc)
- rc = vsdResponse(pInst, rc);
-
- return(rc);
-
- } /* of ProcCuePoint() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcGeneral */
- /* */
- /* DESCRIPTIVE NAME: Process General commands. */
- /* */
- /* FUNCTION: Process any MCI command messages that the MCI does not */
- /* handle but are completely handled by the hardware specific */
- /* MCI Driver. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* USHORT usMessage -- requested action to be performed. */
- /* ULONG *pulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* USHORT usUserParm -- User Parameter for mciDriverNotify. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcGeneral(PINST pInst, USHORT usMessage, ULONG *pulParam1,
- PVOID pParam2, USHORT usUserParm)
- {
- ULONG rc = MCIERR_SUCCESS;
- ULONG ulP1Temp;
- PVOID pTemp;
-
- /* validate pointers within the pParam2 structure, if known */
- switch (usMessage)
- {
- case MCI_ESCAPE :
- /* check string pointer for validity */
- rc = ValPointer(((MCI_ESCAPE_PARMS *)pParam2)->pszCommand,
- sizeof(BYTE));
- break;
- case MCI_GETTOC :
- /* validate TOC buffer pointer for existence & space for 1 entry */
- if (ValPointer(((MCI_TOC_PARMS *)pParam2)->pBuf,
- sizeof(MCI_TOC_REC)))
- ((MCI_TOC_PARMS *)pParam2)->ulBufSize = 0L; //invalid pointer
- ulP1Temp = *pulParam1;
- *pulParam1 = (*pulParam1 & WAIT_NOTIFY_MASK) | MCI_WAIT;
- break;
- case MCI_LOAD :
- pTemp = ((MCI_LOAD_PARMS *)pParam2)->pszElementName;
- if (pTemp != NULL)
- rc = ValPointer(pTemp, sizeof(BYTE));
- break;
- } /* of switch */
-
- /* validate state for message */
- if (!rc)
- {
- rc = ValState(pInst);
- /* protect GET TOC, let others slip by */
- if (rc == MCIERR_DEVICE_NOT_READY && usMessage != MCI_GETTOC)
- rc = MCIERR_SUCCESS;
- }
-
- if (!rc)
- {
- /* call VSD (Vendor Specific Driver), the hardware specific MCI Driver */
- rc = pInst->pMCIDriver(pInst->hHWMCID, usMessage, pulParam1,
- pParam2, usUserParm);
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc);
-
- } /* if drive is ready for command */
-
- if (usMessage == MCI_GETTOC)
- *pulParam1 = ulP1Temp; // Restore original flags
-
- return(rc);
-
- } /* of ProcGeneral() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcCaps */
- /* */
- /* DESCRIPTIVE NAME: Process Capabilities */
- /* */
- /* FUNCTION: Process MCI_GETDEVCAPS command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_FLAGS_NOT_COMPATIBLE -- invalid combinations. */
- /* MCIERR_PARAM_OVERFLOW -- Invalid PARMS pointer. */
- /* MCIERR_INVALID_FLAG -- No message value. */
- /* MCIERR_INVALID_ITEM_FLAG -- Invalid capability item. */
- /* */
- /* NOTES: This function returns the drives capabilities, not those of the */
- /* component nor of the instance. */
- /* */
- /****************************************************************************/
-
- ULONG ProcCaps(PINST pInst, ULONG ulParam1, MCI_GETDEVCAPS_PARMS *pParam2)
- {
- ULONG rc;
-
- ulParam1 &= WAIT_NOTIFY_MASK;
- rc = MCIERR_SUCCESS; /* assume the best */
- ULONG_HIWD(rc) = MCI_TRUE_FALSE_RETURN; //Most will be T/F, adjust later
-
- switch(ulParam1)
- {
- case MCI_GETDEVCAPS_MESSAGE :
- switch(pParam2->usMessage)
- { /* check empty case */
- case 0 :
- pParam2->ulReturn = MCI_FALSE;
- rc = MCIERR_INVALID_FLAG;
- break;
- /* return true on those commands that the MCI Driver Does */
- case MCI_CLOSE : case MCI_CONNECTOR :
- case MCI_GETDEVCAPS : case MCI_INFO :
- case MCI_MASTERAUDIO : case MCI_OPEN :
- case MCI_SET : case MCI_SET_SYNC_OFFSET :
- case MCI_STATUS :
- pParam2->ulReturn = MCI_TRUE;
- break;
- /* return false on commands that the MCI Driver cannot do */
- case MCI_RECORD :
- pParam2->ulReturn = MCI_FALSE;
- break;
- /* return true on commands MCD does when streaming */
- case MCI_CUE : case MCI_PLAY :
- case MCI_PAUSE : case MCI_RESUME :
- case MCI_SEEK : case MCI_SET_CUEPOINT :
- case MCI_SET_POSITION_ADVISE : case MCI_STOP :
- if (pInst->ulMode & CDMC_CAN_STREAM)
- {
- pParam2->ulReturn = MCI_TRUE;
- break;
- }
- /* else drop down to default and ask VSD */
- default : /* ask VSD */
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_GETDEVCAPS,
- &ulParam1, pParam2, 0);
- if (!ULONG_LOWD(rc))
- ULONG_HIWD(rc) = MCI_TRUE_FALSE_RETURN;
- } /* of message switch */
- break;
- case MCI_GETDEVCAPS_ITEM :
- switch(pParam2->ulItem)
- { /* check empty case */
- case 0 :
- pParam2->ulReturn = MCI_FALSE;
- rc = MCIERR_INVALID_ITEM_FLAG;
- break;
- /* list the always TRUE */
- case MCI_GETDEVCAPS_CAN_PLAY :
- pParam2->ulReturn = MCI_TRUE;
- break;
- /* list the always FALSE */
- case MCI_GETDEVCAPS_CAN_RECORD :
- case MCI_GETDEVCAPS_CAN_RECORD_INSERT :
- case MCI_GETDEVCAPS_CAN_SAVE :
- case MCI_GETDEVCAPS_USES_FILES :
- case MCI_GETDEVCAPS_HAS_VIDEO :
- pParam2->ulReturn = MCI_FALSE;
- break;
- /* list the conditionals */
- case MCI_GETDEVCAPS_CAN_EJECT :
- if (pInst->usCaps & CDVSD_CAP_CAN_EJECT)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- case MCI_GETDEVCAPS_HAS_AUDIO :
- if (pInst->usCaps & CDVSD_CAP_HAS_AUDIO)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- case MCI_GETDEVCAPS_DEVICE_TYPE :
- pParam2->ulReturn = MCI_DEVTYPE_CD_AUDIO;
- ULONG_HIWD(rc) = MCI_DEVICENAME_RETURN;
- break;
- case MCI_GETDEVCAPS_CAN_LOCKEJECT :
- if (pInst->usCaps & CDVSD_CAP_CAN_LOCK)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- case MCI_GETDEVCAPS_CAN_PROCESS_INTERNAL :
- if (pInst->usCaps & CDVSD_CAP_HAS_DAC)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- case MCI_GETDEVCAPS_CAN_SETVOLUME :
- if (pInst->usCaps & CDVSD_CAP_CAN_VOLUME)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- case MCI_GETDEVCAPS_CAN_STREAM :
- if (pInst->usCaps & CDVSD_CAP_CAN_STREAM)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- case MCI_GETDEVCAPS_PREROLL_TYPE :
- pParam2->ulReturn = pInst->ulPrerollType;
- ULONG_HIWD(rc) = MCI_INTEGER_RETURNED;
- break;
- case MCI_GETDEVCAPS_PREROLL_TIME :
- pParam2->ulReturn = pInst->ulPrerollTime;
- ULONG_HIWD(rc) = MCI_INTEGER_RETURNED;
- break;
- default : // unknown flag, call VSD
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_GETDEVCAPS,
- &ulParam1, pParam2, 0);
-
- } /* of item switch */
- break;
- case MCI_GETDEVCAPS_MESSAGE | MCI_GETDEVCAPS_ITEM :
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
- break;
- case 0 :
- rc = MCIERR_MISSING_FLAG;
- break;
- default : // unknown flag, call VSD
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_GETDEVCAPS,
- &ulParam1, pParam2, 0);
-
- } /* of ulParam1 switch */
-
- return(rc);
-
- } /* of ProcCaps() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcInfo */
- /* */
- /* DESCRIPTIVE NAME: Process device Information. */
- /* */
- /* FUNCTION: Process MCI_INFO command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_INVALID_BUFFER -- Buffer size was too small. */
- /* MCIERR_PARAM_OVERFLOW -- Invalid PARMS pointer. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcInfo(PINST pInst, ULONG ulParam1, MCI_INFO_PARMS *pParam2)
- {
- ULONG rc, ulFlags;
- USHORT len=UPC_SIZE+1;
- BYTE buf[UPC_SIZE+1], cnt = 0;
- MCI_CD_ID *ptr;
- MCI_STATUS_PARMS recStatus;
-
- /* validate buffer pointer */
- if (ValPointer(pParam2->pszReturn, sizeof(BYTE)))
- pParam2->ulRetSize = 0L; //invalid pointer
-
- /* validate flags */
- rc = MCIERR_SUCCESS;
- ulParam1 &= WAIT_NOTIFY_MASK;
-
- if (ulParam1 & MCI_CD_INFO_ID)
- cnt++;
- if (ulParam1 & MCI_CD_INFO_UPC)
- cnt++;
- if (ulParam1 & MCI_INFO_PRODUCT)
- cnt++;
- if (cnt > 1)
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
-
- if (!rc)
- {
- /* If it is something that can be handled internally, */
- /* find the minimum length to return */
- if (ulParam1 == MCI_CD_INFO_ID || ulParam1 == MCI_CD_INFO_UPC)
- {
- if (pInst->usStatus < REGDISC)
- rc = MCIERR_DEVICE_NOT_READY;
-
- /* Make sure disc is present before you rely on cache */
- else
- {
- recStatus.ulItem = MCI_STATUS_POSITION;
- ulFlags = MCI_STATUS_ITEM | MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_STATUS,
- &ulFlags, &recStatus, 0);
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc);
- } /* of else disc was registered */
-
- if (pParam2->ulRetSize < UPC_SIZE+1)
- len = (USHORT) pParam2->ulRetSize;
- else
- len = UPC_SIZE+1;
- } /* of if internal process flag */
- } /* of if no error */
-
- if (!rc)
- /* process flag */
- switch(ulParam1)
- {
- case MCI_CD_INFO_ID :
- /* formulate in the buffer */
- ptr = (MCI_CD_ID *)buf;
- ptr->Mode = 1; // ID = 1
- ptr->usTrack1 = (USHORT) pInst->recTrack.TrackRecArr->ulStartAddr;
- ptr->NumTracks = (BYTE) (pInst->recDisc.HighestTrackNum -
- pInst->recDisc.LowestTrackNum + 1);
- /* lead-out track is end address for last track */
- ptr->ulLeadOut = (pInst->recTrack.TrackRecArr +
- (ptr->NumTracks - 1))->ulEndAddr;
-
- if (len)
- memcpy(pParam2->pszReturn, buf, len);
-
- if (len == UPC_SIZE+1)
- rc = MCIERR_SUCCESS;
- else
- rc = MCIERR_INVALID_BUFFER;
- pParam2->ulRetSize = UPC_SIZE+1;
-
- break;
- case MCI_CD_INFO_UPC :
- if (len) //if zero then invalid buffer
- {
- buf[0] = 0;
- memcpy(buf+1, pInst->recDisc.UPC, UPC_SIZE);
- memcpy(pParam2->pszReturn, buf, len);
- }
-
- if (len == UPC_SIZE+1)
- rc = MCIERR_SUCCESS;
- else
- rc = MCIERR_INVALID_BUFFER;
- pParam2->ulRetSize = UPC_SIZE+1;
- break;
- case 0 :
- rc = MCIERR_MISSING_FLAG;
- break;
- default :
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_INFO, &ulParam1,
- pParam2, 0);
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc);
-
- } /* of switch */
-
- return(rc);
-
- } /* of ProcInfo() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcMAudio */
- /* */
- /* DESCRIPTIVE NAME: Process Master Audio */
- /* */
- /* FUNCTION: Process MCI_MASTERAUDIO command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* MCI_MASTERAUDIO_PARMS *pParam2 -- pointer to structure. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_FLAGS_NOT_COMPATIBLE -- Flags not compatible. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcMAudio(PINST pInst, ULONG ulParam1, MCI_MASTERAUDIO_PARMS *pParam2)
- {
- ULONG rc = MCIERR_SUCCESS;
- ULONG ulSetParam1;
- ULONG ulType;
- MCI_SET_PARMS recSet;
-
- /* eliminate general reserved flags */
- ulType = ulParam1 & WAIT_NOTIFY_MASK;
-
- switch(ulType)
- {
- case MCI_MASTERVOL:
- if (pParam2->ulMasterVolume > 100)
- pInst->ulMasterVolume = 100;
- else
- pInst->ulMasterVolume = pParam2->ulMasterVolume;
- break;
- case MCI_SPEAKERS | MCI_ON:
- pInst->ulMode |= CDMC_SPEAKER;
- break;
- case MCI_SPEAKERS | MCI_OFF:
- if (pInst->ulMode & CDMC_SPEAKER)
- pInst->ulMode ^= CDMC_SPEAKER;
- break;
- case MCI_HEADPHONES | MCI_ON:
- pInst->ulMode |= CDMC_HEADPHONE;
- break;
- case MCI_HEADPHONES | MCI_OFF:
- if (pInst->ulMode & CDMC_HEADPHONE)
- pInst->ulMode ^= CDMC_HEADPHONE;
- break;
- default :
- if (ulType & MCI_ON && ulType & MCI_OFF)
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
- else
- rc = MCIERR_INVALID_FLAG;
- } /* of switch */
-
- /* update volume settings if needed */
- if (!rc)
- {
- rc = ValState(pInst);
- if (!rc || rc == MCIERR_INVALID_MEDIA_TYPE)
- {
- /* fill in Set record structure so that ProcSet() will respond */
- recSet.ulAudio = MCI_SET_AUDIO_LEFT;
- recSet.ulLevel = (ULONG) VOL_LEFT(pInst->ulLevel);
- recSet.ulOver = 0L;
- ulSetParam1 = MCI_SET_AUDIO | MCI_SET_VOLUME | MCI_WAIT;
-
- ProcSet(pInst, &ulSetParam1, &recSet);
-
- } /* is state is such that volume can be adjusted */
- else
- rc = MCIERR_SUCCESS; // okay if not setting hardware
- } /* no error from validating flags */
-
- return(rc);
-
- } /* of ProcMAudio() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcOpen */
- /* */
- /* DESCRIPTIVE NAME: Process Open. */
- /* */
- /* FUNCTION: Process MCI_OPEN command. */
- /* */
- /* PARAMETERS: */
- /* ULONG *pulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* USHORT usUserParm -- user defined parameter. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- Action completed without error. */
- /* MCIERR_OUTOFRANGE -- Cannot stream on stream only hardware. */
- /* MCIERR_INI_FILE -- Corrupted INI file, drive is not CD-ROM drive. */
- /* MCIERR_OUT_OF_MEMORY -- Could not create instance or semaphore. */
- /* MCIERR_INVALID_DEVICE_NAME -- Illegal drive name. */
- /* MCIERR_PARAM_OVERFLOW -- Invalid PARMS pointer. */
- /* MCIERR_CANNOT_LOAD_DRIVER -- Unable to load VSD. */
- /* MCIERR_INVALID_FLAG -- Flag not supported by the VSD. */
- /* MCIERR_DEVICE_LOCKED -- CD-ROM drive, previously opened exclusively.*/
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcOpen(ULONG *pulParam1, MMDRV_OPEN_PARMS *pParam2, USHORT usUserParm)
- {
- ULONG rc;
- ULONG rsp, ulDevParmLen, usNotify = FALSE;
- PINST pInst = NULL;
- CHAR buf[LOAD_MOD_BUF_LEN];
- CHAR *pMCDToken, *pDummy, CDDrive;
- PVOID pMCDParm;
- int i;
-
- /* validate pointers */
- rc = ValPointer(pParam2->pDevParm, sizeof(BYTE));
-
- /* MCI_OPEN is from MDM, accept all flags as valid */
-
- /* get memory and pointer to instance structure */
- if (!rc)
- {
- pInst = HhpAllocMem(CDMC_hHeap, sizeof(struct instance_state));
-
- /* create semaphore so only one command will access instance table */
- if (pInst == NULL)
- rc = MCIERR_OUT_OF_MEMORY;
- else
- if (DosCreateMutexSem((PSZ) NULL, &pInst->hInstSem, 0L, FALSE))
- rc = MCIERR_OUT_OF_MEMORY;
- } /* of if no error to get memory */
-
- if (!rc)
- { /* instance entry created */
- pInst->usDeviceID = pParam2->usDeviceID;
- pInst->ulMasterVolume = (ULONG) -1L;
- pInst->usStatus = UNLOADED;
- /* set all fields in ulMode */
- pInst->ulMode = CDMC_MMTIME | CDMC_ALL_CH;
- pInst->hHWMCID = NULL;
- pInst->ulOffset = 0L;
- pInst->ulLevel = 0x00640064; /* set to 100% volume */
- pInst->ulTrackInfoSize = 0L;
- pInst->usDeviceOrd = pParam2->usDeviceOrd;
- pInst->recDisc.DiscID.Mode = (BYTE) -1; /* used as first time flag */
- CDDrive = 0;
- memcpy(pInst->valid, "CDDA", VALLEN);
-
- /* process shareable flag */
- if (*pulParam1 & MCI_OPEN_SHAREABLE)
- {
- pInst->ulMode |= CDMC_SHAREABLE;
- *pulParam1 ^= MCI_OPEN_SHAREABLE; // remove non-VSD flag
- }
-
- /* init cuepoint array */
- for (i=0; i < CDMCD_CUEPOINT_MAX; i++)
- pInst->arrCuePoint[i] = (ULONG) -1L; //clear flag
-
- /* Get and Validate drive letter */
- /* copy string so that it doesn't get disturb for the VSD */
- ulDevParmLen = strlen(pParam2->pDevParm) + 2;
- pMCDParm = (PSZ) HhpAllocMem(CDMC_hHeap, ulDevParmLen);
- strcpy((CHAR *)pMCDParm, pParam2->pDevParm);
- parse_DevParm((CHAR *)pMCDParm, &pMCDToken, &pDummy);
- if (*(pMCDToken + 1) == '\0' || *(pMCDToken + 1) == ':')
- CDDrive = *pMCDToken;
- HhpFreeMem(CDMC_hHeap, pMCDParm);
-
- if (CDDrive < 'A' || CDDrive >'Z')
- rc = MCIERR_INVALID_DEVICE_NAME; /* of if invalid drive letter */
- else
- {
- /* load hardware specific MCI Driver (VSD -- Vendor Specific Driver)*/
- /* fail if does not load */
- rsp = DosLoadModule(buf, LOAD_MOD_BUF_LEN,
- pParam2->szDevDLLName, &pInst->hMod);
- if (!rsp)
- rsp = DosQueryProcAddr(pInst->hMod, 0L, "vsdDriverEntry",
- (PFN *) &pInst->pMCIDriver);
- if (rsp)
- rc = MCIERR_CANNOT_LOAD_DRIVER;
- else
- {
- /* open Vendor Specific Driver */
- if (*pulParam1 & MCI_NOTIFY)
- {
- usNotify = TRUE;
- *pulParam1 ^= MCI_NOTIFY; //remove flag, don't send notify twice
- }
-
- *pulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(NULL, MCI_OPEN, pulParam1, pParam2, 0);
-
- } /* of else VSD loaded */
- } /* of else valid drive letter */
-
- if (!rc)
- {
- /* get and pass instance handles */
- pInst->hHWMCID = pParam2->pInstance;
- pParam2->pInstance = (PVOID) pInst;
- pInst->usStatus = OPENED;
-
- /* Register Hardware & streaming capabilities */
- rc = Register(pInst);
-
- }
- } /* of if no memory problem creating instance structure */
-
- if (rc)
- {
- if (pInst != NULL) // if memory was created
- {
- DosCloseMutexSem(pInst->hInstSem);
- HhpFreeMem(CDMC_hHeap, pInst);
- }
- } /* of if error */
- else
- {
- pInst->usStatus += SUSPEND; // go inactive until MDM issues a restore
-
- /*****************************************************************/
- /* If successful and notify is requested then send notification. */
- /* This is needed because the instance pointer (lpInstance) */
- /* in mciDriverEntry() is not valid on MCI_OPEN. */
- /*****************************************************************/
- if (usNotify)
- mdmDriverNotify(pInst->usDeviceID, pParam2->hwndCallback,
- MM_MCINOTIFY, usUserParm,
- MAKEULONG(MCI_OPEN, MCI_NOTIFY_SUCCESSFUL));
-
- } /* of else no error */
-
- return(rc);
-
- } /* of ProcOpen() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcPause */
- /* */
- /* DESCRIPTIVE NAME: Process Pause. */
- /* */
- /* FUNCTION: Process MCI_PAUSE command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcPause(PINST pInst, ULONG ulParam1)
- {
- ULONG rc;
-
- rc = ValState(pInst);
-
- /* if drive is not ready, ignore call */
- if (rc == MCIERR_DEVICE_NOT_READY)
- if (ulParam1 & WAIT_NOTIFY_MASK)
- return(MCIERR_INVALID_FLAG);
- else
- return(MCIERR_SUCCESS);
-
- /* validate flags */
- if (!rc && ulParam1 & WAIT_NOTIFY_MASK)
- rc = MCIERR_INVALID_FLAG;
-
- if (!rc)
- {
- switch(pInst->usStatus)
- {
- case PLAYING:
- pInst->usStatus = PAUSED;
-
- /* call VSD (Vendor Specific Driver) */
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_PAUSE, 0L, 0L, 0);
- if (rc)
- {
- pInst->usStatus = STOPPED;
- rc = vsdResponse(pInst, rc); //if error, process response
- }
- break;
- case PAUSED:
- /* already pausing */
- rc = MCIERR_SUCCESS;
- break;
- default : rc = MCIERR_SUCCESS; //pretend that we paused
-
- } /* of switch */
- } /* if drive is ready for command */
-
- return(rc);
-
- } /* of ProcPause() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcPlay */
- /* */
- /* DESCRIPTIVE NAME: Process Play. */
- /* */
- /* FUNCTION: Process MCI_PLAY command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG *pulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* USHORT usUserParm -- User Parameter for mciDriverNotify. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_OUTOFRANGE -- invalid track, or cannot reverse. */
- /* MCIERR_PARAM_OVERFLOW -- Invalid PARMS pointer. */
- /* MCIERR_NO_CONNECTION -- no way to play, no stream/DAC. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcPlay(PINST pInst, ULONG *pulParam1,
- MCI_PLAY_PARMS *pParam2, USHORT usUserParm)
- {
- ULONG rc, ulFlags;
- MCI_STATUS_PARMS recStatus;
- MCI_PLAY_PARMS recPlay;
-
- rc = ValState(pInst);
-
- /* validate flags */
- if (!rc && *pulParam1 & (0xFFFFFFFF ^
- (MCI_WAIT | MCI_NOTIFY | MCI_FROM | MCI_TO)))
- rc = MCIERR_INVALID_FLAG;
-
- if (!rc)
- {
- /* Make sure disc is present before you rely on cache */
- recStatus.ulItem = MCI_STATUS_POSITION;
- ulFlags = MCI_STATUS_ITEM | MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_STATUS,
- &ulFlags, &recStatus, 0);
- if (ULONG_LOWD(rc))
- {
- rc = vsdResponse(pInst, rc);
- if (!rc) //Disc Change, get starting address
- recStatus.ulReturn = pInst->ulStart_disk;
- }
- } /* of if no error */
-
- if (!rc)
- {
- /* get starting address */
- if (*pulParam1 & MCI_FROM)
- {
- recPlay.ulFrom = GetTimeAddr(pInst, pParam2->ulFrom, TRUE);
- if (recPlay.ulFrom == (ULONG) -1L)
- rc = MCIERR_OUTOFRANGE; // invalid track number
- else
- recPlay.ulFrom += pInst->ulOffset;
- } /* of if FROM */
- else
- { /* start at current position */
- recPlay.ulFrom = recStatus.ulReturn;
- }
-
- if (!rc)
- {
- /* get ending address */
- if (*pulParam1 & MCI_TO)
- {
- recPlay.ulTo = GetTimeAddr(pInst, pParam2->ulTo, TRUE);
- if (recPlay.ulTo == (ULONG) -1L)
- rc = MCIERR_OUTOFRANGE; // invalid track number
- else
- recPlay.ulTo += pInst->ulOffset;
- }
- else
- recPlay.ulTo = pInst->ulEnd_disk; /* no TO flag, goto end */
-
- /* check hardware start limitations */
- if (recPlay.ulFrom < pInst->ulMinStartTime)
- recPlay.ulFrom = pInst->ulMinStartTime;
- if (recPlay.ulTo < pInst->ulMinStartTime)
- recPlay.ulTo = pInst->ulMinStartTime;
-
- /* validate address */
- rc = ValAddress(pInst, &recPlay.ulFrom, &recPlay.ulTo, TRUE);
-
- } /* of if no error after getting starting address */
- } /* of if no error from validating state */
-
- /* Call the play command */
- if (rc)
- DosReleaseMutexSem(pInst->hInstSem);
- else
- {
- pInst->ulEnd_play = recPlay.ulTo;
- pInst->ulCur_pos = recPlay.ulFrom; //update current position
-
- if (pInst->ulMode & CDMC_INTDAC)
- {
- /* update instance prior to call */
- pInst->usStatus = PLAYING;
- recPlay.hwndCallback = pParam2->hwndCallback;
- DosReleaseMutexSem(pInst->hInstSem);
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_PLAY, pulParam1,
- &recPlay, usUserParm);
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc); //if error, process response
- }
- else
- {
- rc = MCIERR_NO_CONNECTION; //no internal DAC
- DosReleaseMutexSem(pInst->hInstSem);
- }
-
- /* if play terminated with an error then set to STOP */
- if (ULONG_LOWD(rc) && pInst->usStatus > NODISC)
- pInst->usStatus = STOPPED;
-
- } /* of else no error after validating addresses */
-
- return(rc);
-
- } /* of ProcPlay() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcPosAdvise */
- /* */
- /* DESCRIPTIVE NAME: Process Position Advise */
- /* */
- /* FUNCTION: Process MCI_SET_POSITION_ADVISE command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* USHORT usUserParm -- User passthru value. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- No Disc is present. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_FLAGS_NOT_COMPATIBLE -- Invalid flag combinations. */
- /* MCIERR_INVALID_FLAG -- Unknown or unsupported flag. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcPosAdvise(PINST pInst, ULONG ulParam1, MCI_POSITION_PARMS *pParam2)
- {
- ULONG rc, ulTime, ulFlags;
- MCI_POSITION_PARMS recPosition;
- MCI_STATUS_PARMS recStatus;
- PID pid;
- TID tid;
-
- rc = ValState(pInst);
-
- /* Make sure disc is present before you rely on cache */
- if (!rc)
- {
- recStatus.ulItem = MCI_STATUS_POSITION;
- ulFlags = MCI_STATUS_ITEM | MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_STATUS,
- &ulFlags, &recStatus, 0);
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc);
- } /* of if no error */
-
- /* if flag doesn't require an active/ready state, process it */
- if (!(ulParam1 & MCI_SET_POSITION_ADVISE_ON) &&
- rc != MCIERR_INSTANCE_INACTIVE)
- rc = MCIERR_SUCCESS;
-
- /* validate callback handle */
- if (!rc && !(ulParam1 & MCI_NOTIFY))
- if (!WinQueryWindowProcess(pParam2->hwndCallback, &pid, &tid))
- rc = MCIERR_INVALID_CALLBACK_HANDLE;
-
- if (!rc)
- {
- ulParam1 &= WAIT_NOTIFY_MASK;
-
- switch(ulParam1)
- {
- case MCI_SET_POSITION_ADVISE_ON :
- /* validate time */
- ulTime = GetTimeAddr(pInst, pParam2->ulUnits, TRUE);
-
- /* check for invalid track number or no position specified */
- if ((ulTime == (ULONG) -1L) || (ulTime == 0L))
- rc = MCIERR_OUTOFRANGE;
- else
- if (ulTime > pInst->ulEnd_disk)
- rc = MCIERR_OUTOFRANGE;
-
- /* enable position advise */
- if (!rc)
- {
- memcpy(&recPosition, pParam2, sizeof(MCI_POSITION_PARMS));
- recPosition.ulUnits = ulTime;
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_SET_POSITION_ADVISE,
- &ulParam1, &recPosition, 0);
-
- } /* of if no error, enable it */
- break;
- case MCI_SET_POSITION_ADVISE_OFF :
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_SET_POSITION_ADVISE,
- &ulParam1, 0L, 0);
- break;
- case MCI_SET_POSITION_ADVISE_ON | MCI_SET_POSITION_ADVISE_OFF :
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
- break;
- case 0 :
- rc = MCIERR_MISSING_FLAG;
- break;
- default :
- rc = MCIERR_INVALID_FLAG;
-
- } /* of switch */
- } /* of if no error */
-
- if (rc)
- rc = vsdResponse(pInst, rc);
-
- return(rc);
-
- } /* of ProcPosAdvise() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcRestore */
- /* */
- /* DESCRIPTIVE NAME: Process Restore. */
- /* */
- /* FUNCTION: Process MCIDRV_RESTORE command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_FILE_NOT_FOUND -- improper disc not loaded. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_OUT_OF_MEMORY -- Out of memory for thread. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcRestore(PINST pInst)
- {
- ULONG rc;
- MCI_CD_REGDISC_PARMS recDisc;
- USHORT usSameDisc = TRUE, usOldStatus;
-
- /* Set player the way it was */
- pInst->usStatus -= SUSPEND;
-
- if (pInst->usStatus <= NODISC)
- {
- rc = MCIERR_SUCCESS;
- pInst->usStatus = REGDRIVE; //reset because position is not known
-
- /* check if disc was inserted */
- ReRegister(pInst);
- }
- else // there was a disc when we saved
- {
- usOldStatus = pInst->usStatus; // retain original status
-
- /* Validate disc as same as old state */
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCIDRV_REGISTER_DISC,
- 0L, &recDisc, 0);
- if (rc)
- usSameDisc = FALSE;
- else
- if (memcmp(&pInst->recDisc.DiscID, &recDisc.DiscID, IDSIZE))
- usSameDisc = FALSE;
-
- /* get current master volume settings */
- QMAudio(pInst);
-
- /* set parameters on restore */
- pInst->recSave.ulEndPlay = pInst->ulEnd_play;
-
- /* set volume */
- if (pInst->ulMode & CDMC_LFT_CH && pInst->ulMode & CDMC_HEADPHONE)
- VOL_LEFT(pInst->recSave.ulLevel) = (USHORT)
- ((ULONG)VOL_LEFT(pInst->ulLevel) * pInst->ulMasterVolume / 100);
- else
- VOL_LEFT(pInst->recSave.ulLevel) = 0;
-
- if (pInst->ulMode & CDMC_RGT_CH && pInst->ulMode & CDMC_HEADPHONE)
- VOL_RIGHT(pInst->recSave.ulLevel) = (USHORT)
- ((ULONG)VOL_RIGHT(pInst->ulLevel) * pInst->ulMasterVolume / 100);
- else
- VOL_RIGHT(pInst->recSave.ulLevel) = 0;
-
- /* set restoring mode */
- if (!usSameDisc)
- pInst->recSave.ulMode = MCI_MODE_NOT_READY;
- else if (pInst->ulMode & CDMC_STREAM)
- pInst->recSave.ulMode = MCI_MODE_STOP;
- else
- switch (usOldStatus)
- {
- case PLAYING:
- pInst->recSave.ulMode = MCI_MODE_PLAY;
- break;
- case PAUSED:
- pInst->recSave.ulMode = MCI_MODE_PAUSE;
- break;
- default : // must be status = STOPPED
- pInst->recSave.ulMode = MCI_MODE_STOP;
-
- } /* of switch */
-
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCIDRV_RESTORE, 0L,
- &pInst->recSave, 0);
-
- if (rc)
- rc = vsdResponse(pInst, rc); //if error, process response
-
- if (!usSameDisc)
- rc = ReRegister(pInst); //accept and load new disc
-
- } /* of else there was a disc when we saved */
-
- return(MCIERR_SUCCESS);
-
- } /* of ProcRestore() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcResume */
- /* */
- /* DESCRIPTIVE NAME: Process Resume */
- /* */
- /* FUNCTION: Process MCI_RESUME command. Unpause after a Pause. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcResume(PINST pInst, ULONG ulParam1)
- {
- ULONG rc, ulFlags;
- MCI_STATUS_PARMS recStatus;
-
- rc = ValState(pInst);
-
- /* if drive is not ready, ignore call */
- if (rc == MCIERR_DEVICE_NOT_READY)
- if (ulParam1 & WAIT_NOTIFY_MASK)
- return(MCIERR_INVALID_FLAG);
- else
- return(MCIERR_SUCCESS);
-
- /* validate flags */
- if (!rc && ulParam1 & WAIT_NOTIFY_MASK)
- rc = MCIERR_INVALID_FLAG;
-
- if (!rc) /* make sure we are in a PAUSED state */
- if (pInst->usStatus != PAUSED)
- return(MCIERR_SUCCESS); // ignore call,
-
- if (!rc) /* Make sure disc is valid before resuming */
- {
- recStatus.ulItem = MCI_STATUS_POSITION;
- ulFlags = MCI_STATUS_ITEM | MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_STATUS,
- &ulFlags, &recStatus, 0);
- if (ULONG_LOWD(rc))
- {
- rc = vsdResponse(pInst, rc);
- return(rc); //if rc==MCIERR_SUCCESS means Disc Change
- } /* of if VSD reported an error */
- } /* if no error */
-
- if (!rc)
- {
- pInst->usStatus = PLAYING;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_RESUME, 0L, 0L, 0);
- if (ULONG_LOWD(rc))
- {
- pInst->usStatus = STOPPED;
- rc = vsdResponse(pInst, rc); //if error, process response
- }
- } /* of if no error */
-
- return(rc);
-
- } /* of ProcResume() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcSave */
- /* */
- /* DESCRIPTIVE NAME: Process Save. */
- /* */
- /* FUNCTION: Process MCI_SAVE command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcSave(PINST pInst)
- {
- ULONG rc;
-
- pInst->usStatus += SUSPEND;
-
- /* tell the VSD that it is being saved and get values */
- pInst->recSave.ulLevel = pInst->ulLevel;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCIDRV_SAVE, 0L, &pInst->recSave, 0);
-
- pInst->ulCur_pos = pInst->recSave.ulPosition;
-
- if (rc) /* info was not saved, restore will re-register */
- pInst->usStatus = NODISC + SUSPEND;
-
- return(MCIERR_SUCCESS);
-
- } /* of ProcSave() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcSeek */
- /* */
- /* DESCRIPTIVE NAME: Process Seek. */
- /* */
- /* FUNCTION: Process MCI_SEEK command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_OUTOFRANGE -- invalid track or address. */
- /* MCIERR_PARAM_OVERFLOW -- Invalid PARMS pointer. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcSeek(PINST pInst, ULONG ulParam1, MCI_SEEK_PARMS *pParam2)
- {
- ULONG rc = MCIERR_SUCCESS, ulFlags;
- MCI_SEEK_PARMS recSeek;
- MCI_STATUS_PARMS recStatus;
- ULONG ulType;
-
- rc = ValState(pInst);
-
- /* validate flags */
- if (!rc)
- if (ulParam1 & (0xFFFFFFFF ^
- (MCI_WAIT | MCI_NOTIFY | MCI_TO | MCI_TO_START | MCI_TO_END)))
- rc = MCIERR_INVALID_FLAG;
- else
- {
- /* Make sure disc is present before you rely on cache */
- recStatus.ulItem = MCI_STATUS_POSITION;
- ulFlags = MCI_STATUS_ITEM | MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_STATUS,
- &ulFlags, &recStatus, 0);
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc);
- }
-
- if (!rc)
- {
- ulType = ulParam1 & WAIT_NOTIFY_MASK;
- switch (ulType)
- {
- case MCI_TO_START : /* seek to first position */
- recSeek.ulTo = pInst->ulStart_disk;
- break;
- case MCI_TO_END : /* seek to last position */
- recSeek.ulTo = pInst->ulEnd_disk - MMT_FRAME;
- break;
- case 0L : /* No address specified, error */
- rc = MCIERR_MISSING_FLAG;
- break;
- case MCI_TO : /* seek to specified address */
- /* make sure it is a playable address */
- recSeek.ulTo = GetTimeAddr(pInst, pParam2->ulTo, TRUE);
- if (recSeek.ulTo == (ULONG) -1L)
- rc = MCIERR_OUTOFRANGE; // invalid track number
- else
- {
- recSeek.ulTo += pInst->ulOffset;
- rc = ValAddress(pInst, NULL, &recSeek.ulTo, FALSE);
- }
- break;
- default : /* unknown flag combination */
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
- } /* of switch() */
-
- if (!rc)
- { /* No error, set it up */
- /* check hardware start limitations */
- if (recSeek.ulTo < pInst->ulMinStartTime)
- recSeek.ulTo = pInst->ulMinStartTime;
-
- /* call VSD (Vendor Specific Driver) */
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_SEEK, 0L, &recSeek, 0);
-
- pInst->usStatus = STOPPED;
-
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc); //if error, process response
-
- } /* of if no error */
- } /* of if no error from validating state */
-
- return(rc);
-
- } /* of ProcSeek() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcSet */
- /* */
- /* DESCRIPTIVE NAME: Process Set. */
- /* */
- /* FUNCTION: Process MCI_SET command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG *pulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_PARAM_OVERFLOW -- Invalid PARMS pointer. */
- /* MCIERR_UNSUPPORTED_FLAG -- Flag not supported by this MCD. */
- /* MCIERR_INVALID_FLAG -- Unknown flag or value used. */
- /* MCIERR_SPEED_FORMAT_FLAG -- Unknown speed type specified. */
- /* MCIERR_OUT_OF_MEMORY -- Could not create thread. */
- /* MCIERR_INVALID_AUDIO_FLAG -- Unknown audio flag specified. */
- /* MCIERR_FLAGS_NOT_COMPATIBLE -- Conflicting Flags. */
- /* MCIERR_INVALID_TIME_FORMAT_FLAG -- Unknown time type specified. */
- /* */
- /* NOTES: Flags needing a valid pParam2 are checked in verify_entry() */
- /* */
- /****************************************************************************/
-
- ULONG ProcSet(PINST pInst, ULONG *pulParam1, MCI_SET_PARMS *pParam2)
- {
- ULONG rc, ulLevel, ulP1Temp;
- USHORT SemHolding = TRUE;
- ULONG ulMode;
- MCI_SET_PARMS recSet;
-
- rc = ValState(pInst);
- if (rc == MCIERR_INVALID_MEDIA_TYPE)
- rc = MCIERR_SUCCESS;
-
- /* validate flags */
- if (!rc)
- {
- ulP1Temp = *pulParam1 & WAIT_NOTIFY_MASK; //mask off N/W flags
- if (ulP1Temp & MCI_SET_VIDEO || ulP1Temp & MCI_SET_ITEM)
- rc = MCIERR_UNSUPPORTED_FLAG;
- else
- if (!(ulP1Temp) || // no flags,
- (!(ulP1Temp & MCI_SET_AUDIO) && // check flags needing
- (ulP1Temp & MCI_SET_VOLUME || // MCI_SET_AUDIO
- ulP1Temp & MCI_SET_ON || ulP1Temp & MCI_SET_OFF)))
- rc = MCIERR_MISSING_FLAG;
- } /* of if no error to validate first set of flags */
-
- if (!rc)
- {
- ulMode = pInst->ulMode;
- ulLevel = pInst->ulLevel;
-
- /* copy pParam2 structure to make changes */
- if (pParam2 != NULL)
- memcpy(&recSet, pParam2, sizeof(MCI_SET_PARMS));
-
- if (ulP1Temp & MCI_SET_SPEED_FORMAT)
- {
- ulP1Temp ^= MCI_SET_SPEED_FORMAT; // remove non VSD flag
- switch (pParam2->ulSpeedFormat)
- {
- case MCI_FORMAT_PERCENTAGE :
- ulMode |= CDMC_PERCENT;
- break;
- case MCI_FORMAT_FPS :
- if (ulMode & CDMC_PERCENT)
- ulMode ^= CDMC_PERCENT;
- break;
- default : rc = MCIERR_SPEED_FORMAT_FLAG;
-
- } /* of switch time format */
- } /* of if speed format */
-
- if (!rc && ulP1Temp & MCI_SET_TIME_FORMAT)
- {
- ulP1Temp ^= MCI_SET_TIME_FORMAT; // remove non VSD flag
- switch (pParam2->ulTimeFormat)
- {
- case MCI_FORMAT_MILLISECONDS :
- ulMode = ulMode & TIME_MODE_SET | CDMC_MILLSEC;
- break;
- case MCI_FORMAT_MMTIME :
- ulMode = ulMode & TIME_MODE_SET | CDMC_MMTIME;
- break;
- case MCI_FORMAT_MSF :
- ulMode = ulMode & TIME_MODE_SET | CDMC_REDBOOK;
- break;
- case MCI_FORMAT_TMSF :
- ulMode = ulMode & TIME_MODE_SET | CDMC_TMSF;
- break;
- default : rc = MCIERR_INVALID_TIME_FORMAT_FLAG;
-
- } /* of switch time format */
- } /* of if time format */
-
- if (!rc && ulP1Temp & MCI_SET_DOOR_LOCK && ulP1Temp & MCI_SET_DOOR_UNLOCK)
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
-
- if (!rc && ulP1Temp & MCI_SET_DOOR_OPEN && ulP1Temp & MCI_SET_DOOR_CLOSED)
- rc = MCIERR_FLAGS_NOT_COMPATIBLE;
-
- if (!rc && ulP1Temp & MCI_SET_AUDIO)
- rc = SetAudio(pInst, &ulP1Temp, &recSet, &ulMode, &ulLevel);
-
- /* process VSD flags, if they exist */
- if (!rc && ulP1Temp)
- {
- ulP1Temp |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_SET, &ulP1Temp,
- &recSet, 0);
- if (rc)
- rc = vsdResponse(pInst, rc); //if error, process response
- }
- } /* of if valid state */
-
- if (!rc)
- {
- pInst->ulMode = ulMode;
- pInst->ulLevel = ulLevel;
- } /* of else no error */
-
- if (SemHolding) //Release semaphore if not already done
- DosReleaseMutexSem(pInst->hInstSem);
-
- return(rc);
-
- } /* of ProcSet() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcSetSync */
- /* */
- /* DESCRIPTIVE NAME: Process Set Synchronization Offset */
- /* */
- /* FUNCTION: Process MCI_SET_SYNC_OFFSET command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_INVALID_FLAG -- Unknown flag or value used. */
- /* MCIERR_OUTOFRANGE -- invalid track specified. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcSetSync(PINST pInst, ULONG ulParam1, MCI_SYNC_OFFSET_PARMS *pParam2)
- {
- ULONG rc = MCIERR_SUCCESS;
- USHORT temp;
-
- ulParam1 &= WAIT_NOTIFY_MASK;
-
- if (ulParam1)
- rc = MCIERR_INVALID_FLAG;
- else
- {
- /* check if disc is needed, track info is needed for TMSF mode */
- if (pInst->ulMode & TIME_MODE == CDMC_TMSF)
- {
- temp = (USHORT)(pInst->usStatus % SUSPEND);
- if (temp <= NODISC)
- rc = MCIERR_DEVICE_NOT_READY;
- }
-
- if (!rc)
- {
- pInst->ulOffset = GetTimeAddr(pInst, pParam2->ulOffset, TRUE);
- if (pInst->ulOffset == (ULONG) -1)
- { // Invalid track specified for TMSF
- pInst->ulOffset = 0L;
- rc = MCIERR_OUTOFRANGE;
- }
- } /* of if no error */
- } /* no invalid flags */
-
- return(rc);
-
- } /* of ProcSetSync() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcStatus */
- /* */
- /* DESCRIPTIVE NAME: Process Status. */
- /* */
- /* FUNCTION: Process MCI_STATUS command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_OUTOFRANGE -- invalid track supplied. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_INVALID_ITEM_FLAG -- Invalid item specified. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_PARAM_OVERFLOW -- Invalid PARMS pointer. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcStatus(PINST pInst, ULONG ulParam1, MCI_STATUS_PARMS *pParam2)
- {
- ULONG rc, rsp;
-
- rsp = ValState(pInst);
-
- /* validate flags */
- ulParam1 &= WAIT_NOTIFY_MASK;
- pParam2->ulReturn = 0L;
-
- switch(ulParam1)
- {
- case MCI_STATUS_ITEM :
- rc = MCIERR_SUCCESS;
- switch(pParam2->ulItem)
- {
- /* process items that the MCI Driver can do */
-
- case MCI_STATUS_AUDIO :
- ULONG_HIWD(rc) = MCI_TRUE_FALSE_RETURN;
- switch (pParam2->ulValue)
- {
- case MCI_STATUS_AUDIO_LEFT :
- if (pInst->ulMode & CDMC_LFT_CH)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- case MCI_STATUS_AUDIO_RIGHT :
- if (pInst->ulMode & CDMC_RGT_CH)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- case MCI_STATUS_AUDIO_ALL :
- if (pInst->ulMode & CDMC_ALL_CH)
- pParam2->ulReturn = MCI_TRUE;
- else
- pParam2->ulReturn = MCI_FALSE;
- break;
- default : rc = MCIERR_INVALID_AUDIO_FLAG;
- } /* of switch */
- break;
- case MCI_STATUS_SPEED_FORMAT :
- ULONG_HIWD(rc) = MCI_SPEED_FORMAT_RETURN;
- if (pInst->ulMode & CDMC_PERCENT)
- pParam2->ulReturn = MCI_FORMAT_PERCENTAGE;
- else
- pParam2->ulReturn = MCI_FORMAT_FPS;
- break;
- case MCI_STATUS_TIME_FORMAT :
- ULONG_HIWD(rc) = MCI_TIME_FORMAT_RETURN;
- switch (pInst->ulMode & TIME_MODE)
- {
- case CDMC_MILLSEC :
- pParam2->ulReturn = MCI_FORMAT_MILLISECONDS;
- break;
- case CDMC_REDBOOK :
- pParam2->ulReturn = MCI_FORMAT_MSF;
- break;
- case CDMC_TMSF :
- pParam2->ulReturn = MCI_FORMAT_TMSF;
- break;
- default : // must be CDMC_MMTIME
- pParam2->ulReturn = MCI_FORMAT_MMTIME;
- } /* of switch */
- break;
-
- /* Process commands that the MCD can do with the VSD */
-
- case MCI_STATUS_LENGTH :
- case MCI_STATUS_NUMBER_OF_TRACKS :
- rc = StatusMCD(pInst, ulParam1, pParam2, rsp, TRUE);
- break;
- case MCI_STATUS_POSITION :
- case MCI_STATUS_POSITION_IN_TRACK :
- case MCI_STATUS_CURRENT_TRACK :
- case MCI_CD_STATUS_TRACK_TYPE :
- case MCI_CD_STATUS_TRACK_COPYPERMITTED :
- case MCI_CD_STATUS_TRACK_CHANNELS :
- case MCI_CD_STATUS_TRACK_PREEMPHASIS :
- rc = StatusMCD(pInst, ulParam1, pParam2, rsp, FALSE);
- break;
-
- /* Process commands that the VSD can only do */
- /* MCI_STATUS_MEDIA_PRESENT, MCI_STATUS_VOLUME */
- /* MCI_STATUS_MODE, MCI_STATUS_READY, others */
- default :
- rc = StatusVSD(pInst, ulParam1, pParam2, rsp);
-
- } /* of item switch */
- break;
- case MCI_STATUS_ITEM | MCI_TRACK :
- switch(pParam2->ulItem)
- {
- case MCI_STATUS_LENGTH :
- case MCI_CD_STATUS_TRACK_TYPE :
- case MCI_CD_STATUS_TRACK_COPYPERMITTED :
- case MCI_STATUS_POSITION :
- case MCI_CD_STATUS_TRACK_CHANNELS :
- case MCI_CD_STATUS_TRACK_PREEMPHASIS :
- rc = StatusMCD(pInst, ulParam1, pParam2, rsp, TRUE);
- break;
- default :
- rc = StatusVSD(pInst, ulParam1, pParam2, rsp);
- } /* of item switch */
- break;
- case MCI_STATUS_ITEM | MCI_STATUS_START :
- switch(pParam2->ulItem)
- {
- case MCI_STATUS_POSITION :
- rc = StatusMCD(pInst, ulParam1, pParam2, rsp, FALSE);
- break;
- default :
- rc = MCIERR_INVALID_ITEM_FLAG;
- } /* of item switch */
- break;
- case 0 :
- rc = MCIERR_MISSING_FLAG;
- break;
- default :
- if (rsp)
- {
- if (rsp == MCIERR_INSTANCE_INACTIVE)
- if (pInst->usStatus - SUSPEND <= NODISC)
- rc = MCIERR_DEVICE_NOT_READY;
- else
- rsp = MCIERR_SUCCESS; //clear flag and let VSD process it
- else
- rc = rsp;
- }
-
- if (!rsp) // unknown flag, query VSD
- {
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_STATUS,
- &ulParam1, pParam2, 0);
- if (ULONG_LOWD(rc))
- rc = vsdResponse(pInst, rc); //if error, process response
- }
- } /* of switch on flags */
-
- return(rc);
-
- } /* of ProcStatus() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcStop */
- /* */
- /* DESCRIPTIVE NAME: Process Stop. */
- /* */
- /* FUNCTION: Process MCI_STOP command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcStop(PINST pInst, ULONG ulParam1)
- {
- ULONG rc;
-
- rc = ValState(pInst);
-
- /* if drive is not ready, ignore call */
- if (rc == MCIERR_DEVICE_NOT_READY)
- if (ulParam1 & WAIT_NOTIFY_MASK)
- return(MCIERR_INVALID_FLAG);
- else
- return(MCIERR_SUCCESS);
-
- /* validate flags */
- if (!rc && ulParam1 & WAIT_NOTIFY_MASK)
- rc = MCIERR_INVALID_FLAG;
-
- if (!rc)
- {
- /* call VSD (Vendor Specific Driver) */
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCI_STOP, 0L, 0L, 0);
- if (rc)
- rc = vsdResponse(pInst, rc); //if error, process response
-
- pInst->usStatus = STOPPED;
-
- } /* if drive is ready for command */
-
- return(rc);
-
- } /* of ProcStop() */
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: ProcSync */
- /* */
- /* DESCRIPTIVE NAME: Process Synchronization */
- /* */
- /* FUNCTION: Process MCIDRV_SYNC command. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- pointer to instance. */
- /* ULONG ulParam1 -- flag for this message. */
- /* PVOID pParam2 -- pointer to structure (message dependent). */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INVALID_MEDIA_TYPE -- No audio tracks were found. */
- /* MCIERR_INSTANCE_INACTIVE -- Instance is suspended. */
- /* MCIERR_NO_CONNECTION -- no way to play, no stream/DAC. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
-
- ULONG ProcSync(PINST pInst, ULONG ulParam1, MCIDRV_SYNC_PARMS *pParam2)
- {
- ULONG rc;
- USHORT cnt=0;
-
- rc = ValState(pInst);
-
- if (rc != MCIERR_INSTANCE_INACTIVE)
- {
- /* validate flags */
- ulParam1 &= WAIT_NOTIFY_MASK;
- if (ulParam1 & MCIDRV_SYNC_ENABLE)
- cnt++;
- if (ulParam1 & MCIDRV_SYNC_DISABLE)
- cnt++;
- if (ulParam1 & MCIDRV_SYNC_SET_MASTER)
- cnt++;
- if (ulParam1 & MCIDRV_SYNC_REC_PULSE)
- cnt++;
- if (cnt > 1)
- return(MCIERR_FLAGS_NOT_COMPATIBLE);
-
- switch (ulParam1)
- {
- case MCIDRV_SYNC_ENABLE :
- rc = MCIERR_SUCCESS;
-
- if (pInst->ulMode & CDMC_INTDAC)
- {
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCIDRV_SYNC,
- &ulParam1, pParam2, 0);
- }
- else
- rc = MCIERR_NO_CONNECTION; //no internal DAC
- break;
- case MCIDRV_SYNC_DISABLE :
- case MCIDRV_SYNC_MASTER :
- rc = MCIERR_SUCCESS;
- case MCIDRV_SYNC_REC_PULSE :
- if (!rc)
- if (pInst->ulMode & CDMC_INTDAC)
- {
- ulParam1 |= MCI_WAIT;
- rc = pInst->pMCIDriver(pInst->hHWMCID, MCIDRV_SYNC,
- &ulParam1, pParam2, 0);
- }
- else
- if (!(pInst->ulMode & CDMC_STREAM))
- rc = MCIERR_NO_CONNECTION; //not streaming either
- break;
- case 0L :
- if (!rc)
- rc = MCIERR_MISSING_FLAG;
- break;
- default :
- if (!rc)
- rc = MCIERR_INVALID_FLAG;
- } /* of switch */
-
- if (rc)
- rc = vsdResponse(pInst, rc); //if error, process response
-
- } /* if drive is ready for command */
-
- return(rc);
-
- } /* of ProcSync() */
-
-
-