VirtualBox

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

Last change on this file since 69500 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

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