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