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