[NTVDM]: Use variable-length buffers in DisplayMessage, in case we display a very...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 9 Nov 2014 01:46:31 +0000 (01:46 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 9 Nov 2014 01:46:31 +0000 (01:46 +0000)
svn path=/trunk/; revision=65336

reactos/subsystems/ntvdm/ntvdm.c

index 8a194e1..fb81ec1 100644 (file)
@@ -185,13 +185,48 @@ static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr)
 VOID
 DisplayMessage(LPCWSTR Format, ...)
 {
 VOID
 DisplayMessage(LPCWSTR Format, ...)
 {
-    WCHAR Buffer[256];
+#ifndef WIN2K_COMPLIANT
+    WCHAR  StaticBuffer[256];
+    LPWSTR Buffer = StaticBuffer; // Use the static buffer by default.
+#else
+    WCHAR  Buffer[2048]; // Large enough. If not, increase it by hand.
+#endif
+    size_t MsgLen;
     va_list Parameters;
 
     va_start(Parameters, Format);
     va_list Parameters;
 
     va_start(Parameters, Format);
-    _vsnwprintf(Buffer, 256, Format, Parameters);
+
+#ifndef WIN2K_COMPLIANT
+    /*
+     * Retrieve the message length and if it is too long, allocate
+     * an auxiliary buffer; otherwise use the static buffer.
+     */
+    MsgLen = _vscwprintf(Format, Parameters) + 1; // NULL-terminated
+    if (MsgLen > sizeof(StaticBuffer)/sizeof(StaticBuffer[0]))
+    {
+        Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MsgLen * sizeof(WCHAR));
+        if (Buffer == NULL)
+        {
+            /* Allocation failed, use the static buffer and display a suitable error message */
+            Buffer = StaticBuffer;
+            Format = L"DisplayMessage()\nOriginal message is too long and allocating an auxiliary buffer failed.";
+            MsgLen = wcslen(Format);
+        }
+    }
+#else
+    MsgLen = sizeof(Buffer)/sizeof(Buffer[0]);
+#endif
+
+    /* Display the message */
+    _vsnwprintf(Buffer, MsgLen, Format, Parameters);
     DPRINT1("\n\nNTVDM Subsystem\n%S\n\n", Buffer);
     MessageBoxW(NULL, Buffer, L"NTVDM Subsystem", MB_OK);
     DPRINT1("\n\nNTVDM Subsystem\n%S\n\n", Buffer);
     MessageBoxW(NULL, Buffer, L"NTVDM Subsystem", MB_OK);
+
+#ifndef WIN2K_COMPLIANT
+    /* Free the buffer if needed */
+    if (Buffer != StaticBuffer) HeapFree(GetProcessHeap(), 0, Buffer);
+#endif
+
     va_end(Parameters);
 }
 
     va_end(Parameters);
 }
 
@@ -205,8 +240,8 @@ ConsoleCtrlHandler(DWORD ControlType)
         case CTRL_BREAK_EVENT:
         {
             /* HACK: Stop the VDM */
         case CTRL_BREAK_EVENT:
         {
             /* HACK: Stop the VDM */
+            DPRINT1("Ctrl-C/Break: Stop the VDM\n");
             EmulatorTerminate();
             EmulatorTerminate();
-
             break;
         }
         case CTRL_LAST_CLOSE_EVENT:
             break;
         }
         case CTRL_LAST_CLOSE_EVENT: