install the registry keys before enabling the driver
[reactos.git] / reactos / subsys / system / vmwinst / vmwinst.c
index 3af6cbd..74b5397 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;
 
@@ -58,7 +63,7 @@ LONG WINAPI ExceptionHandler(LPEXCEPTION_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);
+  ExitProcess(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION);
   return EXCEPTION_CONTINUE_EXECUTION;
 }
 
@@ -66,10 +71,10 @@ 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! */
   __asm__ __volatile__("inl  %%dx, %%eax"
@@ -81,7 +86,7 @@ DetectVMware(int *Version)
     *Version = ver;
     return TRUE;
   }
-  
+
   return FALSE;
 }
 
@@ -110,13 +115,13 @@ 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;
@@ -127,11 +132,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 +170,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 +189,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 +201,7 @@ InstallFile(WCHAR *Destination, WCHAR *File)
       return FALSE;
     }
   }
-  
+
   CloseHandle(SourceFileHandle);
   CloseHandle(DestFileHandle);
   return TRUE;
@@ -184,7 +213,7 @@ IsVMwareCDInDrive(WCHAR *Drv)
 {
   static WCHAR Drive[4] = L"X:\\";
   WCHAR Current;
-  
+
   *Drv = L'\0';
   for(Current = 'C'; Current <= 'Z'; Current++)
   {
@@ -204,7 +233,7 @@ IsVMwareCDInDrive(WCHAR *Drv)
         SetCurrentDirectory(DestinationPath);
         continue;
       }
-      
+
       if(FileExists(SrcPath, vmx_fb) &&
          FileExists(SrcPath, vmx_mode) &&
          FileExists(SrcPath, vmx_svga))
@@ -216,7 +245,7 @@ IsVMwareCDInDrive(WCHAR *Drv)
     }
 #endif
   }
-  
+
   return FALSE;
 }
 
@@ -225,9 +254,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 +267,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 +291,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 +304,7 @@ IsVmwSVGAEnabled(VOID)
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   RegCloseKey(hReg);
   return (Value == 1);
 }
@@ -286,10 +315,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 +327,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 +349,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 +361,7 @@ EnableDriver(WCHAR *Key, BOOL Enable)
     RegCloseKey(hReg);
     return FALSE;
   }
-  
+
   RegCloseKey(hReg);
   return TRUE;
 }
@@ -353,7 +382,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;
 }
 
@@ -383,6 +485,12 @@ PageWelcomeProc(
   {
     case WM_NOTIFY:
     {
+      HWND hwndControl;
+
+      /* Center the wizard window */
+      hwndControl = GetParent(hwndDlg);
+      CenterWindow (hwndControl);
+
       LPNMHDR pnmh = (LPNMHDR)lParam;
       switch(pnmh->code)
       {
@@ -395,8 +503,10 @@ PageWelcomeProc(
         {
           if(DriverFilesFound)
           {
-            if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
+            /* FIXME - check for existing registry entries! */
+            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 +577,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 +596,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 +649,7 @@ done:
       SendMessage(hInstallationNotifyWnd, WM_INSTABORT, 0, 0);
       break;
   }
-  
+
 cleanup:
   hThread = (HANDLE)InterlockedExchange((LONG*)&hInstallationThread, 0);
   if(hThread != NULL)
@@ -670,7 +785,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)
@@ -702,7 +817,7 @@ PageConfigProc(
     {
       DWORD ResX = 0, ResY = 0, ColDepth = 0;
       int cbSel;
-      
+
       FillComboBox(hwndDlg, IDC_COLORQUALITY, 10001, 10003);
       if(LoadResolutionSettings(&ResX, &ResY, &ColDepth))
       {
@@ -728,6 +843,12 @@ PageConfigProc(
     }
     case WM_NOTIFY:
     {
+      HWND hwndControl;
+
+      /* Center the wizard window */
+      hwndControl = GetParent(hwndDlg);
+      CenterWindow (hwndControl);
+
       LPNMHDR pnmh = (LPNMHDR)lParam;
       switch(pnmh->code)
       {
@@ -776,7 +897,7 @@ PageConfigProc(
               break;
             }
           }
-          
+
           switch(SendDlgItemMessage(hwndDlg, IDC_COLORQUALITY, CB_GETCURSEL, 0, 0))
           {
             case 0:
@@ -789,7 +910,7 @@ PageConfigProc(
               cd = 32;
               break;
           }
-          
+
           SaveResolutionSettings(rx, ry, cd);
           break;
         }
@@ -831,7 +952,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 +960,9 @@ PageChooseActionProc(
               break;
             }
           }
-          
+
           UninstallDriver = (i == IDC_UNINSTALL);
-          
+
           SetWindowLong(hwndDlg, DWL_MSGRESULT, SelPage[i - IDC_CONFIGSETTINGS]);
           return TRUE;
         }
@@ -897,7 +1018,7 @@ PageSelectDriverProc(
           }
           ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
           if(!EnableVmwareDriver(ActivateVBE,
-                                 !ActivateVBE,
+                                 TRUE,
                                  FALSE))
           {
             WCHAR Msg[1024];
@@ -946,7 +1067,7 @@ PageDoUninstallProc(
           if(UninstallDriver)
           {
             if(!EnableVmwareDriver(ActivateVBE,
-                                   !ActivateVBE,
+                                   TRUE,
                                    FALSE))
             {
               WCHAR Msg[1024];
@@ -969,52 +1090,109 @@ 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;
   int Version;
   WCHAR *lc;
-  
+
   hAppInstance = hInstance;
 
   /* Setup our exception "handler" ;-) */
   OldHandler = SetUnhandledExceptionFilter(ExceptionHandler);
-  
+
   if(!DetectVMware(&Version))
   {
     ExitProcess(1);
@@ -1023,7 +1201,7 @@ WinMain(HINSTANCE hInstance,
 
   /* restore the exception handler */
   SetUnhandledExceptionFilter(OldHandler);
-  
+
   lc = DestinationPath;
   lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
   if(lc >= DestinationPath && *lc != L'\\')
@@ -1033,18 +1211,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;
 }