Index: /trunk/src/VBox/Main/include/GuestFileImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestFileImpl.h	(revision 71781)
+++ /trunk/src/VBox/Main/include/GuestFileImpl.h	(revision 71782)
@@ -56,4 +56,5 @@
     int             i_onRemove(void);
     int             i_openFile(uint32_t uTimeoutMS, int *pGuestRc);
+    int             i_queryInfo(GuestFsObjData &objData, int *prcGuest);
     int             i_readData(uint32_t uSize, uint32_t uTimeoutMS, void* pvData, uint32_t cbData, uint32_t* pcbRead);
     int             i_readDataAt(uint64_t uOffset, uint32_t uSize, uint32_t uTimeoutMS,
Index: /trunk/src/VBox/Main/src-client/GuestFileImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestFileImpl.cpp	(revision 71781)
+++ /trunk/src/VBox/Main/src-client/GuestFileImpl.cpp	(revision 71782)
@@ -434,6 +434,4 @@
         return VERR_INVALID_PARAMETER;
 
-    int rc = VINF_SUCCESS;
-
     int idx = 1; /* Current parameter index. */
     CALLBACKDATA_FILE_NOTIFY dataCb;
@@ -444,6 +442,5 @@
     int rcGuest = (int)dataCb.rc; /* uint32_t vs. int. */
 
-    LogFlowFunc(("uType=%RU32, rcGuest=%Rrc\n",
-                 dataCb.uType, rcGuest));
+    LogFlowThisFunc(("uType=%RU32, rcGuest=%Rrc\n", dataCb.uType, rcGuest));
 
     if (RT_FAILURE(rcGuest))
@@ -457,11 +454,15 @@
     }
 
+    AssertMsg(mObjectID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID),
+              ("File ID %RU32 does not match object ID %RU32\n", mObjectID,
+               VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID)));
+
+    int rc = VERR_NOT_SUPPORTED; /* Play safe by default. */
+
     switch (dataCb.uType)
     {
         case GUEST_FILE_NOTIFYTYPE_ERROR:
         {
-            int rc2 = i_setFileStatus(FileStatus_Error, rcGuest);
-            AssertRC(rc2);
-
+            rc = i_setFileStatus(FileStatus_Error, rcGuest);
             break;
         }
@@ -471,17 +472,11 @@
             if (pSvcCbData->mParms == 4)
             {
-                pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle);
-
-                AssertMsg(mObjectID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID),
-                          ("File ID %RU32 does not match object ID %RU32\n", mObjectID,
-                           VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID)));
+                rc = pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle);
+                if (RT_FAILURE(rc))
+                    break;
 
                 /* Set the process status. */
-                int rc2 = i_setFileStatus(FileStatus_Open, rcGuest);
-                AssertRC(rc2);
+                rc = i_setFileStatus(FileStatus_Open, rcGuest);
             }
-            else
-                rc = VERR_NOT_SUPPORTED;
-
             break;
         }
@@ -489,7 +484,5 @@
         case GUEST_FILE_NOTIFYTYPE_CLOSE:
         {
-            int rc2 = i_setFileStatus(FileStatus_Closed, rcGuest);
-            AssertRC(rc2);
-
+            rc = i_setFileStatus(FileStatus_Closed, rcGuest);
             break;
         }
@@ -499,7 +492,11 @@
             if (pSvcCbData->mParms == 4)
             {
-                pSvcCbData->mpaParms[idx++].getPointer(&dataCb.u.read.pvData,
-                                                       &dataCb.u.read.cbData);
-                uint32_t cbRead = dataCb.u.read.cbData;
+                rc = pSvcCbData->mpaParms[idx++].getPointer(&dataCb.u.read.pvData, &dataCb.u.read.cbData);
+                if (RT_FAILURE(rc))
+                    break;
+
+                const uint32_t cbRead = dataCb.u.read.cbData;
+
+                Log3ThisFunc(("cbRead=%RU32\n", cbRead));
 
                 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -515,6 +512,4 @@
                                        cbRead, ComSafeArrayAsInParam(data));
             }
-            else
-                rc = VERR_NOT_SUPPORTED;
             break;
         }
@@ -524,18 +519,19 @@
             if (pSvcCbData->mParms == 4)
             {
-                pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.write.cbWritten);
+                rc = pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.write.cbWritten);
+                if (RT_FAILURE(rc))
+                    break;
+
+                Log3ThisFunc(("cbWritten=%RU32\n", dataCb.u.write.cbWritten));
 
                 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
                 mData.mOffCurrent += dataCb.u.write.cbWritten;
-                uint64_t uOffCurrent = mData.mOffCurrent;
 
                 alock.release();
 
-                fireGuestFileWriteEvent(mEventSource, mSession, this, uOffCurrent,
+                fireGuestFileWriteEvent(mEventSource, mSession, this, mData.mOffCurrent,
                                         dataCb.u.write.cbWritten);
             }
-            else
-                rc = VERR_NOT_SUPPORTED;
             break;
         }
@@ -545,5 +541,9 @@
             if (pSvcCbData->mParms == 4)
             {
-                pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.seek.uOffActual);
+                rc = pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.seek.uOffActual);
+                if (RT_FAILURE(rc))
+                    break;
+
+                Log3ThisFunc(("uOffActual=%RU64\n", dataCb.u.seek.uOffActual));
 
                 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -553,9 +553,6 @@
                 alock.release();
 
-                fireGuestFileOffsetChangedEvent(mEventSource, mSession, this,
-                                                dataCb.u.seek.uOffActual, 0 /* Processed */);
+                fireGuestFileOffsetChangedEvent(mEventSource, mSession, this, mData.mOffCurrent, 0 /* Processed */);
             }
-            else
-                rc = VERR_NOT_SUPPORTED;
             break;
         }
@@ -565,5 +562,9 @@
             if (pSvcCbData->mParms == 4)
             {
-                pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.tell.uOffActual);
+                rc = pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.tell.uOffActual);
+                if (RT_FAILURE(rc))
+                    break;
+
+                Log3ThisFunc(("uOffActual=%RU64\n", dataCb.u.tell.uOffActual));
 
                 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
@@ -573,14 +574,10 @@
                 alock.release();
 
-                fireGuestFileOffsetChangedEvent(mEventSource, mSession, this,
-                                                dataCb.u.tell.uOffActual, 0 /* Processed */);
+                fireGuestFileOffsetChangedEvent(mEventSource, mSession, this, mData.mOffCurrent, 0 /* Processed */);
             }
-            else
-                rc = VERR_NOT_SUPPORTED;
             break;
         }
 
         default:
-            rc = VERR_NOT_SUPPORTED;
             break;
     }
@@ -639,12 +636,66 @@
 int GuestFile::i_openFile(uint32_t uTimeoutMS, int *prcGuest)
 {
+    AssertReturn(mData.mOpenInfo.mFileName.isNotEmpty(), VERR_INVALID_PARAMETER);
+
     LogFlowThisFuncEnter();
 
     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    LogFlowThisFunc(("strFile=%s, enmAccessMode=%d (%s) enmOpenAction=%d (%s) uCreationMode=%RU32, mfOpenEx=%RU32\n",
-                     mData.mOpenInfo.mFileName.c_str(), mData.mOpenInfo.mAccessMode, mData.mOpenInfo.mpszAccessMode,
-                     mData.mOpenInfo.mOpenAction, mData.mOpenInfo.mpszOpenAction, mData.mOpenInfo.mCreationMode,
-                     mData.mOpenInfo.mfOpenEx));
+    LogFlowThisFunc(("strFile=%s, enmAccessMode=0x%x, enmOpenAction=0x%x, uCreationMode=%RU32, mfOpenEx=%RU32\n",
+                     mData.mOpenInfo.mFileName.c_str(), mData.mOpenInfo.mAccessMode, mData.mOpenInfo.mOpenAction,
+                     mData.mOpenInfo.mCreationMode, mData.mOpenInfo.mfOpenEx));
+
+    /* Validate and translate open action. */
+    const char *pszOpenAction = NULL;
+    switch (mData.mOpenInfo.mOpenAction)
+    {
+        case (FileOpenAction_T)FileOpenAction_OpenExisting:          pszOpenAction = "oe"; break;
+        case (FileOpenAction_T)FileOpenAction_OpenOrCreate:          pszOpenAction = "oc"; break;
+        case (FileOpenAction_T)FileOpenAction_CreateNew:             pszOpenAction = "ce"; break;
+        case (FileOpenAction_T)FileOpenAction_CreateOrReplace:       pszOpenAction = "ca"; break;
+        case (FileOpenAction_T)FileOpenAction_OpenExistingTruncated: pszOpenAction = "ot"; break;
+        case (FileOpenAction_T)FileOpenAction_AppendOrCreate:
+            pszOpenAction = "oa"; /** @todo get rid of this one and implement AppendOnly/AppendRead. */
+            break;
+        default:
+            return VERR_INVALID_PARAMETER;
+    }
+
+    /* Validate and translate access mode. */
+    const char *pszAccessMode = NULL;
+    switch (mData.mOpenInfo.mAccessMode)
+    {
+        case (FileAccessMode_T)FileAccessMode_ReadOnly:  pszAccessMode = "r";  break;
+        case (FileAccessMode_T)FileAccessMode_WriteOnly: pszAccessMode = "w";  break;
+        case (FileAccessMode_T)FileAccessMode_ReadWrite: pszAccessMode = "r+"; break;
+        case (FileAccessMode_T)FileAccessMode_AppendOnly:
+            RT_FALL_THRU();
+        case (FileAccessMode_T)FileAccessMode_AppendRead:
+            return VERR_NOT_IMPLEMENTED;
+        default:
+            return VERR_INVALID_PARAMETER;
+    }
+
+    /* Validate and translate sharing mode. */
+    const char *pszSharingMode = NULL;
+    switch (mData.mOpenInfo.mSharingMode)
+    {
+        case (FileSharingMode_T)FileSharingMode_All:       pszSharingMode = ""; break;
+        case (FileSharingMode_T)FileSharingMode_Read:
+            RT_FALL_THRU();
+        case (FileSharingMode_T)FileSharingMode_Write:
+            RT_FALL_THRU();
+        case (FileSharingMode_T)FileSharingMode_ReadWrite:
+            RT_FALL_THRU();
+        case (FileSharingMode_T)FileSharingMode_Delete:
+            RT_FALL_THRU();
+        case (FileSharingMode_T)FileSharingMode_ReadDelete:
+            RT_FALL_THRU();
+        case (FileSharingMode_T)FileSharingMode_WriteDelete:
+            return VERR_NOT_IMPLEMENTED;
+        default:
+            return VERR_INVALID_PARAMETER;
+    }
+
     int vrc;
 
@@ -671,9 +722,9 @@
     paParms[i++].setPointer((void*)mData.mOpenInfo.mFileName.c_str(),
                             (ULONG)mData.mOpenInfo.mFileName.length() + 1);
-    paParms[i++].setString(mData.mOpenInfo.mpszAccessMode);
-    paParms[i++].setString(mData.mOpenInfo.mpszOpenAction);
-    paParms[i++].setString(""); /** @todo sharing mode. */
+    paParms[i++].setString(pszAccessMode);
+    paParms[i++].setString(pszOpenAction);
+    paParms[i++].setString(pszSharingMode);
     paParms[i++].setUInt32(mData.mOpenInfo.mCreationMode);
-    paParms[i++].setUInt64(0 /* initial offset */);
+    paParms[i++].setUInt64(mData.mOpenInfo.muOffset);
     /** @todo Next protocol version: add flags, replace strings, remove initial offset. */
 
@@ -688,4 +739,10 @@
     LogFlowFuncLeaveRC(vrc);
     return vrc;
+}
+
+int GuestFile::i_queryInfo(GuestFsObjData &objData, int *prcGuest)
+{
+    AssertPtr(mSession);
+    return mSession->i_fsQueryInfo(mData.mOpenInfo.mFileName, FALSE /* fFollowSymlinks */, objData, prcGuest);
 }
 
@@ -956,12 +1013,14 @@
                 hr = pFileEvent->COMGETTER(Data)(ComSafeArrayAsOutParam(data));
                 ComAssertComRC(hr);
-                size_t cbRead = data.size();
-                if (   cbRead
-                    && cbRead <= cbData)
+                const size_t cbRead = data.size();
+                if (cbRead)
                 {
-                    memcpy(pvData, data.raw(), data.size());
+                    if (cbRead <= cbData)
+                        memcpy(pvData, data.raw(), cbRead);
+                    else
+                        vrc = VERR_BUFFER_OVERFLOW;
                 }
                 else
-                    vrc = VERR_BUFFER_OVERFLOW;
+                    vrc = VERR_NO_DATA;
             }
             if (pcbRead)
@@ -1205,12 +1264,67 @@
 HRESULT GuestFile::queryInfo(ComPtr<IFsObjInfo> &aObjInfo)
 {
-    RT_NOREF(aObjInfo);
-    ReturnComNotImplemented();
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    LogFlowThisFuncEnter();
+
+    HRESULT hr = S_OK;
+
+    GuestFsObjData fsObjData; int rcGuest;
+    int vrc = i_queryInfo(fsObjData, &rcGuest);
+    if (RT_SUCCESS(vrc))
+    {
+        ComObjPtr<GuestFsObjInfo> ptrFsObjInfo;
+        hr = ptrFsObjInfo.createObject();
+        if (SUCCEEDED(hr))
+        {
+            vrc = ptrFsObjInfo->init(fsObjData);
+            if (RT_SUCCESS(vrc))
+                hr = ptrFsObjInfo.queryInterfaceTo(aObjInfo.asOutParam());
+            else
+                hr = setErrorVrc(vrc);
+        }
+    }
+    else
+    {
+        if (GuestProcess::i_isGuestError(vrc))
+        {
+            hr = GuestProcess::i_setErrorExternal(this, rcGuest);
+        }
+        else
+            hr = setErrorVrc(vrc, tr("Querying file information failed: %Rrc"), vrc);
+    }
+
+    LogFlowFuncLeaveRC(vrc);
+    return hr;
 }
 
 HRESULT GuestFile::querySize(LONG64 *aSize)
 {
-    RT_NOREF(aSize);
-    ReturnComNotImplemented();
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    LogFlowThisFuncEnter();
+
+    HRESULT hr = S_OK;
+
+    GuestFsObjData fsObjData; int rcGuest;
+    int vrc = i_queryInfo(fsObjData, &rcGuest);
+    if (RT_SUCCESS(vrc))
+    {
+        *aSize = fsObjData.mObjectSize;
+    }
+    else
+    {
+        if (GuestProcess::i_isGuestError(vrc))
+        {
+            hr = GuestProcess::i_setErrorExternal(this, rcGuest);
+        }
+        else
+            hr = setErrorVrc(vrc, tr("Querying file size failed: %Rrc"), vrc);
+    }
+
+    LogFlowFuncLeaveRC(vrc);
+    return hr;
 }
 
@@ -1255,6 +1369,6 @@
     return hr;
 }
+
 HRESULT GuestFile::readAt(LONG64 aOffset, ULONG aToRead, ULONG aTimeoutMS, std::vector<BYTE> &aData)
-
 {
     AutoCaller autoCaller(this);
@@ -1387,5 +1501,4 @@
 
 HRESULT GuestFile::writeAt(LONG64 aOffset, const std::vector<BYTE> &aData, ULONG aTimeoutMS, ULONG *aWritten)
-
 {
     AutoCaller autoCaller(this);
