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