diff options
author | Felix Geyer <debfx-pkg@fobos.de> | 2010-08-06 21:27:11 +0200 |
---|---|---|
committer | Felix Geyer <debfx-pkg@fobos.de> | 2010-08-06 21:27:11 +0200 |
commit | adf97a4e6386ea334ce8d77f0cde3b92454b9fa5 (patch) | |
tree | 62a6d6e6a4743f2aa3e55fa0cdc850fb1d6a2eb9 | |
parent | 3cc524b669caddac0b3c8c8fd0b57eaff7f490eb (diff) | |
download | virtualbox-adf97a4e6386ea334ce8d77f0cde3b92454b9fa5.tar.gz |
Imported Upstream version 3.2.8-dfsgupstream/3.2.8-dfsg
146 files changed, 16819 insertions, 2092 deletions
diff --git a/Config.kmk b/Config.kmk index 1a7399a75..7c27b6da5 100644 --- a/Config.kmk +++ b/Config.kmk @@ -148,7 +148,7 @@ VBOX_VERSION_MINOR = 2 # This is the current build number. It should be increased every time we publish a # new build. The define is available in every source file. Only even build numbers # will be published, odd numbers are set during development. -VBOX_VERSION_BUILD = 6 +VBOX_VERSION_BUILD = 8 # Full version string (may include more than just x.y.z, but no spaces or other problematic chars). VBOX_VERSION_STRING = $(VBOX_VERSION_MAJOR).$(VBOX_VERSION_MINOR).$(VBOX_VERSION_BUILD) # Force the additions.sh script to get an exact additions build when we're doing the release. @@ -158,7 +158,7 @@ ifeq ($(int-mod $(VBOX_VERSION_BUILD),2),0) export VBOX_DOCUMENTATION_SH_MODE = release export VBOX_EFI_SH_MODE = release endif - + # Some info on the vendor VBOX_VENDOR = Oracle Corporation VBOX_VENDOR_SHORT = Oracle @@ -689,9 +689,7 @@ ifeq ($(KBUILD_TARGET),darwin) VBOX_WITH_VRDP_RDESKTOP= # Permanent (no working SDL). VBOX_WITH_VBOXSDL= - ifeq ($(KBUILD_TARGET_ARCH),amd64) - VBOX_WITH_VBOXBFE= - endif + VBOX_WITH_VBOXBFE= endif ifeq ($(KBUILD_TARGET),freebsd) @@ -4218,7 +4216,7 @@ endif SVN ?= svn$(HOSTSUFF_EXE) VBOX_SVN_REV_KMK = $(PATH_OUT)/revision.kmk ifndef VBOX_SVN_REV - VBOX_SVN_REV_FALLBACK := $(patsubst %:,, $Rev: 63112 $ ) + VBOX_SVN_REV_FALLBACK := $(patsubst %:,, $Rev: 64453 $ ) VBOX_SVN_DEP := $(wildcard $(PATH_ROOT)/.svn/entries) ifeq ($(which $(SVN)),) VBOX_SVN_DEP := @@ -1388,12 +1388,13 @@ extern "C" int main(void) dpy = XOpenDisplay(NULL); if (dpy) { - if (glXQueryVersion(dpy, &major, &minor)) + Bool glx_version = glXQueryVersion(dpy, &major, &minor); + XCloseDisplay(dpy); + if (glx_version) { printf("found version %u.%u, OK.\n", major, minor); return 0; } - XCloseDisplay(dpy); } printf("found (inactive), OK.\n"); return 0; diff --git a/configure.vbs b/configure.vbs index 6745811ba..8594f3868 100644 --- a/configure.vbs +++ b/configure.vbs @@ -9,16 +9,16 @@ '
'
-' Copyright (C) 2006-2007 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.
-'
+' Copyright (C) 2006-2007 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. +' '*****************************************************************************
diff --git a/include/VBox/VBoxGuestLib.h b/include/VBox/VBoxGuestLib.h index 389f4f7d1..60d98bd30 100644 --- a/include/VBox/VBoxGuestLib.h +++ b/include/VBox/VBoxGuestLib.h @@ -411,8 +411,12 @@ VBGLR3DECL(int) VbglR3PidFile(const char *pszPath, PRTFILE phFile); VBGLR3DECL(void) VbglR3ClosePidFile(const char *pszPath, RTFILE hFile); VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot); VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents); + +VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestStatusFacility Facility, VBoxGuestStatusCurrent StatusCurrent, uint32_t uFlags); VBGLR3DECL(int) VbglR3GetAdditionsVersion(char **ppszVer, char **ppszRev); VBGLR3DECL(int) VbglR3GetAdditionsInstallationPath(char **ppszPath); +VBGLR3DECL(int) VbglR3GetSessionId(uint64_t *pu64IdSession); + /** @} */ /** @name Shared clipboard @@ -559,6 +563,7 @@ VBGLR3DECL(int) VbglR3RegisterSharedModule(char *pszModuleName, char *pszVer VBGLR3DECL(int) VbglR3UnregisterSharedModule(char *pszModuleName, char *pszVersion, RTGCPTR64 GCBaseAddr, uint32_t cbModule); VBGLR3DECL(int) VbglR3CheckSharedModules(void); VBGLR3DECL(bool) VbglR3PageSharingIsEnabled(void); +VBGLR3DECL(int) VbglR3PageIsShared(RTGCPTR pPage, bool *pfShared, uint64_t *puPageFlags); /** @} */ #endif /* IN_RING3 */ diff --git a/include/VBox/VBoxHDD.h b/include/VBox/VBoxHDD.h index 6520c0d12..2745be1d7 100644 --- a/include/VBox/VBoxHDD.h +++ b/include/VBox/VBoxHDD.h @@ -168,11 +168,13 @@ typedef struct VBOXHDDRAW /** Open image for asynchronous access. * Only available if VD_CAP_ASYNC_IO is set * Check with VDIsAsynchonousIoSupported wether - * asynchronous I/O is really supported for this file. - */ + * asynchronous I/O is really supported for this file. */ #define VD_OPEN_FLAGS_ASYNC_IO RT_BIT(4) +/** Allow sharing of the image for writable images. May be ignored if the + * format backend doesn't support this type of concurrent access. */ +#define VD_OPEN_FLAGS_SHAREABLE RT_BIT(5) /** Mask of valid flags. */ -#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO) +#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE) /** @}*/ @@ -463,9 +465,11 @@ typedef DECLCALLBACK(int) FNVDCOMPLETED(void *pvUser, int rcReq); typedef FNVDCOMPLETED *PFNVDCOMPLETED; /** Open the storage readonly. */ -#define VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY RT_BIT(0) +#define VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY RT_BIT(0) /** Create the storage backend if it doesn't exist. */ -#define VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE RT_BIT(1) +#define VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE RT_BIT(1) +/** Don't write lock the opened file. */ +#define VD_INTERFACEASYNCIO_OPEN_FLAGS_DONT_LOCK RT_BIT(2) /** * Support interface for asynchronous I/O diff --git a/include/VBox/VMMDev.h b/include/VBox/VMMDev.h index c4936eeff..69af61d72 100644 --- a/include/VBox/VMMDev.h +++ b/include/VBox/VMMDev.h @@ -137,6 +137,7 @@ typedef enum VMMDevReq_CtlGuestFilterMask = 42, VMMDevReq_ReportGuestInfo = 50, VMMDevReq_ReportGuestInfo2 = 58, /* since version 3.2.0 */ + VMMDevReq_ReportGuestStatus = 59, /* since version 3.2.8 */ VMMDevReq_GetDisplayChangeRequest = 51, VMMDevReq_VideoModeSupported = 52, VMMDevReq_GetHeightReduction = 53, @@ -174,6 +175,8 @@ typedef enum VMMDevReq_UnregisterSharedModule = 213, VMMDevReq_CheckSharedModules = 214, VMMDevReq_GetPageSharingStatus = 215, + VMMDevReq_DebugIsPageShared = 216, + VMMDevReq_GetSessionId = 217, /* since version 3.2.8 */ VMMDevReq_SizeHack = 0x7fffffff } VMMDevRequestType; @@ -431,7 +434,7 @@ typedef struct } VMMDevReqGuestCapabilities2; AssertCompileSize(VMMDevReqGuestCapabilities2, 24+8); -/** @name Guest capability bits . +/** @name Guest capability bits. * Used by VMMDevReq_ReportGuestCapabilities and VMMDevReq_SetGuestCapabilities. * @{ */ /** The guest supports seamless display rendering. */ @@ -645,6 +648,67 @@ AssertCompileSize(VMMDevReportGuestInfo2, 24+144); /** + * Guest status facility. + */ +typedef enum +{ + VBoxGuestStatusFacility_Unknown = 0, + VBoxGuestStatusFacility_VBoxGuestDriver = 20, + VBoxGuestStatusFacility_VBoxService = 100, + VBoxGuestStatusFacility_VBoxTray = 101, + VBoxGuestStatusFacility_All = 999, + VBoxGuestStatusFacility_SizeHack = 0x7fffffff +} VBoxGuestStatusFacility; +AssertCompileSize(VBoxGuestStatusFacility, 4); + +/** + * The current guest status of a facility. + */ +typedef enum +{ + VBoxGuestStatusCurrent_Disabled = 0, + VBoxGuestStatusCurrent_Inactive = 1, + VBoxGuestStatusCurrent_PreInit = 20, + VBoxGuestStatusCurrent_Init = 30, + VBoxGuestStatusCurrent_Active = 50, + VBoxGuestStatusCurrent_Terminating = 100, + VBoxGuestStatusCurrent_Terminated = 101, + VBoxGuestStatusCurrent_SizeHack = 0x7fffffff +} VBoxGuestStatusCurrent; +AssertCompileSize(VBoxGuestStatusCurrent, 4); + +/** + * Guest status structure. + * + * Used by VMMDevReqGuestStatus. + */ +typedef struct VBoxGuestStatus +{ + /** Facility the status is indicated for. */ + VBoxGuestStatusFacility facility; + /** Current guest status. */ + VBoxGuestStatusCurrent status; + /** Flags, not used at the moment. */ + uint32_t flags; +} VBoxGuestStatus; +AssertCompileSize(VBoxGuestStatus, 12); + +/** + * Guest Additions status structure. + * + * Used by VMMDevReq_ReportGuestStatus. + */ +typedef struct +{ + /** Header. */ + VMMDevRequestHeader header; + /** Guest information. */ + VBoxGuestStatus guestStatus; +} VMMDevReportGuestStatus; +AssertCompileSize(VMMDevReportGuestStatus, 24+12); + + +/** * Guest statistics structure. * * Used by VMMDevReportGuestStats and PDMIVMMDEVCONNECTOR::pfnReportStatistics. @@ -1185,6 +1249,38 @@ typedef struct } VMMDevPageSharingStatusRequest; AssertCompileSize(VMMDevPageSharingStatusRequest, 24+4); + +/** + * Page sharing status query (debug build only) + */ +typedef struct +{ + /** Header. */ + VMMDevRequestHeader header; + /** Page address. */ + RTGCPTR GCPtrPage; + /** Page flags. */ + uint64_t uPageFlags; + /** Shared flag (out) */ + bool fShared; + /** Alignment */ + bool fAlignment[3]; +} VMMDevPageIsSharedRequest; + +/** + * Session id request structure. + * + * Used by VMMDevReq_GetSessionId. + */ +typedef struct +{ + /** Header */ + VMMDevRequestHeader header; + /** OUT: unique session id; the id will be different after each start, reset or restore of the VM */ + uint64_t idSession; +} VMMDevReqSessionId; +AssertCompileSize(VMMDevReqSessionId, 24+8); + #pragma pack() @@ -1630,6 +1726,8 @@ DECLINLINE(size_t) vmmdevGetRequestSize(VMMDevRequestType requestType) return sizeof(VMMDevReportGuestInfo); case VMMDevReq_ReportGuestInfo2: return sizeof(VMMDevReportGuestInfo2); + case VMMDevReq_ReportGuestStatus: + return sizeof(VMMDevReportGuestStatus); case VMMDevReq_GetDisplayChangeRequest: return sizeof(VMMDevDisplayChangeRequest); case VMMDevReq_GetDisplayChangeRequest2: @@ -1695,7 +1793,10 @@ DECLINLINE(size_t) vmmdevGetRequestSize(VMMDevRequestType requestType) return sizeof(VMMDevSharedModuleCheckRequest); case VMMDevReq_GetPageSharingStatus: return sizeof(VMMDevPageSharingStatusRequest); - + case VMMDevReq_DebugIsPageShared: + return sizeof(VMMDevPageIsSharedRequest); + case VMMDevReq_GetSessionId: + return sizeof(VMMDevReqSessionId); default: return 0; } diff --git a/include/VBox/com/AutoLock.h b/include/VBox/com/AutoLock.h index f5a12f784..3b6181eb6 100644 --- a/include/VBox/com/AutoLock.h +++ b/include/VBox/com/AutoLock.h @@ -65,21 +65,22 @@ namespace util enum VBoxLockingClass { LOCKCLASS_NONE = 0, - LOCKCLASS_VIRTUALBOXOBJECT = 1, // highest order: VirtualBox object lock - LOCKCLASS_HOSTOBJECT = 2, // Host object lock - LOCKCLASS_LISTOFMACHINES = 3, // list of machines in VirtualBox object - LOCKCLASS_MACHINEOBJECT = 4, // Machine object lock - LOCKCLASS_SNAPSHOTOBJECT = 5, // snapshot object locks + LOCKCLASS_WEBSERVICE = 1, // highest order: webservice locks + LOCKCLASS_VIRTUALBOXOBJECT = 2, // highest order within Main itself: VirtualBox object lock + LOCKCLASS_HOSTOBJECT = 3, // Host object lock + LOCKCLASS_LISTOFMACHINES = 4, // list of machines in VirtualBox object + LOCKCLASS_MACHINEOBJECT = 5, // Machine object lock + LOCKCLASS_SNAPSHOTOBJECT = 6, // snapshot object locks // (the snapshots tree, including the child pointers in Snapshot, // is protected by the normal Machine object lock) - LOCKCLASS_LISTOFMEDIA = 6, // list of media (hard disks, DVDs, floppies) in VirtualBox object - LOCKCLASS_LISTOFOTHEROBJECTS = 7, // any other list of objects - LOCKCLASS_OTHEROBJECT = 8, // any regular object member variable lock - LOCKCLASS_USBLIST = 9, // temporary hack to avoid having to clean up the USB filters + LOCKCLASS_LISTOFMEDIA = 7, // list of media (hard disks, DVDs, floppies) in VirtualBox object + LOCKCLASS_LISTOFOTHEROBJECTS = 8, // any other list of objects + LOCKCLASS_OTHEROBJECT = 9, // any regular object member variable lock + LOCKCLASS_USBLIST = 10, // temporary hack to avoid having to clean up the USB filters // too much @todo r=dj get rid of this! - LOCKCLASS_PROGRESSLIST = 10, // list of progress objects in VirtualBox; no other object lock + LOCKCLASS_PROGRESSLIST = 11, // list of progress objects in VirtualBox; no other object lock // may be held after this! - LOCKCLASS_OBJECTSTATE = 11 // object state lock (handled by AutoCaller classes) + LOCKCLASS_OBJECTSTATE = 12 // object state lock (handled by AutoCaller classes) }; void InitAutoLockSystem(); diff --git a/include/VBox/err.h b/include/VBox/err.h index a8923f634..0612d664e 100644 --- a/include/VBox/err.h +++ b/include/VBox/err.h @@ -680,6 +680,8 @@ #define VERR_VM_DRIVER_VERSION_MISMATCH (-1912) /** Saving the VM state is temporarily not allowed. Try again later. */ #define VERR_VM_SAVE_STATE_NOT_ALLOWED (-1913) +/** An EMT called an API which cannot be called on such a thread. */ +#define VERR_VM_THREAD_IS_EMT (-1914) /** @} */ diff --git a/include/VBox/gmm.h b/include/VBox/gmm.h index d4069d936..6363d71a9 100644 --- a/include/VBox/gmm.h +++ b/include/VBox/gmm.h @@ -298,13 +298,10 @@ GMMR0DECL(int) GMMR0SeedChunk(PVM pVM, VMCPUID idCpu, RTR3PTR pvR3); GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule, unsigned cRegions, VMMDEVSHAREDREGIONDESC *pRegions); GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule); GMMR0DECL(int) GMMR0UnregisterAllSharedModules(PVM pVM, VMCPUID idCpu); -GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu); +GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu); GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu); -#ifdef LOG_ENABLED -GMMR0DECL(int) GMMR0CheckSharedModulesStart(PVM pVM); -GMMR0DECL(int) GMMR0CheckSharedModulesEnd(PVM pVM); -#endif - +GMMR0DECL(int) GMMR0CheckSharedModulesStart(PVM pVM); +GMMR0DECL(int) GMMR0CheckSharedModulesEnd(PVM pVM); /** * Request buffer for GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION. @@ -561,7 +558,7 @@ typedef struct GMMSHAREDPAGEDESC /** Pointer to a GMMSHAREDPAGEDESC. */ typedef GMMSHAREDPAGEDESC *PGMMSHAREDPAGEDESC; -GMMR0DECL(int) GMMR0SharedModuleCheckRange(PGVM pGVM, PGMMSHAREDMODULE pModule, unsigned idxRegion, unsigned cPages, PGMMSHAREDPAGEDESC paPageDesc); +GMMR0DECL(int) GMMR0SharedModuleCheckPage(PGVM pGVM, PGMMSHAREDMODULE pModule, unsigned idxRegion, unsigned idxPage, PGMMSHAREDPAGEDESC pPageDesc); /** * Request buffer for GMMR0UnregisterSharedModuleReq / VMMR0_DO_GMM_UNREGISTER_SHARED_MODULE. @@ -587,6 +584,25 @@ typedef GMMUNREGISTERSHAREDMODULEREQ *PGMMUNREGISTERSHAREDMODULEREQ; GMMR0DECL(int) GMMR0UnregisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMUNREGISTERSHAREDMODULEREQ pReq); +#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 +/** + * Request buffer for GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE. + * @see GMMR0FindDuplicatePage. + */ +typedef struct GMMFINDDUPLICATEPAGEREQ +{ + /** The header. */ + SUPVMMR0REQHDR Hdr; + /** Page id. */ + uint32_t idPage; + /** Duplicate flag (out) */ + bool fDuplicate; +} GMMFINDDUPLICATEPAGEREQ; +/** Pointer to a GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE request buffer. */ +typedef GMMFINDDUPLICATEPAGEREQ *PGMMFINDDUPLICATEPAGEREQ; + +GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq); +#endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */ #ifdef IN_RING3 /** @defgroup grp_gmm_r3 The Global Memory Manager Ring-3 API Wrappers @@ -615,6 +631,11 @@ GMMR3DECL(int) GMMR3RegisterSharedModule(PVM pVM, PGMMREGISTERSHAREDMODULEREQ p GMMR3DECL(int) GMMR3UnregisterSharedModule(PVM pVM, PGMMUNREGISTERSHAREDMODULEREQ pReq); GMMR3DECL(int) GMMR3CheckSharedModules(PVM pVM); GMMR3DECL(int) GMMR3ResetSharedModules(PVM pVM); + +# if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 +GMMR3DECL(bool) GMMR3IsDuplicatePage(PVM pVM, uint32_t idPage); +# endif + /** @} */ #endif /* IN_RING3 */ diff --git a/include/VBox/pdmasynccompletion.h b/include/VBox/pdmasynccompletion.h index d439e24c8..dfd32d268 100644 --- a/include/VBox/pdmasynccompletion.h +++ b/include/VBox/pdmasynccompletion.h @@ -230,6 +230,12 @@ VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT #define PDMACEP_FILE_FLAGS_READ_ONLY RT_BIT_32(0) /** whether file content should be cached by the endpoint. */ #define PDMACEP_FILE_FLAGS_CACHING RT_BIT_32(1) +/** Whether the file should not be write protected. + * The default is to protect the file against writes by other processes + * when opened in read/write mode to prevent data corruption by + * concurrent access which can occur if the local writeback cache is enabled. + */ +#define PDMACEP_FILE_FLAGS_DONT_LOCK RT_BIT_32(2) /** @} */ /** diff --git a/include/VBox/pdmifs.h b/include/VBox/pdmifs.h index 033e88a48..830826dd4 100644 --- a/include/VBox/pdmifs.h +++ b/include/VBox/pdmifs.h @@ -2070,13 +2070,15 @@ typedef struct PDMIHPETLEGACYNOTIFY #define VMMDEV_SETCREDENTIALS_JUDGE RT_BIT(15) /** @} */ - -/** Forward declaration of the video accelerator command memory. */ -struct VBVAMEMORY; /** Forward declaration of the guest information structure. */ struct VBoxGuestInfo; /** Forward declaration of the guest statistics structure */ struct VBoxGuestStatistics; +/** Forward declaration of the guest status structure */ +struct VBoxGuestStatus; + +/** Forward declaration of the video accelerator command memory. */ +struct VBVAMEMORY; /** Pointer to video accelerator command memory. */ typedef struct VBVAMEMORY *PVBVAMEMORY; @@ -2089,14 +2091,24 @@ typedef struct PDMIVMMDEVCONNECTOR *PPDMIVMMDEVCONNECTOR; typedef struct PDMIVMMDEVCONNECTOR { /** - * Report guest OS version. - * Called whenever the Additions issue a guest version report request. + * Reports the guest status. + * Called whenever the Additions issue a guest status report request. + * + * @param pInterface Pointer to this interface. + * @param pGuestStatus Pointer to guest information structure + * @thread The emulation thread. + */ + DECLR3CALLBACKMEMBER(void, pfnUpdateGuestStatus,(PPDMIVMMDEVCONNECTOR pInterface, const struct VBoxGuestStatus *pGuestStatus)); + + /** + * Reports the guest API and OS version. + * Called whenever the Additions issue a guest info report request. * * @param pInterface Pointer to this interface. * @param pGuestInfo Pointer to guest information structure * @thread The emulation thread. */ - DECLR3CALLBACKMEMBER(void, pfnUpdateGuestVersion,(PPDMIVMMDEVCONNECTOR pInterface, struct VBoxGuestInfo *pGuestInfo)); + DECLR3CALLBACKMEMBER(void, pfnUpdateGuestInfo,(PPDMIVMMDEVCONNECTOR pInterface, const struct VBoxGuestInfo *pGuestInfo)); /** * Update the guest additions capabilities. diff --git a/include/VBox/pdmnetinline.h b/include/VBox/pdmnetinline.h index 9864edc1c..b15c1ee4b 100644 --- a/include/VBox/pdmnetinline.h +++ b/include/VBox/pdmnetinline.h @@ -39,6 +39,21 @@ #include <iprt/string.h> +/** + * Checksum type. + */ +typedef enum PDMNETCSUMTYPE +{ + /** No checksum. */ + PDMNETCSUMTYPE_NONE = 0, + /** Normal TCP checksum. */ + PDMNETCSUMTYPE_COMPLETE, + /** Checksum on pseudo header (used with GSO). */ + PDMNETCSUMTYPE_PSEUDO, + /** The usual 32-bit hack. */ + PDMNETCSUMTYPE_32_BIT_HACK = 0x7fffffff +} PDMNETCSUMTYPE; + /** * Validates the GSO context. @@ -162,15 +177,31 @@ DECLINLINE(uint8_t) pgmNetGsoCalcIpv6Offset(uint8_t *pbSegHdrs, uint8_t offIPv4H * @param pbPayload Pointer to the payload bytes. * @param cbPayload The amount of payload. * @param cbHdrs The size of all the headers. - * @param fPayloadChecksum Whether to checksum the payload or not. + * @param enmCsumType Whether to checksum the payload, the pseudo + * header or nothing. * @internal */ DECLINLINE(void) pdmNetGsoUpdateUdpHdr(uint32_t u32PseudoSum, uint8_t *pbSegHdrs, uint8_t offUdpHdr, - uint8_t const *pbPayload, uint32_t cbPayload, uint8_t cbHdrs, bool fPayloadChecksum) + uint8_t const *pbPayload, uint32_t cbPayload, uint8_t cbHdrs, + PDMNETCSUMTYPE enmCsumType) { PRTNETUDP pUdpHdr = (PRTNETUDP)&pbSegHdrs[offUdpHdr]; pUdpHdr->uh_ulen = cbPayload + cbHdrs - offUdpHdr; - pUdpHdr->uh_sum = fPayloadChecksum ? RTNetUDPChecksum(u32PseudoSum, pUdpHdr) : 0; + switch (enmCsumType) + { + case PDMNETCSUMTYPE_NONE: + pUdpHdr->uh_sum = 0; + break; + case PDMNETCSUMTYPE_COMPLETE: + pUdpHdr->uh_sum = RTNetUDPChecksum(u32PseudoSum, pUdpHdr); + break; + case PDMNETCSUMTYPE_PSEUDO: + pUdpHdr->uh_sum = ~RTNetIPv4FinalizeChecksum(u32PseudoSum); + break; + default: + AssertFailed(); + break; + } } @@ -187,18 +218,33 @@ DECLINLINE(void) pdmNetGsoUpdateUdpHdr(uint32_t u32PseudoSum, uint8_t *pbSegHdrs * immediately after the TCP header w/ options. * @param cbHdrs The size of all the headers. * @param fLastSeg Set if this is the last segment. - * @param fPayloadChecksum Whether to checksum the payload or not. + * @param enmCsumType Whether to checksum the payload, the pseudo + * header or nothing. * @internal */ DECLINLINE(void) pdmNetGsoUpdateTcpHdr(uint32_t u32PseudoSum, uint8_t *pbSegHdrs, uint8_t offTcpHdr, uint8_t const *pbPayload, uint32_t cbPayload, uint32_t offPayload, uint8_t cbHdrs, - bool fLastSeg, bool fPayloadChecksum) + bool fLastSeg, PDMNETCSUMTYPE enmCsumType) { PRTNETTCP pTcpHdr = (PRTNETTCP)&pbSegHdrs[offTcpHdr]; pTcpHdr->th_seq = RT_H2N_U32(RT_N2H_U32(pTcpHdr->th_seq) + offPayload); if (!fLastSeg) pTcpHdr->th_flags &= ~(RTNETTCP_F_FIN | RTNETTCP_F_PSH); - pTcpHdr->th_sum = fPayloadChecksum ? RTNetTCPChecksum(u32PseudoSum, pTcpHdr, pbPayload, cbPayload) : 0; + switch (enmCsumType) + { + case PDMNETCSUMTYPE_NONE: + pTcpHdr->th_sum = 0; + break; + case PDMNETCSUMTYPE_COMPLETE: + pTcpHdr->th_sum = RTNetTCPChecksum(u32PseudoSum, pTcpHdr, pbPayload, cbPayload); + break; + case PDMNETCSUMTYPE_PSEUDO: + pTcpHdr->th_sum = ~RTNetIPv4FinalizeChecksum(u32PseudoSum); + break; + default: + AssertFailed(); + break; + } } @@ -305,35 +351,35 @@ DECLINLINE(void *) PDMNetGsoCarveSegmentQD(PCPDMNETWORKGSO pGso, uint8_t *pbFram case PDMNETWORKGSOTYPE_IPV4_TCP: pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs), pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, - pGso->cbHdrs, iSeg + 1 == cSegs, true); + pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV4_UDP: pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs), - pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true); + pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV6_TCP: pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, - pGso->cbHdrs, iSeg + 1 == cSegs, true); + pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV6_UDP: pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), - pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true); + pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP: pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs); pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1), cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, - pGso->cbHdrs, iSeg + 1 == cSegs, true); + pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP: pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs); pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1), cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), - pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true); + pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_INVALID: case PDMNETWORKGSOTYPE_END: @@ -398,35 +444,35 @@ DECLINLINE(uint32_t) PDMNetGsoCarveSegment(PCPDMNETWORKGSO pGso, const uint8_t * case PDMNETWORKGSOTYPE_IPV4_TCP: pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs), pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, - pGso->cbHdrs, iSeg + 1 == cSegs, true); + pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV4_UDP: pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs), - pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true); + pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV6_TCP: pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, - pGso->cbHdrs, iSeg + 1 == cSegs, true); + pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV6_UDP: pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), - pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true); + pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP: pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs); pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1), cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg, - pGso->cbHdrs, iSeg + 1 == cSegs, true); + pGso->cbHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP: pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrs); pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1), cbSegPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), - pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, true); + pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrs, PDMNETCSUMTYPE_COMPLETE); break; case PDMNETWORKGSOTYPE_INVALID: case PDMNETWORKGSOTYPE_END: @@ -445,9 +491,10 @@ DECLINLINE(uint32_t) PDMNetGsoCarveSegment(PCPDMNETWORKGSO pGso, const uint8_t * * @param pGso The GSO context. * @param pvFrame The frame to prepare. * @param cbFrame The frame size. - * @param fPayloadChecksum Whether to checksum payload. + * @param enmCsumType Whether to checksum the payload, the pseudo + * header or nothing. */ -DECLINLINE(void) PDMNetGsoPrepForDirectUse(PCPDMNETWORKGSO pGso, void *pvFrame, size_t cbFrame, bool fPayloadChecksum) +DECLINLINE(void) PDMNetGsoPrepForDirectUse(PCPDMNETWORKGSO pGso, void *pvFrame, size_t cbFrame, PDMNETCSUMTYPE enmCsumType) { /* * Figure out where the payload is and where the header starts before we @@ -470,33 +517,33 @@ DECLINLINE(void) PDMNetGsoPrepForDirectUse(PCPDMNETWORKGSO pGso, void *pvFrame, { case PDMNETWORKGSOTYPE_IPV4_TCP: pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbFrame32 - pGso->cbHdrs, 0, pGso->cbHdrs), - pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, fPayloadChecksum); + pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, enmCsumType); break; case PDMNETWORKGSOTYPE_IPV4_UDP: pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbFrame32 - pGso->cbHdrs, 0, pGso->cbHdrs), - pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, fPayloadChecksum); + pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, enmCsumType); break; case PDMNETWORKGSOTYPE_IPV6_TCP: pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pGso->offHdr1, cbPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), - pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, fPayloadChecksum); + pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, enmCsumType); break; case PDMNETWORKGSOTYPE_IPV6_UDP: pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pGso->offHdr1, cbPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), - pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, fPayloadChecksum); + pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, enmCsumType); break; case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP: pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbPayload, 0, pGso->cbHdrs); pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pgmNetGsoCalcIpv6Offset(pbHdrs, pGso->offHdr1), cbPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP), - pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, fPayloadChecksum); + pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrs, true, enmCsumType); break; case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP: pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbPayload, 0, pGso->cbHdrs); pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pgmNetGsoCalcIpv6Offset(pbHdrs, pGso->offHdr1), cbPayload, pGso->cbHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP), - pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, fPayloadChecksum); + pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrs, enmCsumType); break; case PDMNETWORKGSOTYPE_INVALID: case PDMNETWORKGSOTYPE_END: diff --git a/include/VBox/settings.h b/include/VBox/settings.h index ca48fc0c0..fe758b541 100644 --- a/include/VBox/settings.h +++ b/include/VBox/settings.h @@ -882,6 +882,9 @@ public: uint32_t fl, std::list<xml::ElementNode*> *pllElementsWithUuidAttributes); + static bool isAudioDriverAllowedOnThisHost(AudioDriverType_T drv); + static AudioDriverType_T getHostDefaultAudioDriver(); + private: void readNetworkAdapters(const xml::ElementNode &elmHardware, NetworkAdaptersList &ll); void readAttachedNetworkMode(const xml::ElementNode &pelmMode, bool fEnabled, NetworkAdapter &nic); @@ -889,6 +892,7 @@ private: void readCpuTree(const xml::ElementNode &elmCpu, CpuList &ll); void readSerialPorts(const xml::ElementNode &elmUART, SerialPortsList &ll); void readParallelPorts(const xml::ElementNode &elmLPT, ParallelPortsList &ll); + void readAudioAdapter(const xml::ElementNode &elmAudioAdapter, AudioAdapter &aa); void readGuestProperties(const xml::ElementNode &elmGuestProperties, Hardware &hw); void readStorageControllerAttributes(const xml::ElementNode &elmStorageController, StorageController &sctl); void readHardware(const xml::ElementNode &elmHardware, Hardware &hw, Storage &strg); diff --git a/include/VBox/vm.h b/include/VBox/vm.h index 3d1e7493c..4a2cd6f79 100644 --- a/include/VBox/vm.h +++ b/include/VBox/vm.h @@ -101,6 +101,8 @@ typedef struct VMCPU VMCPUID idCpu; /** The native thread handle. */ RTNATIVETHREAD hNativeThread; + /** The native R0 thread handle. (different from the R3 handle!) */ + RTNATIVETHREAD hNativeThreadR0; /** Which host CPU ID is this EMT running on. * Only valid when in RC or HWACCMR0 with scheduling disabled. */ RTCPUID volatile idHostCpu; @@ -113,7 +115,7 @@ typedef struct VMCPU * data could be lumped together at the end with a < 64 byte padding * following it (to grow into and align the struct size). * */ - uint8_t abAlignment1[HC_ARCH_BITS == 32 ? 28 : 12]; + uint8_t abAlignment1[HC_ARCH_BITS == 32 ? 24 : 4]; /** CPUM part. */ union @@ -269,14 +271,17 @@ typedef struct VMCPU /** This action forces the VM to service pending requests from other * thread or requests which must be executed in another context. */ #define VM_FF_REQUEST RT_BIT_32(9) -/** Terminate the VM immediately. */ -#define VM_FF_TERMINATE RT_BIT_32(10) +/** Check for VM state changes and take appropriate action. */ +#define VM_FF_CHECK_VM_STATE RT_BIT_32(VM_FF_CHECK_VM_STATE_BIT) +/** The bit number for VM_FF_CHECK_VM_STATE. */ +#define VM_FF_CHECK_VM_STATE_BIT 10 /** Reset the VM. (postponed) */ #define VM_FF_RESET RT_BIT_32(VM_FF_RESET_BIT) /** The bit number for VM_FF_RESET. */ #define VM_FF_RESET_BIT 11 /** EMT rendezvous in VMM. */ #define VM_FF_EMT_RENDEZVOUS RT_BIT_32(VM_FF_EMT_RENDEZVOUS_BIT) +/** The bit number for VM_FF_EMT_RENDEZVOUS. */ #define VM_FF_EMT_RENDEZVOUS_BIT 12 /** PGM needs to allocate handy pages. */ @@ -345,18 +350,19 @@ typedef struct VMCPU #define VMCPU_FF_TO_R3 RT_BIT_32(28) /** Externally VM forced actions. Used to quit the idle/wait loop. */ -#define VM_FF_EXTERNAL_SUSPENDED_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_REQUEST | VM_FF_EMT_RENDEZVOUS) +#define VM_FF_EXTERNAL_SUSPENDED_MASK (VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_REQUEST | VM_FF_EMT_RENDEZVOUS) /** Externally VMCPU forced actions. Used to quit the idle/wait loop. */ #define VMCPU_FF_EXTERNAL_SUSPENDED_MASK (VMCPU_FF_REQUEST) /** Externally forced VM actions. Used to quit the idle/wait loop. */ -#define VM_FF_EXTERNAL_HALTED_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_EMT_RENDEZVOUS) +#define VM_FF_EXTERNAL_HALTED_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_REQUEST \ + | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_EMT_RENDEZVOUS) /** Externally forced VMCPU actions. Used to quit the idle/wait loop. */ #define VMCPU_FF_EXTERNAL_HALTED_MASK (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST | VMCPU_FF_TIMER) /** High priority VM pre-execution actions. */ -#define VM_FF_HIGH_PRIORITY_PRE_MASK ( VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_TM_VIRTUAL_SYNC | VM_FF_DEBUG_SUSPEND \ - | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS) +#define VM_FF_HIGH_PRIORITY_PRE_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_TM_VIRTUAL_SYNC \ + | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS) /** High priority VMCPU pre-execution actions. */ #define VMCPU_FF_HIGH_PRIORITY_PRE_MASK ( VMCPU_FF_TIMER | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_PGM_SYNC_CR3 \ | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \ @@ -374,7 +380,8 @@ typedef struct VMCPU #define VMCPU_FF_HIGH_PRIORITY_POST_MASK (VMCPU_FF_PDM_CRITSECT|VMCPU_FF_CSAM_PENDING_ACTION) /** Normal priority VM post-execution actions. */ -#define VM_FF_NORMAL_PRIORITY_POST_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS) +#define VM_FF_NORMAL_PRIORITY_POST_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_RESET \ + | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS) /** Normal priority VMCPU post-execution actions. */ #define VMCPU_FF_NORMAL_PRIORITY_POST_MASK (VMCPU_FF_CSAM_SCAN_PAGE) diff --git a/include/VBox/vm.mac b/include/VBox/vm.mac index b92cc003f..76a35b5ab 100644 --- a/include/VBox/vm.mac +++ b/include/VBox/vm.mac @@ -118,6 +118,7 @@ struc VMCPU .idCpu resd 1 .hNativeThread RTR0PTR_RES 1 + .hNativeThreadR0 RTR0PTR_RES 1 .idHostCpu resd 1 alignb 64 diff --git a/include/iprt/sg.h b/include/iprt/sg.h index f9e45aca2..c0c68dac0 100644 --- a/include/iprt/sg.h +++ b/include/iprt/sg.h @@ -55,13 +55,13 @@ typedef PRTSGSEG *PPRTSGSEG; typedef struct RTSGBUF { /** Pointer to the scatter/gather array. */ - PCRTSGSEG pcaSeg; + PCRTSGSEG paSegs; /** Number of segments. */ - unsigned cSeg; + unsigned cSegs; /** Current segment we are in. */ unsigned idxSeg; /** Pointer to the current segment start. */ - void *pvSegCurr; + void *pvSegCur; /** Number of bytes left in the current buffer. */ size_t cbSegLeft; } RTSGBUF; @@ -77,10 +77,10 @@ typedef PRTSGBUF *PPRTSGBUF; * * @returns nothing. * @param pSgBuf Pointer to the S/G buffer to initialize. - * @param pcaSeg Pointer to the start of the segment array. - * @param cSeg Number of segments in the array. + * @param paSegs Pointer to the start of the segment array. + * @param cSegs Number of segments in the array. */ -RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG pcaSeg, unsigned cSeg); +RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG paSegs, size_t cSegs); /** * Resets the internal buffer position of the S/G buffer to the beginning. diff --git a/include/iprt/socket.h b/include/iprt/socket.h index cf312071f..6ea2b9b6f 100644 --- a/include/iprt/socket.h +++ b/include/iprt/socket.h @@ -187,6 +187,44 @@ RTDECL(int) RTSocketGetPeerAddress(RTSOCKET hSocket, PRTNETADDR pAddr); */ RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf); +/** + * Send data from multiple buffers to a socket. + * + * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls + * for lazy coders. The "L" in the function name is short for "list" just like + * in the execl libc API. + * + * @returns IPRT status code. + * @retval VERR_INTERRUPTED if interrupted before anything was written. + * + * @param hSocket The socket handle. + * @param cSegs The number of data segments in the following + * ellipsis. + * @param ... Pairs of buffer pointers (void const *) and buffer + * sizes (size_t). Make 101% sure the pointer is + * really size_t. + */ +RTDECL(int) RTSocketSgWriteL(RTSOCKET hSocket, size_t cSegs, ...); + +/** + * Send data from multiple buffers to a socket. + * + * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls + * for lazy coders. The "L" in the function name is short for "list" just like + * in the execl libc API. + * + * @returns IPRT status code. + * @retval VERR_INTERRUPTED if interrupted before anything was written. + * + * @param hSocket The socket handle. + * @param cSegs The number of data segments in the following + * argument list. + * @param va Pairs of buffer pointers (void const *) and buffer + * sizes (size_t). Make 101% sure the pointer is + * really size_t. + */ +RTDECL(int) RTSocketSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va); + /** @} */ RT_C_DECLS_END diff --git a/include/iprt/string.h b/include/iprt/string.h index 4d30b8dd5..33e496d9d 100644 --- a/include/iprt/string.h +++ b/include/iprt/string.h @@ -379,6 +379,14 @@ RTDECL(int) RTStrValidateEncodingEx(const char *psz, size_t cch, uint32_t fFlags RTDECL(bool) RTStrIsValidEncoding(const char *psz); /** + * Purge all bad UTF-8 encoding in the string, replacing it with '?'. + * + * @returns The number of bad characters (0 if nothing was done). + * @param psz The string to purge. + */ +RTDECL(size_t) RTStrPurgeEncoding(char *psz); + +/** * Gets the number of code points the string is made up of, excluding * the terminator. * @@ -516,7 +524,8 @@ RTDECL(RTUNICP) RTStrGetCpInternal(const char *psz); * * @returns iprt status code * @returns VERR_INVALID_UTF8_ENCODING if the encoding is invalid. - * @param ppsz The string. + * @param ppsz The string cursor. + * This is advanced one character forward on failure. * @param pCp Where to store the unicode code point. * Stores RTUNICP_INVALID if the encoding is invalid. */ @@ -582,6 +591,7 @@ DECLINLINE(RTUNICP) RTStrGetCp(const char *psz) * @returns iprt status code. * @param ppsz Pointer to the string pointer. This will be updated to * point to the char following the current code point. + * This is advanced one character forward on failure. * @param pCp Where to store the code point. * RTUNICP_INVALID is stored here on failure. * diff --git a/include/iprt/tcp.h b/include/iprt/tcp.h index 32676650b..1e031caa1 100644 --- a/include/iprt/tcp.h +++ b/include/iprt/tcp.h @@ -291,6 +291,45 @@ RTR3DECL(int) RTTcpGetPeerAddress(RTSOCKET Sock, PRTNETADDR pAddr); */ RTR3DECL(int) RTTcpSgWrite(RTSOCKET Sock, PCRTSGBUF pSgBuf); + +/** + * Send data from multiple buffers to a socket. + * + * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls + * for lazy coders. The "L" in the function name is short for "list" just like + * in the execl libc API. + * + * @returns IPRT status code. + * @retval VERR_INTERRUPTED if interrupted before anything was written. + * + * @param hSocket The socket handle. + * @param cSegs The number of data segments in the following + * ellipsis. + * @param ... Pairs of buffer pointers (void const *) and buffer + * sizes (size_t). Make 101% sure the pointer is + * really size_t. + */ +RTR3DECL(int) RTTcpSgWriteL(RTSOCKET hSocket, size_t cSegs, ...); + +/** + * Send data from multiple buffers to a socket. + * + * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls + * for lazy coders. The "L" in the function name is short for "list" just like + * in the execl libc API. + * + * @returns IPRT status code. + * @retval VERR_INTERRUPTED if interrupted before anything was written. + * + * @param hSocket The socket handle. + * @param cSegs The number of data segments in the following + * argument list. + * @param va Pairs of buffer pointers (void const *) and buffer + * sizes (size_t). Make 101% sure the pointer is + * really size_t. + */ +RTR3DECL(int) RTTcpSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va); + /** @} */ RT_C_DECLS_END diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp index ab85e2c25..01d9e5bd4 100644 --- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp +++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp @@ -262,6 +262,9 @@ static int vboxGuestSetFilterMask(PVBOXGUESTDEVEXT pDevExt, uint32_t fMask) */ static int vboxGuestInitReportGuestInfo(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enmOSType) { + /* + * Report general info + capabilities to host. + */ VMMDevReportGuestInfo *pReq; int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo); if (RT_SUCCESS(rc)) @@ -285,12 +288,33 @@ static int vboxGuestInitReportGuestInfo(PVBOXGUESTDEVEXT pDevExt, VBOXOSTYPE enm pReq2->guestInfo.additionsFeatures = 0; RTStrCopy(pReq2->guestInfo.szName, sizeof(pReq2->guestInfo.szName), VBOX_VERSION_STRING); rc = VbglGRPerform(&pReq2->header); - if (rc == VERR_NOT_IMPLEMENTED) /* compatibility with older hosts */ + if (rc == VERR_NOT_IMPLEMENTED) /* Compatibility with older hosts. */ rc = VINF_SUCCESS; if (RT_FAILURE(rc)) LogRel(("vboxGuestInitReportGuestInfo: 2nd part failed with rc=%Rrc\n", rc)); VbglGRFree(&pReq2->header); } + + /* + * Report guest status to host. Because the host set the "Guest Additions active" flag as soon + * as he received the VMMDevReportGuestInfo above to make sure all is compatible with older Guest + * Additions we now have to disable that flag again here (too early, VBoxService and friends need + * to start up first). + */ + VMMDevReportGuestStatus *pReq3; + rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq3, sizeof(*pReq3), VMMDevReq_ReportGuestStatus); + if (RT_SUCCESS(rc)) + { + pReq3->guestStatus.facility = VBoxGuestStatusFacility_VBoxGuestDriver; + pReq3->guestStatus.status = VBoxGuestStatusCurrent_Active; /** @todo Are we actually *really* active at this point? */ + pReq3->guestStatus.flags = 0; + rc = VbglGRPerform(&pReq3->header); + if (rc == VERR_NOT_IMPLEMENTED) /* Compatibility with older hosts. */ + rc = VINF_SUCCESS; + if (RT_FAILURE(rc)) + LogRel(("vboxGuestInitReportGuestInfo: reporting status failed with rc=%Rrc\n", rc)); + VbglGRFree(&pReq3->header); + } return rc; } diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp index b217e1569..7511a31d8 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp @@ -139,6 +139,31 @@ static int vbglR3CloseAdditionsWinStoragePath(HKEY hKey) #endif /* RT_OS_WINDOWS */ /** + * Reports the Guest Additions status of a certain facility to the host. + * + * @returns IPRT status value + * @param uFacility + * @param uStatus + * @param uFlags + */ +VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestStatusFacility Facility, VBoxGuestStatusCurrent StatusCurrent, uint32_t uFlags) +{ + VMMDevReportGuestStatus Report; + RT_ZERO(Report); + int rc = vmmdevInitRequest((VMMDevRequestHeader*)&Report, VMMDevReq_ReportGuestStatus); + if (RT_SUCCESS(rc)) + { + + Report.guestStatus.facility = Facility; + Report.guestStatus.status = StatusCurrent; + Report.guestStatus.flags = uFlags; + + rc = vbglR3GRPerform(&Report.header); + } + return rc; +} + +/** * Retrieves the installed Guest Additions version and/or revision. * * @returns IPRT status value diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp index c081b2786..6845226e2 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestProp.cpp @@ -47,6 +47,41 @@ extern "C" char* xf86strcpy(char*,const char*); extern "C" void* xf86memchr(const void*,int,xf86size_t); # undef memchr # define memchr xf86memchr +extern "C" void* xf86memset(const void*,int,xf86size_t); +# undef memset +# define memset xf86memset + +# undef RTSTrEnd +# define RTStrEnd xf86RTStrEnd + +DECLINLINE(char const *) RTStrEnd(char const *pszString, size_t cchMax) +{ + /* Avoid potential issues with memchr seen in glibc. */ + if (cchMax > RTSTR_MEMCHR_MAX) + { + char const *pszRet = (char const *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX); + if (RT_LIKELY(pszRet)) + return pszRet; + pszString += RTSTR_MEMCHR_MAX; + cchMax -= RTSTR_MEMCHR_MAX; + } + return (char const *)memchr(pszString, '\0', cchMax); +} + +DECLINLINE(char *) RTStrEnd(char *pszString, size_t cchMax) +{ + /* Avoid potential issues with memchr seen in glibc. */ + if (cchMax > RTSTR_MEMCHR_MAX) + { + char *pszRet = (char *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX); + if (RT_LIKELY(pszRet)) + return pszRet; + pszString += RTSTR_MEMCHR_MAX; + cchMax -= RTSTR_MEMCHR_MAX; + } + return (char *)memchr(pszString, '\0', cchMax); +} + #endif /* VBOX_VBGLR3_XFREE86 */ /******************************************************************************* diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp index 0c69e7082..7fb6537ff 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp @@ -74,3 +74,22 @@ VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot) return rc; } +/** + * Query the session id of this VM; this is a unique id that gets changed for each VM start, reset or restore. + * Useful for detection a VM restore. + * + * @returns IPRT status code. + * pu64IdSession Session id (out) + * + */ +VBGLR3DECL(int) VbglR3GetSessionId(uint64_t *pu64IdSession) +{ + VMMDevReqSessionId Req; + + vmmdevInitRequest(&Req.header, VMMDevReq_GetSessionId); + int rc = vbglR3GRPerform(&Req.header); + if (rc == VINF_SUCCESS) + *pu64IdSession = Req.idSession; + + return rc; +} diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp index 1887e37b1..d7b100ae0 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibSeamless.cpp @@ -36,6 +36,13 @@ #include "VBGLR3Internal.h" +#ifdef VBOX_VBGLR3_XFREE86 +/* Rather than try to resolve all the header file conflicts, I will just + prototype what we need here. */ +extern "C" void* xf86memcpy(void*,const void*,xf86size_t); +# undef memcpy +# define memcpy xf86memcpy +#endif /* VBOX_VBGLR3_XFREE86 */ /** * Tell the host that we support (or no longer support) seamless mode. diff --git a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp index d8fdd38d3..ea0c1c03b 100644 --- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp +++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibVideo.cpp @@ -36,6 +36,14 @@ #include "VBGLR3Internal.h" +#ifdef VBOX_VBGLR3_XFREE86 +/* Rather than try to resolve all the header file conflicts, I will just + prototype what we need here. */ +extern "C" void* xf86memcpy(void*,const void*,xf86size_t); +# undef memcpy +# define memcpy xf86memcpy +#endif /* VBOX_VBGLR3_XFREE86 */ + #define VIDEO_PROP_PREFIX "/VirtualBox/GuestAdd/Vbgl/Video/" /** diff --git a/src/VBox/Additions/common/VBoxService/VBoxService.cpp b/src/VBox/Additions/common/VBoxService/VBoxService.cpp index acc3211bf..a8892150f 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxService.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxService.cpp @@ -437,6 +437,13 @@ void VBoxServiceMainWait(void) { int rc; + /* Report the host that we're up and running! */ + rc = VbglR3ReportAdditionsStatus(VBoxGuestStatusFacility_VBoxService, + VBoxGuestStatusCurrent_Active, + 0); /* Flags; not used. */ + if (RT_FAILURE(rc)) + VBoxServiceError("Failed to report Guest Additions status to the host! rc=%Rrc\n", rc); + #ifdef RT_OS_WINDOWS /* * Wait for the semaphore to be signalled. @@ -505,6 +512,16 @@ int main(int argc, char **argv) if (RT_FAILURE(rc)) return VBoxServiceError("VbglR3Init failed with rc=%Rrc.\n", rc); +#ifdef RT_OS_WINDOWS + /* Special forked VBoxService.exe process for handling page fusion. */ + /* Note: ugly hack, but annoying to install additional executables. */ + if ( argc == 2 + && !strcmp(argv[1], "-pagefusionfork")) + { + return VBoxServicePageSharingInitFork(); + } +#endif + /* Do pre-init of services. */ g_pszProgName = RTPathFilename(argv[0]); for (unsigned j = 0; j < RT_ELEMENTS(g_aServices); j++) diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp index 0353c44a9..9d159f761 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp @@ -483,9 +483,11 @@ static int VBoxServiceControlExecProcLoop(PVBOXSERVICECTRLTHREAD pThread, rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, pData->uPID, uStatus, uFlags, NULL /* pvData */, 0 /* cbData */); + VBoxServiceVerbose(3, "ControlExec: Process loop ended with rc=%Rrc\n", rc); } + else + VBoxServiceError("ControlExec: Process loop failed with rc=%Rrc\n", rc); RTMemFree(StdInBuf.pch); - VBoxServiceVerbose(3, "ControlExec: Process loop ended with rc=%Rrc\n", rc); return rc; } @@ -869,7 +871,7 @@ DECLCALLBACK(int) VBoxServiceControlExecProcessWorker(PVBOXSERVICECTRLTHREAD pTh /* * Tell the control thread that it can continue * spawning services. This needs to be done after the new - * process has been started because otherwise signal handling + * process has been started because otherwise signal handling * on (Open) Solaris does not work correctly (see #5068). */ int rc2 = RTThreadUserSignal(RTThreadSelf()); @@ -938,9 +940,9 @@ DECLCALLBACK(int) VBoxServiceControlExecProcessWorker(PVBOXSERVICECTRLTHREAD pTh VBoxServiceVerbose(3, "ControlExec: Thread of process \"%s\" (PID: %u) ended with rc=%Rrc\n", pData->pszCmd, pData->uPID, rc); - /* + /* * If something went wrong signal the user event so that others don't wait - * forever on this thread. + * forever on this thread. */ if (RT_FAILURE(rc) && !fSignalled) RTThreadUserSignal(RTThreadSelf()); diff --git a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h index 9a1043222..774d78668 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h +++ b/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h @@ -284,6 +284,9 @@ extern int VBoxServiceControlExecWritePipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pB #ifdef VBOXSERVICE_MANAGEMENT extern uint32_t VBoxServiceBalloonQueryPages(uint32_t cbPage); #endif +#if defined(VBOX_WITH_PAGE_SHARING) && defined(RT_OS_WINDOWS) +extern RTEXITCODE VBoxServicePageSharingInitFork(void); +#endif RT_C_DECLS_END diff --git a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp index 3eff7d457..b4c43471d 100644 --- a/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp +++ b/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp @@ -23,6 +23,8 @@ #include <iprt/avl.h> #include <iprt/asm.h> #include <iprt/mem.h> +#include <iprt/process.h> +#include <iprt/env.h> #include <iprt/stream.h> #include <iprt/file.h> #include <iprt/string.h> @@ -82,9 +84,10 @@ static PFNZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL; static HMODULE hNtdll = 0; -static DECLCALLBACK(int) VBoxServicePageSharingEmptyTreeCallback(PAVLPVNODECORE pNode, void *); +static DECLCALLBACK(int) VBoxServicePageSharingEmptyTreeCallback(PAVLPVNODECORE pNode, void *pvUser); -static PAVLPVNODECORE pKnownModuleTree = NULL; +static PAVLPVNODECORE g_pKnownModuleTree = NULL; +static uint64_t g_idSession = 0; /** * Registers a new module with the VMM @@ -299,7 +302,7 @@ void VBoxServicePageSharingInspectModules(DWORD dwProcessId, PAVLPVNODECORE *ppN PAVLPVNODECORE pRec = RTAvlPVGet(ppNewTree, ModuleInfo.modBaseAddr); if (!pRec) { - pRec = RTAvlPVRemove(&pKnownModuleTree, ModuleInfo.modBaseAddr); + pRec = RTAvlPVRemove(&g_pKnownModuleTree, ModuleInfo.modBaseAddr); if (!pRec) { /* New module; register it. */ @@ -408,7 +411,7 @@ void VBoxServicePageSharingInspectGuest() PAVLPVNODECORE pRec = RTAvlPVGet(&pNewTree, pSystemModules->Modules[i].ImageBase); if (!pRec) { - pRec = RTAvlPVRemove(&pKnownModuleTree, pSystemModules->Modules[i].ImageBase); + pRec = RTAvlPVRemove(&g_pKnownModuleTree, pSystemModules->Modules[i].ImageBase); if (!pRec) { /* New module; register it. */ @@ -481,27 +484,36 @@ skipkernelmodules: } /* Delete leftover modules in the old tree. */ - RTAvlPVDestroy(&pKnownModuleTree, VBoxServicePageSharingEmptyTreeCallback, NULL); + RTAvlPVDestroy(&g_pKnownModuleTree, VBoxServicePageSharingEmptyTreeCallback, NULL); /* Check all registered modules. */ VbglR3CheckSharedModules(); /* Activate new module tree. */ - pKnownModuleTree = pNewTree; + g_pKnownModuleTree = pNewTree; } /** * RTAvlPVDestroy callback. */ -static DECLCALLBACK(int) VBoxServicePageSharingEmptyTreeCallback(PAVLPVNODECORE pNode, void *) +static DECLCALLBACK(int) VBoxServicePageSharingEmptyTreeCallback(PAVLPVNODECORE pNode, void *pvUser) { PKNOWN_MODULE pModule = (PKNOWN_MODULE)pNode; + bool *pfUnregister = (bool *)pvUser; VBoxServiceVerbose(3, "VBoxServicePageSharingEmptyTreeCallback %s %s\n", pModule->Info.szModule, pModule->szFileVersion); - /* Defererence module in the hypervisor. */ - int rc = VbglR3UnregisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (RTGCPTR64)pModule->Info.modBaseAddr, pModule->Info.modBaseSize); - AssertRC(rc); + /* Dereference module in the hypervisor. */ + if ( !pfUnregister + || *pfUnregister == true) + { + #ifdef RT_ARCH_X86 + int rc = VbglR3UnregisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (RTGCPTR32)pModule->Info.modBaseAddr, pModule->Info.modBaseSize); + #else + int rc = VbglR3UnregisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (RTGCPTR64)pModule->Info.modBaseAddr, pModule->Info.modBaseSize); + #endif + AssertRC(rc); + } if (pModule->hModule) FreeLibrary(pModule->hModule); @@ -553,9 +565,11 @@ static DECLCALLBACK(int) VBoxServicePageSharingInit(void) if (hNtdll) ZwQuerySystemInformation = (PFNZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "ZwQuerySystemInformation"); + + rc = VbglR3GetSessionId(&g_idSession); + AssertRCReturn(rc, rc); #endif - /* @todo report system name and version */ /* Never fail here. */ return VINF_SUCCESS; } @@ -570,31 +584,124 @@ DECLCALLBACK(int) VBoxServicePageSharingWorker(bool volatile *pfShutdown) RTThreadUserSignal(RTThreadSelf()); /* - * Block here first for a minute as using DONT_RESOLVE_DLL_REFERENCES is kind of risky; other code that uses LoadLibrary on a dll loaded like this - * before will end up crashing the process as the dll's init routine was never called. - * - * We have to use this feature as we can't simply execute all init code in our service process. - * + * Now enter the loop retrieving runtime data continuously. */ - int rc = RTSemEventMultiWait(g_PageSharingEvent, 60000); - if (*pfShutdown) - goto end; - - if (rc != VERR_TIMEOUT && RT_FAILURE(rc)) + for (;;) { - VBoxServiceError("RTSemEventMultiWait failed; rc=%Rrc\n", rc); - goto end; + uint64_t idNewSession; + BOOL fEnabled = VbglR3PageSharingIsEnabled(); + + VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: enabled=%d\n", fEnabled); + + if (fEnabled) + VBoxServicePageSharingInspectGuest(); + + /* + * Block for a minute. + * + * The event semaphore takes care of ignoring interruptions and it + * allows us to implement service wakeup later. + */ + if (*pfShutdown) + break; + int rc = RTSemEventMultiWait(g_PageSharingEvent, 60000); + if (*pfShutdown) + break; + if (rc != VERR_TIMEOUT && RT_FAILURE(rc)) + { + VBoxServiceError("RTSemEventMultiWait failed; rc=%Rrc\n", rc); + break; + } +#if defined(RT_OS_WINDOWS) && !defined(TARGET_NT4) + idNewSession = g_idSession; + rc = VbglR3GetSessionId(&idNewSession); + AssertRC(rc); + + if (idNewSession != g_idSession) + { + bool fUnregister = false; + + VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: VM was restored!!\n"); + /* The VM was restored, so reregister all modules the next time. */ + RTAvlPVDestroy(&g_pKnownModuleTree, VBoxServicePageSharingEmptyTreeCallback, &fUnregister); + g_pKnownModuleTree = NULL; + + g_idSession = idNewSession; + } +#endif } + RTSemEventMultiDestroy(g_PageSharingEvent); + g_PageSharingEvent = NIL_RTSEMEVENTMULTI; + + VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: finished thread\n"); + return 0; +} + +#ifdef RT_OS_WINDOWS + +/** + * This gets control when VBoxService is launched with -pagefusionfork by + * VBoxServicePageSharingWorkerProcess(). + * + * @returns RTEXITCODE_SUCCESS. + * + * @remarks It won't normally return since the parent drops the shutdown hint + * via RTProcTerminate(). + */ +RTEXITCODE VBoxServicePageSharingInitFork(void) +{ + VBoxServiceVerbose(3, "VBoxServicePageSharingInitFork\n"); + + bool fShutdown = false; + VBoxServicePageSharingInit(); + VBoxServicePageSharingWorker(&fShutdown); + + return RTEXITCODE_SUCCESS; +} + +/** @copydoc VBOXSERVICE::pfnWorker */ +DECLCALLBACK(int) VBoxServicePageSharingWorkerProcess(bool volatile *pfShutdown) +{ + RTPROCESS hProcess = NIL_RTPROCESS; + int rc; + + /* + * Tell the control thread that it can continue + * spawning services. + */ + RTThreadUserSignal(RTThreadSelf()); + /* * Now enter the loop retrieving runtime data continuously. */ for (;;) { - VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: enabled=%d\n", VbglR3PageSharingIsEnabled()); + BOOL fEnabled = VbglR3PageSharingIsEnabled(); + VBoxServiceVerbose(3, "VBoxServicePageSharingWorkerProcess: enabled=%d\n", fEnabled); - if (VbglR3PageSharingIsEnabled()) - VBoxServicePageSharingInspectGuest(); + if ( fEnabled + && hProcess == NIL_RTPROCESS) + { + char szExeName[256]; + char *pszExeName; + char *pszArgs[3]; + + pszExeName = RTProcGetExecutableName(szExeName, sizeof(szExeName)); + + if (pszExeName) + { + pszArgs[0] = pszExeName; + pszArgs[1] = "-pagefusionfork"; + pszArgs[2] = NULL; + /* Start a 2nd VBoxService process to deal with page fusion as we do not wish to dummy load + * dlls into this process. (first load with DONT_RESOLVE_DLL_REFERENCES, 2nd normal -> dll init routines not called!) + */ + rc = RTProcCreate(pszExeName, pszArgs, RTENV_DEFAULT, 0 /* normal child */, &hProcess); + if (rc != VINF_SUCCESS) + VBoxServiceError("RTProcCreate %s failed; rc=%Rrc\n", pszExeName, rc); + } + } /* * Block for a minute. @@ -614,14 +721,18 @@ DECLCALLBACK(int) VBoxServicePageSharingWorker(bool volatile *pfShutdown) } } -end: + if (hProcess != NIL_RTPROCESS) + RTProcTerminate(hProcess); + RTSemEventMultiDestroy(g_PageSharingEvent); g_PageSharingEvent = NIL_RTSEMEVENTMULTI; - VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: finished thread\n"); + VBoxServiceVerbose(3, "VBoxServicePageSharingWorkerProcess: finished thread\n"); return 0; } +#endif /* RT_OS_WINDOWS */ + /** @copydoc VBOXSERVICE::pfnTerm */ static DECLCALLBACK(void) VBoxServicePageSharingTerm(void) { @@ -659,7 +770,11 @@ VBOXSERVICE g_PageSharing = VBoxServicePageSharingPreInit, VBoxServicePageSharingOption, VBoxServicePageSharingInit, +#ifdef RT_OS_WINDOWS + VBoxServicePageSharingWorkerProcess, +#else VBoxServicePageSharingWorker, +#endif VBoxServicePageSharingStop, VBoxServicePageSharingTerm }; diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs.h index 1cc58aa11..d6675589b 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs.h +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs.h @@ -24,6 +24,8 @@ extern "C" { #define MAX_HOST_NAME 256 #define MAX_NLS_NAME 32 +/** Default stat cache ttl (in ms) */ +#define DEF_STAT_TTL_MS 200 /** The module name. */ #define DEVICE_NAME "vboxfs" @@ -32,7 +34,6 @@ extern "C" { #include "../../common/VBoxGuestLib/VBoxCalls.h" #include <sys/vfs.h> -#include <sys/vfs_opreg.h> /** VNode for VBoxVFS */ typedef struct vboxvfs_vnode diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c index 40031c67b..f725c74f3 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c @@ -52,9 +52,11 @@ static void Usage(char *pszName) " ro mount read only\n" " uid=UID set the default file owner user id to UID\n" " gid=GID set the default file owner group id to GID\n" + " stat_ttl=TTL set the \"time to live\" (in ms) for the stat caches (default %d)\n" + " fsync honor fsync calls instead of ignoring them\n" " ttl=TTL set the \"time to live\" to TID for the dentry\n" " iocharset CHARSET use the character set CHARSET for i/o operations (default utf8)\n" - " convertcp CHARSET convert the shared folder name from the character set CHARSET to utf8\n\n"); + " convertcp CHARSET convert the shared folder name from the character set CHARSET to utf8\n\n", DEF_STAT_TTL_MS); fprintf(stderr, "Less common used options:\n" " noexec,exec,nodev,dev,nosuid,suid\n"); exit(1); diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c index 473ecb14e..17cbed11a 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c @@ -1,5 +1,6 @@ /** @file * VirtualBox File System for Solaris Guests, provider implementation. + * Portions contributed by: Ronald. */ /* @@ -28,6 +29,7 @@ #include <sys/sysmacros.h> #include <sys/ddi.h> #include <sys/sunddi.h> +#include <sys/dirent.h> #include "vboxfs_prov.h" #ifdef u #undef u @@ -378,6 +380,17 @@ sfprov_write(sfp_file_t *fp, char *buffer, uint64_t offset, uint32_t *numbytes) return (0); } +int +sfprov_fsync(sfp_file_t *fp) +{ + int rc; + + rc = vboxCallFlush(&vbox_client, &fp->map, fp->handle); + if (RT_FAILURE(rc)) + return (EIO); + return (0); +} + static int sfprov_getinfo(sfp_mount_t *mnt, char *path, RTFSOBJINFO *info) @@ -405,52 +418,66 @@ sfprov_getinfo(sfp_mount_t *mnt, char *path, RTFSOBJINFO *info) /* * get information about a file (or directory) */ -int -sfprov_get_mode(sfp_mount_t *mnt, char *path, mode_t *mode) +static void +sfprov_mode_from_fmode(mode_t *mode, RTFMODE fMode) { - int rc; - RTFSOBJINFO info; mode_t m = 0; - rc = sfprov_getinfo(mnt, path, &info); - if (rc) - return (rc); - if (RTFS_IS_DIRECTORY(info.Attr.fMode)) + if (RTFS_IS_DIRECTORY(fMode)) m |= S_IFDIR; - else if (RTFS_IS_FILE(info.Attr.fMode)) + else if (RTFS_IS_FILE(fMode)) m |= S_IFREG; - else if (RTFS_IS_FIFO(info.Attr.fMode)) - m |= S_IFDIR; - else if (RTFS_IS_DEV_CHAR(info.Attr.fMode)) + else if (RTFS_IS_FIFO(fMode)) + m |= S_IFIFO; + else if (RTFS_IS_DEV_CHAR(fMode)) m |= S_IFCHR; - else if (RTFS_IS_DEV_BLOCK(info.Attr.fMode)) + else if (RTFS_IS_DEV_BLOCK(fMode)) m |= S_IFBLK; - else if (RTFS_IS_SYMLINK(info.Attr.fMode)) + else if (RTFS_IS_SYMLINK(fMode)) m |= S_IFLNK; - else if (RTFS_IS_SOCKET(info.Attr.fMode)) + else if (RTFS_IS_SOCKET(fMode)) m |= S_IFSOCK; - if (info.Attr.fMode & RTFS_UNIX_IRUSR) + if (fMode & RTFS_UNIX_IRUSR) m |= S_IRUSR; - if (info.Attr.fMode & RTFS_UNIX_IWUSR) + if (fMode & RTFS_UNIX_IWUSR) m |= S_IWUSR; - if (info.Attr.fMode & RTFS_UNIX_IXUSR) + if (fMode & RTFS_UNIX_IXUSR) m |= S_IXUSR; - if (info.Attr.fMode & RTFS_UNIX_IRGRP) + if (fMode & RTFS_UNIX_IRGRP) m |= S_IRGRP; - if (info.Attr.fMode & RTFS_UNIX_IWGRP) + if (fMode & RTFS_UNIX_IWGRP) m |= S_IWGRP; - if (info.Attr.fMode & RTFS_UNIX_IXGRP) + if (fMode & RTFS_UNIX_IXGRP) m |= S_IXGRP; - if (info.Attr.fMode & RTFS_UNIX_IROTH) + if (fMode & RTFS_UNIX_IROTH) m |= S_IROTH; - if (info.Attr.fMode & RTFS_UNIX_IWOTH) + if (fMode & RTFS_UNIX_IWOTH) m |= S_IWOTH; - if (info.Attr.fMode & RTFS_UNIX_IXOTH) + if (fMode & RTFS_UNIX_IXOTH) m |= S_IXOTH; - if (info.Attr.fMode & RTFS_UNIX_ISUID) + if (fMode & RTFS_UNIX_ISUID) m |= S_ISUID; + if (fMode & RTFS_UNIX_ISGID) + m |= S_ISGID; + if (fMode & RTFS_UNIX_ISTXT) + m |= S_ISVTX; *mode = m; +} + +/* + * get information about a file (or directory) + */ +int +sfprov_get_mode(sfp_mount_t *mnt, char *path, mode_t *mode) +{ + int rc; + RTFSOBJINFO info; + + rc = sfprov_getinfo(mnt, path, &info); + if (rc) + return (rc); + sfprov_mode_from_fmode(mode, info.Attr.fMode); return (0); } @@ -467,19 +494,24 @@ sfprov_get_size(sfp_mount_t *mnt, char *path, uint64_t *size) return (0); } +static void +sfprov_ftime_from_timespec(timestruc_t *time, RTTIMESPEC *ts) +{ + uint64_t nanosec = RTTimeSpecGetNano(ts); + time->tv_sec = nanosec / UINT64_C(1000000000); + time->tv_nsec = nanosec % UINT64_C(1000000000); +} + int sfprov_get_atime(sfp_mount_t *mnt, char *path, timestruc_t *time) { int rc; RTFSOBJINFO info; - uint64_t nanosec; rc = sfprov_getinfo(mnt, path, &info); if (rc) return (rc); - nanosec = RTTimeSpecGetNano(&info.AccessTime); - time->tv_sec = nanosec / 1000000000; - time->tv_nsec = nanosec % 1000000000; + sfprov_ftime_from_timespec(time, &info.AccessTime); return (0); } @@ -488,14 +520,11 @@ sfprov_get_mtime(sfp_mount_t *mnt, char *path, timestruc_t *time) { int rc; RTFSOBJINFO info; - uint64_t nanosec; rc = sfprov_getinfo(mnt, path, &info); if (rc) return (rc); - nanosec = RTTimeSpecGetNano(&info.ModificationTime); - time->tv_sec = nanosec / 1000000000; - time->tv_nsec = nanosec % 1000000000; + sfprov_ftime_from_timespec(time, &info.ModificationTime); return (0); } @@ -504,17 +533,209 @@ sfprov_get_ctime(sfp_mount_t *mnt, char *path, timestruc_t *time) { int rc; RTFSOBJINFO info; - uint64_t nanosec; rc = sfprov_getinfo(mnt, path, &info); if (rc) return (rc); - nanosec = RTTimeSpecGetNano(&info.ChangeTime); - time->tv_sec = nanosec / 1000000000; - time->tv_nsec = nanosec % 1000000000; + sfprov_ftime_from_timespec(time, &info.ChangeTime); + return (0); +} + +int +sfprov_get_attr( + sfp_mount_t *mnt, + char *path, + mode_t *mode, + uint64_t *size, + timestruc_t *atime, + timestruc_t *mtime, + timestruc_t *ctime) +{ + int rc; + RTFSOBJINFO info; + + rc = sfprov_getinfo(mnt, path, &info); + if (rc) + return (rc); + + if (mode) + sfprov_mode_from_fmode(mode, info.Attr.fMode); + if (size != NULL) + *size = info.cbObject; + if (atime != NULL) + sfprov_ftime_from_timespec(atime, &info.AccessTime); + if (mtime != NULL) + sfprov_ftime_from_timespec(mtime, &info.ModificationTime); + if (ctime != NULL) + sfprov_ftime_from_timespec(ctime, &info.ChangeTime); + return (0); } +static void +sfprov_timespec_from_ftime(RTTIMESPEC *ts, timestruc_t time) +{ + uint64_t nanosec = UINT64_C(1000000000) * time.tv_sec + time.tv_nsec; + RTTimeSpecSetNano(ts, nanosec); +} + +int +sfprov_set_attr( + sfp_mount_t *mnt, + char *path, + uint_t mask, + mode_t mode, + timestruc_t atime, + timestruc_t mtime, + timestruc_t ctime) +{ + int rc, err; + SHFLCREATEPARMS parms; + SHFLSTRING *str; + RTFSOBJINFO info; + uint32_t bytes; + int str_size; + + str = sfprov_string(path, &str_size); + parms.Handle = 0; + parms.Info.cbObject = 0; + parms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS + | SHFL_CF_ACT_FAIL_IF_NEW + | SHFL_CF_ACCESS_ATTR_WRITE; + + rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms); + + if (RT_FAILURE(rc)) { + cmn_err(CE_WARN, "sfprov_set_attr: vboxCallCreate(%s) failed rc=%d", + path, rc); + err = EINVAL; + goto fail2; + } + if (parms.Result != SHFL_FILE_EXISTS) { + err = ENOENT; + goto fail1; + } + + RT_ZERO(info); + if (mask & AT_MODE) { +#define mode_set(r) ((mode & (S_##r)) ? RTFS_UNIX_##r : 0) + + info.Attr.fMode = mode_set (ISUID); + info.Attr.fMode |= mode_set (ISGID); + info.Attr.fMode |= (mode & S_ISVTX) ? RTFS_UNIX_ISTXT : 0; + info.Attr.fMode |= mode_set (IRUSR); + info.Attr.fMode |= mode_set (IWUSR); + info.Attr.fMode |= mode_set (IXUSR); + info.Attr.fMode |= mode_set (IRGRP); + info.Attr.fMode |= mode_set (IWGRP); + info.Attr.fMode |= mode_set (IXGRP); + info.Attr.fMode |= mode_set (IROTH); + info.Attr.fMode |= mode_set (IWOTH); + info.Attr.fMode |= mode_set (IXOTH); + + if (S_ISDIR(mode)) + info.Attr.fMode |= RTFS_TYPE_DIRECTORY; + else if (S_ISREG(mode)) + info.Attr.fMode |= RTFS_TYPE_FILE; + else if (S_ISFIFO(mode)) + info.Attr.fMode |= RTFS_TYPE_FIFO; + else if (S_ISCHR(mode)) + info.Attr.fMode |= RTFS_TYPE_DEV_CHAR; + else if (S_ISBLK(mode)) + info.Attr.fMode |= RTFS_TYPE_DEV_BLOCK; + else if (S_ISLNK(mode)) + info.Attr.fMode |= RTFS_TYPE_SYMLINK; + else if (S_ISSOCK(mode)) + info.Attr.fMode |= RTFS_TYPE_SOCKET; + else + info.Attr.fMode |= RTFS_TYPE_FILE; + } + + if (mask & AT_ATIME) + sfprov_timespec_from_ftime(&info.AccessTime, atime); + if (mask & AT_MTIME) + sfprov_timespec_from_ftime(&info.ModificationTime, mtime); + if (mask & AT_CTIME) + sfprov_timespec_from_ftime(&info.ChangeTime, ctime); + + bytes = sizeof(info); + rc = vboxCallFSInfo(&vbox_client, &mnt->map, parms.Handle, + (SHFL_INFO_SET | SHFL_INFO_FILE), &bytes, (SHFLDIRINFO *)&info); + if (RT_FAILURE(rc)) { + cmn_err(CE_WARN, "sfprov_set_attr: vboxCallFSInfo(%s, FILE) failed rc=%d", + path, rc); + err = RTErrConvertToErrno(rc); + goto fail1; + } + + err = 0; + +fail1: + rc = vboxCallClose(&vbox_client, &mnt->map, parms.Handle); + if (RT_FAILURE(rc)) { + cmn_err(CE_WARN, "sfprov_set_attr: vboxCallClose(%s) failed rc=%d", + path, rc); + } +fail2: + kmem_free(str, str_size); + return err; +} + +int +sfprov_set_size(sfp_mount_t *mnt, char *path, uint64_t size) +{ + int rc, err; + SHFLCREATEPARMS parms; + SHFLSTRING *str; + RTFSOBJINFO info; + uint32_t bytes; + int str_size; + + str = sfprov_string(path, &str_size); + parms.Handle = 0; + parms.Info.cbObject = 0; + parms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS + | SHFL_CF_ACT_FAIL_IF_NEW + | SHFL_CF_ACCESS_WRITE; + + rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms); + + if (RT_FAILURE(rc)) { + cmn_err(CE_WARN, "sfprov_set_size: vboxCallCreate(%s) failed rc=%d", + path, rc); + err = EINVAL; + goto fail2; + } + if (parms.Result != SHFL_FILE_EXISTS) { + err = ENOENT; + goto fail1; + } + + RT_ZERO(info); + info.cbObject = size; + bytes = sizeof(info); + rc = vboxCallFSInfo(&vbox_client, &mnt->map, parms.Handle, + (SHFL_INFO_SET | SHFL_INFO_SIZE), &bytes, (SHFLDIRINFO *)&info); + if (RT_FAILURE(rc)) { + cmn_err(CE_WARN, "sfprov_set_size: vboxCallFSInfo(%s, SIZE) failed rc=%d", + path, rc); + err = RTErrConvertToErrno(rc); + goto fail1; + } + + err = 0; + +fail1: + rc = vboxCallClose(&vbox_client, &mnt->map, parms.Handle); + if (RT_FAILURE(rc)) { + cmn_err(CE_WARN, "sfprov_set_size: vboxCallClose(%s) failed rc=%d", + path, rc); + } +fail2: + kmem_free(str, str_size); + return err; +} + /* * Directory operations */ @@ -606,23 +827,16 @@ sfprov_rename(sfp_mount_t *mnt, char *from, char *to, uint_t is_dir) * - ENOENT - Couldn't open the directory for reading * - EINVAL - Internal error of some kind * - * On successful return, buffer[0] is the start of an array of "char *" - * pointers to the filenames. The array ends with a NULL pointer. - * The remaining storage in buffer after that NULL pointer is where the - * filename strings actually are. - * - * On input nents is the max number of filenames the requestor can handle. - * On output nents is the number of entries at buff[0] - * - * The caller is responsible for freeing the returned buffer. + * On successful return, *dirents points to a list of sffs_dirents_t; + * for each dirent, all fields except the d_ino will be set appropriately. + * The caller is responsible for freeing the dirents buffer. */ int sfprov_readdir( sfp_mount_t *mnt, char *path, - void **buffer, - size_t *buffersize, - uint32_t *nents) + sffs_dirents_t **dirents, + sffs_stats_t **stats) { int error; char *cp; @@ -630,84 +844,168 @@ sfprov_readdir( SHFLSTRING *mask_str = NULL; /* must be path with "/*" appended */ int mask_size; sfp_file_t *fp; - void *buff_start = NULL; - size_t buff_size; - static char infobuff[2 * MAXNAMELEN]; /* not on stack!! */ - SHFLDIRINFO *info = (SHFLDIRINFO *)&infobuff; - uint32_t numbytes = sizeof (infobuff); - uint32_t justone; + uint32_t infobuff_alloc = 16384; + SHFLDIRINFO *infobuff = NULL, *info; + uint32_t numbytes; + uint32_t nents; + uint32_t size; uint32_t cnt; - char **name_ptrs; + sffs_dirents_t *cur_buf; + sffs_stats_t *cur_stats; + struct dirent64 *dirent; + sffs_stat_t *stat; + unsigned short reclen; + + *dirents = NULL; + *stats = NULL; - *buffer = NULL; - *buffersize = 0; - if (*nents == 0) - return (EINVAL); error = sfprov_open(mnt, path, &fp); if (error != 0) return (ENOENT); /* + * Allocate the first dirents and stats buffers. + */ + *dirents = kmem_alloc(SFFS_DIRENTS_SIZE, KM_SLEEP); + if (*dirents == NULL) { + error = (ENOSPC); + goto done; + } + cur_buf = *dirents; + cur_buf->sf_next = NULL; + cur_buf->sf_len = 0; + + *stats = kmem_alloc(sizeof(**stats), KM_SLEEP); + if (*stats == NULL) { + error = (ENOSPC); + goto done; + } + cur_stats = *stats; + cur_stats->sf_next = NULL; + cur_stats->sf_num = 0; + + /* * Create mask that VBox expects. This needs to be the directory path, * plus a "*" wildcard to get all files. */ len = strlen(path) + 3; cp = kmem_alloc(len, KM_SLEEP); + if (cp == NULL) { + error = (ENOSPC); + goto done; + } strcpy(cp, path); strcat(cp, "/*"); mask_str = sfprov_string(cp, &mask_size); kmem_free(cp, len); /* - * Allocate the buffer to use for return values. Each entry - * in the buffer will have a pointer and the string itself. - * The pointers go in the front of the buffer, the strings - * at the end. + * Now loop using vboxCallDirInfo */ - buff_size = *nents * (sizeof(char *) + MAXNAMELEN); - name_ptrs = buff_start = kmem_alloc(buff_size, KM_SLEEP); - cp = (char *)buff_start + buff_size; + infobuff = kmem_alloc(infobuff_alloc, KM_SLEEP); + if (infobuff == NULL) { + error = (ENOSPC); + goto done; + } - /* - * Now loop using vboxCallDirInfo to get one file name at a time - */ cnt = 0; for (;;) { - justone = 1; - numbytes = sizeof (infobuff); + numbytes = infobuff_alloc; error = vboxCallDirInfo(&vbox_client, &fp->map, fp->handle, - mask_str, SHFL_LIST_RETURN_ONE, 0, &numbytes, info, - &justone); - if (error == VERR_NO_MORE_FILES) { + mask_str, 0, 0, &numbytes, infobuff, &nents); + switch (error) { + + case VINF_SUCCESS: + /* fallthrough */ + case VERR_NO_MORE_FILES: break; - } - else if (error == VERR_NO_TRANSLATION) { - continue; /* ?? just skip this one */ - } - else if (error != VINF_SUCCESS || justone != 1) { - error = EINVAL; - goto done; + + case VERR_NO_TRANSLATION: + /* XXX ??? */ + break; + + default: + error = RTErrConvertToErrno(error); + goto done; } /* - * Put this name in the buffer, stop if we run out of room. + * Create the dirent_t's and save the stats for each name */ - cp -= strlen(info->name.String.utf8) + 1; - if (cp < (char *)(&name_ptrs[cnt + 2])) + for (info = infobuff; (char *) info < (char *) infobuff + numbytes; nents--) { + /* expand buffers if we need more space */ + reclen = DIRENT64_RECLEN(strlen(info->name.String.utf8)); + if (SFFS_DIRENTS_OFF + cur_buf->sf_len + reclen > SFFS_DIRENTS_SIZE) { + cur_buf->sf_next = kmem_alloc(SFFS_DIRENTS_SIZE, KM_SLEEP); + if (cur_buf->sf_next == NULL) { + error = ENOSPC; + goto done; + } + cur_buf = cur_buf->sf_next; + cur_buf->sf_next = NULL; + cur_buf->sf_len = 0; + } + + if (cur_stats->sf_num >= SFFS_STATS_LEN) { + cur_stats->sf_next = kmem_alloc(sizeof(**stats), KM_SLEEP); + if (cur_stats->sf_next == NULL) { + error = (ENOSPC); + goto done; + } + cur_stats = cur_stats->sf_next; + cur_stats->sf_next = NULL; + cur_stats->sf_num = 0; + } + + /* create the dirent with the name, offset, and len */ + dirent = (dirent64_t *) + (((char *) &cur_buf->sf_entries[0]) + cur_buf->sf_len); + strcpy(&dirent->d_name[0], info->name.String.utf8); + dirent->d_reclen = reclen; + dirent->d_off = cnt; + + cur_buf->sf_len += reclen; + ++cnt; + + /* save the stats */ + stat = &cur_stats->sf_stats[cur_stats->sf_num]; + ++cur_stats->sf_num; + + sfprov_mode_from_fmode(&stat->sf_mode, info->Info.Attr.fMode); + stat->sf_size = info->Info.cbObject; + sfprov_ftime_from_timespec(&stat->sf_atime, &info->Info.AccessTime); + sfprov_ftime_from_timespec(&stat->sf_mtime, &info->Info.ModificationTime); + sfprov_ftime_from_timespec(&stat->sf_ctime, &info->Info.ChangeTime); + + /* next info */ + size = offsetof (SHFLDIRINFO, name.String) + info->name.u16Size; + info = (SHFLDIRINFO *) ((uintptr_t) info + size); + } + ASSERT(nents == 0); + ASSERT((char *) info == (char *) infobuff + numbytes); + + if (error == VERR_NO_MORE_FILES) break; - strcpy(cp, info->name.String.utf8); - name_ptrs[cnt] = cp; - ++cnt; } error = 0; - name_ptrs[cnt] = NULL; - *nents = cnt; - *buffer = buff_start; - *buffersize = buff_size; + done: - if (error != 0) - kmem_free(buff_start, buff_size); - kmem_free(mask_str, mask_size); + if (error != 0) { + while (*dirents) { + cur_buf = (*dirents)->sf_next; + kmem_free(*dirents, SFFS_DIRENTS_SIZE); + *dirents = cur_buf; + } + while (*stats) { + cur_stats = (*stats)->sf_next; + kmem_free(*stats, sizeof(**stats)); + *stats = cur_stats; + } + } + if (infobuff != NULL) + kmem_free(infobuff, infobuff_alloc); + if (mask_str != NULL) + kmem_free(mask_str, mask_size); sfprov_close(fp); return (error); } diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h index 1f77cec69..3601de115 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h @@ -1,6 +1,7 @@ /* $Id: vboxfs_prov.h $ */ /** @file * VirtualBox File System for Solaris Guests, provider header. + * Portions contributed by: Ronald. */ /* @@ -82,16 +83,22 @@ extern int sfprov_read(sfp_file_t *, char * buffer, uint64_t offset, uint32_t *numbytes); extern int sfprov_write(sfp_file_t *, char * buffer, uint64_t offset, uint32_t *numbytes); +extern int sfprov_fsync(sfp_file_t *fp); /* - * get information about a file (or directory) using pathname + * get/set information about a file (or directory) using pathname */ extern int sfprov_get_mode(sfp_mount_t *, char *, mode_t *); extern int sfprov_get_size(sfp_mount_t *, char *, uint64_t *); extern int sfprov_get_atime(sfp_mount_t *, char *, timestruc_t *); extern int sfprov_get_mtime(sfp_mount_t *, char *, timestruc_t *); extern int sfprov_get_ctime(sfp_mount_t *, char *, timestruc_t *); +extern int sfprov_get_attr(sfp_mount_t *, char *, mode_t *, uint64_t *, + timestruc_t *, timestruc_t *, timestruc_t *); +extern int sfprov_set_attr(sfp_mount_t *, char *, uint_t, mode_t, + timestruc_t, timestruc_t, timestruc_t); +extern int sfprov_set_size(sfp_mount_t *, char *, uint64_t); /* @@ -106,8 +113,36 @@ extern int sfprov_rename(sfp_mount_t *, char *from, char *to, uint_t is_dir); /* * Read directory entries. */ -extern int sfprov_readdir(sfp_mount_t *mnt, char *path, void **buffer, - size_t *buffersize, uint32_t *nents); +/* + * a singly linked list of buffers, each containing an array of dirent's. + * sf_len is length of the sf_entries array, in bytes. + */ +typedef struct sffs_dirents { + struct sffs_dirents *sf_next; + len_t sf_len; + dirent64_t sf_entries[1]; +} sffs_dirents_t; + +#define SFFS_DIRENTS_SIZE 8192 +#define SFFS_DIRENTS_OFF (offsetof(sffs_dirents_t, sf_entries[0])) +#define SFFS_STATS_LEN 100 + +typedef struct sffs_stat { + mode_t sf_mode; + off_t sf_size; + timestruc_t sf_atime; + timestruc_t sf_mtime; + timestruc_t sf_ctime; +} sffs_stat_t; + +typedef struct sffs_stats { + struct sffs_stats *sf_next; + len_t sf_num; + sffs_stat_t sf_stats[SFFS_STATS_LEN]; +} sffs_stats_t; + +extern int sfprov_readdir(sfp_mount_t *mnt, char *path, sffs_dirents_t **dirents, + sffs_stats_t **stats); #ifdef __cplusplus } diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c index 70a175089..da3282a10 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c @@ -35,6 +35,7 @@ #include "vboxfs_prov.h" #include "vboxfs_vnode.h" #include "vboxfs_vfs.h" +#include "vboxfs.h" #ifdef u #undef u @@ -63,7 +64,9 @@ static int sffs_statvfs(vfs_t *vfsp, statvfs64_t *sbp); static mntopt_t sffs_options[] = { /* Option Cancels Opt Arg Flags Data */ {"uid", NULL, NULL, MO_HASVALUE, NULL}, - {"gid", NULL, NULL, MO_HASVALUE, NULL} + {"gid", NULL, NULL, MO_HASVALUE, NULL}, + {"stat_ttl", NULL, NULL, MO_HASVALUE, NULL}, + {"fsync", NULL, NULL, 0, NULL} }; static mntopts_t sffs_options_table = { @@ -226,6 +229,8 @@ sffs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr) dev_t dev; uid_t uid = 0; gid_t gid = 0; + int stat_ttl = DEF_STAT_TTL_MS; + int fsync = 0; char *optval; long val; char *path; @@ -288,6 +293,20 @@ sffs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr) gid = val; /* + * ttl to use for stat caches + */ + if (vfs_optionisset(vfsp, "stat_ttl", &optval) && + ddi_strtol(optval, NULL, 10, &val) == 0 && + (int)val == val) + stat_ttl = val; + + /* + * whether to honor fsync + */ + if (vfs_optionisset(vfsp, "fsync", &optval)) + fsync = 1; + + /* * Any unknown options are an error */ if ((uap->flags & MS_DATA) && uap->datalen > 0) { @@ -338,6 +357,8 @@ sffs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr) sffs->sf_vfsp = vfsp; sffs->sf_uid = uid; sffs->sf_gid = gid; + sffs->sf_stat_ttl = stat_ttl; + sffs->sf_fsync = fsync; sffs->sf_share_name = share_name; sffs->sf_mntpath = mount_point; sffs->sf_handle = handle; @@ -361,7 +382,7 @@ sffs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr) path = kmem_alloc(2, KM_SLEEP); strcpy(path, "."); mutex_enter(&sffs_lock); - sfnode = sfnode_make(sffs, path, VDIR, NULL, NULL); + sfnode = sfnode_make(sffs, path, VDIR, NULL, NULL, NULL, 0); sffs->sf_rootnode = sfnode_get_vnode(sfnode); sffs->sf_rootnode->v_flag |= VROOT; sffs->sf_rootnode->v_vfsp = vfsp; diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h index db4ebc2cc..c1ff4d4a8 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h @@ -30,6 +30,8 @@ typedef struct sffs_data { vnode_t *sf_rootnode; /* of vnode of the root directory */ uid_t sf_uid; /* owner of all shared folders */ gid_t sf_gid; /* group of all shared folders */ + int sf_stat_ttl; /* ttl for stat caches (in ms) */ + int sf_fsync; /* whether to honor fsync or not */ char *sf_share_name; char *sf_mntpath; /* name of mount point */ sfp_mount_t *sf_handle; @@ -42,3 +44,4 @@ typedef struct sffs_data { #endif #endif /* !___VBoxFS_vfs_Solaris_h */ + diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c index 2b3585afc..45a40ce39 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c @@ -1,5 +1,6 @@ /** @file * VirtualBox File System for Solaris Guests, vnode implementation. + * Portions contributed by: Ronald. */ /* @@ -58,6 +59,7 @@ #include <VBox/log.h> +#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mntent.h> @@ -76,6 +78,7 @@ #include <sys/pathname.h> #include <sys/dirent.h> #include <sys/fs_subr.h> +#include <sys/time.h> #include "vboxfs_prov.h" #include "vboxfs_vnode.h" #include "vboxfs_vfs.h" @@ -141,6 +144,27 @@ sfnode_construct_path(sfnode_t *node, char *tail) } /* + * Clears the (cached) directory listing for the node. + */ +static void +sfnode_clear_dir_list(sfnode_t *node) +{ + ASSERT(MUTEX_HELD(&sffs_lock)); + + while (node->sf_dir_list != NULL) { + sffs_dirents_t *next = node->sf_dir_list->sf_next; + kmem_free(node->sf_dir_list, SFFS_DIRENTS_SIZE); + node->sf_dir_list = next; + } + + while (node->sf_dir_stats != NULL) { + sffs_stats_t *next = node->sf_dir_stats->sf_next; + kmem_free(node->sf_dir_stats, sizeof(*node->sf_dir_stats)); + node->sf_dir_stats = next; + } +} + +/* * Open the provider file associated with a vnode. Holding the file open is * the only way we have of trying to have a vnode continue to refer to the * same host file in the host in light of the possibility of host side renames. @@ -193,7 +217,9 @@ sfnode_make( char *path, vtype_t type, sfp_file_t *fp, - sfnode_t *parent) /* can be NULL for root */ + sfnode_t *parent, /* can be NULL for root */ + sffs_stat_t *stat, + uint64_t stat_time) { sfnode_t *node; avl_index_t where; @@ -217,6 +243,14 @@ sfnode_make( node->sf_parent = parent; if (parent) ++parent->sf_children; + node->sf_dir_list = NULL; + node->sf_dir_stats = NULL; + if (stat != NULL) { + node->sf_stat = *stat; + node->sf_stat_time = stat_time; + } else { + node->sf_stat_time = 0; + } /* * add the new node to our cache @@ -242,7 +276,7 @@ top: ASSERT(node->sf_path != NULL); LogFlowFunc(("sffs_destroy(%s)%s\n", node->sf_path, node->sf_is_stale ? " stale": "")); if (node->sf_children != 0) - panic("sfnode_destroy(%s) has %d children", node->sf_children); + panic("sfnode_destroy(%s) has %d children", node->sf_path, node->sf_children); if (node->sf_vnode != NULL) panic("sfnode_destroy(%s) has active vnode", node->sf_path); @@ -255,11 +289,13 @@ top: avl_remove(tree, node); VFS_RELE(node->sf_sffs->sf_vfsp); + sfnode_clear_dir_list(node); kmem_free(node->sf_path, strlen(node->sf_path) + 1); kmem_free(node, sizeof (*node)); if (parent != NULL) { + sfnode_clear_dir_list(parent); if (parent->sf_children == 0) - panic("sfnode_destroy(%s) parent has no child"); + panic("sfnode_destroy(%s) parent has no child", node->sf_path); --parent->sf_children; if (parent->sf_children == 0 && parent->sf_is_stale && @@ -310,6 +346,7 @@ sfnode_make_stale(sfnode_t *node) sfnode_destroy(n); } else { LogFlowFunc(("sffs_make_stale(%s) sub\n", n->sf_path)); + sfnode_clear_dir_list(n); if (avl_find(&sfnodes, n, &where) == NULL) panic("sfnode_make_stale(%s)" " not in sfnodes", n->sf_path); @@ -330,6 +367,9 @@ sfnode_make_stale(sfnode_t *node) sfnode_destroy(node); } else if (!node->sf_is_stale) { LogFlowFunc(("sffs_make_stale(%s)\n", node->sf_path)); + sfnode_clear_dir_list(node); + if (node->sf_parent) + sfnode_clear_dir_list(node->sf_parent); if (avl_find(&sfnodes, node, &where) == NULL) panic("sfnode_make_stale(%s) not in sfnodes", node->sf_path); @@ -341,6 +381,48 @@ sfnode_make_stale(sfnode_t *node) } } +static uint64_t +sfnode_cur_time_usec(void) +{ + timestruc_t now = hrestime; + return (now.tv_sec * 1000000L + now.tv_nsec / 1000L); +} + +static int +sfnode_stat_cached(sfnode_t *node) +{ + return (sfnode_cur_time_usec() - node->sf_stat_time) < + node->sf_sffs->sf_stat_ttl * 1000L; +} + +static int +sfnode_get_stat(sfp_mount_t *mnt, char *path, sffs_stat_t *stat) +{ + return sfprov_get_attr(mnt, path, &stat->sf_mode, &stat->sf_size, + &stat->sf_atime, &stat->sf_mtime, &stat->sf_ctime); +} + +static void +sfnode_invalidate_stat_cache(sfnode_t *node) +{ + node->sf_stat_time = 0; +} + +static int +sfnode_update_stat_cache(sfnode_t *node) +{ + int error; + + error = sfnode_get_stat(node->sf_sffs->sf_handle, node->sf_path, + &node->sf_stat); + if (error == ENOENT) + sfnode_make_stale(node); + if (error == 0) + node->sf_stat_time = sfnode_cur_time_usec(); + + return (error); +} + /* * Rename a file or a directory */ @@ -430,6 +512,8 @@ sfnode_rename(sfnode_t *node, sfnode_t *newparent, char *path) panic("sfnode_rename(%s) no parent", node->sf_path); if (node->sf_parent->sf_children == 0) panic("sfnode_rename(%s) parent has no child", node->sf_path); + sfnode_clear_dir_list(node->sf_parent); + sfnode_clear_dir_list(newparent); --node->sf_parent->sf_children; node->sf_parent = newparent; ++newparent->sf_children; @@ -444,7 +528,12 @@ sfnode_rename(sfnode_t *node, sfnode_t *newparent, char *path) * bumped by 1. */ static sfnode_t * -sfnode_lookup(sfnode_t *dir, char *name, vtype_t create) +sfnode_lookup( + sfnode_t *dir, + char *name, + vtype_t create, + sffs_stat_t *stat, + uint64_t stat_time) { avl_index_t where; sfnode_t template; @@ -453,6 +542,7 @@ sfnode_lookup(sfnode_t *dir, char *name, vtype_t create) int type; char *fullpath; sfp_file_t *fp; + sffs_stat_t tmp_stat; ASSERT(MUTEX_HELD(&sffs_lock)); @@ -498,8 +588,15 @@ sfnode_lookup(sfnode_t *dir, char *name, vtype_t create) mode_t m; fp = NULL; type = VNON; - error = - sfprov_get_mode(dir->sf_sffs->sf_handle, fullpath, &m); + if (stat == NULL) { + stat = &tmp_stat; + error = sfnode_get_stat(dir->sf_sffs->sf_handle, + fullpath, stat); + stat_time = sfnode_cur_time_usec(); + } else { + error = 0; + } + m = stat->sf_mode; if (error != 0) error = ENOENT; else if (S_ISDIR(m)) @@ -515,7 +612,8 @@ sfnode_lookup(sfnode_t *dir, char *name, vtype_t create) kmem_free(fullpath, strlen(fullpath) + 1); return (NULL); } - node = sfnode_make(dir->sf_sffs, fullpath, type, fp, dir); + node = sfnode_make(dir->sf_sffs, fullpath, type, fp, dir, stat, + stat_time); return (node); } @@ -535,14 +633,13 @@ sfnode_access(sfnode_t *node, mode_t mode, cred_t *cr) ASSERT(MUTEX_HELD(&sffs_lock)); /* - * get the mode from the provider + * get the mode from the cache or provider */ - error = sfprov_get_mode(node->sf_sffs->sf_handle, node->sf_path, &m); - if (error != 0) { - m = 0; - if (error == ENOENT) - sfnode_make_stale(node); - } + if (sfnode_stat_cached(node)) + error = 0; + else + error = sfnode_update_stat_cache(node); + m = (error == 0) ? node->sf_stat.sf_mode : 0; /* * mask off the permissions based on uid/gid @@ -581,14 +678,12 @@ sffs_readdir( sfnode_t *dir = VN2SFN(vp); sfnode_t *node; struct dirent64 *dirent; + sffs_dirents_t *cur_buf; + sffs_stats_t *cur_stats; + int cur_snum; + offset_t offset; int dummy_eof; int error = 0; - int namelen; - void *prov_buff = NULL; - size_t prov_buff_size; - char **names; - uint32_t nents; - uint32_t index; if (uiop->uio_iovcnt != 1) return (EINVAL); @@ -605,63 +700,70 @@ sffs_readdir( return (0); } - dirent = kmem_zalloc(DIRENT64_RECLEN(MAXNAMELEN), KM_SLEEP); - /* * Get the directory entry names from the host. This gets all - * entries, so add in starting offset. Max the caller can expect - * would be the size of the UIO buffer / sizeof of a dirent for - * file with name of length 1 + * entries. These are stored in a linked list of sffs_dirents_t + * buffers, each of which contains a list of dirent64_t's. */ mutex_enter(&sffs_lock); - index = uiop->uio_loffset; - nents = index + (uiop->uio_resid / DIRENT64_RECLEN(1)); - error = sfprov_readdir(dir->sf_sffs->sf_handle, dir->sf_path, - &prov_buff, &prov_buff_size, &nents); - if (error != 0) - goto done; - if (nents <= index) { - *eofp = 1; - goto done; + + if (dir->sf_dir_list == NULL) { + error = sfprov_readdir(dir->sf_sffs->sf_handle, dir->sf_path, + &dir->sf_dir_list, &dir->sf_dir_stats); + if (error != 0) + goto done; } - names = (void *)prov_buff; /* - * Lookup each of the names, so that we have ino's. + * Lookup each of the names, so that we have ino's, and copy to + * result buffer. */ - for (; index < nents; ++index) { - if (strcmp(names[index], ".") == 0) { + offset = 0; + cur_buf = dir->sf_dir_list; + cur_stats = dir->sf_dir_stats; + cur_snum = 0; + while (cur_buf != NULL) { + if (offset + cur_buf->sf_len <= uiop->uio_loffset) { + offset += cur_buf->sf_len; + cur_buf = cur_buf->sf_next; + continue; + } + + if (cur_snum >= SFFS_STATS_LEN) { + cur_stats = cur_stats->sf_next; + cur_snum = 0; + } + + dirent = (dirent64_t *) + (((char *) &cur_buf->sf_entries[0]) + + (uiop->uio_loffset - offset)); + if (dirent->d_reclen > uiop->uio_resid) + break; + + if (strcmp(dirent->d_name, ".") == 0) { node = dir; - } else if (strcmp(names[index], "..") == 0) { + } else if (strcmp(dirent->d_name, "..") == 0) { node = dir->sf_parent; if (node == NULL) node = dir; } else { - node = sfnode_lookup(dir, names[index], VNON); + node = sfnode_lookup(dir, dirent->d_name, VNON, + &cur_stats->sf_stats[cur_snum], + sfnode_cur_time_usec()); if (node == NULL) panic("sffs_readdir() lookup failed"); } - namelen = strlen(names[index]); - strcpy(&dirent->d_name[0], names[index]); - dirent->d_reclen = DIRENT64_RECLEN(namelen); - dirent->d_off = index; dirent->d_ino = node->sf_ino; - if (dirent->d_reclen > uiop->uio_resid) { - error = ENOSPC; - break; - } + error = uiomove(dirent, dirent->d_reclen, UIO_READ, uiop); + ++cur_snum; if (error != 0) break; - bzero(&dirent->d_name[0], namelen); } - if (error == 0 && index >= nents) + if (error == 0 && cur_buf == NULL) *eofp = 1; done: mutex_exit(&sffs_lock); - if (prov_buff != NULL) - kmem_free(prov_buff, prov_buff_size); - kmem_free(dirent, DIRENT64_RECLEN(MAXNAMELEN)); return (error); } @@ -706,9 +808,7 @@ sffs_getattr( sfnode_t *node = VN2SFN(vp); sffs_data_t *sffs = node->sf_sffs; mode_t mode; - timestruc_t time; - uint64_t x; - int error; + int error = 0; mutex_enter(&sffs_lock); vap->va_type = vp->v_type; @@ -720,47 +820,108 @@ sffs_getattr( vap->va_rdev = sffs->sf_vfsp->vfs_dev; vap->va_seq = 0; - error = sfprov_get_mode(node->sf_sffs->sf_handle, node->sf_path, &mode); - if (error == ENOENT) - sfnode_make_stale(node); - if (error != 0) - goto done; - vap->va_mode = mode & MODEMASK; + if (!sfnode_stat_cached(node)) { + error = sfnode_update_stat_cache(node); + if (error != 0) + goto done; + } - error = sfprov_get_size(node->sf_sffs->sf_handle, node->sf_path, &x); - if (error == ENOENT) - sfnode_make_stale(node); - if (error != 0) - goto done; - vap->va_size = x; + vap->va_atime = node->sf_stat.sf_atime; + vap->va_mtime = node->sf_stat.sf_mtime; + vap->va_ctime = node->sf_stat.sf_ctime; + + mode = node->sf_stat.sf_mode; + vap->va_mode = mode & MODEMASK; + if (S_ISDIR(mode)) + vap->va_type = VDIR; + else if (S_ISREG(mode)) + vap->va_type = VREG; + else if (S_ISFIFO(mode)) + vap->va_type = VFIFO; + else if (S_ISCHR(mode)) + vap->va_type = VCHR; + else if (S_ISBLK(mode)) + vap->va_type = VBLK; + else if (S_ISLNK(mode)) + vap->va_type = VLNK; + else if (S_ISSOCK(mode)) + vap->va_type = VSOCK; + + vap->va_size = node->sf_stat.sf_size; vap->va_blksize = 512; - vap->va_nblocks = (x + 511) / 512; + vap->va_nblocks = (vap->va_size + 511) / 512; - error = - sfprov_get_atime(node->sf_sffs->sf_handle, node->sf_path, &time); - if (error == ENOENT) - sfnode_make_stale(node); - if (error != 0) - goto done; - vap->va_atime = time; +done: + mutex_exit(&sffs_lock); + return (error); +} - error = - sfprov_get_mtime(node->sf_sffs->sf_handle, node->sf_path, &time); +static int +sffs_setattr( + vnode_t *vp, + vattr_t *vap, + int flags, + cred_t *cred, + caller_context_t *ct) +{ + sfnode_t *node = VN2SFN(vp); + int error; + mode_t mode; + + mode = vap->va_mode; + if (vp->v_type == VREG) + mode |= S_IFREG; + else if (vp->v_type == VDIR) + mode |= S_IFDIR; + else if (vp->v_type == VBLK) + mode |= S_IFBLK; + else if (vp->v_type == VCHR) + mode |= S_IFCHR; + else if (vp->v_type == VLNK) + mode |= S_IFLNK; + else if (vp->v_type == VFIFO) + mode |= S_IFIFO; + else if (vp->v_type == VSOCK) + mode |= S_IFSOCK; + + mutex_enter(&sffs_lock); + + sfnode_invalidate_stat_cache(node); + error = sfprov_set_attr(node->sf_sffs->sf_handle, node->sf_path, + vap->va_mask, mode, vap->va_atime, vap->va_mtime, vap->va_ctime); if (error == ENOENT) sfnode_make_stale(node); - if (error != 0) - goto done; - vap->va_mtime = time; - error = - sfprov_get_ctime(node->sf_sffs->sf_handle, node->sf_path, &time); + mutex_exit(&sffs_lock); + return (error); +} + +static int +sffs_space( + vnode_t *vp, + int cmd, + struct flock64 *bfp, + int flags, + offset_t off, + cred_t *cred, + caller_context_t *ct) +{ + sfnode_t *node = VN2SFN(vp); + int error; + + /* we only support changing the length of the file */ + if (bfp->l_whence != SEEK_SET || bfp->l_len != 0) + return ENOSYS; + + mutex_enter(&sffs_lock); + + sfnode_invalidate_stat_cache(node); + + error = sfprov_set_size(node->sf_sffs->sf_handle, node->sf_path, + bfp->l_start); if (error == ENOENT) sfnode_make_stale(node); - if (error != 0) - goto done; - vap->va_ctime = time; -done: mutex_exit(&sffs_lock); return (error); } @@ -786,12 +947,12 @@ sffs_read( if (vp->v_type != VREG) return (EINVAL); if (uio->uio_loffset >= MAXOFF_T) - return (0); - if (uio->uio_loffset < 0) - return (EINVAL); - total = uio->uio_resid; - if (total == 0) - return (0); + return (0); + if (uio->uio_loffset < 0) + return (EINVAL); + total = uio->uio_resid; + if (total == 0) + return (0); mutex_enter(&sffs_lock); sfnode_open(node); @@ -850,6 +1011,9 @@ sffs_write( mutex_exit(&sffs_lock); return (EINVAL); } + + sfnode_invalidate_stat_cache(node); + if (ioflag & FAPPEND) { uint64_t endoffile; @@ -866,12 +1030,12 @@ sffs_write( if (vp->v_type != VREG || uiop->uio_loffset < 0) { mutex_exit(&sffs_lock); - return (EINVAL); + return (EINVAL); } if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T) - limit = MAXOFFSET_T; + limit = MAXOFFSET_T; if (limit > MAXOFF_T) - limit = MAXOFF_T; + limit = MAXOFF_T; if (uiop->uio_loffset >= limit) { proc_t *p = ttoproc(curthread); @@ -888,22 +1052,21 @@ sffs_write( return (EFBIG); } - - total = uiop->uio_resid; - if (total == 0) { + total = uiop->uio_resid; + if (total == 0) { mutex_exit(&sffs_lock); - return (0); + return (0); } do { offset = uiop->uio_offset; bytes = MIN(PAGESIZE, uiop->uio_resid); if (offset + bytes >= limit) { - if (offset >= limit) { - error = EFBIG; - break; - } - bytes = limit - offset; + if (offset >= limit) { + error = EFBIG; + break; + } + bytes = limit - offset; } error = uiomove(sffs_buffer, bytes, UIO_WRITE, uiop); if (error != 0) @@ -993,7 +1156,7 @@ sffs_lookup( /* * Lookup the node. */ - node = sfnode_lookup(VN2SFN(dvp), name, VNON); + node = sfnode_lookup(VN2SFN(dvp), name, VNON, NULL, 0); if (node != NULL) *vpp = sfnode_get_vnode(node); mutex_exit(&sffs_lock); @@ -1060,6 +1223,8 @@ sffs_create( return (error); } + sfnode_invalidate_stat_cache(VN2SFN(dvp)); + /* * handle truncating an existing file */ @@ -1086,7 +1251,7 @@ sffs_create( * Create a new node. First check for a race creating it. */ mutex_enter(&sffs_lock); - node = sfnode_lookup(VN2SFN(dvp), name, VNON); + node = sfnode_lookup(VN2SFN(dvp), name, VNON, NULL, 0); if (node != NULL) { mutex_exit(&sffs_lock); return (EEXIST); @@ -1095,7 +1260,20 @@ sffs_create( /* * Doesn't exist yet and we have the lock, so create it. */ - node = sfnode_lookup(VN2SFN(dvp), name, VREG); + sfnode_invalidate_stat_cache(VN2SFN(dvp)); + node = sfnode_lookup(VN2SFN(dvp), name, VREG, NULL, 0); + if (node && (vap->va_mask & AT_MODE)) { + timestruc_t dummy; + error = sfprov_set_attr(node->sf_sffs->sf_handle, node->sf_path, + AT_MODE, vap->va_mode, dummy, dummy, dummy); + if (error) + cmn_err(CE_WARN, "sffs_create: set_mode(%s, %o) failed" + " rc=%d", node->sf_path, vap->va_mode, error); + } + + if (node->sf_parent) + sfnode_clear_dir_list(node->sf_parent); + mutex_exit(&sffs_lock); if (node == NULL) return (EINVAL); @@ -1148,7 +1326,21 @@ sffs_mkdir( return (error); } - node = sfnode_lookup(VN2SFN(dvp), nm, VDIR); + sfnode_invalidate_stat_cache(VN2SFN(dvp)); + + node = sfnode_lookup(VN2SFN(dvp), nm, VDIR, NULL, 0); + if (node && (va->va_mask & AT_MODE)) { + timestruc_t dummy; + error = sfprov_set_attr(node->sf_sffs->sf_handle, node->sf_path, + AT_MODE, va->va_mode, dummy, dummy, dummy); + if (error) + cmn_err(CE_WARN, "sffs_mkdir: set_mode(%s, %o) failed" + " rc=%d", node->sf_path, va->va_mode, error); + } + + if (node->sf_parent) + sfnode_clear_dir_list(node->sf_parent); + mutex_exit(&sffs_lock); if (node == NULL) return (EACCES); @@ -1224,9 +1416,13 @@ sffs_rmdir( /* * Remove the directory on the host and mark the node as stale. */ + sfnode_invalidate_stat_cache(VN2SFN(dvp)); error = sfprov_rmdir(node->sf_sffs->sf_handle, node->sf_path); if (error == ENOENT || error == 0) sfnode_make_stale(node); + + if (node->sf_parent) + sfnode_clear_dir_list(node->sf_parent); done: mutex_exit(&sffs_lock); VN_RELE(vp); @@ -1283,9 +1479,14 @@ sffs_remove( /* * Remove the file on the host and mark the node as stale. */ + sfnode_invalidate_stat_cache(VN2SFN(dvp)); + error = sfprov_remove(node->sf_sffs->sf_handle, node->sf_path); if (error == ENOENT || error == 0) sfnode_make_stale(node); + + if (node->sf_parent) + sfnode_clear_dir_list(node->sf_parent); done: mutex_exit(&sffs_lock); VN_RELE(vp); @@ -1325,16 +1526,19 @@ sffs_rename( if (error) goto done; - node = sfnode_lookup(VN2SFN(old_dir), old_nm, VNON); + node = sfnode_lookup(VN2SFN(old_dir), old_nm, VNON, NULL, 0); if (node == NULL) { error = ENOENT; goto done; } - /* * Rename the file on the host and in our caches. */ + sfnode_invalidate_stat_cache(node); + sfnode_invalidate_stat_cache(VN2SFN(old_dir)); + sfnode_invalidate_stat_cache(VN2SFN(new_dir)); + newpath = sfnode_construct_path(VN2SFN(new_dir), new_nm); error = sfprov_rename(node->sf_sffs->sf_handle, node->sf_path, newpath, node->sf_type == VDIR); @@ -1355,20 +1559,22 @@ done: static int sffs_fsync(vnode_t *vp, int flag, cred_t *cr, caller_context_t *ct) { -#if 0 sfnode_t *node; + int error; /* * Ask the host to sync any data it may have cached for open files. - * I don't think we care about errors. */ mutex_enter(&sffs_lock); node = VN2SFN(vp); - if (node->sf_file != NULL) - (void) sfprov_fsync(node->sf_file); + if (node->sf_file == NULL) + error = EBADF; + else if (node->sf_sffs->sf_fsync) + error = sfprov_fsync(node->sf_file); + else + error = 0; mutex_exit(&sffs_lock); -#endif - return (0); + return (error); } /* @@ -1377,7 +1583,11 @@ sffs_fsync(vnode_t *vp, int flag, cred_t *cr, caller_context_t *ct) */ /*ARGSUSED*/ static void +#if defined(VBOX_VFS_SOLARIS_10U6) +sffs_inactive(vnode_t *vp, cred_t *cr) +#else sffs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) +#endif { sfnode_t *node; @@ -1407,7 +1617,7 @@ sffs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) mutex_exit(&vp->v_lock); vn_invalid(vp); vn_free(vp); - LogFlowFunc((" %s vnode cleared\n", node->sf_path)); + LogFlowFunc((" %s vnode cleared\n", node->sf_path)); /* * Close the sf_file for the node. @@ -1418,6 +1628,13 @@ sffs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) } /* + * Free the directory entries for the node. This should normally + * have been taken care of in sffs_close(), but better safe than + * sorry. + */ + sfnode_clear_dir_list(node); + + /* * If the node is stale, we can also destroy it. */ if (node->sf_is_stale && node->sf_children == 0) @@ -1450,6 +1667,25 @@ sffs_close( cred_t *cr, caller_context_t *ct) { + sfnode_t *node; + + mutex_enter(&sffs_lock); + node = VN2SFN(vp); + + /* + * Free the directory entries for the node. We do this on this call + * here because the directory node may not become inactive for a long + * time after the readdir is over. Case in point, if somebody cd's into + * the directory then it won't become inactive until they cd away again. + * In such a case we would end up with the directory listing not getting + * updated (i.e. the result of 'ls' always being the same) until they + * change the working directory. + */ + sfnode_clear_dir_list(node); + + sfnode_invalidate_stat_cache(node); + + mutex_exit(&sffs_lock); return (0); } @@ -1497,6 +1733,8 @@ const fs_operation_def_t sffs_ops_template[] = { VOPNAME_RENAME, sffs_rename, VOPNAME_RMDIR, sffs_rmdir, VOPNAME_SEEK, sffs_seek, + VOPNAME_SETATTR, sffs_setattr, + VOPNAME_SPACE, sffs_space, VOPNAME_WRITE, sffs_write, NULL, NULL #else @@ -1517,6 +1755,8 @@ const fs_operation_def_t sffs_ops_template[] = { VOPNAME_RENAME, { .vop_rename = sffs_rename }, VOPNAME_RMDIR, { .vop_rmdir = sffs_rmdir }, VOPNAME_SEEK, { .vop_seek = sffs_seek }, + VOPNAME_SETATTR, { .vop_setattr = sffs_setattr }, + VOPNAME_SPACE, { .vop_space = sffs_space }, VOPNAME_WRITE, { .vop_write = sffs_write }, NULL, NULL #endif @@ -1607,7 +1847,6 @@ sffs_purge(struct sffs_data *sffs) prev = node; } } -done: mutex_exit(&sffs_lock); return (0); } diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h index 20392e6c9..278ea6442 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h @@ -47,6 +47,10 @@ typedef struct sfnode { uint16_t sf_children; /* number of children sfnodes */ uint8_t sf_type; /* VDIR or VREG */ uint8_t sf_is_stale; /* this is stale and should be purged */ + sffs_stat_t sf_stat; /* cached file attrs for this node */ + uint64_t sf_stat_time; /* last-modified time of sf_stat */ + sffs_dirents_t *sf_dir_list; /* list of entries for this directory */ + sffs_stats_t *sf_dir_stats; /* file attrs for the above entries */ } sfnode_t; #define VN2SFN(vp) ((sfnode_t *)(vp)->v_data) @@ -55,7 +59,7 @@ typedef struct sfnode { extern int sffs_vnode_init(void); extern void sffs_vnode_fini(void); extern sfnode_t *sfnode_make(struct sffs_data *, char *, vtype_t, sfp_file_t *, - sfnode_t *parent); + sfnode_t *parent, sffs_stat_t *, uint64_t stat_time); extern vnode_t *sfnode_get_vnode(sfnode_t *); /* diff --git a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk index 87921d9ef..381c7b8ef 100644 --- a/src/VBox/Additions/x11/vboxvideo/Makefile.kmk +++ b/src/VBox/Additions/x11/vboxvideo/Makefile.kmk @@ -275,7 +275,7 @@ ifdef VBOX_WITH_TESTCASES OTHERS += $(PATH_vboxvideo_drv)/tstvboxvideo68.run $$(PATH_vboxvideo_drv)/tstvboxvideo68.run: $$(INSTARGET_vboxvideo_drv) $(QUIET)/bin/sh $(PATH_ROOT)/src/bldprogs/checkUndefined.sh $(KBUILD_TARGET) \ - $(INSTARGET_vboxvideo_drv) $(OUR_PATH_VBOXVIDEO)/undefined_70 --static + $(INSTARGET_vboxvideo_drv) $(OUR_PATH_VBOXVIDEO)/undefined_68 --static $(QUIET)$(APPEND) -t "$@" "done" endif diff --git a/src/VBox/Additions/x11/vboxvideo/undefined_68 b/src/VBox/Additions/x11/vboxvideo/undefined_68 index 6b36dcb1b..ebcea43db 100644 --- a/src/VBox/Additions/x11/vboxvideo/undefined_68 +++ b/src/VBox/Additions/x11/vboxvideo/undefined_68 @@ -1,76 +1,104 @@ -xf86PruneDriverModes -xf86DPMSInit -xf86GetEntityInfo -miSetPixmapDepths -xf86SetGamma -xf86MapPciMem -xf86LoaderReqSymLists -xf86LoadSubModule -xf86open -xf86memset -serverGeneration +DGAInit +ErrorF +LoaderRefSymLists +PixmapWidthPaddingInfo +SetTimeSinceLastInputEvent +ShadowFBInit2 +VBEExtendedInit +VBEGetVBEMode +VBEInit +VBESaveRestore +VBESetDisplayStart +VBESetGetPaletteData +VBESetVBEMode +VErrorF +XNFalloc +XNFcalloc +XNFrealloc +XNFstrdup +Xalloc +Xcalloc Xfree Xrealloc -xf86SetBlackWhitePixels -xf86Screens -xf86ShowUnusedOptions -xf86GetPciVideoInfo -xf86AddDriver -xf86ValidateModes -xf86ConfigPciEntity -xf86strerror -xf86SetDefaultVisual -xf86IsUnblank -VBESetVBEMode +fbPictureInit +fbScreenInit +flock +miClearVisualTypes +miCreateDefColormap miDCInitialize -LoaderRefSymLists -xf86DrvMsg +miInitializeBackingStore +miSetPixmapDepths miSetVisualTypes -xf86SetWeight -xf86CollectOptions pciFindFirst -xf86PrintChipsets -fbPictureInit -SetTimeSinceLastInputEvent -miCreateDefColormap -xf86close -xf86ioctl -XNFrealloc +pciReadLong +pciTag +pthread_sigmask +resVgaShared +serverGeneration +sigdelset +sigfillset +vgaHWDPMSSet +vgaHWFreeHWRec +vgaHWGetHWRec +vgaHWGetIndex +vgaHWHandleColormaps +vgaHWMapMem +vgaHWRestoreFonts +vgaHWSaveFonts +vgaHWSaveScreen +vgaHWUnmapMem +xf86AddDriver +xf86CollectOptions +xf86ConfigPciEntity +xf86CreateCursorInfoRec +xf86DPMSInit +xf86DestroyCursorInfoRec +xf86DrvMsg +xf86GetEntityInfo +xf86GetPciInfoForEntity +xf86GetPciVideoInfo +xf86GetPointerScreenFuncs +xf86HandleColormaps +xf86InitCursor +xf86IsUnblank +xf86LoadSubModule +xf86LoaderReqSymLists +xf86MapPciMem +xf86MapVidMem +xf86MatchDevice xf86MatchPciInstances -VBEInit +xf86Msg +xf86PrintChipsets xf86PrintDepthBpp -xf86HandleColormaps -xf86GetPointerScreenFuncs -Xcalloc +xf86PrintModes +xf86ProcessOptions +xf86PruneDriverModes +xf86Screens +xf86SetBackingStore +xf86SetBlackWhitePixels +xf86SetDefaultVisual +xf86SetDepthBpp xf86SetDpi -miInitializeBackingStore -pciReadLong -miClearVisualTypes -xf86MatchDevice -XNFcalloc -xf86UnMapVidMem -VBEGetVBEMode -ShadowFBInit2 +xf86SetGamma +xf86SetWeight +xf86ShowUnusedOptions xf86SlowBcopy +xf86UnMapVidMem +xf86ValidateModes +xf86close +xf86errno +xf86ioctl +xf86isspace +xf86memchr xf86memcpy -xf86ProcessOptions -xf86InitCursor -DGAInit -pciTag -VBESaveRestore -PixmapWidthPaddingInfo -Xalloc -VBESetDisplayStart +xf86memset +xf86open +xf86sprintf xf86sscanf -xf86SetDepthBpp -XNFalloc -fbScreenInit -xf86PrintModes +xf86strcmp +xf86strcpy xf86strdup -xf86MapVidMem -VBESetGetPaletteData -xf86GetPciInfoForEntity -xf86errno -xf86CreateCursorInfoRec -resVgaShared -xf86SetBackingStore +xf86strerror +xf86strlen +xf86strtoul +xf86vsnprintf diff --git a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/env.cmd b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/env.cmd index 2eeead491..1b11dc228 100644 --- a/src/VBox/Devices/EFI/Firmware2/VBoxPkg/env.cmd +++ b/src/VBox/Devices/EFI/Firmware2/VBoxPkg/env.cmd @@ -6,16 +6,16 @@ REM * Environment Setup Script for VBoxPkg + EDK2. REM */
REM /*
-REM Copyright (C) 2009 Oracle Corporation
-REM
-REM This file is part of VirtualBox Open Source Edition (OSE), as
-REM available from http://www.virtualbox.org. This file is free software;
-REM you can redistribute it and/or modify it under the terms of the GNU
-REM General Public License (GPL) as published by the Free Software
-REM Foundation, in version 2 as it comes in the "COPYING" file of the
-REM VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-REM hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-REM
+REM Copyright (C) 2009 Oracle Corporation +REM +REM This file is part of VirtualBox Open Source Edition (OSE), as +REM available from http://www.virtualbox.org. This file is free software; +REM you can redistribute it and/or modify it under the terms of the GNU +REM General Public License (GPL) as published by the Free Software +REM Foundation, in version 2 as it comes in the "COPYING" file of the +REM VirtualBox OSE distribution. VirtualBox OSE is distributed in the +REM hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +REM REM */
rem
diff --git a/src/VBox/Devices/Graphics/DevVGA.cpp b/src/VBox/Devices/Graphics/DevVGA.cpp index 28b9437c4..fb7f05091 100644 --- a/src/VBox/Devices/Graphics/DevVGA.cpp +++ b/src/VBox/Devices/Graphics/DevVGA.cpp @@ -127,6 +127,7 @@ #include <VBox/pgm.h> #ifdef IN_RING3 #include <iprt/alloc.h> +#include <iprt/ctype.h> #endif /* IN_RING3 */ #include <iprt/assert.h> #include <iprt/asm.h> @@ -4627,7 +4628,10 @@ static DECLCALLBACK(void) vgaInfoText(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, co { for (col = 0; col < num_cols; ++col) { - pHlp->pfnPrintf(pHlp, "%c", *src); + if (RT_C_IS_PRINT(*src)) + pHlp->pfnPrintf(pHlp, "%c", *src); + else + pHlp->pfnPrintf(pHlp, "."); src += 8; /* chars are spaced 8 bytes apart */ } pHlp->pfnPrintf(pHlp, "\n"); diff --git a/src/VBox/Devices/Network/DrvTAP.cpp b/src/VBox/Devices/Network/DrvTAP.cpp index 3cd66a8b2..92ab36aea 100644 --- a/src/VBox/Devices/Network/DrvTAP.cpp +++ b/src/VBox/Devices/Network/DrvTAP.cpp @@ -1104,12 +1104,6 @@ static DECLCALLBACK(int) drvTAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin } /* - * Create the transmit lock. - */ - rc = RTCritSectInit(&pThis->XmitLock); - AssertRCReturn(rc, rc); - - /* * Do the setup. */ # ifdef VBOX_WITH_CROSSBOW @@ -1139,6 +1133,12 @@ static DECLCALLBACK(int) drvTAPConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uin #endif /* !RT_OS_SOLARIS */ /* + * Create the transmit lock. + */ + rc = RTCritSectInit(&pThis->XmitLock); + AssertRCReturn(rc, rc); + + /* * Make sure the descriptor is non-blocking and valid. * * We should actually query if it's a TAP device, but I haven't diff --git a/src/VBox/Devices/Network/SrvIntNetR0.cpp b/src/VBox/Devices/Network/SrvIntNetR0.cpp index bd2e40d74..f084a5134 100644 --- a/src/VBox/Devices/Network/SrvIntNetR0.cpp +++ b/src/VBox/Devices/Network/SrvIntNetR0.cpp @@ -632,7 +632,7 @@ static void intnetR0BusyWait(PINTNETNETWORK pNetwork, uint32_t volatile *pcBusy) AssertMsg((cCurBusy & INTNET_BUSY_WAKEUP_MASK), ("%#x\n", cCurBusy)); AssertMsg((cCurBusy & ~INTNET_BUSY_WAKEUP_MASK) < INTNET_MAX_IFS * 3, ("%#x\n", cCurBusy)); } while ( cCurBusy != INTNET_BUSY_WAKEUP_MASK - || ASMAtomicCmpXchgU32(pcBusy, 0, INTNET_BUSY_WAKEUP_MASK)); + || !ASMAtomicCmpXchgU32(pcBusy, 0, INTNET_BUSY_WAKEUP_MASK)); } @@ -3676,8 +3676,9 @@ INTNETR0DECL(int) IntNetR0IfSetMacAddressReq(PSUPDRVSESSION pSession, PINTNETIFS * Worker for intnetR0IfSetActive and intnetR0IfDestruct. * * This function will update the active interface count on the network and - * activate or deactivate the trunk connection if necessary. Note that in - * order to do this it is necessary to abandond the network semaphore. + * activate or deactivate the trunk connection if necessary. + * + * The call must own the giant lock (we cannot take it here). * * @returns VBox status code. * @param pNetwork The network. @@ -3695,10 +3696,6 @@ static int intnetR0NetworkSetIfActive(PINTNETNETWORK pNetwork, PINTNETIF pIf, bo * big lock protects the calling of pfnSetState. Grab both lock at once * to save us the extra hazzle. */ - PINTNET pIntNet = pNetwork->pIntNet; - int rc = RTSemMutexRequest(pIntNet->hMtxCreateOpenDestroy, RT_INDEFINITE_WAIT); - AssertRCReturn(rc, rc); - PINTNETTRUNKIF pTrunk = NULL; RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; RTSpinlockAcquireNoInts(pNetwork->hAddrSpinlock, &Tmp); @@ -3744,11 +3741,15 @@ static int intnetR0NetworkSetIfActive(PINTNETNETWORK pNetwork, PINTNETIF pIf, bo /* * Tell the trunk if necessary. + * The wait for !busy is for the Solaris streams trunk driver (mostly). */ if (pTrunk && pTrunk->pIfPort) - pTrunk->pIfPort->pfnSetState(pTrunk->pIfPort, fActive ? INTNETTRUNKIFSTATE_ACTIVE : INTNETTRUNKIFSTATE_INACTIVE); + { + if (!fActive) + intnetR0BusyWait(pNetwork, &pTrunk->cBusy); - RTSemMutexRelease(pIntNet->hMtxCreateOpenDestroy); + pTrunk->pIfPort->pfnSetState(pTrunk->pIfPort, fActive ? INTNETTRUNKIFSTATE_ACTIVE : INTNETTRUNKIFSTATE_INACTIVE); + } return VINF_SUCCESS; } @@ -3784,20 +3785,32 @@ INTNETR0DECL(int) IntNetR0IfSetActive(INTNETIFHANDLE hIf, PSUPDRVSESSION pSessio * Hand it to the network since it might involve the trunk and things are * tricky there wrt to locking order. * - * Note! We mark the interface busy so the network cannot be removed while - * we're working on it - paranoia strikes again. + * 1. We take the giant lock here. This makes sure nobody is re-enabling + * the network while we're pausing it and vice versa. This also enables + * us to wait for the network to become idle before telling the trunk. + * (Important on Solaris.) + * + * 2. For paranoid reasons, we grab a busy reference to the calling + * interface. This is totally unnecessary but should hurt (when done + * after grabbing the giant lock). */ - intnetR0BusyIncIf(pIf); + int rc = RTSemMutexRequest(pIntNet->hMtxCreateOpenDestroy, RT_INDEFINITE_WAIT); + if (RT_SUCCESS(rc)) + { + intnetR0BusyIncIf(pIf); - int rc; - PINTNETNETWORK pNetwork = pIf->pNetwork; - if (pNetwork) - rc = intnetR0NetworkSetIfActive(pNetwork, pIf, fActive); - else - rc = VERR_WRONG_ORDER; + PINTNETNETWORK pNetwork = pIf->pNetwork; + if (pNetwork) + rc = intnetR0NetworkSetIfActive(pNetwork, pIf, fActive); + else + rc = VERR_WRONG_ORDER; + + intnetR0BusyDecIf(pIf); + RTSemMutexRelease(pIntNet->hMtxCreateOpenDestroy); + } - intnetR0BusyDecIf(pIf); intnetR0IfRelease(pIf, pSession); + LogFlow(("IntNetR0IfSetActive: returns %Rrc\n", rc)); return rc; } diff --git a/src/VBox/Devices/PC/BIOS/rombios.c b/src/VBox/Devices/PC/BIOS/rombios.c index 925c944b0..ed038dea1 100644 --- a/src/VBox/Devices/PC/BIOS/rombios.c +++ b/src/VBox/Devices/PC/BIOS/rombios.c @@ -10243,11 +10243,7 @@ pci_routing_table_structure: db 0x24, 0x50, 0x49, 0x52 ;; "$PIR" signature db 0, 1 ;; version #ifdef VBOX -#if 0 dw 32 + (30 * 16) ;; table size -#else - dw 32 + (20 * 16) ;; table size -#endif #else /* !VBOX */ dw 32 + (6 * 16) ;; table size #endif /* !VBOX */ diff --git a/src/VBox/Devices/PC/DevPcBios.cpp b/src/VBox/Devices/PC/DevPcBios.cpp index 8236fd25b..2044d3a94 100644 --- a/src/VBox/Devices/PC/DevPcBios.cpp +++ b/src/VBox/Devices/PC/DevPcBios.cpp @@ -96,7 +96,7 @@ 0x61 - 0x65 Second CMOS bank (offsets 0x80 to 0xff): - Reserved for future use: + Reserved for internal use by PXE ROM: 0x80 - 0x81 First net boot device PCI bus/dev/fn: 0x82 - 0x83 diff --git a/src/VBox/Devices/PC/vbox.dsl b/src/VBox/Devices/PC/vbox.dsl index 0b2a40478..1f108e8c0 100644 --- a/src/VBox/Devices/PC/vbox.dsl +++ b/src/VBox/Devices/PC/vbox.dsl @@ -986,7 +986,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "VBOX ", "VBOXBIOS", 2) // (all of low memory space) ResourceProducer, // bit 0 of general flags is 0 PosDecode, // positive Decode - MinFixed, // Range is fixed + MinNotFixed, // Range is not fixed MaxFixed, // Range is fixed Cacheable, ReadWrite, @@ -995,7 +995,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 1, "VBOX ", "VBOXBIOS", 2) 0xffdfffff, // Max = 4GB - 2MB 0x00000000, // Translation - 0xdfdfffff, // Range Length (calculated + 0x00000000, // Range Length (calculated // dynamically) , // Optional field left blank , // Optional field left blank diff --git a/src/VBox/Devices/Storage/DevBusLogic.cpp b/src/VBox/Devices/Storage/DevBusLogic.cpp index 62ccd0668..639445980 100644 --- a/src/VBox/Devices/Storage/DevBusLogic.cpp +++ b/src/VBox/Devices/Storage/DevBusLogic.cpp @@ -275,9 +275,9 @@ typedef struct BUSLOGIC /** Pointer to the device instance - RC ptr. */ PPDMDEVINSRC pDevInsRC; - /* Whether R0 is enabled. */ + /** Whether R0 is enabled. */ bool fR0Enabled; - /** Whether GC is enabled. */ + /** Whether RC is enabled. */ bool fGCEnabled; /** Base address of the I/O ports. */ @@ -361,9 +361,7 @@ typedef struct BUSLOGIC /** Queue to send tasks to R3. - RC ptr */ RCPTRTYPE(PPDMQUEUE) pNotifierQueueRC; -#if HC_ARCH_BITS == 64 uint32_t Alignment2; -#endif /** Critical section protecting access to the interrupt status register. */ PDMCRITSECT CritSectIntr; @@ -379,19 +377,19 @@ typedef struct BUSLOGIC /** The base interface. * @todo use PDMDEVINS::IBase */ - PDMIBASE IBase; + PDMIBASE IBase; /** Status Port - Leds interface. */ - PDMILEDPORTS ILeds; + PDMILEDPORTS ILeds; /** Partner of ILeds. */ - R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector; + R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector; #if HC_ARCH_BITS == 64 - uint32_t Alignment3; + uint32_t Alignment3; #endif /** Indicates that PDMDevHlpAsyncNotificationCompleted should be called when * a port is entering the idle state. */ - bool volatile fSignalIdle; + bool volatile fSignalIdle; } BUSLOGIC, *PBUSLOGIC; @@ -783,20 +781,22 @@ static void buslogicClearInterrupt(PBUSLOGIC pBusLogic) { LogFlowFunc(("pBusLogic=%#p\n", pBusLogic)); pBusLogic->regInterrupt = 0; - PDMDevHlpPCISetIrqNoWait(pBusLogic->CTX_SUFF(pDevIns), 0, 0); + PDMDevHlpPCISetIrq(pBusLogic->CTX_SUFF(pDevIns), 0, 0); } /** * Assert IRQ line of the BusLogic adapter. * * @returns nothing. - * @param pBusLogic Pointer to the BusLogic device instance. + * @param pBusLogic Pointer to the BusLogic device instance. + * @param fSuppressIrq Flag to suppress IRQ generation regardless of fIRQEnabled */ -static void buslogicSetInterrupt(PBUSLOGIC pBusLogic) +static void buslogicSetInterrupt(PBUSLOGIC pBusLogic, bool fSuppressIrq) { LogFlowFunc(("pBusLogic=%#p\n", pBusLogic)); pBusLogic->regInterrupt |= BUSLOGIC_REGISTER_INTERRUPT_INTERRUPT_VALID; - PDMDevHlpPCISetIrqNoWait(pBusLogic->CTX_SUFF(pDevIns), 0, 1); + if (pBusLogic->fIRQEnabled && !fSuppressIrq) + PDMDevHlpPCISetIrq(pBusLogic->CTX_SUFF(pDevIns), 0, 1); } #if defined(IN_RING3) @@ -840,7 +840,7 @@ static int buslogicHwReset(PBUSLOGIC pBusLogic) LogFlowFunc(("pBusLogic=%#p\n", pBusLogic)); /* Reset registers to default value. */ - pBusLogic->regStatus = BUSLOGIC_REGISTER_STATUS_HOST_ADAPTER_READY; + pBusLogic->regStatus = BUSLOGIC_REGISTER_STATUS_HOST_ADAPTER_READY | BUSLOGIC_REGISTER_STATUS_INITIALIZATION_REQUIRED; pBusLogic->regInterrupt = 0; pBusLogic->regGeometry = BUSLOGIC_REGISTER_GEOMETRY_EXTENTED_TRANSLATION_ENABLED; pBusLogic->uOperationCode = 0xff; /* No command executing. */ @@ -862,9 +862,10 @@ static int buslogicHwReset(PBUSLOGIC pBusLogic) * Resets the command state machine for the next command and notifies the guest. * * @returns nothing. - * @param pBusLogic Pointer to the BusLogic device instance + * @param pBusLogic Pointer to the BusLogic device instance + * @param fSuppressIrq Flag to suppress IRQ generation regardless of current state */ -static void buslogicCommandComplete(PBUSLOGIC pBusLogic) +static void buslogicCommandComplete(PBUSLOGIC pBusLogic, bool fSuppressIrq) { LogFlowFunc(("pBusLogic=%#p\n", pBusLogic)); @@ -873,15 +874,13 @@ static void buslogicCommandComplete(PBUSLOGIC pBusLogic) pBusLogic->iReply = 0; /* Modify I/O address does not generate an interrupt. */ - if ( (pBusLogic->uOperationCode != BUSLOGICCOMMAND_MODIFY_IO_ADDRESS) - && (pBusLogic->uOperationCode != BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND)) + if (pBusLogic->uOperationCode != BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND) { /* Notify that the command is complete. */ pBusLogic->regStatus &= ~BUSLOGIC_REGISTER_STATUS_DATA_IN_REGISTER_READY; pBusLogic->regInterrupt |= BUSLOGIC_REGISTER_INTERRUPT_COMMAND_COMPLETE; - if (pBusLogic->fIRQEnabled) - buslogicSetInterrupt(pBusLogic); + buslogicSetInterrupt(pBusLogic, fSuppressIrq); } pBusLogic->uOperationCode = 0xff; @@ -942,8 +941,7 @@ static void buslogicSendIncomingMailbox(PBUSLOGIC pBusLogic, PBUSLOGICTASKSTATE pBusLogic->uMailboxIncomingPositionCurrent = 0; pBusLogic->regInterrupt |= BUSLOGIC_REGISTER_INTERRUPT_INCOMING_MAILBOX_LOADED; - if (pBusLogic->fIRQEnabled) - buslogicSetInterrupt(pBusLogic); + buslogicSetInterrupt(pBusLogic, false); PDMCritSectLeave(&pBusLogic->CritSectIntr); } @@ -1266,6 +1264,7 @@ static int buslogicSenseBufferAlloc(PBUSLOGICTASKSTATE pTaskState) static int buslogicProcessCommand(PBUSLOGIC pBusLogic) { int rc = VINF_SUCCESS; + bool fSuppressIrq = false; LogFlowFunc(("pBusLogic=%#p\n", pBusLogic)); AssertMsg(pBusLogic->uOperationCode != 0xff, ("There is no command to execute\n")); @@ -1291,12 +1290,17 @@ static int buslogicProcessCommand(PBUSLOGIC pBusLogic) Log(("Disabling ISA I/O ports.\n")); pBusLogic->fISAEnabled = false; } + fSuppressIrq = true; break; } case BUSLOGICCOMMAND_INQUIRE_BOARD_ID: { - pBusLogic->aReplyBuffer[0] = '0'; /* @todo figure out what to write here. */ - pBusLogic->aReplyBuffer[1] = '0'; /* @todo figure out what to write here. */ + /* The special option byte is important: If it is '0' or 'B', Windows NT drivers + * for Adaptec AHA-154x may claim the adapter. The BusLogic drivers will claim + * the adapter only when the byte is *not* '0' or 'B'. + */ + pBusLogic->aReplyBuffer[0] = 'A'; /* Firmware option bytes */ + pBusLogic->aReplyBuffer[1] = 'A'; /* Special option byte */ /* We report version 5.07B. This reply will provide the first two digits. */ pBusLogic->aReplyBuffer[2] = '5'; /* Major version 5 */ @@ -1320,11 +1324,11 @@ static int buslogicProcessCommand(PBUSLOGIC pBusLogic) { /* The reply length is set by the guest and is found in the first byte of the command buffer. */ pBusLogic->cbReplyParametersLeft = pBusLogic->aCommandBuffer[0]; - memset(pBusLogic->aReplyBuffer, 0, pBusLogic->cbReplyParametersLeft); + memset(pBusLogic->aReplyBuffer, ' ', pBusLogic->cbReplyParametersLeft); const char aModelName[] = "958"; - int cCharsToTransfer = (pBusLogic->cbReplyParametersLeft <= sizeof(aModelName)) + int cCharsToTransfer = (pBusLogic->cbReplyParametersLeft <= (sizeof(aModelName) - 1)) ? pBusLogic->cbReplyParametersLeft - : sizeof(aModelName); + : sizeof(aModelName) - 1; for (int i = 0; i < cCharsToTransfer; i++) pBusLogic->aReplyBuffer[i] = aModelName[i]; @@ -1351,10 +1355,13 @@ static int buslogicProcessCommand(PBUSLOGIC pBusLogic) PReplyInquireExtendedSetupInformation pReply = (PReplyInquireExtendedSetupInformation)pBusLogic->aReplyBuffer; memset(pReply, 0, sizeof(ReplyInquireExtendedSetupInformation)); + //@todo: should this reflect the RAM contents (AutoSCSIRam)? + pReply->uBusType = 'E'; /* EISA style */ + pReply->u16ScatterGatherLimit = 8192; + pReply->fLevelSensitiveInterrupt = true; pReply->fHostWideSCSI = true; pReply->fHostUltraSCSI = true; - pReply->u16ScatterGatherLimit = 8192; - pBusLogic->regStatus |= BUSLOGIC_REGISTER_STATUS_INITIALIZATION_REQUIRED; + memcpy(pReply->aFirmwareRevision, "07B", sizeof(pReply->aFirmwareRevision)); break; } @@ -1392,6 +1399,7 @@ static int buslogicProcessCommand(PBUSLOGIC pBusLogic) Log(("GCPhysAddrMailboxOutgoingBase=%RGp\n", pBusLogic->GCPhysAddrMailboxIncomingBase)); Log(("cMailboxes=%u\n", pBusLogic->cMailbox)); + pBusLogic->regStatus &= ~BUSLOGIC_REGISTER_STATUS_INITIALIZATION_REQUIRED; pBusLogic->cbReplyParametersLeft = 0; break; } @@ -1449,6 +1457,28 @@ static int buslogicProcessCommand(PBUSLOGIC pBusLogic) pBusLogic->fIRQEnabled = false; else pBusLogic->fIRQEnabled = true; + /* No interrupt signaled regardless of enable/disable. */ + fSuppressIrq = true; + break; + } + case BUSLOGICCOMMAND_ECHO_COMMAND_DATA: + { + pBusLogic->aReplyBuffer[0] = pBusLogic->aCommandBuffer[0]; + pBusLogic->cbReplyParametersLeft = 1; + break; + } + case BUSLOGICCOMMAND_SET_PREEMPT_TIME_ON_BUS: + { + pBusLogic->cbReplyParametersLeft = 0; + pBusLogic->LocalRam.structured.autoSCSIData.uBusOnDelay = pBusLogic->aCommandBuffer[0]; + Log(("Bus-on time: %d\n", pBusLogic->aCommandBuffer[0])); + break; + } + case BUSLOGICCOMMAND_SET_TIME_OFF_BUS: + { + pBusLogic->cbReplyParametersLeft = 0; + pBusLogic->LocalRam.structured.autoSCSIData.uBusOffDelay = pBusLogic->aCommandBuffer[0]; + Log(("Bus-off time: %d\n", pBusLogic->aCommandBuffer[0])); break; } case BUSLOGICCOMMAND_EXECUTE_MAILBOX_COMMAND: /* Should be handled already. */ @@ -1456,13 +1486,13 @@ static int buslogicProcessCommand(PBUSLOGIC pBusLogic) AssertMsgFailed(("Invalid command %#x\n", pBusLogic->uOperationCode)); } - Log(("cbReplyParametersLeft=%d\n", pBusLogic->cbReplyParametersLeft)); + Log(("uOperationCode=%#x, cbReplyParametersLeft=%d\n", pBusLogic->uOperationCode, pBusLogic->cbReplyParametersLeft)); /* Set the data in ready bit in the status register in case the command has a reply. */ if (pBusLogic->cbReplyParametersLeft) pBusLogic->regStatus |= BUSLOGIC_REGISTER_STATUS_DATA_IN_REGISTER_READY; else - buslogicCommandComplete(pBusLogic); + buslogicCommandComplete(pBusLogic, fSuppressIrq); return rc; } @@ -1505,13 +1535,14 @@ static int buslogicRegisterRead(PBUSLOGIC pBusLogic, unsigned iRegister, uint32_ pBusLogic->iReply++; pBusLogic->cbReplyParametersLeft--; + LogFlowFunc(("cbReplyParametersLeft=%u\n", pBusLogic->cbReplyParametersLeft)); if (!pBusLogic->cbReplyParametersLeft) { /* * Reply finished, set command complete bit, unset data in ready bit and * interrupt the guest if enabled. */ - buslogicCommandComplete(pBusLogic); + buslogicCommandComplete(pBusLogic, false); } break; } @@ -1619,6 +1650,9 @@ static int buslogicRegisterWrite(PBUSLOGIC pBusLogic, unsigned iRegister, uint8_ case BUSLOGICCOMMAND_SET_CCB_FORMAT: case BUSLOGICCOMMAND_INQUIRE_SYNCHRONOUS_PERIOD: case BUSLOGICCOMMAND_DISABLE_HOST_ADAPTER_INTERRUPT: + case BUSLOGICCOMMAND_ECHO_COMMAND_DATA: + case BUSLOGICCOMMAND_SET_PREEMPT_TIME_ON_BUS: + case BUSLOGICCOMMAND_SET_TIME_OFF_BUS: pBusLogic->cbCommandParametersLeft = 1; break; case BUSLOGICCOMMAND_FETCH_HOST_ADAPTER_LOCAL_RAM: @@ -1771,7 +1805,7 @@ static int buslogicIsaIOPortRead (PPDMDEVINS pDevIns, void *pvUser, Assert(cb == 1); if (!pBusLogic->fISAEnabled) - return VERR_IOM_IOPORT_UNUSED; + return VINF_SUCCESS; rc = vboxscsiReadRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_ISA_IO_PORT), pu32); @@ -1855,7 +1889,7 @@ static int buslogicIsaIOPortWrite (PPDMDEVINS pDevIns, void *pvUser, Assert(cb == 1); if (!pBusLogic->fISAEnabled) - return VERR_IOM_IOPORT_UNUSED; + return VINF_SUCCESS; rc = vboxscsiWriteRegister(&pBusLogic->VBoxSCSI, (Port - BUSLOGIC_ISA_IO_PORT), (uint8_t)u32); if (rc == VERR_MORE_DATA) diff --git a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp index 4dc129247..1cb0bc291 100644 --- a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp +++ b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp @@ -29,6 +29,7 @@ # include <iprt/mem.h> # include <iprt/param.h> # include <iprt/uuid.h> +# include <iprt/time.h> #endif #include "DevLsiLogicSCSI.h" @@ -44,6 +45,9 @@ * include the device config part. */ #define LSILOGIC_SAVED_STATE_VERSION_VBOX_30 1 +/** Maximum number of entries in the release log. */ +#define MAX_REL_LOG_ERRORS 1024 + /** * Reply data. */ @@ -952,9 +956,19 @@ static int lsilogicRegisterWrite(PLSILOGICSCSI pThis, uint32_t uOffset, void *pv } case LSILOGIC_REG_REQUEST_QUEUE: { - ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[pThis->uRequestQueueNextEntryFreeWrite], u32); - pThis->uRequestQueueNextEntryFreeWrite++; - pThis->uRequestQueueNextEntryFreeWrite %= pThis->cRequestQueueEntries; + uint32_t uNextWrite = ASMAtomicReadU32(&pThis->uRequestQueueNextEntryFreeWrite); + + ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[uNextWrite], u32); + + /* + * Don't update the value in place. It can happen that we get preempted + * after the increment but before the modulo. + * Another EMT will read the wrong value when processing the queues + * and hang in an endless loop creating thousands of requests. + */ + uNextWrite++; + uNextWrite %= pThis->cRequestQueueEntries; + ASMAtomicWriteU32(&pThis->uRequestQueueNextEntryFreeWrite, uNextWrite); /* Send notification to R3 if there is not one send already. */ if (!ASMAtomicXchgBool(&pThis->fNotificationSend, true)) @@ -1896,23 +1910,6 @@ static int lsilogicProcessSCSIIORequest(PLSILOGICSCSI pLsiLogic, PLSILOGICTASKST pTaskState->fBIOS = false; - uint32_t uChainOffset = pTaskState->GuestRequest.SCSIIO.u8ChainOffset; - - if (uChainOffset) - uChainOffset = uChainOffset * sizeof(uint32_t) - sizeof(MptSCSIIORequest); - - /* Create Scatter gather list. */ - rc = lsilogicScatterGatherListCreate(pLsiLogic, pTaskState, - pTaskState->GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest), - uChainOffset); - AssertRC(rc); - -#if 0 - /* Map sense buffer. */ - rc = lsilogicMapGCSenseBufferIntoR3(pLsiLogic, pTaskState); - AssertRC(rc); -#endif - if (RT_LIKELY( (pTaskState->GuestRequest.SCSIIO.u8TargetID < pLsiLogic->cDeviceStates) && (pTaskState->GuestRequest.SCSIIO.u8Bus == 0))) { @@ -1921,6 +1918,25 @@ static int lsilogicProcessSCSIIORequest(PLSILOGICSCSI pLsiLogic, PLSILOGICTASKST if (pTargetDevice->pDrvBase) { + uint32_t uChainOffset; + + /* Create Scatter gather list. */ + uChainOffset = pTaskState->GuestRequest.SCSIIO.u8ChainOffset; + + if (uChainOffset) + uChainOffset = uChainOffset * sizeof(uint32_t) - sizeof(MptSCSIIORequest); + + rc = lsilogicScatterGatherListCreate(pLsiLogic, pTaskState, + pTaskState->GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest), + uChainOffset); + AssertRC(rc); + +#if 0 + /* Map sense buffer. */ + rc = lsilogicMapGCSenseBufferIntoR3(pLsiLogic, pTaskState); + AssertRC(rc); +#endif + /* Setup the SCSI request. */ pTaskState->pTargetDevice = pTargetDevice; pTaskState->PDMScsiRequest.uLogicalUnit = pTaskState->GuestRequest.SCSIIO.au8LUN[1]; @@ -1964,6 +1980,20 @@ static int lsilogicProcessSCSIIORequest(PLSILOGICSCSI pLsiLogic, PLSILOGICTASKST pTaskState->IOCReply.SCSIIOError.u16IOCStatus = MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_TARGETID; } + static int g_cLogged = 0; + + if (g_cLogged++ < MAX_REL_LOG_ERRORS) + { + LogRel(("LsiLogic#%d: %d/%d (Bus/Target) doesn't exist\n", pLsiLogic->CTX_SUFF(pDevIns)->iInstance, + pTaskState->GuestRequest.SCSIIO.u8TargetID, pTaskState->GuestRequest.SCSIIO.u8Bus)); + /* Log the CDB too */ + LogRel(("LsiLogic#%d: Guest issued CDB {%#x", + pLsiLogic->CTX_SUFF(pDevIns)->iInstance, pTaskState->GuestRequest.SCSIIO.au8CDB[0])); + for (unsigned i = 1; i < pTaskState->GuestRequest.SCSIIO.u8CDBLength; i++) + LogRel((", %#x", pTaskState->GuestRequest.SCSIIO.au8CDB[i])); + LogRel(("}\n")); + } + /* The rest is equal to both errors. */ pTaskState->IOCReply.SCSIIOError.u8TargetID = pTaskState->GuestRequest.SCSIIO.u8TargetID; pTaskState->IOCReply.SCSIIOError.u8Bus = pTaskState->GuestRequest.SCSIIO.u8Bus; @@ -2835,6 +2865,8 @@ static int lsilogicProcessConfigurationRequest(PLSILOGICSCSI pLsiLogic, PMptConf if (pConfigurationReq->SimpleSGElement.f64BitAddress) GCPhysAddrPageBuffer |= (uint64_t)pConfigurationReq->SimpleSGElement.u32DataBufferAddressHigh << 32; + LogFlow(("cbBuffer=%u cbPage=%u\n", cbBuffer, cbPage)); + PDMDevHlpPhysRead(pLsiLogic->CTX_SUFF(pDevIns), GCPhysAddrPageBuffer, pbPageData, RT_MIN(cbBuffer, cbPage)); } @@ -3399,12 +3431,12 @@ static DECLCALLBACK(bool) lsilogicNotifyQueueConsumer(PPDMDEVINS pDevIns, PPDMQU LogFlowFunc(("pDevIns=%#p pItem=%#p\n", pDevIns, pItem)); - /* Only process request which arrived before we received the notification. */ - uint32_t uRequestQueueNextEntryWrite = ASMAtomicReadU32(&pLsiLogic->uRequestQueueNextEntryFreeWrite); - /* Reset notification event. */ ASMAtomicXchgBool(&pLsiLogic->fNotificationSend, false); + /* Only process request which arrived before we received the notification. */ + uint32_t uRequestQueueNextEntryWrite = ASMAtomicReadU32(&pLsiLogic->uRequestQueueNextEntryFreeWrite); + /* Go through the messages now and process them. */ while ( RT_LIKELY(pLsiLogic->enmState == LSILOGICSTATE_OPERATIONAL) && (pLsiLogic->uRequestQueueNextAddressRead != uRequestQueueNextEntryWrite)) diff --git a/src/VBox/Devices/Storage/DrvVD.cpp b/src/VBox/Devices/Storage/DrvVD.cpp index f8324d6b9..022691b6a 100644 --- a/src/VBox/Devices/Storage/DrvVD.cpp +++ b/src/VBox/Devices/Storage/DrvVD.cpp @@ -158,6 +158,8 @@ typedef struct VBOXDISK PPDMIMEDIAASYNCPORT pDrvMediaAsyncPort; /** Pointer to the list of data we need to keep per image. */ PVBOXIMAGE pImages; + /** Flag whether the media should allow concurrent open for writing. */ + bool fShareable; /** Flag whether a merge operation has been set up. */ bool fMergePending; /** Synchronization to prevent destruction before merge finishes. */ @@ -333,10 +335,19 @@ static DECLCALLBACK(int) drvvdAsyncIOOpen(void *pvUser, const char *pszLocation, drvvdAsyncTaskCompleted, pStorageBackend, "AsyncTaskCompleted"); if (RT_SUCCESS(rc)) { - rc = PDMR3AsyncCompletionEpCreateForFile(&pStorageBackend->pEndpoint, pszLocation, - uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY - ? PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_CACHING - : PDMACEP_FILE_FLAGS_CACHING, + uint32_t fFlags = uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY + ? PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_CACHING + : 0; + if (pThis->fShareable) + { + Assert(uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_DONT_LOCK); + + fFlags |= PDMACEP_FILE_FLAGS_DONT_LOCK; + } + else + fFlags |= PDMACEP_FILE_FLAGS_CACHING; + rc = PDMR3AsyncCompletionEpCreateForFile(&pStorageBackend->pEndpoint, + pszLocation, fFlags, pStorageBackend->pTemplate); if (RT_SUCCESS(rc)) { @@ -739,10 +750,10 @@ static DECLCALLBACK(int) drvvdINIPSgWrite(RTSOCKET Sock, PCRTSGBUF pSgBuf) /* This is an extremely crude emulation, however it's good enough * for our iSCSI code. INIP has no sendmsg(). */ - for (unsigned i = 0; i < pSgBuf->cSeg; i++) + for (unsigned i = 0; i < pSgBuf->cSegs; i++) { - rc = drvvdINIPWrite(Sock, pSgBuf->pcaSeg[i].pvSeg, - pSgBuf->pcaSeg[i].cbSeg); + rc = drvvdINIPWrite(Sock, pSgBuf->paSegs[i].pvSeg, + pSgBuf->paSegs[i].cbSeg); if (RT_FAILURE(rc)) break; } @@ -1232,6 +1243,7 @@ static DECLCALLBACK(int) drvvdConstruct(PPDMDRVINS pDrvIns, char *pszName = NULL; /**< The path of the disk image file. */ char *pszFormat = NULL; /**< The format backed to use for this image. */ bool fReadOnly; /**< True if the media is read-only. */ + bool fMaybeReadOnly; /**< True if the media may or may not be read-only. */ bool fHonorZeroWrites; /**< True if zero blocks should be written. */ PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); @@ -1243,6 +1255,7 @@ static DECLCALLBACK(int) drvvdConstruct(PPDMDRVINS pDrvIns, pThis->fTempReadOnly = false; pThis->pDisk = NULL; pThis->fAsyncIOSupported = false; + pThis->fShareable = false; pThis->fMergePending = false; pThis->MergeCompleteMutex = NIL_RTSEMFASTMUTEX; pThis->uMergeSource = VD_LAST_IMAGE; @@ -1311,7 +1324,7 @@ static DECLCALLBACK(int) drvvdConstruct(PPDMDRVINS pDrvIns, * open flags. Some might be converted to per-image flags later. */ fValid = CFGMR3AreValuesValid(pCurNode, "Format\0Path\0" - "ReadOnly\0TempReadOnly\0HonorZeroWrites\0" + "ReadOnly\0MaybeReadOnly\0TempReadOnly\0Shareable\0HonorZeroWrites\0" "HostIPStack\0UseNewIo\0" "SetupMerge\0MergeSource\0MergeTarget\0"); } @@ -1355,6 +1368,14 @@ static DECLCALLBACK(int) drvvdConstruct(PPDMDRVINS pDrvIns, break; } + rc = CFGMR3QueryBoolDef(pCurNode, "MaybeReadOnly", &fMaybeReadOnly, false); + if (RT_FAILURE(rc)) + { + rc = PDMDRV_SET_ERROR(pDrvIns, rc, + N_("DrvVD: Configuration error: Querying \"MaybeReadOnly\" as boolean failed")); + break; + } + rc = CFGMR3QueryBoolDef(pCurNode, "TempReadOnly", &pThis->fTempReadOnly, false); if (RT_FAILURE(rc)) { @@ -1368,6 +1389,15 @@ static DECLCALLBACK(int) drvvdConstruct(PPDMDRVINS pDrvIns, N_("DrvVD: Configuration error: Both \"ReadOnly\" and \"TempReadOnly\" are set")); break; } + + rc = CFGMR3QueryBoolDef(pCurNode, "Shareable", &pThis->fShareable, false); + if (RT_FAILURE(rc)) + { + rc = PDMDRV_SET_ERROR(pDrvIns, rc, + N_("DrvVD: Configuration error: Querying \"Shareable\" as boolean failed")); + break; + } + rc = CFGMR3QueryBoolDef(pCurNode, "UseNewIo", &fUseNewIo, false); if (RT_FAILURE(rc)) { @@ -1599,6 +1629,8 @@ static DECLCALLBACK(int) drvvdConstruct(PPDMDRVINS pDrvIns, uOpenFlags |= VD_OPEN_FLAGS_HONOR_ZEROES; if (pThis->fAsyncIOSupported) uOpenFlags |= VD_OPEN_FLAGS_ASYNC_IO; + if (pThis->fShareable) + uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE; /* Try to open backend in async I/O mode first. */ rc = VDOpen(pThis->pDisk, pszFormat, pszName, uOpenFlags, pImage->pVDIfsImage); @@ -1614,8 +1646,9 @@ static DECLCALLBACK(int) drvvdConstruct(PPDMDRVINS pDrvIns, Log(("%s: %d - Opened '%s' in %s mode\n", __FUNCTION__, iLevel, pszName, VDIsReadOnly(pThis->pDisk) ? "read-only" : "read-write")); - if ( VDIsReadOnly(pThis->pDisk) + if ( VDIsReadOnly(pThis->pDisk) && !fReadOnly + && !fMaybeReadOnly && !pThis->fTempReadOnly && iLevel == 0) { diff --git a/src/VBox/Devices/Storage/ISCSIHDDCore.cpp b/src/VBox/Devices/Storage/ISCSIHDDCore.cpp index bd4225a1b..b9dbec113 100644 --- a/src/VBox/Devices/Storage/ISCSIHDDCore.cpp +++ b/src/VBox/Devices/Storage/ISCSIHDDCore.cpp @@ -251,6 +251,16 @@ typedef enum ISCSISTATE ISCSISTATE_IN_LOGOUT } ISCSISTATE; +/** + * iSCSI PDU send flags (and maybe more in the future). */ +typedef enum ISCSIPDUFLAGS +{ + /** No special flags */ + ISCSIPDU_DEFAULT = 0, + /** Do not attempt to re-attach to the target if the connection is lost */ + ISCSIPDU_NO_REATTACH = RT_BIT(1) +} ISCSIPDUFLAGS; + /******************************************************************************* * Structures and Typedefs * @@ -489,7 +499,7 @@ static const VDCONFIGINFO s_iscsiConfigInfo[] = /* iSCSI low-level functions (only to be used from the iSCSI high-level functions). */ static uint32_t iscsiNewITT(PISCSIIMAGE pImage); -static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq); +static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq, uint32_t uFlags); static int iscsiRecvPDU(PISCSIIMAGE pImage, uint32_t itt, PISCSIRES paRes, uint32_t cnRes); static int drvISCSIValidatePDU(PISCSIRES paRes, uint32_t cnRes); static int iscsiTextAddKeyValue(uint8_t *pbBuf, size_t cbBuf, size_t *pcbBufCurr, const char *pcszKey, const char *pcszValue, size_t cbValue); @@ -625,6 +635,7 @@ static int iscsiTransportRead(PISCSIIMAGE pImage, PISCSIRES paResponse, unsigned /* The other end has closed the connection. */ pImage->pInterfaceNetCallbacks->pfnClientClose(pImage->Socket); pImage->Socket = NIL_RTSOCKET; + pImage->state = ISCSISTATE_FREE; rc = VERR_NET_CONNECTION_RESET; break; } @@ -710,7 +721,7 @@ static int iscsiTransportWrite(PISCSIIMAGE pImage, PISCSIREQ paRequest, unsigned uint32_t pad = 0; unsigned int i; - LogFlow(("iscsiTransportWrite: cnRequest=%d (%s:%d)\n", cnRequest, pImage->pszHostname, pImage->uPort)); + LogFlowFunc(("cnRequest=%d (%s:%d)\n", cnRequest, pImage->pszHostname, pImage->uPort)); if (pImage->Socket == NIL_RTSOCKET) { /* Attempt to reconnect if the connection was previously broken. */ @@ -765,7 +776,7 @@ static int iscsiTransportWrite(PISCSIIMAGE pImage, PISCSIREQ paRequest, unsigned rc = VERR_BROKEN_PIPE; } - LogFlow(("iscsiTransportWrite: returns %Rrc\n", rc)); + LogFlowFunc(("returns %Rrc\n", rc)); return rc; } @@ -1084,7 +1095,7 @@ restart: aISCSIReq[cnISCSIReq].cbSeg = cbBuf; cnISCSIReq++; - rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq); + rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq, ISCSIPDU_NO_REATTACH); if (RT_SUCCESS(rc)) { ISCSIOPCODE cmd; @@ -1346,7 +1357,7 @@ static int iscsiDetach(PISCSIIMAGE pImage) uint32_t cnISCSIReq = 0; ISCSIREQ aISCSIReq[4]; uint32_t aReqBHS[12]; - LogFlow(("iscsiDetach: entering\n")); + LogFlowFunc(("entering\n")); RTSemMutexRequest(pImage->Mutex, RT_INDEFINITE_WAIT); @@ -1376,7 +1387,7 @@ static int iscsiDetach(PISCSIIMAGE pImage) aISCSIReq[cnISCSIReq].cbSeg = sizeof(aReqBHS); cnISCSIReq++; - rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq); + rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq, ISCSIPDU_NO_REATTACH); if (RT_SUCCESS(rc)) { /* @@ -1414,7 +1425,7 @@ static int iscsiDetach(PISCSIIMAGE pImage) RTSemMutexRelease(pImage->Mutex); - LogFlow(("iscsiDetach: leaving\n")); + LogFlowFunc(("leaving\n")); LogRel(("iSCSI: logout to target %s\n", pImage->pszTargetName)); return VINF_SUCCESS; } @@ -1446,7 +1457,7 @@ static int iscsiCommand(PISCSIIMAGE pImage, PSCSIREQ pRequest) uint32_t ExpDataSN = 0; bool final = false; - LogFlow(("iscsiCommand: entering, CmdSN=%d\n", pImage->CmdSN)); + LogFlowFunc(("entering, CmdSN=%d\n", pImage->CmdSN)); Assert(pRequest->enmXfer != SCSIXFER_TO_FROM_TARGET); /**< @todo not yet supported, would require AHS. */ Assert(pRequest->cbI2TData <= 0xffffff); /* larger transfers would require R2T support. */ @@ -1503,7 +1514,7 @@ static int iscsiCommand(PISCSIIMAGE pImage, PSCSIREQ pRequest) cnISCSIReq++; } - rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq); + rc = iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq, ISCSIPDU_DEFAULT); if (RT_FAILURE(rc)) goto out_release; @@ -1646,7 +1657,7 @@ out_release: RTSemMutexRelease(pImage->Mutex); out: - LogFlow(("iscsiCommand: returns %Rrc\n", rc)); + LogFlowFunc(("returns %Rrc\n", rc)); return rc; } @@ -1676,14 +1687,15 @@ static uint32_t iscsiNewITT(PISCSIIMAGE pImage) * @param pImage The iSCSI connection state to be used. * @param paReq Pointer to array of iSCSI request sections. * @param cnReq Number of valid iSCSI request sections in the array. + * @param uFlags Flags controlling the exact send semantics. */ -static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq) +static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq, + uint32_t uFlags) { int rc = VINF_SUCCESS; /** @todo return VERR_VD_ISCSI_INVALID_STATE in the appropriate situations, * needs cleaning up of timeout/disconnect handling a bit, as otherwise * too many incorrect errors are signalled. */ - Assert(pImage->paCurrReq == NULL); Assert(cnReq >= 1); Assert(paReq[0].cbSeg >= ISCSI_BHS_SIZE); @@ -1692,7 +1704,8 @@ static int iscsiSendPDU(PISCSIIMAGE pImage, PISCSIREQ paReq, uint32_t cnReq) rc = iscsiTransportWrite(pImage, paReq, cnReq); if (RT_SUCCESS(rc)) break; - if (rc != VERR_BROKEN_PIPE && rc != VERR_NET_CONNECTION_REFUSED) + if ( (uFlags & ISCSIPDU_NO_REATTACH) + || (rc != VERR_BROKEN_PIPE && rc != VERR_NET_CONNECTION_REFUSED)) break; /* No point in reestablishing the connection for a logout */ if (pImage->state == ISCSISTATE_IN_LOGOUT) @@ -1753,7 +1766,7 @@ static int iscsiRecvPDU(PISCSIIMAGE pImage, uint32_t itt, PISCSIRES paRes, uint3 } if (pImage->paCurrReq != NULL) { - rc = iscsiSendPDU(pImage, pImage->paCurrReq, pImage->cnCurrReq); + rc = iscsiSendPDU(pImage, pImage->paCurrReq, pImage->cnCurrReq, ISCSIPDU_DEFAULT); if (RT_FAILURE(rc)) break; } @@ -1873,7 +1886,7 @@ static int iscsiRecvPDU(PISCSIIMAGE pImage, uint32_t itt, PISCSIRES paRes, uint3 aISCSIReq[cnISCSIReq].cbSeg = sizeof(aReqBHS); cnISCSIReq++; - iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq); + iscsiSendPDU(pImage, aISCSIReq, cnISCSIReq, ISCSIPDU_NO_REATTACH); } } } @@ -1963,7 +1976,7 @@ static int drvISCSIValidatePDU(PISCSIRES paRes, uint32_t cnRes) case ISCSIOP_REJECT: default: /* Do some logging, ignore PDU. */ - LogFlow(("drvISCSIValidatePDU: ignore unhandled PDU, first word %#08x\n", RT_N2H_U32(pcrgResBHS[0]))); + LogFlowFunc(("ignore unhandled PDU, first word %#08x\n", RT_N2H_U32(pcrgResBHS[0]))); return VERR_PARSE_ERROR; } /* A target must not send PDUs with MaxCmdSN less than ExpCmdSN-1. */ @@ -3368,10 +3381,22 @@ static int iscsiSetOpenFlags(void *pBackendData, unsigned uOpenFlags) goto out; } - /* Implement this operation via reopening the image. */ - iscsiFreeImage(pImage, false); - rc = iscsiOpenImage(pImage, uOpenFlags); - + /* Implement this operation via reopening the image if we actually need + * to do something. A read/write -> readonly transition doesn't need a + * reopen. In the other direction we don't have the necessary information + * as the "disk is readonly" flag is thrown away. Can be optimized too, + * but it's not worth the effort at the moment. */ + if ( !(uOpenFlags & VD_OPEN_FLAGS_READONLY) + && (pImage->uOpenFlags & VD_OPEN_FLAGS_READONLY)) + { + iscsiFreeImage(pImage, false); + rc = iscsiOpenImage(pImage, uOpenFlags); + } + else + { + pImage->uOpenFlags = uOpenFlags; + rc = VINF_SUCCESS; + } out: LogFlowFunc(("returns %Rrc\n", rc)); return rc; diff --git a/src/VBox/Devices/Storage/ParallelsHDDCore.cpp b/src/VBox/Devices/Storage/ParallelsHDDCore.cpp index 093f11075..b945e7dd9 100644 --- a/src/VBox/Devices/Storage/ParallelsHDDCore.cpp +++ b/src/VBox/Devices/Storage/ParallelsHDDCore.cpp @@ -882,7 +882,7 @@ static int parallelsSetOpenFlags(void *pBackendData, unsigned uOpenFlags) /* Image must be opened and the new flags must be valid. Just readonly and * info flags are supported. */ - if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO))) + if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_SHAREABLE))) { rc = VERR_INVALID_PARAMETER; goto out; diff --git a/src/VBox/Devices/Storage/VBoxHDD.cpp b/src/VBox/Devices/Storage/VBoxHDD.cpp index 5d24619a6..49d5efdc9 100644 --- a/src/VBox/Devices/Storage/VBoxHDD.cpp +++ b/src/VBox/Devices/Storage/VBoxHDD.cpp @@ -571,8 +571,9 @@ static int vdReadHelper(PVBOXHDD pDisk, PVDIMAGE pImage, PVDIMAGE pImageParentOv /* No image in the chain contains the data for the block. */ if (rc == VERR_VD_BLOCK_FREE) { - /* Fill the free space with 0 if we are told to do so. */ - if (fHandleFreeBlocks) + /* Fill the free space with 0 if we are told to do so + * or a previous read returned valid data. */ + if (fHandleFreeBlocks || !fAllFree) memset(pvBuf, '\0', cbThisRead); else cbBufClear += cbThisRead; @@ -1500,6 +1501,7 @@ static int vdWriteHelperAsync(PVDIOCTX pIoCtx) /* Set the state to growing. */ LogFlowFunc(("Disk is growing because of pIoCtx=%#p pIoCtxWrite=%#p\n", + pIoCtx, pIoCtxWrite)); ASMAtomicWriteBool(&pDisk->fGrowing, true); @@ -1700,9 +1702,16 @@ static int vdAsyncIOOpen(void *pvUser, const char *pszLocation, unsigned uOpenFl uint32_t fOpen = 0; if (uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY) - fOpen |= RTFILE_O_READ | RTFILE_O_DENY_NONE; + fOpen |= RTFILE_O_READ | RTFILE_O_DENY_NONE; else - fOpen |= RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE; + { + fOpen |= RTFILE_O_READWRITE; + + if (uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_DONT_LOCK) + fOpen |= RTFILE_O_DENY_NONE; + else + fOpen |= RTFILE_O_DENY_WRITE; + } if (uOpenFlags & VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE) fOpen |= RTFILE_O_CREATE; @@ -2916,6 +2925,16 @@ VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend, uImageFlags |= VD_IMAGE_FLAGS_DIFF; } } + + /* Ensure we always get correct diff information, even if the backend + * doesn't actually have a stored flag for this. It must not return + * bogus information for the parent UUID if it is not a diff image. */ + RTUUID parentUuid; + RTUuidClear(&parentUuid); + rc2 = pImage->Backend->pfnGetParentUuid(pImage->pvBackendData, &parentUuid); + if (RT_SUCCESS(rc2) && !RTUuidIsNull(&parentUuid)) + uImageFlags |= VD_IMAGE_FLAGS_DIFF; + pImage->uImageFlags = uImageFlags; /* Force sane optimization settings. It's not worth avoiding writes @@ -5299,7 +5318,7 @@ VBOXDDU_DECL(int) VDGetImageFlags(PVBOXHDD pDisk, unsigned nImage, PVDIMAGE pImage = vdGetImageByNumber(pDisk, nImage); AssertPtrBreakStmt(pImage, rc = VERR_VD_IMAGE_NOT_FOUND); - *puImageFlags = pImage->Backend->pfnGetImageFlags(pImage->pvBackendData); + *puImageFlags = pImage->uImageFlags; } while (0); if (RT_UNLIKELY(fLockRead)) diff --git a/src/VBox/Devices/Storage/VDIHDDCore.cpp b/src/VBox/Devices/Storage/VDIHDDCore.cpp index d843588fc..a4b0cf62c 100644 --- a/src/VBox/Devices/Storage/VDIHDDCore.cpp +++ b/src/VBox/Devices/Storage/VDIHDDCore.cpp @@ -78,15 +78,17 @@ DECLINLINE(int) vdiError(PVDIIMAGEDESC pImage, int rc, RT_SRC_POS_DECL, } -static int vdiFileOpen(PVDIIMAGEDESC pImage, bool fReadonly, bool fCreate) +static int vdiFileOpen(PVDIIMAGEDESC pImage, bool fReadonly, bool fShareable, + bool fCreate) { int rc = VINF_SUCCESS; - AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly whilebeing created\n")); + AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n")); #ifndef VBOX_WITH_NEW_IO_CODE - uint32_t fOpen = fReadonly ? RTFILE_O_READ | RTFILE_O_DENY_NONE - : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE; + uint32_t fDeny = fReadonly | fShareable ? RTFILE_O_DENY_NONE : RTFILE_O_DENY_WRITE; + uint32_t fOpen = fReadonly ? RTFILE_O_READ : RTFILE_O_READWRITE; + fOpen |= fDeny; if (fCreate) fOpen |= RTFILE_O_CREATE; @@ -100,6 +102,9 @@ static int vdiFileOpen(PVDIIMAGEDESC pImage, bool fReadonly, bool fCreate) if (fCreate) uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE; + if (fShareable) + uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_DONT_LOCK; + rc = pImage->pInterfaceIOCallbacks->pfnOpen(pImage->pInterfaceIO->pvUser, pImage->pszFilename, uOpenFlags, @@ -512,8 +517,9 @@ static int vdiCreateImage(PVDIIMAGEDESC pImage, uint64_t cbSize, unsigned uImageFlags, const char *pszComment, PCPDMMEDIAGEOMETRY pPCHSGeometry, PCPDMMEDIAGEOMETRY pLCHSGeometry, PCRTUUID pUuid, - PFNVDPROGRESS pfnProgress, void *pvUser, - unsigned uPercentStart, unsigned uPercentSpan) + unsigned uOpenFlags, PFNVDPROGRESS pfnProgress, + void *pvUser, unsigned uPercentStart, + unsigned uPercentSpan) { int rc; uint64_t cbTotal; @@ -578,7 +584,9 @@ static int vdiCreateImage(PVDIIMAGEDESC pImage, uint64_t cbSize, vdiSetupImageDesc(pImage); /* Create image file. */ - rc = vdiFileOpen(pImage, false /* fReadonly */, true /* fCreate */); + rc = vdiFileOpen(pImage, false /* fReadonly */, + !!(uOpenFlags & VD_OPEN_FLAGS_SHAREABLE), + true /* fCreate */); if (RT_FAILURE(rc)) { rc = vdiError(pImage, rc, RT_SRC_POS, N_("VDI: cannot create image '%s'"), pImage->pszFilename); @@ -731,7 +739,10 @@ static int vdiOpenImage(PVDIIMAGEDESC pImage, unsigned uOpenFlags) /* * Open the image. */ - rc = vdiFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false /* fCreate */); + rc = vdiFileOpen(pImage, + !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), + !!(uOpenFlags & VD_OPEN_FLAGS_SHAREABLE), + false /* fCreate */); if (RT_FAILURE(rc)) { /* Do NOT signal an appropriate error here, as the VD layer has the @@ -873,6 +884,7 @@ static int vdiUpdateHeaderAsync(PVDIIMAGEDESC pImage, PVDIOCTX pIoCtx) rc = vdiFileWriteMetaAsync(pImage, sizeof(VDIPREHEADER), &pImage->Header.u.v0, sizeof(pImage->Header.u.v0), pIoCtx, NULL, NULL); + break; case 1: if (pImage->Header.u.v1plus.cbHeader < sizeof(pImage->Header.u.v1plus)) @@ -1150,7 +1162,7 @@ static int vdiCreate(const char *pszFilename, uint64_t cbSize, pImage->pVDIfsImage = pVDIfsImage; rc = vdiCreateImage(pImage, cbSize, uImageFlags, pszComment, - pPCHSGeometry, pLCHSGeometry, pUuid, + pPCHSGeometry, pLCHSGeometry, pUuid, uOpenFlags, pfnProgress, pvUser, uPercentStart, uPercentSpan); if (RT_SUCCESS(rc)) { @@ -1650,7 +1662,7 @@ static int vdiSetOpenFlags(void *pBackendData, unsigned uOpenFlags) /* Image must be opened and the new flags must be valid. Just readonly and * info flags are supported. */ - if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO))) + if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE))) { rc = VERR_INVALID_PARAMETER; goto out; diff --git a/src/VBox/Devices/Storage/VHDHDDCore.cpp b/src/VBox/Devices/Storage/VHDHDDCore.cpp index c9928ee33..181462ce8 100644 --- a/src/VBox/Devices/Storage/VHDHDDCore.cpp +++ b/src/VBox/Devices/Storage/VHDHDDCore.cpp @@ -215,15 +215,17 @@ static const char *const s_apszVhdFileExtensions[] = static int vhdFlush(void *pBackendData); static int vhdLoadDynamicDisk(PVHDIMAGE pImage, uint64_t uDynamicDiskHeaderOffset); -static int vhdFileOpen(PVHDIMAGE pImage, bool fReadonly, bool fCreate) +static int vhdFileOpen(PVHDIMAGE pImage, bool fReadonly, bool fShareable, + bool fCreate) { int rc = VINF_SUCCESS; AssertMsg(!(fReadonly && fCreate), ("Image can't be opened readonly while being created\n")); #ifndef VBOX_WITH_NEW_IO_CODE - uint32_t fOpen = fReadonly ? RTFILE_O_READ | RTFILE_O_DENY_NONE - : RTFILE_O_READWRITE | RTFILE_O_DENY_WRITE; + uint32_t fDeny = fReadonly | fShareable ? RTFILE_O_DENY_NONE : RTFILE_O_DENY_WRITE; + uint32_t fOpen = fReadonly ? RTFILE_O_READ : RTFILE_O_READWRITE; + fOpen |= fDeny; if (fCreate) fOpen |= RTFILE_O_CREATE; @@ -237,6 +239,9 @@ static int vhdFileOpen(PVHDIMAGE pImage, bool fReadonly, bool fCreate) if (fCreate) uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE; + if (fShareable) + uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_DONT_LOCK; + rc = pImage->pInterfaceIOCallbacks->pfnOpen(pImage->pInterfaceIO->pvUser, pImage->pszFilename, uOpenFlags, @@ -588,7 +593,8 @@ static int vhdOpenImage(PVHDIMAGE pImage, unsigned uOpenFlags) /* * Open the image. */ - int rc = vhdFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false); + int rc = vhdFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), + !!(uOpenFlags & VD_OPEN_FLAGS_SHAREABLE), false); if (RT_FAILURE(rc)) { /* Do NOT signal an appropriate error here, as the VD layer has the @@ -945,7 +951,7 @@ static int vhdSetOpenFlags(void *pBackendData, unsigned uOpenFlags) /* Image must be opened and the new flags must be valid. Just readonly and * info flags are supported. */ - if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO))) + if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_SHAREABLE))) { rc = VERR_INVALID_PARAMETER; goto out; @@ -956,7 +962,8 @@ static int vhdSetOpenFlags(void *pBackendData, unsigned uOpenFlags) goto out; vhdFileClose(pImage); pImage->uOpenFlags = uOpenFlags; - rc = vhdFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), false); + rc = vhdFileOpen(pImage, !!(uOpenFlags & VD_OPEN_FLAGS_READONLY), + !!(uOpenFlags & VD_OPEN_FLAGS_SHAREABLE), false); out: LogFlowFunc(("returned %Rrc\n", rc)); @@ -1810,7 +1817,9 @@ static int vhdCreateImage(PVHDIMAGE pImage, uint64_t cbSize, if (pImage->pInterfaceError) pImage->pInterfaceErrorCallbacks = VDGetInterfaceError(pImage->pInterfaceError); - rc = vhdFileOpen(pImage, false /* fReadonly */, true /* fCreate */); + rc = vhdFileOpen(pImage, false /* fReadonly */, + !!(uOpenFlags & VD_OPEN_FLAGS_SHAREABLE), + true /* fCreate */); if (RT_FAILURE(rc)) return vhdError(pImage, rc, RT_SRC_POS, N_("VHD: cannot create image '%s'"), pImage->pszFilename); diff --git a/src/VBox/Devices/Storage/VmdkHDDCore.cpp b/src/VBox/Devices/Storage/VmdkHDDCore.cpp index d55a4cbd8..432cebdc7 100644 --- a/src/VBox/Devices/Storage/VmdkHDDCore.cpp +++ b/src/VBox/Devices/Storage/VmdkHDDCore.cpp @@ -602,6 +602,8 @@ static int vmdkFileOpen(PVMDKIMAGE pImage, PVMDKFILE *ppVmdkFile, uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_READONLY; if ((fOpen & RTFILE_O_ACTION_MASK) == RTFILE_O_CREATE) uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_CREATE; + if ((fOpen & RTFILE_O_DENY_MASK) == RTFILE_O_DENY_NONE) + uOpenFlags |= VD_INTERFACEASYNCIO_OPEN_FLAGS_DONT_LOCK; rc = pImage->pInterfaceIOCallbacks->pfnOpen(pImage->pInterfaceIO->pvUser, pszFilename, @@ -2030,6 +2032,7 @@ static int vmdkDescSetLCHSGeometry(PVMDKIMAGE pImage, return rc; rc = vmdkDescDDBSetU32(pImage, &pImage->Descriptor, VMDK_DDB_GEO_LCHS_HEADS, + pLCHSGeometry->cHeads); if (RT_FAILURE(rc)) return rc; @@ -2230,6 +2233,7 @@ static int vmdkParseDescriptor(PVMDKIMAGE pImage, char *pDescData, } else return vmdkError(pImage, VERR_VD_VMDK_INVALID_HEADER, RT_SRC_POS, N_("VMDK: parse error in extent description in '%s'"), pImage->pszFilename); + if (pImage->pExtents[i].enmType == VMDKETYPE_ZERO) { /* This one has no basename or offset. */ @@ -2642,6 +2646,7 @@ static int vmdkWriteDescriptorAsync(PVMDKIMAGE pImage, PVDIOCTX pIoCtx) RTMemFree(pszDescriptor); return rc; + } /** @@ -3066,6 +3071,21 @@ static int vmdkCreateExtents(PVMDKIMAGE pImage, unsigned cExtents) } /** + * Internal: Translate the VBoxHDD open flags to RTFile open flags. + */ +static uint32_t vmdkFileOpenFlags(unsigned uOpenFlags) +{ + uint32_t fDeny = uOpenFlags & (VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_SHAREABLE) + ? RTFILE_O_DENY_NONE + : RTFILE_O_DENY_WRITE; + uint32_t fOpen = uOpenFlags & VD_OPEN_FLAGS_READONLY + ? RTFILE_O_READ + : RTFILE_O_READWRITE; + fOpen |= RTFILE_O_OPEN | fDeny; + return fOpen; +} + +/** * Internal: Open an image, constructing all necessary data structures. */ static int vmdkOpenImage(PVMDKIMAGE pImage, unsigned uOpenFlags) @@ -3093,10 +3113,9 @@ static int vmdkOpenImage(PVMDKIMAGE pImage, unsigned uOpenFlags) * we only support raw access and the opened file is a description * file were no data is stored. */ + rc = vmdkFileOpen(pImage, &pFile, pImage->pszFilename, - uOpenFlags & VD_OPEN_FLAGS_READONLY - ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE - : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, false); + vmdkFileOpenFlags(uOpenFlags), false); if (RT_FAILURE(rc)) { /* Do NOT signal an appropriate error here, as the VD layer has the @@ -3318,9 +3337,7 @@ static int vmdkOpenImage(PVMDKIMAGE pImage, unsigned uOpenFlags) { case VMDKETYPE_HOSTED_SPARSE: rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname, - uOpenFlags & VD_OPEN_FLAGS_READONLY - ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE - : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, false); + vmdkFileOpenFlags(uOpenFlags), false); if (RT_FAILURE(rc)) { /* Do NOT signal an appropriate error here, as the VD @@ -3345,9 +3362,7 @@ static int vmdkOpenImage(PVMDKIMAGE pImage, unsigned uOpenFlags) case VMDKETYPE_VMFS: case VMDKETYPE_FLAT: rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname, - uOpenFlags & VD_OPEN_FLAGS_READONLY - ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE - : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, true); + vmdkFileOpenFlags(uOpenFlags), true); if (RT_FAILURE(rc)) { /* Do NOT signal an appropriate error here, as the VD @@ -3428,6 +3443,19 @@ out: } /** + * Internal: Translate the VBoxHDD open flags to RTFile open/create flags. + */ +static uint32_t vmdkFileCreateFlags(unsigned uOpenFlags) +{ + uint32_t fDeny = uOpenFlags & VD_OPEN_FLAGS_SHAREABLE + ? RTFILE_O_DENY_NONE + : RTFILE_O_DENY_WRITE; + uint32_t fOpen = RTFILE_O_READWRITE | RTFILE_O_NOT_CONTENT_INDEXED; + fOpen |= RTFILE_O_CREATE | fDeny; + return fOpen; +} + +/** * Internal: create VMDK images for raw disk/partition access. */ static int vmdkCreateRawImage(PVMDKIMAGE pImage, const PVBOXHDDRAW pRaw, @@ -3446,8 +3474,7 @@ static int vmdkCreateRawImage(PVMDKIMAGE pImage, const PVBOXHDDRAW pRaw, pExtent = &pImage->pExtents[0]; /* Create raw disk descriptor file. */ rc = vmdkFileOpen(pImage, &pImage->pFile, pImage->pszFilename, - RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_WRITE | RTFILE_O_NOT_CONTENT_INDEXED, - false); + vmdkFileCreateFlags(pImage->uOpenFlags), false); if (RT_FAILURE(rc)) return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not create new file '%s'"), pImage->pszFilename); @@ -3470,7 +3497,8 @@ static int vmdkCreateRawImage(PVMDKIMAGE pImage, const PVBOXHDDRAW pRaw, /* Open flat image, the raw disk. */ rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname, - RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, false); + vmdkFileOpenFlags(pImage->uOpenFlags & ~VD_OPEN_FLAGS_READONLY), + false); if (RT_FAILURE(rc)) return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not open raw disk file '%s'"), pExtent->pszFullname); } @@ -3506,8 +3534,7 @@ static int vmdkCreateRawImage(PVMDKIMAGE pImage, const PVBOXHDDRAW pRaw, /* Create raw partition descriptor file. */ rc = vmdkFileOpen(pImage, &pImage->pFile, pImage->pszFilename, - RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_WRITE | RTFILE_O_NOT_CONTENT_INDEXED, - false); + vmdkFileCreateFlags(pImage->uOpenFlags), false); if (RT_FAILURE(rc)) return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not create new file '%s'"), pImage->pszFilename); @@ -3581,7 +3608,7 @@ static int vmdkCreateRawImage(PVMDKIMAGE pImage, const PVBOXHDDRAW pRaw, /* Create partition table flat image. */ rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname, - RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_WRITE | RTFILE_O_NOT_CONTENT_INDEXED, + vmdkFileCreateFlags(pImage->uOpenFlags), false); if (RT_FAILURE(rc)) return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not create new partition data file '%s'"), pExtent->pszFullname); @@ -3616,7 +3643,7 @@ static int vmdkCreateRawImage(PVMDKIMAGE pImage, const PVBOXHDDRAW pRaw, /* Open flat image, the raw partition. */ rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname, - RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, + vmdkFileOpenFlags(pImage->uOpenFlags & ~VD_OPEN_FLAGS_READONLY), false); if (RT_FAILURE(rc)) return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not open raw partition file '%s'"), pExtent->pszFullname); @@ -3689,8 +3716,7 @@ static int vmdkCreateRegularImage(PVMDKIMAGE pImage, uint64_t cbSize, if (cExtents != 1 || (uImageFlags & VD_IMAGE_FLAGS_FIXED)) { rc = vmdkFileOpen(pImage, &pImage->pFile, pImage->pszFilename, - RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_WRITE | RTFILE_O_NOT_CONTENT_INDEXED, - false); + vmdkFileCreateFlags(pImage->uOpenFlags), false); if (RT_FAILURE(rc)) return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not create new sparse descriptor file '%s'"), pImage->pszFilename); } @@ -3759,8 +3785,7 @@ static int vmdkCreateRegularImage(PVMDKIMAGE pImage, uint64_t cbSize, /* Create file for extent. */ rc = vmdkFileOpen(pImage, &pExtent->pFile, pExtent->pszFullname, - RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_WRITE | RTFILE_O_NOT_CONTENT_INDEXED, - false); + vmdkFileCreateFlags(pImage->uOpenFlags), false); if (RT_FAILURE(rc)) return vmdkError(pImage, rc, RT_SRC_POS, N_("VMDK: could not create new file '%s'"), pExtent->pszFullname); if (uImageFlags & VD_IMAGE_FLAGS_FIXED) @@ -3960,6 +3985,7 @@ static int vmdkCreateImage(PVMDKIMAGE pImage, uint64_t cbSize, } if (RT_FAILURE(rc)) + goto out; if (RT_SUCCESS(rc) && pfnProgress) @@ -5062,7 +5088,8 @@ rollback: /* Restore the old descriptor. */ PVMDKFILE pFile; rrc = vmdkFileOpen(pImage, &pFile, pszOldDescName, - RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, false); + vmdkFileOpenFlags(VD_OPEN_FLAGS_NORMAL), + false); AssertRC(rrc); if (fEmbeddedDesc) { @@ -5182,6 +5209,7 @@ static int vmdkRead(void *pBackendData, uint64_t uOffset, void *pvBuf, goto out; } + /* Clip read range to remain in this extent. */ cbToRead = RT_MIN(cbToRead, VMDK_SECTOR2BYTE(pExtent->uSectorOffset + pExtent->cNominalSectors - uSectorExtentRel)); @@ -5665,7 +5693,7 @@ static int vmdkSetOpenFlags(void *pBackendData, unsigned uOpenFlags) /* Image must be opened and the new flags must be valid. Just readonly and * info flags are supported. */ - if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO))) + if (!pImage || (uOpenFlags & ~(VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE))) { rc = VERR_INVALID_PARAMETER; goto out; diff --git a/src/VBox/Devices/Storage/fdc.c b/src/VBox/Devices/Storage/fdc.c index 958633e5c..4e54bbbf0 100644 --- a/src/VBox/Devices/Storage/fdc.c +++ b/src/VBox/Devices/Storage/fdc.c @@ -1279,6 +1279,16 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, case FD_DIR_WRITE: /* WRITE commands */ #ifdef VBOX + if (cur_drv->ro) + { + /* Handle readonly medium early, no need to do DMA, touch the + * LED or attempt any writes. A real floppy doesn't attempt + * to write to readonly media either. */ + fdctrl_stop_transfer (fdctrl, 0x60, 0x00 | (cur_drv->ro << 1), + 0x00); + goto transfer_error; + } + { uint32_t written; int rc2 = PDMDevHlpDMAReadMemory(fdctrl->pDevIns, nchan, @@ -1287,20 +1297,7 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, len, &written); AssertMsgRC (rc2, ("DMAReadMemory -> %Rrc\n", rc2)); } -#else - DMA_read_memory (nchan, fdctrl->fifo + rel_pos, - fdctrl->data_pos, len); -#endif -/* cpu_physical_memory_read(addr + fdctrl->data_pos, */ -/* fdctrl->fifo + rel_pos, len); */ -#ifndef VBOX - if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), - fdctrl->fifo, 1) < 0) { - FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv)); - fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00); - goto transfer_error; - } -#else /* VBOX */ + cur_drv->Led.Asserted.s.fWriting = cur_drv->Led.Actual.s.fWriting = 1; @@ -1314,9 +1311,21 @@ static int fdctrl_transfer_handler (void *opaque, int nchan, cur_drv->Led.Actual.s.fWriting = 0; if (RT_FAILURE (rc)) { - AssertMsgFailed (("Floppy: error writing sector %d. rc=%Rrc", - fd_sector (cur_drv), rc)); - fdctrl_stop_transfer (fdctrl, 0x60, 0x00, 0x00); + AssertMsgFailed(("Floppy: error writing sector %d. rc=%Rrc", + fd_sector (cur_drv), rc)); + fdctrl_stop_transfer (fdctrl, 0x60, 0x00 | (cur_drv->ro << 1), + 0x00); + goto transfer_error; + } +#else + DMA_read_memory (nchan, fdctrl->fifo + rel_pos, + fdctrl->data_pos, len); +/* cpu_physical_memory_read(addr + fdctrl->data_pos, */ +/* fdctrl->fifo + rel_pos, len); */ + if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), + fdctrl->fifo, 1) < 0) { + FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv)); + fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00); goto transfer_error; } #endif diff --git a/src/VBox/Devices/USB/DevOHCI.cpp b/src/VBox/Devices/USB/DevOHCI.cpp index 8814fa8b3..1ee858395 100644 --- a/src/VBox/Devices/USB/DevOHCI.cpp +++ b/src/VBox/Devices/USB/DevOHCI.cpp @@ -3639,9 +3639,9 @@ static void rhport_power(POHCIROOTHUB pRh, unsigned iPort, bool fPowerUp) { /* power down */ pPort->fReg &= ~( OHCI_PORT_R_POWER_STATUS - | OHCI_PORT_R_CURRENT_CONNECT_STATUS - | OHCI_PORT_R_SUSPEND_STATUS - | OHCI_PORT_R_RESET_STATUS); + | OHCI_PORT_R_CURRENT_CONNECT_STATUS + | OHCI_PORT_R_SUSPEND_STATUS + | OHCI_PORT_R_RESET_STATUS); if (pPort->pDev && fOldPPS) VUSBIDevPowerOff(pPort->pDev); } @@ -4579,6 +4579,7 @@ static int HcRhPortStatus_w(POHCI pOhci, uint32_t iReg, uint32_t val) rhport_power(&pOhci->RootHub, i, true /* power up */); pOhci->RootHub.aPorts[i].fReg &= ~OHCI_PORT_R_SUSPEND_STATUS; pOhci->RootHub.aPorts[i].fReg |= OHCI_PORT_R_SUSPEND_STATUS_CHANGE; + ohciSetInterrupt(pOhci, OHCI_INTR_ROOT_HUB_STATUS_CHANGE); } if (p->fReg != old_state) diff --git a/src/VBox/Devices/VMMDev/VMMDev.cpp b/src/VBox/Devices/VMMDev/VMMDev.cpp index af2f2d4b7..50a5f5e87 100644 --- a/src/VBox/Devices/VMMDev/VMMDev.cpp +++ b/src/VBox/Devices/VMMDev/VMMDev.cpp @@ -32,6 +32,7 @@ #include <VBox/vm.h> /* for VM_IS_EMT */ #include <iprt/asm.h> +#include <iprt/asm-amd64-x86.h> #include <iprt/assert.h> #include <iprt/buildconfig.h> #include <iprt/string.h> @@ -468,7 +469,7 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser, */ case VMMDevReq_ReportGuestInfo: { - if (pRequestHeader->size < sizeof(VMMDevReportGuestInfo)) + if (pRequestHeader->size != sizeof(VMMDevReportGuestInfo)) { AssertMsgFailed(("VMMDev guest information structure has an invalid size!\n")); pRequestHeader->rc = VERR_INVALID_PARAMETER; @@ -488,7 +489,7 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser, LogRel(("Guest Additions information report: Interface = 0x%08X osType = 0x%08X\n", pThis->guestInfo.additionsVersion, pThis->guestInfo.osType)); - pThis->pDrv->pfnUpdateGuestVersion(pThis->pDrv, &pThis->guestInfo); + pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo); } if (pThis->fu32AdditionsOk) @@ -505,7 +506,7 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser, case VMMDevReq_ReportGuestInfo2: { - if (pRequestHeader->size < sizeof(VMMDevReportGuestInfo2)) + if (pRequestHeader->size != sizeof(VMMDevReportGuestInfo2)) { AssertMsgFailed(("VMMDev guest information 2 structure has an invalid size!\n")); pRequestHeader->rc = VERR_INVALID_PARAMETER; @@ -521,6 +522,23 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser, break; } + case VMMDevReq_ReportGuestStatus: + { + if (pRequestHeader->size != sizeof(VMMDevReportGuestStatus)) + { + AssertMsgFailed(("VMMDev guest status structure has an invalid size!\n")); + pRequestHeader->rc = VERR_INVALID_PARAMETER; + } + else + { + VBoxGuestStatus *guestStatus = &((VMMDevReportGuestStatus*)pRequestHeader)->guestStatus; + pThis->pDrv->pfnUpdateGuestStatus(pThis->pDrv, guestStatus); + + pRequestHeader->rc = VINF_SUCCESS; + } + break; + } + /* Report guest capabilities */ case VMMDevReq_ReportGuestCapabilities: { @@ -1860,12 +1878,30 @@ static DECLCALLBACK(int) vmmdevRequestHandler(PPDMDEVINS pDevIns, void *pvUser, break; } #endif + /* + * Get a unique session id for this VM; the id will be different after each start, reset or restore of the VM + * This can be used for restore detection inside the guest. + */ + case VMMDevReq_GetSessionId: + { + if (pRequestHeader->size != sizeof(VMMDevReqSessionId)) + { + AssertMsgFailed(("VMMDevReq_GetSessionId request size too small.\n")); + pRequestHeader->rc = VERR_INVALID_PARAMETER; + } + else + { + VMMDevReqSessionId *pReq = (VMMDevReqSessionId *)pRequestHeader; + pReq->idSession = pThis->idSession; + pRequestHeader->rc = VINF_SUCCESS; + } + break; + } + default: { pRequestHeader->rc = VERR_NOT_IMPLEMENTED; - Log(("VMMDev unknown request type %d\n", pRequestHeader->requestType)); - break; } } @@ -2547,7 +2583,7 @@ static DECLCALLBACK(int) vmmdevLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uin pThis->guestInfo.additionsVersion, pThis->guestInfo.osType)); if (pThis->pDrv) - pThis->pDrv->pfnUpdateGuestVersion(pThis->pDrv, &pThis->guestInfo); + pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo); } if (pThis->pDrv) pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps); @@ -2684,9 +2720,14 @@ static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns) * Call the update functions as required. */ if (fVersionChanged) - pThis->pDrv->pfnUpdateGuestVersion(pThis->pDrv, &pThis->guestInfo); + pThis->pDrv->pfnUpdateGuestInfo(pThis->pDrv, &pThis->guestInfo); if (fCapsChanged) pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps); + + /* Generate a unique session id for this VM; it will be changed for each start, reset or restore. + * This can be used for restore detection inside the guest. + */ + pThis->idSession = ASMReadTSC(); } @@ -2908,6 +2949,10 @@ static DECLCALLBACK(int) vmmdevConstruct(PPDMDEVINS pDevIns, int iInstance, PCFG PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatMemBalloonChunks, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, STAMUNIT_COUNT, "Memory balloon size", "/Devices/VMMDev/BalloonChunks"); + /* Generate a unique session id for this VM; it will be changed for each start, reset or restore. + * This can be used for restore detection inside the guest. + */ + pThis->idSession = ASMReadTSC(); return rc; } diff --git a/src/VBox/Devices/VMMDev/VMMDevState.h b/src/VBox/Devices/VMMDev/VMMDevState.h index 259572f5d..448017f97 100644 --- a/src/VBox/Devices/VMMDev/VMMDevState.h +++ b/src/VBox/Devices/VMMDev/VMMDevState.h @@ -126,8 +126,7 @@ typedef struct VMMDevState */ VBoxGuestInfo guestInfo; - /** Information reported by guest via VMMDevReportGuestCapabilities - */ + /** Information reported by guest via VMMDevReportGuestCapabilities. */ uint32_t guestCaps; /** "Additions are Ok" indicator, set to true after processing VMMDevReportGuestInfo, @@ -164,6 +163,9 @@ typedef struct VMMDevState /* guest ram size */ uint64_t cbGuestRAM; + /* unique session id; the id will be different after each start, reset or restore of the VM. */ + uint64_t idSession; + /* statistics interval change request */ uint32_t u32StatIntervalSize, u32LastStatIntervalSize; diff --git a/src/VBox/Frontends/VBoxBFE/VMMDev.h b/src/VBox/Frontends/VBoxBFE/VMMDev.h index a5081e0e0..b2aa0a926 100644 --- a/src/VBox/Frontends/VBoxBFE/VMMDev.h +++ b/src/VBox/Frontends/VBoxBFE/VMMDev.h @@ -43,7 +43,8 @@ public: int hgcmHostCall (const char *pszServiceName, uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms); private: - static DECLCALLBACK(void) UpdateGuestVersion(PPDMIVMMDEVCONNECTOR pInterface, VBoxGuestInfo *guestInfo); + static DECLCALLBACK(void) UpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestStatus *guestStatus); + static DECLCALLBACK(void) UpdateGuestInfo(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestInfo *guestInfo); static DECLCALLBACK(void) UpdateGuestCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities); static DECLCALLBACK(void) UpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities); static DECLCALLBACK(void) UpdatePointerShape(PPDMIVMMDEVCONNECTOR pInterface, bool fVisible, bool fAlpha, diff --git a/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp b/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp index 577a24e4c..6fe5ce19c 100644 --- a/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp +++ b/src/VBox/Frontends/VBoxBFE/VMMDevInterface.cpp @@ -107,14 +107,27 @@ PPDMIVMMDEVPORT VMMDev::getVMMDevPort() /** - * Report guest OS version. + * Reports Guest Additions status. + * Called whenever the Additions issue a guest status report request or the VM is reset. + * + * @param pInterface Pointer to this interface. + * @param guestInfo Pointer to guest information structure + * @thread The emulation thread. + */ +DECLCALLBACK(void) VMMDev::UpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestStatus *guestStatus) +{ + return; +} + +/** + * Report guest information. * Called whenever the Additions issue a guest version report request. * * @param pInterface Pointer to this interface. * @param guestInfo Pointer to guest information structure * @thread The emulation thread. */ -DECLCALLBACK(void) VMMDev::UpdateGuestVersion(PPDMIVMMDEVCONNECTOR pInterface, VBoxGuestInfo *guestInfo) +DECLCALLBACK(void) VMMDev::UpdateGuestInfo(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestInfo *guestInfo) { return; } @@ -374,7 +387,8 @@ DECLCALLBACK(int) VMMDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint3 */ pDrvIns->IBase.pfnQueryInterface = VMMDev::drvQueryInterface; - pData->Connector.pfnUpdateGuestVersion = VMMDev::UpdateGuestVersion; + pData->Connector.pfnUpdateGuestStatus = VMMDev::UpdateGuestStatus; + pData->Connector.pfnUpdateGuestInfo = VMMDev::UpdateGuestInfo; pData->Connector.pfnUpdateGuestCapabilities = VMMDev::UpdateGuestCapabilities; pData->Connector.pfnUpdateMouseCapabilities = VMMDev::UpdateMouseCapabilities; pData->Connector.pfnUpdatePointerShape = VMMDev::UpdatePointerShape; diff --git a/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp b/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp index 33cbce2b4..c7bd4d34a 100644 --- a/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp +++ b/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp @@ -206,8 +206,8 @@ public: Utf8Str utf8Key = key; if (utf8Key == "/VirtualBox/GuestInfo/OS/NoLoggedInUsers") { - /* Check if the "disconnect on logout feature" is enabled. */ - BOOL fDisconnectOnGuestLogout = FALSE; + /* Check if this is our machine and the "disconnect on logout feature" is enabled. */ + BOOL fProcessDisconnectOnGuestLogout = FALSE; ComPtr <IMachine> machine; HRESULT hrc = S_OK; @@ -216,16 +216,21 @@ public: hrc = gConsole->COMGETTER(Machine)(machine.asOutParam()); if (SUCCEEDED(hrc) && machine) { - Bstr value1; - hrc = machine->GetExtraData(Bstr("VRDP/DisconnectOnGuestLogout"), value1.asOutParam()); - if (SUCCEEDED(hrc) && value1 == "1") + Bstr id; + hrc = machine->COMGETTER(Id)(id.asOutParam()); + if (id == machineId) { - fDisconnectOnGuestLogout = TRUE; + Bstr value1; + hrc = machine->GetExtraData(Bstr("VRDP/DisconnectOnGuestLogout"), value1.asOutParam()); + if (SUCCEEDED(hrc) && value1 == "1") + { + fProcessDisconnectOnGuestLogout = TRUE; + } } } } - if (fDisconnectOnGuestLogout) + if (fProcessDisconnectOnGuestLogout) { Utf8Str utf8Value = value; if (utf8Value == "true") @@ -1146,6 +1151,23 @@ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) CHECK_ERROR_BREAK(console, PowerUp(progress.asOutParam())); /* wait for result because there can be errors */ + /** @todo The error handling here is kind of peculiar, anyone care + * to comment why this works just fine? */ + for (;;) + { + rc = progress->WaitForCompletion(500); + if (FAILED(rc)) + break; + + /* Processing events is vital for teleportation targets. */ + gEventQ->processEventQueue(0); + + BOOL fCompleted; + rc = progress->COMGETTER(Completed)(&fCompleted); + if (FAILED(rc) || fCompleted) + break; + } + if (SUCCEEDED(progress->WaitForCompletion(-1))) { LONG progressRc; diff --git a/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp b/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp index 74d367bb9..4e6a0c866 100644 --- a/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp +++ b/src/VBox/Frontends/VBoxManage/VBoxInternalManage.cpp @@ -572,7 +572,7 @@ static int CmdDumpHDInfo(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox, /* we need exactly one parameter: the image file */ if (argc != 1) { - return errorSyntax(USAGE_SETHDUUID, "Not enough parameters"); + return errorSyntax(USAGE_DUMPHDINFO, "Not enough parameters"); } /* just try it */ diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp index 8030f2902..c8a57fe48 100644 --- a/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp +++ b/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp @@ -227,7 +227,9 @@ int handleCreateHardDisk(HandlerArg *a) case 't': // --type vrc = parseDiskType(ValueUnion.psz, &DiskType); if ( RT_FAILURE(vrc) - || (DiskType != MediumType_Normal && DiskType != MediumType_Writethrough)) + || ( DiskType != MediumType_Normal + && DiskType != MediumType_Writethrough + && DiskType != MediumType_Shareable)) return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz); break; @@ -303,9 +305,10 @@ int handleCreateHardDisk(HandlerArg *a) Bstr uuid; CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam())); - if (DiskType == MediumType_Writethrough) + if ( DiskType == MediumType_Writethrough + || DiskType == MediumType_Shareable) { - CHECK_ERROR(hardDisk, COMSETTER(Type)(MediumType_Writethrough)); + CHECK_ERROR(hardDisk, COMSETTER(Type)(DiskType)); } RTPrintf("Disk image created. UUID: %s\n", Utf8Str(uuid).raw()); diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp index 941672903..30d4cf051 100644 --- a/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp +++ b/src/VBox/Frontends/VBoxManage/VBoxManageGuestProp.cpp @@ -341,7 +341,7 @@ static int handleEnumGuestProperty(HandlerArg *a) /* * Pack the patterns */ - Utf8Str Utf8Patterns(a->argc > 2 ? a->argv[2] : "*"); + Utf8Str Utf8Patterns(a->argc > 2 ? a->argv[2] : ""); for (int i = 3; i < a->argc; ++i) Utf8Patterns = Utf8StrFmt ("%s,%s", Utf8Patterns.raw(), a->argv[i]); diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp index d6d36ab83..485dbd00b 100644 --- a/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp +++ b/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp @@ -426,7 +426,8 @@ void printUsage(USAGECATEGORY u64Cmd) if (u64Cmd & USAGE_OPENMEDIUM) { RTPrintf("VBoxManage openmedium disk|dvd|floppy <filename>\n" - " [--type normal|immutable|writethrough] (disk only)\n" + " [--type normal|immutable|writethrough|\n" + " shareable] (disk only)\n" " [--uuid <uuid>]\n" " [--parentuuid <uuid>] (disk only)\n" "\n"); @@ -479,7 +480,8 @@ void printUsage(USAGECATEGORY u64Cmd) " --size <megabytes>\n" " [--format VDI|VMDK|VHD] (default: VDI)\n" " [--variant Standard,Fixed,Split2G,Stream,ESX]\n" - " [--type normal|writethrough] (default: normal)\n" + " [--type normal|writethrough|\n" + " shareable] (default: normal)\n" " [--comment <comment>]\n" " [--remember]\n" "\n"); @@ -488,7 +490,7 @@ void printUsage(USAGECATEGORY u64Cmd) if (u64Cmd & USAGE_MODIFYHD) { RTPrintf("VBoxManage modifyhd <uuid>|<filename>\n" - " [--type normal|writethrough|immutable]\n" + " [--type normal|writethrough|immutable|shareable]\n" " [--autoreset on|off]\n" " [--compact]\n" "\n"); @@ -499,7 +501,7 @@ void printUsage(USAGECATEGORY u64Cmd) RTPrintf("VBoxManage clonehd <uuid>|<filename> <outputfile>\n" " [--format VDI|VMDK|VHD|RAW|<other>]\n" " [--variant Standard,Fixed,Split2G,Stream,ESX]\n" - " [--type normal|writethrough|immutable]\n" + " [--type normal|writethrough|immutable|shareable]\n" " [--remember] [--existing]\n" "\n"); } @@ -524,7 +526,7 @@ void printUsage(USAGECATEGORY u64Cmd) " [--encodedlun <lun>]\n" " [--username <username>]\n" " [--password <password>]\n" - " [--type normal|writethrough|immutable]\n" + " [--type normal|writethrough|immutable|shareable]\n" " [--intnet]\n" "\n"); } diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp index 39882b908..b224693d7 100644 --- a/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp +++ b/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp @@ -1905,10 +1905,53 @@ HRESULT showVMInfo (ComPtr<IVirtualBox> virtualBox, } } - ULONG guestVal; + if (details != VMINFO_MACHINEREADABLE) RTPrintf("Guest:\n\n"); + if (console) + { + ComPtr<IGuest> guest; + rc = console->COMGETTER(Guest)(guest.asOutParam()); + if (SUCCEEDED(rc)) + { + Bstr guestString; + rc = guest->COMGETTER(OSTypeId)(guestString.asOutParam()); + if ( SUCCEEDED(rc) + && !guestString.isEmpty()) + { + if (details == VMINFO_MACHINEREADABLE) + RTPrintf("GuestOSType=\"%lS\"\n", guestString.raw()); + else + RTPrintf("OS type: %lS\n", guestString.raw()); + } + + BOOL guestFlag; + rc = guest->COMGETTER(AdditionsActive)(&guestFlag); + if (SUCCEEDED(rc)) + { + if (details == VMINFO_MACHINEREADABLE) + RTPrintf("GuestAdditionsActive=%s\n", guestFlag ? "on" : "off"); + else + RTPrintf("Additions active: %s\n", guestFlag ? "yes" : "no"); + } + + if (details == VMINFO_FULL) + { + rc = guest->COMGETTER(AdditionsVersion)(guestString.asOutParam()); + if ( SUCCEEDED(rc) + && !guestString.isEmpty()) + { + if (details == VMINFO_MACHINEREADABLE) + RTPrintf("GuestAdditionsVersion=\"%lS\"\n", guestString.raw()); + else + RTPrintf("Additions version: %lS\n\n", guestString.raw()); + } + } + } + } + + ULONG guestVal; rc = machine->COMGETTER(MemoryBalloonSize)(&guestVal); if (SUCCEEDED(rc)) { diff --git a/src/VBox/Frontends/VBoxShell/vboxinfo.vbs b/src/VBox/Frontends/VBoxShell/vboxinfo.vbs index c62659549..7ef0d6e57 100644 --- a/src/VBox/Frontends/VBoxShell/vboxinfo.vbs +++ b/src/VBox/Frontends/VBoxShell/vboxinfo.vbs @@ -1,14 +1,14 @@ '
-' Copyright (C) 2009 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.
-'
+' Copyright (C) 2009 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. +' Sub Print(str)
Wscript.Echo str
diff --git a/src/VBox/Frontends/VirtualBox/VBoxUI.pro b/src/VBox/Frontends/VirtualBox/VBoxUI.pro index c768338d8..f11665737 100644 --- a/src/VBox/Frontends/VirtualBox/VBoxUI.pro +++ b/src/VBox/Frontends/VirtualBox/VBoxUI.pro @@ -70,37 +70,38 @@ FORMS = \ src/widgets/VBoxApplianceEditorWgt.ui TRANSLATIONS = \ - nls/VirtualBox_en.ts \ - nls/VirtualBox_el.ts \ - nls/VirtualBox_tr.ts \ - nls/VirtualBox_id.ts \ + nls/VirtualBox_ar.ts \ + nls/VirtualBox_bg.ts \ nls/VirtualBox_ca.ts \ nls/VirtualBox_ca_VA.ts \ - nls/VirtualBox_sk.ts \ - nls/VirtualBox_eu.ts \ - nls/VirtualBox_nl.ts \ nls/VirtualBox_cs.ts \ - nls/VirtualBox_hu.ts \ - nls/VirtualBox_fi.ts \ - nls/VirtualBox_sr.ts \ - nls/VirtualBox_ko.ts \ - nls/VirtualBox_sv.ts \ - nls/VirtualBox_pt.ts \ - nls/VirtualBox_pt_BR.ts \ - nls/VirtualBox_ja.ts \ - nls/VirtualBox_pl.ts \ - nls/VirtualBox_ar.ts \ + nls/VirtualBox_da.ts \ nls/VirtualBox_de.ts \ + nls/VirtualBox_el.ts \ + nls/VirtualBox_en.ts \ nls/VirtualBox_es.ts \ - nls/VirtualBox_gl_ES.ts \ + nls/VirtualBox_eu.ts \ + nls/VirtualBox_fi.ts \ nls/VirtualBox_fr.ts \ + nls/VirtualBox_gl_ES.ts \ + nls/VirtualBox_hu.ts \ + nls/VirtualBox_id.ts \ nls/VirtualBox_it.ts \ + nls/VirtualBox_ja.ts \ + nls/VirtualBox_km_KH.ts \ + nls/VirtualBox_ko.ts \ + nls/VirtualBox_lt.ts \ + nls/VirtualBox_nl.ts \ + nls/VirtualBox_pl.ts \ + nls/VirtualBox_pt.ts \ + nls/VirtualBox_pt_BR.ts \ nls/VirtualBox_ro.ts \ nls/VirtualBox_ru.ts \ - nls/VirtualBox_zh_CN.ts \ - nls/VirtualBox_zh_TW.ts \ - nls/VirtualBox_km_KH.ts \ - nls/VirtualBox_bg.ts \ + nls/VirtualBox_sk.ts \ + nls/VirtualBox_sr.ts \ + nls/VirtualBox_sv.ts \ + nls/VirtualBox_tr.ts \ nls/VirtualBox_uk.ts \ - nls/VirtualBox_da.ts + nls/VirtualBox_zh_CN.ts \ + nls/VirtualBox_zh_TW.ts diff --git a/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk b/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk index ad0a37da3..905238525 100644 --- a/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk +++ b/src/VBox/Frontends/VirtualBox/nls/ApprovedLanguages.kmk @@ -35,6 +35,7 @@ VBOX_APPROVED_GUI_LANGUAGES := \ ja \ km_KH \ ko \ + lt \ nl \ pl \ pt \ @@ -48,4 +49,3 @@ VBOX_APPROVED_GUI_LANGUAGES := \ uk \ zh_CN \ zh_TW - diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts index 1ab33aefa..aa7bb330f 100644 --- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts +++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_ca.ts @@ -26,7 +26,7 @@ <message> <source>Oracle Corporation</source> <comment>Comma-separated list of translators</comment> - <translation>Vicent Fornés, Pau Iranzo <pau@somgnu.cat></translation> + <translation>Vicent Fornés, Pau Iranzo <pau.iranzo@softcatala.org></translation> </message> </context> <context> @@ -666,61 +666,61 @@ </message> <message> <source>Enter &Fullscreen Mode</source> - <translation type="unfinished"></translation> + <translation>Entra al mode de &pantalla completa</translation> </message> <message> <source>Exit &Fullscreen Mode</source> - <translation type="unfinished"></translation> + <translation>Surt del mode de &pantalla completa</translation> </message> <message> <source>Switch to normal mode</source> - <translation type="unfinished"></translation> + <translation>Canvia al mode normal</translation> </message> <message> <source>Enter Seam&less Mode</source> - <translation type="unfinished"></translation> + <translation>Entra en el mode &fluid</translation> </message> <message> <source>Exit Seam&less Mode</source> - <translation type="unfinished"></translation> + <translation>Surt del mode &fluid</translation> </message> <message> <source>Enable &Guest Display Auto-resize</source> - <translation type="unfinished"></translation> + <translation>Habilita el redimensionament automàtic de la pantalla del &client</translation> </message> <message> <source>Disable &Guest Display Auto-resize</source> - <translation type="unfinished"></translation> + <translation>Inhabilita el redimensionament automàtic de la pantalla del &client</translation> </message> <message> <source>Disable automatic resize of the guest display when the window is resized</source> - <translation type="unfinished"></translation> + <translation>Inhabilita el redimensinament automàtic de la pantalla del client quan es canvia la mida de la finestra</translation> </message> <message> <source>&Enable Remote Display</source> - <translation type="unfinished"></translation> + <translation>&Habilita la pantalla remota</translation> </message> <message> <source>Enable remote desktop (RDP) connections to this machine</source> - <translation type="unfinished"></translation> + <translation>Habilita les connexions d'escriptori remot (RDP) en aquesta màquina</translation> </message> <message> <source>&Disable Remote Display</source> - <translation type="unfinished"></translation> + <translation>&Inhabilita la pantalla remota</translation> </message> <message> <source>Disable remote desktop (RDP) connections to this machine</source> - <translation type="unfinished"></translation> + <translation>Inhabilita les connexions d'escriptori remot (RDP) en aquesta màquina</translation> </message> <message> <source>Enable &Logging...</source> <comment>debug action</comment> - <translation type="unfinished"></translation> + <translation>Activa l'&enregistrament...</translation> </message> <message> <source>Disable &Logging...</source> <comment>debug action</comment> - <translation type="unfinished"></translation> + <translation>Desactiva l'&enregistrament...</translation> </message> </context> <context> @@ -2250,7 +2250,7 @@ pas i connectar discos durs més endavant, fent servir el diàleg de configuraci </message> <message> <source>Boot Hard &Disk</source> - <translation type="unfinished"></translation> + <translation>Arrenca el &disc dur</translation> </message> </context> <context> @@ -2527,7 +2527,7 @@ Versió %1</translation> </message> <message> <source>Hard Disk Controller (SAS)</source> - <translation type="unfinished"></translation> + <translation>Mòdul de disc dur (SAS)</translation> </message> </context> <context> @@ -5386,12 +5386,12 @@ Versió %1</translation> <message> <source>Unknown device</source> <comment>USB device details</comment> - <translation type="unfinished"></translation> + <translation>Dispositiu desconegut</translation> </message> <message> <source>SAS Port %1</source> <comment>New Storage UI : Slot Name</comment> - <translation type="unfinished"></translation> + <translation>Port SAS %1</translation> </message> </context> <context> @@ -7960,12 +7960,12 @@ un disc dur per connectar a la ranura remarcada actualment.</a></translati <message> <source>&File</source> <comment>Mac OS X version</comment> - <translation type="unfinished">&Fitxer</translation> + <translation>&Fitxer</translation> </message> <message> <source>&File</source> <comment>Non Mac OS X version</comment> - <translation type="unfinished">&Fitxer</translation> + <translation>&Fitxer</translation> </message> </context> <context> diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts index bdb19f5eb..9ee7afc39 100644 --- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts +++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_it.ts @@ -6680,7 +6680,7 @@ la lingua a quella predefinita di sistema.</qt> <message> <source>Result&nbsp;Code: </source> <comment>error info</comment> - <translation>Codice&nbspd'uscita: </translation> + <translation>Codice&nbsp;'uscita: </translation> </message> <message> <source>Component: </source> diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts new file mode 100644 index 000000000..f0d378469 --- /dev/null +++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_lt.ts @@ -0,0 +1,6514 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="lt_LT" sourcelanguage="en"> +<context> + <name>@@@</name> + <message> + <source>English</source> + <comment>Native language name</comment> + <translation>Lietuvių</translation> + </message> + <message> + <source>--</source> + <comment>Native language country name (empty if this language is for all countries) +</comment> + <translatorcomment>Lietuva</translatorcomment> + <translation></translation> + </message> + <message> + <source>English</source> + <comment>Language name, in English</comment> + <translation>Lithuanian</translation> + </message> + <message> + <source>--</source> + <comment>Language country name, in English (empty if native country name is empty) +</comment> + <translatorcomment>Lithuanian</translatorcomment> + <translation></translation> + </message> + <message> + <source>Oracle Corporation</source> + <comment>Comma-separated list of translators</comment> + <translation>Mindaugas Baranauskas</translation> + </message> +</context> +<context> + <name>QApplication</name> + <message> + <source>Executable <b>%1</b> requires Qt %2.x, found Qt %3.</source> + <translation>Programai <b>%1</b> reikia Qt %2.x, bet rasta Qt %3 versija.</translation> + </message> + <message> + <source>Incompatible Qt Library Error</source> + <translation>Klaida: QT bibliotekos nesuderinamos</translation> + </message> + <message> + <source>VirtualBox - Error In %1</source> + <translation>VirtualBox - %1 klaida</translation> + </message> + <message> + <source><html><b>%1 (rc=%2)</b><br/><br/></source> + <translation><html><b>%1 (rc=%2)</b><br/><br/></translation> + </message> + <message> + <source>Please try reinstalling VirtualBox.</source> + <translation>Bandykite iš naujo įdiegti VirtualBox.</translation> + </message> + <message> + <source>The VirtualBox Linux kernel driver (vboxdrv) is either not loaded or there is a permission problem with /dev/vboxdrv. Please reinstall the kernel module by executing<br/><br/> <font color=blue>'/etc/init.d/vboxdrv setup'</font><br/><br/>as root. Users of Ubuntu, Fedora or Mandriva should install the DKMS package first. This package keeps track of Linux kernel changes and recompiles the vboxdrv kernel module if necessary.</source> + <translation>VirtualBox Linux branduolio modulis (vboxdrv) arba nėra įkeltas, arba nepakanka leidimų dirbti su /dev/vboxdrv. Iš naujo įdiekite branduolio modulį root teisėmis įvykdydami <br/><br/><font color=blue>'/etc/init.d/vboxdrv setup'</font><br/><br/>. Ubuntu, Fedora ir Mandriva platinamųjų paketų naudotojai pirma turi įsidiegti DKMS paketą. Šis paketas seka Linux branduolio pakeitimus ir, jei reikia, perkompiliuoja vboxdrv branduolio modulį.</translation> + </message> + <message> + <source>Make sure the kernel module has been loaded successfully.</source> + <translation>Įsitikinte, ar tinkamai įkeltas branduolio modulis.</translation> + </message> + <message> + <source>VirtualBox - Runtime Error</source> + <translation>VirtualBox - vykdymo klaida</translation> + </message> + <message> + <source><b>Cannot access the kernel driver!</b><br/><br/></source> + <translation><b>Nepavyksta pasiekti branduolio tvarkyklės!</b><br/><br/></translation> + </message> + <message> + <source>Unknown error %2 during initialization of the Runtime</source> + <translation>Vykdant įvykonežinoma klaida %2</translation> + </message> + <message> + <source>Kernel driver not accessible</source> + <translation>Branduolio tvarkyklė nepasiekiama</translation> + </message> + <message> + <source>The VirtualBox kernel modules do not match this version of VirtualBox. The installation of VirtualBox was apparently not successful. Please try completely uninstalling and reinstalling VirtualBox.</source> + <translation>VirtualBox branduolio moduliai neatitinka įdiegtos VirtualBox versijos. Tikriausiai VirtualBox nebuvo pilnai įdiegta. Patariame visiškai pašalinti VirtualBox ir įdiegti iš naujo.</translation> + </message> + <message> + <source>The VirtualBox kernel modules do not match this version of VirtualBox. The installation of VirtualBox was apparently not successful. Executing<br/><br/> <font color=blue>'/etc/init.d/vboxdrv setup'</font><br/><br/>may correct this. Make sure that you do not mix the OSE version and the PUEL version of VirtualBox.</source> + <translation>VirtualBox branduolio moduliai neatitinka įdiegtos VirtualBox versijos. Tikriausiai VirtualBox nebuvo pilnai įdiegta. Galbūt administratoriaus teisėmis įvykdžius <br/><br/><font color=blue>'/etc/init.d/vboxdrv setup'</font><br/><br/> ši problema išsispręs. Įsitikinkite, kad nenaudojate OSE ir PUEL VirtualBox versijų dalių vienu metu.</translation> + </message> + <message> + <source>This error means that the kernel driver was either not able to allocate enough memory or that some mapping operation failed.</source> + <translation>Ši klaida reiškia, kad branduolio modulis arba negali išnaudoti pakankamai atminties, arba nepavyko atlikti kai kurių planavimo operacijų.</translation> + </message> +</context> +<context> + <name>QIArrowSplitter</name> + <message> + <source>&Back</source> + <translation>&Atgal</translation> + </message> + <message> + <source>&Next</source> + <translation>&Toliau</translation> + </message> +</context> +<context> + <name>QIFileDialog</name> + <message> + <source>Select a directory</source> + <translation>Pasirinkti aplanką</translation> + </message> + <message> + <source>Select a file</source> + <translation>Pasirinkti rinkmeną</translation> + </message> +</context> +<context> + <name>QIHotKeyEdit</name> + <message> + <source>Left </source> + <translation>Kairėn </translation> + </message> + <message> + <source>Right </source> + <translation>Dešinėn </translation> + </message> + <message> + <source>Left Shift</source> + <translation>Kairysis Lyg2</translation> + </message> + <message> + <source>Right Shift</source> + <translation>Dešinysis Lyg2</translation> + </message> + <message> + <source>Left Ctrl</source> + <translation>Kairysis Vald</translation> + </message> + <message> + <source>Right Ctrl</source> + <translation>Dešinysis Vald</translation> + </message> + <message> + <source>Left Alt</source> + <translation>Kairysis Alt</translation> + </message> + <message> + <source>Right Alt</source> + <translation>Dešinysis Alt</translation> + </message> + <message> + <source>Left WinKey</source> + <translation>Kairysis Win</translation> + </message> + <message> + <source>Right WinKey</source> + <translation>Dešinysis Win</translation> + </message> + <message> + <source>Menu key</source> + <translation>Meniu klavišas</translation> + </message> + <message> + <source>Alt Gr</source> + <translation>Lyg3</translation> + </message> + <message> + <source>Caps Lock</source> + <translation>Didž(iosios)</translation> + </message> + <message> + <source>Scroll Lock</source> + <translation>Slinkti</translation> + </message> + <message> + <source><key_%1></source> + <translation><%1_klavišas></translation> + </message> + <message> + <source>Pause</source> + <translation>Pauzė</translation> + </message> + <message> + <source>Print Screen</source> + <translation>Ekrano nuotrauka</translation> + </message> + <message> + <source>F1</source> + <translation>F1</translation> + </message> + <message> + <source>F2</source> + <translation>F2</translation> + </message> + <message> + <source>F3</source> + <translation>F3</translation> + </message> + <message> + <source>F4</source> + <translation>F4</translation> + </message> + <message> + <source>F5</source> + <translation>F5</translation> + </message> + <message> + <source>F6</source> + <translation>F6</translation> + </message> + <message> + <source>F7</source> + <translation>F7</translation> + </message> + <message> + <source>F8</source> + <translation>F8</translation> + </message> + <message> + <source>F9</source> + <translation>F9</translation> + </message> + <message> + <source>F10</source> + <translation>F10</translation> + </message> + <message> + <source>F11</source> + <translation>F11</translation> + </message> + <message> + <source>F12</source> + <translation>F12</translation> + </message> + <message> + <source>F13</source> + <translation>F13</translation> + </message> + <message> + <source>F14</source> + <translation>F14</translation> + </message> + <message> + <source>F15</source> + <translation>F15</translation> + </message> + <message> + <source>F16</source> + <translation>F16</translation> + </message> + <message> + <source>F17</source> + <translation>F17</translation> + </message> + <message> + <source>F18</source> + <translation>F18</translation> + </message> + <message> + <source>F19</source> + <translation>F19</translation> + </message> + <message> + <source>F20</source> + <translation>F20</translation> + </message> + <message> + <source>F21</source> + <translation>F21</translation> + </message> + <message> + <source>F22</source> + <translation>F22</translation> + </message> + <message> + <source>F23</source> + <translation>F23</translation> + </message> + <message> + <source>F24</source> + <translation>F24</translation> + </message> + <message> + <source>Num Lock</source> + <translation>Skaitm(enys)</translation> + </message> + <message> + <source>Forward</source> + <translation>Toliau</translation> + </message> + <message> + <source>Back</source> + <translation>Atgal</translation> + </message> +</context> +<context> + <name>QIHttp</name> + <message> + <source>Connection timed out</source> + <translation>Bandymui prisijungti laikas baigėsi</translation> + </message> + <message> + <source>Could not locate the file on the server (response: %1)</source> + <translation>Serveryje nepavyksta rasti rinkmenos (atsakas: %1)</translation> + </message> +</context> +<context> + <name>QILabel</name> + <message> + <source>&Copy</source> + <translation>&Kopijuoti</translation> + </message> +</context> +<context> + <name>QIMessageBox</name> + <message> + <source>OK</source> + <translation>Gerai</translation> + </message> + <message> + <source>Yes</source> + <translation>Taip</translation> + </message> + <message> + <source>No</source> + <translation>Ne</translation> + </message> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>Ignore</source> + <translation>Nepaisyti</translation> + </message> + <message> + <source>&Details</source> + <translation>&Detalės</translation> + </message> + <message> + <source>&Details (%1 of %2)</source> + <translation>&Detalės (%1 iš %2)</translation> + </message> +</context> +<context> + <name>QIWidgetValidator</name> + <message> + <source>not complete</source> + <comment>value state +</comment> + <translation>neužbaigta</translation> + </message> + <message> + <source>invalid</source> + <comment>value state +</comment> + <translation>neleistina</translation> + </message> + <message> + <source><qt>The value of the <b>%1</b> field on the <b>%2</b> page is %3.</qt></source> + <translation><qt>Laukelio <b>%1</b> reikšmė puslapyje „<b>%2</b>“ yra %3.</qt></translation> + </message> + <message> + <source><qt>One of the values on the <b>%1</b> page is %2.</qt></source> + <translation><qt>Viena iš puslapio „<b>%1</b>“ reikšmių yra %2.</qt></translation> + </message> +</context> +<context> + <name>QIWizardPage</name> + <message> + <source>Use the <b>%1</b> button to go to the next page of the wizard and the <b>%2</b> button to return to the previous page. You can also press <b>%3</b> if you want to cancel the execution of this wizard.</p></source> + <translation>Nuspaudę <b>%1</b> pereisite į tolesnį vediklio puslapį, o mygtuku <b>%2</b> – grįšite į ankstesnįjį. Norėdami užverti vediklį, spauskite <b>%3</b>.</p></translation> + </message> +</context> +<context> + <name>UIActionsPool</name> + <message> + <source>&Machine</source> + <translation>&Mašina</translation> + </message> + <message> + <source>Switch to fullscreen mode</source> + <translation>Pereiti į darbą visame ekrane</translation> + </message> + <message> + <source>Switch to seamless desktop integration mode</source> + <translation>Virtualią mašiną integruoti į darbalaukį</translation> + </message> + <message> + <source>Automatically resize the guest display when the window is resized (requires Guest Additions)</source> + <translation>Keičiant lango dydį, automatiškai keičiamas ir svečio ekrano dydis (reikia „Svečio papildinių“)</translation> + </message> + <message> + <source>&Adjust Window Size</source> + <translation>Lango dydį pritaikyti pagal &mašinos ekraną</translation> + </message> + <message> + <source>Adjust window size and position to best fit the guest display</source> + <translation>Lango dydį ir padėtį parinkti taip, kad geriausiai atitiktų svečio ekraną</translation> + </message> + <message> + <source>Disable &Mouse Integration</source> + <translation>Uždrausti &pelės integravimą</translation> + </message> + <message> + <source>Temporarily disable host mouse pointer integration</source> + <translation>Laikinai uždrausti kompiuterio pelės žymeklio integravimą</translation> + </message> + <message> + <source>Enable &Mouse Integration</source> + <translation>Įgalinti &pelės integravimą</translation> + </message> + <message> + <source>Enable temporarily disabled host mouse pointer integration</source> + <translation>Laikinai įgalinti kompiuterio pelės žymeklio integravimą</translation> + </message> + <message> + <source>&Insert Ctrl-Alt-Del</source> + <translation>Su&rinkti Vald+Alt+Šalinti</translation> + </message> + <message> + <source>Send the Ctrl-Alt-Del sequence to the virtual machine</source> + <translation>Mašinai nusiųsti klavišų kombinaciją Vald+Alt+Šalinti(Delete)</translation> + </message> + <message> + <source>&Insert Ctrl-Alt-Backspace</source> + <translation>Su&rinkti Vald+Alt+Naikinti</translation> + </message> + <message> + <source>Send the Ctrl-Alt-Backspace sequence to the virtual machine</source> + <translation>Mašinai nusiųsti klavišų kombinaciją Vald+Alt+Naikinti(Backspace)</translation> + </message> + <message> + <source>Take &Snapshot...</source> + <translation>&Sukurti dabartinio būvio kopiją...</translation> + </message> + <message> + <source>Take a snapshot of the virtual machine</source> + <translation>Padaryti virtualios mašinos dabartinio būvio kopiją</translation> + </message> + <message> + <source>Session I&nformation Dialog</source> + <translation>Sesijos i&nformacija</translation> + </message> + <message> + <source>Show Session Information Dialog</source> + <translation>Rodyti informaciją apie šią sesiją</translation> + </message> + <message> + <source>&Pause</source> + <translation>&Pristabdyti</translation> + </message> + <message> + <source>Suspend the execution of the virtual machine</source> + <translation>Sustabdyti virtualią mašiną jos būseną išsaugant diske</translation> + </message> + <message> + <source>R&esume</source> + <translation>&Tęsti</translation> + </message> + <message> + <source>Resume the execution of the virtual machine</source> + <translation>Tęsti pristabdytos virtualios mašinos darbą</translation> + </message> + <message> + <source>&Reset</source> + <translation>&Perkrauti</translation> + </message> + <message> + <source>Reset the virtual machine</source> + <translation>Perkrauti virtualią mašiną</translation> + </message> + <message> + <source>ACPI Sh&utdown</source> + <translation>Išj&ungti per ACPI</translation> + </message> + <message> + <source>ACPI S&hutdown</source> + <translation>Išjunti per &ACPI</translation> + </message> + <message> + <source>Send the ACPI Power Button press event to the virtual machine</source> + <translation>Virtualioje mašinoje nuspausti kompiuterio išjungimo mygtuką</translation> + </message> + <message> + <source>&Close...</source> + <translation>&Užverti...</translation> + </message> + <message> + <source>Close the virtual machine</source> + <translation>Užverti virtualią mašiną</translation> + </message> + <message> + <source>&View</source> + <translation>&Peržiūra</translation> + </message> + <message> + <source>&Devices</source> + <translation>Į&renginiai</translation> + </message> + <message> + <source>&CD/DVD Devices</source> + <translation>&CD/DVD įrenginiai</translation> + </message> + <message> + <source>&Floppy Devices</source> + <translation>&Diskeliai</translation> + </message> + <message> + <source>&USB Devices</source> + <translation>&USB įrenginiai</translation> + </message> + <message> + <source>&Network Adapters...</source> + <translation>&Tinklo plokštės...</translation> + </message> + <message> + <source>Change the settings of network adapters</source> + <translation>Keisti tinklo plokščių nuostatas</translation> + </message> + <message> + <source>&Shared Folders...</source> + <translation>&Bendrieji aplankai...</translation> + </message> + <message> + <source>Create or modify shared folders</source> + <translation>Kurti arba keisti bendruosius aplankus</translation> + </message> + <message> + <source>&Install Guest Additions...</source> + <translation>Į&diegti svečio papildinius...</translation> + </message> + <message> + <source>Mount the Guest Additions installation image</source> + <translation>Prijungti svečio papildinių disko atvaizdą</translation> + </message> + <message> + <source>De&bug</source> + <translation>D&erinimas</translation> + </message> + <message> + <source>&Statistics...</source> + <comment>debug action +</comment> + <translation>&Statistika...</translation> + </message> + <message> + <source>&Command Line...</source> + <comment>debug action +</comment> + <translation>&Komandinė eilutė...</translation> + </message> + <message> + <source>&Help</source> + <translation>&Pagalba</translation> + </message> + <message> + <source>Dock Icon</source> + <translation>Ženkliukas sitemos dėkle</translation> + </message> + <message> + <source>Show Monitor Preview</source> + <translation>Vaizduoklio peržiūra</translation> + </message> + <message> + <source>Show Application Icon</source> + <translation>Rodyti programos ženkliuką</translation> + </message> + <message> + <source>Enter &Fullscreen Mode</source> + <translation>Įeiti į &viso ekrano veikseną</translation> + </message> + <message> + <source>Exit &Fullscreen Mode</source> + <translation>Baigti &viso ekrano veikseną</translation> + </message> + <message> + <source>Switch to normal mode</source> + <translation>Pereiti į įprastą veikseną</translation> + </message> + <message> + <source>Enter Seam&less Mode</source> + <translation>Įeiti į &integruotą veikseną</translation> + </message> + <message> + <source>Exit Seam&less Mode</source> + <translation>Baigti &integruotą veikseną</translation> + </message> + <message> + <source>Enable &Guest Display Auto-resize</source> + <translation>Įgalinti automatinį svečio &ekrano keitimą</translation> + </message> + <message> + <source>Disable &Guest Display Auto-resize</source> + <translation>Uždrausti automatinį svečio &ekrano keitimą</translation> + </message> + <message> + <source>Disable automatic resize of the guest display when the window is resized</source> + <translation>Uždraudžia automatinį svečio ekrano dydžio keitimą, kai keičiamas VM lango dydis</translation> + </message> + <message> + <source>&Enable Remote Display</source> + <translation>Įgalinti &nuotolinį ekraną</translation> + </message> + <message> + <source>Enable remote desktop (RDP) connections to this machine</source> + <translation>Įgalinti nuotolinio darbastalio (RDP) prisijungimus prie šios mašinos</translation> + </message> + <message> + <source>&Disable Remote Display</source> + <translation>Uždrausti &nuotolinį ekraną</translation> + </message> + <message> + <source>Disable remote desktop (RDP) connections to this machine</source> + <translation>Uždrausti nuotolinio darbastalio (RDP) prisijungimus prie šios mašinos</translation> + </message> + <message> + <source>Enable &Logging...</source> + <comment>debug action</comment> + <translation>Uždrausti žurnalų pildy&mą...</translation> + </message> + <message> + <source>Disable &Logging...</source> + <comment>debug action</comment> + <translation>Įgalinti žurnalų pildy&mą...</translation> + </message> +</context> +<context> + <name>UIDownloader</name> + <message> + <source>The download process has been canceled by the user.</source> + <translation>Parsiuntimą nutraukė naudotojas.</translation> + </message> +</context> +<context> + <name>UIDownloaderAdditions</name> + <message> + <source><p>Failed to save the downloaded file as <nobr><b>%1</b>.</nobr></p></source> + <translation><p>Nepavyko įrašyti parsiųstos rinkmenos kaip <nobr><b>%1</b>.</nobr></p></translation> + </message> + <message> + <source>Select folder to save Guest Additions image to</source> + <translation>Nurodykite aplanką, kuriame bus įrašyta „svečio papildinių“ atvaizdas</translation> + </message> +</context> +<context> + <name>UIDownloaderUserManual</name> + <message> + <source>Select folder to save User Manual to</source> + <translation>Nurodykite aplanką, kuriame bus įrašytas naudotojo žinynas</translation> + </message> +</context> +<context> + <name>UIExportApplianceWzd</name> + <message> + <source>Appliance Export Wizard</source> + <translation>Virtualios mašinos eksportavimo vediklis</translation> + </message> + <message> + <source>Restore Defaults</source> + <translation>Atkurti pirmines reiškmes</translation> + </message> +</context> +<context> + <name>UIExportApplianceWzdPage1</name> + <message> + <source>Welcome to the Appliance Export Wizard!</source> + <translation>Jus sveikina virtualios mašinos eksportavimo vediklis!</translation> + </message> + <message> + <source><p>This wizard will guide you through the process of exporting an appliance.</p><p>%1</p><p>Please select the virtual machines that should be added to the appliance. You can select more than one. Please note that these machines have to be turned off before they can be exported.</p></source> + <translation><p>Šis vediklis padės perkelti virtualios mašinos duomenis.</p><p>%1</p><p>Pasirinkite virtualias mašinas, kurias ketinate eksportuoti. Galite pasirinkti daugiau nei vieną. Atminkite, kad eksportuojamos mašinos turi būti išjungtos.</p></translation> + </message> +</context> +<context> + <name>UIExportApplianceWzdPage2</name> + <message> + <source>Here you can change additional configuration values of the selected virtual machines. You can modify most of the properties shown by double-clicking on the items.</source> + <translation>Čia galite keisti papildomas konfigūracijos reikšmes pasirinktai virtualiai mašinai. Daugelį savybių pakeisite jas dukart spragtelėję pele.</translation> + </message> + <message> + <source>Appliance Export Settings</source> + <translation>Virtualios mašinos eksportavimo nuostatos</translation> + </message> +</context> +<context> + <name>UIExportApplianceWzdPage3</name> + <message> + <source>Please specify the target for the OVF export. You can choose between a local file system export, uploading the OVF to the Sun Cloud service or an S3 storage server.</source> + <translation>Nurodykite OVF eksportavimo paskirtį. Galite rinktis vietinę rinkmenų sistemą, įkėlimą į Sun debesį arba į S3 saugojimo serverį.</translation> + </message> + <message> + <source>&Local Filesystem </source> + <translation>&Vietinė rinkmenų sistema</translation> + </message> + <message> + <source>Sun &Cloud</source> + <translation>Sun &debesis</translation> + </message> + <message> + <source>&Simple Storage System (S3)</source> + <translation>&Paprasta saugojimo sistema (S3)</translation> + </message> + <message> + <source>Appliance Export Settings</source> + <translation>Virtualios mašinos eksportavimo nuostatos</translation> + </message> +</context> +<context> + <name>UIExportApplianceWzdPage4</name> + <message> + <source>&Username:</source> + <translation>&Naudotojo vardas:</translation> + </message> + <message> + <source>&Password:</source> + <translation>&Slaptažodis:</translation> + </message> + <message> + <source>&Hostname:</source> + <translation>&Pagrindinio kompiuterio vardas:</translation> + </message> + <message> + <source>&Bucket:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>&File:</source> + <translation>&Rinkmena:</translation> + </message> + <message> + <source>Write in legacy OVF 0.9 format for compatibility with other virtualization products.</source> + <translation>Norėdami suderinti su kitais virtualizavimo produktais, galite eksportuoti senuoju OVF 0.9 formatu.</translation> + </message> + <message> + <source>&Write legacy OVF 0.9</source> + <translation>&Kurti senuoju OVF 0.9 formatu</translation> + </message> + <message> + <source>Appliance Export Settings</source> + <translation>Virtualios mašinos eksportavimo nuostatos</translation> + </message> + <message> + <source>Appliance</source> + <translation>Mašina</translation> + </message> + <message> + <source>Select a file to export into</source> + <translation>Pasirinkite, į kurią rinkmeną eksportuoti</translation> + </message> + <message> + <source>Open Virtualization Format (%1)</source> + <translation>Atviras Virtualizavimo Formatas (%1)</translation> + </message> + <message> + <source>Please choose a filename to export the OVF to.</source> + <translation>Nurodykite rinkmenos pavadinimą, į kurią bus eksportuojamas OVF.</translation> + </message> + <message> + <source>Please complete the additional fields like the username, password and the bucket, and provide a filename for the OVF target.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Please complete the additional fields like the username, password, hostname and the bucket, and provide a filename for the OVF target.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Checking files ...</source> + <translation>Tikrinamos rinkmenos...</translation> + </message> + <message> + <source>Removing files ...</source> + <translation>Šalinamos rinkmenos...</translation> + </message> + <message> + <source>Exporting Appliance ...</source> + <translation>Mašina eksportuojama...</translation> + </message> +</context> +<context> + <name>UIFirstRunWzd</name> + <message> + <source>First Run Wizard</source> + <translation>Pirmojo paleidimo vediklis</translation> + </message> +</context> +<context> + <name>UIFirstRunWzdPage1</name> + <message> + <source>Welcome to the First Run Wizard!</source> + <translation>Jus sveikina pirmojo paleidimo vediklis!</translation> + </message> + <message> + <source><p>You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for installing an operating system of your choice onto this virtual machine.</p><p>%1</p></source> + <translation><p>Jūs pirmą kartą paleidote naujai sukurtą virtualią mašiną. Šis vediklis padės atlikti svarbiausius žingsnius įdiegiant pasirinktą operacinę sistemą į šią virtualią mašiną.</p><p>%1</p></translation> + </message> + <message> + <source><p>You have started a newly created virtual machine for the first time. This wizard will help you to perform the steps necessary for booting an operating system of your choice on the virtual machine.</p><p>Note that you will not be able to install an operating system into this virtual machine right now because you did not attach any hard disk to it. If this is not what you want, you can cancel the execution of this wizard, select <b>Settings</b> from the <b>Machine</b> menu of the main VirtualBox window to access the settings dialog of this machine and change the hard disk configuration.</p><p>%1</p></source> + <translation><p>Pirmą kartą paleidote naujai sukurtą virtualią mašiną. Šis vediklis padės atlikti svarbiausius žingsnius įkraunant operacinę sistemą iš pasirinktos virtualios mašinos.</p><p>Atminkite, kad šią akimirką negalite įdiegti operacinės sistemos į virtualią mašiną, nes neprijungėte jokio standžiojo disko. Jei vis tik norite įdiegti, galite atšaukti šį vediklį, pagrindiniame VirtualBox lange iš <b>Mašinos</b> meniu pasirinkite <b>Nuostatas</b> ir pakeiskite standžiųjų diskų konfigūraciją.</p><p>%1</p></translation> + </message> +</context> +<context> + <name>UIFirstRunWzdPage2</name> + <message> + <source><p>Select the media which contains the setup program of the operating system you want to install. This media must be bootable, otherwise the setup program will not be able to start.</p></source> + <translation><p>Pasirinkite laikmeną, kuri turi operacinės sistemos diegimo programą. Ši laikmena turi būti įkraunama; antraip nepavyks paleisti diegimo programos.</p></translation> + </message> + <message> + <source><p>Select the media that contains the operating system you want to work with. This media must be bootable, otherwise the operating system will not be able to start.</p></source> + <translation><p>Pasirinkite laikmeną, kuri turi norimą operacinę sistemą. Ši laikmena turi būti įkraunama, antraip operacinė sistema nepasileis.</p> </translation> + </message> + <message> + <source>Media Source</source> + <translation>Laikmemos šaltinis</translation> + </message> + <message> + <source>Select Installation Media</source> + <translation>Pasirinkite diegimo laikmeną</translation> + </message> +</context> +<context> + <name>UIFirstRunWzdPage3</name> + <message> + <source><p>You have selected the following media to boot from:</p></source> + <translation><p>Įkrovimui pasirinkote šią laikmeną:</p></translation> + </message> + <message> + <source><p>You have selected the following media to boot an operating system from:</p></source> + <translation><p>Pasirinkote šią operacinės sistemos įkrovimo laikmeną: </p></translation> + </message> + <message> + <source><p>If the above is correct, press the <b>Finish</b> button. Once you press it, the selected media will be temporarily mounted on the virtual machine and the machine will start execution.</p><p>Please note that when you close the virtual machine, the specified media will be automatically unmounted and the boot device will be set back to the first hard disk.</p><p>Depending on the type of the setup program, you may need to manually unmount (eject) the media after the setup program reboots the virtual machine, to prevent the installation process from starting again. You can do this by selecting the corresponding <b>Unmount...</b> action in the <b>Devices</b> menu.</p></source> + <translation><p>Jei aukščiau esantys duomenys yra tinkami, spauskite mygtuką <b>Užbaigti</b>. Tuomet pasirinkta laikmena laikinai bus prijungta prie virtualios mašinos ir paleista.</p><p>Atminkite, kad užvėrus virtualią mašiną, ši laikmena bus atjungta, o įkrovos pirmenybė suteikta pirmajam standžiajam diskui.</p><p>Priklausomai nuo diegimo programos, gali tekti rankiniu būdu pašalinti (atjungti) laikmeną po sistemos persikrovimo, taip siekiant išvengti pakartotinio tos programos paleidimo. Tai galite padaryti pasirinkdami atitinkamą <b>Atjungti...</b> veiksmą iš <b>Įrenginių</b> meniu.</p></translation> + </message> + <message> + <source><p>If the above is correct, press the <b>Finish</b> button. Once you press it, the selected media will be mounted on the virtual machine and the machine will start execution.</p></source> + <translation><p>Jei aukščiau esantys duomenys yra tinkami, spauskite mygtuką <b>Užbaigti</b>. Tuomet pasirinkta laikmena bus prijungta prie virtualios mašinos ir paleista.</p></translation> + </message> + <message> + <source>Summary</source> + <translation>Santrauka</translation> + </message> + <message> + <source>CD/DVD-ROM Device</source> + <translation>CD/DVD įrenginys</translation> + </message> + <message> + <source>Type</source> + <comment>summary +</comment> + <translation>Tipas</translation> + </message> + <message> + <source>Source</source> + <comment>summary +</comment> + <translation>Šaltinis</translation> + </message> +</context> +<context> + <name>UIImportApplianceWzd</name> + <message> + <source>Appliance Import Wizard</source> + <translation>Virtualios mašinos importavimo vediklis</translation> + </message> + <message> + <source>Restore Defaults</source> + <translation>Atkurti pirmines reiškmes</translation> + </message> +</context> +<context> + <name>UIImportApplianceWzdPage1</name> + <message> + <source>Select an appliance to import</source> + <translation>Pasirinkite, iš kurios rinkmenos importuoti</translation> + </message> + <message> + <source>Open Virtualization Format (%1)</source> + <translation>Atviras Virtualizavimo Formatas (%1)</translation> + </message> + <message> + <source>Welcome to the Appliance Import Wizard!</source> + <translation>Jus sveikina virtualios mašinos importavimo vediklis!</translation> + </message> + <message> + <source><p>This wizard will guide you through importing an appliance.</p><p>%1</p><p>VirtualBox currently supports importing appliances saved in the Open Virtualization Format (OVF). To continue, select the file to import below:</p></source> + <translation><p>Šis vediklis padės importuoti virtualią mašiną.</p><p>%1</p><p>VirtualBox šiuo metu palaiko importavimą mašinų, įrašytų Atviru Virtualizacijos Formatu (OVF, Open Virtualization Format). Nėrėdami tęsti, pasirinkite importuotiną rinkmeną:</p></translation> + </message> +</context> +<context> + <name>UIImportApplianceWzdPage2</name> + <message> + <source>These are the virtual machines contained in the appliance and the suggested settings of the imported VirtualBox machines. You can change many of the properties shown by double-clicking on the items and disable others using the check boxes below.</source> + <translation>Rinkmenoje rastos šios virtualios mašinos ir jų nuostatos importavimui į VirtualBox. Čia daugelį savybių galite keisti dukart spragtelėdami peleties elementu, o uždrausti – pažymėdami žymimąjį langelį.</translation> + </message> + <message> + <source>Appliance Import Settings</source> + <translation>Virtualios mašinos importavimo nuostatos</translation> + </message> +</context> +<context> + <name>UIImportLicenseViewer</name> + <message> + <source><b>The virtual system "%1" requires that you agree to the terms and conditions of the software license agreement shown below.</b><br /><br />Click <b>Agree</b> to continue or click <b>Disagree</b> to cancel the import.</source> + <translation><b>„%1“ virtuali sistema reikalauja, kad sutiktumėte su toliau pateiktomis programinės įrangos licencijos sąlygomis.</b><br /><br />Norėdami tęsti, spauskite <b>Sutinku</b>. O jei norite nutraukti importavimą, spauskite <b>Nesutinku</b>.</translation> + </message> + <message> + <source>Software License Agreement</source> + <translation>Programinės įrangos licencijos sutartis</translation> + </message> + <message> + <source>&Disagree</source> + <translation>&Nesutinku</translation> + </message> + <message> + <source>&Agree</source> + <translation>&Sutinku</translation> + </message> + <message> + <source>&Print...</source> + <translation>&Spausdinti...</translation> + </message> + <message> + <source>&Save...</source> + <translation>Į&rašyti...</translation> + </message> + <message> + <source>Text (*.txt)</source> + <translation>Tekstas (*.txt)</translation> + </message> + <message> + <source>Save license to file...</source> + <translation>Licenciją įrašyti į rinkmeną...</translation> + </message> +</context> +<context> + <name>UIIndicatorsPool</name> + <message> + <source><p style='white-space:pre'><nobr>Indicates the activity of the virtual hard disks:</nobr>%1</p></source> + <comment>HDD tooltip +</comment> + <translation><p style='white-space:pre'><nobr>Rodo, virtualių standžiųjų diskų aktyvumą:</nobr>%1</p></translation> + </message> + <message> + <source><p style='white-space:pre'><nobr>Indicates the activity of the CD/DVD devices:</nobr>%1</p></source> + <comment>CD/DVD tooltip +</comment> + <translation><p style='white-space:pre'><nobr>Rodo CD/DVD įrenginių aktyvumą:</nobr>%1</p></translation> + </message> + <message> + <source><p style='white-space:pre'><nobr>Indicates the activity of the floppy devices:</nobr>%1</p></source> + <comment>FD tooltip +</comment> + <translation><p style='white-space:pre'><nobr>Rodo diskelių įrenginių aktyvumą:</nobr>%1</p></translation> + </message> + <message> + <source><p style='white-space:pre'><nobr>Indicates the activity of the network interfaces:</nobr>%1</p></source> + <comment>Network adapters tooltip +</comment> + <translation><p style='white-space:pre'><nobr>Rodo tinklo sąsajų aktyvumą:</nobr>%1</p></translation> + </message> + <message> + <source><br><nobr><b>Adapter %1 (%2)</b>: %3 cable %4</nobr></source> + <comment>Network adapters tooltip</comment> + <translation><br><nobr><b>Plokštė %1 (%2)</b>: %3 kabelis %4</nobr></translation> + </message> + <message> + <source>connected</source> + <comment>Network adapters tooltip +</comment> + <translation>prijungtas</translation> + </message> + <message> + <source>disconnected</source> + <comment>Network adapters tooltip +</comment> + <translation>atjungtas</translation> + </message> + <message> + <source><br><nobr><b>All network adapters are disabled</b></nobr></source> + <comment>Network adapters tooltip +</comment> + <translation><br><nobr><b>Nėra aktyvių tinklo plokščių</b></nobr></translation> + </message> + <message> + <source><p style='white-space:pre'><nobr>Indicates the activity of the attached USB devices:</nobr>%1</p></source> + <comment>USB device tooltip +</comment> + <translation><p style='white-space:pre'><nobr>Rodo prijungtų USB įrenginių aktyvumą:</nobr>%1</p></translation> + </message> + <message> + <source><br><nobr><b>No USB devices attached</b></nobr></source> + <comment>USB device tooltip +</comment> + <translation><br><nobr><b>Neprijungtas joks USB įrenginys</b></nobr></translation> + </message> + <message> + <source><br><nobr><b>USB Controller is disabled</b></nobr></source> + <comment>USB device tooltip +</comment> + <translation><br><nobr><b>USB valdiklis uždraustas</b></nobr></translation> + </message> + <message> + <source><p style='white-space:pre'><nobr>Indicates the activity of the machine's shared folders:</nobr>%1</p></source> + <comment>Shared folders tooltip +</comment> + <translation><p style='white-space:pre'><nobr>Rodo bendrųjų aplankų aktyvumą:</nobr>%1</p></translation> + </message> + <message> + <source><br><nobr><b>No shared folders</b></nobr></source> + <comment>Shared folders tooltip +</comment> + <translation><br><nobr><b>Bendrųjų aplankų nėra</b></br></translation> + </message> + <message> + <source>Indicates whether the Remote Display (VRDP Server) is enabled (<img src=:/vrdp_16px.png/>) or not (<img src=:/vrdp_disabled_16px.png/>).</source> + <translation>Rodo, ar nuotolinis ekranas (VRDP serveris) yra įgalintas (<img src=:/vrdp_16px.png/>), ar uždraustas (<img src=:/vrdp_disabled_16px.png/>).</translation> + </message> + <message> + <source><hr>The VRDP Server is listening on port %1</source> + <translation><hr>VRDP serveris naujasi prievadu %1</translation> + </message> + <message> + <source>Indicates the status of the hardware virtualization features used by this virtual machine:<br><nobr><b>%1:</b>&nbsp;%2</nobr><br><nobr><b>%3:</b>&nbsp;%4</nobr></source> + <comment>Virtualization Stuff LED +</comment> + <translation>Rodo virtualizavimo procesoriaus būseną: <br><nobr><b>%1 :</b>&nbsp;%2</nobr><br><nobr><b>%3 :</b>&nbsp;%4</nobr></translation> + </message> + <message> + <source><br><nobr><b>%1:</b>&nbsp;%2</nobr></source> + <comment>Virtualization Stuff LED +</comment> + <translation><br><nobr><b>%1 :</b>&nbsp;%2</nobr></translation> + </message> + <message> + <source>Indicates whether the host mouse pointer is captured by the guest OS:<br><nobr><img src=:/mouse_disabled_16px.png/>&nbsp;&nbsp;pointer is not captured</nobr><br><nobr><img src=:/mouse_16px.png/>&nbsp;&nbsp;pointer is captured</nobr><br><nobr><img src=:/mouse_seamless_16px.png/>&nbsp;&nbsp;mouse integration (MI) is On</nobr><br><nobr><img src=:/mouse_can_seamless_16px.png/>&nbsp;&nbsp;MI is Off, pointer is captured</nobr><br><nobr><img src=:/mouse_can_seamless_uncaptured_16px.png/>&nbsp;&nbsp;MI is Off, pointer is not captured</nobr><br>Note that the mouse integration feature requires Guest Additions to be installed in the guest OS.</source> + <translation>Rodo, ar svečio OS reaguoja į pelės žymeklį:<br><nobr><img src=:/mouse_disabled_16px.png/>&nbsp;&nbsp;nereaguojama</nobr><br><nobr><img src=:/mouse_16px.png/>&nbsp;&nbsp;reaguojama</nobr><br><nobr><img src=:/mouse_seamless_16px.png/>&nbsp;&nbsp;pelės integravimo paslauga įjungta</nobr><br><nobr><img src=:/mouse_can_seamless_16px.png/>&nbsp;&nbsp;pelės integravimas išjungtas, į žymeklį reaguojama</nobr><br><nobr><img src=:/mouse_can_seamless_uncaptured_16px.png/>&nbsp;&nbsp;pelės integravimas išjungtas, į žymeklį nereaguojama</nobr><br>Pastaba: pelės integravimo paslauga galima tik virtualioje svečio OS įdiegus „Svečio papildinius“.</translation> + </message> + <message> + <source>Indicates whether the keyboard is captured by the guest OS (<img src=:/hostkey_captured_16px.png/>) or not (<img src=:/hostkey_16px.png/>).</source> + <translation>Rodo, ar svečio OS klaviatūros įvestį priima (<img src=:/hostkey_captured_16px.png/>) ar nepriima (<img src=:/hostkey_16px.png/>).</translation> + </message> +</context> +<context> + <name>UIMachineLogic</name> + <message> + <source>VirtualBox OSE</source> + <translation>VirtualBox OSE</translation> + </message> + <message> + <source> EXPERIMENTAL build %1r%2 - %3</source> + <translation> EKSPERIMENTINĖ kompiliacija %1r%2 - %3</translation> + </message> + <message> + <source>Preview Monitor %1</source> + <translation>Vaizduoklio peržiūra %1</translation> + </message> + <message> + <source>Snapshot %1</source> + <translation>Momentinė kopija Nr. %1</translation> + </message> + <message> + <source>More CD/DVD Images...</source> + <translation>Daugiau CD/DVD atvaizdų...</translation> + </message> + <message> + <source>Unmount CD/DVD Device</source> + <translation>Atjungti CD/DVD įrenginį</translation> + </message> + <message> + <source>More Floppy Images...</source> + <translation>Daugiau diskelių atvaizdų...</translation> + </message> + <message> + <source>Unmount Floppy Device</source> + <translation>Atjungti diskelių įrenginį</translation> + </message> + <message> + <source>No CD/DVD Devices Attached</source> + <translation>Neprijungtas joks CD/DVD</translation> + </message> + <message> + <source>No CD/DVD devices attached to that VM</source> + <translation>Prie šios VM neprijungtas joks CD/DVD</translation> + </message> + <message> + <source>No Floppy Devices Attached</source> + <translation>Neprijungtas joks diskelių įrenginys</translation> + </message> + <message> + <source>No floppy devices attached to that VM</source> + <translation>Prie šios VM neprijungtas joks diskelis</translation> + </message> + <message> + <source>No USB Devices Connected</source> + <translation>Neprijungtas joks USB įrenginys</translation> + </message> + <message> + <source>No supported devices connected to the host PC</source> + <translation>Prie kompiuterio nėra prijungtų palaikomų įrenginių</translation> + </message> +</context> +<context> + <name>UIMachineWindowNormal</name> + <message> + <source>Shows the currently assigned Host key.<br>This key, when pressed alone, toggles the keyboard and mouse capture state. It can also be used in combination with other keys to quickly perform actions from the main menu.</source> + <translation>Rodo pasirinktą pagrindinį klavišą. <br>Pavieniui nuspaustas, šis klavišas perjungia įvedimo klaviatūra veikseną. Jis taip pat gali būti naudojamas kartu su kitais klavišais norint greitai įvykdyti pagrindinio meniu komandas.</translation> + </message> +</context> +<context> + <name>UIMiniProcessWidgetAdditions</name> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>Cancel the VirtualBox Guest Additions CD image download</source> + <translation>Atšaukti „VirtualBox svečio papildinių“ CD atvaizdo parsiuntimą</translation> + </message> + <message> + <source>Downloading the VirtualBox Guest Additions CD image from <nobr><b>%1</b>...</nobr></source> + <translation>Parsiunčiamas „VirtualBox svečio papildinių“ CD atvaizdas iš <nobr><b>%1</b>...</nobr></translation> + </message> +</context> +<context> + <name>UIMiniProcessWidgetUserManual</name> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>Cancel the VirtualBox User Manual download</source> + <translation>Atšaukti VirtualBox naudotojo žinyno parsiuntimą</translation> + </message> + <message> + <source>Downloading the VirtualBox User Manual</source> + <translation>Pasiunčiamas VirtualBox naudotojo žinynas</translation> + </message> + <message> + <source>Downloading the VirtualBox User Manual <nobr><b>%1</b>...</nobr></source> + <translation>Pasiunčiamas VirtualBox naudotojo žinynas <nobr><b>%1</b>...</nobr></translation> + </message> +</context> +<context> + <name>UIMultiScreenLayout</name> + <message> + <source>Virtual Screen %1</source> + <translation>Virtualus ekranas %1</translation> + </message> + <message> + <source>Use Host Screen %1</source> + <translation>Naudoti pagrindinio kompiuterio ekraną %1</translation> + </message> +</context> +<context> + <name>UINewHDWzd</name> + <message> + <source>Create New Virtual Disk</source> + <translation>Sukurti naują virtualų diską</translation> + </message> +</context> +<context> + <name>UINewHDWzdPage1</name> + <message> + <source>Welcome to the Create New Virtual Disk Wizard!</source> + <translation>Jus sveikina naujo virtulaus disko kūrimo vediklis!</translation> + </message> + <message> + <source><p>This wizard will help you to create a new virtual hard disk for your virtual machine.</p><p>%1</p></source> + <translation><p>Šis vediklis padės sukurti naują virtualų standųjį diską virtualiai mašinai.</p><p>%1</p></translation> + </message> +</context> +<context> + <name>UINewHDWzdPage2</name> + <message> + <source><p>Select the type of virtual hard disk you want to create.</p><p>A <b>dynamically expanding storage</b> initially occupies a very small amount of space on your physical hard disk. It will grow dynamically (up to the size specified) as the Guest OS claims disk space.</p><p>A <b>fixed-size storage</b> does not grow. It is stored in a file of approximately the same size as the size of the virtual hard disk. The creation of a fixed-size storage may take a long time depending on the storage size and the write performance of your harddisk.</p></source> + <translation><p>Pasirinkite norimo sukurti virtualaus standžiojo disko tipą.</p><p><b>Dinamiško dydžio disko atvaizdas</b> iš pradžių užima ypač mažai vietos fiziniame Jūsų kompiuteryje. Jis didėja dinamiškai (iki tam tikro nurodyto dydžio) pagal svečio operacinės sistemos disko poreikius.</p><p><b>Pastovaus dydžio disko atvaizdas</b> yra nekintamo dydžio. Jo rinkmena užima maždaug tiek vietos, kiek virtualus standusis diskas. Priklausomai nuo pasirinkto dydžio ir jūsų kompiuterio rašymo greičio, pastovaus dydžio disko kūrimas gali užtrukti ilgai.</p></translation> + </message> + <message> + <source>Storage Type</source> + <translation>Kaupiklio tipas</translation> + </message> + <message> + <source>&Dynamically expanding storage</source> + <translation>&Dinamiško dydžio disko atvaizdas</translation> + </message> + <message> + <source>&Fixed-size storage</source> + <translation>&Pastovaus dydžio disko atvaizdas</translation> + </message> + <message> + <source>Hard Disk Storage Type</source> + <translation>Standžiojo disko kaupiklio tipas</translation> + </message> +</context> +<context> + <name>UINewHDWzdPage3</name> + <message> + <source><p>Press the <b>Select</b> button to select the location of a file to store the hard disk data or type a file name in the entry field.</p></source> + <translation><p>Norėdami nurodyti rinkmenos, kurioje bus laikomi virtualaus standžiojo disko duomenys, vietą, spauskite <b>Pasirinkti</b> arba įveskite rinkmenos pavadinimą laukelyje.</p></translation> + </message> + <message> + <source>&Location</source> + <translation>&Vieta</translation> + </message> + <message> + <source><p>Select the size of the virtual hard disk in megabytes. This size will be reported to the Guest OS as the maximum size of this hard disk.</p></source> + <translation><p>Nurodykite virtualaus standžiojo disko dydį megabaitais. Šis dydis svečio operacinėje sistemoje bus rodomas kaip didžiausias standžiojo disko dydis.</p></translation> + </message> + <message> + <source>&Size</source> + <translation>&Dydis</translation> + </message> + <message> + <source>Virtual Disk Location and Size</source> + <translation>Virtualaus disko vieta ir dydis</translation> + </message> + <message> + <source>Select a file for the new hard disk image file</source> + <translation>Pasirinkite rinkmeną naujo standžiojo disko atvaizdui</translation> + </message> + <message> + <source>Hard disk images (*.vdi)</source> + <translation>Standžiųjų diskų atvaizdai (*.vdi)</translation> + </message> + <message> + <source><nobr>%1 (%2 B)</nobr></source> + <translation><nobr>%1 (%2 B)</nobr></translation> + </message> +</context> +<context> + <name>UINewHDWzdPage4</name> + <message> + <source>You are going to create a new virtual hard disk with the following parameters:</source> + <translation>Netrukus pradėsime kurti naują virtualų standųjį diską tokiomis savybėmis:</translation> + </message> + <message> + <source>Summary</source> + <translation>Santrauka</translation> + </message> + <message> + <source>%1 B</source> + <translation>%1 B</translation> + </message> + <message> + <source>Type</source> + <comment>summary +</comment> + <translation>Tipas</translation> + </message> + <message> + <source>Location</source> + <comment>summary +</comment> + <translation>Vieta</translation> + </message> + <message> + <source>Size</source> + <comment>summary +</comment> + <translation>Dydis</translation> + </message> + <message> + <source>If the above settings are correct, press the <b>%1</b> button. Once you press it, a new hard disk will be created.</source> + <translation>Jei aukščiau esančios nuostatos tinkamos, spauskite mygtuką <b>%1</b>. Tuomet bus sukurtas naujas standusis diskas.</translation> + </message> +</context> +<context> + <name>UINewVMWzd</name> + <message> + <source>Create New Virtual Machine</source> + <translation>Sukurti naują virtualią mašiną</translation> + </message> +</context> +<context> + <name>UINewVMWzdPage1</name> + <message> + <source>Welcome to the New Virtual Machine Wizard!</source> + <translation>Jus sveikina naujos virtualios mašinos kūrimo vediklis!</translation> + </message> + <message> + <source><p>This wizard will guide you through the steps that are necessary to create a new virtual machine for VirtualBox.</p><p>%1</p></source> + <translation><p>Šis vediklis padės sukurti naują virtualią mašina su VirtualBox.</p><p>%1</p></translation> + </message> +</context> +<context> + <name>UINewVMWzdPage2</name> + <message> + <source><p>Enter a name for the new virtual machine and select the type of the guest operating system you plan to install onto the virtual machine.</p><p>The name of the virtual machine usually indicates its software and hardware configuration. It will be used by all VirtualBox components to identify your virtual machine.</p></source> + <translation><p>Pavadinkite naują virtualią mašiną ir pasirinkite svečio operacinės sistemos tipą, kurį ketinate įdiegti šioje mašinoje.</p><p>Virtualios mašinos pavadinimas paprastai nurodo joje esančią programinę įrangą ir aparatinės įrangos konfigūraciją. VirtualBox elementai pavadinimą naudos šios virtualios mašinos identifikavimui.</p></translation> + </message> + <message> + <source>N&ame</source> + <translation>&Pavadinimas</translation> + </message> + <message> + <source>OS &Type</source> + <translation>OS &tipas</translation> + </message> + <message> + <source>VM Name and OS Type</source> + <translation>Virtualios mašinos pavadinimas ir operacinės sistemos tipas</translation> + </message> +</context> +<context> + <name>UINewVMWzdPage3</name> + <message> + <source><p>Select the amount of base memory (RAM) in megabytes to be allocated to the virtual machine.</p></source> + <translation><p>Nurodykite laisvosios prieigos atminties (RAM) kiekį megabaitais, kurį gali išnaudoti virtuali mašina.</p></translation> + </message> + <message> + <source>Base &Memory Size</source> + <translation>Laisvosios prieigos &atminties dydis</translation> + </message> + <message> + <source>MB</source> + <translation>MB</translation> + </message> + <message> + <source>Memory</source> + <translation>Atmintis</translation> + </message> + <message> + <source>The recommended base memory size is <b>%1</b> MB.</source> + <translation>Patariama laisvosios prieigos atminčiai paskirti <b>%1</b> MB.</translation> + </message> + <message> + <source>MB</source> + <comment>size suffix MBytes=1024 KBytes +</comment> + <translation>MB</translation> + </message> +</context> +<context> + <name>UINewVMWzdPage4</name> + <message> + <source><p>Select a hard disk image to be used as the boot hard disk of the virtual machine. You can either create a new hard disk using the <b>New</b> button or select an existing hard disk image from the drop-down list or by pressing the <b>Existing</b> button (to invoke the Virtual Media Manager dialog).</p><p>If you need a more complicated hard disk setup, you can also skip this step and attach hard disks later using the VM Settings dialog.</p></source> + <translation><p>Pasirinkite standžiojo diko atvaizdą, naudotiną kaip virtualios mašinos įkrovos standųjį diską. Galite arba sukurti naują diską nuspaudę <b>Naujas</b>, arba pasirinkite jau sukurtąjį iš išskleidžiamojo meniu nuspaudę <b>Esamas</b> (atsivers virtualių laikmenų tvarkytuvė).</p><p>Jei norite sudėtingesnės disko konfigūracijos, galite praleisti šį etapą – standųjį diską pridėsite vėliau per šios virtualios mašinos nuostatas.</p></translation> + </message> + <message> + <source>&Create new hard disk</source> + <translation>&Sukurti naują virtualų diską</translation> + </message> + <message> + <source>&Use existing hard disk</source> + <translation>&Naudoti esamą standųjį diską</translation> + </message> + <message> + <source>Virtual Hard Disk</source> + <translation>Virtualus standusis diskas</translation> + </message> + <message> + <source>The recommended size of the boot hard disk is <b>%1</b> MB.</source> + <translation>Įkraunamam standžiajam diskui patariama paskirti <b>%1</b> MB.</translation> + </message> + <message> + <source>Boot Hard &Disk</source> + <translation>Įkraunamas standusis &diskas</translation> + </message> +</context> +<context> + <name>UINewVMWzdPage5</name> + <message> + <source><p>You are going to create a new virtual machine with the following parameters:</p></source> + <translation><p>Ketinate sukurti naują virtualią mašiną, turinčią šias savybes:</p></translation> + </message> + <message> + <source>Summary</source> + <translation>Santrauka</translation> + </message> + <message> + <source>Name</source> + <comment>summary +</comment> + <translation>Pavadinimas</translation> + </message> + <message> + <source>OS Type</source> + <comment>summary +</comment> + <translation>OS tipas</translation> + </message> + <message> + <source>Base Memory</source> + <comment>summary +</comment> + <translation>Pagrindinė atmintis</translation> + </message> + <message> + <source>MB</source> + <comment>size suffix MBytes=1024KBytes +</comment> + <translation>MB</translation> + </message> + <message> + <source>Boot Hard Disk</source> + <comment>summary +</comment> + <translation>Įkraunamas standusis diskas</translation> + </message> + <message> + <source><p>If the above is correct press the <b>%1</b> button. Once you press it, a new virtual machine will be created. </p><p>Note that you can alter these and all other setting of the created virtual machine at any time using the <b>Settings</b> dialog accessible through the menu of the main window.</p></source> + <translation><p>Jei aukščiau esantys duomenys tinka, spauskite <b>%1</b>. Tuomet bus sukurta nauja virtuali mašina.</p><p>Atminkite, kad šiuos parametrus bet kada galėsite pakeisti. Tam pagrindiniame lange nuspauskite mygtuką <b>Nuostatos</b> arba atitinkamą meniu punktą.</p></translation> + </message> +</context> +<context> + <name>VBoxAboutDlg</name> + <message> + <source>VirtualBox - About</source> + <translation>Apie VirtualBox</translation> + </message> + <message> + <source>VirtualBox Graphical User Interface</source> + <translation>VirtualBox naudotojo sąsajos</translation> + </message> + <message> + <source>Version %1</source> + <translation>versija %1</translation> + </message> +</context> +<context> + <name>VBoxApplianceEditorWgt</name> + <message> + <source>Virtual System %1</source> + <translation>%1 virtuali sistema</translation> + </message> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> + <source>Product</source> + <translation>Produktas</translation> + </message> + <message> + <source>Product-URL</source> + <translation>Produkto URL adresas</translation> + </message> + <message> + <source>Vendor</source> + <translation>Gamintojas</translation> + </message> + <message> + <source>Vendor-URL</source> + <translation>Gamintojo URL adresas</translation> + </message> + <message> + <source>Version</source> + <translation>Versija</translation> + </message> + <message> + <source>Description</source> + <translation>Aprašymas</translation> + </message> + <message> + <source>License</source> + <translation>Licencija</translation> + </message> + <message> + <source>Guest OS Type</source> + <translation>Svečio OS tipas</translation> + </message> + <message> + <source>CPU</source> + <translation>Procesorius</translation> + </message> + <message> + <source>RAM</source> + <translation>Laisvosios prieigos atmintis (RAM)</translation> + </message> + <message> + <source>Hard Disk Controller (IDE)</source> + <translation>Standžiojo disko valdiklis (IDE)</translation> + </message> + <message> + <source>Hard Disk Controller (SATA)</source> + <translation>Standžiojo disko valdiklis (SATA)</translation> + </message> + <message> + <source>Hard Disk Controller (SCSI)</source> + <translation>Standžiojo disko valdiklis (SCSI)</translation> + </message> + <message> + <source>DVD</source> + <translation>DVD</translation> + </message> + <message> + <source>Floppy</source> + <translation>Diskelis</translation> + </message> + <message> + <source>Network Adapter</source> + <translation>Tinklo plokštė</translation> + </message> + <message> + <source>USB Controller</source> + <translation>USB valdiklis</translation> + </message> + <message> + <source>Sound Card</source> + <translation>Garso plokštė</translation> + </message> + <message> + <source>Virtual Disk Image</source> + <translation>Virtualaus disko atvaizdas</translation> + </message> + <message> + <source>Unknown Hardware Item</source> + <translation>Nežinomas elementas</translation> + </message> + <message> + <source><b>Original Value:</b> %1</source> + <translation><b>Originali reikšmė:</b> %1</translation> + </message> + <message> + <source>Configuration</source> + <translation>Konfigūracija</translation> + </message> + <message> + <source>Warnings:</source> + <translation>Įspėjimai:</translation> + </message> + <message> + <source>MB</source> + <comment>size suffix MBytes=1024 KBytes +</comment> + <translation>MB</translation> + </message> + <message> + <source>Hard Disk Controller (SAS)</source> + <translation>Standžiojo disko valdiklis (SAS)</translation> + </message> +</context> +<context> + <name>VBoxCloseVMDlg</name> + <message> + <source>Close Virtual Machine</source> + <translation>Užverti virtualią mašiną</translation> + </message> + <message> + <source>You want to:</source> + <translation>Norite:</translation> + </message> + <message> + <source>&Save the machine state</source> + <translation>&Išsaugoti mašinos būseną</translation> + </message> + <message> + <source>&Power off the machine</source> + <translation>&Išjungti mašiną</translation> + </message> + <message> + <source>S&end the shutdown signal</source> + <translation>&Siųsti signalą išsijungimui</translation> + </message> + <message> + <source><p>When checked, the machine will be returned to the state stored in the current snapshot after it is turned off. This is useful if you are sure that you want to discard the results of your last sessions and start again at that snapshot.</p></source> + <translation><p>Pasirinkus, po mašinos išjungimo ji grįš į momentinėje kopijoje išsaugotą būvį. Ši funkcija naudinga, kai tikrai norite atsisakyti visų šioje sesijoje atliktų pakeitimų ir norite iš naujo paleisti anksčiau išsaugotą būvį.</p></translation> + </message> + <message> + <source><p>Saves the current execution state of the virtual machine to the physical hard disk of the host PC.</p><p>Next time this machine is started, it will be restored from the saved state and continue execution from the same place you saved it at, which will let you continue your work immediately.</p><p>Note that saving the machine state may take a long time, depending on the guest operating system type and the amount of memory you assigned to the virtual machine.</p></source> + <translation><p>Virtualios mašinos dabartinį būvį įrašo į pagrindinio kompiuterio standųjį diską.</p><p>Sekantį kartą paleidus mašiną, bus atkurtas išsaugotasis būvis, mašina toliau veiks nuo tos vietos, kurioje ją buvote sustabdę.</p><p>Atminkite, kad būvio išsaugojimo procesas gali užtrukti ilgai; tai priklauso nuo svečio operacinės sistemos tipo, virtualiai mašinai priskirtos atminties kiekio.</p></translation> + </message> + <message> + <source><p>Sends the ACPI Power Button press event to the virtual machine.</p><p>Normally, the guest operating system running inside the virtual machine will detect this event and perform a clean shutdown procedure. This is a recommended way to turn off the virtual machine because all applications running inside it will get a chance to save their data and state.</p><p>If the machine doesn't respond to this action then the guest operating system may be misconfigured or doesn't understand ACPI Power Button events at all. In this case you should select the <b>Power off the machine</b> action to stop virtual machine execution.</p></source> + <translation><p>Virtualioje mašinoje nuspaudžia ACPI kompiuterio išjungimo mygtuką.</p><p>Paprastai virtualioje mašinoje esanti svečio operacinė sistema sureaguoja į šį veiksmą ir pradeda pati išsijunginėti. Būtent šiuo būdu ir patariama išjungti virtualią mašiną, kadangi joje veikiančios programos gali spėti išsaugoti savo duomenis ir būsenas.</p><p>Jei mašina nereaguoja į šį veiksmą, galbūt svečio operacinė sistema nėra tinkamai sukonfigūruota arba apskritai nesupranta ACPI kompiuterio išjungimo mygtuko nuspaudimo. Tokiu galite <b>Išjungti mašiną</b>.</p></translation> + </message> + <message> + <source><p>Turns off the virtual machine.</p><p>Note that this action will stop machine execution immediately so that the guest operating system running inside it will not be able to perform a clean shutdown procedure which may result in <i>data loss</i> inside the virtual machine. Selecting this action is recommended only if the virtual machine does not respond to the <b>Send the shutdown signal</b> action.</p></source> + <translation><p>Išjungia virtualią mašiną.</p><p>Atminkite, kad išjungdami staigiai sustabdysite mašinos darbą, tad joje esanti operacinė sistema negalės deramai išsijungti, tad virtualioje mašinoje galite <i>prarasti duomenis</i>. Šį veiksmą rinktis patariama tik jei virtuali mašina nereaguoja įvydžius <b>Siųsti signalą išsijungimui</b>.</p></translation> + </message> + <message> + <source>Restore the machine state stored in the current snapshot</source> + <translation>Atkurti virtualios mašinos būseną iš momentinio būvio kopijos</translation> + </message> + <message> + <source>&Restore current snapshot '%1'</source> + <translation>&Atkurti dabartinį momentinį būvį „%1“</translation> + </message> +</context> +<context> + <name>VBoxEmptyFileSelector</name> + <message> + <source>&Choose...</source> + <translation>&Pasirinkti...</translation> + </message> +</context> +<context> + <name>VBoxFilePathSelectorWidget</name> + <message> + <source><reset to default></source> + <translation><numatyta></translation> + </message> + <message> + <source>The actual default path value will be displayed after accepting the changes and opening this dialog again.</source> + <translation>Pasirinkus, patvirtinus pasirinkimą ir iš naujo atvėrus šį langą, matysite numatytąjį kelią.</translation> + </message> + <message> + <source><not selected></source> + <translation><nepasirinkta></translation> + </message> + <message> + <source>Please use the <b>Other...</b> item from the drop-down list to select a path.</source> + <translation>Norėdami pasirinkti kelią, iš išskleidžiamojo sąrašo rinkitės <b>Kita...</b>.</translation> + </message> + <message> + <source>Other...</source> + <translation>Kita...</translation> + </message> + <message> + <source>Reset</source> + <translation>Numatyta</translation> + </message> + <message> + <source>Opens a dialog to select a different folder.</source> + <translation>Atveriamas langas kitokio aplanko pasirinkimui.</translation> + </message> + <message> + <source>Resets the folder path to the default value.</source> + <translation>Atstato numatytąjį aplanko kelią.</translation> + </message> + <message> + <source>Opens a dialog to select a different file.</source> + <translation>Atveriamas langas kitokios rinkmenos pasirinkimui.</translation> + </message> + <message> + <source>Resets the file path to the default value.</source> + <translation>Atstato numatytąjį rinkmenos kelią.</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Kopijuoti</translation> + </message> + <message> + <source>Please type the folder path here.</source> + <translation>Įrašykite aplanko kelią.</translation> + </message> + <message> + <source>Please type the file path here.</source> + <translation>Įrašykite rinkmenos kelią.</translation> + </message> +</context> +<context> + <name>VBoxGLSettingsDlg</name> + <message> + <source>General</source> + <translation>Bendra</translation> + </message> + <message> + <source>Input</source> + <translation>Įvestis</translation> + </message> + <message> + <source>Update</source> + <translation>Atnaujinimas</translation> + </message> + <message> + <source>Language</source> + <translation>Kalba</translation> + </message> + <message> + <source>USB</source> + <translation>USB</translation> + </message> + <message> + <source>VirtualBox - %1</source> + <translation>VirtualBox - %1</translation> + </message> + <message> + <source>Network</source> + <translation>Tinklas</translation> + </message> +</context> +<context> + <name>VBoxGLSettingsGeneral</name> + <message> + <source>Displays the path to the default virtual machine folder. This folder is used, if not explicitly specified otherwise, when creating new virtual machines.</source> + <translation>Rodo kelią iki numatytojo virtualios mašinos aplanko. Šis aplankas naudojamas, jei kuriant naują virtualią mašiną nenurodomas joks kitas.</translation> + </message> + <message> + <source>Displays the path to the library that provides authentication for Remote Display (VRDP) clients.</source> + <translation>Rodo kelią iki bibliotekos, kuri pateikia nuotolinio ekrano (VRDP) klientų atpažinimo funkciją.</translation> + </message> + <message> + <source>Default &Hard Disk Folder:</source> + <translation>Numatytasis &standžiųjų diskų aplankas:</translation> + </message> + <message> + <source>Default &Machine Folder:</source> + <translation>Numatytasis &mašinos aplankas:</translation> + </message> + <message> + <source>V&RDP Authentication Library:</source> + <translation>V&RDP atpažinimo biblioteka:</translation> + </message> + <message> + <source>Displays the path to the default hard disk folder. This folder is used, if not explicitly specified otherwise, when adding existing or creating new virtual hard disks.</source> + <translation>Rodo kelią iki numatytojo standžiųjų diskų aplanko. Šis aplankas naudojamas, jei kuriant naują ar pridedant esantį virtualų diską nenurodomas joks kitas.</translation> + </message> + <message> + <source>When checked, the application will provide an icon with the context menu in the system tray.</source> + <translation>Pasirinkus, sistemos dėkle bus rodomas programos ženkliukas.</translation> + </message> + <message> + <source>&Show System Tray Icon</source> + <translation>&Rodyti ženkliuką sistemos dėkle</translation> + </message> + <message> + <source>&Auto show Dock and Menubar in fullscreen</source> + <translation>Viso ekrano veiksenoje &automatiškai rodyti sistemos dėklą ir meniu juostą</translation> + </message> +</context> +<context> + <name>VBoxGLSettingsInput</name> + <message> + <source>Host &Key:</source> + <translation>Pagrindinis &klavišas:</translation> + </message> + <message> + <source>Displays the key used as a Host Key in the VM window. Activate the entry field and press a new Host Key. Note that alphanumeric, cursor movement and editing keys cannot be used.</source> + <translation>Rodo klavišą, naudojamą kaip pagrindinio kompiuterio klavišą virtualioje mašinoje. Nuspauskite įvesties laukelį ir nuspauskite būsimą „pagrindinį“ klavišą. Atminkite, kad negalima priskirti raidių, skaičių, žymeklio perkėlimo, redagavimo klavišų.</translation> + </message> + <message> + <source>When checked, the keyboard is automatically captured every time the VM window is activated. When the keyboard is captured, all keystrokes (including system ones like Alt-Tab) are directed to the VM.</source> + <translation>Jei pasirinkta, virtuali mašina į klaviatūrą ims reaguoti kaskart, kai tos VM langas tampa aktyvus. Tuomet virtuali mašina tiesiogiai reaguoja į daugelį sparčiųjų klavišų (taip pat ir į Alt+Tab).</translation> + </message> + <message> + <source>&Auto Capture Keyboard</source> + <translation>&Automatiškai reaguoti į klaviatūrą</translation> + </message> + <message> + <source>Reset Host Key</source> + <translation>Atstatyti pagrindinį klavišą</translation> + </message> + <message> + <source>Resets the key used as a Host Key in the VM window.</source> + <translation>Pagrindinį klavišą atstato į numatytą.</translation> + </message> +</context> +<context> + <name>VBoxGLSettingsLanguage</name> + <message> + <source> (built-in)</source> + <comment>Language +</comment> + <translation> (standartinė)</translation> + </message> + <message> + <source><unavailable></source> + <comment>Language +</comment> + <translation><neprieinama></translation> + </message> + <message> + <source><unknown></source> + <comment>Author(s) +</comment> + <translation><nežinoma></translation> + </message> + <message> + <source>Default</source> + <comment>Language +</comment> + <translation>Numatytoji</translation> + </message> + <message> + <source>Language:</source> + <translation>Kalba: </translation> + </message> + <message> + <source>&Interface Language:</source> + <translation>&Sąsajos kalba:</translation> + </message> + <message> + <source>Lists all available user interface languages. The effective language is written in <b>bold</b>. Select <i>Default</i> to reset to the system default language.</source> + <translation>Naudotojo sąsajos galimų kalbų sąrašas. Šiuo metu naudojama kalba yra <b>paryškinta</b>. Pasirinkite <i>Numatytąją</i>, jei norite naudoti sistemos pagrindinę kalbą.</translation> + </message> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> + <source>Id</source> + <translation>Identificatorius</translation> + </message> + <message> + <source>Language</source> + <translation>Kalba</translation> + </message> + <message> + <source>Author</source> + <translation>Autorius</translation> + </message> + <message> + <source>Author(s):</source> + <translation>Autorius(-iai): </translation> + </message> +</context> +<context> + <name>VBoxGLSettingsNetwork</name> + <message> + <source>%1 network</source> + <comment><adapter name> network +</comment> + <translation>%1 tinklas</translation> + </message> + <message> + <source>host IPv4 address of <b>%1</b> is wrong</source> + <translation>pagrindinio kompiuterio IPv4 adresas<b>%1</b> yra netinkamas</translation> + </message> + <message> + <source>host IPv4 network mask of <b>%1</b> is wrong</source> + <translation>pagrindinio kompiuterio IPv4 tinklo kaukė <b>%1</b> yra netinkama</translation> + </message> + <message> + <source>host IPv6 address of <b>%1</b> is wrong</source> + <translation>pagrindinio kompiuterio IPv6 adresas<b>%1</b> yra netinkamas</translation> + </message> + <message> + <source>DHCP server address of <b>%1</b> is wrong</source> + <translation>DHCP serverio adresas<b>%1</b> yra netinkamas</translation> + </message> + <message> + <source>DHCP server network mask of <b>%1</b> is wrong</source> + <translation>DHCP serverio tinklo kaukė <b>%1</b> yra netinkama</translation> + </message> + <message> + <source>DHCP lower address bound of <b>%1</b> is wrong</source> + <translation>DHCP serverio adreso apatinė riba <b>%1</b> yra netinkama</translation> + </message> + <message> + <source>DHCP upper address bound of <b>%1</b> is wrong</source> + <translation>DHCP serverio adreso viršutinė riba <b>%1</b> yra netinkama</translation> + </message> + <message> + <source>Adapter</source> + <translation>Plokštė</translation> + </message> + <message> + <source>Automatically configured</source> + <comment>interface +</comment> + <translation>Automatinė konfigūracija</translation> + </message> + <message> + <source>Manually configured</source> + <comment>interface +</comment> + <translation>Rankinė konfigūracija</translation> + </message> + <message> + <source>IPv4 Address</source> + <translation>IPv4 adresas</translation> + </message> + <message> + <source>Not set</source> + <comment>address +</comment> + <translation>nesukonfigūruota</translation> + </message> + <message> + <source>IPv4 Network Mask</source> + <translation>IPv4 tinklo kaukė</translation> + </message> + <message> + <source>Not set</source> + <comment>mask +</comment> + <translation>nesukonfigūruota</translation> + </message> + <message> + <source>IPv6 Address</source> + <translation>IPv6 adresas</translation> + </message> + <message> + <source>IPv6 Network Mask Length</source> + <translation>IPv6 tinklo kaukės ilgis</translation> + </message> + <message> + <source>Not set</source> + <comment>length +</comment> + <translation>nesukonfigūruota</translation> + </message> + <message> + <source>DHCP Server</source> + <translation>DHCP serveris</translation> + </message> + <message> + <source>Enabled</source> + <comment>server +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>server +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Address</source> + <translation>Adresas</translation> + </message> + <message> + <source>Network Mask</source> + <translation>Tinklo kaukė</translation> + </message> + <message> + <source>Lower Bound</source> + <translation>Apatinė riba</translation> + </message> + <message> + <source>Not set</source> + <comment>bound +</comment> + <translation>nesukonfigūruota</translation> + </message> + <message> + <source>Upper Bound</source> + <translation>Viršutinė riba</translation> + </message> + <message> + <source>&Add host-only network</source> + <translation>Pri&dėti tinklą prie pagr. kompiuterio</translation> + </message> + <message> + <source>&Remove host-only network</source> + <translation>&Pašalinti tinklą prie pagr. kompiuterio</translation> + </message> + <message> + <source>&Edit host-only network</source> + <translation>&Keisti tinklą prie pagr. kompiuterio</translation> + </message> + <message> + <source>Performing</source> + <comment>creating/removing host-only network +</comment> + <translation>Vykdoma</translation> + </message> + <message> + <source>&Host-only Networks:</source> + <translation>&Tinklo ryšiai prisijungimui tik prie pagrindinio kompiuterio:</translation> + </message> + <message> + <source>Lists all available host-only networks.</source> + <translation>Pateikia sąrašą visų prieinamų tinklų, kuriais galima prisijungti tik prie pagrindinio kompiuterio.</translation> + </message> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> +</context> +<context> + <name>VBoxGLSettingsNetworkDetails</name> + <message> + <source>Host-only Network Details</source> + <translation>Tik prie pagr. kompiuterio prisijungiančio tinklo detalės</translation> + </message> + <message> + <source>&Adapter</source> + <translation>&Plokštė</translation> + </message> + <message> + <source>Manual &Configuration</source> + <translation>Rankinė &konfigūracija</translation> + </message> + <message> + <source>Use manual configuration for this host-only network adapter.</source> + <translation>Šiam tinklui, prisijunčiam tik prie pagrindinio kompiuterio, naudoti rankinę konfigūraciją.</translation> + </message> + <message> + <source>&IPv4 Address:</source> + <translation>&IPv4 adresas:</translation> + </message> + <message> + <source>Displays the host IPv4 address for this adapter.</source> + <translation>Rodo šio pagrindinio kompiuterio IPv4 adresą šiai plokštei.</translation> + </message> + <message> + <source>IPv4 Network &Mask:</source> + <translation>IPv4 tinklo &kaukė:</translation> + </message> + <message> + <source>Displays the host IPv4 network mask for this adapter.</source> + <translation>Rodo šio pagrindinio kompiuterio IPv4 tinklo kaukę šiai plokštei.</translation> + </message> + <message> + <source>I&Pv6 Address:</source> + <translation>&IPv6 adresas:</translation> + </message> + <message> + <source>Displays the host IPv6 address for this adapter if IPv6 is supported.</source> + <translation>Rodo šio pagrindinio kompiuterio IPv4 adresą šiai plokštei, jei palaikomas +IPv6.</translation> + </message> + <message> + <source>IPv6 Network Mask &Length:</source> + <translation>IPv6 tinklo kaukės i&lgis:</translation> + </message> + <message> + <source>Displays the host IPv6 network mask prefix length for this adapter if IPv6 is supported.</source> + <translation>Rodo šio pagrindinio kompiuterio IPv4 tinklo kaukės prefikso ilgį šiai plokštei, jei palaikomas IPv6.</translation> + </message> + <message> + <source>&DHCP Server</source> + <translation>&DHCP serveris</translation> + </message> + <message> + <source>&Enable Server</source> + <translation>Į&galinti serverį</translation> + </message> + <message> + <source>Indicates whether the DHCP Server is enabled on machine startup or not.</source> + <translation>Rodo, ar mašinos paleidimo metu įgalinamas DHCP serveris.</translation> + </message> + <message> + <source>Server Add&ress:</source> + <translation>Serve&rio adresas:</translation> + </message> + <message> + <source>Displays the address of the DHCP server servicing the network associated with this host-only adapter.</source> + <translation>Rodo adresą to DHCP serverio, kuris aptarnauja tinklą, susijusį su plokšte, kuri gali prisijungti tik prie pagrindinio kompiuterio.</translation> + </message> + <message> + <source>Server &Mask:</source> + <translation>Serverio &kaukė:</translation> + </message> + <message> + <source>Displays the network mask of the DHCP server servicing the network associated with this host-only adapter.</source> + <translation>Rodo tinklo kaukę to DHCP serverio, kuris aptarnauja tinklą, susijusį su plokšte, kuri gali prisijungti tik prie pagrindinio kompiuterio.</translation> + </message> + <message> + <source>&Lower Address Bound:</source> + <translation>Adreso &apatinė riba:</translation> + </message> + <message> + <source>Displays the lower address bound offered by the DHCP server servicing the network associated with this host-only adapter.</source> + <translation>Rodo adreso apatinę ribą to DHCP serverio, kuris aptarnauja tinklą, susijusį su plokšte, kuri gali prisijungti tik prie pagrindinio kompiuterio.</translation> + </message> + <message> + <source>&Upper Address Bound:</source> + <translation>Adreso &viršutinė riba:</translation> + </message> + <message> + <source>Displays the upper address bound offered by the DHCP server servicing the network associated with this host-only adapter.</source> + <translation>Rodo adreso viršutinę ribą to DHCP serverio, kuris aptarnauja tinklą, susijusį su plokšte, kuri gali prisijungti tik prie pagrindinio kompiuterio.</translation> + </message> +</context> +<context> + <name>VBoxGLSettingsUpdate</name> + <message> + <source>When checked, the application will periodically connect to the VirtualBox website and check whether a new VirtualBox version is available.</source> + <translation>Pasirinkus, programa karts nuo karto prisijungs prie VirtualBox svetainės ir tikrins, ar yra naujesnių VirtualBox versijų.</translation> + </message> + <message> + <source>&Check for updates</source> + <translation>&Tikrinti, ar yra atnaujinimų</translation> + </message> + <message> + <source>&Once per:</source> + <translation>&Kas:</translation> + </message> + <message> + <source>Specifies how often the new version check should be performed. Note that if you want to completely disable this check, just clear the above check box.</source> + <translation>Nurodo, kaip dažnai ieškoti naujų versijų. Jei nenorite, kad būtų ieškoma naujų versijų, tiesiog nuimkite varnelę nuo aukščiau esančio langelio.</translation> + </message> + <message> + <source>Next Check:</source> + <translation>Sekantis tikrinimas:</translation> + </message> + <message> + <source>Check for:</source> + <translation>Tikrinti:</translation> + </message> + <message> + <source><p>Choose this if you only wish to be notified about stable updates to VirtualBox.</p></source> + <translation><p>Pasirinkite, jei norite sužinoti tik apie galimas stabilias VirtualBox versijas.</p></translation> + </message> + <message> + <source>&Stable release versions</source> + <translation>&Stabilias versijas</translation> + </message> + <message> + <source><p>Choose this if you wish to be notified about all new VirtualBox releases.</p></source> + <translation><p>Pasirinkite, jei norite sužinoti apie visas naujas VirtualBox versijas.</p></translation> + </message> + <message> + <source>&All new releases</source> + <translation>&Visas naujas versijas</translation> + </message> + <message> + <source><p>Choose this to be notified about all new VirtualBox releases and pre-release versions of VirtualBox.</p></source> + <translation><p>Pasirinkite, jei norite sužinoti apie visas naujas VirtualBox versijas, įskaitant ir eksperimentines.</p></translation> + </message> + <message> + <source>All new releases and &pre-releases</source> + <translation>Visas naujas versijas, įskaitant &eksperimentines</translation> + </message> +</context> +<context> + <name>VBoxGlobal</name> + <message> + <source>Unknown device %1:%2</source> + <comment>USB device details +</comment> + <translation>Nežinomas įrenginys %1:%2</translation> + </message> + <message> + <source><nobr>Vendor ID: %1</nobr><br><nobr>Product ID: %2</nobr><br><nobr>Revision: %3</nobr></source> + <comment>USB device tooltip +</comment> + <translation><nobr>Gamintojo ID: %1</nobr><br><nobr>Produkto ID: %2</nobr><br><nobr>Revizija: %3</nobr></translation> + </message> + <message> + <source><br><nobr>Serial No. %1</nobr></source> + <comment>USB device tooltip +</comment> + <translation><nobr>Serijinis numeris: %1</nobr></translation> + </message> + <message> + <source><br><nobr>State: %1</nobr></source> + <comment>USB device tooltip +</comment> + <translation><nobr>Būsena: %1</nobr></translation> + </message> + <message> + <source>Name</source> + <comment>details report +</comment> + <translation>Pavadinimas</translation> + </message> + <message> + <source>OS Type</source> + <comment>details report +</comment> + <translation>OS tipas</translation> + </message> + <message> + <source>Base Memory</source> + <comment>details report +</comment> + <translation>Pagrindinė atmintis</translation> + </message> + <message> + <source>General</source> + <comment>details report +</comment> + <translation>Bendra</translation> + </message> + <message> + <source>Video Memory</source> + <comment>details report +</comment> + <translation>Vaizdo atmintis</translation> + </message> + <message> + <source>Boot Order</source> + <comment>details report +</comment> + <translation>Įkrovos eiliškumas</translation> + </message> + <message> + <source>ACPI</source> + <comment>details report +</comment> + <translation>ACPI</translation> + </message> + <message> + <source>IO APIC</source> + <comment>details report +</comment> + <translation>IO APIC</translation> + </message> + <message> + <source>Enabled</source> + <comment>details report (ACPI) +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (ACPI) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Enabled</source> + <comment>details report (IO APIC) +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (IO APIC) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (audio) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Audio</source> + <comment>details report +</comment> + <translation>Garsas</translation> + </message> + <message> + <source>Adapter %1</source> + <comment>details report (network) +</comment> + <translation>%1 plokštė</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (network) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Network</source> + <comment>details report +</comment> + <translation>Tinklas</translation> + </message> + <message> + <source>Device Filters</source> + <comment>details report (USB) +</comment> + <translation>Įrenginių filtras</translation> + </message> + <message> + <source>%1 (%2 active)</source> + <comment>details report (USB) +</comment> + <translation>%1 (%2 įgalinta)</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (USB) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Powered Off</source> + <comment>MachineState +</comment> + <translation>Išjungta</translation> + </message> + <message> + <source>Saved</source> + <comment>MachineState +</comment> + <translation>Išsaugota</translation> + </message> + <message> + <source>Aborted</source> + <comment>MachineState +</comment> + <translation>Nutraukta</translation> + </message> + <message> + <source>Running</source> + <comment>MachineState +</comment> + <translation>Veikia</translation> + </message> + <message> + <source>Paused</source> + <comment>MachineState +</comment> + <translation>Pristabdyta</translation> + </message> + <message> + <source>Starting</source> + <comment>MachineState +</comment> + <translation>Paleidžiama</translation> + </message> + <message> + <source>Stopping</source> + <comment>MachineState +</comment> + <translation>Sustabdoma</translation> + </message> + <message> + <source>Saving</source> + <comment>MachineState +</comment> + <translation>Išsaugoma</translation> + </message> + <message> + <source>Restoring</source> + <comment>MachineState +</comment> + <translation>atkuriama</translation> + </message> + <message> + <source>Closed</source> + <comment>SessionState +</comment> + <translation>užverta</translation> + </message> + <message> + <source>Open</source> + <comment>SessionState +</comment> + <translation>atverta</translation> + </message> + <message> + <source>Spawning</source> + <comment>SessionState +</comment> + <translation>įkeliama</translation> + </message> + <message> + <source>Closing</source> + <comment>SessionState +</comment> + <translation>užveriama</translation> + </message> + <message> + <source>None</source> + <comment>DeviceType +</comment> + <translation>Nieko</translation> + </message> + <message> + <source>Floppy</source> + <comment>DeviceType +</comment> + <translation>Diskelis</translation> + </message> + <message> + <source>CD/DVD-ROM</source> + <comment>DeviceType +</comment> + <translation>CD/DVD</translation> + </message> + <message> + <source>Hard Disk</source> + <comment>DeviceType +</comment> + <translation>Standusis diskas</translation> + </message> + <message> + <source>Network</source> + <comment>DeviceType +</comment> + <translation>Tinklas</translation> + </message> + <message> + <source>Normal</source> + <comment>DiskType +</comment> + <translation>Įprastas</translation> + </message> + <message> + <source>Immutable</source> + <comment>DiskType +</comment> + <translation>Nekintamas</translation> + </message> + <message> + <source>Writethrough</source> + <comment>DiskType</comment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Null</source> + <comment>VRDPAuthType +</comment> + <translation>Nėra</translation> + </message> + <message> + <source>External</source> + <comment>VRDPAuthType +</comment> + <translation>Išorinis</translation> + </message> + <message> + <source>Guest</source> + <comment>VRDPAuthType +</comment> + <translation>Klientas</translation> + </message> + <message> + <source>Ignore</source> + <comment>USBFilterActionType +</comment> + <translation>Nepaisyti</translation> + </message> + <message> + <source>Hold</source> + <comment>USBFilterActionType</comment> + <translation>Sulaikyti</translation> + </message> + <message> + <source>Null Audio Driver</source> + <comment>AudioDriverType +</comment> + <translation>Be garso tvarkyklės</translation> + </message> + <message> + <source>Windows Multimedia</source> + <comment>AudioDriverType +</comment> + <translation>Windows daugialypė terpė</translation> + </message> + <message> + <source>OSS Audio Driver</source> + <comment>AudioDriverType +</comment> + <translation>OSS garso tvarkyklė</translation> + </message> + <message> + <source>ALSA Audio Driver</source> + <comment>AudioDriverType +</comment> + <translation>ALSA garso tvarkyklė</translation> + </message> + <message> + <source>Windows DirectSound</source> + <comment>AudioDriverType +</comment> + <translation>Windows DirectSound</translation> + </message> + <message> + <source>CoreAudio</source> + <comment>AudioDriverType</comment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Not attached</source> + <comment>NetworkAttachmentType +</comment> + <translation>Neprijungta</translation> + </message> + <message> + <source>NAT</source> + <comment>NetworkAttachmentType</comment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Internal Network</source> + <comment>NetworkAttachmentType +</comment> + <translation>Vidinis tinklas</translation> + </message> + <message> + <source>Not supported</source> + <comment>USBDeviceState +</comment> + <translation>Nepalaikoma</translation> + </message> + <message> + <source>Unavailable</source> + <comment>USBDeviceState +</comment> + <translation>Neprieinama</translation> + </message> + <message> + <source>Busy</source> + <comment>USBDeviceState +</comment> + <translation>Užimta</translation> + </message> + <message> + <source>Available</source> + <comment>USBDeviceState +</comment> + <translation>Prieinama</translation> + </message> + <message> + <source>Held</source> + <comment>USBDeviceState +</comment> + <translation>Sulaikytas</translation> + </message> + <message> + <source>Captured</source> + <comment>USBDeviceState +</comment> + <translation>Aktyvus</translation> + </message> + <message> + <source>Disabled</source> + <comment>ClipboardType +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Host To Guest</source> + <comment>ClipboardType +</comment> + <translation>Iš kompiuterio į svečią</translation> + </message> + <message> + <source>Guest To Host</source> + <comment>ClipboardType +</comment> + <translation>Iš svečio į kompiuterį</translation> + </message> + <message> + <source>Bidirectional</source> + <comment>ClipboardType +</comment> + <translation>Abikryptis</translation> + </message> + <message> + <source>Port %1</source> + <comment>details report (serial ports) +</comment> + <translation>%1 prievadas</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (serial ports) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Serial Ports</source> + <comment>details report +</comment> + <translation>Nuoseklieji prievadai</translation> + </message> + <message> + <source>USB</source> + <comment>details report +</comment> + <translation>USB</translation> + </message> + <message> + <source>Shared Folders</source> + <comment>details report (shared folders) +</comment> + <translation>Bendrieji aplankai</translation> + </message> + <message> + <source>None</source> + <comment>details report (shared folders) +</comment> + <translation>Nieko</translation> + </message> + <message> + <source>Shared Folders</source> + <comment>details report +</comment> + <translation>Bendrieji aplankai</translation> + </message> + <message> + <source>Disconnected</source> + <comment>PortMode +</comment> + <translation>Atjungta</translation> + </message> + <message> + <source>Host Pipe</source> + <comment>PortMode +</comment> + <translation>Kompiuterio kanalas</translation> + </message> + <message> + <source>Host Device</source> + <comment>PortMode +</comment> + <translation>Kompiuterio įrenginys</translation> + </message> + <message> + <source>User-defined</source> + <comment>serial port +</comment> + <translation>Naudotojo apibrėžtas</translation> + </message> + <message> + <source>VT-x/AMD-V</source> + <comment>details report +</comment> + <translation>VT-x/AMD-V</translation> + </message> + <message> + <source>PAE/NX</source> + <comment>details report +</comment> + <translation>PAE/NX</translation> + </message> + <message> + <source>Enabled</source> + <comment>details report (VT-x/AMD-V) +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (VT-x/AMD-V) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Enabled</source> + <comment>details report (PAE/NX) +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (PAE/NX) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Host Driver</source> + <comment>details report (audio) +</comment> + <translation>Kompiuterio tvarkyklė</translation> + </message> + <message> + <source>Controller</source> + <comment>details report (audio) +</comment> + <translation>Valdiklis</translation> + </message> + <message> + <source>Port %1</source> + <comment>details report (parallel ports) +</comment> + <translation>%1 prievadas</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (parallel ports) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Parallel Ports</source> + <comment>details report +</comment> + <translation>Nuoseklieji prievadai</translation> + </message> + <message> + <source>USB</source> + <comment>DeviceType +</comment> + <translation>USB</translation> + </message> + <message> + <source>Shared Folder</source> + <comment>DeviceType +</comment> + <translation>Bendrasis aplankas</translation> + </message> + <message> + <source>IDE</source> + <comment>StorageBus +</comment> + <translation>IDE</translation> + </message> + <message> + <source>SATA</source> + <comment>StorageBus +</comment> + <translation>SATA</translation> + </message> + <message> + <source>Primary</source> + <comment>StorageBusChannel +</comment> + <translation>pirminis</translation> + </message> + <message> + <source>Secondary</source> + <comment>StorageBusChannel +</comment> + <translation>antrinis</translation> + </message> + <message> + <source>Master</source> + <comment>StorageBusDevice +</comment> + <translation>pagrindinis</translation> + </message> + <message> + <source>Slave</source> + <comment>StorageBusDevice +</comment> + <translation>šalutinis</translation> + </message> + <message> + <source>Port %1</source> + <comment>StorageBusChannel +</comment> + <translation>%1 prievadas</translation> + </message> + <message> + <source>Solaris Audio</source> + <comment>AudioDriverType +</comment> + <translation>Solaris garsas</translation> + </message> + <message> + <source>PulseAudio</source> + <comment>AudioDriverType +</comment> + <translation>PulseAudio</translation> + </message> + <message> + <source>ICH AC97</source> + <comment>AudioControllerType +</comment> + <translation>ICH AC97</translation> + </message> + <message> + <source>SoundBlaster 16</source> + <comment>AudioControllerType +</comment> + <translation>SoundBlaster 16</translation> + </message> + <message> + <source>PCnet-PCI II (Am79C970A)</source> + <comment>NetworkAdapterType +</comment> + <translation>PCnet-PCI II (Am79C970A)</translation> + </message> + <message> + <source>PCnet-FAST III (Am79C973)</source> + <comment>NetworkAdapterType +</comment> + <translation>PCnet-FAST III (Am79C973)</translation> + </message> + <message> + <source>Intel PRO/1000 MT Desktop (82540EM)</source> + <comment>NetworkAdapterType +</comment> + <translation>Intel PRO/1000 MT darbastalis (82540EM)</translation> + </message> + <message> + <source>Intel PRO/1000 T Server (82543GC)</source> + <comment>NetworkAdapterType +</comment> + <translation>Intel PRO/1000 T serveris (82543GC)</translation> + </message> + <message> + <source><nobr>Vendor ID: %1</nobr></source> + <comment>USB filter tooltip +</comment> + <translation><nobr>Gamintojo ID: %1</nobr></translation> + </message> + <message> + <source><nobr>Product ID: %2</nobr></source> + <comment>USB filter tooltip +</comment> + <translation><nobr>Produkto ID: %2</nobr></translation> + </message> + <message> + <source><nobr>Revision: %3</nobr></source> + <comment>USB filter tooltip +</comment> + <translation><nobr>Revizija: %3</nobr></translation> + </message> + <message> + <source><nobr>Product: %4</nobr></source> + <comment>USB filter tooltip +</comment> + <translation><nobr>Produktas: %4</nobr></translation> + </message> + <message> + <source><nobr>Manufacturer: %5</nobr></source> + <comment>USB filter tooltip +</comment> + <translation><nobr>Gamintojas: %5</nobr></translation> + </message> + <message> + <source><nobr>Serial No.: %1</nobr></source> + <comment>USB filter tooltip +</comment> + <translation><nobr>Serijinis numeris: %1</nobr></translation> + </message> + <message> + <source><nobr>Port: %1</nobr></source> + <comment>USB filter tooltip +</comment> + <translation><nobr>Prievadas: %1</nobr></translation> + </message> + <message> + <source><nobr>State: %1</nobr></source> + <comment>USB filter tooltip +</comment> + <translation><nobr>Būsena: %1</nobr></translation> + </message> + <message> + <source>Adapter %1</source> + <comment>network +</comment> + <translation>%1 plokštė</translation> + </message> + <message> + <source>Checking...</source> + <comment>medium +</comment> + <translation>Tikrinama...</translation> + </message> + <message> + <source>Inaccessible</source> + <comment>medium +</comment> + <translation>Neprieinama</translation> + </message> + <message> + <source>3D Acceleration</source> + <comment>details report +</comment> + <translation>3D spartinimas</translation> + </message> + <message> + <source>Enabled</source> + <comment>details report (3D Acceleration) +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (3D Acceleration) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Setting Up</source> + <comment>MachineState +</comment> + <translation>Ruošiama</translation> + </message> + <message> + <source>Differencing</source> + <comment>DiskType +</comment> + <translation>Vediniai</translation> + </message> + <message> + <source>Nested Paging</source> + <comment>details report</comment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Enabled</source> + <comment>details report (Nested Paging) +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (Nested Paging) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Internal network, '%1'</source> + <comment>details report (network) +</comment> + <translation>Vidinis tinklas, „%1“</translation> + </message> + <message> + <source>SCSI</source> + <comment>StorageBus +</comment> + <translation>SCSI</translation> + </message> + <message> + <source>PIIX3</source> + <comment>StorageControllerType +</comment> + <translation>PIIX3</translation> + </message> + <message> + <source>PIIX4</source> + <comment>StorageControllerType +</comment> + <translation>PIIX4</translation> + </message> + <message> + <source>ICH6</source> + <comment>StorageControllerType +</comment> + <translation>ICH6</translation> + </message> + <message> + <source>AHCI</source> + <comment>StorageControllerType +</comment> + <translation>AHCI</translation> + </message> + <message> + <source>Lsilogic</source> + <comment>StorageControllerType +</comment> + <translation>Lsilogic</translation> + </message> + <message> + <source>BusLogic</source> + <comment>StorageControllerType +</comment> + <translation>BusLogic</translation> + </message> + <message> + <source>Bridged adapter, %1</source> + <comment>details report (network)</comment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Host-only adapter, '%1'</source> + <comment>details report (network)</comment> + <translation>Plokštė prisijungimui tik prie pagrindinio kompiuterio, „%1“</translation> + </message> + <message> + <source>Intel PRO/1000 MT Server (82545EM)</source> + <comment>NetworkAdapterType +</comment> + <translation>Intel PRO/1000 MT serveris (82545EM)</translation> + </message> + <message> + <source>Bridged Adapter</source> + <comment>NetworkAttachmentType</comment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Host-only Adapter</source> + <comment>NetworkAttachmentType</comment> + <translation>Plokštė prisijungimui tik prie pagrindinio kompiuterio</translation> + </message> + <message> + <source><nobr>%1 MB</nobr></source> + <comment>details report +</comment> + <translation><nobr>%1 MB</nobr></translation> + </message> + <message> + <source>Processor(s)</source> + <comment>details report +</comment> + <translation>Procesorius(-iai)</translation> + </message> + <message> + <source><nobr>%1</nobr></source> + <comment>details report +</comment> + <translation><nobr>%1</nobr></translation> + </message> + <message> + <source>System</source> + <comment>details report +</comment> + <translation>Sistema</translation> + </message> + <message> + <source>Remote Display Server Port</source> + <comment>details report (VRDP Server) +</comment> + <translation>Nuotolinio ekrano (RDP) serverio prievadas</translation> + </message> + <message> + <source>Remote Display Server</source> + <comment>details report (VRDP Server) +</comment> + <translation>Nuotolinio ekrano (RDP) serveris</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (VRDP Server) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Display</source> + <comment>details report +</comment> + <translation>Ekranas</translation> + </message> + <message> + <source>Raw File</source> + <comment>PortMode +</comment> + <translation>Neapdorota rinkmena</translation> + </message> + <message> + <source>Enabled</source> + <comment>details report (2D Video Acceleration) +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>details report (2D Video Acceleration) +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>2D Video Acceleration</source> + <comment>details report +</comment> + <translation>2D vaizdo spartinimas</translation> + </message> + <message> + <source>Not Attached</source> + <comment>details report (Storage) +</comment> + <translation>Neprijunta</translation> + </message> + <message> + <source>Storage</source> + <comment>details report +</comment> + <translation>Atminties įtaisas</translation> + </message> + <message> + <source>Teleported</source> + <comment>MachineState</comment> + <translation>Teleportuota</translation> + </message> + <message> + <source>Guru Meditation</source> + <comment>MachineState +</comment> + <translation>Gili meditacija</translation> + </message> + <message> + <source>Teleporting</source> + <comment>MachineState</comment> + <translation>Teleportuojama</translation> + </message> + <message> + <source>Taking Live Snapshot</source> + <comment>MachineState</comment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Teleporting Paused VM</source> + <comment>MachineState</comment> + <translation>Teleportuojama pristabdyta VM</translation> + </message> + <message> + <source>Restoring Snapshot</source> + <comment>MachineState +</comment> + <translation>Atkuriamas momentinis būvis</translation> + </message> + <message> + <source>Deleting Snapshot</source> + <comment>MachineState +</comment> + <translation>Pašalinamas momentinis būvis</translation> + </message> + <message> + <source>Floppy</source> + <comment>StorageBus +</comment> + <translation>Diskelis</translation> + </message> + <message> + <source>Device %1</source> + <comment>StorageBusDevice +</comment> + <translation>%1 įrenginys</translation> + </message> + <message> + <source>IDE Primary Master</source> + <comment>New Storage UI : Slot Name +</comment> + <translation>IDE pirminis pagrindinis</translation> + </message> + <message> + <source>IDE Primary Slave</source> + <comment>New Storage UI : Slot Name +</comment> + <translation>IDE pirminis šalutinis</translation> + </message> + <message> + <source>IDE Secondary Master</source> + <comment>New Storage UI : Slot Name +</comment> + <translation>IDE antrinis pagrindinis</translation> + </message> + <message> + <source>IDE Secondary Slave</source> + <comment>New Storage UI : Slot Name +</comment> + <translation>IDE antrinis šalutinis</translation> + </message> + <message> + <source>SATA Port %1</source> + <comment>New Storage UI : Slot Name +</comment> + <translation>SATA prievadas %1</translation> + </message> + <message> + <source>SCSI Port %1</source> + <comment>New Storage UI : Slot Name +</comment> + <translation>SCSI prievadas %1</translation> + </message> + <message> + <source>Floppy Device %1</source> + <comment>New Storage UI : Slot Name +</comment> + <translation>%1 diskelių įrenginys</translation> + </message> + <message> + <source>Paravirtualized Network (virtio-net)</source> + <comment>NetworkAdapterType</comment> + <translation>Paravirtualizuotas tinklas (virtio-net)</translation> + </message> + <message> + <source>I82078</source> + <comment>StorageControllerType +</comment> + <translation>I82078</translation> + </message> + <message> + <source>Empty</source> + <comment>medium +</comment> + <translation>Tuščia</translation> + </message> + <message> + <source>Host Drive '%1'</source> + <comment>medium</comment> + <translation>Pagrindinio kompiuterio įrenginys „%1“</translation> + </message> + <message> + <source>Host Drive %1 (%2)</source> + <comment>medium</comment> + <translation>Pagrindinio kompiuterio įrenginys %1 (%2)</translation> + </message> + <message> + <source><p style=white-space:pre>Type (Format): %1 (%2)</p></source> + <comment>medium +</comment> + <translation><p style=white-space:pre>Tipas (formatas) : %1 (%2)</p></translation> + </message> + <message> + <source><p>Attached to: %1</p></source> + <comment>image +</comment> + <translation><p>Priskirta prie: %1</p></translation> + </message> + <message> + <source><i>Not Attached</i></source> + <comment>image +</comment> + <translation><i>Nepriskirta</i></translation> + </message> + <message> + <source><i>Checking accessibility...</i></source> + <comment>medium +</comment> + <translation><i>Tikrinamas prieinamumas...</i></translation> + </message> + <message> + <source>Failed to check media accessibility.</source> + <comment>medium +</comment> + <translation>Nepavyko patikrinti laikmenų prieinamumo.</translation> + </message> + <message> + <source><b>No medium selected</b></source> + <comment>medium +</comment> + <translation><b>Laikmena nepasirinkta</b></translation> + </message> + <message> + <source>You can also change this while the machine is running.</source> + <translation>Galite pakeisti ir veikiančioje mašinoje.</translation> + </message> + <message> + <source><b>No media available</b></source> + <comment>medium +</comment> + <translation><b>Laikmenų nėra</b></translation> + </message> + <message> + <source>You can create media images using the virtual media manager.</source> + <translation>Naują laikmeną sukursite naudodamiesi virtualių laikmenų tvarkytuve.</translation> + </message> + <message> + <source>Attaching this hard disk will be performed indirectly using a newly created differencing hard disk.</source> + <comment>medium</comment> + <translation>Su šiuo standžiuoju disku bus dirbama ne tiesiogiai, o naudojant naujai sukurtą standžiojo disko vedinį.</translation> + </message> + <message> + <source>Some of the media in this hard disk chain are inaccessible. Please use the Virtual Media Manager in <b>Show Differencing Hard Disks</b> mode to inspect these media.</source> + <comment>medium +</comment> + <translation>Kai kurių laikmenų neavyksta rasti standžiajame diske. Virtualių laikmenų tvarkytuvėje pasirinkę <b>rodyti diskų vedinius</b>, galite pamatytio tas laikmenas.</translation> + </message> + <message> + <source>This base hard disk is indirectly attached using the following differencing hard disk:</source> + <comment>medium</comment> + <translation>Šis pagrindinis standusis diskas prijungtas ne tiesiogiai, o naudojant šį jo vedinį:</translation> + </message> + <message numerus="yes"> + <source>%n year(s)</source> + <translation> + <numerusform>%n metai</numerusform> + <numerusform>%n metai</numerusform> + <numerusform>%n metų</numerusform> + </translation> + </message> + <message numerus="yes"> + <source>%n month(s)</source> + <translation> + <numerusform>%n mėnuo</numerusform> + <numerusform>%n menesiai</numerusform> + <numerusform>%n mėnesių</numerusform> + </translation> + </message> + <message numerus="yes"> + <source>%n day(s)</source> + <translation> + <numerusform>%n diena</numerusform> + <numerusform>%n dienos</numerusform> + <numerusform>%n dienų</numerusform> + </translation> + </message> + <message numerus="yes"> + <source>%n hour(s)</source> + <translation> + <numerusform>%n valanda</numerusform> + <numerusform>%n valandos</numerusform> + <numerusform>%n valandų</numerusform> + </translation> + </message> + <message numerus="yes"> + <source>%n minute(s)</source> + <translation> + <numerusform>%n minutė</numerusform> + <numerusform>%n minutės</numerusform> + <numerusform>%n minučių</numerusform> + </translation> + </message> + <message numerus="yes"> + <source>%n second(s)</source> + <translation> + <numerusform>%n secondė</numerusform> + <numerusform>%n secondės</numerusform> + <numerusform>%n sekundžių</numerusform> + </translation> + </message> + <message> + <source>(CD/DVD)</source> + <translation>(CD/DVD)</translation> + </message> + <message> + <source>Screens</source> + <comment>details report</comment> + <translation>Ekranai</translation> + </message> + <message> + <source>VDE network, '%1'</source> + <comment>details report (network)</comment> + <translation>VDE tinklas, „%1“</translation> + </message> + <message> + <source>SAS</source> + <comment>StorageBus</comment> + <translation>SAS</translation> + </message> + <message> + <source>VDE Adapter</source> + <comment>NetworkAttachmentType</comment> + <translation>VDE plokštė</translation> + </message> + <message> + <source>LsiLogic SAS</source> + <comment>StorageControllerType</comment> + <translation>LsiLogic SAS</translation> + </message> + <message> + <source>^(?:(?:(\d+)(?:\s?(B|KB|MB|GB|TB|PB))?)|(?:(\d*)%1(\d{1,2})(?:\s?(KB|MB|GB|TB|PB))))$</source> + <comment>regexp for matching ####[.##] B|KB|MB|GB|TB|PB, %1=decimal point</comment> + <translation>^(?:(?:(\d+)(?:\s?(B|KB|MB|GB|TB|PB))?)|(?:(\d*)%1(\d{1,2})(?:\s?(KB|MB|GB|TB|PB))))$</translation> + </message> + <message> + <source>B</source> + <comment>size suffix Bytes</comment> + <translation>B</translation> + </message> + <message> + <source>KB</source> + <comment>size suffix KBytes=1024 Bytes</comment> + <translation>KB</translation> + </message> + <message> + <source>MB</source> + <comment>size suffix MBytes=1024 KBytes +</comment> + <translation>MB</translation> + </message> + <message> + <source>GB</source> + <comment>size suffix GBytes=1024 MBytes</comment> + <translation>GB</translation> + </message> + <message> + <source>TB</source> + <comment>size suffix TBytes=1024 GBytes</comment> + <translation>TB</translation> + </message> + <message> + <source>PB</source> + <comment>size suffix PBytes=1024 TBytes</comment> + <translation>PB</translation> + </message> + <message> + <source>Enabled</source> + <comment>nested paging +</comment> + <translation>Įgalinta</translation> + </message> + <message> + <source>Disabled</source> + <comment>nested paging +</comment> + <translation>Uždrausta</translation> + </message> + <message> + <source>Nested Paging</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Shareable</source> + <comment>DiskType</comment> + <translation>Bendrasis</translation> + </message> + <message> + <source>Unknown device</source> + <comment>USB device details</comment> + <translation>Nežinomas įrenginys</translation> + </message> + <message> + <source>SAS Port %1</source> + <comment>New Storage UI : Slot Name</comment> + <translation>SAS prievadas %1</translation> + </message> +</context> +<context> + <name>VBoxGlobalSettings</name> + <message> + <source>'%1 (0x%2)' is an invalid host key code.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>The value '%1' of the key '%2' doesn't match the regexp constraint '%3'.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Cannot delete the key '%1'.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>VBoxHelpButton</name> + <message> + <source>&Help</source> + <translation>&Pagalba</translation> + </message> +</context> +<context> + <name>VBoxImportApplianceWgt</name> + <message> + <source>Importing Appliance ...</source> + <translation>Įkeliama virtuali mašina...</translation> + </message> + <message> + <source>Reading Appliance ...</source> + <translation>Skaitoma virtuali mašina...</translation> + </message> +</context> +<context> + <name>VBoxLicenseViewer</name> + <message> + <source>VirtualBox License</source> + <translation>VirtualBox licencija</translation> + </message> + <message> + <source>I &Agree</source> + <translation>&Sutinku</translation> + </message> + <message> + <source>I &Disagree</source> + <translation>&Nesutinku</translation> + </message> +</context> +<context> + <name>VBoxLineTextEdit</name> + <message> + <source>&Edit</source> + <translation>&Keisti</translation> + </message> +</context> +<context> + <name>VBoxLogSearchPanel</name> + <message> + <source>Close the search panel</source> + <translation>Užverti paieškos skydelį</translation> + </message> + <message> + <source>Find </source> + <translation>Ieškoti </translation> + </message> + <message> + <source>Enter a search string here</source> + <translation>Įveskite paieškos reiškinį</translation> + </message> + <message> + <source>&Previous</source> + <translation>&Ankstesnis</translation> + </message> + <message> + <source>Search for the previous occurrence of the string</source> + <translation>Ieškoti ankstesnių paieškos reiškinių</translation> + </message> + <message> + <source>&Next</source> + <translation>&Toliau</translation> + </message> + <message> + <source>Search for the next occurrence of the string</source> + <translation>Ieškoti tolesnių paieškos reiškinių</translation> + </message> + <message> + <source>C&ase Sensitive</source> + <translation>&Skirti raidžių dydį</translation> + </message> + <message> + <source>Perform case sensitive search (when checked)</source> + <translation>Skirti raidžių dydį (jei pasirinkta)</translation> + </message> + <message> + <source>String not found</source> + <translation>Nerasta</translation> + </message> +</context> +<context> + <name>VBoxMediaManagerDlg</name> + <message> + <source>&Actions</source> + <translation>&Veiksmai</translation> + </message> + <message> + <source>&New...</source> + <translation>&Naujas...</translation> + </message> + <message> + <source>&Add...</source> + <translation>Pri&dėti...</translation> + </message> + <message> + <source>R&emove</source> + <translation>Pašalin&ti</translation> + </message> + <message> + <source>Re&lease</source> + <translation>At&laisvinti</translation> + </message> + <message> + <source>Re&fresh</source> + <translation>&Atnaujinti</translation> + </message> + <message> + <source>Create a new virtual hard disk</source> + <translation>Sukurti naują virtualų standųjį diską</translation> + </message> + <message> + <source>Add an existing medium</source> + <translation>Pridėti esamą laikmeną</translation> + </message> + <message> + <source>Remove the selected medium</source> + <translation>Pašalinti pasirinktą laikmeną</translation> + </message> + <message> + <source>Release the selected medium by detaching it from the machines</source> + <translation>Atlaisvinus pasirinktą laikmeną, ji nebebus susieta su mašinomis</translation> + </message> + <message> + <source>Refresh the media list</source> + <translation>Atnaujinti laikmenų sąrašą</translation> + </message> + <message> + <source>Location</source> + <translation>Vieta</translation> + </message> + <message> + <source>Type (Format)</source> + <translation>Tipas (formatas) </translation> + </message> + <message> + <source>Attached to</source> + <translation>Susietas su </translation> + </message> + <message> + <source>Checking accessibility</source> + <translation>Tikrinamas prieinamumas</translation> + </message> + <message> + <source>&Select</source> + <translation>Pa&sirinkti</translation> + </message> + <message> + <source>All hard disk images (%1)</source> + <translation>Visi standžiųjų diskų atvaizdai (%1)</translation> + </message> + <message> + <source>All files (*)</source> + <translation>Visos rinkmenos (*)</translation> + </message> + <message> + <source>Select a hard disk image file</source> + <translation>Pasirinkite standžiojo disko atvaizdo rinkmeną</translation> + </message> + <message> + <source>CD/DVD-ROM images (*.iso);;All files (*)</source> + <translation>CD/DVD atvaizdai (*.iso);;Visos rinkmenos (*)</translation> + </message> + <message> + <source>Select a CD/DVD-ROM disk image file</source> + <translation>Pasirinkite CD/DVD atvaizdą</translation> + </message> + <message> + <source>Floppy images (*.img);;All files (*)</source> + <translation>Diskelių atvaizdai (*.img);;Visos rinkmenos (*)</translation> + </message> + <message> + <source>Select a floppy disk image file</source> + <translation>Pasirinkite diskelio atvaizdo rinkmeną</translation> + </message> + <message> + <source><i>Not&nbsp;Attached</i></source> + <translation><i>nesusieta</i></translation> + </message> + <message> + <source>--</source> + <comment>no info +</comment> + <translation>--</translation> + </message> + <message> + <source>Virtual Media Manager</source> + <translation>Virtualių laikmenų tvarkytuvė</translation> + </message> + <message> + <source>Hard &Disks</source> + <translation>Standieji &diskai</translation> + </message> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> + <source>Virtual Size</source> + <translation>Virtualus dydis</translation> + </message> + <message> + <source>Actual Size</source> + <translation>Tikras dydis</translation> + </message> + <message> + <source>&CD/DVD Images</source> + <translation>&CD/DVD atvaizdai</translation> + </message> + <message> + <source>Size</source> + <translation>Dydis</translation> + </message> + <message> + <source>&Floppy Images</source> + <translation>&Diskelių atvaizdai</translation> + </message> + <message> + <source>Attached to</source> + <comment>VMM: Virtual Disk +</comment> + <translation>Susietas su </translation> + </message> + <message> + <source>Attached to</source> + <comment>VMM: CD/DVD Image +</comment> + <translation>Susietas su </translation> + </message> + <message> + <source>Attached to</source> + <comment>VMM: Floppy Image +</comment> + <translation>Susietas su </translation> + </message> +</context> +<context> + <name>VBoxMiniToolBar</name> + <message> + <source>Always show the toolbar</source> + <translation>Įrankių juostą rodyti visada</translation> + </message> + <message> + <source>Exit Full Screen or Seamless Mode</source> + <translation>Išeiti iš viso ekrano arba integruotos veiksenos</translation> + </message> + <message> + <source>Close VM</source> + <translation>Užverti virtualią mašiną</translation> + </message> +</context> +<context> + <name>VBoxNetworkDialog</name> + <message> + <source>Network Adapters</source> + <translation>Tinklo plokštės</translation> + </message> +</context> +<context> + <name>VBoxOSTypeSelectorWidget</name> + <message> + <source>Operating &System:</source> + <translation>&Operacinė sistema:</translation> + </message> + <message> + <source>Displays the operating system family that you plan to install into this virtual machine.</source> + <translation>Rodo šeimą operacinių sistemų, kurią ketinate įdiegti virtualioje mašinoje.</translation> + </message> + <message> + <source>Displays the operating system type that you plan to install into this virtual machine (called a guest operating system).</source> + <translation>Rodo operacinės sistemos tipą, kurį ketinate įdiegti šioje virtualioje mašinoje (pastaroji dar vadinama svečio operacine sistema).</translation> + </message> + <message> + <source>&Version:</source> + <translation>&Versija:</translation> + </message> +</context> +<context> + <name>VBoxProblemReporter</name> + <message> + <source>VirtualBox - Information</source> + <comment>msg box title +</comment> + <translation>VirtualBox - informacija</translation> + </message> + <message> + <source>VirtualBox - Question</source> + <comment>msg box title +</comment> + <translation>VirtualBox - klausimas</translation> + </message> + <message> + <source>VirtualBox - Warning</source> + <comment>msg box title +</comment> + <translation>VirtualBox - įspėjimas</translation> + </message> + <message> + <source>VirtualBox - Error</source> + <comment>msg box title +</comment> + <translation>VirtualBox - klaida</translation> + </message> + <message> + <source>VirtualBox - Critical Error</source> + <comment>msg box title +</comment> + <translation>VirtialBox - lemtinga klaida</translation> + </message> + <message> + <source>Do not show this message again</source> + <comment>msg box flag +</comment> + <translation>Daugiau nerodyti šios žinutės</translation> + </message> + <message> + <source>Failed to open <tt>%1</tt>. Make sure your desktop environment can properly handle URLs of this type.</source> + <translation>Nepavyko atverti <tt>%1</tt>. Įsitikinkite, ar darbastalio aplinka tikrai gali apdoroti šio tipo URL.</translation> + </message> + <message> + <source><p>Failed to initialize COM or to find the VirtualBox COM server. Most likely, the VirtualBox server is not running or failed to start.</p><p>The application will now terminate.</p></source> + <translation><p>Nepavyko paruošti COM arba nerastas VirtualBox COM serveris. Greičiausis VirtualBox serveris nėra paleistas arba jo nepavyko paleisti</p><p>Programa netrukus išsijungs.</p></translation> + </message> + <message> + <source><p>Failed to create the VirtualBox COM object.</p><p>The application will now terminate.</p></source> + <translation><p>Nepavyko sukurti VirtualBox COM objekto.</p><p>Programa netrukus išsijungs.</p></translation> + </message> + <message> + <source>Failed to set global VirtualBox properties.</source> + <translation>Nepavyko nustatyti bendrų VirtualBox savybių.</translation> + </message> + <message> + <source>Failed to access the USB subsystem.</source> + <translation>Nepavyko pasiekti USB posistemės.</translation> + </message> + <message> + <source>Failed to create a new virtual machine.</source> + <translation>Nepavyko sukurti naujos virtualios mašinos.</translation> + </message> + <message> + <source>Failed to create a new virtual machine <b>%1</b>.</source> + <translation>Nepavyko sukurti naujos virtualios mašinos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to apply the settings to the virtual machine <b>%1</b>.</source> + <translation>Virtualiai mašinai <b>%1</b> nepavyko pritaikyti nuostatų.</translation> + </message> + <message> + <source>Failed to start the virtual machine <b>%1</b>.</source> + <translation>Nepavyko paleisti virtualios mašinos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to pause the execution of the virtual machine <b>%1</b>.</source> + <translation>Nepavyko pristabdyti virtualios mašinos <b>%1</b> darbo.</translation> + </message> + <message> + <source>Failed to resume the execution of the virtual machine <b>%1</b>.</source> + <translation>Nepavyko atkurti virtualios mašinos <b>%1</b> darbo.</translation> + </message> + <message> + <source>Failed to save the state of the virtual machine <b>%1</b>.</source> + <translation>Nepavyko sukurti virtualios mašinos momentinės būvio kopijos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to create a snapshot of the virtual machine <b>%1</b>.</source> + <translation>Nepavyko sukurti virtualios mašinos momentinės būvio kopijos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to stop the virtual machine <b>%1</b>.</source> + <translation>Nepavyko sustabdyti virtualios mašinos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to remove the virtual machine <b>%1</b>.</source> + <translation>Nepavyko pašalinti virtualios mašinos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to discard the saved state of the virtual machine <b>%1</b>.</source> + <translation>Nepavyko panaikinti virtualios mašinos momentinės būvio kopijos <b>%1</b>.</translation> + </message> + <message> + <source>There is no virtual machine named <b>%1</b>.</source> + <translation>Nėra tokios virtualios mašinos su pavadinimu <b>%1</b>.</translation> + </message> + <message> + <source><p>Are you sure you want to permanently delete the virtual machine <b>%1</b>?</p><p>This operation cannot be undone.</p></source> + <translation><p>Tikrai norite negrįžtamai pašalinti virtualią mašiną <b>%1</b>?</p><p>Šio veiksmo negalėsite atšaukti.</p></translation> + </message> + <message> + <source><p>Are you sure you want to unregister the inaccessible virtual machine <b>%1</b>?</p><p>You will not be able to register it again from GUI.</p></source> + <translation><p>Tikrai norite išregistruoti neprieinamą virtualią mašiną <b>%1</b>?</p><p>Jos nebegalėsite priregistruoti grafinėje aplinkoje.</p></translation> + </message> + <message> + <source><p>Are you sure you want to discard the saved state of the virtual machine <b>%1</b>?</p><p>This operation is equivalent to resetting or powering off the machine without doing a proper shutdown of the guest OS.</p></source> + <translation><p>Tikrai norite panaikinti išsaugotą virtualios mašinos momentinę būvio kopiją <b>%1</b>?</p><p>Šis veiksmas atitinka mašinos perkrovimą arba išjungimą be deramo svečio OS darbo užbaigimo.</p></translation> + </message> + <message> + <source>Failed to create a new session.</source> + <translation>Nepavyko sukurti naujos sesijos.</translation> + </message> + <message> + <source>Failed to open a session for the virtual machine <b>%1</b>.</source> + <translation>Nepavyko atverti sesijos virtualiai mašinai <b>%1</b>.</translation> + </message> + <message> + <source>Failed to remove the host network interface <b>%1</b>.</source> + <translation>Nepavyko pašalinti pagrindinio kompiuterio tinklo sąsajos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to attach the USB device <b>%1</b> to the virtual machine <b>%2</b>.</source> + <translation>Nepavyko prijungti USB įrenginio <b>%1</b> prie virtualios mašinos <b>%2</b>.</translation> + </message> + <message> + <source>Failed to detach the USB device <b>%1</b> from the virtual machine <b>%2</b>.</source> + <translation>Nepavyko atjungti USB įrenginio <b>%1</b> nuo virtualios mašinos <b>%2</b>.</translation> + </message> + <message> + <source>Failed to create the shared folder <b>%1</b> (pointing to <nobr><b>%2</b></nobr>) for the virtual machine <b>%3</b>.</source> + <translation>Nepavyko sukurti bendrojo aplanko <b>%1</b> (ties <nobr><b>%2</b></nobr>) virtualiai mašinai <b>%3</b>.</translation> + </message> + <message> + <source>Failed to remove the shared folder <b>%1</b> (pointing to <nobr><b>%2</b></nobr>) from the virtual machine <b>%3</b>.</source> + <translation>Nepavyko pervadinti bendrojo aplanko <b>%1</b> (ties <nobr><b>%2</b></nobr>) virtualiai mašinai <b>%3</b>.</translation> + </message> + <message> + <source><p>The Virtual Machine reports that the guest OS does not support <b>mouse pointer integration</b> in the current video mode. You need to capture the mouse (by clicking over the VM display or pressing the host key) in order to use the mouse inside the guest OS.</p></source> + <translation><p>Virtuali mašina pranešė, kad svečio OS nepalaiko <b>pelės žymeklio integravimo</b> šioje vaizdo veiksenoje. Jei norite, kad virtuali mašina reaguotų į pelę, spragtelėkite pele svečio OS lange arba nuspauskite pagrindinį kompiuterio klavišą (host).</p></translation> + </message> + <message> + <source><p>The Virtual Machine is currently in the <b>Paused</b> state and not able to see any keyboard or mouse input. If you want to continue to work inside the VM, you need to resume it by selecting the corresponding action from the menu bar.</p></source> + <translation><p>Virtuali mašina yra <b>pristabdyta</b>, tad ji nereaguos į klaviatūros ar pelės paspaudimus. Jei norite toliau dirbti virtualioje mašinoje, tęskite nuspaudę atitinkamą meniu mygtuką.</p></translation> + </message> + <message> + <source><p>Cannot run VirtualBox in <i>VM Selector</i> mode due to local restrictions.</p><p>The application will now terminate.</p></source> + <translation><p>Dėl vietinių apribojimų nepavyksta paleisti VirtualBox <i>VM pasirinkimo</i> veiksenos.</p><p>Programa netrukus baigs darbą.</p></translation> + </message> + <message> + <source><nobr>Fatal Error</nobr></source> + <comment>runtime error info +</comment> + <translation><nobr>Lemtinga klaida</nobr></translation> + </message> + <message> + <source><nobr>Non-Fatal Error</nobr></source> + <comment>runtime error info +</comment> + <translation><nobr>Klaida nėra lemtinga</nobr></translation> + </message> + <message> + <source><nobr>Warning</nobr></source> + <comment>runtime error info +</comment> + <translation><nobr>Įspėjimai</nobr></translation> + </message> + <message> + <source><nobr>Error ID: </nobr></source> + <comment>runtime error info +</comment> + <translation><nobr>Klaidos ID: </nobr></translation> + </message> + <message> + <source>Severity: </source> + <comment>runtime error info +</comment> + <translation>Rimtumas:</translation> + </message> + <message> + <source><p>A fatal error has occurred during virtual machine execution! The virtual machine will be powered off. Please copy the following error message using the clipboard to help diagnose the problem:</p></source> + <translation><p>Virtualios mašinos darbo metu įvyko lemtinga klaida! Virtuali mašina netrukus išsijungs. Jei norite padėti nustatyti problemą, nukopijuokite toliau pateiktą klaidos pranešimą naudodamiesi iškarpine:</p></translation> + </message> + <message> + <source><p>An error has occurred during virtual machine execution! The error details are shown below. You may try to correct the error and resume the virtual machine execution.</p></source> + <translation><p>Virtualios mašinos darbo metu įvyko klaida! Šios klaidos detalės pateiktos žemiau. Galite ištaisyti klaidą ir toliau tęsti darbą.</p></translation> + </message> + <message> + <source><p>The virtual machine execution may run into an error condition as described below. We suggest that you take an appropriate action to avert the error.</p></source> + <translation><p>Virtuali mašiną gali veikti esant toliau nurodytai klaidai. Tikimės, kad elgsitės taip, kad išvengtumėte šios klaidos pasekmių.</p></translation> + </message> + <message> + <source>Result&nbsp;Code: </source> + <comment>error info +</comment> + <translation>Rezultato&nbsp;kodas: </translation> + </message> + <message> + <source>Component: </source> + <comment>error info +</comment> + <translation>Elementas:</translation> + </message> + <message> + <source>Interface: </source> + <comment>error info +</comment> + <translation>Sąsaja: </translation> + </message> + <message> + <source>Callee: </source> + <comment>error info</comment> + <translation>Iššaukė: </translation> + </message> + <message> + <source>Callee&nbsp;RC: </source> + <comment>error info</comment> + <translation>Iššaukė&nbsp;RC: </translation> + </message> + <message> + <source><p>Could not find a language file for the language <b>%1</b> in the directory <b><nobr>%2</nobr></b>.</p><p>The language will be temporarily reset to the system default language. Please go to the <b>Preferences</b> dialog which you can open from the <b>File</b> menu of the main VirtualBox window, and select one of the existing languages on the <b>Language</b> page.</p></source> + <translation><p>Nepavyksta rasti <b>%1</b> kalbos rinkmenos aplanke <b><nobr>%2</nobr></b>.</p><p>Laikinai bus naudojama sistemos numatytoji kalba. Eikite į <b>nuostatas</b> per <b>rinkmenos</b> meniu, esantį pagrindiniame VirtualBox lange, ir pasirinkite egzistuojančią kalbą <b>kalbos</b> kortelėje.</p></translation> + </message> + <message> + <source><p>Could not load the language file <b><nobr>%1</nobr></b>. <p>The language will be temporarily reset to English (built-in). Please go to the <b>Preferences</b> dialog which you can open from the <b>File</b> menu of the main VirtualBox window, and select one of the existing languages on the <b>Language</b> page.</p></source> + <translation><p>Nepavyksta įkelti kalbos rinkmenos <b><nobr>%1</nobr></b>. <p>Laikinai bus naudojama anglų kalba.Eikite į <b>nuostatas</b> per <b>rinkmenos</b> meniu, esantį pagrindiniame VirtualBox lange, ir pasirinkite egzistuojančią kalbą <b>kalbos</b> kortelėje.</p></translation> + </message> + <message> + <source><p>The VirtualBox Guest Additions installed in the Guest OS are too old: the installed version is %1, the expected version is %2. Some features that require Guest Additions (mouse integration, guest display auto-resize) will most likely stop working properly.</p><p>Please update the Guest Additions to the current version by choosing <b>Install Guest Additions</b> from the <b>Devices</b> menu.</p></source> + <translation><p>Įdiegtieji VirtualBox svečio papildiniai yra per seni: yra įdiegta %1 versija, bet tikėtasi %2 versijos. Kai kurios funkcijos (pelės integravimas, svečio ekrano dydžio automatinis keitimas) gali neveikti tinkamai.</p><p>Atnaujinkite svečio papildinius iki tinkamos versijos nuspaudę <b>Įdiegti svečio papildinius</b> iš <b>įrenginių</b> meniu.</p></translation> + </message> + <message> + <source><p>The VirtualBox Guest Additions installed in the Guest OS are outdated: the installed version is %1, the expected version is %2. Some features that require Guest Additions (mouse integration, guest display auto-resize) may not work as expected.</p><p>It is recommended to update the Guest Additions to the current version by choosing <b>Install Guest Additions</b> from the <b>Devices</b> menu.</p></source> + <translation><p>Įdiegtieji VirtualBox svečio papildiniai nėra patys naujausi: yra įdiegta %1 versija, bet tikėtasi %2 versijos. Kai kurios funkcijos (pelės integravimas, svečio ekrano dydžio automatinis keitimas) gali neveikti tinkamai.</p><p>Patariama atnaujinti svečio papildinius iki tinkamos versijos nuspaudus <b>Įdiegti svečio papildinius</b> iš <b>įrenginių</b> meniu.</p></translation> + </message> + <message> + <source><p>The VirtualBox Guest Additions installed in the Guest OS are too recent for this version of VirtualBox: the installed version is %1, the expected version is %2.</p><p>Using a newer version of Additions with an older version of VirtualBox is not supported. Please install the current version of the Guest Additions by choosing <b>Install Guest Additions</b> from the <b>Devices</b> menu.</p></source> + <translation><p>Įdiegtieji VirtualBox svečio papildiniai yra per nauji: yra įdiegta %1 versija, bet tikėtasi %2 versijos. Negalima naudoti naujesnių svečio papildinių už versiją, kurią palaiko VirtualBox.</p><p>Atnaujinkite svečio papildinius iki tinkamos versijos nuspaudę <b>Įdiegti svečio papildinius</b> iš <b>įrenginių</b> meniu.</p></translation> + </message> + <message> + <source>Failed to change the snapshot folder path of the virtual machine <b>%1<b> to <nobr><b>%2</b></nobr>.</source> + <translation>Nepavyko pekeisti momentinių kopijų aplanko virtualiai mašinai <b>%1<b> į <nobr><b>%2</b></nobr>.</translation> + </message> + <message> + <source><p>Failed to remove the shared folder <b>%1</b> (pointing to <nobr><b>%2</b></nobr>) from the virtual machine <b>%3</b>.</p><p>Please close all programs in the guest OS that may be using this shared folder and try again.</p></source> + <translation><p>Nepavyko pašalinti bendrojo aplanko <b>%1</b> (ties <nobr><b>%2</b></nobr>) iš virtualios mašinos <b>%3</b>.</p><p>Užverkite visas svečio OS programas, kurios gali naudotis tuo aplanku ir bandykite iš naujo.</p></translation> + </message> + <message> + <source><p>Could not find the VirtualBox Guest Additions CD image file <nobr><b>%1</b></nobr> or <nobr><b>%2</b>.</nobr></p><p>Do you wish to download this CD image from the Internet?</p></source> + <translation><p>Nepavyksta rasti VirtualBox svečio papildinių CD atvaizdo <nobr><b>%1</b></nobr> arba <nobr><b>%2</b>.</nobr></p><p>Ar atsisiųsti šį CD atvaizdą iš interneto?</p></translation> + </message> + <message> + <source><p>Failed to download the VirtualBox Guest Additions CD image from <nobr><a href="%1">%2</a>.</nobr></p><p>%3</p></source> + <translation><p>Nepavyko parsiųsti VirtualBox svečio papildinių CD avaizdo iš <nobr><a href="%1">%2</a>.</nobr></p><p>%3</p></translation> + </message> + <message> + <source><p>Are you sure you want to download the VirtualBox Guest Additions CD image from <nobr><a href="%1">%2</a></nobr> (size %3 bytes)?</p></source> + <translation><p>Tikrai parsiųsti VirtualBox svečio papildinių CD atvaizdą iš <nobr><a href="%1">%2</a></nobr> (%3 baitų dydžio)?</p></translation> + </message> + <message> + <source><p>The VirtualBox Guest Additions CD image has been successfully downloaded from <nobr><a href="%1">%2</a></nobr> and saved locally as <nobr><b>%3</b>.</nobr></p><p>Do you wish to register this CD image and mount it on the virtual CD/DVD drive?</p></source> + <translation><p>VirtualBox svečio papildinių CD atvaizdas iš <nobr><a href="%1">%2</a></nobr> parsiųstas sėkmingai ir įrašytas vietinėje sistemoje <nobr><b>%3</b>.</nobr></p><p>Priregistruoti šį CD atvaizdą ir prijungti jį virtualiame CD/DVD kaupiklyje?</p></translation> + </message> + <message> + <source><p>The virtual machine window is optimized to work in <b>%1&nbsp;bit</b> color mode but the virtual display is currently set to <b>%2&nbsp;bit</b>.</p><p>Please open the display properties dialog of the guest OS and select a <b>%3&nbsp;bit</b> color mode, if it is available, for best possible performance of the virtual video subsystem.</p><p><b>Note</b>. Some operating systems, like OS/2, may actually work in 32&nbsp;bit mode but report it as 24&nbsp;bit (16 million colors). You may try to select a different color mode to see if this message disappears or you can simply disable the message now if you are sure the required color mode (%4&nbsp;bit) is not available in the guest OS.</p></source> + <translation><p>Virtualios mašinos langas sukonfigūruotas dirbti <b>%1&nbsp;bitų</b> spalvų veiksenoje, tačiau virtualus ekranas šiuo metu naudoja <b>%2&nbsp;bitų</b> veikseną.</p><p>Jei įmanoma, atverkite svečio OS ekrano nuostatas ir pasirinkite <b>%3&nbsp;bitų</b> spalvų veikseną; taip užtikrinsite geriausią virtualios vaizdo posistemės veikimą.</p><p><b>Atminkite</b>. Kai kurios operacinės sistemos, pavyzdžiui OS/2, gali iš tikrųjų dirbti 32&nbsp;bitų veiksenoje, tačiau pranešti, kad yra 24&nbsp;bitų (16 milijonų spalvų). Galite pasirinkti kitą spalvų veikseną, kad įsitikintumėte, ar šis pranešimai pasirodo pagrįstai; arba galite uždrausti šio pranešimo pakartotinį rodymą, jei žinote, kad reikiamos spalvų veiksenos (%4&nbsp;bitų) svečio OS nepalaiko.</p></translation> + </message> + <message> + <source><p>You didn't attach a hard disk to the new virtual machine. The machine will not be able to boot unless you attach a hard disk with a guest operating system or some other bootable media to it later using the machine settings dialog or the First Run Wizard.</p><p>Do you wish to continue?</p></source> + <translation><p>Naujai virtualiai mašinai nepriskyrėte jokio standžiojo disko. Mašina negalės įsikrauti, jei nepriskirsite standžiojo disko su svečio operacine sistema arba kitos įkraunamos laikmenos, kuri būtų naudojama mašinos nuostatų lange arba pirmojo paleidimo vediklyje.</p><p>Tęsti?</p></translation> + </message> + <message> + <source>Failed to find license files in <nobr><b>%1</b></nobr>.</source> + <translation>Nepavyko rasti licencijos rinkmenos <nobr><b>%1</b></nobr>.</translation> + </message> + <message> + <source>Failed to open the license file <nobr><b>%1</b></nobr>. Check file permissions.</source> + <translation>Nepavyko atverti licencijos rinkmenos <nobr><b>%1</b></nobr>. Tikrinkite leidimus.</translation> + </message> + <message> + <source>Failed to send the ACPI Power Button press event to the virtual machine <b>%1</b>.</source> + <translation>Nepavyko virtualioje mašinoje <b>%1</b> nuspausti kompiuterio išjungimo mygtuko.</translation> + </message> + <message> + <source><p>Congratulations! You have been successfully registered as a user of VirtualBox.</p><p>Thank you for finding time to fill out the registration form!</p></source> + <translation><p>Sveikiname! VirtualBox naudotojas sėkmingai užregistruotas.</p><p>Dėkojame, kad užsiregistravote!</p></translation> + </message> + <message> + <source><p>Failed to save the global VirtualBox settings to <b><nobr>%1</nobr></b>.</p></source> + <translation><p>Nepavyko įrašyti bendrų VirtualBox nuostatų į <b><nobr>%1</nobr></b>.</p></translation> + </message> + <message> + <source><p>Failed to load the global GUI configuration from <b><nobr>%1</nobr></b>.</p><p>The application will now terminate.</p></source> + <translation><p>Nepavyko įkelti bendrų naudotojo grafinės sąsajos konfigūracijos iš <b><nobr>%1</nobr></b>.</p><p>Programa netrukus išsijungs.</p></translation> + </message> + <message> + <source><p>Failed to save the global GUI configuration to <b><nobr>%1</nobr></b>.</p><p>The application will now terminate.</p></source> + <translation><p>Nepavyko įrašyti bendrų naudotojo grafinės sąsajos konfigūracijos į <b><nobr>%1</nobr></b>.</p><p>Programa netrukus išsijungs.</p></translation> + </message> + <message> + <source>Failed to save the settings of the virtual machine <b>%1</b> to <b><nobr>%2</nobr></b>.</source> + <translation>Nepavyko įrašyti virtualios mašinos <b>%1</b> nuostatų į <b><nobr>%2</nobr></b>.</translation> + </message> + <message> + <source>Failed to load the settings of the virtual machine <b>%1</b> from <b><nobr>%2</nobr></b>.</source> + <translation>Nepavyko įkelti virtualios mašinos <b>%1</b> nuostatų iš <b><nobr>%2</nobr></b>.</translation> + </message> + <message> + <source>Delete</source> + <comment>machine +</comment> + <translation>Pašalinti</translation> + </message> + <message> + <source>Unregister</source> + <comment>machine</comment> + <translation>Išregistruoti</translation> + </message> + <message> + <source>Discard</source> + <comment>saved state +</comment> + <translation>Atmesti</translation> + </message> + <message> + <source>Disable</source> + <comment>hard disk +</comment> + <translation>Uždrausti</translation> + </message> + <message> + <source>Download</source> + <comment>additions +</comment> + <translation>Parsiųsti</translation> + </message> + <message> + <source>Mount</source> + <comment>additions +</comment> + <translation>Prijungti</translation> + </message> + <message> + <source><p>The host key is currently defined as <b>%1</b>.</p></source> + <comment>additional message box paragraph</comment> + <translation><p>Šiuo metu pagrindinis kompiuterio klavišas yra <b>%1</b>.</p></translation> + </message> + <message> + <source>Capture</source> + <comment>do input capture</comment> + <translation>Reaguoti</translation> + </message> + <message> + <source>Check</source> + <comment>inaccessible media message box +</comment> + <translation>Tikrinti</translation> + </message> + <message> + <source>Switch</source> + <comment>fullscreen +</comment> + <translation>Perjungti</translation> + </message> + <message> + <source>Switch</source> + <comment>seamless +</comment> + <translation>Perjungti</translation> + </message> + <message> + <source><p>Do you really want to reset the virtual machine?</p><p>This will cause any unsaved data in applications running inside it to be lost.</p></source> + <translation><p>Tikrai norite perkrauti virtualią mašiną?</p><p>Prarasite visus neišsaugotus duomenis.</p></translation> + </message> + <message> + <source>Reset</source> + <comment>machine +</comment> + <translation>Perkrauti</translation> + </message> + <message> + <source>Continue</source> + <comment>no hard disk attached +</comment> + <translation>Tęsti</translation> + </message> + <message> + <source>Go Back</source> + <comment>no hard disk attached +</comment> + <translation>Atgal</translation> + </message> + <message> + <source>Failed to copy file <b><nobr>%1</nobr></b> to <b><nobr>%2</nobr></b> (%3).</source> + <translation>Nepavyko nukopijuoti rinkmenos <b><nobr>%1</nobr></b> į <b><nobr>%2</nobr></b> (%3).</translation> + </message> + <message> + <source><p>Could not enter seamless mode due to insufficient guest video memory.</p><p>You should configure the virtual machine to have at least <b>%1</b> of video memory.</p></source> + <translation><p>Nepakanka svečio sistemos vaizdo atminties, kad būtų pereita į integruotą veikseną.</p><p>Sukonfigūruokite virtualią mašiną taip, kad vaizdo atminties būtų bent <b>%1</b>.</p></translation> + </message> + <message> + <source><p>Could not switch the guest display to fullscreen mode due to insufficient guest video memory.</p><p>You should configure the virtual machine to have at least <b>%1</b> of video memory.</p><p>Press <b>Ignore</b> to switch to fullscreen mode anyway or press <b>Cancel</b> to cancel the operation.</p></source> + <translation><p>Nepakanka svečio sistemos vaizdo atminties, kad būtų galima pereiti į viso ekrano veikseną.</p><p>Sukonfigūruokite virtualią mašiną taip, kad ši turėtų bent <b>%1</b> virtualios atminties.</p><p>Spauskite <b>Nepaisyti</b>, jei norite vis tiek pabandyti pereiti į viso ekrano veikseną, arba spauskite <b>Atšaukti</b>.</p></translation> + </message> + <message> + <source>You are already running the most recent version of VirtualBox.</source> + <translation>Jau naudotės naujausia VirtualBox versija.</translation> + </message> + <message> + <source><p>You have <b>clicked the mouse</b> inside the Virtual Machine display or pressed the <b>host key</b>. This will cause the Virtual Machine to <b>capture</b> the host mouse pointer (only if the mouse pointer integration is not currently supported by the guest OS) and the keyboard, which will make them unavailable to other applications running on your host machine.</p><p>You can press the <b>host key</b> at any time to <b>uncapture</b> the keyboard and mouse (if it is captured) and return them to normal operation. The currently assigned host key is shown on the status bar at the bottom of the Virtual Machine window, next to the&nbsp;<img src=:/hostkey_16px.png/>&nbsp;icon. This icon, together with the mouse icon placed nearby, indicate the current keyboard and mouse capture state.</p></source> + <translation><p><b>Spragtelėjote pele</b> virtualios mašinos lange arba nuspaudėte kompiuterio <b>pagrindinį klavišą (Host)</b>. Todėl virtuali mašina ims <b>reaguoti</b> į pagrindinio kompiuterio pelės žymeklį (tik jei svečio operacinė sistema nepalaiko pelės žymeklio integravimo) ir į klaviatūrą; į pelę ir klaiviatūrą nebereaguos jokios kitos pagrindinio kompiuterio programos.</p><p>Nuspaudus kompiuterio <b>pagrindinį klavišą (host)</b> bus<b>nebereaguojama</b> automatiškai į pelę ir klaviatūrą (jei buvo reaguojama) ir darbas vyks įprastu būdu. Šiuo metu kaip pagrindnis klavišas yra naudojamas tas, kuris rodomas virtualios mašinos lango apatiniame kampe ties&nbsp;<img src=:/hostkey_16px.png/>&nbsp;ženkliuku. Šis ir pelės ženkliukas rodo reagavimo į klaviatūrą ir pelę būseną.</p></translation> + </message> + <message> + <source><p>You have the <b>Auto capture keyboard</b> option turned on. This will cause the Virtual Machine to automatically <b>capture</b> the keyboard every time the VM window is activated and make it unavailable to other applications running on your host machine: when the keyboard is captured, all keystrokes (including system ones like Alt-Tab) will be directed to the VM.</p><p>You can press the <b>host key</b> at any time to <b>uncapture</b> the keyboard and mouse (if it is captured) and return them to normal operation. The currently assigned host key is shown on the status bar at the bottom of the Virtual Machine window, next to the&nbsp;<img src=:/hostkey_16px.png/>&nbsp;icon. This icon, together with the mouse icon placed nearby, indicate the current keyboard and mouse capture state.</p></source> + <translation><p>Įgalinta <b>Automatinio reagavimo į klaviatūrą</b> parinktis. Todėl virtuali mašina automatiškai <b>reaguos</b> į klaviatūros paspaudimus, jei virtualios mašinos langas bus aktyvus; tuomet į klaviatūrą nereaguos jokios kitos pagrindiniame kompiuteryje paleistos programos; netgi dauguma sparčiųjų klavišų (įskaitant Alt+Tab) bus tiesiogiai perduoti virtualiai mašinai.</p><p>Nuspaudus kompiuterio <b>pagrindinį klavišą (host)</b> bus<b>nebereaguojama</b> automatiškai į pelę ir klaviatūrą (jei buvo reaguojama) ir darbas vyks įprastu būdu. Šiuo metu kaip pagrindnis klavišas yra naudojamas tas, kuris rodomas virtualios mašinos lango apatiniame kampe ties&nbsp;<img src=:/hostkey_16px.png/>&nbsp;ženkliuku. Šis ir pelės ženkliukas rodo reagavimo į klaviatūrą ir pelę būseną.</p></translation> + </message> + <message> + <source><p>The Virtual Machine reports that the guest OS supports <b>mouse pointer integration</b>. This means that you do not need to <i>capture</i> the mouse pointer to be able to use it in your guest OS -- all mouse actions you perform when the mouse pointer is over the Virtual Machine's display are directly sent to the guest OS. If the mouse is currently captured, it will be automatically uncaptured.</p><p>The mouse icon on the status bar will look like&nbsp;<img src=:/mouse_seamless_16px.png/>&nbsp;to inform you that mouse pointer integration is supported by the guest OS and is currently turned on.</p><p><b>Note</b>: Some applications may behave incorrectly in mouse pointer integration mode. You can always disable it for the current session (and enable it again) by selecting the corresponding action from the menu bar.</p></source> + <translation><p>Virtuali mašina pranešė, kad svečio OS palaiko <b>pelės žymeklio integravimą</b>. Taigi nereikia nieko specialiai daryti, kad pelė <i>reaguotų</i> ir veiktų svečio operacinėje sistemoje -- visi jūsų atliekami pelės veiksmai, kai pelė bus virš virtualios mašinos ekrano, bus tiesiogiai siunčiami į svečio OS. O palikus langą, į pelę automatiškai nebebus reaguojama.</p><p>Pelės ženkliukas būsenos juostoje, atrodantis &nbsp;<img src=:/mouse_seamless_16px.png/>&nbsp;praneš, kad svečio OS palaiko pelės žymeklio integravimą ir yra naudojamasi šia funkcija.</p><p><b>Atminkite</b>: Kai kurios programos pelės žymeklio integravimo veiksenoje gali elgtis netinkamai. Tad galite uždrausti šią funkciją esamai sesijai (ir paskui vėl įgalinti) pasirinkę atitinkamą meniu juostos veiksmą.</p></translation> + </message> + <message> + <source><p>The virtual machine window will be now switched to <b>fullscreen</b> mode. You can go back to windowed mode at any time by pressing <b>%1</b>. Note that the <i>Host</i> key is currently defined as <b>%2</b>.</p><p>Note that the main menu bar is hidden in fullscreen mode. You can access it by pressing <b>Host+Home</b>.</p></source> + <translation><p>Virtualios mašinos langas netrukus pereis į <b>viso ekrano</b> veikseną. Į įprastą lango veikseną sugrįšite nuspaudę <b>%1</b>. Atminkite, kad <i>Pagrindinis</i> klavišas šiuo metu yra <b>%2</b>.</p><p>Be to, viso ekrano veiksenoje meniu juosta yra paslėpta. Ją pasieksite nuspaudę <b>Pagrindinis+Namai</b>.</p></translation> + </message> + <message> + <source><p>The virtual machine window will be now switched to <b>Seamless</b> mode. You can go back to windowed mode at any time by pressing <b>%1</b>. Note that the <i>Host</i> key is currently defined as <b>%2</b>.</p><p>Note that the main menu bar is hidden in seamless mode. You can access it by pressing <b>Host+Home</b>.</p></source> + <translation><p>Virtualios mašinos langas netrukus pereis į <b>integruoto darbalaukio</b> veikseną. Į įprastą lango veikseną sugrįšite nuspaudę <b>%1</b>. Atminkite, kad <i>Pagrindinis</i> klavišas šiuo metu yra <b>%2</b>.</p><p>Be to, integruotoje veiksenoje meniu juosta yra paslėpta. Ją pasieksite nuspaudę <b>Pagrindinis+Namai</b>.</p></translation> + </message> + <message> + <source>&Contents...</source> + <translation>&Turinys...</translation> + </message> + <message> + <source>Show the online help contents</source> + <translation>Rodyti nuotolinės pagalbos turinį</translation> + </message> + <message> + <source>&VirtualBox Web Site...</source> + <translation>&VirtualBox svetainė...</translation> + </message> + <message> + <source>Open the browser and go to the VirtualBox product web site</source> + <translation>Atverti naršyklę ir eiti į VirtualBox svetainę</translation> + </message> + <message> + <source>&Reset All Warnings</source> + <translation>&Pamiršti visus įspėjimus</translation> + </message> + <message> + <source>Go back to showing all suppressed warnings and messages</source> + <translation>Vėl rodyti visus įspėjimus ir pranešimus</translation> + </message> + <message> + <source>R&egister VirtualBox...</source> + <translation>&Užregistruoti VirtualBox...</translation> + </message> + <message> + <source>Open VirtualBox registration form</source> + <translation>VirtualBox užregistravimo forma</translation> + </message> + <message> + <source>C&heck for Updates...</source> + <translation>Tikrinti, ar yra at&naujinimų...</translation> + </message> + <message> + <source>Check for a new VirtualBox version</source> + <translation>Patikrinti, ar yra naujesnių VirtualBox versijų</translation> + </message> + <message> + <source>&About VirtualBox...</source> + <translation>&Apie VirtualBox...</translation> + </message> + <message> + <source>Show a dialog with product information</source> + <translation>Rodyti langą su produkto informacija</translation> + </message> + <message> + <source><p>A new version of VirtualBox has been released! Version <b>%1</b> is available at <a href="http://www.virtualbox.org/">virtualbox.org</a>.</p><p>You can download this version using the link:</p><p><a href=%2>%3</a></p></source> + <translation><p>Pasirodė nauja VirtualBox versija! Versija <b>%1</b> pasiekiama <a href="http://www.virtualbox.org/">virtualbox.org</a> svetainėje.</p><p>Šią versiją galite atsisiųsti spustelėję šią nuorodą: </p><p><a href=%2>%3</a></p></translation> + </message> + <message> + <source><p>Are you sure you want to release the %1 <nobr><b>%2</b></nobr>?</p><p>This will detach it from the following virtual machine(s): <b>%3</b>.</p></source> + <translation><p>Tikrai atlaisvinti %1 <nobr><b>%2</b></nobr>?</p><p>Tuomet laikmena nebebus susieta su šia (šiomis) virtualia(-iomis) mašina(-omis): <b>%3</b>.</p></translation> + </message> + <message> + <source>Release</source> + <comment>detach medium +</comment> + <translation>Atlaisvinti</translation> + </message> + <message> + <source><p>Are you sure you want to remove the %1 <nobr><b>%2</b></nobr> from the list of known media?</p></source> + <translation><p>Tikrai pašalinti %1 <nobr><b>%2</b></nobr> iš žinomų laikmenų sąrašo?</p></translation> + </message> + <message> + <source>Note that as this hard disk is inaccessible its storage unit cannot be deleted right now.</source> + <translation>Atminkite, kad šio standžiojo disko dabar negalima ištrinti, nes jis neprieinamas.</translation> + </message> + <message> + <source>The next dialog will let you choose whether you also want to delete the storage unit of this hard disk or keep it for later usage.</source> + <translation>Sekančiame puslapyje galėsite pasirinkti, ar ištrinti šį standųjį diską, ar išlaikyti vėlesniam naudojimui.</translation> + </message> + <message> + <source><p>Note that the storage unit of this medium will not be deleted and that it will be possible to add it to the list later again.</p></source> + <translation><p>Atminkite, kad ši laikmena nebus ištrinta, tad vėliau galėsite ją vėl įtraukti į sąrašą.</p></translation> + </message> + <message> + <source>Remove</source> + <comment>medium +</comment> + <translation>Pašalinti</translation> + </message> + <message> + <source><p>The hard disk storage unit at location <b>%1</b> already exists. You cannot create a new virtual hard disk that uses this location because it can be already used by another virtual hard disk.</p><p>Please specify a different location.</p></source> + <translation><p>Standusis diskas ties <b>%1</b> jau yra. Negalima sukurti kurti naujo virtualaus standžiojo disko, kuris užima tą pačią vietą.</p><p>Nurodykite kitą vietą.</p></translation> + </message> + <message> + <source><p>Do you want to delete the storage unit of the hard disk <nobr><b>%1</b></nobr>?</p><p>If you select <b>Delete</b> then the specified storage unit will be permanently deleted. This operation <b>cannot be undone</b>.</p><p>If you select <b>Keep</b> then the hard disk will be only removed from the list of known hard disks, but the storage unit will be left untouched which makes it possible to add this hard disk to the list later again.</p></source> + <translation><p>Tikrai norite ištrinti standųjį diską <nobr><b>%1</b></nobr>?</p><p>Jei renkatės <b>Pašalinti</b>, laikmena iš karto ištrinta <b>negrįžtamai</b>.</p><p>Jei renkatės <b>Išlaikyti</b>, standusis diskas bus pašalintas tik iš žinomų laikmenų sąrašo, bet jis nebus ištrintas kompiuteryje, tad vėiau jį vėl galėsite įtraukti į minėtą sąrašą.</p></translation> + </message> + <message> + <source>Delete</source> + <comment>hard disk storage +</comment> + <translation>Pašalinti</translation> + </message> + <message> + <source>Keep</source> + <comment>hard disk storage +</comment> + <translation>Išlaikyti</translation> + </message> + <message> + <source>Failed to delete the storage unit of the hard disk <b>%1</b>.</source> + <translation>Nepavyko pašalinti standžiojo disko kaupiklio <b>%1</b>.</translation> + </message> + <message> + <source>Failed to create the hard disk storage <nobr><b>%1</b>.</nobr></source> + <translation>Nepavyko sukurti standžiojo disko kaupiklio <nobr><b>%1</b>.</nobr></translation> + </message> + <message> + <source>Failed to open the %1 <nobr><b>%2</b></nobr>.</source> + <translation>Nepavyko atverti %1 <nobr><b>%2</b></nobr>.</translation> + </message> + <message> + <source>Failed to close the %1 <nobr><b>%2</b></nobr>.</source> + <translation>Nepavyko užverti %1 <nobr><b>%2</b></nobr>.</translation> + </message> + <message> + <source>Failed to determine the accessibility state of the medium <nobr><b>%1</b></nobr>.</source> + <translation>Nepavyko nustatyti <nobr><b>%1</b></nobr> laikmenos pasiekiamumo būsenos.</translation> + </message> + <message> + <source><p>Failed to connect to the VirtualBox online registration service due to the following error:</p><p><b>%1</b></p></source> + <translation><p>Nepavyko prisijungti prie VirtualBox nuotolinės registracijos paslaugos, nes įvyko klaida:</p><p><b>%1</b></p></translation> + </message> + <message> + <source><p>Unable to obtain the new version information due to the following error:</p><p><b>%1</b></p></source> + <translation><p>Nepavyksta gauti informacijos apie naują versiją, nes įvyko klaida:</p><p><b>%1</b></p></translation> + </message> + <message> + <source><p>One or more virtual hard disks, CD/DVD or floppy media are not currently accessible. As a result, you will not be able to operate virtual machines that use these media until they become accessible later.</p><p>Press <b>Check</b> to open the Virtual Media Manager window and see what media are inaccessible, or press <b>Ignore</b> to ignore this message.</p></source> + <translation><p>Vienas ar keli virtualūs standieji diskai, CD/DVD ar diskelių įrenginiai nebepasiekiami. Todėl negalėsite naudotis tomis virtualiomis mašinomis, kurios naudoja tas laikmenas tol, kol jos nebus pasiekiamos.</p><p>Norėdami atverti virtualių laikmenų tvarkytuvę ir pamatyti tas laikmenas, spauskite <b>Tikrinti</b>, o norėdami nekreipti dėmesio į šį pranešimą, spauskite <b>Nepaisyti</b>.</p></translation> + </message> + <message> + <source><p>A critical error has occurred while running the virtual machine and the machine execution has been stopped.</p><p>For help, please see the Community section on <a href=http://www.virtualbox.org>http://www.virtualbox.org</a> or your support contract. Please provide the contents of the log file <tt>VBox.log</tt> and the image file <tt>VBox.png</tt>, which you can find in the <nobr><b>%1</b></nobr> directory, as well as a description of what you were doing when this error happened. Note that you can also access the above files by selecting <b>Show Log</b> from the <b>Machine</b> menu of the main VirtualBox window.</p><p>Press <b>OK</b> if you want to power off the machine or press <b>Ignore</b> if you want to leave it as is for debugging. Please note that debugging requires special knowledge and tools, so it is recommended to press <b>OK</b> now.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>The following files already exist:<br /><br />%1<br /><br />Are you sure you want to replace them? Replacing them will overwrite their contents.</source> + <translation>Šios rinkmenos jau yra:<br /><br />%1<br /><br />Ar jas pakeisti? Tokiu atveju būtų perrašytas jų turinys.</translation> + </message> + <message> + <source>Failed to remove the file <b>%1</b>.<br /><br />Please try to remove the file yourself and try again.</source> + <translation>Nepavyko pašalinti rinkmenos <b>%1</b>.<br /><br />Pašalinkite savarankiškai ir bandykite iš naujo.</translation> + </message> + <message> + <source>You are running a prerelease version of VirtualBox. This version is not suitable for production use.</source> + <translation>Naudojate eksperimentinę VirtualBox versiją. Ši versija gali būti netinkama naudoti.</translation> + </message> + <message> + <source>Could not access USB on the host system, because neither the USB file system (usbfs) nor the DBus and hal services are currently available. If you wish to use host USB devices inside guest systems, you must correct this and restart VirtualBox.</source> + <translation>Nepavyksta pasiekti pagrindinio kompiuteryje esančių USB įrenginių, nes neprieinama nei USB rinkmenų sistema (usbfs), nei DBus su hal paslaugomis. Jei svečio sistemoje norite naudoti pagrindinio kompiuterio USB įrenginius, privalote pašalinti trūkumus ir iš naujo paleisti VirtualBox.</translation> + </message> + <message> + <source>You are trying to shut down the guest with the ACPI power button. This is currently not possible because the guest does not support software shutdown.</source> + <translation>Bandote virtualioje mašinoje nuspausti ACPI išjungimo mygtuką. Tai neįmanoma, nes svečio sistema nepalaiko programinio išjungimo.</translation> + </message> + <message> + <source><p>VT-x/AMD-V hardware acceleration has been enabled, but is not operational. Your 64-bit guest will fail to detect a 64-bit CPU and will not be able to boot.</p><p>Please ensure that you have enabled VT-x/AMD-V properly in the BIOS of your host computer.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Close VM</source> + <translation>Užverti virtualią mašiną</translation> + </message> + <message> + <source>Continue</source> + <translation>Tęsti</translation> + </message> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source><p>There are hard disks attached to ports of the additional controller. If you disable the additional controller, all these hard disks will be automatically detached.</p><p>Are you sure you want to disable the additional controller?</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><p>There are hard disks attached to ports of the additional controller. If you change the additional controller, all these hard disks will be automatically detached.</p><p>Are you sure you want to change the additional controller?</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Change</source> + <comment>hard disk +</comment> + <translation>Keisti</translation> + </message> + <message> + <source>Failed to create the host-only network interface.</source> + <translation>Nepavyko sukurti sąsajos prisijungimui tik prie pagrindinio kompiuterio.</translation> + </message> + <message> + <source><p>Your existing VirtualBox settings files will be automatically converted from the old format to a new format required by the new version of VirtualBox.</p><p>Press <b>OK</b> to start VirtualBox now or press <b>Exit</b> if you want to terminate the VirtualBox application without any further actions.</p></source> + <translation><p>Esamos VirtualBox nuostatų rinkmenos bus automatiškai konvertuotos iš seno į naują formatą, kurį naudoja naujoji VirtualBox versija.</p><p>Norėdami paleisti VirtualBox dabar, spauskite <b>Gerai</b>, o jei norite užverti VirtualBox nieko nedarant, spauskite <b>Baigti</b>.</p></translation> + </message> + <message> + <source>Failed to open appliance.</source> + <translation>Nepavyko atverti mašinos.</translation> + </message> + <message> + <source>Failed to open/interpret appliance <b>%1</b>.</source> + <translation>Nepavyko atverti/interpretuoti virtualios mašinos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to import appliance <b>%1</b>.</source> + <translation>Nepavyko importuoti virtualios mašinos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to create appliance.</source> + <translation>Nepavyko sukurti virtualios mašinos.</translation> + </message> + <message> + <source>Failed to prepare the export of the appliance <b>%1</b>.</source> + <translation>Nepavyko eksportavimui paruošti virtualios mašinos <b>%1</b>.</translation> + </message> + <message> + <source>Failed to create an appliance.</source> + <translation>Virtualios mašinos sukurti nepavyko.</translation> + </message> + <message> + <source>Failed to export appliance <b>%1</b>.</source> + <translation>Nepavyko eksportuoti virtualios mašinos <b>%1</b>.</translation> + </message> + <message> + <source><p>Deleting this host-only network will remove the host-only interface this network is based on. Do you want to remove the (host-only network) interface <nobr><b>%1</b>?</nobr></p><p><b>Note:</b> this interface may be in use by one or more virtual network adapters belonging to one of your VMs. After it is removed, these adapters will no longer be usable until you correct their settings by either choosing a different interface name or a different adapter attachment type.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>A file named <b>%1</b> already exists. Are you sure you want to replace it?<br /><br />Replacing it will overwrite its contents.</source> + <translation>Rinkmena pavadinimu <b>%1</b> jau yra. Ar ją pakeisti?<br /><br />Tokiu atveju būtų perrašytas jos turinys.</translation> + </message> + <message> + <source><p>VT-x/AMD-V hardware acceleration has been enabled, but is not operational. Certain guests (e.g. OS/2 and QNX) require this feature.</p><p>Please ensure that you have enabled VT-x/AMD-V properly in the BIOS of your host computer.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><p>Invalid e-mail address or password specified.</p></source> + <translation><p>Klaidingas el. pašto adresas arba slaptažodis.</p></translation> + </message> + <message> + <source><p>Failed to register the VirtualBox product.</p><p>%1</p></source> + <translation><p>Nepavyko užregistruoti VirtualBox produkto.</p><p>%1</p></translation> + </message> + <message> + <source>Failed to check files.</source> + <translation>Rinkmenų patikrinti nepavyko.</translation> + </message> + <message> + <source>Failed to remove file.</source> + <translation>Nepavyko pašalinti rinkmenos.</translation> + </message> + <message> + <source>You seem to have the USBFS filesystem mounted at /sys/bus/usb/drivers. We strongly recommend that you change this, as it is a severe mis-configuration of your system which could cause USB devices to fail in unexpected ways.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>You are running an EXPERIMENTAL build of VirtualBox. This version is not suitable for production use.</source> + <translation>Naudojate EKSPERIMENTINĘ VirtualBox versiją. Ši versija gali būti netinkama naudoti.</translation> + </message> + <message> + <source><p>Are you sure you want to restore snapshot <b>%1</b>? This will cause you to lose your current machine state, which cannot be recovered.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Restore</source> + <translation>Atkurti</translation> + </message> + <message> + <source><p>Deleting the snapshot will cause the state information saved in it to be lost, and disk data spread over several image files that VirtualBox has created together with the snapshot will be merged into one file. This can be a lengthy process, and the information in the snapshot cannot be recovered.</p></p>Are you sure you want to delete the selected snapshot <b>%1</b>?</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Delete</source> + <translation>Pašalinti</translation> + </message> + <message> + <source>Failed to restore the snapshot <b>%1</b> of the virtual machine <b>%2</b>.</source> + <translation>Nepavyko atkurti momentinio būvio iš kopijos <b>%1</b>, skirtos virtualiai mašinai <b>%2</b>.</translation> + </message> + <message> + <source>Failed to delete the snapshot <b>%1</b> of the virtual machine <b>%2</b>.</source> + <translation>Nepavyko pašalinti momentinės būvio kopijos <b>%1</b>, skirtos virtualiai mašinai <b>%2</b>.</translation> + </message> + <message> + <source><p>There are no unused media available for the newly created attachment.</p><p>Press the <b>Create</b> button to start the <i>New Virtual Disk</i> wizard and create a new medium, or press the <b>Select</b> if you wish to open the <i>Virtual Media Manager</i>.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>&Create</source> + <comment>medium +</comment> + <translation>Su&kurti</translation> + </message> + <message> + <source>&Select</source> + <comment>medium +</comment> + <translation>Pa&sirinkti</translation> + </message> + <message> + <source><p>There are no unused media available for the newly created attachment.</p><p>Press the <b>Select</b> if you wish to open the <i>Virtual Media Manager</i>.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Failed to attach the %1 to slot <i>%2</i> of the machine <b>%3</b>.</source> + <translation>Nepavyko prijungti %1 prie <i>%2</i> lizdo mašinoje <b>%3</b>.</translation> + </message> + <message> + <source>Failed to detach the %1 from slot <i>%2</i> of the machine <b>%3</b>.</source> + <translation>Nepavyko atjungti %1 nuo <i>%2</i> lizdo mašinoje <b>%3</b>.</translation> + </message> + <message> + <source>Unable to mount the %1 <nobr><b>%2</b></nobr> on the machine <b>%3</b>.</source> + <translation>Nepavyksta prijungti %1 <nobr><b>%2</b></nobr> prie mašinos <b>%3</b>.</translation> + </message> + <message> + <source> Would you like to force mounting of this medium?</source> + <translation> Ar šią laikmeną prijungti priverstinai?</translation> + </message> + <message> + <source>Unable to unmount the %1 <nobr><b>%2</b></nobr> from the machine <b>%3</b>.</source> + <translation>Nepavyksta atjungti %1 <nobr><b>%2</b></nobr> nuo mašinos <b>%3</b>.</translation> + </message> + <message> + <source> Would you like to force unmounting of this medium?</source> + <translation> Ar šią laikmeną atjungti priverstinai?</translation> + </message> + <message> + <source>Force Unmount</source> + <translation>Priverstinai atjungti</translation> + </message> + <message> + <source>Failed to eject the disk from the virtual drive. The drive may be locked by the guest operating system. Please check this and try again.</source> + <translation>Nepavyko išmesti disko iš virtualaus įrenginio. Įrenginį galbūt užblokavo svečio operacinė sistema. Patikrinkite ir bandykite iš naujo.</translation> + </message> + <message> + <source><p>Could not insert the VirtualBox Guest Additions installer CD image into the virtual machine <b>%1</b>, as the machine has no CD/DVD-ROM drives. Please add a drive using the storage page of the virtual machine settings dialog.</p></source> + <translation><p>Nepavyksta prijungti VirtualBox svečio papildinių diegimo CD atvaizdo prie virtualios mašinos <b>%1</b>, nes mašina neturi CD/DVD įrenginio.</p></translation> + </message> + <message> + <source>E&xit</source> + <comment>warnAboutSettingsAutoConversion message box +</comment> + <translation>&Baigti</translation> + </message> + <message> + <source><p>The following VirtualBox settings files will be automatically converted from the old format to a new format required by the new version of VirtualBox.</p><p>Press <b>OK</b> to start VirtualBox now or press <b>Exit</b> if you want to terminate the VirtualBox application without any further actions.</p></source> + <translation><p>Sekančios VirtualBox nuostatų rinkmenos bus automatiškai konvertuotos iš seno į naują formatą, kurį naudoja naujoji VirtualBox versija.</p><p>Norėdami paleisti VirtualBox dabar, spauskite <b>Gerai</b>, o jei norite užverti VirtualBox nieko nedarant, spauskite <b>Baigti</b>.</p></translation> + </message> + <message> + <source>hard disk</source> + <comment>failed to mount ... +</comment> + <translation>standžiojo disko</translation> + </message> + <message> + <source>CD/DVD</source> + <comment>failed to mount ... host-drive +</comment> + <translation>CD/DVD</translation> + </message> + <message> + <source>CD/DVD image</source> + <comment>failed to mount ... +</comment> + <translation>CD/DVD atvaizdo</translation> + </message> + <message> + <source>floppy</source> + <comment>failed to mount ... host-drive +</comment> + <translation>diskelio</translation> + </message> + <message> + <source>floppy image</source> + <comment>failed to mount ... +</comment> + <translation>diskelio atvaizdo</translation> + </message> + <message> + <source>hard disk</source> + <comment>failed to attach ... +</comment> + <translation>standžiojo disko</translation> + </message> + <message> + <source>CD/DVD device</source> + <comment>failed to attach ... +</comment> + <translation>CD/DVD įrenginio</translation> + </message> + <message> + <source>floppy device</source> + <comment>failed to close ... +</comment> + <translation>diskelių įrenginio</translation> + </message> + <message> + <source><p>Are you sure you want to delete the CD/DVD-ROM device?</p><p>You will not be able to mount any CDs or ISO images or install the Guest Additions without it!</p></source> + <translation><p>Tikrai pašalinti CD/DVD-ROM įrenginį?</p><p>Jei taip, negalėsite prijungti jokio CD ar ISO atvaizdo, negaėsite įdiegti svečio papildinių!</p></translation> + </message> + <message> + <source>&Remove</source> + <comment>medium +</comment> + <translation>Pašalin&ti</translation> + </message> + <message> + <source><p>VT-x/AMD-V hardware acceleration is not available on your system. Your 64-bit guest will fail to detect a 64-bit CPU and will not be able to boot.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><p>VT-x/AMD-V hardware acceleration is not available on your system. Certain guests (e.g. OS/2 and QNX) require this feature and will fail to boot without it.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><p>Deleting the snapshot %1 will temporarily need more disk space. In the worst case the size of image %2 will grow by %3, however on this filesystem there is only %4 free.</p><p>Running out of disk space during the merge operation can result in corruption of the image and the VM configuration, i.e. loss of the VM and its data.</p><p>You may continue with deleting the snapshot at your own risk.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><p>Could not change the guest screen to this host screen due to insufficient guest video memory.</p><p>You should configure the virtual machine to have at least <b>%1</b> of video memory.</p></source> + <translation><p>Nepakanka vaizdo atminties, kad būtų pakeistas svečio sistemos ekranas šiam pagrindinio kompiuterio ekranui.</p><p>Sukonfigūruokite virtualią mašiną taip, kad ji turėtų bent <b>%1</b> vaizdo atminties.</p></translation> + </message> + <message> + <source><p>Could not change the guest screen to this host screen due to insufficient guest video memory.</p><p>You should configure the virtual machine to have at least <b>%1</b> of video memory.</p><p>Press <b>Ignore</b> to switch the screen anyway or press <b>Cancel</b> to cancel the operation.</p></source> + <translation><p>Nepakanka vaizdo atminties, kad būtų pakeistas svečio sistemos ekranas šiam pagrindinio kompiuterio ekranui.</p><p>Sukonfigūruokite virtualią mašiną taip, kad ji turėtų bent <b>%1</b> vaizdo atminties.</p><p>Spauskite <b>Nepaisyti</b>, jei vis tiek norite pabandyti perjungti ekraną, arba spauskite <b>Atšaukti</b>.</p></translation> + </message> + <message> + <source><p>Can not switch the guest display to fullscreen mode. You have more virtual screens configured than physical screens are attached to your host.</p><p>Please either lower the virtual screens in your VM configuration or attach additional screens to your host.</p></source> + <translation><p>Nepavyksta svečio ekrano perjungti į viso ekrano veikseną. Sukonfigūravote daugiau virtualių ekranų nei yra fizinių ekranų, prijungtų prie pagrindinio kompiuterio.</p><p>Arba sumažinkite virtualių ekranų skaičių, arba prie pagrindinio kompiuterio prijunkite papildomų fizinių ekranų.</p></translation> + </message> + <message> + <source><p>Can not switch the guest display to seamless mode. You have more virtual screens configured than physical screens are attached to your host.</p><p>Please either lower the virtual screens in your VM configuration or attach additional screens to your host.</p></source> + <translation><p>Nepavyksta svečio ekrano perjungti į integruoto darbalaukio veikseną. Sukonfigūravote daugiau virtualių ekranų nei yra fizinių ekranų, prijungtų prie pagrindinio kompiuterio.</p><p>Arba sumažinkite virtualių ekranų skaičių, arba prie pagrindinio kompiuterio prijunkite papildomų fizinių ekranų.</p></translation> + </message> + <message> + <source><p>Could not find the VirtualBox User Manual <nobr><b>%1</b>.</nobr></p><p>Do you wish to download this file from the Internet?</p></source> + <translation><p>Nepavyksta rasti VirtualBox naudotojo žinyno <nobr><b>%1</b>.</nobr></p><p>Ar parsiųsti jį iš interneto?</p></translation> + </message> + <message> + <source><p>Are you sure you want to download the VirtualBox User Manual from <nobr><a href="%1">%2</a></nobr> (size %3 bytes)?</p></source> + <translation><p>Tikrai parsiųsti VirtualBox naudotojo žinyną iš <nobr><a href="%1">%2</a></nobr> (%3 baitų dydžio)?</p></translation> + </message> + <message> + <source><p>Failed to download the VirtualBox User Manual from <nobr><a href="%1">%2</a>.</nobr></p><p>%3</p></source> + <translation><p>Nepavyko parsiųsti VirtualBox naudojo žinyno iš <nobr><a href="%1">%2</a>.</nobr></p><p>%3</p></translation> + </message> + <message> + <source><p>The VirtualBox User Manual has been successfully downloaded from <nobr><a href="%1">%2</a></nobr> and saved locally as <nobr><b>%3</b>.</nobr></p></source> + <translation><p>Sėkmingai parsiųstas VirtualBox naudotojo žinynas iš <nobr><a href="%1">%2</a></nobr> ir įrašytas vietinėje sistemoje kaip <nobr><b>%3</b>.</nobr></p></translation> + </message> + <message> + <source><p>The VirtualBox User Manual has been successfully downloaded from <nobr><a href="%1">%2</a></nobr> but can't be saved locally as <nobr><b>%3</b>.</nobr></p><p>Please choose another location for that file.</p></source> + <translation><p>Sėkmingai parsiųstas VirtualBox naudotojo žinynas iš <nobr><a href="%1">%2</a></nobr>, tačiau nepavyksta jo įrašyti vietinėje sistemoje kaip <nobr><b>%3</b>.</nobr></p><p>Nurodykite kitą rinkmenos įrašymo vietą.</p></translation> + </message> +</context> +<context> + <name>VBoxProgressDialog</name> + <message> + <source>A few seconds remaining</source> + <translation>Liko kelios sekundės</translation> + </message> + <message> + <source>Canceling...</source> + <translation>Atšaukiama...</translation> + </message> + <message> + <source>&Cancel</source> + <translation>&Atšaukti</translation> + </message> + <message> + <source>Cancel the current operation</source> + <translation>Atšaukti dabartinį veiksmą</translation> + </message> + <message> + <source>%1, %2 remaining</source> + <comment>You may wish to translate this more like "Time remaining: %1, %2" +</comment> + <translation>Liko: %1 %2</translation> + </message> + <message> + <source>%1 remaining</source> + <comment>You may wish to translate this more like "Time remaining: %1" +</comment> + <translation>Liko: %1</translation> + </message> +</context> +<context> + <name>VBoxSFDialog</name> + <message> + <source>Shared Folders</source> + <translation>Bendrieji aplankai</translation> + </message> +</context> +<context> + <name>VBoxScreenshotViewer</name> + <message> + <source>Screenshot of %1 (%2)</source> + <translation>%1 momentinis būvis (%2)</translation> + </message> + <message> + <source>Click to view non-scaled screenshot.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Click to view scaled screenshot.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>VBoxSelectorWnd</name> + <message> + <source>VirtualBox OSE</source> + <translation>VirtualBox OSE</translation> + </message> + <message> + <source>&Details</source> + <translation>&Detalės</translation> + </message> + <message> + <source>&Preferences...</source> + <comment>global settings +</comment> + <translation>Nuos&tatos...</translation> + </message> + <message> + <source>Display the global settings dialog</source> + <translation>Keisti bendras nuostatas</translation> + </message> + <message> + <source>E&xit</source> + <translation>&Baigti</translation> + </message> + <message> + <source>Close application</source> + <translation>Užverti VirtualBox</translation> + </message> + <message> + <source>&New...</source> + <translation>&Nauja...</translation> + </message> + <message> + <source>Create a new virtual machine</source> + <translation>Sukurti naują virtualią mašiną</translation> + </message> + <message> + <source>&Settings...</source> + <translation>Nuo&statos...</translation> + </message> + <message> + <source>Configure the selected virtual machine</source> + <translation>Konfigūruoti pasirinktą virtualią mašiną</translation> + </message> + <message> + <source>&Delete</source> + <translation>Paša&linti</translation> + </message> + <message> + <source>Delete the selected virtual machine</source> + <translation>Pašalinti pasirinktą virtualią mašiną</translation> + </message> + <message> + <source>D&iscard</source> + <translation>At&mesti</translation> + </message> + <message> + <source>Discard the saved state of the selected virtual machine</source> + <translation>Panaikinti išsaugotą pasirinktos virtualios mašinos būvį</translation> + </message> + <message> + <source>Refresh the accessibility state of the selected virtual machine</source> + <translation>Atnaujinti pasirinktos virtualios mašinos pasiekiamumo būseną</translation> + </message> + <message> + <source>&Help</source> + <translation>&Pagalba</translation> + </message> + <message> + <source>&Snapshots</source> + <translation>&Momentiniai būviai</translation> + </message> + <message> + <source>D&escription</source> + <translation>&Aprašymas</translation> + </message> + <message> + <source>D&escription *</source> + <translation>&Aprašymas *</translation> + </message> + <message> + <source>S&how</source> + <translation>&Rodyti</translation> + </message> + <message> + <source>Switch to the window of the selected virtual machine</source> + <translation>Pereiti į pasirinktos virtualios mašinos langą</translation> + </message> + <message> + <source>S&tart</source> + <translation>&Paleisti</translation> + </message> + <message> + <source>Start the selected virtual machine</source> + <translation>Paleisti pasirinktą virtualią mašiną</translation> + </message> + <message> + <source>&Machine</source> + <translation>&Mašina</translation> + </message> + <message> + <source>Show &Log...</source> + <translation>Peržiūrėti ž&urnalus...</translation> + </message> + <message> + <source>Show the log files of the selected virtual machine</source> + <translation>Rodyti pasirinktos virtualios mašinos žurnalus</translation> + </message> + <message> + <source>R&esume</source> + <translation>&Tęsti</translation> + </message> + <message> + <source>Resume the execution of the virtual machine</source> + <translation>Tęsti pristabdytos virtualios mašinos darbą</translation> + </message> + <message> + <source>&Pause</source> + <translation>&Pristabdyti</translation> + </message> + <message> + <source>Suspend the execution of the virtual machine</source> + <translation>Sustabdyti virtualią mašiną jos būseną išsaugant diske</translation> + </message> + <message> + <source><h3>Welcome to VirtualBox!</h3><p>The left part of this window is a list of all virtual machines on your computer. The list is empty now because you haven't created any virtual machines yet.<img src=:/welcome.png align=right/></p><p>In order to create a new virtual machine, press the <b>New</b> button in the main tool bar located at the top of the window.</p><p>You can press the <b>%1</b> key to get instant help, or visit <a href=http://www.virtualbox.org>www.virtualbox.org</a> for the latest information and news.</p></source> + <translation><h3>Jus sveikina VirtualBox!</h3><p>Kairėje lango pusėje pateikiamas visų Jūsų virtualių mašinų sąrašas. Kol kas šis sąrašas tuščias, kadangi dar nesukūrėte nei vienos virtualios mašinos.<img src=:/welcome.png align=right/></p><p>Norėdami sukurti naują VM, spauskite mygtuką <b>Nauja</b>, kuris yra pagrindinėje įrankių juostoje lango viršuje.</p><p>Trumpą pagalbą gausite nuspaudę <b>%1</b>. Naujausią informaciją rasite apsilankę svetainėje<a href=http://www.virtualbox.org>www.virtualbox.org</a>.</p></translation> + </message> + <message> + <source>&Virtual Media Manager...</source> + <translation>&Virtualių laikmenų tvarkytuvė...</translation> + </message> + <message> + <source>Display the Virtual Media Manager dialog</source> + <translation>Atveria virtualių laikmenų tvarkytuvę</translation> + </message> + <message> + <source>Log</source> + <comment>icon text +</comment> + <translation>Žurnalas</translation> + </message> + <message> + <source>&Import Appliance...</source> + <translation>&Importuoti virtualią mašiną...</translation> + </message> + <message> + <source>Import an appliance into VirtualBox</source> + <translation>Importuoja mašiną į VirtualBox</translation> + </message> + <message> + <source>&Export Appliance...</source> + <translation>&Eksportuoti virtualią mašiną...</translation> + </message> + <message> + <source>Export one or more VirtualBox virtual machines as an appliance</source> + <translation>Eksportuoja vieną ar kelias VirtualBox virtualias mašinas</translation> + </message> + <message> + <source>Re&fresh</source> + <translation>&Atnaujinti</translation> + </message> + <message> + <source>&File</source> + <comment>Mac OS X version +</comment> + <translation>&Rinkmena</translation> + </message> + <message> + <source>&File</source> + <comment>Non Mac OS X version +</comment> + <translation>&Rinkmena</translation> + </message> +</context> +<context> + <name>VBoxSettingsDialog</name> + <message> + <source><i>Select a settings category from the list on the left-hand side and move the mouse over a settings item to get more information</i>.</source> + <translation><i>Iš sąrašo kairėje pusėje pasirinkite nuostatų grupę. Užvedę pelę virš +konkrečių nuostatų, matysite paaiškinimus<i>.</translation> + </message> + <message> + <source>Invalid settings detected</source> + <translation>Rastos netinkamos nuostatos</translation> + </message> + <message> + <source>Settings</source> + <translation>Nuostatos</translation> + </message> + <message> + <source>Non-optimal settings detected</source> + <translation>Rastos ne itin gerai tinkančios nuostatos</translation> + </message> + <message> + <source>On the <b>%1</b> page, %2</source> + <translation>Ties <b>%1</b>, %2</translation> + </message> +</context> +<context> + <name>VBoxSnapshotDetailsDlg</name> + <message> + <source>Details of %1 (%2)</source> + <translation>%1 detalės (%2)</translation> + </message> + <message> + <source>Click to enlarge the screenshot.</source> + <translation>Norėdami padidinti nuotrauką, spragtelėkite.</translation> + </message> + <message> + <source>&Name:</source> + <translation>&Pavadinimas:</translation> + </message> + <message> + <source>Taken:</source> + <translation>Sukurta:</translation> + </message> + <message> + <source>&Description:</source> + <translation>&Aprašymas:</translation> + </message> + <message> + <source>D&etails:</source> + <translation>&Detalės :</translation> + </message> +</context> +<context> + <name>VBoxSnapshotsWgt</name> + <message> + <source>VBoxSnapshotsWgt</source> + <translation>VBoxSnapshotsWgt</translation> + </message> + <message> + <source>Current State (changed)</source> + <comment>Current State (Modified) +</comment> + <translation>Dabartinė būsena (pakeista)</translation> + </message> + <message> + <source>Current State</source> + <comment>Current State (Unmodified) +</comment> + <translation>Dabartinė būsena</translation> + </message> + <message> + <source>The current state differs from the state stored in the current snapshot</source> + <translation>Dabartinė būsena skiriasi nuo išsaugotosios momentinio būvio kopijoje</translation> + </message> + <message> + <source>The current state is identical to the state stored in the current snapshot</source> + <translation>Dabartinė būsena yra tokia pati kaip ir išsaugotoji momentinio būvio kopijoje</translation> + </message> + <message> + <source> (current, </source> + <comment>Snapshot details +</comment> + <translation> (dabartinė, </translation> + </message> + <message> + <source>online)</source> + <comment>Snapshot details +</comment> + <translation>prisijungta)</translation> + </message> + <message> + <source>offline)</source> + <comment>Snapshot details +</comment> + <translation>atsijungta)</translation> + </message> + <message> + <source>Taken at %1</source> + <comment>Snapshot (time) +</comment> + <translation>Sukurta %1</translation> + </message> + <message> + <source>Taken on %1</source> + <comment>Snapshot (date + time) +</comment> + <translation>Sukurta %1</translation> + </message> + <message> + <source>%1 since %2</source> + <comment>Current State (time or date + time) +</comment> + <translation>%1 nuo %2</translation> + </message> + <message> + <source>Snapshot %1</source> + <translation>Momentinė kopija Nr. %1</translation> + </message> + <message> + <source>Take &Snapshot</source> + <translation>&Sukurti dabartinio momentinio būvio kopiją</translation> + </message> + <message> + <source>S&how Details</source> + <translation>Parodyti &detales</translation> + </message> + <message> + <source>Take a snapshot of the current virtual machine state</source> + <translation>Padaryti virtualios mašinos dabartinio būvio kopiją</translation> + </message> + <message> + <source>Show the details of the selected snapshot</source> + <translation>Rodyti daugiau informacijos apie pasirinktą momentinio būvio kopiją</translation> + </message> + <message> + <source> (%1)</source> + <translation> (%1)</translation> + </message> + <message> + <source>&Restore Snapshot</source> + <translation>&Atkurti momentinį būvį</translation> + </message> + <message> + <source>&Delete Snapshot</source> + <translation>&Pašalinti momentinį būvį</translation> + </message> + <message> + <source>Restore the selected snapshot of the virtual machine</source> + <translation>Atkurti virtualios mašinos būseną iš pasirinkto momentinio būvio kopijos</translation> + </message> + <message> + <source>Delete the selected snapshot of the virtual machine</source> + <translation>Ištrinti pasirinktą virtualios mašinos momentinio būvio kopiją</translation> + </message> + <message> + <source> (%1 ago)</source> + <translation> (prieš %1)</translation> + </message> +</context> +<context> + <name>VBoxSwitchMenu</name> + <message> + <source>Disable</source> + <translation>Uždrausti</translation> + </message> + <message> + <source>Enable</source> + <translation>Įgalinti</translation> + </message> +</context> +<context> + <name>VBoxTakeSnapshotDlg</name> + <message> + <source>Take Snapshot of Virtual Machine</source> + <translation>Padaryti virtualios mašinos dabartinio būvio momentinę kopiją</translation> + </message> + <message> + <source>Snapshot &Name</source> + <translation>Momentinio būvio &pavadinimas</translation> + </message> + <message> + <source>Snapshot &Description</source> + <translation>Momentinio būvio &aprašymas</translation> + </message> + <message numerus="yes"> + <source>Warning: You are taking a snapshot of a running machine which has %n immutable image(s) attached to it. As long as you are working from this snapshot the immutable image(s) will not be reset to avoid loss of data.</source> + <translatorcomment>Avertissement: vous êtes en train de saisir un instantané d'une machine en cours d'exécution avec %n images disque immuable connecté. Tant que vous travaillez sous cet instantané, les image ne sera pas réinitialisé pour éviter la perte de donnés.</translatorcomment> + <translation> + <numerusform>Dėmesio: jūs mėginate sukurti momentinę būvio kopiją veikiančios mašinos, kuri turi %n priskirtą nekeičiamų atvaizdų. Kol dirbdate su šiuo būviu, tol nekeičiami atvaizdai nebus perstatyti siekiant išvengti duomenų praradimo.</numerusform> + <numerusform>Dėmesio: jūs mėginate sukurti momentinę būvio kopiją veikiančios mašinos, kuri turi %n priskirtus nekeičiamų atvaizdų. Kol dirbdate su šiuo būviu, tol nekeičiami atvaizdai nebus perstatyti siekiant išvengti duomenų praradimo.</numerusform> + <numerusform>Dėmesio: jūs mėginate sukurti momentinę būvio kopiją veikiančios mašinos, kuri turi %n priskirtų nekeičiamų atvaizdų. Kol dirbdate su šiuo būviu, tol nekeičiami atvaizdai nebus perstatyti siekiant išvengti duomenų praradimo.</numerusform> + </translation> + </message> +</context> +<context> + <name>VBoxTextEditor</name> + <message> + <source>Edit text</source> + <translation>Redaguoti tekstą</translation> + </message> + <message> + <source>&Replace...</source> + <translation>&Pakeisti...</translation> + </message> + <message> + <source>Replaces the current text with the content of a file.</source> + <translation>Šį tekstą pakeisti rinkmenos turiniu.</translation> + </message> + <message> + <source>Text (*.txt);;All (*.*)</source> + <translation>Tekstas (*.txt);;Visos (*.*)</translation> + </message> + <message> + <source>Select a file to open...</source> + <translation>Pasirinkite atvertiną rinkmeną...</translation> + </message> +</context> +<context> + <name>VBoxTrayIcon</name> + <message> + <source>Show Selector Window</source> + <translation>Rodyti pasirinktą langą</translation> + </message> + <message> + <source>Show the selector window assigned to this menu</source> + <translation>Rodyti su šiuo meniu susijusį pasirinkimo langą</translation> + </message> + <message> + <source>Hide Tray Icon</source> + <translation>Ženkliuką nuleisti į sistemos dėklą</translation> + </message> + <message> + <source>Remove this icon from the system tray</source> + <translation>Pašalinti sistemos dėklo ženkliuką</translation> + </message> + <message> + <source>&Other Machines...</source> + <comment>tray menu +</comment> + <translation>&Kitos mašinos...</translation> + </message> +</context> +<context> + <name>VBoxUSBMenu</name> + <message> + <source><no devices available></source> + <comment>USB devices +</comment> + <translation><nėra įrenginių></translation> + </message> + <message> + <source>No supported devices connected to the host PC</source> + <comment>USB device tooltip +</comment> + <translation>Prie kompiuterio nėra prijungtų palaikomų įrenginių</translation> + </message> +</context> +<context> + <name>VBoxUpdateDlg</name> + <message> + <source>1 day</source> + <translation>1 dieną</translation> + </message> + <message> + <source>2 days</source> + <translation>2 dienas</translation> + </message> + <message> + <source>3 days</source> + <translation>3 dienas</translation> + </message> + <message> + <source>4 days</source> + <translation>4 dienas</translation> + </message> + <message> + <source>5 days</source> + <translation>5 dienas</translation> + </message> + <message> + <source>6 days</source> + <translation>6 dienas</translation> + </message> + <message> + <source>1 week</source> + <translation>1 savaitę</translation> + </message> + <message> + <source>2 weeks</source> + <translation>2 savaites</translation> + </message> + <message> + <source>3 weeks</source> + <translation>3 savaites</translation> + </message> + <message> + <source>1 month</source> + <translation>1 mėnesį</translation> + </message> + <message> + <source>Never</source> + <translation>Niekada</translation> + </message> + <message> + <source>Chec&k</source> + <translation>&Tikrinti</translation> + </message> + <message> + <source>&Close</source> + <translation>&Užverti</translation> + </message> + <message> + <source>VirtualBox Update Wizard</source> + <translation>VirtualBox atnaujinimo vediklis</translation> + </message> + <message> + <source>Check for Updates</source> + <translation>Tikrinti, ar yra atnaujinimų</translation> + </message> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>Summary</source> + <translation>Santrauka</translation> + </message> + <message> + <source><p>A new version of VirtualBox has been released! Version <b>%1</b> is available at <a href="http://www.virtualbox.org/">virtualbox.org</a>.</p><p>You can download this version using the link:</p><p><a href=%2>%3</a></p></source> + <translation><p>Pasirodė nauja VirtualBox versija! Versija <b>%1</b> pasiekiama <a href="http://www.virtualbox.org/">virtualbox.org</a> svetainėje.</p><p>Šią versiją galite atsisiųsti spustelėję šią nuorodą: </p><p><a href=%2>%3</a></p></translation> + </message> + <message> + <source><p>Unable to obtain the new version information due to the following network error:</p><p><b>%1</b></p></source> + <translation><p>Nepavyksta gauti informacijos apie naujas versijas dėl tinklo ryšio klaidos: </p><p><b>%1</b></p></translation> + </message> + <message> + <source>You are already running the most recent version of VirtualBox.</source> + <translation>Jau naudotės naujausia VirtualBox versija.</translation> + </message> + <message> + <source><p>This wizard will connect to the VirtualBox web-site and check if a newer version of VirtualBox is available.</p><p>Use the <b>Check</b> button to check for a new version now or the <b>Cancel</b> button if you do not want to perform this check.</p><p>You can run this wizard at any time by choosing <b>Check for Updates...</b> from the <b>Help</b> menu.</p></source> + <translation><p>Šis vediklis prisijungs prie VirtualBox svetainės ir patikrins, ar yra naujesnių VirtualBox versijų.</p><p>Tikrinimą pradėsite iš karto nuspaudę <b>Tikrinti</b>; o jei nenorite ieškoti galimų atnaujinimų, spauskite <b>Atšaukti</b>.</p><p>Šį vediklį galite paleisti ir bet kada vėliau iš <b>Pagalbos</b> meniu pasirinkę <b>Tikrinti, ar yra atnaujinimų...</b></translation> + </message> +</context> +<context> + <name>VBoxVMDescriptionPage</name> + <message> + <source>No description. Press the Edit button below to add it.</source> + <translation>Aprašymo nėra. Norėdami pridėti aprašymą, spauskite mygtuką „Keisti“.</translation> + </message> + <message> + <source>Edit</source> + <translation>Keisti</translation> + </message> + <message> + <source>Edit (Ctrl+E)</source> + <translation>Keisti (Vald+E)</translation> + </message> +</context> +<context> + <name>VBoxVMDetailsView</name> + <message> + <source>The selected virtual machine is <i>inaccessible</i>. Please inspect the error message shown below and press the <b>Refresh</b> button if you want to repeat the accessibility check:</source> + <translation>Virtuali mašina <i>nepasiekiama</i>. Atidžiai perskaitykite klaidos žemiau pateikt pranešimą. Jei norite iš naujo pabandyti pasiekti virtualią mašiną, spauskite mygtuką <b>Atnaujinti</b>:</translation> + </message> +</context> +<context> + <name>VBoxVMInformationDlg</name> + <message> + <source>%1 - Session Information</source> + <translation>%1 - sesijos informacija</translation> + </message> + <message> + <source>&Details</source> + <translation>&Detalės</translation> + </message> + <message> + <source>&Runtime</source> + <translation>&Vykdymas</translation> + </message> + <message> + <source>DMA Transfers</source> + <translation>DMA perdavimai</translation> + </message> + <message> + <source>PIO Transfers</source> + <translation>PIO perdavimai</translation> + </message> + <message> + <source>Data Read</source> + <translation>Perskaityta duomenų</translation> + </message> + <message> + <source>Data Written</source> + <translation>Įrašyta duomenų</translation> + </message> + <message> + <source>Data Transmitted</source> + <translation>Perduota duomenų</translation> + </message> + <message> + <source>Data Received</source> + <translation>Gauta duomenų</translation> + </message> + <message> + <source>Runtime Attributes</source> + <translation>Vykdymo ypatybės</translation> + </message> + <message> + <source>Screen Resolution</source> + <translation>Ekrano skiriamoji geba</translation> + </message> + <message> + <source>Not Detected</source> + <comment>guest additions +</comment> + <translation>Neaptikta</translation> + </message> + <message> + <source>Not Detected</source> + <comment>guest os type +</comment> + <translation>Neaptikta</translation> + </message> + <message> + <source>Guest Additions</source> + <translation>Svečio papildiniai</translation> + </message> + <message> + <source>Guest OS Type</source> + <translation>Svečio OS tipas</translation> + </message> + <message> + <source>No Network Adapters</source> + <translation>Tinklo plokščių nėra</translation> + </message> + <message> + <source>VBoxVMInformationDlg</source> + <translation>VBoxVMInformationDlg</translation> + </message> + <message> + <source>Not Available</source> + <comment>details report (VRDP server port) +</comment> + <translation>Neprieinama</translation> + </message> + <message> + <source>Storage Statistics</source> + <translation>Atminties įrenginių statistika</translation> + </message> + <message> + <source>No Storage Devices</source> + <translation>Atminties įrenginių nėra</translation> + </message> + <message> + <source>Network Statistics</source> + <translation>Tinklo statistika</translation> + </message> +</context> +<context> + <name>UIVMListView</name> + <message> + <source>Inaccessible</source> + <translation>Neprieinama</translation> + </message> + <message> + <source><nobr>%1<br></nobr><nobr>%2 since %3</nobr><br><nobr>Session %4</nobr></source> + <comment>VM tooltip (name, last state change, session state) +</comment> + <translation><nobr>%1<br></nobr><nobr>%2 nuo %3</nobr><br><nobr>Sesija %4</nobr></translation> + </message> + <message> + <source><nobr><b>%1</b><br></nobr><nobr>Inaccessible since %2</nobr></source> + <comment>Inaccessible VM tooltip (name, last state change) +</comment> + <translation><nobr><b>%1</b><br></nobr><nobr>neprienama nuo %2</nobr></translation> + </message> + <message> + <source>S&how</source> + <translation>&Rodyti</translation> + </message> + <message> + <source>Switch to the window of the selected virtual machine</source> + <translation>Pereiti į pasirinktos virtualios mašinos langą</translation> + </message> + <message> + <source>S&tart</source> + <translation>&Paleisti</translation> + </message> + <message> + <source>Start the selected virtual machine</source> + <translation>Paleisti pasirinktą virtualią mašiną</translation> + </message> + <message> + <source>R&esume</source> + <translation>&Tęsti</translation> + </message> + <message> + <source>Resume the execution of the virtual machine</source> + <translation>Tęsti pristabdytos virtualios mašinos darbą</translation> + </message> + <message> + <source>&Pause</source> + <translation>&Pristabdyti</translation> + </message> + <message> + <source>Suspend the execution of the virtual machine</source> + <translation>Sustabdyti virtualią mašiną jos būseną išsaugant diske</translation> + </message> +</context> +<context> + <name>VBoxVMLogViewer</name> + <message> + <source>Log Viewer</source> + <translation>Žurnalų peržiūra</translation> + </message> + <message> + <source>&Save</source> + <translation>Į&rašyti</translation> + </message> + <message> + <source>&Refresh</source> + <translation>&Atnaujinti</translation> + </message> + <message> + <source>%1 - VirtualBox Log Viewer</source> + <translation>%1 - VirtualBox žurnalų peržiūra</translation> + </message> + <message> + <source><p>No log files found. Press the <b>Refresh</b> button to rescan the log folder <nobr><b>%1</b></nobr>.</p></source> + <translation><p>Žurnalų nėra. Norėdami iš naujo nuskaityti žurnalų aplanką <nobr><b>%1</b></nobr>, spauskite <b>Atnaujinti</b>.</p></translation> + </message> + <message> + <source>Save VirtualBox Log As</source> + <translation>VirtualBox žurnalą įrašyti kaip</translation> + </message> + <message> + <source>&Find</source> + <translation>&Ieškoti</translation> + </message> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsAudio</name> + <message> + <source>When checked, a virtual PCI audio card will be plugged into the virtual machine and will communicate with the host audio system using the specified driver.</source> + <translation>Jei pasirinkta, virtuali garso plokštė bus prijungta prie virtualios mašinos. Plokštė bendraus su pagrindiniu kompiuteriu per nurodytą tvarkyklę.</translation> + </message> + <message> + <source>Enable &Audio</source> + <translation>Įgalinti &garsą</translation> + </message> + <message> + <source>Host Audio &Driver:</source> + <translation>Pagrindinio kompiuterio garso &tvarkyklė:</translation> + </message> + <message> + <source>Controls the audio output driver. The <b>Null Audio Driver</b> makes the guest see an audio card, however every access to it will be ignored.</source> + <translation>Valdo garso išvesties tvarkyklę. Pasirinkus <b>Be garso tvarkyklės</b>, garso plokštė taip pat bus simuliuojama, tačiau bus nepaisoma bet kokio priėjimo prie jos.</translation> + </message> + <message> + <source>Audio &Controller:</source> + <translation>Garso &valdiklis: </translation> + </message> + <message> + <source>Selects the type of the virtual sound card. Depending on this value, VirtualBox will provide different audio hardware to the virtual machine.</source> + <translation>Parenka virtualios garso plokštės tipą. Ši reikšmė nurodo garso plokštę, kurią VirtualBox įrengs virtualioje mašinoje.</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsDisplay</name> + <message> + <source>you have assigned less than <b>%1</b> of video memory which is the minimum amount required to switch the virtual machine to fullscreen or seamless mode.</source> + <translation>vaizdo atminčiai paskyrėte mažiau kaip <b>%1</b>. Pastarasis dydis yra mažiausias amtinties kiekis, kurio reikia mašinai pereiti į viso ekrano arbą integruotą darbastalio veikseną.</translation> + </message> + <message> + <source><qt>%1&nbsp;MB</qt></source> + <translation><qt>%1&nbsp;MB</qt></translation> + </message> + <message> + <source>&Video</source> + <translation>&Vaizdas</translation> + </message> + <message> + <source>Video &Memory:</source> + <translation>&Vaizdo atmintis:</translation> + </message> + <message> + <source>Controls the amount of video memory provided to the virtual machine.</source> + <translation>Nurodo, kiek virtuali mašina gali išnaudoti vaizdo atminties.</translation> + </message> + <message> + <source>MB</source> + <translation>MB</translation> + </message> + <message> + <source>Extended Features:</source> + <translation>Papildomos savybės:</translation> + </message> + <message> + <source>When checked, the virtual machine will be given access to the 3D graphics capabilities available on the host.</source> + <translation>Pažymėjus, virtualiai mašinai bus leista naudotis pagrindinio kompiuterio 3D vaizdo funkcijomis.</translation> + </message> + <message> + <source>Enable &3D Acceleration</source> + <translation>Įgalinti &3D spartinimą</translation> + </message> + <message> + <source>&Remote Display</source> + <translation>&Nuotolinis ekranas</translation> + </message> + <message> + <source>When checked, the VM will act as a Remote Desktop Protocol (RDP) server, allowing remote clients to connect and operate the VM (when it is running) using a standard RDP client.</source> + <translation>Pažymėjus, VM veiks kaip nuotolinio darbastalio (RDP) serveris, kuris leidiža nuotoliniams klientams prisijungti prie VM ir ją valdyti (jos veikimo metu) naudojant įprastą RDP klientą.</translation> + </message> + <message> + <source>&Enable Server</source> + <translation>Į&galinti serverį</translation> + </message> + <message> + <source>Server &Port:</source> + <translation>Serverio &prievadas: </translation> + </message> + <message> + <source>Authentication &Method:</source> + <translation>Atpažinimo &būdas:</translation> + </message> + <message> + <source>Defines the VRDP authentication method.</source> + <translation>Nurodo VRDP atpažinimo būdą.</translation> + </message> + <message> + <source>Authentication &Timeout:</source> + <translation>Atpažinimo &delsa:</translation> + </message> + <message> + <source>Specifies the timeout for guest authentication, in milliseconds.</source> + <translation>Nurodo laiką, per kurį svečias gali mėginti prisijungti, milisekundėmis.</translation> + </message> + <message> + <source>you have assigned less than <b>%1</b> of video memory which is the minimum amount required for HD Video to be played efficiently.</source> + <translation>vaizdo atminčiai paskyrėte mažiau kaip <b>%1</b>. Pastarasis dydis yra mažiausias amtinties kiekis, kurio reikia be trikdžių peržiūrint HD vaizdo kūrinius.</translation> + </message> + <message> + <source>When checked, the virtual machine will be given access to the Video Acceleration capabilities available on the host.</source> + <translation>Pažymėjus, virtualiai mašinai bus leista naudotis pagrindinio kompiuterio vaizdo spartinimo funkcijomis.</translation> + </message> + <message> + <source>Enable &2D Video Acceleration</source> + <translation>Įgalinti &2D vaizdo spartinimą</translation> + </message> + <message> + <source>The VRDP Server port number. You may specify <tt>0</tt> (zero), to select port 3389, the standard port for RDP.</source> + <translation>VRDP serverio prievado numeris. Jei nurodysie <tt>0</tt> (nulį), bus naudojamas standartinis RDP prievadas 3389.</translation> + </message> + <message> + <source>Mo&nitor Count:</source> + <translation>&Vaizduoklių skaičius:</translation> + </message> + <message> + <source>Controls the amount of virtual monitors provided to the virtual machine.</source> + <translation>Nurodo, kiek virtuali mašina turi virtualių monitorių.</translation> + </message> + <message> + <source><qt>%1</qt></source> + <translation><qt>%1</qt></translation> + </message> +</context> +<context> + <name>VBoxVMSettingsDlg</name> + <message> + <source>General</source> + <translation>Bendra</translation> + </message> + <message> + <source>Storage</source> + <translation>Atminties įtaisas</translation> + </message> + <message> + <source>Hard Disks</source> + <translation>Standieji diskai</translation> + </message> + <message> + <source>CD/DVD-ROM</source> + <translation>CD/DVD</translation> + </message> + <message> + <source>Floppy</source> + <translation>Diskelis</translation> + </message> + <message> + <source>Audio</source> + <translation>Garsas</translation> + </message> + <message> + <source>Network</source> + <translation>Tinklas</translation> + </message> + <message> + <source>Ports</source> + <translation>Prievadai</translation> + </message> + <message> + <source>Serial Ports</source> + <translation>Nuoseklieji prievadai</translation> + </message> + <message> + <source>Parallel Ports</source> + <translation>Lygiagretieji prievadai</translation> + </message> + <message> + <source>USB</source> + <translation>USB</translation> + </message> + <message> + <source>Shared Folders</source> + <translation>Bendrieji aplankai</translation> + </message> + <message> + <source>%1 - %2</source> + <translation>%1 - %2</translation> + </message> + <message> + <source>System</source> + <translation>Sistema</translation> + </message> + <message> + <source>Display</source> + <translation>Ekranas</translation> + </message> + <message> + <source>you have selected a 64-bit guest OS type for this VM. As such guests require hardware virtualization (VT-x/AMD-V), this feature will be enabled automatically.</source> + <translation>pasirinkote 64 bitų svečio OS šioje mašinoje. Kadangi toks svečias reikalauja virtualizaciją palaikančio procesoriaus (VT-x/AMD-V), pastaroji parinktis bus įgalinta automatiškai.</translation> + </message> + <message> + <source>you have selected a 64-bit guest OS type for this VM. VirtualBox does not currently support more than one virtual CPU for 64-bit guests executed on 32-bit hosts.</source> + <translation>pasirinkote 64 bitų svečio OS šioje mašinoje. VirtualBox šiuo metu nepalaiko daugiau nei vieno virtualaus procesoriaus 64 bitų svečiui veikiančiam 32 bitų pagrindiniame kompiuteryje.</translation> + </message> + <message> + <source>you have 2D Video Acceleration enabled. As 2D Video Acceleration is supported for Windows guests only, this feature will be disabled.</source> + <translation>įgalinote 2D vaizdo spartinimą. Kadangi 2D vaizdo spartinimas palaikomas tik Windows svečiui, pastaroji savybė bus uždrausta.</translation> + </message> + <message> + <source>you have enabled a USB HID (Human Interface Device). This will not work unless USB emulation is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source> + <translation>įgalinote USB HID (žmogaus sąsajos įrenginį). Jis neveiks tol, kol neįgalinsite USB emuliacijos. Todėl pastaroji bus įgalinta automatiškai po to, kai patvirtinsite VM nuostatas mygtuku „Gerai“.</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsGeneral</name> + <message> + <source>Displays the path where snapshots of this virtual machine will be stored. Be aware that snapshots can take quite a lot of disk space.</source> + <translation>Rodo kelią, kur bus saugomos šios virtualios mašinos momentinių būvių kopijos. Atminkite, kad būvių kopijos gali užimti daug vietos.</translation> + </message> + <message> + <source>&Basic</source> + <translation>&Pagrindai</translation> + </message> + <message> + <source>&Name:</source> + <translation>&Pavadinimas:</translation> + </message> + <message> + <source>Displays the name of the virtual machine.</source> + <translation>Pateikia virtualios mašinos pavadinimą.</translation> + </message> + <message> + <source>&Advanced</source> + <translation>&Sudėtingiau</translation> + </message> + <message> + <source>&Shared Clipboard:</source> + <translation>&Bendros iškarpinės naudojimas:</translation> + </message> + <message> + <source>Selects which clipboard data will be copied between the guest and the host OS. This feature requires Guest Additions to be installed in the guest OS.</source> + <translation>Nurodo, kaip kopijuojant iškarpinės duomenys bus perduodami tarp svečio ir pagrindinio kompiuterio OS. Ši funkcija galima tik įdiegus „svečio papildinius“ svečio operacinėje sistemoje.</translation> + </message> + <message> + <source>S&napshot Folder:</source> + <translation>&Momentinių būvių aplankas:</translation> + </message> + <message> + <source>&Description</source> + <translation>&Aprašymas</translation> + </message> + <message> + <source>Displays the description of the virtual machine. The description field is useful for commenting on configuration details of the installed guest OS.</source> + <translation>Rodo virtualios mašinos aprašymą. Aprašymo laukelis naudingas komentuojant įdiegtos svečio OS konfigūracijos niuansus.</translation> + </message> + <message> + <source>If checked, any change to mounted CD/DVD or Floppy media performed during machine execution will be saved in the settings file in order to preserve the configuration of mounted media between runs.</source> + <translation>Jei pažymėta, bus įsimintas bet koks CD/DVD ar diskelių prijungimo pakeitimas mašinos veikimo metu. Šie pakeitimai bus įrašyti į nuostatas siekiant išlaikyti tą pačią pakeistą prijungtų įrenginių konfigūraciją sekantį kartą paleidus svečio OS.</translation> + </message> + <message> + <source>Removable Media:</source> + <translation>Keičiamoji laikmena:</translation> + </message> + <message> + <source>&Remember Runtime Changes</source> + <translation>Įsi&minti pakeitimus, atliktus darbo metu</translation> + </message> + <message> + <source>Mini ToolBar:</source> + <translation>Maža įrankinė:</translation> + </message> + <message> + <source>If checked, show the Mini ToolBar in Fullscreen and Seamless modes.</source> + <translation>Jei pažymėta, viso ekrano ir integruoto darbo veiksenose bus rodoma maža įrankinė.</translation> + </message> + <message> + <source>Show In &Fullscreen/Seamless</source> + <translation>Rodyti viso &ekrano/integravimo veiksenoje</translation> + </message> + <message> + <source>If checked, show the Mini ToolBar at the top of the screen, rather than in its default position at the bottom of the screen.</source> + <translation>Jei pažymėta, maža įrankinė bus rodoma ekrano viršuje, o ne apačioje.</translation> + </message> + <message> + <source>Show At &Top Of Screen</source> + <translation>Rodyti &virš kitų langų</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsHD</name> + <message> + <source>If checked, shows the differencing hard disks that are attached to slots rather than their base hard disks (shown for indirect attachments) and allows explicit attaching of differencing hard disks. Check this only if you need a complex hard disk setup.</source> + <translation>Jei pažymėta, bus rodomi diskų vediniai, kurie prijunti prie lizdų, o ne jų pamatiniai standieji diskai (t. y. netiesioginiai prijungimai); bus leidžiama tiksliai prijungti pamatinių standžiųjų diskų vedinius (pvz., būvių kopijas). Šią parinktį naudokite tik jei norite sudėtingos standžiųjų diskų konfigūracijos.</translation> + </message> + <message> + <source><nobr><b>%1</b></nobr><br><nobr>Bus:&nbsp;&nbsp;%2</nobr><br><nobr>Type:&nbsp;&nbsp;%3</nobr></source> + <translation><nobr><b>%1</b></nobr><br><nobr>Magistralė&nbsp;:&nbsp;&nbsp;%2</nobr><br><nobr>Tipas&nbsp;:&nbsp;&nbsp;%3</nobr></translation> + </message> + <message> + <source><nobr>Expand/Collapse&nbsp;Item</nobr></source> + <translation><nobr>Išskleisti/sutraukti&nbsp;elementą</nobr></translation> + </message> + <message> + <source><nobr>Add&nbsp;Hard&nbsp;Disk</nobr></source> + <translation><nobr>Pridėti&nbsp;standųjį&nbsp;diską</nobr></translation> + </message> + <message> + <source><nobr>Add&nbsp;CD/DVD&nbsp;Device</nobr></source> + <translation><nobr>Pridėti&nbsp;CD/DVD&nbsp;įrenginį</nobr></translation> + </message> + <message> + <source><nobr>Add&nbsp;Floppy&nbsp;Device</nobr></source> + <translation><nobr>Pridėti&nbsp;diskelių&nbsp;įrenginį</nobr></translation> + </message> + <message> + <source>No hard disk is selected for <i>%1</i>.</source> + <translation>Neparinktas joks standusis diskas <i>%1</i>.</translation> + </message> + <message> + <source><i>%1</i> uses a medium that is already attached to <i>%2</i>.</source> + <translation><i>%1</i> naudoja laikmeną, kuri jau prijungta prie <i>%2</i>.</translation> + </message> + <message> + <source>Add Controller</source> + <translation>Pridėti valdiklį</translation> + </message> + <message> + <source>Add IDE Controller</source> + <translation>Pridėti IDE valdiklį</translation> + </message> + <message> + <source>Add SATA Controller</source> + <translation>Pridėti SATA valdiklį</translation> + </message> + <message> + <source>Add SCSI Controller</source> + <translation>Pridėti SCSI valdiklį</translation> + </message> + <message> + <source>Add Floppy Controller</source> + <translation>Pridėti diskelio valdiklį</translation> + </message> + <message> + <source>Remove Controller</source> + <translation>Pašalinti valdiklį</translation> + </message> + <message> + <source>Add Attachment</source> + <translation>Pridėti įrenginį</translation> + </message> + <message> + <source>Add Hard Disk</source> + <translation>Pridėti standųjį diską</translation> + </message> + <message> + <source>Add CD/DVD Device</source> + <translation>pridėti CD/DVD įrenginį</translation> + </message> + <message> + <source>Add Floppy Device</source> + <translation>Pridėti diskelių įrenginį</translation> + </message> + <message> + <source>Remove Attachment</source> + <translation>Pašalinti įrenginį</translation> + </message> + <message> + <source>Adds a new controller to the end of the Storage Tree.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Removes the controller highlighted in the Storage Tree.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Adds a new attachment to the Storage Tree using currently selected controller as parent.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Removes the attachment highlighted in the Storage Tree.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>IDE Controller</source> + <translation>IDE valdiklis</translation> + </message> + <message> + <source>SATA Controller</source> + <translation>SATA valdiklis</translation> + </message> + <message> + <source>SCSI Controller</source> + <translation>SCSI valdiklis</translation> + </message> + <message> + <source>Floppy Controller</source> + <translation>Diskelių valdiklis</translation> + </message> + <message> + <source>Hard &Disk:</source> + <translation>Standusis &diskas:</translation> + </message> + <message> + <source>&CD/DVD Device:</source> + <translation>&CD/DVD įrenginys:</translation> + </message> + <message> + <source>&Floppy Device:</source> + <translation>&Diskelis:</translation> + </message> + <message> + <source>&Storage Tree</source> + <translation>&Atminties įtaisų medis</translation> + </message> + <message> + <source>Contains all storage controllers for this machine and the virtual images and host drives attached to them.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Information</source> + <translation>Informacija</translation> + </message> + <message> + <source>The Storage Tree can contain several controllers of different types. This machine currently has no controllers.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Attributes</source> + <translation>Atributai</translation> + </message> + <message> + <source>&Name:</source> + <translation>&Pavadinimas:</translation> + </message> + <message> + <source>Changes the name of the storage controller currently selected in the Storage Tree.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>&Type:</source> + <translation>&Tipas:</translation> + </message> + <message> + <source>Selects the sub-type of the storage controller currently selected in the Storage Tree.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>S&lot:</source> + <translation>&Lizdas:</translation> + </message> + <message> + <source>Selects the slot on the storage controller used by this attachment. The available slots depend on the type of the controller and other attachments on it.</source> + <translation>Leidžia pasirinkti šio įrenginio lizdą atminties įtaisų valdiklyje. Galimi lizdai priklauso nuo valdiklio tipo ir nuo jau jam priskirtų įrenginių.</translation> + </message> + <message> + <source>Selects the virtual disk image or the host drive used by this attachment.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Opens the Virtual Media Manager to select a virtual image for this attachment.</source> + <translation>Atveria virtualių laikmenų tvarkytuvę, leidžiančią pasirinkti virtualų atvaizdą šiam įrenginiui.</translation> + </message> + <message> + <source>Open Virtual Media Manager</source> + <translation>Atverti virtualių laikmenų tvarkytuvę</translation> + </message> + <message> + <source>D&ifferencing Disks</source> + <translation>Diskų &vediniai</translation> + </message> + <message> + <source>When checked, allows the guest to send ATAPI commands directly to the host-drive which makes it possible to use CD/DVD writers connected to the host inside the VM. Note that writing audio CD inside the VM is not yet supported.</source> + <translation>Jei pažymėta, leidžia svečiui tiesiogiai siųsti ATAPI komandas į pagrindinio kompiuterio įrenginį. Pavyzdžiui, ši parinktis leidžia rašyti į pagrindinio kompiuterio CD/DVD iš virtualios mašinos. Atminkite, kad garso CD įrašymas iš virtualios mašinos dar nepalaikomas.</translation> + </message> + <message> + <source>&Passthrough</source> + <translation>&Tiesioginė veiksena</translation> + </message> + <message> + <source>Virtual Size:</source> + <translation>Virtualus dydis:</translation> + </message> + <message> + <source>Actual Size:</source> + <translation>Tikras dydis:</translation> + </message> + <message> + <source>Size:</source> + <translation>Dydis:</translation> + </message> + <message> + <source>Location:</source> + <translation>Vieta:</translation> + </message> + <message> + <source>Type (Format):</source> + <translation>Tipas (formatas):</translation> + </message> + <message> + <source>Attached To:</source> + <translation>Susietas su:</translation> + </message> + <message> + <source>Allows to use host I/O caching capabilities.</source> + <translation>Leidžia naudotis pagrindinio kompiuterio įvesties/išvesties podėlio funkcijomis.</translation> + </message> + <message> + <source>Use host I/O cache</source> + <translation>Naudoti pagrindinio kompiuterio įvesties/išvesties podėlį</translation> + </message> + <message> + <source>Add SAS Controller</source> + <translation>Pridėti SAS valdiklį</translation> + </message> + <message> + <source>SAS Controller</source> + <translation>SAS valdiklis</translation> + </message> + <message> + <source>Storage Controller</source> + <translation>Atminties įtaiso valdiklis</translation> + </message> + <message> + <source>Storage Controller 1</source> + <translation>Atminties įtaiso valdiklis 1</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsNetwork</name> + <message> + <source>When checked, plugs this virtual network adapter into the virtual machine.</source> + <translation>Jei pažymėta, virtualioje mašinoje bus įtaisoma tinklo plokštė.</translation> + </message> + <message> + <source>&Enable Network Adapter</source> + <translation>Į&galinti tinklo plokštę</translation> + </message> + <message> + <source>Selects the type of the virtual network adapter. Depending on this value, VirtualBox will provide different network hardware to the virtual machine.</source> + <translation>Parenka virtualios tinklo plokštės tipą. Ši reikšmė nurodo tinklo plokštę, kurią VirtualBox įrengs virtualioje mašinoje.</translation> + </message> + <message> + <source>&Attached to:</source> + <translation>&Priskirta prie: </translation> + </message> + <message> + <source>Controls how this virtual adapter is attached to the real network of the Host OS.</source> + <translation>Valdo būdą, kuriuo ši virtuali plokštė prijungiama prie tikro tinklo per pagrindinį kompiuterį.</translation> + </message> + <message> + <source>Adapter &Type:</source> + <translation>Plokštės &tipas:</translation> + </message> + <message> + <source>no bridged network adapter is selected</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>no internal network name is specified</source> + <translation>nenurodytas vidinio tinklo pavadinimas</translation> + </message> + <message> + <source>no host-only network adapter is selected</source> + <translation>nepasirinkta plokštė, leidžianti prisijungti tik prie pagrindinio kompiuterio</translation> + </message> + <message> + <source>Not selected</source> + <comment>network adapter name +</comment> + <translation>Nepasirinkta</translation> + </message> + <message> + <source>&Name:</source> + <translation>&Pavadinimas:</translation> + </message> + <message> + <source>Selects the name of the network adapter for <b>Bridged Adapter</b> or <b>Host-only Adapter</b> attachments and the name of the network <b>Internal Network</b> attachments.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>A&dvanced</source> + <translation>&Sudėtingiau</translation> + </message> + <message> + <source>Shows or hides additional network adapter options.</source> + <translation>Parodo arba paslepia papildomas tinklo plokštės parinktis.</translation> + </message> + <message> + <source>&Mac Address:</source> + <translation>&MAC adresas:</translation> + </message> + <message> + <source>Displays the MAC address of this adapter. It contains exactly 12 characters chosen from {0-9,A-F}. Note that the second character must be an even digit.</source> + <translation>Rodo šios plokštės MAC adresą. Jis susideda iš 12 rašmenų {0-9,A-F}. Atminkite, antrasis rašmuo turi būti lyginis skaičius.</translation> + </message> + <message> + <source>Generates a new random MAC address.</source> + <translation>Sugeneruoti naują atsitiktinį MAC adresą.</translation> + </message> + <message> + <source>Indicates whether the virtual network cable is plugged in on machine startup or not.</source> + <translation>Rodo, ar virtualaus tinklo kabelis yra prijungtas mašinos paleidimo metu.</translation> + </message> + <message> + <source>&Cable connected</source> + <translation>&Kabelis prijungtas</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsParallel</name> + <message> + <source>Port %1</source> + <comment>parallel ports +</comment> + <translation>%1 prievadas</translation> + </message> + <message> + <source>When checked, enables the given parallel port of the virtual machine.</source> + <translation>Jei pažymėta, įgalinamas nurodytas lygiagretusis prievadas.</translation> + </message> + <message> + <source>&Enable Parallel Port</source> + <translation>Į&galinti lygiagretųjį prievadą</translation> + </message> + <message> + <source>Port &Number:</source> + <translation>Prievado &numeris: </translation> + </message> + <message> + <source>Displays the parallel port number. You can choose one of the standard parallel ports or select <b>User-defined</b> and specify port parameters manually.</source> + <translation>Roro lygiagrečiojo prievado numerį. Galite pasirinkti kurį nors standartinį lygiagretųjį prievadą arba galite rankiniu būdu parinkti prievado parametrus nuspaudę mygtuką <b>Naudotojo apibrėžtas</b>.</translation> + </message> + <message> + <source>&IRQ:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>I/O Po&rt:</source> + <translation>I/O p&rievadas: </translation> + </message> + <message> + <source>Port &Path:</source> + <translation>&Prievado kelias: </translation> + </message> + <message> + <source>Displays the host parallel device name.</source> + <translation>Rodo pagrindinio kopiuterio lygiagrečiųjų įrenginių pavadinimus.</translation> + </message> + <message> + <source>Displays the IRQ number of this parallel port. This should be a whole number between <tt>0</tt> and <tt>255</tt>. Values greater than <tt>15</tt> may only be used if the <b>IO APIC</b> setting is enabled for this virtual machine.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Displays the base I/O port address of this parallel port. Valid values are integer numbers in range from <tt>0</tt> to <tt>0xFFFF</tt>.</source> + <translation>Rodo pagrindinį įvesties/išvesties prievado adresą šiam lygiagrečiam prievadui. Galimos reikšmės yra sveikieji skaičiai nuo <tt>0</tt> iki <tt>0xFFFF</tt>.</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsParallelPage</name> + <message> + <source>Duplicate port number selected </source> + <translation>Pasirinktas prievado numeris kartojasi</translation> + </message> + <message> + <source>Port path not specified </source> + <translation>Nenurodytas prievado kelias</translation> + </message> + <message> + <source>Duplicate port path entered </source> + <translation>Nurodytas prievado kelias kartojasi</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsSF</name> + <message> + <source>Adds a new shared folder definition.</source> + <translation>Prideda naują bendrąjį aplanką.</translation> + </message> + <message> + <source>Edits the selected shared folder definition.</source> + <translation>Keičia pasirinktą bendrąjį aplanką.</translation> + </message> + <message> + <source>Removes the selected shared folder definition.</source> + <translation>Šalina pasirinktą bendrąjį aplanką.</translation> + </message> + <message> + <source> Machine Folders</source> + <translation> Nuolatiniai aplankai</translation> + </message> + <message> + <source> Transient Folders</source> + <translation> Laikini aplankai</translation> + </message> + <message> + <source>Full</source> + <translation>Visiškas</translation> + </message> + <message> + <source>Read-only</source> + <translation>Tik skaityti</translation> + </message> + <message> + <source>Lists all shared folders accessible to this machine. Use 'net use x: \\vboxsvr\share' to access a shared folder named <i>share</i> from a DOS-like OS, or 'mount -t vboxsf share mount_point' to access it from a Linux OS. This feature requires Guest Additions.</source> + <translation>Pateikia visų šiai mašinai pasiekiamų bendrųjų aplankų sąrašą. Norėdami pasiekti aplanką <i>bendrasis</i> iš DOS tipo OS, pvz., Windows, įvykdykite „net use x: \\vboxsvr\bendrasis“, o norėdami pasiekti iš Linux OS – įvykdykite „mount -t vboxsf bendrasis /prijungimo/vieta“. Ši funkcija galima tik įdiegus „svečio papildinius“.</translation> + </message> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> + <source>Path</source> + <translation>Kelias</translation> + </message> + <message> + <source>Access</source> + <translation>Priėjimas</translation> + </message> + <message> + <source> Global Folders</source> + <translation> Bendri aplankai</translation> + </message> + <message> + <source>&Add Shared Folder</source> + <translation>&Pridėti bendrąjį aplanką</translation> + </message> + <message> + <source>&Edit Shared Folder</source> + <translation>&Keisti bendrąjį aplanką</translation> + </message> + <message> + <source>&Remove Shared Folder</source> + <translation>&Pašalinti bendrąjį aplanką</translation> + </message> + <message> + <source>&Folders List</source> + <translation>&Aplankų sąrašas</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsSFDetails</name> + <message> + <source>Add Share</source> + <translation>Pridėti bendrąjį elementą</translation> + </message> + <message> + <source>Edit Share</source> + <translation>Keisti bendrąjį elementą</translation> + </message> + <message> + <source>Dialog</source> + <translation>Skydelis</translation> + </message> + <message> + <source>Folder Path:</source> + <translation>Aplanko kelias:</translation> + </message> + <message> + <source>Folder Name:</source> + <translation>Aplanko pavadinimas:</translation> + </message> + <message> + <source>Displays the name of the shared folder (as it will be seen by the guest OS).</source> + <translation>Rodo bendrųjų aplankų pavadinimus (kaip jie matomi iš svečio OS).</translation> + </message> + <message> + <source>When checked, the guest OS will not be able to write to the specified shared folder.</source> + <translation>Pažymėjus, svečio OS įrašyti į nurodytą aplanką negalės.</translation> + </message> + <message> + <source>&Read-only</source> + <translation>&Tik skaitymui</translation> + </message> + <message> + <source>&Make Permanent</source> + <translation>&Nuolatinis</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsSerial</name> + <message> + <source>Port %1</source> + <comment>serial ports +</comment> + <translation>%1 prievadas</translation> + </message> + <message> + <source>When checked, enables the given serial port of the virtual machine.</source> + <translation>Jei pažymėta, įgalinamas nurodytas nuoseklusis prievadas.</translation> + </message> + <message> + <source>&Enable Serial Port</source> + <translation>Į&galinti nuoseklųjį prievadą</translation> + </message> + <message> + <source>Port &Number:</source> + <translation>Prievado &numeris: </translation> + </message> + <message> + <source>Displays the serial port number. You can choose one of the standard serial ports or select <b>User-defined</b> and specify port parameters manually.</source> + <translation>Roro nuosekliojo prievado numerį. Galite pasirinkti kurį nors standartinį lygiagretųjį prievadą arba galite rankiniu būdu parinkti prievado parametrus nuspaudę mygtuką <b>Naudotojo apibrėžtas</b>.</translation> + </message> + <message> + <source>&IRQ:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>I/O Po&rt:</source> + <translation>I/O p&rievadas: </translation> + </message> + <message> + <source>Port &Mode:</source> + <translation>Prievado &veiksena: </translation> + </message> + <message> + <source>Controls the working mode of this serial port. If you select <b>Disconnected</b>, the guest OS will detect the serial port but will not be able to operate it.</source> + <translation>Valdo šio nuosekliojo prievado veikimo būdą. Pasirinkus <b>Atjungta</b>, svečio OS aptiks nuoseklųjį prievadą, tačiau negalės juo naudotis.</translation> + </message> + <message> + <source>If checked, the pipe specified in the <b>Port Path</b> field will be created by the virtual machine when it starts. Otherwise, the virtual machine will assume that the pipe exists and try to use it.</source> + <translation>Pažymėjus, virtuali mašina pasileisdama sukurs kanalą, nurodytą laukelyje <b>Prievado kelias</b>. Priešingu atveju, virtuali mašina manys, kad kanalas jau yra ir mėgins jį naudoti.</translation> + </message> + <message> + <source>&Create Pipe</source> + <translation>Sukurti &kanalą</translation> + </message> + <message> + <source>Displays the path to the serial port's pipe on the host when the port is working in <b>Host Pipe</b> mode, or the host serial device name when the port is working in <b>Host Device</b> mode.</source> + <translation>Rodo kelią iki nuosekliojo prievado kanalo pagrindiniame kompiuteryje, kai dirbama <b>Pagrindinio kompiuterio kanalo</b> veiksenoje, arba pagrindinio kompiuterio nuosekliojo įrenginio pavadinimą, kai dirbama <b>Pagrindinio kompiuterio įrenginio</b> veiksenoje.</translation> + </message> + <message> + <source>Port/File &Path:</source> + <translation>&Prievado/rinkmenos kelias:</translation> + </message> + <message> + <source>Displays the IRQ number of this serial port. This should be a whole number between <tt>0</tt> and <tt>255</tt>. Values greater than <tt>15</tt> may only be used if the <b>IO APIC</b> setting is enabled for this virtual machine.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Displays the base I/O port address of this serial port. Valid values are integer numbers in range from <tt>0</tt> to <tt>0xFFFF</tt>.</source> + <translation>Rodo pagrindinį įvesties/išvesties prievado adresą šiam nuosekliam prievadui. Galimos reikšmės yra sveikieji skaičiai nuo <tt>0</tt> iki <tt>0xFFFF</tt>.</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsSerialPage</name> + <message> + <source>Duplicate port number selected </source> + <translation>Pasirinktas prievado numeris kartojasi</translation> + </message> + <message> + <source>Port path not specified </source> + <translation>Nenurodytas prievado kelias</translation> + </message> + <message> + <source>Duplicate port path entered </source> + <translation>Nurodytas prievado kelias kartojasi</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsSystem</name> + <message> + <source>you have assigned more than <b>%1%</b> of your computer's memory (<b>%2</b>) to the virtual machine. Not enough memory is left for your host operating system. Please select a smaller amount.</source> + <translation>virtualiai mašinai paskyrėte daugiau kaip <b>%1%</b> savo kompiuterio atminties (<b>%2</b>). Nepakankamai atminties lieka Jūsų pagrindinei operacinei sistemai. Parinkite mažesnį atminties kiekį svečio sistemai.</translation> + </message> + <message> + <source>you have assigned more than <b>%1%</b> of your computer's memory (<b>%2</b>) to the virtual machine. There might not be enough memory left for your host operating system. Continue at your own risk.</source> + <translation>virtualiai mašinai paskyrėte daugiau kaip <b>%1%</b> savo kompiuterio atminties (<b>%2</b>). Gali nepakakti atminties Jūsų pagrindinei operacinei sistemai. Atsakomybę už darbą tokiomis sąlygomis prisiimkite patys.</translation> + </message> + <message> + <source>for performance reasons, the number of virtual CPUs attached to the virtual machine may not be more than twice the number of physical CPUs on the host (<b>%1</b>). Please reduce the number of virtual CPUs.</source> + <translation>dėl našumo apribojimų, virtualių procesorių skaičius virtualioje mašinoje negali būti dvigubai didesnis nei yra procesorių pagrinidiniame kompiuteryje (<b>%1</b>).Sumažinkite virtualių procsorių skaičių.</translation> + </message> + <message> + <source>you have assigned more virtual CPUs to the virtual machine than the number of physical CPUs on your host system (<b>%1</b>). This is likely to degrade the performance of your virtual machine. Please consider reducing the number of virtual CPUs.</source> + <translation>virtualiai mašinai paskyrėte daugiau virtualių procesorių nei yra tikrame pagrindiniame kompiuteryje (<b>%1</b>). Tikėtina, kad smarkiai nukentės virtualios mašinos našumas. Patartina sumažinti virtualių procesorių skaičių.</translation> + </message> + <message> + <source>you have assigned more than one virtual CPU to this VM. This will not work unless the IO-APIC feature is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source> + <translation>šiai virtualiai mašinai priskyrėte daugiau kaip vieną virtualų procesorių. Ši funkcija neveiktų, jei neįgalinsite IO-ACPI. Todėl šią savybė bus automatiškai įgalinta nuspausdus mygtuką „Gerai“.</translation> + </message> + <message> + <source>you have assigned more than one virtual CPU to this VM. This will not work unless hardware virtualization (VT-x/AMD-V) is also enabled. This will be done automatically when you accept the VM Settings by pressing the OK button.</source> + <translation>šiai virtualiai mašinai priskyrėte daugiau kaip vieną virtualų procesorių. Ši funkcija neveiktų, jei neįgalinsite procesoriaus virtualizavimo aparatiniame lygyje (VT-x/AMD-V). Todėl šią savybė bus automatiškai įgalinta nuspausdus mygtuką „Gerai“.</translation> + </message> + <message> + <source><qt>%1&nbsp;MB</qt></source> + <translation><qt>%1&nbsp;MB</qt></translation> + </message> + <message> + <source><qt>%1&nbsp;CPU</qt></source> + <comment>%1 is 1 for now +</comment> + <translation><qt>%1&nbsp;procesorius</qt></translation> + </message> + <message> + <source>&Motherboard</source> + <translation>&Motininė plokštė</translation> + </message> + <message> + <source>Base &Memory:</source> + <translation>Pagrindinė &atmintis:</translation> + </message> + <message> + <source>Controls the amount of memory provided to the virtual machine. If you assign too much, the machine might not start.</source> + <translation>Nurodo atminties kiekį, kurį galės naudoti virtuali mašina. Jei paskirsite per daug, mašina gali nepasileisti.</translation> + </message> + <message> + <source>MB</source> + <translation>MB</translation> + </message> + <message> + <source>&Boot Order:</source> + <translation>Į&krovos tvarka:</translation> + </message> + <message> + <source>Defines the boot device order. Use the checkboxes on the left to enable or disable individual boot devices. Move items up and down to change the device order.</source> + <translation>Nurodo bandomų įkrauti įrenginių eiliškumą. Langeliuose kairėje pusėje įgalinkite arba uždrauskite pavienius įkrovimo įrenginius. Eiliškumą keisite elementus keldami arba nuleisdami.</translation> + </message> + <message> + <source>Move Down (Ctrl-Down)</source> + <translation>Nuleisti žemiau (Vald+Žemyn)</translation> + </message> + <message> + <source>Moves the selected boot device down.</source> + <translation>Nuleisti pasirinktą įrenginį žemiau.</translation> + </message> + <message> + <source>Move Up (Ctrl-Up)</source> + <translation>Pakelti aukščiau (Vald+Aukštyn)</translation> + </message> + <message> + <source>Moves the selected boot device up.</source> + <translation>Kelti pasirinktą įrenginį aukščiau.</translation> + </message> + <message> + <source>Extended Features:</source> + <translation>Papildomos savybės:</translation> + </message> + <message> + <source>When checked, the virtual machine will support the Input Output APIC (IO APIC), which may slightly decrease performance. <b>Note:</b> don't disable this feature after having installed a Windows guest operating system!</source> + <translation>Pažymėjus, virtuali mašina palaikys įvesties/išvesties APIC (IO APIC), kuris gali šiek tiek sumažinti našumą. <b>Atminkite:</b> neuždrauskite šios parinkties, jei įdiegėte Windows kaip svečio operacinę sistemą!</translation> + </message> + <message> + <source>Enable &IO APIC</source> + <translation>Įgalinti &IO APIC</translation> + </message> + <message> + <source>&Processor</source> + <translation>&Procesorius</translation> + </message> + <message> + <source>&Processor(s):</source> + <translation>&Procesorius(-iai):</translation> + </message> + <message> + <source>When checked, the Physical Address Extension (PAE) feature of the host CPU will be exposed to the virtual machine.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Enable PA&E/NX</source> + <translation>Įgalinti PA&E/NX</translation> + </message> + <message> + <source>Acce&leration</source> + <translation>&Spartinimas</translation> + </message> + <message> + <source>Hardware Virtualization:</source> + <translation>Virtualizacija aparatiniame lygyje:</translation> + </message> + <message> + <source>When checked, the virtual machine will try to make use of the host CPU's hardware virtualization extensions such as Intel VT-x and AMD-V.</source> + <translation>Pažymėjus, virtuali mašina bandys pasinaudoti pagrindinio kompiuterio virtualizavimo aparatiniame lygyje galimybėmis, pavyzdžiui, Intel VT-x ar AMD-V.</translation> + </message> + <message> + <source>Enable &VT-x/AMD-V</source> + <translation>Įgalinti &VT-x/AMD-V</translation> + </message> + <message> + <source>When checked, the virtual machine will try to make use of the nested paging extension of Intel VT-x and AMD-V.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Enable Nested Pa&ging</source> + <translation type="unfinished"></translation> + </message> + <message> + <source><qt>%1&nbsp;CPUs</qt></source> + <comment>%1 is host cpu count * 2 for now +</comment> + <translation><qt>%1&nbsp;procesoriai</qt></translation> + </message> + <message> + <source>When checked, the guest will support the Extended Firmware Interface (EFI), which is required to boot certain guest OSes. Non-EFI aware OSes will not be able to boot if this option is activated.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Enable &EFI (special OSes only)</source> + <translation>Įgalinti &EFI (tik specialioms OS)</translation> + </message> + <message> + <source>If checked, the RTC device will report the time in UTC, otherwise in local (host) time. Unix usually expects the hardware clock to be set to UTC.</source> + <translation>Pažymėjus, RTC įrenginys laiką praneš pasauliniu formatu (UTC); priešingu atveju – vietiniu (pagrindinio kompiuterio) laiku. Unix sistemose aparatinis laikrodis paprastai nustatytas į pasaulinį.</translation> + </message> + <message> + <source>Hardware clock in &UTC time</source> + <translation>Aparatinis laikrodis &pasauliniu laiku</translation> + </message> + <message> + <source>Controls the number of virtual CPUs in the virtual machine. You need hardware virtualization support on your host system to use more than one virtual CPU.</source> + <translation>Nurodo virtualių procesorių skaičių šioje virtualioje mašinoje. Norėdami naudoti daugiau kaip vieną virtualų procesorių, pagrindinis kompiuteris turi palaikyti virtualizaciją aparatiniame lygyje.</translation> + </message> + <message> + <source>If checked, an absolute pointing device (a USB tablet) will be supported. Otherwise, only a standard PS/2 mouse will be emulated.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Enable &absolute pointing device</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>VBoxVMSettingsUSB</name> + <message> + <source>&Add Empty Filter</source> + <translation>&Pridėti tuščią filtrą</translation> + </message> + <message> + <source>A&dd Filter From Device</source> + <translation>P&ridėti filtrą iš įrenginio</translation> + </message> + <message> + <source>&Edit Filter</source> + <translation>&Keisti filtrą</translation> + </message> + <message> + <source>&Remove Filter</source> + <translation>P&ašalinti filtrą</translation> + </message> + <message> + <source>&Move Filter Up</source> + <translation>Filtrą kelti a&ukščiau</translation> + </message> + <message> + <source>M&ove Filter Down</source> + <translation>Filtrą &nuleisti žemiau</translation> + </message> + <message> + <source>Adds a new USB filter with all fields initially set to empty strings. Note that such a filter will match any attached USB device.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Adds a new USB filter with all fields set to the values of the selected USB device attached to the host PC.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Edits the selected USB filter.</source> + <translation>Keičia pasirinktą USB filtrą.</translation> + </message> + <message> + <source>Removes the selected USB filter.</source> + <translation>Pašalina pasirinktą USB filtrą.</translation> + </message> + <message> + <source>Moves the selected USB filter up.</source> + <translation>Pakelti pasirinktą USB filtrą aukščiau.</translation> + </message> + <message> + <source>Moves the selected USB filter down.</source> + <translation>Nuleisti pasirinktą USB filtrą žemiau.</translation> + </message> + <message> + <source>New Filter %1</source> + <comment>usb +</comment> + <translation>Naujas filtras %1</translation> + </message> + <message> + <source>When checked, enables the virtual USB controller of this machine.</source> + <translation>Pažymėjus, įgalinamas šios mašinos virtualus USB valdiklis.</translation> + </message> + <message> + <source>Enable &USB Controller</source> + <translation>Įgalinti &USB valdiklį</translation> + </message> + <message> + <source>When checked, enables the virtual USB EHCI controller of this machine. The USB EHCI controller provides USB 2.0 support.</source> + <translation>Pažymėjus, įgalinamas šios mašinos virtualus USB EHCI valdiklis. USB EHCI valdiklis leidžia naudotis USB 2.0 įrenginiais.</translation> + </message> + <message> + <source>Enable USB 2.0 (E&HCI) Controller</source> + <translation>Įgalinti USB 2.0 (E&HCI) valdiklį</translation> + </message> + <message> + <source>USB Device &Filters</source> + <translation>&USB įrenginių filtrai</translation> + </message> + <message> + <source>Lists all USB filters of this machine. The checkbox to the left defines whether the particular filter is enabled or not. Use the context menu or buttons to the right to add or remove USB filters.</source> + <translation>Pateikia visų šios mašinos USB filtrų sąrašą. Kairėje esantis žymimasis langelis rodo, ar konkretus filtras yra įgalintas, ar nėra. Norėdami pridėti arba pašalinti USB filtrus, naudokitės kontekstiniu meniu arba mygtukais dešinėje.</translation> + </message> + <message> + <source>[filter]</source> + <translation>[filtras]</translation> + </message> +</context> +<context> + <name>VBoxVMSettingsUSBFilterDetails</name> + <message> + <source>Any</source> + <comment>remote +</comment> + <translation>Bet koks</translation> + </message> + <message> + <source>Yes</source> + <comment>remote +</comment> + <translation>Taip</translation> + </message> + <message> + <source>No</source> + <comment>remote +</comment> + <translation>Ne</translation> + </message> + <message> + <source>&Name:</source> + <translation>&Pavadinimas:</translation> + </message> + <message> + <source>Displays the filter name.</source> + <translation>Rodo filtro pavadinimą.</translation> + </message> + <message> + <source>&Vendor ID:</source> + <translation>&Gamintojo ID:</translation> + </message> + <message> + <source>Defines the vendor ID filter. The <i>exact match</i> string format is <tt>XXXX</tt> where <tt>X</tt> is a hexadecimal digit. An empty string will match any value.</source> + <translation>Nurodo gamintojo ID filtrą. <i>Tikslaus atitikmens</i> eilutės formatas yra <tt>XXXX</tt>, kur <tt>X</tt> yra šešeioliktainis skaičius. Tuščia eilutė atitiks bet kokią reikšmę.</translation> + </message> + <message> + <source>&Product ID:</source> + <translation>&Produkto ID:</translation> + </message> + <message> + <source>Defines the product ID filter. The <i>exact match</i> string format is <tt>XXXX</tt> where <tt>X</tt> is a hexadecimal digit. An empty string will match any value.</source> + <translation>Nurodo produkto ID filtrą. <i>Tikslaus atitikmens</i> eilutės formatas yra <tt>XXXX</tt>, kur <tt>X</tt> yra šešeioliktainis skaičius. Tuščia eilutė atitiks bet kokią reikšmę.</translation> + </message> + <message> + <source>&Revision:</source> + <translation>&Revizija:</translation> + </message> + <message> + <source>Defines the revision number filter. The <i>exact match</i> string format is <tt>IIFF</tt> where <tt>I</tt> is a decimal digit of the integer part and <tt>F</tt> is a decimal digit of the fractional part. An empty string will match any value.</source> + <translation>Nurodo revizijos numerio filtrą. <i>Tikslaus atitikmens</i> eilutės formatas yra <tt>IIFF</tt>, kur <tt>I</tt> yra dešimtainio skaičiaus sveikoji dalis, o <tt>F</tt> yra dešimtainio skaičiaus trupmeninė dalis. Tuščia eilutė atitiks bet kokią reikšmę.</translation> + </message> + <message> + <source>&Manufacturer:</source> + <translation>&Gamintojas:</translation> + </message> + <message> + <source>Defines the manufacturer filter as an <i>exact match</i> string. An empty string will match any value.</source> + <translation>Nurodo gamintojo filtrą <i>tikslaus atitikmens</i> eilute. Tuščia eilutė reikš bet kokią reikšmę.</translation> + </message> + <message> + <source>Pro&duct:</source> + <translation>Pro&duktas:</translation> + </message> + <message> + <source>Defines the product name filter as an <i>exact match</i> string. An empty string will match any value.</source> + <translation>Nurodo produkto filtrą <i>tikslaus atitikmens</i> eilute. Tuščia eilutė reikš bet kokią reikšmę.</translation> + </message> + <message> + <source>&Serial No.:</source> + <translation>&Serijinis Nr.:</translation> + </message> + <message> + <source>Defines the serial number filter as an <i>exact match</i> string. An empty string will match any value.</source> + <translation>Nurodo serijinio numerio filtrą <i>tikslaus atitikmens</i> eilute. Tuščia eilutė reikš bet kokią reikšmę.</translation> + </message> + <message> + <source>Por&t:</source> + <translation>Prieva&das:</translation> + </message> + <message> + <source>Defines the host USB port filter as an <i>exact match</i> string. An empty string will match any value.</source> + <translation>Nurodo pagrindinio kompiuterio USB prievado filtrą <i>tikslaus atitikmens</i> eilute. Tuščia eilutė reikš bet kokią reikšmę.</translation> + </message> + <message> + <source>R&emote:</source> + <translation>&Nuotolinis: </translation> + </message> + <message> + <source>Defines whether this filter applies to USB devices attached locally to the host computer (<i>No</i>), to a VRDP client's computer (<i>Yes</i>), or both (<i>Any</i>).</source> + <translatorcomment>Nurodo, ar šis filtras taikomas USB įrenginiams, kurie prijungti prie vietinio pagrindinio kompiuterio (<i>Ne</i>), ar kurie prijungti prie VRDP kliento kompiuterio (<i>Taip</i>), ar kurie prijungti prie abiejų (<i>Bet koks</i>).</translatorcomment> + <translation></translation> + </message> + <message> + <source>&Action:</source> + <translation>&Veiksmas: </translation> + </message> + <message> + <source>Defines an action performed by the host computer when a matching device is attached: give it up to the host OS (<i>Ignore</i>) or grab it for later usage by virtual machines (<i>Hold</i>).</source> + <translation>Nurodo veiksmą, kurį atlieka pagrindinis kompiuteris, kai prijungiamas atitinkamas įrenginys: palikti pagrindinio kompiuterio žinioje (<i>Nepaisyti</i>) arba atiduoti į virtualios mašinos valdymui (<i>Sulaikyti</i>).</translation> + </message> + <message> + <source>USB Filter Details</source> + <translation>USB filtro detalės</translation> + </message> +</context> +</TS> diff --git a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts index e2d8560a8..f57531d4d 100644 --- a/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts +++ b/src/VBox/Frontends/VirtualBox/nls/VirtualBox_nl.ts @@ -5482,7 +5482,7 @@ p, li { white-space: pre-wrap; } </message> <message> <source><p>Deleting the snapshot will cause the state information saved in it to be lost, and disk data spread over several image files that VirtualBox has created together with the snapshot will be merged into one file. This can be a lengthy process, and the information in the snapshot cannot be recovered.</p></p>Are you sure you want to delete the selected snapshot <b>%1</b>?</p></source> - <translation><p>Door het verwijderen van een momentopname wordt de status informatie opgeslagen in de momentopname weg gegooid. En de schijf gegevens, verspreidt over verschillende image bestanden, die VirtualBox heeft aangemaakt tesamen met de momentopname, worden samengevoegd in één bestand. Dit kan een langdurig proces zijn en de informatie in de momentopname kan niet hersteld worden.</p></p>Bent u er zeker van dat u de geselecteerde momentopname <b>%1</b>wilt verwijderen?</p></translation> + <translation><p>Door het verwijderen van een momentopname wordt de status informatie opgeslagen in de momentopname weg gegooid. En de schijf gegevens, verspreidt over verschillende image bestanden, die VirtualBox heeft aangemaakt tesamen met de momentopname, worden samengevoegd in één bestand. Dit kan een langdurig proces zijn en de informatie in de momentopname kan niet hersteld worden.</p></p>Bent u er zeker van dat u de geselecteerde momentopname <b>%1</b> wilt verwijderen?</p></translation> </message> <message> <source>Delete</source> diff --git a/src/VBox/Frontends/VirtualBox/nls/qt_lt.ts b/src/VBox/Frontends/VirtualBox/nls/qt_lt.ts new file mode 100644 index 000000000..8c69923f5 --- /dev/null +++ b/src/VBox/Frontends/VirtualBox/nls/qt_lt.ts @@ -0,0 +1,5693 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="lt"> +<context> + <name>AudioOutput</name> + <message> + <source><html>The audio playback device <b>%1</b> does not work.<br/>Falling back to <b>%2</b>.</html></source> + <translation><html><b>%1</b>Garso atkūrimo įrenginys neveikia.<br/>Naudosimas <b>%2</b>.</html></translation> + </message> + <message> + <source><html>Switching to the audio playback device <b>%1</b><br/>which just became available and has higher preference.</html></source> + <translation><html>Naudosimas <b>%1</b> garso atkūrimo įrenginys,<br/>kuris ką tik tapo prieinamu bei turi aukštesnį prioritetą.</html></translation> + </message> + <message> + <source>Revert back to device '%1'</source> + <translation>Naudosimas įrenginys „%1“</translation> + </message> +</context> +<context> + <name>Phonon::</name> + <message> + <source>Notifications</source> + <translation>Pranešimai</translation> + </message> + <message> + <source>Music</source> + <translation>Muzika</translation> + </message> + <message> + <source>Video</source> + <translation>Vaizdai</translation> + </message> + <message> + <source>Communication</source> + <translation>Bendravimas</translation> + </message> + <message> + <source>Games</source> + <translation>Žaidimai</translation> + </message> + <message> + <source>Accessibility</source> + <translation>Prieinamumas</translation> + </message> +</context> +<context> + <name>Phonon::Gstreamer::Backend</name> + <message> + <source>Warning: You do not seem to have the package gstreamer0.10-plugins-good installed. + Some video features have been disabled.</source> + <translatorcomment>Attention: Vous n'avez apparemment pas installé le paquet gstreamer0.10-plugins-good. +Des fonctionnalités vidéo ont été desactivées.</translatorcomment> + <translation>Dėmesio: panašu, kad gstreamer0.10-plugins-good paketas neįdiegtas. + Kai kurios vaizdo funkcijos uždraustos.</translation> + </message> + <message> + <source>Warning: You do not seem to have the base GStreamer plugins installed. + All audio and video support has been disabled</source> + <translatorcomment>Attention: Vous n'avez apparemment pas installées les plugins de base de GStreamer. +Le support audio et vidéo est désactivé.</translatorcomment> + <translation>Dėmesio: panašu, kad neįdiegtas pagrindinis GStreamer papildinys. + Visas garso ir vaizdo palaikymas yra uždraustas</translation> + </message> +</context> +<context> + <name>Phonon::Gstreamer::MediaObject</name> + <message> + <source>Cannot start playback. + +Check your Gstreamer installation and make sure you +have libgstreamer-plugins-base installed.</source> + <translatorcomment>Impossible de démarrer la lecture. Verifiez votre installation de Gstreamer et assuez-vousd'avoir installé libgstreamer-plugins-base.</translatorcomment> + <translation>Nepavyksta groti. + +Patikrinkite, ar tinkamai įdiegtas Gstreamer ir +jo elementas libgstreamer-plugins-base.</translation> + </message> + <message numerus="yes"> + <source>A required codec is missing. You need to install the following codec(s) to play this content: %0</source> + <translatorcomment>Des codecs requis sont manquants. Vous devez installer les codecs suivants pour jouer le contenu</translatorcomment> + <translation> + <numerusform>Trūksta reikiamos kodavimo priemonės. Norėdami atlikti šį kūrinį, įdiekite šią kodavimo priemonę: %0</numerusform> + <numerusform>Trūksta reikiamos kodavimo priemonės. Norėdami atlikti šį kūrinį, įdiekite šias kodavimo priemones: %0</numerusform> + <numerusform>Trūksta reikiamos kodavimo priemonės. Norėdami atlikti šį kūrinį, įdiekite šias kodavimo priemones: %0</numerusform> + </translation> + </message> + <message> + <source>Could not open media source.</source> + <translation>Nepavyksta atverti kūrinio šaltinio.</translation> + </message> + <message> + <source>Invalid source type.</source> + <translation>Netinkamas šaltinio tipas.</translation> + </message> + <message> + <source>Could not locate media source.</source> + <translation>Nepavyksta rasti kūrinio šaltinio.</translation> + </message> + <message> + <source>Could not open audio device. The device is already in use.</source> + <translation>Nepavyksta atverti garso įrenginio.Įrenginys užimtas.</translation> + </message> + <message> + <source>Could not decode media source.</source> + <translation>Nepavyksta iškoduoti kūrinio šaltinio.</translation> + </message> +</context> +<context> + <name>Phonon::VolumeSlider</name> + <message> + <source>Volume: %1%</source> + <translation>Garsumas: %1%</translation> + </message> + <message> + <source>Use this slider to adjust the volume. The leftmost position is 0%, the rightmost is %1%</source> + <translatorcomment>Utilisez le slider pour ajuster le volume. La position la plus à gauche est 0%, la plus à droite est %1%</translatorcomment> + <translation>Garsumą keiskite šliaužikliu. Kairiausia padėtis atitinka 0%, o dešiniausia – %1%</translation> + </message> +</context> +<context> + <name>Q3Accel</name> + <message> + <source>%1, %2 not defined</source> + <translatorcomment>La séquence %1, %2 n'est pas définie</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ambiguous %1 not handled</source> + <translatorcomment>Séquence ambiguë %1 non traitée</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>Q3DataTable</name> + <message> + <source>True</source> + <translation>Tiesa</translation> + </message> + <message> + <source>False</source> + <translation>Melas</translation> + </message> + <message> + <source>Insert</source> + <translation>Įterpti</translation> + </message> + <message> + <source>Update</source> + <translation>Atnaujinti</translation> + </message> + <message> + <source>Delete</source> + <translation>Ištrinti</translation> + </message> +</context> +<context> + <name>Q3FileDialog</name> + <message> + <source>Copy or Move a File</source> + <translation>Kopijuoti arba perkelti rinkmeną</translation> + </message> + <message> + <source>Read: %1</source> + <translation>Skaityti: %1</translation> + </message> + <message> + <source>Write: %1</source> + <translation>Rašyti: %1</translation> + </message> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>All Files (*)</source> + <translation>Visos rinkmenos (*)</translation> + </message> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> + <source>Size</source> + <translation>Dydis</translation> + </message> + <message> + <source>Type</source> + <translation>Tipas</translation> + </message> + <message> + <source>Date</source> + <translation>Data</translation> + </message> + <message> + <source>Attributes</source> + <translation>Savybės</translation> + </message> + <message> + <source>&OK</source> + <translation>&Gerai</translation> + </message> + <message> + <source>Look &in:</source> + <translation>Kur &ieškoti:</translation> + </message> + <message> + <source>File &name:</source> + <translation>Rinkmenos &pavadinimas:</translation> + </message> + <message> + <source>File &type:</source> + <translation>Rinkmenos &tipas:</translation> + </message> + <message> + <source>Back</source> + <translation>Atgal</translation> + </message> + <message> + <source>One directory up</source> + <translation>Į aukštesnį aplanką</translation> + </message> + <message> + <source>Create New Folder</source> + <translation>Sukurti naują aplanką</translation> + </message> + <message> + <source>List View</source> + <translation>Sąrašo rodinys</translation> + </message> + <message> + <source>Detail View</source> + <translation>Detalus rodinys</translation> + </message> + <message> + <source>Preview File Info</source> + <translatorcomment>Informations du fichier prévisualisé</translatorcomment> + <translation>Rinkmenos informacijos peržiūra</translation> + </message> + <message> + <source>Preview File Contents</source> + <translatorcomment>Contenu du fichier prévisualisé</translatorcomment> + <translation>Rinkmenos turinio peržiūra</translation> + </message> + <message> + <source>Read-write</source> + <translation>Tik rašyti</translation> + </message> + <message> + <source>Read-only</source> + <translation>Tik skaityti</translation> + </message> + <message> + <source>Write-only</source> + <translation>Tik rašyti</translation> + </message> + <message> + <source>Inaccessible</source> + <translation>Neprieinama</translation> + </message> + <message> + <source>Symlink to File</source> + <translation>Sukurti simbolinę nuorodą į rinkmeną</translation> + </message> + <message> + <source>Symlink to Directory</source> + <translation>Sukurti simbolinę nuorodą į aplanką</translation> + </message> + <message> + <source>Symlink to Special</source> + <translation>Sukurti specialią simbolinę nuorodą</translation> + </message> + <message> + <source>File</source> + <translation>Rinkmena</translation> + </message> + <message> + <source>Dir</source> + <translation>Aplankas</translation> + </message> + <message> + <source>Special</source> + <translation>Specialus</translation> + </message> + <message> + <source>Open</source> + <translation>Atverti</translation> + </message> + <message> + <source>Save As</source> + <translation>Įrašyti kaip</translation> + </message> + <message> + <source>&Open</source> + <translation>At&verti</translation> + </message> + <message> + <source>&Save</source> + <translation>Į&rašyti</translation> + </message> + <message> + <source>&Rename</source> + <translation>&Pervadinti</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Ištrinti</translation> + </message> + <message> + <source>R&eload</source> + <translation>Įk&elti iš naujo</translation> + </message> + <message> + <source>Sort by &Name</source> + <translation>Rikiuoti pagal &pavadinimą</translation> + </message> + <message> + <source>Sort by &Size</source> + <translation>Rikiuoti pagal &dydį</translation> + </message> + <message> + <source>Sort by &Date</source> + <translation>Rikiuoti pagal &datą</translation> + </message> + <message> + <source>&Unsorted</source> + <translation>&Nerikiuoti</translation> + </message> + <message> + <source>Sort</source> + <translation>Rikiuoti</translation> + </message> + <message> + <source>Show &hidden files</source> + <translation>Rodyti paslėptas &rinkmenas</translation> + </message> + <message> + <source>the file</source> + <translation type="unfinished">rinkmeną</translation> + </message> + <message> + <source>the directory</source> + <translation type="unfinished">aplanką</translation> + </message> + <message> + <source>the symlink</source> + <translation type="unfinished">simbolinę nuorodą</translation> + </message> + <message> + <source>Delete %1</source> + <translation>Ištrinti %1</translation> + </message> + <message> + <source><qt>Are you sure you wish to delete %1 "%2"?</qt></source> + <translation><qt>Tikrai ištrinti %1 „%2“?</qt></translation> + </message> + <message> + <source>&Yes</source> + <translation>&Taip</translation> + </message> + <message> + <source>&No</source> + <translation>&Ne</translation> + </message> + <message> + <source>New Folder 1</source> + <translation>Naujas aplankas 1</translation> + </message> + <message> + <source>New Folder</source> + <translation>Naujas aplankas</translation> + </message> + <message> + <source>New Folder %1</source> + <translation>Naujas aplankas %1</translation> + </message> + <message> + <source>Find Directory</source> + <translation>Ieškoti aplanko</translation> + </message> + <message> + <source>Directories</source> + <translation>Aplankai</translation> + </message> + <message> + <source>Directory:</source> + <translation>Aplankas:</translation> + </message> + <message> + <source>Error</source> + <translation>Klaida</translation> + </message> + <message> + <source>%1 +File not found. +Check path and filename.</source> + <translation>%1 +Rinkmena nerasta. +Patikrinkite rinkmenos kelią ir pavadinimą.</translation> + </message> +</context> +<context> + <name>Q3LocalFs</name> + <message> + <source>Could not read directory +%1</source> + <translation>Nepavyksta nuskaityti iš aplanko +%1</translation> + </message> + <message> + <source>Could not create directory +%1</source> + <translation>Nepavyksta sukurti aplanko +%1</translation> + </message> + <message> + <source>Could not remove file or directory +%1</source> + <translation>Nepavyksta pašalinti rinkmenos arba aplanko +%1</translation> + </message> + <message> + <source>Could not rename +%1 +to +%2</source> + <translation>%1 +nepavyksta pervadinti į +%2</translation> + </message> + <message> + <source>Could not open +%1</source> + <translation>Nepavyksta atverti +%1</translation> + </message> + <message> + <source>Could not write +%1</source> + <translation>Nepavyksta rašyti į +%1</translation> + </message> +</context> +<context> + <name>Q3MainWindow</name> + <message> + <source>Line up</source> + <translatorcomment>Aligner</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Customize...</source> + <translatorcomment>Personnaliser...</translatorcomment> + <translation>Derinti...</translation> + </message> +</context> +<context> + <name>Q3NetworkProtocol</name> + <message> + <source>Operation stopped by the user</source> + <translation>Veiksmą nutraukė naudotojas</translation> + </message> +</context> +<context> + <name>Q3ProgressDialog</name> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> +</context> +<context> + <name>Q3TabDialog</name> + <message> + <source>OK</source> + <translation>Gerai</translation> + </message> + <message> + <source>Apply</source> + <translation>Pritaikyti</translation> + </message> + <message> + <source>Help</source> + <translation>Pagalba</translation> + </message> + <message> + <source>Defaults</source> + <translation>Numatyta</translation> + </message> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> +</context> +<context> + <name>Q3TextEdit</name> + <message> + <source>&Undo</source> + <translation>Atša&ukti</translation> + </message> + <message> + <source>&Redo</source> + <translation>Paka&rtoti</translation> + </message> + <message> + <source>Cu&t</source> + <translation>Iškirp&ti</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Kopijuoti</translation> + </message> + <message> + <source>&Paste</source> + <translation>&Padėti</translation> + </message> + <message> + <source>Clear</source> + <translation>Išvalyti</translation> + </message> + <message> + <source>Select All</source> + <translation>Viską pažymėti</translation> + </message> +</context> +<context> + <name>Q3TitleBar</name> + <message> + <source>System</source> + <translation>Sistema</translation> + </message> + <message> + <source>Restore up</source> + <translation>Atstatyti aukščiau</translation> + </message> + <message> + <source>Minimize</source> + <translation>Sumažinti</translation> + </message> + <message> + <source>Restore down</source> + <translation>Atstatyti žemiau</translation> + </message> + <message> + <source>Maximize</source> + <translation>Išdidinti</translation> + </message> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> + <message> + <source>Contains commands to manipulate the window</source> + <translatorcomment>Contient des commandes pour manipuler la fenêtre</translatorcomment> + <translation>Komandos langui valdyti</translation> + </message> + <message> + <source>Puts a minimized back to normal</source> + <translation>Sumažintą langą grąžina į įprastą būseną</translation> + </message> + <message> + <source>Moves the window out of the way</source> + <translatorcomment>Déplace la fenêtre à l'écart</translatorcomment> + <translation>Nukelia langą</translation> + </message> + <message> + <source>Puts a maximized window back to normal</source> + <translation>Išdidintą langą grąžina į įprastą būseną</translation> + </message> + <message> + <source>Makes the window full screen</source> + <translation>Langą rodo visame ekrane</translation> + </message> + <message> + <source>Closes the window</source> + <translation>Užveria langą</translation> + </message> + <message> + <source>Displays the name of the window and contains controls to manipulate it</source> + <translatorcomment>Affiche le nom de la fenêtre et contient des contrôles pour la manipuler</translatorcomment> + <translation>Rodo lango pavadinimą ir turi jo tvarkymo priemones</translation> + </message> +</context> +<context> + <name>Q3ToolBar</name> + <message> + <source>More...</source> + <translation>Daugiau...</translation> + </message> +</context> +<context> + <name>Q3UrlOperator</name> + <message> + <source>The protocol `%1' is not supported</source> + <translation>Protokolas „%1“ nepalaikomas</translation> + </message> + <message> + <source>The protocol `%1' does not support listing directories</source> + <translatorcomment>Le protocole `%1' ne permet pas de lister les fichiers d'un dossier</translatorcomment> + <translation>Protokolas „%1“ nepalaiko aplankų sąrašų pateikimo</translation> + </message> + <message> + <source>The protocol `%1' does not support creating new directories</source> + <translation>Protokolas „%1“ nepaliko naujų aplankų kūrimo</translation> + </message> + <message> + <source>The protocol `%1' does not support removing files or directories</source> + <translation>Protokolas „%1“ nepaliko rinkmenų ir aplankų šalinimo</translation> + </message> + <message> + <source>The protocol `%1' does not support renaming files or directories</source> + <translation>Protokolas „%1“ nepaliko rinkmenų ir aplankų pervedinimo</translation> + </message> + <message> + <source>The protocol `%1' does not support getting files</source> + <translation>Protokolas „%1“ nepalaiko rinkmenų gavimo</translation> + </message> + <message> + <source>The protocol `%1' does not support putting files</source> + <translation>Protokolas „%1“ nepalaiko rinkmenų įkėlimo</translation> + </message> + <message> + <source>The protocol `%1' does not support copying or moving files or directories</source> + <translation>Protokolas „%1“ nepaliko rinkmenų ir aplankų kopijavimo ir perkėlimo</translation> + </message> + <message> + <source>(unknown)</source> + <translation>(nežinoma)</translation> + </message> +</context> +<context> + <name>Q3Wizard</name> + <message> + <source>&Cancel</source> + <translation>&Atšaukti</translation> + </message> + <message> + <source>< &Back</source> + <translation>< &Atgal</translation> + </message> + <message> + <source>&Next ></source> + <translation>&Toliau ></translation> + </message> + <message> + <source>&Finish</source> + <translation>&Užbaigti</translation> + </message> + <message> + <source>&Help</source> + <translation>&Pagalba</translation> + </message> +</context> +<context> + <name>QAbstractSocket</name> + <message> + <source>Host not found</source> + <translation>Pagrindinis kompiuteris nerastas</translation> + </message> + <message> + <source>Connection refused</source> + <translatorcomment>Connexion refusée</translatorcomment> + <translation>Ryšys atmestas</translation> + </message> + <message> + <source>Socket operation timed out</source> + <translatorcomment>Opération socket expirée</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Socket is not connected</source> + <translatorcomment>Le socket n'est pas connecté</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QAbstractSpinBox</name> + <message> + <source>&Step up</source> + <translation>Pa&didinti</translation> + </message> + <message> + <source>Step &down</source> + <translation>Su&mažinti</translation> + </message> + <message> + <source>&Select All</source> + <translation>&Viską pažymėti</translation> + </message> +</context> +<context> + <name>QApplication</name> + <message> + <source>Activate</source> + <translation>Aktyvuoti</translation> + </message> + <message> + <source>Executable '%1' requires Qt %2, found Qt %3.</source> + <translation>„%1“ vykdymui reikia Qt %2 (rasta Qt %3).</translation> + </message> + <message> + <source>Incompatible Qt Library Error</source> + <translation>Klaida: QT bibliotekos nesuderinamos</translation> + </message> + <message> + <source>QT_LAYOUT_DIRECTION</source> + <comment>Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout.</comment> + <translation>LTR</translation> + </message> + <message> + <source>Activates the program's main window</source> + <translation>Aktyvuoja programos pagrindinį langą</translation> + </message> +</context> +<context> + <name>QCheckBox</name> + <message> + <source>Uncheck</source> + <translation>Atžymėti</translation> + </message> + <message> + <source>Check</source> + <translation>Pažymėti</translation> + </message> + <message> + <source>Toggle</source> + <translation>Perjungti</translation> + </message> +</context> +<context> + <name>QColorDialog</name> + <message> + <source>Hu&e:</source> + <translation>&Tonas :</translation> + </message> + <message> + <source>&Sat:</source> + <translation>&Sodrumas:</translation> + </message> + <message> + <source>&Val:</source> + <translation>&Reikšmė:</translation> + </message> + <message> + <source>&Red:</source> + <translation>&Raudona:</translation> + </message> + <message> + <source>&Green:</source> + <translation>&Žalia:</translation> + </message> + <message> + <source>Bl&ue:</source> + <translation>&Mėlyna:</translation> + </message> + <message> + <source>A&lpha channel:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>&Basic colors</source> + <translation>&Pagrindinės spalvos</translation> + </message> + <message> + <source>&Custom colors</source> + <translation>&Derintos spalvos</translation> + </message> + <message> + <source>&Add to Custom Colors</source> + <translation>Pridėti prie d&erintų spalvų</translation> + </message> + <message> + <source>Select color</source> + <translation>Spalvos pasirinkimas</translation> + </message> +</context> +<context> + <name>QComboBox</name> + <message> + <source>Open</source> + <translation>Atverti</translation> + </message> + <message> + <source>False</source> + <translation>Melas</translation> + </message> + <message> + <source>True</source> + <translation>Tiesa</translation> + </message> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> +</context> +<context> + <name>QCoreApplication</name> + <message> + <source>%1: permission denied</source> + <comment>QSystemSemaphore</comment> + <translation>%1: nepakanka leidimų</translation> + </message> + <message> + <source>%1: already exists</source> + <comment>QSystemSemaphore</comment> + <translation>%1: jau yra</translation> + </message> + <message> + <source>%1: doesn't exists</source> + <comment>QSystemSemaphore</comment> + <translation>%1: nėra</translation> + </message> + <message> + <source>%1: out of resources</source> + <comment>QSystemSemaphore</comment> + <translatorcomment>%1: plus de ressources disponibles</translatorcomment> + <translation>%1: viršija išteklius</translation> + </message> + <message> + <source>%1: unknown error %2</source> + <comment>QSystemSemaphore</comment> + <translation>%1: nežinoma klaida %2</translation> + </message> + <message> + <source>%1: key is empty</source> + <comment>QSystemSemaphore</comment> + <translatorcomment>%1: clé vide</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: unable to make key</source> + <comment>QSystemSemaphore</comment> + <translatorcomment>%1: impossible de créer la clé</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: ftok failed</source> + <comment>QSystemSemaphore</comment> + <translatorcomment>%1: ftok a échoué</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QDB2Driver</name> + <message> + <source>Unable to connect</source> + <translatorcomment>Incapable d'établir une connexion</translatorcomment> + <translation>Nepavyksta prisijungti</translation> + </message> + <message> + <source>Unable to commit transaction</source> + <translatorcomment>Incapable de soumettre la transaction</translatorcomment> + <translation>Nepavyksta įkelti operacijos</translation> + </message> + <message> + <source>Unable to rollback transaction</source> + <translatorcomment>Incapable d'annuler la transaction</translatorcomment> + <translation>Nepavyksta atsisakyti operacijos</translation> + </message> + <message> + <source>Unable to set autocommit</source> + <translatorcomment>Impossible d'activer l'auto-soumission</translatorcomment> + <translation>Nepavyksta įgalinti automatinio įkėlimo</translation> + </message> +</context> +<context> + <name>QDB2Result</name> + <message> + <source>Unable to execute statement</source> + <translatorcomment>Impossible d'exécuter la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to prepare statement</source> + <translatorcomment>Impossible de prépare la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to bind variable</source> + <translatorcomment>Impossible d'attacher la variable</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to fetch record %1</source> + <translatorcomment>Impossible de récupérer l'enregistrement %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to fetch next</source> + <translatorcomment>Impossible de récupérer le suivant</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to fetch first</source> + <translatorcomment>Impossible de récupérer le premier</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QDateTimeEdit</name> + <message> + <source>AM</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>am</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PM</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>pm</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QDial</name> + <message> + <source>QDial</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>SpeedoMeter</source> + <translation>Greičio matuoklis</translation> + </message> + <message> + <source>SliderHandle</source> + <translatorcomment>Poignée</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QDialog</name> + <message> + <source>What's This?</source> + <translation>Kas tai?</translation> + </message> + <message> + <source>Done</source> + <translation>Užbaigti</translation> + </message> +</context> +<context> + <name>QDialogButtonBox</name> + <message> + <source>OK</source> + <translation>Gerai</translation> + </message> + <message> + <source>Save</source> + <translation>Įrašyti</translation> + </message> + <message> + <source>Open</source> + <translation>Atverti</translation> + </message> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> + <message> + <source>Apply</source> + <translation>Pritaikyti</translation> + </message> + <message> + <source>Reset</source> + <translation>Iš naujo</translation> + </message> + <message> + <source>Help</source> + <translation>Pagalba</translation> + </message> + <message> + <source>Don't Save</source> + <translation>Neįrašyti</translation> + </message> + <message> + <source>Discard</source> + <translation>Panaikinti</translation> + </message> + <message> + <source>&Yes</source> + <translation>&Taip</translation> + </message> + <message> + <source>Yes to &All</source> + <translation>Taip &viskam</translation> + </message> + <message> + <source>&No</source> + <translation>&Ne</translation> + </message> + <message> + <source>N&o to All</source> + <translation>N&e viskam</translation> + </message> + <message> + <source>Save All</source> + <translation>Viską įrašyti</translation> + </message> + <message> + <source>Abort</source> + <translation>Nutraukti</translation> + </message> + <message> + <source>Retry</source> + <translation>Kartoti</translation> + </message> + <message> + <source>Ignore</source> + <translation>Nepaisyti</translation> + </message> + <message> + <source>Restore Defaults</source> + <translation>Atkurti numatytąsias reikšmes</translation> + </message> + <message> + <source>Close without Saving</source> + <translation>Užverti neišsaugant</translation> + </message> + <message> + <source>&OK</source> + <translation>&Gerai</translation> + </message> +</context> +<context> + <name>QDirModel</name> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> + <source>Size</source> + <translation>Dydis</translation> + </message> + <message> + <source>Kind</source> + <comment>Match OS X Finder</comment> + <translation>Tipas</translation> + </message> + <message> + <source>Type</source> + <comment>All other platforms</comment> + <translation>Tipas</translation> + </message> + <message> + <source>Date Modified</source> + <translation>Pakeitimo data</translation> + </message> +</context> +<context> + <name>QDockWidget</name> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> + <message> + <source>Dock</source> + <translatorcomment>Attacher</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Float</source> + <translatorcomment>Détacher</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QDoubleSpinBox</name> + <message> + <source>More</source> + <translation>Daugiau</translation> + </message> + <message> + <source>Less</source> + <translation>Mažiau</translation> + </message> +</context> +<context> + <name>QErrorMessage</name> + <message> + <source>Debug Message:</source> + <translation>Derinimo pranešimas:</translation> + </message> + <message> + <source>Warning:</source> + <translation>Įspėjimas:</translation> + </message> + <message> + <source>Fatal Error:</source> + <translation>Lemtinga klaida:</translation> + </message> + <message> + <source>&Show this message again</source> + <translation>&Rodyti šį pranešimą dar kartą</translation> + </message> + <message> + <source>&OK</source> + <translation>&Gerai</translation> + </message> +</context> +<context> + <name>QFileDialog</name> + <message> + <source>All Files (*)</source> + <translation>Visos rinkmenos (*)</translation> + </message> + <message> + <source>Directories</source> + <translation>Aplankai</translation> + </message> + <message> + <source>&Open</source> + <translation>At&verti</translation> + </message> + <message> + <source>&Save</source> + <translation>Į&rašyti</translation> + </message> + <message> + <source>Open</source> + <translation>Atverti</translation> + </message> + <message> + <source>%1 already exists. +Do you want to replace it?</source> + <translation>Rinkmena %1 jau yra. Perrašyti ją?</translation> + </message> + <message> + <source>%1 +File not found. +Please verify the correct file name was given.</source> + <translation>%1 +Rinkmena nerasta. +Patikrinkite rinkmenos kelią ir pavadinimą.</translation> + </message> + <message> + <source>My Computer</source> + <translation>Mano kompiuteris</translation> + </message> + <message> + <source>&Rename</source> + <translation>&Pervadinti</translation> + </message> + <message> + <source>&Delete</source> + <translation>&Ištrinti</translation> + </message> + <message> + <source>Show &hidden files</source> + <translation>Rodyti paslėptas &rinkmenas</translation> + </message> + <message> + <source>Back</source> + <translation>Atgal</translation> + </message> + <message> + <source>Parent Directory</source> + <translation>Į aukštesnį aplanką</translation> + </message> + <message> + <source>List View</source> + <translation>Sąrašo rodinys</translation> + </message> + <message> + <source>Detail View</source> + <translation>Detalus rodinys</translation> + </message> + <message> + <source>Files of type:</source> + <translation>Rinkmenos, kurių tipas:</translation> + </message> + <message> + <source>Directory:</source> + <translation>Aplankas:</translation> + </message> + <message> + <source>%1 +Directory not found. +Please verify the correct directory name was given.</source> + <translation>%1 +Aplankas nerastas. +Patikrinkite aplanko pavadinimą.</translation> + </message> + <message> + <source>'%1' is write protected. +Do you want to delete it anyway?</source> + <translation>„%1“ apsaugotas nuo įrašymas. +Vis tiek norite ištrinti?</translation> + </message> + <message> + <source>Are sure you want to delete '%1'?</source> + <translation>Tikrai norite ištrinti „%1“?</translation> + </message> + <message> + <source>Could not delete directory.</source> + <translation>Nepavyksta pašalinti aplanko.</translation> + </message> + <message> + <source>Save As</source> + <translation>Įrašyti kaip</translation> + </message> + <message> + <source>Drive</source> + <translation></translation> + </message> + <message> + <source>File</source> + <translation>Rinkmena</translation> + </message> + <message> + <source>Unknown</source> + <translation>Nežinoma</translation> + </message> + <message> + <source>Find Directory</source> + <translation>Ieškoti aplanko</translation> + </message> + <message> + <source>Show </source> + <translation>Rodyti </translation> + </message> + <message> + <source>Forward</source> + <translation>Toliau</translation> + </message> + <message> + <source>New Folder</source> + <translation>Naujas aplankas</translation> + </message> + <message> + <source>&New Folder</source> + <translation>&Naujas aplankas</translation> + </message> + <message> + <source>&Choose</source> + <translation>&Pasirinkti</translation> + </message> + <message> + <source>Remove</source> + <translation>Pašalinti</translation> + </message> + <message> + <source>File &name:</source> + <translation>Rinkmenos &pavadinimas:</translation> + </message> + <message> + <source>Look in:</source> + <translation>Kur ieškoti:</translation> + </message> + <message> + <source>Create New Folder</source> + <translation>Sukurti naują aplanką</translation> + </message> +</context> +<context> + <name>QFileSystemModel</name> + <message> + <source>Invalid filename</source> + <translation>Rinkmenos pavadinimas netinkamas</translation> + </message> + <message> + <source><b>The name "%1" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks.</source> + <translation><b>Negalima naudoti pavadinimo „%1“</b><p>Naudokite kitą trumpesnį pavadinimą be skyrybos ženklų.</translation> + </message> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> + <source>Size</source> + <translation>Dydis</translation> + </message> + <message> + <source>Kind</source> + <comment>Match OS X Finder</comment> + <translation>Tipas</translation> + </message> + <message> + <source>Type</source> + <comment>All other platforms</comment> + <translation>Tipas</translation> + </message> + <message> + <source>Date Modified</source> + <translation>Pakeitimo data</translation> + </message> + <message> + <source>My Computer</source> + <translation>Mano kompiuteris</translation> + </message> + <message> + <source>Computer</source> + <translation>Kompiuteris</translation> + </message> + <message> + <source>%1 TB</source> + <translation>%1 TB</translation> + </message> + <message> + <source>%1 GB</source> + <translation>%1 GB</translation> + </message> + <message> + <source>%1 MB</source> + <translation>%1 MB</translation> + </message> + <message> + <source>%1 KB</source> + <translation>%1 KB</translation> + </message> + <message> + <source>%1 bytes</source> + <translation>%1 baitai</translation> + </message> +</context> +<context> + <name>QFontDatabase</name> + <message> + <source>Normal</source> + <translation>Įprastas</translation> + </message> + <message> + <source>Bold</source> + <translation>Pusjuodis</translation> + </message> + <message> + <source>Demi Bold</source> + <translation>Silpnai pusjuodis</translation> + </message> + <message> + <source>Black</source> + <translation>Juodas</translation> + </message> + <message> + <source>Demi</source> + <translation>Pusiau</translation> + </message> + <message> + <source>Light</source> + <translation>Plonas</translation> + </message> + <message> + <source>Italic</source> + <translation>Kursyvinis</translation> + </message> + <message> + <source>Oblique</source> + <translation>Pasviras</translation> + </message> + <message> + <source>Any</source> + <translation>Bet koks</translation> + </message> + <message> + <source>Latin</source> + <translation>Lotynų</translation> + </message> + <message> + <source>Greek</source> + <translation>Graikų</translation> + </message> + <message> + <source>Cyrillic</source> + <translation>Kirilica</translation> + </message> + <message> + <source>Armenian</source> + <translation>Armėnų</translation> + </message> + <message> + <source>Hebrew</source> + <translation>Hebrajų</translation> + </message> + <message> + <source>Arabic</source> + <translation>Arabų</translation> + </message> + <message> + <source>Syriac</source> + <translation>Sirų</translation> + </message> + <message> + <source>Thaana</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Devanagari</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Bengali</source> + <translation>Bengalų</translation> + </message> + <message> + <source>Gurmukhi</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Gujarati</source> + <translation>Gudžarati</translation> + </message> + <message> + <source>Oriya</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Tamil</source> + <translation>Tamilų</translation> + </message> + <message> + <source>Telugu</source> + <translation>Telugu</translation> + </message> + <message> + <source>Kannada</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Malayalam</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Sinhala</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Thai</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Lao</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Tibetan</source> + <translation>Tibeto</translation> + </message> + <message> + <source>Myanmar</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Georgian</source> + <translation>Gruzinų</translation> + </message> + <message> + <source>Khmer</source> + <translation>Chmerų</translation> + </message> + <message> + <source>Simplified Chinese</source> + <translation>Supaprastinta kinų</translation> + </message> + <message> + <source>Traditional Chinese</source> + <translation>Tradicinė kinų</translation> + </message> + <message> + <source>Japanese</source> + <translation>Japonų</translation> + </message> + <message> + <source>Korean</source> + <translation>Korėjiečių</translation> + </message> + <message> + <source>Vietnamese</source> + <translation>Vietnamiečių</translation> + </message> + <message> + <source>Symbol</source> + <translation>Simbolis</translation> + </message> + <message> + <source>Ogham</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Runic</source> + <translation>Runų</translation> + </message> +</context> +<context> + <name>QFontDialog</name> + <message> + <source>&Font</source> + <translation>&Šriftas</translation> + </message> + <message> + <source>Font st&yle</source> + <translation>Šrifto &stilius</translation> + </message> + <message> + <source>&Size</source> + <translation>&Dydis</translation> + </message> + <message> + <source>Effects</source> + <translation>Efektai</translation> + </message> + <message> + <source>Stri&keout</source> + <translation>Per&braukta</translation> + </message> + <message> + <source>&Underline</source> + <translation>&Pabrauktas</translation> + </message> + <message> + <source>Sample</source> + <translation>Pavyzdys</translation> + </message> + <message> + <source>Wr&iting System</source> + <translation>Rašymo &sistema</translation> + </message> + <message> + <source>Select Font</source> + <translation>Pasirinkti šriftą</translation> + </message> +</context> +<context> + <name>QFtp</name> + <message> + <source>Not connected</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Host %1 not found</source> + <translation>Pagrindinis kompiuteris %1 nerastas</translation> + </message> + <message> + <source>Connection refused to host %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Connected to host %1</source> + <translation>Prisijungta prie pagrindinio kompiuterio %1</translation> + </message> + <message> + <source>Connection refused for data connection</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unknown error</source> + <translation>Nežinoma klaida</translation> + </message> + <message> + <source>Connecting to host failed: +%1</source> + <translation>Nepavyko prisijungti prie pagrindinio kompiuterio: +%1</translation> + </message> + <message> + <source>Login failed: +%1</source> + <translation>Prisijungti nepavyko: +%1</translation> + </message> + <message> + <source>Listing directory failed: +%1</source> + <translation>Nepavyko pateikti aplankų sąrašo: +%1</translation> + </message> + <message> + <source>Changing directory failed: +%1</source> + <translation>Nepavyko pakeisti aplanko: +%1</translation> + </message> + <message> + <source>Downloading file failed: +%1</source> + <translation>Nepavyko parsiųsti rinkmenos: +%1</translation> + </message> + <message> + <source>Uploading file failed: +%1</source> + <translation>Nepavyko įkelti rinkmenos: +%1</translation> + </message> + <message> + <source>Removing file failed: +%1</source> + <translation>Nepavyko pašalinti rinkmenos: +%1</translation> + </message> + <message> + <source>Creating directory failed: +%1</source> + <translation>Nepavyko sukurti aplanko: +%1</translation> + </message> + <message> + <source>Removing directory failed: +%1</source> + <translation>Nepavyko pašalinti aplanko: +%1</translation> + </message> + <message> + <source>Connection closed</source> + <translation>Ryšys nutrauktas</translation> + </message> + <message> + <source>Host %1 found</source> + <translation>Rastas pagrindinis kompiuteris %1</translation> + </message> + <message> + <source>Connection to %1 closed</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Host found</source> + <translation>Rastas pagrindinis kompiuteris</translation> + </message> + <message> + <source>Connected to host</source> + <translation>Prisijungta prie pagrindinio kompiuterio</translation> + </message> +</context> +<context> + <name>QHostInfo</name> + <message> + <source>Unknown error</source> + <translation>Nežinoma klaida</translation> + </message> +</context> +<context> + <name>QHostInfoAgent</name> + <message> + <source>Host not found</source> + <translation>Pagrindinis kompiuteris nerastas</translation> + </message> + <message> + <source>Unknown address type</source> + <translation>Nežinimo tipo adresas</translation> + </message> + <message> + <source>Unknown error</source> + <translation>Nežinoma klaida</translation> + </message> +</context> +<context> + <name>QHttp</name> + <message> + <source>Unknown error</source> + <translation>Nežinoma klaida</translation> + </message> + <message> + <source>Request aborted</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>No server set to connect to</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Wrong content length</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Server closed connection unexpectedly</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Connection refused</source> + <translation>Ryšys atmestas</translation> + </message> + <message> + <source>Host %1 not found</source> + <translation>Pagrindinis kompiuteris %1 nerastas</translation> + </message> + <message> + <source>HTTP request failed</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid HTTP response header</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid HTTP chunked body</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Host %1 found</source> + <translation>Rastas pagrindinis kompiuteris %1</translation> + </message> + <message> + <source>Connected to host %1</source> + <translation>Prisijungta prie pagrindinio kompiuterio %1</translation> + </message> + <message> + <source>Connection to %1 closed</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Host found</source> + <translation>Rastas pagrindinis kompiuteris</translation> + </message> + <message> + <source>Connected to host</source> + <translation>Prisijungta prie pagrindinio kompiuterio</translation> + </message> + <message> + <source>Connection closed</source> + <translation>Ryšys nutrauktas</translation> + </message> + <message> + <source>Proxy authentication required</source> + <translatorcomment>Le proxy requiert une authentification</translatorcomment> + <translation>Reikia nustatyti tapatybę įgaliotame serveryje</translation> + </message> + <message> + <source>Authentication required</source> + <translation>Reikia nustatyti tapatybę</translation> + </message> + <message> + <source>Connection refused (or timed out)</source> + <translation>Ryšys atmestas (arba pasibaigė laikas)</translation> + </message> + <message> + <source>Proxy requires authentication</source> + <translation>Įgaliotasis serveris reikalauja nustatyti tapatybę</translation> + </message> + <message> + <source>Host requires authentication</source> + <translatorcomment>L'hôte requiert une authentification</translatorcomment> + <translation>Pagrindinis kompiuteris reikalauja nustatyti tapatybę</translation> + </message> + <message> + <source>Data corrupted</source> + <translatorcomment>Données corrompues</translatorcomment> + <translation>Duomenys sugadinti</translation> + </message> + <message> + <source>Unknown protocol specified</source> + <translatorcomment>Protocole spécifié inconnu</translatorcomment> + <translation>Nurodytas nežinomas protokolas</translation> + </message> + <message> + <source>SSL handshake failed</source> + <translatorcomment>le handshake SSL a échoué</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>HTTPS connection requested but SSL support not compiled in</source> + <translatorcomment>Connexion HTTPS requise mais le support SSL n'est pas compilé</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QHttpSocketEngine</name> + <message> + <source>Authentication required</source> + <translation>Reikia nustatyti tapatybę</translation> + </message> +</context> +<context> + <name>QIBaseDriver</name> + <message> + <source>Error opening database</source> + <translatorcomment>Erreur d'ouverture de la base de données</translatorcomment> + <translation>Atveriant duomenų bazę įvyko klaida</translation> + </message> + <message> + <source>Could not start transaction</source> + <translatorcomment>La transaction n'a pas pu être démarrée</translatorcomment> + <translation>Nepavyksta pradėti operacijos</translation> + </message> + <message> + <source>Unable to commit transaction</source> + <translation>Nepavyksta įkelti operacijos</translation> + </message> + <message> + <source>Unable to rollback transaction</source> + <translation>Nepavyksta atsisakyti operacijos</translation> + </message> +</context> +<context> + <name>QIBaseResult</name> + <message> + <source>Unable to create BLOB</source> + <translation>Nepavyksta sukurti BLOB</translation> + </message> + <message> + <source>Unable to write BLOB</source> + <translation>Nepavyksta įrašyti BLOB</translation> + </message> + <message> + <source>Unable to open BLOB</source> + <translation>Nepavyksta atverti BLOB</translation> + </message> + <message> + <source>Unable to read BLOB</source> + <translation>Nepavyksta nuskaityti BLOB</translation> + </message> + <message> + <source>Could not find array</source> + <translatorcomment>Impossible de trouver le tableau</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not get array data</source> + <translatorcomment>Impossible de trouver le tableau de données</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not get query info</source> + <translatorcomment>Impossible d'avoir les informations sur la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not start transaction</source> + <translation>Nepavyksta pradėti operacijos</translation> + </message> + <message> + <source>Unable to commit transaction</source> + <translation>Nepavyksta įkelti operacijos</translation> + </message> + <message> + <source>Could not allocate statement</source> + <translatorcomment>Impossible d'allouer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not prepare statement</source> + <translatorcomment>Impossible de préparer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not describe input statement</source> + <translatorcomment>Impossible de décrire la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not describe statement</source> + <translatorcomment>Impossible de décrire la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to close statement</source> + <translatorcomment>Impossible de fermer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to execute query</source> + <translatorcomment>Impossible d'exécuter la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not fetch next item</source> + <translatorcomment>Impossible de récuperer l'élément suivant</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not get statement info</source> + <translatorcomment>Impossible d'avoir les informations sur la requête</translatorcomment> + <translation>Nepavyksta gauti informacijos apie būseną</translation> + </message> +</context> +<context> + <name>QIODevice</name> + <message> + <source>Permission denied</source> + <translation>Nepakanka leidimų</translation> + </message> + <message> + <source>Too many open files</source> + <translatorcomment>Trop de fichiers ouverts simultanément</translatorcomment> + <translation>Atverta per daug rinkmenų</translation> + </message> + <message> + <source>No such file or directory</source> + <translatorcomment>Aucun fichier ou dossier de ce nom</translatorcomment> + <translation>Tokios rinkmenos ar aplanko nėra</translation> + </message> + <message> + <source>No space left on device</source> + <translatorcomment>Aucun espace disponible sur le périphérique</translatorcomment> + <translation>Įrenginyje nebėra vietos</translation> + </message> + <message> + <source>Unknown error</source> + <translation>Nežinoma klaida</translation> + </message> +</context> +<context> + <name>QInputContext</name> + <message> + <source>XIM</source> + <translation>XIM</translation> + </message> + <message> + <source>XIM input method</source> + <translation>XIM įvesties metodas</translation> + </message> + <message> + <source>Windows input method</source> + <translation>Windows įvesties metodas</translation> + </message> + <message> + <source>Mac OS X input method</source> + <translation>Mac OS X įvesties metodas</translation> + </message> +</context> +<context> + <name>QLibrary</name> + <message> + <source>QLibrary::load_sys: Cannot load %1 (%2)</source> + <translation>QLibrary::load_sys: Nepavyksta įkelti %1 (%2)</translation> + </message> + <message> + <source>QLibrary::unload_sys: Cannot unload %1 (%2)</source> + <translation>QLibrary::unload_sys: Nepavyksta iškelti %1 (%2)</translation> + </message> + <message> + <source>QLibrary::resolve_sys: Symbol "%1" undefined in %2 (%3)</source> + <translatorcomment>QLibrary::resolve_sys: Symbole "%1" non défini dans %2 (%3)</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not mmap '%1': %2</source> + <translatorcomment>Impossible d'établir la projection en mémoire de '%1' : %2</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Plugin verification data mismatch in '%1'</source> + <translatorcomment>Données de vérification du plugin différente dans '%1'</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Could not unmap '%1': %2</source> + <translatorcomment>Impossible de supprimer la projection en mémoire de '%1' : %2</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The plugin '%1' uses incompatible Qt library. (%2.%3.%4) [%5]</source> + <translatorcomment>Le plugin '%1' utilise une bibliothèque Qt incompatible. (%2.%3.%4) [%5]</translatorcomment> + <translation>„%1“ papildinys naudoja nesuderinamą Qt biblioteką. (%2.%3.%4) [%5]</translation> + </message> + <message> + <source>The plugin '%1' uses incompatible Qt library. Expected build key "%2", got "%3"</source> + <translatorcomment>Le plugin '%1' utilise une bibliothèque Qt incompatible. Clé attendue "%2", reçue "%3"</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unknown error</source> + <translation>Nežinoma klaida</translation> + </message> + <message> + <source>The shared library was not found.</source> + <translatorcomment>La bibliothèque partagée est introuvable.</translatorcomment> + <translation>Bendra biblioteka nerasta.</translation> + </message> + <message> + <source>The file '%1' is not a valid Qt plugin.</source> + <translatorcomment>Le fichier '%1' n'est pas un plugin Qt valide.</translatorcomment> + <translation>Rinkmena „%1“ nėra tinkamas Qt papildinys.</translation> + </message> + <message> + <source>The plugin '%1' uses incompatible Qt library. (Cannot mix debug and release libraries.)</source> + <translatorcomment>Le plugin '%1' utilise une bibliothèque Qt incompatible. (Il est impossible de mélanger des bibliothèques 'debug' et 'release'.)</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QLineEdit</name> + <message> + <source>&Undo</source> + <translation>Atša&ukti</translation> + </message> + <message> + <source>&Redo</source> + <translation>Paka&rtoti</translation> + </message> + <message> + <source>Cu&t</source> + <translation>Iškirp&ti</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Kopijuoti</translation> + </message> + <message> + <source>&Paste</source> + <translation>&Padėti</translation> + </message> + <message> + <source>Delete</source> + <translation>Ištrinti</translation> + </message> + <message> + <source>Select All</source> + <translation>Viską pažymėti</translation> + </message> +</context> +<context> + <name>QLocalServer</name> + <message> + <source>%1: Name error</source> + <translation>%1: Vardo klaida</translation> + </message> + <message> + <source>%1: Permission denied</source> + <translation>%1: Nepakanka leidimų</translation> + </message> + <message> + <source>%1: Address in use</source> + <translation>%1: Adresas jau naudojamas</translation> + </message> + <message> + <source>%1: Unknown error %2</source> + <translation>%1: Nežinoma klaida %2</translation> + </message> +</context> +<context> + <name>QLocalSocket</name> + <message> + <source>%1: Connection refused</source> + <translation>%1: Ryšys atmestas</translation> + </message> + <message> + <source>%1: Remote closed</source> + <translation>%1: Ryšys nutrauktas</translation> + </message> + <message> + <source>%1: Invalid name</source> + <translation>%1: Netinkamas pavadinimas</translation> + </message> + <message> + <source>%1: Socket access error</source> + <translatorcomment>%1: Erreur d'accès au socket</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: Socket resource error</source> + <translatorcomment>%1: Erreur de ressource du socket</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: Socket operation timed out</source> + <translatorcomment>%1: L'opération socket a expiré</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: Datagram too large</source> + <translatorcomment>%1: Datagramme trop grand</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: Connection error</source> + <translation>%1: Ryšio klaida</translation> + </message> + <message> + <source>%1: The socket operation is not supported</source> + <translatorcomment>%1: L'opération n'est pas supportée</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: Unknown error %2</source> + <translation>%1: Nežinoma klaida %2</translation> + </message> +</context> +<context> + <name>QMYSQLDriver</name> + <message> + <source>Unable to open database '</source> + <translation>Napavyksta atverti duomenų bazės</translation> + </message> + <message> + <source>Unable to connect</source> + <translation>Nepavyksta prisijungti</translation> + </message> + <message> + <source>Unable to begin transaction</source> + <translation>Nepavyksta pradėti operacijos</translation> + </message> + <message> + <source>Unable to commit transaction</source> + <translation>Nepavyksta įkelti operacijos</translation> + </message> + <message> + <source>Unable to rollback transaction</source> + <translation>Nepavyksta atsisakyti operacijos</translation> + </message> +</context> +<context> + <name>QMYSQLResult</name> + <message> + <source>Unable to fetch data</source> + <translation>Nepavyksta gauti duomenų</translation> + </message> + <message> + <source>Unable to execute query</source> + <translatorcomment>Impossible d'exécuter la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to store result</source> + <translatorcomment>Impossible de stocker le résultat</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to prepare statement</source> + <translatorcomment>Impossible de préparer l'instruction</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to reset statement</source> + <translatorcomment>Impossible de réinitialiser l'instruction</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to bind value</source> + <translatorcomment>Impossible d'attacher la valeur</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to execute statement</source> + <translatorcomment>Impossible d'exécuter la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to bind outvalues</source> + <translatorcomment>Impossible d'attacher les valeurs de sortie</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to store statement results</source> + <translatorcomment>Impossible de stocker les résultats de la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to execute next query</source> + <translatorcomment>Impossible d'exécuterla prochaine requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to store next result</source> + <translatorcomment>Impossible de stocker le prochain résultat</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QMdiArea</name> + <message> + <source>(Untitled)</source> + <translation>(be antraštės)</translation> + </message> +</context> +<context> + <name>QMdiSubWindow</name> + <message> + <source>%1 - [%2]</source> + <translation>%1 - [%2]</translation> + </message> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> + <message> + <source>Minimize</source> + <translation>Sumažinti</translation> + </message> + <message> + <source>Restore Down</source> + <translation>Atstatyti žemiau</translation> + </message> + <message> + <source>&Restore</source> + <translation>&Atstatyti</translation> + </message> + <message> + <source>&Move</source> + <translation>&Perkelti</translation> + </message> + <message> + <source>&Size</source> + <translation>&Dydis</translation> + </message> + <message> + <source>Mi&nimize</source> + <translation>Su&mažinti</translation> + </message> + <message> + <source>Ma&ximize</source> + <translation>Iš&didinti</translation> + </message> + <message> + <source>Stay on &Top</source> + <translation>&Visada viršuje</translation> + </message> + <message> + <source>&Close</source> + <translation>&Užverti</translation> + </message> + <message> + <source>- [%1]</source> + <translation>- [%1]</translation> + </message> + <message> + <source>Maximize</source> + <translation>Išdidinti</translation> + </message> + <message> + <source>Unshade</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Shade</source> + <translatorcomment>Ombrer</translatorcomment> + <translation>Patamsinti</translation> + </message> + <message> + <source>Restore</source> + <translation>Atstatyti</translation> + </message> + <message> + <source>Help</source> + <translation>Pagalba</translation> + </message> + <message> + <source>Menu</source> + <translation>Meniu</translation> + </message> +</context> +<context> + <name>QMenu</name> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> + <message> + <source>Open</source> + <translation>Atverti</translation> + </message> + <message> + <source>Execute</source> + <translation>Įvykdyti</translation> + </message> +</context> +<context> + <name>QMessageBox</name> + <message> + <source>Help</source> + <translation>Pagalba</translation> + </message> + <message> + <source>OK</source> + <translation>Gerai</translation> + </message> + <message> + <source>About Qt</source> + <translation>Apie Qt</translation> + </message> + <message> + <source><p>This program uses Qt version %1.</p></source> + <translation><p>Ši programa naudoja %1 Qt versija.</p></translation> + </message> + <message> + <source>Show Details...</source> + <translation>Rodyti detales...</translation> + </message> + <message> + <source>Hide Details...</source> + <translation>Slėpti detales...</translation> + </message> + <message> + <source><p>This program uses Qt Open Source Edition version %1.</p><p>Qt Open Source Edition is intended for the development of Open Source applications. You need a commercial Qt license for development of proprietary (closed source) applications.</p><p>Please see <a href="http://www.trolltech.com/company/model/">www.trolltech.com/company/model/</a> for an overview of Qt licensing.</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source><h3>About Qt</h3>%1<p>Qt is a C++ toolkit for cross-platform application development.</p><p>Qt provides single-source portability across MS&nbsp;Windows, Mac&nbsp;OS&nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.</p><p>Qt is a Nokia product. See <a href="http://www.trolltech.com/qt/">www.trolltech.com/qt/</a> for more information.</p></source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QMultiInputContext</name> + <message> + <source>Select IM</source> + <translatorcomment>Sélectionner IM</translatorcomment> + <translation>Pasirinkti ĮM</translation> + </message> +</context> +<context> + <name>QMultiInputContextPlugin</name> + <message> + <source>Multiple input method switcher</source> + <translatorcomment>Sélectionneur de méthode de saisie</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Multiple input method switcher that uses the context menu of the text widgets</source> + <translatorcomment>Sélectionneur de méthode de saisie qui utilise le menu contextuel des widgets de texte</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QNativeSocketEngine</name> + <message> + <source>The remote host closed the connection</source> + <translatorcomment>L'hôte distant a fermé la connexion</translatorcomment> + <translation>Nuotolinis pagrindinis kompiuteris nutraukė ryšį</translation> + </message> + <message> + <source>Network operation timed out</source> + <translatorcomment>L'opération réseau a expiré</translatorcomment> + <translation>Baigėsi laikas tinklo operacijai</translation> + </message> + <message> + <source>Out of resources</source> + <translatorcomment>Manque de ressources</translatorcomment> + <translation>Trūksta išteklių</translation> + </message> + <message> + <source>Unsupported socket operation</source> + <translatorcomment>Opération socket non supportée</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Protocol type not supported</source> + <translatorcomment>Protocol non géré</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid socket descriptor</source> + <translatorcomment>Descripteur de socket invalide</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Network unreachable</source> + <translatorcomment>Réseau impossible à rejoindre</translatorcomment> + <translation>Tinklas nepasiekiamas</translation> + </message> + <message> + <source>Permission denied</source> + <translation>Nepakanka leidimų</translation> + </message> + <message> + <source>Connection timed out</source> + <translatorcomment>Connexion expirée</translatorcomment> + <translation>Baigėsi ryšio laikas</translation> + </message> + <message> + <source>Connection refused</source> + <translation>Ryšys atmestas</translation> + </message> + <message> + <source>The bound address is already in use</source> + <translatorcomment>L'adresse liée est déjà en usage</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The address is not available</source> + <translatorcomment>L'adresse n'est pas disponible</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The address is protected</source> + <translatorcomment>L'adresse est protégée</translatorcomment> + <translation>Adresas apsaugotas</translation> + </message> + <message> + <source>Unable to send a message</source> + <translatorcomment>Impossible d'envoyer un message</translatorcomment> + <translation>Nepavyksta išsiųsti žinutės</translation> + </message> + <message> + <source>Unable to receive a message</source> + <translatorcomment>Impossible de recevoir un message</translatorcomment> + <translation>Nepavyksta gauti žinutės</translation> + </message> + <message> + <source>Unable to write</source> + <translatorcomment>Impossible d'écrire</translatorcomment> + <translation>Nepavyksta įrašyti</translation> + </message> + <message> + <source>Network error</source> + <translation>Tinklo klaida</translation> + </message> + <message> + <source>Another socket is already listening on the same port</source> + <translatorcomment>Un autre socket écoute déjà sur le même port</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to initialize non-blocking socket</source> + <translatorcomment>Impossible d'initialiser le socket asynchrone</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to initialize broadcast socket</source> + <translatorcomment>Impossible d'initialiser le socket broadcast</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Attempt to use IPv6 socket on a platform with no IPv6 support</source> + <translatorcomment>Tentative d'utiliser un socket IPv6 sur une plateforme qui ne supporte pas IPv6</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Host unreachable</source> + <translatorcomment>Hôte inaccessible</translatorcomment> + <translation>Pagrindinis kompiuteris nepasiekiamas</translation> + </message> + <message> + <source>Datagram was too large to send</source> + <translatorcomment>Le datagramme était trop grand pour être envoyé</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Operation on non-socket</source> + <translatorcomment>Operation sur non-socket</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unknown error</source> + <translation>Nežinoma klaida</translation> + </message> + <message> + <source>The proxy type is invalid for this operation</source> + <translatorcomment>Le type de proxy est invalide pour cette opération</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QNetworkAccessFileBackend</name> + <message> + <source>Request for opening non-local file %1</source> + <translatorcomment>Requête d'ouverture de fichier distant %1</translatorcomment> + <translation>Bandoma atverti nuotolinę rinkmeną %1</translation> + </message> + <message> + <source>Error opening %1: %2</source> + <translatorcomment>Erreur lors de l'ouverture de %1 : %2</translatorcomment> + <translation>Atveriant %1 įvyko klaida: %2</translation> + </message> + <message> + <source>Write error writing to %1: %2</source> + <translatorcomment>Erreur d'écriture de %1 : %2</translatorcomment> + <translation>Klaida rašant į %1: %2</translation> + </message> + <message> + <source>Cannot open %1: Path is a directory</source> + <translatorcomment>Impossible d'ouvrir %1 : le chemin est un dossier</translatorcomment> + <translation>Nepavyksta atverti %1: kelias yra aplankas</translation> + </message> + <message> + <source>Read error reading from %1: %2</source> + <translatorcomment>Erreur de lecture de %1 : %2</translatorcomment> + <translation>Klaida skaitant iš %1: %2</translation> + </message> +</context> +<context> + <name>QNetworkAccessFtpBackend</name> + <message> + <source>Cannot open %1: is a directory</source> + <translation>Nepavyksta atverti %1: tai yra aplankas</translation> + </message> + <message> + <source>Logging in to %1 failed: authentication required</source> + <translatorcomment>Connexion à %1 a échoué : authentification requise</translatorcomment> + <translation>Nepavyko prisijungti prie %1: reikia patvirtinti tapatybę</translation> + </message> + <message> + <source>Error while downloading %1: %2</source> + <translation>Klaida įvyko parsiunčiant %1 : %2</translation> + </message> + <message> + <source>Error while uploading %1: %2</source> + <translation>Klaida įvyko įkeliant %1 : %2</translation> + </message> +</context> +<context> + <name>QNetworkReply</name> + <message> + <source>Error downloading %1 - server replied: %2</source> + <translation>Klaida parsiunčiant %1 - serveris grąžino: %2</translation> + </message> + <message> + <source>Protocol "%1" is unknown</source> + <translation>Protokolas „%1“ nežinomas</translation> + </message> +</context> +<context> + <name>QNetworkReplyImpl</name> + <message> + <source>Operation canceled</source> + <translation>Veiksmas atšauktas</translation> + </message> +</context> +<context> + <name>QOCIDriver</name> + <message> + <source>Unable to logon</source> + <translation>Nepavyskta pradėti sesijos</translation> + </message> + <message> + <source>Unable to initialize</source> + <comment>QOCIDriver</comment> + <translation>Nepavyksta paruošti</translation> + </message> + <message> + <source>Unable to begin transaction</source> + <translation>Nepavyksta pradėti operacijos</translation> + </message> + <message> + <source>Unable to commit transaction</source> + <translation>Nepavyksta įrašyti operacijos</translation> + </message> + <message> + <source>Unable to rollback transaction</source> + <translation>Nepavyksta atsisakyti operacijos</translation> + </message> +</context> +<context> + <name>QOCIResult</name> + <message> + <source>Unable to bind column for batch execute</source> + <translatorcomment>Impossible d'attacher la colonne pour une execution batch</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to execute batch statement</source> + <translatorcomment>Impossible d'exécuter l'instruction batch</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to goto next</source> + <translatorcomment>Impossible de passer au suivant</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to alloc statement</source> + <translatorcomment>Impossible d'allouer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to prepare statement</source> + <translatorcomment>Impossible de préparer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to bind value</source> + <translatorcomment>Impossible d'attacher la valeur</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to execute select statement</source> + <translatorcomment>Impossible d'exéctuer la requête select</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to execute statement</source> + <translatorcomment>Impossible d'exéctuer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QODBCDriver</name> + <message> + <source>Unable to connect</source> + <translatorcomment>Incapable d'établir une connexion</translatorcomment> + <translation>Nepavyksta prisijungti</translation> + </message> + <message> + <source>Unable to connect - Driver doesn't support all needed functionality</source> + <translatorcomment>Impossible de se connecter - Le pilote ne supporte pas toutes les fonctionnalités nécessaires</translatorcomment> + <translation>Nepavyksta prisijungti - tvarkyklė nepaiko reikiamų funkcijų</translation> + </message> + <message> + <source>Unable to disable autocommit</source> + <translation>Nepavyksta uždrausti automatinio įkėlimo</translation> + </message> + <message> + <source>Unable to commit transaction</source> + <translation>Nepavyksta įkelti operacijos</translation> + </message> + <message> + <source>Unable to rollback transaction</source> + <translation>Nepavyksta atsisakyti operacijos</translation> + </message> + <message> + <source>Unable to enable autocommit</source> + <translation>Nepavyksta įgalinti automatinio įkėlimo</translation> + </message> +</context> +<context> + <name>QODBCResult</name> + <message> + <source>QODBCResult::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration</source> + <translatorcomment>QODBCResult::reset: Impossible d'utiliser 'SQL_CURSOR_STATIC' comme attribut de requête. Veuillez vérifier la configuration de votre pilote ODBC</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to execute statement</source> + <translatorcomment>Impossible d'exéctuer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to fetch next</source> + <translatorcomment>Impossible de récupérer le suivant</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to prepare statement</source> + <translatorcomment>Impossible de préparer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to bind variable</source> + <translatorcomment>Impossible d'attacher la variable</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to fetch last</source> + <translatorcomment>Impossible de récupérer le dernier</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to fetch</source> + <translation>Nepavyksta gauti</translation> + </message> + <message> + <source>Unable to fetch first</source> + <translatorcomment>Impossible de récupérer le premier</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to fetch previous</source> + <translatorcomment>Impossible de récupérer le précedent</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <source>Operation not supported on %1</source> + <translatorcomment>Opération non supportée sur %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid URI: %1</source> + <translation>Klaidingas URI: %1</translation> + </message> + <message> + <source>Write error writing to %1: %2</source> + <translation>Klaida rašant į %1: %2</translation> + </message> + <message> + <source>Read error reading from %1: %2</source> + <translation>Klaida skaitant iš %1: %2</translation> + </message> + <message> + <source>Socket error on %1: %2</source> + <translatorcomment>Erreur de socket sur %1 : %2</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Remote host closed the connection prematurely on %1</source> + <translatorcomment>L'hôte distant a fermé sa connexion de façon prématurée sur %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Protocol error: packet of size 0 received</source> + <translatorcomment>Erreur de protocole: paquet de taille 0 reçu</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QPPDOptionsModel</name> + <message> + <source>Name</source> + <translation>Pavadinimas</translation> + </message> + <message> + <source>Value</source> + <translation>Reikšmė</translation> + </message> +</context> +<context> + <name>QPSQLDriver</name> + <message> + <source>Unable to connect</source> + <translatorcomment>Impossible d'établir une connexion</translatorcomment> + <translation>Nepavyksta prisijungti</translation> + </message> + <message> + <source>Could not begin transaction</source> + <translation>Nepavyksta pradėti operacijos</translation> + </message> + <message> + <source>Could not commit transaction</source> + <translation>Nepavyksta įkelti operacijos</translation> + </message> + <message> + <source>Could not rollback transaction</source> + <translation>Nepavyksta atsisakyti operacijos</translation> + </message> + <message> + <source>Unable to subscribe</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to unsubscribe</source> + <translatorcomment>Impossible de se désinscrire</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QPSQLResult</name> + <message> + <source>Unable to create query</source> + <translatorcomment>Impossible de créer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to prepare statement</source> + <translatorcomment>Impossible de préparer la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QPageSetupWidget</name> + <message> + <source>Centimeters (cm)</source> + <translation>Centimetrai (cm)</translation> + </message> + <message> + <source>Millimeters (mm)</source> + <translation>Millimetrai (mm)</translation> + </message> + <message> + <source>Inches (in)</source> + <translation>Coliai (in)</translation> + </message> + <message> + <source>Points (pt)</source> + <translation>Taškai (pt)</translation> + </message> + <message> + <source>Form</source> + <translation>Forma</translation> + </message> + <message> + <source>Paper</source> + <translation>Popierius</translation> + </message> + <message> + <source>Page size:</source> + <translation>Puslapio dydis:</translation> + </message> + <message> + <source>Width:</source> + <translation>Plotis:</translation> + </message> + <message> + <source>Height:</source> + <translation>Aukštis:</translation> + </message> + <message> + <source>Paper source:</source> + <translation>Popieriaus šaltinis:</translation> + </message> + <message> + <source>Orientation</source> + <translation>Orientacija</translation> + </message> + <message> + <source>Portrait</source> + <translation>Stačias</translation> + </message> + <message> + <source>Landscape</source> + <translation>Gulsčias</translation> + </message> + <message> + <source>Reverse landscape</source> + <translation>Apverstas gulsčias</translation> + </message> + <message> + <source>Reverse portrait</source> + <translation>Apverstas stačias</translation> + </message> + <message> + <source>Margins</source> + <translation>Paraštės</translation> + </message> + <message> + <source>top margin</source> + <translation>viršutinė paraštė</translation> + </message> + <message> + <source>left margin</source> + <translation>kairioji paraštė</translation> + </message> + <message> + <source>right margin</source> + <translation>dešinioji paraštė</translation> + </message> + <message> + <source>bottom margin</source> + <translation>apatinė paraštė</translation> + </message> +</context> +<context> + <name>QPluginLoader</name> + <message> + <source>Unknown error</source> + <translation>Nežinoma klaida</translation> + </message> + <message> + <source>The plugin was not loaded.</source> + <translation>Papildinys neįkeltas.</translation> + </message> +</context> +<context> + <name>QPrintDialog</name> + <message> + <source>locally connected</source> + <translation>vietinis prijungimas</translation> + </message> + <message> + <source>Aliases: %1</source> + <translation>Pseudonimai: %1</translation> + </message> + <message> + <source>unknown</source> + <translation>nežinoma</translation> + </message> + <message> + <source>Print To File ...</source> + <translation>Spausdinti į rinkmeną...</translation> + </message> + <message> + <source>File %1 is not writable. +Please choose a different file name.</source> + <translation>Nepavyksta rašyti į %1. +Pasirinkite kitą rinkmenos pavadinimą.</translation> + </message> + <message> + <source>%1 already exists. +Do you want to overwrite it?</source> + <translation>%1 jau yra. +Perrašyti?</translation> + </message> + <message> + <source>%1 is a directory. +Please choose a different file name.</source> + <translation>%1 yra aplankas. +Pasirinkite kitą rinkmenos pavadinimą.</translation> + </message> + <message> + <source>A0</source> + <translation>A0</translation> + </message> + <message> + <source>A1</source> + <translation>A1</translation> + </message> + <message> + <source>A2</source> + <translation>A2</translation> + </message> + <message> + <source>A3</source> + <translation>A3</translation> + </message> + <message> + <source>A4</source> + <translation>A4</translation> + </message> + <message> + <source>A5</source> + <translation>A5</translation> + </message> + <message> + <source>A6</source> + <translation>A6</translation> + </message> + <message> + <source>A7</source> + <translation>A7</translation> + </message> + <message> + <source>A8</source> + <translation>A8</translation> + </message> + <message> + <source>A9</source> + <translation>A9</translation> + </message> + <message> + <source>B0</source> + <translation>B0</translation> + </message> + <message> + <source>B1</source> + <translation>B1</translation> + </message> + <message> + <source>B2</source> + <translation>B2</translation> + </message> + <message> + <source>B3</source> + <translation>B3</translation> + </message> + <message> + <source>B4</source> + <translation>B4</translation> + </message> + <message> + <source>B5</source> + <translation>B5</translation> + </message> + <message> + <source>B6</source> + <translation>B6</translation> + </message> + <message> + <source>B7</source> + <translation>B7</translation> + </message> + <message> + <source>B8</source> + <translation>B8</translation> + </message> + <message> + <source>B9</source> + <translation>B9</translation> + </message> + <message> + <source>B10</source> + <translation>B10</translation> + </message> + <message> + <source>C5E</source> + <translation>C5E</translation> + </message> + <message> + <source>DLE</source> + <translation>DLE</translation> + </message> + <message> + <source>Executive</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Folio</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ledger</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Legal</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Letter</source> + <translation>Laiškas</translation> + </message> + <message> + <source>Tabloid</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>US Common #10 Envelope</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Custom</source> + <translation>Savitas</translation> + </message> + <message> + <source>&Options >></source> + <translation>&Parinktys >></translation> + </message> + <message> + <source>&Print</source> + <translation>&Spausdinti</translation> + </message> + <message> + <source>&Options <<</source> + <translation>&Parinktys <<</translation> + </message> + <message> + <source>Print to File (PDF)</source> + <translation>Spausdinti į rinkmeną (PDF)</translation> + </message> + <message> + <source>Print to File (Postscript)</source> + <translation>Spausdinti į rinkmeną (PostScript)</translation> + </message> + <message> + <source>Local file</source> + <translation>Vietinė rinkmena</translation> + </message> + <message> + <source>Write %1 file</source> + <translation>Įrašyti į rinkmeną %1</translation> + </message> +</context> +<context> + <name>QPrintPreviewDialog</name> + <message> + <source>Page Setup</source> + <translation>Puslapio konfigūracija</translation> + </message> + <message> + <source>Print Preview</source> + <translation>Spaudinio peržiūra</translation> + </message> + <message> + <source>Next page</source> + <translation>Tolesnis puslapis</translation> + </message> + <message> + <source>Previous page</source> + <translation>Ankstesnis puslapis</translation> + </message> + <message> + <source>First page</source> + <translation>Pirmas puslapis</translation> + </message> + <message> + <source>Last page</source> + <translation>Paskutinis puslapis</translation> + </message> + <message> + <source>Fit width</source> + <translation>Taikyti pagal plotį</translation> + </message> + <message> + <source>Fit page</source> + <translation>Įtalpinti puslapį</translation> + </message> + <message> + <source>Zoom in</source> + <translation>Priartinti</translation> + </message> + <message> + <source>Zoom out</source> + <translation>Atitolinti</translation> + </message> + <message> + <source>Portrait</source> + <translation>Stačias</translation> + </message> + <message> + <source>Landscape</source> + <translation>Gulsčias</translation> + </message> + <message> + <source>Show single page</source> + <translation>Rodyti vieną puslapį</translation> + </message> + <message> + <source>Show facing pages</source> + <translation>Rodyti po du puslapius</translation> + </message> + <message> + <source>Show overview of all pages</source> + <translation>Rodyti visus puslapius</translation> + </message> + <message> + <source>Print</source> + <translation>Spausdinti</translation> + </message> + <message> + <source>Page setup</source> + <translation>Puslapio konfigūracija</translation> + </message> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> +</context> +<context> + <name>QPrintPropertiesWidget</name> + <message> + <source>Form</source> + <translation>Forma</translation> + </message> + <message> + <source>Page</source> + <translation>Puslapis</translation> + </message> + <message> + <source>Advanced</source> + <translation>Sudėtingiau</translation> + </message> +</context> +<context> + <name>QPrintSettingsOutput</name> + <message> + <source>Form</source> + <translation>Forma</translation> + </message> + <message> + <source>Copies</source> + <translation>Kopijos</translation> + </message> + <message> + <source>Print range</source> + <translatorcomment>Imprimer la sélection</translatorcomment> + <translation>Spausdinimo rėžis</translation> + </message> + <message> + <source>Print all</source> + <translation>Viską spausdinti</translation> + </message> + <message> + <source>Pages from</source> + <translation>Puslapius nuo</translation> + </message> + <message> + <source>to</source> + <translation>iki</translation> + </message> + <message> + <source>Selection</source> + <translatorcomment>Sélection</translatorcomment> + <translation>Pasirinkimas</translation> + </message> + <message> + <source>Output Settings</source> + <translatorcomment>Paramètres de sortie</translatorcomment> + <translation>Išvesties nuostatos</translation> + </message> + <message> + <source>Copies:</source> + <translation>Kopijos:</translation> + </message> + <message> + <source>Collate</source> + <translatorcomment>Assembler</translatorcomment> + <translation>Rikiuoti</translation> + </message> + <message> + <source>Reverse</source> + <translatorcomment>Inverse</translatorcomment> + <translation>Atvirkščiai</translation> + </message> + <message> + <source>Options</source> + <translation>Parinktys</translation> + </message> + <message> + <source>Color Mode</source> + <translation>Spalvų veiksena</translation> + </message> + <message> + <source>Color</source> + <translation>Spalvota</translation> + </message> + <message> + <source>Grayscale</source> + <translation>Pilkumo skalė</translation> + </message> + <message> + <source>Duplex Printing</source> + <translatorcomment>Impression en duplex</translatorcomment> + <translation>Dvipusis spausdinimas</translation> + </message> + <message> + <source>None</source> + <translation>Nieko</translation> + </message> + <message> + <source>Long side</source> + <translatorcomment>Côté long</translatorcomment> + <translation>Platusis kraštas</translation> + </message> + <message> + <source>Short side</source> + <translatorcomment>Côté court</translatorcomment> + <translation>Siaurasis kraštas</translation> + </message> +</context> +<context> + <name>QPrintWidget</name> + <message> + <source>Form</source> + <translation>Forma</translation> + </message> + <message> + <source>Printer</source> + <translation>Spausdintuvas</translation> + </message> + <message> + <source>&Name:</source> + <translation>&Pavadinimas:</translation> + </message> + <message> + <source>P&roperties</source> + <translation>&Savybės</translation> + </message> + <message> + <source>Location:</source> + <translation>Vieta:</translation> + </message> + <message> + <source>Preview</source> + <translation>Peržiūra</translation> + </message> + <message> + <source>Type:</source> + <translation>Tipas:</translation> + </message> + <message> + <source>Output &file:</source> + <translation>Išvesties &rinkmena:</translation> + </message> + <message> + <source>...</source> + <translation>...</translation> + </message> +</context> +<context> + <name>QProgressDialog</name> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> +</context> +<context> + <name>QPushButton</name> + <message> + <source>Open</source> + <translation>Atverti</translation> + </message> +</context> +<context> + <name>QRadioButton</name> + <message> + <source>Check</source> + <translation>Pažymėti</translation> + </message> +</context> +<context> + <name>QRegExp</name> + <message> + <source>no error occurred</source> + <translatorcomment>aucune erreur ne s'est produite</translatorcomment> + <translation>jokių klaidų</translation> + </message> + <message> + <source>disabled feature used</source> + <translation>parinktis uždrausta</translation> + </message> + <message> + <source>bad char class syntax</source> + <translatorcomment>syntaxe invalide pour classe de caractère</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>bad lookahead syntax</source> + <translatorcomment>syntaxe invalide pour lookahead</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>bad repetition syntax</source> + <translatorcomment>syntaxe invalide pour répétition</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>invalid octal value</source> + <translatorcomment>valeur octale invalide</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>missing left delim</source> + <translatorcomment>délémiteur gauche manquant</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>unexpected end</source> + <translatorcomment>fin impromptue</translatorcomment> + <translation>netikėta pabaiga</translation> + </message> + <message> + <source>met internal limit</source> + <translatorcomment>rencontré limite interne</translatorcomment> + <translation>pasiekta vidinė riba</translation> + </message> +</context> +<context> + <name>QSQLite2Driver</name> + <message> + <source>Error to open database</source> + <translatorcomment>Erreur à l'ouverture de la base de données</translatorcomment> + <translation>Atveriant duomenų bazę įvyko klaida</translation> + </message> + <message> + <source>Unable to begin transaction</source> + <translation>Nepavyksta pradėti operacijos</translation> + </message> + <message> + <source>Unable to commit transaction</source> + <translation>Nepavyksta įkelti operacijos</translation> + </message> + <message> + <source>Unable to rollback Transaction</source> + <translation>Nepavyksta atsisakyti operacijos</translation> + </message> +</context> +<context> + <name>QSQLite2Result</name> + <message> + <source>Unable to fetch results</source> + <translation>Nepavyksta gauti rezultatų</translation> + </message> + <message> + <source>Unable to execute statement</source> + <translatorcomment>Impossible d'exécuter la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QSQLiteDriver</name> + <message> + <source>Error opening database</source> + <translation>Atveriant duomenų bazę įvyko klaida</translation> + </message> + <message> + <source>Error closing database</source> + <translation>Užveriant duomenų bazę įvyko klaida</translation> + </message> + <message> + <source>Unable to begin transaction</source> + <translation>Nepavyksta pradėti operacijos</translation> + </message> + <message> + <source>Unable to commit transaction</source> + <translation>Nepavyksta įkelti operacijos</translation> + </message> + <message> + <source>Unable to rollback transaction</source> + <translation>Nepavyksta atsisakyti operacijos</translation> + </message> +</context> +<context> + <name>QSQLiteResult</name> + <message> + <source>Unable to fetch row</source> + <translation>Nepavyksta gauti dabar</translation> + </message> + <message> + <source>Unable to execute statement</source> + <translatorcomment>Impossible d'exécuter la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to reset statement</source> + <translatorcomment>Impossible de réinitialiser la requête</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unable to bind parameters</source> + <translatorcomment>Impossible d'attacher les paramètres</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Parameter count mismatch</source> + <translatorcomment>Nombre de paramètres incorrect</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No query</source> + <translatorcomment>Pas de requête</translatorcomment> + <translation>Užklausos nėra</translation> + </message> +</context> +<context> + <name>QScrollBar</name> + <message> + <source>Scroll here</source> + <translation>Slikti iki čia</translation> + </message> + <message> + <source>Left edge</source> + <translation>Kairysis kraštas</translation> + </message> + <message> + <source>Top</source> + <translation>Viršus</translation> + </message> + <message> + <source>Right edge</source> + <translation>Dešinysis kraštas</translation> + </message> + <message> + <source>Bottom</source> + <translation>Apačia</translation> + </message> + <message> + <source>Page left</source> + <translation>Puslapis kairėje</translation> + </message> + <message> + <source>Page up</source> + <translation>Puslapiu aukštyn</translation> + </message> + <message> + <source>Page right</source> + <translation>Puslapis dešinėje</translation> + </message> + <message> + <source>Page down</source> + <translation>Puslapiu žemyn</translation> + </message> + <message> + <source>Scroll left</source> + <translation>Slinkti kairėn</translation> + </message> + <message> + <source>Scroll up</source> + <translation>Slikti auktyn</translation> + </message> + <message> + <source>Scroll right</source> + <translation>Slinkti dešinėn</translation> + </message> + <message> + <source>Scroll down</source> + <translation>Slinkti žemyn</translation> + </message> + <message> + <source>Line up</source> + <translation>Linija aukštyn</translation> + </message> + <message> + <source>Position</source> + <translation>Padėtis</translation> + </message> + <message> + <source>Line down</source> + <translation>Linija žemyn</translation> + </message> +</context> +<context> + <name>QSharedMemory</name> + <message> + <source>%1: unable to set key on lock</source> + <translatorcomment>%1 : impossible d'affecter la clé au verrou</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: create size is less then 0</source> + <translatorcomment>%1 : taille de création est inférieur à 0</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: unable to lock</source> + <translatorcomment>%1 : impossible de vérrouiller</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: unable to unlock</source> + <translatorcomment>%1 : impossible de déverrouiller</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: permission denied</source> + <translation>%1: nepakanka leidimų</translation> + </message> + <message> + <source>%1: already exists</source> + <translation>%1: jau yra</translation> + </message> + <message> + <source>%1: doesn't exists</source> + <translation>%1: nėra</translation> + </message> + <message> + <source>%1: out of resources</source> + <translation>%1: viršija išteklius</translation> + </message> + <message> + <source>%1: unknown error %2</source> + <translation>%1: nežinoma klaida %2</translation> + </message> + <message> + <source>%1: key is empty</source> + <translatorcomment>%1 : clé vide</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: unix key file doesn't exists</source> + <translatorcomment>%1 : le fichier de clé unix n'existe pas</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: ftok failed</source> + <translatorcomment>%1 : ftok a échoué</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: unable to make key</source> + <translatorcomment>%1 : impossible de créer la clé</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: system-imposed size restrictions</source> + <translatorcomment>%1 : le système impose des restrictions sur la taille</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1: not attached</source> + <translatorcomment>%1 : non attaché</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QShortcut</name> + <message> + <source>Space</source> + <translation>Tarpas</translation> + </message> + <message> + <source>Esc</source> + <translation>Gr(įžti)</translation> + </message> + <message> + <source>Tab</source> + <translation>Tab(uliacija)</translation> + </message> + <message> + <source>Backtab</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Backspace</source> + <translation>Naikinti</translation> + </message> + <message> + <source>Return</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Enter</source> + <translation>Įvesti</translation> + </message> + <message> + <source>Ins</source> + <translation>Įterpti</translation> + </message> + <message> + <source>Del</source> + <translation>Šalinti</translation> + </message> + <message> + <source>Pause</source> + <translation>Pauzė</translation> + </message> + <message> + <source>Print</source> + <translation>Ekrano nuotrauka</translation> + </message> + <message> + <source>SysReq</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Home</source> + <translation>Prad(žia)</translation> + </message> + <message> + <source>End</source> + <translation>Pab(aiga)</translation> + </message> + <message> + <source>Left</source> + <translation>Kairėn</translation> + </message> + <message> + <source>Up</source> + <translation>Aukštyn</translation> + </message> + <message> + <source>Right</source> + <translation>Dešinėn</translation> + </message> + <message> + <source>Down</source> + <translation>Žemyn</translation> + </message> + <message> + <source>PgUp</source> + <translation>Psl aukštyn</translation> + </message> + <message> + <source>PgDown</source> + <translation>Psl žemyn</translation> + </message> + <message> + <source>CapsLock</source> + <translation>Didž(iosios)</translation> + </message> + <message> + <source>NumLock</source> + <translation>Skaitm(enys)</translation> + </message> + <message> + <source>ScrollLock</source> + <translation>Slinkti</translation> + </message> + <message> + <source>Menu</source> + <translation>Meniu</translation> + </message> + <message> + <source>Help</source> + <translation>Pagalba</translation> + </message> + <message> + <source>Back</source> + <translation>Atgal</translation> + </message> + <message> + <source>Forward</source> + <translation>Toliau</translation> + </message> + <message> + <source>Stop</source> + <translation>Stabdyti</translation> + </message> + <message> + <source>Refresh</source> + <translation>Atnaujinti</translation> + </message> + <message> + <source>Volume Down</source> + <translation>Pritildyti</translation> + </message> + <message> + <source>Volume Mute</source> + <translation>Nutildyti</translation> + </message> + <message> + <source>Volume Up</source> + <translation>Pagarsinti</translation> + </message> + <message> + <source>Bass Boost</source> + <translatorcomment>Graves fort</translatorcomment> + <translation>Žemi dažniai</translation> + </message> + <message> + <source>Bass Up</source> + <translatorcomment>Graves haut</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Bass Down</source> + <translatorcomment>Graves bas</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Treble Up</source> + <translatorcomment>Aigus haut</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Treble Down</source> + <translatorcomment>Aigus bas</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Media Play</source> + <translation>Groti kūrinį</translation> + </message> + <message> + <source>Media Stop</source> + <translation>Sustabdyti kūrinį</translation> + </message> + <message> + <source>Media Previous</source> + <translation>Ankstenis kūrinys</translation> + </message> + <message> + <source>Media Next</source> + <translation>Tolesnis kūrinys</translation> + </message> + <message> + <source>Media Record</source> + <translation>Įrašyti kūrinį</translation> + </message> + <message> + <source>Favorites</source> + <translatorcomment>Préférés</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Search</source> + <translatorcomment>Recherche</translatorcomment> + <translation>Ieškoti</translation> + </message> + <message> + <source>Standby</source> + <translatorcomment>Attente</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Open URL</source> + <translation>Atverti URL</translation> + </message> + <message> + <source>Launch Mail</source> + <translatorcomment>Lancer courrier</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Launch Media</source> + <translatorcomment>Lancer média</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Launch (0)</source> + <translation>Paleisti (0)</translation> + </message> + <message> + <source>Launch (1)</source> + <translation>Paleisti (1)</translation> + </message> + <message> + <source>Launch (2)</source> + <translation>Paleisti (2)</translation> + </message> + <message> + <source>Launch (3)</source> + <translation>Paleisti (3)</translation> + </message> + <message> + <source>Launch (4)</source> + <translation>Paleisti (4)</translation> + </message> + <message> + <source>Launch (5)</source> + <translation>Paleisti (5)</translation> + </message> + <message> + <source>Launch (6)</source> + <translation>Paleisti (6)</translation> + </message> + <message> + <source>Launch (7)</source> + <translation>Paleisti (7)</translation> + </message> + <message> + <source>Launch (8)</source> + <translation>Paleisti (8)</translation> + </message> + <message> + <source>Launch (9)</source> + <translation>Paleisti (9)</translation> + </message> + <message> + <source>Launch (A)</source> + <translation>Paleisti (A)</translation> + </message> + <message> + <source>Launch (B)</source> + <translation>Paleisti (B)</translation> + </message> + <message> + <source>Launch (C)</source> + <translation>Paleisti (C)</translation> + </message> + <message> + <source>Launch (D)</source> + <translation>Paleisti (D)</translation> + </message> + <message> + <source>Launch (E)</source> + <translation>Paleisti (E)</translation> + </message> + <message> + <source>Launch (F)</source> + <translation>Paleisti (F)</translation> + </message> + <message> + <source>Print Screen</source> + <translation>Ekrano nuotrauka</translation> + </message> + <message> + <source>Page Up</source> + <translation>Puslapiu aukštyn</translation> + </message> + <message> + <source>Page Down</source> + <translation>Puslapiu žemyn</translation> + </message> + <message> + <source>Caps Lock</source> + <translation>Didžiosios</translation> + </message> + <message> + <source>Num Lock</source> + <translation>Skaitmenys</translation> + </message> + <message> + <source>Number Lock</source> + <translation>Skaitmenys</translation> + </message> + <message> + <source>Scroll Lock</source> + <translation>Slinkti</translation> + </message> + <message> + <source>Insert</source> + <translation>Įterpti</translation> + </message> + <message> + <source>Delete</source> + <translation>Šalinti</translation> + </message> + <message> + <source>Escape</source> + <translation>Grįžti</translation> + </message> + <message> + <source>System Request</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Select</source> + <translation>Pasirinkti</translation> + </message> + <message> + <source>Yes</source> + <translation>Taip</translation> + </message> + <message> + <source>No</source> + <translation>Ne</translation> + </message> + <message> + <source>Context1</source> + <translation type="unfinished">Contexte1</translation> + </message> + <message> + <source>Context2</source> + <translation type="unfinished">Contexte2</translation> + </message> + <message> + <source>Context3</source> + <translation type="unfinished">Contexte3</translation> + </message> + <message> + <source>Context4</source> + <translation type="unfinished">Contexte4</translation> + </message> + <message> + <source>Call</source> + <translation type="unfinished">Appeler</translation> + </message> + <message> + <source>Hangup</source> + <translation type="unfinished">Raccrocher</translation> + </message> + <message> + <source>Flip</source> + <translation type="unfinished">Retourner</translation> + </message> + <message> + <source>Ctrl</source> + <translation>Vald</translation> + </message> + <message> + <source>Shift</source> + <translation>Lyg2</translation> + </message> + <message> + <source>Alt</source> + <translation>Alt</translation> + </message> + <message> + <source>Meta</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>+</source> + <translation>+</translation> + </message> + <message> + <source>F%1</source> + <translation>F%1</translation> + </message> + <message> + <source>Home Page</source> + <translation>Pagrindinis puslapis</translation> + </message> +</context> +<context> + <name>QSlider</name> + <message> + <source>Page left</source> + <translation>Puslapis kairėje</translation> + </message> + <message> + <source>Page up</source> + <translation>Puslapiu aukštyn</translation> + </message> + <message> + <source>Position</source> + <translation>Padėtis</translation> + </message> + <message> + <source>Page right</source> + <translation>Puslapis dešinėje</translation> + </message> + <message> + <source>Page down</source> + <translation>Puslapiu žemyn</translation> + </message> +</context> +<context> + <name>QSocks5SocketEngine</name> + <message> + <source>Socks5 timeout error connecting to socks server</source> + <translatorcomment>Erreur d'expiration socks5 lors de l'établissement d'une connexion au serveur socks</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Network operation timed out</source> + <translatorcomment>L'opération réseau a expiré</translatorcomment> + <translation>Baigėsi laikas tinklo operacijai</translation> + </message> +</context> +<context> + <name>QSpinBox</name> + <message> + <source>More</source> + <translation>Daugiau</translation> + </message> + <message> + <source>Less</source> + <translation>Mažiau</translation> + </message> +</context> +<context> + <name>QSql</name> + <message> + <source>Delete</source> + <translatorcomment>Supprimer</translatorcomment> + <translation>Šalinti</translation> + </message> + <message> + <source>Delete this record?</source> + <translatorcomment>Supprimer cet enregistrement ?</translatorcomment> + <translation>Pašalinti įrašą?</translation> + </message> + <message> + <source>Yes</source> + <translation>Taip</translation> + </message> + <message> + <source>No</source> + <translation>Ne</translation> + </message> + <message> + <source>Insert</source> + <translatorcomment>Insérer</translatorcomment> + <translation>Įterpti</translation> + </message> + <message> + <source>Update</source> + <translation>Atnaujinti</translation> + </message> + <message> + <source>Save edits?</source> + <translatorcomment>Enregistrer les modifications</translatorcomment> + <translation>Išsaugoti pakeitimus?</translation> + </message> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>Confirm</source> + <translation>Patvirtinti</translation> + </message> + <message> + <source>Cancel your edits?</source> + <translatorcomment>Annuler vos modifications </translatorcomment> + <translation>Atmesti pakeitimus?</translation> + </message> +</context> +<context> + <name>QSslSocket</name> + <message> + <source>Unable to write data: %1</source> + <translation>Nepavyksta įrašyti duomenų: %1</translation> + </message> + <message> + <source>Error while reading: %1</source> + <translation>Skaitymo klaida: %1</translation> + </message> + <message> + <source>Error during SSL handshake: %1</source> + <translatorcomment>Erreur lors de la poignée de main SSL : %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Error creating SSL context (%1)</source> + <translatorcomment>Erreur lors de la création du contexte SSL (%1)</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid or empty cipher list (%1)</source> + <translatorcomment>La list de chiffrements est invalide ou vide (%1)</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Error creating SSL session, %1</source> + <translation>Kuriant SSL sesiją įvyko klaida, %1</translation> + </message> + <message> + <source>Error creating SSL session: %1</source> + <translation>Kuriant SSL sesiją įvyko klaida: %1</translation> + </message> + <message> + <source>Cannot provide a certificate with no key, %1</source> + <translatorcomment>Impossible de fournir un certificat sans clé, %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Error loading local certificate, %1</source> + <translation>Įkeliant vietinį liudijimą įvyko klaida, %1</translation> + </message> + <message> + <source>Error loading private key, %1</source> + <translatorcomment>Erreur lors du chargement de la clé privée, %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Private key does not certificate public key, %1</source> + <translatorcomment>La clé privée ne certifie pas la clé publique, %1</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QTDSDriver</name> + <message> + <source>Unable to open connection</source> + <translatorcomment>Impossible d'ouvrir la connexion</translatorcomment> + <translation>nepavyksta atverti ryšio</translation> + </message> + <message> + <source>Unable to use database</source> + <translatorcomment>Impossible d'utiliser la base de données</translatorcomment> + <translation>Napavyksta pasinaudoti duomenų baze</translation> + </message> +</context> +<context> + <name>QTabBar</name> + <message> + <source>Scroll Left</source> + <translation>Slinkti kairėn</translation> + </message> + <message> + <source>Scroll Right</source> + <translation>Slinkti dešinėn</translation> + </message> +</context> +<context> + <name>QTextControl</name> + <message> + <source>&Undo</source> + <translation>Atša&ukti</translation> + </message> + <message> + <source>&Redo</source> + <translation>Paka&rtoti</translation> + </message> + <message> + <source>Cu&t</source> + <translation>Iškirp&ti</translation> + </message> + <message> + <source>&Copy</source> + <translation>&Kopijuoti</translation> + </message> + <message> + <source>Copy &Link Location</source> + <translation>Kopijuoti &jungties adresą</translation> + </message> + <message> + <source>&Paste</source> + <translation>&Padėti</translation> + </message> + <message> + <source>Delete</source> + <translation>Ištrinti</translation> + </message> + <message> + <source>Select All</source> + <translation>Viską pažymėti</translation> + </message> +</context> +<context> + <name>QToolButton</name> + <message> + <source>Press</source> + <translation>Spausti</translation> + </message> + <message> + <source>Open</source> + <translation>Atverti</translation> + </message> +</context> +<context> + <name>QUdpSocket</name> + <message> + <source>This platform does not support IPv6</source> + <translatorcomment>Cette plateforme ne supporte pas IPv6</translatorcomment> + <translation>Ši platforma nepalaiko IPv6</translation> + </message> +</context> +<context> + <name>QUndoGroup</name> + <message> + <source>Undo</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>Redo</source> + <translation>Pakartoti</translation> + </message> +</context> +<context> + <name>QUndoModel</name> + <message> + <source><empty></source> + <translation><tuščia></translation> + </message> +</context> +<context> + <name>QUndoStack</name> + <message> + <source>Undo</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>Redo</source> + <translation>Pakartoti</translation> + </message> +</context> +<context> + <name>QUnicodeControlCharacterMenu</name> + <message> + <source>LRM Left-to-right mark</source> + <translation>LRM žymė iš kairės į dešinę</translation> + </message> + <message> + <source>RLM Right-to-left mark</source> + <translation>RLM žymė iš dešinės į kairę</translation> + </message> + <message> + <source>ZWJ Zero width joiner</source> + <translation>ZWJ nulinio pločio jungtis</translation> + </message> + <message> + <source>ZWNJ Zero width non-joiner</source> + <translation>ZWNJ nulinio pločio nejungtis</translation> + </message> + <message> + <source>ZWSP Zero width space</source> + <translation>ZWSP nulinio pločio tarpas</translation> + </message> + <message> + <source>LRE Start of left-to-right embedding</source> + <translation>LRE „iš kairės į dešinę“ integruotas</translation> + </message> + <message> + <source>RLE Start of right-to-left embedding</source> + <translation>RLE „iš dešinės į kairę“ integruotas</translation> + </message> + <message> + <source>LRO Start of left-to-right override</source> + <translation>LRO „iš kairės į dešinę“ atšaukimas</translation> + </message> + <message> + <source>RLO Start of right-to-left override</source> + <translation>RLO „iš dešinės į kairę“ atšaukimas</translation> + </message> + <message> + <source>PDF Pop directional formatting</source> + <translation>PDF Pop kryptingas formatavimas</translation> + </message> + <message> + <source>Insert Unicode control character</source> + <translation>Įterpti unikodo valdymo simbolį</translation> + </message> +</context> +<context> + <name>QWebFrame</name> + <message> + <source>Request cancelled</source> + <translatorcomment>Requête annulée</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Request blocked</source> + <translatorcomment>Requête bloquée</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Cannot show URL</source> + <translation>Nepavyksta parodyti URL</translation> + </message> + <message> + <source>Frame load interruped by policy change</source> + <translatorcomment>Chargement de la frame interrompu par un changement de configuration</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Cannot show mimetype</source> + <translatorcomment>Impossible d'afficher le mimetype</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>File does not exist</source> + <translation>Rinkmenos nėra</translation> + </message> +</context> +<context> + <name>QWebPage</name> + <message> + <source>Bad HTTP request</source> + <translatorcomment>Requête HTTP erronée</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Submit</source> + <comment>default label for Submit buttons in forms on web pages</comment> + <translation>Pateikti</translation> + </message> + <message> + <source>Submit</source> + <comment>Submit (input element) alt text for <input> elements with no alt, title, or value</comment> + <translation>Pateikti</translation> + </message> + <message> + <source>Reset</source> + <comment>default label for Reset buttons in forms on web pages</comment> + <translation>Iš naujo</translation> + </message> + <message> + <source>This is a searchable index. Enter search keywords: </source> + <comment>text that appears at the start of nearly-obsolete web pages in the form of a 'searchable index'</comment> + <translatorcomment>Ceci est un index. Veuillez saisir les mots-clé :</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Choose File</source> + <comment>title for file button used in HTML forms</comment> + <translation>Pasirinkti rinkmeną</translation> + </message> + <message> + <source>No file selected</source> + <comment>text to display in file button used in HTML forms when no file is selected</comment> + <translation>Rinkmena nepasirinkta</translation> + </message> + <message> + <source>Open in New Window</source> + <comment>Open in New Window context menu item</comment> + <translation>Atverti naujame lange</translation> + </message> + <message> + <source>Save Link...</source> + <comment>Download Linked File context menu item</comment> + <translation>Įrašyti nuorodą...</translation> + </message> + <message> + <source>Copy Link</source> + <comment>Copy Link context menu item</comment> + <translation>Kopijuoti nuorodą</translation> + </message> + <message> + <source>Open Image</source> + <comment>Open Image in New Window context menu item</comment> + <translation>Atverti paveikslėlį</translation> + </message> + <message> + <source>Save Image</source> + <comment>Download Image context menu item</comment> + <translation>Įrašyti paveikslėlį</translation> + </message> + <message> + <source>Copy Image</source> + <comment>Copy Link context menu item</comment> + <translation>Kopijuoti paveikslėlį</translation> + </message> + <message> + <source>Open Frame</source> + <comment>Open Frame in New Window context menu item</comment> + <translation>Atverti kadrą</translation> + </message> + <message> + <source>Copy</source> + <comment>Copy context menu item</comment> + <translation>Kopijuoti</translation> + </message> + <message> + <source>Go Back</source> + <comment>Back context menu item</comment> + <translation>Atgal</translation> + </message> + <message> + <source>Go Forward</source> + <comment>Forward context menu item</comment> + <translation>Toliau</translation> + </message> + <message> + <source>Stop</source> + <comment>Stop context menu item</comment> + <translation>Stabdyti</translation> + </message> + <message> + <source>Reload</source> + <comment>Reload context menu item</comment> + <translation>Įkelti iš naujo</translation> + </message> + <message> + <source>Cut</source> + <comment>Cut context menu item</comment> + <translation>Iškirpti</translation> + </message> + <message> + <source>Paste</source> + <comment>Paste context menu item</comment> + <translation>Padėti</translation> + </message> + <message> + <source>No Guesses Found</source> + <comment>No Guesses Found context menu item</comment> + <translatorcomment>Pas de candidat trouvés</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ignore</source> + <comment>Ignore Spelling context menu item</comment> + <translation>Nepaisyti</translation> + </message> + <message> + <source>Add To Dictionary</source> + <comment>Learn Spelling context menu item</comment> + <translation>Įtraukti į žodyną</translation> + </message> + <message> + <source>Search The Web</source> + <comment>Search The Web context menu item</comment> + <translation>Ieškoti žiniatinklyje</translation> + </message> + <message> + <source>Look Up In Dictionary</source> + <comment>Look Up in Dictionary context menu item</comment> + <translation>Ieškoti žodyne</translation> + </message> + <message> + <source>Open Link</source> + <comment>Open Link context menu item</comment> + <translation>Atverti nuorodą</translation> + </message> + <message> + <source>Ignore</source> + <comment>Ignore Grammar context menu item</comment> + <translation>Nepaisyti</translation> + </message> + <message> + <source>Spelling</source> + <comment>Spelling and Grammar context sub-menu item</comment> + <translation>Rašybos tikrinimas</translation> + </message> + <message> + <source>Show Spelling and Grammar</source> + <comment>menu item title</comment> + <translation>Rodyti rašybos ir gramatikos tikrinimą</translation> + </message> + <message> + <source>Hide Spelling and Grammar</source> + <comment>menu item title</comment> + <translation>Slėpti rašybos ir gramatikos tikrinimą</translation> + </message> + <message> + <source>Check Spelling</source> + <comment>Check spelling context menu item</comment> + <translation>Tikrinti rašybą</translation> + </message> + <message> + <source>Check Spelling While Typing</source> + <comment>Check spelling while typing context menu item</comment> + <translation>Rašybą tikrinti įvedimo metu</translation> + </message> + <message> + <source>Check Grammar With Spelling</source> + <comment>Check grammar with spelling context menu item</comment> + <translation>Tikrinant rašybą, tikrinti ir gramatiką</translation> + </message> + <message> + <source>Fonts</source> + <comment>Font context sub-menu item</comment> + <translation>Šriftai</translation> + </message> + <message> + <source>Bold</source> + <comment>Bold context menu item</comment> + <translation>Pusjuodis</translation> + </message> + <message> + <source>Italic</source> + <comment>Italic context menu item</comment> + <translation>Kursyvinis</translation> + </message> + <message> + <source>Underline</source> + <comment>Underline context menu item</comment> + <translation>Pabrauktas</translation> + </message> + <message> + <source>Outline</source> + <comment>Outline context menu item</comment> + <translation>Kontūras</translation> + </message> + <message> + <source>Direction</source> + <comment>Writing direction context sub-menu item</comment> + <translation>Kryptis</translation> + </message> + <message> + <source>Default</source> + <comment>Default writing direction context menu item</comment> + <translation>Numatyta</translation> + </message> + <message> + <source>LTR</source> + <comment>Left to Right context menu item</comment> + <translation>Iš kairės į dešinę</translation> + </message> + <message> + <source>RTL</source> + <comment>Right to Left context menu item</comment> + <translation>Iš dešinės į kairę</translation> + </message> + <message> + <source>Inspect</source> + <comment>Inspect Element context menu item</comment> + <translatorcomment>Inspecter</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No recent searches</source> + <comment>Label for only item in menu that appears when clicking on the search field image, when no searches have been performed</comment> + <translation>Paieškų nebuvo</translation> + </message> + <message> + <source>Recent searches</source> + <comment>label for first item in the menu that appears when clicking on the search field image, used as embedded menu title</comment> + <translation>Paskiausios paieškos</translation> + </message> + <message> + <source>Clear recent searches</source> + <comment>menu item in Recent Searches menu that empties menu's contents</comment> + <translation>Išvalyti paskiausias paieškas</translation> + </message> + <message> + <source>Unknown</source> + <comment>Unknown filesize FTP directory listing item</comment> + <translation>Nežinoma</translation> + </message> + <message> + <source>%1 (%2x%3 pixels)</source> + <comment>Title string for images</comment> + <translation>%1 (%2x%3 tšk)</translation> + </message> + <message> + <source>Web Inspector - %2</source> + <translatorcomment>Inspecteur Web - %2</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QWhatsThisAction</name> + <message> + <source>What's This?</source> + <translation>Kas tai?</translation> + </message> +</context> +<context> + <name>QWidget</name> + <message> + <source>*</source> + <translation>*</translation> + </message> +</context> +<context> + <name>QWizard</name> + <message> + <source>Go Back</source> + <translation>Atgal</translation> + </message> + <message> + <source>Continue</source> + <translation>Toliau</translation> + </message> + <message> + <source>Commit</source> + <translation>Įkelti</translation> + </message> + <message> + <source>Done</source> + <translation>Užbaigti</translation> + </message> + <message> + <source>Quit</source> + <translation>Baigti</translation> + </message> + <message> + <source>Help</source> + <translation>Pagalba</translation> + </message> + <message> + <source>< &Back</source> + <translation>< &Atgal</translation> + </message> + <message> + <source>&Finish</source> + <translation>&Užbaigti</translation> + </message> + <message> + <source>Cancel</source> + <translation>Atšaukti</translation> + </message> + <message> + <source>&Help</source> + <translation>&Pagalba</translation> + </message> + <message> + <source>&Next</source> + <translation>&Toliau</translation> + </message> + <message> + <source>&Next ></source> + <translation>&Toliau ></translation> + </message> +</context> +<context> + <name>QWorkspace</name> + <message> + <source>&Restore</source> + <translation>&Atstatyti</translation> + </message> + <message> + <source>&Move</source> + <translation>&Perkelti</translation> + </message> + <message> + <source>&Size</source> + <translation>&Keisti dydį</translation> + </message> + <message> + <source>Mi&nimize</source> + <translation>Su&mažinti</translation> + </message> + <message> + <source>Ma&ximize</source> + <translation>Iš&didinti</translation> + </message> + <message> + <source>&Close</source> + <translation>&Užverti</translation> + </message> + <message> + <source>Stay on &Top</source> + <translation>&Visada viršuje</translation> + </message> + <message> + <source>Sh&ade</source> + <translatorcomment>&Enrouler</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 - [%2]</source> + <translation>%1 - [%2]</translation> + </message> + <message> + <source>Minimize</source> + <translation>Sumažinti</translation> + </message> + <message> + <source>Restore Down</source> + <translatorcomment>Restaurer en bas</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Close</source> + <translation>Užverti</translation> + </message> + <message> + <source>&Unshade</source> + <translatorcomment>&Dérouler</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QXml</name> + <message> + <source>no error occurred</source> + <translatorcomment>aucune erreur ne s'est produite</translatorcomment> + <translation>jokių klaidų</translation> + </message> + <message> + <source>error triggered by consumer</source> + <translatorcomment>erreur déclenchée par le consommateur</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>unexpected end of file</source> + <translatorcomment>fin de fichier impromptue</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>more than one document type definition</source> + <translatorcomment>plus d'une définition de type de document</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>error occurred while parsing element</source> + <translatorcomment>une erreur s'est produite lors de l'analyse d'un élément</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>tag mismatch</source> + <translatorcomment>balise débalancée</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>error occurred while parsing content</source> + <translatorcomment>une erreur s'est produise lors de l'analyse du contenu</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>unexpected character</source> + <translatorcomment>caractère impromptu</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>invalid name for processing instruction</source> + <translatorcomment>nom d'instruction de traitement invalide</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>version expected while reading the XML declaration</source> + <translatorcomment>version attendue dans la déclaration XML</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>wrong value for standalone declaration</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>encoding declaration or standalone declaration expected while reading the XML declaration</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>standalone declaration expected while reading the XML declaration</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>error occurred while parsing document type definition</source> + <translatorcomment>une erreur s'est produite lors de l'analyse d'une définition de type de document</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>letter is expected</source> + <translatorcomment>lettre attendue</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>error occurred while parsing comment</source> + <translatorcomment>une erreur s'est produise lors de l'analyse d'un commentaire</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>error occurred while parsing reference</source> + <translatorcomment>une erreur s'est produite lors de l'analyse d'une référence</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>internal general entity reference not allowed in DTD</source> + <translatorcomment>appel d'entité interne générale non permis dans la DTD</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>external parsed general entity reference not allowed in attribute value</source> + <translatorcomment>appel d'entité externe parsée non permis dans la valeur d'un attribut</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>external parsed general entity reference not allowed in DTD</source> + <translatorcomment>appel d'entité externe parsée générale non permis dans la DTD</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>unparsed entity reference in wrong context</source> + <translatorcomment>appel d'entité non parsée dans un contexte invalide</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>recursive entities</source> + <translatorcomment>entités récursives</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>error in the text declaration of an external entity</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QXmlStream</name> + <message> + <source>Extra content at end of document.</source> + <translatorcomment>Conteny supplémentaire à la fin du document.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid entity value.</source> + <translatorcomment>Valeur de l'entité invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid XML character.</source> + <translatorcomment>Caractère XML invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Sequence ']]>' not allowed in content.</source> + <translatorcomment>Séquence ']]>' interdite dans le contenu.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Namespace prefix '%1' not declared</source> + <translatorcomment>Le préfixe de namespace '%1' non déclaré</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Attribute redefined.</source> + <translatorcomment>Attribut redéfini.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unexpected character '%1' in public id literal.</source> + <translatorcomment>Caractère '%1' inattendu dans un 'public id literal'.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid XML version string.</source> + <translatorcomment>Version XML invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unsupported XML version.</source> + <translatorcomment>Version XML non supportée.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an invalid encoding name.</source> + <translatorcomment>%1 n'est pas un encodage valide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Encoding %1 is unsupported</source> + <translatorcomment>Encodage %1 n'est pas supporté</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Standalone accepts only yes or no.</source> + <translatorcomment>'Standalone' n'accepte que 'yes' ou 'no'.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid attribute in XML declaration.</source> + <translatorcomment>Attribut invalide dans la déclaration XML.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Premature end of document.</source> + <translatorcomment>Fin de document prématurée.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid document.</source> + <translatorcomment>Document invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Expected </source> + <translatorcomment>Attendu </translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>, but got '</source> + <translatorcomment>, mais eu '</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Unexpected '</source> + <translatorcomment>Inattendu '</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Expected character data.</source> + <translatorcomment>Character data attendu.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Recursive entity detected.</source> + <translatorcomment>Entité recursive détectée.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Start tag expected.</source> + <translatorcomment>Balise ouvrante attendue.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>XML declaration not at start of document.</source> + <translatorcomment>Déclaration XML après le début du document.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>NDATA in parameter entity declaration.</source> + <translatorcomment>NDATA dans une déclaration d'entité paramètre.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an invalid processing instruction name.</source> + <translatorcomment>%1 est un nom d'instruction de traitement invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid processing instruction name.</source> + <translatorcomment>Nom d'instruction de traitement invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Illegal namespace declaration.</source> + <translatorcomment>Déclaration de namespace illégale.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid XML name.</source> + <translatorcomment>Nom XML invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Opening and ending tag mismatch.</source> + <translatorcomment>Ouverture et fermeture de balise invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Reference to unparsed entity '%1'.</source> + <translatorcomment>Référence vers une entité non analysée '%1'.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Entity '%1' not declared.</source> + <translatorcomment>Entité '%1' non déclarée.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Reference to external entity '%1' in attribute value.</source> + <translatorcomment>Référence vers une entité externe '%1' dans la valeur de l'attribut.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Invalid character reference.</source> + <translatorcomment>Référence vers un caractère invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Encountered incorrectly encoded content.</source> + <translatorcomment>Encodage du contenu incorrect.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The standalone pseudo attribute must appear after the encoding.</source> + <translatorcomment>Le pseudo attribut standalone doit apparaître après l'encodage.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an invalid PUBLIC identifier.</source> + <translatorcomment>%1 n'est pas un identifiant PUBLIC valide.</translatorcomment> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>QtXmlPatterns</name> + <message> + <source>An %1-attribute with value %2 has already been declared.</source> + <translatorcomment>Un attribute %1 avec la valeur %2 est déjà déclaré.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>An %1-attribute must have a valid %2 as value, which %3 isn't.</source> + <translatorcomment>Un attribute %1 doit avoir un %2 valide, %3 ne l'a pas.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Network timeout.</source> + <translation>Tinklo ryšiui laikas baigėsi.</translation> + </message> + <message> + <source>Element %1 can't be serialized because it appears outside the document element.</source> + <translatorcomment>L'élément %1 ne peut pas être sérialisé parce qu'il est hors de l'élément document.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Year %1 is invalid because it begins with %2.</source> + <translatorcomment>L'année %1 est invalide parce qu'elle commence par %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Day %1 is outside the range %2..%3.</source> + <translatorcomment>Le jour %1 est hors de l'intervalle %2..%3.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Month %1 is outside the range %2..%3.</source> + <translatorcomment>Le mois %1 est hors de l'intervalle %2..%3.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Overflow: Can't represent date %1.</source> + <translatorcomment>Overflow: ne peut pas représenter la date %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Day %1 is invalid for month %2.</source> + <translatorcomment>Jour %1 est invalide pour le mois %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Time 24:%1:%2.%3 is invalid. Hour is 24, but minutes, seconds, and milliseconds are not all 0; </source> + <translatorcomment>L'heure 24:%1:%2.%3 est invalide. L'heure est 24 mais les minutes, seconndes et millisecondes ne sont pas à 0;</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Time %1:%2:%3.%4 is invalid.</source> + <translatorcomment>L'heure %1:%2:%3.%4 est invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Overflow: Date can't be represented.</source> + <translatorcomment>Overflow : la date ne peut pas être représentée.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>At least one component must be present.</source> + <translatorcomment>Au moins un composant doit être présent.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>At least one time component must appear after the %1-delimiter.</source> + <translatorcomment>Au moins un composant doit apparaître après le délimiteur %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No operand in an integer division, %1, can be %2.</source> + <translatorcomment>Pas d'opérande dans une division entière, %1, peut être %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The first operand in an integer division, %1, cannot be infinity (%2).</source> + <translatorcomment>Le premier opérande dans une division entière, %1, ne peut être infini (%2).</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The second operand in a division, %1, cannot be zero (%2).</source> + <translatorcomment>Le second opérande dans une division, %1, ne peut être nul (%2).</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not a valid value of type %2.</source> + <translatorcomment>%1 n'est pas une valeur valide du type %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>When casting to %1 from %2, the source value cannot be %3.</source> + <translatorcomment>En castant de %2 vers %1, la valeur source ne peut pas être %3.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Integer division (%1) by zero (%2) is undefined.</source> + <translatorcomment>Division entière (%1) par zéro (%2) indéfinie.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Division (%1) by zero (%2) is undefined.</source> + <translatorcomment>Division (%1) par zéro (%2) indéfinie.</translatorcomment> + <translation>Dalyba (%1) iš nulio (%2) negalima.</translation> + </message> + <message> + <source>Modulus division (%1) by zero (%2) is undefined.</source> + <translatorcomment>Module division (%1) par zéro (%2) indéfinie.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Dividing a value of type %1 by %2 (not-a-number) is not allowed.</source> + <translatorcomment>Diviser une valeur du type %1 par %2 (not-a-number) est interdit.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Dividing a value of type %1 by %2 or %3 (plus or minus zero) is not allowed.</source> + <translatorcomment>Diviser une valeur de type %1 par %2 ou %3 (plus ou moins zéro) est interdit.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Multiplication of a value of type %1 by %2 or %3 (plus or minus infinity) is not allowed.</source> + <translatorcomment>La multiplication d'une valeur du type %1 par %2 ou %3 (plus ou moins infini) est interdite.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A value of type %1 cannot have an Effective Boolean Value.</source> + <translatorcomment>Une valeur de type %1 ne peut pas avoir une Effective Boolean Value.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Effective Boolean Value cannot be calculated for a sequence containing two or more atomic values.</source> + <translatorcomment>Effective Boolean Value ne peut être calculée pour une séquence contenant deux ou plus valeurs atomiques.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Value %1 of type %2 exceeds maximum (%3).</source> + <translatorcomment>La valeur %1 de type %2 excède le maximum (%3).</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Value %1 of type %2 is below minimum (%3).</source> + <translatorcomment>La valeur %1 de type %2 est inférieur au minimum (%3).</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A value of type %1 must contain an even number of digits. The value %2 does not.</source> + <translatorcomment>Une valeur de type %1 doit contenir un nombre pair de chiffre. La valeur %2 n'est pas conforme.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not valid as a value of type %2.</source> + <translatorcomment>%1 n'est pas une valeur valide de type %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Operator %1 cannot be used on type %2.</source> + <translatorcomment>L'opérateur %1 ne peut pas être utilisé pour le type %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Operator %1 cannot be used on atomic values of type %2 and %3.</source> + <translatorcomment>L'opérateur %1 ne peut pas être utilisé pour des valeurs atomiques de type %2 ou %3.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The namespace URI in the name for a computed attribute cannot be %1.</source> + <translatorcomment>L'URI de namespace dans le nom d'un attribut calculé ne peut pas être %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The name for a computed attribute cannot have the namespace URI %1 with the local name %2.</source> + <translatorcomment>Le nom d'un attribut calculé ne peut pas avoir l'URI de namespace %1 avec le nom local %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Type error in cast, expected %1, received %2.</source> + <translatorcomment>Erreur de type lors du cast, attendu %1 mais reçu %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>When casting to %1 or types derived from it, the source value must be of the same type, or it must be a string literal. Type %2 is not allowed.</source> + <translatorcomment>En castant vers %1 ou des types dérivés, la valeur source doit être du même type ou une chaîne. Le type %2 n'est pas autorisé.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No casting is possible with %1 as the target type.</source> + <translatorcomment>Aucun cast n'est possible avec %1 comme type de destination.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>It is not possible to cast from %1 to %2.</source> + <translatorcomment>Il est impossible de caster de %1 en %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Casting to %1 is not possible because it is an abstract type, and can therefore never be instantiated.</source> + <translatorcomment>Caster vers %1 est impossible parce que c'est un type abstrait qui ne peut donc être instancié.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>It's not possible to cast the value %1 of type %2 to %3</source> + <translatorcomment>I lest impossible de caster la valeur %1 de type %2 en %3</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Failure when casting from %1 to %2: %3</source> + <translatorcomment>Echec en castant de %1 ver %2 : %3</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A comment cannot contain %1</source> + <translatorcomment>Un commentaire ne peut pas contenir %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A comment cannot end with a %1.</source> + <translatorcomment>Un commentaire ne peut pas finir par %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No comparisons can be done involving the type %1.</source> + <translatorcomment>Aucune comparaison ne peut être faite avec le type %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Operator %1 is not available between atomic values of type %2 and %3.</source> + <translatorcomment>L'opérateur %1 n'est pas disponible entre valeurs atomiques de type %2 et %3.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>An attribute node cannot be a child of a document node. Therefore, the attribute %1 is out of place.</source> + <translatorcomment>Un noeuds attribut ne peut être un fils d'un noeuds document. C'est pourquoi l'attribut %1 est mal placé.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A library module cannot be evaluated directly. It must be imported from a main module.</source> + <translatorcomment>Un module de bibliothèque ne peut pas être évalué directement. Il doit être importé d'un module principal.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A value of type %1 cannot be a predicate. A predicate must have either a numeric type or an Effective Boolean Value type.</source> + <translatorcomment>Une valeur de type %1 ne peut être un prédicat. Un prédicat doit être de type numérique ou un Effective Boolean Value.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A positional predicate must evaluate to a single numeric value.</source> + <translatorcomment>Un prédicat de position doit être évalué en une unique valeur numérique.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The target name in a processing instruction cannot be %1 in any combination of upper and lower case. Therefore, is %2 invalid.</source> + <translatorcomment>Le nom de destination dans une instruction de traitement ne peut être %1. %2 est invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not a valid target name in a processing instruction. It must be a %2 value, e.g. %3.</source> + <translatorcomment>%1 n'est pas un nom de destination valide dans une instruction de traitement. Ce doit être une valeur %2, par ex. %3.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The last step in a path must contain either nodes or atomic values. It cannot be a mixture between the two.</source> + <translatorcomment>La dernière étape dans un chemin doit contenir soit des noeuds soit des valeurs atomiques. Cela ne peut pas être un mélange des deux.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The data of a processing instruction cannot contain the string %1</source> + <translatorcomment>Les données d'une instruction de traitement ne peut contenir la chaîne %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No namespace binding exists for the prefix %1</source> + <translatorcomment>Aucun lien de namespace n'existe pour le préfixe %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No namespace binding exists for the prefix %1 in %2</source> + <translatorcomment>Aucun lien de namespace n'existe pour le préfixe %1 dans %2</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an invalid %2</source> + <translatorcomment>%1 est un ivalide %2</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <source>%1 takes at most %n argument(s). %2 is therefore invalid.</source> + <translatorcomment>%1 prend au maximum %n argument. %2 est donc invalide.</translatorcomment> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + </message> + <message numerus="yes"> + <source>%1 requires at least %n argument(s). %2 is therefore invalid.</source> + <translatorcomment>%1 requiert au moins %n argument. %2 est donc invalide.</translatorcomment> + <translation type="unfinished"> + <numerusform></numerusform> + </translation> + </message> + <message> + <source>The first argument to %1 cannot be of type %2. It must be a numeric type, xs:yearMonthDuration or xs:dayTimeDuration.</source> + <translatorcomment>Le premier argument de %1 ne peut être du type %2. Il doit être de type numérique, xs:yearMonthDuration ou xs:dayTimeDuration.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The first argument to %1 cannot be of type %2. It must be of type %3, %4, or %5.</source> + <translatorcomment>Le premier argument de %1 ne peut être du type %2. Il doit être de type %3, %4 ou %5.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The second argument to %1 cannot be of type %2. It must be of type %3, %4, or %5.</source> + <translatorcomment>Le deuxième argument de %1 ne peut être du type %2. Il doit être de type %3, %4 ou %5.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not a valid XML 1.0 character.</source> + <translatorcomment>%1 n'est pas un caractère XML 1.0 valide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The first argument to %1 cannot be of type %2.</source> + <translatorcomment>Le premier argument de %1 ne peut être du type %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>If both values have zone offsets, they must have the same zone offset. %1 and %2 are not the same.</source> + <translatorcomment>Si les deux valeurs ont des décalages de zone, elle doivent avoir le même. %1 et %2 sont différents.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 was called.</source> + <translatorcomment>%1 a été appelé.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 must be followed by %2 or %3, not at the end of the replacement string.</source> + <translatorcomment>%1 doit être suivi par %2 ou %3, et non à la fin de la chaîne de remplacement.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>In the replacement string, %1 must be followed by at least one digit when not escaped.</source> + <translatorcomment>Dans la chaîne de remplacement, %1 doit être suivi par au moins un chiffre s'il n'est pas échappé.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>In the replacement string, %1 can only be used to escape itself or %2, not %3</source> + <translatorcomment>Dans la chaîne de remplacement, %1 peut seulement être utilisé pour échapper lui-même ou %2 mais pas %3</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 matches newline characters</source> + <translatorcomment>%1 correspond à des caractères de saut de ligne</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 and %2 match the start and end of a line.</source> + <translatorcomment>%1 et %2 correspondent au début et à la fin d'une ligne.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Matches are case insensitive</source> + <translation>Atitikmenys nepaiso raidžių dydžio</translation> + </message> + <message> + <source>Whitespace characters are removed, except when they appear in character classes</source> + <translatorcomment>Les blancs sont supprimés excepté quand ils apparaissent dans les classes de caractère</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an invalid regular expression pattern: %2</source> + <translatorcomment>%1 est un modèle d'expression régulière invalide: %2</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an invalid flag for regular expressions. Valid flags are:</source> + <translatorcomment>%1 est un flag invalide pour des expressions régulières. Les flags valides sont :</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>If the first argument is the empty sequence or a zero-length string (no namespace), a prefix cannot be specified. Prefix %1 was specified.</source> + <translatorcomment>Si le premier argument est une sequence vide ou un chaîne vide (sans namespace), un préfixe ne peut être spécifié. Le préfixe %1 a été spécifié.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>It will not be possible to retrieve %1.</source> + <translatorcomment>Il sera impossible de récupérer %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The root node of the second argument to function %1 must be a document node. %2 is not a document node.</source> + <translatorcomment>Le noeuds racine du deuxième argument à la fonction %1 doit être un noeuds document. %2 n'est pas un document.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The default collection is undefined</source> + <translatorcomment>I'l n'y a pas de collection par défaut</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 cannot be retrieved</source> + <translation>Nepavyksta gauti %1</translation> + </message> + <message> + <source>The normalization form %1 is unsupported. The supported forms are %2, %3, %4, and %5, and none, i.e. the empty string (no normalization).</source> + <translatorcomment>Le forme de normalisation %1 n'est pas supportée. Les formes supportées sont %2, %3, %4 et %5, et aucun, ie. une chaîne vide (pas de normalisation).</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A zone offset must be in the range %1..%2 inclusive. %3 is out of range.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not a whole number of minutes.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Required cardinality is %1; got cardinality %2.</source> + <translatorcomment>La cardinalité requise est %1; reçu %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The item %1 did not match the required type %2.</source> + <translatorcomment>L'item %1 ne correspond pas au type requis %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an unknown schema type.</source> + <translatorcomment>%1 est un type de schema inconnu.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Only one %1 declaration can occur in the query prolog.</source> + <translatorcomment>Seulement une déclaration %1 peut intervenir lors du prologue de la requête.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The initialization of variable %1 depends on itself</source> + <translatorcomment>L'initialisation de la variable %1 dépend d'elle-même</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No variable by name %1 exists</source> + <translatorcomment>Aucun variable nommée %1 existe</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The variable %1 is unused</source> + <translation>Kintamasis %1 nenaudojamas</translation> + </message> + <message> + <source>Version %1 is not supported. The supported XQuery version is 1.0.</source> + <translation>Versija %1nepalaikoma. Palaikoma XQuery versija yra 1.0.</translation> + </message> + <message> + <source>The encoding %1 is invalid. It must contain Latin characters only, must not contain whitespace, and must match the regular expression %2.</source> + <translatorcomment>L'encodage %1 est invalide. Il doit contenir uniquement des caractères latins, sans blanc et doit être conforme à l'expression régulière %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No function with signature %1 is available</source> + <translatorcomment>Aucune fonction avec la signature %1 n'est disponible</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A default namespace declaration must occur before function, variable, and option declarations.</source> + <translatorcomment>Un déclaration de namespace par défaut doit être placée avant toute fonction, variable ou declaration d'option.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Namespace declarations must occur before function, variable, and option declarations.</source> + <translatorcomment>Les declarations de namespace doivent être placées avant tout fonction, variable ou déclaration d'option.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Module imports must occur before function, variable, and option declarations.</source> + <translatorcomment>Les imports de module doivent être placés avant tout fonction, variable ou déclaration d'option.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>It is not possible to redeclare prefix %1.</source> + <translatorcomment>Il est impossible de redéclarer le préfixe %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Only the prefix %1 can be declared to bind the namespace %2. By default, it is already bound to the prefix %1.</source> + <translatorcomment>Seul le préfixe %1 peut être déclaré pour lié le namespace %2. Par défaut, il est déjà lié au préfixe %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Prefix %1 is already declared in the prolog.</source> + <translatorcomment>Le préfixe %1 est déjà déclaré dans le prologue.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The name of an option must have a prefix. There is no default namespace for options.</source> + <translatorcomment>Le nom d'une option doit avoir un préfixe. Il n'y a pas de namespace par défaut pour les options.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The Schema Import feature is not supported, and therefore %1 declarations cannot occur.</source> + <translatorcomment>La fonctionnalité "Schema Import" n'est pas supportée et les déclarations %1 ne peuvent donc intervenir.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The target namespace of a %1 cannot be empty.</source> + <translatorcomment>Le namespace cible d'un %1 ne peut être vide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The module import feature is not supported</source> + <translatorcomment>La fonctionnalité "module import" n'est pas supportée</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A variable by name %1 has already been declared in the prolog.</source> + <translatorcomment>Une variable du nom %1 a déjà été déclarée dans le prologue.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No value is available for the external variable by name %1.</source> + <translatorcomment>Aucune valeur n'est disponible pour la variable externe %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The namespace %1 is reserved; therefore user defined functions may not use it. Try the predefined prefix %2, which exists for these cases.</source> + <translatorcomment>Le namespace %1 est réservé; c'est pourquoi les fonctions définies par l'utilisateur ne peuvent l'utiliser. Essayez le préfixe prédéfini %2 qui existe pour ces cas.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The namespace of a user defined function in a library module must be equivalent to the module namespace. In other words, it should be %1 instead of %2</source> + <translatorcomment>Le namespace d'une fonction utilisateur dans un module de bibliothèque doit être équivalent au namespace du module. En d'autres mots, il devrait être %1 au lieu de %2</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A function already exists with the signature %1.</source> + <translatorcomment>Une fonction avec la signature %1 existe déjà.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No external functions are supported. All supported functions can be used directly, without first declaring them as external</source> + <translatorcomment>Les fonctions externes ne sont pas supportées. Toutes les fonctions supportées peuvent êter utilisées directement sans les déclarer préalablement comme externes</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>An argument by name %1 has already been declared. Every argument name must be unique.</source> + <translatorcomment>Un argument nommé %1 a déjà été déclaré. Chaque nom d'argument doit être unique.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The name of a variable bound in a for-expression must be different from the positional variable. Hence, the two variables named %1 collide.</source> + <translatorcomment>Le nom d'une variable liée dans un expression for doit être different de la variable positionnelle. Les deux variables appelées %1 sont en conflit.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The Schema Validation Feature is not supported. Hence, %1-expressions may not be used.</source> + <translatorcomment>La fonctionnalité "Schema Validation" n'est pas supportée. Les expressions %1 ne seront pas utilisées.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>None of the pragma expressions are supported. Therefore, a fallback expression must be present</source> + <translatorcomment>Aucune des expressions pragma n'est supportée. Une expression par défault doit être présente</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The %1-axis is unsupported in XQuery</source> + <translatorcomment>L'axe %1 n'est pas supporté dans XQuery</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not a valid numeric literal.</source> + <translatorcomment>%1 n'est pas une valeur numérique valide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>No function by name %1 is available.</source> + <translatorcomment>La fonction %1 n'est pas disponible.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The namespace URI cannot be the empty string when binding to a prefix, %1.</source> + <translatorcomment>L'URI de namespace ne peut être une chaîne vide quand on le lie à un préfixe, %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an invalid namespace URI.</source> + <translatorcomment>%1 est un URI de namespace invalide.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>It is not possible to bind to the prefix %1</source> + <translatorcomment>Il est impossible de se lier au préfixe %1</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared).</source> + <translatorcomment>Le namespace %1 peut seulement être lié à %2 (et doit être pré-déclaré).</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared).</source> + <translatorcomment>Le préfixe %1 peut seulement être lié à %2 (et doit être prédéclaré).</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Two namespace declaration attributes have the same name: %1.</source> + <translatorcomment>Deux attributs de déclarations de namespace ont le même nom : %1.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The namespace URI must be a constant and cannot use enclosed expressions.</source> + <translatorcomment>L'URI de namespace doit être une constante et ne peut contenir d'expressions.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>An attribute by name %1 has already appeared on this element.</source> + <translatorcomment>Un attribute nommé %1 existe déjà pour cet élément.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>A direct element constructor is not well-formed. %1 is ended with %2.</source> + <translatorcomment>Un constructeur direct d'élément est mal-formé. %1 est terminé par %2.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The name %1 does not refer to any schema type.</source> + <translatorcomment>Le nom %1 ne se réfère à aucun type de schema.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is an complex type. Casting to complex types is not possible. However, casting to atomic types such as %2 works.</source> + <translatorcomment>%1 est une type complexe. Caster vers des types complexes n'est pas possible. Cependant, caster vers des types atomiques comme %2 marche.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not an atomic type. Casting is only possible to atomic types.</source> + <translatorcomment>%1 n'est pas un type atomique. Il est uniquement possible de caster vers des types atomiques.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not a valid name for a processing-instruction. Therefore this name test will never match.</source> + <translatorcomment>%1 n'est pas un nom valide pour une instruction de traitement. C'est pourquoi ce test de nom ne réussira jamais.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 is not in the in-scope attribute declarations. Note that the schema import feature is not supported.</source> + <translatorcomment>%1 n'est pas dans les déclaration d'attribut in-scope. La fonctionnalité d'inport de schéma n'est pas supportée.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The name of an extension expression must be in a namespace.</source> + <translatorcomment>Le nom d'une expression d'extension doit être dans un namespace.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>empty</source> + <translatorcomment>vide</translatorcomment> + <translation>tuščia</translation> + </message> + <message> + <source>zero or one</source> + <translatorcomment>zéro ou un</translatorcomment> + <translation>nulis arba vienas</translation> + </message> + <message> + <source>exactly one</source> + <translatorcomment>exactement un</translatorcomment> + <translation>tik vienas</translation> + </message> + <message> + <source>one or more</source> + <translation>vienas arba daugiau</translation> + </message> + <message> + <source>zero or more</source> + <translation>nulis arba daugiau</translation> + </message> + <message> + <source>Required type is %1, but %2 was found.</source> + <translatorcomment>Le type requis est %1, mais %2 a été reçu.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Promoting %1 to %2 may cause loss of precision.</source> + <translatorcomment>La Promotion de %1 vers %2 peut causer un perte de précision.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The focus is undefined.</source> + <translatorcomment>Le focus est indéfini.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>It's not possible to add attributes after any other kind of node.</source> + <translatorcomment>Il est impossible d'ajouter des attributs après un autre type de noeuds.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>An attribute by name %1 has already been created.</source> + <translatorcomment>Un attribute de nom %1 a déjà été créé.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>Only the Unicode Codepoint Collation is supported(%1). %2 is unsupported.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Attribute %1 can't be serialized because it appears at the top level.</source> + <translatorcomment>L'attribut %1 ne peut pas être sérialisé car il apparaît à la racine.</translatorcomment> + <translation type="unfinished"></translation> + </message> + <message> + <source>The namespace for a user defined function cannot be empty (try the predefined prefix %1 which exists for cases like this)</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>VolumeSlider</name> + <message> + <source>Muted</source> + <translation>Nutildyta</translation> + </message> + <message> + <source>Volume: %1%</source> + <translation>Garsumas: %1%</translation> + </message> +</context> +<context> + <name>WebCore::PlatformScrollbar</name> + <message> + <source>Scroll here</source> + <translation>Slikti iki čia</translation> + </message> + <message> + <source>Left edge</source> + <translation>Kairysis kraštas</translation> + </message> + <message> + <source>Top</source> + <translation>Viršus</translation> + </message> + <message> + <source>Right edge</source> + <translation>Dešinysis kraštas</translation> + </message> + <message> + <source>Bottom</source> + <translation>Apačia</translation> + </message> + <message> + <source>Page left</source> + <translation>Puslapis kairėje</translation> + </message> + <message> + <source>Page up</source> + <translation>Puslapis viršuje</translation> + </message> + <message> + <source>Page right</source> + <translation>Puslapis dešinėje</translation> + </message> + <message> + <source>Page down</source> + <translation>Puslapis apačioje</translation> + </message> + <message> + <source>Scroll left</source> + <translation>Slinkti kairėn</translation> + </message> + <message> + <source>Scroll up</source> + <translation>Slikti auktyn</translation> + </message> + <message> + <source>Scroll right</source> + <translation>Slinkti dešinėn</translation> + </message> + <message> + <source>Scroll down</source> + <translation>Slinkti žemyn</translation> + </message> +</context> +</TS> diff --git a/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp b/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp index 697d92109..ce91b547a 100644 --- a/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp +++ b/src/VBox/Frontends/VirtualBox/src/VBoxFBOverlay.cpp @@ -469,7 +469,7 @@ private: int VBoxVHWAGlShader::init() { - int rc; + int rc = VERR_GENERAL_FAILURE; GLint *length; const char **sources; length = new GLint[mcComponents]; @@ -480,55 +480,59 @@ int VBoxVHWAGlShader::init() rc = maComponents[i]->init(); AssertRC(rc); if(RT_FAILURE(rc)) - return rc; + break; sources[i] = maComponents[i]->contents(); } -#ifdef DEBUG - VBOXQGLLOG(("\ncompiling shaders:\n------------\n")); - for(int i = 0; i < mcComponents; i++) + if(RT_SUCCESS(rc)) { - VBOXQGLLOG(("**********\n%s\n***********\n", sources[i])); - } - VBOXQGLLOG(("------------\n")); +#ifdef DEBUG + VBOXQGLLOG(("\ncompiling shaders:\n------------\n")); + for(int i = 0; i < mcComponents; i++) + { + VBOXQGLLOG(("**********\n%s\n***********\n", sources[i])); + } + VBOXQGLLOG(("------------\n")); #endif - mShader = vboxglCreateShader(mType); + mShader = vboxglCreateShader(mType); - VBOXQGL_CHECKERR( - vboxglShaderSource(mShader, mcComponents, sources, length); - ); + VBOXQGL_CHECKERR( + vboxglShaderSource(mShader, mcComponents, sources, length); + ); - VBOXQGL_CHECKERR( - vboxglCompileShader(mShader); - ); + VBOXQGL_CHECKERR( + vboxglCompileShader(mShader); + ); - GLint compiled; - VBOXQGL_CHECKERR( - vboxglGetShaderiv(mShader, GL_COMPILE_STATUS, &compiled); - ); + GLint compiled; + VBOXQGL_CHECKERR( + vboxglGetShaderiv(mShader, GL_COMPILE_STATUS, &compiled); + ); #ifdef DEBUG - GLchar * pBuf = new GLchar[16300]; - vboxglGetShaderInfoLog(mShader, 16300, NULL, pBuf); - VBOXQGLLOG(("\ncompile log:\n-----------\n%s\n---------\n", pBuf)); - delete pBuf; + GLchar * pBuf = new GLchar[16300]; + vboxglGetShaderInfoLog(mShader, 16300, NULL, pBuf); + VBOXQGLLOG(("\ncompile log:\n-----------\n%s\n---------\n", pBuf)); + delete[] pBuf; #endif - Assert(compiled); - if(compiled) - { - return VINF_SUCCESS; + Assert(compiled); + if(compiled) + { + rc = VINF_SUCCESS; + } + else + { + VBOXQGL_CHECKERR( + vboxglDeleteShader(mShader); + ); + mShader = 0; + } } - - VBOXQGL_CHECKERR( - vboxglDeleteShader(mShader); - ); - mShader = 0; - delete[] length; delete[] sources; - return VERR_GENERAL_FAILURE; + return rc; } class VBoxVHWAGlProgram diff --git a/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp b/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp index 34095118e..e5a2c39ea 100644 --- a/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp +++ b/src/VBox/Frontends/VirtualBox/src/extensions/QIFileDialog.cpp @@ -365,8 +365,12 @@ QString QIFileDialog::getExistingDirectory (const QString &aDir, #else QFileDialog::Options o; +# if defined (Q_WS_X11) + if (vboxGlobal().isKWinManaged()) + o |= QFileDialog::DontUseNativeDialog; +# endif if (aDirOnly) - o = QFileDialog::ShowDirsOnly; + o |= QFileDialog::ShowDirsOnly; if (!aResolveSymlinks) o |= QFileDialog::DontResolveSymlinks; return QFileDialog::getExistingDirectory (aParent, aCaption, aDir, o); @@ -573,6 +577,10 @@ QString QIFileDialog::getSaveFileName (const QString &aStartWith, #else QFileDialog::Options o; +# if defined (Q_WS_X11) + if (vboxGlobal().isKWinManaged()) + o |= QFileDialog::DontUseNativeDialog; +# endif if (!aResolveSymlinks) o |= QFileDialog::DontResolveSymlinks; o |= QFileDialog::DontConfirmOverwrite; @@ -633,7 +641,8 @@ QStringList QIFileDialog::getOpenFileNames (const QString &aStartWith, bool aResolveSymlinks /* = true */, bool aSingleFile /* = false */) { -#if defined Q_WS_WIN +/* It seems, running QFileDialog in separate thread is NOT needed under windows any more: */ +#if defined (Q_WS_WIN) && (QT_VERSION < 0x040403) /** * QEvent class reimplementation to carry Win32 API native dialog's @@ -816,6 +825,11 @@ QStringList QIFileDialog::getOpenFileNames (const QString &aStartWith, QFileDialog::Options o; if (!aResolveSymlinks) o |= QFileDialog::DontResolveSymlinks; +# if defined (Q_WS_X11) + if (vboxGlobal().isKWinManaged()) + o |= QFileDialog::DontUseNativeDialog; +# endif + if (aSingleFile) return QStringList() << QFileDialog::getOpenFileName (aParent, aCaption, aStartWith, aFilters, aSelectedFilter, o); diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp index 62ee8f762..7c0d069b8 100644 --- a/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp +++ b/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp @@ -1897,7 +1897,7 @@ void UIMachineView::paintEvent(QPaintEvent *pPaintEvent) if (m_pauseShot.isNull()) { /* Delegate the paint function to the VBoxFrameBuffer interface: */ - if (m_pFrameBuffer) + if (m_pFrameBuffer && !uisession()->isTurnedOff()) m_pFrameBuffer->paintEvent(pPaintEvent); #ifdef Q_WS_MAC /* Update the dock icon if we are in the running state */ diff --git a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp index 47c2ecf3b..e96a0de0e 100644 --- a/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp +++ b/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp @@ -905,6 +905,18 @@ void UISession::sltInstallGuestAdditionsFrom(const QString &strSource) void UISession::sltCloseVirtualSession() { + /* Use a single shot with timeout 0 to allow the widgets to cleanly close and test then again. + * If all open widgets are closed destroy ourself: */ + QWidget *widget = QApplication::activeModalWidget() ? + QApplication::activeModalWidget() : + QApplication::activePopupWidget() ? + QApplication::activePopupWidget() : 0; + if (widget) + { + widget->hide(); + QTimer::singleShot(0, this, SLOT(sltCloseVirtualSession())); + return; + } m_pMachine->closeVirtualMachine(); } diff --git a/src/VBox/GuestHost/OpenGL/include/cr_extstring.h b/src/VBox/GuestHost/OpenGL/include/cr_extstring.h index b36230df3..b480359c3 100644 --- a/src/VBox/GuestHost/OpenGL/include/cr_extstring.h +++ b/src/VBox/GuestHost/OpenGL/include/cr_extstring.h @@ -211,7 +211,7 @@ static const char *crExtensions = "GL_ARB_fragment_shader " #endif #ifdef CR_EXT_texture_sRGB - "CR_EXT_texture_sRGB " + "GL_EXT_texture_sRGB " #endif ""; diff --git a/src/VBox/HostDrivers/Support/win/VBoxDrv.inf b/src/VBox/HostDrivers/Support/win/VBoxDrv.inf index 10fb18208..b4469b235 100644 --- a/src/VBox/HostDrivers/Support/win/VBoxDrv.inf +++ b/src/VBox/HostDrivers/Support/win/VBoxDrv.inf @@ -4,25 +4,25 @@ ;
;
-; Copyright (C) 2006-2007 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.
-;
-; The contents of this file may alternatively be used under the terms
-; of the Common Development and Distribution License Version 1.0
-; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
-; VirtualBox OSE distribution, in which case the provisions of the
-; CDDL are applicable instead of those of the GPL.
-;
-; You may elect to license modified versions of this file under the
-; terms and conditions of either the GPL or the CDDL or both.
-;
+; Copyright (C) 2006-2007 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. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; [Version]
Signature="$Windows NT$"
diff --git a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c index 80ee6f320..8a80f699f 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c +++ b/src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c @@ -113,6 +113,18 @@ #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) +/** This enables or disables handling of GSO frames coming from the wire (GRO). */ +# define VBOXNETFLT_WITH_GRO 1 +#endif +/* + * GRO support was backported to RHEL 5.4 + */ +#ifdef RHEL_RELEASE_CODE +# if RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(5, 4) +# define VBOXNETFLT_WITH_GRO 1 +# endif +#endif /******************************************************************************* * Internal Functions * @@ -569,7 +581,7 @@ static struct sk_buff *vboxNetFltLinuxSkBufFromSG(PVBOXNETFLTINS pThis, PINTNETS # endif } if (!fDstWire) - PDMNetGsoPrepForDirectUse(&pSG->GsoCtx, pPkt->data, pSG->cbTotal, false /*fPayloadChecksum*/); + PDMNetGsoPrepForDirectUse(&pSG->GsoCtx, pPkt->data, pSG->cbTotal, PDMNETCSUMTYPE_PSEUDO); } #endif /* VBOXNETFLT_WITH_GSO_XMIT_WIRE || VBOXNETFLT_WITH_GSO_XMIT_HOST */ @@ -613,15 +625,6 @@ DECLINLINE(void) vboxNetFltLinuxSkBufToSG(PVBOXNETFLTINS pThis, struct sk_buff * Assert(!skb_shinfo(pBuf)->frag_list); - if (fSrc & INTNETTRUNKDIR_WIRE) - { - /* - * The packet came from wire, ethernet header was removed by device driver. - * Restore it. - */ - skb_push(pBuf, ETH_HLEN); - } - if (!pGsoCtx) IntNetSgInitTempSegs(pSG, pBuf->len, cSegs, 0 /*cSegsUsed*/); else @@ -709,6 +712,7 @@ static int vboxNetFltLinuxPacketHandler(struct sk_buff *pBuf, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) Log3(("vboxNetFltLinuxPacketHandler: skb len=%u data_len=%u truesize=%u next=%p nr_frags=%u gso_size=%u gso_seqs=%u gso_type=%x frag_list=%p pkt_type=%x\n", pBuf->len, pBuf->data_len, pBuf->truesize, pBuf->next, skb_shinfo(pBuf)->nr_frags, skb_shinfo(pBuf)->gso_size, skb_shinfo(pBuf)->gso_segs, skb_shinfo(pBuf)->gso_type, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type)); + Log4(("vboxNetFltLinuxPacketHandler: packet dump follows:\n%.*Rhxd\n", pBuf->len-pBuf->data_len, skb_mac_header(pBuf))); #else Log3(("vboxNetFltLinuxPacketHandler: skb len=%u data_len=%u truesize=%u next=%p nr_frags=%u tso_size=%u tso_seqs=%u frag_list=%p pkt_type=%x\n", pBuf->len, pBuf->data_len, pBuf->truesize, pBuf->next, skb_shinfo(pBuf)->nr_frags, skb_shinfo(pBuf)->tso_size, skb_shinfo(pBuf)->tso_segs, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type)); @@ -751,6 +755,7 @@ static int vboxNetFltLinuxPacketHandler(struct sk_buff *pBuf, # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) Log3(("vboxNetFltLinuxPacketHandler: skb copy len=%u data_len=%u truesize=%u next=%p nr_frags=%u gso_size=%u gso_seqs=%u gso_type=%x frag_list=%p pkt_type=%x\n", pBuf->len, pBuf->data_len, pBuf->truesize, pBuf->next, skb_shinfo(pBuf)->nr_frags, skb_shinfo(pBuf)->gso_size, skb_shinfo(pBuf)->gso_segs, skb_shinfo(pBuf)->gso_type, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type)); + Log4(("vboxNetFltLinuxPacketHandler: packet dump follows:\n%.*Rhxd\n", pBuf->len-pBuf->data_len, skb_mac_header(pBuf))); # else Log3(("vboxNetFltLinuxPacketHandler: skb copy len=%u data_len=%u truesize=%u next=%p nr_frags=%u tso_size=%u tso_seqs=%u frag_list=%p pkt_type=%x\n", pBuf->len, pBuf->data_len, pBuf->truesize, pBuf->next, skb_shinfo(pBuf)->nr_frags, skb_shinfo(pBuf)->tso_size, skb_shinfo(pBuf)->tso_segs, skb_shinfo(pBuf)->frag_list, pBuf->pkt_type)); @@ -889,22 +894,39 @@ static bool vboxNetFltLinuxCanForwardAsGso(PVBOXNETFLTINS pThis, struct sk_buff Log5(("vboxNetFltLinuxCanForwardAsGso: gso_size=%#x skb_len=%#x (max=%#x)\n", skb_shinfo(pSkb)->gso_size, pSkb->len, VBOX_MAX_GSO_SIZE)); return false; } + /* + * It is possible to receive GSO packets from wire if GRO is enabled. + */ if (RT_UNLIKELY(fSrc & INTNETTRUNKDIR_WIRE)) { Log5(("vboxNetFltLinuxCanForwardAsGso: fSrc=wire\n")); +#ifdef VBOXNETFLT_WITH_GRO + /* + * The packet came from the wire and the driver has already consumed + * mac header. We need to restore it back. + */ + pSkb->mac_len = skb_network_header(pSkb) - skb_mac_header(pSkb); + skb_push(pSkb, pSkb->mac_len); + Log5(("vboxNetFltLinuxCanForwardAsGso: mac_len=%d data=%p mac_header=%p network_header=%p\n", + pSkb->mac_len, pSkb->data, skb_mac_header(pSkb), skb_network_header(pSkb))); +#else /* !VBOXNETFLT_WITH_GRO */ + /* Older kernels didn't have GRO. */ return false; +#endif /* !VBOXNETFLT_WITH_GRO */ } - - /* - * skb_gso_segment does the following. Do we need to do it as well? - */ + else + { + /* + * skb_gso_segment does the following. Do we need to do it as well? + */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) - skb_reset_mac_header(pSkb); - pSkb->mac_len = pSkb->network_header - pSkb->mac_header; + skb_reset_mac_header(pSkb); + pSkb->mac_len = pSkb->network_header - pSkb->mac_header; #else - pSkb->mac.raw = pSkb->data; - pSkb->mac_len = pSkb->nh.raw - pSkb->data; + pSkb->mac.raw = pSkb->data; + pSkb->mac_len = pSkb->nh.raw - pSkb->data; #endif + } /* * Switch on the ethertype. @@ -1102,6 +1124,15 @@ static int vboxNetFltLinuxForwardSegment(PVBOXNETFLTINS pThis, struct sk_buff *p PINTNETSG pSG = (PINTNETSG)alloca(RT_OFFSETOF(INTNETSG, aSegs[cSegs])); if (RT_LIKELY(pSG)) { + if (fSrc & INTNETTRUNKDIR_WIRE) + { + /* + * The packet came from wire, ethernet header was removed by device driver. + * Restore it. + */ + skb_push(pBuf, ETH_HLEN); + } + vboxNetFltLinuxSkBufToSG(pThis, pBuf, pSG, cSegs, fSrc, NULL /*pGsoCtx*/); vboxNetFltDumpPacket(pSG, false, (fSrc & INTNETTRUNKDIR_HOST) ? "host" : "wire", 1); diff --git a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c index 3343238df..10ec74748 100644 --- a/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c +++ b/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c @@ -343,10 +343,17 @@ typedef struct vboxnetflt_promisc_stream_t PRTTIMER pIp6Timer; /* ipv6 stream poll timer for dynamic ipv6 stream attachment */ #endif size_t cLoopback; /* loopback queue size list */ + timeout_id_t TimeoutId; /* timeout id of promisc. req */ PVBOXNETFLTPACKETID pHead; /* loopback packet identifier head */ PVBOXNETFLTPACKETID pTail; /* loopback packet identifier tail */ } vboxnetflt_promisc_stream_t; +typedef struct vboxnetflt_promisc_params_t +{ + PVBOXNETFLTINS pThis; /* the backend instance */ + bool fPromiscOn; /* whether promiscuous req. on or off */ +} vboxnetflt_promisc_params_t; + /******************************************************************************* * Internal Functions * @@ -752,6 +759,7 @@ static int VBoxNetFltSolarisModOpen(queue_t *pQueue, dev_t *pDev, int fOpenMode, pPromiscStream->pHead = NULL; pPromiscStream->pTail = NULL; pPromiscStream->cLoopback = 0; + pPromiscStream->TimeoutId = 0; #ifdef VBOXNETFLT_SOLARIS_IPV6_POLLING pPromiscStream->pIp6Timer = NULL; #endif @@ -1344,6 +1352,29 @@ static int vboxNetFltSolarisPromiscReq(queue_t *pQueue, bool fPromisc) } +/* + * Callback wrapper for qtimeout to safely send promiscuous off request. + * + * @param pvData Pointer to a vboxnetflt_promisc_params_t structure, will be freed by us. + */ +static void vboxNetFltSolarisPromiscReqWrap(void *pvData) +{ + vboxnetflt_promisc_params_t *pParams = pvData; + if (RT_LIKELY(pParams)) + { + PVBOXNETFLTINS pThis = pParams->pThis; + vboxnetflt_promisc_stream_t *pPromiscStream = ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pvPromiscStream); + if ( pPromiscStream + && pPromiscStream->Stream.pReadQueue) + { + pPromiscStream->TimeoutId = 0; + vboxNetFltSolarisPromiscReq(pPromiscStream->Stream.pReadQueue, pParams->fPromiscOn); + } + RTMemFree(pParams); + } +} + + /** * Send a fake physical address request downstream. * @@ -1990,6 +2021,16 @@ static void vboxNetFltSolarisCloseStream(PVBOXNETFLTINS pThis) if (pThis->u.s.hIface) { + /* + * If there are any timeout scheduled, we need to make sure they are cancelled. + */ + vboxnetflt_promisc_stream_t *pPromiscStream = ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pvPromiscStream); + if ( pPromiscStream + && pPromiscStream->TimeoutId) + { + quntimeout(WR(pPromiscStream->Stream.pReadQueue), pPromiscStream->TimeoutId); + } + ldi_close(pThis->u.s.hIface, FREAD | FWRITE, kcred); pThis->u.s.hIface = NULL; } @@ -3578,20 +3619,24 @@ void vboxNetFltPortOsSetActive(PVBOXNETFLTINS pThis, bool fActive) /* * Enable/disable promiscuous mode. */ - vboxnetflt_stream_t *pStream = ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pvPromiscStream); - if (pStream) + vboxnetflt_promisc_params_t *pData = RTMemAllocZ(sizeof(vboxnetflt_promisc_params_t)); + if (RT_LIKELY(pData)) { - if (pStream->pReadQueue) + vboxnetflt_promisc_stream_t *pPromiscStream = ASMAtomicUoReadPtr((void * volatile *)&pThis->u.s.pvPromiscStream); + if ( pPromiscStream + && pPromiscStream->Stream.pReadQueue) { - int rc = vboxNetFltSolarisPromiscReq(pStream->pReadQueue, fActive); - if (RT_FAILURE(rc)) - LogRel((DEVICE_NAME ":vboxNetFltPortOsSetActive failed to request promiscuous mode! rc=%d\n", rc)); + pData->pThis = pThis; + pData->fPromiscOn = fActive; + if (pPromiscStream->TimeoutId != 0) + quntimeout(WR(pPromiscStream->Stream.pReadQueue), pPromiscStream->TimeoutId); + pPromiscStream->TimeoutId = qtimeout(WR(pPromiscStream->Stream.pReadQueue), vboxNetFltSolarisPromiscReqWrap, pData, 1 /* ticks */); + return; } - else - LogRel((DEVICE_NAME ":vboxNetFltPortOsSetActive queue not found!\n")); + RTMemFree(pData); } else - LogRel((DEVICE_NAME ":vboxNetFltPortOsSetActive stream not found!\n")); + LogRel((DEVICE_NAME ":vboxNetFltPortOsSetActive out of memory!\n")); } diff --git a/src/VBox/HostServices/GuestControl/service.cpp b/src/VBox/HostServices/GuestControl/service.cpp index d121ab419..690278c1d 100644 --- a/src/VBox/HostServices/GuestControl/service.cpp +++ b/src/VBox/HostServices/GuestControl/service.cpp @@ -717,24 +717,35 @@ void Service::call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, { switch (eFunction) { - /* The guest asks the host for the next messsage to process. */ + /* + * The guest asks the host for the next messsage to process. + */ case GUEST_GET_HOST_MSG: LogFlowFunc(("GUEST_GET_HOST_MSG\n")); rc = retrieveNextHostCmd(u32ClientID, callHandle, cParms, paParms); break; + /* + * The guest wants to shut down and asks us (this service) to cancel + * all blocking pending waits (VINF_HGCM_ASYNC_EXECUTE) so that the + * guest can gracefully shut down. + */ case GUEST_CANCEL_PENDING_WAITS: LogFlowFunc(("GUEST_CANCEL_PENDING_WAITS\n")); rc = cancelPendingWaits(u32ClientID); break; - /* The guest notifies the host that some output at stdout/stderr is available. */ + /* + * The guest notifies the host that some output at stdout/stderr is available. + */ case GUEST_EXEC_SEND_OUTPUT: LogFlowFunc(("GUEST_EXEC_SEND_OUTPUT\n")); rc = notifyHost(eFunction, cParms, paParms); break; - /* The guest notifies the host of the current client status. */ + /* + * The guest notifies the host of the current client status. + */ case GUEST_EXEC_SEND_STATUS: LogFlowFunc(("SEND_STATUS\n")); rc = notifyHost(eFunction, cParms, paParms); diff --git a/src/VBox/Installer/solaris/Makefile.kmk b/src/VBox/Installer/solaris/Makefile.kmk index 219e35efd..cd47765fb 100644 --- a/src/VBox/Installer/solaris/Makefile.kmk +++ b/src/VBox/Installer/solaris/Makefile.kmk @@ -343,7 +343,8 @@ endif ifdef VBOX_WITH_VRDP SOLARIS_STRIP_BINS += \ VBoxVRDP.so \ - VRDPAuth.so + VRDPAuth.so \ + VRDPAuthSimple.so SOLARIS_COMMON += \ rdesktop-vrdp.tar.gz ifdef VBOX_WITH_VRDP_RDESKTOP diff --git a/src/VBox/Installer/solaris/checkinstall.sh b/src/VBox/Installer/solaris/checkinstall.sh index 95ab27562..c238f7d82 100755 --- a/src/VBox/Installer/solaris/checkinstall.sh +++ b/src/VBox/Installer/solaris/checkinstall.sh @@ -22,6 +22,10 @@ abort_error() exit 1 } +# nothing to check for targetted install +if test "x${BASEDIR}" != "x/"; then + exit 0 +fi # Check if VBoxSVC is currently running VBOXSVC_PID=`ps -eo pid,fname | grep VBoxSVC | grep -v grep | awk '{ print $1 }'` @@ -36,7 +40,8 @@ if test ! -z "$servicefound"; then echo "## VirtualBox's zone access service appears to still be running." echo "## Halting & removing zone access service..." /usr/sbin/svcadm disable -s svc:/application/virtualbox/zoneaccess - /usr/sbin/svccfg delete svc:/application/virtualbox/zoneaccess + # Don't delete the service, handled by manifest class action + # /usr/sbin/svccfg delete svc:/application/virtualbox/zoneaccess fi # Check if the Web service is running, if so stop & remove it @@ -45,7 +50,8 @@ if test ! -z "$servicefound"; then echo "## VirtualBox web service appears to still be running." echo "## Halting & removing webservice..." /usr/sbin/svcadm disable -s svc:/application/virtualbox/webservice - /usr/sbin/svccfg delete svc:/application/virtualbox/webservice + # Don't delete the service, handled by manifest class action + # /usr/sbin/svccfg delete svc:/application/virtualbox/webservice fi # Check if vboxnet is still plumbed, if so try unplumb it diff --git a/src/VBox/Installer/solaris/makepackage.sh b/src/VBox/Installer/solaris/makepackage.sh index 127594eb1..95e835bac 100755 --- a/src/VBox/Installer/solaris/makepackage.sh +++ b/src/VBox/Installer/solaris/makepackage.sh @@ -78,6 +78,12 @@ filelist_fixup() mv -f "tmp-$1" "$1" } +dirlist_fixup() +{ + "$VBOX_AWK" 'NF == 6 && $1 == "d" && '"$2"' { '"$3"' } { print }' "$1" > "tmp-$1" + mv -f "tmp-$1" "$1" +} + hardlink_fixup() { "$VBOX_AWK" 'NF == 3 && $1=="l" && '"$2"' { '"$3"' } { print }' "$1" > "tmp-$1" @@ -131,8 +137,9 @@ fi cd "$PKG_BASE_DIR" find . ! -type d | $VBOX_GGREP -v -E 'prototype|makepackage.sh|vbox.pkginfo|postinstall.sh|checkinstall.sh|preremove.sh|ReadMe.txt|vbox.space|vbox.depend|vbox.copyright|VirtualBoxKern' | pkgproto >> prototype -# Include only opt/VirtualBox and subdirectories as we want uninstall to clean up directory structure as well -find . -type d | $VBOX_GGREP -E 'opt/VirtualBox' | pkgproto >> prototype +# Include opt/VirtualBox and subdirectories as we want uninstall to clean up directory structure. +# Inlcude var/svc for manifest class action script does not create them. +find . -type d | $VBOX_GGREP -E 'opt/VirtualBox|var/svc/manifest/application/virtualbox' | pkgproto >> prototype # fix up file permissions (owner/group) # don't grok for class-specific files (like sed, if any) @@ -166,6 +173,14 @@ filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/amd64/vboxusbmon"' filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/vboxusb"' '$6 = "sys"' filelist_fixup prototype '$3 == "platform/i86pc/kernel/drv/amd64/vboxusb"' '$6 = "sys"' +# Manifest class action scripts +filelist_fixup prototype '$3 == "var/svc/manifest/application/virtualbox/virtualbox-webservice.xml"' '$2 = "manifest";$6 = "sys"' +filelist_fixup prototype '$3 == "var/svc/manifest/application/virtualbox/virtualbox-zoneaccess.xml"' '$2 = "manifest";$6 = "sys"' + +# Use 'root' as group so as to match attributes with the previous installation and prevent a conflict. Otherwise pkgadd bails out thinking +# we're violating directory attributes of another (non existing) package +dirlist_fixup prototype '$3 == "var/svc/manifest/application/virtualbox"' '$6 = "root"' + # hardening requires some executables to be marked setuid. if test -n "$HARDENED"; then $VBOX_AWK 'NF == 6 \ diff --git a/src/VBox/Installer/solaris/pkginstall.sh b/src/VBox/Installer/solaris/pkginstall.sh index e6a79f87b..ab7c3b4b5 100755 --- a/src/VBox/Installer/solaris/pkginstall.sh +++ b/src/VBox/Installer/solaris/pkginstall.sh @@ -28,11 +28,11 @@ else ISIPS="" fi -/opt/VirtualBox/vboxconfig.sh --preremove --fatal "$ISIPS" +${BASEDIR}/opt/VirtualBox/vboxconfig.sh --preremove --fatal "$ISIPS" if test "$?" -eq 0; then echo "Installing new ones..." - /opt/VirtualBox/vboxconfig.sh --postinstall + ${BASEDIR}/opt/VirtualBox/vboxconfig.sh --postinstall rc=$? if test "$rc" -ne 0; then echo "Completed but with errors." diff --git a/src/VBox/Installer/solaris/postinstall.sh b/src/VBox/Installer/solaris/postinstall.sh index 581436e60..074fdf7d8 100755 --- a/src/VBox/Installer/solaris/postinstall.sh +++ b/src/VBox/Installer/solaris/postinstall.sh @@ -18,10 +18,11 @@ currentzone=`zonename` if test "$currentzone" = "global"; then - /opt/VirtualBox/pkginstall.sh --srv4 + ${BASEDIR}/opt/VirtualBox/pkginstall.sh --srv4 rc=$? fi +# installf inherits ${PKG_INSTALL_ROOT} from pkgadd, no need to explicitly specify /usr/sbin/installf -f $PKGINST # return 20 = requires reboot, 2 = partial failure, 0 = success diff --git a/src/VBox/Installer/solaris/preremove.sh b/src/VBox/Installer/solaris/preremove.sh index 1d1290c38..2ca023f07 100755 --- a/src/VBox/Installer/solaris/preremove.sh +++ b/src/VBox/Installer/solaris/preremove.sh @@ -16,7 +16,7 @@ currentzone=`zonename` if test "$currentzone" = "global"; then echo "Removing VirtualBox services and drivers..." - /opt/VirtualBox/vboxconfig.sh --preremove + ${BASEDIR}/opt/VirtualBox/vboxconfig.sh --preremove if test "$?" -eq 0; then echo "Done." exit 0 diff --git a/src/VBox/Installer/solaris/smf-vboxwebsrv.sh b/src/VBox/Installer/solaris/smf-vboxwebsrv.sh index a17a2cd23..604059bc2 100755 --- a/src/VBox/Installer/solaris/smf-vboxwebsrv.sh +++ b/src/VBox/Installer/solaris/smf-vboxwebsrv.sh @@ -1,7 +1,7 @@ #!/sbin/sh # $Id: smf-vboxwebsrv.sh $ -# Copyright (C) 2008 Oracle Corporation +# Copyright (C) 2008-2010 Oracle Corporation # # This file is part of VirtualBox Open Source Edition (OSE), as # available from http://www.virtualbox.org. This file is free software; @@ -45,6 +45,8 @@ case $VW_OPT in [ $? != 0 ] && VW_TIMEOUT= VW_CHECK_INTERVAL=`/usr/bin/svcprop -p config/checkinterval $SMF_FMRI 2>/dev/null` [ $? != 0 ] && VW_CHECK_INTERVAL= + VW_KEEPALIVE=`/usr/bin/svcprop -p config/keepalive $SMF_FMRI 2>/dev/null` + [ $? != 0 ] && VW_KEEPALIVE= # Provide sensible defaults [ -z "$VW_USER" ] && VW_USER=root @@ -52,7 +54,8 @@ case $VW_OPT in [ -z "$VW_PORT" -o "$VW_PORT" -eq 0 ] && VW_PORT=18083 [ -z "$VW_TIMEOUT" ] && VW_TIMEOUT=20 [ -z "$VW_CHECK_INTERVAL" ] && VW_CHECK_INTERVAL=5 - exec su - "$VW_USER" -c "/opt/VirtualBox/vboxwebsrv --host \"$VW_HOST\" --port \"$VW_PORT\" --timeout \"$VW_TIMEOUT\" --check-interval \"$VW_CHECK_INTERVAL\"" + [ -z "$VW_KEEPALIVE" ] && VW_KEEPALIVE=1000 + exec su - "$VW_USER" -c "/opt/VirtualBox/vboxwebsrv --host \"$VW_HOST\" --port \"$VW_PORT\" --timeout \"$VW_TIMEOUT\" --check-interval \"$VW_CHECK_INTERVAL\" --keepalive \"$VW_KEEPALIVE\"" VW_EXIT=$? if [ $VW_EXIT != 0 ]; then diff --git a/src/VBox/Installer/solaris/vbox.pkginfo b/src/VBox/Installer/solaris/vbox.pkginfo index 3528cb4e6..6b7f7486b 100644 --- a/src/VBox/Installer/solaris/vbox.pkginfo +++ b/src/VBox/Installer/solaris/vbox.pkginfo @@ -11,6 +11,6 @@ HOTLINE="Please contact your local service provider" BASEDIR="/" MAXINST=1 EMAIL="info@virtualbox.org" -CLASSES=none sed +CLASSES=none manifest DESC="A powerful PC virtualization solution" diff --git a/src/VBox/Installer/solaris/vboxconfig.sh b/src/VBox/Installer/solaris/vboxconfig.sh index cdad76c34..8a8c5a9b2 100755 --- a/src/VBox/Installer/solaris/vboxconfig.sh +++ b/src/VBox/Installer/solaris/vboxconfig.sh @@ -15,18 +15,17 @@ # hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. # - # Never use exit 2 or exit 20 etc., the return codes are used in # SRv4 postinstall procedures which carry special meaning. Just use exit 1 for failure. # S10 or OpenSoalris HOST_OS_MAJORVERSION=`uname -r` # Which OpenSolaris version (snv_xxx)? -HOST_OS_MINORVERSION=`uname -v | sed -e "s/snv_//" -e "s/[^0-9]//"` +HOST_OS_MINORVERSION=`uname -v | grep 'snv' | sed -e "s/snv_//" -e "s/[^0-9]//"` -DIR_VBOXBASE=/opt/VirtualBox -DIR_CONF="/platform/i86pc/kernel/drv" -DIR_MOD_32="/platform/i86pc/kernel/drv" +DIR_VBOXBASE=${BASEDIR}/opt/VirtualBox +DIR_CONF="${BASEDIR}/platform/i86pc/kernel/drv" +DIR_MOD_32="${BASEDIR}/platform/i86pc/kernel/drv" DIR_MOD_64=$DIR_MOD_32/amd64 BIN_ADDDRV=/usr/sbin/add_drv @@ -62,6 +61,7 @@ DESC_VBOXUSBMON="USBMonitor" MOD_VBOXUSB=vboxusb DESC_VBOXUSB="USB" +REMOTEINST=0 FATALOP=fatal NULLOP=nulloutput SILENTOP=silent @@ -148,6 +148,33 @@ check_root() fi } +# get_sysinfo +# cannot fail +get_sysinfo() +{ + if test "$REMOTEINST" -eq 1 || test -z "$HOST_OS_MINORVERSION" || test -z "$HOST_OS_MAJORVERSION"; then + if test -f "${BASEDIR}/etc/release"; then + HOST_OS_MAJORVERSION=`cat ${BASEDIR}/etc/release | grep "Solaris 10"` + if test -n "$HOST_OS_MAJORVERSION"; then + HOST_OS_MAJORVERSION="5.10" + else + HOST_OS_MAJORVERSION=`cat ${BASEDIR}/etc/release | grep "snv_"` + if test -n "$HOST_OS_MAJORVERSION"; then + HOST_OS_MAJORVERSION="5.11" + fi + fi + if test "$HOST_OS_MAJORVERSION" != "5.10"; then + HOST_OS_MINORVERSION=`cat ${BASEDIR}/etc/release | tr ' ' '\n' | grep 'snv_' | sed -e "s/snv_//" -e "s/[^0-9]//"` + else + HOST_OS_MINORVERSION="" + fi + else + HOST_OS_MAJORVERSION="" + HOST_OS_MINORVERSION="" + fi + fi +} + # check_zone() # !! failure is always fatal check_zone() @@ -191,8 +218,8 @@ module_added() fi # Add a space at end of module name to make sure we have a perfect match to avoid - # any substring matches: e.g "vboxusb" & "vboxusbmon" - loadentry=`cat /etc/name_to_major | grep "$1 "` + # any substring matches: e.g "vboxusb" & "vbo $BASEDIR_OPT xusbmon" + loadentry=`cat ${BASEDIR}/etc/name_to_major | grep "$1 "` if test -z "$loadentry"; then return 1 fi @@ -234,15 +261,15 @@ add_driver() if test -n "$modperm"; then if test "$nullop" = "$NULLOP"; then - $BIN_ADDDRV -m"$modperm" $modname >/dev/null 2>&1 + $BIN_ADDDRV $BASEDIR_OPT -m"$modperm" $modname >/dev/null 2>&1 else - $BIN_ADDDRV -m"$modperm" $modname + $BIN_ADDDRV $BASEDIR_OPT -m"$modperm" $modname fi else if test "$nullop" = "$NULLOP"; then - $BIN_ADDDRV $modname >/dev/null 2>&1 + $BIN_ADDDRV $BASEDIR_OPT $modname >/dev/null 2>&1 else - $BIN_ADDDRV $modname + $BIN_ADDDRV $BASEDIR_OPT $modname fi fi @@ -252,6 +279,8 @@ add_driver() exit 1 fi return 1 + elif test "$REMOTEINST" -eq 1 && test "$?" -eq 0; then + subprint "Added: $moddesc driver" fi return 0 } @@ -268,13 +297,15 @@ rem_driver() modname=$1 moddesc=$2 fatal=$3 + module_added $modname if test "$?" -eq 0; then if test "$ISIPS" != "$IPSOP"; then - $BIN_REMDRV $modname + $BIN_REMDRV $BASEDIR_OPT $modname else - $BIN_REMDRV $modname >/dev/null 2>&1 + $BIN_REMDRV $BASEDIR_OPT $modname >/dev/null 2>&1 fi + # for remote installs, don't bother with return values of rem_drv if test $? -eq 0; then subprint "Removed: $moddesc module" return 0 @@ -297,6 +328,11 @@ unload_module() exit 1 fi + # No-OP for non-root installs + if test "$REMOTEINST" -eq 1; then + return 0 + fi + modname=$1 moddesc=$2 fatal=$3 @@ -326,6 +362,11 @@ load_module() exit 1 fi + # No-OP for non-root installs + if test "$REMOTEINST" -eq 1; then + return 0 + fi + modname=$1 moddesc=$2 fatal=$3 @@ -359,58 +400,72 @@ install_drivers() fi # Add vboxdrv to devlink.tab - sed -e '/name=vboxdrv/d' /etc/devlink.tab > /etc/devlink.vbox - echo "type=ddi_pseudo;name=vboxdrv \D" >> /etc/devlink.vbox - mv -f /etc/devlink.vbox /etc/devlink.tab - - # Create the device link - /usr/sbin/devfsadm -i "$MOD_VBOXDRV" - - if test $? -eq 0 && test -h "/dev/vboxdrv"; then + if test -f "${BASEDIR}/etc/devlink.tab"; then + sed -e '/name=vboxdrv/d' ${BASEDIR}/etc/devlink.tab > ${BASEDIR}/etc/devlink.vbox + echo "type=ddi_pseudo;name=vboxdrv \D" >> ${BASEDIR}/etc/devlink.vbox + mv -f ${BASEDIR}/etc/devlink.vbox ${BASEDIR}/etc/devlink.tab + else + errorprint "Missing ${BASEDIR}/etc/devlink.tab, aborting install" + return 1 + fi - if test -f "$DIR_CONF/vboxnet.conf"; then - add_driver "$MOD_VBOXNET" "$DESC_VBOXNET" "$FATALOP" - load_module "drv/$MOD_VBOXNET" "$DESC_VBOXNET" "$FATALOP" + # Create the device link for non-remote installs + if test "$REMOTEINST" -eq 0; then + /usr/sbin/devfsadm -i "$MOD_VBOXDRV" + if test $? -ne 0 || test ! -h "/dev/vboxdrv"; then + errorprint "Failed to create device link for $MOD_VBOXDRV." + exit 1 fi + fi - if test -f "$DIR_CONF/vboxflt.conf"; then - add_driver "$MOD_VBOXFLT" "$DESC_VBOXFLT" "$FATALOP" - load_module "drv/$MOD_VBOXFLT" "$DESC_VBOXFLT" "$FATALOP" - fi + # Load VBoxNetAdp + if test -f "$DIR_CONF/vboxnet.conf"; then + add_driver "$MOD_VBOXNET" "$DESC_VBOXNET" "$FATALOP" + load_module "drv/$MOD_VBOXNET" "$DESC_VBOXNET" "$FATALOP" + fi + + # Load VBoxNetFlt + if test -f "$DIR_CONF/vboxflt.conf"; then + add_driver "$MOD_VBOXFLT" "$DESC_VBOXFLT" "$FATALOP" + load_module "drv/$MOD_VBOXFLT" "$DESC_VBOXFLT" "$FATALOP" + fi - if test -f "$DIR_CONF/vboxusbmon.conf" && test "$HOST_OS_MAJORVERSION" != "5.10"; then - # For VirtualBox 3.1 the new USB code requires Nevada > 123 - if test "$HOST_OS_MINORVERSION" -gt 123; then - add_driver "$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP" "not-$NULLOP" "'* 0666 root sys'" - load_module "drv/$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP" + # Load VBoxUSBMon, VBoxUSB + if test -f "$DIR_CONF/vboxusbmon.conf" && test "$HOST_OS_MAJORVERSION" != "5.10"; then + # For VirtualBox 3.1 the new USB code requires Nevada > 123 + if test "$HOST_OS_MINORVERSION" -gt 123; then + add_driver "$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP" "not-$NULLOP" "'* 0666 root sys'" + load_module "drv/$MOD_VBOXUSBMON" "$DESC_VBOXUSBMON" "$FATALOP" - # Add vboxusbmon to devlink.tab - sed -e '/name=vboxusbmon/d' /etc/devlink.tab > /etc/devlink.vbox - echo "type=ddi_pseudo;name=vboxusbmon \D" >> /etc/devlink.vbox - mv -f /etc/devlink.vbox /etc/devlink.tab + # Add vboxusbmon to devlink.tab + sed -e '/name=vboxusbmon/d' ${BASEDIR}/etc/devlink.tab > ${BASEDIR}/etc/devlink.vbox + echo "type=ddi_pseudo;name=vboxusbmon \D" >> ${BASEDIR}/etc/devlink.vbox + mv -f ${BASEDIR}/etc/devlink.vbox ${BASEDIR}/etc/devlink.tab - # Create the device link + # Create the device link for non-remote installs + if test "$REMOTEINST" -eq 0; then /usr/sbin/devfsadm -i "$MOD_VBOXUSBMON" if test $? -ne 0; then errorprint "Failed to create device link for $MOD_VBOXUSBMON." exit 1 fi + fi - # Add vboxusb if present - # This driver is special, we need it in the boot-archive but since there is no - # USB device to attach to now (it's done at runtime) it will fail to attach so - # redirect attaching failure output to /dev/null - if test -f "$DIR_CONF/vboxusb.conf"; then - add_driver "$MOD_VBOXUSB" "$DESC_VBOXUSB" "$FATALOP" "$NULLOP" - load_module "drv/$MOD_VBOXUSB" "$DESC_VBOXUSB" "$FATALOP" - fi - else + # Add vboxusb if present + # This driver is special, we need it in the boot-archive but since there is no + # USB device to attach to now (it's done at runtime) it will fail to attach so + # redirect attaching failure output to /dev/null + if test -f "$DIR_CONF/vboxusb.conf"; then + add_driver "$MOD_VBOXUSB" "$DESC_VBOXUSB" "$FATALOP" "$NULLOP" + load_module "drv/$MOD_VBOXUSB" "$DESC_VBOXUSB" "$FATALOP" + fi + else + if test -n "$HOST_OS_MINORVERSION"; then warnprint "Solaris 5.11 snv_124 or higher required for USB support. Skipped installing USB support." + else + warnprint "Failed to determine Solaris 5.11 snv version. Skipped installing USB support." fi fi - else - errorprint "Failed to create device link for $MOD_VBOXDRV." - exit 1 fi return $? @@ -423,17 +478,19 @@ remove_drivers() fatal=$1 # Remove vboxdrv from devlink.tab - devlinkfound=`cat /etc/devlink.tab | grep vboxdrv` - if test -n "$devlinkfound"; then - sed -e '/name=vboxdrv/d' /etc/devlink.tab > /etc/devlink.vbox - mv -f /etc/devlink.vbox /etc/devlink.tab - fi + if test -f ${BASEDIR}/etc/devlink.tab; then + devlinkfound=`cat ${BASEDIR}/etc/devlink.tab | grep vboxdrv` + if test -n "$devlinkfound"; then + sed -e '/name=vboxdrv/d' ${BASEDIR}/etc/devlink.tab > ${BASEDIR}/etc/devlink.vbox + mv -f ${BASEDIR}/etc/devlink.vbox ${BASEDIR}/etc/devlink.tab + fi - # Remove vboxusbmon from devlink.tab - devlinkfound=`cat /etc/devlink.tab | grep vboxusbmon` - if test -n "$devlinkfound"; then - sed -e '/name=vboxusbmon/d' /etc/devlink.tab > /etc/devlink.vbox - mv -f /etc/devlink.vbox /etc/devlink.tab + # Remove vboxusbmon from devlink.tab + devlinkfound=`cat ${BASEDIR}/etc/devlink.tab | grep vboxusbmon` + if test -n "$devlinkfound"; then + sed -e '/name=vboxusbmon/d' ${BASEDIR}/etc/devlink.tab > ${BASEDIR}/etc/devlink.vbox + mv -f ${BASEDIR}/etc/devlink.vbox ${BASEDIR}/etc/devlink.tab + fi fi unload_module "$MOD_VBOXUSB" "$DESC_VBOXUSB" "$fatal" @@ -455,15 +512,15 @@ remove_drivers() # unload_module "$MOD_VBI" "$DESC_VBI" "$fatal" # remove devlinks - if test -h "/dev/vboxdrv" || test -f "/dev/vboxdrv"; then - rm -f /dev/vboxdrv + if test -h "${BASEDIR}/dev/vboxdrv" || test -f "${BASEDIR}/dev/vboxdrv"; then + rm -f ${BASEDIR}/dev/vboxdrv fi - if test -h "/dev/vboxusbmon" || test -f "/dev/vboxusbmon"; then - rm -f /dev/vboxusbmon + if test -h "${BASEDIR}/dev/vboxusbmon" || test -f "${BASEDIR}/dev/vboxusbmon"; then + rm -f ${BASEDIR}/dev/vboxusbmon fi # unpatch nwam/dhcpagent fix - nwamfile=/etc/nwam/llp + nwamfile=${BASEDIR}/etc/nwam/llp nwambackupfile=$nwamfile.vbox if test -f "$nwamfile"; then sed -e '/vboxnet/d' $nwamfile > $nwambackupfile @@ -471,7 +528,7 @@ remove_drivers() fi # remove netmask configuration - nmaskfile=/etc/netmasks + nmaskfile=${BASEDIR}/etc/netmasks nmaskbackupfile=$nmaskfile.vbox if test -f "$nmaskfile"; then sed -e '/#VirtualBox_SectionStart/,/#VirtualBox_SectionEnd/d' $nmaskfile > $nmaskbackupfile @@ -518,11 +575,17 @@ cleanup_install() { fatal=$1 - # stop and unregister webservice SMF + # No-Op for remote installs + if test "$REMOTEINST" -eq 1; then + return 0 + fi + + # stop webservice servicefound=`$BIN_SVCS -a | grep "virtualbox/webservice" 2>/dev/null` if test ! -z "$servicefound"; then $BIN_SVCADM disable -s svc:/application/virtualbox/webservice:default - $BIN_SVCCFG delete svc:/application/virtualbox/webservice:default + # Don't delete the manifest, this is handled by the manifest class action + # $BIN_SVCCFG delete svc:/application/virtualbox/webservice:default if test "$?" -eq 0; then subprint "Unloaded: Web service" else @@ -530,11 +593,12 @@ cleanup_install() fi fi - # stop and unregister zoneaccess SMF + # stop zoneaccess service servicefound=`$BIN_SVCS -a | grep "virtualbox/zoneaccess" 2>/dev/null` if test ! -z "$servicefound"; then $BIN_SVCADM disable -s svc:/application/virtualbox/zoneaccess - $BIN_SVCCFG delete svc:/application/virtualbox/zoneaccess + # Don't delete the manifest, this is handled by the manifest class action + # $BIN_SVCCFG delete svc:/application/virtualbox/zoneaccess if test "$?" -eq 0; then subprint "Unloaded: Zone access service" else @@ -542,7 +606,7 @@ cleanup_install() fi fi - # unplumb all vboxnet instances + # unplumb all vboxnet instances for non-remote installs inst=0 while test $inst -ne $MOD_VBOXNET_INST; do vboxnetup=`$BIN_IFCONFIG vboxnet$inst >/dev/null 2>&1` @@ -583,7 +647,7 @@ postinstall() if test "$?" -eq 0; then if test -f "$DIR_CONF/vboxnet.conf"; then # nwam/dhcpagent fix - nwamfile=/etc/nwam/llp + nwamfile=${BASEDIR}/etc/nwam/llp nwambackupfile=$nwamfile.vbox if test -f "$nwamfile"; then sed -e '/vboxnet/d' $nwamfile > $nwambackupfile @@ -599,97 +663,101 @@ postinstall() mv -f $nwambackupfile $nwamfile fi - # plumb and configure vboxnet0 - $BIN_IFCONFIG vboxnet0 plumb up - if test "$?" -eq 0; then - $BIN_IFCONFIG vboxnet0 192.168.56.1 netmask 255.255.255.0 up - - # add the netmask to stay persistent across host reboots - nmaskfile=/etc/netmasks - nmaskbackupfile=$nmaskfile.vbox - if test -f $nmaskfile; then - sed -e '/#VirtualBox_SectionStart/,/#VirtualBox_SectionEnd/d' $nmaskfile > $nmaskbackupfile - echo "#VirtualBox_SectionStart" >> $nmaskbackupfile - inst=0 - networkn=56 - while test $inst -ne 1; do - echo "192.168.$networkn.0 255.255.255.0" >> $nmaskbackupfile - inst=`expr $inst + 1` - networkn=`expr $networkn + 1` - done - echo "#VirtualBox_SectionEnd" >> $nmaskbackupfile - mv -f $nmaskbackupfile $nmaskfile + # plumb and configure vboxnet0 for non-remote installs + if test "$REMOTEINST" -eq 0; then + $BIN_IFCONFIG vboxnet0 plumb up + if test "$?" -eq 0; then + $BIN_IFCONFIG vboxnet0 192.168.56.1 netmask 255.255.255.0 up + + # add the netmask to stay persistent across host reboots + nmaskfile=${BASEDIR}/etc/netmasks + nmaskbackupfile=$nmaskfile.vbox + if test -f $nmaskfile; then + sed -e '/#VirtualBox_SectionStart/,/#VirtualBox_SectionEnd/d' $nmaskfile > $nmaskbackupfile + echo "#VirtualBox_SectionStart" >> $nmaskbackupfile + inst=0 + networkn=56 + while test $inst -ne 1; do + echo "192.168.$networkn.0 255.255.255.0" >> $nmaskbackupfile + inst=`expr $inst + 1` + networkn=`expr $networkn + 1` + done + echo "#VirtualBox_SectionEnd" >> $nmaskbackupfile + mv -f $nmaskbackupfile $nmaskfile + fi + else + # Should this be fatal? + warnprint "Failed to bring up vboxnet0!!" fi - else - # Should this be fatal? - warnprint "Failed to bring up vboxnet0!!" fi fi - if test -f /var/svc/manifest/application/virtualbox/virtualbox-webservice.xml || test -f /var/svc/manifest/application/virtualbox/virtualbox-zoneaccess.xml; then + if test -f ${BASEDIR}/var/svc/manifest/application/virtualbox/virtualbox-webservice.xml || test -f ${BASEDIR}/var/svc/manifest/application/virtualbox/virtualbox-zoneaccess.xml; then infoprint "Configuring services..." - fi - - # Web service - if test -f /var/svc/manifest/application/virtualbox/virtualbox-webservice.xml; then - /usr/sbin/svccfg import /var/svc/manifest/application/virtualbox/virtualbox-webservice.xml - /usr/sbin/svcadm disable -s svc:/application/virtualbox/webservice:default - if test "$?" -eq 0; then - subprint "Loaded: Web service" - else - subprint "Loading: Web service ...ERROR(S)." + if test "$REMOTEINST" -eq 1; then + subprint "Skipped for targetted installs." fi fi - # Zone access service - if test -f /var/svc/manifest/application/virtualbox/virtualbox-zoneaccess.xml; then - /usr/sbin/svccfg import /var/svc/manifest/application/virtualbox/virtualbox-zoneaccess.xml - /usr/sbin/svcadm enable -s svc:/application/virtualbox/zoneaccess - if test "$?" -eq 0; then - subprint "Loaded: Zone access service" - else - subprint "Loading: Zone access service ...ERROR(S)." - fi - fi - - # Install python bindings - if test -f "$DIR_VBOXBASE/sdk/installer/vboxapisetup.py" || test -h "$DIR_VBOXBASE/sdk/installer/vboxapisetup.py"; then - PYTHONBIN=`which python 2> /dev/null` - if test -f "$PYTHONBIN" || test -h "$PYTHONBIN"; then - infoprint "Installing Python bindings..." - - INSTALLEDIT=1 - PYTHONBIN=`which python2.4 2>/dev/null` - install_python_bindings "$PYTHONBIN" "Python 2.4" - if test "$?" -eq 0; then - INSTALLEDIT=0 - fi - PYTHONBIN=`which python2.5 2>/dev/null` - install_python_bindings "$PYTHONBIN" "Python 2.5" - if test "$?" -eq 0; then - INSTALLEDIT=0 - fi - PYTHONBIN=`which python2.6 2>/dev/null` - install_python_bindings "$PYTHONBIN" "Python 2.6" + # Enable Zone access service for non-remote installs, other services (Webservice) are delivered disabled by the manifest class action + if test "$REMOTEINST" -eq 0; then + servicefound=`$BIN_SVCS -a | grep "virtualbox/zoneaccess" | grep "disabled" 2>/dev/null` + if test ! -z "$servicefound"; then + /usr/sbin/svcadm enable -s svc:/application/virtualbox/zoneaccess if test "$?" -eq 0; then - INSTALLEDIT=0 + subprint "Loaded: Zone access service" + else + subprint "Loading Zone access service ...FAILED." fi + fi + fi - # remove files installed by Python build - rm -rf $DIR_VBOXBASE/sdk/installer/build - - if test "$INSTALLEDIT" -ne 0; then - warnprint "No suitable Python version found. Required Python 2.4, 2.5 or 2.6." - warnprint "Skipped installing the Python bindings." + # Install python bindings for non-remote installs + if test "$REMOTEINST" -eq 0; then + if test -f "$DIR_VBOXBASE/sdk/installer/vboxapisetup.py" || test -h "$DIR_VBOXBASE/sdk/installer/vboxapisetup.py"; then + PYTHONBIN=`which python 2> /dev/null` + if test -f "$PYTHONBIN" || test -h "$PYTHONBIN"; then + infoprint "Installing Python bindings..." + + INSTALLEDIT=1 + PYTHONBIN=`which python2.4 2>/dev/null` + install_python_bindings "$PYTHONBIN" "Python 2.4" + if test "$?" -eq 0; then + INSTALLEDIT=0 + fi + PYTHONBIN=`which python2.5 2>/dev/null` + install_python_bindings "$PYTHONBIN" "Python 2.5" + if test "$?" -eq 0; then + INSTALLEDIT=0 + fi + PYTHONBIN=`which python2.6 2>/dev/null` + install_python_bindings "$PYTHONBIN" "Python 2.6" + if test "$?" -eq 0; then + INSTALLEDIT=0 + fi + + # remove files installed by Python build + rm -rf $DIR_VBOXBASE/sdk/installer/build + + if test "$INSTALLEDIT" -ne 0; then + warnprint "No suitable Python version found. Required Python 2.4, 2.5 or 2.6." + warnprint "Skipped installing the Python bindings." + fi + else + warnprint "Python not found, skipped installed Python bindings." fi - else - warnprint "Python not found, skipped installed Python bindings." fi + else + warnprint "Skipped installing Python bindings. Run, as root, 'vboxapisetup.py install' manually from the booted system." fi # Update boot archive infoprint "Updating the boot archive..." - $BIN_BOOTADM update-archive > /dev/null + if test "$REMOTEINST" -eq 0; then + $BIN_BOOTADM update-archive > /dev/null + else + $BIN_BOOTADM update-archive -R ${BASEDIR} > /dev/null + fi return 0 else @@ -721,6 +789,12 @@ check_root check_isa check_zone find_bins +get_sysinfo + +if test "x${BASEDIR}" != "x/"; then + BASEDIR_OPT="-b ${BASEDIR}" + REMOTEINST=1 +fi # Get command line options while test $# -gt 0; diff --git a/src/VBox/Main/AudioAdapterImpl.cpp b/src/VBox/Main/AudioAdapterImpl.cpp index 41dc6b770..b4767d180 100644 --- a/src/VBox/Main/AudioAdapterImpl.cpp +++ b/src/VBox/Main/AudioAdapterImpl.cpp @@ -245,59 +245,19 @@ STDMETHODIMP AudioAdapter::COMSETTER(AudioDriver)(AudioDriverType_T aAudioDriver if (mData->mAudioDriver != aAudioDriver) { - /* - * which audio driver type are we supposed to use? - */ - switch (aAudioDriver) + if (settings::MachineConfigFile::isAudioDriverAllowedOnThisHost(aAudioDriver)) { - case AudioDriverType_Null: -#ifdef RT_OS_WINDOWS -# ifdef VBOX_WITH_WINMM - case AudioDriverType_WinMM: -# endif - case AudioDriverType_DirectSound: -#endif /* RT_OS_WINDOWS */ -#ifdef RT_OS_SOLARIS - case AudioDriverType_SolAudio: -#endif -#ifdef RT_OS_LINUX -# ifdef VBOX_WITH_ALSA - case AudioDriverType_ALSA: -# endif -# ifdef VBOX_WITH_PULSE - case AudioDriverType_Pulse: -# endif -#endif /* RT_OS_LINUX */ -#if defined (RT_OS_LINUX) || defined (RT_OS_FREEBSD) || defined(VBOX_WITH_SOLARIS_OSS) - case AudioDriverType_OSS: -#endif -#ifdef RT_OS_FREEBSD -# ifdef VBOX_WITH_PULSE - case AudioDriverType_Pulse: -# endif -#endif -#ifdef RT_OS_DARWIN - case AudioDriverType_CoreAudio: -#endif -#ifdef RT_OS_OS2 - case AudioDriverType_MMPM: -#endif - { - mData.backup(); - mData->mAudioDriver = aAudioDriver; - - alock.release(); - AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking - mParent->setModified(Machine::IsModified_AudioAdapter); - break; - } + mData.backup(); + mData->mAudioDriver = aAudioDriver; - default: - { - AssertMsgFailed (("Wrong audio driver type %d\n", - aAudioDriver)); - rc = E_FAIL; - } + alock.release(); + AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking + mParent->setModified(Machine::IsModified_AudioAdapter); + } + else + { + AssertMsgFailed(("Wrong audio driver type %d\n", aAudioDriver)); + rc = E_FAIL; } } diff --git a/src/VBox/Main/ConsoleImpl.cpp b/src/VBox/Main/ConsoleImpl.cpp index 3a44c536e..1b8b96881 100644 --- a/src/VBox/Main/ConsoleImpl.cpp +++ b/src/VBox/Main/ConsoleImpl.cpp @@ -929,7 +929,18 @@ int Console::VRDPClientLogon(uint32_t u32ClientId, const char *pszUser, const ch hrc = mMachine->GetExtraData(Bstr("VRDP/ProvideGuestCredentials"), value.asOutParam()); if (SUCCEEDED(hrc) && value == "1") { - fProvideGuestCredentials = TRUE; + /* Provide credentials only if there are no logged in users. */ + Bstr noLoggedInUsersValue; + ULONG64 ul64Timestamp = 0; + Bstr flags; + + hrc = getGuestProperty(Bstr("/VirtualBox/GuestInfo/OS/NoLoggedInUsers"), + noLoggedInUsersValue.asOutParam(), &ul64Timestamp, flags.asOutParam()); + + if (SUCCEEDED(hrc) && noLoggedInUsersValue != Bstr("false")) + { + fProvideGuestCredentials = TRUE; + } } if ( fProvideGuestCredentials @@ -1355,15 +1366,7 @@ HRESULT Console::doEnumerateGuestProperties(CBSTR aPatterns, Utf8Str utf8Patterns(aPatterns); parm[0].type = VBOX_HGCM_SVC_PARM_PTR; - // mutableRaw() returns NULL for an empty string -// if ((parm[0].u.pointer.addr = utf8Patterns.mutableRaw())) -// parm[0].u.pointer.size = (uint32_t)utf8Patterns.length() + 1; -// else -// { -// parm[0].u.pointer.addr = (void*)""; -// parm[0].u.pointer.size = 1; -// } - parm[0].u.pointer.addr = utf8Patterns.mutableRaw(); + parm[0].u.pointer.addr = (void*)utf8Patterns.c_str(); parm[0].u.pointer.size = (uint32_t)utf8Patterns.length() + 1; /* @@ -6211,7 +6214,7 @@ DECLCALLBACK(void) Console::vmstateChangeCallback(PVM aVM, that->setMachineState(MachineState_Saved); break; case MachineState_TeleportingIn: - /* Teleportation failed or was cancelled. Back to powered off. */ + /* Teleportation failed or was canceled. Back to powered off. */ that->setMachineState(MachineState_PoweredOff); break; case MachineState_TeleportingPausedVM: @@ -7738,7 +7741,7 @@ DECLCALLBACK(int) Console::fntTakeSnapshotWorker(RTTHREAD Thread, void *pvUser) pTask->mProgress->setCancelCallback(NULL, NULL); if (!pTask->mProgress->notifyPointOfNoReturn()) - throw setError(E_FAIL, tr("Cancelled")); + throw setError(E_FAIL, tr("Canceled")); that->mptrCancelableProgress.setNull(); // STEP 4: reattach hard disks diff --git a/src/VBox/Main/ConsoleImpl2.cpp b/src/VBox/Main/ConsoleImpl2.cpp index 0c1ba64a1..0b13870a0 100644 --- a/src/VBox/Main/ConsoleImpl2.cpp +++ b/src/VBox/Main/ConsoleImpl2.cpp @@ -434,6 +434,12 @@ DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole) hrc = pMachine->COMGETTER(MemoryBalloonSize)(&ulBalloonSize); H(); rc = CFGMR3InsertInteger(pRoot, "MemBalloonSize", ulBalloonSize); RC_CHECK(); + /* + * CPUM values. + */ + PCFGMNODE pCPUM; + rc = CFGMR3InsertNode(pRoot, "CPUM", &pCPUM); RC_CHECK(); + /* cpuid leaf overrides. */ static uint32_t const s_auCpuIdRanges[] = { @@ -448,7 +454,7 @@ DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole) if (SUCCEEDED(hrc)) { PCFGMNODE pLeaf; - rc = CFGMR3InsertNodeF(pRoot, &pLeaf, "CPUM/HostCPUID/%RX32", uLeaf); RC_CHECK(); + rc = CFGMR3InsertNodeF(pCPUM, &pLeaf, "HostCPUID/%RX32", uLeaf); RC_CHECK(); rc = CFGMR3InsertInteger(pLeaf, "eax", ulEax); RC_CHECK(); rc = CFGMR3InsertInteger(pLeaf, "ebx", ulEbx); RC_CHECK(); @@ -458,30 +464,24 @@ DECLCALLBACK(int) Console::configConstructor(PVM pVM, void *pvConsole) else if (hrc != E_INVALIDARG) H(); } + /* We must limit CPUID count for Windows NT 4, as otherwise it stops + with error 0x3e (MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED). */ if (osTypeId == "WindowsNT4") { - /* - * We must limit CPUID count for Windows NT 4, as otherwise it stops - * with error 0x3e (MULTIPROCESSOR_CONFIGURATION_NOT_SUPPORTED). - */ LogRel(("Limiting CPUID leaf count for NT4 guests\n")); - PCFGMNODE pCPUM; - rc = CFGMR3InsertNode(pRoot, "CPUM", &pCPUM); RC_CHECK(); rc = CFGMR3InsertInteger(pCPUM, "NT4LeafLimit", true); RC_CHECK(); } + /* Expose extended MWAIT features to Mac OS X guests. */ if (fOsXGuest) { - /* - * Expose extended MWAIT features to Mac OS X guests. - */ LogRel(("Using MWAIT extensions\n")); - PCFGMNODE pCPUM; - rc = CFGMR3InsertNode(pRoot, "CPUM", &pCPUM); RC_CHECK(); rc = CFGMR3InsertInteger(pCPUM, "MWaitExtensions", true); RC_CHECK(); } - /* hardware virtualization extensions */ + /* + * Hardware virtualization extensions. + */ BOOL fHWVirtExEnabled; BOOL fHwVirtExtForced; #ifdef VBOX_WITH_RAW_MODE @@ -2402,7 +2402,13 @@ int Console::configMediumAttachment(PCFGMNODE pCtlInst, ComPtr<IMedium> pMedium; hrc = pMediumAtt->COMGETTER(Medium)(pMedium.asOutParam()); H(); - if (lType == DeviceType_HardDisk) + /* + * 1. Only check this for hard disk images. + * 2. Only check during VM creation and not later, especially not during + * taking an online snapshot! + */ + if ( lType == DeviceType_HardDisk + && aMachineState == MachineState_Starting) { /* * Some sanity checks. @@ -2621,9 +2627,11 @@ int Console::configMedium(PCFGMNODE pLunL0, PCFGMNODE pCfg = NULL; BOOL fHostDrive = FALSE; + MediumType_T mediumType = MediumType_Normal; if (pMedium) { hrc = pMedium->COMGETTER(HostDrive)(&fHostDrive); H(); + hrc = pMedium->COMGETTER(Type)(&mediumType); H(); } if (fHostDrive) @@ -2730,11 +2738,15 @@ int Console::configMedium(PCFGMNODE pLunL0, hrc = pMedium->COMGETTER(Format)(bstr.asOutParam()); H(); rc = CFGMR3InsertStringW(pCfg, "Format", bstr.raw()); RC_CHECK(); - /* DVDs are always readonly */ + /* DVDs are always readonly, floppies may be readonly */ if (enmType == DeviceType_DVD) { rc = CFGMR3InsertInteger(pCfg, "ReadOnly", 1); RC_CHECK(); } + else if (enmType == DeviceType_Floppy) + { + rc = CFGMR3InsertInteger(pCfg, "MaybeReadOnly", 1); RC_CHECK(); + } /* Start without exclusive write access to the images. */ /** @todo Live Migration: I don't quite like this, we risk screwing up when @@ -2750,6 +2762,14 @@ int Console::configMedium(PCFGMNODE pLunL0, rc = CFGMR3InsertInteger(pCfg, "TempReadOnly", 1); RC_CHECK(); } + /* Flag for opening the medium for sharing between VMs. This + * is done at the moment only for the first (and only) medium + * in the chain, as shared media can have no diffs. */ + if (mediumType == MediumType_Shareable) + { + rc = CFGMR3InsertInteger(pCfg, "Shareable", 1); RC_CHECK(); + } + if (!fUseHostIOCache) { rc = CFGMR3InsertInteger(pCfg, "UseNewIo", 1); RC_CHECK(); diff --git a/src/VBox/Main/ConsoleImplTeleporter.cpp b/src/VBox/Main/ConsoleImplTeleporter.cpp index d67e00828..986c91ac6 100644 --- a/src/VBox/Main/ConsoleImplTeleporter.cpp +++ b/src/VBox/Main/ConsoleImplTeleporter.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009 Oracle Corporation + * Copyright (C) 2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -286,12 +286,7 @@ Console::teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, HRESULT Console::teleporterSrcSubmitCommand(TeleporterStateSrc *pState, const char *pszCommand, bool fWaitForAck /*= true*/) { - size_t cchCommand = strlen(pszCommand); - int vrc = RTTcpWrite(pState->mhSocket, pszCommand, cchCommand); - if (RT_SUCCESS(vrc)) - vrc = RTTcpWrite(pState->mhSocket, "\n", sizeof("\n") - 1); - if (RT_SUCCESS(vrc)) - vrc = RTTcpFlush(pState->mhSocket); + int vrc = RTTcpSgWriteL(pState->mhSocket, 2, pszCommand, strlen(pszCommand), "\n", sizeof("\n") - 1); if (RT_FAILURE(vrc)) return setError(E_FAIL, tr("Failed writing command '%s': %Rrc"), pszCommand, vrc); if (!fWaitForAck) @@ -313,22 +308,13 @@ static DECLCALLBACK(int) teleporterTcpOpWrite(void *pvUser, uint64_t offStream, for (;;) { - /* Write block header. */ TELEPORTERTCPHDR Hdr; Hdr.u32Magic = TELEPORTERTCPHDR_MAGIC; Hdr.cb = RT_MIN((uint32_t)cbToWrite, TELEPORTERTCPHDR_MAX_SIZE); - int rc = RTTcpWrite(pState->mhSocket, &Hdr, sizeof(Hdr)); - if (RT_FAILURE(rc)) - { - LogRel(("Teleporter/TCP: Header write error: %Rrc\n", rc)); - return rc; - } - - /* Write the data. */ - rc = RTTcpWrite(pState->mhSocket, pvBuf, Hdr.cb); + int rc = RTTcpSgWriteL(pState->mhSocket, 2, &Hdr, sizeof(Hdr), pvBuf, (size_t)Hdr.cb); if (RT_FAILURE(rc)) { - LogRel(("Teleporter/TCP: Data write error: %Rrc (cb=%#x)\n", rc, Hdr.cb)); + LogRel(("Teleporter/TCP: Write error: %Rrc (cb=%#x)\n", rc, Hdr.cb)); return rc; } pState->moffStream += Hdr.cb; @@ -530,7 +516,7 @@ static DECLCALLBACK(int) teleporterTcpOpIsOk(void *pvUser) /** * @copydoc SSMSTRMOPS::pfnClose */ -static DECLCALLBACK(int) teleporterTcpOpClose(void *pvUser, bool fCancelled) +static DECLCALLBACK(int) teleporterTcpOpClose(void *pvUser, bool fCanceled) { TeleporterState *pState = (TeleporterState *)pvUser; @@ -538,10 +524,8 @@ static DECLCALLBACK(int) teleporterTcpOpClose(void *pvUser, bool fCancelled) { TELEPORTERTCPHDR EofHdr; EofHdr.u32Magic = TELEPORTERTCPHDR_MAGIC; - EofHdr.cb = fCancelled ? UINT32_MAX : 0; + EofHdr.cb = fCanceled ? UINT32_MAX : 0; int rc = RTTcpWrite(pState->mhSocket, &EofHdr, sizeof(EofHdr)); - if (RT_SUCCESS(rc)) - rc = RTTcpFlush(pState->mhSocket); if (RT_FAILURE(rc)) { LogRel(("Teleporter/TCP: EOF Header write error: %Rrc\n", rc)); @@ -551,7 +535,6 @@ static DECLCALLBACK(int) teleporterTcpOpClose(void *pvUser, bool fCancelled) else { ASMAtomicWriteBool(&pState->mfStopReading, true); - RTTcpFlush(pState->mhSocket); } return VINF_SUCCESS; @@ -601,9 +584,9 @@ static DECLCALLBACK(int) teleporterProgressCallback(PVM pVM, unsigned uPercent, if (FAILED(hrc)) { /* check if the failure was caused by cancellation. */ - BOOL fCancelled; - hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCancelled); - if (SUCCEEDED(hrc) && fCancelled) + BOOL fCanceled; + hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCanceled); + if (SUCCEEDED(hrc) && fCanceled) { SSMR3Cancel(pState->mpVM); return VERR_SSM_CANCELLED; @@ -642,21 +625,23 @@ Console::teleporterSrc(TeleporterStateSrc *pState) */ { AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS); } - BOOL fCancelled = TRUE; - HRESULT hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCancelled); + BOOL fCanceled = TRUE; + HRESULT hrc = pState->mptrProgress->COMGETTER(Canceled)(&fCanceled); if (FAILED(hrc)) return hrc; - if (fCancelled) - return setError(E_FAIL, tr("cancelled")); + if (fCanceled) + return setError(E_FAIL, tr("canceled")); /* - * Try connect to the destination machine. + * Try connect to the destination machine, disable Nagle. * (Note. The caller cleans up mhSocket, so we can return without worries.) */ int vrc = RTTcpClientConnect(pState->mstrHostname.c_str(), pState->muPort, &pState->mhSocket); if (RT_FAILURE(vrc)) return setError(E_FAIL, tr("Failed to connect to port %u on '%s': %Rrc"), pState->muPort, pState->mstrHostname.c_str(), vrc); + vrc = RTTcpSetSendCoalescing(pState->mhSocket, false /*fEnable*/); + AssertRC(vrc); /* Read and check the welcome message. */ char szLine[RT_MAX(128, sizeof(g_szWelcome))]; @@ -789,7 +774,7 @@ Console::teleporterSrcThreadWrapper(RTTHREAD hThread, void *pvUser) if (FAILED(hrc)) pState->mptrProgress->notifyComplete(hrc); - /* We can no longer be cancelled (success), or it doesn't matter any longer (failure). */ + /* We can no longer be canceled (success), or it doesn't matter any longer (failure). */ pState->mptrProgress->setCancelCallback(NULL, NULL); /* @@ -1136,9 +1121,9 @@ Console::teleporterTrg(PVM pVM, IMachine *pMachine, Utf8Str *pErrorMsg, bool fSt } else if (vrc == VERR_TCP_SERVER_SHUTDOWN) { - BOOL fCancelled = TRUE; - hrc = pProgress->COMGETTER(Canceled)(&fCancelled); - if (FAILED(hrc) || fCancelled) + BOOL fCanceled = TRUE; + hrc = pProgress->COMGETTER(Canceled)(&fCanceled); + if (FAILED(hrc) || fCanceled) hrc = setError(E_FAIL, tr("Teleporting canceled")); else hrc = setError(E_FAIL, tr("Teleporter timed out waiting for incoming connection")); @@ -1208,7 +1193,6 @@ static int teleporterTcpWriteACK(TeleporterStateTrg *pState, bool fAutomaticUnlo if (fAutomaticUnlock) teleporterTrgUnlockMedia(pState); } - RTTcpFlush(pState->mhSocket); return rc; } @@ -1235,7 +1219,6 @@ static int teleporterTcpWriteNACK(TeleporterStateTrg *pState, int32_t rc2, const int rc = RTTcpWrite(pState->mhSocket, szMsg, cch); if (RT_FAILURE(rc)) LogRel(("Teleporter: RTTcpWrite(,%s,%zu) -> %Rrc\n", szMsg, cch, rc)); - RTTcpFlush(pState->mhSocket); return rc; } @@ -1252,9 +1235,11 @@ Console::teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser) pState->mhSocket = Sock; /* - * Say hello. + * Disable Nagle and say hello. */ - int vrc = RTTcpWrite(Sock, g_szWelcome, sizeof(g_szWelcome) - 1); + int vrc = RTTcpSetSendCoalescing(pState->mhSocket, false /*fEnable*/); + AssertRC(vrc); + vrc = RTTcpWrite(Sock, g_szWelcome, sizeof(g_szWelcome) - 1); if (RT_FAILURE(vrc)) { LogRel(("Teleporter: Failed to write welcome message: %Rrc\n", vrc)); diff --git a/src/VBox/Main/GuestImpl.cpp b/src/VBox/Main/GuestImpl.cpp index 52952b2ac..a42e005fb 100644 --- a/src/VBox/Main/GuestImpl.cpp +++ b/src/VBox/Main/GuestImpl.cpp @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2006-2008 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -105,8 +105,8 @@ HRESULT Guest::init (Console *aParent) } /** - * Uninitializes the instance and sets the ready flag to FALSE. - * Called either from FinalRelease() or by the parent when it gets destroyed. + * Uninitializes the instance and sets the ready flag to FALSE. + * Called either from FinalRelease() or by the parent when it gets destroyed. */ void Guest::uninit() { @@ -121,12 +121,12 @@ void Guest::uninit() * ref counts). */ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); - + /* Clean up callback data. */ CallbackMapIter it; for (it = mCallbackMap.begin(); it != mCallbackMap.end(); it++) destroyCtrlCallbackContext(it); - + /* Clear process map. */ mGuestProcessMap.clear(); } @@ -382,7 +382,7 @@ STDMETHODIMP Guest::InternalGetStatistics(ULONG *aCpuUser, ULONG *aCpuKernel, UL return S_OK; } -HRESULT Guest::SetStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal) +HRESULT Guest::setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal) { AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); @@ -504,7 +504,7 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension, int rc = VINF_SUCCESS; if (u32Function == GUEST_DISCONNECTED) { - LogFlowFunc(("GUEST_DISCONNECTED\n")); + //LogFlowFunc(("GUEST_DISCONNECTED\n")); PCALLBACKDATACLIENTDISCONNECTED pCBData = reinterpret_cast<PCALLBACKDATACLIENTDISCONNECTED>(pvParms); AssertPtr(pCBData); @@ -515,7 +515,7 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension, } else if (u32Function == GUEST_EXEC_SEND_STATUS) { - LogFlowFunc(("GUEST_EXEC_SEND_STATUS\n")); + //LogFlowFunc(("GUEST_EXEC_SEND_STATUS\n")); PCALLBACKDATAEXECSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvParms); AssertPtr(pCBData); @@ -526,7 +526,7 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension, } else if (u32Function == GUEST_EXEC_SEND_OUTPUT) { - LogFlowFunc(("GUEST_EXEC_SEND_OUTPUT\n")); + //LogFlowFunc(("GUEST_EXEC_SEND_OUTPUT\n")); PCALLBACKDATAEXECOUT pCBData = reinterpret_cast<PCALLBACKDATAEXECOUT>(pvParms); AssertPtr(pCBData); @@ -544,7 +544,7 @@ DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension, int Guest::notifyCtrlExecStatus(uint32_t u32Function, PCALLBACKDATAEXECSTATUS pData) { - int rc = VINF_SUCCESS; + int vrc = VINF_SUCCESS; AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); @@ -562,60 +562,72 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function, pCBData->u32Flags = pData->u32Flags; /** @todo Copy void* buffer contents! */ + Utf8Str errMsg; + /* Was progress canceled before? */ BOOL fCanceled; - ComAssert(it->second.pProgress.isNotNull()); - it->second.pProgress->COMGETTER(Canceled)(&fCanceled); - - Utf8Str errMsg; - if (!fCanceled) - { + ComAssert(!it->second.pProgress.isNull()); + if ( SUCCEEDED(it->second.pProgress->COMGETTER(Canceled)(&fCanceled)) + && !fCanceled) + { /* Do progress handling. */ + HRESULT hr; switch (pData->u32Status) { case PROC_STS_STARTED: - rc = it->second.pProgress->SetNextOperation(BstrFmt(tr("Waiting for process to exit ...")), 1 /* Weight */); - if (FAILED(rc)) - errMsg = Utf8StrFmt(Guest::tr("Cannot enter waiting for process exit stage! rc=%u"), - rc); + LogRel(("Guest process (PID %u) started\n", pCBData->u32PID)); /** @todo Add process name */ + hr = it->second.pProgress->SetNextOperation(BstrFmt(tr("Waiting for process to exit ...")), 1 /* Weight */); + AssertComRC(hr); break; - + case PROC_STS_TEN: /* Terminated normally. */ - it->second.pProgress->notifyComplete(S_OK); + LogRel(("Guest process (PID %u) exited normally\n", pCBData->u32PID)); /** @todo Add process name */ + hr = it->second.pProgress->notifyComplete(S_OK); + AssertComRC(hr); LogFlowFunc(("Proccess (context ID=%u, status=%u) terminated successfully\n", pData->hdr.u32ContextID, pData->u32Status)); break; - + case PROC_STS_TEA: /* Terminated abnormally. */ + LogRel(("Guest process (PID %u) terminated abnormally with exit code = %u\n", + pCBData->u32PID, pCBData->u32Flags)); /** @todo Add process name */ errMsg = Utf8StrFmt(Guest::tr("Process terminated abnormally with status '%u'"), pCBData->u32Flags); break; - + case PROC_STS_TES: /* Terminated through signal. */ + LogRel(("Guest process (PID %u) terminated through signal with exit code = %u\n", + pCBData->u32PID, pCBData->u32Flags)); /** @todo Add process name */ errMsg = Utf8StrFmt(Guest::tr("Process terminated via signal with status '%u'"), pCBData->u32Flags); break; - + case PROC_STS_TOK: + LogRel(("Guest process (PID %u) timed out and was killed\n", pCBData->u32PID)); /** @todo Add process name */ errMsg = Utf8StrFmt(Guest::tr("Process timed out and was killed")); break; - + case PROC_STS_TOA: + LogRel(("Guest process (PID %u) timed out and could not be killed\n", pCBData->u32PID)); /** @todo Add process name */ errMsg = Utf8StrFmt(Guest::tr("Process timed out and could not be killed")); break; - + case PROC_STS_DWN: + LogRel(("Guest process (PID %u) exited because system is shutting down\n", pCBData->u32PID)); /** @todo Add process name */ errMsg = Utf8StrFmt(Guest::tr("Process exited because system is shutting down")); break; - + case PROC_STS_ERROR: + LogRel(("Guest process (PID %u) could not be started because of rc=%Rrc\n", + pCBData->u32PID, pCBData->u32Flags)); /** @todo Add process name */ errMsg = Utf8StrFmt(Guest::tr("Process execution failed with rc=%Rrc"), pCBData->u32Flags); break; - + default: + vrc = VERR_INVALID_PARAMETER; break; } - + /* Handle process map. */ /** @todo What happens on/deal with PID reuse? */ /** @todo How to deal with multiple updates at once? */ @@ -629,7 +641,7 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function, newProcess.mStatus = pCBData->u32Status; newProcess.mExitCode = pCBData->u32Flags; /* Contains exit code. */ newProcess.mFlags = 0; - + mGuestProcessMap[pCBData->u32PID] = newProcess; } else /* Update map. */ @@ -642,22 +654,25 @@ int Guest::notifyCtrlExecStatus(uint32_t u32Function, } else errMsg = Utf8StrFmt(Guest::tr("Process execution canceled")); - + if (!it->second.pProgress->getCompleted()) { - if ( errMsg.length() - || fCanceled) /* If cancelled we have to report E_FAIL! */ + if ( errMsg.length() + || fCanceled) /* If canceled we have to report E_FAIL! */ { - it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest), - (CBSTR)Guest::getComponentName(), errMsg.c_str()); + HRESULT hr2 = it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest), + Guest::getComponentName(), + "%s", errMsg.c_str()); + AssertComRC(hr2); LogFlowFunc(("Process (context ID=%u, status=%u) reported error: %s\n", pData->hdr.u32ContextID, pData->u32Status, errMsg.c_str())); } - } + } } else LogFlowFunc(("Unexpected callback (magic=%u, context ID=%u) arrived\n", pData->hdr.u32Magic, pData->hdr.u32ContextID)); - return rc; + LogFlowFunc(("Returned with rc=%Rrc\n", vrc)); + return vrc; } /* Function for handling the execution output notification. */ @@ -698,14 +713,16 @@ int Guest::notifyCtrlExecOut(uint32_t u32Function, /* Was progress canceled before? */ BOOL fCanceled; - ComAssert(it->second.pProgress.isNotNull()); - it->second.pProgress->COMGETTER(Canceled)(&fCanceled); - - if (!fCanceled) - it->second.pProgress->notifyComplete(S_OK); + ComAssert(!it->second.pProgress.isNull()); + if (SUCCEEDED(it->second.pProgress->COMGETTER(Canceled)(&fCanceled)) && fCanceled) + { + it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, + COM_IIDOF(IGuest), + Guest::getComponentName(), + Guest::tr("The output operation was canceled")); + } else - it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest), - (CBSTR)Guest::getComponentName(), Guest::tr("The output operation was cancelled")); + it->second.pProgress->notifyComplete(S_OK); } else LogFlowFunc(("Unexpected callback (magic=%u, context ID=%u) arrived\n", pData->hdr.u32Magic, pData->hdr.u32ContextID)); @@ -729,7 +746,7 @@ int Guest::notifyCtrlClientDisconnected(uint32_t u32Funct Guest::CallbackMapIter Guest::getCtrlCallbackContextByID(uint32_t u32ContextID) { - AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); return mCallbackMap.find(u32ContextID); } @@ -742,35 +759,50 @@ Guest::GuestProcessMapIter Guest::getProcessByPID(uint32_t u32PID) /* No locking here; */ void Guest::destroyCtrlCallbackContext(Guest::CallbackMapIter it) { + LogFlowFunc(("Destroying callback with CID=%u ...\n", it->first)); + if (it->second.pvData) { - LogFlowFunc(("Destroying callback with context ID=%u ...\n", it->first)); - RTMemFree(it->second.pvData); it->second.pvData = NULL; it->second.cbData = 0; } /* Notify outstanding waits for progress ... */ - if (it->second.pProgress && it->second.pProgress.isNotNull()) + if ( it->second.pProgress + && !it->second.pProgress.isNull()) { - LogFlowFunc(("Handling progress of context ID=%u ...\n", it->first)); + LogFlowFunc(("Handling progress for CID=%u ...\n", it->first)); - BOOL fCompleted; + /* + * Assume we didn't complete to make sure we clean up even if the + * following call fails. + */ + BOOL fCompleted = FALSE; it->second.pProgress->COMGETTER(Completed)(&fCompleted); if (!fCompleted) { + LogFlowFunc(("Progress of CID=%u *not* completed, cancelling ...\n", it->first)); + /* Only cancel if not canceled before! */ BOOL fCanceled; if (SUCCEEDED(it->second.pProgress->COMGETTER(Canceled)(&fCanceled)) && !fCanceled) - it->second.pProgress->Cancel(); + it->second.pProgress->Cancel(); - /* To get waitForCompletion notified we have to notify it if necessary. */ - it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, COM_IIDOF(IGuest), - (CBSTR)Guest::getComponentName(), Guest::tr("The operation was canceled during shutdown")); - } + /* + * To get waitForCompletion completed (unblocked) we have to notify it if necessary (only + * cancle won't work!). This could happen if the client thread (e.g. VBoxService, thread of a spawned process) + * is disconnecting without having the chance to sending a status message before, so we + * have to abort here to make sure the host never hangs/gets stuck while waiting for the + * progress object to become signalled. + */ + it->second.pProgress->notifyComplete(VBOX_E_IPRT_ERROR, + COM_IIDOF(IGuest), + Guest::getComponentName(), + Guest::tr("The operation was canceled because client is shutting down")); + } /* - * Do *not NULL pProgress here, because waiting function like executeProcess() + * Do *not* NULL pProgress here, because waiting function like executeProcess() * will still rely on this object for checking whether they have to give up! */ } @@ -794,13 +826,13 @@ uint32_t Guest::addCtrlCallbackContext(eVBoxGuestCtrlCallbackType enmType, void CallbackMapIter it; uint32_t uNewContext = 0; do - { + { /* Create a new context ID ... */ uNewContext = ASMAtomicIncU32(&mNextContextID); if (uNewContext == UINT32_MAX) ASMAtomicUoWriteU32(&mNextContextID, 1000); /* Is the context ID already used? */ - it = getCtrlCallbackContextByID(uNewContext); + it = getCtrlCallbackContextByID(uNewContext); } while(it != mCallbackMap.end()); uint32_t nCallbacks = 0; @@ -941,6 +973,9 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, } } + LogRel(("Executing guest process \"%s\" as user \"%s\" ...\n", + Utf8Command.raw(), Utf8UserName.raw())); + if (RT_SUCCESS(vrc)) { PCALLBACKDATAEXECSTATUS pData = (PCALLBACKDATAEXECSTATUS)RTMemAlloc(sizeof(CALLBACKDATAEXECSTATUS)); @@ -1001,7 +1036,7 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, BOOL fCanceled = FALSE; if (it != mCallbackMap.end()) { - ComAssert(it->second.pProgress.isNotNull()); + ComAssert(!it->second.pProgress.isNull()); /* * Wait for the first stage (=0) to complete (that is starting the process). @@ -1016,12 +1051,12 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, if (!fCanceled) { - AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); - + AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); + pData = (PCALLBACKDATAEXECSTATUS)it->second.pvData; Assert(it->second.cbData == sizeof(CALLBACKDATAEXECSTATUS)); AssertPtr(pData); - + /* Did we get some status? */ switch (pData->u32Status) { @@ -1029,7 +1064,7 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, /* Process is (still) running; get PID. */ *aPID = pData->u32PID; break; - + /* In any other case the process either already * terminated or something else went wrong, so no PID ... */ case PROC_STS_TEN: /* Terminated normally. */ @@ -1038,17 +1073,17 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, case PROC_STS_TOK: case PROC_STS_TOA: case PROC_STS_DWN: - /* + /* * Process (already) ended, but we want to get the - * PID anyway to retrieve the output in a later call. + * PID anyway to retrieve the output in a later call. */ *aPID = pData->u32PID; break; - + case PROC_STS_ERROR: vrc = pData->u32Flags; /* u32Flags member contains IPRT error code. */ break; - + case PROC_STS_UNDEFINED: vrc = VERR_TIMEOUT; /* Operation did not complete within time. */ break; @@ -1063,7 +1098,7 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, } else /* Operation did not complete within time. */ vrc = VERR_TIMEOUT; - + /* * Do *not* remove the callback yet - we might wait with the IProgress object on something * else (like end of process) ... @@ -1085,7 +1120,7 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, rc = setError(VBOX_E_IPRT_ERROR, tr("The file '%s' is not an executable format on guest"), Utf8Command.raw()); } - else if (vrc == VERR_LOGON_FAILURE) + else if (vrc == VERR_AUTHENTICATION_FAILURE) { rc = setError(VBOX_E_IPRT_ERROR, tr("The specified user '%s' was not able to logon on guest"), Utf8UserName.raw()); @@ -1113,7 +1148,7 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, else rc = setError(E_UNEXPECTED, tr("The service call failed with error %Rrc"), vrc); - } + } } else /* Execution went fine. */ { @@ -1136,6 +1171,11 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, rc = setError(VBOX_E_VM_ERROR, tr("The guest execution service is not ready")); } + else if (vrc == VERR_HGCM_SERVICE_NOT_FOUND) + { + rc = setError(VBOX_E_VM_ERROR, + tr("The guest execution service is not available")); + } else /* HGCM call went wrong. */ { rc = setError(E_UNEXPECTED, @@ -1147,6 +1187,10 @@ STDMETHODIMP Guest::ExecuteProcess(IN_BSTR aCommand, ULONG aFlags, RTMemFree(papszArgv[i]); RTMemFree(papszArgv); } + + if (RT_FAILURE(vrc)) + LogRel(("Executing guest process \"%s\" as user \"%s\" failed with %Rrc\n", + Utf8Command.raw(), Utf8UserName.raw(), vrc)); } catch (std::bad_alloc &) { @@ -1181,7 +1225,7 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS, * Create progress object. * This progress object, compared to the one in executeProgress() above, * is only local and is used to determine whether the operation finished - * or got cancelled. + * or got canceled. */ ComObjPtr <Progress> progress; rc = progress.createObject(); @@ -1250,12 +1294,12 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS, BOOL fCanceled = FALSE; if (it != mCallbackMap.end()) { - ComAssert(it->second.pProgress.isNotNull()); + ComAssert(!it->second.pProgress.isNull()); /* Wait until operation completed. */ rc = it->second.pProgress->WaitForCompletion(aTimeoutMS); if (FAILED(rc)) throw rc; - + /* Was the operation canceled by one of the parties? */ rc = it->second.pProgress->COMGETTER(Canceled)(&fCanceled); if (FAILED(rc)) throw rc; @@ -1320,6 +1364,9 @@ STDMETHODIMP Guest::GetProcessOutput(ULONG aPID, ULONG aFlags, ULONG aTimeoutMS, { AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + /* + * Destroy locally used progress object. + */ destroyCtrlCallbackContext(it); } @@ -1390,40 +1437,84 @@ STDMETHODIMP Guest::GetProcessStatus(ULONG aPID, ULONG *aExitCode, ULONG *aFlags // public methods only for internal purposes ///////////////////////////////////////////////////////////////////////////// -void Guest::setAdditionsVersion(Bstr aVersion, VBOXOSTYPE aOsType) +/** + * Sets the general Guest Additions information like + * API version and OS type. + * + * @param aVersion + * @param aOsType + */ +void Guest::setAdditionsInfo(Bstr aVersion, VBOXOSTYPE aOsType) { AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); + /* + * Set the Guest Additions API (interface) version. + * Note that this is *not* the actual Guest Additions version and may differ! + */ mData.mAdditionsVersion = aVersion; + /* + * Older Additions rely on the Additions API version whether they + * are assumed to be active or not. Newer additions will disable + * this immediately. + */ mData.mAdditionsActive = !aVersion.isEmpty(); - /* Older Additions didn't have this finer grained capability bit, + /* + * Older Additions didn't have this finer grained capability bit, * so enable it by default. Newer Additions will disable it immediately - * if relevant. */ + * if relevant. + */ mData.mSupportsGraphics = mData.mAdditionsActive; + /* + * Note! There is a race going on between setting mAdditionsActive and + * mSupportsGraphics here and disabling/enabling it later according to + * its real status when using new(er) Guest Additions. + */ + mData.mOSTypeId = Global::OSTypeId (aOsType); } -void Guest::setSupportsSeamless (BOOL aSupportsSeamless) +/** + * Sets the status of a certain Guest Additions facility. + * + * @param Facility + * @param Status + * @param ulFlags + */ +void Guest::setAdditionsStatus (VBoxGuestStatusFacility Facility, VBoxGuestStatusCurrent Status, ULONG ulFlags) { AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); - mData.mSupportsSeamless = aSupportsSeamless; + /* + * Only mark Guest Additions as active when VBoxService started up. + */ + mData.mAdditionsActive = ( Facility == VBoxGuestStatusFacility_VBoxService + && Status == VBoxGuestStatusCurrent_Active) ? TRUE : FALSE; } -void Guest::setSupportsGraphics (BOOL aSupportsGraphics) +/** + * Sets the supported features (and whether they are active or not). + * + * @param ulCaps + * @param ulActive + */ +void Guest::setSupportedFeatures (ULONG64 ulCaps, ULONG64 ulActive) { AutoCaller autoCaller(this); AssertComRCReturnVoid (autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); - mData.mSupportsGraphics = aSupportsGraphics; + mData.mSupportsSeamless = (ulCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS); + /** @todo Add VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING */ + mData.mSupportsGraphics = (ulCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS); } /* vi: set tabstop=4 shiftwidth=4 expandtab: */ + diff --git a/src/VBox/Main/MachineImpl.cpp b/src/VBox/Main/MachineImpl.cpp index bb046276c..ef8e5fb5b 100644 --- a/src/VBox/Main/MachineImpl.cpp +++ b/src/VBox/Main/MachineImpl.cpp @@ -364,8 +364,10 @@ HRESULT Machine::init(VirtualBox *aParent, /** * Initializes a new instance with data from machine XML (formerly Init_Registered). * Gets called in two modes: + * * -- from VirtualBox::initMachines() during VirtualBox startup; in that case, the * UUID is specified and we mark the machine as "registered"; + * * -- from the public VirtualBox::OpenMachine() API, in which case the UUID is NULL * and the machine remains unregistered until RegisterMachine() is called. * @@ -455,7 +457,7 @@ HRESULT Machine::init(VirtualBox *aParent, /** * Initializes a new instance from a machine config that is already in memory - * (import OVF import case). Since we are importing, the UUID in the machine + * (import OVF case). Since we are importing, the UUID in the machine * config is ignored and we always generate a fresh one. * * @param strName Name for the new machine; this overrides what is specified in config and is used @@ -5015,6 +5017,7 @@ STDMETHODIMP Machine::ReadLog(ULONG aIdx, ULONG64 aOffset, ULONG64 aSize, ComSaf rc = setError(VBOX_E_IPRT_ERROR, tr("Could not read log file '%s' (%Rrc)"), log.raw(), vrc); + RTFileClose(LogFile); } else rc = setError(VBOX_E_IPRT_ERROR, @@ -5254,10 +5257,6 @@ HRESULT Machine::openSession(IInternalSessionControl *aControl) if (SUCCEEDED(rc)) { -#ifdef VBOX_WITH_RESOURCE_USAGE_API - registerMetrics(mParent->performanceCollector(), this, pid); -#endif /* VBOX_WITH_RESOURCE_USAGE_API */ - /* * Set the session state to Spawning to protect against subsequent * attempts to open a session and to unregister the machine after @@ -9181,6 +9180,9 @@ void Machine::copyFrom(Machine *aThat) void Machine::registerMetrics(PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid) { + AssertReturnVoid(isWriteLockOnCurrentThread()); + AssertPtrReturnVoid(aCollector); + pm::CollectorHAL *hal = aCollector->getHAL(); /* Create sub metrics */ pm::SubMetric *cpuLoadUser = new pm::SubMetric("CPU/Load/User", @@ -9297,11 +9299,19 @@ void Machine::registerMetrics(PerformanceCollector *aCollector, Machine *aMachin void Machine::unregisterMetrics(PerformanceCollector *aCollector, Machine *aMachine) { - aCollector->unregisterMetricsFor(aMachine); - aCollector->unregisterBaseMetricsFor(aMachine); + AssertReturnVoid(isWriteLockOnCurrentThread()); + + if (aCollector) + { + aCollector->unregisterMetricsFor(aMachine); + aCollector->unregisterBaseMetricsFor(aMachine); + } if (mGuestHAL) + { delete mGuestHAL; + mGuestHAL = NULL; + } } #endif /* VBOX_WITH_RESOURCE_USAGE_API */ @@ -9607,9 +9617,10 @@ void SessionMachine::uninit(Uninit::Reason aReason) // and others need mParent lock, and USB needs host lock. AutoMultiWriteLock3 multilock(mParent, mParent->host(), this COMMA_LOCKVAL_SRC_POS); -#ifdef VBOX_WITH_RESOURCE_USAGE_API - unregisterMetrics(mParent->performanceCollector(), mPeer); -#endif /* VBOX_WITH_RESOURCE_USAGE_API */ + // Trigger async cleanup tasks, avoid doing things here which are not + // vital to be done immediately and maybe need more locks. This calls + // Machine::unregisterMetrics(). + mParent->onMachineUninit(mPeer); if (aReason == Uninit::Abnormal) { @@ -9874,6 +9885,18 @@ STDMETHODIMP SessionMachine::EndPowerUp(LONG iResult) { mData->mSession.mProgress->notifyComplete((HRESULT)iResult); mData->mSession.mProgress.setNull(); + + if (SUCCEEDED((HRESULT)iResult)) + { +#ifdef VBOX_WITH_RESOURCE_USAGE_API + /* The VM has been powered up successfully, so it makes sense + * now to offer the performance metrics for a running machine + * object. Doing it earlier wouldn't be safe. */ + registerMetrics(mParent->performanceCollector(), mPeer, + mData->mSession.mPid); +#endif /* VBOX_WITH_RESOURCE_USAGE_API */ + + } } return S_OK; } @@ -10350,7 +10373,7 @@ STDMETHODIMP SessionMachine::PushGuestProperty(IN_BSTR aName, mData->mGuestPropertiesModified = TRUE; break; } - if (aValue != NULL) + if (aValue != NULL && aValue[0] != '\0') { HWData::GuestProperty property = { aName, aValue, aTimestamp, fFlags }; mHWData->mGuestProperties.push_back(property); @@ -10882,8 +10905,11 @@ HRESULT SessionMachine::lockMedia() // attached later. if (pMedium != NULL) { - bool fIsReadOnlyImage = (devType == DeviceType_DVD); + MediumType_T mediumType = pMedium->getType(); + bool fIsReadOnlyImage = devType == DeviceType_DVD + || mediumType == MediumType_Shareable; bool fIsVitalImage = (devType == DeviceType_HardDisk); + mrc = pMedium->createMediumLockList(fIsVitalImage /* fFailIfInaccessible */, !fIsReadOnlyImage /* fMediumLockWrite */, NULL, diff --git a/src/VBox/Main/MediumImpl.cpp b/src/VBox/Main/MediumImpl.cpp index 880377b58..13cab871c 100644 --- a/src/VBox/Main/MediumImpl.cpp +++ b/src/VBox/Main/MediumImpl.cpp @@ -44,7 +44,7 @@ // //////////////////////////////////////////////////////////////////////////////// -/** Describes how a machine refers to this image. */ +/** Describes how a machine refers to this medium. */ struct BackRef { /** Equality predicate for stdc++. */ @@ -83,6 +83,7 @@ struct Medium::Data Data() : pVirtualBox(NULL), state(MediumState_NotCreated), + variant(MediumVariant_Standard), size(0), readers(0), preLockState(MediumState_NotCreated), @@ -107,6 +108,7 @@ struct Medium::Data const Guid id; Utf8Str strDescription; MediumState_T state; + MediumVariant_T variant; Utf8Str strLocation; Utf8Str strLocationFull; uint64_t size; @@ -789,7 +791,7 @@ HRESULT Medium::init(VirtualBox *aVirtualBox, /** * Initializes the medium object by opening the storage unit at the specified - * location. The enOpenMode parameter defines whether the image will be opened + * location. The enOpenMode parameter defines whether the medium will be opened * read/write or read-only. * * Note that the UUID, format and the parent of this medium will be @@ -799,10 +801,10 @@ HRESULT Medium::init(VirtualBox *aVirtualBox, * * @param aVirtualBox VirtualBox object. * @param aLocation Storage unit location. - * @param enOpenMode Whether to open the image read/write or read-only. + * @param enOpenMode Whether to open the medium read/write or read-only. * @param aDeviceType Device type of medium. - * @param aSetImageId Whether to set the image UUID or not. - * @param aImageId New image UUID if @aSetId is true. Empty string means + * @param aSetImageId Whether to set the medium UUID or not. + * @param aImageId New medium UUID if @aSetId is true. Empty string means * create a new UUID, and a zero UUID is invalid. * @param aSetParentId Whether to set the parent UUID or not. * @param aParentId New parent UUID if @aSetParentId is true. Empty string @@ -883,7 +885,7 @@ HRESULT Medium::init(VirtualBox *aVirtualBox, /** * Initializes the medium object by loading its data from the given settings - * node. In this mode, the image will always be opened read/write. + * node. In this mode, the medium will always be opened read/write. * * @param aVirtualBox VirtualBox object. * @param aParent Parent medium disk or NULL for a root (base) medium. @@ -914,7 +916,7 @@ HRESULT Medium::init(VirtualBox *aVirtualBox, * unconditionally unregister on failure */ if (aParent) { - // differencing image: add to parent + // differencing medium: add to parent AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); m->pParent = aParent; aParent->m->llChildren.push_back(this); @@ -951,9 +953,8 @@ HRESULT Medium::init(VirtualBox *aVirtualBox, if (FAILED(rc)) return rc; } - /* optional, only for diffs, default is false; - * we can only auto-reset diff images, so they - * must not have a parent */ + /* optional, only for diffs, default is false; we can only auto-reset + * diff media so they must have a parent */ if (aParent != NULL) m->autoReset = data.fAutoReset; else @@ -1093,7 +1094,7 @@ HRESULT Medium::init(VirtualBox *aVirtualBox, * * Called either from FinalRelease() or by the parent when it gets destroyed. * - * @note All children of this hard disk get uninitialized by calling their + * @note All children of this medium get uninitialized by calling their * uninit() methods. * * @note Caller must hold the tree lock of the medium tree this medium is on. @@ -1150,7 +1151,7 @@ void Medium::uninit() * Internal helper that removes "this" from the list of children of its * parent. Used in uninit() and other places when reparenting is necessary. * - * The caller must hold the hard disk tree lock! + * The caller must hold the medium tree lock! */ void Medium::deparent() { @@ -1173,7 +1174,7 @@ void Medium::deparent() * Internal helper that removes "this" from the list of children of its * parent. Used in uninit() and other places when reparenting is necessary. * - * The caller must hold the hard disk tree lock! + * The caller must hold the medium tree lock! */ void Medium::setParent(const ComObjPtr<Medium> &pParent) { @@ -1246,7 +1247,6 @@ STDMETHODIMP Medium::COMGETTER(State)(MediumState_T *aState) return S_OK; } - STDMETHODIMP Medium::COMGETTER(Location)(BSTR *aLocation) { CheckComArgOutPointerValid(aLocation); @@ -1395,25 +1395,22 @@ STDMETHODIMP Medium::COMSETTER(Type)(MediumType_T aType) return setStateError(); } - /** @todo implement this case later */ - CheckComArgExpr(aType, aType != MediumType_Shareable); - if (m->type == aType) { /* Nothing to do */ return S_OK; } - /* cannot change the type of a differencing hard disk */ + /* cannot change the type of a differencing medium */ if (m->pParent) return setError(E_FAIL, - tr("Cannot change the type of hard disk '%s' because it is a differencing hard disk"), + tr("Cannot change the type of medium '%s' because it is a differencing medium"), m->strLocationFull.raw()); - /* cannot change the type of a hard disk being in use by more than one VM */ + /* cannot change the type of a medium being in use by more than one VM */ if (m->backRefs.size() > 1) return setError(E_FAIL, - tr("Cannot change the type of hard disk '%s' because it is attached to %d virtual machines"), + tr("Cannot change the type of medium '%s' because it is attached to %d virtual machines"), m->strLocationFull.raw(), m->backRefs.size()); switch (aType) @@ -1432,8 +1429,17 @@ STDMETHODIMP Medium::COMSETTER(Type)(MediumType_T aType) /* cannot change to writethrough or shareable if there are children */ if (getChildren().size() != 0) return setError(E_FAIL, - tr("Cannot change type for hard disk '%s' since it has %d child hard disk(s)"), + tr("Cannot change type for medium '%s' since it has %d child media"), m->strLocationFull.raw(), getChildren().size()); + if (aType == MediumType_Shareable) + { + MediumVariant_T variant = getVariant(); + if (!(variant & MediumVariant_Fixed)) + return setError(E_FAIL, + tr("Cannot change type for medium '%s' to 'Shareable' since it is a dynamic medium storage unit"), + m->strLocationFull.raw()); + + } break; } default: @@ -1528,8 +1534,8 @@ STDMETHODIMP Medium::COMGETTER(LogicalSize)(ULONG64 *aLogicalSize) } /* We assume that some backend may decide to return a meaningless value in - * response to VDGetSize() for differencing hard disks and therefore - * always ask the base hard disk ourselves. */ + * response to VDGetSize() for differencing media and therefore always + * ask the base medium ourselves. */ /* base() will do callers/locking */ @@ -1545,7 +1551,7 @@ STDMETHODIMP Medium::COMGETTER(AutoReset)(BOOL *aAutoReset) AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); - if (m->pParent) + if (m->pParent.isNull()) *aAutoReset = FALSE; else *aAutoReset = m->autoReset; @@ -1562,7 +1568,7 @@ STDMETHODIMP Medium::COMSETTER(AutoReset)(BOOL aAutoReset) if (m->pParent.isNull()) return setError(VBOX_E_NOT_SUPPORTED, - tr("Hard disk '%s' is not differencing"), + tr("Medium '%s' is not differencing"), m->strLocationFull.raw()); if (m->autoReset != !!aAutoReset) @@ -2119,12 +2125,12 @@ STDMETHODIMP Medium::CreateBaseStorage(ULONG64 aLogicalSize, if ( !(aVariant & MediumVariant_Fixed) && !(m->formatObj->capabilities() & MediumFormatCapabilities_CreateDynamic)) throw setError(VBOX_E_NOT_SUPPORTED, - tr("Hard disk format '%s' does not support dynamic storage creation"), + tr("Medium format '%s' does not support dynamic storage creation"), m->strFormat.raw()); if ( (aVariant & MediumVariant_Fixed) && !(m->formatObj->capabilities() & MediumFormatCapabilities_CreateDynamic)) throw setError(VBOX_E_NOT_SUPPORTED, - tr("Hard disk format '%s' does not support fixed storage creation"), + tr("Medium format '%s' does not support fixed storage creation"), m->strFormat.raw()); if (m->state != MediumState_NotCreated) @@ -2134,8 +2140,8 @@ STDMETHODIMP Medium::CreateBaseStorage(ULONG64 aLogicalSize, rc = pProgress->init(m->pVirtualBox, static_cast<IMedium*>(this), (aVariant & MediumVariant_Fixed) - ? BstrFmt(tr("Creating fixed hard disk storage unit '%s'"), m->strLocationFull.raw()) - : BstrFmt(tr("Creating dynamic hard disk storage unit '%s'"), m->strLocationFull.raw()), + ? BstrFmt(tr("Creating fixed medium storage unit '%s'"), m->strLocationFull.raw()) + : BstrFmt(tr("Creating dynamic medium storage unit '%s'"), m->strLocationFull.raw()), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; @@ -2206,7 +2212,11 @@ STDMETHODIMP Medium::CreateDiffStorage(IMedium *aTarget, if (m->type == MediumType_Writethrough) return setError(E_FAIL, - tr("Hard disk '%s' is Writethrough"), + tr("Medium type of '%s' is Writethrough"), + m->strLocationFull.raw()); + else if (m->type == MediumType_Shareable) + return setError(E_FAIL, + tr("Medium type of '%s' is Shareable"), m->strLocationFull.raw()); /* Apply the normal locking logic to the entire chain. */ @@ -2293,7 +2303,7 @@ STDMETHODIMP Medium::CloneTo(IMedium *aTarget, { // locking: we need the tree lock first because we access parent pointers AutoReadLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); - // and we need to write-lock the images involved + // and we need to write-lock the media involved AutoMultiWriteLock3 alock(this, pTarget, pParent COMMA_LOCKVAL_SRC_POS); if ( pTarget->m->state != MediumState_NotCreated @@ -2347,7 +2357,7 @@ STDMETHODIMP Medium::CloneTo(IMedium *aTarget, pProgress.createObject(); rc = pProgress->init(m->pVirtualBox, static_cast <IMedium *>(this), - BstrFmt(tr("Creating clone hard disk '%s'"), pTarget->m->strLocationFull.raw()), + BstrFmt(tr("Creating clone medium '%s'"), pTarget->m->strLocationFull.raw()), TRUE /* aCancelable */); if (FAILED(rc)) { @@ -2426,7 +2436,7 @@ STDMETHODIMP Medium::Compact(IProgress **aProgress) pProgress.createObject(); rc = pProgress->init(m->pVirtualBox, static_cast <IMedium *>(this), - BstrFmt(tr("Compacting hard disk '%s'"), m->strLocationFull.raw()), + BstrFmt(tr("Compacting medium '%s'"), m->strLocationFull.raw()), TRUE /* aCancelable */); if (FAILED(rc)) { @@ -2490,7 +2500,7 @@ STDMETHODIMP Medium::Reset(IProgress **aProgress) if (m->pParent.isNull()) throw setError(VBOX_E_NOT_SUPPORTED, - tr("Hard disk '%s' is not differencing"), + tr("Medium type of '%s' is not differencing"), m->strLocationFull.raw()); rc = canClose(); @@ -2521,7 +2531,7 @@ STDMETHODIMP Medium::Reset(IProgress **aProgress) pProgress.createObject(); rc = pProgress->init(m->pVirtualBox, static_cast<IMedium*>(this), - BstrFmt(tr("Resetting differencing hard disk '%s'"), m->strLocationFull.raw()), + BstrFmt(tr("Resetting differencing medium '%s'"), m->strLocationFull.raw()), FALSE /* aCancelable */); if (FAILED(rc)) throw rc; @@ -2593,7 +2603,7 @@ const Guid& Medium::getId() const } /** - * Internal method to return the medium's GUID. Must have caller + locking! + * Internal method to return the medium's state. Must have caller + locking! * @return */ MediumState_T Medium::getState() const @@ -2602,6 +2612,15 @@ MediumState_T Medium::getState() const } /** + * Internal method to return the medium's variant. Must have caller + locking! + * @return + */ +MediumVariant_T Medium::getVariant() const +{ + return m->variant; +} + +/** * Internal method to return the medium's location. Must have caller + locking! * @return */ @@ -2648,7 +2667,7 @@ uint64_t Medium::getSize() const /** * Adds the given machine and optionally the snapshot to the list of the objects - * this image is attached to. + * this medium is attached to. * * @param aMachineId Machine ID. * @param aSnapshotId Snapshot ID; when non-empty, adds a snapshot attachment. @@ -2679,7 +2698,7 @@ HRESULT Medium::attachTo(const Guid &aMachineId, if (m->numCreateDiffTasks > 0) return setError(E_FAIL, - tr("Cannot attach hard disk '%s' {%RTuuid}: %u differencing child hard disk(s) are being created"), + tr("Cannot attach medium '%s' {%RTuuid}: %u differencing child media are being created"), m->strLocationFull.raw(), m->id.raw(), m->numCreateDiffTasks); @@ -2740,7 +2759,7 @@ HRESULT Medium::attachTo(const Guid &aMachineId, /** * Removes the given machine and optionally the snapshot from the list of the - * objects this image is attached to. + * objects this medium is attached to. * * @param aMachineId Machine ID. * @param aSnapshotId Snapshot ID; when non-empty, removes the snapshot @@ -2878,7 +2897,7 @@ HRESULT Medium::updatePath(const char *aOldPath, const char *aNewPath) /** * Checks if the given change of \a aOldPath to \a aNewPath affects the location - * of this hard disk or any its child and updates the paths if necessary to + * of this medium or any its child and updates the paths if necessary to * reflect the new location. * * @param aOldPath Old path (full). @@ -2911,13 +2930,13 @@ void Medium::updatePaths(const char *aOldPath, const char *aNewPath) } /** - * Returns the base hard disk of the hard disk chain this hard disk is part of. + * Returns the base medium of the media chain this medium is part of. * - * The base hard disk is found by walking up the parent-child relationship axis. - * If the hard disk doesn't have a parent (i.e. it's a base hard disk), it + * The base medium is found by walking up the parent-child relationship axis. + * If the medium doesn't have a parent (i.e. it's a base medium), it * returns itself in response to this method. * - * @param aLevel Where to store the number of ancestors of this hard disk + * @param aLevel Where to store the number of ancestors of this medium * (zero for the base), may be @c NULL. * * @note Locks medium tree for reading. @@ -2958,8 +2977,8 @@ ComObjPtr<Medium> Medium::getBase(uint32_t *aLevel /*= NULL*/) } /** - * Returns @c true if this hard disk cannot be modified because it has - * dependants (children) or is part of the snapshot. Related to the hard disk + * Returns @c true if this medium cannot be modified because it has + * dependants (children) or is part of the snapshot. Related to the medium * type and posterity, not to the current media state. * * @note Locks this object and medium tree for reading. @@ -3001,8 +3020,8 @@ bool Medium::isReadOnly() } /** - * Saves hard disk data by appending a new <HardDisk> child node to the given - * parent node which can be either <HardDisks> or <HardDisk>. + * Saves medium data by appending a new child node to the given + * parent XML settings node. * * @param data Settings struct to be updated. * @@ -3046,7 +3065,7 @@ HRESULT Medium::saveSettings(settings::Medium &data) } } - /* only for base hard disks */ + /* only for base media */ if (m->pParent.isNull()) data.hdType = m->type; @@ -3065,7 +3084,7 @@ HRESULT Medium::saveSettings(settings::Medium &data) } /** - * Compares the location of this hard disk to the given location. + * Compares the location of this medium to the given location. * * The comparison takes the location details into account. For example, if the * location is a file in the host's filesystem, a case insensitive comparison @@ -3104,7 +3123,7 @@ HRESULT Medium::compareLocationTo(const char *aLocation, int &aResult) int vrc = m->pVirtualBox->calculateFullPath(location, location); if (RT_FAILURE(vrc)) return setError(E_FAIL, - tr("Invalid hard disk storage file location '%s' (%Rrc)"), + tr("Invalid medium storage file location '%s' (%Rrc)"), location.raw(), vrc); @@ -3123,7 +3142,7 @@ HRESULT Medium::compareLocationTo(const char *aLocation, int &aResult) * * @param fFailIfInaccessible If true, this fails with an error if a medium is inaccessible. If false, * inaccessible media are silently skipped and not locked (i.e. their state remains "Inaccessible"); - * this is necessary for a VM's removable images on VM startup for which we do not want to fail. + * this is necessary for a VM's removable media VM startup for which we do not want to fail. * @param fMediumLockWrite Whether to associate a write lock with this medium. * @param pToBeParent Medium which will become the parent of this medium. * @param mediumLockList Where to store the resulting list. @@ -3160,7 +3179,7 @@ HRESULT Medium::createMediumLockList(bool fFailIfInaccessible, /* Accessibility check must be first, otherwise locking interferes * with getting the medium state. Lock lists are not created for - * fun, and thus getting the image status is no luxury. */ + * fun, and thus getting the medium status is no luxury. */ MediumState_T mediumState = pMedium->getState(); if (mediumState == MediumState_Inaccessible) { @@ -3169,7 +3188,7 @@ HRESULT Medium::createMediumLockList(bool fFailIfInaccessible, if (mediumState == MediumState_Inaccessible) { - // ignore inaccessible ISO images and silently return S_OK, + // ignore inaccessible ISO media and silently return S_OK, // otherwise VM startup (esp. restore) may fail without good reason if (!fFailIfInaccessible) return S_OK; @@ -3208,7 +3227,7 @@ HRESULT Medium::createMediumLockList(bool fFailIfInaccessible, } /** - * Returns a preferred format for differencing hard disks. + * Returns a preferred format for differencing media. */ Bstr Medium::preferredDiffFormat() { @@ -3257,7 +3276,7 @@ Utf8Str Medium::getName() /** * Sets the value of m->strLocation and calculates the value of m->strLocationFull. * - * Treats non-FS-path locations specially, and prepends the default hard disk + * Treats non-FS-path locations specially, and prepends the default medium * folder if the given location string does not contain any path information * at all. * @@ -3431,7 +3450,7 @@ HRESULT Medium::setLocation(const Utf8Str &aLocation, const Utf8Str &aFormat) } /** - * Queries information from the image file. + * Queries information from the medium. * * As a result of this call, the accessibility state and data members such as * size and description will be updated with the current information. @@ -3478,7 +3497,7 @@ HRESULT Medium::queryInfo() /* are we dealing with a new medium constructed using the existing * location? */ bool isImport = m->id.isEmpty(); - unsigned flags = VD_OPEN_FLAGS_INFO; + unsigned uOpenFlags = VD_OPEN_FLAGS_INFO; /* Note that we don't use VD_OPEN_FLAGS_READONLY when opening new * media because that would prevent necessary modifications @@ -3488,10 +3507,14 @@ HRESULT Medium::queryInfo() if ( (m->hddOpenMode == OpenReadOnly) || !isImport ) - flags |= VD_OPEN_FLAGS_READONLY; + uOpenFlags |= VD_OPEN_FLAGS_READONLY; + + /* Open shareable medium with the appropriate flags */ + if (m->type == MediumType_Shareable) + uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE; /* Lock the medium, which makes the behavior much more consistent */ - if (flags & VD_OPEN_FLAGS_READONLY) + if (uOpenFlags & (VD_OPEN_FLAGS_READONLY || VD_OPEN_FLAGS_SHAREABLE)) rc = LockRead(NULL); else rc = LockWrite(NULL); @@ -3532,13 +3555,13 @@ HRESULT Medium::queryInfo() try { - /** @todo This kind of opening of images is assuming that diff - * images can be opened as base images. Should be documented if + /** @todo This kind of opening of media is assuming that diff + * media can be opened as base media. Should be documented that * it must work for all medium format backends. */ vrc = VDOpen(hdd, format.c_str(), location.c_str(), - flags, + uOpenFlags, m->vdDiskIfaces); if (RT_FAILURE(vrc)) { @@ -3611,11 +3634,13 @@ HRESULT Medium::queryInfo() } } - /* check the type */ + /* get the medium variant */ unsigned uImageFlags; vrc = VDGetImageFlags(hdd, 0, &uImageFlags); ComAssertRCThrow(vrc, E_FAIL); + m->variant = (MediumVariant_T)uImageFlags; + /* check/get the parent uuid and update corresponding state */ if (uImageFlags & VD_IMAGE_FLAGS_DIFF) { RTUUID parentId; @@ -3625,21 +3650,21 @@ HRESULT Medium::queryInfo() if (isImport) { /* the parent must be known to us. Note that we freely - * call locking methods of mVirtualBox and parent from the - * write lock (breaking the {parent,child} lock order) - * because there may be no concurrent access to the just - * opened hard disk on ther threads yet (and init() will - * fail if this method reporst MediumState_Inaccessible) */ + * call locking methods of mVirtualBox and parent, as all + * relevant locks must be already held. There may be no + * concurrent access to the just opened medium on other + * threads yet (and init() will fail if this method reports + * MediumState_Inaccessible) */ Guid id = parentId; ComObjPtr<Medium> pParent; rc = m->pVirtualBox->findHardDisk(&id, NULL, - false /* aSetError */, - &pParent); + false /* aSetError */, + &pParent); if (FAILED(rc)) { lastAccessError = Utf8StrFmt( - tr("Parent hard disk with UUID {%RTuuid} of the hard disk '%s' is not found in the media registry ('%s')"), + tr("Parent medium with UUID {%RTuuid} of the medium '%s' is not found in the media registry ('%s')"), &parentId, location.c_str(), m->pVirtualBox->settingsFilePath().c_str()); throw S_OK; @@ -3664,7 +3689,7 @@ HRESULT Medium::queryInfo() if (m->pParent.isNull()) { lastAccessError = Utf8StrFmt( - tr("Hard disk '%s' is differencing but it is not associated with any parent hard disk in the media registry ('%s')"), + tr("Medium type of '%s' is differencing but it is not associated with any parent medium in the media registry ('%s')"), location.c_str(), m->pVirtualBox->settingsFilePath().c_str()); throw S_OK; @@ -3675,7 +3700,7 @@ HRESULT Medium::queryInfo() && m->pParent->getId() != parentId) { lastAccessError = Utf8StrFmt( - tr("Parent UUID {%RTuuid} of the hard disk '%s' does not match UUID {%RTuuid} of its parent hard disk stored in the media registry ('%s')"), + tr("Parent UUID {%RTuuid} of the medium '%s' does not match UUID {%RTuuid} of its parent medium stored in the media registry ('%s')"), &parentId, location.c_str(), m->pParent->getId().raw(), m->pVirtualBox->settingsFilePath().c_str()); @@ -3735,7 +3760,7 @@ HRESULT Medium::queryInfo() else m->preLockState = MediumState_Inaccessible; - if (flags & VD_OPEN_FLAGS_READONLY) + if (uOpenFlags & (VD_OPEN_FLAGS_READONLY || VD_OPEN_FLAGS_SHAREABLE)) rc = UnlockRead(NULL); else rc = UnlockWrite(NULL); @@ -3821,7 +3846,7 @@ HRESULT Medium::setStateError() } /** - * Deletes the hard disk storage unit. + * Deletes the medium storage unit. * * If @a aProgress is not NULL but the object it points to is @c null then a new * progress object will be created and assigned to @a *aProgress on success, @@ -3870,16 +3895,16 @@ HRESULT Medium::deleteStorage(ComObjPtr<Progress> *aProgress, if ( !(m->formatObj->capabilities() & ( MediumFormatCapabilities_CreateDynamic | MediumFormatCapabilities_CreateFixed))) throw setError(VBOX_E_NOT_SUPPORTED, - tr("Hard disk format '%s' does not support storage deletion"), + tr("Medium format '%s' does not support storage deletion"), m->strFormat.raw()); /* Note that we are fine with Inaccessible state too: a) for symmetry * with create calls and b) because it doesn't really harm to try, if * it is really inaccessible, the delete operation will fail anyway. * Accepting Inaccessible state is especially important because all - * registered hard disks are initially Inaccessible upon VBoxSVC - * startup until COMGETTER(RefreshState) is called. Accept Deleting - * state because some callers need to put the image in this state early + * registered media are initially Inaccessible upon VBoxSVC startup + * until COMGETTER(RefreshState) is called. Accept Deleting state + * because some callers need to put the medium in this state early * to prevent races. */ switch (m->state) { @@ -3907,7 +3932,7 @@ HRESULT Medium::deleteStorage(ComObjPtr<Progress> *aProgress, dumpBackRefs(); #endif throw setError(VBOX_E_OBJECT_IN_USE, - tr("Cannot delete storage: hard disk '%s' is still attached to the following %d virtual machine(s): %s"), + tr("Cannot delete storage: medium '%s' is still attached to the following %d virtual machine(s): %s"), m->strLocationFull.c_str(), m->backRefs.size(), strMachines.c_str()); @@ -3946,7 +3971,7 @@ HRESULT Medium::deleteStorage(ComObjPtr<Progress> *aProgress, getLocationFull().raw()); } - /* try to remove from the list of known hard disks before performing + /* try to remove from the list of known media before performing * actual deletion (we favor the consistency of the media registry * which would have been broken if unregisterWithVirtualBox() failed * after we successfully deleted the storage) */ @@ -3967,7 +3992,7 @@ HRESULT Medium::deleteStorage(ComObjPtr<Progress> *aProgress, pProgress.createObject(); rc = pProgress->init(m->pVirtualBox, static_cast<IMedium*>(this), - BstrFmt(tr("Deleting hard disk storage unit '%s'"), m->strLocationFull.raw()), + BstrFmt(tr("Deleting medium storage unit '%s'"), m->strLocationFull.raw()), FALSE /* aCancelable */); if (FAILED(rc)) throw rc; @@ -4084,8 +4109,8 @@ HRESULT Medium::unmarkLockedForDeletion() } /** - * Creates a new differencing storage unit using the given target hard disk's - * format and the location. Note that @c aTarget must be NotCreated. + * Creates a new differencing storage unit using the format of the given target + * medium and the location. Note that @c aTarget must be NotCreated. * * The @a aMediumLockList parameter contains the associated medium lock list, * which must be in locked state. If @a aWait is @c true then the caller is @@ -4102,8 +4127,8 @@ HRESULT Medium::unmarkLockedForDeletion() * caller until the operation is completed. Note that @a aProgress cannot be * NULL when @a aWait is @c false (this method will assert in this case). * - * @param aTarget Target hard disk. - * @param aVariant Precise image variant to create. + * @param aTarget Target medium. + * @param aVariant Precise medium variant to create. * @param aMediumLockList List of media which should be locked. * @param aProgress Where to find/store a Progress object to track * operation completion. @@ -4145,13 +4170,14 @@ HRESULT Medium::createDiffStorage(ComObjPtr<Medium> &aTarget, { AutoMultiWriteLock2 alock(this, aTarget COMMA_LOCKVAL_SRC_POS); - ComAssertThrow(m->type != MediumType_Writethrough, E_FAIL); + ComAssertThrow( m->type != MediumType_Writethrough + && m->type != MediumType_Shareable, E_FAIL); ComAssertThrow(m->state == MediumState_LockedRead, E_FAIL); if (aTarget->m->state != MediumState_NotCreated) throw aTarget->setStateError(); - /* Check that the hard disk is not attached to the current state of + /* Check that the medium is not attached to the current state of * any VM referring to it. */ for (BackRefList::const_iterator it = m->backRefs.begin(); it != m->backRefs.end(); @@ -4159,8 +4185,8 @@ HRESULT Medium::createDiffStorage(ComObjPtr<Medium> &aTarget, { if (it->fInCurState) { - /* Note: when a VM snapshot is being taken, all normal hard - * disks attached to the VM in the current state will be, as an + /* Note: when a VM snapshot is being taken, all normal media + * attached to the VM in the current state will be, as an * exception, also associated with the snapshot which is about * to create (see SnapshotMachine::init()) before deassociating * them from the current state (which takes place only on @@ -4169,7 +4195,7 @@ HRESULT Medium::createDiffStorage(ComObjPtr<Medium> &aTarget, * used to filter out this legal situation. */ if (it->llSnapshotIds.size() == 0) throw setError(VBOX_E_INVALID_OBJECT_STATE, - tr("Hard disk '%s' is attached to a virtual machine with UUID {%RTuuid}. No differencing hard disks based on it may be created until it is detached"), + tr("Medium '%s' is attached to a virtual machine with UUID {%RTuuid}. No differencing media based on it may be created until it is detached"), m->strLocationFull.raw(), it->machineId.raw()); Assert(it->llSnapshotIds.size() == 1); @@ -4187,7 +4213,7 @@ HRESULT Medium::createDiffStorage(ComObjPtr<Medium> &aTarget, pProgress.createObject(); rc = pProgress->init(m->pVirtualBox, static_cast<IMedium*>(this), - BstrFmt(tr("Creating differencing hard disk storage unit '%s'"), aTarget->m->strLocationFull.raw()), + BstrFmt(tr("Creating differencing medium storage unit '%s'"), aTarget->m->strLocationFull.raw()), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; @@ -4228,17 +4254,17 @@ HRESULT Medium::createDiffStorage(ComObjPtr<Medium> &aTarget, } /** - * Prepares this (source) hard disk, target hard disk and all intermediate hard - * disks for the merge operation. + * Prepares this (source) medium, target medium and all intermediate media + * for the merge operation. * * This method is to be called prior to calling the #mergeTo() to perform - * necessary consistency checks and place involved hard disks to appropriate + * necessary consistency checks and place involved media to appropriate * states. If #mergeTo() is not called or fails, the state modifications * performed by this method must be undone by #cancelMergeTo(). * * See #mergeTo() for more information about merging. * - * @param pTarget Target hard disk. + * @param pTarget Target medium. * @param aMachineId Allowed machine attachment. NULL means do not check. * @param aSnapshotId Allowed snapshot attachment. NULL or empty UUID means * do not check. @@ -4252,7 +4278,7 @@ HRESULT Medium::createDiffStorage(ComObjPtr<Medium> &aTarget, * @param aMediumLockList Medium locking information (out). * * @note Locks medium tree for reading. Locks this object, aTarget and all - * intermediate hard disks for writing. + * intermediate media for writing. */ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, const Guid *aMachineId, @@ -4307,7 +4333,7 @@ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); throw setError(E_FAIL, - tr("Hard disks '%s' and '%s' are unrelated"), + tr("Media '%s' and '%s' are unrelated"), m->strLocationFull.raw(), tgtLoc.raw()); } } @@ -4357,7 +4383,7 @@ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, m->strLocationFull.raw(), getChildren().size()); } /* One backreference is only allowed if the machine ID is not empty - * and it matches the machine the image is attached to (including + * and it matches the machine the medium is attached to (including * the snapshot ID if not empty). */ if ( m->backRefs.size() != 0 && ( !aMachineId @@ -4521,11 +4547,11 @@ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, } /** - * Merges this hard disk to the specified hard disk which must be either its + * Merges this medium to the specified medium which must be either its * direct ancestor or descendant. * - * Given this hard disk is SOURCE and the specified hard disk is TARGET, we will - * get two varians of the merge operation: + * Given this medium is SOURCE and the specified medium is TARGET, we will + * get two variants of the merge operation: * * forward merge * -------------------------> @@ -4538,16 +4564,16 @@ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, * TARGET <- Intermediate <- SOURCE <- [Extra] * LockWr Del Del LockWr * - * Each diagram shows the involved hard disks on the hard disk chain where - * SOURCE and TARGET belong. Under each hard disk there is a state value which - * the hard disk must have at a time of the mergeTo() call. + * Each diagram shows the involved media on the media chain where + * SOURCE and TARGET belong. Under each medium there is a state value which + * the medium must have at a time of the mergeTo() call. * - * The hard disks in the square braces may be absent (e.g. when the forward - * operation takes place and SOURCE is the base hard disk, or when the backward + * The media in the square braces may be absent (e.g. when the forward + * operation takes place and SOURCE is the base medium, or when the backward * merge operation takes place and TARGET is the last child in the chain) but if * they present they are involved too as shown. * - * Nor the source hard disk neither intermediate hard disks may be attached to + * Neither the source medium nor intermediate media may be attached to * any VM directly or in the snapshot, otherwise this method will assert. * * The #prepareMergeTo() method must be called prior to this method to place all @@ -4555,22 +4581,22 @@ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, * * If @a aWait is @c true then this method will perform the operation on the * calling thread and will not return to the caller until the operation is - * completed. When this method succeeds, all intermediate hard disk objects in - * the chain will be uninitialized, the state of the target hard disk (and all - * involved extra hard disks) will be restored. @a aMediumLockList will not be + * completed. When this method succeeds, all intermediate medium objects in + * the chain will be uninitialized, the state of the target medium (and all + * involved extra media) will be restored. @a aMediumLockList will not be * deleted, whether the operation is successful or not. The caller has to do - * this if appropriate. Note that this (source) hard disk is not uninitialized + * this if appropriate. Note that this (source) medium is not uninitialized * because of possible AutoCaller instances held by the caller of this method * on the current thread. It's therefore the responsibility of the caller to * call Medium::uninit() after releasing all callers. * * If @a aWait is @c false then this method will create a thread to perform the * operation asynchronously and will return immediately. If the operation - * succeeds, the thread will uninitialize the source hard disk object and all - * intermediate hard disk objects in the chain, reset the state of the target - * hard disk (and all involved extra hard disks) and delete @a aMediumLockList. + * succeeds, the thread will uninitialize the source medium object and all + * intermediate medium objects in the chain, reset the state of the target + * medium (and all involved extra media) and delete @a aMediumLockList. * If the operation fails, the thread will only reset the states of all - * involved hard disks and delete @a aMediumLockList. + * involved media and delete @a aMediumLockList. * * When this method fails (regardless of the @a aWait mode), it is a caller's * responsiblity to undo state changes and delete @a aMediumLockList using @@ -4582,7 +4608,7 @@ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, * progress object is created/used at all. Note that @a aProgress cannot be * NULL when @a aWait is @c false (this method will assert in this case). * - * @param pTarget Target hard disk. + * @param pTarget Target medium. * @param fMergeForward Merge direction. * @param pParentForTarget New parent for target medium after merge. * @param aChildrenToReparent List of children of the source which will have @@ -4597,7 +4623,7 @@ HRESULT Medium::prepareMergeTo(const ComObjPtr<Medium> &pTarget, * This only works in "wait" mode; otherwise saveSettings gets called automatically by the thread that was created, * and this parameter is ignored. * - * @note Locks the tree lock for writing. Locks the hard disks from the chain + * @note Locks the tree lock for writing. Locks the media from the chain * for writing. */ HRESULT Medium::mergeTo(const ComObjPtr<Medium> &pTarget, @@ -4645,7 +4671,7 @@ HRESULT Medium::mergeTo(const ComObjPtr<Medium> &pTarget, pProgress.createObject(); rc = pProgress->init(m->pVirtualBox, static_cast<IMedium*>(this), - BstrFmt(tr("Merging hard disk '%s' to '%s'"), + BstrFmt(tr("Merging medium '%s' to '%s'"), getName().raw(), tgtName.raw()), TRUE /* aCancelable */); @@ -4691,7 +4717,7 @@ HRESULT Medium::mergeTo(const ComObjPtr<Medium> &pTarget, * to be reparented to the target after merge. * @param aMediumLockList Medium locking information. * - * @note Locks the hard disks from the chain for writing. + * @note Locks the media from the chain for writing. */ void Medium::cancelMergeTo(const MediaList &aChildrenToReparent, MediumLockList *aMediumLockList) @@ -4756,7 +4782,7 @@ HRESULT Medium::setFormat(CBSTR aFormat) = m->pVirtualBox->systemProperties()->mediumFormat(aFormat); if (m->formatObj.isNull()) return setError(E_INVALIDARG, - tr("Invalid hard disk storage format '%ls'"), + tr("Invalid medium storage format '%ls'"), aFormat); /* reference the format permanently to prevent its unexpected @@ -4795,7 +4821,7 @@ HRESULT Medium::canClose() if (getChildren().size() != 0) return setError(E_FAIL, - tr("Cannot close medium '%s' because it has %d child hard disk(s)"), + tr("Cannot close medium '%s' because it has %d child media"), m->strLocationFull.raw(), getChildren().size()); return S_OK; @@ -5053,7 +5079,7 @@ HRESULT Medium::fixParentUuidOfChildren(const MediaList &childrenToReparent) const ComObjPtr<Medium> &pMedium = mediumLock.GetMedium(); AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); - // open the image + // open the medium vrc = VDOpen(hdd, pMedium->m->strFormat.c_str(), pMedium->m->strLocationFull.c_str(), @@ -5151,6 +5177,7 @@ HRESULT Medium::taskCreateBaseHandler(Medium::CreateBaseTask &task) /* these parameters we need after creation */ uint64_t size = 0, logicalSize = 0; + MediumVariant_T variant = MediumVariant_Standard; bool fGenerateUuid = false; try @@ -5205,11 +5232,15 @@ HRESULT Medium::taskCreateBaseHandler(Medium::CreateBaseTask &task) task.mVDOperationIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not create the hard disk storage unit '%s'%s"), + tr("Could not create the medium storage unit '%s'%s"), location.raw(), vdError(vrc).raw()); size = VDGetFileSize(hdd, 0); logicalSize = VDGetSize(hdd, 0) / _1M; + unsigned uImageFlags; + vrc = VDGetImageFlags(hdd, 0, &uImageFlags); + if (RT_SUCCESS(vrc)) + variant = (MediumVariant_T)uImageFlags; } catch (HRESULT aRC) { rc = aRC; } @@ -5243,6 +5274,7 @@ HRESULT Medium::taskCreateBaseHandler(Medium::CreateBaseTask &task) m->size = size; m->logicalSize = logicalSize; + m->variant = variant; } else { @@ -5278,6 +5310,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) const ComObjPtr<Medium> &pTarget = task.mTarget; uint64_t size = 0, logicalSize = 0; + MediumVariant_T variant = MediumVariant_Standard; bool fGenerateUuid = false; try @@ -5316,7 +5349,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) try { - /* Open all hard disk images in the target chain but the last. */ + /* Open all media in the target chain but the last. */ MediumLockList::Base::const_iterator targetListBegin = task.mpMediumLockList->GetBegin(); MediumLockList::Base::const_iterator targetListEnd = @@ -5330,14 +5363,14 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) AutoReadLock alock(pMedium COMMA_LOCKVAL_SRC_POS); - /* Skip over the target diff image */ + /* Skip over the target diff medium */ if (pMedium->m->state == MediumState_Creating) continue; /* sanity check */ Assert(pMedium->m->state == MediumState_LockedRead); - /* Open all images in appropriate mode. */ + /* Open all media in appropriate mode. */ vrc = VDOpen(hdd, pMedium->m->strFormat.c_str(), pMedium->m->strLocationFull.c_str(), @@ -5345,7 +5378,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) pMedium->m->vdDiskIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not open the hard disk storage unit '%s'%s"), + tr("Could not open the medium storage unit '%s'%s"), pMedium->m->strLocationFull.raw(), vdError(vrc).raw()); } @@ -5367,11 +5400,15 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) task.mVDOperationIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not create the differencing hard disk storage unit '%s'%s"), + tr("Could not create the differencing medium storage unit '%s'%s"), targetLocation.raw(), vdError(vrc).raw()); size = VDGetFileSize(hdd, VD_LAST_IMAGE); logicalSize = VDGetSize(hdd, VD_LAST_IMAGE) / _1M; + unsigned uImageFlags; + vrc = VDGetImageFlags(hdd, 0, &uImageFlags); + if (RT_SUCCESS(vrc)) + variant = (MediumVariant_T)uImageFlags; } catch (HRESULT aRC) { rc = aRC; } @@ -5391,7 +5428,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) /** @todo r=klaus neither target nor base() are locked, * potential race! */ - /* diffs for immutable hard disks are auto-reset by default */ + /* diffs for immutable media are auto-reset by default */ pTarget->m->autoReset = (getBase()->m->type == MediumType_Immutable); /* register with mVirtualBox as the last step and move to @@ -5412,6 +5449,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) pTarget->m->size = size; pTarget->m->logicalSize = logicalSize; + pTarget->m->variant = variant; } else { @@ -5445,7 +5483,7 @@ HRESULT Medium::taskCreateDiffHandler(Medium::CreateDiffTask &task) *task.m_pfNeedsSaveSettings = fNeedsSaveSettings; /* Note that in sync mode, it's the caller's responsibility to - * unlock the hard disk */ + * unlock the medium. */ return rc; } @@ -5482,7 +5520,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) unsigned uTargetIdx = VD_LAST_IMAGE; unsigned uSourceIdx = VD_LAST_IMAGE; - /* Open all hard disks in the chain. */ + /* Open all media in the chain. */ MediumLockList::Base::iterator lockListBegin = task.mpMediumLockList->GetBegin(); MediumLockList::Base::iterator lockListEnd = @@ -5505,8 +5543,8 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) /* * complex sanity (sane complexity) * - * The current image must be in the Deleting (image is merged) - * or LockedRead (parent image) state if it is not the target. + * The current medium must be in the Deleting (medium is merged) + * or LockedRead (parent medium) state if it is not the target. * If it is the target it must be in the LockedWrite state. */ Assert( ( pMedium != pTarget @@ -5516,7 +5554,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) && pMedium->m->state == MediumState_LockedWrite)); /* - * Image must be the target, in the LockedRead state + * Medium must be the target, in the LockedRead state * or Deleting state where it is not allowed to be attached * to a virtual machine. */ @@ -5528,13 +5566,15 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) Assert( pMedium != this || pMedium->m->state == MediumState_Deleting); - unsigned uOpenFlags = 0; + unsigned uOpenFlags = VD_OPEN_FLAGS_NORMAL; if ( pMedium->m->state == MediumState_LockedRead || pMedium->m->state == MediumState_Deleting) uOpenFlags = VD_OPEN_FLAGS_READONLY; + if (pMedium->m->type == MediumType_Shareable) + uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE; - /* Open the image */ + /* Open the medium */ vrc = VDOpen(hdd, pMedium->m->strFormat.c_str(), pMedium->m->strLocationFull.c_str(), @@ -5593,7 +5633,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) catch (int aVRC) { throw setError(E_FAIL, - tr("Could not merge the hard disk '%s' to '%s'%s"), + tr("Could not merge the medium '%s' to '%s'%s"), m->strLocationFull.raw(), pTarget->m->strLocationFull.raw(), vdError(aVRC).raw()); @@ -5607,7 +5647,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) if (SUCCEEDED(rc)) { - /* all hard disks but the target were successfully deleted by + /* all media but the target were successfully deleted by * VDMerge; reparent the last one and uninitialize deleted media. */ AutoWriteLock treeLock(m->pVirtualBox->getMediaTreeLockHandle() COMMA_LOCKVAL_SRC_POS); @@ -5615,7 +5655,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) if (task.mfMergeForward) { /* first, unregister the target since it may become a base - * hard disk which needs re-registration */ + * medium which needs re-registration */ rc2 = m->pVirtualBox->unregisterHardDisk(pTarget, NULL /*&fNeedsSaveSettings*/); AssertComRC(rc2); @@ -5661,7 +5701,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) } } - /* unregister and uninitialize all hard disks removed by the merge */ + /* unregister and uninitialize all media removed by the merge */ MediumLockList::Base::iterator lockListBegin = task.mpMediumLockList->GetBegin(); MediumLockList::Base::iterator lockListEnd = @@ -5675,7 +5715,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) * lock deletion below would invalidate the referenced object. */ const ComObjPtr<Medium> pMedium = mediumLock.GetMedium(); - /* The target and all images not merged (readonly) are skipped */ + /* The target and all media not merged (readonly) are skipped */ if ( pMedium == pTarget || pMedium->m->state == MediumState_LockedRead) { @@ -5687,13 +5727,13 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) NULL /*pfNeedsSaveSettings*/); AssertComRC(rc2); - /* now, uninitialize the deleted hard disk (note that + /* now, uninitialize the deleted medium (note that * due to the Deleting state, uninit() will not touch * the parent-child relationship so we need to * uninitialize each disk individually) */ - /* note that the operation initiator hard disk (which is - * normally also the source hard disk) is a special case + /* note that the operation initiator medium (which is + * normally also the source medium) is a special case * -- there is one more caller added by Task to it which * we must release. Also, if we are in sync mode, the * caller may still hold an AutoCaller instance for it @@ -5733,7 +5773,7 @@ HRESULT Medium::taskMergeHandler(Medium::MergeTask &task) { /* Here we come if either VDMerge() failed (in which case we * assume that it tried to do everything to make a further - * retry possible -- e.g. not deleted intermediate hard disks + * retry possible -- e.g. not deleted intermediate media * and so on) or VirtualBox::saveSettings() failed (where we * should have the original tree but with intermediate storage * units deleted by VDMerge()). We have to only restore states @@ -5770,6 +5810,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) bool fCreatingTarget = false; uint64_t size = 0, logicalSize = 0; + MediumVariant_T variant = MediumVariant_Standard; bool fGenerateUuid = false; try @@ -5798,7 +5839,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) try { - /* Open all hard disk images in the source chain. */ + /* Open all media in the source chain. */ MediumLockList::Base::const_iterator sourceListBegin = task.mpSourceMediumLockList->GetBegin(); MediumLockList::Base::const_iterator sourceListEnd = @@ -5814,7 +5855,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) /* sanity check */ Assert(pMedium->m->state == MediumState_LockedRead); - /** Open all images in read-only mode. */ + /** Open all media in read-only mode. */ vrc = VDOpen(hdd, pMedium->m->strFormat.c_str(), pMedium->m->strLocationFull.c_str(), @@ -5822,7 +5863,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) pMedium->m->vdDiskIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not open the hard disk storage unit '%s'%s"), + tr("Could not open the medium storage unit '%s'%s"), pMedium->m->strLocationFull.raw(), vdError(vrc).raw()); } @@ -5849,7 +5890,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) try { - /* Open all hard disk images in the target chain. */ + /* Open all media in the target chain. */ MediumLockList::Base::const_iterator targetListBegin = task.mpTargetMediumLockList->GetBegin(); MediumLockList::Base::const_iterator targetListEnd = @@ -5872,15 +5913,21 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) Assert( pMedium->m->state == MediumState_LockedRead || pMedium->m->state == MediumState_LockedWrite); - /* Open all images in appropriate mode. */ + unsigned uOpenFlags = VD_OPEN_FLAGS_NORMAL; + if (pMedium->m->state != MediumState_LockedWrite) + uOpenFlags = VD_OPEN_FLAGS_READONLY; + if (pMedium->m->type == MediumType_Shareable) + uOpenFlags |= VD_OPEN_FLAGS_SHAREABLE; + + /* Open all media in appropriate mode. */ vrc = VDOpen(targetHdd, pMedium->m->strFormat.c_str(), pMedium->m->strLocationFull.c_str(), - (pMedium->m->state == MediumState_LockedWrite) ? VD_OPEN_FLAGS_NORMAL : VD_OPEN_FLAGS_READONLY, + uOpenFlags, pMedium->m->vdDiskIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not open the hard disk storage unit '%s'%s"), + tr("Could not open the medium storage unit '%s'%s"), pMedium->m->strLocationFull.raw(), vdError(vrc).raw()); } @@ -5900,11 +5947,15 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) task.mVDOperationIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not create the clone hard disk '%s'%s"), + tr("Could not create the clone medium '%s'%s"), targetLocation.raw(), vdError(vrc).raw()); size = VDGetFileSize(targetHdd, VD_LAST_IMAGE); logicalSize = VDGetSize(targetHdd, VD_LAST_IMAGE) / _1M; + unsigned uImageFlags; + vrc = VDGetImageFlags(targetHdd, 0, &uImageFlags); + if (RT_SUCCESS(vrc)) + variant = (MediumVariant_T)uImageFlags; } catch (HRESULT aRC) { rc = aRC; } @@ -5916,7 +5967,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) } catch (HRESULT aRC) { rc = aRC; } - /* Only do the parent changes for newly created images. */ + /* Only do the parent changes for newly created media. */ if (SUCCEEDED(rc) && fCreatingTarget) { /* we set mParent & children() */ @@ -5957,6 +6008,7 @@ HRESULT Medium::taskCloneHandler(Medium::CloneTask &task) pTarget->m->size = size; pTarget->m->logicalSize = logicalSize; + pTarget->m->variant = variant; } else { @@ -6030,7 +6082,7 @@ HRESULT Medium::taskDeleteHandler(Medium::DeleteTask &task) if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not delete the hard disk storage unit '%s'%s"), + tr("Could not delete the medium storage unit '%s'%s"), location.raw(), vdError(vrc).raw()); } @@ -6067,6 +6119,7 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) HRESULT rc = S_OK; uint64_t size = 0, logicalSize = 0; + MediumVariant_T variant = MediumVariant_Standard; try { @@ -6098,7 +6151,7 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) try { - /* Open all hard disk images in the target chain but the last. */ + /* Open all media in the target chain but the last. */ MediumLockList::Base::const_iterator targetListBegin = task.mpMediumLockList->GetBegin(); MediumLockList::Base::const_iterator targetListEnd = @@ -6116,7 +6169,7 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) Assert( pMedium == this || pMedium->m->state == MediumState_LockedRead); - /* Open all images in appropriate mode. */ + /* Open all media in appropriate mode. */ vrc = VDOpen(hdd, pMedium->m->strFormat.c_str(), pMedium->m->strLocationFull.c_str(), @@ -6124,11 +6177,11 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) pMedium->m->vdDiskIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not open the hard disk storage unit '%s'%s"), + tr("Could not open the medium storage unit '%s'%s"), pMedium->m->strLocationFull.raw(), vdError(vrc).raw()); - /* Done when we hit the image which should be reset */ + /* Done when we hit the media which should be reset */ if (pMedium == this) break; } @@ -6137,7 +6190,7 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) vrc = VDClose(hdd, true /* fDelete */); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not delete the hard disk storage unit '%s'%s"), + tr("Could not delete the medium storage unit '%s'%s"), location.raw(), vdError(vrc).raw()); /* next, create it again */ @@ -6148,13 +6201,13 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) m->vdDiskIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not open the hard disk storage unit '%s'%s"), + tr("Could not open the medium storage unit '%s'%s"), parentLocation.raw(), vdError(vrc).raw()); vrc = VDCreateDiff(hdd, format.c_str(), location.c_str(), - /// @todo use the same image variant as before + /// @todo use the same medium variant as before VD_IMAGE_FLAGS_NONE, NULL, id.raw(), @@ -6164,11 +6217,15 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) task.mVDOperationIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not create the differencing hard disk storage unit '%s'%s"), + tr("Could not create the differencing medium storage unit '%s'%s"), location.raw(), vdError(vrc).raw()); size = VDGetFileSize(hdd, VD_LAST_IMAGE); logicalSize = VDGetSize(hdd, VD_LAST_IMAGE) / _1M; + unsigned uImageFlags; + vrc = VDGetImageFlags(hdd, 0, &uImageFlags); + if (RT_SUCCESS(vrc)) + variant = (MediumVariant_T)uImageFlags; } catch (HRESULT aRC) { rc = aRC; } @@ -6180,6 +6237,7 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) m->size = size; m->logicalSize = logicalSize; + m->variant = variant; if (task.isAsync()) { @@ -6189,7 +6247,7 @@ HRESULT Medium::taskResetHandler(Medium::ResetTask &task) } /* Note that in sync mode, it's the caller's responsibility to - * unlock the hard disk */ + * unlock the medium. */ return rc; } @@ -6217,7 +6275,7 @@ HRESULT Medium::taskCompactHandler(Medium::CompactTask &task) try { - /* Open all hard disk images in the chain. */ + /* Open all media in the chain. */ MediumLockList::Base::const_iterator mediumListBegin = task.mpMediumLockList->GetBegin(); MediumLockList::Base::const_iterator mediumListEnd = @@ -6239,7 +6297,9 @@ HRESULT Medium::taskCompactHandler(Medium::CompactTask &task) else Assert(pMedium->m->state == MediumState_LockedRead); - /** Open all images but last in read-only mode. */ + /* Open all media but last in read-only mode. Do not handle + * shareable media, as compaction and sharing are mutually + * exclusive. */ vrc = VDOpen(hdd, pMedium->m->strFormat.c_str(), pMedium->m->strLocationFull.c_str(), @@ -6247,7 +6307,7 @@ HRESULT Medium::taskCompactHandler(Medium::CompactTask &task) pMedium->m->vdDiskIfaces); if (RT_FAILURE(vrc)) throw setError(E_FAIL, - tr("Could not open the hard disk storage unit '%s'%s"), + tr("Could not open the medium storage unit '%s'%s"), pMedium->m->strLocationFull.raw(), vdError(vrc).raw()); } @@ -6264,15 +6324,15 @@ HRESULT Medium::taskCompactHandler(Medium::CompactTask &task) { if (vrc == VERR_NOT_SUPPORTED) throw setError(VBOX_E_NOT_SUPPORTED, - tr("Compacting is not yet supported for hard disk '%s'"), + tr("Compacting is not yet supported for medium '%s'"), location.raw()); else if (vrc == VERR_NOT_IMPLEMENTED) throw setError(E_NOTIMPL, - tr("Compacting is not implemented, hard disk '%s'"), + tr("Compacting is not implemented, medium '%s'"), location.raw()); else throw setError(E_FAIL, - tr("Could not compact hard disk '%s'%s"), + tr("Could not compact medium '%s'%s"), location.raw(), vdError(vrc).raw()); } @@ -6284,7 +6344,7 @@ HRESULT Medium::taskCompactHandler(Medium::CompactTask &task) catch (HRESULT aRC) { rc = aRC; } /* Everything is explicitly unlocked when the task exits, - * as the task destruction also destroys the image chain. */ + * as the task destruction also destroys the media chain. */ return rc; } diff --git a/src/VBox/Main/Performance.cpp b/src/VBox/Main/Performance.cpp index f2e0215fd..773ad967f 100644 --- a/src/VBox/Main/Performance.cpp +++ b/src/VBox/Main/Performance.cpp @@ -119,17 +119,43 @@ int CollectorHAL::getHostCpuMHz(ULONG *mhz) } #ifndef VBOX_COLLECTOR_TEST_CASE + +uint32_t CollectorGuestHAL::cVMsEnabled = 0; + +CollectorGuestHAL::CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL) + : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL), + mGuest(NULL), mLastTick(0), mHostHAL(hostHAL), mCpuUser(0), + mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0), + mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0) +{ + Assert(mMachine); + /* cannot use ComObjPtr<Machine> in Performance.h, do it manually */ + mMachine->AddRef(); +} + CollectorGuestHAL::~CollectorGuestHAL() { + /* cannot use ComObjPtr<Machine> in Performance.h, do it manually */ + mMachine->Release(); Assert(!cEnabled); } int CollectorGuestHAL::enable() { + /* Must make sure that the machine object does not get uninitialized + * in the middle of enabling this collector. Causes timing-related + * behavior otherwise, which we don't want. In particular the + * GetRemoteConsole call below can hang if the VM didn't completely + * terminate (the VM processes stop processing events shortly before + * closing the session). This avoids the hang. */ + AutoCaller autoCaller(mMachine); + if (FAILED(autoCaller.rc())) return autoCaller.rc(); + HRESULT ret = S_OK; if (ASMAtomicIncU32(&cEnabled) == 1) { + ASMAtomicIncU32(&cVMsEnabled); ComPtr<IInternalSessionControl> directControl; ret = mMachine->getDirectControl(&directControl); @@ -152,6 +178,11 @@ int CollectorGuestHAL::disable() { if (ASMAtomicDecU32(&cEnabled) == 0) { + if (ASMAtomicDecU32(&cVMsEnabled) == 0) + { + if (mHostHAL) + mHostHAL->setMemHypervisorStats(0 /* ulMemAllocTotal */, 0 /* ulMemFreeTotal */, 0 /* ulMemBalloonTotal */, 0 /* ulMemSharedTotal */); + } Assert(mGuest && mConsole); mGuest->COMSETTER(StatisticsUpdateInterval)(0 /* off */); } diff --git a/src/VBox/Main/SnapshotImpl.cpp b/src/VBox/Main/SnapshotImpl.cpp index 1ce8d0fa7..d97a22107 100644 --- a/src/VBox/Main/SnapshotImpl.cpp +++ b/src/VBox/Main/SnapshotImpl.cpp @@ -1795,6 +1795,7 @@ void SessionMachine::restoreSnapshotHandler(RestoreSnapshotTask &aTask) alock.leave(); /* copy the state file */ + RTFileDelete(stateFilePath.c_str()); int vrc = RTFileCopyEx(snapStateFilePath.c_str(), stateFilePath.c_str(), 0, @@ -2064,7 +2065,10 @@ STDMETHODIMP SessionMachine::DeleteSnapshot(IConsole *aInitiator, AutoReadLock mlock(pHD COMMA_LOCKVAL_SRC_POS); MediumType_T type = pHD->getType(); - if (type != MediumType_Writethrough) // writethrough images are unaffected by snapshots, so do nothing for them + // writethrough and shareable images are unaffected by snapshots, + // so do nothing for them + if ( type != MediumType_Writethrough + && type != MediumType_Shareable) { // normal or immutable media need attention ++ulOpCount; @@ -2280,10 +2284,12 @@ void SessionMachine::deleteSnapshotHandler(DeleteSnapshotTask &aTask) Assert(!pHD.isNull()); { - // writethrough images are unaffected by snapshots, skip them + // writethrough and shareable images are unaffected by + // snapshots, skip them AutoReadLock medlock(pHD COMMA_LOCKVAL_SRC_POS); MediumType_T type = pHD->getType(); - if (type == MediumType_Writethrough) + if ( type == MediumType_Writethrough + || type == MediumType_Shareable) continue; } @@ -2754,8 +2760,10 @@ HRESULT SessionMachine::prepareDeleteSnapshotMedium(const ComObjPtr<Medium> &aHD AutoWriteLock alock(aHD COMMA_LOCKVAL_SRC_POS); - // Medium must not be writethrough at this point - AssertReturn(aHD->getType() != MediumType_Writethrough, E_FAIL); + // Medium must not be writethrough/shareable at this point + MediumType_T type = aHD->getType(); + AssertReturn( type != MediumType_Writethrough + && type != MediumType_Shareable, E_FAIL); aMediumLockList = NULL; fNeedsOnlineMerge = false; diff --git a/src/VBox/Main/SystemPropertiesImpl.cpp b/src/VBox/Main/SystemPropertiesImpl.cpp index 932c2a8c3..a95ae61c1 100644 --- a/src/VBox/Main/SystemPropertiesImpl.cpp +++ b/src/VBox/Main/SystemPropertiesImpl.cpp @@ -28,8 +28,6 @@ #include <iprt/path.h> #include <iprt/dir.h> -#include <iprt/process.h> -#include <iprt/ldr.h> #include <VBox/err.h> #include <VBox/param.h> @@ -116,40 +114,6 @@ HRESULT SystemProperties::init(VirtualBox *aParent) } } - /* Driver defaults which are OS specific */ -#if defined(RT_OS_WINDOWS) -# ifdef VBOX_WITH_WINMM - mDefaultAudioDriver = AudioDriverType_WinMM; -# else /* VBOX_WITH_WINMM */ - mDefaultAudioDriver = AudioDriverType_DirectSound; -# endif /* !VBOX_WITH_WINMM */ -#elif defined(RT_OS_SOLARIS) - mDefaultAudioDriver = AudioDriverType_SolAudio; -#elif defined(RT_OS_LINUX) -# if defined(VBOX_WITH_PULSE) - /* Check for the pulse library & that the pulse audio daemon is running. */ - if (RTProcIsRunningByName("pulseaudio") && - RTLdrIsLoadable("libpulse.so.0")) - mDefaultAudioDriver = AudioDriverType_Pulse; - else -# endif /* VBOX_WITH_PULSE */ -# if defined(VBOX_WITH_ALSA) - /* Check if we can load the ALSA library */ - if (RTLdrIsLoadable("libasound.so.2")) - mDefaultAudioDriver = AudioDriverType_ALSA; - else -# endif /* VBOX_WITH_ALSA */ - mDefaultAudioDriver = AudioDriverType_OSS; -#elif defined(RT_OS_DARWIN) - mDefaultAudioDriver = AudioDriverType_CoreAudio; -#elif defined(RT_OS_OS2) - mDefaultAudioDriver = AudioDriverType_MMP; -#elif defined(RT_OS_FREEBSD) - mDefaultAudioDriver = AudioDriverType_OSS; -#else - mDefaultAudioDriver = AudioDriverType_Null; -#endif - /* Confirm a successful initialization */ if (SUCCEEDED(rc)) autoInitSpan.setSucceeded(); @@ -819,7 +783,7 @@ STDMETHODIMP SystemProperties::COMGETTER(DefaultAudioDriver)(AudioDriverType_T * AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); - *aAudioDriver = mDefaultAudioDriver; + *aAudioDriver = settings::MachineConfigFile::getHostDefaultAudioDriver(); return S_OK; } diff --git a/src/VBox/Main/VMMDevInterface.cpp b/src/VBox/Main/VMMDevInterface.cpp index 12041ebcb..b376a78e7 100644 --- a/src/VBox/Main/VMMDevInterface.cpp +++ b/src/VBox/Main/VMMDevInterface.cpp @@ -157,14 +157,43 @@ int VMMDev::SetCredentialsJudgementResult (uint32_t u32Flags) /** - * Report guest OS version. + * Reports Guest Additions status. + * Called whenever the Additions issue a guest status report request or the VM is reset. + * + * @param pInterface Pointer to this interface. + * @param guestInfo Pointer to guest information structure + * @thread The emulation thread. + */ +DECLCALLBACK(void) vmmdevUpdateGuestStatus(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestStatus *guestStatus) +{ + PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface); + + Assert(guestStatus); + if (!guestStatus) + return; + + /* Store that information in IGuest */ + Guest* guest = pDrv->pVMMDev->getParent()->getGuest(); + Assert(guest); + if (!guest) + return; + + guest->setAdditionsStatus((VBoxGuestStatusFacility)guestStatus->facility, + (VBoxGuestStatusCurrent)guestStatus->status, + guestStatus->flags); + pDrv->pVMMDev->getParent()->onAdditionsStateChange(); +} + + +/** + * Reports Guest Additions API and OS version. * Called whenever the Additions issue a guest version report request or the VM is reset. * * @param pInterface Pointer to this interface. * @param guestInfo Pointer to guest information structure * @thread The emulation thread. */ -DECLCALLBACK(void) vmmdevUpdateGuestVersion(PPDMIVMMDEVCONNECTOR pInterface, VBoxGuestInfo *guestInfo) +DECLCALLBACK(void) vmmdevUpdateGuestInfo(PPDMIVMMDEVCONNECTOR pInterface, const VBoxGuestInfo *guestInfo) { PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface); @@ -172,7 +201,7 @@ DECLCALLBACK(void) vmmdevUpdateGuestVersion(PPDMIVMMDEVCONNECTOR pInterface, VBo if (!guestInfo) return; - /* store that information in IGuest */ + /* Store that information in IGuest */ Guest* guest = pDrv->pVMMDev->getParent()->getGuest(); Assert(guest); if (!guest) @@ -182,7 +211,7 @@ DECLCALLBACK(void) vmmdevUpdateGuestVersion(PPDMIVMMDEVCONNECTOR pInterface, VBo { char version[20]; RTStrPrintf(version, sizeof(version), "%d", guestInfo->additionsVersion); - guest->setAdditionsVersion(Bstr(version), guestInfo->osType); + guest->setAdditionsInfo(Bstr(version), guestInfo->osType); /* * Tell the console interface about the event @@ -199,7 +228,10 @@ DECLCALLBACK(void) vmmdevUpdateGuestVersion(PPDMIVMMDEVCONNECTOR pInterface, VBo * The guest additions was disabled because of a reset * or driver unload. */ - guest->setAdditionsVersion (Bstr(), guestInfo->osType); + guest->setAdditionsInfo(Bstr(), guestInfo->osType); + guest->setAdditionsStatus(VBoxGuestStatusFacility_Unknown, + VBoxGuestStatusCurrent_Disabled, + 0); /* Flags; not used. */ pDrv->pVMMDev->getParent()->onAdditionsStateChange(); } } @@ -223,8 +255,10 @@ DECLCALLBACK(void) vmmdevUpdateGuestCapabilities(PPDMIVMMDEVCONNECTOR pInterface if (!guest) return; - guest->setSupportsSeamless(BOOL (newCapabilities & VMMDEV_GUEST_SUPPORTS_SEAMLESS)); - guest->setSupportsGraphics(BOOL (newCapabilities & VMMDEV_GUEST_SUPPORTS_GRAPHICS)); + /* + * Report our current capabilites (and assume none is active yet). + */ + guest->setSupportedFeatures((ULONG64)newCapabilities, 0 /* Active capabilities, not used here. */); /* * Tell the console interface about the event @@ -542,32 +576,32 @@ DECLCALLBACK(int) vmmdevReportStatistics(PPDMIVMMDEVCONNECTOR pInterface, VBoxGu return VERR_INVALID_PARAMETER; /** @todo wrong error */ if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_CPU_LOAD_IDLE) - guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUIDLE, pGuestStats->u32CpuLoad_Idle); + guest->setStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUIDLE, pGuestStats->u32CpuLoad_Idle); if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_CPU_LOAD_KERNEL) - guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUKERNEL, pGuestStats->u32CpuLoad_Kernel); + guest->setStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUKERNEL, pGuestStats->u32CpuLoad_Kernel); if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_CPU_LOAD_USER) - guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUUSER, pGuestStats->u32CpuLoad_User); + guest->setStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_CPUUSER, pGuestStats->u32CpuLoad_User); /** @todo r=bird: Convert from 4KB to 1KB units? * CollectorGuestHAL::getGuestMemLoad says it returns KB units to * preCollect(). I might be wrong ofc, this is convoluted code... */ if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PHYS_MEM_TOTAL) - guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMTOTAL, pGuestStats->u32PhysMemTotal); + guest->setStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMTOTAL, pGuestStats->u32PhysMemTotal); if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PHYS_MEM_AVAIL) - guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMFREE, pGuestStats->u32PhysMemAvail); + guest->setStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMFREE, pGuestStats->u32PhysMemAvail); if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PHYS_MEM_BALLOON) - guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMBALLOON, pGuestStats->u32PhysMemBalloon); + guest->setStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMBALLOON, pGuestStats->u32PhysMemBalloon); if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_MEM_SYSTEM_CACHE) - guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMCACHE, pGuestStats->u32MemSystemCache); + guest->setStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_MEMCACHE, pGuestStats->u32MemSystemCache); if (pGuestStats->u32StatCaps & VBOX_GUEST_STAT_PAGE_FILE_SIZE) - guest->SetStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_PAGETOTAL, pGuestStats->u32PageFileSize); + guest->setStatistic(pGuestStats->u32CpuId, GUESTSTATTYPE_PAGETOTAL, pGuestStats->u32PageFileSize); return VINF_SUCCESS; } @@ -761,7 +795,8 @@ DECLCALLBACK(int) VMMDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, */ pDrvIns->IBase.pfnQueryInterface = VMMDev::drvQueryInterface; - pData->Connector.pfnUpdateGuestVersion = vmmdevUpdateGuestVersion; + pData->Connector.pfnUpdateGuestStatus = vmmdevUpdateGuestStatus; + pData->Connector.pfnUpdateGuestInfo = vmmdevUpdateGuestInfo; pData->Connector.pfnUpdateGuestCapabilities = vmmdevUpdateGuestCapabilities; pData->Connector.pfnUpdateMouseCapabilities = vmmdevUpdateMouseCapabilities; pData->Connector.pfnUpdatePointerShape = vmmdevUpdatePointerShape; diff --git a/src/VBox/Main/VirtualBoxImpl.cpp b/src/VBox/Main/VirtualBoxImpl.cpp index a57c9d915..b06975f8e 100644 --- a/src/VBox/Main/VirtualBoxImpl.cpp +++ b/src/VBox/Main/VirtualBoxImpl.cpp @@ -2420,7 +2420,7 @@ VirtualBox::SVCHelperClientThread(RTTHREAD aThread, void *aUser) * (pressing the Cancel button to close the Run As dialog) */ if (vrc2 == VERR_CANCELLED) rc = setError(E_FAIL, - tr("Operation cancelled by the user")); + tr("Operation canceled by the user")); else rc = setError(E_FAIL, tr("Could not launch a privileged process '%s' (%Rrc)"), @@ -2821,6 +2821,54 @@ void VirtualBox::onGuestPropertyChange(const Guid &aMachineId, IN_BSTR aName, postEvent(new GuestPropertyEvent(this, aMachineId, aName, aValue, aFlags)); } +/** Event for onMachineUninit(), this is not a CallbackEvent */ +class MachineUninitEvent : public Event +{ +public: + + MachineUninitEvent(VirtualBox *aVirtualBox, Machine *aMachine) + : mVirtualBox(aVirtualBox), mMachine(aMachine) + { + Assert(aVirtualBox); + Assert(aMachine); + } + + void *handler() + { +#ifdef VBOX_WITH_RESOURCE_USAGE_API + /* Handle unregistering metrics here, as it is not vital to get + * it done immediately. It reduces the number of locks needed and + * the lock contention in SessionMachine::uninit. */ + { + AutoWriteLock mLock(mMachine COMMA_LOCKVAL_SRC_POS); + mMachine->unregisterMetrics(mVirtualBox->performanceCollector(), mMachine); + } +#endif /* VBOX_WITH_RESOURCE_USAGE_API */ + + return NULL; + } + +private: + + /** + * Note that this is a weak ref -- the CallbackEvent handler thread + * is bound to the lifetime of the VirtualBox instance, so it's safe. + */ + VirtualBox *mVirtualBox; + + /** Reference to the machine object. */ + ComObjPtr<Machine> mMachine; +}; + +/** + * Trigger internal event. This isn't meant to be signalled to clients. + * @note Doesn't lock any object. + */ +void VirtualBox::onMachineUninit(Machine *aMachine) +{ + postEvent(new MachineUninitEvent(this, aMachine)); +} + /** * @note Locks this object for reading. */ diff --git a/src/VBox/Main/idl/VirtualBox.xidl b/src/VBox/Main/idl/VirtualBox.xidl index 526b2cfdc..0a55200d0 100644 --- a/src/VBox/Main/idl/VirtualBox.xidl +++ b/src/VBox/Main/idl/VirtualBox.xidl @@ -726,12 +726,14 @@ </const> <const name="DeletingSnapshotOnline" value="16"> <desc> - Teleporting the machine state in from another host or process. + Like @c DeletingSnapshot, but the merging of media is ongoing in + the background while the machine is running. </desc> </const> <const name="DeletingSnapshotPaused" value="17"> <desc> - Teleporting the machine state in from another host or process. + Like @c DeletingSnapshotOnline, but the machine was paused when the + merging of differencing media was started. </desc> </const> <const name="RestoringSnapshot" value="18"> @@ -742,7 +744,8 @@ <const name="DeletingSnapshot" value="19"> <desc> A machine snapshot is being deleted; this can take a long time since this - may require merging differencing media. + may require merging differencing media. This value indicates that the + machine is not running while the snapshot is being deleted. </desc> </const> <const name="SettingUp" value="20"> @@ -7331,8 +7334,9 @@ </ul> - The virtual machine's <link to="IMachine::state">state</link> is changed to "DeletingSnapshot" - while this operation is in progress. + The virtual machine's <link to="IMachine::state">state</link> is + changed to "DeletingSnapshot", "DeletingSnapshotOnline" or + "DeletingSnapshotPaused" while this operation is in progress. <note> Merging medium contents can be very time and disk space @@ -7342,7 +7346,10 @@ quick. </note> <result name="VBOX_E_INVALID_VM_STATE"> - Virtual machine is running. + The running virtual machine prevents deleting this snapshot. This + happens only in very specific situations, usually snapshots can be + deleted without trouble while a VM is running. The error message + text explains the reason for the failure. </result> </desc> <param name="id" type="uuid" mod="string" dir="in"> @@ -9269,7 +9276,7 @@ <const name="Shareable" value="3"> <desc> Allow using this medium concurrently by several machines. - <note>This is a stub value. Not usable until this note is removed.</note> + <note>Present since VirtualBox 3.2.0, and accepted since 3.2.8.</note> </desc> </const> </enum> @@ -9311,7 +9318,7 @@ </const> <const name="Diff" value="0x20000"> <desc> - Fixed image. Only allowed for base images. + Differencing image. Only allowed for child images. </desc> </const> </enum> @@ -9474,8 +9481,8 @@ <h3>Medium types</h3> - There are three types of medium behavior (see <link to="MediumType" />): - "normal", "immutable" and "writethrough", represented by the + There are four types of medium behavior (see <link to="MediumType" />): + "normal", "immutable", "writethrough" and "shareable", represented by the <link to="#type"/> attribute. The type of the medium defines how the medium is attached to a virtual machine and what happens when a <link to="ISnapshot">snapshot</link> of the virtual machine with the @@ -9500,7 +9507,7 @@ child medium to its parent). It is also possible to walk down the tree using the <link to="#children"/> attribute. - Note that the type of all differencing media is "Normal"; all other + Note that the type of all differencing media is "normal"; all other values are meaningless for them. Base media may be of any type. <h3>Creating hard disks</h3> @@ -9598,6 +9605,13 @@ <li><b>Writethrough</b> hard disks are always attached <b>directly</b>, also as designed. This also means that writethrough hard disks cannot have other hard disks linked to them at all.</li> + <li><b>Shareable</b> hard disks are always attached <b>directly</b>, + also as designed. This also means that shareable hard disks cannot + have other hard disks linked to them at all. They behave almost + like writethrough hard disks, except that shareable hard disks can + be attached to several virtual machines which are running, allowing + concurrent accesses. You need special cluster software running in + the virtual machines to make use of such disks.</li> </ul> Note that the same hard disk, regardless of its type, may be attached to diff --git a/src/VBox/Main/include/GuestImpl.h b/src/VBox/Main/include/GuestImpl.h index 3047f0370..a06da46e8 100644 --- a/src/VBox/Main/include/GuestImpl.h +++ b/src/VBox/Main/include/GuestImpl.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -69,16 +69,29 @@ public: HRESULT FinalConstruct(); void FinalRelease(); - // public initializer/uninitializer for internal purposes only + // Public initializer/uninitializer for internal purposes only HRESULT init (Console *aParent); void uninit(); // IGuest properties STDMETHOD(COMGETTER(OSTypeId)) (BSTR *aOSTypeId); +#if 0 + /** @todo Will replace old AdditionsActive call. */ + STDMETHOD(COMGETTER(AdditionsActive)) (ULONG aLevel, BOOL *aAdditionsActive); +#endif STDMETHOD(COMGETTER(AdditionsActive)) (BOOL *aAdditionsActive); +#if 0 + /** @todo Will replace AdditionsVersion to be more clear. */ + STDMETHOD(COMGETTER(AdditionsAPIVersion)) (BSTR *aAdditionsVersion); +#endif STDMETHOD(COMGETTER(AdditionsVersion)) (BSTR *aAdditionsVersion); + /** @todo Remove */ STDMETHOD(COMGETTER(SupportsSeamless)) (BOOL *aSupportsSeamless); STDMETHOD(COMGETTER(SupportsGraphics)) (BOOL *aSupportsGraphics); +#if 0 + /** @todo Will replace SupportsSeamless, SupportsGraphics, ... */ + STDMETHOD(COMGETTER(AdditionsFeatureAvailable)) (ULONG64 aFeature, BOOL *aActive, BOOL *aAvailable); +#endif STDMETHOD(COMGETTER(MemoryBalloonSize)) (ULONG *aMemoryBalloonSize); STDMETHOD(COMSETTER(MemoryBalloonSize)) (ULONG aMemoryBalloonSize); STDMETHOD(COMGETTER(PageFusionEnabled)) (BOOL *aPageFusionEnabled); @@ -99,14 +112,11 @@ public: ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared, ULONG *aMemCache, ULONG *aPageTotal, ULONG *aMemAllocTotal, ULONG *aMemFreeTotal, ULONG *aMemBalloonTotal, ULONG *aMemSharedTotal); - // public methods that are not in IDL - void setAdditionsVersion (Bstr aVersion, VBOXOSTYPE aOsType); - - void setSupportsSeamless (BOOL aSupportsSeamless); - - void setSupportsGraphics (BOOL aSupportsGraphics); - - HRESULT SetStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal); + // Public methods that are not in IDL (only called internally). + void setAdditionsInfo(Bstr aVersion, VBOXOSTYPE aOsType); + void setAdditionsStatus(VBoxGuestStatusFacility Facility, VBoxGuestStatusCurrent Status, ULONG ulFlags); + void setSupportedFeatures(ULONG64 ulCaps, ULONG64 ulActive); + HRESULT setStatistic(ULONG aCpuId, GUESTSTATTYPE enmType, ULONG aVal); // for VirtualBoxSupportErrorInfoImpl static const wchar_t *getComponentName() { return L"Guest"; } diff --git a/src/VBox/Main/include/MachineImpl.h b/src/VBox/Main/include/MachineImpl.h index 7e8b160c1..cd2b0804c 100644 --- a/src/VBox/Main/include/MachineImpl.h +++ b/src/VBox/Main/include/MachineImpl.h @@ -358,6 +358,11 @@ public: void uninit(); +#ifdef VBOX_WITH_RESOURCE_USAGE_API + // Needed from VirtualBox, for the delayed metrics cleanup. + void unregisterMetrics(PerformanceCollector *aCollector, Machine *aMachine); +#endif /* VBOX_WITH_RESOURCE_USAGE_API */ + protected: HRESULT initImpl(VirtualBox *aParent, const Utf8Str &strConfigFile); @@ -805,7 +810,6 @@ protected: #ifdef VBOX_WITH_RESOURCE_USAGE_API void registerMetrics(PerformanceCollector *aCollector, Machine *aMachine, RTPROCESS pid); - void unregisterMetrics(PerformanceCollector *aCollector, Machine *aMachine); pm::CollectorGuestHAL *mGuestHAL; #endif /* VBOX_WITH_RESOURCE_USAGE_API */ diff --git a/src/VBox/Main/include/MediumImpl.h b/src/VBox/Main/include/MediumImpl.h index 62cd2e985..8db7e98da 100644 --- a/src/VBox/Main/include/MediumImpl.h +++ b/src/VBox/Main/include/MediumImpl.h @@ -156,6 +156,7 @@ public: // a caller and a read lock before calling them!) const Guid& getId() const; MediumState_T getState() const; + MediumVariant_T getVariant() const; const Utf8Str& getLocation() const; const Utf8Str& getLocationFull() const; const Utf8Str& getFormat() const; diff --git a/src/VBox/Main/include/Performance.h b/src/VBox/Main/include/Performance.h index 4e2474b29..a9e028b21 100644 --- a/src/VBox/Main/include/Performance.h +++ b/src/VBox/Main/include/Performance.h @@ -185,9 +185,7 @@ namespace pm class CollectorGuestHAL : public CollectorHAL { public: - CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL) : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL), mGuest(NULL), - mLastTick(0), mHostHAL(hostHAL), mCpuUser(0), mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0), - mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0) {}; + CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL); ~CollectorGuestHAL(); virtual int preCollect(const CollectorHints& hints, uint64_t iTick); @@ -235,6 +233,9 @@ namespace pm ULONG mMemShared; ULONG mMemCache; ULONG mPageTotal; + + private: + static uint32_t cVMsEnabled; }; extern CollectorHAL *createHAL(); diff --git a/src/VBox/Main/include/SystemPropertiesImpl.h b/src/VBox/Main/include/SystemPropertiesImpl.h index 63d363e2f..32ab9c943 100644 --- a/src/VBox/Main/include/SystemPropertiesImpl.h +++ b/src/VBox/Main/include/SystemPropertiesImpl.h @@ -140,7 +140,6 @@ private: Utf8Str m_strRemoteDisplayAuthLibrary; Utf8Str m_strWebServiceAuthLibrary; ULONG mLogHistoryCount; - AudioDriverType_T mDefaultAudioDriver; friend class VirtualBox; }; diff --git a/src/VBox/Main/include/VirtualBoxImpl.h b/src/VBox/Main/include/VirtualBoxImpl.h index 3137bde3b..71a9b6a45 100644 --- a/src/VBox/Main/include/VirtualBoxImpl.h +++ b/src/VBox/Main/include/VirtualBoxImpl.h @@ -240,6 +240,7 @@ public: void onSnapshotChange(const Guid &aMachineId, const Guid &aSnapshotId); void onGuestPropertyChange(const Guid &aMachineId, IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags); + void onMachineUninit(Machine *aMachine); ComObjPtr<GuestOSType> getUnknownOSType(); diff --git a/src/VBox/Main/webservice/vboxweb.cpp b/src/VBox/Main/webservice/vboxweb.cpp index 2227be5ac..820a8b04d 100644 --- a/src/VBox/Main/webservice/vboxweb.cpp +++ b/src/VBox/Main/webservice/vboxweb.cpp @@ -37,6 +37,7 @@ #include <iprt/string.h> #include <iprt/ldr.h> #include <iprt/semaphore.h> +#include <iprt/time.h> // workaround for compile problems on gcc 4.1 #ifdef __GNUC__ @@ -99,6 +100,7 @@ const char *g_pcszBindToHost = NULL; // host; NULL = current unsigned int g_uBindToPort = 18083; // port unsigned int g_uBacklog = 100; // backlog = max queue size for requests unsigned int g_cMaxWorkerThreads = 100; // max. no. of worker threads +unsigned int g_cMaxKeepAlive = 100; // maximum number of soap requests in one connection bool g_fVerbose = false; // be verbose PRTSTREAM g_pstrLog = NULL; @@ -118,15 +120,21 @@ class SoapQ; SoapQ *g_pSoapQ = NULL; // this mutex protects the auth lib and authentication -util::RWLockHandle *g_pAuthLibLockHandle; +util::WriteLockHandle *g_pAuthLibLockHandle; // this mutex protects all of the below -util::RWLockHandle *g_pSessionsLockHandle; +util::WriteLockHandle *g_pSessionsLockHandle; SessionsMap g_mapSessions; ULONG64 g_iMaxManagedObjectID = 0; ULONG64 g_cManagedObjects = 0; +// this mutex protects g_mapThreads +util::RWLockHandle *g_pThreadsLockHandle; + +// this mutex synchronizes logging +util::WriteLockHandle *g_pWebLogLockHandle; + // Threads map, so we can quickly map an RTTHREAD struct to a logger prefix typedef std::map<RTTHREAD, com::Utf8Str> ThreadsMap; ThreadsMap g_mapThreads; @@ -148,6 +156,7 @@ static const RTGETOPTDEF g_aOptions[] { "--timeout", 't', RTGETOPT_REQ_UINT32 }, { "--check-interval", 'i', RTGETOPT_REQ_UINT32 }, { "--threads", 'T', RTGETOPT_REQ_UINT32 }, + { "--keepalive", 'k', RTGETOPT_REQ_UINT32 }, { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, { "--logfile", 'F', RTGETOPT_REQ_STRING }, }; @@ -170,41 +179,45 @@ void DisplayHelp() { case 'h': pcszDescr = "Print this help message and exit."; - break; + break; #if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined (RT_OS_SOLARIS) || defined(RT_OS_FREEBSD) case 'b': pcszDescr = "Run in background (daemon mode)."; - break; + break; #endif case 'H': pcszDescr = "The host to bind to (localhost)."; - break; + break; case 'p': pcszDescr = "The port to bind to (18083)."; - break; + break; case 't': pcszDescr = "Session timeout in seconds; 0 = disable timeouts (" DEFAULT_TIMEOUT_SECS_STRING ")."; - break; + break; case 'T': pcszDescr = "Maximum number of worker threads to run in parallel (100)."; - break; + break; + + case 'k': + pcszDescr = "Maximum number of requests before a socket will be closed (100)."; + break; case 'i': pcszDescr = "Frequency of timeout checks in seconds (5)."; - break; + break; case 'v': pcszDescr = "Be verbose."; - break; + break; case 'F': pcszDescr = "Name of file to write log to (no file)."; - break; + break; } RTStrmPrintf(g_pStdErr, "%-23s%s\n", str.c_str(), pcszDescr); @@ -232,18 +245,30 @@ public: SoapQ &q, const struct soap *soap) : m_u(u), + m_strThread(com::Utf8StrFmt("SoapQWrk%02d", m_u)), m_pQ(&q) { // make a copy of the soap struct for the new thread m_soap = soap_copy(soap); + /* The soap.max_keep_alive value can be set to the maximum keep-alive calls allowed, + * which is important to avoid a client from holding a thread indefinitely. + * http://www.cs.fsu.edu/~engelen/soapdoc2.html#sec:keepalive + * + * Strings with 8-bit content can hold ASCII (default) or UTF8. The latter is + * possible by enabling the SOAP_C_UTFSTRING flag. + */ + soap_set_omode(m_soap, SOAP_IO_KEEPALIVE | SOAP_C_UTFSTRING); + soap_set_imode(m_soap, SOAP_IO_KEEPALIVE | SOAP_C_UTFSTRING); + m_soap->max_keep_alive = g_cMaxKeepAlive; + if (!RT_SUCCESS(RTThreadCreate(&m_pThread, fntWrapper, this, // pvUser 0, // cbStack, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0, - "SoapQWorker"))) + m_strThread.c_str()))) { RTStrmPrintf(g_pStdErr, "[!] Cannot start worker thread %d\n", u); exit(1); @@ -266,10 +291,11 @@ public: return 0; } - size_t m_u; // thread number - SoapQ *m_pQ; // the single SOAP queue that all the threads service - struct soap *m_soap; // copy of the soap structure for this thread (from soap_copy()) - RTTHREAD m_pThread; // IPRT thread struct for this thread + size_t m_u; // thread number + com::Utf8Str m_strThread; // thread name ("SoapQWrkXX") + SoapQ *m_pQ; // the single SOAP queue that all the threads service + struct soap *m_soap; // copy of the soap structure for this thread (from soap_copy()) + RTTHREAD m_pThread; // IPRT thread struct for this thread }; /** @@ -287,7 +313,7 @@ public: */ SoapQ(const struct soap *pSoap) : m_soap(pSoap), - m_mutex(util::LOCKCLASS_OBJECTSTATE), + m_mutex(util::LOCKCLASS_OBJECTSTATE), // lowest lock order, no other may be held while this is held m_cIdleThreads(0) { RTSemEventMultiCreate(&m_event); @@ -321,6 +347,7 @@ public: *this, m_soap); m_llAllThreads.push_back(pst); + util::AutoWriteLock thrLock(g_pThreadsLockHandle COMMA_LOCKVAL_SRC_POS); g_mapThreads[pst->m_pThread] = com::Utf8StrFmt("[%3u]", pst->m_u); ++m_cIdleThreads; } @@ -450,22 +477,40 @@ void WebLog(const char *pszFormat, ...) va_end(args); const char *pcszPrefix = "[ ]"; + util::AutoReadLock thrLock(g_pThreadsLockHandle COMMA_LOCKVAL_SRC_POS); ThreadsMap::iterator it = g_mapThreads.find(RTThreadSelf()); if (it != g_mapThreads.end()) pcszPrefix = it->second.c_str(); + thrLock.release(); + + // make a timestamp + RTTIMESPEC ts; + RTTimeLocalNow(&ts); + RTTIME t; + RTTimeExplode(&t, &ts); + + com::Utf8StrFmt strPrefix("%04d-%02d-%02d %02d:%02d:%02d %s", + t.i32Year, t.u8Month, t.u8MonthDay, + t.u8Hour, t.u8Minute, t.u8Second, + pcszPrefix); + // synchronize the actual output + util::AutoWriteLock logLock(g_pWebLogLockHandle COMMA_LOCKVAL_SRC_POS); // terminal - RTPrintf("%s %s", pcszPrefix, psz); + RTPrintf("%s %s", strPrefix.c_str(), psz); // log file if (g_pstrLog) { - RTStrmPrintf(g_pstrLog, "%s %s", pcszPrefix, psz); + RTStrmPrintf(g_pstrLog, "%s %s", strPrefix.c_str(), psz); RTStrmFlush(g_pstrLog); } +#ifdef DEBUG // logger instance RTLogLoggerEx(LOG_INSTANCE, RTLOGGRPFLAGS_DJ, LOG_GROUP, "%s %s", pcszPrefix, psz); +#endif + logLock.release(); RTStrFree(psz); } @@ -550,7 +595,9 @@ void doQueuesLoop() int fntQPumper(RTTHREAD ThreadSelf, void *pvUser) { // store a log prefix for this thread + util::AutoWriteLock thrLock(g_pThreadsLockHandle COMMA_LOCKVAL_SRC_POS); g_mapThreads[RTThreadSelf()] = "[ P ]"; + thrLock.release(); doQueuesLoop(); @@ -591,19 +638,19 @@ int main(int argc, char* argv[]) { case 'H': g_pcszBindToHost = ValueUnion.psz; - break; + break; case 'p': g_uBindToPort = ValueUnion.u32; - break; + break; case 't': g_iWatchdogTimeoutSecs = ValueUnion.u32; - break; + break; case 'i': g_iWatchdogCheckInterval = ValueUnion.u32; - break; + break; case 'F': { @@ -616,33 +663,37 @@ int main(int argc, char* argv[]) WebLog("Sun VirtualBox Webservice Version %s\n" "Opened log file \"%s\"\n", VBOX_VERSION_STRING, ValueUnion.psz); + break; } - break; case 'T': g_cMaxWorkerThreads = ValueUnion.u32; - break; + break; + + case 'k': + g_cMaxKeepAlive = ValueUnion.u32; + break; case 'h': DisplayHelp(); - return 0; + return 0; case 'v': g_fVerbose = true; - break; + break; #if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined (RT_OS_SOLARIS) || defined(RT_OS_FREEBSD) case 'b': g_fDaemonize = true; - break; + break; #endif case 'V': RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr()); - return 0; + return 0; default: rc = RTGetOptPrintError(c, &ValueUnion); - return rc; + return rc; } } @@ -692,8 +743,10 @@ int main(int argc, char* argv[]) } // create the global mutexes - g_pAuthLibLockHandle = new util::RWLockHandle(util::LOCKCLASS_OBJECTSTATE); - g_pSessionsLockHandle = new util::RWLockHandle(util::LOCKCLASS_OBJECTSTATE); + g_pAuthLibLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE); + g_pSessionsLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE); + g_pThreadsLockHandle = new util::RWLockHandle(util::LOCKCLASS_OBJECTSTATE); + g_pWebLogLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE); // SOAP queue pumper thread RTTHREAD tQPumper; @@ -733,7 +786,7 @@ int main(int argc, char* argv[]) // we have to process main event queue WEBDEBUG(("Pumping COM event queue\n")); int vrc = pQ->processEventQueue(RT_INDEFINITE_WAIT); - if (FAILED(vrc)) + if (FAILED(vrc) && (vrc != VERR_TIMEOUT)) com::GluePrintRCMessage(vrc); } @@ -758,7 +811,9 @@ int main(int argc, char* argv[]) int fntWatchdog(RTTHREAD ThreadSelf, void *pvUser) { // store a log prefix for this thread + util::AutoWriteLock thrLock(g_pThreadsLockHandle COMMA_LOCKVAL_SRC_POS); g_mapThreads[RTThreadSelf()] = "[W ]"; + thrLock.release(); WEBDEBUG(("Watchdog thread started\n")); @@ -770,8 +825,7 @@ int fntWatchdog(RTTHREAD ThreadSelf, void *pvUser) time_t tNow; time(&tNow); - // lock the sessions while we're iterating; this blocks - // out the COM code from messing with it + // we're messing with sessions, so lock them util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); WEBDEBUG(("Watchdog: checking %d sessions\n", g_mapSessions.size())); @@ -923,7 +977,7 @@ void RaiseSoapRuntimeFault(struct soap *soap, ex->interfaceID = ConvertComString(info.getInterfaceID()); // compose descriptive message - com::Utf8StrFmt str("VirtualBox error: %s (0x%RU32)", ex->text.c_str(), ex->resultCode); + com::Utf8StrFmt str("VirtualBox error: %s (0x%lX)", ex->text.c_str(), ex->resultCode); RaiseSoapFault(soap, str.c_str(), @@ -1012,7 +1066,7 @@ class WebServiceSessionPrivate /** * Constructor for the session object. * - * Preconditions: Caller must have locked g_pSessionsLockHandle in write mode. + * Preconditions: Caller must have locked g_pSessionsLockHandle. * * @param username * @param password @@ -1033,7 +1087,7 @@ WebServiceSession::WebServiceSession() /** * Destructor. Cleans up and destroys all contained managed object references on the way. * - * Preconditions: Caller must have locked g_pSessionsLockHandle in write mode. + * Preconditions: Caller must have locked g_pSessionsLockHandle. */ WebServiceSession::~WebServiceSession() { @@ -1188,14 +1242,14 @@ int WebServiceSession::authenticate(const char *pcszUsername, * ComPtr<IVirtualBox>, for example. As we store the ComPtr<IUnknown> in * our private hash table, we must search for one too. * - * Preconditions: Caller must have locked g_pSessionsLockHandle in read mode. + * Preconditions: Caller must have locked g_pSessionsLockHandle. * * @param pcu pointer to a COM object. * @return The existing ManagedObjectRef that represents the COM object, or NULL if there's none yet. */ ManagedObjectRef* WebServiceSession::findRefFromPtr(const ComPtr<IUnknown> &pcu) { - // Assert(g_pSessionsLockHandle->isReadLockOnCurrentThread()); // @todo + Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread()); IUnknown *p = pcu; uintptr_t ulp = (uintptr_t)p; @@ -1206,7 +1260,7 @@ ManagedObjectRef* WebServiceSession::findRefFromPtr(const ComPtr<IUnknown> &pcu) { pRef = it->second; WSDLT_ID id = pRef->toWSDL(); - WEBDEBUG((" %s: found existing ref %s for COM obj 0x%lX\n", __FUNCTION__, id.c_str(), ulp)); + WEBDEBUG((" %s: found existing ref %s (%s) for COM obj 0x%lX\n", __FUNCTION__, id.c_str(), pRef->getInterfaceName(), ulp)); } else pRef = NULL; @@ -1225,7 +1279,7 @@ ManagedObjectRef* WebServiceSession::findRefFromPtr(const ComPtr<IUnknown> &pcu) */ WebServiceSession* WebServiceSession::findSessionFromRef(const WSDLT_ID &id) { - // Assert(g_pSessionsLockHandle->isReadLockOnCurrentThread()); // @todo + Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread()); WebServiceSession *pSession = NULL; uint64_t sessid; @@ -1310,7 +1364,7 @@ void WebServiceSession::DumpRefs() * createRefFromObject() template function in vboxweb.h, which * does perform that check. * - * Preconditions: Caller must have locked g_pSessionsLockHandle in write mode. + * Preconditions: Caller must have locked g_pSessionsLockHandle. * * @param pObj */ @@ -1345,7 +1399,7 @@ ManagedObjectRef::ManagedObjectRef(WebServiceSession &session, * Destructor; removes the instance from the global hash of * managed objects. * - * Preconditions: Caller must have locked g_pSessionsLockHandle in write mode. + * Preconditions: Caller must have locked g_pSessionsLockHandle. */ ManagedObjectRef::~ManagedObjectRef() { @@ -1471,10 +1525,12 @@ int __vbox__IManagedObjectRef_USCOREgetInterfaceName( _vbox__IManagedObjectRef_USCOREgetInterfaceNameResponse *resp) { HRESULT rc = SOAP_OK; - WEBDEBUG(("\n-- entering %s\n", __FUNCTION__)); + WEBDEBUG(("-- entering %s\n", __FUNCTION__)); - do { - util::AutoReadLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); + do + { + // findRefFromId require the lock + util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); ManagedObjectRef *pRef; if (!ManagedObjectRef::findRefFromId(req->_USCOREthis, &pRef, false)) @@ -1504,11 +1560,11 @@ int __vbox__IManagedObjectRef_USCORErelease( _vbox__IManagedObjectRef_USCOREreleaseResponse *resp) { HRESULT rc = SOAP_OK; - WEBDEBUG(("\n-- entering %s\n", __FUNCTION__)); + WEBDEBUG(("-- entering %s\n", __FUNCTION__)); - do { - // findRefFromId needs read lock, and the delete call below requires - // the write lock, so get the write lock here + do + { + // findRefFromId and the delete call below require the lock util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); ManagedObjectRef *pRef; @@ -1519,11 +1575,11 @@ int __vbox__IManagedObjectRef_USCORErelease( } WEBDEBUG((" found reference; deleting!\n")); + // this removes the object from all stacks; since + // there's a ComPtr<> hidden inside the reference, + // this should also invoke Release() on the COM + // object delete pRef; - // this removes the object from all stacks; since - // there's a ComPtr<> hidden inside the reference, - // this should also invoke Release() on the COM - // object } while (0); WEBDEBUG(("-- leaving %s, rc: 0x%lX\n", __FUNCTION__, rc)); @@ -1575,9 +1631,10 @@ int __vbox__IWebsessionManager_USCORElogon( _vbox__IWebsessionManager_USCORElogonResponse *resp) { HRESULT rc = SOAP_OK; - WEBDEBUG(("\n-- entering %s\n", __FUNCTION__)); + WEBDEBUG(("-- entering %s\n", __FUNCTION__)); - do { + do + { // WebServiceSession constructor tinkers with global MOR map and requires a write lock util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); @@ -1615,17 +1672,17 @@ int __vbox__IWebsessionManager_USCOREgetSessionObject( _vbox__IWebsessionManager_USCOREgetSessionObjectResponse *resp) { HRESULT rc = SOAP_OK; - WEBDEBUG(("\n-- entering %s\n", __FUNCTION__)); + WEBDEBUG(("-- entering %s\n", __FUNCTION__)); - do { - // findSessionFromRef needs read lock - util::AutoReadLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); + do + { + // findSessionFromRef needs lock + util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); WebServiceSession* pSession; if ((pSession = WebServiceSession::findSessionFromRef(req->refIVirtualBox))) - { resp->returnval = pSession->getSessionObject(); - } + } while (0); WEBDEBUG(("-- leaving %s, rc: 0x%lX\n", __FUNCTION__, rc)); @@ -1648,11 +1705,11 @@ int __vbox__IWebsessionManager_USCORElogoff( _vbox__IWebsessionManager_USCORElogoffResponse *resp) { HRESULT rc = SOAP_OK; - WEBDEBUG(("\n-- entering %s\n", __FUNCTION__)); + WEBDEBUG(("-- entering %s\n", __FUNCTION__)); - do { - // findSessionFromRef needs read lock, and the session destructor requires - // the write lock, so get the write lock here + do + { + // findSessionFromRef and the session destructor require the lock util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); WebServiceSession* pSession; diff --git a/src/VBox/Main/webservice/vboxweb.h b/src/VBox/Main/webservice/vboxweb.h index 9290e2437..fd444f2e7 100644 --- a/src/VBox/Main/webservice/vboxweb.h +++ b/src/VBox/Main/webservice/vboxweb.h @@ -23,8 +23,10 @@ void WebLog(const char *pszFormat, ...); #define WEBDEBUG(a) if (g_fVerbose) { WebLog a; } +#ifdef DEBUG #define LOG_GROUP LOG_GROUP_WEBSERVICE #include <VBox/log.h> +#endif #include <VBox/com/VirtualBox.h> #include <VBox/com/Guid.h> @@ -47,9 +49,8 @@ extern bool g_fVerbose; extern PRTSTREAM g_pstrLog; -extern util::RWLockHandle *g_pAuthLibLockHandle; - -extern util::RWLockHandle *g_pSessionsLockHandle; +extern util::WriteLockHandle *g_pAuthLibLockHandle; +extern util::WriteLockHandle *g_pSessionsLockHandle; /**************************************************************************** * @@ -223,9 +224,8 @@ int findComPtrFromId(struct soap *soap, ComPtr<T> &pComPtr, bool fNullAllowed) { - // we're only reading the MOR maps, not modifying them, so a readlock is good enough - // (allow concurrency, this code gets called from everywhere in methodmaps.cpp) - util::AutoReadLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); + // findRefFromId requires thelock + util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); int rc; ManagedObjectRef *pRef; @@ -269,11 +269,10 @@ WSDLT_ID createOrFindRefFromComPtr(const WSDLT_ID &idParent, // NULL comptr should return NULL MOR if (pc.isNull()) { - WEBDEBUG((" createOrFindRefFromComPtr(): returning empty MOR for NULL COM pointer\n")); + WEBDEBUG((" createOrFindRefFromComPtr(): returning empty MOR for NULL %s pointer\n", pcszInterface)); return ""; } - // we might be modifying the MOR maps below, so request write lock now util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS); WebServiceSession *pSession; if ((pSession = WebServiceSession::findSessionFromRef(idParent))) diff --git a/src/VBox/Main/webservice/websrv-cpp.xsl b/src/VBox/Main/webservice/websrv-cpp.xsl index b669d5a7a..bfae463cf 100644 --- a/src/VBox/Main/webservice/websrv-cpp.xsl +++ b/src/VBox/Main/webservice/websrv-cpp.xsl @@ -86,7 +86,7 @@ const char *g_pcszCallingComMethod = " calling COM method %s\n"; const char *g_pcszDoneCallingComMethod = " done calling COM method\n"; const char *g_pcszConvertComOutputBack = " convert COM output \"%s\" back to caller format\n"; const char *g_pcszDoneConvertingComOutputBack = " done converting COM output \"%s\" back to caller format\n"; -const char *g_pcszEntering = "\n-- entering %s\n"; +const char *g_pcszEntering = "-- entering %s\n"; const char *g_pcszLeaving = "-- leaving %s, rc: 0x%lX (%d)\n"; // generated string constants for all interface names diff --git a/src/VBox/Main/win/comregister.cmd b/src/VBox/Main/win/comregister.cmd index d4ffd423d..6a38f5ed7 100644 --- a/src/VBox/Main/win/comregister.cmd +++ b/src/VBox/Main/win/comregister.cmd @@ -6,16 +6,16 @@ REM * (both inproc and out-of-process) REM */
REM /*
-REM Copyright (C) 2006-2007 Oracle Corporation
-REM
-REM This file is part of VirtualBox Open Source Edition (OSE), as
-REM available from http://www.virtualbox.org. This file is free software;
-REM you can redistribute it and/or modify it under the terms of the GNU
-REM General Public License (GPL) as published by the Free Software
-REM Foundation, in version 2 as it comes in the "COPYING" file of the
-REM VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-REM hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-REM
+REM Copyright (C) 2006-2007 Oracle Corporation +REM +REM This file is part of VirtualBox Open Source Edition (OSE), as +REM available from http://www.virtualbox.org. This file is free software; +REM you can redistribute it and/or modify it under the terms of the GNU +REM General Public License (GPL) as published by the Free Software +REM Foundation, in version 2 as it comes in the "COPYING" file of the +REM VirtualBox OSE distribution. VirtualBox OSE is distributed in the +REM hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +REM REM */
diff --git a/src/VBox/Main/xml/Settings.cpp b/src/VBox/Main/xml/Settings.cpp index f317a8eab..7cb9a8fb6 100644 --- a/src/VBox/Main/xml/Settings.cpp +++ b/src/VBox/Main/xml/Settings.cpp @@ -59,6 +59,9 @@ #include <iprt/stream.h> #include <iprt/ctype.h> #include <iprt/file.h> +#include <iprt/process.h> +#include <iprt/ldr.h> +#include <iprt/cpp/lock.h> // generated header #include "SchemaDefs.h" @@ -909,11 +912,7 @@ void MainConfigFile::readMedium(MediaType t, else if (strType == "WRITETHROUGH") med.hdType = MediumType_Writethrough; else if (strType == "SHAREABLE") - { - /// @todo remove check once the medium type is implemented - throw ConfigFileError(this, &elmMedium, N_("HardDisk/@type attribute of Shareable is not implemented yet")); med.hdType = MediumType_Shareable; - } else throw ConfigFileError(this, &elmMedium, N_("HardDisk/@type attribute must be one of Normal, Immutable or Writethrough")); } @@ -2025,6 +2024,62 @@ void MachineConfigFile::readParallelPorts(const xml::ElementNode &elmLPT, } /** + * Called from MachineConfigFile::readHardware() to read audio adapter information + * and maybe fix driver information depending on the current host hardware. + * + * @param elmAudioAdapter "AudioAdapter" XML element. + * @param hw + */ +void MachineConfigFile::readAudioAdapter(const xml::ElementNode &elmAudioAdapter, + AudioAdapter &aa) +{ + elmAudioAdapter.getAttributeValue("enabled", aa.fEnabled); + + Utf8Str strTemp; + if (elmAudioAdapter.getAttributeValue("controller", strTemp)) + { + if (strTemp == "SB16") + aa.controllerType = AudioControllerType_SB16; + else if (strTemp == "AC97") + aa.controllerType = AudioControllerType_AC97; + else + throw ConfigFileError(this, &elmAudioAdapter, N_("Invalid value '%s' in AudioAdapter/@controller attribute"), strTemp.c_str()); + } + + if (elmAudioAdapter.getAttributeValue("driver", strTemp)) + { + // settings before 1.3 used lower case so make sure this is case-insensitive + strTemp.toUpper(); + if (strTemp == "NULL") + aa.driverType = AudioDriverType_Null; + else if (strTemp == "WINMM") + aa.driverType = AudioDriverType_WinMM; + else if ( (strTemp == "DIRECTSOUND") || (strTemp == "DSOUND") ) + aa.driverType = AudioDriverType_DirectSound; + else if (strTemp == "SOLAUDIO") + aa.driverType = AudioDriverType_SolAudio; + else if (strTemp == "ALSA") + aa.driverType = AudioDriverType_ALSA; + else if (strTemp == "PULSE") + aa.driverType = AudioDriverType_Pulse; + else if (strTemp == "OSS") + aa.driverType = AudioDriverType_OSS; + else if (strTemp == "COREAUDIO") + aa.driverType = AudioDriverType_CoreAudio; + else if (strTemp == "MMPM") + aa.driverType = AudioDriverType_MMPM; + else + throw ConfigFileError(this, &elmAudioAdapter, N_("Invalid value '%s' in AudioAdapter/@driver attribute"), strTemp.c_str()); + + // now check if this is actually supported on the current host platform; + // people might be opening a file created on a Windows host, and that + // VM should still start on a Linux host + if (!isAudioDriverAllowedOnThisHost(aa.driverType)) + aa.driverType = getHostDefaultAudioDriver(); + } +} + +/** * Called from MachineConfigFile::readHardware() to read guest property information. * @param elmGuestProperties * @param hw @@ -2414,45 +2469,7 @@ void MachineConfigFile::readHardware(const xml::ElementNode &elmHardware, ) readParallelPorts(*pelmHwChild, hw.llParallelPorts); else if (pelmHwChild->nameEquals("AudioAdapter")) - { - pelmHwChild->getAttributeValue("enabled", hw.audioAdapter.fEnabled); - - Utf8Str strTemp; - if (pelmHwChild->getAttributeValue("controller", strTemp)) - { - if (strTemp == "SB16") - hw.audioAdapter.controllerType = AudioControllerType_SB16; - else if (strTemp == "AC97") - hw.audioAdapter.controllerType = AudioControllerType_AC97; - else - throw ConfigFileError(this, pelmHwChild, N_("Invalid value '%s' in AudioAdapter/@controller attribute"), strTemp.c_str()); - } - if (pelmHwChild->getAttributeValue("driver", strTemp)) - { - // settings before 1.3 used lower case so make sure this is case-insensitive - strTemp.toUpper(); - if (strTemp == "NULL") - hw.audioAdapter.driverType = AudioDriverType_Null; - else if (strTemp == "WINMM") - hw.audioAdapter.driverType = AudioDriverType_WinMM; - else if ( (strTemp == "DIRECTSOUND") || (strTemp == "DSOUND") ) - hw.audioAdapter.driverType = AudioDriverType_DirectSound; - else if (strTemp == "SOLAUDIO") - hw.audioAdapter.driverType = AudioDriverType_SolAudio; - else if (strTemp == "ALSA") - hw.audioAdapter.driverType = AudioDriverType_ALSA; - else if (strTemp == "PULSE") - hw.audioAdapter.driverType = AudioDriverType_Pulse; - else if (strTemp == "OSS") - hw.audioAdapter.driverType = AudioDriverType_OSS; - else if (strTemp == "COREAUDIO") - hw.audioAdapter.driverType = AudioDriverType_CoreAudio; - else if (strTemp == "MMPM") - hw.audioAdapter.driverType = AudioDriverType_MMPM; - else - throw ConfigFileError(this, pelmHwChild, N_("Invalid value '%s' in AudioAdapter/@driver attribute"), strTemp.c_str()); - } - } + readAudioAdapter(*pelmHwChild, hw.audioAdapter); else if (pelmHwChild->nameEquals("SharedFolders")) { xml::NodesLoop nl2(*pelmHwChild, "SharedFolder"); @@ -3551,6 +3568,8 @@ void MachineConfigFile::buildNetworkXML(NetworkAttachmentType_T mode, xml::ElementNode *pelmNAT; pelmNAT = elmParent.createChild("NAT"); + if (nic.nat.strNetwork.length()) + pelmNAT->setAttribute("network", nic.nat.strNetwork); if (nic.nat.strBindIP.length()) pelmNAT->setAttribute("hostip", nic.nat.strBindIP); if (nic.nat.u32Mtu) @@ -3905,6 +3924,108 @@ void MachineConfigFile::buildMachineXML(xml::ElementNode &elmMachine, } /** + * Returns true only if the given AudioDriverType is supported on + * the current host platform. For example, this would return false + * for AudioDriverType_DirectSound when compiled on a Linux host. + * @param drv AudioDriverType_* enum to test. + * @return true only if the current host supports that driver. + */ +/*static*/ +bool MachineConfigFile::isAudioDriverAllowedOnThisHost(AudioDriverType_T drv) +{ + switch (drv) + { + case AudioDriverType_Null: +#ifdef RT_OS_WINDOWS +# ifdef VBOX_WITH_WINMM + case AudioDriverType_WinMM: +# endif + case AudioDriverType_DirectSound: +#endif /* RT_OS_WINDOWS */ +#ifdef RT_OS_SOLARIS + case AudioDriverType_SolAudio: +#endif +#ifdef RT_OS_LINUX +# ifdef VBOX_WITH_ALSA + case AudioDriverType_ALSA: +# endif +# ifdef VBOX_WITH_PULSE + case AudioDriverType_Pulse: +# endif +#endif /* RT_OS_LINUX */ +#if defined (RT_OS_LINUX) || defined (RT_OS_FREEBSD) || defined(VBOX_WITH_SOLARIS_OSS) + case AudioDriverType_OSS: +#endif +#ifdef RT_OS_FREEBSD +# ifdef VBOX_WITH_PULSE + case AudioDriverType_Pulse: +# endif +#endif +#ifdef RT_OS_DARWIN + case AudioDriverType_CoreAudio: +#endif +#ifdef RT_OS_OS2 + case AudioDriverType_MMPM: +#endif + return true; + } + + return false; +} + +/** + * Returns the AudioDriverType_* which should be used by default on this + * host platform. On Linux, this will check at runtime whether PulseAudio + * or ALSA are actually supported on the first call. + * @return + */ +/*static*/ +AudioDriverType_T MachineConfigFile::getHostDefaultAudioDriver() +{ +#if defined(RT_OS_WINDOWS) +# ifdef VBOX_WITH_WINMM + return AudioDriverType_WinMM; +# else /* VBOX_WITH_WINMM */ + return AudioDriverType_DirectSound; +# endif /* !VBOX_WITH_WINMM */ +#elif defined(RT_OS_SOLARIS) + return AudioDriverType_SolAudio; +#elif defined(RT_OS_LINUX) + // on Linux, we need to check at runtime what's actually supported... + static RTLockMtx s_mtx; + static AudioDriverType_T s_linuxDriver = -1; + RTLock lock(s_mtx); + if (s_linuxDriver == (AudioDriverType_T)-1) + { +# if defined(VBOX_WITH_PULSE) + /* Check for the pulse library & that the pulse audio daemon is running. */ + if (RTProcIsRunningByName("pulseaudio") && + RTLdrIsLoadable("libpulse.so.0")) + s_linuxDriver = AudioDriverType_Pulse; + else +# endif /* VBOX_WITH_PULSE */ +# if defined(VBOX_WITH_ALSA) + /* Check if we can load the ALSA library */ + if (RTLdrIsLoadable("libasound.so.2")) + s_linuxDriver = AudioDriverType_ALSA; + else +# endif /* VBOX_WITH_ALSA */ + s_linuxDriver = AudioDriverType_OSS; + } + return s_linuxDriver; +// end elif defined(RT_OS_LINUX) +#elif defined(RT_OS_DARWIN) + return AudioDriverType_CoreAudio; +#elif defined(RT_OS_OS2) + return AudioDriverType_MMP; +#elif defined(RT_OS_FREEBSD) + return AudioDriverType_OSS; +#else + return AudioDriverType_Null; +#endif +} + +/** * Called from write() before calling ConfigFileBase::createStubDocument(). * This adjusts the settings version in m->sv if incompatible settings require * a settings bump, whereas otherwise we try to preserve the settings version @@ -3958,7 +4079,7 @@ void MachineConfigFile::bumpSettingsVersionIfNeeded() ++it2) { // we can only write the StorageController/@Instance attribute with v1.9 - if (sctl.ulInstance != 0) + if (sctl.ulInstance != 0) { if (m->sv < SettingsVersion_v1_9) m->sv = SettingsVersion_v1_9; diff --git a/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp b/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp index 91c46637d..d6f75ace0 100644 --- a/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp +++ b/src/VBox/NetworkServices/NetLib/VBoxNetUDP.cpp @@ -122,7 +122,7 @@ void *VBoxNetUDPMatch(PINTNETBUF pBuf, unsigned uDstPort, PCRTMAC pDstMac, uint3 * are set correctly (they are usually set to 0). */ if (pGso) - PDMNetGsoPrepForDirectUse(pGso, (void *)pvFrame, cbFrame, false /*fPayloadChecksum*/); + PDMNetGsoPrepForDirectUse(pGso, (void *)pvFrame, cbFrame, PDMNETCSUMTYPE_NONE); /* * IP validation and matching. diff --git a/src/VBox/Runtime/common/misc/sg.cpp b/src/VBox/Runtime/common/misc/sg.cpp index f5f1ad8f7..d49c947ae 100644 --- a/src/VBox/Runtime/common/misc/sg.cpp +++ b/src/VBox/Runtime/common/misc/sg.cpp @@ -36,7 +36,7 @@ static void *sgBufGet(PRTSGBUF pSgBuf, size_t *pcbData) { size_t cbData = RT_MIN(*pcbData, pSgBuf->cbSegLeft); - void *pvBuf = pSgBuf->pvSegCurr; + void *pvBuf = pSgBuf->pvSegCur; pSgBuf->cbSegLeft -= cbData; @@ -45,37 +45,38 @@ static void *sgBufGet(PRTSGBUF pSgBuf, size_t *pcbData) { pSgBuf->idxSeg++; - if (RT_UNLIKELY(pSgBuf->idxSeg == pSgBuf->cSeg)) + if (RT_UNLIKELY(pSgBuf->idxSeg == pSgBuf->cSegs)) { pSgBuf->cbSegLeft = 0; - pSgBuf->pvSegCurr = NULL; + pSgBuf->pvSegCur = NULL; } else { - pSgBuf->pvSegCurr = pSgBuf->pcaSeg[pSgBuf->idxSeg].pvSeg; - pSgBuf->cbSegLeft = pSgBuf->pcaSeg[pSgBuf->idxSeg].cbSeg; + pSgBuf->pvSegCur = pSgBuf->paSegs[pSgBuf->idxSeg].pvSeg; + pSgBuf->cbSegLeft = pSgBuf->paSegs[pSgBuf->idxSeg].cbSeg; } *pcbData = cbData; } else - pSgBuf->pvSegCurr = (void *)((uintptr_t)pSgBuf->pvSegCurr + cbData); + pSgBuf->pvSegCur = (uint8_t *)pSgBuf->pvSegCur + cbData; return pvBuf; } -RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG pcaSeg, unsigned cSeg) +RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG paSegs, size_t cSegs) { - AssertPtrReturnVoid(pSgBuf); - AssertPtrReturnVoid(pcaSeg); - AssertReturnVoid(cSeg > 0); + AssertPtr(pSgBuf); + AssertPtr(paSegs); + Assert(cSegs > 0); + Assert(cSegs < (~(unsigned)0 >> 1)); - pSgBuf->pcaSeg = pcaSeg; - pSgBuf->cSeg = cSeg; + pSgBuf->paSegs = paSegs; + pSgBuf->cSegs = (unsigned)cSegs; pSgBuf->idxSeg = 0; - pSgBuf->pvSegCurr = pcaSeg[0].pvSeg; - pSgBuf->cbSegLeft = pcaSeg[0].cbSeg; + pSgBuf->pvSegCur = paSegs[0].pvSeg; + pSgBuf->cbSegLeft = paSegs[0].cbSeg; } @@ -84,20 +85,20 @@ RTDECL(void) RTSgBufReset(PRTSGBUF pSgBuf) AssertPtrReturnVoid(pSgBuf); pSgBuf->idxSeg = 0; - pSgBuf->pvSegCurr = pSgBuf->pcaSeg[0].pvSeg; - pSgBuf->cbSegLeft = pSgBuf->pcaSeg[0].cbSeg; + pSgBuf->pvSegCur = pSgBuf->paSegs[0].pvSeg; + pSgBuf->cbSegLeft = pSgBuf->paSegs[0].cbSeg; } RTDECL(void) RTSgBufClone(PRTSGBUF pSgBufTo, PCRTSGBUF pSgBufFrom) { - AssertPtrReturnVoid(pSgBufTo); - AssertPtrReturnVoid(pSgBufFrom); + AssertPtr(pSgBufTo); + AssertPtr(pSgBufFrom); - pSgBufTo->pcaSeg = pSgBufFrom->pcaSeg; - pSgBufTo->cSeg = pSgBufFrom->cSeg; + pSgBufTo->paSegs = pSgBufFrom->paSegs; + pSgBufTo->cSegs = pSgBufFrom->cSegs; pSgBufTo->idxSeg = pSgBufFrom->idxSeg; - pSgBufTo->pvSegCurr = pSgBufFrom->pvSegCurr; + pSgBufTo->pvSegCur = pSgBufFrom->pvSegCur; pSgBufTo->cbSegLeft = pSgBufFrom->cbSegLeft; } diff --git a/src/VBox/Runtime/common/string/utf-8.cpp b/src/VBox/Runtime/common/string/utf-8.cpp index d6cbb28ba..cfc39e2dc 100644 --- a/src/VBox/Runtime/common/string/utf-8.cpp +++ b/src/VBox/Runtime/common/string/utf-8.cpp @@ -327,6 +327,29 @@ RTDECL(bool) RTStrIsValidEncoding(const char *psz) RT_EXPORT_SYMBOL(RTStrIsValidEncoding); +RTDECL(size_t) RTStrPurgeEncoding(char *psz) +{ + size_t cErrors = 0; + for (;;) + { + RTUNICP Cp; + int rc = RTStrGetCpEx((const char **)&psz, &Cp); + if (RT_SUCCESS(rc)) + { + if (!Cp) + break; + } + else + { + psz[-1] = '?'; + cErrors++; + } + } + return cErrors; +} +RT_EXPORT_SYMBOL(RTStrPurgeEncoding); + + RTDECL(int) RTStrToUni(const char *pszString, PRTUNICP *ppaCps) { /* diff --git a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp index e9dd1e913..875780ed3 100644 --- a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp +++ b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp @@ -224,6 +224,14 @@ int rtR0InitNative(void) g_cbrtNtPbQuantumEnd = 1; g_offrtNtPbDpcQueueDepth = 0x3400 + 0x18; } + /* Windows7.7600.16539.amd64fre.win7_gdr.100226-1909 */ + else if ( BuildNumber == 7600 + && !memcmp(&pbPrcb[0x4bb8], &u.szVendor[0], 4*3)) + { + g_offrtNtPbQuantumEnd = 0x21d9; + g_cbrtNtPbQuantumEnd = 1; + g_offrtNtPbDpcQueueDepth = 0x2180 + 0x18; + } #else # error "port me" diff --git a/src/VBox/Runtime/r3/socket.cpp b/src/VBox/Runtime/r3/socket.cpp index 9f3caa48e..4e7fbba89 100644 --- a/src/VBox/Runtime/r3/socket.cpp +++ b/src/VBox/Runtime/r3/socket.cpp @@ -51,6 +51,7 @@ #include "internal/iprt.h" #include <iprt/socket.h> +#include <iprt/alloca.h> #include <iprt/asm.h> #include <iprt/assert.h> #include <iprt/err.h> @@ -585,70 +586,103 @@ RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf) AssertPtrReturn(pThis, VERR_INVALID_HANDLE); AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); AssertPtrReturn(pSgBuf, VERR_INVALID_PARAMETER); - AssertReturn(pSgBuf->cSeg > 0, VERR_INVALID_PARAMETER); + AssertReturn(pSgBuf->cSegs > 0, VERR_INVALID_PARAMETER); AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); /* * Construct message descriptor (translate pSgBuf) and send it. */ - int rc = VINF_SUCCESS; - do - { + int rc = VERR_NO_TMP_MEMORY; #ifdef RT_OS_WINDOWS - AssertCompileSize(WSABUF, sizeof(RTSGSEG)); - AssertCompileMemberSize(WSABUF, buf, RT_SIZEOFMEMB(RTSGSEG, pvSeg)); + AssertCompileSize(WSABUF, sizeof(RTSGSEG)); + AssertCompileMemberSize(WSABUF, buf, RT_SIZEOFMEMB(RTSGSEG, pvSeg)); - LPWSABUF paMsg = (LPWSABUF)RTMemTmpAllocZ(pSgBuf->cSeg * sizeof(WSABUF)); - AssertPtrBreakStmt(paMsg, rc = VERR_NO_MEMORY); - for (unsigned i = 0; i < pSgBuf->cSeg; i++) + LPWSABUF paMsg = (LPWSABUF)RTMemTmpAllocZ(pSgBuf->cSegs * sizeof(WSABUF)); + if (paMsg) + { + for (unsigned i = 0; i < pSgBuf->cSegs; i++) { - paMsg[i].buf = (char *)pSgBuf->pcaSeg[i].pvSeg; - paMsg[i].len = (u_long)pSgBuf->pcaSeg[i].cbSeg; + paMsg[i].buf = (char *)pSgBuf->paSegs[i].pvSeg; + paMsg[i].len = (u_long)pSgBuf->paSegs[i].cbSeg; } DWORD dwSent; - int hrc = WSASend(pThis->hNative, paMsg, pSgBuf->cSeg, &dwSent, + int hrc = WSASend(pThis->hNative, paMsg, pSgBuf->cSegs, &dwSent, MSG_NOSIGNAL, NULL, NULL); - ssize_t cbWritten; if (!hrc) - { - /* avoid overflowing ssize_t, the exact value isn't important */ - cbWritten = RT_MIN(dwSent, INT_MAX); - } + rc = VINF_SUCCESS; +/** @todo check for incomplete writes */ else - cbWritten = -1; -#else - AssertCompileSize(struct iovec, sizeof(RTSGSEG)); - AssertCompileMemberSize(struct iovec, iov_base, RT_SIZEOFMEMB(RTSGSEG, pvSeg)); - AssertCompileMemberSize(struct iovec, iov_len, RT_SIZEOFMEMB(RTSGSEG, cbSeg)); + rc = rtSocketError(); - struct iovec *paMsg = (struct iovec *)RTMemTmpAllocZ(pSgBuf->cSeg * sizeof(struct iovec)); - AssertPtrBreakStmt(paMsg, rc = VERR_NO_MEMORY); - for (unsigned i = 0; i < pSgBuf->cSeg; i++) + RTMemTmpFree(paMsg); + } + +#else /* !RT_OS_WINDOWS */ + AssertCompileSize(struct iovec, sizeof(RTSGSEG)); + AssertCompileMemberSize(struct iovec, iov_base, RT_SIZEOFMEMB(RTSGSEG, pvSeg)); + AssertCompileMemberSize(struct iovec, iov_len, RT_SIZEOFMEMB(RTSGSEG, cbSeg)); + + struct iovec *paMsg = (struct iovec *)RTMemTmpAllocZ(pSgBuf->cSegs * sizeof(struct iovec)); + if (paMsg) + { + for (unsigned i = 0; i < pSgBuf->cSegs; i++) { - paMsg[i].iov_base = pSgBuf->pcaSeg[i].pvSeg; - paMsg[i].iov_len = pSgBuf->pcaSeg[i].cbSeg; + paMsg[i].iov_base = pSgBuf->paSegs[i].pvSeg; + paMsg[i].iov_len = pSgBuf->paSegs[i].cbSeg; } struct msghdr msgHdr; - memset(&msgHdr, '\0', sizeof(msgHdr)); - msgHdr.msg_iov = paMsg; - msgHdr.msg_iovlen = pSgBuf->cSeg; + RT_ZERO(msgHdr); + msgHdr.msg_iov = paMsg; + msgHdr.msg_iovlen = pSgBuf->cSegs; ssize_t cbWritten = sendmsg(pThis->hNative, &msgHdr, MSG_NOSIGNAL); -#endif - - RTMemTmpFree(paMsg); if (RT_LIKELY(cbWritten >= 0)) rc = VINF_SUCCESS; +/** @todo check for incomplete writes */ else rc = rtSocketError(); - } while (0); + + RTMemTmpFree(paMsg); + } +#endif /* !RT_OS_WINDOWS */ rtSocketUnlock(pThis); return rc; } +RTDECL(int) RTSocketSgWriteL(RTSOCKET hSocket, size_t cSegs, ...) +{ + va_list va; + va_start(va, cSegs); + int rc = RTSocketSgWriteLV(hSocket, cSegs, va); + va_end(va); + return rc; +} + + +RTDECL(int) RTSocketSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va) +{ + /* + * Set up a S/G segment array + buffer on the stack and pass it + * on to RTSocketSgWrite. + */ + Assert(cSegs <= 16); + PRTSGSEG paSegs = (PRTSGSEG)alloca(cSegs * sizeof(RTSGSEG)); + AssertReturn(paSegs, VERR_NO_TMP_MEMORY); + for (size_t i = 0; i < cSegs; i++) + { + paSegs[i].pvSeg = va_arg(va, void *); + paSegs[i].cbSeg = va_arg(va, size_t); + } + + RTSGBUF SgBuf; + RTSgBufInit(&SgBuf, paSegs, cSegs); + return RTSocketSgWrite(hSocket, &SgBuf); +} + + RTDECL(int) RTSocketSelectOne(RTSOCKET hSocket, RTMSINTERVAL cMillies) { /* diff --git a/src/VBox/Runtime/r3/tcp.cpp b/src/VBox/Runtime/r3/tcp.cpp index 05b6dc7b8..e333e71d3 100644 --- a/src/VBox/Runtime/r3/tcp.cpp +++ b/src/VBox/Runtime/r3/tcp.cpp @@ -1019,3 +1019,19 @@ RTR3DECL(int) RTTcpSgWrite(RTSOCKET Sock, PCRTSGBUF pSgBuf) return RTSocketSgWrite(Sock, pSgBuf); } + +RTR3DECL(int) RTTcpSgWriteL(RTSOCKET hSocket, size_t cSegs, ...) +{ + va_list va; + va_start(va, cSegs); + int rc = RTSocketSgWriteLV(hSocket, cSegs, va); + va_end(va); + return rc; +} + + +RTR3DECL(int) RTTcpSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va) +{ + return RTSocketSgWriteLV(hSocket, cSegs, va); +} + diff --git a/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp b/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp index b1d92a710..daf872458 100644 --- a/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp +++ b/src/VBox/Runtime/testcase/tstRTStrAlloc.cpp @@ -42,7 +42,7 @@ static void tst1(void) { RTTestISub("Basics"); char *psz; - int rc; + int rc = VINF_SUCCESS; /* RTStrAlloc */ RTTESTI_CHECK(psz = RTStrAlloc(0)); diff --git a/src/VBox/Runtime/testcase/tstUtf8.cpp b/src/VBox/Runtime/testcase/tstUtf8.cpp index 6dcf55afb..cb55786e8 100644 --- a/src/VBox/Runtime/testcase/tstUtf8.cpp +++ b/src/VBox/Runtime/testcase/tstUtf8.cpp @@ -790,6 +790,63 @@ void TstRTStrXCmp(RTTEST hTest) /** + * Check case insensitivity. + */ +void TstRTStrPurgeEncoding(RTTEST hTest) +{ + RTTestSub(hTest, "RTStrPurgeEncoding"); + + /* + * Test some good strings. + */ + char sz1[] = "1234567890wertyuiopsdfghjklzxcvbnm"; + char sz1Copy[sizeof(sz1)]; + memcpy(sz1Copy, sz1, sizeof(sz1)); + + RTTESTI_CHECK_RETV(RTStrPurgeEncoding(sz1) == 0); + RTTESTI_CHECK_RETV(!memcmp(sz1, sz1Copy, sizeof(sz1))); + + char *pszAll = RTStrDup(g_szAll); + if (pszAll) + { + RTTESTI_CHECK(RTStrPurgeEncoding(pszAll) == 0); + RTTESTI_CHECK(!memcmp(pszAll, g_szAll, sizeof(g_szAll))); + RTStrFree(pszAll); + } + + /* + * Test some bad stuff. + */ + struct + { + size_t cErrors; + unsigned char szIn[5]; + const char *pszExpect; + } aTests[] = + { + { 0, { '1', '2', '3', '4', '\0' }, "1234" }, + { 1, { 0x80, '2', '3', '4', '\0' }, "?234" }, + { 1, { '1', 0x80, '3', '4', '\0' }, "1?34" }, + { 1, { '1', '2', 0x80, '4', '\0' }, "12?4" }, + { 1, { '1', '2', '3', 0x80, '\0' }, "123?" }, + { 2, { 0x80, 0x81, '3', '4', '\0' }, "??34" }, + { 2, { '1', 0x80, 0x81, '4', '\0' }, "1??4" }, + { 2, { '1', '2', 0x80, 0x81, '\0' }, "12??" }, + }; + for (size_t i = 0; i < RT_ELEMENTS(aTests); i++) + { + size_t cErrors = RTStrPurgeEncoding((char *)aTests[i].szIn); + if (cErrors != aTests[i].cErrors) + RTTestFailed(hTest, "#%u: cErrors=%u expected %u\n", i, cErrors, aTests[i].cErrors); + else if (strcmp((char *)aTests[i].szIn, aTests[i].pszExpect)) + RTTestFailed(hTest, "#%u: %.5Rhxs expected %.5Rhxs (%s)\n", i, aTests[i].szIn, aTests[i].pszExpect, aTests[i].pszExpect); + } + + RTTestSubDone(hTest); +} + + +/** * Benchmark stuff. */ void Benchmarks(RTTEST hTest) @@ -1234,6 +1291,7 @@ int main() test2(hTest); test3(hTest); TstRTStrXCmp(hTest); + TstRTStrPurgeEncoding(hTest); testStrEnd(hTest); testStrStr(hTest); testMinistring(hTest); diff --git a/src/VBox/VMM/EM.cpp b/src/VBox/VMM/EM.cpp index fa5d23235..42ca9157e 100644 --- a/src/VBox/VMM/EM.cpp +++ b/src/VBox/VMM/EM.cpp @@ -942,7 +942,7 @@ static int emR3RemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone) * We might have missed the raising of VMREQ, TIMER and some other * imporant FFs while we were busy switching the state. So, check again. */ - if ( VM_FF_ISPENDING(pVM, VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_DBGF | VM_FF_TERMINATE | VM_FF_RESET) + if ( VM_FF_ISPENDING(pVM, VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_DBGF | VM_FF_CHECK_VM_STATE | VM_FF_RESET) || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TIMER | VMCPU_FF_REQUEST)) { LogFlow(("emR3RemExecute: Skipping run, because FF is set. %#x\n", pVM->fGlobalForcedActions)); @@ -1299,13 +1299,27 @@ int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc) } /* - * Termination request. + * State change request (cleared by vmR3SetStateLocked). */ - if (VM_FF_ISPENDING(pVM, VM_FF_TERMINATE)) + if (VM_FF_ISPENDING(pVM, VM_FF_CHECK_VM_STATE)) { - Log2(("emR3ForcedActions: returns VINF_EM_TERMINATE\n")); - STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a); - return VINF_EM_TERMINATE; + VMSTATE enmState = VMR3GetState(pVM); + switch (enmState) + { + case VMSTATE_FATAL_ERROR: + case VMSTATE_FATAL_ERROR_LS: + Log2(("emR3ForcedActions: %s -> VINF_EM_SUSPEND\n", VMGetStateName(enmState) )); + STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a); + return VINF_EM_SUSPEND; + + case VMSTATE_DESTROYING: + Log2(("emR3ForcedActions: %s -> VINF_EM_TERMINATE\n", VMGetStateName(enmState) )); + STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a); + return VINF_EM_TERMINATE; + + default: + AssertMsgFailed(("%s\n", VMGetStateName(enmState))); + } } /* @@ -1353,7 +1367,7 @@ int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc) } /* check that we got them all */ - AssertCompile(VM_FF_NORMAL_PRIORITY_POST_MASK == (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS)); + AssertCompile(VM_FF_NORMAL_PRIORITY_POST_MASK == (VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS)); AssertCompile(VMCPU_FF_NORMAL_PRIORITY_POST_MASK == VMCPU_FF_CSAM_SCAN_PAGE); } @@ -1566,7 +1580,7 @@ int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc) { rc2 = VMMR3EmtRendezvousFF(pVM, pVCpu); UPDATE_RC(); - /** @todo HACK ALERT! The following test is to make sure EM+TM things the VM is + /** @todo HACK ALERT! The following test is to make sure EM+TM thinks the VM is * stopped/reset before the next VM state change is made. We need a better * solution for this, or at least make it possible to do: (rc >= VINF_EM_FIRST * && rc >= VINF_EM_SUSPEND). */ @@ -1579,13 +1593,27 @@ int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc) } /* - * Termination request. + * State change request (cleared by vmR3SetStateLocked). */ - if (VM_FF_ISPENDING(pVM, VM_FF_TERMINATE)) + if (VM_FF_ISPENDING(pVM, VM_FF_CHECK_VM_STATE)) { - Log2(("emR3ForcedActions: returns VINF_EM_TERMINATE\n")); - STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a); - return VINF_EM_TERMINATE; + VMSTATE enmState = VMR3GetState(pVM); + switch (enmState) + { + case VMSTATE_FATAL_ERROR: + case VMSTATE_FATAL_ERROR_LS: + Log2(("emR3ForcedActions: %s -> VINF_EM_SUSPEND\n", VMGetStateName(enmState) )); + STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a); + return VINF_EM_SUSPEND; + + case VMSTATE_DESTROYING: + Log2(("emR3ForcedActions: %s -> VINF_EM_TERMINATE\n", VMGetStateName(enmState) )); + STAM_REL_PROFILE_STOP(&pVCpu->em.s.StatForcedActions, a); + return VINF_EM_TERMINATE; + + default: + AssertMsgFailed(("%s\n", VMGetStateName(enmState))); + } } /* @@ -1621,7 +1649,7 @@ int emR3ForcedActions(PVM pVM, PVMCPU pVCpu, int rc) #endif /* check that we got them all */ - AssertCompile(VM_FF_HIGH_PRIORITY_PRE_MASK == (VM_FF_TM_VIRTUAL_SYNC | VM_FF_DBGF | VM_FF_TERMINATE | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS)); + AssertCompile(VM_FF_HIGH_PRIORITY_PRE_MASK == (VM_FF_TM_VIRTUAL_SYNC | VM_FF_DBGF | VM_FF_CHECK_VM_STATE | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS)); AssertCompile(VMCPU_FF_HIGH_PRIORITY_PRE_MASK == (VMCPU_FF_TIMER | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS)); } diff --git a/src/VBox/VMM/PDMAsyncCompletion.cpp b/src/VBox/VMM/PDMAsyncCompletion.cpp index ae17738b7..2802cefe5 100644 --- a/src/VBox/VMM/PDMAsyncCompletion.cpp +++ b/src/VBox/VMM/PDMAsyncCompletion.cpp @@ -883,7 +883,7 @@ VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT AssertReturn(VALID_PTR(pTemplate), VERR_INVALID_POINTER); /* Check that the flags are valid. */ - AssertReturn(((~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_CACHING) & fFlags) == 0), + AssertReturn(((~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_CACHING | PDMACEP_FILE_FLAGS_DONT_LOCK) & fFlags) == 0), VERR_INVALID_PARAMETER); PVM pVM = pTemplate->pVM; diff --git a/src/VBox/VMM/PDMAsyncCompletionFile.cpp b/src/VBox/VMM/PDMAsyncCompletionFile.cpp index 94a55cb42..2eb7fbafa 100644 --- a/src/VBox/VMM/PDMAsyncCompletionFile.cpp +++ b/src/VBox/VMM/PDMAsyncCompletionFile.cpp @@ -794,12 +794,32 @@ static int pdmacFileEpInitialize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, PDMACEPFILEMGRTYPE enmMgrType = pEpClassFile->enmMgrTypeOverride; PDMACFILEEPBACKEND enmEpBackend = pEpClassFile->enmEpBackendDefault; - AssertMsgReturn((fFlags & ~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_CACHING)) == 0, + AssertMsgReturn((fFlags & ~(PDMACEP_FILE_FLAGS_READ_ONLY | PDMACEP_FILE_FLAGS_CACHING | PDMACEP_FILE_FLAGS_DONT_LOCK)) == 0, ("PDMAsyncCompletion: Invalid flag specified\n"), VERR_INVALID_PARAMETER); - unsigned fFileFlags = fFlags & PDMACEP_FILE_FLAGS_READ_ONLY - ? RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE - : RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE; + unsigned fFileFlags = RTFILE_O_OPEN; + + if (fFlags & PDMACEP_FILE_FLAGS_READ_ONLY) + fFileFlags |= RTFILE_O_READ | RTFILE_O_DENY_NONE; + else + { + fFileFlags |= RTFILE_O_READWRITE; + + /* + * Opened in read/write mode. Check whether the caller wants to + * avoid the lock. Return an error in case caching is enabled + * because this can lead to data corruption. + */ + if (fFlags & PDMACEP_FILE_FLAGS_DONT_LOCK) + { + if (fFlags & PDMACEP_FILE_FLAGS_CACHING) + return VERR_NOT_SUPPORTED; + else + fFileFlags |= RTFILE_O_DENY_NONE; + } + else + fFileFlags |= RTFILE_O_DENY_WRITE; + } if (enmMgrType == PDMACEPFILEMGRTYPE_ASYNC) fFileFlags |= RTFILE_O_ASYNC_IO; diff --git a/src/VBox/VMM/PGMInternal.h b/src/VBox/VMM/PGMInternal.h index 28030f8e1..323771630 100644 --- a/src/VBox/VMM/PGMInternal.h +++ b/src/VBox/VMM/PGMInternal.h @@ -3369,6 +3369,7 @@ int pgmPhysGCPhys2CCPtrInternal(PVM pVM, PPGMPAGE pPage, RTGCPHYS GC int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, const void **ppv); VMMDECL(int) pgmPhysHandlerRedirectToHC(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser); VMMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser); +int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys); #ifdef IN_RING3 void pgmR3PhysRelinkRamRanges(PVM pVM); int pgmR3PhysRamPreAllocate(PVM pVM); diff --git a/src/VBox/VMM/PGMPhys.cpp b/src/VBox/VMM/PGMPhys.cpp index 78e4210cc..a62b592a6 100644 --- a/src/VBox/VMM/PGMPhys.cpp +++ b/src/VBox/VMM/PGMPhys.cpp @@ -51,7 +51,6 @@ * Internal Functions * *******************************************************************************/ static DECLCALLBACK(int) pgmR3PhysRomWriteHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser); -static int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys); /* @@ -1403,8 +1402,23 @@ int pgmR3PhysRamReset(PVM pVM) rc = GMMR3ResetSharedModules(pVM); AssertRC(rc); #endif - /* Reset counter. */ + /* Reset counters. */ pVM->pgm.s.cReusedSharedPages = 0; + pVM->pgm.s.cBalloonedPages = 0; + +#if 1 /* temporary code for extra logging */ + { + uint64_t cAllocPages, cMaxPages, cBalloonPages; + + if (GMMR3QueryMemoryStats(pVM, &cAllocPages, &cMaxPages, &cBalloonPages) == VINF_SUCCESS) + { + LogRel(("GMM: Statistics:\n" + " Allocated pages: %RX64\n" + " Maximum pages: %RX64\n" + " Ballooned pages: %RX64\n", cAllocPages, cMaxPages, cBalloonPages)); + } + } +#endif /* * We batch up pages that should be freed instead of calling GMM for @@ -3509,7 +3523,7 @@ VMMR3DECL(int) PGMR3PhysAllocateLargeHandyPage(PVM pVM, RTGCPHYS GCPhys) * - page id (GCPhys) + 1 = page id (GCPhys + PAGE_SIZE) */ rc = pgmPhysPageMapByPageID(pVM, idPage, HCPhys, &pv); - AssertLogRelMsg(RT_SUCCESS(rc), ("idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc", idPage, HCPhys, rc)); + AssertLogRelMsg(RT_SUCCESS(rc), ("idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc\n", idPage, HCPhys, rc)); if (RT_SUCCESS(rc)) { @@ -3610,6 +3624,14 @@ VMMR3DECL(int) PGMR3PhysAllocateHandyPages(PVM pVM) rc = VMMR3CallR0(pVM, VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES, 0, NULL); } + /* todo: we should split this up into an allocate and flush operation. sometimes you want to flush and not allocate more (which will trigger the vm account limit error) */ + if ( rc == VERR_GMM_HIT_VM_ACCOUNT_LIMIT + && pVM->pgm.s.cHandyPages > 0) + { + /* Still handy pages left, so don't panic. */ + rc = VINF_SUCCESS; + } + if (RT_SUCCESS(rc)) { AssertMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); @@ -3625,7 +3647,7 @@ VMMR3DECL(int) PGMR3PhysAllocateHandyPages(PVM pVM) PGMMPAGEDESC pPage = &pVM->pgm.s.aHandyPages[iClear]; void *pv; rc = pgmPhysPageMapByPageID(pVM, pPage->idPage, pPage->HCPhysGCPhys, &pv); - AssertLogRelMsgBreak(RT_SUCCESS(rc), ("idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc", pPage->idPage, pPage->HCPhysGCPhys, rc)); + AssertLogRelMsgBreak(RT_SUCCESS(rc), ("idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc\n", pPage->idPage, pPage->HCPhysGCPhys, rc)); ASMMemZeroPage(pv); iClear++; Log3(("PGMR3PhysAllocateHandyPages: idPage=%#x HCPhys=%RGp\n", pPage->idPage, pPage->HCPhysGCPhys)); @@ -3709,7 +3731,7 @@ VMMR3DECL(int) PGMR3PhysAllocateHandyPages(PVM pVM) * * @remarks The caller must own the PGM lock. */ -static int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys) +int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys) { /* * Assert sanity. diff --git a/src/VBox/VMM/PGMSavedState.cpp b/src/VBox/VMM/PGMSavedState.cpp index 7b2824474..5d5c8b4c7 100644 --- a/src/VBox/VMM/PGMSavedState.cpp +++ b/src/VBox/VMM/PGMSavedState.cpp @@ -2510,17 +2510,38 @@ static int pgmR3LoadMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) uint32_t iPage = UINT32_MAX - 10; PPGMROMRANGE pRom = NULL; PPGMMMIO2RANGE pMmio2 = NULL; + + /* + * We batch up pages that should be freed instead of calling GMM for + * each and every one of them. + */ + uint32_t cPendingPages = 0; + PGMMFREEPAGESREQ pReq; + int rc = GMMR3FreePagesPrepare(pVM, &pReq, 128 /* batch size */, GMMACCOUNT_BASE); + AssertLogRelRCReturn(rc, rc); + for (;;) { /* * Get the record type and flags. */ uint8_t u8; - int rc = SSMR3GetU8(pSSM, &u8); + rc = SSMR3GetU8(pSSM, &u8); if (RT_FAILURE(rc)) return rc; if (u8 == PGM_STATE_REC_END) + { + /* + * Finish off any pages pending freeing. + */ + if (cPendingPages) + { + rc = GMMR3FreePagesPerform(pVM, pReq, cPendingPages); + AssertLogRelRCReturn(rc, rc); + } + GMMR3FreePagesCleanup(pReq); return VINF_SUCCESS; + } AssertLogRelMsgReturn((u8 & ~PGM_STATE_REC_FLAG_ADDR) <= PGM_STATE_REC_LAST, ("%#x\n", u8), VERR_SSM_DATA_UNIT_FORMAT_CHANGED); switch (u8 & ~PGM_STATE_REC_FLAG_ADDR) { @@ -2557,12 +2578,10 @@ static int pgmR3LoadMemory(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass) if ( PGM_PAGE_IS_ZERO(pPage) || PGM_PAGE_IS_BALLOONED(pPage)) break; - /** @todo implement zero page replacing. */ - AssertLogRelMsgReturn(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED, ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_INTERNAL_ERROR_5); - void *pvDstPage; - rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvDstPage); - AssertLogRelMsgRCReturn(rc, ("GCPhys=%RGp %R[pgmpage] rc=%Rrc\n", GCPhys, pPage, rc), rc); - ASMMemZeroPage(pvDstPage); + AssertLogRelMsgReturn(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED, ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_INTERNAL_ERROR_5); + /* Allocated before (prealloc), so free it now. */ + rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys); + AssertRC(rc); break; } diff --git a/src/VBox/VMM/PGMSharedPage.cpp b/src/VBox/VMM/PGMSharedPage.cpp index 6f12e0c0d..75a8d008b 100644 --- a/src/VBox/VMM/PGMSharedPage.cpp +++ b/src/VBox/VMM/PGMSharedPage.cpp @@ -152,7 +152,7 @@ static DECLCALLBACK(VBOXSTRICTRC) pgmR3SharedModuleRegRendezvous(PVM pVM, PVMCPU pgmLock(pVM); rc = GMMR3CheckSharedModules(pVM); pgmUnlock(pVM); - + AssertLogRelRC(rc); return rc; } diff --git a/src/VBox/VMM/VM.cpp b/src/VBox/VMM/VM.cpp index d0de12f34..e70fffaca 100644 --- a/src/VBox/VMM/VM.cpp +++ b/src/VBox/VMM/VM.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2006-2007 Oracle Corporation + * Copyright (C) 2006-2010 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -572,13 +572,16 @@ static int vmR3CreateU(PUVM pUVM, uint32_t cCpus, PFNCFGMCONSTRUCTOR pfnCFGMCons for (VMCPUID i = 0; i < pVM->cCpus; i++) { - pVM->aCpus[i].pUVCpu = &pUVM->aCpus[i]; - pVM->aCpus[i].idCpu = i; - pVM->aCpus[i].hNativeThread = pUVM->aCpus[i].vm.s.NativeThreadEMT; + pVM->aCpus[i].pUVCpu = &pUVM->aCpus[i]; + pVM->aCpus[i].idCpu = i; + pVM->aCpus[i].hNativeThread = pUVM->aCpus[i].vm.s.NativeThreadEMT; Assert(pVM->aCpus[i].hNativeThread != NIL_RTNATIVETHREAD); - pUVM->aCpus[i].pVCpu = &pVM->aCpus[i]; - pUVM->aCpus[i].pVM = pVM; + /* Initialized on the fly by page fusion. */ + pVM->aCpus[i].hNativeThreadR0 = NIL_RTNATIVETHREAD; + + pUVM->aCpus[i].pVCpu = &pVM->aCpus[i]; + pUVM->aCpus[i].pVM = pVM; } @@ -2129,7 +2132,7 @@ VMMR3DECL(int) VMR3PowerOff(PVM pVM) * * @param pVM The handle of the VM which should be destroyed. * - * @thread EMT(0) or any none emulation thread. + * @thread Any none emulation thread. * @vmstate Off, Created * @vmstateto N/A */ @@ -2143,7 +2146,7 @@ VMMR3DECL(int) VMR3Destroy(PVM pVM) if (!pVM) return VERR_INVALID_PARAMETER; VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); - Assert(VMMGetCpuId(pVM) == 0 || VMMGetCpuId(pVM) == NIL_VMCPUID); + AssertLogRelReturn(!VM_IS_EMT(pVM), VERR_VM_THREAD_IS_EMT); /* * Change VM state to destroying and unlink the VM. @@ -2173,33 +2176,15 @@ VMMR3DECL(int) VMR3Destroy(PVM pVM) vmR3AtDtor(pVM); /* - * EMT(0) does the final cleanup, so if we're it calling VMR3Destroy then - * we'll have to postpone parts of it till later. Otherwise, call - * vmR3Destroy on each of the EMTs in ending with EMT(0) doing the bulk + * Call vmR3Destroy on each of the EMTs ending with EMT(0) doing the bulk * of the cleanup. */ - if (VMMGetCpuId(pVM) == 0) - { - pUVM->vm.s.fEMTDoesTheCleanup = true; - pUVM->vm.s.fTerminateEMT = true; - VM_FF_SET(pVM, VM_FF_TERMINATE); - - /* Terminate the other EMTs. */ - for (VMCPUID idCpu = 1; idCpu < pVM->cCpus; idCpu++) - { - rc = VMR3ReqCallWaitU(pUVM, idCpu, (PFNRT)vmR3Destroy, 1, pVM); - AssertLogRelRC(rc); - } - } - else - { - /* vmR3Destroy on all EMTs, ending with EMT(0). */ - rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ALL_REVERSE, (PFNRT)vmR3Destroy, 1, pVM); - AssertLogRelRC(rc); + /* vmR3Destroy on all EMTs, ending with EMT(0). */ + rc = VMR3ReqCallWaitU(pUVM, VMCPUID_ALL_REVERSE, (PFNRT)vmR3Destroy, 1, pVM); + AssertLogRelRC(rc); - /* Wait for EMTs and destroy the UVM. */ - vmR3DestroyUVM(pUVM, 30000); - } + /* Wait for EMTs and destroy the UVM. */ + vmR3DestroyUVM(pUVM, 30000); LogFlow(("VMR3Destroy: returns VINF_SUCCESS\n")); return VINF_SUCCESS; @@ -2228,11 +2213,10 @@ DECLCALLBACK(int) vmR3Destroy(PVM pVM) LogFlow(("vmR3Destroy: pVM=%p pUVM=%p pVCpu=%p idCpu=%u\n", pVM, pUVM, pVCpu, pVCpu->idCpu)); /* - * Only VCPU 0 does the full cleanup. + * Only VCPU 0 does the full cleanup (last). */ if (pVCpu->idCpu == 0) { - /* * Dump statistics to the log. */ @@ -2290,10 +2274,10 @@ DECLCALLBACK(int) vmR3Destroy(PVM pVM) AssertRC(rc); /* - * We're done in this thread (EMT). + * We're done, tell the other EMTs to quit. */ ASMAtomicUoWriteBool(&pUVM->vm.s.fTerminateEMT, true); - ASMAtomicWriteU32(&pVM->fGlobalForcedActions, VM_FF_TERMINATE); + ASMAtomicWriteU32(&pVM->fGlobalForcedActions, VM_FF_CHECK_VM_STATE); /* Can't hurt... */ LogFlow(("vmR3Destroy: returning %Rrc\n", VINF_EM_TERMINATE)); } return VINF_EM_TERMINATE; @@ -2301,54 +2285,10 @@ DECLCALLBACK(int) vmR3Destroy(PVM pVM) /** - * Called at the end of the EMT procedure to take care of the final cleanup. - * - * Currently only EMT(0) will do work here. It will destroy the shared VM - * structure if it is still around. If EMT(0) was the caller of VMR3Destroy it - * will destroy UVM and nothing will be left behind upon exit. But if some - * other thread is calling VMR3Destroy, they will clean up UVM after all EMTs - * has exitted. - * - * @param pUVM The UVM handle. - * @param idCpu The virtual CPU id. - */ -void vmR3DestroyFinalBitFromEMT(PUVM pUVM, VMCPUID idCpu) -{ - /* - * Only EMT(0) has work to do here. - */ - if (idCpu != 0) - return; - Assert( !pUVM->pVM - || VMMGetCpuId(pUVM->pVM) == 0); - - /* - * If we have a shared VM structure, change its state to Terminated and - * tell GVMM to destroy it. - */ - if (pUVM->pVM) - { - vmR3SetState(pUVM->pVM, VMSTATE_TERMINATED, VMSTATE_DESTROYING); - int rc = SUPR3CallVMMR0Ex(pUVM->pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL); - AssertLogRelRC(rc); - pUVM->pVM = NULL; - } - - /* - * If EMT(0) called VMR3Destroy, then it will destroy UVM as well. - */ - if (pUVM->vm.s.fEMTDoesTheCleanup) - vmR3DestroyUVM(pUVM, 30000); -} - - -/** * Destroys the UVM portion. * * This is called as the final step in the VM destruction or as the cleanup - * in case of a creation failure. If EMT(0) called VMR3Destroy, meaning - * VMINTUSERPERVM::fEMTDoesTheCleanup is true, it will call this as - * vmR3DestroyFinalBitFromEMT completes. + * in case of a creation failure. * * @param pVM VM Handle. * @param cMilliesEMTWait The number of milliseconds to wait for the emulation @@ -2362,11 +2302,10 @@ static void vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait) */ /* Signal them. */ ASMAtomicUoWriteBool(&pUVM->vm.s.fTerminateEMT, true); + if (pUVM->pVM) + VM_FF_SET(pUVM->pVM, VM_FF_CHECK_VM_STATE); /* Can't hurt... */ for (VMCPUID i = 0; i < pUVM->cCpus; i++) { - ASMAtomicUoWriteBool(&pUVM->aCpus[i].vm.s.fTerminateEMT, true); - if (pUVM->pVM) - VM_FF_SET(pUVM->pVM, VM_FF_TERMINATE); VMR3NotifyGlobalFFU(pUVM, VMNOTIFYFF_FLAGS_DONE_REM); RTSemEventSignal(pUVM->aCpus[i].vm.s.EventSemWait); } @@ -3088,6 +3027,7 @@ static void vmR3SetStateLocked(PVM pVM, PUVM pUVM, VMSTATE enmStateNew, VMSTATE ("%s != %s\n", VMR3GetStateName(pVM->enmVMState), VMR3GetStateName(enmStateOld))); pUVM->vm.s.enmPrevVMState = enmStateOld; pVM->enmVMState = enmStateNew; + VM_FF_CLEAR(pVM, VM_FF_CHECK_VM_STATE); vmR3DoAtState(pVM, pUVM, enmStateNew, enmStateOld); } @@ -3236,6 +3176,17 @@ void vmR3SetGuruMeditation(PVM pVM) /** + * Called by vmR3EmulationThreadWithId just before the VM structure is freed. + * + * @param pVM The VM handle. + */ +void vmR3SetTerminated(PVM pVM) +{ + vmR3SetState(pVM, VMSTATE_TERMINATED, VMSTATE_DESTROYING); +} + + +/** * Checks if the VM was teleported and hasn't been fully resumed yet. * * This applies to both sides of the teleportation since we may leave a working @@ -3256,7 +3207,7 @@ VMMR3DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM) * Registers a VM state change callback. * * You are not allowed to call any function which changes the VM state from a - * state callback, except VMR3Destroy(). + * state callback. * * @returns VBox status code. * @param pVM VM handle. @@ -3761,8 +3712,8 @@ VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PVM pVM, PFNVMATRUNTIMEERROR pfnAt * EMT rendezvous worker that vmR3SetRuntimeErrorCommon uses to safely change * the state to FatalError(LS). * - * @returns VERR_VM_INVALID_VM_STATE or VINF_SUCCESS. (This is a strict return - * code, see FNVMMEMTRENDEZVOUS.) + * @returns VERR_VM_INVALID_VM_STATE or VINF_EM_SUSPENED. (This is a strict + * return code, see FNVMMEMTRENDEZVOUS.) * * @param pVM The VM handle. * @param pVCpu The VMCPU handle of the EMT. @@ -3773,12 +3724,24 @@ static DECLCALLBACK(VBOXSTRICTRC) vmR3SetRuntimeErrorChangeState(PVM pVM, PVMCPU NOREF(pVCpu); Assert(!pvUser); NOREF(pvUser); - int rc = vmR3TrySetState(pVM, "VMSetRuntimeError", 2, - VMSTATE_FATAL_ERROR, VMSTATE_RUNNING, - VMSTATE_FATAL_ERROR_LS, VMSTATE_RUNNING_LS); - if (rc == 2) - SSMR3Cancel(pVM); - return RT_SUCCESS(rc) ? VINF_SUCCESS : rc; + /* + * The first EMT thru here changes the state. + */ + if (pVCpu->idCpu == pVM->cCpus - 1) + { + int rc = vmR3TrySetState(pVM, "VMSetRuntimeError", 2, + VMSTATE_FATAL_ERROR, VMSTATE_RUNNING, + VMSTATE_FATAL_ERROR_LS, VMSTATE_RUNNING_LS); + if (RT_FAILURE(rc)) + return rc; + if (rc == 2) + SSMR3Cancel(pVM); + + VM_FF_SET(pVM, VM_FF_CHECK_VM_STATE); + } + + /* This'll make sure we get out of whereever we are (e.g. REM). */ + return VINF_EM_SUSPEND; } @@ -3804,7 +3767,8 @@ static int vmR3SetRuntimeErrorCommon(PVM pVM, uint32_t fFlags, const char *pszEr */ int rc; if (fFlags & VMSETRTERR_FLAGS_FATAL) - rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, vmR3SetRuntimeErrorChangeState, NULL); + rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING | VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR, + vmR3SetRuntimeErrorChangeState, NULL); else if (fFlags & VMSETRTERR_FLAGS_SUSPEND) rc = VMR3Suspend(pVM); else diff --git a/src/VBox/VMM/VMEmt.cpp b/src/VBox/VMM/VMEmt.cpp index 4eb00f217..4e186ce65 100644 --- a/src/VBox/VMM/VMEmt.cpp +++ b/src/VBox/VMM/VMEmt.cpp @@ -148,8 +148,7 @@ int vmR3EmulationThreadWithId(RTTHREAD ThreadSelf, PUVMCPU pUVCpu, VMCPUID idCpu */ PVM pVM = pUVM->pVM; enmBefore = pVM->enmVMState; - if ( VM_FF_ISSET(pVM, VM_FF_TERMINATE) - || pUVM->vm.s.fTerminateEMT) + if (pUVM->vm.s.fTerminateEMT) { rc = VINF_EM_TERMINATE; break; @@ -210,9 +209,7 @@ int vmR3EmulationThreadWithId(RTTHREAD ThreadSelf, PUVMCPU pUVCpu, VMCPUID idCpu * Check for termination requests, these have extremely high priority. */ if ( rc == VINF_EM_TERMINATE - || pUVM->vm.s.fTerminateEMT - || ( pUVM->pVM /* pVM may have become invalid by now. */ - && VM_FF_ISSET(pUVM->pVM, VM_FF_TERMINATE))) + || pUVM->vm.s.fTerminateEMT) break; } @@ -241,26 +238,23 @@ int vmR3EmulationThreadWithId(RTTHREAD ThreadSelf, PUVMCPU pUVCpu, VMCPUID idCpu /* * Cleanup and exit. - * If EMT(0) called VMR3Destroy, EMT(0) will do all the terminating here. */ Log(("vmR3EmulationThread: Terminating emulation thread! Thread=%#x pUVM=%p rc=%Rrc enmBefore=%d enmVMState=%d\n", ThreadSelf, pUVM, rc, enmBefore, pUVM->pVM ? pUVM->pVM->enmVMState : VMSTATE_TERMINATED)); - if ( pUVM->vm.s.fEMTDoesTheCleanup - && idCpu == 0) + if ( idCpu == 0 + && pUVM->pVM) { - Log(("vmR3EmulationThread: executing delayed Destroy\n")); - Assert(pUVM->pVM); - vmR3Destroy(pUVM->pVM); - vmR3DestroyFinalBitFromEMT(pUVM, idCpu); - /* The pUVM structure is now invliad. */ - pUVCpu = NULL; - pUVM = NULL; - } - else - { - vmR3DestroyFinalBitFromEMT(pUVM, idCpu); - pUVCpu->vm.s.NativeThreadEMT = NIL_RTNATIVETHREAD; + PVM pVM = pUVM->pVM; + vmR3SetTerminated(pVM); + pUVM->pVM = NULL; + + /** @todo SMP: This isn't 100% safe. We should wait for the other + * threads to finish before destroy the VM. */ + int rc2 = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_GVMM_DESTROY_VM, 0, NULL); + AssertLogRelRC(rc2); } + + pUVCpu->vm.s.NativeThreadEMT = NIL_RTNATIVETHREAD; Log(("vmR3EmulationThread: EMT is terminated.\n")); return rc; } @@ -288,6 +282,27 @@ static const char *vmR3GetHaltMethodName(VMHALTMETHOD enmMethod) /** + * Signal a fatal wait error. + * + * @returns Fatal error code to be propagated up the call stack. + * @param pUVCpu The user mode per CPU structure of the calling + * EMT. + * @param pszFmt The error format with a single %Rrc in it. + * @param rcFmt The status code to format. + */ +static int vmR3FatalWaitError(PUVMCPU pUVCpu, const char *pszFmt, int rcFmt) +{ + /** @todo This is wrong ... raise a fatal error / guru meditation + * instead. */ + AssertLogRelMsgFailed((pszFmt, rcFmt)); + ASMAtomicUoWriteBool(&pUVCpu->pUVM->vm.s.fTerminateEMT, true); + if (pUVCpu->pVM) + VM_FF_SET(pUVCpu->pVM, VM_FF_CHECK_VM_STATE); + return VERR_INTERNAL_ERROR; +} + + +/** * The old halt loop. */ static DECLCALLBACK(int) vmR3HaltOldDoHalt(PUVMCPU pUVCpu, const uint32_t fMask, uint64_t /* u64Now*/) @@ -361,11 +376,7 @@ static DECLCALLBACK(int) vmR3HaltOldDoHalt(PUVMCPU pUVCpu, const uint32_t fMask, rc = VINF_SUCCESS; else if (RT_FAILURE(rc)) { - AssertRC(rc != VERR_INTERRUPTED); - AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); - ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); - VM_FF_SET(pVM, VM_FF_TERMINATE); - rc = VERR_INTERNAL_ERROR; + rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc\n", rc); break; } } @@ -550,11 +561,7 @@ static DECLCALLBACK(int) vmR3HaltMethod1Halt(PUVMCPU pUVCpu, const uint32_t fMas rc = VINF_SUCCESS; else if (RT_FAILURE(rc)) { - AssertRC(rc != VERR_INTERRUPTED); - AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); - ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); - VM_FF_SET(pVM, VM_FF_TERMINATE); - rc = VERR_INTERNAL_ERROR; + rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc\n", rc); break; } @@ -661,10 +668,7 @@ static DECLCALLBACK(int) vmR3HaltGlobal1Halt(PUVMCPU pUVCpu, const uint32_t fMas rc = VINF_SUCCESS; else if (RT_FAILURE(rc)) { - AssertMsgFailed(("VMMR0_DO_GVMM_SCHED_HALT->%Rrc\n", rc)); - ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); - VM_FF_SET(pVM, VM_FF_TERMINATE); - rc = VERR_INTERNAL_ERROR; + rc = vmR3FatalWaitError(pUVCpu, "VMMR0_DO_GVMM_SCHED_HALT->%Rrc\n", rc); break; } } @@ -719,13 +723,9 @@ static DECLCALLBACK(int) vmR3HaltGlobal1Wait(PUVMCPU pUVCpu) rc = VINF_SUCCESS; else if (RT_FAILURE(rc)) { - AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); - ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); - VM_FF_SET(pVM, VM_FF_TERMINATE); - rc = VERR_INTERNAL_ERROR; + rc = vmR3FatalWaitError(pUVCpu, "VMMR0_DO_GVMM_SCHED_HALT->%Rrc\n", rc); break; } - } ASMAtomicUoWriteBool(&pUVCpu->vm.s.fWait, false); @@ -797,7 +797,7 @@ static DECLCALLBACK(int) vmR3BootstrapWait(PUVMCPU pUVCpu) ) ) break; - if (pUVCpu->vm.s.fTerminateEMT) + if (pUVM->vm.s.fTerminateEMT) break; /* @@ -809,14 +809,9 @@ static DECLCALLBACK(int) vmR3BootstrapWait(PUVMCPU pUVCpu) rc = VINF_SUCCESS; else if (RT_FAILURE(rc)) { - AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); - ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); - if (pUVCpu->pVM) - VM_FF_SET(pUVCpu->pVM, VM_FF_TERMINATE); - rc = VERR_INTERNAL_ERROR; + rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc\n", rc); break; } - } ASMAtomicUoWriteBool(&pUVCpu->vm.s.fWait, false); @@ -872,13 +867,9 @@ static DECLCALLBACK(int) vmR3DefaultWait(PUVMCPU pUVCpu) rc = VINF_SUCCESS; else if (RT_FAILURE(rc)) { - AssertMsgFailed(("RTSemEventWait->%Rrc\n", rc)); - ASMAtomicUoWriteBool(&pUVCpu->vm.s.fTerminateEMT, true); - VM_FF_SET(pVM, VM_FF_TERMINATE); - rc = VERR_INTERNAL_ERROR; + rc = vmR3FatalWaitError(pUVCpu, "RTSemEventWait->%Rrc", rc); break; } - } ASMAtomicUoWriteBool(&pUVCpu->vm.s.fWait, false); diff --git a/src/VBox/VMM/VMInternal.h b/src/VBox/VMM/VMInternal.h index 4da3d8baf..fc5750ff2 100644 --- a/src/VBox/VMM/VMInternal.h +++ b/src/VBox/VMM/VMInternal.h @@ -209,9 +209,6 @@ typedef struct VMINTUSERPERVM /** Force EMT to terminate. */ bool volatile fTerminateEMT; - /** If set the EMT(0) does the final VM cleanup when it exits. - * If clear the VMR3Destroy() caller does so. */ - bool fEMTDoesTheCleanup; /** Critical section for pAtState and enmPrevVMState. */ RTCRITSECT AtStateCritSect; @@ -311,13 +308,8 @@ typedef struct VMINTUSERPERVMCPU RTSEMEVENT EventSemWait; /** Wait/Idle indicator. */ bool volatile fWait; - /** Force EMT to terminate. */ - bool volatile fTerminateEMT; - /** If set the EMT does the final VM cleanup when it exits. - * If clear the VMR3Destroy() caller does so. */ - bool fEMTDoesTheCleanup; /** Align the next bit. */ - bool afAlignment[5]; + bool afAlignment[7]; /** @name Generic Halt data * @{ @@ -428,8 +420,8 @@ void vmSetErrorCopy(PVM pVM, int rc, RT_SRC_POS_DECL, const char DECLCALLBACK(int) vmR3SetRuntimeError(PVM pVM, uint32_t fFlags, const char *pszErrorId, char *pszMessage); DECLCALLBACK(int) vmR3SetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list *pVa); void vmSetRuntimeErrorCopy(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va); -void vmR3DestroyFinalBitFromEMT(PUVM pUVM, VMCPUID idCpu); void vmR3SetGuruMeditation(PVM pVM); +void vmR3SetTerminated(PVM pVM); RT_C_DECLS_END diff --git a/src/VBox/VMM/VMM.cpp b/src/VBox/VMM/VMM.cpp index 3df9c824a..4994ae2c4 100644 --- a/src/VBox/VMM/VMM.cpp +++ b/src/VBox/VMM/VMM.cpp @@ -2206,7 +2206,7 @@ static DECLCALLBACK(void) vmmR3InfoFF(PVM pVM, PCDBGFINFOHLP pHlp, const char *p PRINT_FLAG(VM_FF_,PDM_DMA); PRINT_FLAG(VM_FF_,DBGF); PRINT_FLAG(VM_FF_,REQUEST); - PRINT_FLAG(VM_FF_,TERMINATE); + PRINT_FLAG(VM_FF_,CHECK_VM_STATE); PRINT_FLAG(VM_FF_,RESET); PRINT_FLAG(VM_FF_,EMT_RENDEZVOUS); PRINT_FLAG(VM_FF_,PGM_NEED_HANDY_PAGES); diff --git a/src/VBox/VMM/VMMAll/PGMAllPhys.cpp b/src/VBox/VMM/VMMAll/PGMAllPhys.cpp index 4d0fb026b..509d4ee11 100644 --- a/src/VBox/VMM/VMMAll/PGMAllPhys.cpp +++ b/src/VBox/VMM/VMMAll/PGMAllPhys.cpp @@ -229,7 +229,7 @@ VMMDECL(void) PGMPhysInvalidatePageMapTLB(PVM pVM) pVM->pgm.s.PhysTlbHC.aEntries[i].pMap = 0; pVM->pgm.s.PhysTlbHC.aEntries[i].pv = 0; } - /* @todo clear the RC TLB whenever we add it. */ + /** @todo clear the RC TLB whenever we add it. */ pgmUnlock(pVM); } @@ -389,7 +389,7 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys) if (rc == VINF_SUCCESS) return rc; - /* fall back to 4kb pages. */ + /* fall back to 4KB pages. */ } # endif @@ -471,14 +471,13 @@ int pgmPhysAllocPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys) /* Copy the shared page contents to the replacement page. */ if (pvSharedPage) { - void *pvNewPage; - /* Get the virtual address of the new page. */ + void *pvNewPage; rc = pgmPhysGCPhys2CCPtrInternal(pVM, pPage, GCPhys, &pvNewPage); AssertRC(rc); if (rc == VINF_SUCCESS) { - /** todo write ASMMemCopy */ + /** @todo todo write ASMMemCopyPage */ memcpy(pvNewPage, pvSharedPage, PAGE_SIZE); } } @@ -1021,10 +1020,9 @@ int pgmPhysPageMapReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, void const int pgmPhysPageLoadIntoTlb(PPGM pPGM, RTGCPHYS GCPhys) { Assert(PGMIsLocked(PGM2VM(pPGM))); - STAM_COUNTER_INC(&pPGM->CTX_MID_Z(Stat,PageMapTlbMisses)); /* - * Find the ram range. + * Find the ram range and page and hand it over to the with-page function. * 99.8% of requests are expected to be in the first range. */ PPGMRAMRANGE pRam = pPGM->CTX_SUFF(pRamRanges); @@ -1035,42 +1033,15 @@ int pgmPhysPageLoadIntoTlb(PPGM pPGM, RTGCPHYS GCPhys) { pRam = pRam->CTX_SUFF(pNext); if (!pRam) + { + STAM_COUNTER_INC(&pPGM->CTX_MID_Z(Stat,PageMapTlbMisses)); return VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS; + } off = GCPhys - pRam->GCPhys; } while (off >= pRam->cb); } - /* - * Map the page. - * Make a special case for the zero page as it is kind of special. - */ - PPGMPAGE pPage = &pRam->aPages[off >> PAGE_SHIFT]; - PPGMPAGEMAPTLBE pTlbe = &pPGM->CTXSUFF(PhysTlb).aEntries[PGM_PAGEMAPTLB_IDX(GCPhys)]; - if ( !PGM_PAGE_IS_ZERO(pPage) - && !PGM_PAGE_IS_BALLOONED(pPage)) - { - void *pv; - PPGMPAGEMAP pMap; - int rc = pgmPhysPageMapCommon(PGM2VM(pPGM), pPage, GCPhys, &pMap, &pv); - if (RT_FAILURE(rc)) - return rc; - pTlbe->pMap = pMap; - pTlbe->pv = pv; - Assert(!((uintptr_t)pTlbe->pv & PAGE_OFFSET_MASK)); - } - else - { - Assert(PGM_PAGE_GET_HCPHYS(pPage) == pPGM->HCPhysZeroPg); - pTlbe->pMap = NULL; - pTlbe->pv = pPGM->CTXALLSUFF(pvZeroPg); - } -#ifdef PGM_WITH_PHYS_TLB - pTlbe->GCPhys = GCPhys & X86_PTE_PAE_PG_MASK; -#else - pTlbe->GCPhys = NIL_RTGCPHYS; -#endif - pTlbe->pPage = pPage; - return VINF_SUCCESS; + return pgmPhysPageLoadIntoTlbWithPage(pPGM, &pRam->aPages[off >> PAGE_SHIFT], GCPhys); } @@ -1115,7 +1086,11 @@ int pgmPhysPageLoadIntoTlbWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys) pTlbe->pv = pPGM->CTXALLSUFF(pvZeroPg); } #ifdef PGM_WITH_PHYS_TLB - pTlbe->GCPhys = GCPhys & X86_PTE_PAE_PG_MASK; + if ( PGM_PAGE_GET_TYPE(pPage) < PGMPAGETYPE_ROM_SHADOW + || PGM_PAGE_GET_TYPE(pPage) > PGMPAGETYPE_ROM) + pTlbe->GCPhys = GCPhys & X86_PTE_PAE_PG_MASK; + else + pTlbe->GCPhys = NIL_RTGCPHYS; /* ROM: Problematic because of the two pages. :-/ */ #else pTlbe->GCPhys = NIL_RTGCPHYS; #endif diff --git a/src/VBox/VMM/VMMAll/VMMAll.cpp b/src/VBox/VMM/VMMAll/VMMAll.cpp index 3d4ca8f97..73bc6aa22 100644 --- a/src/VBox/VMM/VMMAll/VMMAll.cpp +++ b/src/VBox/VMM/VMMAll/VMMAll.cpp @@ -25,6 +25,7 @@ #include <VBox/vm.h> #include <VBox/vmm.h> #include <VBox/param.h> +#include <iprt/thread.h> #include <iprt/mp.h> @@ -59,8 +60,11 @@ VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM) if (pVM->cCpus == 1) return 0; - /* RTMpCpuId had better be cheap. */ - RTCPUID idHostCpu = RTMpCpuId(); + /* Search first by host cpu id (most common case) + * and then by native thread id (page fusion case). + */ + /* RTMpCpuId had better be cheap. */ + RTCPUID idHostCpu = RTMpCpuId(); /** @todo optimize for large number of VCPUs when that becomes more common. */ for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) @@ -70,6 +74,18 @@ VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM) if (pVCpu->idHostCpu == idHostCpu) return pVCpu->idCpu; } + + /* RTThreadGetNativeSelf had better be cheap. */ + RTNATIVETHREAD hThread = RTThreadNativeSelf(); + + /** @todo optimize for large number of VCPUs when that becomes more common. */ + for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) + { + PVMCPU pVCpu = &pVM->aCpus[idCpu]; + + if (pVCpu->hNativeThreadR0 == hThread) + return pVCpu->idCpu; + } return NIL_VMCPUID; #else /* RC: Always EMT(0) */ @@ -92,14 +108,18 @@ VMMDECL(PVMCPU) VMMGetCpu(PVM pVM) if (idCpu == NIL_VMCPUID) return NULL; Assert(idCpu < pVM->cCpus); - return &pVM->aCpus[VMR3GetVMCPUId(pVM)]; + return &pVM->aCpus[idCpu]; #elif defined(IN_RING0) if (pVM->cCpus == 1) return &pVM->aCpus[0]; - /* RTMpCpuId had better be cheap. */ - RTCPUID idHostCpu = RTMpCpuId(); + /* Search first by host cpu id (most common case) + * and then by native thread id (page fusion case). + */ + + /* RTMpCpuId had better be cheap. */ + RTCPUID idHostCpu = RTMpCpuId(); /** @todo optimize for large number of VCPUs when that becomes more common. */ for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) @@ -109,6 +129,18 @@ VMMDECL(PVMCPU) VMMGetCpu(PVM pVM) if (pVCpu->idHostCpu == idHostCpu) return pVCpu; } + + /* RTThreadGetNativeSelf had better be cheap. */ + RTNATIVETHREAD hThread = RTThreadNativeSelf(); + + /** @todo optimize for large number of VCPUs when that becomes more common. */ + for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) + { + PVMCPU pVCpu = &pVM->aCpus[idCpu]; + + if (pVCpu->hNativeThreadR0 == hThread) + return pVCpu; + } return NULL; #else /* RC: Always EMT(0) */ diff --git a/src/VBox/VMM/VMMR0/GMMR0.cpp b/src/VBox/VMM/VMMR0/GMMR0.cpp index 7304875cf..9c7930afe 100644 --- a/src/VBox/VMM/VMMR0/GMMR0.cpp +++ b/src/VBox/VMM/VMMR0/GMMR0.cpp @@ -488,7 +488,7 @@ typedef struct GMM GMMCHUNKFREESET Shared; /** Shared module tree (global). */ - /** todo seperate trees for distinctly different guest OSes. */ + /** @todo seperate trees for distinctly different guest OSes. */ PAVLGCPTRNODECORE pGlobalSharedModuleTree; /** The maximum number of pages we're allowed to allocate. @@ -866,6 +866,8 @@ GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM) * and left over mappings. (This'll only catch private pages, shared * pages will be 'left behind'.) */ + /** @todo this might be kind of expensive with a lot of VMs and + * memory hanging around... */ uint64_t cPrivatePages = pGVM->gmm.s.cPrivatePages; /* save */ RTAvlU32DoWithAll(&pGMM->pChunks, true /* fFromLeft */, gmmR0CleanupVMScanChunk, pGVM); if (pGVM->gmm.s.cPrivatePages) @@ -2063,7 +2065,6 @@ GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesTo AssertRC(rc); if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) { - /* No allocations before the initial reservation has been made! */ if (RT_LIKELY( pGVM->gmm.s.Reserved.cBasePages && pGVM->gmm.s.Reserved.cFixedPages @@ -2388,7 +2389,7 @@ GMMR0DECL(int) GMMR0AllocateLargePage(PVM pVM, VMCPUID idCpu, uint32_t cbPage, rc = VERR_INTERNAL_ERROR_5; RTSemFastMutexRelease(pGMM->Mtx); - LogFlow(("GMMR0AllocatePages: returns %Rrc\n", rc)); + LogFlow(("GMMR0AllocateLargePage: returns %Rrc\n", rc)); return rc; } @@ -2967,7 +2968,7 @@ GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmA { case GMMBALLOONACTION_INFLATE: { - if (pGVM->gmm.s.Allocated.cBasePages >= cBalloonedPages) + if (RT_LIKELY(pGVM->gmm.s.Allocated.cBasePages + pGVM->gmm.s.cBalloonedPages + cBalloonedPages <= pGVM->gmm.s.Reserved.cBasePages)) { /* * Record the ballooned memory. @@ -3459,13 +3460,15 @@ GMMR0DECL(int) GMMR0SeedChunk(PVM pVM, VMCPUID idCpu, RTR3PTR pvR3) { /* Grab the lock. */ rc = RTSemFastMutexRequest(pGMM->Mtx); - AssertRCReturn(rc, rc); - - /* - * Add a new chunk with our hGVM. - */ - rc = gmmR0RegisterChunk(pGMM, &pGMM->Private, MemObj, pGVM->hSelf, GMMCHUNKTYPE_NON_CONTINUOUS); - RTSemFastMutexRelease(pGMM->Mtx); + AssertRC(rc); + if (RT_SUCCESS(rc)) + { + /* + * Add a new chunk with our hGVM. + */ + rc = gmmR0RegisterChunk(pGMM, &pGMM->Private, MemObj, pGVM->hSelf, GMMCHUNKTYPE_NON_CONTINUOUS); + RTSemFastMutexRelease(pGMM->Mtx); + } if (RT_FAILURE(rc)) RTR0MemObjFree(MemObj, false /* fFreeMappings */); @@ -3493,7 +3496,7 @@ DECLCALLBACK(int) gmmR0CheckForIdenticalModule(PAVLGCPTRNODECORE pNode, void *pv if ( pInfo && pInfo->enmGuestOS == pModule->enmGuestOS - /** todo replace with RTStrNCmp */ + /** @todo replace with RTStrNCmp */ && !strcmp(pModule->szName, pInfo->pszModuleName) && !strcmp(pModule->szVersion, pInfo->pszVersion)) { @@ -3590,11 +3593,13 @@ GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY en Info.pszModuleName = pszModuleName; Info.enmGuestOS = enmGuestOS; + Log(("Try to find identical module %s\n", pszModuleName)); int ret = RTAvlGCPtrDoWithAll(&pGMM->pGlobalSharedModuleTree, true /* fFromLeft */, gmmR0CheckForIdenticalModule, &Info); if (ret == 1) { Assert(Info.pNode); pGlobalModule = (PGMMSHAREDMODULE)Info.pNode; + Log(("Found identical module at %RGv\n", pGlobalModule->Core.Key)); } } @@ -3614,7 +3619,7 @@ GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY en pGlobalModule->Core.Key = GCBaseAddr; pGlobalModule->cbModule = cbModule; /* Input limit already safe; no need to check again. */ - /** todo replace with RTStrCopy */ + /** @todo replace with RTStrCopy */ strcpy(pGlobalModule->szName, pszModuleName); strcpy(pGlobalModule->szVersion, pszVersion); @@ -3646,7 +3651,7 @@ GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY en Assert(pGlobalModule->cUsers > 0); /* Make sure the name and version are identical. */ - /** todo replace with RTStrNCmp */ + /** @todo replace with RTStrNCmp */ if ( !strcmp(pGlobalModule->szName, pszModuleName) && !strcmp(pGlobalModule->szVersion, pszVersion)) { @@ -3740,49 +3745,58 @@ GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModu if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) { PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)RTAvlGCPtrGet(&pGVM->gmm.s.pSharedModuleTree, GCBaseAddr); - if (!pRecVM) - { - rc = VERR_PGM_SHARED_MODULE_NOT_FOUND; - goto end; - } - /* Remove reference to global shared module. */ - if (!pRecVM->fCollision) + if (pRecVM) { - PGMMSHAREDMODULE pRec = pRecVM->pGlobalModule; - Assert(pRec); - - if (pRec) /* paranoia */ + /* Remove reference to global shared module. */ + if (!pRecVM->fCollision) { - Assert(pRec->cUsers); - pRec->cUsers--; - if (pRec->cUsers == 0) + PGMMSHAREDMODULE pRec = pRecVM->pGlobalModule; + Assert(pRec); + + if (pRec) /* paranoia */ { - /* Free the ranges, but leave the pages intact as there might still be references; they will be cleared by the COW mechanism. */ - for (unsigned i = 0; i < pRec->cRegions; i++) - if (pRec->aRegions[i].paHCPhysPageID) - RTMemFree(pRec->aRegions[i].paHCPhysPageID); - - /* Remove from the tree and free memory. */ - RTAvlGCPtrRemove(&pGMM->pGlobalSharedModuleTree, GCBaseAddr); - RTMemFree(pRec); + Assert(pRec->cUsers); + pRec->cUsers--; + if (pRec->cUsers == 0) + { + /* Free the ranges, but leave the pages intact as there might still be references; they will be cleared by the COW mechanism. */ + for (unsigned i = 0; i < pRec->cRegions; i++) + if (pRec->aRegions[i].paHCPhysPageID) + RTMemFree(pRec->aRegions[i].paHCPhysPageID); + + Assert(pRec->Core.Key == GCBaseAddr || pRec->enmGuestOS == VBOXOSFAMILY_Windows64); + Assert(pRec->cRegions == pRecVM->cRegions); +#ifdef VBOX_STRICT + for (unsigned i = 0; i < pRecVM->cRegions; i++) + { + Assert(pRecVM->aRegions[i].GCRegionAddr == pRec->aRegions[i].GCRegionAddr); + Assert(pRecVM->aRegions[i].cbRegion == pRec->aRegions[i].cbRegion); + } +#endif + + /* Remove from the tree and free memory. */ + RTAvlGCPtrRemove(&pGMM->pGlobalSharedModuleTree, pRec->Core.Key); + RTMemFree(pRec); + } } + else + rc = VERR_PGM_SHARED_MODULE_REGISTRATION_INCONSISTENCY; } else - rc = VERR_PGM_SHARED_MODULE_REGISTRATION_INCONSISTENCY; + Assert(!pRecVM->pGlobalModule); + + /* Remove from the tree and free memory. */ + RTAvlGCPtrRemove(&pGVM->gmm.s.pSharedModuleTree, GCBaseAddr); + RTMemFree(pRecVM); } else - Assert(!pRecVM->pGlobalModule); - - /* Remove from the tree and free memory. */ - RTAvlGCPtrRemove(&pGVM->gmm.s.pSharedModuleTree, GCBaseAddr); - RTMemFree(pRecVM); + rc = VERR_PGM_SHARED_MODULE_NOT_FOUND; GMM_CHECK_SANITY_UPON_LEAVING(pGMM); } else rc = VERR_INTERNAL_ERROR_5; -end: RTSemFastMutexRelease(pGMM->Mtx); return rc; #else @@ -3816,32 +3830,36 @@ GMMR0DECL(int) GMMR0UnregisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMUNREG * Checks specified shared module range for changes * * Performs the following tasks: - * - if a shared page is new, then it changes the GMM page type to shared and returns it in the paPageDesc array - * - if a shared page already exists, then it checks if the VM page is identical and if so frees the VM page and returns the shared page in the paPageDesc array + * - If a shared page is new, then it changes the GMM page type to shared and + * returns it in the pPageDesc descriptor. + * - If a shared page already exists, then it checks if the VM page is + * identical and if so frees the VM page and returns the shared page in + * pPageDesc descriptor. * - * Note: assumes the caller has acquired the GMM semaphore!! + * @remarks ASSUMES the caller has acquired the GMM semaphore!! * * @returns VBox status code. * @param pGMM Pointer to the GMM instance data. * @param pGVM Pointer to the GVM instance data. * @param pModule Module description * @param idxRegion Region index - * @param cPages Number of entries in the paPageDesc array - * @param paPageDesc Page descriptor array (in/out) + * @param idxPage Page index + * @param paPageDesc Page descriptor */ -GMMR0DECL(int) GMMR0SharedModuleCheckRange(PGVM pGVM, PGMMSHAREDMODULE pModule, unsigned idxRegion, unsigned cPages, PGMMSHAREDPAGEDESC paPageDesc) +GMMR0DECL(int) GMMR0SharedModuleCheckPage(PGVM pGVM, PGMMSHAREDMODULE pModule, unsigned idxRegion, unsigned idxPage, + PGMMSHAREDPAGEDESC pPageDesc) { int rc = VINF_SUCCESS; PGMM pGMM; GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR); + unsigned cPages = pModule->aRegions[idxRegion].cbRegion >> PAGE_SHIFT; AssertReturn(idxRegion < pModule->cRegions, VERR_INVALID_PARAMETER); - AssertReturn(cPages == (pModule->aRegions[idxRegion].cbRegion >> PAGE_SHIFT), VERR_INVALID_PARAMETER); + AssertReturn(idxPage < cPages, VERR_INVALID_PARAMETER); - Log(("GMMR0SharedModuleCheckRange %s base %RGv region %d cPages %d\n", pModule->szName, pModule->Core.Key, idxRegion, cPages)); + LogFlow(("GMMR0SharedModuleCheckRange %s base %RGv region %d idxPage %d\n", pModule->szName, pModule->Core.Key, idxRegion, idxPage)); PGMMSHAREDREGIONDESC pGlobalRegion = &pModule->aRegions[idxRegion]; - if (!pGlobalRegion->paHCPhysPageID) { /* First time; create a page descriptor array. */ @@ -3858,122 +3876,120 @@ GMMR0DECL(int) GMMR0SharedModuleCheckRange(PGVM pGVM, PGMMSHAREDMODULE pModule, pGlobalRegion->paHCPhysPageID[i] = NIL_GMM_PAGEID; } - /* Check all pages in the region. */ - for (unsigned i = 0; i < cPages; i++) + /* We've seen this shared page for the first time? */ + if (pGlobalRegion->paHCPhysPageID[idxPage] == NIL_GMM_PAGEID) { - /* Valid page present? */ - if (paPageDesc[i].uHCPhysPageId != NIL_GMM_PAGEID) - { - /* We've seen this shared page for the first time? */ - if (pGlobalRegion->paHCPhysPageID[i] == NIL_GMM_PAGEID) - { new_shared_page: - Log(("New shared page guest %RGp host %RHp\n", paPageDesc[i].GCPhys, paPageDesc[i].HCPhys)); + Log(("New shared page guest %RGp host %RHp\n", pPageDesc->GCPhys, pPageDesc->HCPhys)); - /* Easy case: just change the internal page type. */ - PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uHCPhysPageId); - if (!pPage) - { - AssertFailed(); - rc = VERR_PGM_PHYS_INVALID_PAGE_ID; - goto end; - } + /* Easy case: just change the internal page type. */ + PGMMPAGE pPage = gmmR0GetPage(pGMM, pPageDesc->uHCPhysPageId); + if (!pPage) + { + Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #1 (GCPhys=%RGp HCPhys=%RHp idxRegion=%#x idxPage=%#x)\n", + pPageDesc->uHCPhysPageId, pPageDesc->GCPhys, pPageDesc->HCPhys, idxRegion, idxPage)); + AssertFailed(); + rc = VERR_PGM_PHYS_INVALID_PAGE_ID; + goto end; + } - AssertMsg(paPageDesc[i].GCPhys == (pPage->Private.pfn << 12), ("desc %RGp gmm %RGp\n", paPageDesc[i].HCPhys, (pPage->Private.pfn << 12))); + AssertMsg(pPageDesc->GCPhys == (pPage->Private.pfn << 12), ("desc %RGp gmm %RGp\n", pPageDesc->HCPhys, (pPage->Private.pfn << 12))); - gmmR0ConvertToSharedPage(pGMM, pGVM, paPageDesc[i].HCPhys, paPageDesc[i].uHCPhysPageId, pPage); + gmmR0ConvertToSharedPage(pGMM, pGVM, pPageDesc->HCPhys, pPageDesc->uHCPhysPageId, pPage); - /* Keep track of these references. */ - pGlobalRegion->paHCPhysPageID[i] = paPageDesc[i].uHCPhysPageId; - } - else - { - uint8_t *pbLocalPage, *pbSharedPage; - uint8_t *pbChunk; - PGMMCHUNK pChunk; + /* Keep track of these references. */ + pGlobalRegion->paHCPhysPageID[idxPage] = pPageDesc->uHCPhysPageId; + } + else + { + uint8_t *pbLocalPage, *pbSharedPage; + uint8_t *pbChunk; + PGMMCHUNK pChunk; - Assert(paPageDesc[i].uHCPhysPageId != pGlobalRegion->paHCPhysPageID[i]); + Assert(pPageDesc->uHCPhysPageId != pGlobalRegion->paHCPhysPageID[idxPage]); - Log(("Replace existing page guest %RGp host %RHp id %x -> id %x\n", paPageDesc[i].GCPhys, paPageDesc[i].HCPhys, paPageDesc[i].uHCPhysPageId, pGlobalRegion->paHCPhysPageID[i])); + Log(("Replace existing page guest %RGp host %RHp id %x -> id %x\n", pPageDesc->GCPhys, pPageDesc->HCPhys, pPageDesc->uHCPhysPageId, pGlobalRegion->paHCPhysPageID[idxPage])); - /* Get the shared page source. */ - PGMMPAGE pPage = gmmR0GetPage(pGMM, pGlobalRegion->paHCPhysPageID[i]); - if (!pPage) - { - AssertFailed(); - rc = VERR_PGM_PHYS_INVALID_PAGE_ID; - goto end; - } - if (pPage->Common.u2State != GMM_PAGE_STATE_SHARED) - { - /* Page was freed at some point; invalidate this entry. */ - /** todo this isn't really bullet proof. */ - Log(("Old shared page was freed -> create a new one\n")); - pGlobalRegion->paHCPhysPageID[i] = NIL_GMM_PAGEID; - goto new_shared_page; /* ugly goto */ - } + /* Get the shared page source. */ + PGMMPAGE pPage = gmmR0GetPage(pGMM, pGlobalRegion->paHCPhysPageID[idxPage]); + if (!pPage) + { + Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #2 (idxRegion=%#x idxPage=%#x)\n", + pPageDesc->uHCPhysPageId, idxRegion, idxPage)); + AssertFailed(); + rc = VERR_PGM_PHYS_INVALID_PAGE_ID; + goto end; + } + if (pPage->Common.u2State != GMM_PAGE_STATE_SHARED) + { + /* Page was freed at some point; invalidate this entry. */ + /** @todo this isn't really bullet proof. */ + Log(("Old shared page was freed -> create a new one\n")); + pGlobalRegion->paHCPhysPageID[idxPage] = NIL_GMM_PAGEID; + goto new_shared_page; /* ugly goto */ + } - Log(("Replace existing page guest host %RHp -> %RHp\n", paPageDesc[i].HCPhys, ((uint64_t)pPage->Shared.pfn) << PAGE_SHIFT)); + Log(("Replace existing page guest host %RHp -> %RHp\n", pPageDesc->HCPhys, ((uint64_t)pPage->Shared.pfn) << PAGE_SHIFT)); - /* Calculate the virtual address of the local page. */ - pChunk = gmmR0GetChunk(pGMM, paPageDesc[i].uHCPhysPageId >> GMM_CHUNKID_SHIFT); - if (pChunk) - { - if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) - { - AssertFailed(); - rc = VERR_PGM_PHYS_INVALID_PAGE_ID; - goto end; - } - pbLocalPage = pbChunk + ((paPageDesc[i].uHCPhysPageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT); - } - else - { - AssertFailed(); - rc = VERR_PGM_PHYS_INVALID_PAGE_ID; - goto end; - } + /* Calculate the virtual address of the local page. */ + pChunk = gmmR0GetChunk(pGMM, pPageDesc->uHCPhysPageId >> GMM_CHUNKID_SHIFT); + if (pChunk) + { + if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) + { + Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #3\n", pPageDesc->uHCPhysPageId)); + AssertFailed(); + rc = VERR_PGM_PHYS_INVALID_PAGE_ID; + goto end; + } + pbLocalPage = pbChunk + ((pPageDesc->uHCPhysPageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT); + } + else + { + Log(("GMMR0SharedModuleCheckPage: Invalid idPage=%#x #4\n", pPageDesc->uHCPhysPageId)); + AssertFailed(); + rc = VERR_PGM_PHYS_INVALID_PAGE_ID; + goto end; + } - /* Calculate the virtual address of the shared page. */ - pChunk = gmmR0GetChunk(pGMM, pGlobalRegion->paHCPhysPageID[i] >> GMM_CHUNKID_SHIFT); - Assert(pChunk); /* can't fail as gmmR0GetPage succeeded. */ + /* Calculate the virtual address of the shared page. */ + pChunk = gmmR0GetChunk(pGMM, pGlobalRegion->paHCPhysPageID[idxPage] >> GMM_CHUNKID_SHIFT); + Assert(pChunk); /* can't fail as gmmR0GetPage succeeded. */ - /* Get the virtual address of the physical page; map the chunk into the VM process if not already done. */ - if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) - { - Log(("Map chunk into process!\n")); - rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk); - if (rc != VINF_SUCCESS) - { - AssertRC(rc); - goto end; - } - } - pbSharedPage = pbChunk + ((pGlobalRegion->paHCPhysPageID[i] & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT); + /* Get the virtual address of the physical page; map the chunk into the VM process if not already done. */ + if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) + { + Log(("Map chunk into process!\n")); + rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk); + if (rc != VINF_SUCCESS) + { + AssertRC(rc); + goto end; + } + } + pbSharedPage = pbChunk + ((pGlobalRegion->paHCPhysPageID[idxPage] & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT); - /** todo write ASMMemComparePage. */ - if (memcmp(pbSharedPage, pbLocalPage, PAGE_SIZE)) - { - Log(("Unexpected differences found between local and shared page; skip\n")); - /* Signal to the caller that this one hasn't changed. */ - paPageDesc[i].uHCPhysPageId = NIL_GMM_PAGEID; - continue; - } + /** @todo write ASMMemComparePage. */ + if (memcmp(pbSharedPage, pbLocalPage, PAGE_SIZE)) + { + Log(("Unexpected differences found between local and shared page; skip\n")); + /* Signal to the caller that this one hasn't changed. */ + pPageDesc->uHCPhysPageId = NIL_GMM_PAGEID; + goto end; + } - /* Free the old local page. */ - GMMFREEPAGEDESC PageDesc; + /* Free the old local page. */ + GMMFREEPAGEDESC PageDesc; - PageDesc.idPage = paPageDesc[i].uHCPhysPageId; - rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE); - AssertRC(rc); + PageDesc.idPage = pPageDesc->uHCPhysPageId; + rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE); + AssertRCReturn(rc, rc); - gmmR0UseSharedPage(pGMM, pGVM, pPage); + gmmR0UseSharedPage(pGMM, pGVM, pPage); - /* Pass along the new physical address & page id. */ - paPageDesc[i].HCPhys = ((uint64_t)pPage->Shared.pfn) << PAGE_SHIFT; - paPageDesc[i].uHCPhysPageId = pGlobalRegion->paHCPhysPageID[i]; - } - } + /* Pass along the new physical address & page id. */ + pPageDesc->HCPhys = ((uint64_t)pPage->Shared.pfn) << PAGE_SHIFT; + pPageDesc->uHCPhysPageId = pGlobalRegion->paHCPhysPageID[idxPage]; } end: return rc; @@ -4066,6 +4082,7 @@ typedef struct { PGVM pGVM; VMCPUID idCpu; + int rc; } GMMCHECKSHAREDMODULEINFO, *PGMMCHECKSHAREDMODULEINFO; /** @@ -4081,7 +4098,9 @@ DECLCALLBACK(int) gmmR0CheckSharedModule(PAVLGCPTRNODECORE pNode, void *pvUser) && pGlobalModule) { Log(("gmmR0CheckSharedModule: check %s %s base=%RGv size=%x collision=%d\n", pGlobalModule->szName, pGlobalModule->szVersion, pGlobalModule->Core.Key, pGlobalModule->cbModule, pLocalModule->fCollision)); - PGMR0SharedModuleCheck(pInfo->pGVM->pVM, pInfo->pGVM, pInfo->idCpu, pGlobalModule, pLocalModule->cRegions, pLocalModule->aRegions); + pInfo->rc = PGMR0SharedModuleCheck(pInfo->pGVM->pVM, pInfo->pGVM, pInfo->idCpu, pGlobalModule, pLocalModule->cRegions, pLocalModule->aRegions); + if (RT_FAILURE(pInfo->rc)) + return 1; /* stop enumeration. */ } return 0; } @@ -4168,11 +4187,14 @@ GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu) Log(("GMMR0CheckSharedModules\n")); Info.pGVM = pGVM; Info.idCpu = pVCpu->idCpu; + Info.rc = VINF_SUCCESS; RTAvlGCPtrDoWithAll(&pGVM->gmm.s.pSharedModuleTree, true /* fFromLeft */, gmmR0CheckSharedModule, &Info); + rc = Info.rc; + Log(("GMMR0CheckSharedModules done!\n")); - rc = VINF_SUCCESS; + GMM_CHECK_SANITY_UPON_LEAVING(pGMM); } else @@ -4186,3 +4208,135 @@ GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu) return VERR_NOT_IMPLEMENTED; #endif } + +#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64 +typedef struct +{ + PGVM pGVM; + PGMM pGMM; + uint8_t *pSourcePage; + bool fFoundDuplicate; +} GMMFINDDUPPAGEINFO, *PGMMFINDDUPPAGEINFO; + +/** + * RTAvlU32DoWithAll callback. + * + * @returns 0 + * @param pNode The node to search. + * @param pvInfo Pointer to the input parameters + */ +static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pvInfo) +{ + PGMMCHUNK pChunk = (PGMMCHUNK)pNode; + PGMMFINDDUPPAGEINFO pInfo = (PGMMFINDDUPPAGEINFO)pvInfo; + PGVM pGVM = pInfo->pGVM; + PGMM pGMM = pInfo->pGMM; + uint8_t *pbChunk; + + /* Only take chunks not mapped into this VM process; not entirely correct. */ + if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) + { + int rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk); + if (rc != VINF_SUCCESS) + goto end; + + /* + * Look for duplicate pages + */ + unsigned iPage = (GMM_CHUNK_SIZE >> PAGE_SHIFT); + while (iPage-- > 0) + { + if (GMM_PAGE_IS_PRIVATE(&pChunk->aPages[iPage])) + { + uint8_t *pbDestPage = pbChunk + (iPage << PAGE_SHIFT); + + if (!memcmp(pInfo->pSourcePage, pbDestPage, PAGE_SIZE)) + { + pInfo->fFoundDuplicate = true; + break; + } + } + } + gmmR0UnmapChunk(pGMM, pGVM, pChunk); + } +end: + if (pInfo->fFoundDuplicate) + return 1; /* stop search */ + else + return 0; +} + +/** + * Find a duplicate of the specified page in other active VMs + * + * @returns VBox status code. + * @param pVM VM handle + * @param pReq Request packet + */ +GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq) +{ + /* + * Validate input and pass it on. + */ + AssertPtrReturn(pVM, VERR_INVALID_POINTER); + AssertPtrReturn(pReq, VERR_INVALID_POINTER); + AssertMsgReturn(pReq->Hdr.cbReq == sizeof(*pReq), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER); + + PGMM pGMM; + GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR); + + /* + * Take the sempahore and do some more validations. + */ + int rc = RTSemFastMutexRequest(pGMM->Mtx); + AssertRC(rc); + if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM)) + { + PGVM pGVM; + rc = GVMMR0ByVM(pVM, &pGVM); + if (RT_FAILURE(rc)) + goto end; + + uint8_t *pbChunk; + PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, pReq->idPage >> GMM_CHUNKID_SHIFT); + if (!pChunk) + { + AssertFailed(); + goto end; + } + + if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) + { + AssertFailed(); + goto end; + } + + uint8_t *pbSourcePage = pbChunk + ((pReq->idPage & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT); + + PGMMPAGE pPage = gmmR0GetPage(pGMM, pReq->idPage); + if (!pPage) + { + AssertFailed(); + rc = VERR_PGM_PHYS_INVALID_PAGE_ID; + goto end; + } + GMMFINDDUPPAGEINFO Info; + + Info.pGVM = pGVM; + Info.pGMM = pGMM; + Info.pSourcePage = pbSourcePage; + Info.fFoundDuplicate = false; + RTAvlU32DoWithAll(&pGMM->pChunks, true /* fFromLeft */, gmmR0FindDupPageInChunk, &Info); + + pReq->fDuplicate = Info.fFoundDuplicate; + } + else + rc = VERR_INTERNAL_ERROR_5; + +end: + RTSemFastMutexRelease(pGMM->Mtx); + return rc; +} + +#endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */ + diff --git a/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp b/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp index 522b53844..e2157ca78 100644 --- a/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp +++ b/src/VBox/VMM/VMMR0/PGMR0SharedPage.cpp @@ -37,17 +37,16 @@ * @returns The following VBox status codes. * * @param pVM The VM handle. + * @param pGVM Pointer to the GVM instance data. * @param idCpu VCPU id * @param pModule Module description * @param cRegions Number of regions * @param pRegions Region array - * @param pGVM Pointer to the GVM instance data. */ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHAREDMODULE pModule, uint32_t cRegions, PGMMSHAREDREGIONDESC pRegions) { int rc = VINF_SUCCESS; - PGMMSHAREDPAGEDESC paPageDesc = NULL; - uint32_t cbPreviousRegion = 0; + GMMSHAREDPAGEDESC PageDesc; bool fFlushTLBs = false; PVMCPU pVCpu = &pVM->aCpus[idCpu]; @@ -64,28 +63,13 @@ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHA RTGCPTR GCRegion = pRegions[idxRegion].GCRegionAddr; unsigned cbRegion = pRegions[idxRegion].cbRegion & ~0xfff; unsigned idxPage = 0; - bool fValidChanges = false; - - if (cbPreviousRegion < cbRegion) - { - if (paPageDesc) - RTMemFree(paPageDesc); - - paPageDesc = (PGMMSHAREDPAGEDESC)RTMemAlloc((cbRegion >> PAGE_SHIFT) * sizeof(*paPageDesc)); - if (!paPageDesc) - { - AssertFailed(); - rc = VERR_NO_MEMORY; - goto end; - } - cbPreviousRegion = cbRegion; - } while (cbRegion) { RTGCPHYS GCPhys; uint64_t fFlags; + /** todo: inefficient to fetch each guest page like this... */ rc = PGMGstGetPage(pVCpu, GCRegion, &fFlags, &GCPhys); if ( rc == VINF_SUCCESS && !(fFlags & X86_PTE_RW)) /* important as we make assumptions about this below! */ @@ -93,91 +77,70 @@ VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHA PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys); Assert(!pPage || !PGM_PAGE_IS_BALLOONED(pPage)); if ( pPage - && pPage->uStateY == PGM_PAGE_STATE_ALLOCATED) + && PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED) { - fValidChanges = true; - paPageDesc[idxPage].uHCPhysPageId = PGM_PAGE_GET_PAGEID(pPage); - paPageDesc[idxPage].HCPhys = PGM_PAGE_GET_HCPHYS(pPage); - paPageDesc[idxPage].GCPhys = GCPhys; - } - else - paPageDesc[idxPage].uHCPhysPageId = NIL_GMM_PAGEID; - } - else - paPageDesc[idxPage].uHCPhysPageId = NIL_GMM_PAGEID; - - idxPage++; - GCRegion += PAGE_SIZE; - cbRegion -= PAGE_SIZE; - } - - if (fValidChanges) - { - rc = GMMR0SharedModuleCheckRange(pGVM, pModule, idxRegion, idxPage, paPageDesc); - AssertRC(rc); - if (RT_FAILURE(rc)) - break; + PageDesc.uHCPhysPageId = PGM_PAGE_GET_PAGEID(pPage); + PageDesc.HCPhys = PGM_PAGE_GET_HCPHYS(pPage); + PageDesc.GCPhys = GCPhys; - for (unsigned i = 0; i < idxPage; i++) - { - /* Any change for this page? */ - if (paPageDesc[i].uHCPhysPageId != NIL_GMM_PAGEID) - { - /** todo: maybe cache these to prevent the nth lookup. */ - PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPageDesc[i].GCPhys); - if (!pPage) - { - /* Should never happen. */ - AssertFailed(); - rc = VERR_PGM_PHYS_INVALID_PAGE_ID; - goto end; - } - Assert(pPage->uStateY == PGM_PAGE_STATE_ALLOCATED); - - Log(("PGMR0SharedModuleCheck: shared page gc virt=%RGv phys %RGp host %RHp->%RHp\n", pRegions[idxRegion].GCRegionAddr + i * PAGE_SIZE, paPageDesc[i].GCPhys, PGM_PAGE_GET_HCPHYS(pPage), paPageDesc[i].HCPhys)); - if (paPageDesc[i].HCPhys != PGM_PAGE_GET_HCPHYS(pPage)) + rc = GMMR0SharedModuleCheckPage(pGVM, pModule, idxRegion, idxPage, &PageDesc); + if (rc == VINF_SUCCESS) { - bool fFlush = false; - - /* Page was replaced by an existing shared version of it; clear all references first. */ - rc = pgmPoolTrackUpdateGCPhys(pVM, paPageDesc[i].GCPhys, pPage, true /* clear the entries */, &fFlush); - if (RT_FAILURE(rc)) + /* Any change for this page? */ + if (PageDesc.uHCPhysPageId != NIL_GMM_PAGEID) { - AssertRC(rc); - goto end; + Assert(PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_ALLOCATED); + + Log(("PGMR0SharedModuleCheck: shared page gc virt=%RGv phys %RGp host %RHp->%RHp\n", pRegions[idxRegion].GCRegionAddr + idxPage * PAGE_SIZE, PageDesc.GCPhys, PGM_PAGE_GET_HCPHYS(pPage), PageDesc.HCPhys)); + if (PageDesc.HCPhys != PGM_PAGE_GET_HCPHYS(pPage)) + { + bool fFlush = false; + + /* Page was replaced by an existing shared version of it; clear all references first. */ + rc = pgmPoolTrackUpdateGCPhys(pVM, PageDesc.GCPhys, pPage, true /* clear the entries */, &fFlush); + Assert(rc == VINF_SUCCESS || (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3) && (pVCpu->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL))); + if (rc == VINF_SUCCESS) + fFlushTLBs |= fFlush; + + /* Update the physical address and page id now. */ + PGM_PAGE_SET_HCPHYS(pPage, PageDesc.HCPhys); + PGM_PAGE_SET_PAGEID(pPage, PageDesc.uHCPhysPageId); + + /* Invalidate page map TLB entry for this page too. */ + PGMPhysInvalidatePageMapTLBEntry(pVM, PageDesc.GCPhys); + pVM->pgm.s.cReusedSharedPages++; + } + /* else nothing changed (== this page is now a shared page), so no need to flush anything. */ + + pVM->pgm.s.cSharedPages++; + pVM->pgm.s.cPrivatePages--; + PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_SHARED); } - Assert(rc == VINF_SUCCESS || (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_PGM_SYNC_CR3) && (pVCpu->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL))); - if (rc == VINF_SUCCESS) - fFlushTLBs |= fFlush; - - /* Update the physical address and page id now. */ - PGM_PAGE_SET_HCPHYS(pPage, paPageDesc[i].HCPhys); - PGM_PAGE_SET_PAGEID(pPage, paPageDesc[i].uHCPhysPageId); - - /* Invalidate page map TLB entry for this page too. */ - PGMPhysInvalidatePageMapTLBEntry(pVM, paPageDesc[i].GCPhys); - pVM->pgm.s.cReusedSharedPages++; } - /* else nothing changed (== this page is now a shared page), so no need to flush anything. */ - - pVM->pgm.s.cSharedPages++; - pVM->pgm.s.cPrivatePages--; - PGM_PAGE_SET_STATE(pPage, PGM_PAGE_STATE_SHARED); + else + break; } } + else + { + Assert( rc == VINF_SUCCESS + || rc == VERR_PAGE_NOT_PRESENT + || rc == VERR_PAGE_MAP_LEVEL4_NOT_PRESENT + || rc == VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT + || rc == VERR_PAGE_TABLE_NOT_PRESENT); + rc = VINF_SUCCESS; /* ignore error */ + } + + idxPage++; + GCRegion += PAGE_SIZE; + cbRegion -= PAGE_SIZE; } - else - rc = VINF_SUCCESS; /* nothing to do. */ } -end: pgmUnlock(pVM); if (fFlushTLBs) PGM_INVL_ALL_VCPU_TLBS(pVM); - if (paPageDesc) - RTMemFree(paPageDesc); - return rc; } #endif diff --git a/src/VBox/VMM/VMMR0/VMMR0.cpp b/src/VBox/VMM/VMMR0/VMMR0.cpp index 34ab78cb0..09e1952da 100644 --- a/src/VBox/VMM/VMMR0/VMMR0.cpp +++ b/src/VBox/VMM/VMMR0/VMMR0.cpp @@ -964,23 +964,24 @@ static int vmmR0EntryExWorker(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperatio PVMCPU pVCpu = &pVM->aCpus[idCpu]; - /* Select a valid VCPU context. */ - ASMAtomicWriteU32(&pVCpu->idHostCpu, RTMpCpuId()); + /* Initialize the r0 native thread handle on the fly. */ + if (pVCpu->hNativeThreadR0 == NIL_RTNATIVETHREAD) + pVCpu->hNativeThreadR0 = RTThreadNativeSelf(); # ifdef DEBUG_sandervl /* Make sure that log flushes can jump back to ring-3; annoying to get an incomplete log (this is risky though as the code doesn't take this into account). */ + /* Todo: this can have bad side effects for unexpected jumps back to r3. */ int rc = GMMR0CheckSharedModulesStart(pVM); if (rc == VINF_SUCCESS) { rc = vmmR0CallRing3SetJmp(&pVCpu->vmm.s.CallRing3JmpBufR0, GMMR0CheckSharedModules, pVM, pVCpu); /* this may resume code. */ + Assert( rc == VINF_SUCCESS + || (rc == VINF_VMM_CALL_HOST && pVCpu->vmm.s.enmCallRing3Operation == VMMCALLRING3_VMM_LOGGER_FLUSH)); GMMR0CheckSharedModulesEnd(pVM); } # else int rc = GMMR0CheckSharedModules(pVM, pVCpu); # endif - - /* Clear the VCPU context. */ - ASMAtomicWriteU32(&pVCpu->idHostCpu, NIL_RTCPUID); return rc; } #endif @@ -1240,24 +1241,30 @@ VMMR0DECL(void) vmmR0LoggerFlush(PRTLOGGER pLogger) } PVMCPU pVCpu = VMMGetCpu(pVM); - - /* - * Check that the jump buffer is armed. - */ + if (pVCpu) + { + /* + * Check that the jump buffer is armed. + */ # ifdef RT_ARCH_X86 - if ( !pVCpu->vmm.s.CallRing3JmpBufR0.eip - || pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call) + if ( !pVCpu->vmm.s.CallRing3JmpBufR0.eip + || pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call) # else - if ( !pVCpu->vmm.s.CallRing3JmpBufR0.rip - || pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call) + if ( !pVCpu->vmm.s.CallRing3JmpBufR0.rip + || pVCpu->vmm.s.CallRing3JmpBufR0.fInRing3Call) # endif - { + { # ifdef DEBUG - SUPR0Printf("vmmR0LoggerFlush: Jump buffer isn't armed!\n"); + SUPR0Printf("vmmR0LoggerFlush: Jump buffer isn't armed!\n"); # endif - return; + return; + } + VMMRZCallRing3(pVM, pVCpu, VMMCALLRING3_VMM_LOGGER_FLUSH, 0); } - VMMRZCallRing3(pVM, pVCpu, VMMCALLRING3_VMM_LOGGER_FLUSH, 0); +# ifdef DEBUG + else + SUPR0Printf("vmmR0LoggerFlush: invalid VCPU context!\n"); +# endif #endif } diff --git a/src/apps/svnsync-vbox/Makefile b/src/apps/svnsync-vbox/Makefile index b9be5dc54..d5b4c19c5 100644 --- a/src/apps/svnsync-vbox/Makefile +++ b/src/apps/svnsync-vbox/Makefile @@ -4,8 +4,13 @@ # # Copyright (C) 2006-2007 Oracle Corporation # -# Oracle Corporation confidential -# All rights reserved +# 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. # CC = gcc diff --git a/src/apps/svnsync-vbox/Makefile.kmk b/src/apps/svnsync-vbox/Makefile.kmk index 368eb9211..52d2578aa 100644 --- a/src/apps/svnsync-vbox/Makefile.kmk +++ b/src/apps/svnsync-vbox/Makefile.kmk @@ -6,8 +6,13 @@ # # Copyright (C) 2006-2007 Oracle Corporation # -# Oracle Corporation confidential -# All rights reserved +# 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. # SUB_DEPTH = ../../.. diff --git a/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp b/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp index 019d84098..4c4a92072 100644 --- a/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp +++ b/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp @@ -1346,7 +1346,7 @@ IPC_OnMessageAvailable(ipcMessage *msg) LOG(("got message for target: %s\n", targetStr)); nsMemory::Free(targetStr); - IPC_LogBinary((const PRUint8 *) msg->Data(), msg->DataLen()); +// IPC_LogBinary((const PRUint8 *) msg->Data(), msg->DataLen()); } #endif diff --git a/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp b/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp index a233438ef..f48e3ca3c 100644 --- a/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp +++ b/src/libs/xpcom18a4/ipc/ipcd/extensions/dconnect/src/ipcDConnectService.cpp @@ -1253,8 +1253,8 @@ FinishArrayParam(nsIInterfaceInfo *iinfo, uint16 methodIndex, static PRUint32 NewRequestIndex() { - static PRUint32 sRequestIndex; - return ++sRequestIndex; + static PRInt32 sRequestIndex; + return (PRUint32) PR_AtomicIncrement(&sRequestIndex); } //----------------------------------------------------------------------------- @@ -2260,6 +2260,14 @@ DConnectStub::Release() count = PR_AtomicDecrement((PRInt32 *)&mRefCnt); NS_LOG_RELEASE(this, count, "DConnectStub"); + + #ifdef IPC_LOGGING + const char *name; + mIInfo->GetNameShared(&name); + LOG(("{%p} DConnectStub::Release(): peer=%d instance=0x%Lx {%s}, new count=%d\n", + this, mPeerID, mInstance, name, count)); + #endif + // mRefCntLevels may already be empty here (due to the "stabilize" trick below) if (mRefCntLevels.GetSize() > 0) { @@ -2497,9 +2505,16 @@ DConnectStub::CallMethod(PRUint16 aMethodIndex, PRUint8 i, paramCount = aInfo->GetParamCount(); - LOG((" instance=0x%Lx\n", mInstance)); +#ifdef IPC_LOGGING + const char *name; + nsCOMPtr<nsIInterfaceInfo> iinfo; + GetInterfaceInfo(getter_AddRefs(iinfo)); + iinfo->GetNameShared(&name); + LOG((" instance=0x%Lx {%s}\n", mInstance, name)); LOG((" name=%s\n", aInfo->GetName())); LOG((" param-count=%u\n", (PRUint32) paramCount)); +#endif + ipcMessageWriter writer(16 * paramCount); diff --git a/src/libs/xpcom18a4/python/Makefile.kmk b/src/libs/xpcom18a4/python/Makefile.kmk index 2bf2a9ef3..42853d8f5 100644 --- a/src/libs/xpcom18a4/python/Makefile.kmk +++ b/src/libs/xpcom18a4/python/Makefile.kmk @@ -100,7 +100,8 @@ VBoxPython2_4_INCS = $(VBOX_PYTHON24_INC) VBoxPython2_4_LIBS = $(VBOX_PYTHON24_LIB) endif -if defined(VBOX_PYTHON25_INC) && "$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)" == "darwin.x86" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" == "10.5" +if defined(VBOX_PYTHON25_INC) \ + && ("$(KBUILD_TARGET)" != "darwin" || ("$(KBUILD_TARGET_ARCH)" == "x86" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" == "10.5")) # # Python 2.5 version # |