diff --git a/rfb_win32/Win32Util.cxx b/rfb_win32/Win32Util.cxx
index 28fae2e..ef8039a 100644
--- a/rfb_win32/Win32Util.cxx
+++ b/rfb_win32/Win32Util.cxx
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -18,221 +18,30 @@
 
 // Win32Util.cxx
 
+#include <rfb_win32/ModuleFileName.h>
 #include <rfb_win32/Win32Util.h>
-#include <rdr/Exception.h>
+#include <rfb_win32/MonitorInfo.h>
+#include <rfb_win32/Handle.h>
 #include <rdr/HexOutStream.h>
-
+#include <rdr/Exception.h>
 
 namespace rfb {
 namespace win32 {
 
-LogicalPalette::LogicalPalette() : palette(0), numEntries(0) {
-  BYTE buf[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)];
-  LOGPALETTE* logpal = (LOGPALETTE*)buf;
-  logpal->palVersion = 0x300;
-  logpal->palNumEntries = 256;
-  for (int i=0; i<256;i++) {
-    logpal->palPalEntry[i].peRed = 0;
-    logpal->palPalEntry[i].peGreen = 0;
-    logpal->palPalEntry[i].peBlue = 0;
-    logpal->palPalEntry[i].peFlags = 0;
-  }
-  palette = CreatePalette(logpal);
-  if (!palette)
-    throw rdr::SystemException("failed to CreatePalette", GetLastError());
-}
-
-LogicalPalette::~LogicalPalette() {
-  if (palette)
-    if (!DeleteObject(palette))
-      throw rdr::SystemException("del palette failed", GetLastError());
-}
-
-void LogicalPalette::setEntries(int start, int count, const Colour* cols) {
-  if (numEntries < count) {
-    ResizePalette(palette, start+count);
-    numEntries = start+count;
-  }
-  PALETTEENTRY* logpal = new PALETTEENTRY[count];
-  for (int i=0; i<count; i++) {
-    logpal[i].peRed = cols[i].r >> 8;
-    logpal[i].peGreen = cols[i].g >> 8;
-    logpal[i].peBlue = cols[i].b >> 8;
-    logpal[i].peFlags = 0;
-  }
-  UnrealizeObject(palette);
-  SetPaletteEntries(palette, start, count, logpal);
-  delete [] logpal;
-}
-
-
-static LogWriter dcLog("DeviceContext");
-
-PixelFormat DeviceContext::getPF() const {
-  return getPF(dc);
-}
-
-PixelFormat DeviceContext::getPF(HDC dc) {
-  PixelFormat format;
-  CompatibleBitmap bitmap(dc, 1, 1);
-
-  // -=- Get the bitmap format information
-  BitmapInfo bi;
-  memset(&bi, 0, sizeof(bi));
-  bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-  bi.bmiHeader.biBitCount = 0;
-
-  if (!::GetDIBits(dc, bitmap, 0, 1, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) {
-    throw rdr::SystemException("unable to determine device pixel format", GetLastError());
-  }
-  if (!::GetDIBits(dc, bitmap, 0, 1, NULL, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) {
-    throw rdr::SystemException("unable to determine pixel shifts/palette", GetLastError());
-  }
-
-  // -=- Munge the bitmap info here
-  switch (bi.bmiHeader.biBitCount) {
-  case 1:
-  case 4:
-    bi.bmiHeader.biBitCount = 8;
-    break;
-  case 24:
-    bi.bmiHeader.biBitCount = 32;
-    break;
-  }
-  bi.bmiHeader.biPlanes = 1;
-
-  format.trueColour = bi.bmiHeader.biBitCount > 8;
-  format.bigEndian = 0;
-  format.bpp = format.depth = bi.bmiHeader.biBitCount;
-
-  if (format.trueColour) {
-    DWORD rMask=0, gMask=0, bMask=0;
-
-    // Which true colour format is the DIB section using?
-    switch (bi.bmiHeader.biCompression) {
-    case BI_RGB:
-      // Default RGB layout
-      switch (bi.bmiHeader.biBitCount) {
-      case 16:
-        // RGB 555 - High Colour
-        dcLog.info("16-bit High Color");
-        rMask = 0x7c00;
-        bMask = 0x001f;
-        gMask = 0x03e0;
-        format.depth = 15;
-        break;
-      case 24:
-      case 32:
-        // RGB 888 - True Colour
-        dcLog.info("24/32-bit High Color");
-        rMask = 0xff0000;
-        gMask = 0x00ff00;
-        bMask = 0x0000ff;
-        format.depth = 24;
-        break;
-      default:
-        dcLog.error("bits per pixel %u not supported", bi.bmiHeader.biBitCount);
-        throw rdr::Exception("unknown bits per pixel specified");
-      };
-      break;
-    case BI_BITFIELDS:
-      // Custom RGB layout
-      rMask = bi.mask.red;
-      gMask = bi.mask.green;
-      bMask = bi.mask.blue;
-      dcLog.info("BitFields format: %lu, (%lx, %lx, %lx)",
-        bi.bmiHeader.biBitCount, rMask, gMask, bMask);
-      if (format.bpp == 32)
-        format.depth = 24; // ...probably
-      break;
-    };
-
-    // Convert the data we just retrieved
-    initMaxAndShift(rMask, &format.redMax, &format.redShift);
-    initMaxAndShift(gMask, &format.greenMax, &format.greenShift);
-    initMaxAndShift(bMask, &format.blueMax, &format.blueShift);
-  }
-
-  return format;
-}
-
-
-WindowDC::WindowDC(HWND wnd) : hwnd(wnd) {
-  dc = GetDC(wnd);
-  if (!dc)
-    throw rdr::SystemException("GetDC failed", GetLastError());
-}
-WindowDC::~WindowDC() {
-  if (dc)
-    ReleaseDC(hwnd, dc);
-}
-
-
-CompatibleDC::CompatibleDC(HDC existing) {
-  dc = CreateCompatibleDC(existing);
-  if (!dc)
-    throw rdr::SystemException("CreateCompatibleDC failed", GetLastError());
-}
-CompatibleDC::~CompatibleDC() {
-  if (dc)
-    DeleteDC(dc);
-}
-
-
-BitmapDC::BitmapDC(HDC hdc, HBITMAP hbitmap) : CompatibleDC(hdc){
-  oldBitmap = (HBITMAP)SelectObject(dc, hbitmap);
-  if (!oldBitmap)
-    throw rdr::SystemException("SelectObject to CompatibleDC failed",
-    GetLastError());
-}
-BitmapDC::~BitmapDC() {
-  SelectObject(dc, oldBitmap);
-}
-
-
-CompatibleBitmap::CompatibleBitmap(HDC hdc, int width, int height) {
-  hbmp = CreateCompatibleBitmap(hdc, width, height);
-  if (!hbmp)
-    throw rdr::SystemException("CreateCompatibleBitmap() failed", 
-    GetLastError());
-}
-CompatibleBitmap::~CompatibleBitmap() {
-  if (hbmp) DeleteObject(hbmp);
-}
-
-
-PaletteSelector::PaletteSelector(HDC dc, HPALETTE pal) : device(dc), redrawRequired(false) {
-  oldPal = SelectPalette(dc, pal, FALSE);
-  redrawRequired = RealizePalette(dc) > 0;
-}
-PaletteSelector::~PaletteSelector() {
-  if (oldPal) SelectPalette(device, oldPal, TRUE);
-}
-
-
-IconInfo::IconInfo(HICON icon) {
-  if (!GetIconInfo(icon, this))
-    throw rdr::SystemException("GetIconInfo() failed", GetLastError());
-}
-IconInfo::~IconInfo() {
-  if (hbmColor)
-    DeleteObject(hbmColor);
-  if (hbmMask)
-    DeleteObject(hbmMask);
-}
-
-
-ModuleFileName::ModuleFileName(HMODULE module) : TCharArray(MAX_PATH) {
-  if (!module) module = GetModuleHandle(0);
-  if (!GetModuleFileName(module, buf, MAX_PATH))
-    buf[0] = 0;
-}
-
 
 FileVersionInfo::FileVersionInfo(const TCHAR* filename) {
   // Get executable name
   ModuleFileName exeName;
-  if (!filename) filename = exeName.buf;
+  if (!filename)
+    filename = exeName.buf;
+
+  // Attempt to open the file, to cause Access Denied, etc, errors
+  // to be correctly reported, since the GetFileVersionInfoXXX calls lie...
+  {
+    Handle file(CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0));
+	  if (file.h == INVALID_HANDLE_VALUE)
+      throw rdr::SystemException("Failed to open file", GetLastError());
+  }
 
   // Get version info size
   DWORD handle;
@@ -249,7 +58,7 @@
 const TCHAR* FileVersionInfo::getVerString(const TCHAR* name, DWORD langId) {
   char langIdBuf[sizeof(langId)];
   for (int i=sizeof(langIdBuf)-1; i>=0; i--) {
-    langIdBuf[i] = langId & 0xff;
+    langIdBuf[i] = (char) (langId & 0xff);
     langId = langId >> 8;
   }
 
@@ -273,173 +82,31 @@
 }
 
 
-static LogWriter dfbLog("DynamicFn");
-
-DynamicFnBase::DynamicFnBase(const TCHAR* dllName, const char* fnName) : dllHandle(0), fnPtr(0) {
-  dllHandle = LoadLibrary(dllName);
-  if (!dllHandle) {
-    dfbLog.info("DLL %s not found (%d)", (const char*)CStr(dllName), GetLastError());
-    return;
-  }
-  fnPtr = GetProcAddress(dllHandle, fnName);
-  if (!fnPtr)
-    dfbLog.info("proc %s not found in %s (%d)", fnName, (const char*)CStr(dllName), GetLastError());
-}
-
-DynamicFnBase::~DynamicFnBase() {
-  if (dllHandle)
-    FreeLibrary(dllHandle);
-}
-
-
-static LogWriter miLog("MonitorInfo");
-
-MonitorInfo::MonitorInfo(HWND window) {
-#if (WINVER >= 0x0500)
-  typedef HMONITOR (WINAPI *_MonitorFromWindow_proto)(HWND,DWORD);
-  rfb::win32::DynamicFn<_MonitorFromWindow_proto> _MonitorFromWindow(_T("user32.dll"), "MonitorFromWindow");
-  typedef BOOL (WINAPI *_GetMonitorInfo_proto)(HMONITOR,LPMONITORINFO);
-  rfb::win32::DynamicFn<_GetMonitorInfo_proto> _GetMonitorInfo(_T("user32.dll"), "GetMonitorInfoA");
-
-  // Can we dynamically link to the monitor functions?
-  if (_MonitorFromWindow.isValid()) {
-    if (_GetMonitorInfo.isValid()) {
-      HMONITOR monitor = (*_MonitorFromWindow)(window, MONITOR_DEFAULTTONEAREST);
-      miLog.debug("monitor=%lx", monitor);
-      if (monitor) {
-        memset(this, 0, sizeof(MONITORINFOEXA));
-        cbSize = sizeof(MONITORINFOEXA);
-        if ((*_GetMonitorInfo)(monitor, this)) {
-          miLog.debug("monitor is %d,%d-%d,%d", rcMonitor.left, rcMonitor.top, rcMonitor.right, rcMonitor.bottom);
-          miLog.debug("work area is %d,%d-%d,%d", rcWork.left, rcWork.top, rcWork.right, rcWork.bottom);
-          miLog.debug("device is \"%s\"", szDevice);
-          return;
-        }
-        miLog.error("failed to get monitor info: %ld", GetLastError());
-      }
-    } else {
-      miLog.debug("GetMonitorInfo not found");
-    }
-  } else {
-      miLog.debug("MonitorFromWindow not found");
-  }
-#else
-#pragma message ("not building in GetMonitorInfo")
-  cbSize = sizeof(MonitorInfo);
-  szDevice[0] = 0;
-#endif
-
-  // Legacy fallbacks - just return the desktop settings
-  miLog.debug("using legacy fall-backs");
-  HWND desktop = GetDesktopWindow();
-  GetWindowRect(desktop, &rcMonitor);
-  SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
-  dwFlags = 0;
-}
-
-
-#if (WINVER >= 0x0500)
-
-struct moveToMonitorData {
-  HWND window;
-  const char* monitorName;
-};
-
-typedef BOOL (WINAPI *_GetMonitorInfo_proto)(HMONITOR,LPMONITORINFO);
-static rfb::win32::DynamicFn<_GetMonitorInfo_proto> _GetMonitorInfo(_T("user32.dll"), "GetMonitorInfoA");
-
-static BOOL CALLBACK moveToMonitorEnumProc(HMONITOR monitor,
-                                    HDC dc,
-                                    LPRECT pos,
-                                    LPARAM d) {
-  moveToMonitorData* data = (moveToMonitorData*)d;
-  MONITORINFOEXA info;
-  memset(&info, 0, sizeof(info));
-  info.cbSize = sizeof(info);
-
-  if ((*_GetMonitorInfo)(monitor, &info)) {
-    if (stricmp(data->monitorName, info.szDevice) == 0) {
-      SetWindowPos(data->window, 0,
-        info.rcMonitor.left, info.rcMonitor.top,
-        info.rcMonitor.right, info.rcMonitor.bottom,
-        SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOOWNERZORDER);
-      return FALSE;
-    }
-  }
-
-  return TRUE;
-}
-
-#endif
-
-void moveToMonitor(HWND handle, const char* device) {
-  miLog.debug("moveToMonitor %s", device);
-
-#if (WINVER >= 0x500)
-  typedef BOOL (WINAPI *_EnumDisplayMonitors_proto)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
-  rfb::win32::DynamicFn<_EnumDisplayMonitors_proto> _EnumDisplayMonitors(_T("user32.dll"), "EnumDisplayMonitors");
-  if (!_EnumDisplayMonitors.isValid()) {
-    miLog.debug("EnumDisplayMonitors not found");
-    return;
-  }
-
-  moveToMonitorData data;
-  data.window = handle;
-  data.monitorName = device;
-
-  (*_EnumDisplayMonitors)(0, 0, &moveToMonitorEnumProc, (LPARAM)&data);
-#endif
-}
-
-
-void centerWindow(HWND handle, HWND parent, bool clipToParent) {
+void centerWindow(HWND handle, HWND parent) {
   RECT r;
-  if (parent && IsWindowVisible(parent)) {
-    if (!GetWindowRect(parent, &r)) return;
-  } else {
-    MonitorInfo mi(handle);
+  MonitorInfo mi(parent ? parent : handle);
+  if (!parent || !IsWindowVisible(parent) || !GetWindowRect(parent, &r))
     r=mi.rcWork;
-  }
-  centerWindow(handle, r, clipToParent);
+  centerWindow(handle, r);
+  mi.clipTo(handle);
 }
 
-void centerWindow(HWND handle, const RECT& r, bool clipToRect) {
+void centerWindow(HWND handle, const RECT& r) {
   RECT wr;
   if (!GetWindowRect(handle, &wr)) return;
   int w = wr.right-wr.left;
   int h = wr.bottom-wr.top;
-  if (clipToRect) {
-    w = min(r.right-r.left, w);
-    h = min(r.bottom-r.top, h);
-  }
   int x = (r.left + r.right - w)/2;
   int y = (r.top + r.bottom - h)/2;
-  UINT flags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | (clipToRect ? 0 : SWP_NOSIZE);
-  SetWindowPos(handle, 0, x, y, w, h, flags);
+  UINT flags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOSIZE;
+  SetWindowPos(handle, 0, x, y, 0, 0, flags);
 }
 
-
-int MsgBox(HWND parent, const TCHAR* msg, UINT flags) {
-  const TCHAR* msgType = 0;
-  UINT tflags = flags & 0x70;
-  if (tflags == MB_ICONHAND)
-    msgType = _T("Error");
-  else if (tflags == MB_ICONQUESTION)
-    msgType = _T("Question");
-  else if (tflags == MB_ICONEXCLAMATION)
-    msgType = _T("Warning");
-  else if (tflags == MB_ICONASTERISK)
-    msgType = _T("Information");
-  flags |= MB_TOPMOST | MB_SETFOREGROUND;
-  int len = _tcslen(AppName.buf) + 1;
-  if (msgType) len += _tcslen(msgType) + 3;
-  TCharArray title = new TCHAR[len];
-  _tcscpy(title.buf, AppName.buf);
-  if (msgType) {
-    _tcscat(title.buf, _T(" : "));
-    _tcscat(title.buf, msgType);
-  }
-  return MessageBox(parent, msg, title.buf, flags);
+void resizeWindow(HWND handle, int width, int height) {
+  RECT r;
+  GetWindowRect(handle, &r);
+  SetWindowPos(handle, 0, 0, 0, width, height, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE);
+  centerWindow(handle, r);
 }
 
 
