Index: /trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/Makefile.kmk	(revision 59384)
+++ /trunk/src/VBox/Main/Makefile.kmk	(revision 59385)
@@ -929,4 +929,19 @@
  VBoxCOM_SOURCES       += \
 	$(VBoxCOM_0_OUTDIR)/VirtualBox_i.c
+ VBoxCOM_CLEAN          = \
+ 	$(VBoxCOM_0_OUTDIR)/VirtualBox_i.c \
+ 	$(VBoxCOM_0_OUTDIR)/VirtualBox_p.c \
+ 	$(VBoxCOM_0_OUTDIR)/dlldata.c \
+ 	$(VBoxCOM_0_OUTDIR)/VirtualBox.h \
+ 	$(VBoxCOM_0_OUTDIR)/VirtualBox.tlb
+ ifeq ($(KBUILD_TARGET_ARCH),amd64)
+  VBoxCOM_CLEAN        += \
+ 	$(VBoxCOM_0_OUTDIR)/old64/VirtualBox_i.c \
+ 	$(VBoxCOM_0_OUTDIR)/old64/VirtualBox_p.c \
+ 	$(VBoxCOM_0_OUTDIR)/old64/dlldata.c \
+ 	$(VBoxCOM_0_OUTDIR)/old64/VirtualBox.h \
+ 	$(VBoxCOM_0_OUTDIR)/old64/VirtualBox.tlb
+  VBoxCOM_BLDDIRS      = $(VBoxCOM_0_OUTDIR)/old64/
+ endif
 else # !win
  VBoxCOM_SOURCES       += \
@@ -944,4 +959,12 @@
  VBoxCOM-x86_TEMPLATE = VBoxMainLib-x86
  VBoxCOM-x86_EXTENDS  = VBoxCOM
+ ifeq ($(KBUILD_TARGET),win)
+  VBoxCOM-x86_CLEAN   = \
+ 	$(VBoxCOM-x86_0_OUTDIR)/VirtualBox_i.c \
+ 	$(VBoxCOM-x86_0_OUTDIR)/VirtualBox_p.c \
+ 	$(VBoxCOM-x86_0_OUTDIR)/dlldata.c \
+ 	$(VBoxCOM-x86_0_OUTDIR)/VirtualBox.h \
+ 	$(VBoxCOM-x86_0_OUTDIR)/VirtualBox.tlb
+ endif
 endif
 
@@ -1012,5 +1035,10 @@
 if defined(VBOX_WITH_MIDL_PROXY_STUB) && "$(KBUILD_TARGET)" == "win"
  #
- # Experimental COM proxy + stub DLL.
+ # Experimental COM proxy + stub DLL w/ automatic registration updating.
+ #
+ # The Legacy stub is for older 64-bit windows versions (pre Windows 7) as we
+ # were having various problems on windows server 2003 and 2008 with the code
+ # MIDL generated.  Also, in windows 7 there are some potentially interesting
+ # changes in the generated code where it uses new helpers from OLE32.
  #
  DLLS += VBoxProxyStub
@@ -1030,4 +1058,17 @@
   src-all/win/VBoxProxyStub.rc_DEPS = $(VBoxCOM_0_OUTDIR)/VirtualBox.tlb
 
+ DLLS += VBoxProxyStubLegacy
+ VBoxProxyStubLegacy_TEMPLATE = VBOXMAINCOMP
+ VBoxProxyStubLegacy_EXTENDS  = VBoxProxyStub
+ VBoxProxyStubLegacy_DEFS     = $(VBoxProxyStub_DEFS) VBOX_IN_PROXY_STUB_LEGACY
+ VBoxProxyStubLegacy_INCS     = $(VBoxCOM_0_OUTDIR)/old64/
+ VBoxProxyStubLegacy_SOURCES  = \
+ 	$(VBoxCOM_0_OUTDIR)/old64/VirtualBox_p.c \
+ 	$(VBoxCOM_0_OUTDIR)/old64/VirtualBox_i.c \
+ 	src-all/win/VBoxProxyStub.def \
+ 	src-all/win/VBoxProxyStub.rc \
+ 	src-all/win/VBoxProxyStub.c
+  src-all/win/VBoxProxyStub.rc_DEPS = $(VBoxCOM_0_OUTDIR)/old64/VirtualBox.tlb
+
  ifdef VBOX_WITH_32_ON_64_MAIN_API
   DLLS += VBoxProxyStub-x86
@@ -1092,4 +1133,6 @@
 	$(QUIET)$(VBOX_XSLTPROC) -o $@ $< $(VBOX_XIDL_FILE)
 
+# Note! Because we've got a different proxy stub DLL for pre windows 7 64-bit hosts, we target windows 7 for AMD64.
+#       The output is different and hopefully more efficient, at least memory wise (using more helpers in OLE32).
 $(VBoxCOM_0_OUTDIR)/VirtualBox_i.c \
 + $(VBoxCOM_0_OUTDIR)/VirtualBox.h \
@@ -1097,6 +1140,7 @@
 + $(VBoxCOM_0_OUTDIR)/VirtualBox.tlb: $(VBOX_IDL_FILE.MSCOM) | $$(dir $$@)
 	$(VBOX_WIN_MIDL) /nologo \
-		$(if-expr "$(KBUILD_TARGET_ARCH)" == "amd64" && "$(KBUILD_HOST)" == "win",/env amd64,/env win32) \
-		/robust /protocol all /target NT51 \
+		$(if-expr "$(KBUILD_TARGET_ARCH)" == "amd64" && "$(KBUILD_HOST)" == "win" \
+		,/env amd64 /robust /protocol all /target NT61\
+		,/env win32 /robust /protocol all /target NT51) \
 		/out $(call VBOX_FN_MAKE_WIN_PATH,$(VBoxCOM_0_OUTDIR)) \
 		/cpp_cmd $(subst $(EXEC_X86_WIN32),,$(call VBOX_FN_MAKE_WIN_PATH,$(TOOL_$(VBOX_VCC_TOOL)_CC))) \
@@ -1104,4 +1148,22 @@
 		/I idl \
 		$(call VBOX_FN_MAKE_WIN_PATH,$<)
+
+if defined(VBOX_WITH_MIDL_PROXY_STUB) && "$(KBUILD_TARGET_ARCH)" == "amd64"
+# -Windows Server 2003 AMD64 SP1 does not like the result when using '/protocol all' and '/target NT51'.
+# -Vista AMD64 SP1 and Windows Server 2008 AMD64 seems to have some objections as well, but it seemed
+#  that using an older MIDL compiler (v7.00.0499 instead of v7.00.0555) helps. But the W2K3 fix also works.
+$(VBoxCOM_0_OUTDIR)/old64/VirtualBox_i.c \
++ $(VBoxCOM_0_OUTDIR)/old64/VirtualBox_p.c\
++ $(VBoxCOM_0_OUTDIR)/old64/dlldata.c \
++ $(VBoxCOM_0_OUTDIR)/old64/VirtualBox.h \
++ $(VBoxCOM_0_OUTDIR)/old64/VirtualBox.tlb: $(VBOX_IDL_FILE.MSCOM) | $$(dir $$@)
+	$(VBOX_WIN_MIDL) /nologo \
+		/env win64 /x64 /robust /target NT50 \
+		/out $(call VBOX_FN_MAKE_WIN_PATH,$(dir $@)) \
+		/cpp_cmd $(subst $(EXEC_X86_WIN32),,$(call VBOX_FN_MAKE_WIN_PATH,$(TOOL_$(VBOX_VCC_TOOL)_CC))) \
+		/I $(call VBOX_FN_MAKE_WIN_PATH,$(PATH_SDK_$(VBOX_WINPSDK)_INC)) \
+		/I idl \
+		$(call VBOX_FN_MAKE_WIN_PATH,$<)
+endif
 
 $(VBoxCOM-x86_0_OUTDIR)/VirtualBox_i.c \
Index: /trunk/src/VBox/Main/glue/initterm.cpp
===================================================================
--- /trunk/src/VBox/Main/glue/initterm.cpp	(revision 59384)
+++ /trunk/src/VBox/Main/glue/initterm.cpp	(revision 59385)
@@ -19,4 +19,5 @@
 #if !defined(VBOX_WITH_XPCOM)
 
+# include <iprt/nt/nt-and-windows.h>
 # include <objbase.h>
 
@@ -254,9 +255,20 @@
         int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath));
         if (RT_SUCCESS(vrc))
+        {
 #  ifndef VBOX_IN_32_ON_64_MAIN_API
-            rc = RTPathAppend(szPath, sizeof(szPath), "VBoxProxyStub.dll");
+            rc = RTPathAppend(szPath, sizeof(szPath),
+#   if ARCH_BITS == 64
+                                 RT_MAKE_U64(((PKUSER_SHARED_DATA)MM_SHARED_USER_DATA_VA)->NtMinorVersion,
+                                             ((PKUSER_SHARED_DATA)MM_SHARED_USER_DATA_VA)->NtMajorVersion)
+                              >= RT_MAKE_U64(1/*Lo*/,6/*Hi*/)
+                              ? "VBoxProxyStub.dll" : "VBoxProxyStubLegacy.dll"
+#   else
+                              "VBoxProxyStub.dll"
+#   endif
+                              );
 #  else
             rc = RTPathAppend(szPath, sizeof(szPath), "x86\\VBoxProxyStub-x86.dll");
 #  endif
+        }
         if (RT_SUCCESS(vrc))
         {
Index: /trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c
===================================================================
--- /trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c	(revision 59384)
+++ /trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c	(revision 59385)
@@ -69,4 +69,17 @@
 # define VBSP_LOG_DEL_KEY(a)        do { } while (0)
 #endif
+
+/**
+ * Selects the proxy stub DLL based on 32-on-64-bit and host OS version.
+ *
+ * The legacy DLL covers 64-bit pre Windows 7 versions of Windows. W2K3-amd64
+ * has trouble parsing the result when MIDL /target NT51 or higher. Vista and
+ * windows server 2008 seems to have trouble with newer IDL compilers.
+ */
+#define VBPS_PROXY_STUB_FILE(a_fIs32On64) \
+    ( (a_fIs32On64) ? "x86\\VBoxProxyStub-x86.dll" \
+      : RT_MAKE_U64(((PKUSER_SHARED_DATA)MM_SHARED_USER_DATA_VA)->NtMinorVersion, \
+                    ((PKUSER_SHARED_DATA)MM_SHARED_USER_DATA_VA)->NtMajorVersion) >= RT_MAKE_U64(1/*Lo*/,6/*Hi*/) \
+        ? "VBoxProxyStub.dll" : "VBoxProxyStubLegacy.dll" )
 
 
@@ -142,4 +155,26 @@
             /* Init IPRT. */
             RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
+
+#ifdef VBOX_STRICT
+            {
+                /*
+                 * Check that no interface has more than 256 methods in the stub vtable.
+                 */
+                const ProxyFileInfo **ppProxyFile = &g_apProxyFiles[0];
+                const ProxyFileInfo  *pProxyFile;
+                while ((pProxyFile = *ppProxyFile++) != NULL)
+                {
+                    const PCInterfaceStubVtblList * const   papStubVtbls  = pProxyFile->pStubVtblList;
+                    const char * const                     *papszNames    = pProxyFile->pNamesArray;
+                    unsigned                                iIf           = pProxyFile->TableSize;
+                    AssertStmt(iIf < 1024, iIf = 0);
+                    Assert(pProxyFile->TableVersion == 2);
+
+                    while (iIf-- > 0)
+                        AssertMsg(papStubVtbls[iIf]->header.DispatchTableCount <= 256,
+                                  ("%s: DispatchTableCount=%d\n", papszNames[iIf], papStubVtbls[iIf]->header.DispatchTableCount));
+                }
+            }
+#endif
             break;
 
@@ -1107,5 +1142,6 @@
         unsigned i = pState->cAltDeletes;
         while (i-- > 0)
-            vbpsDeleteKeyRecursiveA(pState, pState->aAltDeletes[i].hkeyClsid, szClsId, __LINE__);
+            if (pState->aAltDeletes[i].hkeyClsid != NULL)
+                vbpsDeleteKeyRecursiveA(pState, pState->aAltDeletes[i].hkeyClsid, szClsId, __LINE__);
         vbpsDeleteKeyRecursiveA(pState, pState->hkeyClsidRootDst, szClsId, __LINE__);
     }
@@ -1232,5 +1268,5 @@
 static void vbpsUpdateTypeLibRegistration(VBPSREGSTATE *pState, PCRTUTF16 pwszVBoxDir, bool fIs32On64)
 {
-    const char * const pszTypeLibDll = !fIs32On64 ? "VBoxProxyStub.dll" : "x86\\VBoxProxyStub-x86.dll";
+    const char * const pszTypeLibDll = VBPS_PROXY_STUB_FILE(fIs32On64);
     const char * const pszWinXx      = !fIs32On64 ? "win64"             : "win32";
     const char * const pszDescription = "VirtualBox Type Library";
@@ -1316,5 +1352,5 @@
      * It's simple compared to the VBox classes, thus all the NULL parameters.
      */
-    const char *pszPsDll = !fIs32On64 ? "VBoxProxyStub.dll" : "x86\\VBoxProxyStub-x86.dll";
+    const char *pszPsDll = VBPS_PROXY_STUB_FILE(fIs32On64);
     Assert(pState->fUpdate && !pState->fDelete);
     VbpsRegisterClassId(pState, &g_ProxyClsId, "PSFactoryBuffer", NULL /*pszAppId*/,
Index: /trunk/src/VBox/Main/src-all/win/comregister.cmd
===================================================================
--- /trunk/src/VBox/Main/src-all/win/comregister.cmd	(revision 59384)
+++ /trunk/src/VBox/Main/src-all/win/comregister.cmd	(revision 59385)
@@ -7,5 +7,5 @@
 
 REM
-REM Copyright (C) 2006-2015 Oracle Corporation
+REM Copyright (C) 2006-2016 Oracle Corporation
 REM
 REM This file is part of VirtualBox Open Source Edition (OSE), as
@@ -121,6 +121,4 @@
 REM
 set fNoProxy=0
-if "%WinVerMajor%" == "5" set fNoProxy=1
-if "%WinVerMajor%" == "4" set fNoProxy=1
 set fUninstallOnly=0
 
@@ -173,9 +171,19 @@
 REM Unregister all first, then register them. The order matters here.
 :register_amd64
+if "%WinVerMajor%" == "5" goto register_amd64_legacy
+if not "%WinVerMajor%" == "6" goto register_amd64_not_legacy
+if not "%WinVerMinor%" == "0" goto register_amd64_not_legacy
+:register_amd64_legacy
+set s64BitProxyStub=VBoxProxyStubLegacy.dll
+goto register_amd64_begin
+:register_amd64_not_legacy
+set s64BitProxyStub=VBoxProxyStub.dll
+:register_amd64_begin
+echo s64BitProxyStub=%s64BitProxyStub%
 @echo on
 "%_VBOX_DIR%VBoxSVC.exe" /UnregServer
 %windir%\system32\regsvr32 /s /u "%_VBOX_DIR%VBoxC.dll"
 %windir%\syswow64\regsvr32 /s /u "%_VBOX_DIR%x86\VBoxClient-x86.dll"
-%windir%\system32\regsvr32 /s /u "%_VBOX_DIR%VBoxProxyStub.dll"
+%windir%\system32\regsvr32 /s /u "%_VBOX_DIR%%s64BitProxyStub%"
 %windir%\syswow64\regsvr32 /s /u "%_VBOX_DIR%x86\VBoxProxyStub-x86.dll"
 if %fUninstallOnly% == 1 goto end
@@ -184,5 +192,5 @@
 %windir%\syswow64\regsvr32 /s    "%_VBOX_DIR%x86\VBoxClient-x86.dll"
 if %fNoProxy% == 1 goto end
-if exist "%_VBOX_DIR%VBoxProxyStub.dll"         %windir%\system32\regsvr32 /s "%_VBOX_DIR%VBoxProxyStub.dll"
+if exist "%_VBOX_DIR%%s64BitProxyStub%"         %windir%\system32\regsvr32 /s "%_VBOX_DIR%%s64BitProxyStub%"
 if exist "%_VBOX_DIR%x86\VBoxProxyStub-x86.dll" %windir%\syswow64\regsvr32 /s "%_VBOX_DIR%x86\VBoxProxyStub-x86.dll"
 @echo off
