VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 5 days ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/* $Id: shflhandle.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * Shared Folders Service - Handles helper functions.
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
33#include "shflhandle.h"
34#include <iprt/alloc.h>
35#include <iprt/assert.h>
36#include <iprt/critsect.h>
37
38
39/*********************************************************************************************************************************
40* Structures and Typedefs *
41*********************************************************************************************************************************/
42/**
43 * Very basic and primitive handle management. Should be sufficient for our needs.
44 * Handle allocation can be rather slow, but at least lookup is fast.
45 */
46typedef struct
47{
48 uint32_t uFlags;
49 uintptr_t pvUserData;
50 PSHFLCLIENTDATA pClient;
51} SHFLINTHANDLE, *PSHFLINTHANDLE;
52
53
54/*********************************************************************************************************************************
55* Global Variables *
56*********************************************************************************************************************************/
57static SHFLINTHANDLE *g_pHandles = NULL;
58static int32_t gLastHandleIndex = 0;
59static RTCRITSECT gLock;
60
61
62int vbsfInitHandleTable()
63{
64 g_pHandles = (SHFLINTHANDLE *)RTMemAllocZ (sizeof (SHFLINTHANDLE) * SHFLHANDLE_MAX);
65 if (!g_pHandles)
66 {
67 AssertFailed();
68 return VERR_NO_MEMORY;
69 }
70
71 /* Never return handle 0 */
72 g_pHandles[0].uFlags = SHFL_HF_TYPE_DONTUSE;
73 gLastHandleIndex = 1;
74
75 return RTCritSectInit(&gLock);
76}
77
78int vbsfFreeHandleTable()
79{
80 if (g_pHandles)
81 RTMemFree(g_pHandles);
82
83 g_pHandles = NULL;
84
85 if (RTCritSectIsInitialized(&gLock))
86 RTCritSectDelete(&gLock);
87
88 return VINF_SUCCESS;
89}
90
91SHFLHANDLE vbsfAllocHandle(PSHFLCLIENTDATA pClient, uint32_t uType,
92 uintptr_t pvUserData)
93{
94 SHFLHANDLE handle;
95
96 Assert((uType & SHFL_HF_TYPE_MASK) != 0 && pvUserData);
97
98 RTCritSectEnter(&gLock);
99
100 /* Find next free handle */
101 if (gLastHandleIndex >= SHFLHANDLE_MAX-1)
102 gLastHandleIndex = 1;
103
104 /* Nice linear search */
105 for(handle=gLastHandleIndex;handle<SHFLHANDLE_MAX;handle++)
106 {
107 if (g_pHandles[handle].pvUserData == 0)
108 {
109 gLastHandleIndex = handle;
110 break;
111 }
112 }
113
114 if (handle == SHFLHANDLE_MAX)
115 {
116 /* Try once more from the start */
117 for(handle=1;handle<SHFLHANDLE_MAX;handle++)
118 {
119 if (g_pHandles[handle].pvUserData == 0)
120 {
121 gLastHandleIndex = handle;
122 break;
123 }
124 }
125 if (handle == SHFLHANDLE_MAX)
126 {
127 /* Out of handles */
128 RTCritSectLeave(&gLock);
129 AssertFailed();
130 return SHFL_HANDLE_NIL;
131 }
132 }
133 g_pHandles[handle].uFlags = (uType & SHFL_HF_TYPE_MASK) | SHFL_HF_VALID;
134 g_pHandles[handle].pvUserData = pvUserData;
135 g_pHandles[handle].pClient = pClient;
136
137 gLastHandleIndex++;
138
139 RTCritSectLeave(&gLock);
140
141 return handle;
142}
143
144static int vbsfFreeHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
145{
146 if ( handle < SHFLHANDLE_MAX
147 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
148 && g_pHandles[handle].pClient == pClient)
149 {
150 g_pHandles[handle].uFlags = 0;
151 g_pHandles[handle].pvUserData = 0;
152 g_pHandles[handle].pClient = 0;
153 return VINF_SUCCESS;
154 }
155 return VERR_INVALID_HANDLE;
156}
157
158static uintptr_t vbsfQueryHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle,
159 uint32_t uType)
160{
161 if ( handle < SHFLHANDLE_MAX
162 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
163 && g_pHandles[handle].pClient == pClient)
164 {
165 Assert((uType & SHFL_HF_TYPE_MASK) != 0);
166
167 if (g_pHandles[handle].uFlags & uType)
168 return g_pHandles[handle].pvUserData;
169 }
170 return 0;
171}
172
173SHFLFILEHANDLE *vbsfQueryFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
174{
175 return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
176 SHFL_HF_TYPE_FILE);
177}
178
179SHFLFILEHANDLE *vbsfQueryDirHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
180{
181 return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
182 SHFL_HF_TYPE_DIR);
183}
184
185uint32_t vbsfQueryHandleType(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
186{
187 if ( handle < SHFLHANDLE_MAX
188 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
189 && g_pHandles[handle].pClient == pClient)
190 return g_pHandles[handle].uFlags & SHFL_HF_TYPE_MASK;
191
192 return 0;
193}
194
195SHFLHANDLE vbsfAllocDirHandle(PSHFLCLIENTDATA pClient)
196{
197 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
198
199 if (pHandle)
200 {
201 pHandle->Header.u32Flags = SHFL_HF_TYPE_DIR;
202 return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
203 (uintptr_t)pHandle);
204 }
205
206 return SHFL_HANDLE_NIL;
207}
208
209SHFLHANDLE vbsfAllocFileHandle(PSHFLCLIENTDATA pClient)
210{
211 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
212
213 if (pHandle)
214 {
215 pHandle->Header.u32Flags = SHFL_HF_TYPE_FILE;
216 return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
217 (uintptr_t)pHandle);
218 }
219
220 return SHFL_HANDLE_NIL;
221}
222
223void vbsfFreeFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE hHandle)
224{
225 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(pClient,
226 hHandle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
227
228 if (pHandle)
229 {
230 vbsfFreeHandle(pClient, hHandle);
231 RTMemFree (pHandle);
232 }
233 else
234 AssertFailed();
235}
236
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