|
|
// File: setupdd.cpp
// The code to install the NM display driver for Windows NT.
// TODO: NM-specific HRESULT codes
#include "precomp.h"
#include "resource.h"
#ifdef NMDLL_HACK
inline HINSTANCE GetInstanceHandle() { return g_hInst; } #endif
const TCHAR g_pcszDisplayCPLName[] = TEXT("DESK.CPL"); const CHAR g_pcszInstallDriverAPIName[] = "InstallGraphicsDriver"; const WCHAR g_pcwszDefaultModelName[] = L"Microsoft NetMeeting graphics driver"; const WCHAR g_pcwszDefaultINFName[] = L"MNMDD.INF";
// Maxmimum size of the model name string
const int NAME_BUFFER_SIZE = 128;
// Prototype for the function installed by the Display CPL
typedef DWORD (*PFNINSTALLGRAPHICSDRIVER)( HWND hwnd, LPCWSTR pszSourceDirectory, LPCWSTR pszModel, LPCWSTR pszInf );
/* C A N I N S T A L L N T D I S P L A Y D R I V E R */ /*-------------------------------------------------------------------------
%%Function: CanInstallNTDisplayDriver This function determines whether the entry point for installing the NT display driver is availalble (i.e. NT 4.0 SP3 or later). -------------------------------------------------------------------------*/ HRESULT CanInstallNTDisplayDriver(void) { if (!IsWindowsNT()) { return E_FAIL; }
// We verify that the major version number is exactly 4 and either
// the minor version number is greater than 0 or the service pack
// number (which is stored in the high byte of the low word of the
// CSD version) is 3 or greater.
OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(osvi); if (FALSE == ::GetVersionEx(&osvi)) { ERROR_OUT(("CanInstallNTDisplayDriver: GetVersionEx failed")); return E_FAIL; }
HRESULT hr = E_FAIL; if (4 == osvi.dwMajorVersion) { if (0 == osvi.dwMinorVersion) { RegEntry re(NT_WINDOWS_SYSTEM_INFO_KEY, HKEY_LOCAL_MACHINE, FALSE); DWORD dwCSDVersion = re.GetNumber(REGVAL_NT_CSD_VERSION, 0); if (3 <= HIBYTE(LOWORD(dwCSDVersion))) { // This is NT 4.0, SP 3 or later
hr = S_OK; } } else { // We assume that any future version of Windows NT 4.x (x > 0)
// will support this.
hr = S_OK; } }
return hr; }
/* I N S T A L L A P P S H A R I N G D D */ /*-------------------------------------------------------------------------
%%Function: InstallAppSharingDD
This function attempts to install the NT display driver. If it succeeds the machine MUST BE RESTARTED before it can be used. -------------------------------------------------------------------------*/ HRESULT InstallAppSharingDD(HWND hwnd) { HRESULT hr; CUSTRING custrPath; TCHAR szDir[MAX_PATH]; LPWSTR pwszSourcePath = NULL; LPWSTR pwszSourcePathEnd; WCHAR pwszModelNameBuffer[NAME_BUFFER_SIZE]; LPCWSTR pcwszModelName; WCHAR pwszINFNameBuffer[MAX_PATH]; LPCWSTR pcwszINFName; PFNINSTALLGRAPHICSDRIVER pfnInstallGraphicsDriver;
// REVIEW: Need NM-specific HRESULTS for all of these
if (!IsWindowsNT()) { return E_FAIL; }
if (!CanInstallNTDisplayDriver()) { return E_FAIL; }
// The driver files are located in the NM directory.
if (!GetInstallDirectory(szDir)) { ERROR_OUT(("GetInstallDirectory() fails")); return E_FAIL; }
// Convert the install directory to Unicode, if necessary
custrPath.AssignString(szDir); pwszSourcePath = custrPath; if (NULL == pwszSourcePath) { ERROR_OUT(("AnsiToUnicode() fails")); return E_FAIL; }
// Strip the trailing backslash that GetInstallDirectory appends
pwszSourcePathEnd = pwszSourcePath + lstrlenW(pwszSourcePath); // Handle X:\, just to be safe
if (pwszSourcePathEnd - pwszSourcePath > 3) { ASSERT(L'\\' == *(pwszSourcePathEnd - 1)); *--pwszSourcePathEnd = L'\0'; }
// Read the model name string from the resource file
if (0 != ::LoadStringW(::GetInstanceHandle(), IDS_NMDD_DISPLAYNAME, pwszModelNameBuffer, CCHMAX(pwszModelNameBuffer))) { pcwszModelName = pwszModelNameBuffer; } else { ERROR_OUT(("LoadStringW() fails, err=%lu", GetLastError())); pcwszModelName = g_pcwszDefaultModelName; }
// Read the INF name string from the resource file
if (0 < ::LoadStringW(::GetInstanceHandle(), IDS_NMDD_INFNAME, pwszINFNameBuffer, CCHMAX(pwszINFNameBuffer))) { pcwszINFName = pwszINFNameBuffer; } else { ERROR_OUT(("LoadStringW() fails, err=%lu", GetLastError())); pcwszINFName = g_pcwszDefaultINFName; }
// Get the entry point for display driver installation
HMODULE hDll = NmLoadLibrary(g_pcszDisplayCPLName,TRUE); if (NULL == hDll) { ERROR_OUT(("NmLoadLibrary failed on %s", g_pcszDisplayCPLName)); return E_FAIL; }
pfnInstallGraphicsDriver = (PFNINSTALLGRAPHICSDRIVER) GetProcAddress(hDll, g_pcszInstallDriverAPIName); if (NULL == pfnInstallGraphicsDriver) { ERROR_OUT(("GetInstallDisplayDriverEntryPoint() fails")); hr = E_FAIL; } else { // Now we're set to call the actual installation function
DWORD dwErr = (*pfnInstallGraphicsDriver)(hwnd, pwszSourcePath, pcwszModelName, pcwszINFName); if (0 != dwErr) { ERROR_OUT(("InstallGraphicsDriver() fails, err=%lu", dwErr)); hr = E_FAIL; } else { WARNING_OUT(("InstallGraphicsDriver() succeeded")); hr = S_OK; } }
// Cleanup
ASSERT(NULL != hDll); FreeLibrary(hDll);
return hr; }
|