adding win32ksys the syscall lib for win32k
[reactos.git] / reactos / subsystems / win32 / csrss / win32csr / guiconsole.c
index dc677b9..6bf3f8e 100644 (file)
@@ -31,6 +31,27 @@ typedef struct GUI_CONSOLE_DATA_TAG
   POINT SelectionStart;
   BOOL MouseDown;
   HMODULE ConsoleLibrary;
+  HANDLE hGuiInitEvent;
+  HWND hVScrollBar;
+  HWND hHScrollBar;
+  WCHAR FontName[LF_FACESIZE];
+  DWORD FontSize;
+  DWORD FontWeight;
+  DWORD HistoryNoDup;
+  DWORD FullScreen;
+  DWORD QuickEdit;
+  DWORD InsertMode;
+  DWORD NumberOfHistoryBuffers;
+  DWORD HistoryBufferSize;
+  DWORD WindowPosition;
+  DWORD ScreenBufferSize;
+  DWORD UseRasterFonts;
+  COLORREF ScreenText;
+  COLORREF ScreenBackground;
+  COLORREF PopupBackground;
+  COLORREF PopupText;
+  COLORREF Colors[16];
+  WCHAR szProcessName[MAX_PATH];
 } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
 
 #ifndef WM_APP
@@ -40,12 +61,135 @@ typedef struct GUI_CONSOLE_DATA_TAG
 #define PM_DESTROY_CONSOLE (WM_APP + 2)
 
 #define CURSOR_BLINK_TIME 500
+#define DEFAULT_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)
 
 static BOOL ConsInitialized = FALSE;
 static HWND NotifyWnd;
 
+typedef struct _GUICONSOLE_MENUITEM
+{
+    UINT uID;
+    const struct _GUICONSOLE_MENUITEM *SubMenu;
+    WORD wCmdID;
+} GUICONSOLE_MENUITEM, *PGUICONSOLE_MENUITEM;
+
+static const GUICONSOLE_MENUITEM GuiConsoleEditMenuItems[] =
+{
+    { IDS_MARK, NULL, ID_SYSTEM_EDIT_MARK },
+    { IDS_COPY, NULL, ID_SYSTEM_EDIT_COPY },
+    { IDS_PASTE, NULL, ID_SYSTEM_EDIT_PASTE },
+    { IDS_SELECTALL, NULL, ID_SYSTEM_EDIT_SELECTALL },
+    { IDS_SCROLL, NULL, ID_SYSTEM_EDIT_SCROLL },
+    { IDS_FIND, NULL, ID_SYSTEM_EDIT_FIND },
+
+    { 0, NULL, 0 } /* End of list */
+};
+
+static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems[] =
+{
+    { (UINT)-1, NULL, 0 }, /* Separator */
+    { IDS_EDIT, GuiConsoleEditMenuItems, 0 },
+    { IDS_DEFAULTS, NULL, ID_SYSTEM_DEFAULTS },
+    { IDS_PROPERTIES, NULL, ID_SYSTEM_PROPERTIES },
+
+    { 0, NULL, 0 } /* End of list */
+};
+
+static const COLORREF s_Colors[] =
+{
+    RGB(0, 0, 0),
+    RGB(0, 0, 128),
+    RGB(0, 128, 0),
+    RGB(0, 128, 128),
+    RGB(128, 0, 0),
+    RGB(128, 0, 128),
+    RGB(128, 128, 0),
+    RGB(192, 192, 192),
+    RGB(128, 128, 128),
+    RGB(0, 0, 255),
+    RGB(0, 255, 0),
+    RGB(0, 255, 255),
+    RGB(255, 0, 0),
+    RGB(255, 0, 255),
+    RGB(255, 255, 0),
+    RGB(255, 255, 255)
+};
+
 /* FUNCTIONS *****************************************************************/
 
+static VOID FASTCALL
+GuiConsoleAppendMenuItems(HMENU hMenu,
+                          const GUICONSOLE_MENUITEM *Items)
+{
+    UINT i;
+    WCHAR szMenuString[255];
+    HMENU hSubMenu;
+
+    for (i = 0; Items[i].uID != 0; i++)
+    {
+        if (Items[i].uID != (UINT)-1)
+        {
+            if (LoadStringW(Win32CsrDllHandle,
+                            Items[i].uID,
+                            szMenuString,
+                            sizeof(szMenuString) / sizeof(szMenuString[0])) > 0)
+            {
+                if (Items[i].SubMenu != NULL)
+                {
+                    hSubMenu = CreatePopupMenu();
+                    if (hSubMenu != NULL)
+                    {
+                        /*GuiConsoleAppendMenuItems(hSubMenu,
+                                                  Items[i].SubMenu);*/
+
+                        if (!AppendMenuW(hMenu,
+                                         MF_STRING | MF_POPUP,
+                                         (UINT_PTR)hSubMenu,
+                                         szMenuString))
+                        {
+                            DestroyMenu(hSubMenu);
+                            DPRINT1("DestroyMenu \n");
+                        }
+                    }
+                }
+                else
+                {
+                    AppendMenuW(hMenu,
+                                MF_STRING,
+                                Items[i].wCmdID,
+                                szMenuString);
+                }
+            }
+        }
+        else
+        {
+            AppendMenuW(hMenu,
+                        MF_SEPARATOR,
+                        0,
+                        NULL);
+        }
+    }
+}
+
+static VOID FASTCALL
+GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console)
+{
+    HMENU hMenu;
+
+    hMenu = GetSystemMenu(Console->hWindow,
+                          FALSE);
+    if (hMenu != NULL)
+    {
+        DPRINT1("adding menu\n");
+        GuiConsoleAppendMenuItems(hMenu,
+                                  GuiConsoleMainMenuItems);
+    }
+    else
+    {
+      DPRINT1("This should never happen, GetSystemMenu == NULL \n");
+    }
+}
+
 static VOID FASTCALL
 GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData)
 {
@@ -53,34 +197,506 @@ GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA
   *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
 }
 
+static BOOL FASTCALL
+GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired)
+{
+  HANDLE hProcessToken = NULL;
+  HANDLE hProcess;
+  
+  BYTE Buffer[256];
+  DWORD Length = 0;
+  UNICODE_STRING SidName;
+  LONG res;
+  PTOKEN_USER TokUser;
+  
+  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId);
+  if (!hProcess)
+    {
+      DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError());
+      return FALSE;
+    }
+
+  if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
+    {
+      DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError());
+      CloseHandle(hProcess);
+      return FALSE;
+    }
+
+  if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length))
+    {
+      DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError());
+      CloseHandle(hProcess);
+      CloseHandle(hProcessToken);
+      return FALSE;
+    }
+  
+  TokUser = ((PTOKEN_USER)Buffer)->User.Sid;
+  if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE)))
+    {
+      DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError());
+      return FALSE;
+    }
+  
+  res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult);
+  RtlFreeUnicodeString(&SidName);
+
+  CloseHandle(hProcessToken);
+  CloseHandle(hProcess);
+
+  //if (hProcHandle)
+  //  *hProcHandle = hProcess;
+  //else
+  //  CloseHandle(hProcess);
+
+  if (res != ERROR_SUCCESS)
+    return FALSE;
+  else
+    return TRUE;
+}
+
+static BOOL FASTCALL
+GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate)
+{
+  WCHAR szProcessName[MAX_PATH];
+  WCHAR szBuffer[MAX_PATH];
+  UINT fLength, wLength;
+  DWORD dwBitmask, dwLength;
+  WCHAR CurDrive[] = { 'A',':', 0 };
+  HANDLE hProcess;
+  HKEY hKey;
+  WCHAR * ptr;
+
+  /*
+   * console properties are stored under
+   * HKCU\Console\*
+   * 
+   * There are 3 ways to store console properties
+   * 
+   *  1. use console title as subkey name
+   *    i.e. cmd.exe
+   *
+   *  2. use application name as subkey name
+   *
+   *  3. use unexpanded path to console application.
+   *     i.e. %SystemRoot%_system32_cmd.exe
+   */
+  
+  DPRINT("GuiConsoleOpenUserSettings entered\n");
+
+  DPRINT1("ProcessId %d\n",ProcessId);
+
+  if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired))
+    {
+      DPRINT1("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); 
+      return FALSE;
+    }
+  
+  hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessId );
+
+
+  /* FIXME we do not getting the process name so no menu will be loading, why ?*/
+  fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR));
+  CloseHandle(hProcess);
+
+  DPRINT1("szProcessName3 : %S\n",szProcessName);
+
+  if (!fLength)
+    {
+      DPRINT1("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess);
+      return FALSE;
+    }
+  /*
+   * try the process name as path
+   */
+    
+  ptr = wcsrchr(szProcessName, L'\\');
+  wcscpy(GuiData->szProcessName, ptr);
+
+  swprintf(szBuffer, L"Console%s",ptr);
+  DPRINT("#1 Path : %S\n", szBuffer);
+
+  if (bCreate)
+    {
+      if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS)
+        {
+          RegCloseKey(hKey);
+          return TRUE;
+        }
+      RegCloseKey(hKey);
+      return FALSE;
+  }
+
+  if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
+    {
+      RegCloseKey(hKey);
+      return TRUE;
+    }
+
+  /*
+   * try the "Shortcut to processname" as path
+   * FIXME: detect wheter the process was started as a shortcut
+   */
+
+  swprintf(szBuffer, L"Console\\Shortcut to %S", ptr);
+  DPRINT("#2 Path : %S\n", szBuffer);
+  if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
+    {
+      swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr);
+      RegCloseKey(hKey);
+      return TRUE;
+    }
+
+  /*
+   * if the path contains \\Device\\HarddiskVolume1\... remove it
+   */
+
+  if (szProcessName[0] == L'\\')
+    {
+      dwBitmask = GetLogicalDrives();
+      while(dwBitmask)
+        {
+          if (dwBitmask & 0x1)
+            {
+              dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH);
+              if (dwLength)
+                {
+                  if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR)))
+                    {
+                      wcscpy(szProcessName, CurDrive);
+                      RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1);
+                      break;
+                    }
+                }
+            }
+          dwBitmask = (dwBitmask >> 1);
+          CurDrive[0]++;
+        }
+    }
+
+  /*
+   * last attempt: check whether the file is under %SystemRoot%
+   * and use path like Console\%SystemRoot%_dir_dir2_file.exe
+   */
+
+  wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH);
+  if (wLength)
+    {
+      if (!wcsncmp(szProcessName, szBuffer, wLength))
+        {
+          /* replace slashes by underscores */
+          while((ptr = wcschr(szProcessName, L'\\')))
+            ptr[0] = L'_';
+          
+          swprintf(szBuffer, L"Console\\\%SystemRoot\%%S", &szProcessName[wLength]);
+          DPRINT("#3 Path : %S\n", szBuffer);
+          if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
+            {
+              swprintf(GuiData->szProcessName, L"\%SystemRoot\%%S", &szProcessName[wLength]);
+              RegCloseKey(hKey);
+              return TRUE;
+            }
+        }
+    }
+  RegCloseKey(hKey);
+  return FALSE;
+}
+
+static VOID
+GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData)
+{
+    HKEY hKey;
+    PCSRSS_PROCESS_DATA ProcessData;
+
+    if (Console->ProcessList.Flink == &Console->ProcessList)
+      {
+        DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n");
+        return;
+      }
+    ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry);
+    if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ | KEY_WRITE, TRUE))
+      {
+        return;
+      }
+
+  if (Console->ActiveBuffer->CursorInfo.dwSize <= 1)
+    {
+      RegDeleteKeyW(hKey, L"CursorSize");
+    }
+  else
+    {
+      RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD));
+    }
+
+  if (GuiData->NumberOfHistoryBuffers == 5)
+    {
+      RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers");
+    }
+  else
+    {
+      RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD));
+    }
+
+  if (GuiData->HistoryBufferSize == 50)
+    {
+      RegDeleteKeyW(hKey, L"HistoryBufferSize");
+    }
+  else
+    {
+      RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD));
+    }
+
+  if (GuiData->FullScreen == FALSE)
+    {
+      RegDeleteKeyW(hKey, L"FullScreen");
+    }
+  else
+    {
+      RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD));
+    }
+
+  if ( GuiData->QuickEdit == FALSE)
+    {
+      RegDeleteKeyW(hKey, L"QuickEdit");
+    }
+    else
+    {
+      RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD));
+    }
+
+  if (GuiData->InsertMode == TRUE)
+    {
+      RegDeleteKeyW(hKey, L"InsertMode");
+    }
+  else
+    {
+      RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD));
+    }
+
+  if (GuiData->HistoryNoDup == FALSE)
+    {
+      RegDeleteKeyW(hKey, L"HistoryNoDup");
+    }
+  else
+    {
+      RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD));
+    }
+
+  if (GuiData->ScreenText == RGB(192, 192, 192))
+    {
+      /*
+       * MS uses console attributes instead of real color
+       */
+       RegDeleteKeyW(hKey, L"ScreenText");
+    }
+  else
+    {
+       RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF));
+    }
+
+  if (GuiData->ScreenBackground == RGB(0, 0, 0))
+    {
+       RegDeleteKeyW(hKey, L"ScreenBackground");
+    }
+  else
+    {
+       RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF));
+    }
+
+  RegCloseKey(hKey);
+}
+
+static void FASTCALL
+GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer)
+{
+  DWORD dwNumSubKeys = 0;
+  DWORD dwIndex;
+  DWORD dwValueName;
+  DWORD dwValue;
+  DWORD dwType;
+  WCHAR szValueName[MAX_PATH];
+  WCHAR szValue[MAX_PATH];
+  DWORD Value;
+
+  if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
+    {
+       DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n");
+       return;
+    }
+
+  DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys);
+
+  for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++)
+    {
+      dwValue = sizeof(Value);
+      dwValueName = MAX_PATH;
+
+      if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS)
+        {
+          if (dwType == REG_SZ)
+            {
+              /*
+               * retry in case of string value
+               */
+              dwValue = sizeof(szValue);
+              dwValueName = MAX_PATH;
+              if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
+                break;
+            }
+          else
+            break;
+        }
+      if (!wcscmp(szValueName, L"CursorSize"))
+        {
+          if (Value == 0x32)
+            {
+              Buffer->CursorInfo.dwSize = Value;
+            }
+          else if (Value == 0x64)
+            {
+              Buffer->CursorInfo.dwSize = Value;
+            }
+        }
+      else if (!wcscmp(szValueName, L"ScreenText"))
+        {
+          GuiData->ScreenText = Value;
+        }
+      else if (!wcscmp(szValueName, L"ScreenBackground"))
+        {
+          GuiData->ScreenBackground = Value;
+        }
+      else if (!wcscmp(szValueName, L"FaceName"))
+        {
+          wcscpy(GuiData->FontName, szValue);
+        }
+      else if (!wcscmp(szValueName, L"FontSize"))
+        {
+          GuiData->FontSize = Value;
+        }
+      else if (!wcscmp(szValueName, L"FontWeight"))
+        {
+          GuiData->FontWeight = Value;
+        }
+      else if (!wcscmp(szValueName, L"HistoryNoDup"))
+        {
+          GuiData->HistoryNoDup = Value;
+        }
+      else if (!wcscmp(szValueName, L"WindowSize"))
+        {
+          Console->Size.X = LOWORD(Value);
+                 Console->Size.Y = HIWORD(Value);
+        }
+      else if (!wcscmp(szValueName, L"ScreenBufferSize"))
+        {
+            if(Buffer)
+              {
+                Buffer->MaxX = LOWORD(Value);
+                Buffer->MaxY = HIWORD(Value);
+              }
+        }
+      else if (!wcscmp(szValueName, L"FullScreen"))
+        {
+          GuiData->FullScreen = Value;
+        }
+      else if (!wcscmp(szValueName, L"QuickEdit"))
+        {
+          GuiData->QuickEdit = Value;
+        }
+      else if (!wcscmp(szValueName, L"InsertMode"))
+        {
+          GuiData->InsertMode = Value;
+        }
+   }
+}
+static VOID FASTCALL
+GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer)
+{
+  /*
+   * init guidata with default properties
+   */
+
+  wcscpy(GuiData->FontName, L"DejaVu Sans Mono");
+  GuiData->FontSize = 0x0008000C; // font is 8x12
+  GuiData->FontWeight = FW_NORMAL;
+  GuiData->HistoryNoDup = FALSE;
+  GuiData->FullScreen = FALSE;
+  GuiData->QuickEdit = FALSE;
+  GuiData->InsertMode = TRUE;
+  GuiData->HistoryBufferSize = 50;
+  GuiData->NumberOfHistoryBuffers = 5;
+  GuiData->ScreenText = RGB(192, 192, 192);
+  GuiData->ScreenBackground = RGB(0, 0, 0); 
+  GuiData->PopupText = RGB(128, 0, 128); 
+  GuiData->PopupBackground = RGB(255, 255, 255); 
+  GuiData->WindowPosition = UINT_MAX;
+  GuiData->ScreenBufferSize = MAKELONG(80, 300); //FIXME
+  GuiData->UseRasterFonts = TRUE;
+  memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors));
+
+  Console->Size.X = 80;
+  Console->Size.Y = 25;
+
+  if (Buffer)
+    {
+      Buffer->MaxX = 80;
+      Buffer->MaxY = 25;
+      Buffer->CursorInfo.bVisible = TRUE;
+      Buffer->CursorInfo.dwSize = 5;
+    }
+}
+
+
+
 static BOOL FASTCALL
 GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
 {
   RECT Rect;
   PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams;
-  PGUI_CONSOLE_DATA GuiData;
+  PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData;
   HDC Dc;
   HFONT OldFont;
   TEXTMETRICW Metrics;
+  PCSRSS_PROCESS_DATA ProcessData;
+  HKEY hKey;
+
+  Console->hWindow = hWnd;
 
-  GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
-                      sizeof(GUI_CONSOLE_DATA) +
-                      (Console->Size.X + 1) * sizeof(WCHAR));
   if (NULL == GuiData)
     {
       DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
       return FALSE;
     }
 
-  InitializeCriticalSection(&GuiData->Lock);
+  GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer);
+  if (Console->ProcessList.Flink != &Console->ProcessList)
+    {
+      ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry);
+      DPRINT1("PtrToUlong(ProcessData->ProcessId) == %d",PtrToUlong(ProcessData->ProcessId));
 
-  GuiData->LineBuffer = (PWCHAR)(GuiData + 1);
+      if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE))
+        {
+          GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer);
+          RegCloseKey(hKey);
+        }
+    }
 
-  GuiData->Font = CreateFontW(12, 0, 0, TA_BASELINE, FW_NORMAL,
-                              FALSE, FALSE, FALSE, OEM_CHARSET,
+  InitializeCriticalSection(&GuiData->Lock);
+
+  GuiData->LineBuffer = (PWCHAR)HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, 
+                                          Console->Size.X * sizeof(WCHAR));
+
+  GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), 
+                              0, //HIWORD(GuiData->FontSize), 
+                              0, 
+                              TA_BASELINE, 
+                              GuiData->FontWeight,
+                              FALSE,
+                              FALSE, 
+                              FALSE,
+                              OEM_CHARSET,
                               OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
                               NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE,
-                              L"Bitstream Vera Sans Mono");
+                              GuiData->FontName);
   if (NULL == GuiData->Font)
     {
       DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
@@ -126,7 +742,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
   GuiData->ForceCursorOff = FALSE;
 
   GuiData->Selection.left = -1;
-
+  DPRINT("Console %p GuiData %p\n", Console, GuiData);
   Console->PrivateData = GuiData;
   SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console);
 
@@ -139,6 +755,8 @@ GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
              Rect.bottom - Rect.top, FALSE);
 
   SetTimer(hWnd, 1, CURSOR_BLINK_TIME, NULL);
+  GuiConsoleCreateSysMenu(Console);
+  SetEvent(GuiData->hGuiInitEvent);
 
   return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create);
 }
@@ -154,10 +772,18 @@ GuiConsoleRGBFromAttribute(BYTE Attribute)
 }
 
 static VOID FASTCALL
-GuiConsoleSetTextColors(HDC Dc, BYTE Attribute)
+GuiConsoleSetTextColors(HDC Dc, BYTE Attribute, PCSRSS_SCREEN_BUFFER Buff, COLORREF TextColor, COLORREF BkColor)
 {
-  SetTextColor(Dc, GuiConsoleRGBFromAttribute(Attribute & 0x0f));
-  SetBkColor(Dc, GuiConsoleRGBFromAttribute((Attribute & 0xf0) >> 4));
+  if (Attribute != Buff->DefaultAttrib)
+    {
+      SetTextColor(Dc, GuiConsoleRGBFromAttribute(Attribute & 0x0f));
+      SetBkColor(Dc, GuiConsoleRGBFromAttribute((Attribute & 0xf0) >> 4));
+    }
+  else
+    {
+      SetTextColor(Dc, TextColor);
+      SetBkColor(Dc, BkColor);
+    }
 }
 
 static VOID FASTCALL
@@ -252,7 +878,7 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
     PWCHAR To;
     BYTE LastAttribute, Attribute;
     ULONG CursorX, CursorY, CursorHeight;
-    HBRUSH CursorBrush, OldBrush;
+    HBRUSH CursorBrush, OldBrush, BackgroundBrush;
     HFONT OldFont;
 
     Buff = Console->ActiveBuffer;
@@ -264,13 +890,20 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
     LastAttribute = Buff->Buffer[(TopLine * Buff->MaxX + LeftChar) * 2 + 1];
 
     GuiConsoleSetTextColors(hDC,
-                            LastAttribute);
+                            LastAttribute,
+                            Buff,
+                            GuiData->ScreenText,
+                            GuiData->ScreenBackground);
 
     EnterCriticalSection(&Buff->Header.Lock);
 
     OldFont = SelectObject(hDC,
                            GuiData->Font);
 
+       BackgroundBrush = CreateSolidBrush(GuiData->ScreenBackground);
+       FillRect(hDC, rc, BackgroundBrush);
+       DeleteObject(BackgroundBrush);
+
     for (Line = TopLine; Line <= BottomLine; Line++)
     {
         if (Line + Buff->ShowY < Buff->MaxY)
@@ -300,7 +933,10 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
                 if (Attribute != LastAttribute)
                 {
                     GuiConsoleSetTextColors(hDC,
-                                            Attribute);
+                                            Attribute,
+                                            Buff,
+                                            GuiData->ScreenText,
+                                            GuiData->ScreenBackground);
                     LastAttribute = Attribute;
                 }
             }
@@ -337,7 +973,16 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
                 CursorHeight = 1;
             }
             From = Buff->Buffer + (Buff->CurrentY * Buff->MaxX + Buff->CurrentX) * 2 + 1;
-            CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From));
+
+            if (*From != DEFAULT_ATTRIB)
+            {
+                CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(*From));
+            }
+            else
+            {
+                CursorBrush = CreateSolidBrush(GuiData->ScreenText);
+            }
+
             OldBrush = SelectObject(hDC,
                                     CursorBrush);
             PatBlt(hDC,
@@ -377,37 +1022,40 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
         if (Console != NULL && GuiData != NULL &&
             Console->ActiveBuffer != NULL)
         {
-            EnterCriticalSection(&GuiData->Lock);
-
-            GuiConsolePaint(Console,
-                            GuiData,
-                            hDC,
-                            &ps.rcPaint);
-
-            if (GuiData->Selection.left != -1)
+            if (Console->ActiveBuffer->Buffer != NULL)
             {
-                RECT rc = GuiData->Selection;
+                EnterCriticalSection(&GuiData->Lock);
 
-                rc.left *= GuiData->CharWidth;
-                rc.top *= GuiData->CharHeight;
-                rc.right *= GuiData->CharWidth;
-                rc.bottom *= GuiData->CharHeight;
+                GuiConsolePaint(Console,
+                                GuiData,
+                                hDC,
+                                &ps.rcPaint);
 
-                /* invert the selection */
-                if (IntersectRect(&rc,
-                                  &ps.rcPaint,
-                                  &rc))
+                if (GuiData->Selection.left != -1)
                 {
-                    PatBlt(hDC,
-                           rc.left,
-                           rc.top,
-                           rc.right - rc.left,
-                           rc.bottom - rc.top,
-                           DSTINVERT);
+                    RECT rc = GuiData->Selection;
+
+                    rc.left *= GuiData->CharWidth;
+                    rc.top *= GuiData->CharHeight;
+                    rc.right *= GuiData->CharWidth;
+                    rc.bottom *= GuiData->CharHeight;
+
+                    /* invert the selection */
+                    if (IntersectRect(&rc,
+                                      &ps.rcPaint,
+                                      &rc))
+                    {
+                        PatBlt(hDC,
+                               rc.left,
+                               rc.top,
+                               rc.right - rc.left,
+                               rc.bottom - rc.top,
+                               DSTINVERT);
+                    }
                 }
-            }
 
-            LeaveCriticalSection(&GuiData->Lock);
+                LeaveCriticalSection(&GuiData->Lock);
+            }
         }
 
         EndPaint(hWnd, &ps);
@@ -630,12 +1278,20 @@ GuiConsoleHandleNcDestroy(HWND hWnd)
 {
   PCSRSS_CONSOLE Console;
   PGUI_CONSOLE_DATA GuiData;
+  HMENU menu;
+
 
   GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
   KillTimer(hWnd, 1);
   Console->PrivateData = NULL;
   DeleteCriticalSection(&GuiData->Lock);
-  GetSystemMenu(hWnd, TRUE);
+
+  menu = GetSystemMenu(hWnd, TRUE);
+  if (menu == NULL)
+  {
+      DPRINT1("This should never happen, GetSystemMenu == NULL \n");
+  }
+
   if (GuiData->ConsoleLibrary)
     FreeLibrary(GuiData->ConsoleLibrary);
 
@@ -781,25 +1437,29 @@ GuiConsoleRightMouseDown(HWND hWnd)
 
 }
 
+
 static VOID
-GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults)
+GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData)
 {
   PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
   APPLET_PROC CPLFunc;
   TCHAR szBuffer[MAX_PATH];
+  ConsoleInfo SharedInfo;
+
+  DPRINT("GuiConsoleShowConsoleProperties entered\n");
 
   GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
 
   if (GuiData == NULL)
-  {
-    DPRINT1("GuiConsoleGetDataPointers failed\n");
-    return;
-  }
+    {
+      DPRINT("GuiConsoleGetDataPointers failed\n");
+      return;
+    }
+
   if (GuiData->ConsoleLibrary == NULL)
     {
-               GetWindowsDirectory(szBuffer,MAX_PATH);
-               _tcscat(szBuffer, _T("\\system32\\console.dll"));
+      GetWindowsDirectory(szBuffer,MAX_PATH);
+      _tcscat(szBuffer, _T("\\system32\\console.dll"));
       GuiData->ConsoleLibrary = LoadLibrary(szBuffer);
 
       if (GuiData->ConsoleLibrary == NULL)
@@ -811,134 +1471,230 @@ GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults)
 
   CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet"));
   if (!CPLFunc)
-  {
-    DPRINT("Error: Console.dll misses CPlApplet export\n");
-    return;
-  }
+    {
+      DPRINT("Error: Console.dll misses CPlApplet export\n");
+      return;
+    }
 
+  /* setup struct */
+  SharedInfo.InsertMode = GuiData->InsertMode;
+  SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize;
+  SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers;
+  SharedInfo.ScreenText = GuiData->ScreenText; 
+  SharedInfo.ScreenBackground = GuiData->ScreenBackground; 
+  SharedInfo.PopupText = GuiData->PopupText; 
+  SharedInfo.PopupBackground = GuiData->PopupBackground; 
+  SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y);
+  SharedInfo.WindowPosition = GuiData->WindowPosition;
+  SharedInfo.ScreenBuffer = GuiData->ScreenBufferSize;
+  SharedInfo.UseRasterFonts = GuiData->UseRasterFonts;
+  SharedInfo.FontSize = (DWORD)GuiData->FontSize;
+  SharedInfo.FontWeight = GuiData->FontWeight;
+  SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
+  SharedInfo.HistoryNoDup = GuiData->HistoryNoDup;
+  SharedInfo.FullScreen = GuiData->FullScreen;
+  SharedInfo.QuickEdit = GuiData->QuickEdit;
+  memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors));
   if (!CPLFunc(hWnd, CPL_INIT, 0, 0))
-  {
-    DPRINT("Error: failed to initialize console.dll\n");
-    return;
-  }
+    {
+      DPRINT("Error: failed to initialize console.dll\n");
+      return;
+    }
 
   if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1)
-  {
-    DPRINT("Error: console.dll returned unexpected CPL count\n");
-    return;
-  }
+    {
+      DPRINT("Error: console.dll returned unexpected CPL count\n");
+      return;
+    }
 
-  CPLFunc(hWnd, CPL_DBLCLK, 0, Defaults);
-
-  // TODO
-  //
-  // read back the changes from console.dll
-  //
-  // if the changes are system-wide then 
-  // console.dll should have written it to
-  // registry
-  //
-  // if the changes only apply to this session
-  // then exchange this info with console.dll in
-  // some private way
+  CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults);
 }
 static LRESULT FASTCALL
-GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
+GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CONSOLE_DATA GuiData)
 {
-  DPRINT1("GuiConsoleHandleSysMenuCommand entered %d\n", wParam);
+    LRESULT Ret = TRUE;
 
-  switch(wParam)
+    switch(wParam)
     {
-      case IDS_MARK:
-      case IDS_COPY:
-      case IDS_PASTE:
-      case IDS_SELECTALL:
-      case IDS_SCROLL:
-      case IDS_FIND:
-        break;
+        case ID_SYSTEM_EDIT_MARK:
+        case ID_SYSTEM_EDIT_COPY:
+        case ID_SYSTEM_EDIT_PASTE:
+        case ID_SYSTEM_EDIT_SELECTALL:
+        case ID_SYSTEM_EDIT_SCROLL:
+        case ID_SYSTEM_EDIT_FIND:
+            break;
+
+        case ID_SYSTEM_DEFAULTS:
+            GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData);
+            break;
+
+        case ID_SYSTEM_PROPERTIES:
+            GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData);
+            break;
+
+        default:
+            Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam);
+            break;
+    }
+    return Ret;
+}
 
-      case IDS_DEFAULTS:
-        GuiConsoleShowConsoleProperties(hWnd, TRUE);
-        break;
-      case IDS_PROPERTIES:
-        GuiConsoleShowConsoleProperties(hWnd, FALSE);
-        break;
-      default:
-        break;
-   }
+static VOID FASTCALL
+GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+  PCSRSS_CONSOLE Console;
+  PGUI_CONSOLE_DATA GuiData;
 
-  return 0;
+  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+  if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)
+  {
+      DPRINT1("GuiConsoleResize X %d Y %d\n", LOWORD(lParam), HIWORD(lParam));
+  }
 }
-static BOOLEAN FASTCALL
-InsertItem(HMENU hMenu, INT fType, INT fMask, INT fState, HMENU hSubMenu, INT ResourceId)
+
+VOID FASTCALL
+GuiConsoleCreateScrollBar(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, HWND NewWindow)
 {
-  MENUITEMINFO MenuItemInfo;
-  TCHAR szBuffer[MAX_PATH];
+  HMENU hMenu;
+  HWND hVScrollBar;
+  HWND hHScrollBar;
+  SCROLLINFO sInfo;
+
+  hMenu = CreatePopupMenu();
+  if (hMenu == NULL)
+    {
+      DPRINT("CreatePopupMenu failed\n");
+      return;
+    }
 
-  memset(&MenuItemInfo, 0x0, sizeof(MENUITEMINFO));
-  MenuItemInfo.cbSize = sizeof (MENUITEMINFO);
-  MenuItemInfo.fMask = fMask;
-  MenuItemInfo.fType = fType;
-  MenuItemInfo.fState = fState;
-  MenuItemInfo.hSubMenu = hSubMenu;
-  MenuItemInfo.wID = ResourceId;
+  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE);
+  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
+  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP);
+  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM);
+  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
+  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP);
+  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN);
+  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
+  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP);
+  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN);
+  
+  hVScrollBar = CreateWindowExW(0L,
+                                L"ScrollBar",
+                                (LPWSTR)NULL,
+                                WS_CHILD | WS_VSCROLL,
+                                0,
+                                0,
+                                200,
+                                50,
+                                NewWindow,
+                                NULL, //hMenu,
+                                GetModuleHandleW(NULL),
+                                (LPVOID)GuiData);
+
+  if (hVScrollBar)
+    {
 
-  if (fType != MFT_SEPARATOR)
+      /* set scrollbar sizes */
+      sInfo.cbSize = sizeof(SCROLLINFO);
+      sInfo.fMask = SIF_RANGE | SIF_POS;
+      sInfo.nMin = 0;
+      sInfo.nMax = Console->ActiveBuffer->MaxY;
+         sInfo.nPos = 0;
+      SetScrollInfo(hVScrollBar, SB_CTL, &sInfo, TRUE);
+      ShowScrollBar(NewWindow, SB_CTL, TRUE);
+         GuiData->hVScrollBar = hVScrollBar;
+    }
+  if (Console->ActiveBuffer->MaxX > Console->Size.X)
     {
-      MenuItemInfo.cch = LoadString(Win32CsrDllHandle, ResourceId, szBuffer, MAX_PATH);
-      if (!MenuItemInfo.cch)
+      hHScrollBar = CreateWindowExW(0L,
+                                    L"ScrollBar",
+                                    (LPWSTR)NULL,
+                                    WS_CHILD | WS_HSCROLL,
+                                    0,
+                                    0,
+                                    200,
+                                    CW_USEDEFAULT,
+                                    NewWindow,
+                                    hMenu,
+                                    GetModuleHandleW(NULL),
+                                   (LPVOID)GuiData);
+      if (hHScrollBar)
         {
-          DPRINT("LoadString failed ResourceId %d Error %x\n", ResourceId, GetLastError());
-          return FALSE;
+          sInfo.nMax = Console->ActiveBuffer->MaxX;
+          SetScrollInfo(hHScrollBar, SB_CTL, &sInfo, TRUE);
+          GuiData->hHScrollBar = hHScrollBar;
         }
-        MenuItemInfo.dwTypeData = szBuffer;
     }
+}
 
-  if (InsertMenuItem(hMenu, ResourceId, FALSE, &MenuItemInfo))
-    return TRUE;
+static VOID FASTCALL
+GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo)
+{
+  DWORD windx, windy;
+  RECT rect;
+    
+  /* apply text / background color */
+  GuiData->ScreenText = pConInfo->ScreenText;
+  GuiData->ScreenBackground = pConInfo->ScreenBackground;
 
-  DPRINT("InsertMenuItem failed Last error %x\n", GetLastError());
-  return FALSE;
-}
+  /* apply cursor size */
+  Console->ActiveBuffer->CursorInfo.dwSize = max(min(pConInfo->CursorSize, 1), 100);
 
+  windx = LOWORD(pConInfo->ScreenBuffer);
+  windy = HIWORD(pConInfo->ScreenBuffer);
 
+  if (windx != Console->ActiveBuffer->MaxX || windy != Console->ActiveBuffer->MaxY)
+  {
+    //
+    // TODO
+    // resize screen buffer
 
-static VOID FASTCALL
-GuiConsoleCreateSysMenu(HWND hWnd)
-{
-  HMENU hMenu;
-  HMENU hSubMenu;
 
+    // Console->ActiveBuffer->MaxX = windx;
+    // Console->ActiveBuffer->MaxY = windy;
+  }
 
-  hMenu = GetSystemMenu(hWnd, FALSE);
-  if (hMenu == NULL)
-    {
-      DPRINT("GetSysMenu failed\n");
-      return;
-    }
-  /* insert seperator */
-  InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
-
-    /* create submenu */
-  hSubMenu = CreatePopupMenu();
-  InsertItem(hSubMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_MARK);
-  InsertItem(hSubMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING | MIIM_STATE, MFS_GRAYED, NULL, IDS_COPY);
-  InsertItem(hSubMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_PASTE);
-  InsertItem(hSubMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SELECTALL);
-  InsertItem(hSubMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLL);
-  InsertItem(hSubMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_FIND);
-  InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING | MIIM_SUBMENU, 0, hSubMenu, IDS_EDIT);
-
-  /* create default/properties item */
-  InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_DEFAULTS);
-  InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_PROPERTIES);
-  DrawMenuBar(hWnd);
+  windx = LOWORD(pConInfo->WindowSize);
+  windy = HIWORD(pConInfo->WindowSize);
+
+  if (windx != Console->Size.X || windy != Console->Size.Y)
+  {
+      /* resize window */
+      Console->Size.X = windx;
+      Console->Size.Y = windy;
+
+      GetWindowRect(pConInfo->hConsoleWindow, &rect);
+
+      rect.right = rect.left + Console->Size.X * GuiData->CharWidth + 2 * GetSystemMetrics(SM_CXFIXEDFRAME);
+      rect.bottom = rect.top + Console->Size.Y * GuiData->CharHeight + 2 * GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION);
+
+      MoveWindow(pConInfo->hConsoleWindow, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, FALSE);
+
+      if (Console->Size.X < Console->ActiveBuffer->MaxX)
+      {
+          /* show scrollbar when window becomes smaller than active screen buffer */
+          //ShowScrollBar(GuiData->hHScrollBar, SB_CTL, TRUE);
+      }
+      else
+      {
+          /* hide scrollbar */
+          //ShowScrollBar(GuiData->hHScrollBar, SB_CTL, FALSE);
+      }
+  }
+  /* repaint window */
+  InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
 }
 
 static LRESULT CALLBACK
 GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
   LRESULT Result = 0;
+  PGUI_CONSOLE_DATA GuiData = NULL;
+  PCSRSS_CONSOLE Console = NULL;
+
+  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
 
   switch(msg)
     {
@@ -976,8 +1732,19 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
       case WM_MOUSEMOVE:
           GuiConsoleMouseMove(hWnd, wParam, lParam);
         break;
-         case WM_SYSCOMMAND:
-          return GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam);         
+      case WM_SYSCOMMAND:
+          Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData);
+          break;
+      case WM_SIZE:
+          GuiConsoleResize(hWnd, wParam, lParam);
+          break;
+      case PM_APPLY_CONSOLE_INFO:
+          GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam);
+          if (lParam)
+            {
+              GuiConsoleWriteUserSettings(Console, GuiData);
+            }
+          break;
       default:
         Result = DefWindowProcW(hWnd, msg, wParam, lParam);
         break;
@@ -1017,7 +1784,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
           }
         NewWindow = CreateWindowW(L"ConsoleWindowClass",
                                   Title,
-                                  WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, // | WS_HSCROLL | WS_VSCROLL,
+                                  WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, //WS_OVERLAPPEDWINDOW
                                   CW_USEDEFAULT,
                                   CW_USEDEFAULT,
                                   CW_USEDEFAULT,
@@ -1030,12 +1797,10 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
           {
             HeapFree(Win32CsrApiHeap, 0, Buffer);
           }
-        Console->hWindow = NewWindow;
         if (NULL != NewWindow)
           {
-            GuiConsoleCreateSysMenu(NewWindow);
-            //ShowScrollBar(NewWindow, SB_VERT, FALSE);
-            //ShowScrollBar(NewWindow, SB_HORZ, FALSE);
+            // scrollbar support
+            //GuiConsoleCreateScrollBar(Console, (PGUI_CONSOLE_DATA)Console->PrivateData, NewWindow);
             SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
             ShowWindow(NewWindow, SW_SHOW);
           }
@@ -1136,7 +1901,7 @@ GuiInit(VOID)
   wc.style = 0;
   wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
   wc.hIcon = LoadIconW(Win32CsrDllHandle, MAKEINTRESOURCEW(1));
-  wc.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_ARROW));
+  wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW);
   wc.hbrBackground = NULL;
   wc.lpszMenuName = NULL;
   wc.cbClsExtra = 0;
@@ -1156,7 +1921,7 @@ GuiInit(VOID)
 static VOID STDCALL
 GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
 {
-  Buffer->DefaultAttrib = 0x0f;
+  Buffer->DefaultAttrib = DEFAULT_ATTRIB;
 }
 
 static BOOL STDCALL
@@ -1176,7 +1941,9 @@ GuiChangeTitle(PCSRSS_CONSOLE Console)
     {
       Title = L"";
     }
+
   SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title);
+
   if (NULL != Buffer)
     {
       HeapFree(Win32CsrApiHeap, 0, Buffer);
@@ -1217,6 +1984,7 @@ GuiInitConsole(PCSRSS_CONSOLE Console)
 {
   HANDLE GraphicsStartupEvent;
   HANDLE ThreadHandle;
+  PGUI_CONSOLE_DATA GuiData;
 
   if (! ConsInitialized)
     {
@@ -1229,8 +1997,6 @@ GuiInitConsole(PCSRSS_CONSOLE Console)
     }
 
   Console->Vtbl = &GuiVtbl;
-  Console->Size.X = 80;
-  Console->Size.Y = 25;
   if (NULL == NotifyWnd)
     {
       GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
@@ -1263,8 +2029,31 @@ GuiInitConsole(PCSRSS_CONSOLE Console)
           return STATUS_UNSUCCESSFUL;
         }
     }
+    GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
+                        sizeof(GUI_CONSOLE_DATA));
+    if (!GuiData)
+      {
+        DPRINT1("Win32Csr: Failed to create GUI_CONSOLE_DATA\n");
+        return STATUS_UNSUCCESSFUL;
+      }
 
-  PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
+    Console->PrivateData = (PVOID) GuiData;
+    /*
+     * we need to wait untill the GUI has been fully initialized
+     * to retrieve custom settings i.e. WindowSize etc..
+     * Ideally we could use SendNotifyMessage for this but its not
+     * yet implemented.
+     *
+     */
+    GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+    /* create console */
+    PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
+
+    /* wait untill initialization has finished */
+    WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
+    DPRINT1("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y);
+    CloseHandle(GuiData->hGuiInitEvent);
+    GuiData->hGuiInitEvent = NULL;
 
   return STATUS_SUCCESS;
 }