VirtualBox

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

Last change on this file since 64107 was 62489, 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: 5.5 KB
Line 
1/** @file
2 *
3 * Shared Folders:
4 * Handles helper functions.
5 */
6
7/*
8 * Copyright (C) 2006-2016 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 *pHandles = NULL;
38static int32_t lastHandleIndex = 0;
39static RTCRITSECT lock;
40
41int vbsfInitHandleTable()
42{
43 pHandles = (SHFLINTHANDLE *)RTMemAllocZ (sizeof (SHFLINTHANDLE) * SHFLHANDLE_MAX);
44 if (pHandles == NULL)
45 {
46 AssertFailed();
47 return VERR_NO_MEMORY;
48 }
49
50 /* Never return handle 0 */
51 pHandles[0].uFlags = SHFL_HF_TYPE_DONTUSE;
52 lastHandleIndex = 1;
53
54 return RTCritSectInit(&lock);
55}
56
57int vbsfFreeHandleTable()
58{
59 if (pHandles)
60 RTMemFree(pHandles);
61
62 pHandles = NULL;
63
64 if (RTCritSectIsInitialized(&lock))
65 RTCritSectDelete(&lock);
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(&lock);
78
79 /* Find next free handle */
80 if(lastHandleIndex >= SHFLHANDLE_MAX-1)
81 {
82 lastHandleIndex = 1;
83 }
84
85 /* Nice linear search */
86 for(handle=lastHandleIndex;handle<SHFLHANDLE_MAX;handle++)
87 {
88 if(pHandles[handle].pvUserData == 0)
89 {
90 lastHandleIndex = handle;
91 break;
92 }
93 }
94
95 if(handle == SHFLHANDLE_MAX)
96 {
97 /* Try once more from the start */
98 for(handle=1;handle<SHFLHANDLE_MAX;handle++)
99 {
100 if(pHandles[handle].pvUserData == 0)
101 {
102 lastHandleIndex = handle;
103 break;
104 }
105 }
106 if(handle == SHFLHANDLE_MAX)
107 { /* Out of handles */
108 RTCritSectLeave(&lock);
109 AssertFailed();
110 return SHFL_HANDLE_NIL;
111 }
112 }
113 pHandles[handle].uFlags = (uType & SHFL_HF_TYPE_MASK) | SHFL_HF_VALID;
114 pHandles[handle].pvUserData = pvUserData;
115 pHandles[handle].pClient = pClient;
116
117 lastHandleIndex++;
118
119 RTCritSectLeave(&lock);
120
121 return handle;
122}
123
124static int vbsfFreeHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
125{
126 if ( handle < SHFLHANDLE_MAX
127 && (pHandles[handle].uFlags & SHFL_HF_VALID)
128 && pHandles[handle].pClient == pClient)
129 {
130 pHandles[handle].uFlags = 0;
131 pHandles[handle].pvUserData = 0;
132 pHandles[handle].pClient = 0;
133 return VINF_SUCCESS;
134 }
135 return VERR_INVALID_HANDLE;
136}
137
138uintptr_t vbsfQueryHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle,
139 uint32_t uType)
140{
141 if ( handle < SHFLHANDLE_MAX
142 && (pHandles[handle].uFlags & SHFL_HF_VALID)
143 && pHandles[handle].pClient == pClient)
144 {
145 Assert((uType & SHFL_HF_TYPE_MASK) != 0);
146
147 if (pHandles[handle].uFlags & uType)
148 return pHandles[handle].pvUserData;
149 }
150 return 0;
151}
152
153SHFLFILEHANDLE *vbsfQueryFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
154{
155 return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
156 SHFL_HF_TYPE_FILE);
157}
158
159SHFLFILEHANDLE *vbsfQueryDirHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
160{
161 return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
162 SHFL_HF_TYPE_DIR);
163}
164
165uint32_t vbsfQueryHandleType(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
166{
167 if ( handle < SHFLHANDLE_MAX
168 && (pHandles[handle].uFlags & SHFL_HF_VALID)
169 && pHandles[handle].pClient == pClient)
170 return pHandles[handle].uFlags & SHFL_HF_TYPE_MASK;
171 else
172 return 0;
173}
174
175SHFLHANDLE vbsfAllocDirHandle(PSHFLCLIENTDATA pClient)
176{
177 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
178
179 if (pHandle)
180 {
181 pHandle->Header.u32Flags = SHFL_HF_TYPE_DIR;
182 return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
183 (uintptr_t)pHandle);
184 }
185
186 return SHFL_HANDLE_NIL;
187}
188
189SHFLHANDLE vbsfAllocFileHandle(PSHFLCLIENTDATA pClient)
190{
191 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
192
193 if (pHandle)
194 {
195 pHandle->Header.u32Flags = SHFL_HF_TYPE_FILE;
196 return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
197 (uintptr_t)pHandle);
198 }
199
200 return SHFL_HANDLE_NIL;
201}
202
203void vbsfFreeFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE hHandle)
204{
205 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(pClient,
206 hHandle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
207
208 if (pHandle)
209 {
210 vbsfFreeHandle(pClient, hHandle);
211 RTMemFree (pHandle);
212 }
213 else
214 AssertFailed();
215
216 return;
217}
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