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