+/* RegisterConsoleVDM EMULATION ***********************************************/
+
+#include <ntddvdeo.h>
+
+typedef
+BOOL
+(WINAPI *pRegisterConsoleVDM)
+(
+ BOOL IsDosVDM_flag,
+ HANDLE EventHandle_1,
+ HANDLE EventHandle_2,
+ HANDLE EventHandle_3,
+ int Unused1,
+ PVOID returned_val_1,
+ PVOID *returned_val_2,
+ PVOID lpUnknownBuffer,
+ DWORD theUnknownBufferLength,
+ COORD theVDMBufferSize,
+ PCHAR *lpVDMBuffer
+);
+
+#if 0
+BOOL
+WINAPI
+RegisterConsoleVDM
+(
+ BOOL IsDosVDM_flag,
+ HANDLE EventHandle_1,
+ HANDLE EventHandle_2,
+ HANDLE EventHandle_3,
+ int Unused1,
+ PVOID returned_val_1,
+ PVOID *returned_val_2,
+ PVOID lpUnknownBuffer,
+ DWORD theUnknownBufferLength,
+ COORD theVDMBufferSize,
+ PVOID *lpVDMBuffer
+);
+
+HMODULE hKernel32 = NULL;
+pRegisterConsoleVDM RegisterConsoleVDM = NULL;
+#endif
+
+/*
+ * This private buffer, per-console, is used by
+ * RegisterConsoleVDM and InvalidateConsoleDIBits.
+ */
+static COORD VDMBufferSize = {0};
+static PCHAR_CELL VDMBuffer = NULL;
+
+static PCHAR_INFO CharBuff = NULL; // This is a hack, which is unneeded
+ // for the real RegisterConsoleVDM and
+ // InvalidateConsoleDIBits
+
+BOOL
+WINAPI
+__RegisterConsoleVDM(BOOL IsDosVDM_flag,
+ HANDLE EventHandle_1,
+ HANDLE EventHandle_2,
+ HANDLE EventHandle_3,
+ int Unused1,
+ PVOID returned_val_1,
+ PVOID *returned_val_2,
+ PVOID lpUnknownBuffer,
+ DWORD theUnknownBufferLength,
+ COORD theVDMBufferSize,
+ PCHAR *lpVDMBuffer)
+{
+ UNREFERENCED_PARAMETER(EventHandle_3);
+ UNREFERENCED_PARAMETER(Unused1);
+ UNREFERENCED_PARAMETER(returned_val_1);
+ UNREFERENCED_PARAMETER(returned_val_2);
+ UNREFERENCED_PARAMETER(lpUnknownBuffer);
+ UNREFERENCED_PARAMETER(theUnknownBufferLength);
+
+ SetLastError(0);
+ DPRINT1("__RegisterConsoleVDM(%d)\n", IsDosVDM_flag);
+
+ if (lpVDMBuffer == NULL) return FALSE;
+
+ if (IsDosVDM_flag)
+ {
+ // if (EventHandle_1 == NULL || EventHandle_2 == NULL) return FALSE;
+ if (VDMBuffer != NULL) return FALSE;
+
+ VDMBufferSize = theVDMBufferSize;
+
+ /* HACK: Cache -- to be removed in the real implementation */
+ CharBuff = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ theVDMBufferSize.X * theVDMBufferSize.Y
+ * sizeof(CHAR_INFO));
+ ASSERT(CharBuff);
+
+ VDMBuffer = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ theVDMBufferSize.X * theVDMBufferSize.Y
+ * sizeof(CHAR_CELL));
+ *lpVDMBuffer = (PCHAR)VDMBuffer;
+ return (VDMBuffer != NULL);
+ }
+ else
+ {
+ /* HACK: Cache -- to be removed in the real implementation */
+ if (CharBuff) HeapFree(GetProcessHeap(), 0, CharBuff);
+ CharBuff = NULL;
+
+ if (VDMBuffer) HeapFree(GetProcessHeap(), 0, VDMBuffer);
+ VDMBuffer = NULL;
+
+ VDMBufferSize.X = VDMBufferSize.Y = 0;
+
+ return TRUE;
+ }
+}
+
+BOOL
+__InvalidateConsoleDIBits(IN HANDLE hConsoleOutput,
+ IN PSMALL_RECT lpRect)
+{
+ if ((hConsoleOutput == TextConsoleBuffer) && (VDMBuffer != NULL))
+ {
+ /* HACK: Write the cached data to the console */
+
+ COORD Origin = { lpRect->Left, lpRect->Top };
+ SHORT i, j;
+
+ ASSERT(CharBuff);
+
+ for (i = 0; i < VDMBufferSize.Y; i++)
+ {
+ for (j = 0; j < VDMBufferSize.X; j++)
+ {
+ CharBuff[i * VDMBufferSize.X + j].Char.AsciiChar = VDMBuffer[i * VDMBufferSize.X + j].Char;
+ CharBuff[i * VDMBufferSize.X + j].Attributes = VDMBuffer[i * VDMBufferSize.X + j].Attributes;
+ }
+ }
+
+ WriteConsoleOutputA(hConsoleOutput,
+ CharBuff,
+ VDMBufferSize,
+ Origin,
+ lpRect);
+ }
+
+ return InvalidateConsoleDIBits(hConsoleOutput, lpRect);
+}
+