/** @file * * Shared Folders: * Handles helper functions. */ /* * Copyright (C) 2006-2016 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ #include "shflhandle.h" #include #include #include /* * 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; static SHFLINTHANDLE *pHandles = NULL; static int32_t lastHandleIndex = 0; static RTCRITSECT lock; int vbsfInitHandleTable() { pHandles = (SHFLINTHANDLE *)RTMemAllocZ (sizeof (SHFLINTHANDLE) * SHFLHANDLE_MAX); if (pHandles == NULL) { AssertFailed(); return VERR_NO_MEMORY; } /* Never return handle 0 */ pHandles[0].uFlags = SHFL_HF_TYPE_DONTUSE; lastHandleIndex = 1; return RTCritSectInit(&lock); } int vbsfFreeHandleTable() { if (pHandles) RTMemFree(pHandles); pHandles = NULL; if (RTCritSectIsInitialized(&lock)) RTCritSectDelete(&lock); return VINF_SUCCESS; } SHFLHANDLE vbsfAllocHandle(PSHFLCLIENTDATA pClient, uint32_t uType, uintptr_t pvUserData) { SHFLHANDLE handle; Assert((uType & SHFL_HF_TYPE_MASK) != 0 && pvUserData); RTCritSectEnter(&lock); /* Find next free handle */ if(lastHandleIndex >= SHFLHANDLE_MAX-1) { lastHandleIndex = 1; } /* Nice linear search */ for(handle=lastHandleIndex;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(); return; }