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.