205 lines
5.4 KiB
C++
205 lines
5.4 KiB
C++
// 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;
|
|
}
|
|
|