Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp	(revision 35305)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageDebugVM.cpp	(revision 35306)
@@ -44,4 +44,24 @@
 
 /**
+ * Handles the info sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param   a                   The handler arguments.
+ * @param   pDebugger           Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_Info(HandlerArg *a, IMachineDebugger *pDebugger)
+{
+    if (a->argc < 3 || a->argc > 4)
+        return errorSyntax(USAGE_DEBUGVM, "The inject sub-command takes at one or two arguments");
+
+    com::Bstr bstrName(a->argv[2]);
+    com::Bstr bstrArgs(a->argv[3]);
+    com::Bstr bstrInfo;
+    CHECK_ERROR2_RET(pDebugger, Info(bstrName.raw(), bstrArgs.raw(), bstrInfo.asOutParam()), RTEXITCODE_FAILURE);
+    RTPrintf("%ls", bstrInfo.raw());
+    return RTEXITCODE_SUCCESS;
+}
+
+/**
  * Handles the inject sub-command.
  *
@@ -116,4 +136,43 @@
     com::Bstr bstrCompression(pszCompression);
     CHECK_ERROR2_RET(pDebugger, DumpGuestCore(bstrFilename.raw(), bstrCompression.raw()), RTEXITCODE_FAILURE);
+    return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the os sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param   a                   The handler arguments.
+ * @param   pDebugger           Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_OSDetect(HandlerArg *a, IMachineDebugger *pDebugger)
+{
+    if (a->argc != 2)
+        return errorSyntax(USAGE_DEBUGVM, "The osdetect sub-command does not take any arguments");
+
+    com::Bstr bstrName;
+    CHECK_ERROR2_RET(pDebugger, DetectOS(bstrName.asOutParam()), RTEXITCODE_FAILURE);
+    RTPrintf("Detected: %ls\n", bstrName.raw());
+    return RTEXITCODE_SUCCESS;
+}
+
+/**
+ * Handles the os sub-command.
+ *
+ * @returns Suitable exit code.
+ * @param   a                   The handler arguments.
+ * @param   pDebugger           Pointer to the debugger interface.
+ */
+static RTEXITCODE handleDebugVM_OSInfo(HandlerArg *a, IMachineDebugger *pDebugger)
+{
+    if (a->argc != 2)
+        return errorSyntax(USAGE_DEBUGVM, "The osinfo sub-command does not take any arguments");
+
+    com::Bstr bstrName;
+    CHECK_ERROR2_RET(pDebugger, COMGETTER(OSName)(bstrName.asOutParam()), RTEXITCODE_FAILURE);
+    com::Bstr bstrVersion;
+    CHECK_ERROR2_RET(pDebugger, COMGETTER(OSVersion)(bstrVersion.asOutParam()), RTEXITCODE_FAILURE);
+    RTPrintf("Name:    %ls\n", bstrName.raw());
+    RTPrintf("Version: %ls\n", bstrVersion.raw());
     return RTEXITCODE_SUCCESS;
 }
@@ -224,6 +283,12 @@
             if (!strcmp(pszSubCmd, "dumpguestcore"))
                 rcExit = handleDebugVM_DumpVMCore(pArgs, ptrDebugger);
+            else if (!strcmp(pszSubCmd, "info"))
+                rcExit = handleDebugVM_Info(pArgs, ptrDebugger);
             else if (!strcmp(pszSubCmd, "injectnmi"))
                 rcExit = handleDebugVM_InjectNMI(pArgs, ptrDebugger);
+            else if (!strcmp(pszSubCmd, "osdetect"))
+                rcExit = handleDebugVM_OSDetect(pArgs, ptrDebugger);
+            else if (!strcmp(pszSubCmd, "osinfo"))
+                rcExit = handleDebugVM_OSInfo(pArgs, ptrDebugger);
             else if (!strcmp(pszSubCmd, "statistics"))
                 rcExit = handleDebugVM_Statistics(pArgs, ptrDebugger);
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 35305)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 35306)
@@ -612,5 +612,8 @@
                      "VBoxManage debugvm          <uuid>|<name>\n"
                      "                            dumpguestcore --filename <name> |\n"
+                     "                            info <item> [args] |\n"
                      "                            injectnmi |\n"
+                     "                            osdetect |\n"
+                     "                            osinfo |\n"
                      "                            statistics [--reset] [--pattern <pattern>]\n"
                      "                            [--descriptions]\n"
Index: /trunk/src/VBox/Main/MachineDebuggerImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MachineDebuggerImpl.cpp	(revision 35305)
+++ /trunk/src/VBox/Main/MachineDebuggerImpl.cpp	(revision 35306)
@@ -1,11 +1,9 @@
 /* $Id$ */
-
 /** @file
- *
- * VirtualBox COM class implementation
+ * VBox IMachineDebugger COM class implementation.
  */
 
 /*
- * Copyright (C) 2006-2008 Oracle Corporation
+ * Copyright (C) 2006-2010 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -546,10 +544,74 @@
 STDMETHODIMP MachineDebugger::COMGETTER(OSName)(BSTR *a_pbstrName)
 {
-    ReturnComNotImplemented();
+    LogFlowThisFunc(("\n"));
+    CheckComArgNotNull(a_pbstrName);
+    AutoCaller autoCaller(this);
+    HRESULT hrc = autoCaller.rc();
+    if (SUCCEEDED(hrc))
+    {
+        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+        Console::SafeVMPtr ptrVM(mParent);
+        hrc = ptrVM.rc();
+        if (SUCCEEDED(hrc))
+        {
+            /*
+             * Do the job and try convert the name.
+             */
+            char szName[64];
+            int vrc = DBGFR3OSQueryNameAndVersion(ptrVM.raw(), szName, sizeof(szName), NULL, 0);
+            if (RT_SUCCESS(vrc))
+            {
+                try
+                {
+                    Bstr bstrName(szName);
+                    bstrName.detachTo(a_pbstrName);
+                }
+                catch (std::bad_alloc)
+                {
+                    hrc = E_OUTOFMEMORY;
+                }
+            }
+            else
+                hrc = setError(VBOX_E_VM_ERROR, tr("DBGFR3OSQueryNameAndVersion failed with %Rrc"), vrc);
+        }
+    }
+    return hrc;
 }
 
 STDMETHODIMP MachineDebugger::COMGETTER(OSVersion)(BSTR *a_pbstrVersion)
 {
-    ReturnComNotImplemented();
+    LogFlowThisFunc(("\n"));
+    CheckComArgNotNull(a_pbstrVersion);
+    AutoCaller autoCaller(this);
+    HRESULT hrc = autoCaller.rc();
+    if (SUCCEEDED(hrc))
+    {
+        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+        Console::SafeVMPtr ptrVM(mParent);
+        hrc = ptrVM.rc();
+        if (SUCCEEDED(hrc))
+        {
+            /*
+             * Do the job and try convert the name.
+             */
+            char szVersion[256];
+            int vrc = DBGFR3OSQueryNameAndVersion(ptrVM.raw(), NULL, 0, szVersion, sizeof(szVersion));
+            if (RT_SUCCESS(vrc))
+            {
+                try
+                {
+                    Bstr bstrVersion(szVersion);
+                    bstrVersion.detachTo(a_pbstrVersion);
+                }
+                catch (std::bad_alloc)
+                {
+                    hrc = E_OUTOFMEMORY;
+                }
+            }
+            else
+                hrc = setError(VBOX_E_VM_ERROR, tr("DBGFR3OSQueryNameAndVersion failed with %Rrc"), vrc);
+        }
+    }
+    return hrc;
 }
 
@@ -708,7 +770,175 @@
 }
 
+/**
+ * Debug info string buffer formatter.
+ */
+typedef struct MACHINEDEBUGGERINOFHLP
+{
+    /** The core info helper structure. */
+    DBGFINFOHLP Core;
+    /** Pointer to the buffer. */
+    char       *pszBuf;
+    /** The size of the buffer. */
+    size_t      cbBuf;
+    /** The offset into the buffer */
+    size_t      offBuf;
+    /** Indicates an out-of-memory condition. */
+    bool        fOutOfMemory;
+} MACHINEDEBUGGERINOFHLP;
+/** Pointer to a Debug info string buffer formatter. */
+typedef MACHINEDEBUGGERINOFHLP *PMACHINEDEBUGGERINOFHLP;
+
+
+/**
+ * @callback_method_impl{FNRTSTROUTPUT}
+ */
+static DECLCALLBACK(size_t) MachineDebuggerInfoOutput(void *pvArg, const char *pachChars, size_t cbChars)
+{
+    PMACHINEDEBUGGERINOFHLP pHlp = (PMACHINEDEBUGGERINOFHLP)pvArg;
+
+    /*
+     * Grow the buffer if required.
+     */
+    size_t const cbRequired  = cbChars + pHlp->offBuf + 1;
+    if (cbRequired > pHlp->cbBuf)
+    {
+        if (RT_UNLIKELY(pHlp->fOutOfMemory))
+            return 0;
+
+        size_t cbBufNew = pHlp->cbBuf * 2;
+        if (cbRequired > cbBufNew)
+            cbBufNew = RT_ALIGN_Z(cbRequired, 256);
+        void *pvBufNew = RTMemRealloc(pHlp->pszBuf, cbBufNew);
+        if (RT_UNLIKELY(!pvBufNew))
+        {
+            pHlp->fOutOfMemory = true;
+            RTMemFree(pHlp->pszBuf);
+            pHlp->pszBuf = NULL;
+            pHlp->cbBuf  = 0;
+            pHlp->offBuf = 0;
+            return 0;
+        }
+
+        pHlp->pszBuf = (char *)pvBufNew;
+        pHlp->cbBuf  = cbBufNew;
+    }
+
+    /*
+     * Copy the bytes into the buffer and terminate it.
+     */
+    memcpy(&pHlp->pszBuf[pHlp->offBuf], pachChars, cbChars);
+    pHlp->offBuf += cbChars;
+    pHlp->pszBuf[pHlp->offBuf] = '\0';
+    Assert(pHlp->offBuf < pHlp->cbBuf);
+    return cbChars;
+}
+
+/**
+ * @interface_method_impl{DBGFINFOHLP, pfnPrintfV}
+ */
+static DECLCALLBACK(void) MachineDebuggerInfoPrintfV(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list va)
+{
+    RTStrFormatV(MachineDebuggerInfoOutput, (void *)pHlp, NULL,  NULL, pszFormat, va);
+}
+
+/**
+ * @interface_method_impl{DBGFINFOHLP, pfnPrintf}
+ */
+static DECLCALLBACK(void) MachineDebuggerInfoPrintf(PCDBGFINFOHLP pHlp, const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    MachineDebuggerInfoPrintfV(pHlp, pszFormat, va);
+    va_end(va);
+}
+
+/**
+ * Initializes the debug info string buffer formatter
+ *
+ * @param   pHlp                The help structure to init.
+ */
+static void MachineDebuggerInfoInit(PMACHINEDEBUGGERINOFHLP pHlp)
+{
+    pHlp->Core.pfnPrintf    = MachineDebuggerInfoPrintf;
+    pHlp->Core.pfnPrintfV   = MachineDebuggerInfoPrintfV;
+    pHlp->pszBuf            = NULL;
+    pHlp->cbBuf             = 0;
+    pHlp->offBuf            = 0;
+    pHlp->fOutOfMemory      = false;
+}
+
+/**
+ * Deletes the debug info string buffer formatter.
+ * @param   pHlp                The helper structure to delete.
+ */
+static void MachineDebuggerInfoDelete(PMACHINEDEBUGGERINOFHLP pHlp)
+{
+    RTMemFree(pHlp->pszBuf);
+    pHlp->pszBuf = NULL;
+}
+
 STDMETHODIMP MachineDebugger::Info(IN_BSTR a_bstrName, IN_BSTR a_bstrArgs, BSTR *a_pbstrInfo)
 {
-    ReturnComNotImplemented();
+    LogFlowThisFunc(("\n"));
+
+    /*
+     * Validate and convert input.
+     */
+    CheckComArgStrNotEmptyOrNull(a_bstrName);
+    Utf8Str strName, strArgs;
+    try
+    {
+        strName = a_bstrName;
+        strArgs = a_bstrArgs;
+    }
+    catch (std::bad_alloc)
+    {
+        return E_OUTOFMEMORY;
+    }
+
+    /*
+     * Do the autocaller and lock bits.
+     */
+    AutoCaller autoCaller(this);
+    HRESULT hrc = autoCaller.rc();
+    if (SUCCEEDED(hrc))
+    {
+        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+        Console::SafeVMPtr ptrVM(mParent);
+        hrc = ptrVM.rc();
+        if (SUCCEEDED(hrc))
+        {
+            /*
+             * Create a helper and call DBGFR3Info.
+             */
+            MACHINEDEBUGGERINOFHLP Hlp;
+            MachineDebuggerInfoInit(&Hlp);
+            int vrc = DBGFR3Info(ptrVM.raw(),  strName.c_str(),  strArgs.c_str(), &Hlp.Core);
+            if (RT_SUCCESS(vrc))
+            {
+                if (!Hlp.fOutOfMemory)
+                {
+                    /*
+                     * Convert the info string, watching out for allocation errors.
+                     */
+                    try
+                    {
+                        Bstr bstrInfo(Hlp.pszBuf);
+                        bstrInfo.detachTo(a_pbstrInfo);
+                    }
+                    catch (std::bad_alloc)
+                    {
+                        hrc = E_OUTOFMEMORY;
+                    }
+                }
+                else
+                    hrc = E_OUTOFMEMORY;
+            }
+            else
+                hrc = setError(VBOX_E_VM_ERROR, tr("DBGFR3Info failed with %Rrc"), vrc);
+            MachineDebuggerInfoDelete(&Hlp);
+        }
+    }
+    return hrc;
 }
 
@@ -773,5 +1003,42 @@
 STDMETHODIMP MachineDebugger::DetectOS(BSTR *a_pbstrName)
 {
-    ReturnComNotImplemented();
+    LogFlowThisFunc(("\n"));
+    CheckComArgNotNull(a_pbstrName);
+
+    /*
+     * Do the autocaller and lock bits.
+     */
+    AutoCaller autoCaller(this);
+    HRESULT hrc = autoCaller.rc();
+    if (SUCCEEDED(hrc))
+    {
+        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+        Console::SafeVMPtr ptrVM(mParent);
+        hrc = ptrVM.rc();
+        if (SUCCEEDED(hrc))
+        {
+            /*
+             * Do the job and try convert the name.
+             */
+/** @todo automatically load the DBGC plugins or this is a waste of time. */
+            char szName[64];
+            int vrc = DBGFR3OSDetect(ptrVM.raw(), szName, sizeof(szName));
+            if (RT_SUCCESS(vrc) && vrc != VINF_DBGF_OS_NOT_DETCTED)
+            {
+                try
+                {
+                    Bstr bstrName(szName);
+                    bstrName.detachTo(a_pbstrName);
+                }
+                catch (std::bad_alloc)
+                {
+                    hrc = E_OUTOFMEMORY;
+                }
+            }
+            else
+                hrc = setError(VBOX_E_VM_ERROR, tr("DBGFR3OSDetect failed with %Rrc"), vrc);
+        }
+    }
+    return hrc;
 }
 
