VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/darwin/testcase/tstOpenUSBDev.cpp@ 31896

最後變更 在這個檔案從31896是 31896,由 vboxsync 提交於 15 年 前

export the VBoxUSB host driver to OSE

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.2 KB
 
1/* $Id: tstOpenUSBDev.cpp 31896 2010-08-24 09:17:44Z vboxsync $ */
2/** @file
3 * Testcase that attempts to locate and open the specfied device.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
8 *
9 * Oracle Corporation confidential
10 * All rights reserved
11 */
12
13
14/*******************************************************************************
15* Header Files *
16*******************************************************************************/
17#include <mach/mach.h>
18#include <Carbon/Carbon.h>
19#include <IOKit/IOKitLib.h>
20#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
21#include <IOKit/scsi/SCSITaskLib.h>
22#include <mach/mach_error.h>
23#include <IOKit/usb/IOUSBLib.h>
24#include <IOKit/IOCFPlugIn.h>
25
26#include <iprt/mem.h>
27#include <iprt/string.h>
28#include <iprt/process.h>
29#include <iprt/assert.h>
30#include <iprt/thread.h>
31#include <iprt/getopt.h>
32#include <iprt/initterm.h>
33#include <iprt/stream.h>
34
35/**
36 * Gets an unsigned 32-bit integer value.
37 *
38 * @returns Success indicator (true/false).
39 * @param DictRef The dictionary.
40 * @param KeyStrRef The key name.
41 * @param pu32 Where to store the key value.
42 */
43static bool tstDictGetU32(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, uint32_t *pu32)
44{
45 CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef);
46 if (ValRef)
47 {
48 if (CFNumberGetValue((CFNumberRef)ValRef, kCFNumberSInt32Type, pu32))
49 return true;
50 }
51 *pu32 = 0;
52 return false;
53}
54
55
56/**
57 * Gets an unsigned 64-bit integer value.
58 *
59 * @returns Success indicator (true/false).
60 * @param DictRef The dictionary.
61 * @param KeyStrRef The key name.
62 * @param pu64 Where to store the key value.
63 */
64static bool tstDictGetU64(CFMutableDictionaryRef DictRef, CFStringRef KeyStrRef, uint64_t *pu64)
65{
66 CFTypeRef ValRef = CFDictionaryGetValue(DictRef, KeyStrRef);
67 if (ValRef)
68 {
69 if (CFNumberGetValue((CFNumberRef)ValRef, kCFNumberSInt64Type, pu64))
70 return true;
71 }
72 *pu64 = 0;
73 return false;
74}
75
76
77static int tstDoWork(io_object_t USBDevice, mach_port_t MasterPort, const char *argv0)
78{
79 /*
80 * Create a plugin interface for the device and query its IOUSBDeviceInterface.
81 */
82 int vrc = VINF_SUCCESS;
83 SInt32 Score = 0;
84 IOCFPlugInInterface **ppPlugInInterface = NULL;
85 IOReturn irc = IOCreatePlugInInterfaceForService(USBDevice, kIOUSBDeviceUserClientTypeID,
86 kIOCFPlugInInterfaceID, &ppPlugInInterface, &Score);
87 if (irc == kIOReturnSuccess)
88 {
89 IOUSBDeviceInterface245 **ppDevI = NULL;
90 HRESULT hrc = (*ppPlugInInterface)->QueryInterface(ppPlugInInterface,
91 CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245),
92 (LPVOID *)&ppDevI);
93 irc = IODestroyPlugInInterface(ppPlugInInterface); Assert(irc == kIOReturnSuccess);
94 ppPlugInInterface = NULL;
95 if (hrc == S_OK)
96 {
97 /*
98 * Try open the device for exclusive access.
99 */
100 irc = (*ppDevI)->USBDeviceOpenSeize(ppDevI);
101 if (irc == kIOReturnExclusiveAccess)
102 {
103 RTThreadSleep(20);
104 irc = (*ppDevI)->USBDeviceOpenSeize(ppDevI);
105 }
106 if (irc == kIOReturnSuccess)
107 {
108#if 0
109 /*
110 * Re-enumerate the device and bail out.
111 */
112 irc = (*ppDevI)->USBDeviceReEnumerate(ppDevI, 0);
113 if (irc != kIOReturnSuccess)
114 {
115 vrc = RTErrConvertFromDarwinIO(irc);
116 RTPrintf("%s: Failed to re-enumerate the device, irc=%#x (vrc=%Rrc).\n", argv0, irc, vrc);
117 }
118#endif
119
120 (*ppDevI)->USBDeviceClose(ppDevI);
121 }
122 else if (irc == kIOReturnExclusiveAccess)
123 {
124 vrc = VERR_SHARING_VIOLATION;
125 RTPrintf("%s: The device is being used by another process (irc=kIOReturnExclusiveAccess)\n", argv0);
126 }
127 else
128 {
129 vrc = VERR_OPEN_FAILED;
130 RTPrintf("%s: Failed to open the device, irc=%#x (vrc=%Rrc).\n", argv0, irc, vrc);
131 }
132 }
133 else
134 {
135 vrc = VERR_OPEN_FAILED;
136 RTPrintf("%s: Failed to create plugin interface for the device, hrc=%#x (vrc=%Rrc).\n", argv0, hrc, vrc);
137 }
138
139 (*ppDevI)->Release(ppDevI);
140 }
141 else
142 {
143 vrc = RTErrConvertFromDarwinIO(irc);
144 RTPrintf("%s: Failed to open the device, plug-in creation failed with irc=%#x (vrc=%Rrc).\n", argv0, irc, vrc);
145 }
146
147 return vrc;
148}
149
150
151static int tstSyntax(const char *argv0)
152{
153 RTPrintf("syntax: %s [criteria]\n"
154 "\n"
155 "Criteria:\n"
156 " -l <location>\n"
157 " -s <session>\n"
158 , argv0);
159 return 1;
160}
161
162
163int main(int argc, char **argv)
164{
165 RTR3Init();
166
167 /*
168 * Show help if not arguments.
169 */
170 if (argc <= 1)
171 return tstSyntax(argv[0]);
172
173 /*
174 * Parse arguments.
175 */
176 static const RTGETOPTDEF g_aOptions[] =
177 {
178 { "--location", 'l', RTGETOPT_REQ_UINT32 },
179 { "--session", 's', RTGETOPT_REQ_UINT64 },
180 };
181
182 kern_return_t krc;
183 uint64_t u64SessionId = 0;
184 uint32_t u32LocationId = 0;
185
186 int ch;
187 int i = 1;
188 RTGETOPTUNION ValueUnion;
189 RTGETOPTSTATE GetState;
190 RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, 0 /* fFlags */);
191 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
192 {
193 switch (ch)
194 {
195 case 'l':
196 u32LocationId = ValueUnion.u32;
197 break;
198 case 's':
199 u64SessionId = ValueUnion.u64;
200 break;
201 case 'h':
202 return tstSyntax(argv[0]);
203 case 'V':
204 RTPrintf("$Revision: 31896 $\n");
205 return 0;
206
207 default:
208 return RTGetOptPrintError(ch, &ValueUnion);
209 }
210 }
211
212 /*
213 * Open the master port.
214 */
215 mach_port_t MasterPort = NULL;
216 krc = IOMasterPort(MACH_PORT_NULL, &MasterPort);
217 if (krc != KERN_SUCCESS)
218 {
219 RTPrintf("%s: IOMasterPort -> %x\n", argv[0], krc);
220 return 1;
221 }
222
223 /*
224 * Iterate the USB devices and find all that matches.
225 */
226 CFMutableDictionaryRef RefMatchingDict = IOServiceMatching(kIOUSBDeviceClassName);
227 if (!RefMatchingDict)
228 {
229 RTPrintf("%s: IOServiceMatching failed\n", argv[0]);
230 return 1;
231 }
232
233 io_iterator_t USBDevices = NULL;
234 IOReturn irc = IOServiceGetMatchingServices(MasterPort, RefMatchingDict, &USBDevices);
235 if (irc != kIOReturnSuccess)
236 {
237 RTPrintf("%s: IOServiceGetMatchingServices -> %#x\n", argv[0], irc);
238 return 1;
239 }
240 RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */
241
242 unsigned cDevices = 0;
243 unsigned cMatches = 0;
244 io_object_t USBDevice;
245 while ((USBDevice = IOIteratorNext(USBDevices)))
246 {
247 cDevices++;
248 CFMutableDictionaryRef PropsRef = 0;
249 krc = IORegistryEntryCreateCFProperties(USBDevice, &PropsRef, kCFAllocatorDefault, kNilOptions);
250 if (krc == KERN_SUCCESS)
251 {
252 uint64_t u64CurSessionId;
253 uint32_t u32CurLocationId;
254 if ( ( !u64SessionId
255 || ( tstDictGetU64(PropsRef, CFSTR("sessionID"), &u64CurSessionId)
256 && u64CurSessionId == u64SessionId))
257 && ( !u32LocationId
258 || ( tstDictGetU32(PropsRef, CFSTR(kUSBDevicePropertyLocationID), &u32CurLocationId)
259 && u32CurLocationId == u32LocationId))
260 )
261 {
262 cMatches++;
263 CFRelease(PropsRef);
264 tstDoWork(USBDevice, MasterPort, argv[0]);
265 }
266 else
267 CFRelease(PropsRef);
268 }
269 IOObjectRelease(USBDevice);
270 }
271 IOObjectRelease(USBDevices);
272
273 /*
274 * Bitch if we didn't find anything matching the criteria.
275 */
276 if (!cMatches)
277 RTPrintf("%s: No matching devices found from a total of %d.\n", argv[0], cDevices);
278 return !cMatches;
279}
280
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette