Index: /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 52904)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 52905)
@@ -167,4 +167,7 @@
     /** The kind of process we're protecting. */
     SUPDRVNTPROTECTKIND volatile enmProcessKind;
+    /** 7,: Hack to allow the supid themes service duplicate handle privileges to
+     *  our process. */
+    bool                fThemesFirstProcessCreateHandle : 1;
     /** Vista, 7 & 8: Hack to allow more rights to the handle returned by
      *  NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */
@@ -176,10 +179,9 @@
      *  NtCreateUserProcess. Only applicable to VmProcessUnconfirmed. */
     bool                fCsrssFirstProcessCreateHandle : 1;
-    /** Vista, 7 & 8: Hack to allow more rights to the handle duplicated by CSR
-     *  during process creation. Only applicable to VmProcessUnconfirmed. */
-    bool                fCsrssFirstProcessDuplicateHandle : 1;
-    /** 7,: Hack to allow the supid themes service duplicate handle privileges to
-     *  our process. */
-    bool                fThemesFirstProcessCreateHandle : 1;
+    /** Vista, 7 & 8: Hack to allow more rights to the handle duplicated by CSRSS
+     * during process creation. Only applicable to VmProcessUnconfirmed.  On
+     * 32-bit systems we allow two as ZoneAlarm's system call hooks has been
+     * observed to do some seemingly unnecessary duplication work. */
+    int32_t volatile    cCsrssFirstProcessDuplicateHandle;
 
     /** The parent PID for VM processes, otherwise NULL. */
@@ -2650,5 +2652,5 @@
         pNtChild->fFirstThreadCreateHandle = true;
         pNtChild->fCsrssFirstProcessCreateHandle = true;
-        pNtChild->fCsrssFirstProcessDuplicateHandle = true;
+        pNtChild->cCsrssFirstProcessDuplicateHandle = ARCH_BITS == 32 ? 2 : 1;
         pNtChild->fThemesFirstProcessCreateHandle = true;
         pNtChild->hParentPid = pNtParent->AvlCore.Key;
@@ -3031,4 +3033,5 @@
                     && pNtProtect->fCsrssFirstProcessCreateHandle
                     && pOpInfo->KernelHandle == 0
+                    && ExGetPreviousMode() == UserMode
                     && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) )
                 {
@@ -3057,4 +3060,5 @@
                     && pNtProtect->fThemesFirstProcessCreateHandle
                     && pOpInfo->KernelHandle == 0
+                    && ExGetPreviousMode() == UserMode
                     && supdrvNtProtectIsFrigginThemesService(pNtProtect, PsGetCurrentProcess()) )
                 {
@@ -3097,13 +3101,14 @@
                 if (   g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 3)
                     && pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed
-                    && pNtProtect->fCsrssFirstProcessDuplicateHandle
+                    && pNtProtect->cCsrssFirstProcessDuplicateHandle > 0
                     && pOpInfo->KernelHandle == 0
+                    && pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess == s_fCsrssStupidDesires
                     &&    pNtProtect->hParentPid
                        == PsGetProcessId((PEPROCESS)pOpInfo->Parameters->DuplicateHandleInformation.SourceProcess)
                     && pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == PsGetCurrentProcess()
-                    && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) )
+                    && ExGetPreviousMode() == UserMode
+                    && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()))
                 {
-                    pNtProtect->fCsrssFirstProcessDuplicateHandle = false;
-                    if (pOpInfo->Parameters->DuplicateHandleInformation.DesiredAccess == s_fCsrssStupidDesires)
+                    if (ASMAtomicDecS32(&pNtProtect->cCsrssFirstProcessDuplicateHandle) >= 0)
                     {
                         /* Not needed: PROCESS_CREATE_THREAD, PROCESS_SET_SESSIONID,
@@ -3249,4 +3254,5 @@
                     && pNtProtect->fFirstThreadCreateHandle
                     && pOpInfo->KernelHandle == 0
+                    && ExGetPreviousMode() == UserMode
                     && pNtProtect->hParentPid == PsGetProcessId(PsGetCurrentProcess()) )
                 {
@@ -3271,4 +3277,5 @@
                         || enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed)
                     && pOpInfo->KernelHandle == 0
+                    && ExGetPreviousMode() == UserMode
                     && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) )
                 {
@@ -3315,4 +3322,5 @@
                     && pOpInfo->Parameters->DuplicateHandleInformation.TargetProcess == PsGetCurrentProcess()
                     && pOpInfo->KernelHandle == 0
+                    && ExGetPreviousMode() == UserMode
                     && supdrvNtProtectIsAssociatedCsrss(pNtProtect, PsGetCurrentProcess()) )
                 {
