VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxUSB/solaris/USBLib-solaris.cpp@ 68033

Last change on this file since 68033 was 62490, checked in by vboxsync, 8 years ago

(C) 2016

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/** $Id: USBLib-solaris.cpp 62490 2016-07-22 18:41:49Z vboxsync $ */
2/** @file
3 * USBLib - Library for wrapping up the VBoxUSB functionality, Solaris flavor.
4 */
5
6/*
7 * Copyright (C) 2008-2016 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 <VBox/usblib.h>
23#include <VBox/err.h>
24#include <VBox/log.h>
25#include <iprt/assert.h>
26#include <iprt/asm.h>
27#include <iprt/file.h>
28#include <iprt/mem.h>
29#include <iprt/process.h>
30#include <iprt/env.h>
31#include <iprt/path.h>
32#include <iprt/string.h>
33
34# include <sys/types.h>
35# include <sys/stat.h>
36# include <errno.h>
37# include <unistd.h>
38# include <string.h>
39# include <limits.h>
40# include <strings.h>
41
42
43/*********************************************************************************************************************************
44* Defined Constants And Macros *
45*********************************************************************************************************************************/
46/** Logging class. */
47#define USBLIBR3 "USBLibR3"
48
49
50/*********************************************************************************************************************************
51* Global Variables *
52*********************************************************************************************************************************/
53/** Reference counter. */
54static uint32_t volatile g_cUsers = 0;
55/** VBoxUSB Device handle. */
56static RTFILE g_hFile = NIL_RTFILE;
57
58
59/*********************************************************************************************************************************
60* Internal Functions *
61*********************************************************************************************************************************/
62static int usblibDoIOCtl(unsigned iFunction, void *pvData, size_t cbData);
63
64
65USBLIB_DECL(int) USBLibInit(void)
66{
67 LogFlow((USBLIBR3 ":USBLibInit\n"));
68
69 /*
70 * Already open?
71 * This isn't properly serialized, but we'll be fine with the current usage.
72 */
73 if (g_cUsers)
74 {
75 ASMAtomicIncU32(&g_cUsers);
76 return VINF_SUCCESS;
77 }
78
79 RTFILE File;
80 int rc = RTFileOpen(&File, VBOXUSB_DEVICE_NAME, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
81 if (RT_FAILURE(rc))
82 {
83 LogRel((USBLIBR3 ":failed to open the VBoxUSB monitor device node '%s' rc=%Rrc\n", VBOXUSB_DEVICE_NAME, rc));
84 return rc;
85 }
86 g_hFile = File;
87
88 ASMAtomicIncU32(&g_cUsers);
89 /*
90 * Check the USBMonitor version.
91 */
92 VBOXUSBREQ_GET_VERSION Req;
93 bzero(&Req, sizeof(Req));
94 rc = usblibDoIOCtl(VBOXUSBMON_IOCTL_GET_VERSION, &Req, sizeof(Req));
95 if (RT_SUCCESS(rc))
96 {
97 if ( Req.u32Major != VBOXUSBMON_VERSION_MAJOR
98 || Req.u32Minor < VBOXUSBMON_VERSION_MINOR)
99 {
100 rc = VERR_VERSION_MISMATCH;
101 LogRel((USBLIBR3 ":USBMonitor version mismatch! driver v%d.%d, expecting ~v%d.%d\n",
102 Req.u32Major, Req.u32Minor, VBOXUSBMON_VERSION_MAJOR, VBOXUSBMON_VERSION_MINOR));
103
104 RTFileClose(File);
105 g_hFile = NIL_RTFILE;
106 ASMAtomicDecU32(&g_cUsers);
107 return rc;
108 }
109 }
110 else
111 {
112 LogRel((USBLIBR3 ":USBMonitor driver version query failed. rc=%Rrc\n", rc));
113 RTFileClose(File);
114 g_hFile = NIL_RTFILE;
115 ASMAtomicDecU32(&g_cUsers);
116 return rc;
117 }
118
119 return VINF_SUCCESS;
120}
121
122
123USBLIB_DECL(int) USBLibTerm(void)
124{
125 LogFlow((USBLIBR3 ":USBLibTerm\n"));
126
127 if (!g_cUsers)
128 return VERR_WRONG_ORDER;
129 if (ASMAtomicDecU32(&g_cUsers) != 0)
130 return VINF_SUCCESS;
131
132 /*
133 * We're the last guy, close down the connection.
134 */
135 RTFILE File = g_hFile;
136 g_hFile = NIL_RTFILE;
137 if (File == NIL_RTFILE)
138 return VERR_INTERNAL_ERROR;
139
140 int rc = RTFileClose(File);
141 AssertRC(rc);
142 return rc;
143}
144
145
146USBLIB_DECL(void *) USBLibAddFilter(PCUSBFILTER pFilter)
147{
148 LogFlow((USBLIBR3 ":USBLibAddFilter pFilter=%p\n", pFilter));
149
150 VBOXUSBREQ_ADD_FILTER Req;
151 Req.Filter = *pFilter;
152 Req.uId = 0;
153
154 int rc = usblibDoIOCtl(VBOXUSBMON_IOCTL_ADD_FILTER, &Req, sizeof(Req));
155 if (RT_SUCCESS(rc))
156 return (void *)Req.uId;
157
158 AssertMsgFailed((USBLIBR3 ":VBOXUSBMON_IOCTL_ADD_FILTER failed! rc=%Rrc\n", rc));
159 return NULL;
160}
161
162
163USBLIB_DECL(void) USBLibRemoveFilter(void *pvId)
164{
165 LogFlow((USBLIBR3 ":USBLibRemoveFilter pvId=%p\n", pvId));
166
167 VBOXUSBREQ_REMOVE_FILTER Req;
168 Req.uId = (uintptr_t)pvId;
169
170 int rc = usblibDoIOCtl(VBOXUSBMON_IOCTL_REMOVE_FILTER, &Req, sizeof(Req));
171 if (RT_SUCCESS(rc))
172 return;
173
174 AssertMsgFailed((USBLIBR3 ":VBOXUSBMON_IOCTL_REMOVE_FILTER failed! rc=%Rrc\n", rc));
175}
176
177
178USBLIB_DECL(int) USBLibGetClientInfo(char *pszDeviceIdent, char **ppszClientPath, int *pInstance)
179{
180 LogFlow((USBLIBR3 ":USBLibGetClientInfo pszDeviceIdent=%s ppszClientPath=%p pInstance=%p\n",
181 pszDeviceIdent, ppszClientPath, pInstance));
182
183 AssertPtrReturn(pInstance, VERR_INVALID_PARAMETER);
184 AssertPtrReturn(ppszClientPath, VERR_INVALID_PARAMETER);
185 AssertPtrReturn(pszDeviceIdent, VERR_INVALID_PARAMETER);
186
187 VBOXUSBREQ_CLIENT_INFO Req;
188 bzero(&Req, sizeof(Req));
189 RTStrPrintf(Req.szDeviceIdent, sizeof(Req.szDeviceIdent), "%s", pszDeviceIdent);
190
191 int rc = usblibDoIOCtl(VBOXUSBMON_IOCTL_CLIENT_INFO, &Req, sizeof(Req));
192 if (RT_SUCCESS(rc))
193 {
194 *pInstance = Req.Instance;
195 rc = RTStrDupEx(ppszClientPath, Req.szClientPath);
196 if (RT_SUCCESS(rc))
197 return VINF_SUCCESS;
198
199 LogRel((USBLIBR3 ":USBLibGetClientInfo RTStrDupEx failed! rc=%Rrc szClientPath=%s\n", rc, Req.szClientPath));
200 }
201 else
202 LogRel((USBLIBR3 ":USBLibGetClientInfo VBOXUSBMON_IOCTL_CLIENTPATH failed! rc=%Rrc\n", rc));
203
204 return rc;
205}
206
207
208USBLIB_DECL(int) USBLibResetDevice(char *pszDevicePath, bool fReattach)
209{
210 LogFlow((USBLIBR3 ":USBLibResetDevice pszDevicePath=%s\n", pszDevicePath));
211
212 size_t cbPath = strlen(pszDevicePath) + 1;
213 size_t cbReq = sizeof(VBOXUSBREQ_RESET_DEVICE) + cbPath;
214 VBOXUSBREQ_RESET_DEVICE *pReq = (VBOXUSBREQ_RESET_DEVICE *)RTMemTmpAllocZ(cbReq);
215 if (RT_UNLIKELY(!pReq))
216 return VERR_NO_MEMORY;
217
218 pReq->fReattach = fReattach;
219 if (strlcpy(pReq->szDevicePath, pszDevicePath, cbPath) >= cbPath)
220 {
221 LogRel((USBLIBR3 ":USBLibResetDevice buffer overflow. cbPath=%u pszDevicePath=%s\n", cbPath, pszDevicePath));
222 return VERR_BUFFER_OVERFLOW;
223 }
224
225 int rc = usblibDoIOCtl(VBOXUSBMON_IOCTL_RESET_DEVICE, pReq, cbReq);
226 if (RT_FAILURE(rc))
227 LogRel((USBLIBR3 ":VBOXUSBMON_IOCTL_RESET_DEVICE failed! rc=%Rrc\n", rc));
228
229 RTMemFree(pReq);
230 return rc;
231}
232
233
234static int usblibDoIOCtl(unsigned iFunction, void *pvData, size_t cbData)
235{
236 if (g_hFile == NIL_RTFILE)
237 {
238 LogRel((USBLIBR3 ":IOCtl failed, device not open.\n"));
239 return VERR_FILE_NOT_FOUND;
240 }
241
242 VBOXUSBREQ Hdr;
243 Hdr.u32Magic = VBOXUSBMON_MAGIC;
244 Hdr.cbData = cbData; /* Don't include full size because the header size is fixed. */
245 Hdr.pvDataR3 = pvData;
246
247 int rc = ioctl(RTFileToNative(g_hFile), iFunction, &Hdr);
248 if (rc < 0)
249 {
250 rc = errno;
251 LogRel((USBLIBR3 ":IOCtl failed iFunction=%x errno=%d g_file=%d\n", iFunction, rc, RTFileToNative(g_hFile)));
252 return RTErrConvertFromErrno(rc);
253 }
254
255 rc = Hdr.rc;
256 if (RT_UNLIKELY(RT_FAILURE(rc)))
257 LogRel((USBLIBR3 ":Function (%x) failed. rc=%Rrc\n", iFunction, rc));
258
259 return rc;
260}
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