Fixed using user_memcpy for data received from userlad. This fixes ticket #6082.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36975 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Siarzhuk Zharski 2010-05-31 19:30:48 +00:00
parent b304c001b9
commit 98694dd385
2 changed files with 105 additions and 64 deletions

View File

@ -107,36 +107,46 @@ static const multi_channel_info channel_descriptions[] = {
static status_t static status_t
get_description(void *cookie, multi_description *data) get_description(void *cookie, multi_description *data)
{ {
data->interface_version = B_CURRENT_INTERFACE_VERSION; multi_description description;
data->interface_minimum = B_CURRENT_INTERFACE_VERSION; if(user_memcpy(&description, data, sizeof(multi_description)) != B_OK) {
return B_BAD_ADDRESS;
strcpy(data->friendly_name, "ALI M5451");
strcpy(data->vendor_info, "Krzysztof Ćwiertnia");
data->output_channel_count = ALI_SUPPORTED_OUTPUT_CHANNELS;
data->input_channel_count = ALI_SUPPORTED_INPUT_CHANNELS;
data->output_bus_channel_count = ALI_SUPPORTED_OUTPUT_CHANNELS;
data->input_bus_channel_count = ALI_SUPPORTED_INPUT_CHANNELS;
data->aux_bus_channel_count = 0;
if ((int32) (sizeof(channel_descriptions)/sizeof(channel_descriptions[0]))
<= data->request_channel_count) {
memcpy(data->channels, &channel_descriptions,
sizeof(channel_descriptions));
} }
data->output_formats = ALI_VALID_OUTPUT_FORMATS; description.interface_version = B_CURRENT_INTERFACE_VERSION;
data->output_rates = ALI_VALID_OUTPUT_SAMPLE_RATES; description.interface_minimum = B_CURRENT_INTERFACE_VERSION;
data->input_formats = ALI_VALID_INPUT_FORMATS; strcpy(description.friendly_name, "ALI M5451");
data->input_rates = ALI_VALID_INPUT_SAMPLE_RATES; strcpy(description.vendor_info, "Krzysztof Ćwiertnia");
data->lock_sources = B_MULTI_LOCK_INTERNAL; description.output_channel_count = ALI_SUPPORTED_OUTPUT_CHANNELS;
data->timecode_sources = 0; description.input_channel_count = ALI_SUPPORTED_INPUT_CHANNELS;
data->interface_flags = B_MULTI_INTERFACE_PLAYBACK|B_MULTI_INTERFACE_RECORD; description.output_bus_channel_count = ALI_SUPPORTED_OUTPUT_CHANNELS;
data->start_latency = 30000; description.input_bus_channel_count = ALI_SUPPORTED_INPUT_CHANNELS;
description.aux_bus_channel_count = 0;
strcpy(data->control_panel,""); description.output_formats = ALI_VALID_OUTPUT_FORMATS;
description.output_rates = ALI_VALID_OUTPUT_SAMPLE_RATES;
description.input_formats = ALI_VALID_INPUT_FORMATS;
description.input_rates = ALI_VALID_INPUT_SAMPLE_RATES;
description.lock_sources = B_MULTI_LOCK_INTERNAL;
description.timecode_sources = 0;
description.interface_flags = B_MULTI_INTERFACE_PLAYBACK|B_MULTI_INTERFACE_RECORD;
description.start_latency = 30000;
strcpy(description.control_panel,"");
if(user_memcpy(data, &description, sizeof(multi_description)) != B_OK) {
return B_BAD_ADDRESS;
}
if(description.request_channel_count >=
sizeof(channel_descriptions) / sizeof(channel_descriptions[0])) {
if(user_memcpy(data->channels,
&channel_descriptions, sizeof(channel_descriptions)) != B_OK)
return B_BAD_ADDRESS;
}
return B_OK; return B_OK;
} }
@ -487,11 +497,16 @@ get_buffers(ali_dev *card, multi_buffer_list *data)
static status_t static status_t
buffer_exchange(ali_dev *card, multi_buffer_info *buffer_info) buffer_exchange(ali_dev *card, multi_buffer_info *info)
{ {
status_t res; status_t res;
ali_stream *play_s, *rec_s; ali_stream *play_s, *rec_s;
multi_buffer_info buffer_info;
if(user_memcpy(&buffer_info, info, sizeof(multi_buffer_info)) != B_OK) {
return B_BAD_ADDRESS;
}
play_s = card->playback_stream; play_s = card->playback_stream;
rec_s = card->record_stream; rec_s = card->record_stream;
@ -513,16 +528,20 @@ buffer_exchange(ali_dev *card, multi_buffer_info *buffer_info)
LOCK(card->lock_sts); LOCK(card->lock_sts);
buffer_info->played_frames_count = play_s->frames_count; buffer_info.played_frames_count = play_s->frames_count;
buffer_info->played_real_time = play_s->real_time; buffer_info.played_real_time = play_s->real_time;
buffer_info->playback_buffer_cycle = play_s->buffer_cycle; buffer_info.playback_buffer_cycle = play_s->buffer_cycle;
buffer_info->recorded_frames_count = rec_s->frames_count; buffer_info.recorded_frames_count = rec_s->frames_count;
buffer_info->recorded_real_time = rec_s->real_time; buffer_info.recorded_real_time = rec_s->real_time;
buffer_info->record_buffer_cycle = rec_s->buffer_cycle; buffer_info.record_buffer_cycle = rec_s->buffer_cycle;
UNLOCK(card->lock_sts); UNLOCK(card->lock_sts);
if(user_memcpy(info, &buffer_info, sizeof(multi_buffer_info)) != B_OK) {
return B_BAD_ADDRESS;
}
return B_OK; return B_OK;
} }

View File

@ -48,36 +48,49 @@ static status_t
get_description(void* cookie, multi_description* data) get_description(void* cookie, multi_description* data)
{ {
dprintf("null_audio: %s\n" , __func__ ); dprintf("null_audio: %s\n" , __func__ );
data->interface_version = B_CURRENT_INTERFACE_VERSION;
data->interface_minimum = B_CURRENT_INTERFACE_VERSION;
strcpy(data->friendly_name,"Virtual audio (null_audio)"); multi_description description;
strcpy(data->vendor_info,"Host/Haiku"); if(user_memcpy(&description, data, sizeof(multi_description)) != B_OK) {
return B_BAD_ADDRESS;
data->output_channel_count = 2;
data->input_channel_count = 2;
data->output_bus_channel_count = 2;
data->input_bus_channel_count = 2;
data->aux_bus_channel_count = 0;
if (data->request_channel_count >= (int)(sizeof(channel_descriptions) / sizeof(channel_descriptions[0]))) {
memcpy(data->channels,&channel_descriptions,sizeof(channel_descriptions));
} }
data->output_rates = B_SR_44100; description.interface_version = B_CURRENT_INTERFACE_VERSION;
data->input_rates = B_SR_44100; description.interface_minimum = B_CURRENT_INTERFACE_VERSION;
data->max_cvsr_rate = 0; strcpy(description.friendly_name,"Virtual audio (null_audio)");
data->min_cvsr_rate = 0; strcpy(description.vendor_info,"Host/Haiku");
data->output_formats = B_FMT_16BIT; description.output_channel_count = 2;
data->input_formats = B_FMT_16BIT; description.input_channel_count = 2;
data->lock_sources = B_MULTI_LOCK_INTERNAL; description.output_bus_channel_count = 2;
data->timecode_sources = 0; description.input_bus_channel_count = 2;
data->interface_flags = B_MULTI_INTERFACE_PLAYBACK | B_MULTI_INTERFACE_RECORD; description.aux_bus_channel_count = 0;
data->start_latency = 30000;
strcpy(data->control_panel,""); description.output_rates = B_SR_44100;
description.input_rates = B_SR_44100;
description.max_cvsr_rate = 0;
description.min_cvsr_rate = 0;
description.output_formats = B_FMT_16BIT;
description.input_formats = B_FMT_16BIT;
description.lock_sources = B_MULTI_LOCK_INTERNAL;
description.timecode_sources = 0;
description.interface_flags = B_MULTI_INTERFACE_PLAYBACK | B_MULTI_INTERFACE_RECORD;
description.start_latency = 30000;
strcpy(description.control_panel,"");
if(user_memcpy(data, &description, sizeof(multi_description)) != B_OK) {
return B_BAD_ADDRESS;
}
if(description.request_channel_count
>= sizeof(channel_descriptions) / sizeof(channel_descriptions[0])) {
if(user_memcpy(data->channels,
&channel_descriptions, sizeof(channel_descriptions)) != B_OK)
return B_BAD_ADDRESS;
}
return B_OK; return B_OK;
} }
@ -255,13 +268,18 @@ get_buffers(device_t* device, multi_buffer_list* data)
static status_t static status_t
buffer_exchange(device_t* device, multi_buffer_info* buffer_info) buffer_exchange(device_t* device, multi_buffer_info* info)
{ {
//dprintf("null_audio: %s\n" , __func__ ); //dprintf("null_audio: %s\n" , __func__ );
static int debug_buffers_exchanged = 0; static int debug_buffers_exchanged = 0;
cpu_status status; cpu_status status;
status_t result; status_t result;
multi_buffer_info buffer_info;
if(user_memcpy(&buffer_info, info, sizeof(multi_buffer_info)) != B_OK) {
return B_BAD_ADDRESS;
}
// On first call, we start our fake hardware. // On first call, we start our fake hardware.
// Usually one would jump into his interrupt handler now // Usually one would jump into his interrupt handler now
if (!device->running) if (!device->running)
@ -282,13 +300,13 @@ buffer_exchange(device_t* device, multi_buffer_info* buffer_info)
status = disable_interrupts(); status = disable_interrupts();
acquire_spinlock(&device->playback_stream.lock); acquire_spinlock(&device->playback_stream.lock);
buffer_info->playback_buffer_cycle = device->playback_stream.buffer_cycle; buffer_info.playback_buffer_cycle = device->playback_stream.buffer_cycle;
buffer_info->played_real_time = device->playback_stream.real_time; buffer_info.played_real_time = device->playback_stream.real_time;
buffer_info->played_frames_count = device->playback_stream.frames_count; buffer_info.played_frames_count = device->playback_stream.frames_count;
buffer_info->record_buffer_cycle = device->record_stream.buffer_cycle; buffer_info.record_buffer_cycle = device->record_stream.buffer_cycle;
buffer_info->recorded_real_time = device->record_stream.real_time; buffer_info.recorded_real_time = device->record_stream.real_time;
buffer_info->recorded_frames_count = device->record_stream.frames_count; buffer_info.recorded_frames_count = device->record_stream.frames_count;
release_spinlock(&device->playback_stream.lock); release_spinlock(&device->playback_stream.lock);
restore_interrupts(status); restore_interrupts(status);
@ -298,6 +316,10 @@ buffer_exchange(device_t* device, multi_buffer_info* buffer_info)
dprintf("null_audio: %s: %d buffers processed\n", __func__, debug_buffers_exchanged); dprintf("null_audio: %s: %d buffers processed\n", __func__, debug_buffers_exchanged);
} }
if(user_memcpy(info, &buffer_info, sizeof(multi_buffer_info)) != B_OK) {
return B_BAD_ADDRESS;
}
return B_OK; return B_OK;
} }