service.cpp revision 039cd2c4871a00e51af909222a34695d9cec3000
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Shared Folders: Host service entry points.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Copyright (C) 2006-2007 innotek GmbH
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * available from http://www.virtualbox.org. This file is free software;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * General Public License as published by the Free Software Foundation,
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * If you received this file as part of a commercial VirtualBox
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * distribution, then only the terms of your commercial VirtualBox
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * license agreement apply instead of the previous paragraph.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/* Shared Folders Host Service.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Shared Folders map a host file system to guest logical filesystem.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * A mapping represents 'host name'<->'guest name' translation and a root
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * identifier to be used to access this mapping.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Examples: "C:\WINNT"<->"F:", "C:\WINNT\System32"<->"/mnt/host/system32".
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Therefore, host name and guest name are strings interpreted
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * only by host service and guest client respectively. Host name is
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * passed to guest only for informational purpose. Guest may for example
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * display the string or construct volume label out of the string.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Root identifiers are unique for whole guest life,
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * that is until next guest reset/fresh start.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * 32 bit value incremented for each new mapping is used.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Mapping strings are taken from VM XML configuration on VM startup.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * The service DLL takes mappings during initialization. There is
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * also API for changing mappings at runtime.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Current mappings and root identifiers are saved when VM is saved.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Guest may use any of these mappings. Full path information
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * about an object on a mapping consists of the root indentifier and
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * a full path of object.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * Guest IFS connects to the service and calls SHFL_FN_QUERY_MAP
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * function which returns current mappings. For guest convenience,
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * removed mappings also returned with REMOVED flag and new mappings
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * are marked with NEW flag.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * To access host file system guest just forwards file system calls
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * to the service, and specifies full paths or handles for objects.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic DECLCALLBACK(int) svcConnect (uint32_t u32ClientID, void *pvClient)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync Log(("svcConnect: u32ClientID = %d\n", u32ClientID));
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic DECLCALLBACK(int) svcDisconnect (uint32_t u32ClientID, void *pvClient)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync Log(("svcDisconnect: u32ClientID = %d\n", u32ClientID));
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/** @note We only save as much state as required to access the shared folder again after restore.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * All I/O requests pending at the time of saving will never be completed or result in errors.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * (file handles no longer valid etc)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * This works as designed at the moment. A full state save would be difficult and not always possible
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync * as the contents of a shared folder might change in between save and restore.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic DECLCALLBACK(int) svcSaveState(uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync Log(("svcSaveState: u32ClientID = %d\n", u32ClientID));
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync /* Save client structure length & contents */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync /* Save all the active mappings. */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync for (int i=0;i<SHFL_MAX_MAPPINGS;i++)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync rc = SSMR3PutU32(pSSM, FolderMapping[i].cMappings);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync len = ShflStringSizeOfBuffer(FolderMapping[i].pFolderName);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync rc = SSMR3PutMem(pSSM, FolderMapping[i].pFolderName, len);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync len = ShflStringSizeOfBuffer(FolderMapping[i].pMapName);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync rc = SSMR3PutMem(pSSM, FolderMapping[i].pMapName, len);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic DECLCALLBACK(int) svcLoadState(uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync Log(("svcLoadState: u32ClientID = %d\n", u32ClientID));
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync /* Restore the client data (flags + path delimiter at the moment) */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync /* We don't actually (fully) restore the state; we simply check if the current state is as we it expect it to be. */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync for (int i=0;i<SHFL_MAX_MAPPINGS;i++)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync /* restore the folder mapping counter. */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync rc = SSMR3GetU32(pSSM, &FolderMapping[i].cMappings);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync /* Check the host path name. */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync if (len != ShflStringSizeOfBuffer(FolderMapping[i].pFolderName))
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync if (memcmp(FolderMapping[i].pFolderName, pName, len))
return VERR_SSM_UNEXPECTED_DATA;
return VERR_NO_MEMORY;
return VERR_SSM_UNEXPECTED_DATA;
return VINF_SUCCESS;
static DECLCALLBACK(void) svcCall (VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
Log(("svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
#ifdef DEBUG
uint32_t i;
for (i = 0; i < cParms; i++)
switch (u32Function)
case SHFL_FN_QUERY_MAPPINGS:
case SHFL_FN_QUERY_MAP_NAME:
case SHFL_FN_CREATE:
case SHFL_FN_CLOSE:
case SHFL_FN_READ:
case SHFL_FN_WRITE:
case SHFL_FN_LOCK:
case SHFL_FN_LIST:
case SHFL_FN_MAP_FOLDER:
case SHFL_FN_UNMAP_FOLDER:
case SHFL_FN_INFORMATION:
case SHFL_FN_REMOVE:
case SHFL_FN_RENAME:
case SHFL_FN_FLUSH:
case SHFL_FN_SET_UTF8:
if (!AsynchronousProcessing)
* We differentiate between a function handler for the guest and one for the host. The guest is not allowed to add or remove mappings for obvious security reasons.
static DECLCALLBACK(int) svcHostCall (uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
#ifdef DEBUG
uint32_t i;
for (i = 0; i < cParms; i++)
switch (u32Function)
case SHFL_FN_ADD_MAPPING:
case SHFL_FN_REMOVE_MAPPING:
return rc;
if (!ptable)
Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
return rc;