Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 55612)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 55613)
@@ -10368,4 +10368,27 @@
 
   <enum
+    name="PathStyle"
+    uuid="97303a5b-42e8-0a55-d16f-d2a92c295261"
+    >
+    <desc>
+      The path style of a system.
+      (Values matches the RTPATH_STR_F_STYLE_XXX defines in iprt/path.h!)
+    </desc>
+    <const name="DOS"     value="1">
+      <desc>DOS-style paths with forward and backward slashes, drive
+      letters and UNC.  Known from DOS, OS/2 and Windows.</desc>
+    </const>
+    <const name="UNIX"    value="2">
+      <desc>UNIX-style paths with forward slashes only.</desc>
+    </const>
+    <const name="Unknown" value="8">
+      <desc>
+        The path style is not known, most likely because the guest additions
+        aren't active yet.
+      </desc>
+    </const>
+  </enum>
+
+  <enum
     name="FileStatus"
     uuid="8c86468b-b97b-4080-8914-e29f5b0abd2c"
@@ -10776,5 +10799,5 @@
   <interface
     name="IGuestSession" extends="$unknown"
-    uuid="bb890975-4903-38f8-4bc2-f39341f95533"
+    uuid="c003c35e-4dc4-4111-4771-51befc3c1d30"
     wsmap="managed"
     >
@@ -10887,4 +10910,10 @@
       <desc>
         Returns all current guest processes.
+      </desc>
+    </attribute>
+    <attribute name="pathStyle" type="PathStyle" readonly="yes">
+      <desc>
+        The style of paths used by the guest.  Handy for giving the right kind
+        of path specifications to <link to="fileOpen"/> and similar methods.
       </desc>
     </attribute>
@@ -11462,4 +11491,55 @@
       <param name="acl" type="wstring" dir="in">
         <desc>Actual ACL string to set. Must comply with the guest OS.</desc>
+      </param>
+    </method>
+
+    <method name="fsExists">
+      <desc>
+        Checks whether a file system object (file, directory, etc) exists in
+        the guest or not.
+
+        <result name="VBOX_E_IPRT_ERROR">
+          Error while checking existence of the file specified.
+        </result>
+      </desc>
+      <param name="path" type="wstring" dir="in">
+        <desc>Path to the file system object to check the existance of.</desc>
+      </param>
+      <param name="followSymlinks" type="boolean" dir="in">
+        <desc>
+           If @c true symbolic links will be followed and the target must
+           exists and be accessible, otherwise, if @c false we'll be happy
+           with a dangling symbolic link.
+         </desc>
+      </param>
+      <param name="exists" type="boolean" dir="return">
+        <desc>Returns @c true if the file exists, @c false if not.</desc>
+      </param>
+    </method>
+
+    <method name="fsQueryInfo">
+      <desc>
+        Queries information about a file system object (file, directory, etc)
+        in the guest.
+
+        <result name="VBOX_E_OBJECT_NOT_FOUND">
+          The file system object was not found.
+        </result>
+        <result name="VBOX_E_IPRT_ERROR">
+          Error while querying information.
+        </result>
+      </desc>
+      <param name="path" type="wstring" dir="in">
+        <desc>Path to the file system object to gather information about</desc>
+      </param>
+      <param name="followSymlinks" type="boolean" dir="in">
+        <desc>
+           Information about symbolic links is returned if @c false.  Otherwise,
+           symbolic links are followed and the returned information concerns
+           itself with the symlink target if @c true.
+         </desc>
+      </param>
+      <param name="info" type="IGuestFsObjInfo" dir="return">
+        <desc><link to="IGuestFsObjInfo"/> object containing the information.</desc>
       </param>
     </method>
Index: /trunk/src/VBox/Main/include/GuestImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestImpl.h	(revision 55612)
+++ /trunk/src/VBox/Main/include/GuestImpl.h	(revision 55613)
@@ -99,4 +99,5 @@
     int         i_dispatchToSession(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
     uint32_t    i_getAdditionsVersion(void) { return mData.mAdditionsVersionFull; }
+    VBOXOSTYPE  i_getGuestOSType(void) { return mData.mOSType; }
     int         i_sessionRemove(GuestSession *pSession);
     int         i_sessionCreate(const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds,
@@ -178,8 +179,9 @@
     struct Data
     {
-        Data() : mAdditionsRunLevel(AdditionsRunLevelType_None)
+        Data() : mOSType(VBOXOSTYPE_Unknown),  mAdditionsRunLevel(AdditionsRunLevelType_None)
             , mAdditionsVersionFull(0), mAdditionsRevision(0), mAdditionsFeatures(0)
         { }
 
+        VBOXOSTYPE                  mOSType;        /**@< For internal used. VBOXOSTYPE_Unknown if not reported. */
         Utf8Str                     mOSTypeId;
         FacilityMap                 mFacilityMap;
Index: /trunk/src/VBox/Main/include/GuestSessionImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/GuestSessionImpl.h	(revision 55612)
+++ /trunk/src/VBox/Main/include/GuestSessionImpl.h	(revision 55613)
@@ -272,4 +272,5 @@
     HRESULT getEnvironmentBase(std::vector<com::Utf8Str> &aEnvironmentBase);
     HRESULT getProcesses(std::vector<ComPtr<IGuestProcess> > &aProcesses);
+    HRESULT getPathStyle(PathStyle_T *aPathStyle);
     HRESULT getDirectories(std::vector<ComPtr<IGuestDirectory> > &aDirectories);
     HRESULT getFiles(std::vector<ComPtr<IGuestFile> > &aFiles);
@@ -349,4 +350,10 @@
     HRESULT fileSetACL(const com::Utf8Str &aFile,
                        const com::Utf8Str &aAcl);
+    HRESULT fsExists(const com::Utf8Str &aPath,
+                     BOOL aFollowSymlinks,
+                     BOOL *pfExists);
+    HRESULT fsQueryInfo(const com::Utf8Str &aPath,
+                        BOOL aFollowSymlinks,
+                        ComPtr<IGuestFsObjInfo> &aInfo);
     HRESULT processCreate(const com::Utf8Str &aCommand,
                           const std::vector<com::Utf8Str> &aArguments,
@@ -404,5 +411,5 @@
     int                     i_directoryOpenInternal(const GuestDirectoryOpenInfo &openInfo,
                                                     ComObjPtr<GuestDirectory> &pDirectory, int *pGuestRc);
-    int                     i_directoryQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc);
+    int                     i_directoryQueryInfoInternal(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
     int                     i_dispatchToDirectory(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
     int                     i_dispatchToFile(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
@@ -414,7 +421,7 @@
     int                     i_fileRemoveInternal(const Utf8Str &strPath, int *pGuestRc);
     int                     i_fileOpenInternal(const GuestFileOpenInfo &openInfo, ComObjPtr<GuestFile> &pFile, int *pGuestRc);
-    int                     i_fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc);
+    int                     i_fileQueryInfoInternal(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
     int                     i_fileQuerySizeInternal(const Utf8Str &strPath, int64_t *pllSize, int *pGuestRc);
-    int                     i_fsQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc);
+    int                     i_fsQueryInfoInternal(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
     const GuestCredentials &i_getCredentials(void);
     EventSource            *i_getEventSource(void) { return mEventSource; }
Index: /trunk/src/VBox/Main/src-client/GuestFsObjInfoImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestFsObjInfoImpl.cpp	(revision 55612)
+++ /trunk/src/VBox/Main/src-client/GuestFsObjInfoImpl.cpp	(revision 55613)
@@ -63,5 +63,5 @@
     /* Enclose the state transition NotReady->InInit->Ready. */
     AutoInitSpan autoInitSpan(this);
-    AssertReturn(autoInitSpan.isOk(), E_FAIL);
+    AssertReturn(autoInitSpan.isOk(), E_FAIL); /** @todo r=bird: returning COM or IPRT status codes here?*/
 
     mData = objData;
Index: /trunk/src/VBox/Main/src-client/GuestImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestImpl.cpp	(revision 55612)
+++ /trunk/src/VBox/Main/src-client/GuestImpl.cpp	(revision 55613)
@@ -898,4 +898,5 @@
      * its real status when using new(er) Guest Additions.
      */
+    mData.mOSType = aOsType;
     mData.mOSTypeId = Global::OSTypeId(aOsType);
 }
Index: /trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp	(revision 55612)
+++ /trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp	(revision 55613)
@@ -2065,4 +2065,12 @@
 }
 
+/**
+ * <Someone write documentation, pretty please!>
+ *
+ * @param   pGuestRc        Optional.  Will be set to VINF_SUCCESS,
+ *                          VERR_NOT_EQUAL or VERR_INVALID_STATE if the
+ *                          process completed.  Should it fail earlier that,
+ *                          you're feel free to enlighten the rest of us...
+ */
 /* static */
 int GuestProcessTool::i_runEx(      GuestSession            *pGuestSession,
Index: /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp	(revision 55612)
+++ /trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp	(revision 55613)
@@ -549,4 +549,29 @@
 }
 
+HRESULT GuestSession::getPathStyle(PathStyle_T *aPathStyle)
+{
+#ifndef VBOX_WITH_GUEST_CONTROL
+    ReturnComNotImplemented();
+#else
+    VBOXOSTYPE enmOsType = mParent->i_getGuestOSType();
+    if (    enmOsType < VBOXOSTYPE_DOS)
+    {
+        *aPathStyle = PathStyle_Unknown;
+        LogFlowFunc(("returns PathStyle_Unknown\n"));
+    }
+    else if (enmOsType < VBOXOSTYPE_Linux)
+    {
+        *aPathStyle = PathStyle_DOS;
+        LogFlowFunc(("returns PathStyle_DOS\n"));
+    }
+    else
+    {
+        *aPathStyle = PathStyle_UNIX;
+        LogFlowFunc(("returns PathStyle_UNIX\n"));
+    }
+    return S_OK;
+#endif
+}
+
 HRESULT GuestSession::getDirectories(std::vector<ComPtr<IGuestDirectory> > &aDirectories)
 {
@@ -734,9 +759,10 @@
 }
 
-int GuestSession::i_directoryQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc)
-{
-    LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
-
-    int vrc = i_fsQueryInfoInternal(strPath, objData, pGuestRc);
+int GuestSession::i_directoryQueryInfoInternal(const Utf8Str &strPath, bool fFollowSymlinks,
+                                               GuestFsObjData &objData, int *pGuestRc)
+{
+    LogFlowThisFunc(("strPath=%s fFollowSymlinks=%RTbool\n", strPath.c_str(), fFollowSymlinks));
+
+    int vrc = i_fsQueryInfoInternal(strPath, fFollowSymlinks, objData, pGuestRc);
     if (RT_SUCCESS(vrc))
     {
@@ -1360,9 +1386,9 @@
 }
 
-int GuestSession::i_fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc)
-{
-    LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
-
-    int vrc = i_fsQueryInfoInternal(strPath, objData, pGuestRc);
+int GuestSession::i_fileQueryInfoInternal(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc)
+{
+    LogFlowThisFunc(("strPath=%s fFollowSymlinks=%RTbool\n", strPath.c_str(), fFollowSymlinks));
+
+    int vrc = i_fsQueryInfoInternal(strPath, fFollowSymlinks, objData, pGuestRc);
     if (RT_SUCCESS(vrc))
     {
@@ -1380,5 +1406,5 @@
 
     GuestFsObjData objData;
-    int vrc = i_fileQueryInfoInternal(strPath, objData, pGuestRc);
+    int vrc = i_fileQueryInfoInternal(strPath, false /*fFollowSymlinks*/, objData, pGuestRc);
     if (RT_SUCCESS(vrc))
         *pllSize = objData.mObjectSize;
@@ -1387,5 +1413,14 @@
 }
 
-int GuestSession::i_fsQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc)
+/**
+ * <Someone write documentation, pretty please!>
+ *
+ * @param   pGuestRc        Optional.  Will be set to VINF_SUCCESS,
+ *                          VERR_NOT_EQUAL or VERR_INVALID_STATE if the
+ *                          process completed.  May probably be set to a lot of
+ *                          other things.  Not sure if these things are related
+ *                          to the process we ran or what, really.  :-(
+ */
+int GuestSession::i_fsQueryInfoInternal(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc)
 {
     LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
@@ -1409,5 +1444,6 @@
     }
 
-    int guestRc; GuestCtrlStreamObjects stdOut;
+    int guestRc;
+    GuestCtrlStreamObjects stdOut;
     if (RT_SUCCESS(vrc))
         vrc = GuestProcessTool::i_runEx(this, procInfo,
@@ -2648,5 +2684,5 @@
 
     GuestFsObjData objData; int guestRc;
-    int rc = i_directoryQueryInfoInternal(aPath, objData, &guestRc);
+    int rc = i_directoryQueryInfoInternal(aPath, false /*fFollowSymlinks*/, objData, &guestRc);
     if (RT_SUCCESS(rc))
         *aExists = objData.mType == FsObjType_Directory;
@@ -2744,5 +2780,5 @@
 
     GuestFsObjData objData; int guestRc;
-    int vrc = i_directoryQueryInfoInternal(aPath, objData, &guestRc);
+    int vrc = i_directoryQueryInfoInternal(aPath, false /*fFollowSymlinks*/, objData, &guestRc);
     if (RT_SUCCESS(vrc))
     {
@@ -3107,5 +3143,5 @@
 
     GuestFsObjData objData; int guestRc;
-    int vrc = i_fileQueryInfoInternal(aPath, objData, &guestRc);
+    int vrc = i_fileQueryInfoInternal(aPath, false /*fFollowSymlinks*/, objData, &guestRc);
     if (RT_SUCCESS(vrc))
     {
@@ -3268,5 +3304,5 @@
 
     GuestFsObjData objData; int guestRc;
-    int vrc = i_fileQueryInfoInternal(aPath, objData, &guestRc);
+    int vrc = i_fileQueryInfoInternal(aPath, false /*fFollowSymlinks*/, objData, &guestRc);
     if (RT_SUCCESS(vrc))
     {
@@ -3387,4 +3423,5 @@
 #endif /* VBOX_WITH_GUEST_CONTROL */
 }
+
 HRESULT GuestSession::fileSetACL(const com::Utf8Str &aFile, const com::Utf8Str &aAcl)
 {
@@ -3395,4 +3432,75 @@
 
     ReturnComNotImplemented();
+#endif /* VBOX_WITH_GUEST_CONTROL */
+}
+
+HRESULT GuestSession::fsExists(const com::Utf8Str &aPath, BOOL aFollowSymlinks, BOOL *aExists)
+{
+#ifndef VBOX_WITH_GUEST_CONTROL
+    ReturnComNotImplemented();
+#else
+    LogFlowThisFuncEnter();
+
+    HRESULT hrc = S_OK;
+    *aExists = false;
+    if (RT_LIKELY(aPath.isNotEmpty()))
+    {
+        GuestFsObjData objData;
+        int rcGuest;
+        int vrc = i_fsQueryInfoInternal(aPath, aFollowSymlinks != FALSE, objData, &rcGuest);
+        if (RT_SUCCESS(vrc))
+            *aExists = TRUE;
+        else if (   vrc == VERR_NOT_A_FILE
+                 || vrc == VERR_PATH_NOT_FOUND
+                 || vrc == VERR_FILE_NOT_FOUND
+                 || vrc == VERR_INVALID_NAME)
+            hrc = S_OK; /* Ignore these vrc values. */
+        else if (vrc == VERR_GSTCTL_GUEST_ERROR) /** @todo What _is_ rcGuest, really? Stuff like VERR_NOT_A_FILE too?? */
+            hrc = GuestProcess::i_setErrorExternal(this, rcGuest);
+        else
+            hrc = setErrorVrc(vrc, tr("Querying file information for \"%s\" failed: %Rrc"), aPath.c_str(), vrc);
+    }
+    /* else: If the file name is empty, there is no way it can exists. So, don't
+       be a tedious and return E_INVALIDARG, simply return FALSE. */
+    LogFlowThisFuncLeave();
+    return hrc;
+#endif /* VBOX_WITH_GUEST_CONTROL */
+}
+
+HRESULT GuestSession::fsQueryInfo(const com::Utf8Str &aPath, BOOL aFollowSymlinks, ComPtr<IGuestFsObjInfo> &aInfo)
+{
+#ifndef VBOX_WITH_GUEST_CONTROL
+    ReturnComNotImplemented();
+#else
+    LogFlowThisFuncEnter();
+
+    HRESULT hrc = S_OK;
+    if (RT_LIKELY(aPath.isNotEmpty()))
+    {
+        GuestFsObjData Info;
+        int rcGuest;
+        int vrc = i_fsQueryInfoInternal(aPath, aFollowSymlinks != FALSE, Info, &rcGuest);
+        if (RT_SUCCESS(vrc))
+        {
+            ComObjPtr<GuestFsObjInfo> ptrFsObjInfo;
+            hrc = ptrFsObjInfo.createObject();
+            if (SUCCEEDED(hrc))
+            {
+                vrc = ptrFsObjInfo->init(Info);
+                if (RT_SUCCESS(vrc))
+                    hrc = ptrFsObjInfo.queryInterfaceTo(aInfo.asOutParam());
+                else
+                    hrc = setErrorVrc(vrc);
+            }
+        }
+        else if (vrc == VERR_GSTCTL_GUEST_ERROR)
+            hrc = GuestProcess::i_setErrorExternal(this, rcGuest);
+        else
+            hrc = setErrorVrc(vrc, tr("Querying file information for \"%s\" failed: %Rrc"), aPath.c_str(), vrc);
+    }
+    /* else: If the file name is empty, there is no way it can exists. So, don't
+       be a tedious and return E_INVALIDARG, simply return FALSE. */
+    LogFlowThisFuncLeave();
+    return hrc;
 #endif /* VBOX_WITH_GUEST_CONTROL */
 }
Index: /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 55612)
+++ /trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp	(revision 55613)
@@ -607,5 +607,5 @@
      */
     GuestFsObjData objData; int guestRc;
-    int rc = pSession->i_fileQueryInfoInternal(Utf8Str(mSource), objData, &guestRc);
+    int rc = pSession->i_fileQueryInfoInternal(Utf8Str(mSource), false /*fFollowSymlinks*/, objData, &guestRc);
     if (RT_FAILURE(rc))
     {
