- userinit, usetup, vmwinst, welcome, winefile, winlogon, winver.
[reactos.git] / reactos / subsys / system / vmwinst / vmwinst.c
index 1405c2b..3729fba 100644 (file)
 #include <string.h>
 #include "vmwinst.h"
 
+extern VOID CALLBACK InstallHinfSectionW(HWND hwnd, HINSTANCE ModuleHandle,
+                                         PCWSTR CmdLineBuffer, INT nCmdShow);
+
+
 HINSTANCE hAppInstance;
 BOOL StartVMwConfigWizard, DriverFilesFound, ActivateVBE = FALSE, UninstallDriver = FALSE;
 
 static WCHAR DestinationDriversPath[MAX_PATH+1];
 static WCHAR CDDrive = L'\0';
+static WCHAR PathToVideoDrivers55[MAX_PATH+1] = L"X:\\program files\\VMware\\VMware Tools\\Drivers\\video\\winnt2k\\32Bit\\";
 static WCHAR PathToVideoDrivers45[MAX_PATH+1] = L"X:\\program files\\VMware\\VMware Tools\\Drivers\\video\\winnt2k\\";
 static WCHAR PathToVideoDrivers40[MAX_PATH+1] = L"X:\\video\\winnt2k\\";
 static WCHAR DestinationPath[MAX_PATH+1];
@@ -55,11 +60,10 @@ static LONG AbortInstall = 0;
 
 /* Helper functions */
 
-LONG WINAPI ExceptionHandler(LPEXCEPTION_POINTERS ExceptionInfo)
+LONG CALLBACK VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
 {
-  /* This is rude, but i don't know how to continue execution properly, that's why
-     we just exit here when we're not running inside of VMware */
-  ExitProcess(ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_PRIVILEGED_INSTRUCTION);
+  /* we're not running in VMware, just terminate the process */
+  ExitProcess(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION);
   return EXCEPTION_CONTINUE_EXECUTION;
 }
 
@@ -73,9 +77,14 @@ DetectVMware(int *Version)
 
   /* Try using a VMware I/O port. If not running in VMware this'll throw an
      exception! */
+#ifndef _MSC_VER
   __asm__ __volatile__("inl  %%dx, %%eax"
     : "=a" (ver), "=b" (magic)
     : "0" (0x564d5868), "d" (0x5658), "c" (0xa));
+#else
+#error PLEASE WRITE THIS IN ASSEMBLY
+#endif
+
 
   if(magic == 0x564d5868)
   {
@@ -120,7 +129,8 @@ FileExists(WCHAR *Path, WCHAR *File)
 
   if(FileHandle == INVALID_HANDLE_VALUE)
   {
-    return FALSE;
+    /* If it was a sharing violation the file must already exist */
+    return GetLastError() == ERROR_SHARING_VIOLATION;
   }
 
   if(GetFileSize(FileHandle, NULL) <= 0)
@@ -218,9 +228,12 @@ IsVMwareCDInDrive(WCHAR *Drv)
     if(GetDriveType(Drive) == DRIVE_CDROM)
     {
 #endif
+      PathToVideoDrivers55[0] = Current;
       PathToVideoDrivers40[0] = Current;
       PathToVideoDrivers45[0] = Current;
-      if(SetCurrentDirectory(PathToVideoDrivers45))
+      if(SetCurrentDirectory(PathToVideoDrivers55))
+        SrcPath = PathToVideoDrivers55;
+      else if(SetCurrentDirectory(PathToVideoDrivers45))
         SrcPath = PathToVideoDrivers45;
       else if(SetCurrentDirectory(PathToVideoDrivers40))
         SrcPath = PathToVideoDrivers40;
@@ -314,7 +327,7 @@ SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
 
   if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                   L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0",
-                  0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
+                  0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS)
   {
     return FALSE;
   }
@@ -382,6 +395,79 @@ EnableVmwareDriver(BOOL VBE, BOOL VGA, BOOL VMX)
   return TRUE;
 }
 
+/* Make sure the required registry entries are present */
+BOOL
+AddVmwareRegistryEntries()
+{
+  HRSRC VmwareInfResource;
+  HGLOBAL VmwareInfMem;
+  PVOID VmwareInfLocked;
+  DWORD Size;
+  WCHAR TempPath[MAX_PATH];
+  WCHAR BufferSize;
+  WCHAR TempFileName[MAX_PATH];
+  HANDLE TempFile;
+  DWORD Written;
+  WCHAR CmdLine[19 + MAX_PATH];
+
+  VmwareInfResource = FindResourceW(hAppInstance,
+                                    MAKEINTRESOURCE(IDR_VMWARE_INF),
+                                    L"RT_INF");
+  if (NULL == VmwareInfResource)
+  {
+    return FALSE;
+  }
+  Size = SizeofResource(hAppInstance, VmwareInfResource);
+  if (0 == Size)
+  {
+    return FALSE;
+  }
+  VmwareInfMem = LoadResource(hAppInstance, VmwareInfResource);
+  if (NULL == VmwareInfMem)
+  {
+    return FALSE;
+  }
+  VmwareInfLocked = LockResource(VmwareInfMem);
+  if (NULL == VmwareInfLocked)
+  {
+    return FALSE;
+  }
+
+  BufferSize = GetTempPathW(sizeof(TempPath) / sizeof(TempPath[0]), TempPath);
+  if (0 == BufferSize || sizeof(TempPath) / sizeof(TempPath[0]) < BufferSize)
+  {
+    return FALSE;
+  }
+  if (0 == GetTempFileNameW(TempPath, L"vmx", 0, TempFileName))
+  {
+    return FALSE;
+  }
+
+  TempFile = CreateFileW(TempFileName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+                         FILE_ATTRIBUTE_NORMAL, NULL);
+  if (INVALID_HANDLE_VALUE == TempFile)
+  {
+    DeleteFile(TempFileName);
+    return FALSE;
+  }
+  if (! WriteFile(TempFile, VmwareInfLocked, Size, &Written, NULL) ||
+      Written != Size)
+  {
+    CloseHandle(TempFile);
+    DeleteFile(TempFileName);
+    return FALSE;
+  }
+  CloseHandle(TempFile);
+
+  wcscpy(CmdLine, L"DefaultInstall 128 ");
+  wcscat(CmdLine, TempFileName);
+  InstallHinfSectionW(NULL, NULL, CmdLine, 0);
+
+  DeleteFile(TempFileName);
+
+  return TRUE;
+}
+
 /* GUI */
 
 void
@@ -404,6 +490,7 @@ PageWelcomeProc(
   LPARAM lParam
 )
 {
+  LPNMHDR pnmh = (LPNMHDR)lParam;
   switch(uMsg)
   {
     case WM_NOTIFY:
@@ -414,7 +501,6 @@ PageWelcomeProc(
       hwndControl = GetParent(hwndDlg);
       CenterWindow (hwndControl);
 
-      LPNMHDR pnmh = (LPNMHDR)lParam;
       switch(pnmh->code)
       {
         case PSN_SETACTIVE:
@@ -426,7 +512,15 @@ PageWelcomeProc(
         {
           if(DriverFilesFound)
           {
-            if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
+            if(!AddVmwareRegistryEntries())
+            {
+              WCHAR Msg[1024];
+              LoadString(hAppInstance, IDS_FAILEDTOADDREGENTRIES, Msg, sizeof(Msg) / sizeof(WCHAR));
+              MessageBox(GetParent(hwndDlg), Msg, NULL, MB_ICONWARNING);
+              SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_WELCOMEPAGE);
+              return TRUE;
+            }
+            if(!EnableVmwareDriver(TRUE, TRUE, TRUE))
             {
 
               WCHAR Msg[1024];
@@ -548,7 +642,12 @@ InstInstallationThread(LPVOID lpParameter)
 
   if(AbortInstall != 0) goto done;
   PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_ENABLINGDRIVER, 0);
-  if(!EnableVmwareDriver(FALSE, FALSE, TRUE))
+  if(!AddVmwareRegistryEntries())
+  {
+    PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOADDREGENTRIES, 0);
+    goto cleanup;
+  }
+  if(!EnableVmwareDriver(TRUE, TRUE, TRUE))
   {
     PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOACTIVATEDRIVER, 0);
     goto cleanup;
@@ -728,6 +827,7 @@ PageConfigProc(
   LPARAM lParam
 )
 {
+  LPNMHDR pnmh = (LPNMHDR)lParam;
   switch(uMsg)
   {
     case WM_INITDIALOG:
@@ -766,7 +866,6 @@ PageConfigProc(
       hwndControl = GetParent(hwndDlg);
       CenterWindow (hwndControl);
 
-      LPNMHDR pnmh = (LPNMHDR)lParam;
       switch(pnmh->code)
       {
         case PSN_SETACTIVE:
@@ -935,7 +1034,7 @@ PageSelectDriverProc(
           }
           ActivateVBE = (SendDlgItemMessage(hwndDlg, IDC_VBE, BM_GETCHECK, 0, 0) == BST_CHECKED);
           if(!EnableVmwareDriver(ActivateVBE,
-                                 !ActivateVBE,
+                                 TRUE,
                                  FALSE))
           {
             WCHAR Msg[1024];
@@ -984,7 +1083,7 @@ PageDoUninstallProc(
           if(UninstallDriver)
           {
             if(!EnableVmwareDriver(ActivateVBE,
-                                   !ActivateVBE,
+                                   TRUE,
                                    FALSE))
             {
               WCHAR Msg[1024];
@@ -1101,23 +1200,28 @@ WinMain(HINSTANCE hInstance,
        int nCmdShow)
 {
 
-  LPTOP_LEVEL_EXCEPTION_FILTER OldHandler;
+  PVOID ExceptionHandler;
   int Version;
   WCHAR *lc;
 
   hAppInstance = hInstance;
 
-  /* Setup our exception "handler" ;-) */
-  OldHandler = SetUnhandledExceptionFilter(ExceptionHandler);
+  /* Setup a vectored exception handler to protect the detection. Don't use SEH
+     here so we notice the next time someone removes support for vectored
+     exception handling from ros... */
+  if (!(ExceptionHandler = AddVectoredExceptionHandler(0,
+                                                       VectoredExceptionHandler)))
+  {
+    return 1;
+  }
 
   if(!DetectVMware(&Version))
   {
-    ExitProcess(1);
     return 1;
   }
 
-  /* restore the exception handler */
-  SetUnhandledExceptionFilter(OldHandler);
+  /* unregister the handler */
+  RemoveVectoredExceptionHandler(ExceptionHandler);
 
   lc = DestinationPath;
   lc += GetSystemDirectory(DestinationPath, MAX_PATH) - 1;