Beispiel #1
0
LONG APIENTRY
DriverProc(
    DWORD DriverId,
    HANDLE DriverHandle,
    UINT Message,
    LONG Parameter1,
    LONG Parameter2)
{
    MMRESULT Result;

    switch ( Message )
    {
        case DRV_LOAD :
        {
            SND_TRACE(L"DRV_LOAD\n");

            Result = InitEntrypointMutexes();

            if ( ! MMSUCCESS(Result) )
                return 0L;

            Result = EnumerateNt4ServiceSoundDevices(L"sndblst",
                                                     0,
                                                     FoundDevice);

            if ( ! MMSUCCESS(Result) )
            {
                CleanupEntrypointMutexes();

                UnlistAllSoundDevices();

                return 0L;
            }

/*
            PSOUND_DEVICE snd;
            GetSoundDevice(WAVE_OUT_DEVICE_TYPE, 0, &snd);
            GetSoundDevice(AUX_DEVICE_TYPE, 0, &snd);
            GetSoundDevice(AUX_DEVICE_TYPE, 1, &snd);
            GetSoundDevice(AUX_DEVICE_TYPE, 2, &snd);
*/

            SND_TRACE(L"Initialisation complete\n");

            return 1L;
        }

        case DRV_FREE :
        {
            SND_TRACE(L"DRV_FREE\n");

            /* TODO: Clean up the path names! */
            UnlistAllSoundDevices();

            CleanupEntrypointMutexes();

            SND_TRACE(L"Unfreed memory blocks: %d\n",
                      GetMemoryAllocationCount());

            return 1L;
        }

        case DRV_ENABLE :
        case DRV_DISABLE :
        {
            SND_TRACE(L"DRV_ENABLE / DRV_DISABLE\n");
            return 1L;
        }

        case DRV_OPEN :
        case DRV_CLOSE :
        {
            SND_TRACE(L"DRV_OPEN / DRV_CLOSE\n");
            return 1L;
        }

        case DRV_QUERYCONFIGURE :
        {
            SND_TRACE(L"DRV_QUERYCONFIGURE");
            return 0L;
        }
        case DRV_CONFIGURE :
            return DRVCNF_OK;

        default :
            SND_TRACE(L"Unhandled message %d\n", Message);
            return DefDriverProc(DriverId,
                                 DriverHandle,
                                 Message,
                                 Parameter1,
                                 Parameter2);
    }
}
Beispiel #2
0
MMRESULT
GetSoundBlasterDeviceCapabilities(
    IN  PSOUND_DEVICE SoundDevice,
    IN  DWORD DeviceId,
    OUT PVOID Capabilities,
    IN  DWORD CapabilitiesSize)
{
    MMRESULT Result;
    MMDEVICE_TYPE DeviceType;

    SND_ASSERT( SoundDevice );
    SND_ASSERT( Capabilities );

    SND_TRACE(L"Sndblst - GetSoundBlasterDeviceCapabilities\n");

    Result = GetSoundDeviceType(SoundDevice, &DeviceType);
    SND_ASSERT( Result == MMSYSERR_NOERROR );

    /* Use the default method of obtaining device capabilities */
    Result = GetNt4SoundDeviceCapabilities(SoundDevice,
                                           Capabilities,
                                           CapabilitiesSize);

    if ( ! MMSUCCESS(Result) )
        return Result;

    /* Inject the appropriate device name */
    switch ( DeviceType )
    {
        case WAVE_OUT_DEVICE_TYPE :
        {
            LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;
            CopyWideString(WaveOutCaps->szPname, SBWaveOutDeviceName);
            break;
        }
        case WAVE_IN_DEVICE_TYPE :
        {
            LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities;
            CopyWideString(WaveInCaps->szPname, SBWaveInDeviceName);
            break;
        }
        case MIDI_OUT_DEVICE_TYPE :
        {
            LPMIDIOUTCAPS MidiOutCaps = (LPMIDIOUTCAPS) Capabilities;
            CopyWideString(MidiOutCaps->szPname, SBMidiOutDeviceName);
            break;
        }
        case MIDI_IN_DEVICE_TYPE :
        {
            LPMIDIINCAPS MidiInCaps = (LPMIDIINCAPS) Capabilities;
            CopyWideString(MidiInCaps->szPname, SBMidiInDeviceName);
            break;
        }
        case AUX_DEVICE_TYPE :
        {
            LPAUXCAPS AuxCaps = (LPAUXCAPS) Capabilities;
            CopyWideString(AuxCaps->szPname, SBAuxDeviceName);
            break;
        }
        case MIXER_DEVICE_TYPE :
        {
            LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities;
            CopyWideString(MixerCaps->szPname, SBMixerDeviceName);
            break;
        }
    }

    return MMSYSERR_NOERROR;
}
Beispiel #3
0
/*
    Standard MME driver entry-point for messages relating to MIDI output.
*/
DWORD
APIENTRY
modMessage(
    UINT DeviceId,
    UINT Message,
    DWORD_PTR PrivateHandle,
    DWORD_PTR Parameter1,
    DWORD_PTR Parameter2)
{
    MMRESULT Result = MMSYSERR_NOTSUPPORTED;

    AcquireEntrypointMutex(MIDI_OUT_DEVICE_TYPE);

    SND_TRACE(L"modMessage - Message type %d\n", Message);

    switch ( Message )
    {
    case MODM_GETNUMDEVS :
    {
        Result = GetSoundDeviceCount(MIDI_OUT_DEVICE_TYPE);
        break;
    }

    case MODM_GETDEVCAPS :
    {
        Result = MmeGetSoundDeviceCapabilities(MIDI_OUT_DEVICE_TYPE,
                                               DeviceId,
                                               (PVOID) Parameter1,
                                               Parameter2);
        break;
    }

    case DRV_QUERYDEVICEINTERFACESIZE :
    {
        Result = MmeGetDeviceInterfaceString(MIDI_OUT_DEVICE_TYPE, DeviceId, NULL, 0, (DWORD*)Parameter1); //FIXME DWORD_PTR
        break;
    }

    case DRV_QUERYDEVICEINTERFACE :
    {
        Result = MmeGetDeviceInterfaceString(MIDI_OUT_DEVICE_TYPE, DeviceId, (LPWSTR)Parameter1, Parameter2, NULL); //FIXME DWORD_PTR
        break;
    }

    case MODM_OPEN :
    {
        Result = MmeOpenDevice(MIDI_OUT_DEVICE_TYPE,
                               DeviceId,
                               (LPWAVEOPENDESC) Parameter1, /* unused */
                               Parameter2,
                               (DWORD_PTR*)PrivateHandle);
        break;
    }

    case MODM_CLOSE :
    {
        Result = MmeCloseDevice(PrivateHandle);

        break;
    }

    }

    SND_TRACE(L"modMessage returning MMRESULT %d\n", Result);

    ReleaseEntrypointMutex(MIDI_OUT_DEVICE_TYPE);

    return Result;
}
Beispiel #4
0
/*
    Open one of the Device sub-keys belonging to the sound driver.
    NT4 only.
*/
MMRESULT
OpenSoundDeviceRegKey(
    IN  LPWSTR ServiceName,
    IN  DWORD DeviceIndex,
    OUT PHKEY KeyHandle)
{
    SIZE_T PathLength;
    PWCHAR RegPath;

    VALIDATE_MMSYS_PARAMETER( ServiceName );
    VALIDATE_MMSYS_PARAMETER( KeyHandle );

    /*
        Work out the space required to hold the path:

        HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
            sndblst\
                Parameters\
                    Device123\
    */
    PathLength = wcslen(REG_SERVICES_KEY_NAME_U) + 1
               + wcslen(ServiceName) + 1
               + wcslen(REG_PARAMETERS_KEY_NAME_U) + 1
               + wcslen(REG_DEVICE_KEY_NAME_U)
               + GetDigitCount(DeviceIndex);

    /* Allocate storage for the string */
    RegPath = AllocateWideString(PathLength);

    if ( ! RegPath )
    {
        return MMSYSERR_NOMEM;
    }

    /* Write the path */
    wsprintf(RegPath,
             L"%ls\\%ls\\%ls\\%ls%d",
             REG_SERVICES_KEY_NAME_U,
             ServiceName,
             REG_PARAMETERS_KEY_NAME_U,
             REG_DEVICE_KEY_NAME_U,
             DeviceIndex);

    SND_TRACE(L"Opening reg key: %wS\n", RegPath);

    /* Perform the open */
    if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                      RegPath,
                      0,
                      KEY_READ,
                      KeyHandle) != ERROR_SUCCESS )
    {
        /* Couldn't open the key */
        SND_ERR(L"Failed to open reg key: %wS\n", RegPath);
        FreeMemory(RegPath);
        return MMSYSERR_ERROR;
    }

    FreeMemory(RegPath);

    return MMSYSERR_NOERROR;
}
Beispiel #5
0
MMRESULT
DestroySoundDeviceInstance(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
{
    MMRESULT Result;
    PMMFUNCTION_TABLE FunctionTable;
    PSOUND_DEVICE SoundDevice;
    PVOID Handle;

    SND_TRACE(L"Destroying a sound device instance\n");

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );

    Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
    if ( ! MMSUCCESS(Result) )
        return TranslateInternalMmResult(Result);

    Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
    if ( ! MMSUCCESS(Result) )
        return TranslateInternalMmResult(Result);

    /* Get the "close" routine from the function table, and validate it */
    Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
    if ( ! MMSUCCESS(Result) )
        return TranslateInternalMmResult(Result);

    SND_ASSERT( FunctionTable->Close );
    if ( FunctionTable->Close == NULL )
    {
        /* This indicates bad practice, really! If you can open, why not close?! */
        return MMSYSERR_NOTSUPPORTED;
    }

    /* Stop the streaming thread */
    if ( SoundDeviceInstance->Thread )
    {
        Result = DestroySoundThread(SoundDeviceInstance->Thread);
        SND_ASSERT( MMSUCCESS(Result) );    /* It should succeed! */
        if ( ! MMSUCCESS(Result ) )
        {
            return TranslateInternalMmResult(Result);
        }
    }

    /* Blank this out here */
    SoundDeviceInstance->Thread = NULL;

    /* Try and close the device */
    Result = FunctionTable->Close(SoundDeviceInstance, Handle);
    SND_ASSERT( MMSUCCESS(Result) );    /* It should succeed! */
    if ( ! MMSUCCESS(Result) )
        return TranslateInternalMmResult(Result);

    /* Drop it from the list */
    Result = UnlistSoundDeviceInstance(SoundDeviceInstance);
    SND_ASSERT( MMSUCCESS(Result) );    /* It should succeed! */
    if ( ! MMSUCCESS(Result) )
        return TranslateInternalMmResult(Result);

    FreeSoundDeviceInstance(SoundDeviceInstance);

    return MMSYSERR_NOERROR;
}
Beispiel #6
0
/*
    Provides an implementation for the "get capabilities" request,
    using the standard IOCTLs used by NT4 sound drivers.
*/
MMRESULT
GetNt4SoundDeviceCapabilities(
    IN  PSOUND_DEVICE SoundDevice,
    OUT PVOID Capabilities,
    IN  DWORD CapabilitiesSize)
{
    MMRESULT Result;
    MMDEVICE_TYPE DeviceType;
    DWORD IoCtl;
    HANDLE DeviceHandle;

    /* If these are bad there's an internal error with MME-Buddy! */
    SND_ASSERT( SoundDevice );
    SND_ASSERT( Capabilities );
    SND_ASSERT( CapabilitiesSize > 0 );

    SND_TRACE(L"NT4 get-capabilities routine called\n");

    /* Get the device type */
    Result = GetSoundDeviceType(SoundDevice, &DeviceType);
    SND_ASSERT( Result == MMSYSERR_NOERROR );

    if ( ! MMSUCCESS(Result) )
        return TranslateInternalMmResult(Result);

    /* Choose the appropriate IOCTL */
    if ( IS_WAVE_DEVICE_TYPE(DeviceType) )
    {
        IoCtl = IOCTL_WAVE_GET_CAPABILITIES;
    }
    else if ( IS_MIDI_DEVICE_TYPE(DeviceType) )
    {
        IoCtl = IOCTL_MIDI_GET_CAPABILITIES;
    }
    else
    {
        /* FIXME - need to support AUX and mixer devices */
        SND_ASSERT( FALSE );
        IoCtl = 0;
    }

    /* Get the capabilities information from the driver */
    Result = OpenNt4KernelSoundDevice(SoundDevice, TRUE, &DeviceHandle);

    if ( ! MMSUCCESS(Result) )
    {
        SND_ERR(L"Failed to open device");
        return TranslateInternalMmResult(Result);
    }

    Result = SyncOverlappedDeviceIoControl(DeviceHandle,
                                           IoCtl,
                                           Capabilities,
                                           CapabilitiesSize,
                                           NULL,
                                           0,
                                           NULL);

    CloseKernelSoundDevice(DeviceHandle);

    if ( ! MMSUCCESS(Result) )
    {
        SND_ERR(L"Retrieval of capabilities information failed\n");
        Result = TranslateInternalMmResult(Result);
    }

    return Result;
}
Beispiel #7
0
MMRESULT
CreateSoundDeviceInstance(
    IN  PSOUND_DEVICE SoundDevice,
    OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance)
{
    MMRESULT Result;
    PMMFUNCTION_TABLE FunctionTable;

    SND_TRACE(L"Creating a sound device instance\n");

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
    VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance != NULL );

    Result = AllocateSoundDeviceInstance(SoundDeviceInstance);

    if ( ! MMSUCCESS(Result) )
        return TranslateInternalMmResult(Result);

    /* Get the "open" routine from the function table, and validate it */
    Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
    if ( ! MMSUCCESS(Result) )
    {
        FreeSoundDeviceInstance(*SoundDeviceInstance);
        return TranslateInternalMmResult(Result);
    }

    if ( FunctionTable->Open == NULL )
    {
        FreeSoundDeviceInstance(*SoundDeviceInstance);
        return MMSYSERR_NOTSUPPORTED;
    }

    /* Set up the members of the structure */
    (*SoundDeviceInstance)->Next = NULL; 
    (*SoundDeviceInstance)->Device = SoundDevice;
    (*SoundDeviceInstance)->Handle = NULL;
    (*SoundDeviceInstance)->Thread = NULL;

    (*SoundDeviceInstance)->WinMM.Handle = INVALID_HANDLE_VALUE;
    (*SoundDeviceInstance)->WinMM.ClientCallback = 0;
    (*SoundDeviceInstance)->WinMM.ClientCallbackInstanceData = 0;
    (*SoundDeviceInstance)->WinMM.Flags = 0;

    /* Initialise the members of the struct used by the sound thread */
    (*SoundDeviceInstance)->HeadWaveHeader = NULL;
    (*SoundDeviceInstance)->TailWaveHeader = NULL;

    (*SoundDeviceInstance)->OutstandingBuffers = 0;

    (*SoundDeviceInstance)->LoopsRemaining = 0;

    /* Create the streaming thread (TODO - is this for wave only?) */
    Result = CreateSoundThread(&(*SoundDeviceInstance)->Thread);
    if ( ! MMSUCCESS(Result) )
    {
        FreeSoundDeviceInstance(*SoundDeviceInstance);
        return TranslateInternalMmResult(Result);
    }

    /* Add the instance to the list */
    Result = ListSoundDeviceInstance(SoundDevice, *SoundDeviceInstance);
    if ( ! MMSUCCESS(Result) )
    {
        FreeSoundDeviceInstance(*SoundDeviceInstance);
        return TranslateInternalMmResult(Result);
    }

    /* Try and open the device */
    Result = FunctionTable->Open(SoundDevice, (&(*SoundDeviceInstance)->Handle));
    if ( ! MMSUCCESS(Result) )
    {
        UnlistSoundDeviceInstance(*SoundDeviceInstance);
        FreeSoundDeviceInstance(*SoundDeviceInstance);
        return TranslateInternalMmResult(Result);
    }

    return MMSYSERR_NOERROR;
}
Beispiel #8
0
MMRESULT
WdmAudQueryMixerInfoByLegacy(
    IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
    IN DWORD DeviceId,
    IN UINT uMsg,
    IN LPVOID Parameter,
    IN DWORD Flags)
{
    MMRESULT Result;
    WDMAUD_DEVICE_INFO DeviceInfo;
    HANDLE Handle;
    DWORD IoControlCode;
    LPMIXERLINEW MixLine;
    LPMIXERLINECONTROLSW MixControls;
    LPMIXERCONTROLDETAILS MixDetails;

    SND_TRACE(L"uMsg %x Flags %x\n", uMsg, Flags);

    Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
    SND_ASSERT( Result == MMSYSERR_NOERROR );

    ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
    DeviceInfo.hDevice = Handle;
    DeviceInfo.DeviceIndex = DeviceId;
    DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
    DeviceInfo.Flags = Flags;

    MixLine = (LPMIXERLINEW)Parameter;
    MixControls = (LPMIXERLINECONTROLSW)Parameter;
    MixDetails = (LPMIXERCONTROLDETAILS)Parameter;

    switch(uMsg)
    {
    case MXDM_GETLINEINFO:
        RtlCopyMemory(&DeviceInfo.u.MixLine, MixLine, sizeof(MIXERLINEW));
        IoControlCode = IOCTL_GETLINEINFO;
        break;
    case MXDM_GETLINECONTROLS:
        RtlCopyMemory(&DeviceInfo.u.MixControls, MixControls, sizeof(MIXERLINECONTROLSW));
        IoControlCode = IOCTL_GETLINECONTROLS;
        break;
    case MXDM_SETCONTROLDETAILS:
        RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
        IoControlCode = IOCTL_SETCONTROLDETAILS;
        break;
    case MXDM_GETCONTROLDETAILS:
        RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
        IoControlCode = IOCTL_GETCONTROLDETAILS;
        break;
    default:
        SND_ASSERT(0);
        return MMSYSERR_NOTSUPPORTED;
    }

    Result = SyncOverlappedDeviceIoControl(KernelHandle,
                                           IoControlCode,
                                           (LPVOID) &DeviceInfo,
                                           sizeof(WDMAUD_DEVICE_INFO),
                                           (LPVOID) &DeviceInfo,
                                           sizeof(WDMAUD_DEVICE_INFO),
                                           NULL);

    if ( ! MMSUCCESS(Result) )
    {
        return Result;
    }

    switch(uMsg)
    {
    case MXDM_GETLINEINFO:
    {
        RtlCopyMemory(MixLine, &DeviceInfo.u.MixLine, sizeof(MIXERLINEW));
        break;
    }
    }

    return Result;
}
Beispiel #9
0
MMRESULT
WdmAudSetWaveDeviceFormatByLegacy(
    IN  PSOUND_DEVICE_INSTANCE Instance,
    IN  DWORD DeviceId,
    IN  PWAVEFORMATEX WaveFormat,
    IN  DWORD WaveFormatSize)
{
    MMRESULT Result;
    PSOUND_DEVICE SoundDevice;
    PVOID Identifier;
    WDMAUD_DEVICE_INFO DeviceInfo;
    MMDEVICE_TYPE DeviceType;

    Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);

    if ( ! MMSUCCESS(Result) )
    {
        return TranslateInternalMmResult(Result);
    }

    Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);

    if ( ! MMSUCCESS(Result) )
    {
        return TranslateInternalMmResult(Result);
    }

    if (Instance->Handle != NULL)
    {
        /* device is already open */
        return MMSYSERR_NOERROR;
    }

    Result = GetSoundDeviceType(SoundDevice, &DeviceType);

    SND_ASSERT( Result == MMSYSERR_NOERROR );

    ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
    DeviceInfo.DeviceType = DeviceType;
    DeviceInfo.DeviceIndex = DeviceId;
    DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize;
    DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
#ifdef USERMODE_MIXER
    DeviceInfo.u.WaveFormatEx.nChannels = 2;
    DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100;
    DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
    DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400;
    DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
#else
    DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels;
    DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
    DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
    DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
    DeviceInfo.u.WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels);
#endif

    Result = SyncOverlappedDeviceIoControl(KernelHandle,
                                           IOCTL_OPEN_WDMAUD,
                                           (LPVOID) &DeviceInfo,
                                           sizeof(WDMAUD_DEVICE_INFO),
                                           (LPVOID) &DeviceInfo,
                                           sizeof(WDMAUD_DEVICE_INFO),
                                           NULL);

    if ( ! MMSUCCESS(Result) )
    {
        return TranslateInternalMmResult(Result);
    }

    if (WaveFormatSize >= sizeof(WAVEFORMAT))
    {
        /* Store format */
        Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
        Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
        Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
        Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
        Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
    }

    /* store details */
    Instance->WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
    Instance->WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels);

    /* Store sound device handle instance handle */
    Instance->Handle = (PVOID)DeviceInfo.hDevice;

    /* Now determine framing requirements */
    Result = SyncOverlappedDeviceIoControl(KernelHandle,
                                           IOCTL_GETFRAMESIZE,
                                           (LPVOID) &DeviceInfo,
                                           sizeof(WDMAUD_DEVICE_INFO),
                                           (LPVOID) &DeviceInfo,
                                           sizeof(WDMAUD_DEVICE_INFO),
                                           NULL);

    if ( MMSUCCESS(Result) )
    {
        if (DeviceInfo.u.FrameSize)
        {
            Instance->FrameSize = DeviceInfo.u.FrameSize * 2;
            Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize;
            SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount);
        }
    }
    else
    {
        // use a default of 100 buffers
        Instance->BufferCount = 100;
    }

    /* Now acquire resources */
    DeviceInfo.u.State = KSSTATE_ACQUIRE;
    SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL);

    /* pause the pin */
    DeviceInfo.u.State = KSSTATE_PAUSE;
    SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL);

    /* start the pin */
    DeviceInfo.u.State = KSSTATE_RUN;
    SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL);


    return MMSYSERR_NOERROR;
}
Beispiel #10
0
MMRESULT
WdmAudOpenSoundDeviceByLegacy(
    IN PSOUND_DEVICE SoundDevice,
    OUT PVOID *Handle)
{
    HDEVINFO hDevInfo;
    SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
    GUID SWBusGuid = {STATIC_KSCATEGORY_WDMAUD};
    PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData;

    if ( KernelHandle == INVALID_HANDLE_VALUE )
    {
        hDevInfo = SetupDiGetClassDevsW(&SWBusGuid, NULL, NULL,  DIGCF_DEVICEINTERFACE| DIGCF_PRESENT);
        if (!hDevInfo)
        {
            // failed
            return MMSYSERR_ERROR;
        }

        DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
        if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &SWBusGuid, 0, &DeviceInterfaceData))
        {
            // failed
            SetupDiDestroyDeviceInfoList(hDevInfo);
            return MMSYSERR_ERROR;
        }

        DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W));
        if (!DeviceInterfaceDetailData)
        {
            // failed
            SetupDiDestroyDeviceInfoList(hDevInfo);
            return MMSYSERR_ERROR;
        }

        DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
        if (!SetupDiGetDeviceInterfaceDetailW(hDevInfo,  &DeviceInterfaceData, DeviceInterfaceDetailData,MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W), NULL, NULL))
        {
            // failed
            HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
            SetupDiDestroyDeviceInfoList(hDevInfo);
            return MMSYSERR_ERROR;
        }
        SND_TRACE(L"Opening wdmaud device '%s'\n",DeviceInterfaceDetailData->DevicePath);
        KernelHandle = CreateFileW(DeviceInterfaceDetailData->DevicePath,
                                   GENERIC_READ | GENERIC_WRITE,
                                   0,
                                   NULL,
                                   OPEN_EXISTING,
                                   FILE_FLAG_OVERLAPPED,
                                   NULL);

        HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
        SetupDiDestroyDeviceInfoList(hDevInfo);
    }


    if ( KernelHandle == INVALID_HANDLE_VALUE )
        return MMSYSERR_ERROR;

    ++ OpenCount;
    return MMSYSERR_NOERROR;

}
Beispiel #11
0
MMRESULT
WdmAudGetCapabilitiesByLegacy(
    IN  PSOUND_DEVICE SoundDevice,
    IN  DWORD DeviceId,
    OUT PVOID Capabilities,
    IN  DWORD CapabilitiesSize)
{
    MMRESULT Result;
    MMDEVICE_TYPE DeviceType;
    WDMAUD_DEVICE_INFO DeviceInfo;

    SND_ASSERT( SoundDevice );
    SND_ASSERT( Capabilities );

    Result = GetSoundDeviceType(SoundDevice, &DeviceType);
    SND_ASSERT( Result == MMSYSERR_NOERROR );

    if ( ! MMSUCCESS(Result) )
        return Result;

    SND_TRACE(L"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType, DeviceId);

    ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
    DeviceInfo.DeviceType = DeviceType;
    DeviceInfo.DeviceIndex = DeviceId;

    Result = SyncOverlappedDeviceIoControl(KernelHandle,
                                           IOCTL_GETCAPABILITIES,
                                           (LPVOID) &DeviceInfo,
                                           sizeof(WDMAUD_DEVICE_INFO),
                                           (LPVOID) &DeviceInfo,
                                           sizeof(WDMAUD_DEVICE_INFO),
                                           NULL);

    if ( ! MMSUCCESS(Result) )
    {
        return TranslateInternalMmResult(Result);
    }

    /* This is pretty much a big hack right now */
    switch ( DeviceType )
    {
    case MIXER_DEVICE_TYPE:
    {
        LPMIXERCAPSW MixerCaps = (LPMIXERCAPSW) Capabilities;

        DeviceInfo.u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
        CopyWideString(MixerCaps->szPname, DeviceInfo.u.MixCaps.szPname);

        MixerCaps->cDestinations = DeviceInfo.u.MixCaps.cDestinations;
        MixerCaps->fdwSupport = DeviceInfo.u.MixCaps.fdwSupport;
        MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion;
        MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid;
        MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid;
        break;
    }
    case WAVE_OUT_DEVICE_TYPE :
    {
        LPWAVEOUTCAPSW WaveOutCaps = (LPWAVEOUTCAPSW) Capabilities;

        DeviceInfo.u.WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
        WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
        WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;

        WaveOutCaps->vDriverVersion = DeviceInfo.u.WaveOutCaps.vDriverVersion;
        CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);

        WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
        WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
        WaveOutCaps->dwSupport = DeviceInfo.u.WaveOutCaps.dwSupport;
        break;
    }
    case WAVE_IN_DEVICE_TYPE :
    {
        LPWAVEINCAPSW WaveInCaps = (LPWAVEINCAPSW) Capabilities;

        DeviceInfo.u.WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0';

        WaveInCaps->wMid = DeviceInfo.u.WaveInCaps.wMid;
        WaveInCaps->wPid = DeviceInfo.u.WaveInCaps.wPid;

        WaveInCaps->vDriverVersion = DeviceInfo.u.WaveInCaps.vDriverVersion;
        CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveInCaps.szPname);

        WaveInCaps->dwFormats = DeviceInfo.u.WaveInCaps.dwFormats;
        WaveInCaps->wChannels = DeviceInfo.u.WaveInCaps.wChannels;
        WaveInCaps->wReserved1 = 0;
        break;
    }
    case MIDI_IN_DEVICE_TYPE :
    {
        LPMIDIINCAPSW MidiInCaps = (LPMIDIINCAPSW)Capabilities;

        DeviceInfo.u.MidiInCaps.szPname[MAXPNAMELEN-1] = L'\0';

        MidiInCaps->vDriverVersion = DeviceInfo.u.MidiInCaps.vDriverVersion;
        MidiInCaps->wMid = DeviceInfo.u.MidiInCaps.wMid;
        MidiInCaps->wPid = DeviceInfo.u.MidiInCaps.wPid;
        MidiInCaps->dwSupport = DeviceInfo.u.MidiInCaps.dwSupport;

        CopyWideString(MidiInCaps->szPname, DeviceInfo.u.MidiInCaps.szPname);
        break;
    }
    case MIDI_OUT_DEVICE_TYPE :
    {
        LPMIDIOUTCAPSW MidiOutCaps = (LPMIDIOUTCAPSW)Capabilities;

        DeviceInfo.u.MidiOutCaps.szPname[MAXPNAMELEN-1] = L'\0';

        MidiOutCaps->vDriverVersion = DeviceInfo.u.MidiOutCaps.vDriverVersion;
        MidiOutCaps->wMid = DeviceInfo.u.MidiOutCaps.wMid;
        MidiOutCaps->wPid = DeviceInfo.u.MidiOutCaps.wPid;
        MidiOutCaps->dwSupport = DeviceInfo.u.MidiOutCaps.dwSupport;

        CopyWideString(MidiOutCaps->szPname, DeviceInfo.u.MidiOutCaps.szPname);
        break;
    }
    }

    return MMSYSERR_NOERROR;
}