VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/solaris/VBoxUSBMon-solaris.c@ 31896

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

export the VBoxUSB host driver to OSE

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 39.8 KB
 
1/* $Id: VBoxUSBMon-solaris.c 31896 2010-08-24 09:17:44Z vboxsync $ */
2/** @file
3 * VirtualBox USB Monitor Driver, Solaris Hosts.
4 */
5
6/*
7 * Copyright (C) 2008 Oracle Corporation
8 *
9 * Oracle Corporation confidential
10 * All rights reserved
11 */
12
13/*******************************************************************************
14* Header Files *
15*******************************************************************************/
16#define LOG_GROUP LOG_GROUP_USB_DRV
17#include "VBoxUSBFilterMgr.h"
18#include <VBox/usblib-solaris.h>
19#include <VBox/version.h>
20#include <VBox/log.h>
21#include <VBox/cdefs.h>
22#include <VBox/types.h>
23#include <VBox/version.h>
24#include <iprt/assert.h>
25#include <iprt/string.h>
26#include <iprt/initterm.h>
27#include <iprt/process.h>
28#include <iprt/mem.h>
29#include <iprt/semaphore.h>
30#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
31# include <iprt/path.h>
32#endif
33
34#define USBDRV_MAJOR_VER 2
35#define USBDRV_MINOR_VER 0
36#include <sys/usb/usba.h>
37#include <sys/conf.h>
38#include <sys/modctl.h>
39#include <sys/mutex.h>
40#include <sys/stat.h>
41#include <sys/ddi.h>
42#include <sys/sunddi.h>
43#include <sys/sunndi.h>
44#include <sys/open.h>
45#include <sys/cmn_err.h>
46
47
48/*******************************************************************************
49* Defined Constants And Macros *
50*******************************************************************************/
51/** The module name. */
52#define DEVICE_NAME "vboxusbmon"
53/** The module description as seen in 'modinfo'. */
54#define DEVICE_DESC_DRV "VirtualBox USBMon"
55
56#if defined(DEBUG_ramshankar)
57# undef LogFlowFunc
58# define LogFlowFunc LogRel
59# undef Log
60# define Log LogRel
61# undef LogFlow
62# define LogFlow LogRel
63#endif
64
65/*******************************************************************************
66* Internal Functions *
67*******************************************************************************/
68static int VBoxUSBMonSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred);
69static int VBoxUSBMonSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred);
70static int VBoxUSBMonSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred);
71static int VBoxUSBMonSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred);
72static int VBoxUSBMonSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal);
73static int VBoxUSBMonSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pArg, void **ppResult);
74static int VBoxUSBMonSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd);
75static int VBoxUSBMonSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd);
76
77/*******************************************************************************
78* Structures and Typedefs *
79*******************************************************************************/
80/**
81 * cb_ops: for drivers that support char/block entry points
82 */
83static struct cb_ops g_VBoxUSBMonSolarisCbOps =
84{
85 VBoxUSBMonSolarisOpen,
86 VBoxUSBMonSolarisClose,
87 nodev, /* b strategy */
88 nodev, /* b dump */
89 nodev, /* b print */
90 VBoxUSBMonSolarisRead,
91 VBoxUSBMonSolarisWrite,
92 VBoxUSBMonSolarisIOCtl,
93 nodev, /* c devmap */
94 nodev, /* c mmap */
95 nodev, /* c segmap */
96 nochpoll, /* c poll */
97 ddi_prop_op, /* property ops */
98 NULL, /* streamtab */
99 D_NEW | D_MP, /* compat. flag */
100 CB_REV /* revision */
101};
102
103/**
104 * dev_ops: for driver device operations
105 */
106static struct dev_ops g_VBoxUSBMonSolarisDevOps =
107{
108 DEVO_REV, /* driver build revision */
109 0, /* ref count */
110 VBoxUSBMonSolarisGetInfo,
111 nulldev, /* identify */
112 nulldev, /* probe */
113 VBoxUSBMonSolarisAttach,
114 VBoxUSBMonSolarisDetach,
115 nodev, /* reset */
116 &g_VBoxUSBMonSolarisCbOps,
117 (struct bus_ops *)0,
118 nodev /* power */
119};
120
121/**
122 * modldrv: export driver specifics to the kernel
123 */
124static struct modldrv g_VBoxUSBMonSolarisModule =
125{
126 &mod_driverops, /* extern from kernel */
127 DEVICE_DESC_DRV " " VBOX_VERSION_STRING "r" RT_XSTR(VBOX_SVN_REV),
128 &g_VBoxUSBMonSolarisDevOps
129};
130
131/**
132 * modlinkage: export install/remove/info to the kernel
133 */
134static struct modlinkage g_VBoxUSBMonSolarisModLinkage =
135{
136 MODREV_1,
137 &g_VBoxUSBMonSolarisModule,
138 NULL,
139};
140
141#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
142/**
143 * Client driver info.
144 */
145typedef struct vboxusbmon_client_t
146{
147 dev_info_t *pDip; /* Client device info. pointer */
148 VBOXUSB_CLIENT_INFO Info; /* Client registeration data. */
149 struct vboxusbmon_client_t *pNext; /* Pointer to next client */
150} vboxusbmon_client_t;
151#endif
152
153/**
154 * Device state info.
155 */
156typedef struct
157{
158 RTPROCESS Process; /* The process (id) of the session */
159} vboxusbmon_state_t;
160
161
162/*******************************************************************************
163* Global Variables *
164*******************************************************************************/
165/** Global Device handle we only support one instance. */
166static dev_info_t *g_pDip;
167/** Global Mutex. */
168static kmutex_t g_VBoxUSBMonSolarisMtx;
169
170#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
171/** Number of userland clients that have kept us open. */
172static uint64_t g_cVBoxUSBMonSolarisClient = 0;
173/** Global list of client drivers registered with us. */
174vboxusbmon_client_t *g_pVBoxUSBMonSolarisClients = 0;
175#endif
176
177/** Opaque pointer to list of soft states. */
178static void *g_pVBoxUSBMonSolarisState;
179
180/*******************************************************************************
181* Internal Functions *
182*******************************************************************************/
183static int vboxUSBMonSolarisProcessIOCtl(int iFunction, void *pvState, void *pvData, size_t cbData, size_t *pcbReturnedData);
184static int vboxUSBMonSolarisResetDevice(char *pszDevicePath, bool fReattach);
185#ifndef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
186static int vboxUSBMonSolarisGetDeviceInstance(char *pszDevicePath, int32_t *pInstance);
187#endif
188
189
190/*******************************************************************************
191* Monitor Global Hooks *
192*******************************************************************************/
193#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
194static int vboxUSBMonSolarisClientInfo(vboxusbmon_state_t *pState, PVBOXUSB_CLIENT_INFO pClientInfo);
195int VBoxUSBMonSolarisRegisterClient(dev_info_t *pClientDip, PVBOXUSB_CLIENT_INFO pClientInfo);
196int VBoxUSBMonSolarisUnregisterClient(dev_info_t *pClientDip);
197int VBoxUSBMonSolarisElectDriver(usb_dev_descr_t *pDevDesc, usb_dev_str_t *pDevStrings, char *pszDevicePath, int Bus, int Port,
198 char **ppszDrv, void *pvReserved);
199#endif
200
201
202/**
203 * Kernel entry points
204 */
205int _init(void)
206{
207 int rc;
208
209 LogFlowFunc((DEVICE_NAME ":_init\n"));
210
211 g_pDip = NULL;
212
213 /*
214 * Prevent module autounloading.
215 */
216 modctl_t *pModCtl = mod_getctl(&g_VBoxUSBMonSolarisModLinkage);
217 if (pModCtl)
218 pModCtl->mod_loadflags |= MOD_NOAUTOUNLOAD;
219 else
220 LogRel((DEVICE_NAME ":failed to disable autounloading!\n"));
221
222 /*
223 * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
224 */
225 rc = RTR0Init(0);
226 if (RT_SUCCESS(rc))
227 {
228 /*
229 * Initialize global mutex.
230 */
231 mutex_init(&g_VBoxUSBMonSolarisMtx, NULL, MUTEX_DRIVER, NULL);
232 rc = ddi_soft_state_init(&g_pVBoxUSBMonSolarisState, sizeof(vboxusbmon_state_t), 1);
233 if (!rc)
234 {
235 rc = mod_install(&g_VBoxUSBMonSolarisModLinkage);
236 if (!rc)
237 return rc;
238
239 LogRel((DEVICE_NAME ":mod_install failed! rc=%d\n", rc));
240 ddi_soft_state_fini(&g_pVBoxUSBMonSolarisState);
241 }
242 else
243 LogRel((DEVICE_NAME ":ddi_soft_state_init failed! rc=%d\n", rc));
244
245 mutex_destroy(&g_VBoxUSBMonSolarisMtx);
246 RTR0Term();
247 }
248 else
249 LogRel((DEVICE_NAME ":RTR0Init failed! rc=%d\n", rc));
250
251 return -1;
252}
253
254
255int _fini(void)
256{
257 int rc;
258
259 LogFlowFunc((DEVICE_NAME ":_fini\n"));
260
261 rc = mod_remove(&g_VBoxUSBMonSolarisModLinkage);
262 if (!rc)
263 {
264 ddi_soft_state_fini(&g_pVBoxUSBMonSolarisState);
265 mutex_destroy(&g_VBoxUSBMonSolarisMtx);
266
267 RTR0Term();
268 }
269 return rc;
270}
271
272
273int _info(struct modinfo *pModInfo)
274{
275 LogFlowFunc((DEVICE_NAME ":_info\n"));
276
277 return mod_info(&g_VBoxUSBMonSolarisModLinkage, pModInfo);
278}
279
280
281/**
282 * Attach entry point, to attach a device to the system or resume it.
283 *
284 * @param pDip The module structure instance.
285 * @param enmCmd Attach type (ddi_attach_cmd_t)
286 *
287 * @returns corresponding solaris error code.
288 */
289static int VBoxUSBMonSolarisAttach(dev_info_t *pDip, ddi_attach_cmd_t enmCmd)
290{
291 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisAttach pDip=%p enmCmd=%d\n", pDip, enmCmd));
292 switch (enmCmd)
293 {
294 case DDI_ATTACH:
295 {
296 vboxusbmon_state_t *pState = NULL;
297 int instance = ddi_get_instance(pDip);
298 int rc;
299
300 pState = RTMemAllocZ(sizeof(*pState));
301 if (pState)
302 {
303 g_pDip = pDip;
304 rc = ddi_create_priv_minor_node(pDip, DEVICE_NAME, S_IFCHR, instance, DDI_PSEUDO, 0,
305 "none", "none", 0666);
306 if (rc == DDI_SUCCESS)
307 {
308 ddi_set_driver_private(pDip, pState);
309 ddi_report_dev(pDip);
310 return rc;
311 }
312 else
313 LogRel((DEVICE_NAME ":ddi_create_minor_node failed! rc=%d\n", rc));
314 RTMemFree(pState);
315 }
316 else
317 LogRel((DEVICE_NAME ":RTMemAllocZ failed to allocated %d bytes for pState\n", sizeof(*pState)));
318 return DDI_FAILURE;
319 }
320
321 case DDI_RESUME:
322 {
323 /* We don't have to bother about power management. */
324 return DDI_SUCCESS;
325 }
326
327 default:
328 return DDI_FAILURE;
329 }
330}
331
332
333/**
334 * Detach entry point, to detach a device to the system or suspend it.
335 *
336 * @param pDip The module structure instance.
337 * @param enmCmd Attach type (ddi_attach_cmd_t)
338 *
339 * @returns corresponding solaris error code.
340 */
341static int VBoxUSBMonSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)
342{
343 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisDetach\n"));
344
345 switch (enmCmd)
346 {
347 case DDI_DETACH:
348 {
349#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
350 /*
351 * Free all registered clients' info.
352 */
353 mutex_enter(&g_VBoxUSBMonSolarisMtx);
354 vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
355 while (pCur)
356 {
357 vboxusbmon_client_t *pNext = pCur->pNext;
358 RTMemFree(pCur);
359 pCur = pNext;
360 }
361 mutex_exit(&g_VBoxUSBMonSolarisMtx);
362#endif
363
364 vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
365 if (pState)
366 {
367 ddi_remove_minor_node(pDip, NULL);
368 RTMemFree(pState);
369 return DDI_SUCCESS;
370 }
371 else
372 LogRel((DEVICE_NAME ":failed to get soft state on detach.\n"));
373 break;
374 }
375
376 case DDI_SUSPEND:
377 {
378 /* We don't have to bother about power management. */
379 return DDI_SUCCESS;
380 }
381
382 default:
383 return DDI_FAILURE;
384 }
385}
386
387
388/**
389 * Info entry point, called by solaris kernel for obtaining driver info.
390 *
391 * @param pDip The module structure instance (do not use).
392 * @param enmCmd Information request type.
393 * @param pvArg Type specific argument.
394 * @param ppvResult Where to store the requested info.
395 *
396 * @returns corresponding solaris error code.
397 */
398static int VBoxUSBMonSolarisGetInfo(dev_info_t *pDip, ddi_info_cmd_t enmCmd, void *pvArg, void **ppvResult)
399{
400 int rc = DDI_SUCCESS;
401
402 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisGetInfo\n"));
403
404 switch (enmCmd)
405 {
406 case DDI_INFO_DEVT2DEVINFO:
407 *ppvResult = (void *)g_pDip;
408 break;
409
410 case DDI_INFO_DEVT2INSTANCE:
411 *ppvResult = (void *)(uintptr_t)ddi_get_instance(g_pDip);
412 break;
413
414 default:
415 rc = DDI_FAILURE;
416 break;
417 }
418 return rc;
419}
420
421
422static int VBoxUSBMonSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)
423{
424 vboxusbmon_state_t *pState = NULL;
425 unsigned iOpenInstance;
426
427 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisOpen\n"));
428
429 /*
430 * Verify we are being opened as a character device
431 */
432 if (fType != OTYP_CHR)
433 return EINVAL;
434
435 /*
436 * Verify that we're called after attach
437 */
438 if (!g_pDip)
439 {
440 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisOpen invalid state for opening.\n"));
441 return ENXIO;
442 }
443
444#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
445 mutex_enter(&g_VBoxUSBMonSolarisMtx);
446 if (!g_cVBoxUSBMonSolarisClient)
447 {
448 mutex_exit(&g_VBoxUSBMonSolarisMtx);
449 int rc = usb_register_dev_driver(g_pDip, VBoxUSBMonSolarisElectDriver);
450 if (RT_UNLIKELY(rc != DDI_SUCCESS))
451 {
452 LogRel((DEVICE_NAME ":Failed to register driver election callback with USBA rc=%d\n", rc));
453 return EINVAL;
454 }
455 LogFlow((DEVICE_NAME ":Successfully registered election callback with USBA\n"));
456 mutex_enter(&g_VBoxUSBMonSolarisMtx);
457 }
458 g_cVBoxUSBMonSolarisClient++;
459 mutex_exit(&g_VBoxUSBMonSolarisMtx);
460#endif
461
462 for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)
463 {
464 if ( !ddi_get_soft_state(g_pVBoxUSBMonSolarisState, iOpenInstance) /* faster */
465 && ddi_soft_state_zalloc(g_pVBoxUSBMonSolarisState, iOpenInstance) == DDI_SUCCESS)
466 {
467 pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, iOpenInstance);
468 break;
469 }
470 }
471 if (!pState)
472 {
473 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisOpen: too many open instances."));
474#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
475 mutex_enter(&g_VBoxUSBMonSolarisMtx);
476 g_cVBoxUSBMonSolarisClient--;
477 mutex_exit(&g_VBoxUSBMonSolarisMtx);
478#endif
479 return ENXIO;
480 }
481
482 pState->Process = RTProcSelf();
483 *pDev = makedevice(getmajor(*pDev), iOpenInstance);
484
485 NOREF(fFlag);
486 NOREF(pCred);
487
488 return 0;
489}
490
491
492static int VBoxUSBMonSolarisClose(dev_t Dev, int fFlag, int fType, cred_t *pCred)
493{
494 vboxusbmon_state_t *pState = NULL;
495
496 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisClose\n"));
497
498 pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, getminor(Dev));
499 if (!pState)
500 {
501 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisClose: failed to get pState.\n"));
502 return EFAULT;
503 }
504
505#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
506 mutex_enter(&g_VBoxUSBMonSolarisMtx);
507 g_cVBoxUSBMonSolarisClient--;
508 if (!g_cVBoxUSBMonSolarisClient)
509 {
510 if (RT_LIKELY(g_pDip))
511 {
512 mutex_exit(&g_VBoxUSBMonSolarisMtx);
513 usb_unregister_dev_driver(g_pDip);
514 LogFlow((DEVICE_NAME ":Successfully deregistered driver election callback\n"));
515 }
516 else
517 {
518 mutex_exit(&g_VBoxUSBMonSolarisMtx);
519 LogRel((DEVICE_NAME ":Extreme error! Missing device info during close.\n"));
520 }
521 }
522 else
523 mutex_exit(&g_VBoxUSBMonSolarisMtx);
524#endif
525
526 /*
527 * Remove all filters for this client process.
528 */
529 VBoxUSBFilterRemoveOwner(pState->Process);
530
531 ddi_soft_state_free(g_pVBoxUSBMonSolarisState, getminor(Dev));
532 pState = NULL;
533
534 NOREF(fFlag);
535 NOREF(fType);
536 NOREF(pCred);
537
538 return 0;
539}
540
541
542static int VBoxUSBMonSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)
543{
544 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisRead\n"));
545 return 0;
546}
547
548
549static int VBoxUSBMonSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)
550{
551 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisWrite\n"));
552 return 0;
553}
554
555
556/** @def IOCPARM_LEN
557 * Gets the length from the ioctl number.
558 * This is normally defined by sys/ioccom.h on BSD systems...
559 */
560#ifndef IOCPARM_LEN
561# define IOCPARM_LEN(Code) (((Code) >> 16) & IOCPARM_MASK)
562#endif
563
564static int VBoxUSBMonSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cred_t *pCred, int *pVal)
565{
566 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl Dev=%d Cmd=%d pArg=%p Mode=%d\n", Dev, Cmd, pArg));
567
568 /*
569 * Get the session from the soft state item.
570 */
571 vboxusbmon_state_t *pState = ddi_get_soft_state(g_pVBoxUSBMonSolarisState, getminor(Dev));
572 if (!pState)
573 {
574 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: no state data for %d\n", getminor(Dev)));
575 return EINVAL;
576 }
577
578 /*
579 * Read the request wrapper. Though We don't really need wrapper struct. now
580 * it's room for the future as Solaris isn't generous regarding the size.
581 */
582 VBOXUSBREQ ReqWrap;
583 if (IOCPARM_LEN(Cmd) != sizeof(ReqWrap))
584 {
585 LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad request %#x size=%d expected=%d\n", Cmd, IOCPARM_LEN(Cmd), sizeof(ReqWrap)));
586 return ENOTTY;
587 }
588
589 int rc = ddi_copyin((void *)pArg, &ReqWrap, sizeof(ReqWrap), Mode);
590 if (RT_UNLIKELY(rc))
591 {
592 LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: ddi_copyin failed to read header pArg=%p Cmd=%d. rc=%d.\n", pArg, Cmd, rc));
593 return EINVAL;
594 }
595
596 if (ReqWrap.u32Magic != VBOXUSBMON_MAGIC)
597 {
598 LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad magic %#x; pArg=%p Cmd=%d.\n", ReqWrap.u32Magic, pArg, Cmd));
599 return EINVAL;
600 }
601 if (RT_UNLIKELY( ReqWrap.cbData == 0
602 || ReqWrap.cbData > _1M*16))
603 {
604 LogRel((DEVICE_NAME ": VBoxUSBMonSolarisIOCtl: bad size %#x; pArg=%p Cmd=%d.\n", ReqWrap.cbData, pArg, Cmd));
605 return EINVAL;
606 }
607
608 /*
609 * Read the request.
610 */
611 void *pvBuf = RTMemTmpAlloc(ReqWrap.cbData);
612 if (RT_UNLIKELY(!pvBuf))
613 {
614 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap.cbData));
615 return ENOMEM;
616 }
617
618 rc = ddi_copyin((void *)(uintptr_t)ReqWrap.pvDataR3, pvBuf, ReqWrap.cbData, Mode);
619 if (RT_UNLIKELY(rc))
620 {
621 RTMemTmpFree(pvBuf);
622 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyin failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
623 return EFAULT;
624 }
625 if (RT_UNLIKELY( ReqWrap.cbData != 0
626 && !VALID_PTR(pvBuf)))
627 {
628 RTMemTmpFree(pvBuf);
629 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pvBuf invalid pointer %p\n", pvBuf));
630 return EINVAL;
631 }
632 LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: pid=%d.\n", (int)RTProcSelf()));
633
634 /*
635 * Process the IOCtl.
636 */
637 size_t cbDataReturned;
638 rc = vboxUSBMonSolarisProcessIOCtl(Cmd, pState, pvBuf, ReqWrap.cbData, &cbDataReturned);
639 ReqWrap.rc = rc;
640 rc = 0;
641
642 if (RT_UNLIKELY(cbDataReturned > ReqWrap.cbData))
643 {
644 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap.cbData));
645 cbDataReturned = ReqWrap.cbData;
646 }
647
648 ReqWrap.cbData = cbDataReturned;
649
650 /*
651 * Copy the request back to user space.
652 */
653 rc = ddi_copyout(&ReqWrap, (void *)pArg, sizeof(ReqWrap), Mode);
654 if (RT_LIKELY(!rc))
655 {
656 /*
657 * Copy the payload (if any) back to user space.
658 */
659 if (cbDataReturned > 0)
660 {
661 rc = ddi_copyout(pvBuf, (void *)(uintptr_t)ReqWrap.pvDataR3, cbDataReturned, Mode);
662 if (RT_UNLIKELY(rc))
663 {
664 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout failed; pvBuf=%p pArg=%p Cmd=%d. rc=%d\n", pvBuf, pArg, Cmd, rc));
665 rc = EFAULT;
666 }
667 }
668 }
669 else
670 {
671 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisIOCtl: ddi_copyout(1) failed pArg=%p Cmd=%d\n", pArg, Cmd));
672 rc = EFAULT;
673 }
674
675 *pVal = rc;
676 RTMemTmpFree(pvBuf);
677 return rc;
678}
679
680
681/**
682 * IOCtl processor for user to kernel and kernel to kernel communcation.
683 *
684 * @returns VBox status code.
685 *
686 * @param iFunction The requested function.
687 * @param pvState Opaque pointer to driver state used for getting ring-3 process (Id).
688 * @param pvData The input/output data buffer. Can be NULL depending on the function.
689 * @param cbData The max size of the data buffer.
690 * @param pcbDataReturned Where to store the amount of returned data. Can be NULL.
691 */
692static int vboxUSBMonSolarisProcessIOCtl(int iFunction, void *pvState, void *pvData, size_t cbData, size_t *pcbReturnedData)
693{
694 LogFlowFunc((DEVICE_NAME ":solarisUSBProcessIOCtl iFunction=%d pvBuf=%p cbBuf=%zu\n", iFunction, pvData, cbData));
695
696 AssertPtrReturn(pvState, VERR_INVALID_POINTER);
697 vboxusbmon_state_t *pState = (vboxusbmon_state_t *)pvState;
698 int rc;
699
700#define CHECKRET_MIN_SIZE(mnemonic, cbMin) \
701 do { \
702 if (cbData < (cbMin)) \
703 { \
704 LogRel(("vboxUSBSolarisProcessIOCtl: " mnemonic ": cbData=%#zx (%zu) min is %#zx (%zu)\n", \
705 cbData, cbData, (size_t)(cbMin), (size_t)(cbMin))); \
706 return VERR_BUFFER_OVERFLOW; \
707 } \
708 if ((cbMin) != 0 && !VALID_PTR(pvData)) \
709 { \
710 LogRel(("vboxUSBSolarisProcessIOCtl: " mnemonic ": Invalid pointer %p\n", pvData)); \
711 return VERR_INVALID_POINTER; \
712 } \
713 } while (0)
714
715 switch (iFunction)
716 {
717 case VBOXUSBMON_IOCTL_ADD_FILTER:
718 {
719 CHECKRET_MIN_SIZE("ADD_FILTER", sizeof(VBOXUSBREQ_ADD_FILTER));
720
721 VBOXUSBREQ_ADD_FILTER *pReq = (VBOXUSBREQ_ADD_FILTER *)pvData;
722 PUSBFILTER pFilter = (PUSBFILTER)&pReq->Filter;
723
724 LogFlow(("vboxUSBMonSolarisProcessIOCtl: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x\n",
725 USBFilterGetNum(pFilter, USBFILTERIDX_VENDOR_ID),
726 USBFilterGetNum(pFilter, USBFILTERIDX_PRODUCT_ID),
727 USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_REV),
728 USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_CLASS),
729 USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_SUB_CLASS),
730 USBFilterGetNum(pFilter, USBFILTERIDX_DEVICE_PROTOCOL),
731 USBFilterGetNum(pFilter, USBFILTERIDX_BUS),
732 USBFilterGetNum(pFilter, USBFILTERIDX_PORT)));
733 LogFlow(("vboxUSBMonSolarisProcessIOCtl: Manufacturer=%s Product=%s Serial=%s\n",
734 USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_MANUFACTURER_STR) : "<null>",
735 USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_PRODUCT_STR) : "<null>",
736 USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(pFilter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>"));
737
738 rc = USBFilterSetMustBePresent(pFilter, USBFILTERIDX_BUS, false /* fMustBePresent */); AssertRC(rc);
739
740 rc = VBoxUSBFilterAdd(pFilter, pState->Process, &pReq->uId);
741 *pcbReturnedData = cbData;
742 LogFlow((DEVICE_NAME ":vboxUSBMonSolarisProcessIOCtl: ADD_FILTER (Process:%d) returned %d\n", pState->Process, rc));
743 break;
744 }
745
746 case VBOXUSBMON_IOCTL_REMOVE_FILTER:
747 {
748 CHECKRET_MIN_SIZE("REMOVE_FILTER", sizeof(VBOXUSBREQ_REMOVE_FILTER));
749
750 VBOXUSBREQ_REMOVE_FILTER *pReq = (VBOXUSBREQ_REMOVE_FILTER *)pvData;
751 rc = VBoxUSBFilterRemove(pState->Process, (uintptr_t)pReq->uId);
752 *pcbReturnedData = 0;
753 LogFlow((DEVICE_NAME ":vboxUSBMonSolarisProcessIOCtl: REMOVE_FILTER (Process:%d) returned %d\n", pState->Process, rc));
754 break;
755 }
756
757 case VBOXUSBMON_IOCTL_RESET_DEVICE:
758 {
759 CHECKRET_MIN_SIZE("RESET_DEVICE", sizeof(VBOXUSBREQ_RESET_DEVICE));
760
761 VBOXUSBREQ_RESET_DEVICE *pReq = (VBOXUSBREQ_RESET_DEVICE *)pvData;
762 rc = vboxUSBMonSolarisResetDevice(pReq->szDevicePath, pReq->fReattach);
763 *pcbReturnedData = 0;
764 LogFlow((DEVICE_NAME ":vboxUSBMonSolarisProcessIOCtl: RESET_DEVICE (Process:%d) returned %d\n", pState->Process, rc));
765 break;
766 }
767
768#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
769 case VBOXUSBMON_IOCTL_CLIENT_INFO:
770 {
771 CHECKRET_MIN_SIZE("CLIENT_INFO", sizeof(VBOXUSBREQ_CLIENT_INFO));
772
773 VBOXUSBREQ_CLIENT_INFO *pReq = (VBOXUSBREQ_CLIENT_INFO *)pvData;
774 rc = vboxUSBMonSolarisClientInfo(pState, pReq);
775 *pcbReturnedData = cbData;
776 LogFlow((DEVICE_NAME ":vboxUSBMonSolarisProcessIOCtl: CLIENT_INFO (Process:%d) returned %d\n", pState->Process, rc));
777 break;
778 }
779#else
780 case VBOXUSBMON_IOCTL_DEVICE_INSTANCE:
781 {
782 CHECKRET_MIN_SIZE("DEVICE_INSTANCE", sizeof(VBOXUSBREQ_DEVICE_INSTANCE));
783
784 VBOXUSBREQ_DEVICE_INSTANCE *pReq = (VBOXUSBREQ_DEVICE_INSTANCE *)pvData;
785 rc = vboxUSBMonSolarisGetDeviceInstance(pReq->szDevicePath, (int32_t *)pReq->pInstance);
786 *pcbReturnedData = cbData;
787 LogFlow((DEVICE_NAME ":vboxUSBMonSolarisProcessIOCtl: DEVICE_INSTANCE returned %d\n", rc));
788 break;
789 }
790#endif
791
792 case VBOXUSBMON_IOCTL_GET_VERSION:
793 {
794 CHECKRET_MIN_SIZE("GET_VERSION", sizeof(VBOXUSBREQ_GET_VERSION));
795
796 PVBOXUSBREQ_GET_VERSION pGetVersionReq = (PVBOXUSBREQ_GET_VERSION)pvData;
797 pGetVersionReq->u32Major = VBOXUSBMON_VERSION_MAJOR;
798 pGetVersionReq->u32Minor = VBOXUSBMON_VERSION_MINOR;
799 *pcbReturnedData = sizeof(VBOXUSBREQ_GET_VERSION);
800 rc = VINF_SUCCESS;
801 LogFlow((DEVICE_NAME ":vboxUSBMonSolarisProcessIOCtl: GET_VERSION returned %d\n", rc));
802 break;
803 }
804
805 default:
806 {
807 LogRel((DEVICE_NAME ":vboxUSBMonSolarisProcessIOCtl: Unknown request (Process:%d) %#x\n", pState->Process, iFunction));
808 rc = VERR_NOT_SUPPORTED;
809 break;
810 }
811 }
812 return rc;
813}
814
815
816static int vboxUSBMonSolarisResetDevice(char *pszDevicePath, bool fReattach)
817{
818 int rc = VERR_GENERAL_FAILURE;
819
820 LogFlowFunc((DEVICE_NAME ":vboxUSBMonSolarisResetDevice pszDevicePath=%s fReattach=%d\n", pszDevicePath, fReattach));
821
822#ifdef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
823 /*
824 * Try grabbing the dev_info_t.
825 */
826 dev_info_t *pDeviceInfo = e_ddi_hold_devi_by_path(pszDevicePath, 0);
827 if (pDeviceInfo)
828 {
829 ddi_release_devi(pDeviceInfo);
830
831 /*
832 * Grab the root device node from the parent hub for resetting.
833 */
834 dev_info_t *pTmpDeviceInfo = NULL;
835 for (;;)
836 {
837 pTmpDeviceInfo = ddi_get_parent(pDeviceInfo);
838 if (!pTmpDeviceInfo)
839 {
840 LogRel((DEVICE_NAME ":vboxUSBMonSolarisResetDevice failed to get parent device info for %s\n", pszDevicePath));
841 return VERR_GENERAL_FAILURE;
842 }
843
844 if (ddi_prop_exists(DDI_DEV_T_ANY, pTmpDeviceInfo, DDI_PROP_DONTPASS, "usb-port-count")) /* parent hub */
845 break;
846
847 pDeviceInfo = pTmpDeviceInfo;
848 }
849
850 /*
851 * Try re-enumerating the device.
852 */
853 rc = usb_reset_device(pDeviceInfo, fReattach ? USB_RESET_LVL_REATTACH : USB_RESET_LVL_DEFAULT);
854 LogFlow((DEVICE_NAME ":usb_reset_device for %s level=%s returned %d\n", pszDevicePath, fReattach ? "ReAttach" : "Default", rc));
855 switch (rc)
856 {
857 case USB_SUCCESS: rc = VINF_SUCCESS; break;
858 case USB_INVALID_PERM: rc = VERR_PERMISSION_DENIED; break;
859 case USB_INVALID_ARGS: rc = VERR_INVALID_PARAMETER; break;
860
861 /* @todo find better codes for these (especially USB_BUSY) */
862 case USB_BUSY:
863 case USB_INVALID_CONTEXT:
864 case USB_FAILURE: rc = VERR_GENERAL_FAILURE; break;
865
866 default: rc = VERR_UNRESOLVED_ERROR; break;
867 }
868 }
869 else
870 {
871 rc = VERR_INVALID_HANDLE;
872 LogRel((DEVICE_NAME ":vboxUSBMonSolarisResetDevice Cannot obtain device info for %s\n", pszDevicePath));
873 }
874
875#else
876 /*
877 * Try grabbing the dev_info_t.
878 */
879 dev_info_t *pDeviceInfo = e_ddi_hold_devi_by_path(pszDevicePath, 0);
880 if (pDeviceInfo)
881 {
882 /*
883 * Try re-enumerating the device.
884 */
885 rc = usb_reset_device(pDeviceInfo, fReattach ? USB_RESET_LVL_REATTACH : USB_RESET_LVL_DEFAULT);
886 LogFlow((DEVICE_NAME ":usb_reset_device for %s level=%s returned %d\n", pszDevicePath, fReattach ? "ReAttach" : "Default", rc));
887
888 ddi_release_devi(pDeviceInfo);
889 switch (rc)
890 {
891 case USB_SUCCESS: rc = VINF_SUCCESS; break;
892 case USB_INVALID_PERM: rc = VERR_PERMISSION_DENIED; break;
893 case USB_INVALID_ARGS: rc = VERR_INVALID_PARAMETER; break;
894
895 /* @todo find better codes for these (especially USB_BUSY) */
896 case USB_BUSY:
897 case USB_INVALID_CONTEXT:
898 case USB_FAILURE: rc = VERR_GENERAL_FAILURE; break;
899
900 default: rc = VERR_UNRESOLVED_ERROR; break;
901 }
902 }
903 else
904 {
905 rc = VERR_INVALID_HANDLE;
906 LogRel(("vboxUSBMonSolarisResetDevice: Cannot obtain dev_info_t for Device %s\n", pszDevicePath));
907 }
908#endif
909
910 return rc;
911}
912
913#ifndef VBOX_WITH_NEW_USB_CODE_ON_SOLARIS
914
915static int vboxUSBMonSolarisGetDeviceInstance(char *pszDevicePath, int32_t *pInstance)
916{
917 LogFlowFunc((DEVICE_NAME ":vboxUSBMonSolarisGetDeviceInstance pszDevicePath=%s pInstance=%p\n", pszDevicePath, pInstance));
918
919 AssertPtrReturn(pInstance, VERR_INVALID_POINTER);
920
921 /*
922 * Try grabbing the dev_info_t.
923 */
924 dev_info_t *pDeviceInfo = e_ddi_hold_devi_by_path(pszDevicePath, 0);
925 if (pDeviceInfo)
926 {
927 /*
928 * Get device instance.
929 */
930 *pInstance = ddi_get_instance(pDeviceInfo);
931 ddi_release_devi(pDeviceInfo);
932 LogFlow(("vboxUSBMonSolarisGetDeviceInstance: instance %d\n", *pInstance));
933 return VINF_SUCCESS;
934 }
935 else
936 LogRel(("vboxUSBMonSolarisGetDeviceInstance: Cannot obtain dev_info_t for Device %s\n", pszDevicePath));
937 return VERR_INVALID_HANDLE;
938}
939
940#else /* VBOX_WITH_NEW_USB_CODE_ON_SOLARIS */
941
942static int vboxUSBMonSolarisClientInfo(vboxusbmon_state_t *pState, PVBOXUSB_CLIENT_INFO pClientInfo)
943{
944 LogFlowFunc((DEVICE_NAME ":vboxUSBMonSolarisClientInfo pState=%p pClientInfo=%p\n", pState, pClientInfo));
945
946 AssertPtrReturn(pState, VERR_INVALID_POINTER);
947 AssertPtrReturn(pClientInfo, VERR_INVALID_POINTER);
948
949 mutex_enter(&g_VBoxUSBMonSolarisMtx);
950 vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
951 vboxusbmon_client_t *pPrev = NULL;
952 while (pCur)
953 {
954 if (strncmp(pClientInfo->achDeviceIdent, pCur->Info.achDeviceIdent, sizeof(pCur->Info.achDeviceIdent) - 1) == 0)
955 {
956 pClientInfo->Instance = pCur->Info.Instance;
957 RTStrPrintf(pClientInfo->achClientPath, sizeof(pClientInfo->achClientPath), "%s", pCur->Info.achClientPath);
958
959 mutex_exit(&g_VBoxUSBMonSolarisMtx);
960
961 LogFlow((DEVICE_NAME ":vboxUSBMonSolarisClientInfo found. %s\n", pClientInfo->achDeviceIdent));
962 return VINF_SUCCESS;
963 }
964 pPrev = pCur;
965 pCur = pCur->pNext;
966 }
967
968 mutex_exit(&g_VBoxUSBMonSolarisMtx);
969
970 LogRel((DEVICE_NAME ":vboxUSBMonSolarisClientInfo Failed to find client %s\n", pClientInfo->achDeviceIdent));
971 return VERR_NOT_FOUND;
972}
973
974
975/**
976 * Registers client driver.
977 *
978 * @returns VBox status code.
979 * @param pszDevicePath The device path of the client driver.
980 * @param Instance The client driver instance.
981 */
982int VBoxUSBMonSolarisRegisterClient(dev_info_t *pClientDip, PVBOXUSB_CLIENT_INFO pClientInfo)
983{
984 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient pClientDip=%p pClientInfo=%p\n", pClientDip, pClientInfo));
985 AssertPtrReturn(pClientInfo, VERR_INVALID_PARAMETER);
986
987 if (RT_LIKELY(g_pDip))
988 {
989 vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
990
991 if (RT_LIKELY(pState))
992 {
993 vboxusbmon_client_t *pClient = RTMemAlloc(sizeof(vboxusbmon_client_t));
994 if (RT_LIKELY(pClient))
995 {
996 bcopy(pClientInfo, &pClient->Info, sizeof(pClient->Info));
997 pClient->pDip = pClientDip;
998
999 mutex_enter(&g_VBoxUSBMonSolarisMtx);
1000 pClient->pNext = g_pVBoxUSBMonSolarisClients;
1001 g_pVBoxUSBMonSolarisClients = pClient;
1002 mutex_exit(&g_VBoxUSBMonSolarisMtx);
1003
1004 LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisRegisterClient registered. %d %s %s\n",
1005 pClient->Info.Instance, pClient->Info.achClientPath, pClient->Info.achDeviceIdent));
1006
1007 return VINF_SUCCESS;
1008 }
1009 else
1010 return VERR_NO_MEMORY;
1011 }
1012 else
1013 return VERR_INTERNAL_ERROR;
1014 }
1015 else
1016 return VERR_INTERNAL_ERROR_2;
1017}
1018
1019
1020/**
1021 * Deregisters client driver.
1022 *
1023 * @returns VBox status code.
1024 * @param pszDevicePath The device path of the client driver.
1025 * @param Instance The client driver instance.
1026 */
1027int VBoxUSBMonSolarisUnregisterClient(dev_info_t *pClientDip)
1028{
1029 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient pClientDip=%p\n", pClientDip));
1030
1031 if (RT_LIKELY(g_pDip))
1032 {
1033 vboxusbmon_state_t *pState = ddi_get_driver_private(g_pDip);
1034
1035 if (RT_LIKELY(pState))
1036 {
1037 mutex_enter(&g_VBoxUSBMonSolarisMtx);
1038
1039 vboxusbmon_client_t *pCur = g_pVBoxUSBMonSolarisClients;
1040 vboxusbmon_client_t *pPrev = NULL;
1041 while (pCur)
1042 {
1043 if (pCur->pDip == pClientDip)
1044 {
1045 if (pPrev)
1046 pPrev->pNext = pCur->pNext;
1047 else
1048 g_pVBoxUSBMonSolarisClients = pCur->pNext;
1049
1050 mutex_exit(&g_VBoxUSBMonSolarisMtx);
1051
1052 LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient unregistered. %d %s %s\n",
1053 pCur->Info.Instance, pCur->Info.achClientPath, pCur->Info.achDeviceIdent));
1054 RTMemFree(pCur);
1055 pCur = NULL;
1056 return VINF_SUCCESS;
1057 }
1058 pPrev = pCur;
1059 pCur = pCur->pNext;
1060 }
1061
1062 mutex_exit(&g_VBoxUSBMonSolarisMtx);
1063
1064 LogRel((DEVICE_NAME ":VBoxUSBMonSolarisUnregisterClient Failed to find registered client %p\n", pClientDip));
1065 return VERR_SEARCH_ERROR;
1066 }
1067 else
1068 return VERR_INTERNAL_ERROR;
1069 }
1070 else
1071 return VERR_INTERNAL_ERROR_2;
1072}
1073
1074
1075/**
1076 * USBA driver election callback.
1077 *
1078 * @returns USB_SUCCESS if we want to capture the device, USB_FAILURE otherwise.
1079 * @param pDevDesc The parsed device descriptor (does not include subconfigs).
1080 * @param pDevStrings Device strings: Manufacturer, Product, Serial Number.
1081 * @param pszDevicePath The physical path of the device being attached.
1082 * @param Bus The Bus number on which the device is on.
1083 * @param Port The Port number on the bus.
1084 * @param ppszDrv The name of the driver we wish to capture the device with.
1085 * @param pvReserved Reserved for future use.
1086 */
1087int VBoxUSBMonSolarisElectDriver(usb_dev_descr_t *pDevDesc, usb_dev_str_t *pDevStrings, char *pszDevicePath, int Bus, int Port,
1088 char **ppszDrv, void *pvReserved)
1089{
1090 LogFlowFunc((DEVICE_NAME ":VBoxUSBMonSolarisElectDriver pDevDesc=%p pDevStrings=%p pszDevicePath=%s Bus=%d Port=%d\n", pDevDesc,
1091 pDevStrings, pszDevicePath, Bus, Port));
1092
1093 AssertPtrReturn(pDevDesc, USB_FAILURE);
1094 AssertPtrReturn(pDevStrings, USB_FAILURE);
1095
1096 /*
1097 * Create a filter from the device being attached.
1098 */
1099 USBFILTER Filter;
1100 USBFilterInit(&Filter, USBFILTERTYPE_CAPTURE);
1101 USBFilterSetNumExact(&Filter, USBFILTERIDX_VENDOR_ID, pDevDesc->idVendor, true);
1102 USBFilterSetNumExact(&Filter, USBFILTERIDX_PRODUCT_ID, pDevDesc->idProduct, true);
1103 USBFilterSetNumExact(&Filter, USBFILTERIDX_DEVICE_REV, pDevDesc->bcdDevice, true);
1104 USBFilterSetNumExact(&Filter, USBFILTERIDX_DEVICE_CLASS, pDevDesc->bDeviceClass, true);
1105 USBFilterSetNumExact(&Filter, USBFILTERIDX_DEVICE_SUB_CLASS, pDevDesc->bDeviceSubClass, true);
1106 USBFilterSetNumExact(&Filter, USBFILTERIDX_DEVICE_PROTOCOL, pDevDesc->bDeviceProtocol, true);
1107 USBFilterSetNumExact(&Filter, USBFILTERIDX_BUS, 0x0 /* Bus */, true); /* Use 0x0 as userland initFilterFromDevice function in Main: see comment on "SetMustBePresent" below */
1108 USBFilterSetNumExact(&Filter, USBFILTERIDX_PORT, Port, true);
1109 USBFilterSetStringExact(&Filter, USBFILTERIDX_MANUFACTURER_STR, pDevStrings->usb_mfg, true);
1110 USBFilterSetStringExact(&Filter, USBFILTERIDX_PRODUCT_STR, pDevStrings->usb_product, true);
1111 USBFilterSetStringExact(&Filter, USBFILTERIDX_SERIAL_NUMBER_STR, pDevStrings->usb_serialno, true);
1112
1113 /* This doesn't work like it should (USBFilterMatch fails on matching field (6) i.e. Bus despite this. Investigate later. */
1114 USBFilterSetMustBePresent(&Filter, USBFILTERIDX_BUS, false /* fMustBePresent */);
1115
1116 LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisElectDriver: idVendor=%#x idProduct=%#x bcdDevice=%#x bDeviceClass=%#x bDeviceSubClass=%#x bDeviceProtocol=%#x bBus=%#x bPort=%#x\n",
1117 USBFilterGetNum(&Filter, USBFILTERIDX_VENDOR_ID),
1118 USBFilterGetNum(&Filter, USBFILTERIDX_PRODUCT_ID),
1119 USBFilterGetNum(&Filter, USBFILTERIDX_DEVICE_REV),
1120 USBFilterGetNum(&Filter, USBFILTERIDX_DEVICE_CLASS),
1121 USBFilterGetNum(&Filter, USBFILTERIDX_DEVICE_SUB_CLASS),
1122 USBFilterGetNum(&Filter, USBFILTERIDX_DEVICE_PROTOCOL),
1123 USBFilterGetNum(&Filter, USBFILTERIDX_BUS),
1124 USBFilterGetNum(&Filter, USBFILTERIDX_PORT)));
1125 LogFlow((DEVICE_NAME ":VBoxUSBMonSolarisElectDriver: Manufacturer=%s Product=%s Serial=%s\n",
1126 USBFilterGetString(&Filter, USBFILTERIDX_MANUFACTURER_STR) ? USBFilterGetString(&Filter, USBFILTERIDX_MANUFACTURER_STR) : "<null>",
1127 USBFilterGetString(&Filter, USBFILTERIDX_PRODUCT_STR) ? USBFilterGetString(&Filter, USBFILTERIDX_PRODUCT_STR) : "<null>",
1128 USBFilterGetString(&Filter, USBFILTERIDX_SERIAL_NUMBER_STR) ? USBFilterGetString(&Filter, USBFILTERIDX_SERIAL_NUMBER_STR) : "<null>"));
1129
1130 /*
1131 * Run through user filters and try to see if it has a match.
1132 */
1133 uintptr_t uId = 0;
1134 RTPROCESS Owner = VBoxUSBFilterMatch(&Filter, &uId);
1135 USBFilterDelete(&Filter);
1136 if (Owner == NIL_RTPROCESS)
1137 {
1138 LogFlow((DEVICE_NAME ":No matching filters, device %#x:%#x uninteresting.\n", pDevDesc->idVendor, pDevDesc->idProduct));
1139 return USB_FAILURE;
1140 }
1141
1142 *ppszDrv = ddi_strdup(VBOXUSB_DRIVER_NAME, KM_SLEEP);
1143 LogRel((DEVICE_NAME ": Capturing %s %#x:%#x:%s\n", pDevStrings->usb_product ? pDevStrings->usb_product : "<Unnamed USB device>",
1144 pDevDesc->idVendor, pDevDesc->idProduct, pszDevicePath));
1145 return USB_SUCCESS;
1146}
1147
1148#endif
1149
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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