windows-nt/Source/XPSP1/NT/shell/ext/hnw/nconn16/theapp.cpp
2020-09-26 16:20:57 +08:00

537 lines
16 KiB
C++

//
// TheApp.cpp
//
// 16-bit code to install network components such as TCP/IP.
//
// History:
//
// 2/02/1999 KenSh Created for JetNet, largely from Internet Connection Wizard
// 9/29/1999 KenSh Adapterd for Home Networking Wizard
//
#include "stdafx.h"
#include <string.h>
#include <regstr.h>
#include "NConn16.h"
#include "strstri.h"
extern "C"
{
// Define missing decs so it builds.
typedef HKEY* LPHKEY;
typedef const BYTE* LPCBYTE;
#define WINCAPI
// missing
#include <setupx.h>
#include <netdi.h>
}
#ifndef _countof
#define _countof(ar) (sizeof(ar) / sizeof((ar)[0]))
#endif
extern "C" BOOL FAR PASCAL thk_ThunkConnect16(LPSTR pszDll16,
LPSTR pszDll32,
WORD hInst,
DWORD dwReason);
//
// SetupX function prototypes
//
typedef RETERR (WINAPI PASCAL FAR * PROC_DiOpenDevRegKey)(
LPDEVICE_INFO lpdi,
LPHKEY lphk,
int iFlags);
typedef DWORD (WINAPI FAR * PROC_SURegSetValueEx)(HKEY hKey,LPCSTR lpszValueName, DWORD dwReserved, DWORD dwType, LPBYTE lpszValue, DWORD dwValSize);
typedef RETERR (WINAPI FAR * PROC_DiCreateDeviceInfo)(
LPLPDEVICE_INFO lplpdi, // Ptr to ptr to dev info
LPCSTR lpszDescription, // If non-null then description string
DWORD hDevnode, // BUGBUG -- MAKE A DEVNODE
HKEY hkey, // Registry hkey for dev info
LPCSTR lpszRegsubkey, // If non-null then reg subkey string
LPCSTR lpszClassName, // If non-null then class name string
HWND hwndParent); // If non-null then hwnd of parent
typedef RETERR (WINAPI FAR * PROC_DiDestroyDeviceInfoList)(LPDEVICE_INFO lpdi);
typedef RETERR (WINAPI FAR * PROC_DiCallClassInstaller)(DI_FUNCTION diFctn, LPDEVICE_INFO lpdi);
typedef DWORD (WINAPI FAR * PROC_SURegCloseKey)(HKEY hKey);
typedef RETERR (WINAPI FAR * PROC_DiGetClassDevs)(
LPLPDEVICE_INFO lplpdi, // Ptr to ptr to dev info
LPCSTR lpszClassName, // Must be name of class
HWND hwndParent, // If non-null then hwnd of parent
int iFlags); // Options
typedef RETERR (WINAPI FAR * PROC_DiSelectDevice)( LPDEVICE_INFO lpdi );
typedef RETERR (WINAPI FAR * PROC_DiBuildCompatDrvList)(LPDEVICE_INFO lpdi);
typedef RETERR (WINAPI FAR * PASCAL PROC_DiCreateDevRegKey)(
LPDEVICE_INFO lpdi,
LPHKEY lphk,
HINF hinf,
LPCSTR lpszInfSection,
int iFlags);
typedef RETERR (WINAPI FAR * PASCAL PROC_DiDeleteDevRegKey)(LPDEVICE_INFO lpdi, int iFlags);
PROC_DiOpenDevRegKey _pfnDiOpenDevRegKey;
PROC_SURegSetValueEx _pfnSURegSetValueEx;
PROC_DiCreateDeviceInfo _pfnDiCreateDeviceInfo;
PROC_DiDestroyDeviceInfoList _pfnDiDestroyDeviceInfoList;
PROC_DiCallClassInstaller _pfnDiCallClassInstaller;
PROC_SURegCloseKey _pfnSURegCloseKey;
PROC_DiGetClassDevs _pfnDiGetClassDevs;
PROC_DiSelectDevice _pfnDiSelectDevice;
PROC_DiBuildCompatDrvList _pfnDiBuildCompatDrvList;
PROC_DiCreateDevRegKey _pfnDiCreateDevRegKey;
PROC_DiDeleteDevRegKey _pfnDiDeleteDevRegKey;
int g_cSetupxInit = 0;
HINSTANCE g_hInstSetupx = NULL;
BOOL InitSetupx()
{
if (g_hInstSetupx == NULL)
{
g_hInstSetupx = LoadLibrary("setupx.dll");
if (g_hInstSetupx < (HINSTANCE)HINSTANCE_ERROR)
return FALSE;
_pfnDiOpenDevRegKey = (PROC_DiOpenDevRegKey)GetProcAddress(g_hInstSetupx, "DiOpenDevRegKey");
_pfnSURegSetValueEx = (PROC_SURegSetValueEx)GetProcAddress(g_hInstSetupx, "SURegSetValueEx");
_pfnDiCreateDeviceInfo = (PROC_DiCreateDeviceInfo)GetProcAddress(g_hInstSetupx, "DiCreateDeviceInfo");
_pfnDiDestroyDeviceInfoList = (PROC_DiDestroyDeviceInfoList)GetProcAddress(g_hInstSetupx, "DiDestroyDeviceInfoList");
_pfnDiCallClassInstaller = (PROC_DiCallClassInstaller)GetProcAddress(g_hInstSetupx, "DiCallClassInstaller");
_pfnSURegCloseKey = (PROC_SURegCloseKey)GetProcAddress(g_hInstSetupx, "SURegCloseKey");
_pfnDiGetClassDevs = (PROC_DiGetClassDevs)GetProcAddress(g_hInstSetupx, "DiGetClassDevs");
_pfnDiSelectDevice = (PROC_DiSelectDevice)GetProcAddress(g_hInstSetupx, "DiSelectDevice");
_pfnDiBuildCompatDrvList = (PROC_DiBuildCompatDrvList)GetProcAddress(g_hInstSetupx, "DiBuildCompatDrvList");
_pfnDiCreateDevRegKey = (PROC_DiCreateDevRegKey)GetProcAddress(g_hInstSetupx, "DiCreateDevRegKey");
_pfnDiDeleteDevRegKey = (PROC_DiDeleteDevRegKey)GetProcAddress(g_hInstSetupx, "DiDeleteDevRegKey");
}
g_cSetupxInit++;
return TRUE;
}
void UninitSetupx()
{
if (g_cSetupxInit > 0)
g_cSetupxInit--;
if (g_cSetupxInit == 0)
{
if (g_hInstSetupx != NULL)
{
FreeLibrary(g_hInstSetupx);
g_hInstSetupx = NULL;
}
}
}
extern "C" int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine)
{
if (wHeapSize != 0)
{
// UnlockData is no longer #defined to UnlockSegment(-1) in windows.h,
// so do it manually here:
//
//UnlockData(0);
UnlockSegment(-1);
}
return 1;
}
extern "C" BOOL FAR PASCAL __export DllEntryPoint(DWORD dwReason, WORD hInstance, WORD wDS, WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
{
if (!thk_ThunkConnect16(
"NCXP16.DLL",
"NCXP32.DLL",
hInstance, dwReason))
{
return FALSE;
}
return TRUE;
}
extern "C" int CALLBACK WEP(int nExitType)
{
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#define ASSERT(x)
// Local function declarations
DWORD CallClassInstaller(HWND hwndParent, LPCSTR lpszClassName, LPCSTR lpszDeviceID);
DWORD BindProtocolToAdapters(HWND hwndParent, LPCSTR lpszClassName, LPCSTR lpszDeviceID);
//////////////////////////////////////////////////////////////////////////////
// String constants
// TODO: clean these up... most of them aren't used any more
// Device Manager class names
const char szClassNetCard[] = "Net";
const char szClassNetClient[] = "NetClient";
const char szClassNetProtocol[] = "NetTrans";
const char szClassModem[] = "Modem";
// Device ID string constants
const char szMSTCPIP_ID[] = "MSTCP";
const char szPPPMAC_ID[] = "*PNP8387";
const char szVREDIR_ID[] = "VREDIR";
const char szNWREDIR_ID[] = "NWREDIR";
const char szIPX_ID[] = "NWLINK";
const char szNETBEUI_ID[] = "NETBEUI";
// Registry string constants
const char szRegValSlowNet[] = "SLOWNET";
const char szRegKeyNdi[] = "Ndi";
const char szRegValDeviceID[] = "DeviceID";
const char szRegKeyBindings[] = "Bindings";
const char szRegPathOptComponents[]=REGSTR_PATH_SETUP REGSTR_KEY_SETUP "\\OptionalComponents";
const char szRegValInstalled[] = "Installed";
const char szRegPathNetwork[] = "Enum\\Network";
const char szRegPathTemp[] = "\\Temp";
const char szRegValCompatibleIDs[]= REGSTR_VAL_COMPATIBLEIDS;
const char szRegValDeviceType[] = REGSTR_VAL_DEVTYPE;
const char szRegValConfigFlags[] = REGSTR_VAL_CONFIGFLAGS;
const char szRegPathPlusSetup[] = "Software\\Microsoft\\Plus!\\Setup";
const char szRegValSourcePath[] = "SourcePath";
const char szRegValHardwareID[] = "HardwareID";
// component string constants
const char szCompRNA[] = "RNA";
const char szCompMail[] = "MAPI";
const char szCompMSN[] = "MSNetwork";
const char szCompMSN105[] = "MSNetwork105";
const char szCompInetMail[] = "InternetMail";
const char szINF[] = "INF";
const char szSection[] = "Section";
// INF string constants
const char szValSignature[] = "$CHICAGO$";
const char szKeySignature[] = "signature";
const char szSectVersion[] = "version";
// other strings
const char szNull[] = "";
const char sz1[] = "1";
const char szSlash[] = "\\";
//////////////////////////////////////////////////////////////////////////////
// CreateTempDevRegKey
//
// Creates a temporary registry key for the device installer.
//
// History:
//
// 2/02/1999 KenSh Borrowed from ICW, which borrowed it from net setup
//
RETERR CreateTempDevRegKey(LPDEVICE_INFO lpdi,LPHKEY lphk)
{
lpdi->hRegKey = HKEY_LOCAL_MACHINE;
lstrcpy(lpdi->szRegSubkey, szRegPathNetwork);
lstrcat(lpdi->szRegSubkey, szSlash);
lstrcat(lpdi->szRegSubkey, lpdi->szClassName);
lstrcat(lpdi->szRegSubkey, szRegPathTemp);
InitSetupx();
RETERR err = (*_pfnDiCreateDevRegKey)(lpdi, lphk, NULL, NULL, DIREG_DEV);
UninitSetupx();
return err;
}
// CallClassInstaller
//
// Calls DiCallClassInstaller for the specified class to install
// the specified device ID
//
// Returns ICERR_xxx return value, defined in NetSetup.h
//
// Parameters:
//
// hwndParent - parent window handle
// lpszClassName - name of device class (e.g. "NetTrans" or "Net")
// lpszDeviceID - unique device ID to install (e.g. "MSTCP" or "PCI\VEN_10b7&DEV_5950"
//
// History:
//
// 2/02/1999 KenSh Borrowed from ICW, changed return codes for JetNet
// 3/18/1999 KenSh Cleaned up
//
extern "C" DWORD WINAPI __export CallClassInstaller16(HWND hwndParent, LPCSTR lpszClassName, LPCSTR lpszDeviceID)
{
RETERR err;
DWORD dwResult = ICERR_OK;
LPDEVICE_INFO lpdi;
HKEY hKeyTmp;
LONG uErr;
ASSERT(lpszClassName != NULL);
ASSERT(lpszDeviceID != NULL);
if (!InitSetupx())
return ICERR_DI_ERROR;
// allocate a DEVICE_INFO struct
err = (*_pfnDiCreateDeviceInfo)(&lpdi, NULL, 0, NULL, NULL, lpszClassName, hwndParent);
ASSERT(err == OK);
if (err != OK)
{
lpdi = NULL;
goto exit;
}
// since the device manager APIs are not very good, to communicate the
// device ID to it we have to create a temporary registry key and
// store the device ID there. This code borrowed from net setup
// which has to do the same thing (fill out an LPDEVICE_INFO based
// on a device ID)
err = CreateTempDevRegKey(lpdi, &hKeyTmp);
ASSERT (err == OK);
if (err != OK)
goto exit;
// set the device ID in the registry
uErr = RegSetValueEx(hKeyTmp, szRegValCompatibleIDs,
0, REG_SZ, (LPBYTE)lpszDeviceID, lstrlen(lpszDeviceID)+1);
ASSERT(uErr == ERROR_SUCCESS);
// now call device mgr API to add driver node lists and fill out structure,
// it will use the device ID we stuffed in registry.
err = (*_pfnDiBuildCompatDrvList)(lpdi);
ASSERT(err == OK);
RegCloseKey(hKeyTmp);
// need to delete temp key, set handle to null, set subkey name to
// null or else net setup thinks this device already exists and
// zany hijinks ensue
(*_pfnDiDeleteDevRegKey)(lpdi, DIREG_DEV);
lpdi->hRegKey = NULL;
lstrcpy(lpdi->szRegSubkey, szNull);
if (err == OK)
{
lpdi->lpSelectedDriver = lpdi->lpCompatDrvList;
ASSERT(lpdi->lpSelectedDriver);
err = (*_pfnDiCallClassInstaller)(DIF_INSTALLDEVICE, lpdi);
ASSERT(err == OK);
if (err == OK)
{
// if we need to reboot, set a special return code NEED_RESTART
// (which also implies success)
if (lpdi->Flags & DI_NEEDREBOOT)
{
// REVIEW: does this need to reboot, or is restart sufficient?
// err = NEED_RESTART;
dwResult = ICERR_NEED_RESTART;
}
}
}
exit:
if (lpdi != NULL)
(*_pfnDiDestroyDeviceInfoList)(lpdi);
if (err != OK)
dwResult = ICERR_DI_ERROR | (DWORD)err;
UninitSetupx();
return dwResult;
}
extern "C" HRESULT WINAPI __export FindClassDev16(HWND hwndParent, LPCSTR pszClass, LPCSTR pszDeviceID)
{
DWORD hr = S_FALSE;
LPDEVICE_INFO lpdi;
RETERR err;
if (!InitSetupx())
return E_FAIL;
if (OK != (err = (*_pfnDiGetClassDevs)(&lpdi, pszClass, NULL, DIGCF_PRESENT)))
{
UninitSetupx();
return E_FAIL;
}
// This is 16-bit code, so these pnp ids are ANSI only
//
LPSTR pszAlternateDeviceID = new char[lstrlen(pszDeviceID) + 1];
if (pszAlternateDeviceID)
{
lstrcpy(pszAlternateDeviceID, pszDeviceID);
LPCSTR szSubsysString = "SUBSYS_";
const int nSubsysIDLength = 8;
LPSTR pszSubsys = strstri(pszAlternateDeviceID, szSubsysString);
if(NULL != pszSubsys)
{
pszSubsys += _countof("SUBSYS_") - 1;
if(nSubsysIDLength <= lstrlen(pszSubsys))
{
for(int i = 0; i < nSubsysIDLength; i++)
{
pszSubsys[i] = '0';
}
}
}
for (LPDEVICE_INFO lpdiCur = lpdi; lpdiCur != NULL; lpdiCur = lpdiCur->lpNextDi)
{
char szBuf[1024];
// wsprintf(szBuf, "System\\CurrentControlSet\\Services\\Class\\%s\\%04d", pszClass, (int)lpdiCur->dnDevnode);
// MessageBox(NULL, szBuf, "RegKey", MB_OK);
HKEY hKey;
if (OK == (*_pfnDiOpenDevRegKey)(lpdiCur, &hKey, DIREG_DEV))
{
static const LPCSTR c_rgRegEntries[] = { "HardwareID", "CompatibleIDs" };
for (int i = 0; i < _countof(c_rgRegEntries); i++)
{
LONG cbBuf = sizeof(szBuf);
if (ERROR_SUCCESS == RegQueryValueEx(hKey, c_rgRegEntries[i], NULL, NULL, (LPBYTE)szBuf, &cbBuf))
{
// char szBuf2[1600];
// wsprintf(szBuf2, "Looking for: %s\n\n%s", pszDeviceID, szBuf);
// MessageBox(NULL, szBuf2, c_rgRegEntries[i], MB_OK);
// aslo check with SUBSYS 00000000 for bug 124967
if (NULL != strstri(szBuf, pszDeviceID) || NULL != strstri(szBuf, pszAlternateDeviceID))
{
hr = S_OK;
break;
}
}
}
RegCloseKey(hKey);
}
if (hr == S_OK)
break;
}
delete [] pszAlternateDeviceID;
}
(*_pfnDiDestroyDeviceInfoList)(lpdi);
UninitSetupx();
return hr;
}
extern "C" HRESULT WINAPI __export LookupDevNode16(HWND hwndParent, LPCSTR pszClass, LPCSTR pszEnumKey, DEVNODE FAR* pDevNode, DWORD FAR* pdwFreePointer)
{
DWORD hr = S_FALSE;
LPDEVICE_INFO lpdi;
RETERR err;
// MessageBox(hwndParent, "LookupDevNode16", "Debug", MB_ICONINFORMATION);
if (pDevNode == NULL || pdwFreePointer == NULL)
{
// MessageBox(hwndParent, "Returning failure 0", "Debug", 0);
return E_POINTER;
}
*pDevNode = 0;
*pdwFreePointer = 0;
if (!InitSetupx())
{
// MessageBox(hwndParent, "Returning failure 1", "Debug", 0);
return E_FAIL;
}
if (OK != (err = (*_pfnDiGetClassDevs)(&lpdi, pszClass, NULL, DIGCF_PRESENT)))
{
// MessageBox(hwndParent, "Returning failure 2", "Debug", 0);
UninitSetupx();
return E_FAIL;
}
for (LPDEVICE_INFO lpdiCur = lpdi; lpdiCur != NULL; lpdiCur = lpdiCur->lpNextDi)
{
// char szBuf[1024];
// wsprintf(szBuf, "comparing:\nlpdiCur->pszRegSubkey = \"%s\"\npszEnumKey = \"%s\"",
// (LPSTR)lpdiCur->szRegSubkey, (LPSTR)pszEnumKey);
// MessageBox(hwndParent, szBuf, "Debug", MB_ICONINFORMATION);
if (0 == lstrcmpi(lpdiCur->szRegSubkey, pszEnumKey))
{
// wsprintf(szBuf, "found devnode 0x%08lX, pvFreePointer = 0x%08lX", (DWORD)lpdiCur->dnDevnode, (DWORD)lpdi);
// MessageBox(hwndParent, szBuf, "Debug", MB_ICONINFORMATION);
*pDevNode = lpdiCur->dnDevnode;
*pdwFreePointer = (DWORD)lpdi;
return S_OK;
}
}
(*_pfnDiDestroyDeviceInfoList)(lpdi);
UninitSetupx();
// MessageBox(hwndParent, "returning failure", "Debug", MB_ICONINFORMATION);
return E_FAIL; // not found
}
extern "C" HRESULT WINAPI __export FreeDevNode16(DWORD dwFreePointer)
{
LPDEVICE_INFO lpdi = (LPDEVICE_INFO)dwFreePointer;
if (lpdi == NULL)
{
return E_INVALIDARG;
}
if (g_hInstSetupx == NULL)
{
return E_FAIL;
}
// char szBuf[1024];
// wsprintf(szBuf, "FreeDevNode16 - freeing lpdi 0x%08lX - continue?", dwFreePointer);
// if (IDYES == MessageBox(NULL, szBuf, "Debug", MB_YESNO | MB_ICONEXCLAMATION))
{
(*_pfnDiDestroyDeviceInfoList)(lpdi);
}
UninitSetupx();
return S_OK;
}
extern "C" HRESULT WINAPI __export IcsUninstall16(void)
{
typedef void (WINAPI *RUNDLLPROC)(HWND hwndStub, HINSTANCE hAppInstance, LPSTR lpszCmdLine, int nCmdShow);
HINSTANCE hInstance = LoadLibrary("issetup.dll");
if(hInstance > 32)
{
RUNDLLPROC pExtUninstall = (RUNDLLPROC) GetProcAddress(hInstance, "ExtUninstall");
if(NULL != pExtUninstall)
{
pExtUninstall(NULL, NULL, NULL, 0);
}
FreeLibrary(hInstance);
}
return S_OK;
}