- userinit, usetup, vmwinst, welcome, winefile, winlogon, winver.
[reactos.git] / reactos / subsys / system / vmwinst / vmwinst.c
index 3af6cbd..3729fba 100644 (file)
@@ -24,6 +24,7 @@
  * PROJECT:     ReactOS VMware(r) driver installation utility
  * FILE:        subsys/system/vmwinst/vmwinst.c
  * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
+ *              Klemens Friedl (frik85@hotmail.com)
  */
 #include <windows.h>
 #include <commctrl.h>
 #include <string.h>
 #include "vmwinst.h"
 
+extern VOID CALLBACK InstallHinfSectionW(HWND hwnd, HINSTANCE ModuleHandle,
+                                         PCWSTR CmdLineBuffer, INT nCmdShow);
+
+
 HINSTANCE hAppInstance;
 BOOL StartVMwConfigWizard, DriverFilesFound, ActivateVBE = FALSE, UninstallDriver = FALSE;
 
 static WCHAR DestinationDriversPath[MAX_PATH+1];
 static WCHAR CDDrive = L'\0';
+static WCHAR PathToVideoDrivers55[MAX_PATH+1] = L"X:\\program files\\VMware\\VMware Tools\\Drivers\\video\\winnt2k\\32Bit\\";
 static WCHAR PathToVideoDrivers45[MAX_PATH+1] = L"X:\\program files\\VMware\\VMware Tools\\Drivers\\video\\winnt2k\\";
 static WCHAR PathToVideoDrivers40[MAX_PATH+1] = L"X:\\video\\winnt2k\\";
 static WCHAR DestinationPath[MAX_PATH+1];
@@ -54,11 +60,10 @@ static LONG AbortInstall = 0;
 
 /* Helper functions */
 
-LONG WINAPI ExceptionHandler(LPEXCEPTION_POINTERS ExceptionInfo)
+LONG CALLBACK VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
 {
-  /* This is rude, but i don't know how to continue execution properly, that's why
-     we just exit here when we're not running inside of VMware */
-  ExitProcess(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION);
+  /* we're not running in VMware, just terminate the process */
+  ExitProcess(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION);
   return EXCEPTION_CONTINUE_EXECUTION;
 }
 
@@ -66,22 +71,27 @@ BOOL
 DetectVMware(int *Version)
 {
   int magic, ver;
-  
+
   magic = 0;
   ver = 0;
-  
+
   /* Try using a VMware I/O port. If not running in VMware this'll throw an
      exception! */
+#ifndef _MSC_VER
   __asm__ __volatile__("inl  %%dx, %%eax"
     : "=a" (ver), "=b" (magic)
     : "0" (0x564d5868), "d" (0x5658), "c" (0xa));
+#else
+#error PLEASE WRITE THIS IN ASSEMBLY
+#endif
+
 
   if(magic == 0x564d5868)
   {
     *Version = ver;
     return TRUE;
   }
-  
+
   return FALSE;
 }
 
@@ -110,16 +120,17 @@ FileExists(WCHAR *Path, WCHAR *File)
 {
   WCHAR FileName[MAX_PATH + 1];
   HANDLE FileHandle;
-  
+
   FileName[0] = L'\0';
   wcscat(FileName, Path);
   wcscat(FileName, File);
 
   FileHandle = CreateFile(FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-  
+
   if(FileHandle == INVALID_HANDLE_VALUE)
   {
-    return FALSE;
+    /* If it was a sharing violation the file must already exist */
+    return GetLastError() == ERROR_SHARING_VIOLATION;
   }
 
   if(GetFileSize(FileHandle, NULL) <= 0)
@@ -127,11 +138,35 @@ FileExists(WCHAR *Path, WCHAR *File)
     CloseHandle(FileHandle);
     return FALSE;
   }
-  
+
   CloseHandle(FileHandle);
   return TRUE;
 }
 
+static VOID
+CenterWindow(HWND hWnd)
+{
+  HWND hWndParent;
+  RECT rcParent;
+  RECT rcWindow;
+
+  hWndParent = GetParent(hWnd);
+  if (hWndParent == NULL)
+    hWndParent = GetDesktopWindow();
+
+  GetWindowRect(hWndParent, &rcParent);
+  GetWindowRect(hWnd, &rcWindow);
+
+  SetWindowPos(hWnd,
+              HWND_TOP,
+              ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
+              ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
+              0,
+              0,
+              SWP_NOSIZE);
+}
+
+
 /* Copy file */
 BOOL
 InstallFile(WCHAR *Destination, WCHAR *File)
@@ -141,14 +176,14 @@ InstallFile(WCHAR *Destination, WCHAR *File)
   WCHAR DestFileName[MAX_PATH + 1];
   HANDLE SourceFileHandle, DestFileHandle;
   DWORD DataRead, DataWritten;
-  
+
   SourceFileName[0] = L'\0';
   DestFileName[0] = L'\0';
   wcscat(SourceFileName, SrcPath);
   wcscat(SourceFileName, File);
   wcscat(DestFileName, Destination);
   wcscat(DestFileName, File);
-  
+
   SourceFileHandle = CreateFile(SourceFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   if(SourceFileHandle == INVALID_HANDLE_VALUE)
   {
@@ -160,7 +195,7 @@ InstallFile(WCHAR *Destination, WCHAR *File)
     CloseHandle(SourceFileHandle);
     return FALSE;
   }
-  
+
   while(ReadFile(SourceFileHandle, Buffer, sizeof(Buffer), &DataRead, NULL) && DataRead > 0)
   {
     if(!WriteFile(DestFileHandle, Buffer, DataRead, &DataWritten, NULL) ||
@@ -172,7 +207,7 @@ InstallFile(WCHAR *Destination, WCHAR *File)
       return FALSE;
     }
   }
-  
+
   CloseHandle(SourceFileHandle);
   CloseHandle(DestFileHandle);
   return TRUE;
@@ -184,7 +219,7 @@ IsVMwareCDInDrive(WCHAR *Drv)
 {
   static WCHAR Drive[4] = L"X:\\";
   WCHAR Current;
-  
+
   *Drv = L'\0';
   for(Current = 'C'; Current <= 'Z'; Current++)
   {
@@ -193,9 +228,12 @@ IsVMwareCDInDrive(WCHAR *Drv)
     if(GetDriveType(Drive) == DRIVE_CDROM)
     {
 #endif
+      PathToVideoDrivers55[0] = Current;
       PathToVideoDrivers40[0] = Current;
       PathToVideoDrivers45[0] = Current;
-      if(SetCurrentDirectory(PathToVideoDrivers45))
+      if(SetCurrentDirectory(PathToVideoDrivers55))
+        SrcPath = PathToVideoDrivers55;
+      else if(SetCurrentDirectory(PathToVideoDrivers45))
         SrcPath = PathToVideoDrivers45;
       else if(SetCurrentDirectory(PathToVideoDrivers40))
         SrcPath = PathToVideoDrivers40;
@@ -204,7 +242,7 @@ IsVMwareCDInDrive(WCHAR *Drv)
         SetCurrentDirectory(DestinationPath);
         continue;
       }
-      
+
       if(FileExists(SrcPath, vmx_fb) &&
          FileExists(SrcPath, vmx_mode) &&
          FileExists(SrcPath, vmx_svga))
@@ -216,7 +254,7 @@ IsVMwareCDInDrive(WCHAR *Drv)
     }
 #endif
   }
-  
+
   return FALSE;
 }
 
@@ -225,9 +263,9 @@ LoadResolutionSettings(DWORD *ResX, DWORD *ResY, DWORD *ColDepth)
 {
   HKEY hReg;
   DWORD Type, Size;
-  
-  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
-                  L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0", 
+
+  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                  L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0",
                   0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
   {
     return FALSE;
@@ -238,21 +276,21 @@ LoadResolutionSettings(DWORD *ResX, DWORD *ResY, DWORD *ColDepth)
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   if(RegQueryValueEx(hReg, L"DefaultSettings.XResolution", 0, &Type, (BYTE*)ResX, &Size) != ERROR_SUCCESS ||
      Type != REG_DWORD)
   {
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   if(RegQueryValueEx(hReg, L"DefaultSettings.YResolution", 0, &Type, (BYTE*)ResY, &Size) != ERROR_SUCCESS ||
      Type != REG_DWORD)
   {
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   RegCloseKey(hReg);
   return TRUE;
 }
@@ -262,9 +300,9 @@ IsVmwSVGAEnabled(VOID)
 {
   HKEY hReg;
   DWORD Type, Size, Value;
-  
-  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
-                  L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga", 
+
+  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                  L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga",
                   0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
   {
     return FALSE;
@@ -275,7 +313,7 @@ IsVmwSVGAEnabled(VOID)
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   RegCloseKey(hReg);
   return (Value == 1);
 }
@@ -286,10 +324,10 @@ BOOL
 SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
 {
   HKEY hReg;
-  
-  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
-                  L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0", 
-                  0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
+
+  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                  L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0",
+                  0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS)
   {
     return FALSE;
   }
@@ -298,19 +336,19 @@ SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   if(RegSetValueEx(hReg, L"DefaultSettings.XResolution", 0, REG_DWORD, (BYTE*)&ResX, sizeof(DWORD)) != ERROR_SUCCESS)
   {
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   if(RegSetValueEx(hReg, L"DefaultSettings.YResolution", 0, REG_DWORD, (BYTE*)&ResY, sizeof(DWORD)) != ERROR_SUCCESS)
   {
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   RegCloseKey(hReg);
   return TRUE;
 }
@@ -320,9 +358,9 @@ EnableDriver(WCHAR *Key, BOOL Enable)
 {
   DWORD Value;
   HKEY hReg;
-  
+
   Value = (Enable ? 1 : 4);
-  
+
   if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key, 0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS)
   {
     return FALSE;
@@ -332,7 +370,7 @@ EnableDriver(WCHAR *Key, BOOL Enable)
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   RegCloseKey(hReg);
   return TRUE;
 }
@@ -353,7 +391,80 @@ EnableVmwareDriver(BOOL VBE, BOOL VGA, BOOL VMX)
   {
     return FALSE;
   }
-  
+
+  return TRUE;
+}
+
+/* Make sure the required registry entries are present */
+BOOL
+AddVmwareRegistryEntries()
+{
+  HRSRC VmwareInfResource;
+  HGLOBAL VmwareInfMem;
+  PVOID VmwareInfLocked;
+  DWORD Size;
+  WCHAR TempPath[MAX_PATH];
+  WCHAR BufferSize;
+  WCHAR TempFileName[MAX_PATH];
+  HANDLE TempFile;
+  DWORD Written;
+  WCHAR CmdLine[19 + MAX_PATH];
+
+  VmwareInfResource = FindResourceW(hAppInstance,
+                                    MAKEINTRESOURCE(IDR_VMWARE_INF),
+                                    L"RT_INF");
+  if (NULL == VmwareInfResource)
+  {
+    return FALSE;
+  }
+  Size = SizeofResource(hAppInstance, VmwareInfResource);
+  if (0 == Size)
+  {
+    return FALSE;
+  }
+  VmwareInfMem = LoadResource(hAppInstance, VmwareInfResource);
+  if (NULL == VmwareInfMem)
+  {
+    return FALSE;
+  }
+  VmwareInfLocked = LockResource(VmwareInfMem);
+  if (NULL == VmwareInfLocked)
+  {
+    return FALSE;
+  }
+
+  BufferSize = GetTempPathW(sizeof(TempPath) / sizeof(TempPath[0]), TempPath);
+  if (0 == BufferSize || sizeof(TempPath) / sizeof(TempPath[0]) < BufferSize)
+  {
+    return FALSE;
+  }
+  if (0 == GetTempFileNameW(TempPath, L"vmx", 0, TempFileName))
+  {
+    return FALSE;
+  }
+
+  TempFile = CreateFileW(TempFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL, NULL);
+  if (INVALID_HANDLE_VALUE == TempFile)
+  {
+    DeleteFile(TempFileName);
+    return FALSE;
+  }
+  if (! WriteFile(TempFile, VmwareInfLocked, Size, &Written, NULL) ||
+      Written != Size)
+  {
+    CloseHandle(TempFile);
+    DeleteFile(TempFileName);
+    return FALSE;
+  }
+  CloseHandle(TempFile);
+
+  wcscpy(CmdLine, L"DefaultInstall 128 ");
+  wcscat(CmdLine, TempFileName);
+  InstallHinfSectionW(NULL, NULL, CmdLine, 0);
+
+  DeleteFile(TempFileName);
+
   return TRUE;
 }
 
@@ -379,11 +490,17 @@ PageWelcomeProc(
   LPARAM lParam
 )
 {
+  LPNMHDR pnmh = (LPNMHDR)lParam;
   switch(uMsg)
   {
     case WM_NOTIFY:
     {
-      LPNMHDR pnmh = (LPNMHDR)lParam;
+      HWND hwndControl;
+
+      /* Center the wizard window */
+      hwndControl = GetParent(hwndDlg);
+      CenterWindow (hwndControl);
+
       switch(pnmh->code)
       {
         case PSN_SETACTIVE:
@@ -395,8 +512,17 @@ PageWelcomeProc(
         {
           if(DriverFilesFound)
           {
-            if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
+            if(!AddVmwareRegistryEntries())
             {
+              WCHAR Msg[1024];
+              LoadString(hAppInstance, IDS_FAILEDTOADDREGENTRIES, Msg, sizeof(Msg) / sizeof(WCHAR));
+              MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
+              SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE);
+              return TRUE;
+            }
+            if(!EnableVmwareDriver(TRUE, TRUE, TRUE))
+            {
+
               WCHAR Msg[1024];
               LoadString(hAppInstance, IDS_FAILEDTOACTIVATEDRIVER, Msg, sizeof(Msg) / sizeof(WCHAR));
               MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
@@ -467,10 +593,10 @@ InstInstallationThread(LPVOID lpParameter)
   HANDLE hThread;
   BOOL DriveAvailable;
   int DrivesTested = 0;
-  
+
   if(AbortInstall != 0) goto done;
   PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_SEARCHINGFORCDROM, 0);
-  
+
   while(AbortInstall == 0)
   {
     Sleep(500);
@@ -486,37 +612,42 @@ InstInstallationThread(LPVOID lpParameter)
 
   if(AbortInstall != 0) goto done;
   PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_COPYINGFILES, 0);
-  
+
   if(AbortInstall != 0) goto done;
   if(!InstallFile(DestinationPath, vmx_fb))
   {
     PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
     goto cleanup;
   }
-  
+
   Sleep(250);
-  
+
   if(AbortInstall != 0) goto done;
   if(!InstallFile(DestinationPath, vmx_mode))
   {
     PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
     goto cleanup;
   }
-  
+
   Sleep(250);
-  
+
   if(AbortInstall != 0) goto done;
   if(!InstallFile(DestinationDriversPath, vmx_svga))
   {
     PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
     goto cleanup;
   }
-  
+
   Sleep(250);
 
   if(AbortInstall != 0) goto done;
   PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_ENABLINGDRIVER, 0);
-  if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
+  if(!AddVmwareRegistryEntries())
+  {
+    PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOADDREGENTRIES, 0);
+    goto cleanup;
+  }
+  if(!EnableVmwareDriver(TRUE, TRUE, TRUE))
   {
     PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOACTIVATEDRIVER, 0);
     goto cleanup;
@@ -534,7 +665,7 @@ done:
       SendMessage(hInstallationNotifyWnd, WM_INSTABORT, 0, 0);
       break;
   }
-  
+
 cleanup:
   hThread = (HANDLE)InterlockedExchange((LONG*)&hInstallationThread, 0);
   if(hThread != NULL)
@@ -670,7 +801,7 @@ FillComboBox(HWND Dlg, int idComboBox, int From, int To)
 {
   int i;
   WCHAR Text[256];
-  
+
   for(i = From; i <= To; i++)
   {
     if(LoadString(hAppInstance, i, Text, 255) > 0)
@@ -696,13 +827,14 @@ PageConfigProc(
   LPARAM lParam
 )
 {
+  LPNMHDR pnmh = (LPNMHDR)lParam;
   switch(uMsg)
   {
     case WM_INITDIALOG:
     {
       DWORD ResX = 0, ResY = 0, ColDepth = 0;
       int cbSel;
-      
+
       FillComboBox(hwndDlg, IDC_COLORQUALITY, 10001, 10003);
       if(LoadResolutionSettings(&ResX, &ResY, &ColDepth))
       {
@@ -728,7 +860,12 @@ PageConfigProc(
     }
     case WM_NOTIFY:
     {
-      LPNMHDR pnmh = (LPNMHDR)lParam;
+      HWND hwndControl;
+
+      /* Center the wizard window */
+      hwndControl = GetParent(hwndDlg);
+      CenterWindow (hwndControl);
+
       switch(pnmh->code)
       {
         case PSN_SETACTIVE:
@@ -776,7 +913,7 @@ PageConfigProc(
               break;
             }
           }
-          
+
           switch(SendDlgItemMessage(hwndDlg, IDC_COLORQUALITY, CB_GETCURSEL, 0, 0))
           {
             case 0:
@@ -789,7 +926,7 @@ PageConfigProc(
               cd = 32;
               break;
           }
-          
+
           SaveResolutionSettings(rx, ry, cd);
           break;
         }
@@ -831,7 +968,7 @@ PageChooseActionProc(
         {
           static ULONG SelPage[4] = {IDD_CONFIG, IDD_SELECTDRIVER, IDD_SELECTDRIVER, IDD_CHOOSEACTION};
           int i;
-          
+
           for(i = IDC_CONFIGSETTINGS; i <= IDC_UNINSTALL; i++)
           {
             if(SendDlgItemMessage(hwndDlg, i, BM_GETCHECK, 0, 0) == BST_CHECKED)
@@ -839,9 +976,9 @@ PageChooseActionProc(
               break;
             }
           }
-          
+
           UninstallDriver = (i == IDC_UNINSTALL);
-          
+
           SetWindowLong(hwndDlg, DWL_MSGRESULT, SelPage[i - IDC_CONFIGSETTINGS]);
           return TRUE;
         }
@@ -897,7 +1034,7 @@ PageSelectDriverProc(
           }
           ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
           if(!EnableVmwareDriver(ActivateVBE,
-                                 !ActivateVBE,
+                                 TRUE,
                                  FALSE))
           {
             WCHAR Msg[1024];
@@ -946,7 +1083,7 @@ PageDoUninstallProc(
           if(UninstallDriver)
           {
             if(!EnableVmwareDriver(ActivateVBE,
-                                   !ActivateVBE,
+                                   TRUE,
                                    FALSE))
             {
               WCHAR Msg[1024];
@@ -969,61 +1106,123 @@ PageDoUninstallProc(
 static LONG
 CreateWizard(VOID)
 {
-  PROPSHEETPAGE psp[8];
   PROPSHEETHEADER psh;
+  HPROPSHEETPAGE ahpsp[8];
+  PROPSHEETPAGE psp;
   WCHAR Caption[1024];
-  
+
   LoadString(hAppInstance, IDS_WIZARD_NAME, Caption, sizeof(Caption) / sizeof(TCHAR));
-  
-  ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
+
+  /* Create the Welcome page */
+  ZeroMemory (&psp, sizeof(PROPSHEETPAGE));
+  psp.dwSize = sizeof(PROPSHEETPAGE);
+  psp.dwFlags = PSP_DEFAULT | PSP_HIDEHEADER;
+  psp.hInstance = hAppInstance;
+  psp.pfnDlgProc = PageWelcomeProc;
+  psp.pszTemplate = MAKEINTRESOURCE(IDD_WELCOMEPAGE);
+  ahpsp[0] = CreatePropertySheetPage(&psp);
+
+  /* Create the INSERT_VMWARE_TOOLS page */
+  psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
+  psp.pszHeaderTitle = MAKEINTRESOURCE(IDD_INSERT_VMWARE_TOOLSTITLE);
+  psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDD_INSERT_VMWARE_TOOLSSUBTITLE);
+  psp.pszTemplate = MAKEINTRESOURCE(IDD_INSERT_VMWARE_TOOLS);
+  psp.pfnDlgProc = PageInsertDiscProc;
+  ahpsp[1] = CreatePropertySheetPage(&psp);
+
+  /* Create the INSTALLING_VMWARE_TOOLS page */
+  psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
+  psp.pszHeaderTitle = MAKEINTRESOURCE(IDD_INSTALLING_VMWARE_TOOLSTITLE);
+  psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDD_INSTALLING_VMWARE_TOOLSSUBTITLE);
+  psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLING_VMWARE_TOOLS);
+  psp.pfnDlgProc = PageInstallingProc;
+  ahpsp[2] = CreatePropertySheetPage(&psp);
+
+  /* Create the CONFIG page */
+  psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
+  psp.pszHeaderTitle = MAKEINTRESOURCE(IDD_CONFIGTITLE);
+  psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDD_CONFIGSUBTITLE);
+  psp.pfnDlgProc = PageConfigProc;
+  psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG);
+  ahpsp[3] = CreatePropertySheetPage(&psp);
+
+  /* Create the INSTALLATION_FAILED page */
+  psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
+  psp.pszHeaderTitle = MAKEINTRESOURCE(IDD_INSTALLATION_FAILEDTITLE);
+  psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDD_INSTALLATION_FAILEDSUBTITLE);
+  psp.pfnDlgProc = PageInstallFailedProc;
+  psp.pszTemplate = MAKEINTRESOURCE(IDD_INSTALLATION_FAILED);
+  ahpsp[4] = CreatePropertySheetPage(&psp);
+
+  /* Create the CHOOSEACTION page */
+  psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
+  psp.pszHeaderTitle = MAKEINTRESOURCE(IDD_CHOOSEACTIONTITLE);
+  psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDD_CHOOSEACTIONSUBTITLE);
+  psp.pfnDlgProc = PageChooseActionProc;
+  psp.pszTemplate = MAKEINTRESOURCE(IDD_CHOOSEACTION);
+  ahpsp[5] = CreatePropertySheetPage(&psp);
+
+  /* Create the SELECTDRIVER page */
+  psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
+  psp.pszHeaderTitle = MAKEINTRESOURCE(IDD_SELECTDRIVERTITLE);
+  psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDD_SELECTDRIVERSUBTITLE);
+  psp.pfnDlgProc = PageSelectDriverProc;
+  psp.pszTemplate = MAKEINTRESOURCE(IDD_SELECTDRIVER);
+  ahpsp[6] = CreatePropertySheetPage(&psp);
+
+  /* Create the DOUNINSTALL page */
+  psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
+  psp.pszHeaderTitle = MAKEINTRESOURCE(IDD_DOUNINSTALLTITLE);
+  psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDD_DOUNINSTALLSUBTITLE);
+  psp.pfnDlgProc = PageDoUninstallProc;
+  psp.pszTemplate = MAKEINTRESOURCE(IDD_DOUNINSTALL);
+  ahpsp[7] = CreatePropertySheetPage(&psp);
+
+  /* Create the property sheet */
   psh.dwSize = sizeof(PROPSHEETHEADER);
-  psh.dwFlags =  PSH_PROPSHEETPAGE | PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
-  psh.hwndParent = NULL;
+  psh.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
   psh.hInstance = hAppInstance;
-  psh.hIcon = 0;
-  psh.pszCaption = Caption;
+  psh.hwndParent = NULL;
   psh.nPages = 7;
   psh.nStartPage = (StartVMwConfigWizard ? 5 : 0);
-  psh.ppsp = psp;
+  psh.phpage = ahpsp;
   psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
   psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
-  
-  InitPropSheetPage(&psp[0], IDD_WELCOMEPAGE, PSP_HIDEHEADER, PageWelcomeProc);
-  InitPropSheetPage(&psp[1], IDD_INSERT_VMWARE_TOOLS, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInsertDiscProc);
-  InitPropSheetPage(&psp[2], IDD_INSTALLING_VMWARE_TOOLS, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInstallingProc);
-  InitPropSheetPage(&psp[3], IDD_CONFIG, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageConfigProc);
-  InitPropSheetPage(&psp[4], IDD_INSTALLATION_FAILED, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInstallFailedProc);
-  InitPropSheetPage(&psp[5], IDD_CHOOSEACTION, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageChooseActionProc);
-  InitPropSheetPage(&psp[6], IDD_SELECTDRIVER, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageSelectDriverProc);
-  InitPropSheetPage(&psp[7], IDD_DOUNINSTALL, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageDoUninstallProc);
-  
+
+  /* Display the wizard */
   return (LONG)(PropertySheet(&psh) != -1);
 }
 
-int WINAPI 
+int WINAPI
 WinMain(HINSTANCE hInstance,
        HINSTANCE hPrevInstance,
        LPSTR lpszCmdLine,
        int nCmdShow)
 {
-  LPTOP_LEVEL_EXCEPTION_FILTER OldHandler;
+
+  PVOID ExceptionHandler;
   int Version;
   WCHAR *lc;
-  
+
   hAppInstance = hInstance;
 
-  /* Setup our exception "handler" ;-) */
-  OldHandler = SetUnhandledExceptionFilter(ExceptionHandler);
-  
+  /* Setup a vectored exception handler to protect the detection. Don't use SEH
+     here so we notice the next time someone removes support for vectored
+     exception handling from ros... */
+  if (!(ExceptionHandler = AddVectoredExceptionHandler(0,
+                                                       VectoredExceptionHandler)))
+  {
+    return 1;
+  }
+
   if(!DetectVMware(&Version))
   {
-    ExitProcess(1);
     return 1;
   }
 
-  /* restore the exception handler */
-  SetUnhandledExceptionFilter(OldHandler);
-  
+  /* unregister the handler */
+  RemoveVectoredExceptionHandler(ExceptionHandler);
+
   lc = DestinationPath;
   lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
   if(lc >= DestinationPath && *lc != L'\\')
@@ -1033,18 +1232,18 @@ WinMain(HINSTANCE hInstance,
   DestinationDriversPath[0] = L'\0';
   wcscat(DestinationDriversPath, DestinationPath);
   wcscat(DestinationDriversPath, L"drivers\\");
-  
+
   SetCurrentDirectory(DestinationPath);
-  
+
   DriverFilesFound = FileExists(DestinationPath, vmx_fb) &&
                      FileExists(DestinationPath, vmx_mode) &&
                      FileExists(DestinationDriversPath, vmx_svga);
-  
+
   StartVMwConfigWizard = DriverFilesFound && IsVmwSVGAEnabled();
-  
+
   /* Show the wizard */
   CreateWizard();
-  
+
   return 2;
 }