reactos/base/setup/vmwinst/vmwinst.c
Timo Kreuzer 9ea495ba33 Create a branch for header work.
svn path=/branches/header-work/; revision=45691
2010-02-26 22:57:55 +00:00

1085 lines
31 KiB
C

/*
* ReactOS VMware(r) driver installation utility
* Copyright (C) 2004 ReactOS Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* VMware is a registered trademark of VMware, Inc.
*
* COPYRIGHT: See COPYING in the top level directory
* 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 <newdev.h>
#include <stdio.h>
#include <string.h>
#include <pseh/pseh2.h>
#include "vmwinst.h"
#include <debug.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 PathToVideoDrivers60[MAX_PATH+1] = L"X:\\program files\\VMWare\\VMWare Tools\\Drivers\\video\\2k\\32bit\\";
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];
static WCHAR *vmx_fb = L"vmx_fb.dll";
static WCHAR *vmx_mode = L"vmx_mode.dll";
static WCHAR *vmx_mode_v6 = L"vmx mode.dll";
static WCHAR *vmx_svga = L"vmx_svga.sys";
static WCHAR *SrcPath = PathToVideoDrivers45;
static HANDLE hInstallationThread = NULL;
static HWND hInstallationNotifyWnd = NULL;
static LONG AbortInstall = 0;
#define WM_INSTABORT (WM_USER + 2)
#define WM_INSTCOMPLETE (WM_USER + 3)
#define WM_INSTSTATUSUPDATE (WM_USER + 4)
/* Helper functions */
BOOL
DetectVMware(int *Version)
{
int magic, ver;
magic = 0;
ver = 0;
_SEH2_TRY
{
/* Try using a VMware I/O port. If not running in VMware this'll throw an
exception! */
#if defined(__GNUC__)
__asm__ __volatile__("inl %%dx, %%eax"
: "=a" (ver), "=b" (magic)
: "0" (0x564d5868), "d" (0x5658), "c" (0xa));
#elif defined(_MSC_VER)
__asm
{
push ebx
mov ecx, 0xa
mov edx, 0x5658
mov eax, 0x564d5868
in eax, dx
mov [ver], eax
mov [magic], ebx
pop ebx
}
#else
#error TODO
#endif
}
_SEH2_EXCEPT(_SEH2_GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
return FALSE;
}
_SEH2_END;
if(magic == 0x564d5868)
{
*Version = ver;
return TRUE;
}
return FALSE;
}
/* try to open the file */
static BOOL
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)
{
/* If it was a sharing violation the file must already exist */
return GetLastError() == ERROR_SHARING_VIOLATION;
}
if(GetFileSize(FileHandle, NULL) <= 0)
{
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);
}
/* Find the drive with the inserted VMware cd-rom */
static BOOL
IsVMwareCDInDrive(WCHAR *Drv)
{
static WCHAR Drive[4] = L"X:\\";
WCHAR Current;
*Drv = L'\0';
for(Current = 'C'; Current <= 'Z'; Current++)
{
Drive[0] = Current;
#if CHECKDRIVETYPE
if(GetDriveType(Drive) == DRIVE_CDROM)
{
#endif
PathToVideoDrivers60[0] = Current;
PathToVideoDrivers55[0] = Current;
PathToVideoDrivers40[0] = Current;
PathToVideoDrivers45[0] = Current;
if(SetCurrentDirectory(PathToVideoDrivers60))
SrcPath = PathToVideoDrivers60;
else if(SetCurrentDirectory(PathToVideoDrivers55))
SrcPath = PathToVideoDrivers55;
else if(SetCurrentDirectory(PathToVideoDrivers45))
SrcPath = PathToVideoDrivers45;
else if(SetCurrentDirectory(PathToVideoDrivers40))
SrcPath = PathToVideoDrivers40;
else
{
SetCurrentDirectory(DestinationPath);
continue;
}
if(FileExists(SrcPath, vmx_fb) &&
(FileExists(SrcPath, vmx_mode) || FileExists(SrcPath, vmx_mode_v6)) &&
FileExists(SrcPath, vmx_svga))
{
*Drv = Current;
return TRUE;
}
#if CHECKDRIVETYPE
}
#endif
}
return FALSE;
}
static BOOL
LoadResolutionSettings(DWORD *ResX, DWORD *ResY, DWORD *ColDepth)
{
HKEY hReg;
DWORD Type, Size = sizeof(DWORD);
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga\\Device0",
0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
{
DEVMODE CurrentDevMode;
/* If this key is absent, just get current settings */
memset(&CurrentDevMode, 0, sizeof(CurrentDevMode));
CurrentDevMode.dmSize = sizeof(CurrentDevMode);
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &CurrentDevMode) == TRUE)
{
*ColDepth = CurrentDevMode.dmBitsPerPel;
*ResX = CurrentDevMode.dmPelsWidth;
*ResY = CurrentDevMode.dmPelsHeight;
return TRUE;
}
}
if(RegQueryValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, &Type, (BYTE*)ColDepth, &Size) != ERROR_SUCCESS ||
Type != REG_DWORD)
{
*ColDepth = 8;
Size = sizeof(DWORD);
}
if(RegQueryValueEx(hReg, L"DefaultSettings.XResolution", 0, &Type, (BYTE*)ResX, &Size) != ERROR_SUCCESS ||
Type != REG_DWORD)
{
*ResX = 640;
Size = sizeof(DWORD);
}
if(RegQueryValueEx(hReg, L"DefaultSettings.YResolution", 0, &Type, (BYTE*)ResY, &Size) != ERROR_SUCCESS ||
Type != REG_DWORD)
{
*ResY = 480;
}
RegCloseKey(hReg);
return TRUE;
}
static BOOL
IsVmwSVGAEnabled(VOID)
{
HKEY hReg;
DWORD Type, Size, Value;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga",
0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
{
return FALSE;
}
Size = sizeof(DWORD);
if(RegQueryValueEx(hReg, L"Start", 0, &Type, (BYTE*)&Value, &Size) != ERROR_SUCCESS ||
Type != REG_DWORD)
{
RegCloseKey(hReg);
return FALSE;
}
RegCloseKey(hReg);
return (Value == 1);
}
static BOOL
SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
{
HKEY hReg;
DWORD VFreq = 85;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga\\Device0",
0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS)
{
return FALSE;
}
if(RegSetValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, REG_DWORD, (BYTE*)&ColDepth, sizeof(DWORD)) != ERROR_SUCCESS)
{
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;
}
if(RegSetValueEx(hReg, L"DefaultSettings.VRefresh", 0, REG_DWORD, (BYTE*)&VFreq, sizeof(DWORD)) != ERROR_SUCCESS)
{
RegCloseKey(hReg);
return FALSE;
}
RegCloseKey(hReg);
return TRUE;
}
static BOOL
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;
}
if(RegSetValueEx(hReg, L"Start", 0, REG_DWORD, (BYTE*)&Value, sizeof(DWORD)) != ERROR_SUCCESS)
{
RegCloseKey(hReg);
return FALSE;
}
RegCloseKey(hReg);
return TRUE;
}
/* Activate the vmware driver and deactivate the others */
static BOOL
EnableVmwareDriver(BOOL VBE, BOOL VGA, BOOL VMX)
{
if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\VBE", VBE))
{
return FALSE;
}
if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\vga", VGA))
{
return FALSE;
}
if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga", VMX))
{
return FALSE;
}
return TRUE;
}
/* GUI */
/* Property page dialog callback */
static INT_PTR CALLBACK
PageWelcomeProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch(uMsg)
{
case WM_NOTIFY:
{
HWND hwndControl;
/* Center the wizard window */
hwndControl = GetParent(hwndDlg);
CenterWindow (hwndControl);
switch(pnmh->code)
{
case PSN_SETACTIVE:
{
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
break;
}
case PSN_WIZNEXT:
{
if(DriverFilesFound)
{
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_CONFIG);
return TRUE;
}
break;
}
}
break;
}
}
return FALSE;
}
/* Property page dialog callback */
static INT_PTR CALLBACK
PageInsertDiscProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_NOTIFY:
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch(pnmh->code)
{
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
break;
case PSN_WIZNEXT:
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_INSTALLING_VMWARE_TOOLS);
break;
}
break;
}
}
return FALSE;
}
static VOID
InstTerminateInstaller(BOOL Wait)
{
if(hInstallationThread != NULL)
{
if(Wait)
{
InterlockedExchange((LONG*)&AbortInstall, 2);
WaitForSingleObject(hInstallationThread, INFINITE);
}
else
{
InterlockedExchange((LONG*)&AbortInstall, 1);
}
}
}
static DWORD WINAPI
InstInstallationThread(LPVOID lpParameter)
{
HANDLE hThread;
WCHAR InfFileName[1024];
BOOL DriveAvailable;
int DrivesTested = 0;
if(AbortInstall != 0) goto done;
PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_SEARCHINGFORCDROM, 0);
while(AbortInstall == 0)
{
Sleep(500);
DriveAvailable = IsVMwareCDInDrive(&CDDrive);
if(DriveAvailable)
break;
if(DrivesTested++ > 20)
{
PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOLOCATEDRIVERS, 0);
goto cleanup;
}
}
if(AbortInstall != 0) goto done;
PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_COPYINGFILES, 0);
wcscpy(InfFileName, SrcPath);
wcscat(InfFileName, L"vmx_svga.inf");
DPRINT1("Calling UpdateDriverForPlugAndPlayDevices()\n");
if (!UpdateDriverForPlugAndPlayDevices(
hInstallationNotifyWnd,
L"PCI\\VEN_15AD&DEV_0405&SUBSYS_040515AD&REV_00",
InfFileName,
0,
NULL))
{
AbortInstall = 1;
}
else
{
AbortInstall = 0;
}
done:
switch(AbortInstall)
{
case 0:
SendMessage(hInstallationNotifyWnd, WM_INSTCOMPLETE, 0, 0);
break;
case 1:
SendMessage(hInstallationNotifyWnd, WM_INSTABORT, 0, 0);
break;
}
cleanup:
hThread = InterlockedExchangePointer((PVOID*)&hInstallationThread, 0);
if(hThread != NULL)
{
CloseHandle(hThread);
}
return 0;
}
static BOOL
InstStartInstallationThread(HWND hwndNotify)
{
if(hInstallationThread == NULL)
{
DWORD ThreadId;
hInstallationNotifyWnd = hwndNotify;
AbortInstall = 0;
hInstallationThread = CreateThread(NULL,
0,
InstInstallationThread,
NULL,
CREATE_SUSPENDED,
&ThreadId);
if(hInstallationThread == NULL)
{
return FALSE;
}
ResumeThread(hInstallationThread);
return TRUE;
}
return FALSE;
}
/* Property page dialog callback */
static INT_PTR CALLBACK
PageInstallingProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_NOTIFY:
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch(pnmh->code)
{
case PSN_SETACTIVE:
SetDlgItemText(hwndDlg, IDC_INSTALLINGSTATUS, L"");
SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, TRUE, 50);
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
InstStartInstallationThread(hwndDlg);
break;
case PSN_RESET:
InstTerminateInstaller(TRUE);
break;
case PSN_WIZBACK:
if(hInstallationThread != NULL)
{
PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
InstTerminateInstaller(FALSE);
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, -1);
return -1;
}
else
{
SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_INSERT_VMWARE_TOOLS);
}
break;
}
break;
}
case WM_INSTABORT:
/* go back in case we aborted the installation thread */
SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSERT_VMWARE_TOOLS);
if(wParam != 0)
{
WCHAR Msg[1024];
LoadString(hAppInstance, wParam, Msg, sizeof(Msg) / sizeof(WCHAR));
MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
}
break;
case WM_INSTCOMPLETE:
SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_CONFIG);
break;
case WM_INSTSTATUSUPDATE:
{
WCHAR Msg[1024];
LoadString(hAppInstance, wParam, Msg, sizeof(Msg) / sizeof(WCHAR));
SetDlgItemText(hwndDlg, IDC_INSTALLINGSTATUS, Msg);
break;
}
}
return FALSE;
}
/* Property page dialog callback */
static INT_PTR CALLBACK
PageInstallFailedProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_NOTIFY:
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch(pnmh->code)
{
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
break;
}
break;
}
}
return FALSE;
}
static void
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)
{
SendDlgItemMessage(Dlg, idComboBox, CB_ADDSTRING, 0, (LPARAM)Text);
}
}
}
typedef struct
{
int ControlID;
int ResX;
int ResY;
} MAPCTLRES;
/* Property page dialog callback */
static INT_PTR CALLBACK
PageConfigProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
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))
{
SendDlgItemMessage(hwndDlg, ResX + ResY, BM_SETCHECK, BST_CHECKED, 0);
switch(ColDepth)
{
case 8:
cbSel = 0;
break;
case 16:
cbSel = 1;
break;
case 32:
cbSel = 2;
break;
default:
cbSel = -1;
break;
}
SendDlgItemMessage(hwndDlg, IDC_COLORQUALITY, CB_SETCURSEL, cbSel, 0);
}
break;
}
case WM_NOTIFY:
{
HWND hwndControl;
/* Center the wizard window */
hwndControl = GetParent(hwndDlg);
CenterWindow (hwndControl);
switch(pnmh->code)
{
case PSN_SETACTIVE:
{
PropSheet_SetWizButtons(GetParent(hwndDlg), ((StartVMwConfigWizard || DriverFilesFound) ? PSWIZB_FINISH | PSWIZB_BACK : PSWIZB_FINISH));
break;
}
case PSN_WIZBACK:
{
if(StartVMwConfigWizard)
{
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
return TRUE;
}
if(DriverFilesFound)
{
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE);
return TRUE;
}
break;
}
case PSN_WIZFINISH:
{
DWORD rx = 800, ry = 600, cd = 32;
int i;
static MAPCTLRES Resolutions[11] = {
{540, 640, 480},
{1400, 800, 600},
{1792, 1024, 768},
{2016, 1152, 864},
{2240, 1280, 960},
{2304, 1280, 1024},
{2450, 1400, 1050},
{2800, 1600, 1200},
{3136, 1792, 1344},
{3248, 1856, 1392},
{3360, 1920, 1440}
};
for(i = 0; i < 11; i++)
{
if(SendDlgItemMessage(hwndDlg, Resolutions[i].ControlID, BM_GETCHECK, 0, 0) == BST_CHECKED)
{
rx = Resolutions[i].ResX;
ry = Resolutions[i].ResY;
break;
}
}
switch(SendDlgItemMessage(hwndDlg, IDC_COLORQUALITY, CB_GETCURSEL, 0, 0))
{
case 0:
cd = 8;
break;
case 1:
cd = 16;
break;
case 2:
cd = 32;
break;
}
SaveResolutionSettings(rx, ry, cd);
break;
}
}
break;
}
}
return FALSE;
}
/* Property page dialog callback */
static INT_PTR CALLBACK
PageChooseActionProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg, IDC_CONFIGSETTINGS, BM_SETCHECK, BST_CHECKED, 0);
break;
case WM_NOTIFY:
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch(pnmh->code)
{
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
break;
case PSN_WIZBACK:
{
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
return TRUE;
}
case PSN_WIZNEXT:
{
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)
{
break;
}
}
UninstallDriver = (i == IDC_UNINSTALL);
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, SelPage[i - IDC_CONFIGSETTINGS]);
return TRUE;
}
}
break;
}
}
return FALSE;
}
/* Property page dialog callback */
static INT_PTR CALLBACK
PageSelectDriverProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg, IDC_VBE, BM_SETCHECK, BST_CHECKED, 0);
break;
case WM_NOTIFY:
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch(pnmh->code)
{
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), (UninstallDriver ? PSWIZB_NEXT | PSWIZB_BACK : PSWIZB_BACK | PSWIZB_FINISH));
break;
case PSN_WIZBACK:
{
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
return TRUE;
}
case PSN_WIZNEXT:
{
ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
if(UninstallDriver)
{
return FALSE;
}
return TRUE;
}
case PSN_WIZFINISH:
{
if(UninstallDriver)
{
return FALSE;
}
ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
if(!EnableVmwareDriver(ActivateVBE,
TRUE,
FALSE))
{
WCHAR Msg[1024];
LoadString(hAppInstance, (ActivateVBE ? IDS_FAILEDTOSELVBEDRIVER : IDS_FAILEDTOSELVGADRIVER), Msg, sizeof(Msg) / sizeof(WCHAR));
MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_SELECTDRIVER);
return TRUE;
}
break;
}
}
break;
}
}
return FALSE;
}
static VOID
ShowUninstNotice(HWND Owner)
{
WCHAR Msg[1024];
LoadString(hAppInstance, IDS_UNINSTNOTICE, Msg, sizeof(Msg) / sizeof(WCHAR));
MessageBox(Owner, Msg, NULL, MB_ICONINFORMATION);
}
static INT_PTR CALLBACK
PageDoUninstallProc(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_NOTIFY:
{
LPNMHDR pnmh = (LPNMHDR)lParam;
switch(pnmh->code)
{
case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
break;
case PSN_WIZFINISH:
{
if(UninstallDriver)
{
if(!EnableVmwareDriver(ActivateVBE,
TRUE,
FALSE))
{
WCHAR Msg[1024];
LoadString(hAppInstance, (ActivateVBE ? IDS_FAILEDTOSELVBEDRIVER : IDS_FAILEDTOSELVGADRIVER), Msg, sizeof(Msg) / sizeof(WCHAR));
MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
SetWindowLongPtr(hwndDlg, DWL_MSGRESULT, IDD_SELECTDRIVER);
return TRUE;
}
ShowUninstNotice(GetParent(hwndDlg));
}
return FALSE;
}
}
break;
}
}
return FALSE;
}
static LONG
CreateWizard(VOID)
{
PROPSHEETHEADER psh;
HPROPSHEETPAGE ahpsp[8];
PROPSHEETPAGE psp;
WCHAR Caption[1024];
LoadString(hAppInstance, IDS_WIZARD_NAME, Caption, sizeof(Caption) / sizeof(TCHAR));
/* 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_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
psh.hInstance = hAppInstance;
psh.hwndParent = NULL;
psh.nPages = 7;
psh.nStartPage = (StartVMwConfigWizard ? 5 : 0);
psh.phpage = ahpsp;
psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
/* Display the wizard */
return (LONG)(PropertySheet(&psh) != -1);
}
int WINAPI
wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpszCmdLine,
int nCmdShow)
{
int Version;
WCHAR *lc;
hAppInstance = hInstance;
if(!DetectVMware(&Version))
{
return 1;
}
lc = DestinationPath;
lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
if(lc >= DestinationPath && *lc != L'\\')
{
wcscat(DestinationPath, L"\\");
}
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;
}