cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

dsound_template.h (7212B)


      1/*
      2 * QEMU DirectSound audio driver header
      3 *
      4 * Copyright (c) 2005 Vassili Karpov (malc)
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to deal
      8 * in the Software without restriction, including without limitation the rights
      9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10 * copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22 * THE SOFTWARE.
     23 */
     24#ifdef DSBTYPE_IN
     25#define NAME "capture buffer"
     26#define NAME2 "DirectSoundCapture"
     27#define TYPE in
     28#define IFACE IDirectSoundCaptureBuffer
     29#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
     30#define FIELD dsound_capture_buffer
     31#define FIELD2 dsound_capture
     32#define HWVOICE HWVoiceIn
     33#define DSOUNDVOICE DSoundVoiceIn
     34#else
     35#define NAME "playback buffer"
     36#define NAME2 "DirectSound"
     37#define TYPE out
     38#define IFACE IDirectSoundBuffer
     39#define BUFPTR LPDIRECTSOUNDBUFFER
     40#define FIELD dsound_buffer
     41#define FIELD2 dsound
     42#define HWVOICE HWVoiceOut
     43#define DSOUNDVOICE DSoundVoiceOut
     44#endif
     45
     46static int glue (dsound_unlock_, TYPE) (
     47    BUFPTR buf,
     48    LPVOID p1,
     49    LPVOID p2,
     50    DWORD blen1,
     51    DWORD blen2
     52    )
     53{
     54    HRESULT hr;
     55
     56    hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
     57    if (FAILED (hr)) {
     58        dsound_logerr (hr, "Could not unlock " NAME "\n");
     59        return -1;
     60    }
     61
     62    return 0;
     63}
     64
     65static int glue (dsound_lock_, TYPE) (
     66    BUFPTR buf,
     67    struct audio_pcm_info *info,
     68    DWORD pos,
     69    DWORD len,
     70    LPVOID *p1p,
     71    LPVOID *p2p,
     72    DWORD *blen1p,
     73    DWORD *blen2p,
     74    int entire,
     75    dsound *s
     76    )
     77{
     78    HRESULT hr;
     79    DWORD flag;
     80
     81#ifdef DSBTYPE_IN
     82    flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
     83#else
     84    flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
     85#endif
     86    hr = glue(IFACE, _Lock)(buf, pos, len, p1p, blen1p, p2p, blen2p, flag);
     87
     88    if (FAILED (hr)) {
     89#ifndef DSBTYPE_IN
     90        if (hr == DSERR_BUFFERLOST) {
     91            if (glue (dsound_restore_, TYPE) (buf, s)) {
     92                dsound_logerr (hr, "Could not lock " NAME "\n");
     93            }
     94            goto fail;
     95        }
     96#endif
     97        dsound_logerr (hr, "Could not lock " NAME "\n");
     98        goto fail;
     99    }
    100
    101    if ((p1p && *p1p && (*blen1p % info->bytes_per_frame)) ||
    102        (p2p && *p2p && (*blen2p % info->bytes_per_frame))) {
    103        dolog("DirectSound returned misaligned buffer %ld %ld\n",
    104              *blen1p, *blen2p);
    105        glue(dsound_unlock_, TYPE)(buf, *p1p, p2p ? *p2p : NULL, *blen1p,
    106                                   blen2p ? *blen2p : 0);
    107        goto fail;
    108    }
    109
    110    if (p1p && !*p1p && *blen1p) {
    111        dolog("warning: !p1 && blen1=%ld\n", *blen1p);
    112        *blen1p = 0;
    113    }
    114
    115    if (p2p && !*p2p && *blen2p) {
    116        dolog("warning: !p2 && blen2=%ld\n", *blen2p);
    117        *blen2p = 0;
    118    }
    119
    120    return 0;
    121
    122 fail:
    123    *p1p = NULL - 1;
    124    *blen1p = -1;
    125    if (p2p) {
    126        *p2p = NULL - 1;
    127        *blen2p = -1;
    128    }
    129    return -1;
    130}
    131
    132#ifdef DSBTYPE_IN
    133static void dsound_fini_in (HWVoiceIn *hw)
    134#else
    135static void dsound_fini_out (HWVoiceOut *hw)
    136#endif
    137{
    138    HRESULT hr;
    139#ifdef DSBTYPE_IN
    140    DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
    141#else
    142    DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
    143#endif
    144
    145    if (ds->FIELD) {
    146        hr = glue (IFACE, _Stop) (ds->FIELD);
    147        if (FAILED (hr)) {
    148            dsound_logerr (hr, "Could not stop " NAME "\n");
    149        }
    150
    151        hr = glue (IFACE, _Release) (ds->FIELD);
    152        if (FAILED (hr)) {
    153            dsound_logerr (hr, "Could not release " NAME "\n");
    154        }
    155        ds->FIELD = NULL;
    156    }
    157}
    158
    159#ifdef DSBTYPE_IN
    160static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
    161                          void *drv_opaque)
    162#else
    163static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
    164                           void *drv_opaque)
    165#endif
    166{
    167    int err;
    168    HRESULT hr;
    169    dsound *s = drv_opaque;
    170    WAVEFORMATEX wfx;
    171    struct audsettings obt_as;
    172#ifdef DSBTYPE_IN
    173    const char *typ = "ADC";
    174    DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
    175    DSCBUFFERDESC bd;
    176    DSCBCAPS bc;
    177    AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.in;
    178#else
    179    const char *typ = "DAC";
    180    DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
    181    DSBUFFERDESC bd;
    182    DSBCAPS bc;
    183    AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.out;
    184#endif
    185
    186    if (!s->FIELD2) {
    187        dolog ("Attempt to initialize voice without " NAME2 " object\n");
    188        return -1;
    189    }
    190
    191    err = waveformat_from_audio_settings (&wfx, as);
    192    if (err) {
    193        return -1;
    194    }
    195
    196    memset (&bd, 0, sizeof (bd));
    197    bd.dwSize = sizeof (bd);
    198    bd.lpwfxFormat = &wfx;
    199    bd.dwBufferBytes = audio_buffer_bytes(pdo, as, 92880);
    200#ifdef DSBTYPE_IN
    201    hr = IDirectSoundCapture_CreateCaptureBuffer (
    202        s->dsound_capture,
    203        &bd,
    204        &ds->dsound_capture_buffer,
    205        NULL
    206        );
    207#else
    208    bd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
    209    hr = IDirectSound_CreateSoundBuffer (
    210        s->dsound,
    211        &bd,
    212        &ds->dsound_buffer,
    213        NULL
    214        );
    215#endif
    216
    217    if (FAILED (hr)) {
    218        dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
    219        return -1;
    220    }
    221
    222    hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
    223    if (FAILED (hr)) {
    224        dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
    225        goto fail0;
    226    }
    227
    228#ifdef DEBUG_DSOUND
    229    dolog (NAME "\n");
    230    print_wave_format (&wfx);
    231#endif
    232
    233    memset (&bc, 0, sizeof (bc));
    234    bc.dwSize = sizeof (bc);
    235
    236    hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
    237    if (FAILED (hr)) {
    238        dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
    239        goto fail0;
    240    }
    241
    242    err = waveformat_to_audio_settings (&wfx, &obt_as);
    243    if (err) {
    244        goto fail0;
    245    }
    246
    247    ds->first_time = true;
    248    obt_as.endianness = 0;
    249    audio_pcm_init_info (&hw->info, &obt_as);
    250
    251    if (bc.dwBufferBytes % hw->info.bytes_per_frame) {
    252        dolog (
    253            "GetCaps returned misaligned buffer size %ld, alignment %d\n",
    254            bc.dwBufferBytes, hw->info.bytes_per_frame
    255            );
    256    }
    257    hw->size_emul = bc.dwBufferBytes;
    258    hw->samples = bc.dwBufferBytes / hw->info.bytes_per_frame;
    259    ds->s = s;
    260
    261#ifdef DEBUG_DSOUND
    262    dolog ("caps %ld, desc %ld\n",
    263           bc.dwBufferBytes, bd.dwBufferBytes);
    264#endif
    265    return 0;
    266
    267 fail0:
    268    glue (dsound_fini_, TYPE) (hw);
    269    return -1;
    270}
    271
    272#undef NAME
    273#undef NAME2
    274#undef TYPE
    275#undef IFACE
    276#undef BUFPTR
    277#undef FIELD
    278#undef FIELD2
    279#undef HWVOICE
    280#undef DSOUNDVOICE