home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* */
- /* SOURCE FILE NAME: IBMCDMSC.C */
- /* */
- /* DESCRIPTIVE NAME: IBM CD-ROMs Miscellaneous */
- /* */
- /* COPYRIGHT: (c) IBM Corp. 1990 - 1993 */
- /* */
- /* FUNCTION: This file contains miscellaneous functions such as the timer */
- /* routine for the MCI_PLAY command, querying the CD table, and */
- /* packaging the IOCTL calls. */
- /* */
- /* */
- /* FUNCTIONS: */
- /* CD01_StartPlay - Start the play operation. */
- /* CD01_Sync - Sync to MDM request. */
- /* CD01_Timer - Timer routine for play operation. */
- /* CD01_TimerNotify - Timer routine to setup and notify events. */
- /* GetTableName - Get the full path name of the CD table. */
- /* OpenFirstTime - First time device open tests. */
- /* QueryTable - Query CD look-up table. */
- /* CallIOCtl - Call the hardware via IOCTLs. */
- /* */
- /* NOTE: CD01_... refers to commands that are compatible with the */
- /* IBM 3510 CD-ROM drive. CD02_... may refer to commands */
- /* that are compatible with the CD02 drives, which are */
- /* not compatible with the CD01_... commands. This way */
- /* different hardware can share the same VSD. */
- /* */
- /* */
- /****************************************************************************/
-
- #define INCL_DOS
- #define INCL_DOSERRORS
- #define INCL_DOSDEVICES
- #define INCL_DOSPROCESS
- #define INCL_DOSFILEMGR
- #define INCL_DOSSEMAPHORES
- #define INCL_WINSHELLDATA
- #include <os2.h>
- #include <string.h>
- #include <stdlib.h>
- #define INCL_MCIOS2
- #include <os2me.h>
- #include <cdaudos2.h>
- #include "ibmcdrom.h"
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: CD01_StartPlay */
- /* */
- /* DESCRIPTIVE NAME: CD Start Play. */
- /* */
- /* FUNCTION: Start playing audio data to internal DAC(s). */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- Instance pointer. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_MEDIA_CHANGED -- Disc changed. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
- ULONG CD01_StartPlay(PINST pInst)
- {
- ULONG rc;
- BYTE param[PLAYAUD_PMAX] = {'C', 'D', '0', '1', RBMODE};
- ULONG ulDataLen = STANDRD_DMAX, ulParamLen = PLAYAUD_PMAX;
- ULONG cnt;
- PTIB ptib;
- PPIB ppib;
-
- /* convert MM Time into Redbook 2 format */
- * (ULONG *)¶m[STARTFFFLD] = REDBOOK2FROMMM(pInst->ulCurPos);
- * (ULONG *)¶m[END_FF_FLD] = REDBOOK2FROMMM(pInst->ulEndPos);
-
- /* play drive */
- rc = CallIOCtl(pInst, CDAUDIO_CAT, PLAY__AUDIO,
- param, ulParamLen, &ulParamLen,
- NULL, ulDataLen, &ulDataLen);
-
- if (!rc)
- {
- /* set timer play flag */
- pInst->usPlayFlag = TIMER_PLAYING;
- DosGetInfoBlocks(&ptib, &ppib);
- pInst->ulPlayTID = ptib->tib_ptib2->tib2_ultid;
- DosResetEventSem(pInst->hTimeLoopSem, &cnt); // force a wait in timer
-
- } /* if no error */
-
- /* original thread owns Mutex sem, */
- /* if not WAIT tell original thead to release it */
- if (pInst->usPlayNotify == MCI_WAIT)
- DosReleaseMutexSem(pInst->hInstSem);
- else
- DosPostEventSem(pInst->hReturnSem);
-
- return(rc);
-
- } /* of CD01_StartPlay() */
-
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: CD01_Sync */
- /* */
- /* DESCRIPTIVE NAME: CD Synchronization. */
- /* */
- /* FUNCTION: Process SYNC messages from MCIDRV_SYNC message. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- Instance pointer. */
- /* ULONG ulParam1 -- Flag for this message. */
- /* MCIDRV_SYNC_PARMS *pParam2 -- pointer to record structure. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_INVALID_FLAG -- Unknown flag. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
- ULONG CD01_Sync(PINST pInst, ULONG ulParam1, MCIDRV_SYNC_PARMS *pParam2)
- {
- ULONG rc = MCIERR_SUCCESS;
- ULONG ulPosition;
- MMTIME mmTime;
- LONG lDelta;
- CHAR szBuf[SSM_LOAD_SIZE];
- HMODULE hMod; // handle to SSM module
-
- ulParam1 &= WAIT_NOTIFY_MASK;
-
- switch (ulParam1)
- {
- case MCIDRV_SYNC_ENABLE :
- pParam2->pevcbSyncPulse = &pInst->evcbSync;
- pParam2->NonStreamMaster = TRUE;
- break;
- case MCIDRV_SYNC_DISABLE :
- pInst->StreamMaster = FALSE;
- break;
- case MCIDRV_SYNC_MASTER :
- pInst->StreamMaster = TRUE; // set master stream flag
- pInst->RptEvent.hid = pParam2->hidMaster; // store id for SSM calls
- pInst->RptEvent.pevcbEvent = (PEVCB) &pInst->evcbSync;
- pInst->evcbSync.mmtimeMaster = (MMTIME) pInst->ulCurPos; // set time
-
- /* get SSM loaded, if not yet loaded */
- if (pInst->pSyncNotify == NULL)
- {
- rc = DosLoadModule(szBuf, SSM_LOAD_SIZE, "SSM", &hMod);
- if (!rc)
- rc = DosQueryProcAddr(hMod, 0L, "SMHEntryPoint",
- &pInst->pSyncNotify);
- if (rc)
- {
- pInst->pSyncNotify = NULL;
- rc = MCIERR_CANNOT_LOAD_DRIVER;
- } /* of if error */
- } /* of if need to get sync entry point */
- break;
- case MCIDRV_SYNC_REC_PULSE :
- /* get current position */
- CD01_GetPosition(pInst, &ulPosition);
-
- mmTime = pInst->evcbSync.mmtimeMaster;
- lDelta = ulPosition - mmTime - SYNC_LATENCY;
- if (lDelta < -SYNC_TOLERANCE || lDelta > SYNC_TOLERANCE)
- rc = CD01_PlayCont(pInst, (ULONG) mmTime, pInst->ulEndPos);
- pInst->evcbSync.mmtimeSlave = mmTime; // reset current time
- /* Clear Sync Flags */
- pInst->evcbSync.ulSyncFlags &= ~(SYNCOVERRUN | SYNCPOLLING);
- break;
- default :
- rc = MCIERR_INVALID_FLAG;
- } /* of switch */
-
- return(rc);
-
- } /* of CD01_Sync() */
-
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: CD01_Timer */
- /* */
- /* DESCRIPTIVE NAME: CD Timer */
- /* */
- /* FUNCTION: Queries the device once a second to determine is a play */
- /* command is still going on. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- Instance pointer. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_MEDIA_CHANGED -- Disc changed on restore as reported by */
- /* MCD. Return error on play thread. */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
- ULONG CD01_Timer(PINST pInst)
- {
- ULONG rc;
- ULONG ulDelay, ulPrevLimit;
- ULONG ulPosAdvise = 0L, ulSyncPos = 0L, ulOldPosAdvise = 0L;
- BYTE dataAud[AUDSTAT_DMAX]; //values for the audio status command
- BYTE dataPos[LOCATON_DMAX],
- param[LOCATON_PMAX] = {'C', 'D', '0', '1', RBMODE};
- ULONG ulDataLen, ulParamLen;
- ULONG cnt, DoLoop = TRUE;
- USHORT usNotifyType = MCI_NOTIFY_SUCCESSFUL;
-
- /* start playing */
- rc = CD01_StartPlay(pInst);
- ulPrevLimit = pInst->ulCurPos;
-
- if (!rc)
- do
- {
- /* check position advise before calling notification routine. */
- /* event must be multiple address relative to address 0. */
- if (pInst->qptPosAdvise.ulEvent != ulOldPosAdvise)
- {
- ulOldPosAdvise = pInst->qptPosAdvise.ulEvent;
- if (ulOldPosAdvise)
- if (pInst->ulCurPos % ulOldPosAdvise) //if past, get next one
- ulPosAdvise = (pInst->ulCurPos / ulOldPosAdvise + 1)
- * ulOldPosAdvise;
- else
- ulPosAdvise = pInst->ulCurPos;
- else
- ulPosAdvise = 0L;
- } /* of if position advise changed */
-
- ulDelay = CD01_TimerNotify(pInst, &ulPosAdvise, &ulSyncPos, &ulPrevLimit);
-
- /********************************************************************
- * wait on the semaphore. If the instance is PAUSED or being SAVED *
- * (no longer active) then wait until RESUME or RESTORE clears the *
- * semaphore. If a destructive STOP is received, the wait will *
- * terminate immediately. Otherwise, wait as long as ulDelay. *
- ********************************************************************/
-
- if (!DosWaitEventSem(pInst->hTimeLoopSem, ulDelay))
- /* semaphore is cleared. Reset it incase we don't exit loop */
- DosResetEventSem(pInst->hTimeLoopSem, &cnt);
-
- /* get new position */
- ulDataLen = LOCATON_DMAX;
- ulParamLen = LOCATON_PMAX;
- rc = CallIOCtl(pInst, CDDRIVE_CAT, Q__LOCATION,
- param, ulParamLen, &ulParamLen,
- dataPos, ulDataLen, &ulDataLen);
-
- /* The only way to receive a media change rc is when closing *
- * an inactive instance after a disc change, process the abort */
- if (rc)
- if (rc == MCIERR_MEDIA_CHANGED)
- rc = MCIERR_SUCCESS;
- else // an error occurred, break out of the loop
- break;
-
- switch (pInst->usPlayFlag)
- {
- case TIMER_EXIT_SUPER :
- usNotifyType = MCI_NOTIFY_SUPERSEDED;
- DoLoop = FALSE;
- break;
- case TIMER_EXIT_ABORTED :
- usNotifyType = MCI_NOTIFY_ABORTED;
- DoLoop = FALSE;
- break;
- case TIMER_EXIT_CHANGED :
- rc = MCIERR_MEDIA_CHANGED;
- DoLoop = FALSE;
- break;
- case TIMER_AVAIL :
- rc = MCIERR_DRIVER_INTERNAL; // abondon ship
- DoLoop = FALSE;
- break;
- case TIMER_PLAY_SUSPEND : // do nothing
- case TIMER_PLAY_SUSP_2 :
- break;
- case TIMER_PLAYING :
- /* update current location */
- pInst->ulCurPos = REDBOOK2TOMM(*(ULONG *)dataPos);
-
- DosRequestMutexSem(pInst->hIOSem, (ULONG)-1L);
-
- /* check if drive is still playing */
- ulDataLen = AUDSTAT_DMAX;
- ulParamLen = STANDRD_PMAX;
- if (DosDevIOCtl(pInst->hDrive, CDDRIVE_CAT, DEV__STATUS,
- "CD01", ulParamLen, &ulParamLen,
- dataAud, ulDataLen, &ulDataLen))
- { // Error
- rc = MCIERR_DEVICE_NOT_READY;
- DoLoop = FALSE;
- } /* of if error calling device */
- else
- {
- if (!(dataAud[STATAUDFLD] & IS_PLAYING)) // if NOT Playing
- {
- /* check to see if PLAY terminated or was STOPPED/PAUSED */
- ulDataLen = AUDSTAT_DMAX;
- ulParamLen = STANDRD_PMAX;
- if (DosDevIOCtl(pInst->hDrive, CDAUDIO_CAT, AUD__STATUS,
- "CD01", ulParamLen, &ulParamLen,
- dataAud, ulDataLen, &ulDataLen))
- {
- rc = MCIERR_DEVICE_NOT_READY;
- DoLoop = FALSE;
- } /* of if error calling device */
- else
- if (!(dataAud[AUDSTATFLD] & WAS_STOPPED))
- { /* PLAY command finished */
- rc = MCIERR_SUCCESS;
- DoLoop = FALSE;
- pInst->ulCurPos = pInst->ulEndPos;
- } /* of else PLAY command terminated itself (finished) */
- /* else it is paused, continue the clock */
-
- } /* of if NOT Playing */
- } /* of else no error querying status */
-
- DosReleaseMutexSem(pInst->hIOSem);
- break;
- default :
- rc = MCIERR_DRIVER_INTERNAL; // unknown play flag
- DoLoop = FALSE;
- break;
-
- } /* of switch on play flag */
- } while(DoLoop); /* of do loop */
-
- if (!rc) // if no error, report any events
- CD01_TimerNotify(pInst, &ulPosAdvise, &ulSyncPos, &ulPrevLimit);
-
- pInst->ulPlayTID = 0L; // clear before exit or return
-
- if (pInst->usPlayNotify != MCI_WAIT)
- {
- if (rc)
- usNotifyType = (USHORT) rc;
-
- /* inform MDM that play has terminated */
- if (pInst->usPlayNotify == MCI_NOTIFY)
- mdmDriverNotify(pInst->usDeviceID, pInst->hwndPlayCallback,
- MM_MCINOTIFY, pInst->usPlayUserParm,
- MAKEULONG(MCI_PLAY, usNotifyType));
-
- /* inform MCD that play has terminated */
- pInst->pCDMCDReturn(pInst->ulCDMCDID, MAKEULONG(MCI_PLAY, usNotifyType),
- 0L); //MCD ignores 3rd field for PLAY
-
- pInst->usPlayFlag = TIMER_AVAIL;
- DosExit(0L, 0L);
- } /* of if notify was used */
-
- if (!rc && usNotifyType == MCI_NOTIFY_SUCCESSFUL)
- pInst->ulCurPos = pInst->ulEndPos;
-
- pInst->usPlayFlag = TIMER_AVAIL;
-
- return(rc);
-
- } /* of CD01_Timer() */
-
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: CD01_TimerNotify */
- /* */
- /* DESCRIPTIVE NAME: CD Timer Notify */
- /* */
- /* FUNCTION: Sets up the wait value to suspend the timer thread based on */
- /* upcoming events. It also sends notification of past or soon */
- /* to pass events. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- Instance pointer. */
- /* ULONG *pulPosAdvise -- Position for next Position Advise Event. */
- /* ULONG *pSyncPos -- Position for next Sync Pulse if master. */
- /* ULONG *pulPrevLimit -- Last range checked. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* */
- /* NOTES: It is important to note that events are in MM Time and delay */
- /* factors are in milliseconds. */
- /* */
- /****************************************************************************/
- ULONG CD01_TimerNotify(PINST pInst, ULONG *pulPosAdvise,
- ULONG *pSyncPos, ULONG *pulPrevLimit)
- {
- ULONG ulDelay, ulUpperLimit, ulEvent;
- LONG lTemp;
- int i;
-
- /* find wait value by finding time to next event */
- ulDelay = WAIT_TIME_MAX;
- ulUpperLimit = pInst->ulCurPos + HALF_TIME_MIN * 3; // *3 is ms to mmtime
-
- /* process cuepoints */
- for (i=0; i < CDMCD_CUEPOINT_MAX; i++)
- {
- ulEvent = pInst->arrCuePoint[i].ulEvent;
-
- /* skip if no event */
- if (ulEvent == (ULONG) -1L)
- continue;
-
- /* check to see if event is in window */
- if (ulEvent >= *pulPrevLimit && ulEvent < ulUpperLimit)
- {
- mdmDriverNotify(pInst->usDeviceID,
- pInst->arrCuePoint[i].hwndCallback,
- MM_MCICUEPOINT, pInst->arrCuePoint[i].usUserParm,
- ulEvent);
- continue;
- }
- // there is an implied ELSE here
- lTemp = (LONG)(ulEvent - pInst->ulCurPos) / 3;
- if (lTemp > 0 && (ULONG)lTemp < ulDelay)
- ulDelay = (ULONG)lTemp;
-
- } /* of cuepoint for loop */
-
- /* process position advise */
- if (*pulPosAdvise)
- {
- /* loop for small advise frequencies */
- do
- {
- lTemp = (LONG)(*pulPosAdvise - pInst->ulCurPos) / 3;
- if (lTemp < HALF_TIME_MIN)
- {
- mdmDriverNotify(pInst->usDeviceID,
- pInst->qptPosAdvise.hwndCallback,
- MM_MCIPOSITIONCHANGE,
- pInst->qptPosAdvise.usUserParm,
- (ULONG) *pulPosAdvise);
- *pulPosAdvise += pInst->qptPosAdvise.ulEvent;
- }
- } while (lTemp < HALF_TIME_MIN);
-
- if ((ULONG)lTemp < ulDelay)
- ulDelay = (ULONG)lTemp;
- } /* of if process advise event pending */
-
- /* process sync pulse if VSD is the master */
- if (pInst->StreamMaster)
- {
- if (*pSyncPos)
- {
- lTemp = (LONG)(*pSyncPos - pInst->ulCurPos) / 3;
- if (lTemp < HALF_TIME_MIN)
- {
- /* set current position/time */
- pInst->evcbSync.mmtimeMaster = (MMTIME) pInst->ulCurPos;
- pInst->RptEvent.ulFunction = SMH_REPORTEVENT;
- pInst->RptEvent.hevent = 0;
- pInst->pSyncNotify(&pInst->RptEvent);
- *pSyncPos = pInst->ulCurPos + SYNC_TOLERANCE * 2 * 3;
- }
- }
- else // new event just started
- *pSyncPos = pInst->ulCurPos + SYNC_TOLERANCE * 2 * 3;
- } /* of if position advise is set */
- else
- *pSyncPos = 0L;
-
- *pulPrevLimit = ulUpperLimit;
-
- /* if suspeneded, set delay flag to forever */
- if (pInst->usPlayFlag == TIMER_PLAY_SUSPEND ||
- pInst->usPlayFlag == TIMER_PLAY_SUSP_2)
- ulDelay = (ULONG) WAIT_FOREVER;
-
- return(ulDelay);
-
- } /* of CD01_TimerNotify() */
-
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: GetTableName DEVELOPER: Garry Lewis */
- /* */
- /* DESCRIPTIVE NAME: Get CD Table full path name. */
- /* */
- /* FUNCTION: Get the full path name of the CD look-up table, MMPMCD.INI. */
- /* */
- /* PARAMETERS: */
- /* CHAR *pName -- Instance structure. */
- /* */
- /* EXIT CODES: None */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
- VOID GetTableName(CHAR *pName)
- {
- CHAR *ptr;
-
- /* find path */
- if (DosScanEnv("MMBASE", &ptr))
- strcpy(pName, "\\MMOS2\\MMPMCD.INI");
- else
- {
- strcpy(pName, ptr);
- ptr = strstr(pName, ";");
- if (ptr)
- *ptr = '\0';
- ptr = pName + strlen(pName);
- strcpy(ptr, "\\MMPMCD.INI");
-
- } /* of else environmental variable was found */
-
- } /* of GetTableName() */
-
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: OpenFirstTime DEVELOPER: Garry Lewis */
- /* */
- /* DESCRIPTIVE NAME: Open drive for the First Time. */
- /* */
- /* FUNCTION: Run tests on the drive after the first successful hardware */
- /* open. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- Instance structure. */
- /* */
- /* EXIT CODES: None */
- /* */
- /* NOTES: */
- /* */
- /****************************************************************************/
- ULONG OpenFirstTime(PINST pInst)
- {
- ULONG rc;
- BYTE data[LOCATON_DMAX], param[LOCATON_PMAX] = {'C', 'D', '0', '1', RBMODE};
- ULONG ulDataLen, ulParamLen, ulStatus;
-
- /* test to see if drive is really a CD-ROM Drive */
- ulDataLen = IDCDROM_DMAX;
- ulParamLen = STANDRD_PMAX;
- if (CallIOCtl(pInst, CDDRIVE_CAT, ID___CD_ROM,
- param, ulParamLen, &ulParamLen,
- data, ulDataLen, &ulDataLen))
- rc = MCIERR_INI_FILE;
- else
- if (memcmp(data, "CD01", IDCDROM_DMAX))
- rc = MCIERR_INI_FILE;
- else
- rc = MCIERR_SUCCESS;
-
- if (!rc)
- { /** Get current position and let the registration *
- * insert information to the instance structure. **/
- ulDataLen = LOCATON_DMAX;
- ulParamLen = LOCATON_PMAX;
- rc = CallIOCtl(pInst, CDDRIVE_CAT, Q__LOCATION,
- param, ulParamLen, &ulParamLen,
- data, ulDataLen, &ulDataLen);
- pInst->ulCurPos = REDBOOK2TOMM(*(ULONG *)data);
-
- rc = CDAudRegDisc(pInst, REG_INST, NULL);
-
- } /* of if no error identifying drive */
-
- return(rc);
-
- } /* of OpenFirstTime() */
-
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: QueryTable DEVELOPER: Garry Lewis */
- /* */
- /* DESCRIPTIVE NAME: Query Table from CD INI file. */
- /* */
- /* FUNCTION: Query the CD look-up table, MMPMCD.INI, and extract */
- /* information or set default information if error. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- Instance structure. */
- /* VVOL_SET_REC *pVVolRec -- pointer to Vector Volume record. */
- /* */
- /* EXIT CODES: None */
- /* */
- /* NOTES: */
- /* This is an example of how to query the CD look-up table, file */
- /* MMPMCD.INI, to get the capabilities and features of a CD-ROM drive. */
- /* A VSD designed to control a specific hardware device, such as this */
- /* VSD, would not need to call the INI file because the capabilities */
- /* should already be known. */
- /* */
- /* */
- /****************************************************************************/
- VOID QueryTable(PINST pInst)
- {
- ULONG rc;
- HAB habTemp;
- HINI hiniFile;
- ULONG ulSize;
- CHAR szIniFile[CCHMAXPATH];
- CHAR szAppName[CDINI_APPSIZE+1], szKeyName[CDINI_KEYSIZE+1];
- MMPMCD_REC recCDEntry;
- BYTE i;
- int len;
- ULONG ulCaps1, ulCaps2, ulMinStart;
- BYTE VolCnt, VolValues[VOLUME_CONTROL];
-
- /* open INI file and get info */
- habTemp = WinInitialize(0);
- if (habTemp) // if sucessful, open INI file
- {
- /* get complete path name for INI file */
- GetTableName(szIniFile);
-
- hiniFile = PrfOpenProfile(habTemp, szIniFile);
- if (hiniFile)
- {
- memcpy(szAppName, pInst->szModel, CDINI_APPSIZE);
- szAppName[CDINI_APPSIZE] = '\0';
- memcpy(szKeyName, pInst->szModel + CDINI_APPSIZE, CDINI_KEYSIZE);
- szKeyName[CDINI_KEYSIZE] = '\0';
-
- /* check to see Key name needs padding, */
- /* trailing spaces are lost in MMPM2.INI */
- for (len = strlen(szKeyName); len < CDINI_KEYSIZE; len++)
- szKeyName[len] = ' ';
- ulSize = sizeof(MMPMCD_REC);
-
- /* make query */
- if (PrfQueryProfileData(hiniFile, szAppName, szKeyName, &recCDEntry,
- &ulSize ))
- { /* if query is okay, extract data */
- ulCaps1 = recCDEntry.ulCaps1;
- ulCaps2 = recCDEntry.ulCaps2;
- ulMinStart = REDBOOK2TOMM(recCDEntry.ulMinStart);
- VolCnt = (BYTE)recCDEntry.usVolCnt;
- for (i=0; i < VolCnt; i++)
- VolValues[i] = (BYTE)recCDEntry.ausVolValues[i];
-
- /******************************************************************
- * In this sample VSD, the IBM 3510-001 CD-ROM Drive is assumed *
- * to be the associated CD-ROM drive. Thus the capabilities of *
- * the drive are already known and the table information is *
- * ignored. *
- ******************************************************************/
-
- } /* of if successful query */
-
- PrfCloseProfile(hiniFile);
-
- } /* of if successful */
-
- WinTerminate(habTemp);
-
- } /* of if successful WinInit */
-
- } /* of QueryTable() */
-
-
-
- /****************************************************************************/
- /* */
- /* SUBROUTINE NAME: CallIOCtl */
- /* */
- /* DESCRIPTIVE NAME: Call DosDevIOCTL() */
- /* */
- /* FUNCTION: Call the DosDevIOCTLM Time to Redbook address. */
- /* */
- /* PARAMETERS: */
- /* PINST pInst -- Instance pointer. */
- /* ULONG ulCat -- Category. */
- /* ULONG ulFunction -- Function number. */
- /* PVOID pParam -- pointer to Parameter array. */
- /* ULONG ulPLen -- Parameter array length. */
- /* ULONG *pulPLen -- pointer to Parameter array length. */
- /* PVOID pData -- pointer to Data array. */
- /* ULONG ulDLen -- Data array length. */
- /* ULONG *pulDLen -- pointer to Data array length. */
- /* */
- /* EXIT CODES: */
- /* MCIERR_SUCCESS -- action completed without error. */
- /* MCIERR_DEVICE_NOT_READY -- device was not ready, no disc. */
- /* MCIERR_MEDIA_CHANGED -- a disc was inserted. */
- /* MCIERR_HARDWARE -- unknown error occurred. */
- /* MCIERR_OUTOFRANGE -- Invalid value. */
- /* MCIERR_UNSUPPORTED_FUNCTION -- unsupported command. */
- /* */
- /* NOTES: DosDevIOCTL sometimes fail when called by a second thread. To */
- /* avoid this, a generated thread should have at least a 16K stack */
- /* size. */
- /* */
- /****************************************************************************/
- ULONG CallIOCtl(PINST pInst, ULONG ulCat, ULONG ulFunction,
- PVOID pParam, ULONG ulPLen, ULONG *pulPLen,
- PVOID pData, ULONG ulDLen, ULONG *pulDLen)
- {
- ULONG rc;
-
- DosRequestMutexSem(pInst->hIOSem, (ULONG)-1L);
- rc = DosDevIOCtl(pInst->hDrive, ulCat, ulFunction,
- pParam, ulPLen, pulPLen,
- pData, ulDLen, pulDLen);
- DosReleaseMutexSem(pInst->hIOSem);
-
- switch(rc)
- {
- case 0L :
- rc = MCIERR_SUCCESS;
- break;
- case 0xFF03 :
- rc = MCIERR_UNSUPPORTED_FUNCTION;
- break;
- case 0xFF06 :
- case 0xFF08 :
- rc = MCIERR_OUTOFRANGE;
- break;
- case 0xFF04 :
- case 0xFF0C :
- rc = MCIERR_HARDWARE;
- break;
- case 0xFF10 :
- rc = MCIERR_MEDIA_CHANGED;
- break;
- default :
- rc = MCIERR_DEVICE_NOT_READY;
- }
-
- return(rc);
-
- } /* of CallIOCtl() */
-
-