MMPM/2 Device Driver Reference:DDCMD Messages

The device driver commands are an interface used by a stream handler to communicate with a physical device driver. This interface uses the inter- device driver communication (IDC) mechanism provided by OS/2 AttachDD DevHelp. The stream handler must attach to the device driver using AttachDD DevHelp to receive the DDCMD entry point address of the device driver. This must be done prior to issuing any DDCMDs. Some device drivers also might require that a DosOpen call be used to open the device driver before it can be used through the AttachDD entry point.

The DDCMDs are provided through a single entry point, DDCMDEntryPoint, which accepts a parameter structure on input. typedef ULONG (FAR*PSHDFN)       (PVOID pParmIn); typedef ULONG (FAR*PDDCMDFN)     (PVOID pParmIn); For the Ring 3 DLL interface, all pointers are 0:32 linear; for Ring 0 stream handlers all pointers are 16:16 far pointers to enable the 16-bit device driver model to be used. The following list contains the message numbers for all DDCMDs. It should be used in the ulFunction field, of the parameter structure passed on the call, to indicate which function is being requested by the stream handler.

DDCMDEntryPoint
This function enables device driver stream handlers to interface with the hardware physical device driver (PDD).
 * 1) include 

PDDCMDCOMMON   pCommon;  /*  Pointer to DDCMDCOMMON. */ ULONG          rc;       /*  Return codes. */

rc = DDCMDEntryPoint(pCommon); pCommon (PDDCMDCOMMON) - input A pointer to a DDCMD message-specific input parameter block. See DDCMDCOMMON.
 * Parameter - pCommon

rc (ULONG) - returns Return codes indicating success or the type of failure :
 * Return Value - rc
 * NO_ERROR
 * Successful.


 * ERROR_INVALID_FUNCTION
 * Invalid function requested.


 * FAILURE
 * A DDCMD message-specific error return code.

Device driver stream handlers communicate with the hardware PDD through the DDCmdEntryPoint. This is accomplished through the use of Device Driver Command (DDCMD) messages, which enable a stream handler to request a PDD to perform functions such as starting, stopping, or resuming operation of a device. This interface uses the IDC mechanism provided by the ATTACHDD DevHelp function. The stream handler must attach to the device driver to receive the DDCMD entry point address of the device driver. This function is performed prior to issuing device driver command messages.
 * Remarks

DDCMD_CONTROL
This message performs a device-specific command.

pParmIn (PDDCMDCONTROL) A pointer to a DDCMDCONTROL data structure. The pParmand ulParmSize fields refer to the CONTROL_PARM data structure. Values for ulCmd include:
 * Parameter - pParmIn
 * DDCMD_START
 * Start a device.


 * DDCMD_STOP
 * Stop a device and return current position.


 * DDCMD_PAUSE
 * Pause a device and return current position.


 * DDCMD_RESUME
 * Resume a paused device


 * DDCMD_ENABLE_EVENT
 * Enable event detection.


 * DDCMD_DISABLE_EVENT
 * Disable event detection in the device driver.


 * DDCMD_PAUSE_TIME
 * Pause time but do not pause stream.


 * DDCMD_RESUME_TIME
 * Resume time.

rc (ULONG) Error code indicating success or the type of failure:
 * Return Value - rc
 * NO_ERROR
 * Success.


 * ERROR_INVALID_FUNCTION
 * Illegal function requested.


 * ERROR_INVALID_REQUEST
 * Device driver does not support events. (Returned when ulCmd of DDCMDCONTROL is set to DDCMD_ENABLE_EVENT.)


 * ERROR_INVALID_STREAM
 * Invalid stream handle.


 * ERROR_INVALID_SEQUENCE
 * Invalid device control command.


 * ERROR_INSUFF_BUFFER
 * The device driver does not have buffers to perform the requested action.


 * ERROR_STREAM_NOT_STARTED
 * The stream cannot perform the requested action unless the stream has been started.


 * ERROR_TOO_MANY_EVENTS
 * The stream handler attempted to enable too many events.


 * FAILURE
 * Device-driver-specific error return code.

The stream handler uses this command to control the actions of the physical device driver.
 * Remarks

The following code illustrates the stream handler requesting the PDD to stop its current task, for example, the PDD stops playing audio.
 * Example Code
 * 1) include       "os2.h"
 * 2) include       "os2me.h"
 * 3) include       "shdd.h"

ULONG        ulRC;                      /* Error return code      */ HSTREAM      hstream;                   /* Stream handle          */ DDCMDCONTROL ddcmdpb;                   /* Parameter block        */ PDDCMDFN     pddcmdfn;                  /* Pointer to DDCMD entry point                 */ .                           .                            . /*---*/ /*  The stream handler directs the physical device driver to stop. */ /*---*/ ddcmdpb.ulFunction = DDCMD_CONTROL; ddcmdpb.hstream = hstream; ddcmdpb.pParm = NULL; ddcmdpb.ulParmSize = NULL; ddcmdpb.ulCmd = DDCMD_STOP;

if (ulRC = pddcmdfn (&ddcmdpb)) return (ulRC);   /* error! */

DDCMD_DEREG_STREAM
This message removes a stream instance from a device driver. The stream handler directs the device driver to deregister the stream-destroy the stream and all associated data.

pParmIn (PDDCMDDEREGISTER) A pointer to a DDCMDDEREGISTER data structure.
 * Parameter - pParmIn

rc (ULONG) Error code indicating success or the type of failure:
 * Return Value - rc
 * NO_ERROR
 * Success.


 * ERROR_INVALID_FUNCTION
 * Illegal function requested.


 * ERROR_INVALID_STREAM
 * Invalid stream handle.


 * FAILURE
 * Device-driver-specific error.


 * Remarks
 * This message removes the communication link between the physical device driver and the stream handler for a particular stream instance. The only input is the stream handle, which indicates to the device driver which stream to destroy.


 * After a deregister, the VSD (or device driver) no longer has access to any buffers, and the buffers will be returned to SSM by the stream handler. The VSD does not have to return the buffers; they are returned for the it. The VSD should not return from the destroy until it has stopped using all buffers.

The following code illustrates the stream handler requesting the stream to be de-registered.
 * Example Code
 * 1) include       "os2.h"
 * 2) include       "os2me.h"
 * 3) include       "shdd.h"

ULONG          ulRC;                    /* Error return code      */ HSTREAM        hstream;                 /* Stream handle          */ DDCMDDEREGISTER ddcmdpb;                /* Parameter block        */ PDDCMDFN       pddcmdfn;                /* Pointer to DDCMD entry */ /* point                 */ .                           .                            . /*---*/ /*   The stream handler deregisters with the physical device driver. */ /*---*/ ddcmdpb.ulFunction = DDCMD_DEREG_STREAM; ddcmdpb.hstream = hstream;

if (ulRC = pddcmdfn (&ddcmdpb)) return (ulRC);   /* error! */

DDCMD_READ
This message performs a read from the device into a buffer.

pParmIn (PDDCMDREADWRITE) A pointer to a DDCMDREADWRITE data structure.
 * Parameter - pParmIn

rc (ULONG) Error code indicating success or the type of failure:
 * Return Value - rc
 * NO_ERROR
 * Success.


 * ERROR_INVALID_FUNCTION
 * Illegal function requested.


 * ERROR_INVALID_STREAM
 * Invalid stream handle.


 * ERROR_INVALID_BLOCK
 * Invalid address passed in parameter block.


 * FAILURE
 * Device-driver-specific error return code.

This message is used by a stream handler to give an empty buffer to the physical device driver. An example would be in an audio recording, where the physical device driver fills the buffer it gets from the stream handler. The pBuffer parameter is a pointer to the buffer to be filled in by the physical device driver. This pointer is either a physical 0:32 pointer, 16: 16 far pointer or a global linear pointer. This is defined when the stream handler registers a stream with the device driver using DDCMD_REG_STREAM.
 * Remarks

Many devices cannot handle a 0 length buffer. If the driver receives a 0 length buffer, it should not reject the buffer. The driver should do nothing with the buffer and return it in the same order in which it was sent.

The following code illustrates the PDD ready to receive an empty buffer from the stream handler.
 * Example Code
 * 1) include       "os2.h"
 * 2) include       "os2me.h"
 * 3) include       "shdd.h"

ULONG          ulRC;              /* Error return code            */ HSTREAM        hstream;           /* Stream handle                */ DDCMDREADWRITE ddcmdpb;           /* Parameter block              */ PDDCMDFN       pddcmdfn;          /* Pointer to DDCMD entry point */ PVOID          pBuffer;           /* Pointer to buffer            */ .                           .                            . /*---*/ /*  Perform a read from the physical device driver. */ /*---*/ ddcmdpb.ulFunction = DDCMD_READ; ddcmdpb.hstream = hstream; ddcmdpb.pBuffer = pBuffer; ddcmdpb.ulBufferSize = 32768;

if (ulRC = pddcmdfn (&ddcmdpb)) return (ulRC);   /* error!*/

DDCMD_REG_STREAM
This message registers a stream instance with a device driver for the first time.

pParmIn (PDDCMDREGISTER) A pointer to a DDCMDREGISTER data structure.
 * Parameter - pParmIn

Values for ulStreamOperation include:
 * STREAM_OPERATION_CONSUME
 * STREAM_OPERATION_PRODUCE

Values for ulAddressType include:
 * ADDRESS_TYPE_VIRTUAL
 * ADDRESS_TYPE_PHYSICAL
 * ADDRESS_TYPE_LINEAR

rc (ULONG) Error code indicating success or the type of failure:
 * Return Value - rc
 * NO_ERROR
 * Success.


 * ERROR_INVALID_FUNCTION
 * Illegal function requested.


 * ERROR_INVALID_STREAM
 * Invalid stream handle.


 * ERROR_HNDLR_REGISTERED
 * Stream had already been registered with the Sync/ Stream Manager.


 * ERROR_INVALID_SPCBKEY
 * Invalid SPCBKEY.


 * ERROR_INITIALIZATION
 * An error occurred during device initialization.


 * ERROR_STREAM_CREATION
 * An error occurred during the creation of this stream instance.


 * FAILURE
 * Device-driver-specific error return code.

A stream handler must register its entry point with the device driver once for each stream instance. This message sets up the communication link between the stream handler and the physical device driver.
 * Remarks

The following code illustrates how to register a stream instance with a device driver.
 * Example Code
 * 1) include       "os2.h"
 * 2) include       "os2me.h"
 * 3) include       "shdd.h"

ULONG          ulRC;                    /* Error return code      */ HSTREAM        hstream;                 /* Stream handle          */ DDCMDREGISTER  ddcmdpb;                 /* Parameter block        */ PDDCMDFN       pddcmdfn;                /* Pointer to DDCMD entry */ /* point                 */ ULONG          ulSysFileNum;            /* Global file handle     */ PSHDFN         pshdfn;                  /* Pointer to SHD entry   */ /* point                 */ SPCBKEY        spcbkey;                 /* Stream protocol key    */ .                            .                             . /*---*/ /*  Register a stream instance with a physical device driver. */ /*---*/  ddcmdpb.ulFunction = DDCMD_REGISTER; ddcmdpb.hstream = hstream; ddcmdpb.ulSysFileNum = ulSysFileNum; ddcmdpb.pSHDEntryPoint = pshdfn; ddcmdpb.ulStreamOperation = STREAM_OPERATION_CONSUME; ddcmdpb.spcbkey = spcbkey;

if (ulRC = pddcmdfn (&ddcmdpb)) return (ulRC);   /* error!*/

DDCMD_SETUP
This message performs device-specific stream instance setup.

pParmIn (PDDCMDSETUP) A pointer to a DDCMDSETUP data structure. The pSetupParmand ulSetupParmSize fields refer to the SETUP_PARM data structure.
 * Parameter - pParmIn

rc (ULONG) Error code indicating success or the type of failure:
 * Return Value - rc
 * NO_ERROR
 * Success.
 * ERROR_INVALID_FUNCTION
 * Illegal function requested.


 * ERROR_INVALID_STREAM
 * Invalid stream handle.


 * ERROR_INVALID_REQUEST
 * Invalid setup request.


 * ERROR_STREAM_NOT_STOP
 * The stream cannot perform the requested function unless the stream has been stopped.


 * FAILURE
 * Device-driver-specific error return code.

This message indicates to the physical device driver that a specific stream instance will become the active stream instance. The pSetupParm field is used for device-specific information. Typically, it is used to pass the current stream time from the stream handler to the PDD because a seek might have been requested on the stream prior to the stream start; thus, the PDD should adjust its time to this new reference time. Time is passed as a pointer to the time in milliseconds.
 * Remarks

The following code illustrates how to perform device-specific stream instance setup.
 * Example Code
 * 1) include       "os2.h"
 * 2) include       "os2me.h"
 * 3) include       "shdd.h"

ULONG          ulRC;                    /* Error return code     */ HSTREAM        hstream;                 /* Stream handle         */ DDCMDSETUP     ddcmdpb;                 /* Parameter block       */ PDDCMDFN       pddcmdfn;                /* Pointer to DDCMD entry*/ /* point                */ ULONG          ulStreamTime             /* Stream time           */ PVOID          pBuffer;                 /* Pointer to buffer     */ .                            .                             . /*--*/ /*Activate a stream instance in a physical device driver (Switch    */ /*                                                         context) */ /*--*/  ddcmdpb.ulFunction = DDCMD_SETUP; ddcmdpb.hstream = hstream; ddcmdpb.pSetupParm = &ulStreamTime;   /* Setting stream time */ ddcmdpbp.ulSetupParmSize = sizeof(ulStreamTime);

if (ulRC = pddcmdfn (&ddcmdpb)) return (ulRC);   /* error!*/

DDCMD_STATUS
This message requests status from the device.

pParmIn (PDDCMDSTATUS) A pointer to a DDCMDSTATUS data structure. The pStatusand ulStatusSize fields refer to the STATUS_PARM data structure.
 * Parameter - pParmIn

rc (ULONG) Error code indicating success or the type of failure:
 * Return Value - rc
 * NO_ERROR
 * Success.


 * ERROR_INVALID_FUNCTION
 * Illegal function requested.


 * ERROR_INVALID_STREAM
 * Invalid stream handle.


 * FAILURE
 * Device-driver-specific error return code.

This message queries the status of physical device driver. This message might not be supported by all physical device drivers. It is commonly used by the stream handler to request the current stream time from the physical device driver.
 * Remarks

The following code illustrates how to request status from the device.
 * Example Code
 * 1) include       "os2.h"
 * 2) include       "os2me.h"
 * 3) include       "shdd.h"

ULONG          ulRC;                     /* Error return code      */ HSTREAM        hstream;                  /* Stream handle          */ DDCMDSTATUS    ddcmdpb;                  /* Parameter block        */ PDDCMDFN       pddcmdfn;                 /* Pointer to DDCMD entry */ /* point                 */ .                           .                            . /**/ /*  Get the current stream time from the physical device driver. */ /**/ ddcmdpb.ulFunction = DDCMD_STATUS; ddcmdpb.hstream = hstream; ddcmdpb.pStatus =NULL;                   /* Return stream time*/ ddcmdpb.ulStatusSize = 0;

if (ulRC = pddcmdfn (&ddcmdpb)) return (ulRC);   /* error!*/

DDCMD_WRITE
This message performs a write from the buffer to the device.

pParmIn (PDDCMDREADWRITE) A pointer to a DDCMDREADWRITE data structure.
 * Parameter - pParmIn

rc (ULONG) Error code indicating success or the type of failure:
 * Return Value - rc
 * NO_ERROR
 * Success.


 * ERROR_INVALID_FUNCTION
 * Illegal function requested.


 * ERROR_INVALID_STREAM
 * Invalid stream handle.


 * ERROR_INVALID_BLOCK
 * Invalid address passed in parameter block.


 * FAILURE
 * Device-driver-specific error return code.

This message is used by a stream handler to give a full buffer to the physical device driver. An example would be the case of audio playback, where the stream handler passes a buffer with data to the physical device driver.
 * Remarks

The pBuffer parameter is a pointer to the data buffer. Note that this pointer is either a physical 0:32 pointer, 16:16 far pointer, or a global linear pointer. The pointer type is defined when the stream registers a stream with the device driver (DDCMD_REG_STREAM).

Many devices cannot handle a 0 length buffer. If the driver receives a 0 length buffer, it should not reject the buffer. The driver should do nothing with the buffer and return it in the same order in which it was sent.

The following code illustrates how to perform a write to the physical device driver.
 * Example Code
 * 1) include       "os2.h"
 * 2) include       "os2me.h"
 * 3) include       "shdd.h"

ULONG          ulRC;                     /* Error return code      */ HSTREAM        hstream;                  /* Stream handle          */ DDCMDREADWRITE ddcmdpb;                  /* Parameter block        */ PDDCMDFN       pddcmdfn;                 /* Pointer to DDCMD entry */ /* point                 */ PVOID          pBuffer;                  /* Pointer to buffer      */ .                            .                             . /**/ /*  Perform a write to the physical device driver. */ /**/  ddcmdpb.ulFunction = DDCMD_WRITE; ddcmdpb.hstream = hstream; ddcmdpb.pBuffer = pBuffer; ddcmdpb.ulBufferSize = 32768;

if (ulRC = pddcmdfn (&ddcmdpb)) return (ulRC);   /* error! */