|
|
//
// 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, // ISSUE-2002/01/16-roelfc: -- 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; }
|