亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? devices.c

?? winNT技術操作系統,國外開放的原代碼和LIUX一樣
?? C
?? 第 1 頁 / 共 2 頁
字號:

        return result;
    }
}

/*
    GetDeviceCount

    Pretty straightforward - pass the device type (WDMAUD_WAVE_IN, ...) and
    a topology device (NT object path) to obtain the number of devices
    present in that topology of that particular type.

    The topology path is supplied to us by winmm.
*/

DWORD GetDeviceCount(CHAR device_type, WCHAR* topology_path)
{
    PWDMAUD_DEVICE_INFO device_data;
    int device_count = 0;

    DPRINT("Topology path %S\n", topology_path);

    device_data = CreateDeviceData(device_type, 0, topology_path, FALSE);

    if (! device_data)
    {
        DPRINT1("Couldn't allocate device data\n");
        goto cleanup;
    }

    DPRINT("Getting num devs\n");

    device_data->with_critical_section = FALSE;

    if ( CallKernelDevice(device_data,
                          IOCTL_WDMAUD_GET_DEVICE_COUNT,
                          0,
                          0) != MMSYSERR_NOERROR )
    {
        DPRINT1("Failed\n");
        goto cleanup;
    }

    device_count = device_data->id;

    DPRINT("There are %d devs\n", device_count);

    cleanup :
    {
        if ( device_data )
            DeleteDeviceData(device_data);

        return device_count;
    }
}

/*
    GetDeviceCapabilities

    This uses a different structure to the traditional documentation, because
    we handle plug and play devices.

    Much sleep was lost over implementing this. I got the ID and type
    parameters the wrong way round!
*/

MMRESULT GetDeviceCapabilities(
    CHAR device_type,
    DWORD device_id,
    WCHAR* device_path,
    LPMDEVICECAPSEX caps
)
{
    PWDMAUD_DEVICE_INFO device = NULL;
    MMRESULT result = MMSYSERR_ERROR;

    DPRINT("Device path %S\n", device_path);

    /* Is this right? */
    if (caps->cbSize == 0)
    {
        DPRINT1("We appear to have been given an invalid parameter\n");
        return MMSYSERR_INVALPARAM;
    }

    DPRINT("Going to have to query the kernel-mode part\n");

    device = CreateDeviceData(device_type, device_id, device_path, FALSE);

    if ( ! device )
    {
        DPRINT("Unable to allocate device data memory\n");
        result = MMSYSERR_NOMEM;
        goto cleanup;
    }

    /* These are not needed as they're already initialized */
    ASSERT( device_id == device->id );
    ASSERT( ! device->with_critical_section );

    *(LPWORD)caps->pCaps = (WORD) 0x43;

    DPRINT("Calling kernel device\n");
    result = CallKernelDevice(device,
                              IOCTL_WDMAUD_GET_CAPABILITIES,
                              (DWORD)caps->cbSize,
                              (DWORD)caps->pCaps);

    if ( result != MMSYSERR_NOERROR )
    {
        DPRINT("IoControl failed\n");
        goto cleanup;
    }

    /* Return code will already be MMSYSERR_NOERROR by now */

    cleanup :
    {
        if ( device )
            DeleteDeviceData(device);

        return result;
    }
}


/*
    OpenDeviceViaKernel

    Internal function to rub the kernel mode part of wdmaud the right way
    so it opens a device on our behalf.
*/

MMRESULT
OpenDeviceViaKernel(
    PWDMAUD_DEVICE_INFO device,
    LPWAVEFORMATEX format
)
{
    DWORD format_struct_len = 0;

    DPRINT("Opening device via kernel\n");

    if ( format->wFormatTag == 1 )  /* FIXME */
    {
        /* Standard PCM format */
        DWORD sample_size;

        DPRINT("Standard (PCM) format\n");

        sample_size = format->nChannels * format->wBitsPerSample;

        device->state->sample_size = sample_size;

        format_struct_len = 16; /* FIXME */
    }
    else
    {
        /* Non-standard format */
        return MMSYSERR_NOTSUPPORTED; /* TODO */
    }

    return CallKernelDevice(device,
                            IOCTL_WDMAUD_OPEN_DEVICE,
                            format_struct_len,
                            (DWORD)format);
}


/* MOVEME */
LPCRITICAL_SECTION CreateCriticalSection()
{
    LPCRITICAL_SECTION cs;

    cs = AllocMem(sizeof(CRITICAL_SECTION));

    if ( ! cs )
        return NULL;

    InitializeCriticalSection(cs);

    return cs;
}


/*
    OpenDevice

    A generic "open device" function, which makes use of the above function
    once parameters have been checked. This is capable of handling both
    MIDI and wave devices, which is an improvement over the previous
    implementation (which had a lot of duplicate functionality.)
*/

MMRESULT
OpenDevice(
    CHAR device_type,
    DWORD device_id,
    LPVOID open_descriptor,
    DWORD flags,
    PWDMAUD_DEVICE_INFO* user_data
)
{
    MMRESULT result = MMSYSERR_ERROR;
    WCHAR* device_path;
    PWDMAUD_DEVICE_INFO device;
    LPWAVEFORMATEX format;

    /* As we support both types */
    LPWAVEOPENDESC wave_opendesc = (LPWAVEOPENDESC) open_descriptor;
    LPMIDIOPENDESC midi_opendesc = (LPMIDIOPENDESC) open_descriptor;

    /* FIXME: Does this just apply to wave, or MIDI also? */
    if ( device_id > 100 )
        return MMSYSERR_BADDEVICEID;

    /* Copy the appropriate dnDevNode value */
    if ( IsWaveDeviceType(device_type) )
        device_path = (WCHAR*) wave_opendesc->dnDevNode;
    else if ( IsMidiDeviceType(device_type) )
        device_path = (WCHAR*) midi_opendesc->dnDevNode;
    else
        return MMSYSERR_INVALPARAM;

    device = CreateDeviceData(device_type, device_id, device_path, TRUE);

    if ( ! device )
    {
        DPRINT1("Couldn't allocate memory for device data\n");
        result = MMSYSERR_NOMEM;
        goto cleanup;
    }

    device->flags = flags;

    if ( ( IsWaveDeviceType(device->type) ) &&
         ( device->flags & WAVE_FORMAT_QUERY ) )
    {
        result = OpenDeviceViaKernel(device, wave_opendesc->lpFormat);

        if ( result != MMSYSERR_NOERROR )
        {
            DPRINT1("Format not supported (mmsys error %d)\n", (int) result);
            result = WAVERR_BADFORMAT;
        }
        else
        {
            DPRINT("Format supported\n");
            result = MMSYSERR_NOERROR;
        }

        goto cleanup;
    }

    device->state->device_queue_guard = CreateCriticalSection();

    if ( ! device->state->device_queue_guard )
    {
        DPRINT1("Couldn't create queue cs\n");
        result = MMSYSERR_NOMEM;
        goto cleanup;
    }

    /* Set up the callbacks */
    device->client_instance = IsWaveDeviceType(device->type)
                              ? wave_opendesc->dwInstance
                              : midi_opendesc->dwInstance;

    device->client_callback = IsWaveDeviceType(device->type)
                              ? wave_opendesc->dwCallback
                              : midi_opendesc->dwCallback;

    /*
        The device state will be stopped and unpaused already, but in some
        cases this isn't the desired behaviour.
    */

    /* FIXME: What do our friends MIDI in and out need? */
    device->state->is_paused = IsWaveOutDeviceType(device->type) ? TRUE : FALSE;

    if ( IsMidiOutDeviceType(device->type) )
    {
        device->state->midi_buffer = AllocMem(2048);

        if ( ! device->state->midi_buffer )
        {
            DPRINT1("Couldn't allocate MIDI buffer\n");
            result = MMSYSERR_NOMEM;
            goto cleanup;
        }
    }

    /* Format is only for wave devices */
    format = IsWaveDeviceType(device->type) ? wave_opendesc->lpFormat : NULL;

    result = OpenDeviceViaKernel(device, format);

    if ( MM_FAILURE(result) )
    {
        DPRINT1("FAILED to open device - mm error %d\n", (int) result);
        goto cleanup;
    }

    EnterCriticalSection(device->state->device_queue_guard);
    /* TODO */
    LeaveCriticalSection(device->state->device_queue_guard);

    if ( IsWaveDeviceType(device->type) )
        wave_opendesc->hWave = (HWAVE) device;
    else
        midi_opendesc->hMidi = (HMIDI) device;

    /* Our "user data" is actually the device information */
    *user_data = device;

    if ( device->client_callback )
    {
        DWORD message = IsWaveInDeviceType(device->type)    ? WIM_OPEN :
                        IsWaveOutDeviceType(device->type)   ? WOM_OPEN :
                        IsMidiInDeviceType(device->type)    ? MIM_OPEN :
                                                              MOM_OPEN;

        DPRINT("Calling client with message %d\n", (int) message);
        NotifyClient(device, message, 0, 0);
    }

    result = MMSYSERR_NOERROR;

    cleanup :
        return result;
}















?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
琪琪久久久久日韩精品| 欧美色倩网站大全免费| 国产精品久久久久久久第一福利 | 成人一区在线观看| 《视频一区视频二区| 欧美裸体bbwbbwbbw| 成人激情动漫在线观看| 偷窥少妇高潮呻吟av久久免费| 日韩欧美中文字幕一区| 91久久精品一区二区二区| 国产aⅴ精品一区二区三区色成熟| 亚洲免费观看高清完整版在线观看熊 | 丰满岳乱妇一区二区三区| 亚洲欧美日韩久久| 国产校园另类小说区| 欧美一级欧美一级在线播放| 91福利视频网站| 国产成+人+日韩+欧美+亚洲| 久久不见久久见免费视频1| 日韩成人免费在线| 午夜久久电影网| 亚洲国产视频直播| 伊人开心综合网| 一区二区三区在线观看欧美| 久久久久九九视频| 久久这里只有精品视频网| 欧美成人精品1314www| 精品国产伦一区二区三区观看体验| 欧美日韩精品系列| 91精品欧美一区二区三区综合在| 91免费视频观看| 欧美图片一区二区三区| 欧美美女一区二区三区| 欧美一级片免费看| 久久久久久久久岛国免费| 国产精品美女一区二区三区| 亚洲天堂2014| 午夜伦欧美伦电影理论片| 蜜臀久久99精品久久久久久9| 日韩av电影一区| 国产成人综合自拍| 欧美在线不卡一区| 日韩视频一区二区三区在线播放| 久久这里都是精品| 一区二区三区免费网站| 五月激情丁香一区二区三区| 久久99蜜桃精品| 一本一道久久a久久精品 | 91视频在线看| 91麻豆精品91久久久久久清纯 | 国产九九视频一区二区三区| bt7086福利一区国产| 91精品国产高清一区二区三区| 久久精品人人做人人爽人人| 亚洲精品伦理在线| 国产中文字幕精品| 69堂成人精品免费视频| 国产精品久久久一区麻豆最新章节| 夜夜嗨av一区二区三区| 成人精品亚洲人成在线| 91精品国产高清一区二区三区| 国产精品久久久久久久裸模| 老司机免费视频一区二区三区| 91在线精品一区二区| 国产人成亚洲第一网站在线播放 | 午夜不卡av免费| 在线观看网站黄不卡| 中文无字幕一区二区三区| 久久精品国产色蜜蜜麻豆| 欧美日韩电影在线| 亚洲高清视频中文字幕| 欧美在线视频全部完| 亚洲精品欧美激情| 在线观看日韩高清av| 18欧美亚洲精品| 欧美性猛交一区二区三区精品| 日韩美女精品在线| 日本韩国欧美在线| 洋洋成人永久网站入口| 欧美日韩一区不卡| 日韩综合小视频| 精品久久久影院| 国产精品亚洲人在线观看| 国产亚洲成aⅴ人片在线观看| 国产91精品一区二区麻豆亚洲| 国产亚洲成年网址在线观看| 99久久亚洲一区二区三区青草| 中文字幕一区免费在线观看 | 欧美性受极品xxxx喷水| 丝袜美腿成人在线| 日韩精品在线一区二区| 国产成人精品影视| 一区二区三区av电影| 欧美电影免费观看高清完整版在 | 一区二区三区免费观看| 在线观看日韩电影| 精品中文字幕一区二区| 日本一区二区免费在线 | 国产精品天美传媒沈樵| 欧美日韩午夜精品| 国产精品自在欧美一区| 亚洲精品免费在线| 精品国产乱码久久久久久久久| caoporn国产一区二区| 日产精品久久久久久久性色| 中文在线资源观看网站视频免费不卡 | 中文字幕成人在线观看| 日韩一区二区在线播放| 色94色欧美sute亚洲线路二| 韩国av一区二区三区| 亚洲成av人片在www色猫咪| 中文一区一区三区高中清不卡| 91精品免费在线| 在线看国产一区| 色哟哟精品一区| 91亚洲精华国产精华精华液| 成人免费视频视频| 国产一区二区三区免费在线观看| 亚洲国产日产av| 亚洲欧美日韩成人高清在线一区| 国产精品色在线观看| 久久午夜羞羞影院免费观看| 91精品国产一区二区三区| 欧美精品日韩一本| 欧美日韩国产免费一区二区 | 91蜜桃免费观看视频| 成人av中文字幕| 99视频在线观看一区三区| 色综合久久久久综合体桃花网| 91色porny在线视频| 在线免费观看成人短视频| 色又黄又爽网站www久久| 欧美专区在线观看一区| 欧美日韩aaa| 精品国产sm最大网站免费看| 久久久国产精品麻豆| 1024精品合集| 日本伊人午夜精品| 国产在线观看免费一区| 成人免费高清在线| 欧美老肥妇做.爰bbww视频| 精品国产不卡一区二区三区| 国产欧美一区二区精品性| 日韩美女久久久| 狠狠久久亚洲欧美| 91麻豆蜜桃一区二区三区| 91精品国产综合久久久久| 亚洲国产高清aⅴ视频| 亚洲一区二区三区四区的| 九一九一国产精品| 91行情网站电视在线观看高清版| 欧美色图天堂网| 国产区在线观看成人精品 | 国产精品免费人成网站| 日韩激情视频在线观看| 99视频国产精品| 欧美一区二区三区四区五区| 综合久久综合久久| 国产麻豆精品在线| 日韩一区二区电影网| 中文字幕在线一区二区三区| 韩国v欧美v亚洲v日本v| 欧美日韩不卡一区二区| 亚洲一区二区三区中文字幕| 91香蕉视频黄| 国产欧美一区二区在线观看| 国产成人自拍高清视频在线免费播放| 欧美日韩亚洲综合在线 欧美亚洲特黄一级 | 美女视频一区二区三区| 欧美性色aⅴ视频一区日韩精品| 亚洲私人影院在线观看| 成人h版在线观看| 欧美激情一区二区三区四区| 国产福利精品一区二区| 国产午夜精品理论片a级大结局 | 色av综合在线| 亚洲成人资源网| 欧美乱妇23p| 午夜激情综合网| 日韩三级在线观看| 国产精品2024| 亚洲欧美日韩国产一区二区三区| 一本色道a无线码一区v| 首页综合国产亚洲丝袜| 日韩欧美亚洲国产另类 | 91国产丝袜在线播放| 婷婷成人激情在线网| 日韩欧美国产wwwww| 国产成人精品亚洲午夜麻豆| 成人欧美一区二区三区| 91精品国产品国语在线不卡| 久久不见久久见免费视频1| 欧美激情一区二区三区四区| 色婷婷精品久久二区二区蜜臀av| 首页国产欧美日韩丝袜| 国产日韩欧美不卡| 91精品国产欧美一区二区成人| 国产在线观看免费一区| 亚洲九九爱视频| 久久蜜桃香蕉精品一区二区三区|