Returning Information to Applications

There are two standardized methods for returning information to applications. One method is used for returning integer values and the other is used for returning strings.

When a driver receives an MCI command that requests information, it also receives the address of a data structure in the lParam2 parameter to DriverProc. A different structure is defined for each MCI command. Customized structures are defined for some device types. The structure’s definition dictates which method is used for returning the requested information.

Following is the structure definition for MCI_STATUS_PARMS, which is used with the MCI_STATUS command to return an integer value:

typedef struct tagMCI_STATUS_PARMS {

    DWORD   dwCallback;

    DWORD   dwReturn;

    DWORD   dwItem;

    DWORD   dwTrack;

} MCI_STATUS_PARMS, *PMCI_STATUS_PARMS, FAR * LPMCI_STATUS_PARMS;

 

The MCI_STATUS_PARMS structure defines a DWORD-sized member called dwReturn. To return an integer value for MCI_STATUS, the driver places a longword value into dwReturn.

Following is the structure definition for MCI_INFO_PARMS, used with the MCI_INFO command to return a string:

typedef struct tagMCI_INFO_PARMS {

    DWORD   dwCallback;

    LPSTR   lpstrReturn;

    DWORD   dwRetSize;

} MCI_INFO_PARMS, FAR * LPMCI_INFO_PARMS;

 

The MCI_INFO_PARMS structure defines two members, lpstrReturn and dwRetSize. These members are used for returning a string value. In this case, the application places a string buffer pointer in lpstrReturn and a buffer size in dwRetSize. The driver copies the return string into the buffer.

Returning String Resource Indentifiers

It is important to remember that applications can communicate with MCI by using either strings or command constants. When an application calls mciSendString, it specifies commands in string form and expects information to be returned in string form. When an application calls mciSendCommand it specifies command constants and flag constants, and expects information to be returned in a command-specific data structure, which it references. MCI drivers sometimes need to return information in both formats, in order to support both interfaces.

Suppose an application uses the MCI_STATUS command to request the device’s current mode, and it happens that the device is currently stopped. An application using mciSendCommand should be able to test the MCI_MODE_STOP flag value stored in the dwReturn member of an MCI_STATUS_PARMS structure. An application using mciSendString should receive the string “stopped” in its string buffer. The driver is responsible for returning both the flag and a string resource identifier. (String resources are discussed in the Win32 SDK.)

The proper way to return both a flag and a string resource identifier is to combine them in the dwReturn member, using the MAKEMCIRESOURCE macro. This macro concatenates two integers to make a single long integer. The resource identifier must be placed in the high word of the long integer.

If a driver returns a resource identifier, it must set the DriverProc return value to MCI_RESOURCE_RETURNED, as shown in the following example. (Notice that, in this case, the flag constant value and the string resource ID value are the same.)

wResource = MCI_MODE_STOP;

lpStatus->dwReturn = (DWORD)MAKEMCIRESOURCE(wResource, wResource);

dReturn = MCI_RESOURCE_RETURNED;

 

If the string resource is defined in a driver-specific resource file, the driver must also set MCI_RESOURCE_DRIVER in the return value, as shown in the following example of returning the “audio” status from an AVI driver. (Notice that, in this case, the flag constant value and the string resource ID value are not the same.)

lpStatus->dwReturn = (npMCI->dwFlags & MCIAVI_PLAYAUDIO) ?

                        (MAKEMCIRESOURCE(MCI_ON, MCI_ON_S)) :

                        (MAKEMCIRESOURCE(MCI_OFF, MCI_OFF_S));

return MCI_RESOURCE_RETURNED | MCI_RESOURCE_DRIVER;

 

Both MCI_RESOURCE_RETURNED and MCI_RESOURCE_DRIVER set bits in the return value’s high word.

If the application used mciSendString to send the command, then winmm.dll checks the high word of the DriverProc return value. If MCI_RESOURCE_RETURNED is set, winmm.dll loads the string associated with the resource identifier and places it in the application’s return buffer.

If the application used mciSendCommand to send the command and MCI_RESOURCE_RETURNED is set in the high word of the DriverProc return value, then winmm.dll just clears the high word before passing the return value to the application.

The following table contains the resource strings provided by winmm.dll for use by drivers. The resource identifiers and constants are defined within mmsystem.h and mmddk.h. (Sometimes the constant and resource ID are the same.) The strings are defined in a resource file that is part of winmm.dll. Driver developers can define additional strings within a driver-specific resource file. The driver calls mciLoadCommandResource to register the resource file with winmm.dll.

Constant Resource ID String
MCI_FALSE MCI_FALSE false
MCI_TRUE MCI_TRUE true
MCI_DEVTYPE_ANIMATION MCI_DEVTYPE_ANIMATION animation
MCI_DEVTYPE_CD_AUDIO MCI_DEVTYPE_CD_AUDIO cdaudio
MCI_DEVTYPE_DAT MCI_DEVTYPE_DAT dat
MCI_DEVTYPE_DIGITAL_VIDEO MCI_DEVTYPE_DIGITAL_VIDEO digitalvideo
MCI_DEVTYPE_OTHER MCI_DEVTYPE_OTHER other
MCI_DEVTYPE_OVERLAY MCI_DEVTYPE_OVERLAY overlay
MCI_DEVTYPE_SCANNER MCI_DEVTYPE_SCANNER scanner
MCI_DEVTYPE_SEQUENCER MCI_DEVTYPE_SEQUENCER sequencer
MCI_DEVTYPE_VCR MCI_DEVTYPE_VCR vcr
MCI_DEVTYPE_VIDEODISC MCI_DEVTYPE_VIDEODISC videodisc
MCI_DEVTYPE_WAVEFORM_AUDIO MCI_DEVTYPE_WAVEFORM_AUDIO waveaudio
MCI_FORMAT_BYTES MCI_FORMAT_BYTES_S bytes
MCI_FORMAT_FRAMES MCI_FORMAT_FRAMES_S frames
MCI_FORMAT_HMS MCI_FORMAT_HMS_S hms
MCI_FORMAT_MILLISECONDS MCI_FORMAT_MILLISECONDS_S milliseconds
MCI_FORMAT_MSF MCI_FORMAT_MSF_S msf
MCI_FORMAT_SAMPLES MCI_FORMAT_SAMPLES_S samples
MCI_FORMAT_SMPTE_24 MCI_FORMAT_SMPTE_24_S smpte 24
MCI_FORMAT_SMPTE_25 MCI_FORMAT_SMPTE_25_S smpte 25
MCI_FORMAT_SMPTE_30 MCI_FORMAT_SMPTE_30_S smpte 30
MCI_FORMAT_SMPTE_30DROP MCI_FORMAT_SMPTE_30DROP_S smpte 30 drop
MCI_FORMAT_TMSF MCI_FORMAT_TMSF_S tmsf
MCI_MODE_NOT_READY MCI_MODE_NOT_READY not ready
MCI_MODE_OPEN MCI_MODE_OPEN open
MCI_MODE_PAUSE MCI_MODE_PAUSE paused
MCI_MODE_PLAY MCI_MODE_PLAY playing
MCI_MODE_RECORD MCI_MODE_RECORD recording
MCI_MODE_SEEK MCI_MODE_SEEK seeking
MCI_MODE_STOP MCI_MODE_STOP stopped
MCI_SEQ_DIV_PPQN MCI_SEQ_DIV_PPQN PPQN
MCI_SEQ_DIV_SMPTE_24 MCI_SEQ_DIV_SMPTE_24 SMPTE 24 Frame
MCI_SEQ_DIV_SMPTE_25 MCI_SEQ_DIV_SMPTE_25 SMPTE 25 Frame
MCI_SEQ_DIV_SMPTE_30 MCI_SEQ_DIV_SMPTE_30 SMPTE 30 Frame
MCI_SEQ_DIV_SMPTE_30DROP MCI_SEQ_DIV_SMPTE_30DROP SMPTE 30 Drop Frame
MCI_SEQ_FILE MCI_SEQ_FILE_S file
MCI_SEQ_FORMAT_SONGPTR MCI_SEQ_FORMAT_SONGPTR_S song pointer
MCI_SEQ_MIDI MCI_SEQ_MIDI_S midi
MCI_SEQ_NONE MCI_SEQ_NONE_S none
MCI_SEQ_SMPTE MCI_SEQ_SMPTE_S smpte
MCI_VD_FORMAT_TRACK MCI_VD_FORMAT_TRACK_S track
MCI_VD_MEDIA_CAV MCI_VD_MEDIA_CAV CAV
MCI_VD_MEDIA_CLV MCI_VD_MEDIA_CLV CLV
MCI_VD_MEDIA_OTHER MCI_VD_MEDIA_OTHER other
MCI_VD_MODE_PARK MCI_VD_MODE_PARK parked
MIDIMAPPER MIDIMAPPER_S mapper
WAVE_FORMAT_PCM WAVE_FORMAT_PCM_S pcm
WAVE_MAPPER WAVE_MAPPER_S mapper

Returning Integers

If an application requests information that is represented as an integer value, the driver just places the integer in the dwReturn member of the command’s data structure. If the application used mciSendString to request the information, then winmm.dll converts the integer to a string and places the string in the application’s return buffer.

The driver can request winmm.dll to insert colons into the integer string. A typical reason for inserting colons is returning time values. To request colon insertion, a driver assigns MCI_COLONIZED3_RETURN or MCI_COLONIZED4_RETURN to the DriverProc return value, as shown in the next example. These constants set bits in the return value’s high word.

DWORD dwSeconds = dwFrames / CAV_FRAMES_PER_SECOND;

lpStatus->dwReturn = MCI_MAKE_HMS(dwSeconds / 3600,

                                  (dwSeconds % 3600) / 60,

                                  dwSeconds % 60);

return MCI_COLONIZED3_RETURN;

 

If the application used mciSendString to request the information, then winmm.dll treats each byte of the return value as a separate integer and inserts a colon between each integer in the string that is returned to the application. For an integer value of 0x01020304, specifying MCI_COLONIZED4_RETURN returns the string “4:3:2:1”, and specifying MCI_COLONIZED3_RETURN returns “4:3:2”.

One other special DriverProc return value, MCI_INTEGER_RETURNED, forces a command’s returned information to be an integer even though the command’s data structure defines the return type as a string. Microsoft uses this flag within winmm.dll, for support of the MCI_SYSINFO command. This command’s MCI_SYSINFO_PARMS structure defines a string return, but if the requested information type is MCI_SYSINFO_QUANTITY, then an integer value is placed in the structure. (For more information, see the Win32 SDK.) If the application requested the information by calling mciSendString, winmm.dll converts the integer to a string.