Source code of Windows XP (NT5)
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.

3731 lines
107 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. rtrutil.cpp
  7. FILE HISTORY:
  8. */
  9. #include "stdafx.h"
  10. #include "rtrutilp.h"
  11. #include "cnctdlg.h"
  12. #include "cncting.h"
  13. #include "rtrstr.h"
  14. #include "ndisutil.h"
  15. #include "netcfgx.h"
  16. #include "register.h"
  17. #include "raseapif.h"
  18. #include "strings.h"
  19. #include "reg.h" // IsNT4Machine
  20. #include "ports.h"
  21. #include "helper.h" // CStrParser
  22. // Include headers needed for IP-specific infobase stuff
  23. #include <rtinfo.h>
  24. #include <fltdefs.h>
  25. #include <ipinfoid.h>
  26. #include <iprtrmib.h>
  27. #include "iprtinfo.h"
  28. // Headers needed for IPX-specific infobase stuff
  29. #include "ipxrtdef.h"
  30. #include <routprot.h> // protocol ids
  31. #include <Wbemidl.h>
  32. #define _PNP_POWER_
  33. #include "ustringp.h"
  34. #include "ntddip.h" // IP_PNP_RECONFIG_REQUEST
  35. #include "ndispnp.h"
  36. #include "globals.h" // structure defaults
  37. #include "raserror.h"
  38. #include "lsa.h" // RtlEncode/RtlDecode
  39. #include "dsgetdc.h" // for DsGetDcName
  40. #include "cmptrmgr.h" // for the computer management nodetype guid
  41. extern "C"
  42. {
  43. #include "mprapip.h" // for MprAdminDomain functions
  44. };
  45. #include "rtutils.h" // Tracing functions
  46. #include "rtrcomn.h" // CoCreateRouterConfig
  47. #include "rrasutil.h"
  48. //
  49. // Timeouts used to control the behavior of ServiceStartPrompt/ServiceStop
  50. //
  51. #define TIMEOUT_START 5000
  52. #define TIMEOUT_MAX 60000
  53. #define TIMEOUT_POLL 5
  54. #define MAX_WAIT_RESTART 60
  55. extern "C" DWORD APIENTRY
  56. MprConfigCreateIpInterfaceInfo(DWORD dwIfType, PBYTE ExistingHeader,
  57. PBYTE* NewHeader );
  58. //----------------------------------------------------------------------------
  59. // Function: ConnectRouter
  60. //
  61. // Connects to the router on the specified machine
  62. //----------------------------------------------------------------------------
  63. TFSCORE_API(DWORD)
  64. ConnectRouter(
  65. IN LPCTSTR pszMachine,
  66. OUT MPR_SERVER_HANDLE * phrouter
  67. )
  68. {
  69. USES_CONVERSION;
  70. //
  71. // Connect to the router
  72. //
  73. Assert(*phrouter == NULL);
  74. return ::MprAdminServerConnect(
  75. T2W((LPTSTR) pszMachine),
  76. phrouter
  77. );
  78. }
  79. TFSCORE_API(DWORD)
  80. GetRouterUpTime(IN LPCTSTR pszMachine,
  81. OUT DWORD * pdwUpTime
  82. )
  83. {
  84. DWORD dwError = NO_ERROR;
  85. MPR_SERVER_HANDLE hMprServer = NULL;
  86. Assert(pdwUpTime);
  87. dwError = ConnectRouter(pszMachine, &hMprServer);
  88. if (NO_ERROR == dwError && hMprServer)
  89. {
  90. MPR_SERVER_0* pServer0 = NULL;
  91. dwError = MprAdminServerGetInfo(hMprServer, 0, (LPBYTE *) &pServer0);
  92. if (NO_ERROR == dwError && pServer0)
  93. {
  94. *pdwUpTime = pServer0->dwUpTime;
  95. MprAdminBufferFree(pServer0);
  96. }
  97. MprAdminServerDisconnect(hMprServer);
  98. }
  99. return dwError;
  100. }
  101. //----------------------------------------------------------------------------
  102. // Function: GetRouterPhonebookPath
  103. //
  104. // Constructs the path to the router-phonebook file on the given machine.
  105. //----------------------------------------------------------------------------
  106. HRESULT
  107. GetRouterPhonebookPath(
  108. IN LPCTSTR pszMachine,
  109. IN CString * pstPath
  110. )
  111. {
  112. HRESULT hr = hrOK;
  113. if (!IsLocalMachine(pszMachine))
  114. {
  115. // Assuming '\\\\' is appended before the call
  116. Assert(StrnCmp(_T("\\\\"), pszMachine, 2) == 0);
  117. //
  118. // Supply the path via the 'ADMIN' share
  119. //
  120. *pstPath = pszMachine;
  121. *pstPath += TEXT('\\');
  122. *pstPath += c_szAdminShare;
  123. *pstPath += TEXT('\\');
  124. *pstPath += c_szSystem32;
  125. *pstPath += TEXT('\\');
  126. }
  127. else
  128. {
  129. UINT i, j;
  130. TCHAR* pszDir;
  131. //
  132. // Supply the path on the local machine
  133. //
  134. if (!(i = GetSystemDirectory(NULL, 0)))
  135. return HResultFromWin32(GetLastError());
  136. pszDir = new TCHAR[++i];
  137. if (!GetSystemDirectory(pszDir, i))
  138. {
  139. hr = HResultFromWin32(GetLastError());
  140. delete [] pszDir;
  141. return hr;
  142. }
  143. *pstPath = pszDir;
  144. *pstPath += TEXT('\\');
  145. delete [] pszDir;
  146. }
  147. *pstPath += c_szRAS;
  148. *pstPath += TEXT('\\');
  149. *pstPath += c_szRouterPbk;
  150. return hr;
  151. }
  152. /*!--------------------------------------------------------------------------
  153. DeleteRouterPhonebook
  154. Deletes the router.pbk of a machine
  155. Author: KennT
  156. ---------------------------------------------------------------------------*/
  157. HRESULT DeleteRouterPhonebook(LPCTSTR pszMachine)
  158. {
  159. HRESULT hr = hrOK;
  160. CString stMachine, stPhonebookPath;
  161. // Setup the server. If this is not the local machine, it will
  162. // need to have \\ as a prefix.
  163. // ----------------------------------------------------------------
  164. stMachine = pszMachine;
  165. if (!IsLocalMachine((LPCTSTR) stMachine))
  166. {
  167. // add on the two slashes to the beginning of the machine name
  168. // ------------------------------------------------------------
  169. if (stMachine.Left(2) != _T("\\\\"))
  170. {
  171. stMachine = _T("\\\\");
  172. stMachine += pszMachine;
  173. }
  174. }
  175. if (FHrOK(GetRouterPhonebookPath(stMachine, &stPhonebookPath)))
  176. hr = HResultFromWin32( ::DeleteFile(stPhonebookPath) );
  177. return hr;
  178. }
  179. /*!--------------------------------------------------------------------------
  180. GetLocalMachineName
  181. -
  182. Author: KennT
  183. ---------------------------------------------------------------------------*/
  184. CString GetLocalMachineName()
  185. {
  186. CString stMachine;
  187. TCHAR szMachine[MAX_COMPUTERNAME_LENGTH + 1];
  188. DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
  189. Verify(GetComputerName(szMachine, &dwSize));
  190. stMachine = szMachine;
  191. return stMachine;
  192. }
  193. TFSCORE_API(DWORD) ConnectInterfaceEx(
  194. IN MPR_SERVER_HANDLE hRouter,
  195. IN HANDLE hInterface,
  196. IN BOOL bConnect,
  197. IN HWND hwndParent,
  198. IN LPCTSTR pszInterface)
  199. {
  200. DWORD dwErr;
  201. Assert(hRouter);
  202. Assert(hInterface);
  203. //
  204. // Initiate the interface connection/disconnection
  205. //
  206. if (!bConnect)
  207. {
  208. dwErr = ::MprAdminInterfaceDisconnect(hRouter, hInterface);
  209. }
  210. else
  211. {
  212. dwErr = ::MprAdminInterfaceConnect(hRouter, hInterface, NULL, FALSE);
  213. if (dwErr == PENDING) { dwErr = NO_ERROR; }
  214. //
  215. // Display a dialog so user knows connection is in progress
  216. //
  217. CInterfaceConnectDialog dlg(hRouter, hInterface, pszInterface,
  218. CWnd::FromHandle(hwndParent));
  219. dlg.DoModal();
  220. }
  221. return dwErr;
  222. }
  223. /*!--------------------------------------------------------------------------
  224. ConnectInterface
  225. -
  226. Author: KennT
  227. ---------------------------------------------------------------------------*/
  228. TFSCORE_API(DWORD) ConnectInterface(
  229. IN LPCTSTR pszMachine,
  230. IN LPCTSTR pszInterface,
  231. IN BOOL bConnect,
  232. IN HWND hwndParent)
  233. {
  234. DWORD dwErr;
  235. SPMprServerHandle sphRouter;
  236. MPR_SERVER_HANDLE hRouter = NULL;
  237. HANDLE hInterface;
  238. WCHAR wszInterface[MAX_INTERFACE_NAME_LEN+1];
  239. //
  240. // Connect to the specified machine, if necessary
  241. //
  242. dwErr = ConnectRouter(pszMachine, &hRouter);
  243. if (dwErr != NO_ERROR)
  244. return dwErr;
  245. sphRouter.Attach(hRouter); // so that it gets released
  246. //
  247. // Retrieve the interface handle, if necessary
  248. //
  249. StrCpyWFromT(wszInterface, pszInterface);
  250. dwErr = ::MprAdminInterfaceGetHandle(
  251. hRouter,
  252. wszInterface,
  253. &hInterface,
  254. FALSE
  255. );
  256. if (dwErr != NO_ERROR)
  257. return dwErr;
  258. return ConnectInterfaceEx(hRouter, hInterface, bConnect, hwndParent,
  259. pszInterface);
  260. }
  261. /*---------------------------------------------------------------------------
  262. CInterfaceConnectDialog
  263. ---------------------------------------------------------------------------*/
  264. CInterfaceConnectDialog::CInterfaceConnectDialog(
  265. MPR_SERVER_HANDLE hServer,
  266. HANDLE hInterface,
  267. LPCTSTR pszInterface,
  268. CWnd* pParent
  269. ) : CDialog(IDD_CONNECTING, pParent),
  270. m_hServer(hServer),
  271. m_hInterface(hInterface),
  272. m_sInterface(pszInterface),
  273. m_dwTimeElapsed(0),
  274. m_dwConnectionState(ROUTER_IF_STATE_CONNECTING),
  275. m_nIDEvent(1) { }
  276. void
  277. CInterfaceConnectDialog::DoDataExchange(CDataExchange* pDX) {
  278. CDialog::DoDataExchange(pDX);
  279. //{{AFX_DATA_MAP(CInterfaceConnectDialog)
  280. //}}AFX_DATA_MAP
  281. }
  282. BEGIN_MESSAGE_MAP(CInterfaceConnectDialog, CDialog)
  283. //{{AFX_MSG_MAP(CInterfaceConnectDialog)
  284. ON_WM_TIMER()
  285. //}}AFX_MSG_MAP
  286. END_MESSAGE_MAP()
  287. BOOL
  288. CInterfaceConnectDialog::OnInitDialog()
  289. {
  290. SetDlgItemText(IDC_EDIT_INTERFACENAME, m_sInterface);
  291. OnTimer(m_nIDEvent);
  292. m_nIDEvent = SetTimer(m_nIDEvent, 1000, NULL);
  293. GetDlgItem(IDCANCEL)->SetFocus();
  294. return FALSE;
  295. }
  296. VOID CInterfaceConnectDialog::OnCancel()
  297. {
  298. ::MprAdminInterfaceDisconnect(m_hServer, m_hInterface);
  299. CDialog::OnCancel();
  300. }
  301. VOID
  302. CInterfaceConnectDialog::OnTimer(
  303. UINT nIDEvent
  304. ) {
  305. DWORD dwErr;
  306. CString sTime, sPrompt;
  307. SPMprAdminBuffer spMprBuffer;
  308. if (nIDEvent != m_nIDEvent)
  309. {
  310. CWnd::OnTimer(nIDEvent);
  311. return;
  312. }
  313. ++m_dwTimeElapsed;
  314. if (!(m_dwTimeElapsed % TIMEOUT_POLL))
  315. {
  316. MPR_INTERFACE_0* pInfo;
  317. dwErr = ::MprAdminInterfaceGetInfo(
  318. m_hServer,
  319. m_hInterface,
  320. 0,
  321. (LPBYTE*)&spMprBuffer
  322. );
  323. pInfo = (MPR_INTERFACE_0 *) (LPBYTE) spMprBuffer;
  324. if (dwErr == NO_ERROR)
  325. {
  326. m_dwConnectionState = pInfo->dwConnectionState;
  327. if (m_dwConnectionState == ROUTER_IF_STATE_CONNECTED)
  328. {
  329. KillTimer(m_nIDEvent);
  330. EndDialog(IDOK);
  331. }
  332. else if (m_dwConnectionState != ROUTER_IF_STATE_CONNECTING)
  333. {
  334. KillTimer(m_nIDEvent);
  335. BringWindowToTop();
  336. if (pInfo->dwLastError == NO_ERROR)
  337. {
  338. AfxMessageBox(IDS_ERR_IF_DISCONNECTED);
  339. }
  340. else
  341. {
  342. //Workaround for bugid: 96347. Change this once
  343. //schannel has an alert for SEC_E_MULTIPLE_ACCOUNTS
  344. if ( pInfo->dwLastError == SEC_E_CERT_UNKNOWN )
  345. {
  346. pInfo->dwLastError = SEC_E_MULTIPLE_ACCOUNTS;
  347. }
  348. FormatSystemError(HResultFromWin32(pInfo->dwLastError),
  349. sPrompt.GetBuffer(1024),
  350. 1024,
  351. IDS_ERR_IF_CONNECTFAILED,
  352. FSEFLAG_ANYMESSAGE
  353. );
  354. sPrompt.ReleaseBuffer();
  355. AfxMessageBox(sPrompt);
  356. }
  357. EndDialog(IDCANCEL);
  358. }
  359. }
  360. }
  361. sPrompt = ConnectionStateToCString(m_dwConnectionState);
  362. SetDlgItemText(IDC_TEXT_IFSTATUS, sPrompt);
  363. FormatNumber(m_dwTimeElapsed, sTime.GetBuffer(1024), 1024, FALSE);
  364. sTime.ReleaseBuffer();
  365. AfxFormatString1(sPrompt, IDS_SECONDSFMT, sTime);
  366. SetDlgItemText(IDC_TEXT_ELAPSED, sPrompt);
  367. }
  368. /*!--------------------------------------------------------------------------
  369. PromptForCredentials
  370. -
  371. Author: KennT
  372. ---------------------------------------------------------------------------*/
  373. TFSCORE_API(DWORD) PromptForCredentials(LPCTSTR pszMachine,
  374. LPCTSTR pszInterface,
  375. BOOL fNT4,
  376. BOOL fNewInterface,
  377. HWND hwndParent)
  378. {
  379. HRESULT hr;
  380. DWORD dwErr;
  381. ULONG_PTR uConnection = 0;
  382. SPMprServerHandle sphRouter;
  383. MPR_SERVER_HANDLE hRouter = NULL;
  384. HANDLE hInterface;
  385. PMPR_INTERFACE_2 pmprInterface = NULL;
  386. PMPR_CREDENTIALSEX_0 pmprCredentials = NULL;
  387. BYTE* pUserDataOut = NULL;
  388. WCHAR wszInterface[MAX_INTERFACE_NAME_LEN+1];
  389. CIfCredentials dlg(pszMachine, pszInterface,
  390. fNewInterface, CWnd::FromHandle(hwndParent));
  391. if (fNT4)
  392. {
  393. dlg.DoModal();
  394. return NO_ERROR;
  395. }
  396. //
  397. // Connect to the specified machine
  398. //
  399. dwErr = ConnectRouter(pszMachine, &hRouter);
  400. if (dwErr != NO_ERROR)
  401. goto L_ERR;
  402. //
  403. // so that it gets released
  404. //
  405. sphRouter.Attach(hRouter);
  406. //
  407. // Retrieve the interface handle
  408. //
  409. StrCpyWFromT(wszInterface, pszInterface);
  410. dwErr = ::MprAdminInterfaceGetHandle(
  411. hRouter,
  412. wszInterface,
  413. &hInterface,
  414. FALSE
  415. );
  416. if (dwErr != NO_ERROR)
  417. goto L_ERR;
  418. dwErr = ::MprAdminInterfaceGetInfo(hRouter, hInterface, 2,
  419. (LPBYTE*)&pmprInterface);
  420. if (dwErr != NO_ERROR)
  421. goto L_ERR;
  422. if (pmprInterface->dwfOptions & RASEO_RequireEAP)
  423. {
  424. GUID guid;
  425. RegKey regkeyEAP;
  426. RegKey regkeyEAPType;
  427. CString stConfigCLSID;
  428. DWORD dwInvokeUsername;
  429. DWORD dwId;
  430. DWORD dwSizeOfUserDataOut;
  431. CComPtr<IEAPProviderConfig> spEAPConfig;
  432. dwId = pmprInterface->dwCustomAuthKey;
  433. TCHAR szStr[40];
  434. _ltot((LONG)dwId, szStr, 10);
  435. CString str(szStr);
  436. dwErr = regkeyEAP.Open(HKEY_LOCAL_MACHINE,
  437. c_szEAPKey, KEY_ALL_ACCESS, pszMachine);
  438. if (ERROR_SUCCESS != dwErr)
  439. goto L_ERR;
  440. dwErr = regkeyEAPType.Open(regkeyEAP, str, KEY_READ);
  441. if (ERROR_SUCCESS != dwErr)
  442. goto L_ERR;
  443. dwErr = regkeyEAPType.QueryValue(c_szInvokeUsernameDialog,
  444. dwInvokeUsername);
  445. if ((ERROR_SUCCESS == dwErr) && !dwInvokeUsername)
  446. {
  447. dwErr = ::MprAdminInterfaceGetCredentialsEx(hRouter, hInterface, 0,
  448. (LPBYTE*)&pmprCredentials);
  449. if (dwErr != NO_ERROR)
  450. goto L_ERR;
  451. dwErr = regkeyEAPType.QueryValue(c_szConfigCLSID, stConfigCLSID);
  452. if (ERROR_SUCCESS != dwErr)
  453. goto L_ERR;
  454. CHECK_HR(hr = CLSIDFromString((LPTSTR)(LPCTSTR)stConfigCLSID,
  455. &guid));
  456. // Create the EAP provider object
  457. CHECK_HR( hr = CoCreateInstance(
  458. guid,
  459. NULL,
  460. CLSCTX_INPROC_SERVER | CLSCTX_ENABLE_CODE_DOWNLOAD,
  461. IID_IEAPProviderConfig,
  462. (LPVOID *) &spEAPConfig) );
  463. // Configure this EAP provider
  464. hr = spEAPConfig->Initialize(pszMachine, dwId, &uConnection);
  465. if ( !FAILED(hr) )
  466. {
  467. hr = spEAPConfig->RouterInvokeCredentialsUI(dwId, uConnection,
  468. hwndParent, RAS_EAP_FLAG_ROUTER,
  469. pmprInterface->lpbCustomAuthData,
  470. pmprInterface->dwCustomAuthDataSize,
  471. pmprCredentials->lpbCredentialsInfo,
  472. pmprCredentials->dwSize,
  473. &pUserDataOut, &dwSizeOfUserDataOut);
  474. spEAPConfig->Uninitialize(dwId, uConnection); // Ignore errors
  475. }
  476. if ( !FAILED(hr) )
  477. {
  478. pmprCredentials->lpbCredentialsInfo = pUserDataOut;
  479. pmprCredentials->dwSize = dwSizeOfUserDataOut;
  480. dwErr = ::MprAdminInterfaceSetCredentialsEx(hRouter, hInterface,
  481. 0, (LPBYTE)pmprCredentials);
  482. if (dwErr != NO_ERROR)
  483. goto L_ERR;
  484. }
  485. goto L_ERR;
  486. }
  487. }
  488. dlg.DoModal();
  489. L_ERR:
  490. if (NULL != pmprInterface)
  491. {
  492. ::MprAdminBufferFree(pmprInterface);
  493. }
  494. if (NULL != pmprCredentials)
  495. {
  496. ::MprAdminBufferFree(pmprCredentials);
  497. }
  498. CoTaskMemFree(pUserDataOut);
  499. return dwErr;
  500. }
  501. /*---------------------------------------------------------------------------
  502. CIfCredentials
  503. ---------------------------------------------------------------------------*/
  504. BEGIN_MESSAGE_MAP(CIfCredentials, CBaseDialog)
  505. END_MESSAGE_MAP()
  506. DWORD CIfCredentials::m_dwHelpMap[] =
  507. {
  508. IDC_EDIT_IC_USERNAME, 0,
  509. IDC_EDIT_IC_DOMAIN, 0,
  510. IDC_EDIT_IC_PASSWORD, 0,
  511. IDC_EDIT_IC_PASSWORD2, 0,
  512. 0,0
  513. };
  514. BOOL
  515. CIfCredentials::OnInitDialog(
  516. ) {
  517. CBaseDialog::OnInitDialog();
  518. ((CEdit*)GetDlgItem(IDC_EDIT_IC_USERNAME))->LimitText(UNLEN);
  519. ((CEdit*)GetDlgItem(IDC_EDIT_IC_DOMAIN))->LimitText(DNLEN);
  520. ((CEdit*)GetDlgItem(IDC_EDIT_IC_PASSWORD))->LimitText(PWLEN);
  521. ((CEdit*)GetDlgItem(IDC_EDIT_IC_PASSWORD2))->LimitText(PWLEN);
  522. //
  523. // if you are editing a new interface, then you are done.
  524. //
  525. if ( m_bNewIf )
  526. return FALSE;
  527. //
  528. // existing interface.
  529. //
  530. WCHAR wszPassword[PWLEN+1];
  531. WCHAR wszPassword2[PWLEN+1];
  532. do
  533. {
  534. DWORD dwErr = (DWORD) -1;
  535. CString sErr;
  536. WCHAR wszUsername[UNLEN+1];
  537. WCHAR wszDomain[DNLEN+1];
  538. WCHAR *pswzMachine = NULL;
  539. WCHAR *pswzInterface = NULL;
  540. //
  541. // Retrieve its credentials
  542. //
  543. pswzMachine = (WCHAR *) alloca((m_sMachine.GetLength()+3) * sizeof(WCHAR));
  544. StrCpyWFromT(pswzMachine, m_sMachine);
  545. pswzInterface = (WCHAR *) alloca((m_sInterface.GetLength()+1) * sizeof(WCHAR));
  546. StrCpyWFromT(pswzInterface, m_sInterface);
  547. ZeroMemory( wszUsername, sizeof( wszUsername ) );
  548. ZeroMemory( wszDomain, sizeof( wszDomain ) );
  549. dwErr = MprAdminInterfaceGetCredentials(
  550. pswzMachine,
  551. pswzInterface,
  552. wszUsername,
  553. #if 1
  554. NULL,
  555. #else
  556. wszPassword,
  557. #endif
  558. wszDomain
  559. );
  560. //
  561. // if credentials were not retrieved successfully do not pop
  562. // up message. It might mean that credentials have never been
  563. // set before.
  564. // Fix for bug # 79607.
  565. //
  566. if ( dwErr != NO_ERROR )
  567. {
  568. // FormatSystemError(dwErr, sErr, IDS_SET_CREDENTIALS_FAILED);
  569. // AfxMessageBox(sErr);
  570. break;
  571. }
  572. //
  573. // fill the edit boxes with the values retrieved.
  574. //
  575. SetDlgItemTextW( IDC_EDIT_IC_USERNAME, wszUsername );
  576. SetDlgItemTextW( IDC_EDIT_IC_DOMAIN, wszDomain );
  577. } while ( FALSE );
  578. ZeroMemory(wszPassword, sizeof(wszPassword));
  579. ZeroMemory(wszPassword2, sizeof(wszPassword2));
  580. // SetDlgItemText(IDC_EDIT_IC_USERNAME, m_sInterface);
  581. return FALSE;
  582. }
  583. VOID
  584. CIfCredentials::OnOK(
  585. ) {
  586. DWORD dwErr;
  587. CString sErr;
  588. WCHAR wszMachine[MAX_COMPUTERNAME_LENGTH+3];
  589. WCHAR wszInterface[MAX_INTERFACE_NAME_LEN+1];
  590. WCHAR wszUsername[UNLEN+1];
  591. WCHAR wszDomain[DNLEN+1];
  592. WCHAR wszPassword[PWLEN+1];
  593. WCHAR wszPassword2[PWLEN+1];
  594. WCHAR* pwszPassword = NULL;
  595. do {
  596. //
  597. // Retrieve the edit-controls' contents
  598. //
  599. wszUsername[0] = L'\0';
  600. wszDomain[0] = L'\0';
  601. wszPassword[0] = L'\0';
  602. wszPassword2[0] = L'\0';
  603. GetDlgItemTextW(IDC_EDIT_IC_USERNAME, wszUsername, UNLEN + 1);
  604. GetDlgItemTextW(IDC_EDIT_IC_DOMAIN, wszDomain, DNLEN + 1);
  605. GetDlgItemTextW(IDC_EDIT_IC_PASSWORD, wszPassword, PWLEN + 1);
  606. GetDlgItemTextW(IDC_EDIT_IC_PASSWORD2, wszPassword2, PWLEN + 1);
  607. //
  608. // Make sure the password matches its confirmation
  609. //
  610. if (lstrcmpW(wszPassword, wszPassword2)) {
  611. AfxMessageBox(IDS_ERR_PASSWORD_MISMATCH);
  612. SetDlgItemText(IDC_EDIT_IC_PASSWORD, TEXT(""));
  613. SetDlgItemText(IDC_EDIT_IC_PASSWORD2, TEXT(""));
  614. GetDlgItem(IDC_EDIT_IC_PASSWORD)->SetFocus();
  615. break;
  616. }
  617. //
  618. // If no Password is present, see if the user wants to remove
  619. // the password or just leave it unreplaced
  620. //
  621. if (lstrlen(wszPassword)) {
  622. pwszPassword = wszPassword;
  623. }
  624. else {
  625. INT id;
  626. id = AfxMessageBox(IDS_PROMPT_NOPASSWORD, MB_YESNOCANCEL|MB_DEFBUTTON2);
  627. if (id == IDYES) { pwszPassword = wszPassword; }
  628. else
  629. if (id == IDCANCEL) { break; }
  630. }
  631. //
  632. // Save the credentials;
  633. //
  634. StrCpyWFromT(wszMachine, m_sMachine);
  635. StrCpyWFromT(wszInterface, m_sInterface);
  636. dwErr = MprAdminInterfaceSetCredentials(
  637. wszMachine,
  638. wszInterface,
  639. wszUsername,
  640. wszDomain,
  641. pwszPassword
  642. );
  643. if (dwErr) {
  644. FormatSystemError(dwErr, sErr.GetBuffer(1024), 1024, IDS_ERR_SET_CREDENTIALS_FAILED, 0xFFFFFFFF);
  645. sErr.ReleaseBuffer();
  646. AfxMessageBox(sErr);
  647. break;
  648. }
  649. CBaseDialog::OnOK();
  650. } while(FALSE);
  651. //
  652. // Erase the passwords from the stack.
  653. //
  654. ZeroMemory(wszPassword, sizeof(wszPassword));
  655. ZeroMemory(wszPassword2, sizeof(wszPassword2));
  656. return;
  657. }
  658. TFSCORE_API(DWORD) UpdateDDM(IInterfaceInfo *pIfInfo)
  659. {
  660. BOOL bStatus = FALSE;
  661. DWORD dwErr = (DWORD) -1;
  662. CString sErr;
  663. MPR_SERVER_HANDLE hServer = NULL;
  664. HANDLE hInterface = NULL;
  665. WCHAR wszMachine[ MAX_COMPUTERNAME_LENGTH + 3 ];
  666. WCHAR wszInterface[ MAX_INTERFACE_NAME_LEN + 1 ];
  667. do
  668. {
  669. // Verify that the router service is running.
  670. StrCpyWFromT( wszMachine, pIfInfo->GetMachineName() );
  671. StrCpyWFromT( wszInterface, pIfInfo->GetId() );
  672. bStatus = ::MprAdminIsServiceRunning( wszMachine );
  673. if ( !bStatus )
  674. {
  675. dwErr = NO_ERROR;
  676. break;
  677. }
  678. dwErr = ConnectRouter( pIfInfo->GetMachineName(), &hServer );
  679. if ( dwErr != NO_ERROR )
  680. break;
  681. dwErr = ::MprAdminInterfaceGetHandle(
  682. hServer,
  683. wszInterface,
  684. &hInterface,
  685. FALSE);
  686. if ( dwErr != NO_ERROR )
  687. break;
  688. // update phone book info. in DDM
  689. dwErr = ::MprAdminInterfaceUpdatePhonebookInfo(
  690. hServer,
  691. hInterface
  692. );
  693. if (dwErr != NO_ERROR )
  694. break;
  695. } while ( FALSE );
  696. if (hServer) { ::MprAdminServerDisconnect(hServer); }
  697. if ( dwErr != NO_ERROR && dwErr != ERROR_NO_SUCH_INTERFACE )
  698. {
  699. FormatSystemError( dwErr, sErr.GetBuffer(1024), 1024, IDS_ERR_IF_CONNECTFAILED, 0xffffffff);
  700. sErr.ReleaseBuffer();
  701. AfxMessageBox( sErr );
  702. }
  703. return dwErr;
  704. }
  705. /*!--------------------------------------------------------------------------
  706. UpdateRoutes
  707. Performs an autostatic update on the given machine's interface,
  708. for a specific transport.
  709. Author: KennT
  710. ---------------------------------------------------------------------------*/
  711. TFSCORE_API(DWORD) UpdateRoutesEx(IN MPR_SERVER_HANDLE hRouter,
  712. IN HANDLE hInterface,
  713. IN DWORD dwTransportId,
  714. IN HWND hwndParent,
  715. IN LPCTSTR pszInterface)
  716. {
  717. DWORD dwErr, dwState;
  718. MPR_INTERFACE_0* pmprif0=NULL;
  719. do {
  720. // See if the interface is connected
  721. dwErr = ::MprAdminInterfaceGetInfo(hRouter,
  722. hInterface,
  723. 0,
  724. (LPBYTE*)&pmprif0);
  725. if (dwErr != NO_ERROR || pmprif0 == NULL) { break; }
  726. dwState = pmprif0->dwConnectionState;
  727. ::MprAdminBufferFree(pmprif0);
  728. // Establish the connection if necessary
  729. if (dwState != (DWORD)ROUTER_IF_STATE_CONNECTED)
  730. {
  731. // Connect the interface
  732. dwErr = ::ConnectInterfaceEx(hRouter,
  733. hInterface,
  734. TRUE,
  735. hwndParent,
  736. pszInterface);
  737. if (dwErr != NO_ERROR) { break; }
  738. }
  739. //
  740. // Now perform the route-update
  741. //
  742. dwErr = ::MprAdminInterfaceUpdateRoutes(
  743. hRouter,
  744. hInterface,
  745. dwTransportId,
  746. NULL
  747. );
  748. if (dwErr != NO_ERROR) { break; }
  749. } while(FALSE);
  750. return dwErr;
  751. }
  752. TFSCORE_API(DWORD) UpdateRoutes(IN LPCTSTR pszMachine,
  753. IN LPCTSTR pszInterface,
  754. IN DWORD dwTransportId,
  755. IN HWND hwndParent)
  756. {
  757. DWORD dwErr, dwState;
  758. HANDLE hInterface = INVALID_HANDLE_VALUE;
  759. MPR_INTERFACE_0* pmprif0;
  760. SPMprServerHandle sphRouter;
  761. MPR_SERVER_HANDLE hMachine = NULL;;
  762. //
  763. // open a handle
  764. //
  765. dwErr = ConnectRouter(pszMachine, &hMachine);
  766. if (dwErr != NO_ERROR)
  767. return dwErr;
  768. sphRouter.Attach(hMachine); // so that it gets released
  769. do {
  770. //
  771. // open a handle to the interface
  772. //
  773. WCHAR wszInterface[MAX_INTERFACE_NAME_LEN + 1];
  774. StrCpyWFromT(wszInterface, pszInterface);
  775. dwErr = MprAdminInterfaceGetHandle(
  776. hMachine,
  777. wszInterface,
  778. &hInterface,
  779. FALSE
  780. );
  781. if (dwErr != NO_ERROR) { break; }
  782. dwErr = ::UpdateRoutesEx(hMachine,
  783. hInterface,
  784. dwTransportId,
  785. hwndParent,
  786. pszInterface);
  787. } while (FALSE);
  788. return dwErr;
  789. }
  790. /*!--------------------------------------------------------------------------
  791. ConnectAsAdmin
  792. Connect to the remote machine as administrator with user-supplied
  793. credentials.
  794. Returns
  795. S_OK - if a connection was established
  796. S_FALSE - if user cancelled out
  797. other - error condition
  798. Author: KennT
  799. ---------------------------------------------------------------------------*/
  800. HRESULT ConnectAsAdmin( IN LPCTSTR szRouterName, IN IRouterInfo *pRouter)
  801. {
  802. //
  803. // allow user to specify credentials
  804. //
  805. DWORD dwRes = (DWORD) -1;
  806. HRESULT hr = hrOK;
  807. CConnectAsDlg caDlg;
  808. CString stIPCShare;
  809. CString stRouterName;
  810. CString stPassword;
  811. stRouterName = szRouterName;
  812. //
  813. // set message text in connect as dialog.
  814. //
  815. caDlg.m_sRouterName = szRouterName;
  816. //
  817. // loop till connect succeeds or user cancels
  818. //
  819. while ( TRUE )
  820. {
  821. // We need to ensure that this dialog is brought to
  822. // the top (if it gets lost behind the main window, we
  823. // are in trouble).
  824. dwRes = caDlg.DoModal();
  825. if ( dwRes == IDCANCEL )
  826. {
  827. hr = S_FALSE;
  828. break;
  829. }
  830. //
  831. // Create remote resource name
  832. //
  833. stIPCShare.Empty();
  834. if ( stRouterName.Left(2) != TEXT( "\\\\" ) )
  835. {
  836. stIPCShare = TEXT( "\\\\" );
  837. }
  838. stIPCShare += stRouterName;
  839. stIPCShare += TEXT( "\\" );
  840. stIPCShare += c_szIPCShare;
  841. NETRESOURCE nr;
  842. nr.dwType = RESOURCETYPE_ANY;
  843. nr.lpLocalName = NULL;
  844. nr.lpRemoteName = (LPTSTR) (LPCTSTR) stIPCShare;
  845. nr.lpProvider = NULL;
  846. //
  847. // connect to \\router\ipc$ to try and establish credentials.
  848. // May not be the best way to establish credentials but is
  849. // the most expendient for now.
  850. //
  851. // Need to unencode the password in the ConnectAsDlg
  852. stPassword = caDlg.m_sPassword;
  853. RtlDecodeW(caDlg.m_ucSeed, stPassword.GetBuffer(0));
  854. stPassword.ReleaseBuffer();
  855. //Remove Net Connections if there are any present
  856. RemoveNetConnection( stIPCShare);
  857. dwRes = WNetAddConnection2(
  858. &nr,
  859. (LPCTSTR) stPassword,
  860. (LPCTSTR) caDlg.m_sUserName,
  861. 0
  862. );
  863. // We need to save off the user name and password
  864. if (dwRes == NO_ERROR)
  865. {
  866. // Parse out the user name, use an arbitrary key for
  867. // the encoding.
  868. SPIRouterAdminAccess spAdmin;
  869. // For every connection that succeeds we have to ensure
  870. // that the connection gets removed. Do this by storing
  871. // the connections globally. This will get freed up in
  872. // the IComponentData destructor.
  873. // --------------------------------------------------------
  874. AddNetConnection((LPCTSTR) stIPCShare);
  875. spAdmin.HrQuery(pRouter);
  876. if (spAdmin)
  877. {
  878. UCHAR ucSeed = 0x83;
  879. CString stName;
  880. CString stUser;
  881. CString stDomain;
  882. LPCTSTR pszUser = NULL;
  883. LPCTSTR pszDomain = NULL;
  884. int iPos = 0;
  885. // Break the user name into domain\user
  886. // look for the first forward slash
  887. stName = caDlg.m_sUserName;
  888. if ((iPos = stName.FindOneOf(_T("\\"))) == -1)
  889. {
  890. // Couldn't find one, there is no domain info
  891. pszUser = (LPCTSTR) stName;
  892. pszDomain = NULL;
  893. }
  894. else
  895. {
  896. stUser = stName.Right(stName.GetLength() - iPos - 1);
  897. stDomain = stName.Left(iPos);
  898. pszUser = (LPCTSTR) stUser;
  899. pszDomain = (LPCTSTR) stDomain;
  900. }
  901. // Use the key 0x83 for the password
  902. RtlEncodeW(&ucSeed, stPassword.GetBuffer(0));
  903. stPassword.ReleaseBuffer();
  904. spAdmin->SetInfo(pszUser,
  905. pszDomain,
  906. (BYTE *) (LPCTSTR) stPassword,
  907. stPassword.GetLength() * sizeof(WCHAR));
  908. }
  909. }
  910. ZeroMemory(stPassword.GetBuffer(0),
  911. stPassword.GetLength() * sizeof(TCHAR));
  912. stPassword.ReleaseBuffer();
  913. if ( dwRes != NO_ERROR )
  914. {
  915. PBYTE pbMsgBuf = NULL;
  916. ::FormatMessage(
  917. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  918. NULL,
  919. dwRes,
  920. MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language
  921. (LPTSTR) &pbMsgBuf,
  922. 0,
  923. NULL
  924. );
  925. AfxMessageBox( (LPCTSTR) pbMsgBuf );
  926. LocalFree( pbMsgBuf );
  927. }
  928. else
  929. {
  930. //
  931. // connection succeeded
  932. //
  933. hr = hrOK;
  934. break;
  935. }
  936. }
  937. return hr;
  938. }
  939. DWORD ValidateMachine(const CString &sName, BOOL bDisplayErr)
  940. {
  941. // We don't use this info just
  942. // make the call to see if the server is out there. Hopefully
  943. // this will be faster than the RegConnectRegistry call.
  944. // We get info level 102 because this will also tell
  945. // us if we have the correct permissions for the machine.
  946. SERVER_INFO_102 *psvInfo102;
  947. DWORD dwr = NetServerGetInfo((LPTSTR)(LPCTSTR)sName,
  948. 102, (LPBYTE*)&psvInfo102);
  949. if (dwr == ERROR_SUCCESS)
  950. {
  951. NetApiBufferFree(psvInfo102);
  952. }
  953. else if (bDisplayErr)
  954. {
  955. CString str;
  956. str.Format(IDS_ERR_THEREHASBEEN, sName);
  957. AfxMessageBox(str);
  958. }
  959. return dwr;
  960. }
  961. /*!--------------------------------------------------------------------------
  962. InitiateServerConnection
  963. -
  964. Author: KennT
  965. ---------------------------------------------------------------------------*/
  966. HRESULT InitiateServerConnection(LPCTSTR pszMachine,
  967. HKEY *phkey,
  968. BOOL fNoConnectingUI,
  969. IRouterInfo *pRouter)
  970. {
  971. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  972. CConnectingDlg cnctingdlg;
  973. DWORD dwRes = IDOK;
  974. HRESULT hr = hrOK;
  975. COSERVERINFO csi;
  976. COAUTHINFO cai;
  977. COAUTHIDENTITY caid;
  978. IUnknown * punk = NULL;
  979. Assert(phkey);
  980. cnctingdlg.m_sName = pszMachine;
  981. // Display the connecting dialog if requested
  982. if (fNoConnectingUI)
  983. {
  984. if (!cnctingdlg.Connect())
  985. dwRes = 0;
  986. }
  987. else
  988. {
  989. dwRes = cnctingdlg.DoModal();
  990. }
  991. if ( !IsLocalMachine(pszMachine) )
  992. {
  993. ZeroMemory(&csi, sizeof(csi));
  994. ZeroMemory(&cai, sizeof(cai));
  995. ZeroMemory(&caid, sizeof(caid));
  996. csi.pAuthInfo = &cai;
  997. cai.pAuthIdentityData = &caid;
  998. hr = CoCreateRouterConfig(pszMachine,
  999. pRouter,
  1000. &csi,
  1001. IID_IRemoteNetworkConfig,
  1002. &punk) ;
  1003. if ( hrOK != hr )
  1004. {
  1005. cnctingdlg.m_dwr = ERROR_ACCESS_DENIED;
  1006. dwRes = 0;
  1007. }
  1008. else
  1009. {
  1010. if ( punk ) punk->Release();
  1011. }
  1012. }
  1013. // check and see if we were successful
  1014. if (dwRes == IDCANCEL)
  1015. {
  1016. *phkey = NULL;
  1017. hr = S_FALSE;
  1018. goto Error;
  1019. }
  1020. else if (dwRes != IDOK)
  1021. {
  1022. DisplayConnectErrorMessage(cnctingdlg.m_dwr);
  1023. hr = HResultFromWin32(cnctingdlg.m_dwr);
  1024. if ((cnctingdlg.m_dwr != ERROR_ACCESS_DENIED) &&
  1025. (cnctingdlg.m_dwr != ERROR_LOGON_FAILURE))
  1026. {
  1027. hr = HResultFromWin32(cnctingdlg.m_dwr);
  1028. goto Error;
  1029. }
  1030. // If there was an access denied error, we ask the
  1031. // user to see if they can supply different credentials
  1032. hr = ConnectAsAdmin(pszMachine, pRouter);
  1033. if (!FHrOK(hr))
  1034. {
  1035. *phkey = NULL;
  1036. hr = HResultFromWin32(ERROR_CANCELLED);
  1037. goto Error;
  1038. }
  1039. // try it again with the new credentials
  1040. dwRes = cnctingdlg.DoModal();
  1041. if (dwRes != IDOK)
  1042. {
  1043. DisplayConnectErrorMessage(cnctingdlg.m_dwr);
  1044. hr = HResultFromWin32(cnctingdlg.m_dwr);
  1045. goto Error;
  1046. }
  1047. }
  1048. // successful connection
  1049. if(phkey)
  1050. *phkey = cnctingdlg.m_hkMachine;
  1051. else
  1052. DisconnectRegistry(cnctingdlg.m_hkMachine);
  1053. Error:
  1054. return hr;
  1055. }
  1056. void DisplayConnectErrorMessage(DWORD dwr)
  1057. {
  1058. switch (dwr)
  1059. {
  1060. case ERROR_ACCESS_DENIED:
  1061. AfxMessageBox(IDS_ERR_ACCESSDENIED);
  1062. break;
  1063. case ERROR_BAD_NETPATH:
  1064. AfxMessageBox(IDS_ERR_NETPATHNOTFOUND);
  1065. break;
  1066. default:
  1067. DisplayIdErrorMessage2(NULL, IDS_ERR_ERRORCONNECT,
  1068. HResultFromWin32(dwr));
  1069. break;
  1070. }
  1071. }
  1072. /*!--------------------------------------------------------------------------
  1073. IsRouterServiceRunning
  1074. This will return hrOK if the service is running.
  1075. This will return hrFalse if the service is stopped (and no error).
  1076. Author: KennT
  1077. ---------------------------------------------------------------------------*/
  1078. TFSCORE_API(HRESULT) IsRouterServiceRunning(IN LPCWSTR pszMachine,
  1079. OUT DWORD *pdwErrorCode)
  1080. {
  1081. HRESULT hr = hrOK;
  1082. DWORD dwServiceStatus = 0;
  1083. hr = GetRouterServiceStatus(pszMachine, &dwServiceStatus, pdwErrorCode);
  1084. if (FHrSucceeded(hr))
  1085. {
  1086. hr = (dwServiceStatus == SERVICE_STOPPED) ? hrFalse : hrOK;
  1087. }
  1088. return hr;
  1089. }
  1090. /*!--------------------------------------------------------------------------
  1091. GetRouterServiceStatus
  1092. -
  1093. Author: KennT
  1094. ---------------------------------------------------------------------------*/
  1095. TFSCORE_API(HRESULT) GetRouterServiceStatus(LPCWSTR pszMachine,
  1096. DWORD *pdwStatus,
  1097. DWORD *pdwErrorCode)
  1098. {
  1099. HRESULT hr = hrOK;
  1100. DWORD dwServiceStatus = 0;
  1101. Assert(pdwStatus);
  1102. // First check the Router service (for Steelhead)
  1103. // ----------------------------------------------------------------
  1104. hr = HResultFromWin32(TFSGetServiceStatus(pszMachine,
  1105. c_szRouter,
  1106. &dwServiceStatus,
  1107. pdwErrorCode));
  1108. // If that failed, then we look at the RemoteAccess
  1109. // ----------------------------------------------------------------
  1110. if (!FHrSucceeded(hr) || (dwServiceStatus == SERVICE_STOPPED))
  1111. {
  1112. hr = HResultFromWin32(TFSGetServiceStatus(pszMachine,
  1113. c_szRemoteAccess,
  1114. &dwServiceStatus,
  1115. pdwErrorCode) );
  1116. }
  1117. if (FHrSucceeded(hr))
  1118. {
  1119. *pdwStatus = dwServiceStatus;
  1120. }
  1121. return hr;
  1122. }
  1123. TFSCORE_API(HRESULT) GetRouterServiceStartType(LPCWSTR pszMachine, DWORD *pdwStartType)
  1124. {
  1125. HRESULT hr = hrOK;
  1126. DWORD dwStartType = 0;
  1127. Assert(pdwStartType);
  1128. // First check the Router service (for Steelhead)
  1129. // ----------------------------------------------------------------
  1130. hr = HResultFromWin32(TFSGetServiceStartType(pszMachine,
  1131. c_szRouter, &dwStartType) );
  1132. // If that failed, then we look at the RemoteAccess service
  1133. // ----------------------------------------------------------------
  1134. if (!FHrSucceeded(hr))
  1135. {
  1136. hr = HResultFromWin32(TFSGetServiceStartType(pszMachine,
  1137. c_szRemoteAccess,
  1138. &dwStartType) );
  1139. }
  1140. //Error:
  1141. if (FHrSucceeded(hr))
  1142. {
  1143. *pdwStartType = dwStartType;
  1144. }
  1145. return hr;
  1146. }
  1147. TFSCORE_API(HRESULT) SetRouterServiceStartType(LPCWSTR pszMachine, DWORD dwStartType)
  1148. {
  1149. HRESULT hr = hrOK;
  1150. // Set the start type for both the Router and RemoteAccess
  1151. // ----------------------------------------------------------------
  1152. hr = HResultFromWin32(TFSSetServiceStartType(pszMachine,
  1153. c_szRouter, dwStartType) );
  1154. hr = HResultFromWin32(TFSSetServiceStartType(pszMachine,
  1155. c_szRemoteAccess,
  1156. dwStartType) );
  1157. return hr;
  1158. }
  1159. TFSCORE_API(HRESULT) ErasePSK(LPCWSTR pszMachine )
  1160. {
  1161. DWORD dwErr = ERROR_SUCCESS;
  1162. HANDLE hMprServer = NULL;
  1163. WCHAR szEmptyPSK[5] = {0};
  1164. HRESULT hr = hrOK;
  1165. MPR_CREDENTIALSEX_0 MprCredentials;
  1166. dwErr = ::MprAdminServerConnect((LPWSTR)pszMachine , &hMprServer);
  1167. if ( ERROR_SUCCESS != dwErr )
  1168. {
  1169. hr = HRESULT_FROM_WIN32(dwErr);
  1170. goto Error;
  1171. }
  1172. ZeroMemory(&MprCredentials, sizeof(MprCredentials));
  1173. //Setup the MprCredentials structure
  1174. MprCredentials.dwSize = 0;
  1175. MprCredentials.lpbCredentialsInfo = (LPBYTE)szEmptyPSK;
  1176. dwErr = MprAdminServerSetCredentials( hMprServer, 0, (LPBYTE)&MprCredentials );
  1177. if ( ERROR_SUCCESS != dwErr )
  1178. {
  1179. //Special case! If 13011 is returned, ignore it.
  1180. //This is because, the ipsec filter is not yet loaded and
  1181. //we are making calls to remove it.
  1182. if ( ERROR_IPSEC_MM_AUTH_NOT_FOUND != dwErr )
  1183. {
  1184. hr = HRESULT_FROM_WIN32(dwErr);
  1185. goto Error;
  1186. }
  1187. }
  1188. Error:
  1189. if ( hMprServer )
  1190. ::MprAdminServerDisconnect(hMprServer);
  1191. return hr;
  1192. }
  1193. /*!--------------------------------------------------------------------------
  1194. StartRouterService
  1195. -
  1196. Author: KennT
  1197. ---------------------------------------------------------------------------*/
  1198. TFSCORE_API(HRESULT) StartRouterService(LPCWSTR pszMachine)
  1199. {
  1200. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1201. HRESULT hr = hrOK;
  1202. CString stServiceDesc;
  1203. DWORD dwErr;
  1204. BOOL fNt4 = FALSE;
  1205. LPCTSTR pszServiceName = NULL;
  1206. HKEY hkeyMachine = NULL;
  1207. DWORD dwErasePSK = 0;
  1208. COM_PROTECT_TRY
  1209. {
  1210. // Ignore the failure code, what else can we do?
  1211. // ------------------------------------------------------------
  1212. dwErr = ConnectRegistry(pszMachine, &hkeyMachine);
  1213. if (dwErr == ERROR_SUCCESS)
  1214. {
  1215. IsNT4Machine(hkeyMachine, &fNt4);
  1216. DisconnectRegistry(hkeyMachine);
  1217. }
  1218. // Windows Nt Bug : 277121
  1219. // If this is an NT4 machine, try to start the Router service
  1220. // rather than the RemoteAccess service.
  1221. // ------------------------------------------------------------
  1222. // pszServiceName = (fNt4 ? c_szRouter : c_szRemoteAccess);
  1223. pszServiceName = c_szRemoteAccess;
  1224. stServiceDesc.LoadString(IDS_RRAS_SERVICE_DESC);
  1225. dwErr = TFSStartService(pszMachine,
  1226. pszServiceName,
  1227. stServiceDesc);
  1228. hr = HResultFromWin32(dwErr);
  1229. if (FHrOK(hr))
  1230. {
  1231. BOOL fIsRunning = FALSE;
  1232. // Windows NT Bug : 254167
  1233. // Need to check to see if the service is running
  1234. // (an error could have occurred in the StartService).
  1235. // --------------------------------------------------------
  1236. dwErr = TFSIsServiceRunning(pszMachine,
  1237. pszServiceName,
  1238. &fIsRunning);
  1239. if ((dwErr == ERROR_SUCCESS) && fIsRunning)
  1240. {
  1241. // Now we need to wait for the router to actually start
  1242. // running.
  1243. CString stText;
  1244. CString stTitle;
  1245. stText.LoadString(IDS_WAIT_FOR_RRAS);
  1246. stTitle.LoadString(IDS_WAIT_FOR_RRAS_TITLE);
  1247. CWaitForRemoteAccessDlg dlg(pszMachine, stText, stTitle, NULL);
  1248. dlg.DoModal();
  1249. }
  1250. //Now that the router service is started, check to see if PSK
  1251. //needs to be cleaned up
  1252. if ( FHrSucceeded (ReadErasePSKReg(pszMachine, &dwErasePSK) ) )
  1253. {
  1254. if ( dwErasePSK )
  1255. {
  1256. //What if the thing fails here. Cannot do much
  1257. if ( FHrSucceeded(ErasePSK (pszMachine)) )
  1258. {
  1259. WriteErasePSKReg(pszMachine, 0 );
  1260. }
  1261. }
  1262. }
  1263. }
  1264. }
  1265. COM_PROTECT_CATCH;
  1266. return hr;
  1267. }
  1268. /*!--------------------------------------------------------------------------
  1269. StopRouterService
  1270. -
  1271. Author: KennT
  1272. ---------------------------------------------------------------------------*/
  1273. TFSCORE_API(HRESULT) StopRouterService(LPCWSTR pszMachine)
  1274. {
  1275. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1276. HRESULT hr = hrOK;
  1277. CString stServiceDesc;
  1278. DWORD dwErr;
  1279. COM_PROTECT_TRY
  1280. {
  1281. // Load the description for the SAP Agent
  1282. stServiceDesc.LoadString(IDS_SAPAGENT_SERVICE_DESC);
  1283. // Stop the SAP Agent
  1284. // ------------------------------------------------------------
  1285. dwErr = TFSStopService(pszMachine,
  1286. c_szNWSAPAgent,
  1287. stServiceDesc);
  1288. // Load the description for the router
  1289. // ------------------------------------------------------------
  1290. stServiceDesc.LoadString(IDS_RRAS_SERVICE_DESC);
  1291. // Stop the router service
  1292. // ------------------------------------------------------------
  1293. dwErr = TFSStopService(pszMachine,
  1294. c_szRouter,
  1295. stServiceDesc);
  1296. // Stop the RemoteAccess service
  1297. // ------------------------------------------------------------
  1298. dwErr = TFSStopService(pszMachine,
  1299. c_szRemoteAccess,
  1300. stServiceDesc);
  1301. // If we get the ERROR_SERVICE_NOT_ACTIVE, this is ok since
  1302. // we are trying to stop the service anyway.
  1303. // ------------------------------------------------------------
  1304. if (dwErr == ERROR_SERVICE_NOT_ACTIVE)
  1305. hr = hrOK;
  1306. else
  1307. hr = HResultFromWin32(dwErr);
  1308. }
  1309. COM_PROTECT_CATCH;
  1310. return hr;
  1311. }
  1312. /*!--------------------------------------------------------------------------
  1313. ForceGlobalRefresh
  1314. -
  1315. Author: KennT
  1316. ---------------------------------------------------------------------------*/
  1317. TFSCORE_API(HRESULT) ForceGlobalRefresh(IRouterInfo *pRouter)
  1318. {
  1319. // Call through to the refresh object to start a refresh action
  1320. SPIRouterRefresh spRefresh;
  1321. HRESULT hr = hrOK;
  1322. if (pRouter == NULL)
  1323. CORg( E_INVALIDARG );
  1324. CORg( pRouter->GetRefreshObject(&spRefresh) );
  1325. if (spRefresh)
  1326. CORg( spRefresh->Refresh() );
  1327. Error:
  1328. return hr;
  1329. }
  1330. /*!--------------------------------------------------------------------------
  1331. FormatRasPortName
  1332. -
  1333. Author: KennT
  1334. ---------------------------------------------------------------------------*/
  1335. void FormatRasPortName(BYTE *pRasPort0, LPTSTR pszBuffer, UINT cchMax)
  1336. {
  1337. RAS_PORT_0 * prp0 = (RAS_PORT_0 *) pRasPort0;
  1338. CString stName;
  1339. stName.Format(_T("%ls (%ls)"), prp0->wszDeviceName, prp0->wszPortName);
  1340. StrnCpy(pszBuffer, (LPCTSTR) stName, cchMax);
  1341. pszBuffer[cchMax-1] = 0;
  1342. }
  1343. static CString s_PortNonOperational;
  1344. static CString s_PortDisconnected;
  1345. static CString s_PortCallingBack;
  1346. static CString s_PortListening;
  1347. static CString s_PortAuthenticating;
  1348. static CString s_PortAuthenticated;
  1349. static CString s_PortInitializing;
  1350. static CString s_PortUnknown;
  1351. static const CStringMapEntry s_PortConditionMap[] =
  1352. {
  1353. { RAS_PORT_NON_OPERATIONAL, &s_PortNonOperational, IDS_PORT_NON_OPERATIONAL },
  1354. { RAS_PORT_DISCONNECTED, &s_PortDisconnected, IDS_PORT_DISCONNECTED },
  1355. { RAS_PORT_CALLING_BACK, &s_PortCallingBack, IDS_PORT_CALLING_BACK },
  1356. { RAS_PORT_LISTENING, &s_PortListening, IDS_PORT_LISTENING },
  1357. { RAS_PORT_AUTHENTICATING, &s_PortAuthenticating, IDS_PORT_AUTHENTICATING },
  1358. { RAS_PORT_AUTHENTICATED, &s_PortAuthenticated, IDS_PORT_AUTHENTICATED },
  1359. { RAS_PORT_INITIALIZING, &s_PortInitializing, IDS_PORT_INITIALIZING },
  1360. { -1, &s_PortUnknown, IDS_PORT_UNKNOWN },
  1361. };
  1362. /*!--------------------------------------------------------------------------
  1363. PortConditionToCString
  1364. -
  1365. Author: KennT
  1366. ---------------------------------------------------------------------------*/
  1367. CString& PortConditionToCString(DWORD dwPortCondition)
  1368. {
  1369. return MapDWORDToCString(dwPortCondition, s_PortConditionMap);
  1370. }
  1371. static CString s_stPortsDeviceTypeNoUsage;
  1372. static CString s_stPortsDeviceTypeRouting;
  1373. static CString s_stPortsDeviceTypeRas;
  1374. static CString s_stPortsDeviceTypeRasRouting;
  1375. static CString s_stPortsDeviceTypeUnknown;
  1376. static const CStringMapEntry s_PortsDeviceTypeMap[] =
  1377. {
  1378. { 0, &s_stPortsDeviceTypeNoUsage, IDS_PORTSDLG_COL_NOUSAGE },
  1379. { 1, &s_stPortsDeviceTypeRouting, IDS_PORTSDLG_COL_ROUTING },
  1380. { 2, &s_stPortsDeviceTypeRas, IDS_PORTSDLG_COL_RAS },
  1381. { 3, &s_stPortsDeviceTypeRasRouting, IDS_PORTSDLG_COL_RASROUTING },
  1382. { -1, &s_stPortsDeviceTypeUnknown, IDS_PORTSDLG_COL_UNKNOWN },
  1383. };
  1384. CString& PortsDeviceTypeToCString(DWORD dwRasRouter)
  1385. {
  1386. return MapDWORDToCString(dwRasRouter, s_PortsDeviceTypeMap);
  1387. }
  1388. /*!--------------------------------------------------------------------------
  1389. RegFindInterfaceKey
  1390. -
  1391. This function returns the HKEY of the router interface with this ID.
  1392. Author: KennT
  1393. ---------------------------------------------------------------------------*/
  1394. STDMETHODIMP RegFindInterfaceKey(LPCTSTR pszInterface,
  1395. HKEY hkeyMachine,
  1396. REGSAM regAccess,
  1397. HKEY *pHKey)
  1398. {
  1399. HRESULT hr = hrFalse;
  1400. HKEY hkey = 0;
  1401. RegKey regkey;
  1402. RegKey regkeyIf;
  1403. RegKeyIterator regkeyIter;
  1404. HRESULT hrIter;
  1405. CString stValue;
  1406. CString stKey;
  1407. DWORD dwErr;
  1408. COM_PROTECT_TRY
  1409. {
  1410. // Open up the remoteaccess key
  1411. CWRg( regkey.Open(hkeyMachine, c_szInterfacesKey) );
  1412. // Now look for the key that matches this one
  1413. CORg( regkeyIter.Init(&regkey) );
  1414. for (hrIter = regkeyIter.Next(&stKey); hrIter == hrOK; hrIter = regkeyIter.Next(&stKey))
  1415. {
  1416. regkeyIf.Close();
  1417. // Open the key
  1418. dwErr = regkeyIf.Open(regkey, stKey, regAccess);
  1419. if (dwErr != ERROR_SUCCESS)
  1420. continue;
  1421. CORg( regkeyIf.QueryValue(c_szInterfaceName, stValue) );
  1422. if (stValue.CompareNoCase(pszInterface) == 0)
  1423. {
  1424. // Ok, we found the key that we want
  1425. if (pHKey)
  1426. {
  1427. *pHKey = regkeyIf.Detach();
  1428. hr = hrOK;
  1429. }
  1430. }
  1431. }
  1432. COM_PROTECT_ERROR_LABEL;
  1433. }
  1434. COM_PROTECT_CATCH;
  1435. return hr;
  1436. }
  1437. // hour map ( one bit for an hour of a week )
  1438. static BYTE s_bitSetting[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
  1439. //====================================================
  1440. // convert a List of Strings to Hour Map
  1441. // Strings in following format: 0 1:00-12:00 15:00-17:00
  1442. // hour map: a bit for an hour, 7 * 24 hours = 7 * 3 bytes
  1443. void StrListToHourMap(CStringList& stList, BYTE* map)
  1444. {
  1445. CStrParser Parser;
  1446. int sh, sm, eh, em = 0; // start hour, (min), end hour (min)
  1447. int day;
  1448. BYTE* pHourMap;
  1449. int i;
  1450. POSITION pos;
  1451. pos = stList.GetHeadPosition();
  1452. memset(map, 0, sizeof(BYTE) * 21);
  1453. while (pos)
  1454. {
  1455. Parser.SetStr( stList.GetNext(pos) );
  1456. Parser.SkipBlank();
  1457. day = Parser.DayOfWeek();
  1458. Parser.SkipBlank();
  1459. if(day == -1) continue;
  1460. pHourMap = map + sizeof(BYTE) * 3 * day;
  1461. while(-1 != (sh = Parser.GetUINT())) // sh:sm-eh:em
  1462. {
  1463. Parser.GotoAfter(_T(':'));
  1464. if(-1 == (sm = Parser.GetUINT())) // min
  1465. break;
  1466. Parser.GotoAfter(_T('-'));
  1467. if(-1 == (eh = Parser.GetUINT())) // hour
  1468. break;
  1469. if(-1 == (sm = Parser.GetUINT())) // min
  1470. break;
  1471. sm %= 60; sh %= 24; em %= 60; eh %= 25; // since we have end hour of 24:00
  1472. for(i = sh; i < eh; i++)
  1473. {
  1474. *(pHourMap + i / 8) |= s_bitSetting[i % 8];
  1475. }
  1476. }
  1477. }
  1478. }
  1479. //=====================================================
  1480. // convert value from map to strings
  1481. void HourMapToStrList(BYTE* map, CStringList& stList)
  1482. {
  1483. int sh, eh; // start hour, (min), end hour (min)
  1484. BYTE* pHourMap;
  1485. int i, j;
  1486. CString* pStr;
  1487. CString tmpStr;
  1488. // update the profile table
  1489. pHourMap = map;
  1490. stList.RemoveAll();
  1491. for( i = 0; i < 7; i++) // for each day
  1492. {
  1493. // if any value for this day
  1494. if(*pHourMap || *(pHourMap + 1) || *(pHourMap + 2))
  1495. {
  1496. // the string for this day
  1497. try{
  1498. pStr = NULL;
  1499. pStr = new CString;
  1500. // Print out the day, the day of the week is
  1501. // represented by an integer (0-6)
  1502. pStr->Format(_T("%d"), i);
  1503. sh = -1; eh = -1; // not start yet
  1504. for(j = 0; j < 24; j++) // for every hour
  1505. {
  1506. int k = j / 8;
  1507. int m = j % 8;
  1508. if(*(pHourMap + k) & s_bitSetting[m]) // this hour is on
  1509. {
  1510. if(sh == -1) sh = j; // set start hour is empty
  1511. eh = j; // extend end hour
  1512. }
  1513. else // this is not on
  1514. {
  1515. if(sh != -1) // some hours need to write out
  1516. {
  1517. tmpStr.Format(_T(" %02d:00-%02d:00"), sh, eh + 1);
  1518. *pStr += tmpStr;
  1519. sh = -1; eh = -1;
  1520. }
  1521. }
  1522. }
  1523. if(sh != -1)
  1524. {
  1525. tmpStr.Format(_T(" %02d:00-%02d:00"), sh, eh + 1);
  1526. *pStr += tmpStr;
  1527. sh = -1; eh = -1;
  1528. }
  1529. stList.AddTail(*pStr);
  1530. }
  1531. catch(CMemoryException&)
  1532. {
  1533. // AfxMessageBox(IDS_OUTOFMEMORY);
  1534. delete pStr;
  1535. stList.RemoveAll();
  1536. return;
  1537. }
  1538. }
  1539. pHourMap += 3;
  1540. }
  1541. }
  1542. /*!--------------------------------------------------------------------------
  1543. SetGlobalRegistrySettings
  1544. hkeyMachine - HKEY of the local machine key
  1545. fInstall - TRUE if we are installing
  1546. fChangeEnableRouter - TRUE if we can change the router key
  1547. (This is NOT the value of IpEnableRouter, but only if we are
  1548. allowed to change the value of this key).
  1549. -
  1550. Author: KennT
  1551. ---------------------------------------------------------------------------*/
  1552. HRESULT SetGlobalRegistrySettings(HKEY hkeyMachine,
  1553. BOOL fInstall,
  1554. BOOL fChangeEnableRouter)
  1555. {
  1556. HRESULT hr = hrOK;
  1557. RegKey regkey;
  1558. DWORD dwInstall = fInstall;
  1559. DWORD dwNotInstall = !fInstall;
  1560. DWORD dwErr;
  1561. // Open the TcpIp parmeters key
  1562. if (regkey.Open(hkeyMachine, c_szRegKeyTcpipParameters) != ERROR_SUCCESS)
  1563. {
  1564. // No need to set the error return code, if an error occurs
  1565. // assume that the key doesn't exist.
  1566. goto Error;
  1567. }
  1568. // Set IPEnableRouter to (fInstall)
  1569. if (fChangeEnableRouter)
  1570. CWRg( regkey.SetValue(c_szRegValIpEnableRouter, dwInstall) );
  1571. // regkey.SetValue(c_szRegValIpEnableRouterBackup, dwNotInstall);
  1572. // Set EnableICMPRedirect to (!fInstall)
  1573. CWRg( regkey.SetValue(c_szRegValEnableICMPRedirect, dwNotInstall) );
  1574. // Set the defaults for the new adapters
  1575. CWRg( regkey.SetValue(c_szRegValDeadGWDetectDefault, dwNotInstall) );
  1576. CWRg( regkey.SetValue(c_szRegValDontAddDefaultGatewayDefault, dwInstall) );
  1577. Error:
  1578. return hr;
  1579. }
  1580. /*!--------------------------------------------------------------------------
  1581. SetPerInterfaceRegistrySettings
  1582. -
  1583. Author: KennT
  1584. ---------------------------------------------------------------------------*/
  1585. HRESULT SetPerInterfaceRegistrySettings(HKEY hkeyMachine, BOOL fInstall)
  1586. {
  1587. HRESULT hr = hrOK;
  1588. DWORD dwInstall = fInstall;
  1589. DWORD dwNotInstall = !fInstall;
  1590. RegKey rkAdapters;
  1591. RegKey rkAdapter;
  1592. RegKeyIterator rkIter;
  1593. HRESULT hrIter;
  1594. CString stAdapter;
  1595. CStringList stIfList;
  1596. DWORD dwErr;
  1597. POSITION posIf;
  1598. RegKey rkIf;
  1599. CString stKey;
  1600. CString stIf;
  1601. // Get the key to the adapters section of TcpIp services
  1602. if (rkAdapters.Open(hkeyMachine, c_szRegKeyTcpipAdapters) != ERROR_SUCCESS)
  1603. {
  1604. // No need to set the error return code, if an error occurs
  1605. // assume that the key doesn't exist.
  1606. goto Error;
  1607. }
  1608. CORg( rkIter.Init(&rkAdapters) );
  1609. // Iterate through all of the adapters and set the key
  1610. for ( hrIter = rkIter.Next(&stAdapter); hrIter == hrOK; hrIter=rkIter.Next(&stAdapter) )
  1611. {
  1612. rkAdapter.Close();
  1613. // Open the adapter key
  1614. // ------------------------------------------------------------
  1615. dwErr = rkAdapter.Open(rkAdapters, stAdapter);
  1616. if (dwErr != ERROR_SUCCESS)
  1617. {
  1618. continue;
  1619. }
  1620. // Now that we have the adapter, we open up the IpConfig key
  1621. // to get the list of interfaces that match up to this adapter.
  1622. // ------------------------------------------------------------
  1623. CWRg( rkAdapter.QueryValue(c_szRegValIpConfig, stIfList) );
  1624. // Iterate through the interface list and set these values
  1625. // on each interface
  1626. // ------------------------------------------------------------
  1627. posIf = stIfList.GetHeadPosition();
  1628. while (posIf)
  1629. {
  1630. stIf = stIfList.GetNext(posIf);
  1631. // Create the right key
  1632. // --------------------------------------------------------
  1633. stKey = c_szSystemCCSServices;
  1634. stKey += _T('\\');
  1635. stKey += stIf;
  1636. rkIf.Close();
  1637. CWRg( rkIf.Open(hkeyMachine, stKey) );
  1638. // Set DeadGWDetect to (!fInstall) for each interface
  1639. // --------------------------------------------------------
  1640. dwErr = rkIf.SetValue(c_szRegValDeadGWDetect, dwNotInstall);
  1641. // Windows NT Bug: 168546
  1642. // Set DontAddDefaultGateway to (fInstall) only on Ndiswan adapters
  1643. // not ALL adapters.
  1644. // --------------------------------------------------------
  1645. if (stAdapter.Left(7).CompareNoCase(_T("NdisWan")) == 0)
  1646. {
  1647. dwErr = rkIf.SetValue(c_szRegValDontAddDefaultGateway, dwInstall);
  1648. }
  1649. }
  1650. }
  1651. Error:
  1652. return hr;
  1653. }
  1654. /*!--------------------------------------------------------------------------
  1655. InstallGlobalSettings
  1656. Sets the global settings (i.e. registry settings) on this machine
  1657. when the router is installed.
  1658. For a specific description of the actions involved, look at
  1659. the comments in the code.
  1660. Author: KennT
  1661. ---------------------------------------------------------------------------*/
  1662. HRESULT InstallGlobalSettings(LPCTSTR pszMachineName, IRouterInfo *pRouter)
  1663. {
  1664. HRESULT hr = hrOK;
  1665. RouterVersionInfo routerVersion;
  1666. BOOL fSetIPEnableRouter = FALSE;
  1667. // We can change the IPEnableRouter only if this is the right build.
  1668. // ----------------------------------------------------------------
  1669. if (pRouter)
  1670. {
  1671. pRouter->GetRouterVersionInfo(&routerVersion);
  1672. }
  1673. else
  1674. {
  1675. // Need to get the version info manually
  1676. // ------------------------------------------------------------
  1677. HKEY hkeyMachine = NULL;
  1678. if (ERROR_SUCCESS == ConnectRegistry(pszMachineName, &hkeyMachine))
  1679. QueryRouterVersionInfo(hkeyMachine, &routerVersion);
  1680. if (hkeyMachine)
  1681. DisconnectRegistry(hkeyMachine);
  1682. }
  1683. if (routerVersion.dwOsBuildNo <= USE_IPENABLEROUTER_VERSION)
  1684. fSetIPEnableRouter = TRUE;
  1685. CORg( SetRouterInstallRegistrySettings(pszMachineName, TRUE, fSetIPEnableRouter) );
  1686. NotifyTcpipOfChanges(pszMachineName,
  1687. pRouter,
  1688. fSetIPEnableRouter /*fEnableRouter*/,
  1689. IP_IRDP_DISABLED /*uPerformRouterDiscovery*/);
  1690. Error:
  1691. return hr;
  1692. }
  1693. /*!--------------------------------------------------------------------------
  1694. UninstallGlobalSettings
  1695. Clears the global settings (i.e. registry settings) on this machine
  1696. when the router is installed.
  1697. Set fSnapinChanges to TRUE if you want to write out the various
  1698. snapin changes.
  1699. For a specific description of the actions involved, look at
  1700. the comments in the code.
  1701. Author: KennT
  1702. ---------------------------------------------------------------------------*/
  1703. HRESULT UninstallGlobalSettings(LPCTSTR pszMachineName,
  1704. IRouterInfo *pRouter,
  1705. BOOL fNt4,
  1706. BOOL fSnapinChanges)
  1707. {
  1708. HRESULT hr = hrOK;
  1709. DWORD dwStatus = SERVICE_RUNNING;
  1710. DWORD dwErr = ERROR_SUCCESS;
  1711. BOOL fChange;
  1712. // Windows NT Bug : 273047
  1713. // Check to see if the SharedAccess service is running.
  1714. // We need to check this only for NT4
  1715. // ----------------------------------------------------------------
  1716. if (!fNt4)
  1717. {
  1718. DWORD dwErrT;
  1719. // Get the status of the SharedAccess service. If we cannot
  1720. // get the status of the service, we assume that the service
  1721. // is stopped.
  1722. // ------------------------------------------------------------
  1723. dwErrT = TFSGetServiceStatus(pszMachineName, c_szSharedAccess,
  1724. &dwStatus, &dwErr);
  1725. // If we have a problem with the API, or if the API reported
  1726. // a service-specific error, we assume the service is stopped.
  1727. // ------------------------------------------------------------
  1728. if ((dwErrT != ERROR_SUCCESS) || (dwErr != ERROR_SUCCESS))
  1729. dwStatus = SERVICE_STOPPED;
  1730. }
  1731. // If the SharedAccess service is running, then we do NOT want to
  1732. // change the IpEnableRouter key.
  1733. // ----------------------------------------------------------------
  1734. fChange = (dwStatus == SERVICE_RUNNING);
  1735. // This will ALWAYS set the IPEnableRouter key to 0, which is fine
  1736. // with us. (We do not need to check the version).
  1737. // ----------------------------------------------------------------
  1738. CORg( SetRouterInstallRegistrySettings(pszMachineName, FALSE, !fChange) );
  1739. if (fSnapinChanges)
  1740. {
  1741. CORg( WriteRouterConfiguredReg(pszMachineName, FALSE) );
  1742. CORg( WriteRRASExtendsComputerManagementKey(pszMachineName, FALSE) );
  1743. }
  1744. NotifyTcpipOfChanges(pszMachineName,
  1745. pRouter,
  1746. FALSE /* fEnableRouter */,
  1747. IP_IRDP_DISABLED_USE_DHCP /* uPerformRouterDiscovery */);
  1748. Error:
  1749. return hr;
  1750. }
  1751. /*!--------------------------------------------------------------------------
  1752. WriteErasePSKReg
  1753. -
  1754. Author: Vivekk
  1755. ---------------------------------------------------------------------------*/
  1756. HRESULT WriteErasePSKReg (LPCTSTR pszServerName, DWORD dwErasePSK )
  1757. {
  1758. HRESULT hr = hrOK;
  1759. RegKey regkey;
  1760. if (ERROR_SUCCESS == regkey.Open(HKEY_LOCAL_MACHINE,c_szRemoteAccessKey,KEY_ALL_ACCESS, pszServerName) )
  1761. CWRg(regkey.SetValue( c_szRouterPSK, dwErasePSK));
  1762. Error:
  1763. return hr;
  1764. }
  1765. /*!--------------------------------------------------------------------------
  1766. ReadErasePSKReg
  1767. -
  1768. Author: Vivekk
  1769. ---------------------------------------------------------------------------*/
  1770. HRESULT ReadErasePSKReg(LPCTSTR pszServerName, DWORD *pdwErasePSK)
  1771. {
  1772. HRESULT hr = hrOK;
  1773. RegKey regkey;
  1774. Assert(pdwErasePSK);
  1775. CWRg( regkey.Open(HKEY_LOCAL_MACHINE,
  1776. c_szRemoteAccessKey,
  1777. KEY_ALL_ACCESS,
  1778. pszServerName) );
  1779. CWRg( regkey.QueryValue( c_szRouterPSK, *pdwErasePSK) );
  1780. Error:
  1781. // If we can't find the key, we assume that the router has not
  1782. // been configured.
  1783. // ----------------------------------------------------------------
  1784. if (hr == HResultFromWin32(ERROR_FILE_NOT_FOUND))
  1785. {
  1786. hr = hrOK;
  1787. *pdwErasePSK = FALSE;
  1788. }
  1789. return hr;
  1790. }
  1791. /*!--------------------------------------------------------------------------
  1792. WriteRouterConfiguredReg
  1793. -
  1794. Author: KennT
  1795. ---------------------------------------------------------------------------*/
  1796. HRESULT WriteRouterConfiguredReg(LPCTSTR pszServerName, DWORD dwConfigured)
  1797. {
  1798. HRESULT hr = hrOK;
  1799. RegKey regkey;
  1800. if (ERROR_SUCCESS == regkey.Open(HKEY_LOCAL_MACHINE,c_szRemoteAccessKey,KEY_ALL_ACCESS, pszServerName) )
  1801. CWRg(regkey.SetValue( c_szRtrConfigured, dwConfigured));
  1802. Error:
  1803. return hr;
  1804. }
  1805. /*!--------------------------------------------------------------------------
  1806. ReadRouterConfiguredReg
  1807. -
  1808. Author: KennT
  1809. ---------------------------------------------------------------------------*/
  1810. HRESULT ReadRouterConfiguredReg(LPCTSTR pszServerName, DWORD *pdwConfigured)
  1811. {
  1812. HRESULT hr = hrOK;
  1813. RegKey regkey;
  1814. Assert(pdwConfigured);
  1815. CWRg( regkey.Open(HKEY_LOCAL_MACHINE,
  1816. c_szRemoteAccessKey,
  1817. KEY_ALL_ACCESS,
  1818. pszServerName) );
  1819. CWRg( regkey.QueryValue( c_szRtrConfigured, *pdwConfigured) );
  1820. Error:
  1821. // If we can't find the key, we assume that the router has not
  1822. // been configured.
  1823. // ----------------------------------------------------------------
  1824. if (hr == HResultFromWin32(ERROR_FILE_NOT_FOUND))
  1825. {
  1826. hr = hrOK;
  1827. *pdwConfigured = FALSE;
  1828. }
  1829. return hr;
  1830. }
  1831. /*!--------------------------------------------------------------------------
  1832. WriteRRASExtendsComputerManagement
  1833. -
  1834. Author: KennT
  1835. ---------------------------------------------------------------------------*/
  1836. HRESULT WriteRRASExtendsComputerManagementKey(LPCTSTR pszServer, DWORD dwConfigured)
  1837. {
  1838. HRESULT hr = hrOK;
  1839. RegKey rkMachine;
  1840. TCHAR szGuid[128];
  1841. // Stringize the RRAS GUID
  1842. ::StringFromGUID2(CLSID_RouterSnapinExtension, szGuid, DimensionOf(szGuid));
  1843. CWRg( rkMachine.Open(HKEY_LOCAL_MACHINE, c_szRegKeyServerApplications,
  1844. KEY_ALL_ACCESS, pszServer) );
  1845. if (dwConfigured)
  1846. {
  1847. // Need to add the following key
  1848. // HKLM \ System \ CurrentControlSet \ Control \ Server Applications
  1849. // <GUID> : REG_SZ : some string
  1850. CWRg( rkMachine.SetValue(szGuid, _T("Remote Access and Routing")) );
  1851. }
  1852. else
  1853. {
  1854. // Need to remove the following key
  1855. // HKLM \ System \ CurrentControlSet \ Control \ Server Applications
  1856. // <GUID> : REG_SZ : some string
  1857. CWRg( rkMachine.DeleteValue( szGuid ) );
  1858. }
  1859. Error:
  1860. return hr;
  1861. }
  1862. /*!--------------------------------------------------------------------------
  1863. NotifyTcpipOfChanges
  1864. -
  1865. Author: KennT
  1866. ---------------------------------------------------------------------------*/
  1867. void NotifyTcpipOfChanges(LPCTSTR pszMachineName,
  1868. IRouterInfo *pRouter,
  1869. BOOL fEnableRouter,
  1870. UCHAR uPerformRouterDiscovery)
  1871. {
  1872. HRESULT hr = hrOK;
  1873. RegKey rkInterfaces;
  1874. RegKey rkIf;
  1875. RegKeyIterator rkIter;
  1876. HRESULT hrIter;
  1877. CString stKey;
  1878. DWORD dwErr;
  1879. COSERVERINFO csi;
  1880. COAUTHINFO cai;
  1881. COAUTHIDENTITY caid;
  1882. ZeroMemory(&csi, sizeof(csi));
  1883. ZeroMemory(&cai, sizeof(cai));
  1884. ZeroMemory(&caid, sizeof(caid));
  1885. csi.pAuthInfo = &cai;
  1886. cai.pAuthIdentityData = &caid;
  1887. // For now, notify the user that they will have to
  1888. // reboot the machine locally.
  1889. if (!IsLocalMachine(pszMachineName))
  1890. {
  1891. SPIRemoteTCPIPChangeNotify spNotify;
  1892. // Create the remote config object
  1893. // ----------------------------------------------------------------
  1894. hr = CoCreateRouterConfig(pszMachineName,
  1895. pRouter,
  1896. &csi,
  1897. IID_IRemoteTCPIPChangeNotify,
  1898. (IUnknown**)&spNotify);
  1899. if (FAILED(hr)) goto Error;
  1900. // Upgrade the configuration (ensure that the registry keys
  1901. // are populated correctly).
  1902. // ------------------------------------------------------------
  1903. // Still do the notification for remote machines in case it is running
  1904. // an old build
  1905. Assert(spNotify);
  1906. hr = spNotify->NotifyChanges(fEnableRouter, uPerformRouterDiscovery);
  1907. spNotify.Release();
  1908. if (csi.pAuthInfo)
  1909. delete csi.pAuthInfo->pAuthIdentityData->Password;
  1910. }
  1911. else
  1912. {
  1913. // For the local case,
  1914. // Don't need to do any notification after bug 405636 and 345700 got fixed
  1915. }
  1916. Error:
  1917. if (!FHrSucceeded(hr))
  1918. {
  1919. if (hr == NETCFG_S_REBOOT)
  1920. AfxMessageBox(IDS_WRN_INSTALL_REBOOT_NOTIFICATION);
  1921. else
  1922. DisplayErrorMessage(NULL, hr);
  1923. }
  1924. }
  1925. /*!--------------------------------------------------------------------------
  1926. AddIpPerInterfaceBlocks
  1927. Setup this interface's infobase for IP.
  1928. Author: KennT
  1929. ---------------------------------------------------------------------------*/
  1930. HRESULT AddIpPerInterfaceBlocks(IInterfaceInfo *pIf, IInfoBase *pInfoBase)
  1931. {
  1932. HRESULT hr = hrOK;
  1933. BYTE* pInfo;
  1934. BYTE* pNewInfo = NULL;
  1935. DWORD dwErr;
  1936. DWORD dwSize;
  1937. CORg( pInfoBase->WriteTo(&pInfo, &dwSize) );
  1938. dwErr = MprConfigCreateIpInterfaceInfo(
  1939. pIf->GetInterfaceType(), pInfo, &pNewInfo );
  1940. CoTaskMemFree(pInfo);
  1941. if (dwErr != NO_ERROR) { return E_OUTOFMEMORY; }
  1942. dwSize = ((RTR_INFO_BLOCK_HEADER*)pNewInfo)->Size;
  1943. CORg( pInfoBase->LoadFrom(dwSize, pNewInfo) );
  1944. Error:
  1945. if (pNewInfo) { MprInfoDelete(pNewInfo); }
  1946. return hr;
  1947. }
  1948. /*!--------------------------------------------------------------------------
  1949. MprConfigCreateIpInterfaceInfo
  1950. Constructs an infobase containing required IP interface configuration.
  1951. The infobase should freed by calling 'MprInfoDelete'.
  1952. Author: AboladeG (based on AddIpPerInterfaceBlocks by KennT).
  1953. ---------------------------------------------------------------------------*/
  1954. extern "C"
  1955. DWORD APIENTRY MprConfigCreateIpInterfaceInfo(DWORD dwIfType,
  1956. PBYTE ExistingHeader, PBYTE* NewHeader )
  1957. {
  1958. DWORD dwErr;
  1959. PBYTE Header = NULL;
  1960. if (ExistingHeader)
  1961. {
  1962. dwErr = MprInfoDuplicate(ExistingHeader, (VOID**)&Header);
  1963. }
  1964. else
  1965. {
  1966. dwErr = MprInfoCreate(RTR_INFO_BLOCK_VERSION, (VOID**)&Header);
  1967. }
  1968. if (dwErr) { return dwErr; }
  1969. do {
  1970. //
  1971. // Check that there is a block for interface-status in the info,
  1972. // and insert the default block if none is found.
  1973. //
  1974. if ( !MprInfoBlockExists(Header, IP_MCAST_HEARBEAT_INFO) )
  1975. {
  1976. dwErr =
  1977. MprInfoBlockAdd(
  1978. Header,
  1979. IP_MCAST_HEARBEAT_INFO,
  1980. sizeof(MCAST_HBEAT_INFO),
  1981. 1,
  1982. g_pIpIfMulticastHeartbeatDefault,
  1983. (VOID**)NewHeader
  1984. );
  1985. if (dwErr) { break; }
  1986. MprInfoDelete(Header); Header = *NewHeader;
  1987. }
  1988. //
  1989. // Check that there is a block for multicast in the info,
  1990. // and insert the default block if none is found.
  1991. //
  1992. if ( !MprInfoBlockExists(Header, IP_INTERFACE_STATUS_INFO) )
  1993. {
  1994. dwErr =
  1995. MprInfoBlockAdd(
  1996. Header,
  1997. IP_INTERFACE_STATUS_INFO,
  1998. sizeof(INTERFACE_STATUS_INFO),
  1999. 1,
  2000. g_pIpIfStatusDefault,
  2001. (VOID**)NewHeader
  2002. );
  2003. if (dwErr) { break; }
  2004. MprInfoDelete(Header); Header = *NewHeader;
  2005. }
  2006. //
  2007. // Check that there is a block for router-discovery,
  2008. // inserting the default block if none is found
  2009. //
  2010. if ( !MprInfoBlockExists(Header, IP_ROUTER_DISC_INFO) )
  2011. {
  2012. //
  2013. // Select the default configuration which is appropriate
  2014. // for the type of interface being configured (LAN/WAN)
  2015. //
  2016. BYTE *pDefault;
  2017. pDefault =
  2018. (dwIfType == ROUTER_IF_TYPE_DEDICATED)
  2019. ? g_pRtrDiscLanDefault
  2020. : g_pRtrDiscWanDefault;
  2021. dwErr =
  2022. MprInfoBlockAdd(
  2023. Header,
  2024. IP_ROUTER_DISC_INFO,
  2025. sizeof(RTR_DISC_INFO),
  2026. 1,
  2027. pDefault,
  2028. (VOID**)NewHeader
  2029. );
  2030. if (dwErr) { break; }
  2031. MprInfoDelete(Header); Header = *NewHeader;
  2032. }
  2033. *NewHeader = Header;
  2034. } while(FALSE);
  2035. if (dwErr) { MprInfoDelete(Header); *NewHeader = NULL; }
  2036. return dwErr;
  2037. }
  2038. /*!--------------------------------------------------------------------------
  2039. AddIpxPerInterfaceBlocks
  2040. -
  2041. Author: KennT
  2042. ---------------------------------------------------------------------------*/
  2043. HRESULT AddIpxPerInterfaceBlocks(IInterfaceInfo *pIf, IInfoBase *pInfoBase)
  2044. {
  2045. HRESULT hr = hrOK;
  2046. #ifdef DEBUG
  2047. InfoBlock * pTestBlock;
  2048. #endif
  2049. //
  2050. // Check that there is a block for interface-status in the info,
  2051. // and insert the default block if none is found.
  2052. //
  2053. if (pInfoBase->BlockExists(IPX_INTERFACE_INFO_TYPE) == hrFalse)
  2054. {
  2055. IPX_IF_INFO ipx;
  2056. ipx.AdminState = ADMIN_STATE_ENABLED;
  2057. ipx.NetbiosAccept = ADMIN_STATE_DISABLED;
  2058. ipx.NetbiosDeliver = ADMIN_STATE_DISABLED;
  2059. CORg( pInfoBase->AddBlock(IPX_INTERFACE_INFO_TYPE,
  2060. sizeof(ipx),
  2061. (PBYTE) &ipx,
  2062. 1 /* count */,
  2063. FALSE /* bRemoveFirst */) );
  2064. Assert( pInfoBase->GetBlock(IPX_INTERFACE_INFO_TYPE,
  2065. &pTestBlock, 0) == hrOK);
  2066. }
  2067. //
  2068. // Check that there is a block for WAN interface-status in the info,
  2069. // and insert the default block if none is found.
  2070. //
  2071. if (pInfoBase->BlockExists(IPXWAN_INTERFACE_INFO_TYPE) == hrFalse)
  2072. {
  2073. IPXWAN_IF_INFO ipxwan;
  2074. ipxwan.AdminState = ADMIN_STATE_DISABLED;
  2075. CORg( pInfoBase->AddBlock(IPXWAN_INTERFACE_INFO_TYPE,
  2076. sizeof(ipxwan),
  2077. (PBYTE) &ipxwan,
  2078. 1 /* count */,
  2079. FALSE /* bRemoveFirst */) );
  2080. Assert( pInfoBase->GetBlock(IPXWAN_INTERFACE_INFO_TYPE,
  2081. &pTestBlock, 0) == hrOK);
  2082. }
  2083. // HACK! HACK!
  2084. // For IPX we have to add the RIP/SAP info blocks otherwise
  2085. // adding IPX to the interface will fail
  2086. // ----------------------------------------------------------------
  2087. if (!FHrOK(pInfoBase->BlockExists(IPX_PROTOCOL_RIP)))
  2088. {
  2089. // Add a RIP_IF_CONFIG block
  2090. BYTE * pDefault;
  2091. if (pIf->GetInterfaceType() == ROUTER_IF_TYPE_DEDICATED)
  2092. pDefault = g_pIpxRipLanInterfaceDefault;
  2093. else
  2094. pDefault = g_pIpxRipInterfaceDefault;
  2095. pInfoBase->AddBlock(IPX_PROTOCOL_RIP,
  2096. sizeof(RIP_IF_CONFIG),
  2097. pDefault,
  2098. 1,
  2099. 0);
  2100. }
  2101. if (!FHrOK(pInfoBase->BlockExists(IPX_PROTOCOL_SAP)))
  2102. {
  2103. // Add a SAP_IF_CONFIG block
  2104. BYTE * pDefault;
  2105. if (pIf->GetInterfaceType() == ROUTER_IF_TYPE_DEDICATED)
  2106. pDefault = g_pIpxSapLanInterfaceDefault;
  2107. else
  2108. pDefault = g_pIpxSapInterfaceDefault;
  2109. pInfoBase->AddBlock(IPX_PROTOCOL_SAP,
  2110. sizeof(SAP_IF_CONFIG),
  2111. pDefault,
  2112. 1,
  2113. 0);
  2114. }
  2115. Error:
  2116. return hr;
  2117. }
  2118. /*!--------------------------------------------------------------------------
  2119. UpdateLanaMapForDialinClients
  2120. -
  2121. Author: KennT
  2122. ---------------------------------------------------------------------------*/
  2123. HRESULT UpdateLanaMapForDialinClients(LPCTSTR pszServerName, DWORD dwAllowNetworkAccess)
  2124. {
  2125. HRESULT hr = hrOK;
  2126. DWORD dwErr;
  2127. RegKey regkeyNetBIOS;
  2128. CStringList rgstBindList;
  2129. CByteArray rgLanaMap;
  2130. int i, cEntries;
  2131. UINT cchNdisWanNbfIn;
  2132. POSITION pos;
  2133. CString st;
  2134. BYTE bValue;
  2135. // Get to the NetBIOS key
  2136. // ----------------------------------------------------------------
  2137. dwErr = regkeyNetBIOS.Open(HKEY_LOCAL_MACHINE,
  2138. c_szRegKeyNetBIOSLinkage,
  2139. KEY_ALL_ACCESS,
  2140. pszServerName);
  2141. if (dwErr != ERROR_SUCCESS)
  2142. {
  2143. // Setup the registry error
  2144. // ------------------------------------------------------------
  2145. SetRegError(0, HResultFromWin32(dwErr),
  2146. IDS_ERR_REG_OPEN_CALL_FAILED,
  2147. c_szHKLM, c_szRegKeyNetBIOSLinkage, NULL);
  2148. goto Error;
  2149. }
  2150. // Get the BIND key (this is a multivalued string)
  2151. // ----------------------------------------------------------------
  2152. dwErr = regkeyNetBIOS.QueryValue(c_szBind, rgstBindList);
  2153. if (dwErr != ERROR_SUCCESS)
  2154. {
  2155. SetRegError(0, HResultFromWin32(dwErr),
  2156. IDS_ERR_REG_QUERYVALUE_CALL_FAILED,
  2157. c_szHKLM, c_szRegKeyNetBIOSLinkage, c_szBind, NULL);
  2158. goto Error;
  2159. }
  2160. // Get the LanaMap key (this is a byte array)
  2161. // ----------------------------------------------------------------
  2162. dwErr = regkeyNetBIOS.QueryValue(c_szRegValLanaMap, rgLanaMap);
  2163. if (dwErr != ERROR_SUCCESS)
  2164. {
  2165. SetRegError(0, HResultFromWin32(dwErr),
  2166. IDS_ERR_REG_QUERYVALUE_CALL_FAILED,
  2167. c_szHKLM, c_szRegKeyNetBIOSLinkage, c_szRegValLanaMap, NULL);
  2168. goto Error;
  2169. }
  2170. // Find the entries that prefix match the "Nbf_NdisWanNbfIn" string.
  2171. // Set the corresponding entries in the LanaMap key to
  2172. // 0 or 1 (entry value = !dwAllowNetworkAccess).
  2173. // ----------------------------------------------------------------
  2174. cEntries = rgstBindList.GetCount();
  2175. pos = rgstBindList.GetHeadPosition();
  2176. cchNdisWanNbfIn = StrLen(c_szDeviceNbfNdisWanNbfIn);
  2177. for (i=0; i<cEntries; i++)
  2178. {
  2179. st = rgstBindList.GetNext(pos);
  2180. if (st.IsEmpty())
  2181. continue;
  2182. if (StrnCmp((LPCTSTR) st, c_szDeviceNbfNdisWanNbfIn, cchNdisWanNbfIn) == 0)
  2183. {
  2184. // Set the appropriate bit in the byte array
  2185. // --------------------------------------------------------
  2186. // We set the value to the opposite of dwAllowNetworkAccess
  2187. // --------------------------------------------------------
  2188. bValue = (dwAllowNetworkAccess ? 0 : 1);
  2189. rgLanaMap.SetAt(2*i, bValue);
  2190. }
  2191. }
  2192. // Write the info back out to the LanaMap key
  2193. // ----------------------------------------------------------------
  2194. dwErr = regkeyNetBIOS.SetValue(c_szRegValLanaMap, rgLanaMap);
  2195. if (dwErr != ERROR_SUCCESS)
  2196. {
  2197. SetRegError(0, HResultFromWin32(dwErr),
  2198. IDS_ERR_REG_SETVALUE_CALL_FAILED,
  2199. c_szHKLM, c_szRegKeyNetBIOSLinkage, c_szRegValLanaMap, NULL);
  2200. goto Error;
  2201. }
  2202. Error:
  2203. return hr;
  2204. }
  2205. /*!--------------------------------------------------------------------------
  2206. HrIsProtocolSupported
  2207. -
  2208. Author: KennT
  2209. ---------------------------------------------------------------------------*/
  2210. HRESULT HrIsProtocolSupported(LPCTSTR pszServerName,
  2211. LPCTSTR pszServiceKey,
  2212. LPCTSTR pszRasServiceKey,
  2213. LPCTSTR pszExtraKey)
  2214. {
  2215. HRESULT hr = hrFalse;
  2216. HRESULT hrTemp;
  2217. DWORD dwErr;
  2218. RegKey regkey;
  2219. HKEY hkeyMachine = NULL;
  2220. COM_PROTECT_TRY
  2221. {
  2222. CWRg( ConnectRegistry(pszServerName, &hkeyMachine) );
  2223. // Try to open both keys, if both succeed, then we
  2224. // consider the protocol to be installed.
  2225. // ------------------------------------------------------------
  2226. dwErr = regkey.Open(hkeyMachine, pszServiceKey, KEY_READ);
  2227. hrTemp = HResultFromWin32(dwErr);
  2228. if (FHrOK(hrTemp))
  2229. {
  2230. regkey.Close();
  2231. dwErr = regkey.Open(hkeyMachine, pszRasServiceKey, KEY_READ);
  2232. hrTemp = HResultFromWin32(dwErr);
  2233. // If pszExtraKey == NULL, then there is no extra key
  2234. // for us to test.
  2235. if (FHrOK(hrTemp) && pszExtraKey)
  2236. {
  2237. regkey.Close();
  2238. dwErr = regkey.Open(hkeyMachine, pszExtraKey, KEY_READ);
  2239. hrTemp = HResultFromWin32(dwErr);
  2240. }
  2241. }
  2242. // Both keys succeeded, so return hrOK
  2243. // ------------------------------------------------------------
  2244. if (FHrOK(hrTemp))
  2245. hr = hrOK;
  2246. else
  2247. hr = hrFalse;
  2248. COM_PROTECT_ERROR_LABEL;
  2249. }
  2250. COM_PROTECT_CATCH;
  2251. if (hkeyMachine)
  2252. DisconnectRegistry(hkeyMachine);
  2253. return hr;
  2254. }
  2255. /*!--------------------------------------------------------------------------
  2256. RegisterRouterInDomain
  2257. -
  2258. Author: KennT
  2259. ---------------------------------------------------------------------------*/
  2260. HRESULT RegisterRouterInDomain(LPCTSTR pszRouterName, BOOL fRegister)
  2261. {
  2262. DOMAIN_CONTROLLER_INFO * pDcInfo = NULL;
  2263. HRESULT hr = hrOK;
  2264. HRESULT hrT = hrOK;
  2265. // If this fails, we assume this is standalone.
  2266. hrT = HrIsStandaloneServer(pszRouterName);
  2267. if (hrT == S_FALSE)
  2268. {
  2269. CWRg( DsGetDcName(pszRouterName, NULL, NULL, NULL, 0, &pDcInfo) );
  2270. CWRg( MprDomainRegisterRasServer(pDcInfo->DomainName,
  2271. (LPTSTR) pszRouterName,
  2272. fRegister) );
  2273. }
  2274. Error:
  2275. if (pDcInfo)
  2276. NetApiBufferFree(pDcInfo);
  2277. return hr;
  2278. }
  2279. /*!--------------------------------------------------------------------------
  2280. SetDeviceType
  2281. For the given machine, this API will set the ports for this
  2282. machine accordingly (given the dwRouterType).
  2283. If dwTotalPorts is non-zero, then the max ports for L2TP/PPTP
  2284. will be adjusted (each will get 1/2 of dwTotalPorts).
  2285. Author: KennT
  2286. ---------------------------------------------------------------------------*/
  2287. HRESULT SetDeviceType(LPCTSTR pszMachineName,
  2288. DWORD dwRouterType,
  2289. DWORD dwTotalPorts)
  2290. {
  2291. PortsDataEntry portsDataEntry;
  2292. PortsDeviceList portsList;
  2293. PortsDeviceEntry * pEntry = NULL;
  2294. HRESULT hr = hrOK;
  2295. POSITION pos;
  2296. CORg( portsDataEntry.Initialize(pszMachineName) );
  2297. CORg( portsDataEntry.LoadDevices( &portsList ) );
  2298. CORg( SetDeviceTypeEx( &portsList, dwRouterType ) );
  2299. if (dwTotalPorts)
  2300. {
  2301. // Set the port sizes for L2TP and PPTP
  2302. CORg( SetPortSize(&portsList, dwTotalPorts/2) );
  2303. }
  2304. // Save the data back
  2305. // ----------------------------------------------------------------
  2306. CORg( portsDataEntry.SaveDevices( &portsList ) );
  2307. Error:
  2308. // Clear out the ports list, we don't need the data anymore
  2309. // ----------------------------------------------------------------
  2310. while (!portsList.IsEmpty())
  2311. delete portsList.RemoveHead();
  2312. return hr;
  2313. }
  2314. /*!--------------------------------------------------------------------------
  2315. SetPortSize
  2316. -
  2317. Author: KennT
  2318. ---------------------------------------------------------------------------*/
  2319. HRESULT SetPortSize(PortsDeviceList *pDeviceList, DWORD dwPorts)
  2320. {
  2321. HRESULT hr = hrOK;
  2322. POSITION pos;
  2323. PortsDeviceEntry * pEntry = NULL;
  2324. pos = pDeviceList->GetHeadPosition();
  2325. while (pos)
  2326. {
  2327. pEntry = pDeviceList->GetNext(pos);
  2328. if ((RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_Pptp) ||
  2329. (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Tunnel_L2tp))
  2330. {
  2331. pEntry->m_fModified = TRUE;
  2332. pEntry->m_dwPorts = dwPorts;
  2333. }
  2334. }
  2335. return hr;
  2336. }
  2337. /*!--------------------------------------------------------------------------
  2338. SetDeviceTypeEx
  2339. This is the core of the function above.
  2340. Author: KennT
  2341. ---------------------------------------------------------------------------*/
  2342. HRESULT SetDeviceTypeEx(PortsDeviceList *pDeviceList,
  2343. DWORD dwRouterType)
  2344. {
  2345. PortsDeviceEntry * pEntry = NULL;
  2346. HRESULT hr = hrOK;
  2347. POSITION pos;
  2348. Assert(pDeviceList);
  2349. Assert(dwRouterType);
  2350. // Ok now we go through and set the type of all of the devices
  2351. // ----------------------------------------------------------------
  2352. pos = pDeviceList->GetHeadPosition();
  2353. while (pos)
  2354. {
  2355. pEntry = pDeviceList->GetNext(pos);
  2356. // If we have enabled routing and if this port did not
  2357. // have routing enabled, enable routing.
  2358. // ------------------------------------------------------------
  2359. if ((dwRouterType & (ROUTER_TYPE_LAN | ROUTER_TYPE_WAN)))
  2360. {
  2361. if (!pEntry->m_dwEnableRouting)
  2362. {
  2363. pEntry->m_dwEnableRouting = TRUE;
  2364. pEntry->m_fModified = TRUE;
  2365. }
  2366. }
  2367. else
  2368. {
  2369. // If this port does NOT have routing enabled
  2370. // and routing is enabled, disable it.
  2371. // --------------------------------------------------------
  2372. if (pEntry->m_dwEnableRouting)
  2373. {
  2374. pEntry->m_dwEnableRouting = FALSE;
  2375. pEntry->m_fModified = TRUE;
  2376. }
  2377. }
  2378. // Windows NT Bug : 292615
  2379. // If this is a parallel port, do not enable RAS.
  2380. // ------------------------------------------------------------
  2381. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_Parallel)
  2382. {
  2383. if (pEntry->m_dwEnableRas)
  2384. {
  2385. pEntry->m_dwEnableRas = FALSE;
  2386. pEntry->m_fModified = TRUE;
  2387. }
  2388. continue;
  2389. }
  2390. //
  2391. // For PPPoE devices disable Ras and Routing. Only outbound
  2392. // routing can be set for PPPoE devices
  2393. if (RAS_DEVICE_TYPE(pEntry->m_eDeviceType) == RDT_PPPoE)
  2394. {
  2395. if (pEntry->m_dwEnableRas)
  2396. {
  2397. pEntry->m_dwEnableRas = FALSE;
  2398. pEntry->m_fModified = TRUE;
  2399. }
  2400. if (pEntry->m_dwEnableRouting)
  2401. {
  2402. pEntry->m_dwEnableRouting = FALSE;
  2403. pEntry->m_fModified = TRUE;
  2404. }
  2405. continue;
  2406. }
  2407. // Similarly for RAS
  2408. // ------------------------------------------------------------
  2409. if (dwRouterType & ROUTER_TYPE_RAS)
  2410. {
  2411. if (!pEntry->m_dwEnableRas)
  2412. {
  2413. pEntry->m_dwEnableRas = TRUE;
  2414. pEntry->m_fModified = TRUE;
  2415. }
  2416. }
  2417. else
  2418. {
  2419. if (pEntry->m_dwEnableRas)
  2420. {
  2421. pEntry->m_dwEnableRas = FALSE;
  2422. pEntry->m_fModified = TRUE;
  2423. }
  2424. }
  2425. }
  2426. return hr;
  2427. }
  2428. HRESULT SetRouterInstallRegistrySettings(LPCWSTR pswzServer,
  2429. BOOL fInstall,
  2430. BOOL fChangeEnableRouter)
  2431. {
  2432. HRESULT hr = hrOK;
  2433. HKEY hklm = NULL;
  2434. CWRg( ConnectRegistry(pswzServer, &hklm) );
  2435. // Write out the global registry settings
  2436. CORg( SetGlobalRegistrySettings(hklm, fInstall, fChangeEnableRouter) );
  2437. // Write the per-interface registry settings
  2438. CORg( SetPerInterfaceRegistrySettings(hklm, fInstall) );
  2439. Error:
  2440. if (hklm)
  2441. {
  2442. DisconnectRegistry(hklm);
  2443. hklm = NULL;
  2444. }
  2445. return hr;
  2446. }
  2447. static CString s_PortDeviceTypeModem;
  2448. static CString s_PortDeviceTypeX25;
  2449. static CString s_PortDeviceTypeIsdn;
  2450. static CString s_PortDeviceTypeSerial;
  2451. static CString s_PortDeviceTypeFrameRelay;
  2452. static CString s_PortDeviceTypeAtm;
  2453. static CString s_PortDeviceTypeSonet;
  2454. static CString s_PortDeviceTypeSw56;
  2455. static CString s_PortDeviceTypePptp;
  2456. static CString s_PortDeviceTypeL2tp;
  2457. static CString s_PortDeviceTypeIrda;
  2458. static CString s_PortDeviceTypeParallel;
  2459. static CString s_PortDeviceTypePPPoE;
  2460. static CString s_PortDeviceTypeOther;
  2461. static const CStringMapEntry s_PortTypeMap[] =
  2462. {
  2463. { RDT_Modem, &s_PortDeviceTypeModem, IDS_PORTSDLG_DEVTYPE_MODEM },
  2464. { RDT_X25, &s_PortDeviceTypeX25, IDS_PORTSDLG_DEVTYPE_X25 },
  2465. { RDT_Isdn, &s_PortDeviceTypeIsdn, IDS_PORTSDLG_DEVTYPE_ISDN },
  2466. { RDT_Serial, &s_PortDeviceTypeSerial, IDS_PORTSDLG_DEVTYPE_SERIAL },
  2467. { RDT_FrameRelay, &s_PortDeviceTypeFrameRelay, IDS_PORTSDLG_DEVTYPE_FRAMERELAY },
  2468. { RDT_Atm, &s_PortDeviceTypeAtm, IDS_PORTSDLG_DEVTYPE_ATM },
  2469. { RDT_Sonet, &s_PortDeviceTypeSonet, IDS_PORTSDLG_DEVTYPE_SONET },
  2470. { RDT_Sw56, &s_PortDeviceTypeSw56, IDS_PORTSDLG_DEVTYPE_SW56 },
  2471. { RDT_Tunnel_Pptp, &s_PortDeviceTypePptp, IDS_PORTSDLG_DEVTYPE_PPTP },
  2472. { RDT_Tunnel_L2tp, &s_PortDeviceTypeL2tp, IDS_PORTSDLG_DEVTYPE_L2TP },
  2473. { RDT_Irda, &s_PortDeviceTypeIrda, IDS_PORTSDLG_DEVTYPE_IRDA },
  2474. { RDT_Parallel, &s_PortDeviceTypeParallel, IDS_PORTSDLG_DEVTYPE_PARALLEL },
  2475. { RDT_PPPoE, &s_PortDeviceTypePPPoE, IDS_PORTSDLG_DEVTYPE_PPPOE },
  2476. { RDT_Other, &s_PortDeviceTypeOther, IDS_PORTSDLG_DEVTYPE_OTHER },
  2477. { -1, &s_PortUnknown, IDS_PORT_UNKNOWN },
  2478. };
  2479. /*!--------------------------------------------------------------------------
  2480. PortTypeToCString
  2481. -
  2482. Author: MikeG (a-migall)
  2483. ---------------------------------------------------------------------------*/
  2484. CString& PortTypeToCString(DWORD dwPortType)
  2485. {
  2486. // Make sure that the class info has been "stripped" from the port
  2487. // type mask.
  2488. DWORD dw = static_cast<DWORD>(RAS_DEVICE_TYPE(dwPortType));
  2489. // For now, if we don't know what the type is we'll default to "Other"
  2490. // as an answer. FUTURE: Someone may want to change this in the future.
  2491. if (dw > RDT_Other)
  2492. dw = RDT_Other;
  2493. return MapDWORDToCString(dwPortType, s_PortTypeMap);
  2494. }
  2495. /*---------------------------------------------------------------------------
  2496. CWaitForRemoteAccessDlg implementation
  2497. ---------------------------------------------------------------------------*/
  2498. CWaitForRemoteAccessDlg::CWaitForRemoteAccessDlg(LPCTSTR pszServerName,
  2499. LPCTSTR pszText, LPCTSTR pszTitle, CWnd *pParent)
  2500. : CWaitDlg(pszServerName, pszText, pszTitle, pParent)
  2501. {
  2502. }
  2503. void CWaitForRemoteAccessDlg::OnTimerTick()
  2504. {
  2505. HRESULT hr = hrOK;
  2506. DWORD dwErrorCode = ERROR_SUCCESS;
  2507. // Windows NT Bug : 266364
  2508. // 266364 - If we got this far we assume that the service has
  2509. // already started, but it may then exit out after that point (due
  2510. // to some other configuration error). So we need to check to see
  2511. // if the service is running.
  2512. hr = IsRouterServiceRunning(m_strServerName, &dwErrorCode);
  2513. if (FHrOK(hr))
  2514. {
  2515. if (MprAdminIsServiceRunning(T2W((LPTSTR)(LPCTSTR) m_strServerName)) == TRUE)
  2516. CDialog::OnOK();
  2517. // If the service is running, but MprAdmin is not finished yet,
  2518. // party on.
  2519. }
  2520. else
  2521. {
  2522. // Stop the timer
  2523. CloseTimer();
  2524. CDialog::OnOK();
  2525. // Ensure that an error info was created
  2526. CreateTFSErrorInfo(NULL);
  2527. // The service is not running. We can exit out of this dialog.
  2528. // An error may have occurred, if we have the error code, report
  2529. // the error.
  2530. if (dwErrorCode != ERROR_SUCCESS)
  2531. {
  2532. TCHAR szBuffer[2048];
  2533. AddHighLevelErrorStringId(IDS_ERR_SERVICE_FAILED_TO_START);
  2534. FormatSystemError(dwErrorCode,
  2535. szBuffer,
  2536. DimensionOf(szBuffer),
  2537. 0,
  2538. FSEFLAG_SYSMESSAGE | FSEFLAG_MPRMESSAGE);
  2539. FillTFSError(0, HResultFromWin32(dwErrorCode), FILLTFSERR_LOW,
  2540. 0, szBuffer, 0);
  2541. DisplayTFSErrorMessage(GetSafeHwnd());
  2542. }
  2543. else
  2544. {
  2545. AddHighLevelErrorStringId(IDS_ERR_SERVICE_FAILED_TO_START_UNKNOWN);
  2546. }
  2547. }
  2548. }
  2549. /////////////////////////////////////////////////////////////////////////////
  2550. // CRestartRouterDlg dialog
  2551. CRestartRouterDlg::CRestartRouterDlg
  2552. (
  2553. LPCTSTR pszServerName,
  2554. LPCTSTR pszText,
  2555. LPCTSTR pszTitle,
  2556. CTime* pTimeStart,
  2557. CWnd* pParent /*= NULL*/
  2558. )
  2559. : CWaitDlg(pszServerName, pszText, pszTitle, pParent)
  2560. {
  2561. m_pTimeStart = pTimeStart;
  2562. m_dwTimeElapsed = 0;
  2563. m_fTimeOut = FALSE;
  2564. m_dwError = NO_ERROR;
  2565. }
  2566. void CRestartRouterDlg::OnTimerTick()
  2567. {
  2568. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2569. m_dwTimeElapsed++;
  2570. if (!(m_dwTimeElapsed % TIMEOUT_POLL))
  2571. {
  2572. HRESULT hr = hrOK;
  2573. DWORD dwError = NO_ERROR;
  2574. DWORD dwServiceStatus = 0;
  2575. BOOL fFinished = FALSE;
  2576. hr = GetRouterServiceStatus((LPCTSTR)m_strServerName, &dwServiceStatus, &dwError);
  2577. if (FHrSucceeded(hr) && SERVICE_RUNNING == dwServiceStatus)
  2578. {
  2579. USES_CONVERSION;
  2580. if (MprAdminIsServiceRunning(T2W((LPTSTR)((LPCTSTR)m_strServerName))))
  2581. {
  2582. DWORD dwUpTime;
  2583. dwError = GetRouterUpTime(m_strServerName, &dwUpTime);
  2584. if (NO_ERROR == dwError &&
  2585. dwUpTime <= (DWORD) ((CTime::GetCurrentTime() - *m_pTimeStart).GetTotalSeconds()))
  2586. {
  2587. CDialog::OnOK();
  2588. fFinished = TRUE;
  2589. m_fTimeOut = FALSE;
  2590. }
  2591. }
  2592. }
  2593. if (NO_ERROR != dwError)
  2594. {
  2595. CDialog::OnOK();
  2596. m_dwError = dwError;
  2597. }
  2598. //NTBUG: ID=249775. The behavior of this dialog has to be same as the start
  2599. // dialog. So, timeout feature is disabled.
  2600. /*
  2601. //if the waiting time has been longer to 60 seconds, we assume someting is wrong
  2602. else if (!fFinished &&
  2603. (CTime::GetCurrentTime() - *m_pTimeStart).GetTotalSeconds() > MAX_WAIT_RESTART)
  2604. {
  2605. CDialog::OnOK();
  2606. m_fTimeOut = TRUE;
  2607. }
  2608. */
  2609. }
  2610. }
  2611. TFSCORE_API(HRESULT) PauseRouterService(LPCWSTR pszMachine)
  2612. {
  2613. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2614. HRESULT hr = hrOK;
  2615. CString stServiceDesc;
  2616. DWORD dwErr;
  2617. COM_PROTECT_TRY
  2618. {
  2619. // Load the description for the SAP Agent
  2620. stServiceDesc.LoadString(IDS_SAPAGENT_SERVICE_DESC);
  2621. // Pause the SAP Agent
  2622. // ------------------------------------------------------------
  2623. dwErr = TFSPauseService(pszMachine,
  2624. c_szNWSAPAgent,
  2625. stServiceDesc);
  2626. if ((dwErr == ERROR_SERVICE_NOT_ACTIVE) ||
  2627. (dwErr == ERROR_SERVICE_DOES_NOT_EXIST))
  2628. hr = hrOK;
  2629. else
  2630. CWRg( dwErr );
  2631. // Load the description for the router
  2632. // ------------------------------------------------------------
  2633. stServiceDesc.LoadString(IDS_RRAS_SERVICE_DESC);
  2634. // Pause the router service
  2635. // ------------------------------------------------------------
  2636. dwErr = TFSPauseService(pszMachine,
  2637. c_szRouter,
  2638. stServiceDesc);
  2639. if ((dwErr == ERROR_SERVICE_NOT_ACTIVE) ||
  2640. (dwErr == ERROR_SERVICE_DOES_NOT_EXIST))
  2641. hr = hrOK;
  2642. else
  2643. CWRg( dwErr );
  2644. // Pause the RemoteAccess service
  2645. // ------------------------------------------------------------
  2646. dwErr = TFSPauseService(pszMachine,
  2647. c_szRemoteAccess,
  2648. stServiceDesc);
  2649. if ((dwErr == ERROR_SERVICE_NOT_ACTIVE) ||
  2650. (dwErr == ERROR_SERVICE_DOES_NOT_EXIST))
  2651. hr = hrOK;
  2652. else
  2653. CWRg( dwErr );
  2654. COM_PROTECT_ERROR_LABEL;
  2655. }
  2656. COM_PROTECT_CATCH;
  2657. return hr;
  2658. }
  2659. TFSCORE_API(HRESULT) ResumeRouterService(LPCWSTR pszMachine)
  2660. {
  2661. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2662. HRESULT hr = hrOK;
  2663. CString stServiceDesc;
  2664. DWORD dwErr;
  2665. COM_PROTECT_TRY
  2666. {
  2667. // Load the description for the SAP Agent
  2668. stServiceDesc.LoadString(IDS_SAPAGENT_SERVICE_DESC);
  2669. // Resume the SAP Agent
  2670. // ------------------------------------------------------------
  2671. dwErr = TFSResumeService(pszMachine,
  2672. c_szNWSAPAgent,
  2673. stServiceDesc);
  2674. if (dwErr == ERROR_SERVICE_NOT_ACTIVE)
  2675. hr = hrOK;
  2676. else
  2677. hr = HResultFromWin32(dwErr);
  2678. // Load the description for the router
  2679. // ------------------------------------------------------------
  2680. stServiceDesc.LoadString(IDS_RRAS_SERVICE_DESC);
  2681. // Resume the router service
  2682. // ------------------------------------------------------------
  2683. dwErr = TFSResumeService(pszMachine,
  2684. c_szRouter,
  2685. stServiceDesc);
  2686. if (dwErr == ERROR_SERVICE_NOT_ACTIVE)
  2687. hr = hrOK;
  2688. else
  2689. hr = HResultFromWin32(dwErr);
  2690. // Resume the RemoteAccess service
  2691. // ------------------------------------------------------------
  2692. dwErr = TFSResumeService(pszMachine,
  2693. c_szRemoteAccess,
  2694. stServiceDesc);
  2695. if (dwErr == ERROR_SERVICE_NOT_ACTIVE)
  2696. hr = hrOK;
  2697. else
  2698. hr = HResultFromWin32(dwErr);
  2699. }
  2700. COM_PROTECT_CATCH;
  2701. return hr;
  2702. }
  2703. /*---------------------------------------------------------------------------
  2704. CNetConnection
  2705. ---------------------------------------------------------------------------*/
  2706. /*---------------------------------------------------------------------------
  2707. Class : CNetConnection
  2708. This class maintains a list of net connections (those connected using
  2709. WNetAddConnection2).
  2710. When told, it will release all of its connections.
  2711. ---------------------------------------------------------------------------*/
  2712. class CNetConnection
  2713. {
  2714. public:
  2715. CNetConnection();
  2716. ~CNetConnection();
  2717. HRESULT Add(LPCTSTR pszConnection);
  2718. HRESULT RemoveAll();
  2719. HRESULT Remove(LPCTSTR pszConnection);
  2720. private:
  2721. CStringList m_listConnections;
  2722. };
  2723. CNetConnection::CNetConnection()
  2724. {
  2725. }
  2726. CNetConnection::~CNetConnection()
  2727. {
  2728. RemoveAll();
  2729. }
  2730. HRESULT CNetConnection::Add(LPCTSTR pszConnection)
  2731. {
  2732. HRESULT hr = hrOK;
  2733. COM_PROTECT_TRY
  2734. {
  2735. m_listConnections.AddTail(pszConnection);
  2736. }
  2737. COM_PROTECT_CATCH;
  2738. return hr;
  2739. }
  2740. HRESULT CNetConnection::Remove(LPCTSTR pszConnection)
  2741. {
  2742. HRESULT hr = hrOK;
  2743. POSITION p;
  2744. COM_PROTECT_TRY
  2745. {
  2746. p = m_listConnections.Find(pszConnection);
  2747. if ( p )
  2748. {
  2749. m_listConnections.RemoveAt(p);
  2750. WNetCancelConnection2(pszConnection,
  2751. 0 /* dwFlags */,
  2752. TRUE /* fForce */);
  2753. }
  2754. }
  2755. COM_PROTECT_CATCH;
  2756. return hr;
  2757. }
  2758. HRESULT CNetConnection::RemoveAll()
  2759. {
  2760. HRESULT hr = hrOK;
  2761. COM_PROTECT_TRY
  2762. {
  2763. while (!m_listConnections.IsEmpty())
  2764. {
  2765. CString st;
  2766. st = m_listConnections.RemoveHead();
  2767. WNetCancelConnection2((LPCTSTR) st,
  2768. 0 /* dwFlags */,
  2769. TRUE /* fForce */);
  2770. }
  2771. }
  2772. COM_PROTECT_CATCH;
  2773. return hr;
  2774. }
  2775. // Global functions to add/remove net connections
  2776. // --------------------------------------------------------------------
  2777. static CNetConnection g_NetConnections;
  2778. HRESULT AddNetConnection(LPCTSTR pszConnection)
  2779. {
  2780. return g_NetConnections.Add(pszConnection);
  2781. }
  2782. HRESULT RemoveAllNetConnections()
  2783. {
  2784. return g_NetConnections.RemoveAll();
  2785. }
  2786. HRESULT RemoveNetConnection(LPCTSTR szServerName)
  2787. {
  2788. //Make the connection name
  2789. CString stIPCShare;
  2790. CString stRouterName = szServerName;
  2791. if ( stRouterName.Left(2) != TEXT( "\\\\" ) )
  2792. {
  2793. stIPCShare = TEXT( "\\\\" );
  2794. }
  2795. stIPCShare += stRouterName;
  2796. stIPCShare += TEXT( "\\" );
  2797. stIPCShare += c_szIPCShare;
  2798. return g_NetConnections.Remove(stIPCShare);
  2799. }
  2800. /*!--------------------------------------------------------------------------
  2801. RefreshMprConfig
  2802. -
  2803. Author: KennT
  2804. ---------------------------------------------------------------------------*/
  2805. HRESULT RefreshMprConfig(LPCTSTR pszServerName)
  2806. {
  2807. HRESULT hr = hrOK;
  2808. SPMprConfigHandle sphConfig;
  2809. CWRg( ::MprConfigServerConnect((LPWSTR) pszServerName,
  2810. &sphConfig) );
  2811. MprConfigServerRefresh(sphConfig);
  2812. Error:
  2813. return hr;
  2814. }
  2815. HRESULT WINAPI
  2816. IsWindows64Bit( LPCWSTR pwszMachine,
  2817. LPCWSTR pwszUserName,
  2818. LPCWSTR pwszPassword,
  2819. LPCWSTR pwszDomain,
  2820. BOOL * pf64Bit)
  2821. {
  2822. HRESULT hr = S_OK;
  2823. RouterVersionInfo routerVersion;
  2824. IWbemLocator * pIWbemLocator = NULL;
  2825. IWbemServices * pIWbemServices = NULL;
  2826. SEC_WINNT_AUTH_IDENTITY_W stAuthIdentity;
  2827. HKEY hkeyMachine = NULL;
  2828. *pf64Bit = FALSE;
  2829. //Check to see if the version is <= 2195. If yes then there is no 64 bit there...
  2830. if (ERROR_SUCCESS == ConnectRegistry(pwszMachine, &hkeyMachine))
  2831. QueryRouterVersionInfo(hkeyMachine, &routerVersion);
  2832. if (hkeyMachine)
  2833. DisconnectRegistry(hkeyMachine);
  2834. if ( routerVersion.dwOsBuildNo <= RASMAN_PPP_KEY_LAST_WIN2k_VERSION )
  2835. {
  2836. return hr;
  2837. }
  2838. hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
  2839. if (FAILED(hr) && (RPC_E_CHANGED_MODE != hr))
  2840. {
  2841. return hr;
  2842. }
  2843. // Create an instance of the WbemLocator interface.
  2844. hr = CoCreateInstance( CLSID_WbemLocator,
  2845. NULL,
  2846. CLSCTX_INPROC_SERVER,
  2847. IID_IWbemLocator,
  2848. (LPVOID *) &pIWbemLocator
  2849. );
  2850. if (hrOK != hr)
  2851. {
  2852. return hr;
  2853. }
  2854. // Using the locator, connect to CIMOM in the given namespace.
  2855. BSTR pNamespace;
  2856. WCHAR szPath[MAX_PATH];
  2857. WCHAR szTemp[MAX_PATH];
  2858. BSTR bstrUserName = NULL, bstrPassword = NULL, bstrDomain = NULL;
  2859. if ( pwszUserName )
  2860. {
  2861. bstrUserName = SysAllocString(pwszUserName);
  2862. if ( pwszPassword )
  2863. bstrPassword = SysAllocString(pwszPassword);
  2864. if ( pwszDomain )
  2865. {
  2866. wsprintf ( szTemp, L"NTLMDOMAIN:%s", pwszDomain );
  2867. bstrDomain = SysAllocString(szTemp);
  2868. }
  2869. }
  2870. wsprintf(szPath, L"\\\\%s\\root\\cimv2", !pwszMachine ? L"." : pwszMachine);
  2871. pNamespace = SysAllocString(szPath);
  2872. hr = pIWbemLocator->ConnectServer( pNamespace,
  2873. (pwszUserName?bstrUserName:NULL), //UserName
  2874. (pwszPassword?bstrPassword:NULL), //Password
  2875. 0L, // locale
  2876. 0L, // securityFlags
  2877. ( pwszDomain?bstrDomain:NULL), // authority (domain for NTLM)
  2878. NULL, // context
  2879. &pIWbemServices);
  2880. if (SUCCEEDED(hr))
  2881. {
  2882. if ( pwszUserName )
  2883. {
  2884. ZeroMemory ( &stAuthIdentity, sizeof(stAuthIdentity));
  2885. stAuthIdentity.User = (LPWSTR)pwszUserName;
  2886. stAuthIdentity.UserLength = lstrlenW(pwszUserName );
  2887. stAuthIdentity.Password = (LPWSTR)pwszPassword;
  2888. stAuthIdentity.PasswordLength = lstrlenW( pwszPassword );
  2889. if ( pwszDomain )
  2890. {
  2891. stAuthIdentity.Domain = (LPWSTR)pwszDomain;
  2892. stAuthIdentity.DomainLength = lstrlenW(pwszDomain);
  2893. }
  2894. stAuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  2895. }
  2896. hr = CoSetProxyBlanket(pIWbemServices,
  2897. RPC_C_AUTHN_WINNT,
  2898. RPC_C_AUTHZ_NONE,
  2899. NULL,
  2900. RPC_C_AUTHN_LEVEL_CALL,
  2901. RPC_C_IMP_LEVEL_IMPERSONATE,
  2902. (pwszUserName?&stAuthIdentity:NULL),
  2903. EOAC_NONE);
  2904. if (SUCCEEDED(hr))
  2905. {
  2906. IEnumWbemClassObject * pEnum = NULL;
  2907. BSTR bstrWQL = SysAllocString(L"WQL");
  2908. VARIANT varArchitecture;
  2909. BSTR bstrPath;
  2910. bstrPath = SysAllocString(L"select * from Win32_Processor");
  2911. hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
  2912. if (SUCCEEDED(hr))
  2913. {
  2914. hr = CoSetProxyBlanket(pEnum,
  2915. RPC_C_AUTHN_WINNT,
  2916. RPC_C_AUTHZ_NONE,
  2917. NULL,
  2918. RPC_C_AUTHN_LEVEL_CALL,
  2919. RPC_C_IMP_LEVEL_IMPERSONATE,
  2920. (pwszUserName?&stAuthIdentity:NULL),
  2921. EOAC_NONE);
  2922. if ( SUCCEEDED(hr) )
  2923. {
  2924. IWbemClassObject *pNSClass;
  2925. ULONG uReturned;
  2926. pEnum->Next(WBEM_INFINITE, 1, &pNSClass, &uReturned );
  2927. if (SUCCEEDED(hr))
  2928. {
  2929. if (uReturned)
  2930. {
  2931. CIMTYPE ctpeType;
  2932. hr = pNSClass->Get(L"Architecture", NULL, &varArchitecture, &ctpeType, NULL);
  2933. if (SUCCEEDED(hr))
  2934. {
  2935. VariantChangeType(&varArchitecture, &varArchitecture, 0, VT_UINT);
  2936. if ( varArchitecture.uintVal == 6 ) //64 bit
  2937. {
  2938. *pf64Bit = TRUE;
  2939. }
  2940. }
  2941. }
  2942. else
  2943. {
  2944. hr = E_UNEXPECTED;
  2945. }
  2946. pNSClass->Release();
  2947. }
  2948. }
  2949. pEnum->Release();
  2950. }
  2951. SysFreeString(bstrPath);
  2952. SysFreeString(bstrWQL);
  2953. pIWbemServices->Release();
  2954. }
  2955. pIWbemLocator->Release();
  2956. if ( bstrUserName ) SysFreeString(bstrUserName);
  2957. if ( bstrPassword ) SysFreeString(bstrPassword);
  2958. if ( bstrDomain ) SysFreeString(bstrDomain);
  2959. }
  2960. SysFreeString(pNamespace);
  2961. CoUninitialize();
  2962. // Translate any WMI errors into Win32 errors:
  2963. switch (hr)
  2964. {
  2965. case WBEM_E_NOT_FOUND:
  2966. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  2967. break;
  2968. case WBEM_E_ACCESS_DENIED:
  2969. hr = E_ACCESSDENIED;
  2970. break;
  2971. case WBEM_E_PROVIDER_FAILURE:
  2972. hr = E_FAIL;
  2973. break;
  2974. case WBEM_E_TYPE_MISMATCH:
  2975. case WBEM_E_INVALID_CONTEXT:
  2976. case WBEM_E_INVALID_PARAMETER:
  2977. hr = E_INVALIDARG;
  2978. break;
  2979. case WBEM_E_OUT_OF_MEMORY:
  2980. hr = E_OUTOFMEMORY;
  2981. break;
  2982. }
  2983. return hr;
  2984. }
  2985. HRESULT WINAPI TransferCredentials ( IRouterInfo * pRISource,
  2986. IRouterInfo * pRIDest
  2987. )
  2988. {
  2989. HRESULT hr = S_OK;
  2990. SPIRouterAdminAccess spAdminSrc;
  2991. SPIRouterAdminAccess spAdminDest;
  2992. SPIRouterInfo spRISource;
  2993. SPIRouterInfo spRIDest;
  2994. PBYTE pbPassword = NULL;
  2995. int nPasswordLen = 0;
  2996. COM_PROTECT_TRY
  2997. {
  2998. spRISource.Set(pRISource);
  2999. spRIDest.Set(pRIDest);
  3000. spAdminSrc.HrQuery(spRISource);
  3001. spAdminDest.HrQuery(spRIDest);
  3002. if (spAdminSrc && spAdminSrc->IsAdminInfoSet() && spAdminDest)
  3003. {
  3004. spAdminSrc->GetUserPassword(NULL, &nPasswordLen );
  3005. pbPassword = (PBYTE) new BYTE [nPasswordLen];
  3006. spAdminSrc->GetUserPassword( pbPassword, &nPasswordLen );
  3007. spAdminDest->SetInfo( spAdminSrc->GetUserName(),
  3008. spAdminSrc->GetDomainName(),
  3009. pbPassword,
  3010. nPasswordLen
  3011. );
  3012. delete pbPassword;
  3013. }
  3014. }
  3015. COM_PROTECT_CATCH;
  3016. return hr;
  3017. }