예제 #1
0
파일: control.c 프로젝트: RareHare/reactos
MMRESULT
SetNt4WaveDeviceFormat(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    IN  DWORD DeviceId,
    IN  LPWAVEFORMATEX Format,
    IN  DWORD FormatSize)
{
    MMRESULT Result;
    HANDLE Handle;

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
    VALIDATE_MMSYS_PARAMETER( Format );
    VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) );

    Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);

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

    SND_TRACE(L"Setting wave device format on handle %x\n", Handle);

    Result = SyncOverlappedDeviceIoControl(Handle,
                                           IOCTL_WAVE_SET_FORMAT,
                                           (LPVOID) Format,
                                           FormatSize,
                                           NULL,
                                           0,
                                           NULL);

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

    return MMSYSERR_NOERROR;
}
예제 #2
0
파일: thread.c 프로젝트: GYGit/reactos
MMRESULT
CallSoundThread(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    IN  SOUND_THREAD_REQUEST_HANDLER RequestHandler,
    IN  PVOID Parameter OPTIONAL)
{
    PSOUND_THREAD Thread;

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
    VALIDATE_MMSYS_PARAMETER( RequestHandler );

    Thread = SoundDeviceInstance->Thread;

    SND_TRACE(L"Waiting for READY event\n");
    WaitForSingleObject(Thread->Events.Ready, INFINITE);

    Thread->Request.Result = MMSYSERR_NOTSUPPORTED;
    Thread->Request.Handler = RequestHandler;
    Thread->Request.SoundDeviceInstance = SoundDeviceInstance;
    Thread->Request.Parameter = Parameter;

    /* Notify the thread it has work to do */
    SND_TRACE(L"Setting REQUEST event\n");
    SetEvent(Thread->Events.Request);

    /* Wait for the work to be done */
    SND_TRACE(L"Waiting for DONE event\n");
    WaitForSingleObject(Thread->Events.Done, INFINITE);

    return Thread->Request.Result;
}
예제 #3
0
MMRESULT
ListSoundDeviceInstance(
    IN  PSOUND_DEVICE SoundDevice,
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
{
    VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
    VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );

    SND_TRACE(L"Listing sound device instance\n");

    if ( ! SoundDevice->HeadInstance )
    {
        /* First entry - assign to head and tail */
        SoundDevice->HeadInstance = SoundDeviceInstance;
        SoundDevice->TailInstance = SoundDeviceInstance;
    }
    else
    {
        /* Attach to the end */
        SoundDevice->TailInstance->Next = SoundDeviceInstance;
        SoundDevice->TailInstance = SoundDeviceInstance;
    }

    return MMSYSERR_NOERROR;
}
예제 #4
0
파일: legacy.c 프로젝트: Strongc/reactos
MMRESULT
WdmAudGetNumWdmDevsByLegacy(
    IN  MMDEVICE_TYPE DeviceType,
    OUT DWORD* DeviceCount)
{
    MMRESULT Result;
    WDMAUD_DEVICE_INFO DeviceInfo;

    VALIDATE_MMSYS_PARAMETER( KernelHandle != INVALID_HANDLE_VALUE );
    VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
    VALIDATE_MMSYS_PARAMETER( DeviceCount );

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

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

    if ( ! MMSUCCESS( Result ) )
    {
        SND_ERR(L"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
        *DeviceCount = 0;
        return TranslateInternalMmResult(Result);
    }

    *DeviceCount = DeviceInfo.DeviceCount;

    return MMSYSERR_NOERROR;
}
예제 #5
0
파일: format.c 프로젝트: GYGit/reactos
MMRESULT
QueryWaveDeviceFormatSupport(
    IN  PSOUND_DEVICE SoundDevice,
    IN  LPWAVEFORMATEX Format,
    IN  DWORD FormatSize)
{
    MMRESULT Result;
    MMDEVICE_TYPE DeviceType;
    PMMFUNCTION_TABLE FunctionTable;

    SND_TRACE(L"Querying wave format support\n");

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
    VALIDATE_MMSYS_PARAMETER( Format );
    VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) );

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

    /* Ensure we have a wave device (TODO: check if this applies to wavein as well) */
    VALIDATE_MMSYS_PARAMETER( IS_WAVE_DEVICE_TYPE(DeviceType) );

    /* Obtain the function table */
    Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
    SND_ASSERT( Result == MMSYSERR_NOERROR );

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

    if ( ! FunctionTable->QueryWaveFormatSupport )
        return MMSYSERR_NOTSUPPORTED;

    return FunctionTable->QueryWaveFormatSupport(SoundDevice, Format, FormatSize);
}
예제 #6
0
파일: control.c 프로젝트: RareHare/reactos
MMRESULT
SubmitNt4WaveHeader(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    IN  PWAVEHDR WaveHeader)
{
    VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
    VALIDATE_MMSYS_PARAMETER( WaveHeader );

    SND_TRACE(L"Submitting wave header %p (in sound thread)\n", WaveHeader);

    /* TODO: This should only submit the header to the device, nothing more! */
}
예제 #7
0
MMRESULT
GetSoundDeviceInstanceHandle(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    OUT PVOID* Handle)
{
    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
    VALIDATE_MMSYS_PARAMETER( Handle );

    *Handle = SoundDeviceInstance->Handle;

    return MMSYSERR_NOERROR;
}
예제 #8
0
파일: control.c 프로젝트: RareHare/reactos
/*
    Device open/close. These are basically wrappers for the MME-Buddy
    open and close routines, which provide a Windows device handle.
    These may seem simple but as you can return pretty much anything
    as the handle, we could just as easily return a structure etc.
*/
MMRESULT
OpenNt4SoundDevice(
    IN  PSOUND_DEVICE SoundDevice,
    OUT PVOID* Handle)
{
    SND_TRACE(L"Opening NT4 style sound device\n");

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
    VALIDATE_MMSYS_PARAMETER( Handle );

    return OpenNt4KernelSoundDevice(SoundDevice, FALSE, Handle);
}
예제 #9
0
MMRESULT
GetSoundDeviceFromInstance(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    OUT PSOUND_DEVICE* SoundDevice)
{
    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
    VALIDATE_MMSYS_PARAMETER( SoundDevice );

    *SoundDevice = SoundDeviceInstance->Device;

    return MMSYSERR_NOERROR;
}
예제 #10
0
파일: registry.c 프로젝트: Moteesh/reactos
/*
    Open the parameters key of a sound driver.
    NT4 only.
*/
MMRESULT
OpenSoundDriverParametersRegKey(
    IN  LPWSTR ServiceName,
    OUT PHKEY KeyHandle)
{
    SIZE_T KeyLength;
    PWCHAR ParametersKeyName;

    VALIDATE_MMSYS_PARAMETER( ServiceName );
    VALIDATE_MMSYS_PARAMETER( KeyHandle );

    /* Work out how long the string will be */
    KeyLength = wcslen(REG_SERVICES_KEY_NAME_U) + 1
              + wcslen(ServiceName) + 1
              + wcslen(REG_PARAMETERS_KEY_NAME_U);

    /* Allocate memory for the string */
    ParametersKeyName = AllocateWideString(KeyLength);

    if ( ! ParametersKeyName )
        return MMSYSERR_NOMEM;

    /* Construct the registry path */
    wsprintf(ParametersKeyName,
             L"%s\\%s\\%s",
             REG_SERVICES_KEY_NAME_U,
             ServiceName,
             REG_PARAMETERS_KEY_NAME_U);

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

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

    FreeMemory(ParametersKeyName);

    return MMSYSERR_NOERROR;
}
예제 #11
0
파일: thread.c 프로젝트: GYGit/reactos
MMRESULT
DestroySoundThread(
    IN  PSOUND_THREAD Thread)
{
    VALIDATE_MMSYS_PARAMETER( Thread );
    SND_ASSERT( Thread->Handle != INVALID_HANDLE_VALUE );

    SND_TRACE(L"Terminating sound thread\n");

    /* Tell the thread to terminate itself */
    TerminateSoundThread(Thread);

    SND_TRACE(L"Sound thread terminated, performing cleanup of thread resources\n");

    CloseHandle(Thread->Handle);    /* Is this needed? */
    Thread->Handle = INVALID_HANDLE_VALUE;

    DestroySoundThreadEvents(Thread->Events.Ready,
                             Thread->Events.Request,
                             Thread->Events.Done);

    /* Wipe and free the memory used for the thread */
    ZeroMemory(Thread, sizeof(SOUND_THREAD));
    FreeMemory(Thread);

    SND_TRACE(L"Finished thread cleanup\n");

    return MMSYSERR_NOERROR;
}
예제 #12
0
파일: thread.c 프로젝트: GYGit/reactos
MMRESULT
DestroySoundThreadEvents(
    IN  HANDLE ReadyEvent,
    IN  HANDLE RequestEvent,
    IN  HANDLE DoneEvent)
{
    VALIDATE_MMSYS_PARAMETER( ReadyEvent != INVALID_HANDLE_VALUE );
    VALIDATE_MMSYS_PARAMETER( RequestEvent != INVALID_HANDLE_VALUE );
    VALIDATE_MMSYS_PARAMETER( DoneEvent != INVALID_HANDLE_VALUE );

    SND_TRACE(L"Destroying thread events\n");

    CloseHandle(ReadyEvent);
    CloseHandle(RequestEvent);
    CloseHandle(DoneEvent);

    return MMSYSERR_NOERROR;
}
예제 #13
0
파일: control.c 프로젝트: RareHare/reactos
/*
    Querying/setting the format of a wave device. Querying format support
    requires us to first open the device, whereas setting format is done
    on an already opened device.
*/
MMRESULT
QueryNt4WaveDeviceFormatSupport(
    IN  PSOUND_DEVICE SoundDevice,
    IN  LPWAVEFORMATEX Format,
    IN  DWORD FormatSize)
{
    MMRESULT Result;
    HANDLE Handle;

    SND_TRACE(L"NT4 wave format support querying routine called\n");

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
    VALIDATE_MMSYS_PARAMETER( Format );
    VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) );

    /* Get the device path */
    Result = OpenNt4KernelSoundDevice(SoundDevice,
                                      FALSE,
                                      &Handle);

    if ( ! MMSUCCESS(Result) )
    {
        SND_ERR(L"Unable to open kernel sound device\n");
        return TranslateInternalMmResult(Result);
    }

    Result = SyncOverlappedDeviceIoControl(Handle,
                                           IOCTL_WAVE_QUERY_FORMAT,
                                           (LPVOID) Format,
                                           FormatSize,
                                           NULL,
                                           0,
                                           NULL);

    if ( ! MMSUCCESS(Result) )
    {
        SND_ERR(L"Sync overlapped I/O failed - MMSYS_ERROR %d\n", Result);
        Result = TranslateInternalMmResult(Result);
    }

    CloseKernelSoundDevice(Handle);

    return MMSYSERR_NOERROR;
}
예제 #14
0
파일: format.c 프로젝트: GYGit/reactos
MMRESULT
SetWaveDeviceFormat(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    IN  DWORD DeviceId,
    IN  LPWAVEFORMATEX Format,
    IN  DWORD FormatSize)
{
    MMRESULT Result;
    MMDEVICE_TYPE DeviceType;
    PMMFUNCTION_TABLE FunctionTable;
    PSOUND_DEVICE SoundDevice;

    SND_TRACE(L"Setting wave format\n");

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );

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

    Result = GetSoundDeviceType(SoundDevice, &DeviceType);
    SND_ASSERT( Result == MMSYSERR_NOERROR );
    if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
    {
        VALIDATE_MMSYS_PARAMETER( Format );
        VALIDATE_MMSYS_PARAMETER( FormatSize >= sizeof(WAVEFORMATEX) );
    }

    /* Ensure we have a wave device (TODO: check if this applies to wavein as well) */
    VALIDATE_MMSYS_PARAMETER( IS_WAVE_DEVICE_TYPE(DeviceType) || IS_MIDI_DEVICE_TYPE(DeviceType) || IS_MIXER_DEVICE_TYPE(DeviceType));

    /* Obtain the function table */
    Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
    SND_ASSERT( Result == MMSYSERR_NOERROR );

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

    if ( ! FunctionTable->SetWaveFormat )
        return MMSYSERR_NOTSUPPORTED;

    return FunctionTable->SetWaveFormat(SoundDeviceInstance, DeviceId, Format, FormatSize);
}
예제 #15
0
파일: control.c 프로젝트: RareHare/reactos
MMRESULT
CloseNt4SoundDevice(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    IN  PVOID Handle)
{
    SND_TRACE(L"Closing NT4 style sound device\n");

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
    return CloseKernelSoundDevice((HANDLE) Handle);
}
예제 #16
0
파일: detect.c 프로젝트: GYGit/reactos
/*
    Brute-force device detection, using a base device name (eg: \\.\WaveOut).

    This will add the device number as a suffix to the end of the string and
    attempt to open the device based on that name. On success, it will
    increment the device number and repeat this process.

    When it runs out of devices, it will give up.
*/
MMRESULT
DetectNt4SoundDevices(
    IN  MMDEVICE_TYPE DeviceType,
    IN  PWSTR BaseDeviceName,
    IN  SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
{
    ULONG DeviceNameLength = 0;
    PWSTR DeviceName = NULL;
    ULONG Index = 0;
    HANDLE DeviceHandle;
    BOOLEAN DoSearch = TRUE;

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceType(DeviceType) );

    DeviceNameLength = wcslen(BaseDeviceName);
    /* Consider the length of the number */
    DeviceNameLength += GetDigitCount(Index);

    DeviceName = AllocateWideString(DeviceNameLength);

    if ( ! DeviceName )
    {
        return MMSYSERR_NOMEM;
    }

    while ( DoSearch )
    {
        /* Nothing like a nice clean device name */
        ZeroWideString(DeviceName);
        wsprintf(DeviceName, L"%ls%d", BaseDeviceName, Index);

        if ( OpenKernelSoundDeviceByName(DeviceName,
                                         TRUE,
                                         &DeviceHandle) == MMSYSERR_NOERROR )
        {
            /* Notify the callback function */
            SND_TRACE(L"Found device: %wS\n", DeviceName);
            SoundDeviceDetectedProc(DeviceType, DeviceName);

            CloseHandle(DeviceHandle);

            ++ Index;
        }
        else
        {
            DoSearch = FALSE;
        }
    }

    FreeMemory(DeviceName);

    return MMSYSERR_NOERROR;
}
예제 #17
0
파일: thread.c 프로젝트: GYGit/reactos
MMRESULT
CreateSoundThreadEvents(
    OUT HANDLE* ReadyEvent,
    OUT HANDLE* RequestEvent,
    OUT HANDLE* DoneEvent)
{
    BOOL ok;

    VALIDATE_MMSYS_PARAMETER( ReadyEvent );
    VALIDATE_MMSYS_PARAMETER( RequestEvent );
    VALIDATE_MMSYS_PARAMETER( DoneEvent );

    SND_TRACE(L"Creating thread events\n");

    /* Initialise these so we can identify them upon failure */
    *ReadyEvent = *RequestEvent = *DoneEvent = INVALID_HANDLE_VALUE;

    ok = (*ReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) != INVALID_HANDLE_VALUE;
    ok &= (*RequestEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) != INVALID_HANDLE_VALUE;
    ok &= (*DoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) != INVALID_HANDLE_VALUE;

    /* If something went wrong, clean up */
    if ( ! ok )
    {
        if ( *ReadyEvent != INVALID_HANDLE_VALUE )
            CloseHandle(*ReadyEvent);

        if ( *RequestEvent != INVALID_HANDLE_VALUE )
            CloseHandle(*RequestEvent);

        if ( *DoneEvent != INVALID_HANDLE_VALUE )
            CloseHandle(*DoneEvent);

        return MMSYSERR_NOMEM;
    }

    return MMSYSERR_NOERROR;
}
예제 #18
0
파일: control.c 프로젝트: RareHare/reactos
/*
    Convenience routine for getting the path of a device and opening it.
*/
MMRESULT
OpenNt4KernelSoundDevice(
    IN  PSOUND_DEVICE SoundDevice,
    IN  BOOLEAN ReadOnly,
    OUT PHANDLE Handle)
{
    PWSTR Path;
    MMRESULT Result;

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
    VALIDATE_MMSYS_PARAMETER( Handle );

    Result = GetSoundDeviceIdentifier(SoundDevice, (PVOID*) &Path);
    if ( ! MMSUCCESS(Result) )
    {
        SND_ERR(L"Unable to get sound device path");
        return TranslateInternalMmResult(Result);
    }

    SND_ASSERT( Path );

    return OpenKernelSoundDeviceByName(Path, ReadOnly, Handle);
}
예제 #19
0
MMRESULT
MmeGetLineInfo(
    IN UINT DeviceId,
    IN  UINT Message,
    IN  DWORD_PTR PrivateHandle,
    IN  DWORD_PTR Parameter1,
    IN  DWORD_PTR Parameter2)
{
    MMRESULT Result;
    PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
    PSOUND_DEVICE SoundDevice;
    PMMFUNCTION_TABLE FunctionTable;

    //SND_TRACE(L"Getting mixer info %u\n", Message);

    if ( PrivateHandle == 0 )
    {
        Result = GetSoundDevice(MIXER_DEVICE_TYPE, DeviceId, &SoundDevice);

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

         Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
         if ( ! MMSUCCESS(Result) )
            return TranslateInternalMmResult(Result);

         Result = FunctionTable->QueryMixerInfo(NULL, DeviceId, Message, (LPVOID)Parameter1, Parameter2);
         return Result;
    }

    VALIDATE_MMSYS_PARAMETER( PrivateHandle );
    SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;

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

    Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
    if ( ! MMSUCCESS(Result) )
        return TranslateInternalMmResult(Result);

    if ( ! FunctionTable->QueryMixerInfo )
        return MMSYSERR_NOTSUPPORTED;

    Result = FunctionTable->QueryMixerInfo(SoundDeviceInstance, DeviceId, Message, (LPVOID)Parameter1, Parameter2);

    return Result;
}
예제 #20
0
MMRESULT
UnlistSoundDeviceInstance(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
{
    MMRESULT Result;
    PSOUND_DEVICE SoundDevice;
    PSOUND_DEVICE_INSTANCE CurrentInstance, PreviousInstance;

    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );

    SND_TRACE(L"Unlisting sound device instance\n");

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

    PreviousInstance = NULL;
    CurrentInstance = SoundDevice->HeadInstance;

    while ( CurrentInstance )
    {
        if ( CurrentInstance == SoundDeviceInstance )
        {
            if ( ! PreviousInstance )
            {
                /* This is the head node */
                SoundDevice->HeadInstance = SoundDevice->HeadInstance->Next;
            }
            else
            {
                /* There are nodes before this one - cut ours out */
                PreviousInstance->Next = CurrentInstance->Next;
            }

            if ( ! CurrentInstance->Next )
            {
                /* This is the tail node */
                SoundDevice->TailInstance = PreviousInstance;
            }
        }

        PreviousInstance = CurrentInstance;
        CurrentInstance = CurrentInstance->Next;
    }

    return MMSYSERR_NOERROR;
}
예제 #21
0
MMRESULT
SetSoundDeviceInstanceMmeData(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    IN  HDRVR MmeHandle,
    IN  DWORD_PTR ClientCallback,
    IN  DWORD_PTR ClientCallbackData,
    IN  DWORD Flags)
{
    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );

    SND_TRACE(L"Setting MME data - handle %x, callback %x, instance data %x, flags %x\n",
              MmeHandle, ClientCallback, ClientCallbackData, Flags);

    SoundDeviceInstance->WinMM.Handle = MmeHandle;
    SoundDeviceInstance->WinMM.ClientCallback = ClientCallback;
    SoundDeviceInstance->WinMM.ClientCallbackInstanceData = ClientCallbackData;
    SoundDeviceInstance->WinMM.Flags = Flags;

    return MMSYSERR_NOERROR;
}
예제 #22
0
MMRESULT
AllocateSoundDeviceInstance(
    OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance)
{
    PSOUND_DEVICE_INSTANCE NewInstance;

    VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );

    /* Allocate memory for the new instance */
    NewInstance = AllocateStruct(SOUND_DEVICE_INSTANCE);

    if ( ! NewInstance )
        return MMSYSERR_NOMEM;

    /* Use default frame size */
    NewInstance->FrameSize = SOUND_KERNEL_BUFFER_SIZE;
    /* Use default buffer count */
    NewInstance->BufferCount = SOUND_KERNEL_BUFFER_COUNT;

    /* Provide the caller with the new instance pointer */
    *SoundDeviceInstance = NewInstance;

    return MMSYSERR_NOERROR;
}
예제 #23
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;
}
예제 #24
0
파일: legacy.c 프로젝트: Strongc/reactos
MMRESULT
WdmAudCommitWaveBufferByLegacy(
    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
    IN  PVOID OffsetPtr,
    IN  DWORD Length,
    IN  PSOUND_OVERLAPPED Overlap,
    IN  LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine)
{
    HANDLE Handle;
    MMRESULT Result;
    PWDMAUD_DEVICE_INFO DeviceInfo;
    PSOUND_DEVICE SoundDevice;
    MMDEVICE_TYPE DeviceType;
    BOOL Ret;

    VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
    VALIDATE_MMSYS_PARAMETER( OffsetPtr );
    VALIDATE_MMSYS_PARAMETER( Overlap );
    VALIDATE_MMSYS_PARAMETER( CompletionRoutine );

    GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
    SND_ASSERT(Handle);

    Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);

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

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

    DeviceInfo = (PWDMAUD_DEVICE_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WDMAUD_DEVICE_INFO));
    if (!DeviceInfo)
    {
        // no memory
        return MMSYSERR_NOMEM;
    }

    DeviceInfo->Header.FrameExtent = Length;
    if (DeviceType == WAVE_OUT_DEVICE_TYPE)
    {
        DeviceInfo->Header.DataUsed = Length;
    }
    DeviceInfo->Header.Data = OffsetPtr;
    DeviceInfo->Header.Size = sizeof(WDMAUD_DEVICE_INFO);
    DeviceInfo->Header.PresentationTime.Numerator = 1;
    DeviceInfo->Header.PresentationTime.Denominator = 1;
    DeviceInfo->hDevice = Handle;
    DeviceInfo->DeviceType = DeviceType;


    // create completion event
    Overlap->Standard.hEvent = Handle = CreateEventW(NULL, FALSE, FALSE, NULL);
    if (Overlap->Standard.hEvent == NULL)
    {
        // no memory
        HeapFree(GetProcessHeap(), 0, DeviceInfo);
        return MMSYSERR_NOMEM;
    }

    Overlap->OriginalCompletionRoutine = CompletionRoutine;
    Overlap->CompletionContext = (PVOID)DeviceInfo;

    if (DeviceType == WAVE_OUT_DEVICE_TYPE)
    {
        Ret = WriteFileEx(KernelHandle, DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, LegacyCompletionRoutine);
        if (Ret)
            WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
    }
    else if (DeviceType == WAVE_IN_DEVICE_TYPE)
    {
        Ret = ReadFileEx(KernelHandle, DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, LegacyCompletionRoutine);
        if (Ret)
            WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
    }

    // close event handle
    CloseHandle(Handle);

    return MMSYSERR_NOERROR;
}
예제 #25
0
파일: thread.c 프로젝트: GYGit/reactos
MMRESULT
CreateSoundThread(
    OUT PSOUND_THREAD* Thread)
{
    MMRESULT Result;
    PSOUND_THREAD NewThread;

    VALIDATE_MMSYS_PARAMETER( Thread );

    NewThread = AllocateStruct(SOUND_THREAD);
    if ( ! NewThread )
        return MMSYSERR_NOMEM;

    /* Prepare the events we'll be using to sync. everything */
    Result = CreateSoundThreadEvents(&NewThread->Events.Ready,
                                     &NewThread->Events.Request,
                                     &NewThread->Events.Done);

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

    SND_TRACE(L"Creating a sound thread\n");
    NewThread->Handle = CreateThread(NULL,
                                     0,
                                     &SoundThreadMain,
                                     (LPVOID) NewThread,
                                     CREATE_SUSPENDED,
                                     NULL);

    /* Something went wrong, bail out! */
    if ( NewThread->Handle == INVALID_HANDLE_VALUE )
    {
        SND_ERR(L"Sound thread creation failed!\n");
        DestroySoundThreadEvents(NewThread->Events.Ready,
                                 NewThread->Events.Request,
                                 NewThread->Events.Done);

        FreeMemory(NewThread);

        return Win32ErrorToMmResult(GetLastError());
    }

    /* Wake the thread up */
    if ( ResumeThread(NewThread->Handle) == -1 )
    {
        SND_ERR(L"Failed to resume thread!\n");
        CloseHandle(NewThread->Handle);
        DestroySoundThreadEvents(NewThread->Events.Ready,
                                 NewThread->Events.Request,
                                 NewThread->Events.Done);

        FreeMemory(NewThread);
        return Win32ErrorToMmResult(GetLastError());
    }

    /* If all is well we can now give the thread to the caller */
    *Thread = NewThread;
    return MMSYSERR_NOERROR;
}
예제 #26
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;
}
예제 #27
0
파일: registry.c 프로젝트: Moteesh/reactos
/*
    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;
}
예제 #28
0
파일: detect.c 프로젝트: GYGit/reactos
/*
    This is the "nice" way to discover audio devices in NT4 - go into the
    service registry key and enumerate the Parameters\Device*\Devices
    values. The value names represent the device name, whereas the data
    assigned to them identifies the type of device.
*/
MMRESULT
EnumerateNt4ServiceSoundDevices(
    IN  LPWSTR ServiceName,
    IN  MMDEVICE_TYPE DeviceType,
    IN  SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
{
    HKEY Key;
    DWORD KeyIndex = 0;

    VALIDATE_MMSYS_PARAMETER( ServiceName );

    /* Device type zero means "all" */
    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceType(DeviceType) ||
                              DeviceType == 0 );

    while ( OpenSoundDeviceRegKey(ServiceName, KeyIndex, &Key) == MMSYSERR_NOERROR )
    {
        HKEY DevicesKey;
        DWORD ValueType = REG_NONE, ValueIndex = 0;
        DWORD MaxNameLength = 0, ValueNameLength = 0;
        PWSTR DevicePath = NULL, ValueName = NULL;
        DWORD ValueDataLength = sizeof(DWORD);
        DWORD ValueData;

        if ( RegOpenKeyEx(Key,
                          REG_DEVICES_KEY_NAME_U,
                          0,
                          KEY_READ,
                          &DevicesKey) == ERROR_SUCCESS )
        {
            /* Find out how much memory is needed for the key name */
            if ( RegQueryInfoKey(DevicesKey,
                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                 &MaxNameLength,
                                 NULL, NULL, NULL) != ERROR_SUCCESS )
            {
                SND_ERR(L"Failed to query registry key information\n");
                RegCloseKey(DevicesKey);
                RegCloseKey(Key);

                return MMSYSERR_ERROR;
            }

            DevicePath = AllocateWideString(MaxNameLength +
                                            strlen("\\\\.\\"));

            /* Check that the memory allocation was successful */
            if ( ! DevicePath )
            {
                /* There's no point in going further */
                RegCloseKey(DevicesKey);
                RegCloseKey(Key);

                return MMSYSERR_NOMEM;
            }

            /* Insert the device path prefix */
            wsprintf(DevicePath, L"\\\\.\\");

            /* The offset of the string following this prefix */
            ValueName = DevicePath + strlen("\\\\.\\");

            /* Copy this so that it may be overwritten - include NULL */
            ValueNameLength = MaxNameLength + sizeof(WCHAR);

            SND_TRACE(L"Interested in devices beginning with %wS\n", DevicePath);

            while ( RegEnumValue(DevicesKey,
                                 ValueIndex,
                                 ValueName,
                                 &ValueNameLength,
                                 NULL,
                                 &ValueType,
                                 (LPBYTE) &ValueData,
                                 &ValueDataLength) == ERROR_SUCCESS )
            {
                /* Device types are stored as DWORDs */
                if ( ( ValueType == REG_DWORD ) &&
                     ( ValueDataLength == sizeof(DWORD) ) )
                {
                    if ( ( DeviceType == 0 ) ||
                         ( DeviceType == ValueData ) )
                    {
                        SND_TRACE(L"Found device: %wS\n", DevicePath);
                        SoundDeviceDetectedProc(ValueData, DevicePath);
                    }
                }

                /* Reset variables for the next iteration */
                ValueNameLength = MaxNameLength + sizeof(WCHAR);
                ZeroMemory(ValueName, (MaxNameLength+1)*sizeof(WCHAR));
                /*ZeroWideString(ValueName);*/
                ValueDataLength = sizeof(DWORD);
                ValueData = 0;
                ValueType = REG_NONE;

                ++ ValueIndex;
            }

            FreeMemory(DevicePath);

            RegCloseKey(DevicesKey);
        }
        else
        {
            SND_WARN(L"Unable to open the Devices key!\n");
        }

        ++ KeyIndex;

        RegCloseKey(Key);
    }

    return MMSYSERR_NOERROR;
}
예제 #29
0
/*
    Standard MME driver entry-point for messages relating to mixers.
*/
DWORD
APIENTRY
mxdMessage(
    UINT DeviceId,
    UINT Message,
    DWORD_PTR PrivateHandle,
    DWORD_PTR Parameter1,
    DWORD_PTR Parameter2)
{
    MMRESULT Result = MMSYSERR_NOTSUPPORTED;

    AcquireEntrypointMutex(MIXER_DEVICE_TYPE);

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

    switch ( Message )
    {
        case MXDM_GETNUMDEVS :
        {
            Result = GetSoundDeviceCount(MIXER_DEVICE_TYPE);
            break;
        }

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

        case MXDM_INIT :
        {
            Result = MMSYSERR_NOERROR;
            break;
        }

        case MXDM_OPEN :
        {
            Result = MmeOpenDevice(MIXER_DEVICE_TYPE,
                                   DeviceId,
                                   (LPWAVEOPENDESC) Parameter1, /* unused */
                                   Parameter2,
                                   (DWORD*) PrivateHandle);
            VALIDATE_MMSYS_PARAMETER(*(DWORD_PTR*)PrivateHandle);
            break;
        }

        case MXDM_CLOSE :
        {
            Result = MmeCloseDevice(PrivateHandle);

            break;
        }

        case MXDM_GETCONTROLDETAILS :
        {
            Result = MmeGetLineInfo(DeviceId,
                                    Message,
                                    PrivateHandle,
                                    Parameter1,
                                    Parameter2);

            break;
        }

        case MXDM_SETCONTROLDETAILS :
        {
            Result = MmeGetLineInfo(DeviceId,
                                    Message,
                                    PrivateHandle,
                                    Parameter1,
                                    Parameter2);

            break;
        }

        case MXDM_GETLINECONTROLS :
        {
            Result = MmeGetLineInfo(DeviceId,
                                    Message,
                                    PrivateHandle,
                                    Parameter1,
                                    Parameter2);

            break;
        }

        case MXDM_GETLINEINFO :
        {
            Result = MmeGetLineInfo(DeviceId,
                                    Message,
                                    PrivateHandle,
                                    Parameter1,
                                    Parameter2);

            break;
        }

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

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

    }

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

    ReleaseEntrypointMutex(MIXER_DEVICE_TYPE);

    return Result;
}