3af6cbdc0a2c0c6e7495c6c179210bf95f88c790
[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$
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
284
285 BOOL
286 SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
287 {
288 HKEY hReg;
289
290 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
291 L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0",
292 0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
293 {
294 return FALSE;
295 }
296 if(RegSetValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, REG_DWORD, (BYTE*)&ColDepth, sizeof(DWORD)) != ERROR_SUCCESS)
297 {
298 RegCloseKey(hReg);
299 return FALSE;
300 }
301
302 if(RegSetValueEx(hReg, L"DefaultSettings.XResolution", 0, REG_DWORD, (BYTE*)&ResX, sizeof(DWORD)) != ERROR_SUCCESS)
303 {
304 RegCloseKey(hReg);
305 return FALSE;
306 }
307
308 if(RegSetValueEx(hReg, L"DefaultSettings.YResolution", 0, REG_DWORD, (BYTE*)&ResY, sizeof(DWORD)) != ERROR_SUCCESS)
309 {
310 RegCloseKey(hReg);
311 return FALSE;
312 }
313
314 RegCloseKey(hReg);
315 return TRUE;
316 }
317
318 BOOL
319 EnableDriver(WCHAR *Key, BOOL Enable)
320 {
321 DWORD Value;
322 HKEY hReg;
323
324 Value = (Enable ? 1 : 4);
325
326 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key, 0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS)
327 {
328 return FALSE;
329 }
330 if(RegSetValueEx(hReg, L"Start", 0, REG_DWORD, (BYTE*)&Value, sizeof(DWORD)) != ERROR_SUCCESS)
331 {
332 RegCloseKey(hReg);
333 return FALSE;
334 }
335
336 RegCloseKey(hReg);
337 return TRUE;
338 }
339
340 /* Activate the vmware driver and deactivate the others */
341 BOOL
342 EnableVmwareDriver(BOOL VBE, BOOL VGA, BOOL VMX)
343 {
344 if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\VBE", VBE))
345 {
346 return FALSE;
347 }
348 if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\vga", VGA))
349 {
350 return FALSE;
351 }
352 if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga", VMX))
353 {
354 return FALSE;
355 }
356
357 return TRUE;
358 }
359
360 /* GUI */
361
362 void
363 InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DWORD Flags, DLGPROC DlgProc)
364 {
365 ZeroMemory(psp, sizeof(PROPSHEETPAGE));
366 psp->dwSize = sizeof(PROPSHEETPAGE);
367 psp->dwFlags = PSP_DEFAULT | Flags;
368 psp->hInstance = hAppInstance;
369 psp->pszTemplate = MAKEINTRESOURCE(idDlg);
370 psp->pfnDlgProc = DlgProc;
371 }
372
373 /* Property page dialog callback */
374 INT_PTR CALLBACK
375 PageWelcomeProc(
376 HWND hwndDlg,
377 UINT uMsg,
378 WPARAM wParam,
379 LPARAM lParam
380 )
381 {
382 switch(uMsg)
383 {
384 case WM_NOTIFY:
385 {
386 LPNMHDR pnmh = (LPNMHDR)lParam;
387 switch(pnmh->code)
388 {
389 case PSN_SETACTIVE:
390 {
391 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
392 break;
393 }
394 case PSN_WIZNEXT:
395 {
396 if(DriverFilesFound)
397 {
398 if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
399 {
400 WCHAR Msg[1024];
401 LoadString(hAppInstance, IDS_FAILEDTOACTIVATEDRIVER, Msg, sizeof(Msg) / sizeof(WCHAR));
402 MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
403 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE);
404 return TRUE;
405 }
406 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CONFIG);
407 return TRUE;
408 }
409 break;
410 }
411 }
412 break;
413 }
414 }
415 return FALSE;
416 }
417
418 /* Property page dialog callback */
419 INT_PTR CALLBACK
420 PageInsertDiscProc(
421 HWND hwndDlg,
422 UINT uMsg,
423 WPARAM wParam,
424 LPARAM lParam
425 )
426 {
427 switch(uMsg)
428 {
429 case WM_NOTIFY:
430 {
431 LPNMHDR pnmh = (LPNMHDR)lParam;
432 switch(pnmh->code)
433 {
434 case PSN_SETACTIVE:
435 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
436 break;
437 case PSN_WIZNEXT:
438 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_INSTALLING_VMWARE_TOOLS);
439 break;
440 }
441 break;
442 }
443 }
444 return FALSE;
445 }
446
447 VOID
448 InstTerminateInstaller(BOOL Wait)
449 {
450 if(hInstallationThread != NULL)
451 {
452 if(Wait)
453 {
454 InterlockedExchange((LONG*)&AbortInstall, 2);
455 WaitForSingleObject(hInstallationThread, INFINITE);
456 }
457 else
458 {
459 InterlockedExchange((LONG*)&AbortInstall, 1);
460 }
461 }
462 }
463
464 DWORD STDCALL
465 InstInstallationThread(LPVOID lpParameter)
466 {
467 HANDLE hThread;
468 BOOL DriveAvailable;
469 int DrivesTested = 0;
470
471 if(AbortInstall != 0) goto done;
472 PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_SEARCHINGFORCDROM, 0);
473
474 while(AbortInstall == 0)
475 {
476 Sleep(500);
477 DriveAvailable = IsVMwareCDInDrive(&CDDrive);
478 if(DriveAvailable)
479 break;
480 if(DrivesTested++ > 20)
481 {
482 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOLOCATEDRIVERS, 0);
483 goto cleanup;
484 }
485 }
486
487 if(AbortInstall != 0) goto done;
488 PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_COPYINGFILES, 0);
489
490 if(AbortInstall != 0) goto done;
491 if(!InstallFile(DestinationPath, vmx_fb))
492 {
493 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
494 goto cleanup;
495 }
496
497 Sleep(250);
498
499 if(AbortInstall != 0) goto done;
500 if(!InstallFile(DestinationPath, vmx_mode))
501 {
502 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
503 goto cleanup;
504 }
505
506 Sleep(250);
507
508 if(AbortInstall != 0) goto done;
509 if(!InstallFile(DestinationDriversPath, vmx_svga))
510 {
511 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOCOPYFILES, 0);
512 goto cleanup;
513 }
514
515 Sleep(250);
516
517 if(AbortInstall != 0) goto done;
518 PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_ENABLINGDRIVER, 0);
519 if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
520 {
521 PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOACTIVATEDRIVER, 0);
522 goto cleanup;
523 }
524
525 Sleep(500);
526
527 done:
528 switch(AbortInstall)
529 {
530 case 0:
531 SendMessage(hInstallationNotifyWnd, WM_INSTCOMPLETE, 0, 0);
532 break;
533 case 1:
534 SendMessage(hInstallationNotifyWnd, WM_INSTABORT, 0, 0);
535 break;
536 }
537
538 cleanup:
539 hThread = (HANDLE)InterlockedExchange((LONG*)&hInstallationThread, 0);
540 if(hThread != NULL)
541 {
542 CloseHandle(hThread);
543 }
544 return 0;
545 }
546
547 BOOL
548 InstStartInstallationThread(HWND hwndNotify)
549 {
550 if(hInstallationThread == NULL)
551 {
552 DWORD ThreadId;
553 hInstallationNotifyWnd = hwndNotify;
554 AbortInstall = 0;
555 hInstallationThread = CreateThread(NULL,
556 0,
557 InstInstallationThread,
558 NULL,
559 CREATE_SUSPENDED,
560 &ThreadId);
561 if(hInstallationThread == NULL)
562 {
563 return FALSE;
564 }
565
566 ResumeThread(hInstallationThread);
567 return TRUE;
568 }
569
570 return FALSE;
571 }
572
573 /* Property page dialog callback */
574 INT_PTR CALLBACK
575 PageInstallingProc(
576 HWND hwndDlg,
577 UINT uMsg,
578 WPARAM wParam,
579 LPARAM lParam
580 )
581 {
582 switch(uMsg)
583 {
584 case WM_NOTIFY:
585 {
586 LPNMHDR pnmh = (LPNMHDR)lParam;
587 switch(pnmh->code)
588 {
589 case PSN_SETACTIVE:
590 SetDlgItemText(hwndDlg, IDC_INSTALLINGSTATUS, NULL);
591 SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, TRUE, 50);
592 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
593 InstStartInstallationThread(hwndDlg);
594 break;
595 case PSN_RESET:
596 InstTerminateInstaller(TRUE);
597 break;
598 case PSN_WIZBACK:
599 if(hInstallationThread != NULL)
600 {
601 PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
602 InstTerminateInstaller(FALSE);
603 SetWindowLong(hwndDlg, DWL_MSGRESULT, -1);
604 return -1;
605 }
606 else
607 {
608 SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
609 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_INSERT_VMWARE_TOOLS);
610 }
611 break;
612 }
613 break;
614 }
615 case WM_INSTABORT:
616 /* go back in case we aborted the installation thread */
617 SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
618 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSERT_VMWARE_TOOLS);
619 if(wParam != 0)
620 {
621 WCHAR Msg[1024];
622 LoadString(hAppInstance, wParam, Msg, sizeof(Msg) / sizeof(WCHAR));
623 MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
624 }
625 break;
626 case WM_INSTCOMPLETE:
627 SendDlgItemMessage(hwndDlg, IDC_INSTALLINGPROGRESS, PBM_SETMARQUEE, FALSE, 0);
628 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
629 PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_CONFIG);
630 break;
631 case WM_INSTSTATUSUPDATE:
632 {
633 WCHAR Msg[1024];
634 LoadString(hAppInstance, wParam, Msg, sizeof(Msg) / sizeof(WCHAR));
635 SetDlgItemText(hwndDlg, IDC_INSTALLINGSTATUS, Msg);
636 break;
637 }
638 }
639 return FALSE;
640 }
641
642 /* Property page dialog callback */
643 INT_PTR CALLBACK
644 PageInstallFailedProc(
645 HWND hwndDlg,
646 UINT uMsg,
647 WPARAM wParam,
648 LPARAM lParam
649 )
650 {
651 switch(uMsg)
652 {
653 case WM_NOTIFY:
654 {
655 LPNMHDR pnmh = (LPNMHDR)lParam;
656 switch(pnmh->code)
657 {
658 case PSN_SETACTIVE:
659 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
660 break;
661 }
662 break;
663 }
664 }
665 return FALSE;
666 }
667
668 void
669 FillComboBox(HWND Dlg, int idComboBox, int From, int To)
670 {
671 int i;
672 WCHAR Text[256];
673
674 for(i = From; i <= To; i++)
675 {
676 if(LoadString(hAppInstance, i, Text, 255) > 0)
677 {
678 SendDlgItemMessage(Dlg, idComboBox, CB_ADDSTRING, 0, (LPARAM)Text);
679 }
680 }
681 }
682
683 typedef struct
684 {
685 int ControlID;
686 int ResX;
687 int ResY;
688 } MAPCTLRES;
689
690 /* Property page dialog callback */
691 INT_PTR CALLBACK
692 PageConfigProc(
693 HWND hwndDlg,
694 UINT uMsg,
695 WPARAM wParam,
696 LPARAM lParam
697 )
698 {
699 switch(uMsg)
700 {
701 case WM_INITDIALOG:
702 {
703 DWORD ResX = 0, ResY = 0, ColDepth = 0;
704 int cbSel;
705
706 FillComboBox(hwndDlg, IDC_COLORQUALITY, 10001, 10003);
707 if(LoadResolutionSettings(&ResX, &ResY, &ColDepth))
708 {
709 SendDlgItemMessage(hwndDlg, ResX + ResY, BM_SETCHECK, BST_CHECKED, 0);
710 switch(ColDepth)
711 {
712 case 8:
713 cbSel = 0;
714 break;
715 case 16:
716 cbSel = 1;
717 break;
718 case 32:
719 cbSel = 2;
720 break;
721 default:
722 cbSel = -1;
723 break;
724 }
725 SendDlgItemMessage(hwndDlg, IDC_COLORQUALITY, CB_SETCURSEL, cbSel, 0);
726 }
727 break;
728 }
729 case WM_NOTIFY:
730 {
731 LPNMHDR pnmh = (LPNMHDR)lParam;
732 switch(pnmh->code)
733 {
734 case PSN_SETACTIVE:
735 {
736 PropSheet_SetWizButtons(GetParent(hwndDlg), ((StartVMwConfigWizard || DriverFilesFound) ? PSWIZB_FINISH | PSWIZB_BACK : PSWIZB_FINISH));
737 break;
738 }
739 case PSN_WIZBACK:
740 {
741 if(StartVMwConfigWizard)
742 {
743 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
744 return TRUE;
745 }
746 if(DriverFilesFound)
747 {
748 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE);
749 return TRUE;
750 }
751 break;
752 }
753 case PSN_WIZFINISH:
754 {
755 DWORD rx = 800, ry = 600, cd = 32;
756 int i;
757 static MAPCTLRES Resolutions[11] = {
758 {540, 640, 480},
759 {1400, 800, 600},
760 {1792, 1024, 768},
761 {2016, 1152, 864},
762 {2240, 1280, 960},
763 {2304, 1280, 1024},
764 {2450, 1400, 1050},
765 {2800, 1600, 1200},
766 {3136, 1792, 1344},
767 {3248, 1856, 1392},
768 {3360, 1920, 1440}
769 };
770 for(i = 0; i < 11; i++)
771 {
772 if(SendDlgItemMessage(hwndDlg, Resolutions[i].ControlID, BM_GETCHECK, 0, 0) == BST_CHECKED)
773 {
774 rx = Resolutions[i].ResX;
775 ry = Resolutions[i].ResY;
776 break;
777 }
778 }
779
780 switch(SendDlgItemMessage(hwndDlg, IDC_COLORQUALITY, CB_GETCURSEL, 0, 0))
781 {
782 case 0:
783 cd = 8;
784 break;
785 case 1:
786 cd = 16;
787 break;
788 case 2:
789 cd = 32;
790 break;
791 }
792
793 SaveResolutionSettings(rx, ry, cd);
794 break;
795 }
796 }
797 break;
798 }
799 }
800 return FALSE;
801 }
802
803 /* Property page dialog callback */
804 INT_PTR CALLBACK
805 PageChooseActionProc(
806 HWND hwndDlg,
807 UINT uMsg,
808 WPARAM wParam,
809 LPARAM lParam
810 )
811 {
812 switch(uMsg)
813 {
814 case WM_INITDIALOG:
815 SendDlgItemMessage(hwndDlg, IDC_CONFIGSETTINGS, BM_SETCHECK, BST_CHECKED, 0);
816 break;
817 case WM_NOTIFY:
818 {
819 LPNMHDR pnmh = (LPNMHDR)lParam;
820 switch(pnmh->code)
821 {
822 case PSN_SETACTIVE:
823 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
824 break;
825 case PSN_WIZBACK:
826 {
827 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
828 return TRUE;
829 }
830 case PSN_WIZNEXT:
831 {
832 static ULONG SelPage[4] = {IDD_CONFIG, IDD_SELECTDRIVER, IDD_SELECTDRIVER, IDD_CHOOSEACTION};
833 int i;
834
835 for(i = IDC_CONFIGSETTINGS; i <= IDC_UNINSTALL; i++)
836 {
837 if(SendDlgItemMessage(hwndDlg, i, BM_GETCHECK, 0, 0) == BST_CHECKED)
838 {
839 break;
840 }
841 }
842
843 UninstallDriver = (i == IDC_UNINSTALL);
844
845 SetWindowLong(hwndDlg, DWL_MSGRESULT, SelPage[i - IDC_CONFIGSETTINGS]);
846 return TRUE;
847 }
848 }
849 break;
850 }
851 }
852 return FALSE;
853 }
854
855 /* Property page dialog callback */
856 INT_PTR CALLBACK
857 PageSelectDriverProc(
858 HWND hwndDlg,
859 UINT uMsg,
860 WPARAM wParam,
861 LPARAM lParam
862 )
863 {
864 switch(uMsg)
865 {
866 case WM_INITDIALOG:
867 SendDlgItemMessage(hwndDlg, IDC_VBE, BM_SETCHECK, BST_CHECKED, 0);
868 break;
869 case WM_NOTIFY:
870 {
871 LPNMHDR pnmh = (LPNMHDR)lParam;
872 switch(pnmh->code)
873 {
874 case PSN_SETACTIVE:
875 PropSheet_SetWizButtons(GetParent(hwndDlg), (UninstallDriver ? PSWIZB_NEXT | PSWIZB_BACK : PSWIZB_BACK | PSWIZB_FINISH));
876 break;
877 case PSN_WIZBACK:
878 {
879 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CHOOSEACTION);
880 return TRUE;
881 }
882 case PSN_WIZNEXT:
883 {
884 ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
885
886 if(UninstallDriver)
887 {
888 return FALSE;
889 }
890 return TRUE;
891 }
892 case PSN_WIZFINISH:
893 {
894 if(UninstallDriver)
895 {
896 return FALSE;
897 }
898 ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
899 if(!EnableVmwareDriver(ActivateVBE,
900 !ActivateVBE,
901 FALSE))
902 {
903 WCHAR Msg[1024];
904 LoadString(hAppInstance, (ActivateVBE ? IDS_FAILEDTOSELVBEDRIVER : IDS_FAILEDTOSELVGADRIVER), Msg, sizeof(Msg) / sizeof(WCHAR));
905 MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
906 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SELECTDRIVER);
907 return TRUE;
908 }
909 break;
910 }
911 }
912 break;
913 }
914 }
915 return FALSE;
916 }
917
918 VOID
919 ShowUninstNotice(HWND Owner)
920 {
921 WCHAR Msg[1024];
922 LoadString(hAppInstance, IDS_UNINSTNOTICE, Msg, sizeof(Msg) / sizeof(WCHAR));
923 MessageBox(Owner, Msg, NULL, MB_ICONINFORMATION);
924 }
925
926 INT_PTR CALLBACK
927 PageDoUninstallProc(
928 HWND hwndDlg,
929 UINT uMsg,
930 WPARAM wParam,
931 LPARAM lParam
932 )
933 {
934 switch(uMsg)
935 {
936 case WM_NOTIFY:
937 {
938 LPNMHDR pnmh = (LPNMHDR)lParam;
939 switch(pnmh->code)
940 {
941 case PSN_SETACTIVE:
942 PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
943 break;
944 case PSN_WIZFINISH:
945 {
946 if(UninstallDriver)
947 {
948 if(!EnableVmwareDriver(ActivateVBE,
949 !ActivateVBE,
950 FALSE))
951 {
952 WCHAR Msg[1024];
953 LoadString(hAppInstance, (ActivateVBE ? IDS_FAILEDTOSELVBEDRIVER : IDS_FAILEDTOSELVGADRIVER), Msg, sizeof(Msg) / sizeof(WCHAR));
954 MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
955 SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SELECTDRIVER);
956 return TRUE;
957 }
958 ShowUninstNotice(GetParent(hwndDlg));
959 }
960 return FALSE;
961 }
962 }
963 break;
964 }
965 }
966 return FALSE;
967 }
968
969 static LONG
970 CreateWizard(VOID)
971 {
972 PROPSHEETPAGE psp[8];
973 PROPSHEETHEADER psh;
974 WCHAR Caption[1024];
975
976 LoadString(hAppInstance, IDS_WIZARD_NAME, Caption, sizeof(Caption) / sizeof(TCHAR));
977
978 ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
979 psh.dwSize = sizeof(PROPSHEETHEADER);
980 psh.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
981 psh.hwndParent = NULL;
982 psh.hInstance = hAppInstance;
983 psh.hIcon = 0;
984 psh.pszCaption = Caption;
985 psh.nPages = 7;
986 psh.nStartPage = (StartVMwConfigWizard ? 5 : 0);
987 psh.ppsp = psp;
988 psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
989 psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
990
991 InitPropSheetPage(&psp[0], IDD_WELCOMEPAGE, PSP_HIDEHEADER, PageWelcomeProc);
992 InitPropSheetPage(&psp[1], IDD_INSERT_VMWARE_TOOLS, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInsertDiscProc);
993 InitPropSheetPage(&psp[2], IDD_INSTALLING_VMWARE_TOOLS, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInstallingProc);
994 InitPropSheetPage(&psp[3], IDD_CONFIG, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageConfigProc);
995 InitPropSheetPage(&psp[4], IDD_INSTALLATION_FAILED, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageInstallFailedProc);
996 InitPropSheetPage(&psp[5], IDD_CHOOSEACTION, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageChooseActionProc);
997 InitPropSheetPage(&psp[6], IDD_SELECTDRIVER, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageSelectDriverProc);
998 InitPropSheetPage(&psp[7], IDD_DOUNINSTALL, PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE, PageDoUninstallProc);
999
1000 return (LONG)(PropertySheet(&psh) != -1);
1001 }
1002
1003 int WINAPI
1004 WinMain(HINSTANCE hInstance,
1005 HINSTANCE hPrevInstance,
1006 LPSTR lpszCmdLine,
1007 int nCmdShow)
1008 {
1009 LPTOP_LEVEL_EXCEPTION_FILTER OldHandler;
1010 int Version;
1011 WCHAR *lc;
1012
1013 hAppInstance = hInstance;
1014
1015 /* Setup our exception "handler" ;-) */
1016 OldHandler = SetUnhandledExceptionFilter(ExceptionHandler);
1017
1018 if(!DetectVMware(&Version))
1019 {
1020 ExitProcess(1);
1021 return 1;
1022 }
1023
1024 /* restore the exception handler */
1025 SetUnhandledExceptionFilter(OldHandler);
1026
1027 lc = DestinationPath;
1028 lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;
1029 if(lc >= DestinationPath && *lc != L'\\')
1030 {
1031 wcscat(DestinationPath, L"\\");
1032 }
1033 DestinationDriversPath[0] = L'\0';
1034 wcscat(DestinationDriversPath, DestinationPath);
1035 wcscat(DestinationDriversPath, L"drivers\\");
1036
1037 SetCurrentDirectory(DestinationPath);
1038
1039 DriverFilesFound = FileExists(DestinationPath, vmx_fb) &&
1040 FileExists(DestinationPath, vmx_mode) &&
1041 FileExists(DestinationDriversPath, vmx_svga);
1042
1043 StartVMwConfigWizard = DriverFilesFound && IsVmwSVGAEnabled();
1044
1045 /* Show the wizard */
1046 CreateWizard();
1047
1048 return 2;
1049 }
1050