vmwinst.c

来自「一个类似windows」· C语言 代码 · 共 1,250 行 · 第 1/3 页

C
1,250
字号
/*
 * 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.
 */
/* $Id: vmwinst.c 21633 2006-04-17 12:16:54Z hpoussin $
 *
 * 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 <stdio.h>
#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];
static WCHAR *vmx_fb = L"vmx_fb.dll";
static WCHAR *vmx_mode = 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;
}

BOOL
ProcessMessage(void)
{
  MSG msg;
  if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    return TRUE;
  }
  return FALSE;
}

void
ProcessMessages(void)
{
  while(ProcessMessage());
}

/* try to open the file */
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);
}


/* Copy file */
BOOL
InstallFile(WCHAR *Destination, WCHAR *File)
{
  static char Buffer[1024];
  WCHAR SourceFileName[MAX_PATH + 1];
  WCHAR DestFileName[MAX_PATH + 1];
  HANDLE SourceFileHandle, DestFileHandle;
  DWORD DataRead, DataWritten;

  SourceFileName[0] = L'\0';
  DestFileName[0] = L'\0';
  wcscat(SourceFileName, SrcPath);
  wcscat(SourceFileName, File);
  wcscat(DestFileName, Destination);
  wcscat(DestFileName, File);

  SourceFileHandle = CreateFile(SourceFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if(SourceFileHandle == INVALID_HANDLE_VALUE)
  {
    return FALSE;
  }
  DestFileHandle = CreateFile(DestFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if(DestFileHandle == INVALID_HANDLE_VALUE)
  {
    CloseHandle(SourceFileHandle);
    return FALSE;
  }

  while(ReadFile(SourceFileHandle, Buffer, sizeof(Buffer), &DataRead, NULL) && DataRead > 0)
  {
    if(!WriteFile(DestFileHandle, Buffer, DataRead, &DataWritten, NULL) ||
       DataRead != DataWritten)
    {
      CloseHandle(SourceFileHandle);
      CloseHandle(DestFileHandle);
      DeleteFile(DestFileName);
      return FALSE;
    }
  }

  CloseHandle(SourceFileHandle);
  CloseHandle(DestFileHandle);
  return TRUE;
}

/* Find the drive with the inserted VMware cd-rom */
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
      PathToVideoDrivers55[0] = Current;
      PathToVideoDrivers40[0] = Current;
      PathToVideoDrivers45[0] = Current;
      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_svga))
      {
        *Drv = Current;
        return TRUE;
      }
#if CHECKDRIVETYPE
    }
#endif
  }

  return FALSE;
}

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

  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                  L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vmx_svga\\Device0",
                  0, KEY_QUERY_VALUE, &hReg) != ERROR_SUCCESS)
  {
    return FALSE;
  }
  if(RegQueryValueEx(hReg, L"DefaultSettings.BitsPerPel", 0, &Type, (BYTE*)ColDepth, &Size) != ERROR_SUCCESS ||
     Type != REG_DWORD)
  {
    RegCloseKey(hReg);
    return FALSE;
  }

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

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

  RegCloseKey(hReg);
  return TRUE;
}

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);
}



BOOL
SaveResolutionSettings(DWORD ResX, DWORD ResY, DWORD ColDepth)
{
  HKEY hReg;

  if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                  L"SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\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;
  }

  RegCloseKey(hReg);
  return TRUE;
}

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 */
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;
}

/* 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)
  {

⌨️ 快捷键说明

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