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.

2008 lines
54 KiB

  1. /*
  2. File hnportmapping.c
  3. Definition of the set port mapping functions for intergrating incoming
  4. connection with personal firewall, for whistler bug#123769
  5. Gang Zhao 11/6/2000
  6. */
  7. #include "rassrv.h"
  8. #include "precomp.h"
  9. //When Using CoSetProxyBlanket, we should set both the interface
  10. //and the IUnknown interface queried from it
  11. HRESULT
  12. HnPMSetProxyBlanket (
  13. IUnknown* pUnk)
  14. {
  15. HRESULT hr;
  16. TRACE("HnPMSetProxyBlanket()");
  17. hr = CoSetProxyBlanket (
  18. pUnk,
  19. RPC_C_AUTHN_WINNT, // use NT default security
  20. RPC_C_AUTHZ_NONE, // use NT default authentication
  21. NULL, // must be null if default
  22. RPC_C_AUTHN_LEVEL_CALL, // call
  23. RPC_C_IMP_LEVEL_IMPERSONATE,
  24. NULL, // use process token
  25. EOAC_NONE);
  26. if(SUCCEEDED(hr))
  27. {
  28. IUnknown * pUnkSet = NULL;
  29. hr = IUnknown_QueryInterface(pUnk, &IID_IUnknown, (void**)&pUnkSet);
  30. if(SUCCEEDED(hr))
  31. {
  32. hr = CoSetProxyBlanket (
  33. pUnkSet,
  34. RPC_C_AUTHN_WINNT, // use NT default security
  35. RPC_C_AUTHZ_NONE, // use NT default authentication
  36. NULL, // must be null if default
  37. RPC_C_AUTHN_LEVEL_CALL, // call
  38. RPC_C_IMP_LEVEL_IMPERSONATE,
  39. NULL, // use process token
  40. EOAC_NONE);
  41. if (pUnkSet)
  42. {
  43. IUnknown_Release(pUnk);
  44. }
  45. }
  46. }
  47. return hr;
  48. }
  49. //end of HnPMSetProxyBlanket()
  50. //Initialize function to do COM initialization
  51. //
  52. DWORD
  53. HnPMInit(
  54. IN OUT LPHNPMParams pInfo)
  55. {
  56. HRESULT hr;
  57. DWORD dwErr = NO_ERROR;
  58. TRACE("HnPMInit");
  59. if( !pInfo->fComInitialized )
  60. {
  61. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED|COINIT_DISABLE_OLE1DDE);
  62. if ( RPC_E_CHANGED_MODE == hr )
  63. {
  64. hr = CoInitializeEx (NULL,
  65. COINIT_APARTMENTTHREADED |COINIT_DISABLE_OLE1DDE);
  66. }
  67. if (FAILED(hr))
  68. {
  69. TRACE1("HnPMCfgMgrInit: CoInitializeEx=%x", hr);
  70. pInfo->fCleanupOle = FALSE;
  71. pInfo->fComInitialized = FALSE;
  72. dwErr= HRESULT_CODE(hr);
  73. }
  74. else
  75. {
  76. pInfo->fCleanupOle = TRUE;
  77. pInfo->fComInitialized = TRUE;
  78. }
  79. }
  80. return dwErr;
  81. }//HnPMInit()
  82. //CleanUp function to UnInitialize Com
  83. //If needed
  84. //
  85. DWORD
  86. HnPMCleanUp(
  87. IN OUT LPHNPMParams pInfo)
  88. {
  89. if (pInfo->fCleanupOle)
  90. {
  91. CoUninitialize();
  92. pInfo->fComInitialized = FALSE;
  93. pInfo->fCleanupOle = FALSE;
  94. }
  95. return NO_ERROR;
  96. }//HnPMCleanUp()
  97. //Parameter Validation for pHNetCfgMgr
  98. //
  99. DWORD
  100. HnPMParamsInitParameterCheck(
  101. IN LPHNPMParams pInfo)
  102. {
  103. ASSERT(pInfo->pHNetCfgMgr);
  104. if( !pInfo->pHNetCfgMgr )
  105. {
  106. return ERROR_INVALID_PARAMETER;
  107. }
  108. return NO_ERROR;
  109. }
  110. //Function:
  111. //Initialize some members of HNPMParams structure
  112. //pSettings, pEnumPMP, Read Title for PPTP, L2TP, IKE
  113. //from resource file
  114. //
  115. //Requirements:
  116. //pHNetCfgMgr should be valid
  117. //
  118. HnPMParamsInit(
  119. IN OUT LPHNPMParams pInfo)
  120. {
  121. HRESULT hr;
  122. DWORD dwErr = NO_ERROR;
  123. dwErr = HnPMParamsInitParameterCheck(pInfo);
  124. if ( NO_ERROR != dwErr)
  125. {
  126. TRACE("HnPMParamsInit: HnPMParamsInitParameterCheck failed!");
  127. return dwErr;
  128. }
  129. do{
  130. hr = IHNetCfgMgr_QueryInterface(
  131. pInfo->pHNetCfgMgr,
  132. &IID_IHNetProtocolSettings,
  133. &pInfo->pSettings
  134. );
  135. if (!SUCCEEDED(hr) )
  136. {
  137. TRACE("HnPMParamsInit: IHNetCfgMgr_QueryInterface failed");
  138. dwErr = ERROR_CAN_NOT_COMPLETE;
  139. break;
  140. }
  141. hr = IHNetProtocolSettings_EnumPortMappingProtocols(
  142. pInfo->pSettings,
  143. &pInfo->pEnumPMP
  144. );
  145. if ( !SUCCEEDED( hr ) )
  146. {
  147. TRACE("HnPMParamsInit: IHNetProtocolSettings_EnumPortMappingProotocols failed");
  148. dwErr = ERROR_CAN_NOT_COMPLETE;
  149. break;
  150. }
  151. //Get title, address information from resource
  152. //
  153. {
  154. TCHAR * pszTmp = NULL;
  155. pszTmp = PszFromId(Globals.hInstDll, SID_PPTP_Title);
  156. if(!pszTmp)
  157. {
  158. TRACE("HnPMParamsInit: Get PPTP_Title string failed!");
  159. dwErr = ERROR_CAN_NOT_COMPLETE;
  160. break;
  161. }
  162. pInfo->pwszTitlePPTP = StrDupWFromT(pszTmp);
  163. Free0(pszTmp);
  164. if( !pInfo->pwszTitlePPTP )
  165. {
  166. TRACE("HnPMParamsInit: PPTP_Title string Conversion failed!");
  167. dwErr = ERROR_CAN_NOT_COMPLETE;
  168. break;
  169. }
  170. pszTmp = PszFromId(Globals.hInstDll, SID_L2TP_Title);
  171. if(!pszTmp)
  172. {
  173. TRACE("HnPMParamsInit: Get L2TP_Title string failed!");
  174. dwErr = ERROR_CAN_NOT_COMPLETE;
  175. break;
  176. }
  177. pInfo->pwszTitleL2TP = StrDupWFromT(pszTmp);
  178. Free0(pszTmp);
  179. if( !pInfo->pwszTitleL2TP )
  180. {
  181. TRACE("HnPMParamsInit: L2TP_Title string Conversion failed!");
  182. dwErr = ERROR_CAN_NOT_COMPLETE;
  183. break;
  184. }
  185. pszTmp = PszFromId(Globals.hInstDll, SID_IKE_Title);
  186. if(!pszTmp)
  187. {
  188. TRACE("HnPMParamsInit: Get IKE_Title string failed!");
  189. dwErr = ERROR_CAN_NOT_COMPLETE;
  190. break;
  191. }
  192. pInfo->pwszTitleIKE = StrDupWFromT(pszTmp);
  193. Free0(pszTmp);
  194. if( !pInfo->pwszTitleIKE )
  195. {
  196. TRACE("HnPMParamsInit: IKE_Title string Conversion failed!");
  197. dwErr = ERROR_CAN_NOT_COMPLETE;
  198. break;
  199. }
  200. //for .Net 690343
  201. pszTmp = PszFromId(Globals.hInstDll, SID_NAT_T_Title);
  202. if(!pszTmp)
  203. {
  204. TRACE("HnPMParamsInit: Get IKE_Title string failed!");
  205. dwErr = ERROR_CAN_NOT_COMPLETE;
  206. break;
  207. }
  208. pInfo->pwszTitleNAT_T= StrDupWFromT(pszTmp);
  209. Free0(pszTmp);
  210. if( !pInfo->pwszTitleNAT_T )
  211. {
  212. TRACE("HnPMParamsInit: NAT_T string Conversion failed!");
  213. dwErr = ERROR_CAN_NOT_COMPLETE;
  214. break;
  215. }
  216. pInfo->pszLoopbackAddr = PszFromId(Globals.hInstDll, SID_LoopbackAddr);
  217. if(!pInfo->pszLoopbackAddr)
  218. {
  219. TRACE("HnPMParamsInit: Get IKE_Title string failed!");
  220. dwErr = ERROR_CAN_NOT_COMPLETE;
  221. break;
  222. }
  223. }
  224. }while(FALSE);
  225. return dwErr;
  226. }//HnPMParamsInit()
  227. //Release pEnumPMP, pSettings
  228. //Free memory for titles for PPTP, L2TP, IKE
  229. //if allocated before
  230. //
  231. DWORD
  232. HnPMParamsCleanUp(
  233. IN OUT LPHNPMParams pInfo)
  234. {
  235. if ( pInfo->pEnumPMP )
  236. {
  237. IEnumHNetPortMappingProtocols_Release( pInfo->pEnumPMP );
  238. pInfo->pEnumPMP = NULL;
  239. }
  240. if ( pInfo->pSettings )
  241. {
  242. IHNetProtocolSettings_Release( pInfo->pSettings );
  243. pInfo->pSettings = NULL;
  244. }
  245. if (pInfo->pwszTitlePPTP)
  246. {
  247. Free0(pInfo->pwszTitlePPTP);
  248. pInfo->pwszTitlePPTP = NULL;
  249. }
  250. if (pInfo->pwszTitleL2TP)
  251. {
  252. Free0(pInfo->pwszTitleL2TP);
  253. pInfo->pwszTitleL2TP = NULL;
  254. }
  255. if (pInfo->pwszTitleIKE)
  256. {
  257. Free0(pInfo->pwszTitleIKE);
  258. pInfo->pwszTitleIKE = NULL;
  259. }
  260. // for .net 690343
  261. if (pInfo->pwszTitleNAT_T)
  262. {
  263. Free0(pInfo->pwszTitleNAT_T);
  264. pInfo->pwszTitleNAT_T = NULL;
  265. }
  266. if (pInfo->pszLoopbackAddr)
  267. {
  268. Free0(pInfo->pszLoopbackAddr);
  269. pInfo->pszLoopbackAddr = NULL;
  270. }
  271. return NO_ERROR;
  272. } //HnPMParamsCleanUp()
  273. //Initialization function before Enumerate all connections of
  274. // type (INetConnection * )
  275. //
  276. //Init connection manager ConnMan,
  277. //Init Connection Enumerator EnumCon
  278. //
  279. DWORD
  280. HnPMConnectionEnumInit(
  281. IN LPHNPMParams pInfo)
  282. {
  283. DWORD dwErr = NO_ERROR;
  284. HRESULT hr;
  285. TRACE("HnPMConnectionEnumInit");
  286. do{
  287. //Do Com Initialization
  288. //
  289. dwErr = HnPMInit(pInfo);
  290. if ( NO_ERROR != dwErr )
  291. {
  292. TRACE("HnPMConnectionEnumInit: HnPMCfgMgrInit failed!");
  293. break;
  294. }
  295. // Instantiate the connection manager
  296. //
  297. hr = CoCreateInstance(
  298. &CLSID_ConnectionManager,
  299. NULL,
  300. CLSCTX_SERVER,
  301. &IID_INetConnectionManager,
  302. (PVOID*)&pInfo->ConnMan
  303. );
  304. if (!SUCCEEDED(hr))
  305. {
  306. TRACE1("HnPMConnectionEnumInit: CoCreateInstance=%x", hr);
  307. pInfo->ConnMan = NULL;
  308. dwErr = ERROR_CAN_NOT_COMPLETE;
  309. break;
  310. }
  311. hr = HnPMSetProxyBlanket( (IUnknown*)pInfo->ConnMan );
  312. if (!SUCCEEDED(hr) && ( E_NOINTERFACE != hr ))
  313. {
  314. TRACE1("HnPMConnectionEnumInit: HnPMSetProxyBlanket=%x for ConnMan", hr);
  315. // dwErr = ERROR_CAN_NOT_COMPLETE;
  316. // break;
  317. }
  318. //
  319. // Instantiate a connection-enumerator
  320. //
  321. hr =
  322. INetConnectionManager_EnumConnections(
  323. pInfo->ConnMan,
  324. NCME_DEFAULT,
  325. &pInfo->EnumCon
  326. );
  327. if (!SUCCEEDED(hr))
  328. {
  329. TRACE1("HnPMConnectionEnumInit: EnumConnections=%x", hr);
  330. pInfo->EnumCon = NULL;
  331. dwErr = ERROR_CAN_NOT_COMPLETE;
  332. break;
  333. }
  334. hr = HnPMSetProxyBlanket( (IUnknown*)pInfo->EnumCon );
  335. if (!SUCCEEDED(hr) && ( E_NOINTERFACE != hr ) )
  336. {
  337. TRACE1("HnPMConnectionEnumInit: HnPMSetProxyBlanket=%x for EnumCon", hr);
  338. // dwErr = ERROR_CAN_NOT_COMPLETE;
  339. // break;
  340. }
  341. }
  342. while(FALSE);
  343. return dwErr;
  344. } //HnPMConnectionEnumInit()
  345. //Connection Enumeration CleanUp
  346. //Release EnumCon, and ConnMan
  347. DWORD
  348. HnPMConnectionEnumCleanUp(
  349. IN LPHNPMParams pInfo)
  350. {
  351. TRACE("HnPMConnectionEnumCleanUp");
  352. if (pInfo->EnumCon)
  353. {
  354. IEnumNetConnection_Release(pInfo->EnumCon);
  355. pInfo->EnumCon = NULL;
  356. }
  357. if (pInfo->ConnMan)
  358. {
  359. INetConnectionManager_Release(pInfo->ConnMan);
  360. pInfo->ConnMan = NULL;
  361. }
  362. HnPMCleanUp(pInfo);
  363. return NO_ERROR;
  364. }
  365. //Connection Enumeration function:
  366. //Its Initialize function will do:
  367. // COM initialized if needed
  368. // Init Connection Manager-- ConnMan
  369. // Init Connection Enumerator--EnumCon
  370. //
  371. //It returns: Array of connections found--ConnArray
  372. // Array of connection properties--ConnPropTable
  373. //Its CleanUp function will do:
  374. // COM un-initialize if needed
  375. // Release ConnMan
  376. // Release EnumCon
  377. //
  378. DWORD
  379. HnPMConnectionEnum(
  380. IN LPHNPMParams pInfo)
  381. {
  382. INetConnection * ConnArray[32];
  383. INetConnection ** LocalConnArray = NULL;
  384. NETCON_PROPERTIES * LocalConnPropTable = NULL;
  385. NETCON_PROPERTIES * ConnProps = NULL;
  386. ULONG LocalConnCount = 0, PerConnCount, i;
  387. DWORD dwErr= NO_ERROR;
  388. HRESULT hr;
  389. TRACE("HnPMConnectionEnum() begins");
  390. i = 0;
  391. do {
  392. dwErr = HnPMConnectionEnumInit(pInfo);
  393. if ( NO_ERROR != dwErr )
  394. {
  395. TRACE("HnPMConnectionEnum: HnPMConnectionEnumInit failed!");
  396. break;
  397. }
  398. // Enumerate the connections of INetConnection type
  399. //
  400. for ( ; ; )
  401. {
  402. hr = IEnumNetConnection_Next(
  403. pInfo->EnumCon,
  404. Dimension(ConnArray),
  405. ConnArray,
  406. &PerConnCount
  407. );
  408. if (!SUCCEEDED(hr) || !PerConnCount)
  409. {
  410. hr = S_OK;
  411. break;
  412. }
  413. // Allocate or reallocate the memory for storing
  414. // connections properties which we will return to the caller.
  415. //
  416. TRACE("Allocating memory for LocalConnPropTable");
  417. if (!LocalConnPropTable)
  418. {
  419. LocalConnPropTable =
  420. (NETCON_PROPERTIES*)
  421. GlobalAlloc(
  422. 0,
  423. PerConnCount * sizeof(NETCON_PROPERTIES)
  424. );
  425. }
  426. else
  427. {
  428. PVOID Temp =
  429. GlobalAlloc(
  430. 0,
  431. (LocalConnCount + PerConnCount) * sizeof(NETCON_PROPERTIES) );
  432. if (Temp)
  433. {
  434. CopyMemory(
  435. Temp,
  436. LocalConnPropTable,
  437. LocalConnCount * sizeof(NETCON_PROPERTIES));
  438. }
  439. GlobalFree(LocalConnPropTable);
  440. LocalConnPropTable = Temp;
  441. }
  442. // Allocate or reallocate the memory for storing
  443. // connections which we will return to the caller.
  444. //
  445. TRACE("Allocating memory for LocalConnArray");
  446. if (!LocalConnArray )
  447. {
  448. LocalConnArray =
  449. (INetConnection**) GlobalAlloc( 0,
  450. PerConnCount * sizeof(INetConnection *) );
  451. }
  452. else
  453. {
  454. INetConnection** Temp =
  455. (INetConnection**) GlobalAlloc( 0,
  456. (LocalConnCount + PerConnCount) *
  457. sizeof(INetConnection *));
  458. if (Temp)
  459. {
  460. CopyMemory(
  461. Temp,
  462. LocalConnArray,
  463. LocalConnCount * sizeof(INetConnection *) );
  464. }
  465. GlobalFree(LocalConnArray);
  466. LocalConnArray = Temp;
  467. }
  468. if (!LocalConnPropTable)
  469. {
  470. TRACE("No memory for LocalConnPropTable");
  471. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  472. break;
  473. }
  474. if (!LocalConnArray)
  475. {
  476. TRACE("No memeory for LocalConnArray");
  477. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  478. break;
  479. }
  480. TRACE1("HnPMConnectionEnum: PerConnCount=(%d)",PerConnCount);
  481. for (i=0; i< PerConnCount; i++)
  482. {
  483. LocalConnArray[LocalConnCount+i] = ConnArray[i];
  484. //Need to set up the proxy blanket for each conneciton
  485. //
  486. TRACE1("SetProxyBlanket for (%d) i", i);
  487. hr = HnPMSetProxyBlanket( (IUnknown*)ConnArray[i] );
  488. if (!SUCCEEDED(hr) && ( E_NOINTERFACE != hr ) )
  489. {
  490. TRACE1("HnPMConnectionEnum:HnPMSetProxyBlanket error at (%d) connection!", i );
  491. //Commented out for whistler bug 256921
  492. //dwErr = ERROR_CAN_NOT_COMPLETE;
  493. //break;
  494. }
  495. TRACE1("GetProperty for (%d)",i);
  496. hr = INetConnection_GetProperties(ConnArray[i], &ConnProps);
  497. ASSERT(ConnProps);
  498. if(!SUCCEEDED(hr))
  499. {
  500. TRACE1("HnPMConnectionEnum:INetConnection_GetProperties error at (%d) connection!", i );
  501. dwErr = ERROR_CAN_NOT_COMPLETE;
  502. break;
  503. }
  504. LocalConnPropTable[LocalConnCount+i] = *ConnProps;
  505. LocalConnPropTable[LocalConnCount+i].pszwName =
  506. StrDup(ConnProps->pszwName);
  507. LocalConnPropTable[LocalConnCount+i].pszwDeviceName =
  508. StrDup(ConnProps->pszwDeviceName);
  509. CoTaskMemFree(ConnProps);
  510. ConnProps = NULL;
  511. }
  512. if( dwErr )
  513. {
  514. break;
  515. }
  516. LocalConnCount += PerConnCount;
  517. } // end Enumerate items
  518. //
  519. //Add this line just in case we will add more code in the future
  520. //and to break out of the do...while block
  521. //
  522. if ( dwErr )
  523. {
  524. // For whistler bug 428307
  525. //
  526. if ( LocalConnArray )
  527. {
  528. GlobalFree(LocalConnArray);
  529. }
  530. if ( LocalConnPropTable )
  531. {
  532. GlobalFree(LocalConnPropTable);
  533. }
  534. break;
  535. }
  536. } while (FALSE);
  537. //Save connection Info
  538. if ( NO_ERROR == dwErr )
  539. {
  540. pInfo->ConnPropTable = LocalConnPropTable;
  541. pInfo->ConnArray = LocalConnArray;
  542. pInfo->ConnCount = LocalConnCount;
  543. }
  544. HnPMConnectionEnumCleanUp(pInfo);
  545. TRACE("HnPMConnectionEnum ends");
  546. return dwErr;
  547. }//end of HnPMConnectionEnum()
  548. //Input parameter check for HnPMPickProtocol
  549. //Requirement:
  550. // All the protocol titles are valid
  551. //
  552. DWORD
  553. HnPMPickProtcolParameterCheck(
  554. IN LPHNPMParams pInfo)
  555. {
  556. ASSERT( pInfo->pwszTitlePPTP );
  557. ASSERT( pInfo->pwszTitleL2TP );
  558. ASSERT( pInfo->pwszTitleIKE );
  559. ASSERT( pInfo->pwszTitleNAT_T);
  560. if ( !pInfo->pwszTitlePPTP ||
  561. !pInfo->pwszTitleL2TP ||
  562. !pInfo->pwszTitleIKE ||
  563. !pInfo->pwszTitleNAT_T )
  564. {
  565. return ERROR_INVALID_PARAMETER;
  566. }
  567. return NO_ERROR;
  568. }
  569. //Pick the PortMapping Protocols needed from all
  570. //the PortMapping Protocols founded by HnPMProtocolEnum()
  571. //
  572. //Criteria: Match the---
  573. // Protocol title
  574. // IPProtocol values: TCP 6, UDP 17
  575. // Transport Layer Port number: PPTP--1723
  576. // L2TP--1701
  577. // IKE---500
  578. //
  579. DWORD
  580. HnPMPickProtocol(
  581. IN OUT LPHNPMParams pInfo,
  582. IN IHNetPortMappingProtocol * pProtocolTemp,
  583. IN WCHAR * pszwName,
  584. IN UCHAR uchIPProtocol,
  585. IN USHORT usPort )
  586. {
  587. DWORD dwErr = NO_ERROR;
  588. dwErr = HnPMPickProtcolParameterCheck(pInfo);
  589. if ( NO_ERROR != dwErr )
  590. {
  591. TRACE("HnPMPickProtocol: HnPMPickProtcolParameterCheck failed!");
  592. return dwErr;
  593. }
  594. dwErr = ERROR_CONTINUE;
  595. if ( !pInfo->pProtocolPPTP &&
  596. NAT_PROTOCOL_TCP == uchIPProtocol &&
  597. !lstrcmpW( pszwName, pInfo->pwszTitlePPTP ) &&
  598. 1723 == usPort )
  599. {
  600. pInfo->pProtocolPPTP = pProtocolTemp;
  601. IHNetPortMappingProtocol_AddRef(pInfo->pProtocolPPTP);
  602. dwErr = ERROR_CONTINUE;
  603. }
  604. else if ( !pInfo->pProtocolL2TP &&
  605. NAT_PROTOCOL_UDP == uchIPProtocol &&
  606. !lstrcmpW( pszwName, pInfo->pwszTitleL2TP ) &&
  607. 1701 == usPort )
  608. {
  609. pInfo->pProtocolL2TP = pProtocolTemp;
  610. IHNetPortMappingProtocol_AddRef(pInfo->pProtocolL2TP);
  611. dwErr = ERROR_CONTINUE;
  612. }
  613. else if ( !pInfo->pProtocolIKE &&
  614. NAT_PROTOCOL_UDP == uchIPProtocol &&
  615. !lstrcmpW( pszwName, pInfo->pwszTitleIKE ) &&
  616. 500 == usPort )
  617. {
  618. pInfo->pProtocolIKE = pProtocolTemp;
  619. IHNetPortMappingProtocol_AddRef(pInfo->pProtocolIKE);
  620. dwErr = ERROR_CONTINUE;
  621. }
  622. else if ( !pInfo->pProtocolNAT_T &&
  623. NAT_PROTOCOL_UDP == uchIPProtocol &&
  624. !lstrcmpW( pszwName, pInfo->pwszTitleNAT_T) &&
  625. 4500 == usPort )
  626. {
  627. pInfo->pProtocolNAT_T = pProtocolTemp;
  628. IHNetPortMappingProtocol_AddRef(pInfo->pProtocolNAT_T);
  629. dwErr = ERROR_CONTINUE;
  630. }
  631. if ( pInfo->pProtocolPPTP &&
  632. pInfo->pProtocolL2TP &&
  633. pInfo->pProtocolIKE &&
  634. pInfo->pProtocolNAT_T)
  635. {
  636. dwErr = NO_ERROR;
  637. }
  638. return dwErr;
  639. }//HnPMPickProtocol()
  640. //Parameter check for HnPMPProtocolEnum()
  641. //
  642. DWORD
  643. HnPMPProtoclEnumParameterCheck(
  644. IN LPHNPMParams pInfo)
  645. {
  646. ASSERT(pInfo->pEnumPMP);
  647. if( !pInfo->pEnumPMP )
  648. {
  649. return ERROR_INVALID_PARAMETER;
  650. }
  651. return NO_ERROR;
  652. }
  653. //Function:
  654. // (1) Enumerate all existing PortMappingProtocol
  655. // (2) then use the CallBack function or the defaulet HnPMPickProtocol
  656. // to pick suitable protocols
  657. //
  658. //Requrement:
  659. // pInfo->pEnumPMP is valid
  660. //
  661. DWORD
  662. HnPMProtocolEnum(
  663. IN OUT LPHNPMParams pInfo,
  664. IN PFNHNPMPICKPROTOCOL pfnPickProtocolCallBack
  665. )
  666. {
  667. IHNetPortMappingProtocol *pProtocolTemp = NULL;
  668. ULONG PerProtocolCount;
  669. DWORD dwErr = NO_ERROR;
  670. HRESULT hr;
  671. UCHAR uchIPProtocol;
  672. USHORT usPort;
  673. WCHAR * pszwName = NULL;
  674. dwErr = HnPMPProtoclEnumParameterCheck(pInfo);
  675. if( NO_ERROR != dwErr )
  676. {
  677. TRACE("HnPMPProtocolEnum: HnPMPProtoclEnumParameterCheck failed!");
  678. return dwErr;
  679. }
  680. dwErr = ERROR_CONTINUE;
  681. do {
  682. hr = IEnumHNetPortMappingProtocols_Next(
  683. pInfo->pEnumPMP,
  684. 1,
  685. &pProtocolTemp,
  686. &PerProtocolCount
  687. );
  688. if ( !SUCCEEDED(hr) || 1 != PerProtocolCount )
  689. {
  690. TRACE("HnPMPProtocolEnum: EnumHNetPortMappingProtocols_Next failed");
  691. hr = S_OK;
  692. break;
  693. }
  694. hr = IHNetPortMappingProtocol_GetIPProtocol(
  695. pProtocolTemp,
  696. &uchIPProtocol
  697. );
  698. if (SUCCEEDED(hr) )
  699. {
  700. hr = IHNetPortMappingProtocol_GetPort(
  701. pProtocolTemp,
  702. &usPort
  703. );
  704. }
  705. if ( SUCCEEDED(hr) )
  706. {
  707. hr = IHNetPortMappingProtocol_GetName(
  708. pProtocolTemp,
  709. &pszwName
  710. );
  711. }
  712. if ( SUCCEEDED(hr) )
  713. {
  714. if(pfnPickProtocolCallBack)
  715. {
  716. dwErr = pfnPickProtocolCallBack(
  717. pInfo,
  718. pProtocolTemp,
  719. pszwName,
  720. uchIPProtocol,
  721. ntohs(usPort) );
  722. }
  723. else
  724. {
  725. dwErr = HnPMPickProtocol(
  726. pInfo,
  727. pProtocolTemp,
  728. pszwName,
  729. uchIPProtocol,
  730. ntohs(usPort) );
  731. }
  732. }
  733. if ( pszwName )
  734. {
  735. Free(pszwName);
  736. pszwName = NULL;
  737. }
  738. IHNetPortMappingProtocol_Release(pProtocolTemp);
  739. if ( NO_ERROR == dwErr )
  740. {
  741. break;
  742. }
  743. }while(TRUE);
  744. return dwErr;
  745. }//HnPMProtocolEnum()
  746. DWORD
  747. HnPMCreatePorotocolParameterCheck(
  748. IN LPHNPMParams pInfo)
  749. {
  750. ASSERT( pInfo->pSettings );
  751. ASSERT( pInfo->pwszTitlePPTP );
  752. ASSERT( pInfo->pwszTitleL2TP );
  753. ASSERT( pInfo->pwszTitleIKE );
  754. ASSERT( pInfo->pwszTitleNAT_T);
  755. if ( !pInfo->pSettings ||
  756. !pInfo->pwszTitlePPTP ||
  757. !pInfo->pwszTitleL2TP ||
  758. !pInfo->pwszTitleIKE ||
  759. !pInfo->pwszTitleNAT_T)
  760. {
  761. return ERROR_INVALID_PARAMETER;
  762. }
  763. return NO_ERROR;
  764. }
  765. //Create PortMapping Protocols
  766. //Function:
  767. // If one or more of PPTP, L2TP and IKE PortMapping protocols are not existing
  768. // create the missing ones.
  769. //
  770. //Requirement:
  771. // pSettings is valid
  772. // All the portmapping protocol titles are valid
  773. //
  774. DWORD
  775. HnPMCreateProtocol(
  776. IN OUT LPHNPMParams pInfo)
  777. {
  778. DWORD dwErr=NO_ERROR;
  779. HRESULT hr;
  780. dwErr = HnPMCreatePorotocolParameterCheck(pInfo);
  781. if( NO_ERROR != dwErr )
  782. {
  783. TRACE("HnPMCreateProtocol: HnPMCreatePorotocolParameterCheck failed!");
  784. return dwErr;
  785. }
  786. do {
  787. if ( !pInfo->pProtocolPPTP )
  788. {
  789. //
  790. //Do port Mapping for PPTP
  791. //Get PortMapping protocol
  792. //the tile should be with WCHAR or OLECHAR type
  793. //any numerical values are in network byte order
  794. //and the type of port is USHORT, so I use htons
  795. //here
  796. //
  797. hr = IHNetProtocolSettings_CreatePortMappingProtocol(
  798. pInfo->pSettings,
  799. pInfo->pwszTitlePPTP,
  800. NAT_PROTOCOL_TCP,
  801. htons(1723),
  802. &pInfo->pProtocolPPTP
  803. );
  804. //If the protocol has already been defined, the CreatePortMapping
  805. //above will fail and returns ERROR_OBJECT_ALREADY_EXISTS
  806. //
  807. if ( ERROR_OBJECT_ALREADY_EXISTS == (DWORD) hr )
  808. {
  809. TRACE("HnPMCreateProtocol: The PortMapping for PPTP is already defined");
  810. dwErr = ERROR_CAN_NOT_COMPLETE;
  811. break;
  812. }
  813. if (!SUCCEEDED(hr) )
  814. {
  815. dwErr = ERROR_CAN_NOT_COMPLETE;
  816. break;
  817. }
  818. }// end of assigning PPTP protocol
  819. //Create a new PortMappingProtocol for L2TP
  820. if ( !pInfo->pProtocolL2TP)
  821. {
  822. //
  823. //Do port Mapping for L2TP
  824. //Get PortMapping protocol
  825. //the tile should be with WCHAR or OLECHAR type
  826. //any numerical values are in network byte order
  827. //and the type of port is USHORT, so I use htons
  828. //here
  829. //
  830. hr = IHNetProtocolSettings_CreatePortMappingProtocol(
  831. pInfo->pSettings,
  832. pInfo->pwszTitleL2TP,
  833. NAT_PROTOCOL_UDP,
  834. htons(1701),
  835. &pInfo->pProtocolL2TP
  836. );
  837. //If the protocol has already been defined, the CreatePortMapping
  838. //above will fail and returns ERROR_OBJECT_ALREADY_EXISTS
  839. //
  840. if ( ERROR_OBJECT_ALREADY_EXISTS == (DWORD)hr )
  841. {
  842. TRACE("HnPMCreateProtocol: The PortMapping for L2TP is already defined!");
  843. dwErr = ERROR_CAN_NOT_COMPLETE;
  844. break;
  845. }
  846. if (!SUCCEEDED(hr) )
  847. {
  848. dwErr = ERROR_CAN_NOT_COMPLETE;
  849. break;
  850. }
  851. }// end of assigning L2TP protocol
  852. //Create a new PortMappingProtocol for IKE
  853. if ( !pInfo->pProtocolIKE )
  854. {
  855. //
  856. //Do port Mapping for IKE
  857. //Get PortMapping protocol
  858. //the tile should be with WCHAR or OLECHAR type
  859. //any numerical values are in network byte order
  860. //and the type of port is USHORT, so I use htons
  861. //here
  862. //
  863. hr = IHNetProtocolSettings_CreatePortMappingProtocol(
  864. pInfo->pSettings,
  865. pInfo->pwszTitleIKE,
  866. NAT_PROTOCOL_UDP,
  867. htons(500),
  868. &pInfo->pProtocolIKE
  869. );
  870. //If the protocol has already been defined, the CreatePortMapping
  871. //above will fail and returns ERROR_OBJECT_ALREADY_EXISTS
  872. //
  873. if ( ERROR_OBJECT_ALREADY_EXISTS == (DWORD)hr )
  874. {
  875. TRACE("HnPMCreateProtocol: The PortMapping for IKE is already defined!");
  876. dwErr = ERROR_CAN_NOT_COMPLETE;
  877. break;
  878. }
  879. if (!SUCCEEDED(hr) )
  880. {
  881. dwErr = ERROR_CAN_NOT_COMPLETE;
  882. break;
  883. }
  884. }// end of assigning IKE protocol
  885. // For .Net 690343
  886. //Create a new PortMappingProtocol for IKE NAT-T
  887. if ( !pInfo->pProtocolNAT_T)
  888. {
  889. //
  890. //Do port Mapping for IKE NAT-T
  891. //Get PortMapping protocol
  892. //the tile should be with WCHAR or OLECHAR type
  893. //any numerical values are in network byte order
  894. //and the type of port is USHORT, so I use htons
  895. //here
  896. //
  897. hr = IHNetProtocolSettings_CreatePortMappingProtocol(
  898. pInfo->pSettings,
  899. pInfo->pwszTitleNAT_T,
  900. NAT_PROTOCOL_UDP,
  901. htons(4500),
  902. &pInfo->pProtocolNAT_T
  903. );
  904. //If the protocol has already been defined, the CreatePortMapping
  905. //above will fail and returns ERROR_OBJECT_ALREADY_EXISTS
  906. //
  907. if ( ERROR_OBJECT_ALREADY_EXISTS == (DWORD)hr )
  908. {
  909. TRACE("HnPMCreateProtocol: The PortMapping for NAT-T is already defined!");
  910. dwErr = ERROR_CAN_NOT_COMPLETE;
  911. break;
  912. }
  913. if (!SUCCEEDED(hr) )
  914. {
  915. dwErr = ERROR_CAN_NOT_COMPLETE;
  916. break;
  917. }
  918. }// end of assigning IKE protocol
  919. }while (FALSE);
  920. return dwErr;
  921. } //HnPMCreateProtocol()
  922. //Function: Enable/Disable a single portmapping Protocol on a Single
  923. // Connection of type IHNetConnection
  924. //
  925. DWORD
  926. HnPMSetSinglePMForSingleConnection(
  927. IN IHNetConnection * pHNetConn,
  928. IN IHNetPortMappingProtocol * pProtocol,
  929. IN TCHAR * pszLoopbackAddr,
  930. IN BOOL fEnabled)
  931. {
  932. IHNetPortMappingBinding * pBinding = NULL;
  933. HRESULT hr;
  934. DWORD dwErr = NO_ERROR;
  935. ULONG ulAddress = INADDR_NONE;
  936. do {
  937. hr = IHNetConnection_GetBindingForPortMappingProtocol(
  938. pHNetConn,
  939. pProtocol,
  940. &pBinding
  941. );
  942. if (!SUCCEEDED(hr) )
  943. {
  944. dwErr = ERROR_CAN_NOT_COMPLETE;
  945. break;
  946. }
  947. ulAddress = IpPszToHostAddr( pszLoopbackAddr );
  948. hr = IHNetPortMappingBinding_SetTargetComputerAddress(
  949. pBinding,
  950. htonl(ulAddress)
  951. );
  952. if (!SUCCEEDED(hr) )
  953. {
  954. dwErr = ERROR_CAN_NOT_COMPLETE;
  955. break;
  956. }
  957. hr = IHNetPortMappingBinding_SetEnabled(
  958. pBinding,
  959. !!fEnabled
  960. );
  961. if (!SUCCEEDED(hr) )
  962. {
  963. dwErr = ERROR_CAN_NOT_COMPLETE;
  964. break;
  965. }
  966. } while(FALSE);
  967. if (pBinding)
  968. {
  969. IHNetPortMappingBinding_Release(pBinding);
  970. }
  971. return dwErr;
  972. } //HnPMSetSinglePMForSingleConnection()
  973. DWORD
  974. HnPMConfigureAllPMForSingleConnectionParameterCheck(
  975. IN OUT LPHNPMParams pInfo)
  976. {
  977. ASSERT( pInfo->pHNetConn );
  978. ASSERT( pInfo->pProtocolPPTP );
  979. ASSERT( pInfo->pProtocolL2TP );
  980. ASSERT( pInfo->pProtocolIKE );
  981. ASSERT( pInfo->pProtocolNAT_T);
  982. ASSERT( pInfo->pszLoopbackAddr );
  983. if ( !pInfo->pHNetConn ||
  984. !pInfo->pProtocolPPTP ||
  985. !pInfo->pProtocolL2TP ||
  986. !pInfo->pszLoopbackAddr )
  987. {
  988. return ERROR_INVALID_PARAMETER;
  989. }
  990. return NO_ERROR;
  991. }
  992. //Function:
  993. // Enable/Disable all the PortMapping protocols inside pInfo
  994. // (currently PPTP, L2TP, IKE) on a single connection
  995. //
  996. //Requirement:
  997. // pHNetConn is valid
  998. // All the portmapping protocols inside pInfo are valid
  999. //
  1000. DWORD
  1001. HnPMConfigureAllPMForSingleConnection(
  1002. IN OUT LPHNPMParams pInfo,
  1003. BOOL fEnabled)
  1004. {
  1005. DWORD dwErr = NO_ERROR;
  1006. dwErr = HnPMConfigureAllPMForSingleConnectionParameterCheck(pInfo);
  1007. if( NO_ERROR != dwErr )
  1008. {
  1009. TRACE("HnPMConfigureAllPMForSingleConnection: parameter check failed!");
  1010. return dwErr;
  1011. }
  1012. do{
  1013. dwErr = HnPMSetSinglePMForSingleConnection(
  1014. pInfo->pHNetConn,
  1015. pInfo->pProtocolPPTP,
  1016. pInfo->pszLoopbackAddr,
  1017. fEnabled);
  1018. if( NO_ERROR != dwErr )
  1019. {
  1020. TRACE("HnPMConfigureAllPMForSingleConnection: PortMapping failed for PPTP!");
  1021. break;
  1022. }
  1023. dwErr = HnPMSetSinglePMForSingleConnection(
  1024. pInfo->pHNetConn,
  1025. pInfo->pProtocolL2TP,
  1026. pInfo->pszLoopbackAddr,
  1027. fEnabled);
  1028. if( NO_ERROR != dwErr )
  1029. {
  1030. TRACE("HnPMConfigureAllPMForSingleConnection: PortMapping failed for L2TP!");
  1031. break;
  1032. }
  1033. dwErr = HnPMSetSinglePMForSingleConnection(
  1034. pInfo->pHNetConn,
  1035. pInfo->pProtocolIKE,
  1036. pInfo->pszLoopbackAddr,
  1037. fEnabled);
  1038. if( NO_ERROR != dwErr )
  1039. {
  1040. TRACE("HnPMConfigureAllPMForSingleConnection: PortMapping failed for IKE!");
  1041. break;
  1042. }
  1043. // For .Net 690343
  1044. dwErr = HnPMSetSinglePMForSingleConnection(
  1045. pInfo->pHNetConn,
  1046. pInfo->pProtocolNAT_T,
  1047. pInfo->pszLoopbackAddr,
  1048. fEnabled);
  1049. if( NO_ERROR != dwErr )
  1050. {
  1051. TRACE("HnPMConfigureAllPMForSingleConnection: PortMapping failed for NAT-T!");
  1052. break;
  1053. }
  1054. } while(FALSE);
  1055. return dwErr;
  1056. } //HnPMConfigureAllPMForSingleConnection()
  1057. //Make sure:
  1058. // pHNetCfgMgr is valid
  1059. // one and only one of pNetConnection and pGuid is valid
  1060. //
  1061. DWORD
  1062. HnPMConfigureSingleConnectionInitParameterCheck(
  1063. IN LPHNPMParams pInfo )
  1064. {
  1065. ASSERT( pInfo->pHNetCfgMgr );
  1066. ASSERT( pInfo->pNetConnection || pInfo->pGuid );
  1067. if ( !pInfo->pHNetCfgMgr ||
  1068. ( !pInfo->pNetConnection && !pInfo->pGuid ) ||
  1069. ( pInfo->pNetConnection && pInfo->pGuid ) )
  1070. {
  1071. return ERROR_INVALID_PARAMETER;
  1072. }
  1073. return NO_ERROR;
  1074. }//HnPMConfigureSingleConnectionInitParameterCheck()
  1075. // (1) Call Parameter checking function
  1076. // pHNetCfgMgr is valid
  1077. // one and only one of pNetConnection and pGuid is valid
  1078. //
  1079. // (2) init pHNetConn by converting from pNetConnection or pGuid
  1080. //
  1081. // (3) call HnPMParamsInit()
  1082. // Initialize some members of HNPMParams structure
  1083. // pSettings, pEnumPMP, Read Title for PPTP, L2TP, IKE
  1084. // from resource file
  1085. //
  1086. DWORD
  1087. HnPMConfigureSingleConnectionInit(
  1088. IN OUT LPHNPMParams pInfo)
  1089. {
  1090. DWORD dwErr = NO_ERROR;
  1091. HRESULT hr;
  1092. dwErr = HnPMConfigureSingleConnectionInitParameterCheck(pInfo);
  1093. if ( NO_ERROR != dwErr )
  1094. {
  1095. return dwErr;
  1096. }
  1097. do {
  1098. if ( pInfo->pNetConnection )
  1099. {
  1100. hr = IHNetCfgMgr_GetIHNetConnectionForINetConnection(
  1101. pInfo->pHNetCfgMgr,
  1102. pInfo->pNetConnection,
  1103. &pInfo->pHNetConn
  1104. );
  1105. if (!SUCCEEDED(hr) )
  1106. {
  1107. TRACE("HnPMConfigureSingleConnection: GetIHNetConnectionForINetConnection failed");
  1108. dwErr = ERROR_CAN_NOT_COMPLETE;
  1109. break;
  1110. }
  1111. }
  1112. else
  1113. {
  1114. hr = IHNetCfgMgr_GetIHNetConnectionForGuid(
  1115. pInfo->pHNetCfgMgr,
  1116. pInfo->pGuid,
  1117. FALSE,//This is not for Lan Connection
  1118. TRUE, //This should always be TRUE
  1119. &pInfo->pHNetConn
  1120. );
  1121. if (!SUCCEEDED(hr) )
  1122. {
  1123. TRACE("HnPMConfigureSingleConnection: GetIHNetConnectionForGuid failed");
  1124. dwErr = ERROR_CAN_NOT_COMPLETE;
  1125. break;
  1126. }
  1127. }
  1128. dwErr = HnPMParamsInit(pInfo);
  1129. }while(FALSE);
  1130. return dwErr;
  1131. } //HnPMConfigureSingleConnectionInit()
  1132. // (1) Release all PortMapping Protocols
  1133. // (2) release the connection just configured
  1134. // (3) call HnPMParamsCleanUp()
  1135. // Release pEnumPMP, pSettings
  1136. // Free memory for titles for PPTP, L2TP, IKE if allocated before
  1137. //
  1138. DWORD
  1139. HnPMConfigureSingleConnectionCleanUp(
  1140. IN OUT LPHNPMParams pInfo)
  1141. {
  1142. if ( pInfo->pProtocolPPTP )
  1143. {
  1144. IHNetPortMappingProtocol_Release( pInfo->pProtocolPPTP );
  1145. pInfo->pProtocolPPTP = NULL;
  1146. }
  1147. if ( pInfo->pProtocolL2TP )
  1148. {
  1149. IHNetPortMappingProtocol_Release( pInfo->pProtocolL2TP );
  1150. pInfo->pProtocolL2TP = NULL;
  1151. }
  1152. if ( pInfo->pHNetConn )
  1153. {
  1154. IHNetConnection_Release( pInfo->pHNetConn );
  1155. pInfo->pHNetConn = NULL;
  1156. }
  1157. if ( pInfo->pProtocolIKE )
  1158. {
  1159. IHNetPortMappingProtocol_Release( pInfo->pProtocolIKE );
  1160. pInfo->pProtocolIKE = NULL;
  1161. }
  1162. // For .Net 690343
  1163. if ( pInfo->pProtocolNAT_T)
  1164. {
  1165. IHNetPortMappingProtocol_Release( pInfo->pProtocolNAT_T );
  1166. pInfo->pProtocolNAT_T = NULL;
  1167. }
  1168. HnPMParamsCleanUp(pInfo);
  1169. return NO_ERROR;
  1170. }//HnPMConfigureSingleConnectionCleanUp
  1171. //Function:
  1172. // Enable/Disable PortMappping(PPTP, L2TP, IKE) on a single connection
  1173. //Step:
  1174. // (1) Initialization
  1175. // (2) Enumerate all existing portmapping protocols
  1176. // (3) Pick PPTP, L2TP, IKE from them
  1177. // (4) If not all of them exist, Create the missing ones
  1178. // (5) Configure each protocol on this connection
  1179. //
  1180. DWORD
  1181. HnPMConfigureSingleConnection(
  1182. IN OUT LPHNPMParams pInfo,
  1183. BOOL fEnabled)
  1184. {
  1185. DWORD dwErr = NO_ERROR;
  1186. do{
  1187. //Init the value needed in this function
  1188. //
  1189. dwErr = HnPMConfigureSingleConnectionInit(pInfo);
  1190. if( NO_ERROR != dwErr )
  1191. {
  1192. TRACE("HnPMConfigureSingleConnection: Init failed!");
  1193. break;
  1194. }
  1195. //Enumerate all PortMapping Protocls and
  1196. //pick the PPTP, L2TP, IKE, NAT-T from them
  1197. //
  1198. dwErr = HnPMProtocolEnum(pInfo, HnPMPickProtocol);
  1199. //Create a new PortMappingProtocol for PPTP
  1200. //if didnt find the PPTP protocl and it is to
  1201. //Enable it
  1202. //
  1203. if ( NO_ERROR != dwErr )
  1204. {
  1205. dwErr = HnPMCreateProtocol(pInfo);
  1206. }
  1207. if ( NO_ERROR != dwErr )
  1208. {
  1209. TRACE("HnPMConfigureSingleConnection: HnPMCreateProtocol failed!");
  1210. break;
  1211. }
  1212. dwErr = HnPMConfigureAllPMForSingleConnection(pInfo, fEnabled);
  1213. if ( NO_ERROR != dwErr )
  1214. {
  1215. TRACE("HnPMConfigureSingleConnection: HnPMConfigureAllPMForSingleConnection failed!");
  1216. break;
  1217. }
  1218. }
  1219. while( FALSE );
  1220. //clean up the structure changed in this function
  1221. //
  1222. HnPMConfigureSingleConnectionCleanUp(pInfo);
  1223. return dwErr;
  1224. } //HnPMConfigureSingleConnection()
  1225. DWORD
  1226. HnPMDeletePortMappingInit(
  1227. IN OUT LPHNPMParams pInfo)
  1228. {
  1229. HRESULT hr;
  1230. DWORD dwErr = NO_ERROR;
  1231. do{
  1232. dwErr = HnPMCfgMgrInit(pInfo);
  1233. if ( NO_ERROR != dwErr )
  1234. {
  1235. TRACE("HnPMDeletePortMappingInit: HnPMCfgMgrInit failed!");
  1236. break;
  1237. }
  1238. dwErr = HnPMParamsInit(pInfo);
  1239. }while(FALSE);
  1240. return dwErr;
  1241. } //HnPMDeletePortMappingInit()
  1242. DWORD
  1243. HnPMDeletePortMappingCleanUp(
  1244. IN OUT LPHNPMParams pInfo)
  1245. {
  1246. HnPMParamsCleanUp(pInfo);
  1247. HnPMCfgMgrCleanUp(pInfo);
  1248. return NO_ERROR;
  1249. }
  1250. //Function:
  1251. // Delete the PortMapping Protocols (PPTP, L2TP, IKE)
  1252. //Step:
  1253. // (1)Initialization:
  1254. // Get all the protocol names, IP protocol number,
  1255. // Transport Layer port number (PPTP: TCP/1723
  1256. // L2TP:UDP/1701, IKE (UDP:500)
  1257. // (2)Enumerate all existing portmapping protocols
  1258. // (3) Pick the protocols to delete and store them in pInfo
  1259. // (4) delete protocols
  1260. //
  1261. DWORD
  1262. HnPMDeletePortMapping()
  1263. {
  1264. HNPMParams Info;
  1265. LPHNPMParams pInfo;
  1266. DWORD dwErr;
  1267. HRESULT hr;
  1268. dwErr = NO_ERROR;
  1269. ZeroMemory(&Info, sizeof(Info) );
  1270. pInfo = &Info;
  1271. do{
  1272. dwErr = HnPMDeletePortMappingInit(pInfo);
  1273. if (NO_ERROR != dwErr)
  1274. {
  1275. TRACE("HnPMDeletePortMapping: HnPMDeletePortMappingInit failed!");
  1276. break;
  1277. }
  1278. //Enumerate all PortMapping Protocls and
  1279. //pick the PPTP, L2TP, IKE from them
  1280. //
  1281. dwErr = HnPMProtocolEnum(pInfo, HnPMPickProtocol);
  1282. if (NO_ERROR != dwErr)
  1283. {
  1284. TRACE("HnPMDeletePortMapping: HnPMProtocolEnum failed!");
  1285. break;
  1286. }
  1287. //Delete All Port Mapping protocols
  1288. if ( pInfo->pProtocolPPTP )
  1289. {
  1290. hr = IHNetPortMappingProtocol_Delete( pInfo->pProtocolPPTP );
  1291. pInfo->pProtocolPPTP = NULL;
  1292. ASSERT(SUCCEEDED(hr));
  1293. if (!SUCCEEDED(hr))
  1294. {
  1295. TRACE1("HnPMDeletePortMapping: delete PPTP portmaping failed = %x!", hr);
  1296. }
  1297. }
  1298. if ( pInfo->pProtocolL2TP )
  1299. {
  1300. hr = IHNetPortMappingProtocol_Delete( pInfo->pProtocolL2TP );
  1301. pInfo->pProtocolL2TP = NULL;
  1302. ASSERT(SUCCEEDED(hr));
  1303. if (!SUCCEEDED(hr))
  1304. {
  1305. TRACE1("HnPMDeletePortMapping: delete L2TP portmaping failed = %x!", hr);
  1306. }
  1307. }
  1308. if ( pInfo->pProtocolIKE )
  1309. {
  1310. hr = IHNetPortMappingProtocol_Delete( pInfo->pProtocolIKE );
  1311. pInfo->pProtocolIKE = NULL;
  1312. ASSERT(SUCCEEDED(hr));
  1313. if (!SUCCEEDED(hr))
  1314. {
  1315. TRACE1("HnPMDeletePortMapping: delete IKE portmaping failed = %x!", hr);
  1316. }
  1317. }
  1318. // For .Net 690343
  1319. if ( pInfo->pProtocolNAT_T)
  1320. {
  1321. hr = IHNetPortMappingProtocol_Delete( pInfo->pProtocolNAT_T );
  1322. pInfo->pProtocolNAT_T = NULL;
  1323. ASSERT(SUCCEEDED(hr));
  1324. if (!SUCCEEDED(hr))
  1325. {
  1326. TRACE1("HnPMDeletePortMapping: delete NAT-T portmaping failed = %x!", hr);
  1327. }
  1328. }
  1329. }while(FALSE);
  1330. HnPMDeletePortMappingCleanUp(pInfo);
  1331. return dwErr;
  1332. }//DeletePortMapping()
  1333. DWORD
  1334. HnPMConfigureAllConnectionsInit(
  1335. IN OUT LPHNPMParams pInfo)
  1336. {
  1337. DWORD dwErr = NO_ERROR;
  1338. dwErr = HnPMCfgMgrInit(pInfo);
  1339. return NO_ERROR;
  1340. }
  1341. DWORD
  1342. HnPMParamsConnectionCleanUp(
  1343. IN OUT LPHNPMParams pInfo)
  1344. {
  1345. DWORD i;
  1346. if ( pInfo->ConnArray )
  1347. {
  1348. for ( i = 0; i < pInfo->ConnCount; i++ )
  1349. {
  1350. INetConnection_Release(pInfo->ConnArray[i]);
  1351. }
  1352. GlobalFree( pInfo->ConnArray );
  1353. pInfo->ConnArray = NULL;
  1354. }
  1355. if ( pInfo->ConnPropTable )
  1356. {
  1357. for ( i = 0; i < pInfo->ConnCount; i++ )
  1358. {
  1359. Free0(pInfo->ConnPropTable[i].pszwName);
  1360. pInfo->ConnPropTable[i].pszwName = NULL;
  1361. Free0(pInfo->ConnPropTable[i].pszwDeviceName);
  1362. pInfo->ConnPropTable[i].pszwDeviceName = NULL;
  1363. }
  1364. GlobalFree( pInfo->ConnPropTable );
  1365. pInfo->ConnPropTable = NULL;
  1366. pInfo->ConnCount = 0;
  1367. }
  1368. return NO_ERROR;
  1369. }//HnPMParamsConnectionCleanUp()
  1370. DWORD
  1371. HnPMConfigureAllConnectionsCleanUp(
  1372. IN OUT LPHNPMParams pInfo)
  1373. {
  1374. HnPMParamsConnectionCleanUp(pInfo);
  1375. HnPMCfgMgrCleanUp(pInfo);
  1376. return NO_ERROR;
  1377. }
  1378. // Enable/Disable portmapping on all connections except incoming connection
  1379. // PortMapping protocols: PPTP, L2TP, IKE
  1380. // If there are no such protocols, create them first
  1381. // Steps:
  1382. // (1) Initialization
  1383. // (2) Enumerate all connections of type INetConnection *
  1384. // (3) If it is not an incomming connection set the portmapping protocols
  1385. // on it.
  1386. DWORD
  1387. HnPMConfigureAllConnections(
  1388. IN BOOL fEnabled )
  1389. {
  1390. DWORD dwErr = NO_ERROR, i;
  1391. HNPMParams Info;
  1392. LPHNPMParams pInfo;
  1393. static const CLSID CLSID_InboundConnection=
  1394. {0xBA126AD9,0x2166,0x11D1,{0xB1,0xD0,0x00,0x80,0x5F,0xC1,0x27,0x0E}};
  1395. TRACE1("HnPMConfigureAllConnections: fEnabled = %d", fEnabled);
  1396. TRACE1("%s", fEnabled ? "Enable PortMaping on all connections." :
  1397. "Diable PortMaping on all connections.");
  1398. ZeroMemory(&Info, sizeof(Info));
  1399. pInfo = &Info;
  1400. do {
  1401. dwErr = HnPMConfigureAllConnectionsInit(pInfo);
  1402. if( NO_ERROR != dwErr )
  1403. {
  1404. TRACE("HnPMConfigureAllConnections: Init failed!");
  1405. break;
  1406. }
  1407. //Get All Connections
  1408. //
  1409. dwErr = HnPMConnectionEnum(pInfo);
  1410. if ( NO_ERROR != dwErr )
  1411. {
  1412. TRACE("HnPMConfigureAllConnections: HnPMConnectionEnum() failed!");
  1413. break;
  1414. }
  1415. TRACE1("HnPMConfigureAllConnections: %l Connections detected", pInfo->ConnCount);
  1416. //Set up PortMapping for each connection
  1417. //
  1418. for ( i = 0; i < pInfo->ConnCount; i++ )
  1419. {
  1420. //won't do PortMapping for Incoming connections
  1421. //
  1422. if ( pInfo->ConnPropTable )
  1423. {
  1424. //define the class id for Incoming connections
  1425. // reference to /nt/net/config/shell/wanui/rasui.cpp
  1426. if( IsEqualCLSID(
  1427. &CLSID_InboundConnection,
  1428. &(pInfo->ConnPropTable[i].clsidThisObject) ) )
  1429. {
  1430. continue;
  1431. }
  1432. }
  1433. pInfo->pNetConnection = pInfo->ConnArray[i];
  1434. if ( NO_ERROR != HnPMConfigureSingleConnection(pInfo, fEnabled) )
  1435. {
  1436. TRACE1("HnPMConfigureAllConnections: HnPMConfigureSingleConnection failed for %lth connection",i);
  1437. }
  1438. }
  1439. }
  1440. while (FALSE);
  1441. //Clean Up
  1442. //
  1443. HnPMConfigureAllConnectionsCleanUp(pInfo);
  1444. return dwErr;
  1445. }//end of HnPMConfigureAllConnections()
  1446. // do the COM initialization and create pHNetCfgMgr
  1447. DWORD
  1448. HnPMCfgMgrInit(
  1449. IN OUT LPHNPMParams pInfo)
  1450. {
  1451. HRESULT hr;
  1452. DWORD dwErr = NO_ERROR;
  1453. do{
  1454. dwErr = HnPMInit(pInfo);
  1455. if (NO_ERROR != dwErr )
  1456. {
  1457. TRACE("HnPMCfgMgrInit: HnPMInit failed!");
  1458. break;
  1459. }
  1460. hr = CoCreateInstance(
  1461. &CLSID_HNetCfgMgr,
  1462. NULL,
  1463. CLSCTX_ALL,
  1464. &IID_IHNetCfgMgr,
  1465. (VOID**) &pInfo->pHNetCfgMgr
  1466. );
  1467. if ( !SUCCEEDED(hr) )
  1468. {
  1469. TRACE("HnPMCfgMgrInit: CoCreateInstance failed");
  1470. dwErr = ERROR_CAN_NOT_COMPLETE;
  1471. break;
  1472. }
  1473. }while(FALSE);
  1474. return dwErr;
  1475. }//HnPMCfgMgrInit()
  1476. DWORD
  1477. HnPMCfgMgrCleanUp(
  1478. IN OUT LPHNPMParams pInfo)
  1479. {
  1480. if ( pInfo->pHNetCfgMgr )
  1481. {
  1482. IHNetCfgMgr_Release(pInfo->pHNetCfgMgr);
  1483. pInfo->pHNetCfgMgr = NULL;
  1484. }
  1485. HnPMCleanUp(pInfo);
  1486. return NO_ERROR;
  1487. }
  1488. DWORD
  1489. HnPMConfigureSingleConnectionGUIDInit(
  1490. IN OUT LPHNPMParams pInfo,
  1491. GUID * pGuid)
  1492. {
  1493. DWORD dwErr = NO_ERROR;
  1494. do{
  1495. dwErr = HnPMCfgMgrInit(pInfo);
  1496. if ( NO_ERROR != dwErr )
  1497. {
  1498. dwErr = ERROR_CAN_NOT_COMPLETE;
  1499. break;
  1500. }
  1501. //Use Guid to indentify the connection
  1502. pInfo->pGuid = pGuid;
  1503. pInfo->pNetConnection = NULL;
  1504. }while(FALSE);
  1505. return dwErr;
  1506. }
  1507. DWORD
  1508. HnPMConfigureSingleConnectionGUIDCleanUp(
  1509. IN OUT LPHNPMParams pInfo)
  1510. {
  1511. pInfo->pGuid = NULL;
  1512. pInfo->pNetConnection = NULL;
  1513. HnPMCfgMgrCleanUp(pInfo);
  1514. return NO_ERROR;
  1515. }
  1516. //Setup PortMapping protocols on a single connection
  1517. //represented by its GUID
  1518. //
  1519. DWORD
  1520. HnPMConfigureSingleConnectionGUID(
  1521. IN GUID * pGuid,
  1522. IN BOOL fEnabled)
  1523. {
  1524. HNPMParams Info;
  1525. LPHNPMParams pInfo;
  1526. DWORD dwErr = NO_ERROR;
  1527. TRACE1("HnPMConfigureSingleConnectionGUID: fEnabled = %d", fEnabled);
  1528. TRACE1("%s", fEnabled ? "Enable PortMapping on this Connection" :
  1529. "Diable PortMapping on this Connection");
  1530. ASSERT( pGuid );
  1531. if ( !pGuid )
  1532. {
  1533. return ERROR_INVALID_PARAMETER;
  1534. }
  1535. ZeroMemory(&Info, sizeof(Info) );
  1536. pInfo = &Info;
  1537. dwErr = NO_ERROR;
  1538. do{
  1539. dwErr = HnPMConfigureSingleConnectionGUIDInit(pInfo, pGuid);
  1540. if (NO_ERROR != dwErr)
  1541. {
  1542. TRACE("HnPMConfigureSingleConnectionGUID: Init failed!");
  1543. break;
  1544. }
  1545. dwErr = HnPMConfigureSingleConnection(pInfo, fEnabled);
  1546. if ( NO_ERROR != dwErr )
  1547. {
  1548. TRACE("HnPMConfigureSingleConnectionGUID: SetPortMappingForSingleConnection failed ");
  1549. break;
  1550. }
  1551. }
  1552. while (FALSE);
  1553. HnPMConfigureSingleConnectionGUIDCleanUp(pInfo);
  1554. return dwErr;
  1555. }//HnPMConfigureSingleConnectionGUID()
  1556. //Set up the port mapping for only one
  1557. //connection according to its GUID only when
  1558. //Incoming Connection exists and
  1559. //the VPN is enabled
  1560. //
  1561. DWORD
  1562. HnPMConfigureSingleConnectionGUIDIfVpnEnabled(
  1563. GUID* pGuid,
  1564. BOOL fDual,
  1565. HANDLE hDatabase)
  1566. {
  1567. HANDLE hDevDatabase = NULL;
  1568. DWORD dwErr;
  1569. BOOL fEnabled = FALSE;
  1570. dwErr = NO_ERROR;
  1571. do
  1572. {
  1573. // Get handles to the databases we're interested in
  1574. //
  1575. if ( !hDatabase )
  1576. {
  1577. dwErr = devOpenDatabase( &hDevDatabase );
  1578. if ( NO_ERROR != dwErr )
  1579. {
  1580. TRACE("HnPMConfigureSingleConnectionGUIDIfVpnEnabled: devOpenDatabase failed!");
  1581. break;
  1582. }
  1583. }
  1584. else
  1585. {
  1586. hDevDatabase = hDatabase;
  1587. }
  1588. dwErr = devGetVpnEnable(hDevDatabase, &fEnabled );
  1589. if ( NO_ERROR != dwErr )
  1590. {
  1591. TRACE("HnPMConfigureSingleConnectionGUIDIfVpnEnabled: devGetVpnEnable failed!");
  1592. break;
  1593. }
  1594. //if fDual == TRUE, can disable/enable the portmapping
  1595. //according to if VPN is enabled or not
  1596. //otherwise, dont do anything if VPN is not enabled.
  1597. if ( !fEnabled && !fDual)
  1598. {
  1599. dwErr = NO_ERROR;
  1600. break;
  1601. }
  1602. dwErr = HnPMConfigureSingleConnectionGUID( pGuid, fEnabled );
  1603. if ( NO_ERROR != dwErr )
  1604. {
  1605. TRACE("HnPMConfigureSingleConnectionGUIDIfVpnEnabled: HnPMConfigureSingleConnectionGUID failed!");
  1606. break;
  1607. }
  1608. }
  1609. while (FALSE);
  1610. if ( !hDatabase && hDevDatabase )
  1611. {
  1612. devCloseDatabase( hDevDatabase );
  1613. }
  1614. return dwErr;
  1615. }//HnPMConfigureSingleConnectionGUIDIfVpnEnabled()
  1616. //whistler bug 123769,
  1617. //when Incoming Connection is running
  1618. //if VPN enabled, go to set up port mapping
  1619. //
  1620. DWORD
  1621. HnPMConfigureIfVpnEnabled(
  1622. BOOL fDual,
  1623. HANDLE hDatabase)
  1624. {
  1625. HANDLE hDevDatabase = NULL;
  1626. DWORD dwErr;
  1627. BOOL fEnabled = FALSE;
  1628. dwErr = NO_ERROR;
  1629. do
  1630. {
  1631. // Get handles to the databases we're interested in
  1632. //
  1633. if ( !hDatabase )
  1634. {
  1635. dwErr = devOpenDatabase( &hDevDatabase );
  1636. if ( NO_ERROR != dwErr )
  1637. {
  1638. TRACE("HnPMConfigureIfVpnEnabled: devOpenDatabase failed!");
  1639. break;
  1640. }
  1641. }
  1642. else
  1643. {
  1644. hDevDatabase = hDatabase;
  1645. }
  1646. dwErr = devGetVpnEnable(hDevDatabase, &fEnabled );
  1647. if ( NO_ERROR != dwErr )
  1648. {
  1649. TRACE("HnPMConfigureIfVpnEnabled: devGetVpnEnable failed!");
  1650. break;
  1651. }
  1652. //if fDual == TRUE, can disable/enable the portmapping
  1653. //according to if VPN is enabled or not
  1654. //otherwise, dont do anything if VPN is not enabled.
  1655. if ( !fEnabled && !fDual)
  1656. {
  1657. dwErr = NO_ERROR;
  1658. break;
  1659. }
  1660. dwErr = HnPMConfigureAllConnections( fEnabled );
  1661. if ( NO_ERROR != dwErr )
  1662. {
  1663. TRACE("HnPMConfigureIfVpnEnabled: SetPortMapingForICVpn failed!");
  1664. break;
  1665. }
  1666. }
  1667. while (FALSE);
  1668. if ( !hDatabase && hDevDatabase )
  1669. {
  1670. devCloseDatabase( hDevDatabase );
  1671. }
  1672. return dwErr;
  1673. }//End of HnPMConfigureIfVpnEnabled()