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