⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmwinst.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * ReactOS VMware(r) driver installation utility
 * Copyright (C) 2004 ReactOS Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * VMware is a registered trademark of VMware, Inc.
 */
/*
 * COPYRIGHT:   See COPYING in the top level directory
 * PROJECT:     ReactOS VMware(r) driver installation utility
 * FILE:        subsys/system/vmwinst/vmwinst.c
 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
 *              Klemens Friedl (frik85@hotmail.com)
 */
#include <windows.h>
#include <commctrl.h>
#include <newdev.h>
#include <stdio.h>
#include <string.h>
#include "vmwinst.h"
#include <debug.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 PathToVideoDrivers60[MAX_PATH+1] = L"X:\\program files\\VMWare\\VMWare Tools\\Drivers\\video\\2k\\32bit\\";
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];
static WCHAR *vmx_fb = L"vmx_fb.dll";
static WCHAR *vmx_mode = L"vmx_mode.dll";
static WCHAR *vmx_mode_v6 = L"vmx mode.dll";
static WCHAR *vmx_svga = L"vmx_svga.sys";

static WCHAR *SrcPath = PathToVideoDrivers45;

static HANDLE hInstallationThread = NULL;
static HWND hInstallationNotifyWnd = NULL;
static LONG AbortInstall = 0;
#define WM_INSTABORT        (WM_USER + 2)
#define WM_INSTCOMPLETE     (WM_USER + 3)
#define WM_INSTSTATUSUPDATE (WM_USER + 4)

/* Helper functions */

LONG CALLBACK VectoredExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
  /* we're not running in VMware, just terminate the process */
  ExitProcess(ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION);
  return EXCEPTION_CONTINUE_EXECUTION;
}

BOOL
DetectVMware(int *Version)
{
  int magic, ver;

  magic = 0;
  ver = 0;

  /* 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)
  {
    *Version = ver;
    return TRUE;
  }

  return FALSE;
}

/* try to open the file */
static BOOL
FileExists(WCHAR *Path, WCHAR *File)
{
  WCHAR FileName[MAX_PATH + 1];
  HANDLE FileHandle;

  FileName[0] = L'\0';
  wcscat(FileName, Path);
  wcscat(FileName, File);

  FileHandle = CreateFile(FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  if(FileHandle == INVALID_HANDLE_VALUE)
  {
    /* If it was a sharing violation the file must already exist */
    return GetLastError() == ERROR_SHARING_VIOLATION;
  }

  if(GetFileSize(FileHandle, NULL) <= 0)
  {
    CloseHandle(FileHandle);
    return FALSE;
  }

  CloseHandle(FileHandle);
  return TRUE;
}

static VOID
CenterWindow(HWND hWnd)
{
  HWND hWndParent;
  RECT rcParent;
  RECT rcWindow;

  hWndParent = GetParent(hWnd);
  if (hWndParent == NULL)
    hWndParent = GetDesktopWindow();

  GetWindowRect(hWndParent, &rcParent);
  GetWindowRect(hWnd, &rcWindow);

  SetWindowPos(hWnd,
	       HWND_TOP,
	       ((rcParent.right - rcParent.left) - (rcWindow.right - rcWindow.left)) / 2,
	       ((rcParent.bottom - rcParent.top) - (rcWindow.bottom - rcWindow.top)) / 2,
	       0,
	       0,
	       SWP_NOSIZE);
}


/* Find the drive with the inserted VMware cd-rom */
static BOOL
IsVMwareCDInDrive(WCHAR *Drv)
{
  static WCHAR Drive[4] = L"X:\\";
  WCHAR Current;

  *Drv = L'\0';
  for(Current = 'C'; Current <= 'Z'; Current++)
  {
    Drive[0] = Current;
#if CHECKDRIVETYPE
    if(GetDriveType(Drive) == DRIVE_CDROM)
    {
#endif
      PathToVideoDrivers60[0] = Current;
      PathToVideoDrivers55[0] = Current;
      PathToVideoDrivers40[0] = Current;
      PathToVideoDrivers45[0] = Current;
      if(SetCurrentDirectory(PathToVideoDrivers60))
        SrcPath = PathToVideoDrivers60;
      else if(SetCurrentDirectory(PathToVideoDrivers55))
        SrcPath = PathToVideoDrivers55;
      else if(SetCurrentDirectory(PathToVideoDrivers45))
        SrcPath = PathToVideoDrivers45;
      else if(SetCurrentDirectory(PathToVideoDrivers40))
        SrcPath = PathToVideoDrivers40;
      else
      {
        SetCurrentDirectory(DestinationPath);
        continue;
      }

      if(FileExists(SrcPath, vmx_fb) &&
         (FileExists(SrcPath, vmx_mode) || FileExists(SrcPath, vmx_mode_v6)) &&
         FileExists(SrcPath, vmx_svga))
      {
        *Drv = Current;
        return TRUE;
      }
#if CHECKDRIVETYPE
    }
#endif
  }

  return FALSE;
}

static BOOL
LoadResolutionSettings(DWORD *ResX, DWORD *ResY, DWORD *ColDepth)
{
  HKEY hReg;
  DWORD Type, Size = sizeof(DWORD);

  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                  L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga\\Device0",
                  0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
  {
    DEVMODE CurrentDevMode;

    /* If this key is absent, just get current settings */
    memset(&CurrentDevMode, 0, sizeof(CurrentDevMode));
    CurrentDevMode.dmSize = sizeof(CurrentDevMode);
    if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &CurrentDevMode) == TRUE)
    {
      *ColDepth = CurrentDevMode.dmBitsPerPel;
      *ResX = CurrentDevMode.dmPelsWidth;
      *ResY = CurrentDevMode.dmPelsHeight;

      return TRUE;
    }
  }

  if(RegQueryValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, &Type, (BYTE*)ColDepth, &Size) != ERROR_SUCCESS ||
     Type != REG_DWORD)
  {
    *ColDepth = 8;
    Size = sizeof(DWORD);
  }

  if(RegQueryValueEx(hReg, L"DefaultSettings.XResolution", 0, &Type, (BYTE*)ResX, &Size) != ERROR_SUCCESS ||
     Type != REG_DWORD)
  {
    *ResX = 640;
    Size = sizeof(DWORD);
  }

  if(RegQueryValueEx(hReg, L"DefaultSettings.YResolution", 0, &Type, (BYTE*)ResY, &Size) != ERROR_SUCCESS ||
     Type != REG_DWORD)
  {
    *ResY = 480;
  }

  RegCloseKey(hReg);
  return TRUE;
}

static BOOL
IsVmwSVGAEnabled(VOID)
{
  HKEY hReg;
  DWORD Type, Size, Value;

  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                  L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga",
                  0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
  {
    return FALSE;
  }
  if(RegQueryValueEx(hReg, L"Start", 0, &Type, (BYTE*)&Value, &Size) != ERROR_SUCCESS ||
     Type != REG_DWORD)
  {
    RegCloseKey(hReg);
    return FALSE;
  }

  RegCloseKey(hReg);
  return (Value == 1);
}



static BOOL
SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
{
  HKEY hReg;
  DWORD VFreq = 85;

  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                  L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga\\Device0",
                  0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS)
  {
    return FALSE;
  }
  if(RegSetValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, REG_DWORD, (BYTE*)&ColDepth, sizeof(DWORD)) != ERROR_SUCCESS)
  {
    RegCloseKey(hReg);
    return FALSE;
  }

  if(RegSetValueEx(hReg, L"DefaultSettings.XResolution", 0, REG_DWORD, (BYTE*)&ResX, sizeof(DWORD)) != ERROR_SUCCESS)
  {
    RegCloseKey(hReg);
    return FALSE;
  }

  if(RegSetValueEx(hReg, L"DefaultSettings.YResolution", 0, REG_DWORD, (BYTE*)&ResY, sizeof(DWORD)) != ERROR_SUCCESS)
  {
    RegCloseKey(hReg);
    return FALSE;
  }

  if(RegSetValueEx(hReg, L"DefaultSettings.VRefresh", 0, REG_DWORD, (BYTE*)&VFreq, sizeof(DWORD)) != ERROR_SUCCESS)
  {
    RegCloseKey(hReg);
    return FALSE;
  }

  RegCloseKey(hReg);
  return TRUE;
}

static BOOL
EnableDriver(WCHAR *Key, BOOL Enable)
{
  DWORD Value;
  HKEY hReg;

  Value = (Enable ? 1 : 4);

  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, Key, 0, KEY_SET_VALUE, &hReg) != ERROR_SUCCESS)
  {
    return FALSE;
  }
  if(RegSetValueEx(hReg, L"Start", 0, REG_DWORD, (BYTE*)&Value, sizeof(DWORD)) != ERROR_SUCCESS)
  {
    RegCloseKey(hReg);
    return FALSE;
  }

  RegCloseKey(hReg);
  return TRUE;
}

/* Activate the vmware driver and deactivate the others */
static BOOL
EnableVmwareDriver(BOOL VBE, BOOL VGA, BOOL VMX)
{
  if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\VBE", VBE))
  {
    return FALSE;
  }
  if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\vga", VGA))
  {
    return FALSE;
  }
  if(!EnableDriver(L"SYSTEM\\CurrentControlSet\\Services\\vmx_svga", VMX))
  {
    return FALSE;
  }

  return TRUE;
}

/* GUI */


/* Property page dialog callback */
static INT_PTR CALLBACK
PageWelcomeProc(
  HWND hwndDlg,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam
)
{
  LPNMHDR pnmh = (LPNMHDR)lParam;
  switch(uMsg)
  {
    case WM_NOTIFY:
    {
      HWND hwndControl;

      /* Center the wizard window */
      hwndControl = GetParent(hwndDlg);
      CenterWindow (hwndControl);

      switch(pnmh->code)
      {
        case PSN_SETACTIVE:
        {
          PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
          break;
        }
        case PSN_WIZNEXT:
        {
          if(DriverFilesFound)
          {
            SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CONFIG);
            return TRUE;
          }
          break;
        }
      }
      break;
    }
  }
  return FALSE;
}

/* Property page dialog callback */
static INT_PTR CALLBACK
PageInsertDiscProc(
  HWND hwndDlg,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam
)
{
  switch(uMsg)
  {
    case WM_NOTIFY:
    {
      LPNMHDR pnmh = (LPNMHDR)lParam;
      switch(pnmh->code)
      {
        case PSN_SETACTIVE:
          PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
          break;
        case PSN_WIZNEXT:
          SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_INSTALLING_VMWARE_TOOLS);
          break;
      }
      break;
    }
  }
  return FALSE;
}

static VOID
InstTerminateInstaller(BOOL Wait)
{
  if(hInstallationThread != NULL)
  {
    if(Wait)
    {
      InterlockedExchange((LONG*)&AbortInstall, 2);
      WaitForSingleObject(hInstallationThread, INFINITE);
    }
    else
    {
      InterlockedExchange((LONG*)&AbortInstall, 1);
    }
  }
}

static DWORD STDCALL
InstInstallationThread(LPVOID lpParameter)
{
  HANDLE hThread;
  WCHAR InfFileName[1024];
  BOOL DriveAvailable;
  int DrivesTested = 0;

  if(AbortInstall != 0) goto done;
  PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_SEARCHINGFORCDROM, 0);

  while(AbortInstall == 0)
  {
    Sleep(500);
    DriveAvailable = IsVMwareCDInDrive(&CDDrive);
    if(DriveAvailable)
      break;
    if(DrivesTested++ > 20)
    {
      PostMessage(hInstallationNotifyWnd, WM_INSTABORT, IDS_FAILEDTOLOCATEDRIVERS, 0);
      goto cleanup;
    }
  }

  if(AbortInstall != 0) goto done;
  PostMessage(hInstallationNotifyWnd, WM_INSTSTATUSUPDATE, IDS_COPYINGFILES, 0);

  wcscpy(InfFileName, SrcPath);
  wcscat(InfFileName, L"vmx_svga.inf");
  DPRINT1("Calling UpdateDriverForPlugAndPlayDevices()\n");
  if (!UpdateDriverForPlugAndPlayDevices(
    hInstallationNotifyWnd,
    L"PCI\\VEN_15AD&DEV_0405&SUBSYS_040515AD&REV_00",
    InfFileName,
    0,
    NULL))
  {
    AbortInstall = 1;
  }
  else
  {
    AbortInstall = 0;
  }

done:
  switch(AbortInstall)
  {
    case 0:
      SendMessage(hInstallationNotifyWnd, WM_INSTCOMPLETE, 0, 0);
      break;
    case 1:
      SendMessage(hInstallationNotifyWnd, WM_INSTABORT, 0, 0);
      break;
  }

cleanup:
  hThread = (HANDLE)InterlockedExchange((LONG*)&hInstallationThread, 0);
  if(hThread != NULL)
  {
    CloseHandle(hThread);
  }
  return 0;
}

static BOOL
InstStartInstallationThread(HWND hwndNotify)
{
  if(hInstallationThread == NULL)
  {
    DWORD ThreadId;
    hInstallationNotifyWnd = hwndNotify;
    AbortInstall = 0;
    hInstallationThread = CreateThread(NULL,
                                       0,
                                       InstInstallationThread,
                                       NULL,
                                       CREATE_SUSPENDED,
                                       &ThreadId);
    if(hInstallationThread == NULL)
    {
      return FALSE;
    }

    ResumeThread(hInstallationThread);
    return TRUE;
  }

  return FALSE;
}

/* Property page dialog callback */
static INT_PTR CALLBACK
PageInstallingProc(
  HWND hwndDlg,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -