Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

536 lines
17 KiB

  1. //
  2. // TheApp.cpp
  3. //
  4. // 16-bit code to install network components such as TCP/IP.
  5. //
  6. // History:
  7. //
  8. // 2/02/1999 KenSh Created for JetNet, largely from Internet Connection Wizard
  9. // 9/29/1999 KenSh Adapterd for Home Networking Wizard
  10. //
  11. #include "stdafx.h"
  12. #include <string.h>
  13. #include <regstr.h>
  14. #include "NConn16.h"
  15. #include "strstri.h"
  16. extern "C"
  17. {
  18. // Define missing decs so it builds.
  19. typedef HKEY* LPHKEY;
  20. typedef const BYTE* LPCBYTE;
  21. #define WINCAPI
  22. // missing
  23. #include <setupx.h>
  24. #include <netdi.h>
  25. }
  26. #ifndef _countof
  27. #define _countof(ar) (sizeof(ar) / sizeof((ar)[0]))
  28. #endif
  29. extern "C" BOOL FAR PASCAL thk_ThunkConnect16(LPSTR pszDll16,
  30. LPSTR pszDll32,
  31. WORD hInst,
  32. DWORD dwReason);
  33. //
  34. // SetupX function prototypes
  35. //
  36. typedef RETERR (WINAPI PASCAL FAR * PROC_DiOpenDevRegKey)(
  37. LPDEVICE_INFO lpdi,
  38. LPHKEY lphk,
  39. int iFlags);
  40. typedef DWORD (WINAPI FAR * PROC_SURegSetValueEx)(HKEY hKey,LPCSTR lpszValueName, DWORD dwReserved, DWORD dwType, LPBYTE lpszValue, DWORD dwValSize);
  41. typedef RETERR (WINAPI FAR * PROC_DiCreateDeviceInfo)(
  42. LPLPDEVICE_INFO lplpdi, // Ptr to ptr to dev info
  43. LPCSTR lpszDescription, // If non-null then description string
  44. DWORD hDevnode, // ISSUE-2002/01/16-roelfc: -- MAKE A DEVNODE
  45. HKEY hkey, // Registry hkey for dev info
  46. LPCSTR lpszRegsubkey, // If non-null then reg subkey string
  47. LPCSTR lpszClassName, // If non-null then class name string
  48. HWND hwndParent); // If non-null then hwnd of parent
  49. typedef RETERR (WINAPI FAR * PROC_DiDestroyDeviceInfoList)(LPDEVICE_INFO lpdi);
  50. typedef RETERR (WINAPI FAR * PROC_DiCallClassInstaller)(DI_FUNCTION diFctn, LPDEVICE_INFO lpdi);
  51. typedef DWORD (WINAPI FAR * PROC_SURegCloseKey)(HKEY hKey);
  52. typedef RETERR (WINAPI FAR * PROC_DiGetClassDevs)(
  53. LPLPDEVICE_INFO lplpdi, // Ptr to ptr to dev info
  54. LPCSTR lpszClassName, // Must be name of class
  55. HWND hwndParent, // If non-null then hwnd of parent
  56. int iFlags); // Options
  57. typedef RETERR (WINAPI FAR * PROC_DiSelectDevice)( LPDEVICE_INFO lpdi );
  58. typedef RETERR (WINAPI FAR * PROC_DiBuildCompatDrvList)(LPDEVICE_INFO lpdi);
  59. typedef RETERR (WINAPI FAR * PASCAL PROC_DiCreateDevRegKey)(
  60. LPDEVICE_INFO lpdi,
  61. LPHKEY lphk,
  62. HINF hinf,
  63. LPCSTR lpszInfSection,
  64. int iFlags);
  65. typedef RETERR (WINAPI FAR * PASCAL PROC_DiDeleteDevRegKey)(LPDEVICE_INFO lpdi, int iFlags);
  66. PROC_DiOpenDevRegKey _pfnDiOpenDevRegKey;
  67. PROC_SURegSetValueEx _pfnSURegSetValueEx;
  68. PROC_DiCreateDeviceInfo _pfnDiCreateDeviceInfo;
  69. PROC_DiDestroyDeviceInfoList _pfnDiDestroyDeviceInfoList;
  70. PROC_DiCallClassInstaller _pfnDiCallClassInstaller;
  71. PROC_SURegCloseKey _pfnSURegCloseKey;
  72. PROC_DiGetClassDevs _pfnDiGetClassDevs;
  73. PROC_DiSelectDevice _pfnDiSelectDevice;
  74. PROC_DiBuildCompatDrvList _pfnDiBuildCompatDrvList;
  75. PROC_DiCreateDevRegKey _pfnDiCreateDevRegKey;
  76. PROC_DiDeleteDevRegKey _pfnDiDeleteDevRegKey;
  77. int g_cSetupxInit = 0;
  78. HINSTANCE g_hInstSetupx = NULL;
  79. BOOL InitSetupx()
  80. {
  81. if (g_hInstSetupx == NULL)
  82. {
  83. g_hInstSetupx = LoadLibrary("setupx.dll");
  84. if (g_hInstSetupx < (HINSTANCE)HINSTANCE_ERROR)
  85. return FALSE;
  86. _pfnDiOpenDevRegKey = (PROC_DiOpenDevRegKey)GetProcAddress(g_hInstSetupx, "DiOpenDevRegKey");
  87. _pfnSURegSetValueEx = (PROC_SURegSetValueEx)GetProcAddress(g_hInstSetupx, "SURegSetValueEx");
  88. _pfnDiCreateDeviceInfo = (PROC_DiCreateDeviceInfo)GetProcAddress(g_hInstSetupx, "DiCreateDeviceInfo");
  89. _pfnDiDestroyDeviceInfoList = (PROC_DiDestroyDeviceInfoList)GetProcAddress(g_hInstSetupx, "DiDestroyDeviceInfoList");
  90. _pfnDiCallClassInstaller = (PROC_DiCallClassInstaller)GetProcAddress(g_hInstSetupx, "DiCallClassInstaller");
  91. _pfnSURegCloseKey = (PROC_SURegCloseKey)GetProcAddress(g_hInstSetupx, "SURegCloseKey");
  92. _pfnDiGetClassDevs = (PROC_DiGetClassDevs)GetProcAddress(g_hInstSetupx, "DiGetClassDevs");
  93. _pfnDiSelectDevice = (PROC_DiSelectDevice)GetProcAddress(g_hInstSetupx, "DiSelectDevice");
  94. _pfnDiBuildCompatDrvList = (PROC_DiBuildCompatDrvList)GetProcAddress(g_hInstSetupx, "DiBuildCompatDrvList");
  95. _pfnDiCreateDevRegKey = (PROC_DiCreateDevRegKey)GetProcAddress(g_hInstSetupx, "DiCreateDevRegKey");
  96. _pfnDiDeleteDevRegKey = (PROC_DiDeleteDevRegKey)GetProcAddress(g_hInstSetupx, "DiDeleteDevRegKey");
  97. }
  98. g_cSetupxInit++;
  99. return TRUE;
  100. }
  101. void UninitSetupx()
  102. {
  103. if (g_cSetupxInit > 0)
  104. g_cSetupxInit--;
  105. if (g_cSetupxInit == 0)
  106. {
  107. if (g_hInstSetupx != NULL)
  108. {
  109. FreeLibrary(g_hInstSetupx);
  110. g_hInstSetupx = NULL;
  111. }
  112. }
  113. }
  114. extern "C" int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD wHeapSize, LPSTR lpszCmdLine)
  115. {
  116. if (wHeapSize != 0)
  117. {
  118. // UnlockData is no longer #defined to UnlockSegment(-1) in windows.h,
  119. // so do it manually here:
  120. //
  121. //UnlockData(0);
  122. UnlockSegment(-1);
  123. }
  124. return 1;
  125. }
  126. extern "C" BOOL FAR PASCAL __export DllEntryPoint(DWORD dwReason, WORD hInstance, WORD wDS, WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
  127. {
  128. if (!thk_ThunkConnect16(
  129. "NCXP16.DLL",
  130. "NCXP32.DLL",
  131. hInstance, dwReason))
  132. {
  133. return FALSE;
  134. }
  135. return TRUE;
  136. }
  137. extern "C" int CALLBACK WEP(int nExitType)
  138. {
  139. return TRUE;
  140. }
  141. //////////////////////////////////////////////////////////////////////////////
  142. //////////////////////////////////////////////////////////////////////////////
  143. #define ASSERT(x)
  144. // Local function declarations
  145. DWORD CallClassInstaller(HWND hwndParent, LPCSTR lpszClassName, LPCSTR lpszDeviceID);
  146. DWORD BindProtocolToAdapters(HWND hwndParent, LPCSTR lpszClassName, LPCSTR lpszDeviceID);
  147. //////////////////////////////////////////////////////////////////////////////
  148. // String constants
  149. // TODO: clean these up... most of them aren't used any more
  150. // Device Manager class names
  151. const char szClassNetCard[] = "Net";
  152. const char szClassNetClient[] = "NetClient";
  153. const char szClassNetProtocol[] = "NetTrans";
  154. const char szClassModem[] = "Modem";
  155. // Device ID string constants
  156. const char szMSTCPIP_ID[] = "MSTCP";
  157. const char szPPPMAC_ID[] = "*PNP8387";
  158. const char szVREDIR_ID[] = "VREDIR";
  159. const char szNWREDIR_ID[] = "NWREDIR";
  160. const char szIPX_ID[] = "NWLINK";
  161. const char szNETBEUI_ID[] = "NETBEUI";
  162. // Registry string constants
  163. const char szRegValSlowNet[] = "SLOWNET";
  164. const char szRegKeyNdi[] = "Ndi";
  165. const char szRegValDeviceID[] = "DeviceID";
  166. const char szRegKeyBindings[] = "Bindings";
  167. const char szRegPathOptComponents[]=REGSTR_PATH_SETUP REGSTR_KEY_SETUP "\\OptionalComponents";
  168. const char szRegValInstalled[] = "Installed";
  169. const char szRegPathNetwork[] = "Enum\\Network";
  170. const char szRegPathTemp[] = "\\Temp";
  171. const char szRegValCompatibleIDs[]= REGSTR_VAL_COMPATIBLEIDS;
  172. const char szRegValDeviceType[] = REGSTR_VAL_DEVTYPE;
  173. const char szRegValConfigFlags[] = REGSTR_VAL_CONFIGFLAGS;
  174. const char szRegPathPlusSetup[] = "Software\\Microsoft\\Plus!\\Setup";
  175. const char szRegValSourcePath[] = "SourcePath";
  176. const char szRegValHardwareID[] = "HardwareID";
  177. // component string constants
  178. const char szCompRNA[] = "RNA";
  179. const char szCompMail[] = "MAPI";
  180. const char szCompMSN[] = "MSNetwork";
  181. const char szCompMSN105[] = "MSNetwork105";
  182. const char szCompInetMail[] = "InternetMail";
  183. const char szINF[] = "INF";
  184. const char szSection[] = "Section";
  185. // INF string constants
  186. const char szValSignature[] = "$CHICAGO$";
  187. const char szKeySignature[] = "signature";
  188. const char szSectVersion[] = "version";
  189. // other strings
  190. const char szNull[] = "";
  191. const char sz1[] = "1";
  192. const char szSlash[] = "\\";
  193. //////////////////////////////////////////////////////////////////////////////
  194. // CreateTempDevRegKey
  195. //
  196. // Creates a temporary registry key for the device installer.
  197. //
  198. // History:
  199. //
  200. // 2/02/1999 KenSh Borrowed from ICW, which borrowed it from net setup
  201. //
  202. RETERR CreateTempDevRegKey(LPDEVICE_INFO lpdi,LPHKEY lphk)
  203. {
  204. lpdi->hRegKey = HKEY_LOCAL_MACHINE;
  205. lstrcpy(lpdi->szRegSubkey, szRegPathNetwork);
  206. lstrcat(lpdi->szRegSubkey, szSlash);
  207. lstrcat(lpdi->szRegSubkey, lpdi->szClassName);
  208. lstrcat(lpdi->szRegSubkey, szRegPathTemp);
  209. InitSetupx();
  210. RETERR err = (*_pfnDiCreateDevRegKey)(lpdi, lphk, NULL, NULL, DIREG_DEV);
  211. UninitSetupx();
  212. return err;
  213. }
  214. // CallClassInstaller
  215. //
  216. // Calls DiCallClassInstaller for the specified class to install
  217. // the specified device ID
  218. //
  219. // Returns ICERR_xxx return value, defined in NetSetup.h
  220. //
  221. // Parameters:
  222. //
  223. // hwndParent - parent window handle
  224. // lpszClassName - name of device class (e.g. "NetTrans" or "Net")
  225. // lpszDeviceID - unique device ID to install (e.g. "MSTCP" or "PCI\VEN_10b7&DEV_5950"
  226. //
  227. // History:
  228. //
  229. // 2/02/1999 KenSh Borrowed from ICW, changed return codes for JetNet
  230. // 3/18/1999 KenSh Cleaned up
  231. //
  232. extern "C" DWORD WINAPI __export CallClassInstaller16(HWND hwndParent, LPCSTR lpszClassName, LPCSTR lpszDeviceID)
  233. {
  234. RETERR err;
  235. DWORD dwResult = ICERR_OK;
  236. LPDEVICE_INFO lpdi;
  237. HKEY hKeyTmp;
  238. LONG uErr;
  239. ASSERT(lpszClassName != NULL);
  240. ASSERT(lpszDeviceID != NULL);
  241. if (!InitSetupx())
  242. return ICERR_DI_ERROR;
  243. // allocate a DEVICE_INFO struct
  244. err = (*_pfnDiCreateDeviceInfo)(&lpdi, NULL, 0, NULL, NULL, lpszClassName, hwndParent);
  245. ASSERT(err == OK);
  246. if (err != OK)
  247. {
  248. lpdi = NULL;
  249. goto exit;
  250. }
  251. // since the device manager APIs are not very good, to communicate the
  252. // device ID to it we have to create a temporary registry key and
  253. // store the device ID there. This code borrowed from net setup
  254. // which has to do the same thing (fill out an LPDEVICE_INFO based
  255. // on a device ID)
  256. err = CreateTempDevRegKey(lpdi, &hKeyTmp);
  257. ASSERT (err == OK);
  258. if (err != OK)
  259. goto exit;
  260. // set the device ID in the registry
  261. uErr = RegSetValueEx(hKeyTmp, szRegValCompatibleIDs,
  262. 0, REG_SZ, (LPBYTE)lpszDeviceID, lstrlen(lpszDeviceID)+1);
  263. ASSERT(uErr == ERROR_SUCCESS);
  264. // now call device mgr API to add driver node lists and fill out structure,
  265. // it will use the device ID we stuffed in registry.
  266. err = (*_pfnDiBuildCompatDrvList)(lpdi);
  267. ASSERT(err == OK);
  268. RegCloseKey(hKeyTmp);
  269. // need to delete temp key, set handle to null, set subkey name to
  270. // null or else net setup thinks this device already exists and
  271. // zany hijinks ensue
  272. (*_pfnDiDeleteDevRegKey)(lpdi, DIREG_DEV);
  273. lpdi->hRegKey = NULL;
  274. lstrcpy(lpdi->szRegSubkey, szNull);
  275. if (err == OK)
  276. {
  277. lpdi->lpSelectedDriver = lpdi->lpCompatDrvList;
  278. ASSERT(lpdi->lpSelectedDriver);
  279. err = (*_pfnDiCallClassInstaller)(DIF_INSTALLDEVICE, lpdi);
  280. ASSERT(err == OK);
  281. if (err == OK)
  282. {
  283. // if we need to reboot, set a special return code NEED_RESTART
  284. // (which also implies success)
  285. if (lpdi->Flags & DI_NEEDREBOOT)
  286. {
  287. // REVIEW: does this need to reboot, or is restart sufficient?
  288. // err = NEED_RESTART;
  289. dwResult = ICERR_NEED_RESTART;
  290. }
  291. }
  292. }
  293. exit:
  294. if (lpdi != NULL)
  295. (*_pfnDiDestroyDeviceInfoList)(lpdi);
  296. if (err != OK)
  297. dwResult = ICERR_DI_ERROR | (DWORD)err;
  298. UninitSetupx();
  299. return dwResult;
  300. }
  301. extern "C" HRESULT WINAPI __export FindClassDev16(HWND hwndParent, LPCSTR pszClass, LPCSTR pszDeviceID)
  302. {
  303. DWORD hr = S_FALSE;
  304. LPDEVICE_INFO lpdi;
  305. RETERR err;
  306. if (!InitSetupx())
  307. return E_FAIL;
  308. if (OK != (err = (*_pfnDiGetClassDevs)(&lpdi, pszClass, NULL, DIGCF_PRESENT)))
  309. {
  310. UninitSetupx();
  311. return E_FAIL;
  312. }
  313. // This is 16-bit code, so these pnp ids are ANSI only
  314. //
  315. LPSTR pszAlternateDeviceID = new char[lstrlen(pszDeviceID) + 1];
  316. if (pszAlternateDeviceID)
  317. {
  318. lstrcpy(pszAlternateDeviceID, pszDeviceID);
  319. LPCSTR szSubsysString = "SUBSYS_";
  320. const int nSubsysIDLength = 8;
  321. LPSTR pszSubsys = strstri(pszAlternateDeviceID, szSubsysString);
  322. if(NULL != pszSubsys)
  323. {
  324. pszSubsys += _countof("SUBSYS_") - 1;
  325. if(nSubsysIDLength <= lstrlen(pszSubsys))
  326. {
  327. for(int i = 0; i < nSubsysIDLength; i++)
  328. {
  329. pszSubsys[i] = '0';
  330. }
  331. }
  332. }
  333. for (LPDEVICE_INFO lpdiCur = lpdi; lpdiCur != NULL; lpdiCur = lpdiCur->lpNextDi)
  334. {
  335. char szBuf[1024];
  336. // wsprintf(szBuf, "System\\CurrentControlSet\\Services\\Class\\%s\\%04d", pszClass, (int)lpdiCur->dnDevnode);
  337. // MessageBox(NULL, szBuf, "RegKey", MB_OK);
  338. HKEY hKey;
  339. if (OK == (*_pfnDiOpenDevRegKey)(lpdiCur, &hKey, DIREG_DEV))
  340. {
  341. static const LPCSTR c_rgRegEntries[] = { "HardwareID", "CompatibleIDs" };
  342. for (int i = 0; i < _countof(c_rgRegEntries); i++)
  343. {
  344. LONG cbBuf = sizeof(szBuf);
  345. if (ERROR_SUCCESS == RegQueryValueEx(hKey, c_rgRegEntries[i], NULL, NULL, (LPBYTE)szBuf, &cbBuf))
  346. {
  347. // char szBuf2[1600];
  348. // wsprintf(szBuf2, "Looking for: %s\n\n%s", pszDeviceID, szBuf);
  349. // MessageBox(NULL, szBuf2, c_rgRegEntries[i], MB_OK);
  350. // aslo check with SUBSYS 00000000 for bug 124967
  351. if (NULL != strstri(szBuf, pszDeviceID) || NULL != strstri(szBuf, pszAlternateDeviceID))
  352. {
  353. hr = S_OK;
  354. break;
  355. }
  356. }
  357. }
  358. RegCloseKey(hKey);
  359. }
  360. if (hr == S_OK)
  361. break;
  362. }
  363. delete [] pszAlternateDeviceID;
  364. }
  365. (*_pfnDiDestroyDeviceInfoList)(lpdi);
  366. UninitSetupx();
  367. return hr;
  368. }
  369. extern "C" HRESULT WINAPI __export LookupDevNode16(HWND hwndParent, LPCSTR pszClass, LPCSTR pszEnumKey, DEVNODE FAR* pDevNode, DWORD FAR* pdwFreePointer)
  370. {
  371. DWORD hr = S_FALSE;
  372. LPDEVICE_INFO lpdi;
  373. RETERR err;
  374. // MessageBox(hwndParent, "LookupDevNode16", "Debug", MB_ICONINFORMATION);
  375. if (pDevNode == NULL || pdwFreePointer == NULL)
  376. {
  377. // MessageBox(hwndParent, "Returning failure 0", "Debug", 0);
  378. return E_POINTER;
  379. }
  380. *pDevNode = 0;
  381. *pdwFreePointer = 0;
  382. if (!InitSetupx())
  383. {
  384. // MessageBox(hwndParent, "Returning failure 1", "Debug", 0);
  385. return E_FAIL;
  386. }
  387. if (OK != (err = (*_pfnDiGetClassDevs)(&lpdi, pszClass, NULL, DIGCF_PRESENT)))
  388. {
  389. // MessageBox(hwndParent, "Returning failure 2", "Debug", 0);
  390. UninitSetupx();
  391. return E_FAIL;
  392. }
  393. for (LPDEVICE_INFO lpdiCur = lpdi; lpdiCur != NULL; lpdiCur = lpdiCur->lpNextDi)
  394. {
  395. // char szBuf[1024];
  396. // wsprintf(szBuf, "comparing:\nlpdiCur->pszRegSubkey = \"%s\"\npszEnumKey = \"%s\"",
  397. // (LPSTR)lpdiCur->szRegSubkey, (LPSTR)pszEnumKey);
  398. // MessageBox(hwndParent, szBuf, "Debug", MB_ICONINFORMATION);
  399. if (0 == lstrcmpi(lpdiCur->szRegSubkey, pszEnumKey))
  400. {
  401. // wsprintf(szBuf, "found devnode 0x%08lX, pvFreePointer = 0x%08lX", (DWORD)lpdiCur->dnDevnode, (DWORD)lpdi);
  402. // MessageBox(hwndParent, szBuf, "Debug", MB_ICONINFORMATION);
  403. *pDevNode = lpdiCur->dnDevnode;
  404. *pdwFreePointer = (DWORD)lpdi;
  405. return S_OK;
  406. }
  407. }
  408. (*_pfnDiDestroyDeviceInfoList)(lpdi);
  409. UninitSetupx();
  410. // MessageBox(hwndParent, "returning failure", "Debug", MB_ICONINFORMATION);
  411. return E_FAIL; // not found
  412. }
  413. extern "C" HRESULT WINAPI __export FreeDevNode16(DWORD dwFreePointer)
  414. {
  415. LPDEVICE_INFO lpdi = (LPDEVICE_INFO)dwFreePointer;
  416. if (lpdi == NULL)
  417. {
  418. return E_INVALIDARG;
  419. }
  420. if (g_hInstSetupx == NULL)
  421. {
  422. return E_FAIL;
  423. }
  424. // char szBuf[1024];
  425. // wsprintf(szBuf, "FreeDevNode16 - freeing lpdi 0x%08lX - continue?", dwFreePointer);
  426. // if (IDYES == MessageBox(NULL, szBuf, "Debug", MB_YESNO | MB_ICONEXCLAMATION))
  427. {
  428. (*_pfnDiDestroyDeviceInfoList)(lpdi);
  429. }
  430. UninitSetupx();
  431. return S_OK;
  432. }
  433. extern "C" HRESULT WINAPI __export IcsUninstall16(void)
  434. {
  435. typedef void (WINAPI *RUNDLLPROC)(HWND hwndStub, HINSTANCE hAppInstance, LPSTR lpszCmdLine, int nCmdShow);
  436. HINSTANCE hInstance = LoadLibrary("issetup.dll");
  437. if(hInstance > 32)
  438. {
  439. RUNDLLPROC pExtUninstall = (RUNDLLPROC) GetProcAddress(hInstance, "ExtUninstall");
  440. if(NULL != pExtUninstall)
  441. {
  442. pExtUninstall(NULL, NULL, NULL, 0);
  443. }
  444. FreeLibrary(hInstance);
  445. }
  446. return S_OK;
  447. }