vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / media / media-add-ons / firewire_dv / FireWireDVAddOn.cpp
blob436b6a43258e41074da487b54db7bbc3df0b30ad
1 /*
2 * FireWire DV media addon for Haiku
4 * Copyright (c) 2008, JiSheng Zhang (jszhang3@mail.ustc.edu.cn)
5 * Distributed under the terms of the MIT License.
7 * Based on DVB media addon
8 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
9 */
11 #include "FireWireDVAddOn.h"
12 #include "FireWireCard.h"
13 #include "FireWireDVNode.h"
15 #include <stdio.h>
16 #include <string.h>
17 #include <time.h>
19 #include <Alert.h>
20 #include <Directory.h>
21 #include <Entry.h>
22 #include <Path.h>
24 #include "debug.h"
26 struct device_info
28 FireWireCard* card;
29 char name[16];
30 media_format in_formats[1];
31 media_format out_formats[1];
32 flavor_info flavor;
35 extern "C" BMediaAddOn*
36 make_media_addon(image_id id)
38 CALLED();
39 return new FireWireDVAddOn(id);
43 FireWireDVAddOn::FireWireDVAddOn(image_id id)
44 : BMediaAddOn(id)
46 CALLED();
47 ScanFolder("/dev/bus/fw");
51 FireWireDVAddOn::~FireWireDVAddOn()
53 CALLED();
54 FreeDeviceList();
58 status_t
59 FireWireDVAddOn::InitCheck(const char** out_failure_text)
61 CALLED();
62 if (!fDeviceList.CountItems()) {
63 *out_failure_text = "No supported device found";
64 return B_ERROR;
66 return B_OK;
70 int32
71 FireWireDVAddOn::CountFlavors()
73 CALLED();
74 return fDeviceList.CountItems();
78 status_t
79 FireWireDVAddOn::GetFlavorAt(int32 n, const flavor_info** out_info)
81 CALLED();
82 device_info* dev = fDeviceList.ItemAt(n);
83 if (!dev)
84 return B_ERROR;
85 *out_info = &dev->flavor;
86 return B_OK;
90 BMediaNode *
91 FireWireDVAddOn::InstantiateNodeFor(const flavor_info* info, BMessage* config,
92 status_t* out_error)
94 CALLED();
95 device_info* dev = fDeviceList.ItemAt(info->internal_id);
96 if (!dev || dev->flavor.internal_id != info->internal_id) {
97 *out_error = B_ERROR;
98 return NULL;
100 *out_error = B_OK;
102 return new FireWireDVNode(this, dev->name, dev->flavor.internal_id,
103 dev->card);
107 bool
108 FireWireDVAddOn::WantsAutoStart()
110 CALLED();
111 return false;
115 status_t
116 FireWireDVAddOn::AutoStart(int index, BMediaNode** outNode,
117 int32* outInternalID, bool* outHasMore)
119 CALLED();
120 return B_ERROR;
124 void
125 FireWireDVAddOn::ScanFolder(const char* path)
127 CALLED();
128 BDirectory dir(path);
129 if (dir.InitCheck() != B_OK)
130 return;
132 BEntry ent;
134 while (dir.GetNextEntry(&ent) == B_OK) {
135 BPath path(&ent);
136 if (!ent.IsDirectory() && !ent.IsSymLink()) {
137 FireWireCard *card = new FireWireCard(path.Path());
138 if (card->InitCheck() == B_OK)
139 AddDevice(card, path.Path());
140 else
141 delete card;
147 void
148 FireWireDVAddOn::AddDevice(FireWireCard* card, const char* path)
150 const char* fwnumber;
152 // get card name, info and type
154 // get interface number
155 const char *p = strrchr(path, '/');
156 fwnumber = p ? p + 1 : "";
158 // create device_info
159 device_info *dev = new device_info;
160 fDeviceList.AddItem(dev);
162 dev->card = card;
164 sprintf(dev->name, "FireWire-%s", fwnumber);
166 // setup supported formats (the lazy way)
167 memset(dev->in_formats, 0, sizeof(dev->in_formats));
168 memset(dev->out_formats, 0, sizeof(dev->out_formats));
169 dev->in_formats[0].type = B_MEDIA_ENCODED_VIDEO;
170 dev->out_formats[0].type = B_MEDIA_ENCODED_VIDEO;
172 // setup flavor info
173 dev->flavor.name = dev->name;
174 dev->flavor.info = (char *)"The FireWireDVNode outputs to fw_raw drivers.";
175 dev->flavor.kinds = B_BUFFER_CONSUMER | B_BUFFER_PRODUCER
176 | B_CONTROLLABLE | B_PHYSICAL_OUTPUT | B_PHYSICAL_INPUT;
177 dev->flavor.flavor_flags = B_FLAVOR_IS_GLOBAL;
178 dev->flavor.internal_id = fDeviceList.CountItems() - 1;
179 dev->flavor.possible_count = 1;
180 dev->flavor.in_format_count = 1;
181 dev->flavor.in_format_flags = 0;
182 dev->flavor.in_formats = dev->in_formats;
183 dev->flavor.out_format_count = 1;
184 dev->flavor.out_format_flags = 0;
185 dev->flavor.out_formats = dev->out_formats;
189 void
190 FireWireDVAddOn::FreeDeviceList()
192 device_info* dev;
193 while ((dev = fDeviceList.RemoveItemAt(0L))) {
194 delete dev->card;
195 delete dev;