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.

577 lines
17 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright (c) 1994-1999 Microsoft Corporation
  4. //*********************************************************************
  5. //
  6. // CFGAPI.C - Functions for exported config API.
  7. //
  8. // HISTORY:
  9. //
  10. // 96/05/22 markdu Created (from inetcfg.dll)
  11. // 96/05/25 markdu Use ICFG_ flags for lpNeedDrivers and lpInstallDrivers.
  12. // 96/05/27 markdu Added lpGetLastInstallErrorText.
  13. //
  14. #include "pch.hpp"
  15. UINT DetectModifyTCPIPBindings(DWORD dwCardFlags,LPCSTR pszBoundTo,BOOL fRemove,BOOL * pfBound);
  16. //*******************************************************************
  17. //
  18. // FUNCTION: IcfgGetLastInstallErrorText
  19. //
  20. // PURPOSE: Get a text string that describes the last installation
  21. // error that occurred. The string should be suitable
  22. // for display in a message box with no further formatting.
  23. //
  24. // PARAMETERS: lpszErrorDesc - points to buffer to receive the string.
  25. // cbErrorDesc - size of buffer.
  26. //
  27. // RETURNS: The length of the string returned.
  28. //
  29. //*******************************************************************
  30. extern "C" DWORD IcfgGetLastInstallErrorText(LPSTR lpszErrorDesc, DWORD cbErrorDesc)
  31. {
  32. if (lpszErrorDesc)
  33. {
  34. lstrcpyn(lpszErrorDesc, gpszLastErrorText, cbErrorDesc);
  35. return lstrlen(lpszErrorDesc);
  36. }
  37. else
  38. {
  39. return 0;
  40. }
  41. }
  42. //*******************************************************************
  43. //
  44. // FUNCTION: IcfgNeedInetComponents
  45. //
  46. // PURPOSE: Detects whether the specified system components are
  47. // installed or not.
  48. //
  49. // PARAMETERS: dwfOptions - a combination of ICFG_ flags that specify
  50. // which components to detect as follows:
  51. //
  52. // ICFG_INSTALLTCP - is TCP/IP needed?
  53. // ICFG_INSTALLRAS - is RAS needed?
  54. // ICFG_INSTALLMAIL - is exchange or internet mail needed?
  55. //
  56. // lpfNeedComponents - TRUE if any specified component needs
  57. // to be installed.
  58. //
  59. // RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
  60. //
  61. // History: 5/8/97 ChrisK Added INSTALLLAN,INSTALLDIALUP,INSTALLTCPONLY
  62. //
  63. //*******************************************************************
  64. extern "C" HRESULT IcfgNeedInetComponents(DWORD dwfOptions, LPBOOL lpfNeedComponents)
  65. {
  66. CLIENTCONFIG ClientConfig;
  67. DEBUGMSG("cfgapi.c::IcfgNeedInetComponents()");
  68. ASSERT(lpfNeedComponents);
  69. // read client configuration
  70. ZeroMemory(&ClientConfig,sizeof(CLIENTCONFIG));
  71. DWORD dwErrCls;
  72. UINT err=GetConfig(&ClientConfig,&dwErrCls);
  73. if (err != OK)
  74. {
  75. PrepareErrorMessage(IDS_ERRReadConfig,(UINT) err,
  76. dwErrCls,MB_ICONEXCLAMATION);
  77. return err;
  78. }
  79. // check if we are allowed to install TCP/IP
  80. if (dwfOptions & ICFG_INSTALLTCP)
  81. {
  82. // need TCP/IP present and bound to PPP driver
  83. if (!ClientConfig.fPPPBoundTCP)
  84. {
  85. if (lpfNeedComponents)
  86. {
  87. *lpfNeedComponents = TRUE;
  88. }
  89. return ERROR_SUCCESS;
  90. }
  91. }
  92. // check if we are allowed to install RNA
  93. if (dwfOptions & ICFG_INSTALLRAS)
  94. {
  95. // need PPPMAC and RNA files if using modem
  96. if (!ClientConfig.fRNAInstalled ||
  97. !ClientConfig.fPPPDriver)
  98. {
  99. if (lpfNeedComponents)
  100. {
  101. *lpfNeedComponents = TRUE;
  102. }
  103. return ERROR_SUCCESS;
  104. }
  105. }
  106. // need Exchange if not installed and user wants to install mail
  107. if ((dwfOptions & ICFG_INSTALLMAIL) &&
  108. (!ClientConfig.fMailInstalled || !ClientConfig.fInetMailInstalled))
  109. {
  110. if (lpfNeedComponents)
  111. {
  112. *lpfNeedComponents = TRUE;
  113. }
  114. return ERROR_SUCCESS;
  115. }
  116. //
  117. // ChrisK 5/8/97
  118. // check if we have a bound LAN adapter
  119. //
  120. if (dwfOptions & ICFG_INSTALLLAN)
  121. {
  122. if (!ClientConfig.fNetcard ||
  123. !ClientConfig.fNetcardBoundTCP)
  124. {
  125. if (lpfNeedComponents)
  126. {
  127. *lpfNeedComponents = TRUE;
  128. }
  129. return ERROR_SUCCESS;
  130. }
  131. }
  132. //
  133. // ChrisK 5/8/97
  134. // Check if we have a bound Dial up adapter
  135. //
  136. if (dwfOptions & ICFG_INSTALLDIALUP)
  137. {
  138. if (!ClientConfig.fPPPDriver ||
  139. !ClientConfig.fPPPBoundTCP)
  140. {
  141. if (lpfNeedComponents)
  142. {
  143. *lpfNeedComponents = TRUE;
  144. }
  145. return ERROR_SUCCESS;
  146. }
  147. }
  148. //
  149. // ChrisK 5/8/97
  150. // Check if TCP is install at all on this system
  151. //
  152. if (dwfOptions & ICFG_INSTALLTCPONLY)
  153. {
  154. if (!ClientConfig.fTcpip)
  155. {
  156. if (lpfNeedComponents)
  157. {
  158. *lpfNeedComponents = TRUE;
  159. }
  160. return ERROR_SUCCESS;
  161. }
  162. }
  163. // no extra drivers needed
  164. if (lpfNeedComponents)
  165. {
  166. *lpfNeedComponents = FALSE;
  167. }
  168. return ERROR_SUCCESS;
  169. }
  170. //*******************************************************************
  171. //
  172. // FUNCTION: IcfgInstallInetComponents
  173. //
  174. // PURPOSE: Install the specified system components.
  175. //
  176. // PARAMETERS: hwndParent - Parent window handle.
  177. // dwfOptions - a combination of ICFG_ flags that controls
  178. // the installation and configuration as follows:
  179. //
  180. // ICFG_INSTALLTCP - install TCP/IP (if needed)
  181. // ICFG_INSTALLRAS - install RAS (if needed)
  182. // ICFG_INSTALLMAIL - install exchange and internet mail
  183. //
  184. // lpfNeedsRestart - if non-NULL, then on return, this will be
  185. // TRUE if windows must be restarted to complete the installation.
  186. //
  187. // RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
  188. //
  189. //*******************************************************************
  190. extern "C" HRESULT IcfgInstallInetComponents(HWND hwndParent, DWORD dwfOptions,
  191. LPBOOL lpfNeedsRestart)
  192. {
  193. RETERR err;
  194. DWORD dwFiles = 0;
  195. BOOL fInitNetMAC = FALSE;
  196. BOOL fNeedTCPIP=FALSE;
  197. BOOL fNeedPPPMAC=FALSE;
  198. BOOL fNeedToRemoveTCPIP=FALSE;
  199. BOOL fNeedReboot = FALSE;
  200. DWORD dwErrCls;
  201. CLIENTCONFIG ClientConfig;
  202. DEBUGMSG("cfgapi.c::IcfgInstallInetComponents()");
  203. // read client configuration
  204. ZeroMemory(&ClientConfig,sizeof(CLIENTCONFIG));
  205. err=GetConfig(&ClientConfig,&dwErrCls);
  206. if (err != OK)
  207. {
  208. PrepareErrorMessage(IDS_ERRReadConfig,(UINT) err,
  209. dwErrCls,MB_ICONEXCLAMATION);
  210. return err;
  211. }
  212. // see if we initially have any kind of net card
  213. fInitNetMAC = (ClientConfig.fNetcard | ClientConfig.fPPPDriver);
  214. // install files we need
  215. // install mail if user wants it and not already installed
  216. if (dwfOptions & ICFG_INSTALLMAIL)
  217. {
  218. // need mail files (capone)?
  219. if (!ClientConfig.fMailInstalled)
  220. {
  221. DEBUGMSG("Installing Exchange files");
  222. dwFiles |= ICIF_MAIL;
  223. }
  224. // need internet mail files (rt 66)?
  225. if (!ClientConfig.fInetMailInstalled)
  226. {
  227. DEBUGMSG("Installing Internet Mail files");
  228. dwFiles |= ICIF_INET_MAIL;
  229. }
  230. }
  231. // check if we are allowed to install RNA
  232. if (dwfOptions & ICFG_INSTALLRAS)
  233. {
  234. // install RNA if user is connecting over modem and RNA
  235. // not already installed
  236. if (!ClientConfig.fRNAInstalled)
  237. {
  238. DEBUGMSG("Installing RNA files");
  239. dwFiles |= ICIF_RNA;
  240. }
  241. }
  242. if (dwFiles)
  243. {
  244. {
  245. WAITCURSOR WaitCursor; // show hourglass
  246. // install the component files
  247. err = InstallComponent(hwndParent,IC_INSTALLFILES,
  248. dwFiles);
  249. if (err == NEED_RESTART)
  250. {
  251. DEBUGMSG("Setting restart flag");
  252. // set restart flag so we restart the system at end
  253. fNeedReboot = TRUE;
  254. // NEED_REBOOT also implies success, so set ret code to OK
  255. err = OK;
  256. }
  257. // force an update of the dialog
  258. if (hwndParent)
  259. {
  260. HWND hParent = GetParent(hwndParent);
  261. UpdateWindow(hParent ? hParent : hwndParent);
  262. }
  263. // runonce.exe may get run at next boot, twiddle the
  264. // registry to work around a bug where it trashes the wallpaper
  265. PrepareForRunOnceApp();
  266. }
  267. if (err != OK)
  268. {
  269. PrepareErrorMessage(IDS_ERRInstallFiles,(UINT) err,
  270. ERRCLS_SETUPX,MB_ICONEXCLAMATION);
  271. return err;
  272. }
  273. WAITCURSOR WaitCursor; // show hourglass
  274. // do some extra stuff if we just installed mail
  275. if (dwFiles & ICIF_MAIL)
  276. {
  277. // .inf file leaves an entry in the registry to run
  278. // MS Exchange wizard, which we don't need since we'll be
  279. // configuring exchange ourselves. Remove the registry
  280. // entry.
  281. RemoveRunOnceEntry(IDS_MAIL_WIZARD_REG_VAL);
  282. // run mlset32, Exchange setup app that it needs to have run.
  283. // need to display error if this fails, this is fairly important.
  284. err=RunMlsetExe(hwndParent);
  285. if (err != ERROR_SUCCESS)
  286. {
  287. PrepareErrorMessage(IDS_ERRInstallFiles,(UINT) err,
  288. ERRCLS_STANDARD,MB_ICONEXCLAMATION);
  289. return err;
  290. }
  291. }
  292. // run the group converter to put the Inbox icon on desktop,
  293. // put Exchange, RNA et al on start menu
  294. CHAR szExecGrpconv[SMALL_BUF_LEN],szParam[SMALL_BUF_LEN];
  295. LoadSz(IDS_EXEC_GRPCONV,szExecGrpconv,sizeof(szExecGrpconv));
  296. LoadSz(IDS_EXEC_GRPCONV_PARAM,szParam,sizeof(szParam));
  297. ShellExecute(NULL,NULL,szExecGrpconv,szParam,NULL,SW_SHOW);
  298. }
  299. // only install PPPMAC if we are allowed to install RNA
  300. if (dwfOptions & ICFG_INSTALLRAS)
  301. {
  302. // install PPPMAC if not already installed
  303. // Note that we have to install PPPMAC *before* TCP/IP, to work
  304. // in the case where the user has no net installed to start with.
  305. // Otherwise when we install TCP/IP, user gets prompted by net setup
  306. // for their net card; net setup doesn't like the idea of TCP/IP lying
  307. // around without something to bind it to.
  308. fNeedPPPMAC = (!ClientConfig.fPPPDriver);
  309. if (fNeedPPPMAC)
  310. {
  311. DEBUGMSG("Installing PPPMAC");
  312. // make up a computer and workgroup name if not already set, so
  313. // user doesn't get prompted
  314. GenerateComputerNameIfNeeded();
  315. err = InstallPPPMAC(hwndParent);
  316. // 96/05/20 markdu MSN BUG 8551 Check for reboot when installing PPPMAC.
  317. //
  318. // ChrisK 5/29/97 Olympus 4692
  319. // Even if we just rebind PPPMAC we still need to restart the machine.
  320. //
  321. if (err == NEED_RESTART || err == OK)
  322. {
  323. // set restart flag so we restart the system at end
  324. DEBUGMSG("Setting restart flag");
  325. fNeedReboot = TRUE;
  326. // NEED_REBOOT also implies success, so set ret code to OK
  327. err = OK;
  328. }
  329. if (err != OK)
  330. {
  331. PrepareErrorMessage(IDS_ERRInstallPPPMAC,(UINT) err,
  332. ERRCLS_SETUPX,MB_ICONEXCLAMATION);
  333. return err;
  334. }
  335. // when we install PPPMAC, if there is another net card then PPPMAC
  336. // will automatically "grow" all the protocols that were bound to the
  337. // net card. Strip these off... (netbeui and IPX)
  338. RETERR errTmp = RemoveProtocols(hwndParent,INSTANCE_PPPDRIVER,
  339. PROT_NETBEUI | PROT_IPX);
  340. ASSERT(errTmp == OK);
  341. }
  342. }
  343. // check if we are allowed to install TCP/IP
  344. if (dwfOptions & ICFG_INSTALLTCP)
  345. {
  346. // figure out if we need to install TCP/IP
  347. // we should only put TCP/IP on appropriate type of card (net card
  348. // or PPP adapter)
  349. // user is connecting via modem, need TCP if not already present
  350. // and bound to PPPMAC. Want to bind to PPP adapters,
  351. //
  352. // As of W98, PPPMAC install also binds TCP/IP to dial-up adapter. Re-read
  353. // the config using a temporary instance of the structure to determine if
  354. // we still need the binding.
  355. // nickball - 03/03/99 - Olympus #49008, Memphis #88375, NT #180684.
  356. //
  357. CLIENTCONFIG TmpConfig;
  358. ZeroMemory(&TmpConfig,sizeof(CLIENTCONFIG));
  359. err=GetConfig(&TmpConfig,&dwErrCls);
  360. if (err != OK)
  361. {
  362. PrepareErrorMessage(IDS_ERRReadConfig,(UINT) err,
  363. dwErrCls,MB_ICONEXCLAMATION);
  364. return err;
  365. }
  366. fNeedTCPIP = !TmpConfig.fPPPBoundTCP;
  367. if (fNeedTCPIP && ClientConfig.fNetcard &&
  368. !ClientConfig.fNetcardBoundTCP)
  369. {
  370. // if we have to add TCP to PPP driver, then check if TCP is already
  371. // on netcard. If not, then TCP is going to glom on to netcard as
  372. // well as PPP driver when we install it, need to remove it from
  373. // netcard later.
  374. fNeedToRemoveTCPIP= TRUE;
  375. }
  376. // special case: if there were any existing instances of TCP/IP and
  377. // we just added PPPMAC then we don't need to install TCP/IP --
  378. // when the PPPMAC adapter got added it automatically gets an instance
  379. // of all installed protocols (incl. TCP/IP) created for it
  380. if (ClientConfig.fTcpip && fNeedPPPMAC)
  381. {
  382. fNeedTCPIP = FALSE;
  383. }
  384. } // if (dwfOptions & ICFG_INSTALLTCP)
  385. // install TCP/IP if necessary
  386. if (fNeedTCPIP)
  387. {
  388. DEBUGMSG("Installing TCP/IP");
  389. // call out to device manager to install TCP/IP
  390. err = InstallTCPIP(hwndParent);
  391. // 96/05/20 markdu MSN BUG 8551 Check for reboot when installing TCP/IP.
  392. if (err == NEED_RESTART)
  393. {
  394. // NEED_REBOOT also implies success, so set ret code to OK
  395. // Reboot flag is set below ALWAYS. Should really be set here,
  396. // but we don't want to suddenly stop rebooting in cases
  397. // where we used to reboot, even if not needed.
  398. err = OK;
  399. }
  400. if (err != OK)
  401. {
  402. PrepareErrorMessage(IDS_ERRInstallTCPIP,(UINT) err,
  403. ERRCLS_SETUPX,MB_ICONEXCLAMATION);
  404. return err;
  405. }
  406. if (fNeedToRemoveTCPIP)
  407. {
  408. // remove TCPIP that may have glommed onto net drivers other
  409. // than the one we intend it for
  410. UINT uErrTmp;
  411. uErrTmp=RemoveProtocols(hwndParent,INSTANCE_NETDRIVER,PROT_TCPIP);
  412. ASSERT(uErrTmp == OK);
  413. }
  414. DEBUGMSG("Setting restart flag");
  415. // set restart flag so we restart the system at end
  416. fNeedReboot = TRUE;
  417. }
  418. // if we just installed TCP/IP or PPPMAC, then adjust bindings
  419. if (fNeedPPPMAC || fNeedTCPIP)
  420. {
  421. UINT uErrTmp;
  422. // if file sharing (vserver) is installed, TCP/IP will bind
  423. // to it by default. This is bad, user could be sharing
  424. // files to Internet without knowing it. Unbind VSERVER
  425. // from TCP/IP instances that may used to connect to Internet
  426. // (instances of type INSTANCE_PPPDRIVER)
  427. uErrTmp = IcfgTurnOffFileSharing(INSTANCE_PPPDRIVER, hwndParent);
  428. ASSERT (uErrTmp == ERROR_SUCCESS);
  429. // unbind TCP/IP from VREDIR, if bound on this card type
  430. BOOL fBound;
  431. uErrTmp = DetectModifyTCPIPBindings(INSTANCE_PPPDRIVER,szVREDIR,
  432. TRUE,&fBound);
  433. ASSERT(uErrTmp == ERROR_SUCCESS);
  434. }
  435. // refresh the client configuration info
  436. err = GetConfig(&ClientConfig,&dwErrCls);
  437. if (err != OK)
  438. {
  439. PrepareErrorMessage(IDS_ERRReadConfig,(UINT) err,
  440. dwErrCls,MB_ICONEXCLAMATION);
  441. return err;
  442. }
  443. // do some special handling if there were *no* netcard devices
  444. // (net cards or PPP drivers) initially installed
  445. if (!fInitNetMAC)
  446. {
  447. ASSERT(fNeedPPPMAC); // should have just installed PPPMAC
  448. // net setup adds some extra net components "by default" when
  449. // we add PPPMAC and there are no net card devices, go kill them
  450. // off.
  451. RETERR reterr = RemoveUnneededDefaultComponents(hwndParent);
  452. ASSERT(reterr == OK);
  453. // since there were no net card devices to begin with, we need
  454. // to restart the system later. (the NDIS VxD is a static VxD
  455. // which needs to run, only gets added when you install a net card.)
  456. DEBUGMSG("Setting restart flag");
  457. // set restart flag so we restart the system at end
  458. fNeedReboot = TRUE;
  459. }
  460. // tell caller whether we need to reboot or not
  461. if (lpfNeedsRestart)
  462. {
  463. *lpfNeedsRestart = fNeedReboot;
  464. }
  465. return ERROR_SUCCESS;
  466. }
  467. /*******************************************************************
  468. NAME: GetConfig
  469. SYNOPSIS: Retrieves client configuration
  470. ********************************************************************/
  471. UINT GetConfig(CLIENTCONFIG * pClientConfig,DWORD * pdwErrCls)
  472. {
  473. ASSERT(pClientConfig);
  474. ASSERT(pdwErrCls);
  475. // get most the client configuration from 16-bit dll
  476. UINT uRet = GetClientConfig(pClientConfig);
  477. if (uRet != OK) {
  478. // GetClientConfig returns SETUPX error codes
  479. *pdwErrCls = ERRCLS_SETUPX;
  480. }
  481. return uRet;
  482. }
  483. //*******************************************************************
  484. //
  485. // FUNCTION: IcfgStartServices
  486. //
  487. // PURPOSE: This is a NOP designed to maintain parity with the NT
  488. // version (icfgnt.dll).
  489. //
  490. // PARAMETERS: none
  491. //
  492. // RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
  493. //
  494. //*******************************************************************
  495. extern "C" HRESULT IcfgStartServices()
  496. {
  497. return ERROR_SUCCESS;
  498. }