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

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