enabled the Wizard97 style
[reactos.git] / reactos / subsys / system / vmwinst / vmwinst.c
1 /*
2 * ReactOS VMware(r) driver installation utility
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * VMware is a registered trademark of VMware, Inc.
20 */
21 /* $Id: vmwinst.c,v 1.10 2004/09/24 20:18:15 weiden Exp $
22 *
23 * COPYRIGHT: See COPYING in the top level directory
24 * PROJECT: ReactOS VMware(r) driver installation utility
25 * FILE: subsys/system/vmwinst/vmwinst.c
26 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
27 */
28 #include <windows.h>
29 #include <commctrl.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include "vmwinst.h"
33
34 HINSTANCE hAppInstance;
35 BOOL StartVMwConfigWizard, DriverFilesFound, ActivateVBE = FALSE, UninstallDriver = FALSE;
36
37 static WCHAR DestinationDriversPath[MAX_PATH+1];
38 static WCHAR CDDrive = L'\0';
39 static WCHAR PathToVideoDrivers45[MAX_PATH+1] = L"X:\\program files\\VMware\\VMware Tools\\Drivers\\video\\winnt2k\\";
40 static WCHAR PathToVideoDrivers40[MAX_PATH+1] = L"X:\\video\\winnt2k\\";
41 static WCHAR DestinationPath[MAX_PATH+1];
42 static WCHAR *vmx_fb = L"vmx_fb.dll";
43 static WCHAR *vmx_mode = L"vmx_mode.dll";
44 static WCHAR *vmx_svga = L"vmx_svga.sys";
45
46 static WCHAR *SrcPath = PathToVideoDrivers45;
47
48 static HANDLE hInstallationThread = NULL;
49 static HWND hInstallationNotifyWnd = NULL;
50 static LONG AbortInstall = 0;
51 #define WM_INSTABORT (WM_USER + 2)
52 #define WM_INSTCOMPLETE (WM_USER + 3)
53 #define WM_INSTSTATUSUPDATE (WM_USER + 4)
54
55 /* Helper functions */
56
57 LONG WINAPI ExceptionHandler(LPEXCEPTION_POINTERS ExceptionInfo)
58 {
59 /* This is rude, but i don't know how to continue execution properly, that's why
60 we just exit here when we're not running inside of VMware */
61 ExitProcess(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION);
62 return EXCEPTION_CONTINUE_EXECUTION;
63 }
64
65 BOOL
66 DetectVMware(int *Version)
67 {
68 int magic, ver;
69
70 magic = 0;
71 ver = 0;
72
73 return TRUE;
74 /* Try using a VMware I/O port. If not running in VMware this'll throw an
75 exception! */
76 __asm__ __volatile__("inl %%dx, %%eax"
77 : "=a" (ver), "=b" (magic)
78 : "0" (0x564d5868), "d" (0x5658), "c" (0xa));
79
80 if(magic == 0x564d5868)
81 {
82 *Version = ver;
83 return TRUE;
84 }
85
86 return FALSE;
87 }
88
89 BOOL
90 ProcessMessage(void)
91 {
92 MSG msg;
93 if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
94 {
95 TranslateMessage(&msg);
96 DispatchMessage(&msg);
97 return TRUE;
98 }
99 return FALSE;
100 }
101
102 void
103 ProcessMessages(void)
104 {
105 while(ProcessMessage());
106 }
107
108 /* try to open the file */
109 BOOL
110 FileExists(WCHAR *Path, WCHAR *File)
111 {
112 WCHAR FileName[MAX_PATH + 1];
113 HANDLE FileHandle;
114
115 FileName[0] = L'\0';
116 wcscat(FileName, Path);
117 wcscat(FileName, File);
118
119 FileHandle = CreateFile(FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
120
121 if(FileHandle == INVALID_HANDLE_VALUE)
122 {
123 return FALSE;
124 }
125
126 if(GetFileSize(FileHandle, NULL) <= 0)
127 {
128 CloseHandle(FileHandle);
129 return FALSE;
130 }
131
132 CloseHandle(FileHandle);
133 return TRUE;
134 }
135
136 /* Copy file */
137 BOOL
138 InstallFile(WCHAR *Destination, WCHAR *File)
139 {
140 static char Buffer[1024];
141 WCHAR SourceFileName[MAX_PATH + 1];
142 WCHAR DestFileName[MAX_PATH + 1];
143 HANDLE SourceFileHandle, DestFileHandle;
144 DWORD DataRead, DataWritten;
145
146 SourceFileName[0] = L'\0';
147 DestFileName[0] = L'\0';
148 wcscat(SourceFileName, SrcPath);
149 wcscat(SourceFileName, File);
150 wcscat(DestFileName, Destination);
151 wcscat(DestFileName, File);
152
153 SourceFileHandle = CreateFile(SourceFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
154 if(SourceFileHandle == INVALID_HANDLE_VALUE)
155 {
156 return FALSE;
157 }
158 DestFileHandle = CreateFile(DestFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
159 if(DestFileHandle == INVALID_HANDLE_VALUE)
160 {
161 CloseHandle(SourceFileHandle);
162 return FALSE;
163 }
164
165 while(ReadFile(SourceFileHandle, Buffer, sizeof(Buffer), &DataRead, NULL) && DataRead > 0)
166 {
167 if(!WriteFile(DestFileHandle, Buffer, DataRead, &DataWritten, NULL) ||
168 DataRead != DataWritten)
169 {
170 CloseHandle(SourceFileHandle);
171 CloseHandle(DestFileHandle);
172 DeleteFile(DestFileName);
173 return FALSE;
174 }
175 }
176
177 CloseHandle(SourceFileHandle);
178 CloseHandle(DestFileHandle);
179 return TRUE;
180 }
181
182 /* Find the drive with the inserted VMware cd-rom */
183 BOOL
184 IsVMwareCDInDrive(WCHAR *Drv)
185 {
186 static WCHAR Drive[4] = L"X:\\";
187 WCHAR Current;
188
189 *Drv = L'\0';
190 for(Current = 'C'; Current <= 'Z'; Current++)
191 {
192 Drive[0] = Current;
193 #if CHECKDRIVETYPE
194 if(GetDriveType(Drive) == DRIVE_CDROM)
195 {
196 #endif
197 PathToVideoDrivers40[0] = Current;
198 PathToVideoDrivers45[0] = Current;
199 if(SetCurrentDirectory(PathToVideoDrivers45))
200 SrcPath = PathToVideoDrivers45;
201 else if(SetCurrentDirectory(PathToVideoDrivers40))
202 SrcPath = PathToVideoDrivers40;
203 else
204 {
205 SetCurrentDirectory(DestinationPath);
206 continue;
207 }
208
209 if(FileExists(SrcPath, vmx_fb) &&
210 FileExists(SrcPath, vmx_mode) &&
211 FileExists(SrcPath, vmx_svga))
212 {
213 *Drv = Current;
214 return TRUE;
215 }
216 #if CHECKDRIVETYPE
217 }
218 #endif
219 }
220
221 return FALSE;
222 }
223
224 BOOL
225 LoadResolutionSettings(DWORD *ResX, DWORD *ResY, DWORD *ColDepth)
226 {
227 HKEY hReg;
228 DWORD Type, Size;
229
230 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
231 L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0",
232 0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
233 {
234 return FALSE;
235 }
236 if(RegQueryValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, &Type, (BYTE*)ColDepth, &Size) != ERROR_SUCCESS ||
237 Type != REG_DWORD)
238 {
239 RegCloseKey(hReg);
240 return FALSE;
241 }
242
243 if(RegQueryValueEx(hReg, L"DefaultSettings.XResolution", 0, &Type, (BYTE*)ResX, &Size) != ERROR_SUCCESS ||
244 Type != REG_DWORD)
245 {
246 RegCloseKey(hReg);
247 return FALSE;
248 }
249
250 if(RegQueryValueEx(hReg, L"DefaultSettings.YResolution", 0, &Type, (BYTE*)ResY, &Size) != ERROR_SUCCESS ||
251 Type != REG_DWORD)
252 {
253 RegCloseKey(hReg);
254 return FALSE;
255 }
256
257 RegCloseKey(hReg);
258 return TRUE;
259 }
260
261 BOOL
262 IsVmwSVGAEnabled(VOID)
263 {
264 HKEY hReg;
265 DWORD Type, Size, Value;
266
267 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
268 L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga",
269 0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
270 {
271 return FALSE;
272 }
273 if(RegQueryValueEx(hReg, L"Start", 0, &Type, (BYTE*)&Value, &Size) != ERROR_SUCCESS ||
274 Type != REG_DWORD)
275 {
276 RegCloseKey(hReg);
277 return FALSE;
278 }
279
280 RegCloseKey(hReg);
281 return (Value == 1);
282 }
283
284 BOOL
285 SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
286 {
287 HKEY hReg;
288
289 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
290 L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0",
291 0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
292 {
293 return FALSE;
294 }
295 if(RegSetValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, REG_DWORD, (BYTE*)&ColDepth, sizeof(DWORD)) != ERROR_SUCCESS)
296 {
297 RegCloseKey(hReg);
298 return FALSE;
299 }
300
301 if(RegSetValueEx(hReg, L"DefaultSettings.XResolution", 0, REG_DWORD, (BYTE*)&ResX, sizeof(DWORD)) != ERROR_SUCCESS)
302 {
303 RegCloseKey(hReg);
304 return FALSE;
305 }
306
307 if(RegSetValueEx(hReg, L"DefaultSettings.YResolution", 0, REG_DWORD, (BYTE*)&ResY, sizeof(DWORD)) != ERROR_SUCCESS)
308 {
309 RegCloseKey(hReg);
310 return FALSE;
311 }
312
313 RegCloseKey(hReg);
314 return TRUE;
315 }
316
317 BOOL
318 EnableDriver(WCHAR *Key, BOOL Enable)
319 {
320 DWORD Value;
321 HKEY hReg;
322
323 Value = (Enable ? 1 : 4);
324
325 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key, 0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS)
326 {
327 return FALSE;
328 }
329 if(RegSetValueEx(hReg, L"Start", 0, REG_DWORD, (BYTE*)&Value, sizeof(DWORD)) != ERROR_SUCCESS)
330 {
331 RegCloseKey(hReg);
332 return FALSE;
333 }
334
335 RegCloseKey(hReg);
336 return TRUE;
337 }
338
339 /* Activate the vmware driver and deactivate the others */
340 BOOL
341 EnableVmwareDriver(BOOL VBE, BOOL VGA, BOOL VMX)
342 {
343 if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\VBE", VBE))
344 {
345 return FALSE;
346 }
347 if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\vga", VGA))
348 {
349 return FALSE;
350 }
351 if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga", VMX))
352 {
353 return FALSE;
354 }
355
356 return TRUE;
357 }
358
359 /* GUI */
360
361 void
362 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DWORD Flags, DLGPROC DlgProc)
363 {
364 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
365 psp->dwSize = sizeof(PROPSHEETPAGE);
366 psp->dwFlags = PSP_DEFAULT | Flags;
367 psp->hInstance = hAppInstance;
368 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
369 psp->pfnDlgProc = DlgProc;
370 }
371
372 /* Property page dialog callback */
373 int CALLBACK
374 PageWelcomeProc(
375 HWND hwndDlg,
376 UINT uMsg,
377 WPARAM wParam,
378 LPARAM lParam
379 )
380 {
381 switch(uMsg)
382 {
383 case WM_NOTIFY:
384 {
385 LPNMHDR pnmh = (LPNMHDR)lParam;
386 switch(pnmh->code)
387 {
388 case PSN_SETACTIVE:
389 {
390 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
391 break;
392 }
393 case PSN_WIZNEXT:
394 {
395 if(DriverFilesFound)
396 {
397 if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
398 {
399 WCHAR Msg[1024];
400 LoadString(hAppInstance, IDS_FAILEDTOACTIVATEDRIVER, Msg, sizeof(Msg) / sizeof(WCHAR));
401 MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
402 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE);
403 return TRUE;
404 }
405 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CONFIG);
406 return TRUE;
407 }
408 break;
409 }
410 }
411 break;
412 }
413 }
414 return FALSE;
415 }
416
417 /* Property page dialog callback */
418 int CALLBACK
419 PageInsertDiscProc(
420 HWND hwndDlg,
421 UINT uMsg,
422 WPARAM wParam,
423 LPARAM lParam
424 )
425 {
426 switch(uMsg)
427 {
428 case WM_NOTIFY:
429 {
430 LPNMHDR pnmh = (LPNMHDR)lParam;
431 switch(pnmh->code)
432 {
433 case PSN_SETACTIVE:
434 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
435 break;
436 case PSN_WIZNEXT:
437 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_INSTALLING_VMWARE_TOOLS);
438 break;
439 }
440 break;
441 }
442 }
443 return FALSE;
444 }
445
446 VOID
447 InstTerminateInstaller(BOOL Wait)
448 {
449 if(hInstallationThread != NULL)
450 {
451 if(Wait)
452 {
453 InterlockedExchange((LONG*)&AbortInstall, 2);
454 WaitForSingleObject(hInstallationThread, INFINITE);
455 }
456 else
457 {
458 InterlockedExchange((LONG*)&AbortInstall, 1);
459 }
460 }
461 }
462
463 DWORD STDCALL
464 InstInstallationThread(LPVOID lpParameter)
465 {
466 HANDLE hThread;
467 BOOL DriveAvailable;
468 int DrivesTested = 0;
469
470 if(AbortInstall != 0) goto done;
471 PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_SEARCHINGFORCDROM, 0);
472
473 while(AbortInstall == 0)
474 {
475 Sleep(500);
476 DriveAvailable = IsVMwareCDInDrive(&CDDrive);
477 if(DriveAvailable)
478 break;
479 if(DrivesTested++ > 20)
480 {
481 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOLOCATEDRIVERS, 0);
482 goto cleanup;
483 }
484 }
485
486 if(AbortInstall != 0) goto done;
487 PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_COPYINGFILES, 0);
488
489 if(AbortInstall != 0) goto done;
490 if(!InstallFile(DestinationPath, vmx_fb))
491 {
492 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
493 goto cleanup;
494 }
495
496 Sleep(250);
497
498 if(AbortInstall != 0) goto done;
499 if(!InstallFile(DestinationPath, vmx_mode))
500 {
501 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
502 goto cleanup;
503 }
504
505 Sleep(250);
506
507 if(AbortInstall != 0) goto done;
508 if(!InstallFile(DestinationDriversPath, vmx_svga))
509 {
510 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
511 goto cleanup;
512 }
513
514 Sleep(250);
515
516 if(AbortInstall != 0) goto done;
517 PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_ENABLINGDRIVER, 0);
518 if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
519 {
520 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOACTIVATEDRIVER, 0);
521 goto cleanup;
522 }
523
524 Sleep(500);
525
526 done:
527 switch(AbortInstall)
528 {
529 case 0:
530 SendMessage(hInstallationNotifyWnd, WM_INSTCOMPLETE, 0, 0);
531 break;
532 case 1:
533 SendMessage(hInstallationNotifyWnd, WM_INSTABORT, 0, 0);
534 break;
535 }
536
537 cleanup:
538 hThread = (HANDLE)InterlockedExchange((LONG*)&hInstallationThread, 0);
539 if(hThread != NULL)
540 {
541 CloseHandle(hThread);
542 }
543 return 0;
544 }
545
546 BOOL
547 InstStartInstallationThread(HWND hwndNotify)
548 {
549 if(hInstallationThread == NULL)
550 {
551 DWORD ThreadId;
552 hInstallationNotifyWnd = hwndNotify;
553 AbortInstall = 0;
554 hInstallationThread = CreateThread(NULL,
555 0,
556 InstInstallationThread,
557 NULL,
558 CREATE_SUSPENDED,
559 &ThreadId);
560 if(hInstallationThread == NULL)
561 {
562 return FALSE;
563 }
564
565 ResumeThread(hInstallationThread);
566 return TRUE;
567 }
568
569 return FALSE;
570 }
571
572 /* Property page dialog callback */
573 int CALLBACK
574 PageInstallingProc(
575 HWND hwndDlg,
576 UINT uMsg,
577 WPARAM wParam,
578 LPARAM lParam
579 )
580 {
581 switch(uMsg)
582 {
583 case WM_NOTIFY:
584 {
585 LPNMHDR pnmh = (LPNMHDR)lParam;
586 switch(pnmh->code)
587 {
588 case PSN_SETACTIVE:
589 SetDlgItemText(hwndDlg, IDC_INSTALLINGSTATUS, NULL);
590 SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, TRUE, 50);
591 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
592 InstStartInstallationThread(hwndDlg);
593 break;
594 case PSN_RESET:
595 InstTerminateInstaller(TRUE);
596 break;
597 case PSN_WIZBACK:
598 if(hInstallationThread != NULL)
599 {
600 PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
601 InstTerminateInstaller(FALSE);
602 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
603 return -1;
604 }
605 else
606 {
607 SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
608 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_INSERT_VMWARE_TOOLS);
609 }
610 break;
611 }
612 break;
613 }
614 case WM_INSTABORT:
615 /* go back in case we aborted the installation thread */
616 SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
617 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSERT_VMWARE_TOOLS);
618 if(wParam != 0)
619 {
620 WCHAR Msg[1024];
621 LoadString(hAppInstance, wParam, Msg, sizeof(Msg) / sizeof(WCHAR));
622 MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
623 }
624 break;
625 case WM_INSTCOMPLETE:
626 SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
627 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
628 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_CONFIG);
629 break;
630 case WM_INSTSTATUSUPDATE:
631 {
632 WCHAR Msg[1024];
633 LoadString(hAppInstance, wParam, Msg, sizeof(Msg) / sizeof(WCHAR));
634 SetDlgItemText(hwndDlg, IDC_INSTALLINGSTATUS, Msg);
635 break;
636 }
637 }
638 return FALSE;
639 }
640
641 /* Property page dialog callback */
642 BOOL CALLBACK
643 PageInstallFailedProc(
644 HWND hwndDlg,
645 UINT uMsg,
646 WPARAM wParam,
647 LPARAM lParam
648 )
649 {
650 switch(uMsg)
651 {
652 case WM_NOTIFY:
653 {
654 LPNMHDR pnmh = (LPNMHDR)lParam;
655 switch(pnmh->code)
656 {
657 case PSN_SETACTIVE:
658 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
659 break;
660 }
661 break;
662 }
663 }
664 return FALSE;
665 }
666
667 void
668 FillComboBox(HWND Dlg, int idComboBox, int From, int To)
669 {
670 int i;
671 WCHAR Text[256];
672
673 for(i = From; i <= To; i++)
674 {
675 if(LoadString(hAppInstance, i, Text, 255) > 0)
676 {
677 SendDlgItemMessage(Dlg, idComboBox, CB_ADDSTRING, 0, (LPARAM)Text);
678 }
679 }
680 }
681
682 typedef struct
683 {
684 int ControlID;
685 int ResX;
686 int ResY;
687 } MAPCTLRES;
688
689 /* Property page dialog callback */
690 BOOL CALLBACK
691 PageConfigProc(
692 HWND hwndDlg,
693 UINT uMsg,
694 WPARAM wParam,
695 LPARAM lParam
696 )
697 {
698 switch(uMsg)
699 {
700 case WM_INITDIALOG:
701 {
702 DWORD ResX = 0, ResY = 0, ColDepth = 0;
703 int cbSel;
704
705 FillComboBox(hwndDlg, IDC_COLORQUALITY, 10001, 10003);
706 if(LoadResolutionSettings(&ResX, &ResY, &ColDepth))
707 {
708 SendDlgItemMessage(hwndDlg, ResX + ResY, BM_SETCHECK, BST_CHECKED, 0);
709 switch(ColDepth)
710 {
711 case 8:
712 cbSel = 0;
713 break;
714 case 16:
715 cbSel = 1;
716 break;
717 case 32:
718 cbSel = 2;
719 break;
720 default:
721 cbSel = -1;
722 break;
723 }
724 SendDlgItemMessage(hwndDlg, IDC_COLORQUALITY, CB_SETCURSEL, cbSel, 0);
725 }
726 break;
727 }
728 case WM_NOTIFY:
729 {
730 LPNMHDR pnmh = (LPNMHDR)lParam;
731 switch(pnmh->code)
732 {
733 case PSN_SETACTIVE:
734 {
735 PropSheet_SetWizButtons(GetParent(hwndDlg), ((StartVMwConfigWizard || DriverFilesFound) ? PSWIZB_FINISH | PSWIZB_BACK : PSWIZB_FINISH));
736 break;
737 }
738 case PSN_WIZBACK:
739 {
740 if(StartVMwConfigWizard)
741 {
742 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
743 return TRUE;
744 }
745 if(DriverFilesFound)
746 {
747 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE);
748 return TRUE;
749 }
750 break;
751 }
752 case PSN_WIZFINISH:
753 {
754 DWORD rx = 800, ry = 600, cd = 32;
755 int i;
756 static MAPCTLRES Resolutions[11] = {
757 {540, 640, 480},
758 {1400, 800, 600},
759 {1792, 1024, 768},
760 {2016, 1152, 864},
761 {2240, 1280, 960},
762 {2304, 1280, 1024},
763 {2450, 1400, 1050},
764 {2800, 1600, 1200},
765 {3136, 1792, 1344},
766 {3248, 1856, 1392},
767 {3360, 1920, 1440}
768 };
769 for(i = 0; i < 11; i++)
770 {
771 if(SendDlgItemMessage(hwndDlg, Resolutions[i].ControlID, BM_GETCHECK, 0, 0) == BST_CHECKED)
772 {
773 rx = Resolutions[i].ResX;
774 ry = Resolutions[i].ResY;
775 break;
776 }
777 }
778
779 switch(SendDlgItemMessage(hwndDlg, IDC_COLORQUALITY, CB_GETCURSEL, 0, 0))
780 {
781 case 0:
782 cd = 8;
783 break;
784 case 1:
785 cd = 16;
786 break;
787 case 2:
788 cd = 32;
789 break;
790 }
791
792 SaveResolutionSettings(rx, ry, cd);
793 break;
794 }
795 }
796 break;
797 }
798 }
799 return FALSE;
800 }
801
802 /* Property page dialog callback */
803 BOOL CALLBACK
804 PageChooseActionProc(
805 HWND hwndDlg,
806 UINT uMsg,
807 WPARAM wParam,
808 LPARAM lParam
809 )
810 {
811 switch(uMsg)
812 {
813 case WM_INITDIALOG:
814 SendDlgItemMessage(hwndDlg, IDC_CONFIGSETTINGS, BM_SETCHECK, BST_CHECKED, 0);
815 break;
816 case WM_NOTIFY:
817 {
818 LPNMHDR pnmh = (LPNMHDR)lParam;
819 switch(pnmh->code)
820 {
821 case PSN_SETACTIVE:
822 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
823 break;
824 case PSN_WIZBACK:
825 {
826 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
827 return TRUE;
828 }
829 case PSN_WIZNEXT:
830 {
831 static ULONG SelPage[4] = {IDD_CONFIG, IDD_SELECTDRIVER, IDD_SELECTDRIVER, IDD_CHOOSEACTION};
832 int i;
833
834 for(i = IDC_CONFIGSETTINGS; i <= IDC_UNINSTALL; i++)
835 {
836 if(SendDlgItemMessage(hwndDlg, i, BM_GETCHECK, 0, 0) == BST_CHECKED)
837 {
838 break;
839 }
840 }
841
842 UninstallDriver = (i == IDC_UNINSTALL);
843
844 SetWindowLong(hwndDlg, DWL_MSGRESULT, SelPage[i - IDC_CONFIGSETTINGS]);
845 return TRUE;
846 }
847 }
848 break;
849 }
850 }
851 return FALSE;
852 }
853
854 /* Property page dialog callback */
855 BOOL CALLBACK
856 PageSelectDriverProc(
857 HWND hwndDlg,
858 UINT uMsg,
859 WPARAM wParam,
860 LPARAM lParam
861 )
862 {
863 switch(uMsg)
864 {
865 case WM_INITDIALOG:
866 SendDlgItemMessage(hwndDlg, IDC_VBE, BM_SETCHECK, BST_CHECKED, 0);
867 break;
868 case WM_NOTIFY:
869 {
870 LPNMHDR pnmh = (LPNMHDR)lParam;
871 switch(pnmh->code)
872 {
873 case PSN_SETACTIVE:
874 PropSheet_SetWizButtons(GetParent(hwndDlg), (UninstallDriver ? PSWIZB_NEXT | PSWIZB_BACK : PSWIZB_BACK | PSWIZB_FINISH));
875 break;
876 case PSN_WIZBACK:
877 {
878 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
879 return TRUE;
880 }
881 case PSN_WIZNEXT:
882 {
883 ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
884
885 if(UninstallDriver)
886 {
887 return FALSE;
888 }
889 return TRUE;
890 }
891 case PSN_WIZFINISH:
892 {
893 if(UninstallDriver)
894 {
895 return FALSE;
896 }
897 ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
898 if(!EnableVmwareDriver(ActivateVBE,
899 !ActivateVBE,
900 FALSE))
901 {
902 WCHAR Msg[1024];
903 LoadString(hAppInstance, (ActivateVBE ? IDS_FAILEDTOSELVBEDRIVER : IDS_FAILEDTOSELVGADRIVER), Msg, sizeof(Msg) / sizeof(WCHAR));
904 MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
905 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SELECTDRIVER);
906 return TRUE;
907 }
908 break;
909 }
910 }
911 break;
912 }
913 }
914 return FALSE;
915 }
916
917 VOID
918 ShowUninstNotice(HWND Owner)
919 {
920 WCHAR Msg[1024];
921 LoadString(hAppInstance, IDS_UNINSTNOTICE, Msg, sizeof(Msg) / sizeof(WCHAR));
922 MessageBox(Owner, Msg, NULL, MB_ICONINFORMATION);
923 }
924
925 BOOL CALLBACK
926 PageDoUninstallProc(
927 HWND hwndDlg,
928 UINT uMsg,
929 WPARAM wParam,
930 LPARAM lParam
931 )
932 {
933 switch(uMsg)
934 {
935 case WM_NOTIFY:
936 {
937 LPNMHDR pnmh = (LPNMHDR)lParam;
938 switch(pnmh->code)
939 {
940 case PSN_SETACTIVE:
941 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
942 break;
943 case PSN_WIZFINISH:
944 {
945 if(UninstallDriver)
946 {
947 if(!EnableVmwareDriver(ActivateVBE,
948 !ActivateVBE,
949 FALSE))
950 {
951 WCHAR Msg[1024];
952 LoadString(hAppInstance, (ActivateVBE ? IDS_FAILEDTOSELVBEDRIVER : IDS_FAILEDTOSELVGADRIVER), Msg, sizeof(Msg) / sizeof(WCHAR));
953 MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
954 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SELECTDRIVER);
955 return TRUE;
956 }
957 ShowUninstNotice(GetParent(hwndDlg));
958 }
959 return FALSE;
960 }
961 }
962 break;
963 }
964 }
965 return FALSE;
966 }
967
968 static LONG
969 CreateWizard(VOID)
970 {
971 PROPSHEETPAGE psp[8];
972 PROPSHEETHEADER psh;
973 WCHAR Caption[1024];
974
975 LoadString(hAppInstance, IDS_WIZARD_NAME, Caption, sizeof(Caption) / sizeof(TCHAR));
976
977 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
978 psh.dwSize = sizeof(PROPSHEETHEADER);
979 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
980 psh.hwndParent = NULL;
981 psh.hInstance = hAppInstance;
982 psh.hIcon = 0;
983 psh.pszCaption = Caption;
984 psh.nPages = 7;
985 psh.nStartPage = (StartVMwConfigWizard ? 5 : 0);
986 psh.ppsp = psp;
987 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
988 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
989
990 InitPropSheetPage(&psp[0], IDD_WELCOMEPAGE, PSP_HIDEHEADER, PageWelcomeProc);
991 InitPropSheetPage(&psp[1], IDD_INSERT_VMWARE_TOOLS, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInsertDiscProc);
992 InitPropSheetPage(&psp[2], IDD_INSTALLING_VMWARE_TOOLS, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInstallingProc);
993 InitPropSheetPage(&psp[3], IDD_CONFIG, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageConfigProc);
994 InitPropSheetPage(&psp[4], IDD_INSTALLATION_FAILED, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInstallFailedProc);
995 InitPropSheetPage(&psp[5], IDD_CHOOSEACTION, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageChooseActionProc);
996 InitPropSheetPage(&psp[6], IDD_SELECTDRIVER, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageSelectDriverProc);
997 InitPropSheetPage(&psp[7], IDD_DOUNINSTALL, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageDoUninstallProc);
998
999 return (LONG)(PropertySheet(&psh) != -1);
1000 }
1001
1002 int WINAPI
1003 WinMain(HINSTANCE hInstance,
1004 HINSTANCE hPrevInstance,
1005 LPSTR lpszCmdLine,
1006 int nCmdShow)
1007 {
1008 LPTOP_LEVEL_EXCEPTION_FILTER OldHandler;
1009 int Version;
1010 WCHAR *lc;
1011
1012 hAppInstance = hInstance;
1013
1014 /* Setup our exception "handler" ;-) */
1015 OldHandler = SetUnhandledExceptionFilter(ExceptionHandler);
1016
1017 if(!DetectVMware(&Version))
1018 {
1019 ExitProcess(1);
1020 return 1;
1021 }
1022
1023 /* restore the exception handler */
1024 SetUnhandledExceptionFilter(OldHandler);
1025
1026 lc = DestinationPath;
1027 lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
1028 if(lc >= DestinationPath && *lc != L'\\')
1029 {
1030 wcscat(DestinationPath, L"\\");
1031 }
1032 DestinationDriversPath[0] = L'\0';
1033 wcscat(DestinationDriversPath, DestinationPath);
1034 wcscat(DestinationDriversPath, L"drivers\\");
1035
1036 SetCurrentDirectory(DestinationPath);
1037
1038 DriverFilesFound = FileExists(DestinationPath, vmx_fb) &&
1039 FileExists(DestinationPath, vmx_mode) &&
1040 FileExists(DestinationDriversPath, vmx_svga);
1041
1042 StartVMwConfigWizard = DriverFilesFound && IsVmwSVGAEnabled();
1043
1044 /* Show the wizard */
1045 CreateWizard();
1046
1047 return 2;
1048 }
1049