VirtualBox

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

Last change on this file since 54558 was 44528, checked in by vboxsync, 12 years ago

header (C) fixes

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

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