VirtualBox

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

Last change on this file since 78903 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1/* $Id: shflhandle.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * Shared Folders Service - Handles helper functions.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
23#include "shflhandle.h"
24#include <iprt/alloc.h>
25#include <iprt/assert.h>
26#include <iprt/critsect.h>
27
28
29/*********************************************************************************************************************************
30* Structures and Typedefs *
31*********************************************************************************************************************************/
32/**
33 * Very basic and primitive handle management. Should be sufficient for our needs.
34 * Handle allocation can be rather slow, but at least lookup is fast.
35 */
36typedef struct
37{
38 uint32_t uFlags;
39 uintptr_t pvUserData;
40 PSHFLCLIENTDATA pClient;
41} SHFLINTHANDLE, *PSHFLINTHANDLE;
42
43
44/*********************************************************************************************************************************
45* Global Variables *
46*********************************************************************************************************************************/
47static SHFLINTHANDLE *g_pHandles = NULL;
48static int32_t gLastHandleIndex = 0;
49static RTCRITSECT gLock;
50
51
52int vbsfInitHandleTable()
53{
54 g_pHandles = (SHFLINTHANDLE *)RTMemAllocZ (sizeof (SHFLINTHANDLE) * SHFLHANDLE_MAX);
55 if (!g_pHandles)
56 {
57 AssertFailed();
58 return VERR_NO_MEMORY;
59 }
60
61 /* Never return handle 0 */
62 g_pHandles[0].uFlags = SHFL_HF_TYPE_DONTUSE;
63 gLastHandleIndex = 1;
64
65 return RTCritSectInit(&gLock);
66}
67
68int vbsfFreeHandleTable()
69{
70 if (g_pHandles)
71 RTMemFree(g_pHandles);
72
73 g_pHandles = NULL;
74
75 if (RTCritSectIsInitialized(&gLock))
76 RTCritSectDelete(&gLock);
77
78 return VINF_SUCCESS;
79}
80
81SHFLHANDLE vbsfAllocHandle(PSHFLCLIENTDATA pClient, uint32_t uType,
82 uintptr_t pvUserData)
83{
84 SHFLHANDLE handle;
85
86 Assert((uType & SHFL_HF_TYPE_MASK) != 0 && pvUserData);
87
88 RTCritSectEnter(&gLock);
89
90 /* Find next free handle */
91 if (gLastHandleIndex >= SHFLHANDLE_MAX-1)
92 gLastHandleIndex = 1;
93
94 /* Nice linear search */
95 for(handle=gLastHandleIndex;handle<SHFLHANDLE_MAX;handle++)
96 {
97 if (g_pHandles[handle].pvUserData == 0)
98 {
99 gLastHandleIndex = handle;
100 break;
101 }
102 }
103
104 if (handle == SHFLHANDLE_MAX)
105 {
106 /* Try once more from the start */
107 for(handle=1;handle<SHFLHANDLE_MAX;handle++)
108 {
109 if (g_pHandles[handle].pvUserData == 0)
110 {
111 gLastHandleIndex = handle;
112 break;
113 }
114 }
115 if (handle == SHFLHANDLE_MAX)
116 {
117 /* Out of handles */
118 RTCritSectLeave(&gLock);
119 AssertFailed();
120 return SHFL_HANDLE_NIL;
121 }
122 }
123 g_pHandles[handle].uFlags = (uType & SHFL_HF_TYPE_MASK) | SHFL_HF_VALID;
124 g_pHandles[handle].pvUserData = pvUserData;
125 g_pHandles[handle].pClient = pClient;
126
127 gLastHandleIndex++;
128
129 RTCritSectLeave(&gLock);
130
131 return handle;
132}
133
134static int vbsfFreeHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
135{
136 if ( handle < SHFLHANDLE_MAX
137 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
138 && g_pHandles[handle].pClient == pClient)
139 {
140 g_pHandles[handle].uFlags = 0;
141 g_pHandles[handle].pvUserData = 0;
142 g_pHandles[handle].pClient = 0;
143 return VINF_SUCCESS;
144 }
145 return VERR_INVALID_HANDLE;
146}
147
148uintptr_t vbsfQueryHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle,
149 uint32_t uType)
150{
151 if ( handle < SHFLHANDLE_MAX
152 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
153 && g_pHandles[handle].pClient == pClient)
154 {
155 Assert((uType & SHFL_HF_TYPE_MASK) != 0);
156
157 if (g_pHandles[handle].uFlags & uType)
158 return g_pHandles[handle].pvUserData;
159 }
160 return 0;
161}
162
163SHFLFILEHANDLE *vbsfQueryFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
164{
165 return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
166 SHFL_HF_TYPE_FILE);
167}
168
169SHFLFILEHANDLE *vbsfQueryDirHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
170{
171 return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
172 SHFL_HF_TYPE_DIR);
173}
174
175uint32_t vbsfQueryHandleType(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
176{
177 if ( handle < SHFLHANDLE_MAX
178 && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
179 && g_pHandles[handle].pClient == pClient)
180 return g_pHandles[handle].uFlags & SHFL_HF_TYPE_MASK;
181
182 return 0;
183}
184
185SHFLHANDLE vbsfAllocDirHandle(PSHFLCLIENTDATA pClient)
186{
187 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
188
189 if (pHandle)
190 {
191 pHandle->Header.u32Flags = SHFL_HF_TYPE_DIR;
192 return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
193 (uintptr_t)pHandle);
194 }
195
196 return SHFL_HANDLE_NIL;
197}
198
199SHFLHANDLE vbsfAllocFileHandle(PSHFLCLIENTDATA pClient)
200{
201 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
202
203 if (pHandle)
204 {
205 pHandle->Header.u32Flags = SHFL_HF_TYPE_FILE;
206 return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
207 (uintptr_t)pHandle);
208 }
209
210 return SHFL_HANDLE_NIL;
211}
212
213void vbsfFreeFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE hHandle)
214{
215 SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(pClient,
216 hHandle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
217
218 if (pHandle)
219 {
220 vbsfFreeHandle(pClient, hHandle);
221 RTMemFree (pHandle);
222 }
223 else
224 AssertFailed();
225}
226
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