cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

rdpsnd.c (3629B)


      1/*
      2 * Licensed to the Apache Software Foundation (ASF) under one
      3 * or more contributor license agreements.  See the NOTICE file
      4 * distributed with this work for additional information
      5 * regarding copyright ownership.  The ASF licenses this file
      6 * to you under the Apache License, Version 2.0 (the
      7 * "License"); you may not use this file except in compliance
      8 * with the License.  You may obtain a copy of the License at
      9 *
     10 *   http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing,
     13 * software distributed under the License is distributed on an
     14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15 * KIND, either express or implied.  See the License for the
     16 * specific language governing permissions and limitations
     17 * under the License.
     18 */
     19
     20#include "channels/common-svc.h"
     21#include "channels/rdpsnd/rdpsnd.h"
     22#include "channels/rdpsnd/rdpsnd-messages.h"
     23#include "rdp.h"
     24
     25#include <freerdp/codec/audio.h>
     26#include <freerdp/freerdp.h>
     27#include <guacamole/client.h>
     28#include <guacamole/mem.h>
     29#include <winpr/stream.h>
     30
     31#include <stdlib.h>
     32
     33void guac_rdpsnd_process_receive(guac_rdp_common_svc* svc,
     34        wStream* input_stream) {
     35
     36    guac_rdpsnd* rdpsnd = (guac_rdpsnd*) svc->data;
     37    guac_rdpsnd_pdu_header header;
     38
     39    /* Check that we have at least the 4 byte header (UINT8 + UINT8 + UINT16) */
     40    if (Stream_GetRemainingLength(input_stream) < 4) {
     41        guac_client_log(svc->client, GUAC_LOG_WARNING, "Audio Stream does not "
     42                "contain the expected number of bytes. Audio redirection may "
     43                "not work as expected.");
     44        return;
     45    }
     46    
     47    /* Read RDPSND PDU header */
     48    Stream_Read_UINT8(input_stream, header.message_type);
     49    Stream_Seek_UINT8(input_stream);
     50    Stream_Read_UINT16(input_stream, header.body_size);
     51    
     52    /* 
     53     * If next PDU is SNDWAVE (due to receiving WaveInfo PDU previously),
     54     * ignore the header and parse as a Wave PDU.
     55     */
     56    if (rdpsnd->next_pdu_is_wave) {
     57        guac_rdpsnd_wave_handler(svc, input_stream, &header);
     58        return;
     59    }
     60
     61    /* Dispatch message to standard handlers */
     62    switch (header.message_type) {
     63
     64        /* Server Audio Formats and Version PDU */
     65        case SNDC_FORMATS:
     66            guac_rdpsnd_formats_handler(svc, input_stream, &header);
     67            break;
     68
     69        /* Training PDU */
     70        case SNDC_TRAINING:
     71            guac_rdpsnd_training_handler(svc, input_stream, &header);
     72            break;
     73
     74        /* WaveInfo PDU */
     75        case SNDC_WAVE:
     76            guac_rdpsnd_wave_info_handler(svc, input_stream, &header);
     77            break;
     78
     79        /* Close PDU */
     80        case SNDC_CLOSE:
     81            guac_rdpsnd_close_handler(svc, input_stream, &header);
     82            break;
     83
     84    }
     85
     86}
     87
     88void guac_rdpsnd_process_connect(guac_rdp_common_svc* svc) {
     89
     90    guac_rdpsnd* rdpsnd = (guac_rdpsnd*) guac_mem_zalloc(sizeof(guac_rdpsnd));
     91    svc->data = rdpsnd;
     92
     93}
     94
     95void guac_rdpsnd_process_terminate(guac_rdp_common_svc* svc) {
     96    guac_mem_free(svc->data);
     97}
     98
     99void guac_rdpsnd_load_plugin(rdpContext* context) {
    100
    101    guac_client* client = ((rdp_freerdp_context*) context)->client;
    102
    103    /* Load support for RDPSND */
    104    if (guac_rdp_common_svc_load_plugin(context, "rdpsnd", 0,
    105                guac_rdpsnd_process_connect, guac_rdpsnd_process_receive,
    106                guac_rdpsnd_process_terminate)) {
    107        guac_client_log(client, GUAC_LOG_WARNING, "Support for the RDPSND "
    108                "channel (audio output) could not be loaded. Sound will not "
    109                "work. Drive redirection and printing MAY not work.");
    110    }
    111
    112}
    113