/** * Checks whether a shared folder share exists or not. * * @returns True if shared folder exists, false if not. * @param u32ClientId The client id returned by VbglR3InfoSvcConnect(). * @param pszShareName Shared folder name to check. */ VBGLR3DECL(bool) VbglR3SharedFolderExists(uint32_t u32ClientId, const char *pszShareName) { AssertPtr(pszShareName); uint32_t cMappings; VBGLR3SHAREDFOLDERMAPPING *paMappings; /** @todo Use some caching here? */ bool fFound = false; int rc = VbglR3SharedFolderGetMappings(u32ClientId, true /* Only process auto-mounted folders */, &paMappings, &cMappings); if (RT_SUCCESS(rc)) { for (uint32_t i = 0; i < cMappings && !fFound; i++) { char *pszName = NULL; rc = VbglR3SharedFolderGetName(u32ClientId, paMappings[i].u32Root, &pszName); if ( RT_SUCCESS(rc) && *pszName) { if (RTStrICmp(pszName, pszShareName) == 0) fFound = true; RTStrFree(pszName); } } VbglR3SharedFolderFreeMappings(paMappings); } return fFound; }
int VBoxSharedFoldersAutoMount(void) { uint32_t u32ClientId; int rc = VbglR3SharedFolderConnect(&u32ClientId); if (RT_SUCCESS(rc)) { uint32_t cMappings; VBGLR3SHAREDFOLDERMAPPING *paMappings; rc = VbglR3SharedFolderGetMappings(u32ClientId, true /* Only process auto-mounted folders */, &paMappings, &cMappings); if (RT_SUCCESS(rc)) { #if 0 /* Check for a fixed/virtual auto-mount share. */ if (VbglR3SharedFolderExists(u32ClientId, "vbsfAutoMount")) { LogFlowFunc(("Hosts supports auto-mount root\n")); } else { #endif LogFlowFunc(("Got %u shared folder mappings\n", cMappings)); for (uint32_t i = 0; i < cMappings && RT_SUCCESS(rc); i++) { char *pszName = NULL; rc = VbglR3SharedFolderGetName(u32ClientId, paMappings[i].u32Root, &pszName); if ( RT_SUCCESS(rc) && *pszName) { LogFlowFunc(("Connecting share %u (%s) ...\n", i+1, pszName)); char *pszShareName; if (RTStrAPrintf(&pszShareName, "\\\\vboxsrv\\%s", pszName) >= 0) { char chDrive = 'D'; /* Start probing whether drive D: is free to use. */ do { char szCurDrive[3]; RTStrPrintf(szCurDrive, sizeof(szCurDrive), "%c:", chDrive++); NETRESOURCE resource; RT_ZERO(resource); resource.dwType = RESOURCETYPE_ANY; resource.lpLocalName = TEXT(szCurDrive); resource.lpRemoteName = TEXT(pszShareName); /* Go straight to our network provider in order to get maximum lookup speed. */ resource.lpProvider = TEXT("VirtualBox Shared Folders"); /** @todo Figure out how to map the drives in a block (F,G,H, ...). Save the mapping for later use. */ DWORD dwErr = WNetAddConnection2A(&resource, NULL, NULL, 0); if (dwErr == NO_ERROR) { LogRel(("Shared folder \"%s\" was mounted to drive \"%s\"\n", pszName, szCurDrive)); break; } else { LogRel(("Mounting \"%s\" to \"%s\" resulted in dwErr = %ld\n", pszName, szCurDrive, dwErr)); switch (dwErr) { /* * The local device specified by the lpLocalName member is already * connected to a network resource. Try next drive ... */ case ERROR_ALREADY_ASSIGNED: break; default: LogRel(("Error while mounting shared folder \"%s\" to \"%s\", error = %ld\n", pszName, szCurDrive, dwErr)); break; } } } while (chDrive <= 'Z'); if (chDrive > 'Z') { LogRel(("No free driver letter found to assign shared folder \"%s\", aborting\n", pszName)); break; } RTStrFree(pszShareName); } else rc = VERR_NO_STR_MEMORY; RTStrFree(pszName); } else LogFlowFunc(("Error while getting the shared folder name for root node = %u, rc = %Rrc\n", paMappings[i].u32Root, rc)); } #if 0 } #endif VbglR3SharedFolderFreeMappings(paMappings); } else LogFlowFunc(("Error while getting the shared folder mappings, rc = %Rrc\n", rc)); VbglR3SharedFolderDisconnect(u32ClientId); } else { LogFlowFunc(("Failed to connect to the shared folder service, error %Rrc\n", rc)); /* return success, otherwise VBoxTray will not start! */ rc = VINF_SUCCESS; } return rc; }
/** @copydoc VBOXSERVICE::pfnWorker */ DECLCALLBACK(int) VBoxServiceAutoMountWorker(bool volatile *pfShutdown) { /* * Tell the control thread that it can continue * spawning services. */ RTThreadUserSignal(RTThreadSelf()); uint32_t cMappings; PVBGLR3SHAREDFOLDERMAPPING paMappings; int rc = VbglR3SharedFolderGetMappings(g_SharedFoldersSvcClientID, true /* Only process auto-mounted folders */, &paMappings, &cMappings); if ( RT_SUCCESS(rc) && cMappings) { char *pszMountDir; rc = VbglR3SharedFolderGetMountDir(&pszMountDir); if (rc == VERR_NOT_FOUND) rc = RTStrDupEx(&pszMountDir, VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR); if (RT_SUCCESS(rc)) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount dir set to \"%s\"\n", pszMountDir); char *pszSharePrefix; rc = VbglR3SharedFolderGetMountPrefix(&pszSharePrefix); if (RT_SUCCESS(rc)) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount prefix set to \"%s\"\n", pszSharePrefix); #ifdef USE_VIRTUAL_SHARES /* Check for a fixed/virtual auto-mount share. */ if (VbglR3SharedFolderExists(g_SharedFoldersSvcClientID, "vbsfAutoMount")) { VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Host supports auto-mount root\n"); } else { #endif VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Got %u shared folder mappings\n", cMappings); rc = VBoxServiceAutoMountProcessMappings(paMappings, cMappings, pszMountDir, pszSharePrefix, g_SharedFoldersSvcClientID); #ifdef USE_VIRTUAL_SHARES } #endif RTStrFree(pszSharePrefix); } /* Mount share prefix. */ else VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mount prefix, rc = %Rrc\n", rc); RTStrFree(pszMountDir); } else VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder directory, rc = %Rrc\n", rc); VbglR3SharedFolderFreeMappings(paMappings); } else if (RT_FAILURE(rc)) VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mappings, rc = %Rrc\n", rc); else VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: No shared folder mappings found\n"); /* * Because this thread is a one-timer at the moment we don't want to break/change * the semantics of the main thread's start/stop sub-threads handling. * * This thread exits so fast while doing its own startup in VBoxServiceStartServices() * that this->fShutdown flag is set to true in VBoxServiceThread() before we have the * chance to check for a service failure in VBoxServiceStartServices() to indicate * a VBoxService startup error. * * Therefore *no* service threads are allowed to quit themselves and need to wait * for the pfShutdown flag to be set by the main thread. */ for (;;) { /* Do we need to shutdown? */ if (*pfShutdown) break; /* Let's sleep for a bit and let others run ... */ RTThreadSleep(500); } RTSemEventMultiDestroy(g_AutoMountEvent); g_AutoMountEvent = NIL_RTSEMEVENTMULTI; VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Finished with rc=%Rrc\n", rc); return VINF_SUCCESS; }
int VBoxSharedFoldersAutoUnmount(void) { uint32_t u32ClientId; int rc = VbglR3SharedFolderConnect(&u32ClientId); if (!RT_SUCCESS(rc)) LogFlowFunc(("Failed to connect to the shared folder service, error %Rrc\n", rc)); else { uint32_t cMappings; VBGLR3SHAREDFOLDERMAPPING *paMappings; rc = VbglR3SharedFolderGetMappings(u32ClientId, true /* Only process auto-mounted folders */, &paMappings, &cMappings); if (RT_SUCCESS(rc)) { for (uint32_t i = 0; i < cMappings && RT_SUCCESS(rc); i++) { char *pszName = NULL; rc = VbglR3SharedFolderGetName(u32ClientId, paMappings[i].u32Root, &pszName); if ( RT_SUCCESS(rc) && *pszName) { LogFlowFunc(("Disconnecting share %u (%s) ...\n", i+1, pszName)); char *pszShareName; if (RTStrAPrintf(&pszShareName, "\\\\vboxsrv\\%s", pszName) >= 0) { DWORD dwErr = WNetCancelConnection2(pszShareName, 0, FALSE /* Force disconnect */); if (dwErr == NO_ERROR) { LogRel(("Share \"%s\" was disconnected\n", pszShareName)); RTStrFree(pszShareName); RTStrFree(pszName); break; } LogRel(("Disconnecting \"%s\" failed, dwErr = %ld\n", pszShareName, dwErr)); switch (dwErr) { case ERROR_NOT_CONNECTED: break; default: LogRel(("Error while disconnecting shared folder \"%s\", error = %ld\n", pszShareName, dwErr)); break; } RTStrFree(pszShareName); } else rc = VERR_NO_MEMORY; RTStrFree(pszName); } else LogFlowFunc(("Error while getting the shared folder name for root node = %u, rc = %Rrc\n", paMappings[i].u32Root, rc)); } VbglR3SharedFolderFreeMappings(paMappings); } else LogFlowFunc(("Error while getting the shared folder mappings, rc = %Rrc\n", rc)); VbglR3SharedFolderDisconnect(u32ClientId); } return rc; }