예제 #1
0
DWORD
GetDeviceCapabilities(
    DeviceType device_type,
    UINT device_id,
    DWORD_PTR capabilities,
    DWORD capabilities_size)
{
    MMRESULT result;
    DWORD ioctl;
    HANDLE handle;
    DWORD bytes_returned;
    BOOL device_io_result;

    ASSERT(capabilities);

    /* Choose the right IOCTL for the job */

    if ( IsWaveDevice(device_type) )
        ioctl = IOCTL_WAVE_GET_CAPABILITIES;
    else if ( IsMidiDevice(device_type) )
        ioctl = IOCTL_MIDI_GET_CAPABILITIES;
    else if ( IsAuxDevice(device_type) )
        return MMSYSERR_NOTSUPPORTED; /* TODO */
    else
        return MMSYSERR_NOTSUPPORTED;

    result = OpenKernelDevice(device_type,
                              device_id,
                              GENERIC_READ,
                              &handle);

    if ( result != MMSYSERR_NOERROR )
    {
        DPRINT("Failed to open kernel device\n");
        return result;
    }

    device_io_result = DeviceIoControl(handle,
                                       ioctl,
                                       NULL,
                                       0,
                                       (LPVOID) capabilities,
                                       capabilities_size,
                                       &bytes_returned,
                                       NULL);

    /* Translate result */

    if ( device_io_result )
        result = MMSYSERR_NOERROR;
    else
        result = ErrorToMmResult(GetLastError());

    /* Clean up and return */

    CloseKernelDevice(handle);

    return result;
}
예제 #2
0
파일: kernel.c 프로젝트: RareHare/reactos
MMRESULT
OpenKernelDevice(
    DeviceType device_type,
    UINT device_id,
    DWORD access,
    HANDLE* handle)
{
    MMRESULT result;
    WCHAR device_name[MAX_DEVICE_NAME_LENGTH];
    DWORD open_flags = 0;

    ASSERT(handle);

    /* Glue the base device name and the ID together */

    result = CobbleDeviceName(device_type, device_id, device_name);

    DPRINT("Opening kernel device %ls\n", device_name);

    if ( result != MMSYSERR_NOERROR )
        return result;

    /* We want overlapped I/O when writing */

    if ( access != GENERIC_READ )
        open_flags = FILE_FLAG_OVERLAPPED;

    /* Now try opening... */

    *handle = CreateFile(device_name,
                         access,
                         FILE_SHARE_WRITE,
                         NULL,
                         OPEN_EXISTING,
                         open_flags,
                         NULL);

    if ( *handle == INVALID_HANDLE_VALUE )
        return ErrorToMmResult(GetLastError());

    return MMSYSERR_NOERROR;
}
예제 #3
0
파일: kernel.c 프로젝트: RareHare/reactos
MMRESULT
GetDeviceData(
    HANDLE device_handle,
    DWORD ioctl,
    PBYTE output_buffer,
    DWORD buffer_size)
{
    OVERLAPPED overlap;
    DWORD bytes_returned;
    BOOL success;
    DWORD transfer;

    DPRINT("GetDeviceData\n");

    memset(&overlap, 0, sizeof(overlap));

    overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    if ( ! overlap.hEvent )
        return MMSYSERR_NOMEM;

    success = DeviceIoControl(device_handle,
                              ioctl,
                              NULL,
                              0,
                              output_buffer,
                              buffer_size,
                              &bytes_returned,
                              &overlap);

    if ( ! success )
    {
        if ( GetLastError() == ERROR_IO_PENDING )
        {
            if ( ! GetOverlappedResult(device_handle, &overlap, &transfer, TRUE) )
            {
                CloseHandle(overlap.hEvent);
                return ErrorToMmResult(GetLastError());
            }
        }
        else
        {
            CloseHandle(overlap.hEvent);
            return ErrorToMmResult(GetLastError());
        }
    }

    while ( TRUE )
    {
        SetEvent(overlap.hEvent);

        if ( WaitForSingleObjectEx(overlap.hEvent, 0, TRUE) != WAIT_IO_COMPLETION )
        {
            break;
        }
    }

    CloseHandle(overlap.hEvent);

    return MMSYSERR_NOERROR;
}