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