vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / drivers / audio / module_driver / audio_module_driver.c
blob9fea1d7c48ced4f2bdd0886ad44e938684e1699d
1 /*
2 * BeOS audio_module_driver
4 * Copyright (c) 2003, Marcus Overhagen <marcus@overhagen.de>
6 * All rights reserved.
7 * Redistribution only allowed under the terms of the MIT license.
9 */
12 #include <KernelExport.h>
13 #include <directories.h>
14 #include <Drivers.h>
15 #include <Errors.h>
16 #include <OS.h>
18 #include <malloc.h>
19 #include <fcntl.h>
20 #include <image.h>
22 #include "audio_module.h"
25 int32 api_version = B_CUR_DRIVER_API_VERSION;
27 #define DRIVER_NAME "audio_module_driver"
29 #define MODULE_TEST_PATH "media/audio/ich"
32 void republish_devices(void);
34 extern image_id load_kernel_addon(const char *path);
35 extern status_t unload_kernel_addon(image_id imid);
38 status_t
39 init_hardware(void)
41 dprintf("audio_module_driver: init_hardware\n");
42 return B_OK;
46 status_t
47 init_driver(void)
49 audio_module_info *audio_module;
50 image_id id;
51 status_t rv;
52 void (*print_hello_world)(void);
54 id = load_kernel_addon(kUserAddonsDirectory "/kernel/media/audio/ich");
55 get_image_symbol(id, "print_hello_world", B_SYMBOL_TYPE_TEXT,
56 (void **) &print_hello_world);
57 print_hello_world();
58 unload_kernel_addon(id);
59 if (rv != B_OK)
60 dprintf("unload_kernel_addon failed\n");
63 if (B_OK != get_module(MODULE_TEST_PATH, (module_info **)&audio_module)) {
64 dprintf("get_module failed\n");
65 return B_ERROR;
68 dprintf("calling audio_module->print_hello()\n");
70 audio_module->print_hello();
72 dprintf("done\n");
74 if (B_OK != put_module(MODULE_TEST_PATH)) {
75 dprintf("put_module failed\n");
76 return B_ERROR;
79 return B_OK;
83 void
84 uninit_driver(void)
86 dprintf("audio_module_driver: uninit_driver\n");
90 static status_t
91 audio_module_driver_open(const char *name, uint32 flags, void **cookie)
93 dprintf("audio_module_driver: open %s\n", name);
94 return B_OK;
98 static status_t
99 audio_module_driver_close(void *cookie)
101 dprintf("audio_module_driver: close\n");
102 return B_OK;
106 static status_t
107 audio_module_driver_free(void *cookie)
109 dprintf("audio_module_driver: free\n");
110 return B_OK;
114 static status_t
115 audio_module_driver_control(void *cookie, uint32 op, void *arg, size_t len)
117 dprintf("audio_module_driver: control\n");
118 switch (op) {
119 default:
120 return B_ERROR;
125 static status_t
126 audio_module_driver_read(void *cookie, off_t position, void *buf,
127 size_t *num_bytes)
129 *num_bytes = 0;
130 return B_IO_ERROR;
134 static status_t
135 audio_module_driver_write(void *cookie, off_t position, const void *buffer,
136 size_t *num_bytes)
138 static int keep_open_fd = -1;
139 if (*num_bytes >= 5 && 0 == memcmp("start", buffer, 5)
140 && keep_open_fd == -1) {
141 keep_open_fd = open("/dev/audio/audio_module_driver", O_RDWR);
142 return B_OK;
144 if (*num_bytes >= 4 && 0 == memcmp("stop", buffer, 4)
145 && keep_open_fd != -1) {
146 close(keep_open_fd);
147 keep_open_fd = -1;
148 return B_OK;
150 if (*num_bytes >= 6 && 0 == memcmp("rescan", buffer, 6)) {
151 republish_devices();
152 return B_OK;
154 *num_bytes = 0;
155 return B_IO_ERROR;
159 static const char *ich_name[] = {
160 "audio/" DRIVER_NAME,
161 "audio/modules/foobar/1",
162 "audio/modules/foobar/2",
163 "audio/modules/snafu/1",
164 "audio/modules/snafu/2",
165 NULL
169 device_hooks audio_module_driver_hooks = {
170 audio_module_driver_open,
171 audio_module_driver_close,
172 audio_module_driver_free,
173 audio_module_driver_control,
174 audio_module_driver_read,
175 audio_module_driver_write,
176 NULL,
177 NULL,
178 NULL,
179 NULL
183 const char**
184 publish_devices(void)
186 dprintf("audio_module_driver: publish_devices\n");
187 return ich_name;
191 device_hooks*
192 find_device(const char *name)
194 dprintf("audio_module_driver: find_device %s\n", name);
195 return &audio_module_driver_hooks;
199 void republish_devices(void)
201 int fd = open("/dev", O_WRONLY);
202 write(fd, DRIVER_NAME, strlen(DRIVER_NAME));
203 close (fd);