[75498] | 1 | /* $Id: shflhandle.cpp 99775 2023-05-12 12:21:58Z vboxsync $ */
|
---|
[3338] | 2 | /** @file
|
---|
[75498] | 3 | * Shared Folders Service - Handles helper functions.
|
---|
[3338] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2006-2023 Oracle and/or its affiliates.
|
---|
[3338] | 8 | *
|
---|
[96407] | 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
|
---|
[3338] | 26 | */
|
---|
| 27 |
|
---|
[75498] | 28 |
|
---|
| 29 | /*********************************************************************************************************************************
|
---|
| 30 | * Header Files *
|
---|
| 31 | *********************************************************************************************************************************/
|
---|
| 32 | #define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
|
---|
[3338] | 33 | #include "shflhandle.h"
|
---|
| 34 | #include <iprt/alloc.h>
|
---|
| 35 | #include <iprt/assert.h>
|
---|
| 36 | #include <iprt/critsect.h>
|
---|
| 37 |
|
---|
| 38 |
|
---|
[75498] | 39 | /*********************************************************************************************************************************
|
---|
| 40 | * Structures and Typedefs *
|
---|
| 41 | *********************************************************************************************************************************/
|
---|
| 42 | /**
|
---|
[3338] | 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 | */
|
---|
| 46 | typedef struct
|
---|
| 47 | {
|
---|
[39544] | 48 | uint32_t uFlags;
|
---|
| 49 | uintptr_t pvUserData;
|
---|
| 50 | PSHFLCLIENTDATA pClient;
|
---|
[3338] | 51 | } SHFLINTHANDLE, *PSHFLINTHANDLE;
|
---|
| 52 |
|
---|
[75498] | 53 |
|
---|
| 54 | /*********************************************************************************************************************************
|
---|
| 55 | * Global Variables *
|
---|
| 56 | *********************************************************************************************************************************/
|
---|
[67018] | 57 | static SHFLINTHANDLE *g_pHandles = NULL;
|
---|
| 58 | static int32_t gLastHandleIndex = 0;
|
---|
| 59 | static RTCRITSECT gLock;
|
---|
[3338] | 60 |
|
---|
[75498] | 61 |
|
---|
[3338] | 62 | int vbsfInitHandleTable()
|
---|
| 63 | {
|
---|
[67018] | 64 | g_pHandles = (SHFLINTHANDLE *)RTMemAllocZ (sizeof (SHFLINTHANDLE) * SHFLHANDLE_MAX);
|
---|
| 65 | if (!g_pHandles)
|
---|
[3338] | 66 | {
|
---|
| 67 | AssertFailed();
|
---|
| 68 | return VERR_NO_MEMORY;
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | /* Never return handle 0 */
|
---|
[67018] | 72 | g_pHandles[0].uFlags = SHFL_HF_TYPE_DONTUSE;
|
---|
| 73 | gLastHandleIndex = 1;
|
---|
[3338] | 74 |
|
---|
[67018] | 75 | return RTCritSectInit(&gLock);
|
---|
[3338] | 76 | }
|
---|
| 77 |
|
---|
| 78 | int vbsfFreeHandleTable()
|
---|
| 79 | {
|
---|
[67018] | 80 | if (g_pHandles)
|
---|
| 81 | RTMemFree(g_pHandles);
|
---|
[3338] | 82 |
|
---|
[67018] | 83 | g_pHandles = NULL;
|
---|
[3338] | 84 |
|
---|
[67018] | 85 | if (RTCritSectIsInitialized(&gLock))
|
---|
| 86 | RTCritSectDelete(&gLock);
|
---|
[3338] | 87 |
|
---|
| 88 | return VINF_SUCCESS;
|
---|
| 89 | }
|
---|
| 90 |
|
---|
[39544] | 91 | SHFLHANDLE vbsfAllocHandle(PSHFLCLIENTDATA pClient, uint32_t uType,
|
---|
| 92 | uintptr_t pvUserData)
|
---|
[3338] | 93 | {
|
---|
| 94 | SHFLHANDLE handle;
|
---|
| 95 |
|
---|
| 96 | Assert((uType & SHFL_HF_TYPE_MASK) != 0 && pvUserData);
|
---|
| 97 |
|
---|
[67018] | 98 | RTCritSectEnter(&gLock);
|
---|
[3338] | 99 |
|
---|
| 100 | /* Find next free handle */
|
---|
[67018] | 101 | if (gLastHandleIndex >= SHFLHANDLE_MAX-1)
|
---|
| 102 | gLastHandleIndex = 1;
|
---|
[3338] | 103 |
|
---|
| 104 | /* Nice linear search */
|
---|
[67018] | 105 | for(handle=gLastHandleIndex;handle<SHFLHANDLE_MAX;handle++)
|
---|
[3338] | 106 | {
|
---|
[67018] | 107 | if (g_pHandles[handle].pvUserData == 0)
|
---|
[3338] | 108 | {
|
---|
[67018] | 109 | gLastHandleIndex = handle;
|
---|
[26514] | 110 | break;
|
---|
[3338] | 111 | }
|
---|
| 112 | }
|
---|
| 113 |
|
---|
[67018] | 114 | if (handle == SHFLHANDLE_MAX)
|
---|
[3338] | 115 | {
|
---|
| 116 | /* Try once more from the start */
|
---|
| 117 | for(handle=1;handle<SHFLHANDLE_MAX;handle++)
|
---|
| 118 | {
|
---|
[67018] | 119 | if (g_pHandles[handle].pvUserData == 0)
|
---|
[3338] | 120 | {
|
---|
[67018] | 121 | gLastHandleIndex = handle;
|
---|
[26514] | 122 | break;
|
---|
[3338] | 123 | }
|
---|
| 124 | }
|
---|
[67018] | 125 | if (handle == SHFLHANDLE_MAX)
|
---|
| 126 | {
|
---|
| 127 | /* Out of handles */
|
---|
| 128 | RTCritSectLeave(&gLock);
|
---|
[3338] | 129 | AssertFailed();
|
---|
| 130 | return SHFL_HANDLE_NIL;
|
---|
| 131 | }
|
---|
| 132 | }
|
---|
[67018] | 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;
|
---|
[3338] | 136 |
|
---|
[67018] | 137 | gLastHandleIndex++;
|
---|
[3338] | 138 |
|
---|
[67018] | 139 | RTCritSectLeave(&gLock);
|
---|
[3338] | 140 |
|
---|
| 141 | return handle;
|
---|
| 142 | }
|
---|
| 143 |
|
---|
[39544] | 144 | static int vbsfFreeHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
|
---|
[3338] | 145 | {
|
---|
[39544] | 146 | if ( handle < SHFLHANDLE_MAX
|
---|
[67018] | 147 | && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
|
---|
| 148 | && g_pHandles[handle].pClient == pClient)
|
---|
[3338] | 149 | {
|
---|
[67018] | 150 | g_pHandles[handle].uFlags = 0;
|
---|
| 151 | g_pHandles[handle].pvUserData = 0;
|
---|
| 152 | g_pHandles[handle].pClient = 0;
|
---|
[3338] | 153 | return VINF_SUCCESS;
|
---|
| 154 | }
|
---|
| 155 | return VERR_INVALID_HANDLE;
|
---|
| 156 | }
|
---|
| 157 |
|
---|
[99775] | 158 | static uintptr_t vbsfQueryHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle,
|
---|
| 159 | uint32_t uType)
|
---|
[3338] | 160 | {
|
---|
[39544] | 161 | if ( handle < SHFLHANDLE_MAX
|
---|
[67018] | 162 | && (g_pHandles[handle].uFlags & SHFL_HF_VALID)
|
---|
| 163 | && g_pHandles[handle].pClient == pClient)
|
---|
[3338] | 164 | {
|
---|
| 165 | Assert((uType & SHFL_HF_TYPE_MASK) != 0);
|
---|
| 166 |
|
---|
[67018] | 167 | if (g_pHandles[handle].uFlags & uType)
|
---|
| 168 | return g_pHandles[handle].pvUserData;
|
---|
[3338] | 169 | }
|
---|
| 170 | return 0;
|
---|
| 171 | }
|
---|
| 172 |
|
---|
[39544] | 173 | SHFLFILEHANDLE *vbsfQueryFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
|
---|
[3338] | 174 | {
|
---|
[39544] | 175 | return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
|
---|
| 176 | SHFL_HF_TYPE_FILE);
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 | SHFLFILEHANDLE *vbsfQueryDirHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
|
---|
| 180 | {
|
---|
| 181 | return (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, handle,
|
---|
| 182 | SHFL_HF_TYPE_DIR);
|
---|
| 183 | }
|
---|
| 184 |
|
---|
| 185 | uint32_t vbsfQueryHandleType(PSHFLCLIENTDATA pClient, SHFLHANDLE handle)
|
---|
| 186 | {
|
---|
| 187 | if ( handle < SHFLHANDLE_MAX
|
---|
[67018] | 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;
|
---|
[39544] | 193 | }
|
---|
| 194 |
|
---|
| 195 | SHFLHANDLE vbsfAllocDirHandle(PSHFLCLIENTDATA pClient)
|
---|
| 196 | {
|
---|
[3338] | 197 | SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
|
---|
| 198 |
|
---|
| 199 | if (pHandle)
|
---|
| 200 | {
|
---|
| 201 | pHandle->Header.u32Flags = SHFL_HF_TYPE_DIR;
|
---|
[39544] | 202 | return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
|
---|
| 203 | (uintptr_t)pHandle);
|
---|
[3338] | 204 | }
|
---|
| 205 |
|
---|
| 206 | return SHFL_HANDLE_NIL;
|
---|
| 207 | }
|
---|
| 208 |
|
---|
[39544] | 209 | SHFLHANDLE vbsfAllocFileHandle(PSHFLCLIENTDATA pClient)
|
---|
[3338] | 210 | {
|
---|
| 211 | SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE));
|
---|
| 212 |
|
---|
| 213 | if (pHandle)
|
---|
| 214 | {
|
---|
| 215 | pHandle->Header.u32Flags = SHFL_HF_TYPE_FILE;
|
---|
[39544] | 216 | return vbsfAllocHandle(pClient, pHandle->Header.u32Flags,
|
---|
| 217 | (uintptr_t)pHandle);
|
---|
[3338] | 218 | }
|
---|
| 219 |
|
---|
| 220 | return SHFL_HANDLE_NIL;
|
---|
| 221 | }
|
---|
| 222 |
|
---|
[39544] | 223 | void vbsfFreeFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE hHandle)
|
---|
[3338] | 224 | {
|
---|
[39544] | 225 | SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(pClient,
|
---|
| 226 | hHandle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE);
|
---|
[3338] | 227 |
|
---|
| 228 | if (pHandle)
|
---|
| 229 | {
|
---|
[39544] | 230 | vbsfFreeHandle(pClient, hHandle);
|
---|
[3338] | 231 | RTMemFree (pHandle);
|
---|
| 232 | }
|
---|
| 233 | else
|
---|
| 234 | AssertFailed();
|
---|
| 235 | }
|
---|
[75498] | 236 |
|
---|