vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / kernel / drivers / input / usb_hid / DeviceList.cpp
blob5444fd92c6b0f40979de216a21f8743008f915c1
1 /*
2 Generic device list for use in drivers.
3 Copyright (C) 2008 Michael Lotz <mmlr@mlotz.ch>
4 Distributed under the terms of the MIT license.
5 */
6 #include "DeviceList.h"
7 #include <util/kernel_cpp.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <new>
12 struct device_list_entry {
13 char * name;
14 void * device;
15 device_list_entry * next;
19 DeviceList::DeviceList()
20 : fDeviceList(NULL),
21 fDeviceCount(0),
22 fPublishList(NULL)
27 DeviceList::~DeviceList()
29 _FreePublishList();
31 device_list_entry *current = fDeviceList;
32 while (current) {
33 device_list_entry *next = current->next;
34 free(current->name);
35 delete current;
36 current = next;
41 status_t
42 DeviceList::AddDevice(const char *name, void *device)
44 device_list_entry *entry = new(std::nothrow) device_list_entry;
45 if (entry == NULL)
46 return B_NO_MEMORY;
48 entry->name = strdup(name);
49 if (entry->name == NULL) {
50 delete entry;
51 return B_NO_MEMORY;
54 entry->device = device;
55 entry->next = NULL;
57 if (fDeviceList == NULL)
58 fDeviceList = entry;
59 else {
60 device_list_entry *current = fDeviceList;
61 while (current) {
62 if (current->next == NULL) {
63 current->next = entry;
64 break;
67 current = current->next;
71 fDeviceCount++;
72 return B_OK;
76 status_t
77 DeviceList::RemoveDevice(const char *name, void *device)
79 if (name == NULL && device == NULL)
80 return B_BAD_VALUE;
82 device_list_entry *previous = NULL;
83 device_list_entry *current = fDeviceList;
84 while (current) {
85 if ((name != NULL && strcmp(current->name, name) == 0)
86 || (device != NULL && current->device == device)) {
87 if (previous == NULL)
88 fDeviceList = current->next;
89 else
90 previous->next = current->next;
92 free(current->name);
93 delete current;
94 fDeviceCount--;
95 return B_OK;
98 previous = current;
99 current = current->next;
102 return B_ENTRY_NOT_FOUND;
106 void *
107 DeviceList::FindDevice(const char *name, void *device)
109 if (name == NULL && device == NULL)
110 return NULL;
112 device_list_entry *current = fDeviceList;
113 while (current) {
114 if ((name != NULL && strcmp(current->name, name) == 0)
115 || (device != NULL && current->device == device))
116 return current->device;
118 current = current->next;
121 return NULL;
125 int32
126 DeviceList::CountDevices(const char *baseName)
128 if (baseName == NULL)
129 return fDeviceCount;
131 int32 count = 0;
132 int32 baseNameLength = strlen(baseName);
133 device_list_entry *current = fDeviceList;
134 while (current) {
135 if (strncmp(current->name, baseName, baseNameLength) == 0)
136 count++;
138 current = current->next;
141 return count;
145 void *
146 DeviceList::DeviceAt(int32 index)
148 device_list_entry *current = fDeviceList;
149 while (current) {
150 if (index-- == 0)
151 return current->device;
153 current = current->next;
156 return NULL;
160 const char **
161 DeviceList::PublishDevices()
163 _FreePublishList();
165 fPublishList = (char **)malloc((fDeviceCount + 1) * sizeof(char *));
166 if (fPublishList == NULL)
167 return NULL;
169 int32 index = 0;
170 device_list_entry *current = fDeviceList;
171 while (current) {
172 fPublishList[index++] = strdup(current->name);
173 current = current->next;
176 fPublishList[index] = NULL;
177 return (const char **)fPublishList;
181 void
182 DeviceList::_FreePublishList()
184 if (fPublishList == NULL)
185 return;
187 int32 index = 0;
188 while (fPublishList[index] != NULL) {
189 free(fPublishList[index]);
190 index++;
193 free(fPublishList);
194 fPublishList = NULL;