VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedFolders/shflhandle.cpp@ 74946

Last change on this file since 74946 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: 5.6 KB
Line 
1/** @file
2 *
3 * Shared Folders:
4 * Handles helper functions.
5 */
6
7/*
8 * Copyright (C) 2006-2017 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "shflhandle.h"
20#include <iprt/alloc.h>
21#include <iprt/assert.h>
22#include <iprt/critsect.h>
23
24
25/*
26 * Very basic and primitive handle management. Should be sufficient for our needs.
27 * Handle allocation can be rather slow, but at least lookup is fast.
28 *
29 */
30typedef struct
31{
32 uint32_t uFlags;
33 uintptr_t pvUserData;
34 PSHFLCLIENTDATA pClient;
35} SHFLINTHANDLE, *PSHFLINTHANDLE;
36
37static SHFLINTHANDLE *g_pHandles = NULL;
38static int32_t gLastHandleIndex = 0;
39static RTCRITSECT gLock;
40
41int vbsfInitHandleTable()
42{
43 g_pHandles = (SHFLINTHANDLE *)RTMemAllocZ (sizeof (SHFLINTHANDLE) * SHFLHANDLE_MAX);
44 if (!g_pHandles)
45 {
46 AssertFailed();
47 return VERR_NO_MEMORY;
48 }
49
50 /* Never return handle 0 */
51 g_pHandles[0].uFlags = SHFL_HF_TYPE_DONTUSE;
52 gLastHandleIndex = 1;
53
54 return RTCritSectInit(&gLock);
55}
56
57int vbsfFreeHandleTable()
58{
59 if (g_pHandles)
60 RTMemFree(g_pHandles);
61
62 g_pHandles = NULL;
63
64 if (RTCritSectIsInitialized(&gLock))
65 RTCritSectDelete(&gLock);
66
67 return VINF_SUCCESS;
68}
69
70SHFLHANDLE vbsfAllocHandle(PSHFLCLIENTDATA pClient, uint32_t uType,
71 uintptr_t pvUserData)
72{
73 SHFLHANDLE handle;
74
75 Assert((uType & SHFL_HF_TYPE_MASK) != 0 && pvUserData);
76
77 RTCritSectEnter(&gLock);
78
79 /* Find next free handle */
80 if (gLastHandleIndex >= SHFLHANDLE_MAX-1)
81 gLastHandleIndex = 1;
82
83 /* Nice linear search */
84 for(handle=gLastHandleIndex;handle<SHFLHANDLE_MAX;handle++)
85 {
86 if (g_pHandles[handle].pvUserData == 0)
87 {
88 gLastHandleIndex = handle;
89 break;
90 }
91 }
92
93 if (handle == SHFLHANDLE_MAX)
94 {
95 /* Try once more from the start */
96 for(handle=1;handle<SHFLHANDLE_MAX;handle++)
97 {
98 if (g_pHandles[handle].pvUserData == 0)
99 {
100 gLastHandleIndex = handle;
101 break;
102 }
103 }
104 if (handle == SHFLHANDLE_MAX)
105 {
106 /* Out of handles */
107 RTCritSectLeave(&gLock);
108 AssertFailed();
109 return SHFL_HANDLE_NIL;
110 }
111 }
112 g_pHandles[handle].uFlags = (uType & SHFL_HF_TYPE_MASK) | SHFL_HF_VALID;
113 g_pHandles[handle].pvUserData = pvUserData;
114 g_pHandles[handle].pClient = pClient;
115
116 gLastHandleIndex++;
117
118 RTCritSectLeave(&gLock);
119
120 return handle;
121}
122
123static int vbsfFreeHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
124{
125 if ( handle < SHFLHANDLE_MAX
126 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
127 && g_pHandles[handle].pClient == pClient)
128 {
129 g_pHandles[handle].uFlags = 0;
130 g_pHandles[handle].pvUserData = 0;
131 g_pHandles[handle].pClient = 0;
132 return VINF_SUCCESS;
133 }
134 return VERR_INVALID_HANDLE;
135}
136
137uintptr_t vbsfQueryHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle,
138 uint32_t uType)
139{
140 if ( handle < SHFLHANDLE_MAX
141 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
142 && g_pHandles[handle].pClient == pClient)
143 {
144 Assert((uType & SHFL_HF_TYPE_MASK) != 0);
145
146 if (g_pHandles[handle].uFlags & uType)
147 return g_pHandles[handle].pvUserData;
148 }
149 return 0;
150}
151
152SHFLFILEHANDLE *vbsfQueryFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
153{
154 return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
155 SHFL_HF_TYPE_FILE);
156}
157
158SHFLFILEHANDLE *vbsfQueryDirHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
159{
160 return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
161 SHFL_HF_TYPE_DIR);
162}
163
164uint32_t vbsfQueryHandleType(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
165{
166 if ( handle < SHFLHANDLE_MAX
167 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
168 && g_pHandles[handle].pClient == pClient)
169 return g_pHandles[handle].uFlags & SHFL_HF_TYPE_MASK;
170
171 return 0;
172}
173
174SHFLHANDLE vbsfAllocDirHandle(PSHFLCLIENTDATA pClient)
175{
176 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
177
178 if (pHandle)
179 {
180 pHandle->Header.u32Flags = SHFL_HF_TYPE_DIR;
181 return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
182 (uintptr_t)pHandle);
183 }
184
185 return SHFL_HANDLE_NIL;
186}
187
188SHFLHANDLE vbsfAllocFileHandle(PSHFLCLIENTDATA pClient)
189{
190 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
191
192 if (pHandle)
193 {
194 pHandle->Header.u32Flags = SHFL_HF_TYPE_FILE;
195 return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
196 (uintptr_t)pHandle);
197 }
198
199 return SHFL_HANDLE_NIL;
200}
201
202void vbsfFreeFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE hHandle)
203{
204 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(pClient,
205 hHandle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
206
207 if (pHandle)
208 {
209 vbsfFreeHandle(pClient, hHandle);
210 RTMemFree (pHandle);
211 }
212 else
213 AssertFailed();
214}
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