VirtualBox

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

Last change on this file since 103068 was 99775, checked in by vboxsync, 19 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409

  • 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 99775 2023-05-12 12:21:58Z vboxsync $ */
2/** @file
3 * Shared Folders Service - Handles helper functions.
4 */
5
6/*
7 * Copyright (C) 2006-2023 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