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.

2049 lines
59 KiB

  1. /****************************************************************************
  2. *
  3. * icfg32.cpp
  4. *
  5. * Microsoft Confidential
  6. * Copyright (c) 1992-1998 Microsoft Corporation
  7. * All rights reserved
  8. *
  9. * This module provides the implementation of the methods for
  10. * the NT specific functionality of inetcfg
  11. *
  12. * 6/5/97 ChrisK Inherited from AmnonH
  13. *
  14. ***************************************************************************/
  15. #define INITGUID
  16. #include <windows.h>
  17. #include <wtypes.h>
  18. #include <cfgapi.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <setupapi.h>
  22. #include <basetyps.h>
  23. #include <devguid.h>
  24. #include <lmsname.h>
  25. #include "debug.h"
  26. const DWORD INFINSTALL_PRIMARYINSTALL = 0x00000001;
  27. const DWORD INFINSTALL_INPROCINTERP = 0x00000002;
  28. #define REG_DATA_EXTRA_SPACE 255
  29. #define CELEMS(x) ((sizeof(x))/(sizeof(x[0])))
  30. DWORD (WINAPI *pfnNetSetupReviewBindings)(HWND hwndParent,
  31. DWORD dwBindFlags);
  32. DWORD (WINAPI *pfnNetSetupComponentInstall)(HWND hwndParent,
  33. PCWSTR pszInfOption,
  34. PCWSTR pszInfName,
  35. PCWSTR pszInstallPath,
  36. PCWSTR plszInfSymbols,
  37. DWORD dwInstallFlags,
  38. PDWORD dwReturn);
  39. DWORD (WINAPI *pfnNetSetupComponentRemove)(HWND hwndParent,
  40. PCWSTR pszInfOption,
  41. DWORD dwInstallFlags,
  42. PDWORD pdwReturn);
  43. DWORD (WINAPI *pfnNetSetupComponentProperties)(HWND hwndParent,
  44. PCWSTR pszInfOption,
  45. DWORD dwInstallFlags,
  46. PDWORD pdwReturn);
  47. DWORD (WINAPI *pfnNetSetupFindHardwareComponent)(PCWSTR pszInfOption,
  48. PWSTR pszInfName,
  49. PDWORD pcchInfName,
  50. PWSTR pszRegBase, // optional, may be NULL
  51. PDWORD pcchRegBase ); // optional, NULL if pszRegBase is NULL
  52. DWORD (WINAPI *pfnNetSetupFindSoftwareComponent)(PCWSTR pszInfOption,
  53. PWSTR pszInfName,
  54. PDWORD pcchInfName,
  55. PWSTR pszRegBase /*= NULL*/,
  56. PDWORD pcchRegBase /*= NULL*/);
  57. DWORD (WINAPI *pfnRegCopyTree)();
  58. HINSTANCE g_hNetcfgInst = NULL;
  59. LPWSTR g_wszInstallPath = 0;
  60. DWORD g_dwLastError = ERROR_SUCCESS;
  61. extern DWORD EnumerateTapiModemPorts(DWORD dwBytes, LPSTR szPortsBuf,
  62. BOOL bWithDelay = FALSE);
  63. typedef struct tagFunctionTableEntry {
  64. LPVOID *pfn;
  65. LPSTR szEntryPoint;
  66. } FunctionTableEntry;
  67. #define REGISTRY_NT_CURRENTVERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CurrentVersion"
  68. FunctionTableEntry NetcfgTable[] = {
  69. { (LPVOID *) &pfnNetSetupComponentInstall, "NetSetupComponentInstall" },
  70. { (LPVOID *) &pfnNetSetupFindSoftwareComponent, "NetSetupFindSoftwareComponent" },
  71. { (LPVOID *) &pfnNetSetupReviewBindings, "NetSetupReviewBindings" },
  72. { (LPVOID *) &pfnNetSetupComponentRemove, "NetSetupComponentRemove" },
  73. { (LPVOID *) &pfnNetSetupComponentProperties, "NetSetupComponentProperties" },
  74. { (LPVOID *) &pfnNetSetupFindHardwareComponent, "NetSetupFindHardwareComponent" },
  75. { 0, 0 }
  76. };
  77. typedef struct tagNetSetup
  78. {
  79. WCHAR szOption[16];
  80. WCHAR szInfName[16];
  81. } NETSETUP;
  82. NETSETUP g_netsetup[] = { L"WKSTA", L"OEMNSVWK.INF",
  83. L"SRV", L"OEMNSVSV.INF",
  84. L"NETBIOS", L"OEMNSVNB.INF",
  85. L"RPCLOCATE", L"OEMNSVRP.INF" };
  86. #define NSERVICES (sizeof g_netsetup / sizeof g_netsetup[0])
  87. inline stricmp(LPSTR s1, LPSTR s2) {
  88. while(*s1 && *s2) {
  89. char c1, c2;
  90. c1 = islower(*s1) ? toupper(*s1) : *s1;
  91. c2 = islower(*s2) ? toupper(*s2) : *s2;
  92. if(c1 != c2)
  93. {
  94. break;
  95. }
  96. s1++; s2++;
  97. }
  98. return(*s1 - *s2);
  99. }
  100. //+----------------------------------------------------------------------------
  101. //
  102. // Function: LoadLibraryToFunctionTable
  103. //
  104. // Synopsis: Load structure with function pointers from FunctionTable
  105. //
  106. // Arguments: pTab - array of function to be loaded
  107. // szDLL - name of DLL to load function from
  108. //
  109. // Returns: Handle to szDLL (NULL indicates failure)
  110. //
  111. // History: 6/5/97 Chrisk Inherited
  112. //
  113. //-----------------------------------------------------------------------------
  114. HINSTANCE
  115. LoadLibraryToFunctionTable(FunctionTableEntry *pTab, LPSTR szDLL)
  116. {
  117. HINSTANCE hInst;
  118. Dprintf("ICFGNT: LoadLibraryToFunctionTable\n");
  119. hInst = LoadLibrary(szDLL);
  120. if(hInst == 0)
  121. {
  122. return(hInst);
  123. }
  124. while(pTab->pfn) {
  125. *pTab->pfn = (LPVOID) GetProcAddress(hInst, pTab->szEntryPoint);
  126. if(*pTab->pfn == 0)
  127. {
  128. FreeLibrary(hInst);
  129. return(0);
  130. }
  131. pTab++;
  132. }
  133. return(hInst);
  134. }
  135. //+----------------------------------------------------------------------------
  136. //
  137. // Function: LoadNetcfg
  138. //
  139. // Synopsis: Load netcfg.dll and function poiners
  140. //
  141. // Arguments: none
  142. //
  143. // Returns: ERROR_SUCCESS if sucessfull and !ERROR_SUCCESS otherwise
  144. //
  145. // History: 6/5/97 ChrisK Inherited
  146. //
  147. //-----------------------------------------------------------------------------
  148. DWORD
  149. LoadNetcfg()
  150. {
  151. if(g_hNetcfgInst == NULL)
  152. {
  153. g_hNetcfgInst = LoadLibraryToFunctionTable(NetcfgTable,
  154. "NETCFG.DLL");
  155. }
  156. if(g_hNetcfgInst == NULL)
  157. {
  158. return(!ERROR_SUCCESS);
  159. }
  160. else
  161. {
  162. return(ERROR_SUCCESS);
  163. }
  164. }
  165. //+----------------------------------------------------------------------------
  166. //
  167. // Function: IcfgSetInstallSourcePath
  168. //
  169. // Synopsis: Set the path that will be used to install system components
  170. //
  171. // Arguments: lpszSourcePath - path to be used as install source (ANSI)
  172. //
  173. // Returns: HRESULT - S_OK is success
  174. //
  175. // History: 6/5/97 ChrisK Inherited
  176. //
  177. //-----------------------------------------------------------------------------
  178. HRESULT WINAPI
  179. IcfgSetInstallSourcePath(LPSTR lpszSourcePath)
  180. {
  181. Dprintf("ICFGNT: IcfgSetInstallSourcePath\n");
  182. if(g_wszInstallPath)
  183. {
  184. HeapFree(GetProcessHeap(), 0, (LPVOID) g_wszInstallPath);
  185. }
  186. DWORD dwLen = lstrlen(lpszSourcePath);
  187. g_wszInstallPath = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwLen * 2 + 2);
  188. if(g_wszInstallPath == 0)
  189. {
  190. return(g_dwLastError = ERROR_OUTOFMEMORY);
  191. }
  192. mbstowcs(g_wszInstallPath, lpszSourcePath, dwLen + 1);
  193. return(ERROR_SUCCESS);
  194. }
  195. //+----------------------------------------------------------------------------
  196. //
  197. // Function: GetLocationOfSetupFiles
  198. //
  199. // Synopsis: Get the location of the files used to install windows.
  200. //
  201. // Arguments: hwndParent - handle of parent window
  202. //
  203. // Returns: win32 error code
  204. //
  205. // History: ChrisK 6/30/97 Created
  206. //-----------------------------------------------------------------------------
  207. DWORD GetLocationOfSetupFiles(HWND hwndParent)
  208. {
  209. DWORD dwRC = ERROR_SUCCESS;
  210. HKEY hkey = NULL;
  211. HINF hInf = INVALID_HANDLE_VALUE;
  212. UINT DiskId = 0;
  213. CHAR TagFile[128];
  214. CHAR lpBuffer[MAX_PATH];
  215. DWORD dwLen = MAX_PATH;
  216. lpBuffer[0] = '\0';
  217. if( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE,
  218. REGISTRY_NT_CURRENTVERSION,
  219. &hkey))
  220. {
  221. hInf = SetupOpenMasterInf();
  222. if (hInf == INVALID_HANDLE_VALUE)
  223. {
  224. dwRC = GetLastError();
  225. goto GetLocationOfSetupFilesExit;
  226. }
  227. if (!SetupGetSourceFileLocation(hInf,NULL,"RASCFG.DLL",&DiskId,NULL,0,NULL))
  228. {
  229. dwRC = GetLastError();
  230. goto GetLocationOfSetupFilesExit;
  231. }
  232. if (!SetupGetSourceInfo(hInf,DiskId,SRCINFO_TAGFILE,TagFile,MAX_PATH,NULL))
  233. {
  234. dwRC = GetLastError();
  235. goto GetLocationOfSetupFilesExit;
  236. }
  237. SetupCloseInfFile(hInf);
  238. hInf = INVALID_HANDLE_VALUE;
  239. if( RegQueryValueEx( hkey,
  240. "SourcePath",
  241. NULL,
  242. NULL,
  243. (LPBYTE)lpBuffer,
  244. &dwLen) == 0)
  245. {
  246. RegCloseKey( hkey );
  247. hkey = NULL;
  248. // Ask the user to provide the drive\path of the sources. We pass this information
  249. // down to NetSetupComponentInstall so that the user is not prompted several times
  250. // for the same information. If the path is correct (IDF_CHECKFIRST) then the user
  251. // is not prompted at all.
  252. if( (dwRC = SetupPromptForDisk(hwndParent,
  253. NULL,
  254. NULL,
  255. lpBuffer,
  256. "RASCFG.DLL",
  257. TagFile, // tag file
  258. IDF_CHECKFIRST,
  259. lpBuffer,
  260. MAX_PATH,
  261. &dwLen
  262. )) != DPROMPT_SUCCESS )
  263. {
  264. Dprintf("ICFG: Install: SetupPromptForDisk failed.\n");
  265. dwRC = GetLastError();
  266. goto GetLocationOfSetupFilesExit;
  267. }
  268. }
  269. // If we failed to get SourcePath from registry, then prompt the user once and use
  270. // this information for subsequent installs.
  271. else
  272. {
  273. if( (dwRC = SetupPromptForDisk(hwndParent,
  274. NULL,
  275. NULL,
  276. NULL,
  277. "RASCFG.DLL",
  278. TagFile, // tag file
  279. IDF_CHECKFIRST,
  280. lpBuffer,
  281. MAX_PATH,
  282. &dwLen
  283. )) != DPROMPT_SUCCESS )
  284. {
  285. Dprintf("ICFG: Install: SetupPromptForDisk failed.\n");
  286. dwRC = GetLastError();
  287. goto GetLocationOfSetupFilesExit;
  288. }
  289. }
  290. }
  291. GetLocationOfSetupFilesExit:
  292. if (ERROR_SUCCESS == dwRC)
  293. {
  294. IcfgSetInstallSourcePath(lpBuffer);
  295. }
  296. if (INVALID_HANDLE_VALUE != hInf)
  297. {
  298. SetupCloseInfFile(hInf);
  299. hInf = NULL;
  300. }
  301. if (NULL != hkey)
  302. {
  303. RegCloseKey(hkey);
  304. }
  305. return dwRC;
  306. }
  307. //+----------------------------------------------------------------------------
  308. //
  309. // Function: InstallNTNetworking
  310. //
  311. // Synopsis: Install NT Server, workstation, netbios, and RPC locator
  312. // services as needed
  313. //
  314. // Arguemtns: hwndParent - parent window
  315. //
  316. // Returns: win32 error code
  317. //
  318. // History: ChrisK 6/27/97 Created
  319. //
  320. //-----------------------------------------------------------------------------
  321. DWORD InstallNTNetworking(HWND hwndParent)
  322. {
  323. DWORD dwRC = ERROR_SUCCESS;
  324. UINT index = 0;
  325. DWORD cchInfName = MAX_PATH;
  326. WCHAR pszInfName[MAX_PATH+1];
  327. SC_HANDLE hscman, hsvc;
  328. DWORD dwReturn;
  329. Dprintf("ICFGNT.DLL: InstallNTNetworking.\n");
  330. Assert(NULL == hwndParent || IsWindow(hwndParent));
  331. if(ERROR_SUCCESS != (dwRC = LoadNetcfg()))
  332. {
  333. Dprintf("ICFGNT.DLL: Failed load Netcfg API's, error %d\n",dwRC);
  334. goto InstallNTNetworkingExit;
  335. }
  336. //
  337. // Check for and install services
  338. //
  339. for (index = 0; index < NSERVICES; index++)
  340. {
  341. Dprintf("ICFGNT.DLL: Check service %d\n",index);
  342. //
  343. // Install service if it is not installed
  344. //
  345. if(pfnNetSetupFindSoftwareComponent(
  346. g_netsetup[index].szOption, // OPTION
  347. pszInfName, // INF Name
  348. &cchInfName,
  349. NULL,
  350. NULL) != ERROR_SUCCESS )
  351. {
  352. if (0 == g_wszInstallPath || 0 == lstrlenW(g_wszInstallPath))
  353. {
  354. GetLocationOfSetupFiles(hwndParent);
  355. }
  356. Dprintf("ICFGNT.DLL: Need service %d.\n",index);
  357. if((dwRC = pfnNetSetupComponentInstall(
  358. hwndParent,
  359. g_netsetup[index].szOption, // OPTION
  360. g_netsetup[index].szInfName, // INF Name
  361. g_wszInstallPath, // Install path optional
  362. NULL, // symbols, optional
  363. 2, // INFINSTALL_INPROCINTERP
  364. &dwReturn)) != ERROR_SUCCESS )
  365. {
  366. Dprintf("ICFGNT.DLL: Installing service %d failed with error %d.\n",
  367. index,
  368. dwRC);
  369. goto InstallNTNetworkingExit;
  370. }
  371. // Since this is downlevel, we can just use the MAKELCID macro
  372. //
  373. if (CSTR_EQUAL == CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
  374. NORM_IGNORECASE, g_netsetup[index].szOption, -1, L"WKSTA", -1))
  375. {
  376. // if we installed the Workstation service, then we should disable
  377. // Netlogon service. We need to do this because netlogon service should
  378. // not be set to autostart if the user has not joined a domain.
  379. //
  380. hscman = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS | GENERIC_WRITE );
  381. if( hscman == NULL)
  382. {
  383. dwRC = GetLastError();
  384. Dprintf("ICFGNT.DLL: Failed to open serviceManager, error %d\n",dwRC);
  385. goto InstallNTNetworkingExit;
  386. }
  387. hsvc = OpenService( hscman, SERVICE_NETLOGON, SERVICE_CHANGE_CONFIG );
  388. if ( hsvc == NULL)
  389. {
  390. dwRC = GetLastError();
  391. Dprintf("ICFGNT.DLL: Failed to open service, error %d\n",dwRC);
  392. goto InstallNTNetworkingExit;
  393. }
  394. ChangeServiceConfig( hsvc, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
  395. CloseServiceHandle(hsvc);
  396. CloseServiceHandle(hscman);
  397. }
  398. }
  399. }
  400. InstallNTNetworkingExit:
  401. return dwRC;
  402. }
  403. //+----------------------------------------------------------------------------
  404. //
  405. // Function: GetRegValue
  406. //
  407. // Synopsis: Dynamically allocate memory and read value from registry
  408. //
  409. // Arguments: hKey - handle to key to be read
  410. // lpValueName - pointer to value name to be read
  411. // lpData - pointer to pointer to data
  412. //
  413. // Returns: Win32 error, ERROR_SUCCESS is it worked
  414. //
  415. // History: 6/5/97 ChrisK Inherited
  416. //
  417. //-----------------------------------------------------------------------------
  418. inline LONG GetRegValue(HKEY hKey, LPSTR lpValueName, LPBYTE *lpData)
  419. {
  420. LONG dwError;
  421. DWORD cbData;
  422. Dprintf("ICFGNT: GetRegValue\n");
  423. dwError = RegQueryValueExA(hKey,
  424. lpValueName,
  425. NULL,
  426. NULL,
  427. NULL,
  428. &cbData);
  429. if(dwError != ERROR_SUCCESS)
  430. {
  431. return(dwError);
  432. }
  433. //
  434. // Allocate space and buffer incase we need to add more info later
  435. // see turn off the printing binding
  436. //
  437. *lpData = (LPBYTE) GlobalAlloc(GPTR,cbData + REG_DATA_EXTRA_SPACE);
  438. if(*lpData == 0)
  439. {
  440. return(ERROR_OUTOFMEMORY);
  441. }
  442. dwError = RegQueryValueExA(hKey,
  443. lpValueName,
  444. NULL,
  445. NULL,
  446. *lpData,
  447. &cbData);
  448. if(dwError != ERROR_SUCCESS)
  449. {
  450. GlobalFree(*lpData);
  451. }
  452. return(dwError);
  453. }
  454. //+----------------------------------------------------------------------------
  455. //
  456. // Function: ParseNetSetupReturn
  457. //
  458. // Synopsis: Interprit return values from NetSetup* functions
  459. //
  460. // Arguments: dwReturn - return value from NetSetup* function
  461. //
  462. // Returns: fReboot - TRUE means reboot required
  463. // fBindReview - TRUE means binding review is required
  464. //
  465. // History: 6/5/97 ChrisK Inherited
  466. //
  467. //-----------------------------------------------------------------------------
  468. inline void
  469. ParseNetSetupReturn(DWORD dwReturn, BOOL &fReboot, BOOL &fBindReview)
  470. {
  471. Dprintf("ICFGNT: ParseNetSetupReturn\n");
  472. if(dwReturn == 0 || dwReturn == 4)
  473. {
  474. fBindReview = TRUE;
  475. }
  476. if(dwReturn == 0 || dwReturn == 5)
  477. {
  478. fReboot = TRUE;
  479. }
  480. }
  481. //+----------------------------------------------------------------------------
  482. //
  483. // Function: ReviewBindings
  484. //
  485. // Synopsis: Force WinNT to review network bindings
  486. //
  487. // Arguments: hwndParent - handle to parent window
  488. //
  489. // Returns: win32 error code (ERROR_SUCCESS means it worked)
  490. //
  491. // History: 6/5/97 ChrisK Inherited
  492. //
  493. //-----------------------------------------------------------------------------
  494. DWORD
  495. ReviewBindings(HWND hwndParent)
  496. {
  497. DWORD dwErr;
  498. Dprintf("ICFGNT: ReviewBindings\n");
  499. dwErr = LoadNetcfg();
  500. if(dwErr != ERROR_SUCCESS)
  501. {
  502. return(dwErr);
  503. }
  504. return(pfnNetSetupReviewBindings(hwndParent, 0));
  505. }
  506. //+----------------------------------------------------------------------------
  507. //
  508. // Function: CallModemInstallWizard
  509. //
  510. // Synopsis: Invoke modem install wizard via SetupDi interfaces
  511. //
  512. // Arguments: hwnd - handle to parent window
  513. //
  514. // Returns: TRUE - success, FALSE - failed
  515. //
  516. // History: 6/5/97 ChrisK Inherited
  517. //
  518. //-----------------------------------------------------------------------------
  519. //
  520. // The following code was stolen from RAS
  521. //
  522. BOOL
  523. CallModemInstallWizard(HWND hwnd)
  524. /* call the Modem.Cpl install wizard to enable the user to install one or more modems
  525. **
  526. ** Return TRUE if the wizard was successfully invoked, FALSE otherwise
  527. **
  528. */
  529. {
  530. HDEVINFO hdi;
  531. BOOL fReturn = FALSE;
  532. // Create a modem DeviceInfoSet
  533. Dprintf("ICFGNT: CallModemInstallWizard\n");
  534. hdi = SetupDiCreateDeviceInfoList((LPGUID)&GUID_DEVCLASS_MODEM, hwnd);
  535. if (hdi)
  536. {
  537. SP_INSTALLWIZARD_DATA iwd;
  538. // Initialize the InstallWizardData
  539. ZeroMemory(&iwd, sizeof(iwd));
  540. iwd.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  541. iwd.ClassInstallHeader.InstallFunction = DIF_INSTALLWIZARD;
  542. iwd.hwndWizardDlg = hwnd;
  543. // Set the InstallWizardData as the ClassInstallParams
  544. if (SetupDiSetClassInstallParams(hdi, NULL, (PSP_CLASSINSTALL_HEADER)&iwd, sizeof(iwd)))
  545. {
  546. // Call the class installer to invoke the installation
  547. // wizard.
  548. if (SetupDiCallClassInstaller(DIF_INSTALLWIZARD, hdi, NULL))
  549. {
  550. // Success. The wizard was invoked and finished.
  551. // Now cleanup.
  552. fReturn = TRUE;
  553. SetupDiCallClassInstaller(DIF_DESTROYWIZARDDATA, hdi, NULL);
  554. }
  555. }
  556. // Clean up
  557. SetupDiDestroyDeviceInfoList(hdi);
  558. }
  559. return fReturn;
  560. }
  561. //+----------------------------------------------------------------------------
  562. //
  563. // Function: IsDialableISDNAdapters
  564. //
  565. // Synopsis: Some ISDN adapters can be installed as RAS devices, but not as
  566. // unimodem devices, so we have to walk through the rest of the
  567. // TAPI devices looking for these.
  568. //
  569. // Arguments: None
  570. //
  571. // Returns: TRUE - there is a device available
  572. //
  573. // History: 7/22/97 ChrisK Created
  574. //
  575. //-----------------------------------------------------------------------------
  576. #define REG_TAPIDEVICES "software\\microsoft\\ras\\tapi devices"
  577. LPSTR szAddress = "Address";
  578. LPSTR szUsage = "Usage";
  579. LPSTR szMediaType = "Media Type";
  580. BOOL IsDialableISDNAdapters()
  581. {
  582. BOOL bRC = FALSE;
  583. HKEY hkey = NULL, hsubkey = NULL;
  584. DWORD dwIdx = 0;
  585. CHAR szBuffer[MAX_PATH + 1];
  586. CHAR szSubKey[MAX_PATH + 1];
  587. LPBYTE lpData = NULL;
  588. LPSTR lpsUsage = NULL;
  589. szBuffer[0] = '\0';
  590. //
  591. // Open TAPI device key
  592. //
  593. if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
  594. REG_TAPIDEVICES,
  595. &hkey))
  596. {
  597. Dprintf("ICFGNT Can not open TAPI key.\n");
  598. goto IsDialableISDNAdaptersExit;
  599. }
  600. //
  601. // Scan for non unimodem device
  602. //
  603. while (FALSE == bRC)
  604. {
  605. szBuffer[0] = '\0';
  606. if (ERROR_SUCCESS != RegEnumKey(hkey,dwIdx,szBuffer,MAX_PATH))
  607. {
  608. goto IsDialableISDNAdaptersExit;
  609. }
  610. Dprintf("ICFGNT sub key (%s) found.\n",szBuffer);
  611. if (CSTR_EQUAL != CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
  612. NORM_IGNORECASE, szBuffer, -1, "unimodem", -1))
  613. {
  614. //
  615. // Open other TAPI device reg key
  616. //
  617. szSubKey[0] = '\0';
  618. wsprintf(szSubKey,"%s\\%s",REG_TAPIDEVICES,szBuffer);
  619. Dprintf("ICFGNT opening (%s).\n",szSubKey);
  620. if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
  621. szSubKey,
  622. &hsubkey))
  623. {
  624. Dprintf("ICFGNT Can not open TAPI SUB key.\n");
  625. goto IsDialableISDNAdaptersExit;
  626. }
  627. if (ERROR_SUCCESS != GetRegValue(hsubkey,szUsage,&lpData))
  628. {
  629. Dprintf("ICFGNT Can not get TAPI SUB key.\n");
  630. goto IsDialableISDNAdaptersExit;
  631. }
  632. //
  633. // Scan for "client"
  634. //
  635. lpsUsage = (LPSTR)lpData;
  636. while (*lpsUsage != '\0')
  637. {
  638. if(NULL != strstr(lpsUsage, "Client"))
  639. {
  640. Dprintf("ICFGNT client found for device.\n");
  641. //
  642. // We found a client device, now check that it is ISDN
  643. //
  644. GlobalFree(lpData);
  645. lpData = NULL;
  646. if (ERROR_SUCCESS != GetRegValue(hsubkey,szMediaType,&lpData))
  647. {
  648. Dprintf("ICFGNT Can not get TAPI SUB value key.\n");
  649. goto IsDialableISDNAdaptersExit;
  650. }
  651. if (CSTR_EQUAL == CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
  652. NORM_IGNORECASE, (LPSTR)lpData, -1, "ISDN", -1))
  653. {
  654. Dprintf("ICFGNT ISDN media type found.\n");
  655. //
  656. // This is a valid dial-out ISDN device!!! Wahoo!!
  657. //
  658. bRC = TRUE;
  659. }
  660. else
  661. {
  662. Dprintf("ICFGNT ISDN media type NOT found.\n");
  663. }
  664. }
  665. else
  666. {
  667. lpsUsage += lstrlen(lpsUsage)+1;
  668. }
  669. }
  670. if (lpData)
  671. {
  672. GlobalFree(lpData);
  673. lpData = NULL;
  674. lpsUsage = NULL;
  675. }
  676. }
  677. //
  678. // Move to the next REG key
  679. //
  680. dwIdx++;
  681. }
  682. IsDialableISDNAdaptersExit:
  683. if (hkey)
  684. {
  685. RegCloseKey(hkey);
  686. hkey = NULL;
  687. }
  688. if (hsubkey)
  689. {
  690. RegCloseKey(hsubkey);
  691. hsubkey = NULL;
  692. }
  693. if (lpData)
  694. {
  695. GlobalFree(lpData);
  696. lpData = NULL;
  697. lpsUsage = NULL;
  698. }
  699. return bRC;
  700. }
  701. //+----------------------------------------------------------------------------
  702. //
  703. // Function: IcfgNeedModem
  704. //
  705. // Synopsis: Check system configuration to determine if there is at least
  706. // one physical modem installed
  707. //
  708. // Arguments: dwfOptions - currently not used
  709. //
  710. // Returns: HRESULT - S_OK if successfull
  711. // lpfNeedModem - TRUE if no modems are available
  712. //
  713. // History: 6/5/97 ChrisK Inherited
  714. //
  715. //-----------------------------------------------------------------------------
  716. LPSTR szRasUnimodemSubKey =
  717. "Software\\Microsoft\\ras\\TAPI DEVICES\\Unimodem";
  718. HRESULT WINAPI
  719. IcfgNeedModemNT4 (DWORD dwfOptions, LPBOOL lpfNeedModem)
  720. {
  721. //
  722. // Ras is insatlled, and ICW wants to know if it needs to
  723. // install a modem.
  724. //
  725. *lpfNeedModem = TRUE;
  726. //
  727. // ChrisK 7/22/97
  728. // Added return code in order to provide centralized place to check
  729. // for ISDN installations
  730. //
  731. HRESULT hRC = ERROR_SUCCESS;
  732. //
  733. // Check what modems are available to RAS
  734. //
  735. HKEY hUnimodem;
  736. LONG dwError;
  737. Dprintf("ICFGNT: IcfgNeedModem\n");
  738. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  739. szRasUnimodemSubKey,
  740. 0,
  741. KEY_READ,
  742. &hUnimodem);
  743. if(dwError != ERROR_SUCCESS)
  744. {
  745. goto IcfgNeedModemExit;
  746. }
  747. else
  748. {
  749. LPBYTE lpData;
  750. dwError = GetRegValue(hUnimodem, szUsage, &lpData);
  751. if(dwError != ERROR_SUCCESS)
  752. goto IcfgNeedModemExit;
  753. LPBYTE lpData2;
  754. dwError = GetRegValue(hUnimodem, szAddress, &lpData2);
  755. if(dwError != ERROR_SUCCESS)
  756. {
  757. hRC = dwError;
  758. goto IcfgNeedModemExit;
  759. }
  760. else
  761. {
  762. //
  763. // Try finding a Client or ClientAndServer Modem
  764. // Also, make sure all modems have corresponding TAPI devices
  765. //
  766. LPSTR pUsage = (LPSTR) lpData;
  767. LPSTR pAddress = (LPSTR) lpData2;
  768. char portsbuf[1000];
  769. dwError = EnumerateTapiModemPorts(sizeof(portsbuf), portsbuf);
  770. if(dwError)
  771. {
  772. hRC = dwError;
  773. goto IcfgNeedModemExit;
  774. }
  775. while(*pUsage != '\0') {
  776. if(lstrcmp(pUsage, "Client") == 0 ||
  777. lstrcmp(pUsage, "ClientAndServer") == 0 ||
  778. lstrcmp(pUsage, "ClientAndServerAndRouter") == 0)
  779. {
  780. *lpfNeedModem = FALSE;
  781. }
  782. //
  783. // Make sure a corresponding TAPI port exists
  784. //
  785. LPSTR pPorts = portsbuf;
  786. while(*pPorts != '\0')
  787. if(stricmp(pAddress, pPorts) == 0)
  788. {
  789. break;
  790. }
  791. else
  792. {
  793. pPorts += lstrlen(pPorts) + 1;
  794. }
  795. if(*pPorts == '\0')
  796. {
  797. hRC = ERROR_INTERNAL_ERROR;
  798. goto IcfgNeedModemExit;
  799. }
  800. pUsage += lstrlen(pUsage) + 1;
  801. pAddress += lstrlen(pAddress) + 1;
  802. }
  803. }
  804. }
  805. IcfgNeedModemExit:
  806. //
  807. // If there was some problem finding a typical dial out device,
  808. // then try again and check for dialing ISDN devices.
  809. //
  810. if (ERROR_SUCCESS != hRC ||
  811. FALSE != *lpfNeedModem)
  812. {
  813. if (IsDialableISDNAdapters())
  814. {
  815. hRC = ERROR_SUCCESS;
  816. *lpfNeedModem = FALSE;
  817. }
  818. }
  819. return(hRC);
  820. }
  821. //+----------------------------------------------------------------------------
  822. //
  823. // Function: IcfgInstallModem
  824. //
  825. // Synopsis:
  826. // This function is called when ICW verified that RAS is installed,
  827. // but no modems are avilable. It needs to make sure a modem is availble.
  828. // There are two possible scenarios:
  829. //
  830. // a. There are no modems installed. This happens when someone deleted
  831. // a modem after installing RAS. In this case we need to run the modem
  832. // install wizard, and configure the newly installed modem to be a RAS
  833. // dialout device.
  834. //
  835. // b. There are modems installed, but non of them is configured as a dial out
  836. // device. In this case, we silently convert them to be DialInOut devices,
  837. // so ICW can use them.
  838. //
  839. // Arguments: hwndParent - handle to parent window
  840. // dwfOptions - not used
  841. //
  842. // Returns: lpfNeedsStart - not used
  843. //
  844. // History: 6/5/97 ChrisK Inherited
  845. //
  846. //-----------------------------------------------------------------------------
  847. HRESULT WINAPI
  848. IcfgInstallModemNT4 (HWND hwndParent, DWORD dwfOptions, LPBOOL lpfNeedsStart)
  849. {
  850. //
  851. // Check what modems are available to RAS
  852. //
  853. HKEY hUnimodem;
  854. LONG dwError;
  855. BOOL fInstallModem = FALSE;
  856. Dprintf("ICFGNT: IcfgInstallModem\n");
  857. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  858. szRasUnimodemSubKey,
  859. 0,
  860. KEY_READ,
  861. &hUnimodem);
  862. if(dwError != ERROR_SUCCESS)
  863. {
  864. fInstallModem = TRUE;
  865. }
  866. else
  867. {
  868. LPBYTE lpData;
  869. dwError = GetRegValue(hUnimodem, szUsage, &lpData);
  870. if(dwError != ERROR_SUCCESS)
  871. {
  872. fInstallModem = TRUE;
  873. }
  874. else
  875. {
  876. // Make sure at least one modem exists
  877. if(*lpData == '\0')
  878. {
  879. fInstallModem = TRUE;
  880. }
  881. }
  882. }
  883. if(fInstallModem)
  884. {
  885. //
  886. // Fire up the modem install wizard
  887. //
  888. if(!CallModemInstallWizard(hwndParent))
  889. {
  890. return(g_dwLastError = GetLastError());
  891. }
  892. //
  893. // Now configure the new modem to be a dial out device.
  894. //
  895. //
  896. // Install ras again with unattneded file!
  897. //
  898. return(ERROR_SUCCESS);
  899. }
  900. else
  901. {
  902. //
  903. // We need to reconfigure dial in devices to be dialinout
  904. //
  905. //
  906. // install ras again with unattended file!
  907. //
  908. return(ERROR_SUCCESS);
  909. }
  910. }
  911. //+----------------------------------------------------------------------------
  912. //
  913. // Function: IcfgNeedInetComponets
  914. //
  915. // Synopsis: Check to see if the components marked in the options are
  916. // installed on the system
  917. //
  918. // Arguements: dwfOptions - set of bit flag indicating which components to
  919. // check for
  920. //
  921. // Returns; HRESULT - S_OK if successfull
  922. // lpfNeedComponents - TRUE is some components are not installed
  923. //
  924. // History: 6/5/97 ChrisK Inherited
  925. //
  926. //-----------------------------------------------------------------------------
  927. HRESULT WINAPI
  928. IcfgNeedInetComponentsNT4(DWORD dwfOptions, LPBOOL lpfNeedComponents) {
  929. DWORD dwErr;
  930. //
  931. // Assume need nothing
  932. //
  933. *lpfNeedComponents = FALSE;
  934. Dprintf("ICFGNT: IcfgNeedInetComponents\n");
  935. dwErr = LoadNetcfg();
  936. if(dwErr != ERROR_SUCCESS)
  937. {
  938. return(g_dwLastError = dwErr); // Shouldn't we map to hResult?
  939. }
  940. WCHAR wszInfNameBuf[512];
  941. DWORD cchInfName = sizeof(wszInfNameBuf) / sizeof(WCHAR);
  942. if(dwfOptions & ICFG_INSTALLTCP)
  943. {
  944. dwErr = pfnNetSetupFindSoftwareComponent(L"TC",
  945. wszInfNameBuf,
  946. &cchInfName,
  947. 0,
  948. 0);
  949. if(dwErr != ERROR_SUCCESS)
  950. *lpfNeedComponents = TRUE;
  951. }
  952. if(dwfOptions & ICFG_INSTALLRAS)
  953. {
  954. dwErr = pfnNetSetupFindSoftwareComponent(L"RAS",
  955. wszInfNameBuf,
  956. &cchInfName,
  957. 0,
  958. 0);
  959. if(dwErr != ERROR_SUCCESS)
  960. *lpfNeedComponents = TRUE;
  961. }
  962. if(dwfOptions & ICFG_INSTALLMAIL)
  963. {
  964. // How do we do this?
  965. }
  966. return(ERROR_SUCCESS);
  967. }
  968. //+----------------------------------------------------------------------------
  969. //
  970. // Function: GenerateRasUnattendedFile
  971. //
  972. // Synopsis: Create the file that will provide RAS setup the necessary
  973. // setting to install in an unattended mode
  974. //
  975. // Arguments: wszTmpFile - name of file to create
  976. // szPortsBuf
  977. //
  978. // Returns: FALSE - failure, TRUE - success
  979. //
  980. // History: 6/5/97 ChrisK Inherited
  981. //
  982. //-----------------------------------------------------------------------------
  983. BOOL
  984. GenerateRasUnattendedFile(LPWSTR wszTmpFile, LPSTR szPortsBuf)
  985. {
  986. WCHAR wszTmpPath[MAX_PATH+1];
  987. WCHAR wszTmpShortPath[MAX_PATH+1];
  988. //
  989. // Create temporary file name and convert to non-wide form
  990. //
  991. Dprintf("ICFGNT: GenerateRasUnattendedFile\n");
  992. if (GetTempPathW(MAX_PATH, wszTmpPath) == 0)
  993. {
  994. return(FALSE);
  995. }
  996. //
  997. // always attempt to create the temp dir as the temp dir may not exist if
  998. // the user logs in with a roaming profile
  999. //
  1000. CreateDirectoryW(wszTmpPath, NULL);
  1001. //
  1002. // need to convert this to a short path since pfnNetSetupComponentInstall()
  1003. // doesn't like to have a long path in the InfSymbols param.
  1004. //
  1005. if (!GetShortPathNameW(wszTmpPath, wszTmpShortPath, MAX_PATH))
  1006. {
  1007. return FALSE;
  1008. }
  1009. if (GetTempFileNameW(wszTmpPath, L"icw", 0, wszTmpFile) == 0)
  1010. {
  1011. return(FALSE);
  1012. }
  1013. //
  1014. // need to convert the temp filename to shortpath too!
  1015. //
  1016. if (!GetShortPathNameW(wszTmpFile, wszTmpShortPath, MAX_PATH))
  1017. {
  1018. return FALSE;
  1019. }
  1020. wcscpy(wszTmpFile, wszTmpShortPath);
  1021. char szTmpFile[MAX_PATH+1];
  1022. wcstombs(szTmpFile, wszTmpFile, wcslen(wszTmpFile) + 1);
  1023. #if 0
  1024. /*
  1025. FILE *fp = fopen(szTmpFile, "w");
  1026. if(fp == 0)
  1027. {
  1028. return(FALSE);
  1029. }
  1030. fprintf(fp, "[RemoteAccessParameters]\n");
  1031. fprintf(fp, "PortSections = ");
  1032. LPSTR szPorts = szPortsBuf;
  1033. while(*szPorts) {
  1034. if(szPorts != szPortsBuf)
  1035. {
  1036. fprintf(fp, ",");
  1037. }
  1038. fprintf(fp, "%s", szPorts);
  1039. szPorts += lstrlen(szPorts) + 1;
  1040. }
  1041. fprintf(fp, "\n");
  1042. fprintf(fp, "DialoutProtocols = TCP/IP\n");
  1043. fprintf(fp, "\n");
  1044. fprintf(fp, "[Modem]\n");
  1045. fprintf(fp, "InstallModem=ModemSection\n");
  1046. fprintf(fp, "\n");
  1047. szPorts = szPortsBuf;
  1048. while(*szPorts) {
  1049. fprintf(fp, "[%s]\n", szPorts);
  1050. fprintf(fp, "PortName = %s\n", szPorts);
  1051. fprintf(fp, "DeviceType = Modem\n");
  1052. fprintf(fp, "PortUsage = DialOut\n");
  1053. fprintf(fp, "\n");
  1054. szPorts += lstrlen(szPorts) + 1;
  1055. }
  1056. fprintf(fp, "[ModemSection]\n");
  1057. fclose(fp);
  1058. */
  1059. #else
  1060. //
  1061. // Open the file for writing, bail on fail.
  1062. //
  1063. BOOL bRet = FALSE;
  1064. HANDLE hFile = CreateFile(szTmpFile,GENERIC_WRITE,0,NULL,OPEN_EXISTING,
  1065. FILE_ATTRIBUTE_NORMAL,NULL);
  1066. if (INVALID_HANDLE_VALUE == hFile)
  1067. {
  1068. return FALSE;
  1069. }
  1070. LPSTR szPorts = szPortsBuf;
  1071. char szFileBuf[MAX_PATH]={0};
  1072. DWORD dwWrite;
  1073. lstrcpy(szFileBuf, "[RemoteAccessParameters]\nPortSections = ");
  1074. if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL))
  1075. {
  1076. goto closefile;
  1077. }
  1078. while (*szPorts)
  1079. {
  1080. //
  1081. // Delimit each item with a comma
  1082. //
  1083. if (szPorts != szPortsBuf)
  1084. {
  1085. lstrcpy(szFileBuf, ",");
  1086. if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL))
  1087. {
  1088. goto closefile;
  1089. }
  1090. }
  1091. //
  1092. // Write each port
  1093. //
  1094. lstrcpyn(szFileBuf, szPorts, CELEMS(szFileBuf));
  1095. if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL))
  1096. {
  1097. goto closefile;
  1098. }
  1099. szPorts += lstrlen(szPorts) + 1;
  1100. }
  1101. //
  1102. // Write DialoutProtocol TCP/IP and InstallModem
  1103. //
  1104. lstrcpy(szFileBuf, "\nDialoutProtocols = TCP/IP\n\n[Modem]\nInstallModem=ModemSection\n\n");
  1105. if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL))
  1106. {
  1107. goto closefile;
  1108. }
  1109. //
  1110. // Enumerate ports again
  1111. //
  1112. szPorts = szPortsBuf;
  1113. while (*szPorts)
  1114. {
  1115. //
  1116. // Write PortName section and entry
  1117. //
  1118. wsprintf(szFileBuf, "[%s]\n", szPorts);
  1119. if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL))
  1120. {
  1121. goto closefile;
  1122. }
  1123. wsprintf(szFileBuf, "PortName = %s\n", szPorts);
  1124. if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL))
  1125. {
  1126. goto closefile;
  1127. }
  1128. //
  1129. // Write DeviceType and PortUsage entry for each port
  1130. //
  1131. lstrcpy(szFileBuf, "DeviceType = Modem\nPortUsage = DialOut\n\n");
  1132. if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL))
  1133. {
  1134. goto closefile;
  1135. }
  1136. szPorts += lstrlen(szPorts) + 1;
  1137. }
  1138. lstrcpy(szFileBuf, "[ModemSection]\n");
  1139. if (!WriteFile(hFile, szFileBuf, lstrlen(szFileBuf), &dwWrite, NULL))
  1140. {
  1141. goto closefile;
  1142. }
  1143. bRet = TRUE;
  1144. closefile:
  1145. CloseHandle(hFile);
  1146. #endif
  1147. return(bRet);
  1148. }
  1149. //+----------------------------------------------------------------------------
  1150. //
  1151. // Function: InstallRAS
  1152. //
  1153. // Synopsis: Invoke unattended RAS installation
  1154. //
  1155. // Arguments: hwndParent - handle to parent window
  1156. // szFile - name of unattended settings file
  1157. // szSection -
  1158. //
  1159. // Returns: DWORD - win32 error
  1160. // pdwReturn - return code from last parameter of
  1161. // pfnNetSetupComponentInstall
  1162. //
  1163. // History: 6/5/97 ChrisK Inherited
  1164. //
  1165. //-----------------------------------------------------------------------------
  1166. DWORD
  1167. InstallRAS(HWND hwndParent, LPWSTR szFile, LPWSTR szSection, LPDWORD pdwReturn)
  1168. {
  1169. WCHAR InfSymbols[1024];
  1170. LPWSTR szInfSymbols = InfSymbols;
  1171. Dprintf("ICFGNT: InstallRAS\n");
  1172. DWORD dwRC = InstallNTNetworking(hwndParent);
  1173. if (ERROR_SUCCESS != dwRC)
  1174. {
  1175. return dwRC;
  1176. }
  1177. LPWSTR szString1 = L"!STF_GUI_UNATTENDED";
  1178. wcscpy(szInfSymbols, szString1);
  1179. szInfSymbols += wcslen(szString1) + 1;
  1180. LPWSTR szString2 = L"YES";
  1181. wcscpy(szInfSymbols, szString2);
  1182. szInfSymbols += wcslen(szString2) + 1;
  1183. LPWSTR szString3 = L"!STF_UNATTENDED";
  1184. wcscpy(szInfSymbols, szString3);
  1185. szInfSymbols += wcslen(szString3) + 1;
  1186. //
  1187. // Unattneded file.
  1188. //
  1189. wcscpy(szInfSymbols, szFile);
  1190. szInfSymbols += wcslen(szFile) + 1;
  1191. LPWSTR szString4 = L"!STF_UNATTENDED_SECTION";
  1192. wcscpy(szInfSymbols, szString4);
  1193. szInfSymbols += wcslen(szString4) + 1;
  1194. //
  1195. // Unattnded section
  1196. //
  1197. wcscpy(szInfSymbols, szSection);
  1198. szInfSymbols += wcslen(szSection) + 1;
  1199. *szInfSymbols++ = 0;
  1200. *szInfSymbols++ = 0;
  1201. return(pfnNetSetupComponentInstall(hwndParent,
  1202. L"RAS",
  1203. L"OEMNSVRA.INF",
  1204. g_wszInstallPath,
  1205. InfSymbols,
  1206. INFINSTALL_INPROCINTERP, // Install Flags
  1207. pdwReturn));
  1208. }
  1209. //+----------------------------------------------------------------------------
  1210. //
  1211. // Function: IcfgInstallInetComponents
  1212. //
  1213. // Synopsis: Install the components as specified by the dwfOptions values
  1214. //
  1215. // Arguments hwndParent - handle to parent window
  1216. // dwfOptions - set of bit flags indicating which components to
  1217. // install
  1218. //
  1219. // Returns: HRESULT - S_OK if success
  1220. // lpfNeedsReboot - TRUE if reboot is required
  1221. //
  1222. // History: 6/5/97 ChrisK Inherited
  1223. //
  1224. //-----------------------------------------------------------------------------
  1225. HRESULT WINAPI
  1226. IcfgInstallInetComponentsNT4(HWND hwndParent, DWORD dwfOptions, LPBOOL lpfNeedsRestart)
  1227. {
  1228. DWORD dwErr;
  1229. DWORD dwReturn;
  1230. BOOL fNeedsReview;
  1231. BOOL fNeedsRestart;
  1232. BOOL fDoReview = FALSE;
  1233. WCHAR wszInfNameBuf[512];
  1234. DWORD cchInfName = sizeof(wszInfNameBuf) / sizeof(WCHAR);
  1235. Dprintf("ICFGNT: IcfgInstallInetComponents\n");
  1236. //
  1237. // Assume don't need restart
  1238. //
  1239. *lpfNeedsRestart = FALSE;
  1240. dwErr = LoadNetcfg();
  1241. if(dwErr != ERROR_SUCCESS)
  1242. {
  1243. return(g_dwLastError = dwErr); // Review: Shouldn't we map to hResult?
  1244. }
  1245. if(dwfOptions & ICFG_INSTALLTCP)
  1246. {
  1247. dwErr = pfnNetSetupFindSoftwareComponent(L"TC",
  1248. wszInfNameBuf,
  1249. &cchInfName,
  1250. 0,
  1251. 0);
  1252. if(dwErr != ERROR_SUCCESS)
  1253. {
  1254. dwErr = pfnNetSetupComponentInstall(hwndParent,
  1255. L"TC",
  1256. L"OEMNXPTC.INF",
  1257. g_wszInstallPath,
  1258. L"\0\0",
  1259. INFINSTALL_INPROCINTERP, // Install Flags
  1260. &dwReturn);
  1261. if(dwErr != ERROR_SUCCESS)
  1262. {
  1263. return(g_dwLastError = dwErr); // Review: Shouldn't we map to hResult?
  1264. }
  1265. ParseNetSetupReturn(dwReturn, fNeedsRestart, fNeedsReview);
  1266. if(fNeedsRestart)
  1267. {
  1268. *lpfNeedsRestart = TRUE;
  1269. }
  1270. if(fNeedsReview)
  1271. {
  1272. fDoReview = TRUE;
  1273. }
  1274. }
  1275. }
  1276. if(dwfOptions & ICFG_INSTALLRAS)
  1277. {
  1278. dwErr = pfnNetSetupFindSoftwareComponent(L"RAS",
  1279. wszInfNameBuf,
  1280. &cchInfName,
  1281. 0,
  1282. 0);
  1283. if(dwErr != ERROR_SUCCESS)
  1284. {
  1285. //
  1286. // Before we install RAS, we have to make have to make sure a modem
  1287. // is installed, because RAS will try to run the modem detection wizard
  1288. // in unattneded mode if there are no modems, and we don't want that.
  1289. //
  1290. // The way we do that is we enumerate devices through TAPI, and if there are
  1291. // no modems installed, we call the modem install wizard. Only after
  1292. // we make sure a modem was installed, we call ras install.
  1293. //
  1294. DWORD DoTapiModemsExist(LPBOOL pfTapiModemsExist);
  1295. char portsbuf[1000];
  1296. dwErr = EnumerateTapiModemPorts(sizeof(portsbuf), portsbuf);
  1297. if(dwErr)
  1298. return(g_dwLastError = dwErr);
  1299. if(*portsbuf == 0)
  1300. {
  1301. if(!CallModemInstallWizard(hwndParent))
  1302. {
  1303. //
  1304. // if CallModemInstallWizard returned FALSE and
  1305. // GetLastError() is ERROR_SUCCESS, it is actually
  1306. // a user cancelled case
  1307. //
  1308. if (ERROR_SUCCESS == (g_dwLastError = GetLastError()))
  1309. g_dwLastError = ERROR_CANCELLED;
  1310. return(g_dwLastError);
  1311. }
  1312. //
  1313. // In this invocation of EnumerateTapiModemPorts
  1314. // we have to wait for a 1 second before we start
  1315. // enumerating the modems - hence set the last parameter
  1316. // to TRUE -- VetriV
  1317. //
  1318. dwErr = EnumerateTapiModemPorts(sizeof(portsbuf), portsbuf,
  1319. TRUE);
  1320. if(dwErr)
  1321. {
  1322. return(g_dwLastError = dwErr);
  1323. }
  1324. if(*portsbuf == 0)
  1325. {
  1326. return(g_dwLastError = ERROR_CANCELLED);
  1327. }
  1328. }
  1329. WCHAR wszUnattFile[MAX_PATH];
  1330. if(!GenerateRasUnattendedFile(wszUnattFile, portsbuf))
  1331. {
  1332. return(g_dwLastError = GetLastError());
  1333. }
  1334. dwErr = InstallRAS(hwndParent,
  1335. wszUnattFile,
  1336. L"RemoteAccessParameters",
  1337. &dwReturn);
  1338. DeleteFileW(wszUnattFile);
  1339. if(dwErr != ERROR_SUCCESS)
  1340. {
  1341. return(g_dwLastError = dwErr); // Review: Shouldn't we map to hResult?
  1342. }
  1343. ParseNetSetupReturn(dwReturn, fNeedsRestart, fNeedsReview);
  1344. if(fNeedsRestart)
  1345. {
  1346. *lpfNeedsRestart = TRUE;
  1347. }
  1348. if(fNeedsReview)
  1349. {
  1350. fDoReview = TRUE;
  1351. }
  1352. }
  1353. }
  1354. if(fDoReview)
  1355. {
  1356. return(g_dwLastError = ReviewBindings(hwndParent)); // Review: Shouldn't we map to hresult?
  1357. }
  1358. else
  1359. {
  1360. return(ERROR_SUCCESS);
  1361. }
  1362. }
  1363. //+----------------------------------------------------------------------------
  1364. //
  1365. // Function: IcfgIsFileSharingTurnedOn
  1366. //
  1367. // Synopsis: Check network bindings to determine if "Server" service is
  1368. // bound to ndiswan adapter
  1369. //
  1370. // Arguments: dwfDriverType -
  1371. //
  1372. // Returns: HRESULT - S_OK is success
  1373. // lpfSharingOn - TRUE if sharing is bound
  1374. //
  1375. // History: 6/5/97 ChrisK Inherited
  1376. //
  1377. //-----------------------------------------------------------------------------
  1378. LPSTR szLanManServerSubKey = "SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Linkage";
  1379. LPSTR szBind = "Bind";
  1380. LPSTR szExport = "Export";
  1381. LPSTR szRoute = "Route";
  1382. LPSTR szLanManServerDisabledSubKey = "SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Linkage\\Disabled";
  1383. LPSTR szNdisWan4 = "NdisWan";
  1384. struct BINDDATA
  1385. {
  1386. CHAR *startb;
  1387. CHAR *currb;
  1388. CHAR *starte;
  1389. CHAR *curre;
  1390. CHAR *startr;
  1391. CHAR *currr;
  1392. } net_bindings;
  1393. HRESULT WINAPI
  1394. IcfgIsFileSharingTurnedOn(DWORD dwfDriverType, LPBOOL lpfSharingOn)
  1395. {
  1396. HRESULT hr = ERROR_SUCCESS;
  1397. HKEY hKey = NULL;
  1398. LPBYTE lpData = NULL;
  1399. CHAR *p;
  1400. Dprintf("ICFGNT: IcfgIsFileSharingTurnedOn\n");
  1401. Assert(lpfSharingOn);
  1402. if (NULL == lpfSharingOn)
  1403. {
  1404. hr = ERROR_INVALID_PARAMETER;
  1405. goto IcfgIsFileSharingTurnedOnExit;
  1406. }
  1407. *lpfSharingOn = FALSE;
  1408. //
  1409. // Open lanmanServer registry key
  1410. //
  1411. if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
  1412. szLanManServerSubKey,
  1413. &hKey))
  1414. {
  1415. Dprintf("ICFGNT: Failed to open lanmanServer key\n");
  1416. goto IcfgIsFileSharingTurnedOnExit;
  1417. }
  1418. if (ERROR_SUCCESS != GetRegValue(hKey, szBind, &lpData))
  1419. {
  1420. Dprintf("ICFGNT: Failed to read binding information\n");
  1421. goto IcfgIsFileSharingTurnedOnExit;
  1422. }
  1423. Assert(lpData);
  1424. //
  1425. // Look for a particular string in the data returned
  1426. // Note: data is terminiated with two NULLs
  1427. //
  1428. p = (CHAR *)lpData;
  1429. while (*p)
  1430. {
  1431. if (strstr( p, szNdisWan4))
  1432. {
  1433. Dprintf("ICFGNT: NdisWan4 binding found in %s\n",p);
  1434. *lpfSharingOn = TRUE;
  1435. break;
  1436. }
  1437. p += (lstrlen( p ) + 1);
  1438. }
  1439. IcfgIsFileSharingTurnedOnExit:
  1440. if (hKey)
  1441. {
  1442. RegCloseKey(hKey);
  1443. hKey = NULL;
  1444. }
  1445. if (lpData)
  1446. {
  1447. GlobalFree(lpData);
  1448. lpData = NULL;
  1449. }
  1450. return hr;
  1451. }
  1452. //+----------------------------------------------------------------------------
  1453. //
  1454. // Function: MoveNextBinding
  1455. //
  1456. // Synopsis: Move to the next string in a MULTISZ data buffer
  1457. //
  1458. // Arguments: lpcBinding - pointer to address of current buffer position
  1459. //
  1460. // Returns: lpcBinding - pointer to next string
  1461. //
  1462. // History: 6/5/97 ChrisK Created
  1463. //
  1464. //-----------------------------------------------------------------------------
  1465. inline void MoveNextBinding(CHAR **lplpcBinding)
  1466. {
  1467. Dprintf("ICFGNT: MoveNextBinding\n");
  1468. Assert(lplpcBinding && *lplpcBinding);
  1469. if (lplpcBinding && *lplpcBinding)
  1470. {
  1471. *lplpcBinding += (lstrlen(*lplpcBinding)+1);
  1472. }
  1473. else
  1474. {
  1475. Dprintf("ICFGNT: MoveNextBinding received invalid parameter\n");
  1476. }
  1477. }
  1478. //+----------------------------------------------------------------------------
  1479. //
  1480. // Function: CompactLinkage
  1481. //
  1482. // Synopsis: Compact a list of Multi_SZ data
  1483. //
  1484. // Arguments: lpBinding - point to the string of an Multi_Sz list that should
  1485. // be over written
  1486. //
  1487. // Returns: none
  1488. //
  1489. // History: 6/5/97 ChrisK Created
  1490. //
  1491. //-----------------------------------------------------------------------------
  1492. inline void CompactLinkage(CHAR *lpBinding)
  1493. {
  1494. Dprintf("ICFGNT: CompactLinkage\n");
  1495. Assert(lpBinding && *lpBinding);
  1496. CHAR *lpLast = lpBinding;
  1497. BOOL fNULLChar = FALSE;
  1498. MoveNextBinding(&lpBinding);
  1499. //
  1500. // ChrisK Olympus 6311 6/11/97
  1501. // Do not compact on a per string basis. This causes the data to become
  1502. // corrupted if the string being removed is shorter than the string being
  1503. // added. Instead compact on a per character basis, since those are always
  1504. // the same size (on a given machine).
  1505. //
  1506. while (!fNULLChar || *lpBinding)
  1507. {
  1508. if (NULL == *lpBinding)
  1509. {
  1510. fNULLChar = TRUE;
  1511. }
  1512. else
  1513. {
  1514. fNULLChar = FALSE;
  1515. }
  1516. *lpLast++ = *lpBinding++;
  1517. }
  1518. //while (*lpBinding)
  1519. //{
  1520. // lstrcpy(lpLast,lpBinding);
  1521. // lpLast = lpBinding;
  1522. // MoveNextBinding(&lpBinding);
  1523. //}
  1524. //
  1525. // Add second terminating NULL
  1526. //
  1527. *lpLast = '\0';
  1528. }
  1529. //+----------------------------------------------------------------------------
  1530. //
  1531. // Function: SizeOfMultiSz
  1532. //
  1533. // Synopsis: determine the total size of a Multi_sz list, including
  1534. // terminating NULLs
  1535. //
  1536. // Arguments: s - pointer to list
  1537. //
  1538. // Returns: DWORD - size of s
  1539. //
  1540. // History: 6/5/97 ChrisK created
  1541. //
  1542. //-----------------------------------------------------------------------------
  1543. DWORD SizeOfMultiSz(CHAR *s)
  1544. {
  1545. Dprintf("ICFGNT: SizeOfMultiSz\n");
  1546. Assert(s);
  1547. DWORD dwLen = 0;
  1548. //
  1549. // total size of all strings
  1550. //
  1551. //
  1552. // ChrisK Olympus 6311 6/11/97
  1553. // Add special case for empty MultiSZ strings
  1554. //
  1555. //
  1556. // Special case for empty MultiSz.
  1557. // Note: even "empty" MultiSZ strings still have the two null terminating characters
  1558. //
  1559. if (!(*s))
  1560. {
  1561. //
  1562. // Make sure we actually have two terminating NULLs in this case.
  1563. //
  1564. Assert(s[1] == '\0');
  1565. //
  1566. // Count terminating NULL.
  1567. //
  1568. dwLen = 1;
  1569. }
  1570. while (*s)
  1571. {
  1572. dwLen += lstrlen(s) + 1;
  1573. s += lstrlen(s) + 1;
  1574. }
  1575. //
  1576. // plus one for the extra terminating NULL
  1577. //
  1578. dwLen++;
  1579. Dprintf("ICFGNT: SizeOfMultiSz returns %d\n", dwLen);
  1580. return dwLen;
  1581. }
  1582. //+----------------------------------------------------------------------------
  1583. //
  1584. // Function: WriteBindings
  1585. //
  1586. // Synopsis: Write the data from a BINDDATA structure to the key given
  1587. //
  1588. // Arguments: bd - BINDDATA structure with data to be written
  1589. // hKey - handle of registry key to get data
  1590. //
  1591. // Returns: win32 error code
  1592. //
  1593. // History: 6/5/97 ChrisK created
  1594. //
  1595. //-----------------------------------------------------------------------------
  1596. DWORD WriteBindings(BINDDATA bd, HKEY hKey)
  1597. {
  1598. DWORD dwRC = ERROR_SUCCESS;
  1599. DWORD dwSize;
  1600. Assert (hKey &&
  1601. bd.startb &&
  1602. bd.starte &&
  1603. bd.startr);
  1604. Dprintf("ICFGNT: WriteBindings\n");
  1605. //
  1606. // Bind
  1607. //
  1608. dwSize = SizeOfMultiSz(bd.startb);
  1609. if (ERROR_SUCCESS != (dwRC = RegSetValueEx(hKey,
  1610. szBind,
  1611. NULL,
  1612. REG_MULTI_SZ,
  1613. (LPBYTE)bd.startb,
  1614. dwSize)))
  1615. {
  1616. Dprintf("ICFGNT: Failed to write Bind key\n");
  1617. goto WriteBindingsExit;
  1618. }
  1619. //
  1620. // Export
  1621. //
  1622. dwSize = SizeOfMultiSz(bd.starte);
  1623. if (ERROR_SUCCESS != (dwRC = RegSetValueEx(hKey,
  1624. szExport,
  1625. NULL,
  1626. REG_MULTI_SZ,
  1627. (LPBYTE)bd.starte,
  1628. dwSize)))
  1629. {
  1630. Dprintf("ICFGNT: Failed to write export key\n");
  1631. goto WriteBindingsExit;
  1632. }
  1633. //
  1634. // Route
  1635. //
  1636. dwSize = SizeOfMultiSz(bd.startr);
  1637. if (ERROR_SUCCESS != (dwRC = RegSetValueEx(hKey,
  1638. szRoute,
  1639. NULL,
  1640. REG_MULTI_SZ,
  1641. (LPBYTE)bd.startr,
  1642. dwSize)))
  1643. {
  1644. Dprintf("ICFGNT: Failed to write route key\n");
  1645. goto WriteBindingsExit;
  1646. }
  1647. WriteBindingsExit:
  1648. return dwRC;
  1649. }
  1650. //+----------------------------------------------------------------------------
  1651. //
  1652. // Function: IcfgTurnOffFileSharing
  1653. //
  1654. // Synopsis; Disable the binding between the "server" net service and the
  1655. // ndiswan4 device
  1656. //
  1657. // Arguments: dwfDriverType -
  1658. // hwndParent - parent window
  1659. //
  1660. // Returns: HRESULT - S_OK if success
  1661. //
  1662. // History: 6/5/97 ChrisK Inherited
  1663. //
  1664. //-----------------------------------------------------------------------------
  1665. HRESULT WINAPI
  1666. IcfgTurnOffFileSharing(DWORD dwfDriverType, HWND hwndParent)
  1667. {
  1668. BINDDATA LinkData = {NULL, NULL, NULL, NULL, NULL, NULL};
  1669. BINDDATA DisData = {NULL, NULL, NULL, NULL, NULL, NULL};
  1670. HKEY hKeyLink = NULL;
  1671. HKEY hKeyDis = NULL;
  1672. HRESULT hr = ERROR_SUCCESS;
  1673. BOOL bUpdateReg = FALSE;
  1674. Dprintf("ICFGNT: IcfgTurnOffFileSharing\n");
  1675. Assert(hwndParent);
  1676. if (NULL == hwndParent)
  1677. {
  1678. hr = ERROR_INVALID_PARAMETER;
  1679. goto IcfgTurnOffFileSharingExit;
  1680. }
  1681. //
  1682. // Open Keys and read binding data
  1683. //
  1684. if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
  1685. szLanManServerSubKey,
  1686. &hKeyLink))
  1687. {
  1688. Dprintf("ICFGNT: failed to open linkdata key\n");
  1689. goto IcfgTurnOffFileSharingExit;
  1690. }
  1691. if (ERROR_SUCCESS != RegOpenKey(HKEY_LOCAL_MACHINE,
  1692. szLanManServerDisabledSubKey,
  1693. &hKeyDis))
  1694. {
  1695. Dprintf("ICFGNT: failed to open linkdata key\n");
  1696. goto IcfgTurnOffFileSharingExit;
  1697. }
  1698. GetRegValue(hKeyLink,szBind,(LPBYTE*)&LinkData.startb);
  1699. GetRegValue(hKeyLink,szExport,(LPBYTE*)&LinkData.starte);
  1700. GetRegValue(hKeyLink,szRoute,(LPBYTE*)&LinkData.startr);
  1701. GetRegValue(hKeyDis,szBind,(LPBYTE*)&DisData.startb);
  1702. GetRegValue(hKeyDis,szExport,(LPBYTE*)&DisData.starte);
  1703. GetRegValue(hKeyDis,szRoute,(LPBYTE*)&DisData.startr);
  1704. //
  1705. // Initialize all current pointers
  1706. //
  1707. LinkData.currb = LinkData.startb;
  1708. LinkData.curre = LinkData.starte;
  1709. LinkData.currr = LinkData.startr;
  1710. DisData.currb = DisData.startb;
  1711. while (*DisData.currb)
  1712. {
  1713. MoveNextBinding(&DisData.currb);
  1714. }
  1715. DisData.curre = DisData.starte;
  1716. while (*DisData.curre)
  1717. {
  1718. MoveNextBinding(&DisData.curre);
  1719. }
  1720. DisData.currr = DisData.startr;
  1721. while (*DisData.currr)
  1722. {
  1723. MoveNextBinding(&DisData.currr);
  1724. }
  1725. //
  1726. // Scan linkages for NdisWan4 bindings
  1727. //
  1728. while (*LinkData.currb)
  1729. {
  1730. if (strstr(LinkData.currb, szNdisWan4))
  1731. {
  1732. Dprintf("ICFGNT: server binding found in %s\n",LinkData.currb);
  1733. //
  1734. // move binding to disabled list
  1735. //
  1736. lstrcpy(DisData.currb,LinkData.currb);
  1737. lstrcpy(DisData.curre,LinkData.curre);
  1738. lstrcpy(DisData.currr,LinkData.currr);
  1739. //
  1740. // Advanve current pointers in DisData
  1741. //
  1742. MoveNextBinding(&DisData.currb);
  1743. MoveNextBinding(&DisData.curre);
  1744. MoveNextBinding(&DisData.currr);
  1745. //
  1746. // Compact remaining linkage
  1747. //
  1748. CompactLinkage(LinkData.currb);
  1749. CompactLinkage(LinkData.curre);
  1750. CompactLinkage(LinkData.currr);
  1751. bUpdateReg = TRUE;
  1752. }
  1753. else
  1754. {
  1755. //
  1756. // Advance to next binding
  1757. //
  1758. MoveNextBinding(&LinkData.currb);
  1759. MoveNextBinding(&LinkData.curre);
  1760. MoveNextBinding(&LinkData.currr);
  1761. }
  1762. }
  1763. if (bUpdateReg)
  1764. {
  1765. WriteBindings(LinkData,hKeyLink);
  1766. WriteBindings(DisData,hKeyDis);
  1767. RegCloseKey(hKeyDis);
  1768. hKeyDis = NULL;
  1769. RegCloseKey(hKeyLink);
  1770. hKeyLink = NULL;
  1771. #if defined(_DEBUG)
  1772. Dprintf("ICFGNT: ReviewBindings returnded %d\n",ReviewBindings(hwndParent));
  1773. #else
  1774. ReviewBindings(hwndParent);
  1775. #endif
  1776. }
  1777. IcfgTurnOffFileSharingExit:
  1778. if (hKeyDis)
  1779. {
  1780. RegCloseKey(hKeyDis);
  1781. hKeyDis = NULL;
  1782. }
  1783. if (hKeyLink)
  1784. {
  1785. RegCloseKey(hKeyLink);
  1786. hKeyLink = NULL;
  1787. }
  1788. return hr;
  1789. }