/* $Id: shflhandle.cpp $ */ /** @file * Shared Folders Service - Handles helper functions. */ /* * Copyright (C) 2006-2023 Oracle and/or its affiliates. * * This file is part of VirtualBox base platform packages, as * available from https://www.virtualbox.org. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, in version 3 of the * License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * SPDX-License-Identifier: GPL-3.0-only */ /********************************************************************************************************************************* * Header Files * *********************************************************************************************************************************/ #define LOG_GROUP LOG_GROUP_SHARED_FOLDERS #include "shflhandle.h" #include #include #include /********************************************************************************************************************************* * Structures and Typedefs * *********************************************************************************************************************************/ /** * Very basic and primitive handle management. Should be sufficient for our needs. * Handle allocation can be rather slow, but at least lookup is fast. */ typedef struct { uint32_t uFlags; uintptr_t pvUserData; PSHFLCLIENTDATA pClient; } SHFLINTHANDLE, *PSHFLINTHANDLE; /********************************************************************************************************************************* * Global Variables * *********************************************************************************************************************************/ static SHFLINTHANDLE *g_pHandles = NULL; static int32_t gLastHandleIndex = 0; static RTCRITSECT gLock; int vbsfInitHandleTable() { g_pHandles = (SHFLINTHANDLE *)RTMemAllocZ (sizeof (SHFLINTHANDLE) * SHFLHANDLE_MAX); if (!g_pHandles) { AssertFailed(); return VERR_NO_MEMORY; } /* Never return handle 0 */ g_pHandles[0].uFlags = SHFL_HF_TYPE_DONTUSE; gLastHandleIndex = 1; return RTCritSectInit(&gLock); } int vbsfFreeHandleTable() { if (g_pHandles) RTMemFree(g_pHandles); g_pHandles = NULL; if (RTCritSectIsInitialized(&gLock)) RTCritSectDelete(&gLock); return VINF_SUCCESS; } SHFLHANDLE vbsfAllocHandle(PSHFLCLIENTDATA pClient, uint32_t uType, uintptr_t pvUserData) { SHFLHANDLE handle; Assert((uType & SHFL_HF_TYPE_MASK) != 0 && pvUserData); RTCritSectEnter(&gLock); /* Find next free handle */ if (gLastHandleIndex >= SHFLHANDLE_MAX-1) gLastHandleIndex = 1; /* Nice linear search */ for(handle=gLastHandleIndex;handleHeader.u32Flags = SHFL_HF_TYPE_DIR; return vbsfAllocHandle(pClient, pHandle->Header.u32Flags, (uintptr_t)pHandle); } return SHFL_HANDLE_NIL; } SHFLHANDLE vbsfAllocFileHandle(PSHFLCLIENTDATA pClient) { SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)RTMemAllocZ (sizeof (SHFLFILEHANDLE)); if (pHandle) { pHandle->Header.u32Flags = SHFL_HF_TYPE_FILE; return vbsfAllocHandle(pClient, pHandle->Header.u32Flags, (uintptr_t)pHandle); } return SHFL_HANDLE_NIL; } void vbsfFreeFileHandle(PSHFLCLIENTDATA pClient, SHFLHANDLE hHandle) { SHFLFILEHANDLE *pHandle = (SHFLFILEHANDLE *)vbsfQueryHandle(pClient, hHandle, SHFL_HF_TYPE_DIR|SHFL_HF_TYPE_FILE); if (pHandle) { vbsfFreeHandle(pClient, hHandle); RTMemFree (pHandle); } else AssertFailed(); }