Need help on old-style user-mode WinMM driver(Installable driver)

Discussion in 'Windows Vista Drivers' started by crystal28, Oct 30, 2008.

  1. crystal28

    crystal28 Guest

    I develop a user-mode WinMM driver,which exports DriverProc,widMessage
    ,wodMessage.I change registry table:
    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32]
    "wave"="XXX.dll"
    and the driver has been loaded.But there is no new item in control
    panel/audio and multimedia,and filters don't show in "audio capture sources"
    and "audio renders" of Graphedit.How to make the filters show?Is there any
    sample?
    Thanks a lot.Here is the code of the driver:

    #include "stdafx.h"
    #include "stdio.h"
    #include "mmsystem.h"
    #include "mmddk.h"
    BOOL APIENTRY DllMain( HANDLE hModule,
    DWORD ul_reason_for_call,
    LPVOID lpReserved
    )
    {
    return TRUE;
    }
    typedef struct tagWAVEMAPDATA {
    struct tagWAVEMAPDATA* self;
    HWAVE hOuterWave;
    HWAVE hInnerWave;

    /* needed data to filter callbacks. Only needed when hAcmStream is not 0
    */
    DWORD dwCallback;
    DWORD dwClientInstance;
    DWORD dwFlags;
    } WAVEMAPDATA;

    static void CALLBACK wodCallback(HWAVE hWave, UINT uMsg, DWORD dwInstance,
    DWORD dwParam1, DWORD dwParam2)
    {
    WAVEMAPDATA* wom = (WAVEMAPDATA*)dwInstance;

    //TRACE("(0x%x %u %ld %lx %lx);\n", hWave, uMsg, dwInstance, dwParam1,
    dwParam2);

    switch (uMsg) {
    case WOM_OPEN:
    case WOM_CLOSE:
    /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
    break;
    case WOM_DONE:
    break;
    default:
    break;
    }

    DriverCallback(wom->dwCallback, HIWORD(wom->dwFlags),
    (HDRVR)wom->hOuterWave,
    uMsg, wom->dwClientInstance, dwParam1, dwParam2);
    }

    static DWORD wodOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
    {
    UINT ndlo, ndhi;
    UINT i;
    WAVEMAPDATA* wom = (WAVEMAPDATA*)HeapAlloc(GetProcessHeap(), 0,
    sizeof(WAVEMAPDATA));
    if (!wom)
    {
    return MMSYSERR_NOMEM;
    }

    ndhi = waveOutGetNumDevs();
    ndlo = 0;
    wom->self = wom;
    wom->dwCallback = lpDesc->dwCallback;
    wom->dwFlags = dwFlags;
    wom->dwClientInstance = lpDesc->dwInstance;
    wom->hOuterWave = lpDesc->hWave;

    for (i = ndlo; i < ndhi; i++) {
    if (waveOutOpen((HWAVEOUT * )&wom->hInnerWave, i,
    (PWAVEFORMATEX)lpDesc->lpFormat, (DWORD)wodCallback,
    (DWORD)wom, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION |
    WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) {
    goto found;
    }
    }

    HeapFree(GetProcessHeap(), 0, wom);
    return MMSYSERR_ALLOCATED;
    found:
    if (dwFlags & WAVE_FORMAT_QUERY)
    {
    *lpdwUser = 0L;
    HeapFree(GetProcessHeap(), 0, wom);
    }
    else
    {
    *lpdwUser = (DWORD)wom;
    }
    return MMSYSERR_NOERROR;
    }

    static DWORD wodClose(WAVEMAPDATA* wom)
    {
    DWORD ret = waveOutClose((HWAVEOUT)wom->hInnerWave);
    if (ret == MMSYSERR_NOERROR) {
    HeapFree(GetProcessHeap(), 0, wom);
    }
    return ret;
    }

    static DWORD wodWrite(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD
    dwParam2)
    {

    return waveOutWrite((HWAVEOUT)wom->hInnerWave, lpWaveHdrSrc, dwParam2);
    }

    static DWORD wodPrepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD
    dwParam2)
    {

    return waveOutPrepareHeader((HWAVEOUT)wom->hInnerWave, lpWaveHdrSrc,
    dwParam2);
    }

    static DWORD wodUnprepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD
    dwParam2)
    {
    return waveOutUnprepareHeader((HWAVEOUT)wom->hInnerWave, lpWaveHdrSrc,
    dwParam2);
    }

    static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)
    {
    return waveOutGetPosition((HWAVEOUT)wom->hInnerWave, lpTime, dwParam2);
    }

    static DWORD wodGetDevCaps(UINT wDevID, WAVEMAPDATA* wom, LPWAVEOUTCAPSA
    lpWaveCaps, DWORD dwParam2)
    {
    /* if opened low driver, forward message */
    return waveOutGetDevCapsA((UINT)wom->hInnerWave, lpWaveCaps, dwParam2);
    }

    static DWORD wodGetVolume(UINT wDevID, WAVEMAPDATA* wom, LPDWORD lpVol)
    {
    return waveOutGetVolume((HWAVEOUT)wom->hInnerWave, lpVol);
    }

    static DWORD wodSetVolume(UINT wDevID, WAVEMAPDATA* wom, DWORD vol)
    {
    return waveOutSetVolume((HWAVEOUT)wom->hInnerWave, vol);
    }

    static DWORD wodPause(WAVEMAPDATA* wom)
    {
    return waveOutPause((HWAVEOUT)wom->hInnerWave);
    }

    static DWORD wodRestart(WAVEMAPDATA* wom)
    {
    return waveOutRestart((HWAVEOUT)wom->hInnerWave);
    }

    static DWORD wodReset(WAVEMAPDATA* wom)
    {
    return waveOutReset((HWAVEOUT)wom->hInnerWave);
    }

    static DWORD wodBreakLoop(WAVEMAPDATA* wom)
    {
    return waveOutBreakLoop((HWAVEOUT)wom->hInnerWave);
    }

    static DWORD wodMapperStatus(WAVEMAPDATA* wom, DWORD flags, LPVOID ptr)
    {
    UINT id;
    DWORD ret = MMSYSERR_NOTSUPPORTED;

    switch (flags) {
    case WAVEOUT_MAPPER_STATUS_DEVICE:
    ret = waveOutGetID((HWAVEOUT)wom->hInnerWave, &id);
    *(LPDWORD)ptr = id;
    break;
    case WAVEOUT_MAPPER_STATUS_MAPPED:
    *(LPDWORD)ptr = 0; /* FIXME ?? */
    break;
    case WAVEOUT_MAPPER_STATUS_FORMAT:
    /* ptr points to a WAVEFORMATEX struct - before or after streaming ? */
    *(LPDWORD)ptr = 0;
    break;
    default:
    *(LPDWORD)ptr = 0;
    break;
    }
    return ret;
    }

    /**************************************************************************
    * wodMessage (MSACMMAP.@)
    */
    DWORD WINAPI wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
    DWORD dwParam1, DWORD dwParam2)
    {
    switch (wMsg) {
    case DRVM_INIT:
    case DRVM_EXIT:
    case DRVM_ENABLE:
    case DRVM_DISABLE:
    /* FIXME: Pretend this is supported */
    return 0;
    case WODM_OPEN: return wodOpen ((LPDWORD)dwUser,
    (LPWAVEOPENDESC)dwParam1,dwParam2);
    case WODM_CLOSE: return wodClose ((WAVEMAPDATA*)dwUser);
    case WODM_WRITE: return wodWrite ((WAVEMAPDATA*)dwUser,
    (LPWAVEHDR)dwParam1, dwParam2);
    case WODM_PAUSE: return wodPause ((WAVEMAPDATA*)dwUser);
    case WODM_GETPOS: return wodGetPosition ((WAVEMAPDATA*)dwUser,
    (LPMMTIME)dwParam1, dwParam2);
    case WODM_BREAKLOOP: return wodBreakLoop ((WAVEMAPDATA*)dwUser);
    case WODM_PREPARE: return wodPrepare ((WAVEMAPDATA*)dwUser,
    (LPWAVEHDR)dwParam1, dwParam2);
    case WODM_UNPREPARE: return wodUnprepare ((WAVEMAPDATA*)dwUser,
    (LPWAVEHDR)dwParam1, dwParam2);
    case WODM_GETDEVCAPS: return wodGetDevCaps (wDevID, (WAVEMAPDATA*)dwUser,
    (LPWAVEOUTCAPSA)dwParam1,dwParam2);
    case WODM_GETNUMDEVS: return 1;
    case WODM_GETPITCH: return MMSYSERR_NOTSUPPORTED;
    case WODM_SETPITCH: return MMSYSERR_NOTSUPPORTED;
    case WODM_GETPLAYBACKRATE: return MMSYSERR_NOTSUPPORTED;
    case WODM_SETPLAYBACKRATE: return MMSYSERR_NOTSUPPORTED;
    case WODM_GETVOLUME: return wodGetVolume (wDevID, (WAVEMAPDATA*)dwUser,
    (LPDWORD)dwParam1);
    case WODM_SETVOLUME: return wodSetVolume (wDevID, (WAVEMAPDATA*)dwUser,
    dwParam1);
    case WODM_RESTART: return wodRestart ((WAVEMAPDATA*)dwUser);
    case WODM_RESET: return wodReset ((WAVEMAPDATA*)dwUser);
    case WODM_MAPPER_STATUS: return wodMapperStatus ((WAVEMAPDATA*)dwUser,
    dwParam1, (LPVOID)dwParam2);
    default:
    break;
    }
    return MMSYSERR_NOTSUPPORTED;
    }

    static void CALLBACK widCallback(HWAVE hWave, UINT uMsg, DWORD dwInstance,
    DWORD dwParam1, DWORD dwParam2)
    {
    WAVEMAPDATA* wim = (WAVEMAPDATA*)dwInstance;

    switch (uMsg) {
    case WIM_OPEN:
    case WIM_CLOSE:
    /* dwParam1 & dwParam2 are supposed to be 0, nothing to do */
    break;
    case WIM_DATA:

    break;
    default:
    break;
    }

    DriverCallback(wim->dwCallback, HIWORD(wim->dwFlags),
    (HDRVR)wim->hOuterWave,
    uMsg, wim->dwClientInstance, dwParam1, dwParam2);
    }
    static DWORD widOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
    {
    UINT ndlo, ndhi;
    UINT i;
    WAVEMAPDATA* wim = (WAVEMAPDATA*)HeapAlloc(GetProcessHeap(), 0,
    sizeof(WAVEMAPDATA));

    if (!wim)
    return MMSYSERR_NOMEM;

    wim->self = wim;
    wim->dwCallback = lpDesc->dwCallback;
    wim->dwFlags = dwFlags;
    wim->dwClientInstance = lpDesc->dwInstance;
    wim->hOuterWave = lpDesc->hWave;

    ndhi = waveOutGetNumDevs();
    ndlo = 0;

    for (i = ndlo; i < ndhi; i++) {
    if (waveInOpen((HWAVEIN * )&wim->hInnerWave, i,
    (PWAVEFORMATEX)lpDesc->lpFormat, (DWORD)widCallback,
    (DWORD)wim, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION |
    WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) {
    goto found;
    }
    }

    HeapFree(GetProcessHeap(), 0, wim);
    return MMSYSERR_ALLOCATED;
    found:
    if (dwFlags & WAVE_FORMAT_QUERY) {
    *lpdwUser = 0L;
    HeapFree(GetProcessHeap(), 0, wim);
    } else {
    *lpdwUser = (DWORD)wim;
    }
    return MMSYSERR_NOERROR;
    }

    static DWORD widClose(WAVEMAPDATA* wim)
    {
    DWORD ret = waveInClose((HWAVEIN)wim->hInnerWave);

    if (ret == MMSYSERR_NOERROR) {
    HeapFree(GetProcessHeap(), 0, wim);
    }
    return ret;
    }

    static DWORD widAddBuffer(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD
    dwParam2)
    {
    return waveInAddBuffer((HWAVEIN)wim->hInnerWave, lpWaveHdrDst, dwParam2);
    }

    static DWORD widPrepare(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD
    dwParam2)
    {
    return waveInPrepareHeader((HWAVEIN)wim->hInnerWave, lpWaveHdrDst,
    dwParam2);

    }

    static DWORD widUnprepare(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD
    dwParam2)
    {
    return waveInUnprepareHeader((HWAVEIN)wim->hInnerWave, lpWaveHdrDst,
    dwParam2);
    }

    static DWORD widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2)
    {
    return waveInGetPosition((HWAVEIN)wim->hInnerWave, lpTime, dwParam2);
    }

    static DWORD widGetDevCaps(UINT wDevID, WAVEMAPDATA* wim, LPWAVEINCAPSA
    lpWaveCaps, DWORD dwParam2)
    {
    /* if opened low driver, forward message */
    return waveInGetDevCapsA((UINT)wim->hInnerWave, lpWaveCaps, dwParam2);
    }

    static DWORD widStop(WAVEMAPDATA* wim)
    {
    return waveInStop((HWAVEIN)wim->hInnerWave);
    }

    static DWORD widStart(WAVEMAPDATA* wim)
    {
    return waveInStart((HWAVEIN)wim->hInnerWave);
    }

    static DWORD widReset(WAVEMAPDATA* wim)
    {
    return waveInReset((HWAVEIN)wim->hInnerWave);
    }

    static DWORD widMapperStatus(WAVEMAPDATA* wim, DWORD flags, LPVOID ptr)
    {
    UINT id;
    DWORD ret = MMSYSERR_NOTSUPPORTED;

    switch (flags) {
    case WAVEIN_MAPPER_STATUS_DEVICE:
    ret = waveInGetID((HWAVEIN)wim->hInnerWave, &id);
    *(LPDWORD)ptr = id;
    break;
    case WAVEIN_MAPPER_STATUS_MAPPED:
    *(LPDWORD)ptr = 0; /* FIXME ?? */
    break;
    case WAVEIN_MAPPER_STATUS_FORMAT:
    /* ptr points to a WAVEFORMATEX struct - before or after streaming ? */
    *(LPDWORD)ptr = 0; /* FIXME ?? */
    break;
    default:
    *(LPDWORD)ptr = 0;
    break;
    }
    return ret;
    }

    /**************************************************************************
    * widMessage (MSACMMAP.@)
    */
    DWORD WINAPI widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
    DWORD dwParam1, DWORD dwParam2)
    {
    switch (wMsg) {
    case DRVM_INIT:
    case DRVM_EXIT:
    case DRVM_ENABLE:
    case DRVM_DISABLE:
    /* FIXME: Pretend this is supported */
    return 0;

    case WIDM_OPEN: return widOpen ((LPDWORD)dwUser,
    (LPWAVEOPENDESC)dwParam1, dwParam2);
    case WIDM_CLOSE: return widClose ((WAVEMAPDATA*)dwUser);

    case WIDM_ADDBUFFER: return widAddBuffer ((WAVEMAPDATA*)dwUser,
    (LPWAVEHDR)dwParam1, dwParam2);
    case WIDM_PREPARE: return widPrepare ((WAVEMAPDATA*)dwUser,
    (LPWAVEHDR)dwParam1, dwParam2);
    case WIDM_UNPREPARE: return widUnprepare ((WAVEMAPDATA*)dwUser,
    (LPWAVEHDR)dwParam1, dwParam2);
    case WIDM_GETDEVCAPS: return widGetDevCaps (wDevID,
    (WAVEMAPDATA*)dwUser, (LPWAVEINCAPSA)dwParam1, dwParam2);
    case WIDM_GETNUMDEVS: return 1;
    case WIDM_GETPOS: return widGetPosition ((WAVEMAPDATA*)dwUser,
    (LPMMTIME)dwParam1, dwParam2);
    case WIDM_RESET: return widReset ((WAVEMAPDATA*)dwUser);
    case WIDM_START: return widStart ((WAVEMAPDATA*)dwUser);
    case WIDM_STOP: return widStop ((WAVEMAPDATA*)dwUser);
    case WIDM_MAPPER_STATUS: return widMapperStatus ((WAVEMAPDATA*)dwUser,
    dwParam1, (LPVOID)dwParam2);
    default:
    break;
    }
    return MMSYSERR_NOTSUPPORTED;
    }

    /*======================================================================*
    * Driver part *
    *======================================================================*/

    static struct WINE_WAVEMAP* oss = NULL;

    /**************************************************************************
    * WAVEMAP_drvOpen [internal]
    */
    static DWORD WAVEMAP_drvOpen(LPSTR str)
    {
    if (oss)
    return 0;

    /* I know, this is ugly, but who cares... */
    oss = (struct WINE_WAVEMAP*)1;
    return 1;
    }

    /**************************************************************************
    * WAVEMAP_drvClose [internal]
    */
    static DWORD WAVEMAP_drvClose(DWORD dwDevID)
    {
    if (oss) {
    oss = NULL;
    return 1;
    }
    return 0;
    }

    /**************************************************************************
    * DriverProc (MSACMMAP.@)
    */
    LRESULT CALLBACK DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
    DWORD dwParam1, DWORD dwParam2)
    {

    switch(wMsg) {
    case DRV_LOAD: return 1;
    case DRV_FREE: return 1;
    case DRV_OPEN: return WAVEMAP_drvOpen((LPSTR)dwParam1);
    case DRV_CLOSE: return WAVEMAP_drvClose(dwDevID);
    case DRV_ENABLE: return 1;
    case DRV_DISABLE: return 1;
    case DRV_QUERYCONFIGURE: return 1;
    case DRV_CONFIGURE: MessageBoxA(0, "WAVEMAP MultiMedia Driver !", "OSS
    Driver", MB_OK); return 1;
    case DRV_INSTALL: return DRVCNF_RESTART;
    case DRV_REMOVE: return DRVCNF_RESTART;
    default:
    return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
    }
    }
     
    crystal28, Oct 30, 2008
    #1
    1. Advertisements

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Similar Threads
  1. John M. Dlugosz

    Font Size - XP style vs Vista style

    John M. Dlugosz, Feb 19, 2008, in forum: Windows Vista General Discussion
    Replies:
    1
    Views:
    609
    Guest
    Feb 19, 2008
  2. John M. Dlugosz

    Font Size - XP style vs Vista style

    John M. Dlugosz, Feb 20, 2008, in forum: Windows Vista General Discussion
    Replies:
    0
    Views:
    569
    John M. Dlugosz
    Feb 20, 2008
  3. John M. Dlugosz

    Font Size - XP style vs Vista style

    John M. Dlugosz, Feb 24, 2008, in forum: Windows Vista General Discussion
    Replies:
    0
    Views:
    551
    John M. Dlugosz
    Feb 24, 2008
  4. User mode winmm driver sample needed!

    , Jan 31, 2006, in forum: Windows Vista Drivers
    Replies:
    0
    Views:
    506
  5. Mark needs WinMMWDM Help

    WinMM Device deleted; no way to reinstall; no sound

    Mark needs WinMMWDM Help, Mar 20, 2006, in forum: Windows Media Player
    Replies:
    1
    Views:
    257
    Neil Smith [MVP Digital Media]
    Mar 20, 2006
  6. Ed

    winmm.dll

    Ed, Sep 14, 2003, in forum: Windows Update
    Replies:
    1
    Views:
    258
    Sir_George
    Sep 14, 2003
  7. Opinicus
    Replies:
    3
    Views:
    508
    Opinicus
    Nov 15, 2007
  8. John K

    winmm.dll

    John K, May 2, 2006, in forum: Windows Media Center
    Replies:
    1
    Views:
    321
    Doug Knox MS-MVP
    May 2, 2006
Loading...