Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

914 lines
31 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // File: N A M I N G . C P P
  7. //
  8. // Contents: Generates Connection Names Automatically
  9. //
  10. // Notes:
  11. //
  12. // Author: deonb 27 Feb 2001
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ncnetcfg.h"
  18. #include "netcon.h"
  19. #include "netconp.h"
  20. #include <ntddndis.h>
  21. #include <ndisprv.h>
  22. #include <devioctl.h>
  23. #include <ndispnp.h>
  24. #include "naming.h"
  25. extern const WCHAR c_szBiNdisAtm[];
  26. extern const WCHAR c_szInfId_MS_AtmElan[];
  27. const WCHAR c_szDevice[] = L"\\DEVICE\\";
  28. //+---------------------------------------------------------------------------
  29. //
  30. // Function: CIntelliName::CIntelliName
  31. //
  32. // Purpose: Constructor
  33. //
  34. // Arguments:
  35. // hInstance [in] Resource instance of binary with naming.rc included
  36. //
  37. // pFNDuplicateNameCheck [in] Callback function of duplicate check. Can be NULL \
  38. // or otherwise of the following callback type:
  39. // + typedef BOOL FNDuplicateNameCheck
  40. // + pIntelliName [in] CIntelliName this pointer (for HrGetPseudoMediaTypes callback)
  41. // + szName [in] Name to check for
  42. // + pncm [out] NetCon Media Type of conflicting connection
  43. // + pncms [out] NetCon SubMedia Type of conflicting connection
  44. // + return TRUE - if conflicting found or FALSE if no conflicting connection found
  45. //
  46. // Returns: None
  47. //
  48. // Author: deonb 27 Feb 2001
  49. //
  50. // Notes:
  51. //
  52. CIntelliName::CIntelliName(HINSTANCE hInstance, FNDuplicateNameCheck *pFNDuplicateNameCheck)
  53. {
  54. m_pFNDuplicateNameCheck = pFNDuplicateNameCheck;
  55. m_hInstance = hInstance;
  56. }
  57. //+---------------------------------------------------------------------------
  58. //
  59. // Function: CIntelliName::NameExists
  60. //
  61. // Purpose: Check if a name already exists
  62. //
  63. // Arguments:
  64. // szName [in] Name to check for
  65. // pncm [out] NetCon Media Type of conflicting connection
  66. // pncms [out] NetCon SubMedia Type of conflicting connection
  67. //
  68. // Returns: TRUE if exists, FALSE if not
  69. //
  70. // Author: deonb 27 Feb 2001
  71. //
  72. // Notes:
  73. //
  74. BOOL CIntelliName::NameExists(IN LPCWSTR szName, IN OUT NETCON_MEDIATYPE *pncm, IN NETCON_SUBMEDIATYPE *pncms)
  75. {
  76. if (m_pFNDuplicateNameCheck)
  77. {
  78. Assert(pncm);
  79. Assert(pncms);
  80. if (IsReservedName(szName))
  81. {
  82. return TRUE;
  83. }
  84. return (*m_pFNDuplicateNameCheck)(this, szName, pncm, pncms);
  85. }
  86. return FALSE;
  87. }
  88. //+---------------------------------------------------------------------------
  89. //
  90. // Function: CIntelliName::IsReservedName
  91. //
  92. // Purpose: Check if a name is a reserved name
  93. //
  94. // Arguments:
  95. // szName [in] Name to check for
  96. //
  97. // Returns: TRUE if reserved, FALSE if not
  98. //
  99. // Author: deonb 12 Mar 2001
  100. //
  101. // Notes:
  102. //
  103. BOOL CIntelliName::IsReservedName(LPCWSTR szName)
  104. {
  105. UINT uiReservedNames[] = {IDS_RESERVED_INCOMING,
  106. IDS_RESERVED_NCW,
  107. IDS_RESERVED_HNW};
  108. for (int x = 0; x < celems(uiReservedNames); x++)
  109. {
  110. WCHAR szReservedName[MAX_PATH];
  111. int nSiz = LoadString (m_hInstance, uiReservedNames[x], szReservedName, MAX_PATH);
  112. if (nSiz)
  113. {
  114. if (0 == lstrcmpi(szName, szReservedName))
  115. {
  116. return TRUE;
  117. }
  118. }
  119. }
  120. return FALSE;
  121. }
  122. //+---------------------------------------------------------------------------
  123. //
  124. // Function: CIntelliName::GenerateNameRenameOnConflict
  125. //
  126. // Purpose: Generate a name, rename if it conflicts with an existing name
  127. //
  128. // Arguments:
  129. // guid [in] GUID of connection
  130. // ncm [in] NetCon Media Type of Connection
  131. // dwCharacteristics [in] NCCF_ Characteristics of Connection (Pass 0 if you don't know)
  132. // szHintName [in] Hint of name (will use as is if not conflicting)
  133. // szHintType [in] String of NetCon Media Type
  134. // szName [out] Resulting connection name - free with CoTaskMemFree
  135. //
  136. // Returns: HRESULT
  137. //
  138. // Author: deonb 27 Feb 2001
  139. //
  140. // Notes:
  141. //
  142. HRESULT CIntelliName::GenerateNameRenameOnConflict(IN REFGUID guid, IN NETCON_MEDIATYPE ncm, IN DWORD dwCharacteristics, IN LPCWSTR szHintName, IN LPCWSTR szHintType, OUT LPWSTR *szName)
  143. {
  144. WCHAR szTemp[MAX_PATH+1];
  145. WCHAR szBaseName[MAX_PATH +1];
  146. Assert(szName)
  147. *szName = NULL;
  148. wcsncpy(szTemp, szHintName, MAX_PATH-45); // reserve last 45 bytes to include specialized info.
  149. BOOL fHasName = FALSE;
  150. DWORD dwInstance = 2;
  151. wcsncpy(szBaseName, szTemp, MAX_PATH);
  152. NETCON_MEDIATYPE ncmdup;
  153. NETCON_SUBMEDIATYPE ncmsdup;
  154. if (NameExists(szTemp, &ncmdup, &ncmsdup))
  155. {
  156. fHasName = TRUE;
  157. BOOL fHasTypeAlready = FALSE;
  158. if ( (ncmdup == ncm) || (NCM_LAN == ncm) )
  159. {
  160. fHasTypeAlready = TRUE;
  161. }
  162. if (!fHasTypeAlready)
  163. {
  164. wsprintf(szTemp, L"%s (%s)", szBaseName, szHintType);
  165. Assert(wcslen(szTemp) <= MAX_PATH);
  166. wcsncpy(szBaseName, szTemp, MAX_PATH);
  167. }
  168. else
  169. {
  170. wsprintf(szTemp, L"%s %d", szBaseName, dwInstance);
  171. Assert(wcslen(szTemp) <= MAX_PATH);
  172. dwInstance++;
  173. }
  174. while (NameExists(szTemp, &ncmdup, &ncmsdup) && (dwInstance < 65535) )
  175. {
  176. wsprintf(szTemp, L"%s %d", szBaseName, dwInstance);
  177. Assert(wcslen(szTemp) <= MAX_PATH);
  178. dwInstance++;
  179. }
  180. if ( (dwInstance >= 65535) && NameExists(szTemp, &ncmdup, &ncmsdup) )
  181. {
  182. fHasName = FALSE;
  183. }
  184. }
  185. else
  186. {
  187. fHasName = TRUE;
  188. }
  189. if (fHasName)
  190. {
  191. HRESULT hr = HrCoTaskMemAllocAndDupSz(szTemp, szName);
  192. return hr;
  193. }
  194. else
  195. {
  196. return E_FAIL;
  197. }
  198. }
  199. //+---------------------------------------------------------------------------
  200. //
  201. // Function: CIntelliName::GenerateNameFromResource
  202. //
  203. // Purpose: Generate a name, rename if it conflicts with an existing name
  204. //
  205. // Arguments:
  206. // guid [in] GUID of connection
  207. // ncm [in] NetCon Media Type of Connection
  208. // dwCharacteristics [in] NCCF_ Characteristics of Connection (Pass 0 if you don't know)
  209. // szHintName [in] Hint of name (will use as is if not conflicting)
  210. // uiNameID [in] Resource id of default name
  211. // uiTypeId [in] Resource id of default type
  212. // szName [out] Resulting connection name - free with CoTaskMemFree
  213. //
  214. // Returns: HRESULT
  215. //
  216. // Author: deonb 27 Feb 2001
  217. //
  218. // Notes:
  219. //
  220. HRESULT CIntelliName::GenerateNameFromResource(IN REFGUID guid, IN NETCON_MEDIATYPE ncm, IN DWORD dwCharacteristics, IN LPCWSTR szHint, IN UINT uiNameID, IN UINT uiTypeId, OUT LPWSTR *szName)
  221. {
  222. Assert(szName);
  223. *szName = NULL;
  224. WCHAR szHintName[MAX_PATH+1];
  225. WCHAR szTypeName[MAX_PATH+1];
  226. if (!szHint || *szHint == L'\0')
  227. {
  228. int nSiz = LoadString (m_hInstance, uiNameID, szHintName, MAX_PATH);
  229. AssertSz(nSiz, "Resource string not found");
  230. }
  231. else
  232. {
  233. wcsncpy(szHintName, szHint, MAX_PATH);
  234. }
  235. int nSiz = LoadString (m_hInstance, uiTypeId, szTypeName, MAX_PATH);
  236. AssertSz(nSiz, "Resource string not found");
  237. return GenerateNameRenameOnConflict(guid, ncm, dwCharacteristics, szHintName, szTypeName, szName);
  238. }
  239. //+---------------------------------------------------------------------------
  240. //
  241. // Function: CIntelliName::HrGetPseudoMediaTypes
  242. //
  243. // Purpose: Generate a name, rename if it conflicts with an existing name
  244. //
  245. // Arguments:
  246. // guid [in] GUID of connection
  247. // pncm [out] Pseudo-NetCon Media Type of Connection (Only NCM_PHONE or NCM_LAN)
  248. // pncms [out] SubMedia Type for LAN connections
  249. //
  250. // Returns: HRESULT
  251. //
  252. // Author: deonb 27 Feb 2001
  253. //
  254. // Notes:
  255. //
  256. HRESULT CIntelliName::HrGetPseudoMediaTypes(IN REFGUID guid, OUT NETCON_MEDIATYPE *pncm, OUT NETCON_SUBMEDIATYPE* pncms)
  257. {
  258. Assert(pncms);
  259. Assert(pncm);
  260. Assert(guid != GUID_NULL);
  261. HRESULT hr;
  262. *pncms = NCSM_NONE;
  263. INetCfg* pNetCfg;
  264. hr = CoCreateInstance(
  265. CLSID_CNetCfg,
  266. NULL,
  267. CLSCTX_INPROC_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  268. IID_INetCfg,
  269. reinterpret_cast<LPVOID *>(&pNetCfg));
  270. if (SUCCEEDED(hr))
  271. {
  272. hr = pNetCfg->Initialize(NULL);
  273. if (SUCCEEDED(hr))
  274. {
  275. CIterNetCfgComponent nccIter(pNetCfg, &GUID_DEVCLASS_NET);
  276. INetCfgComponent* pnccAdapter = NULL;
  277. BOOL fFound = FALSE;
  278. while (!fFound && SUCCEEDED(hr) &&
  279. (S_OK == (hr = nccIter.HrNext(&pnccAdapter))))
  280. {
  281. GUID guidDev;
  282. hr = pnccAdapter->GetInstanceGuid(&guidDev);
  283. if (S_OK == hr)
  284. {
  285. if (guid == guidDev)
  286. {
  287. hr = HrIsLanCapableAdapter(pnccAdapter);
  288. Assert(SUCCEEDED(hr));
  289. if (SUCCEEDED(hr))
  290. {
  291. fFound = TRUE;
  292. if (S_FALSE == hr)
  293. {
  294. *pncm = NCM_PHONE;
  295. }
  296. else if (S_OK == hr)
  297. {
  298. *pncm = NCM_LAN;
  299. BOOL bRet;
  300. DWORD dwMediaType;
  301. DWORD dwMediaTypeSize = sizeof(DWORD);
  302. hr = HrQueryNDISAdapterOID(guid,
  303. OID_GEN_PHYSICAL_MEDIUM,
  304. &dwMediaTypeSize,
  305. &dwMediaType);
  306. if (S_OK == hr)
  307. {
  308. switch (dwMediaType)
  309. {
  310. case NdisPhysicalMedium1394:
  311. *pncms = NCSM_1394;
  312. break;
  313. case NdisPhysicalMediumWirelessLan:
  314. case NdisPhysicalMediumWirelessWan:
  315. *pncms = NCSM_WIRELESS;
  316. break;
  317. default:
  318. hr = S_FALSE;
  319. break;
  320. }
  321. }
  322. if (S_OK != hr) // Couldn't determine the Physical Media type. Try bindings next.
  323. {
  324. HRESULT hrPhysicalMedia = hr;
  325. *pncms = NCSM_LAN;
  326. INetCfgComponentBindings* pnccb;
  327. hr = pnccAdapter->QueryInterface(IID_INetCfgComponentBindings,
  328. reinterpret_cast<LPVOID *>(&pnccb));
  329. if (SUCCEEDED(hr))
  330. {
  331. hr = pnccb->SupportsBindingInterface(NCF_UPPER, c_szBiNdisAtm);
  332. if (S_OK == hr)
  333. {
  334. *pncms = NCSM_ATM;
  335. }
  336. pnccb->Release();
  337. }
  338. if (NCSM_ATM != *pncms)
  339. {
  340. // Not ATM
  341. PWSTR pszwCompId;
  342. hr = pnccAdapter->GetId(&pszwCompId);
  343. if (SUCCEEDED(hr) && (0 == lstrcmpiW(c_szInfId_MS_AtmElan, pszwCompId)))
  344. {
  345. // ATM Elan
  346. *pncms = NCSM_ELAN;
  347. CoTaskMemFree(pszwCompId);
  348. }
  349. }
  350. if ( (FAILED(hrPhysicalMedia)) &&
  351. (NCSM_LAN == *pncms) )
  352. {
  353. // Couldn't determine anything specific from the bindings.
  354. // Return the hr from the Physical Media call if it was an error
  355. hr = hrPhysicalMedia;
  356. }
  357. }
  358. }
  359. } // HrIsLanCapableAdapter SUCCEEDED
  360. } // guid == guidDev
  361. } // SUCCEEDED(pnccAdapter->GetInstanceGuid(&guidDev)
  362. else
  363. {
  364. AssertSz(FALSE, "Could not get instance GUID for Adapter");
  365. }
  366. pnccAdapter->Release();
  367. } // while loop
  368. HRESULT hrT = pNetCfg->Uninitialize();
  369. TraceError("INetCfg failed to uninitialize", hrT);
  370. } // SUCCEEDED(pNetConfig->Initialize(NULL))
  371. pNetCfg->Release();
  372. } // SUCCEEDED(CoCreateInstance(pNetCfg))
  373. else
  374. {
  375. AssertSz(FALSE, "Could not create INetCfg");
  376. }
  377. TraceErrorOptional("HrGetPseudoMediaTypes", hr, (S_FALSE == hr));
  378. return hr;
  379. }
  380. //+---------------------------------------------------------------------------
  381. //
  382. // Function: CIntelliName::GenerateName
  383. //
  384. // Purpose: Generate a name based on a hint
  385. //
  386. // Arguments:
  387. // guid [in] GUID of connection
  388. // ncm [in] NetCon Media Type of Connection
  389. // dwCharacteristics [in] NCCF_ Characteristics of Connection (Pass 0 if you don't know)
  390. // szHintName [in] Hint of name (will use as is if not conflicting)
  391. // szName [out] Resulting connection name - free with CoTaskMemFree
  392. //
  393. // Returns: HRESULT
  394. //
  395. // Author: deonb 27 Feb 2001
  396. //
  397. // Notes:
  398. //
  399. HRESULT CIntelliName::GenerateName(IN REFGUID guid, IN NETCON_MEDIATYPE ncm, IN DWORD dwCharacteristics, IN LPCWSTR szHint, OUT LPWSTR * szName)
  400. {
  401. Assert(szName);
  402. *szName = NULL;
  403. HRESULT hr = S_OK;
  404. if (dwCharacteristics & NCCF_INCOMING_ONLY)
  405. {
  406. WCHAR szIncomingName[MAX_PATH];
  407. int nSiz = LoadString(m_hInstance, IDS_DEFAULT_IncomingName, szIncomingName, MAX_PATH);
  408. AssertSz(nSiz, "Resource string IDS_TO_THE_INTERNET not found");
  409. if (nSiz)
  410. {
  411. hr = HrCoTaskMemAllocAndDupSz(szIncomingName, szName);
  412. }
  413. else
  414. {
  415. hr = E_FAIL;
  416. }
  417. }
  418. else
  419. {
  420. switch (ncm)
  421. {
  422. case NCM_NONE:
  423. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_IncomingName, IDS_DEFAULT_IncomingName_Type, szName);
  424. break;
  425. case NCM_ISDN:
  426. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_ISDNName, IDS_DEFAULT_ISDNName_Type, szName);
  427. break;
  428. case NCM_DIRECT:
  429. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_DIRECTName, IDS_DEFAULT_DIRECTName_Type, szName);
  430. break;
  431. case NCM_PHONE:
  432. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_PHONEName, IDS_DEFAULT_PHONEName_Type, szName);
  433. break;
  434. case NCM_TUNNEL:
  435. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_VPNName, IDS_DEFAULT_VPNName_Type, szName);
  436. break;
  437. case NCM_PPPOE:
  438. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_PPPOEName, IDS_DEFAULT_PPPOEName_Type, szName);
  439. break;
  440. case NCM_BRIDGE:
  441. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_BRIDGEName, IDS_DEFAULT_BRIDGEName_Type, szName);
  442. break;
  443. case NCM_SHAREDACCESSHOST_LAN:
  444. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_SAHLANName, IDS_DEFAULT_SAHLANName_Type, szName);
  445. break;
  446. case NCM_SHAREDACCESSHOST_RAS:
  447. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_SAHRASName, IDS_DEFAULT_SAHRASName_Type, szName);
  448. break;
  449. case NCM_LAN:
  450. NETCON_MEDIATYPE ncmCheck;
  451. NETCON_SUBMEDIATYPE pncms;
  452. {
  453. DWORD dwRetries = 15;
  454. HRESULT hrT;
  455. do
  456. {
  457. hrT = HrGetPseudoMediaTypes(guid, &ncmCheck, &pncms);
  458. if (FAILED(hrT))
  459. {
  460. Sleep(500); // This is probably being called during device install, so give the adapter some
  461. // time to get itself enabled first.
  462. if (dwRetries > 1)
  463. {
  464. TraceTag(ttidError, "HrGetPseudoMediaTypes failed during device name initialization. Retrying...");
  465. }
  466. else
  467. {
  468. TraceTag(ttidError, "HrGetPseudoMediaTypes failed during device name initialization. Giving up.");
  469. }
  470. }
  471. } while (FAILED(hrT) && --dwRetries);
  472. if (SUCCEEDED(hrT))
  473. {
  474. AssertSz(ncmCheck == NCM_LAN, "This LAN adapter thinks it's something else");
  475. }
  476. else
  477. {
  478. pncms = NCSM_LAN; // If we run out of time, just give up and assume LAN.
  479. TraceTag(ttidError, "Could not determine the exact Media SubType for this adapter. Assuming LAN (and naming it such).");
  480. }
  481. switch (pncms)
  482. {
  483. case NCSM_NONE:
  484. AssertSz(FALSE, "LAN Connections should not be NCSM_NONE");
  485. hr = E_FAIL;
  486. break;
  487. case NCSM_LAN:
  488. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_LANName, IDS_DEFAULT_LANName_Type, szName);
  489. break;
  490. case NCSM_ATM:
  491. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_ATMName, IDS_DEFAULT_ATMName_Type, szName);
  492. break;
  493. case NCSM_ELAN:
  494. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_ELANName, IDS_DEFAULT_ELANName_Type, szName);
  495. break;
  496. case NCSM_WIRELESS:
  497. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_WirelessName, IDS_DEFAULT_WirelessName_Type, szName);
  498. break;
  499. case NCSM_1394:
  500. hr = GenerateNameFromResource(guid, ncm, dwCharacteristics, szHint, IDS_DEFAULT_1394Name, IDS_DEFAULT_1394Name_Type, szName);
  501. break;
  502. default:
  503. AssertSz(FALSE, "Unknown submedia type");
  504. hr = E_FAIL;
  505. break;
  506. }
  507. }
  508. break;
  509. default:
  510. AssertSz(FALSE, "Unknown media type");
  511. hr= E_FAIL;
  512. }
  513. }
  514. return hr;
  515. }
  516. //+---------------------------------------------------------------------------
  517. //
  518. // Function: CIntelliName::GenerateInternetName
  519. //
  520. // Purpose: Generate a name with " to the Internet" appened to it
  521. //
  522. // Arguments:
  523. // guid [in] GUID of connection
  524. // ncm [in] NetCon Media Type of Connection
  525. // dwCharacteristics [in] NCCF_ Characteristics of Connection (Pass 0 if you don't know)
  526. // szName [out] Resulting connection name - free with CoTaskMemFree
  527. //
  528. // Returns: HRESULT
  529. //
  530. // Author: deonb 27 Feb 2001
  531. //
  532. // Notes: Will append " to the Internet" to a name
  533. //
  534. HRESULT CIntelliName::GenerateInternetName(REFGUID guid, NETCON_MEDIATYPE ncm, DWORD dwCharacteristics, OUT LPWSTR * szName)
  535. {
  536. LPWSTR szTmpName;
  537. WCHAR szBuffer[MAX_PATH];
  538. WCHAR szHint[MAX_PATH];
  539. HRESULT hr = E_FAIL;
  540. CIntelliName IntelliNameNoDupCheck(m_hInstance, NULL); // Generate the original name
  541. hr = IntelliNameNoDupCheck.GenerateName(guid, ncm, dwCharacteristics, szHint, &szTmpName);
  542. if (SUCCEEDED(hr))
  543. {
  544. int nSiz = LoadString(m_hInstance, IDS_TO_THE_INTERNET, szBuffer, MAX_PATH);
  545. AssertSz(nSiz, "Resource string IDS_TO_THE_INTERNET not found");
  546. if (nSiz)
  547. {
  548. wcsncpy(szHint, szTmpName, MAX_PATH - nSiz);
  549. wcsncat(szHint, szBuffer, MAX_PATH);
  550. CoTaskMemFree(szTmpName);
  551. return GenerateName(guid, ncm, dwCharacteristics, szHint, szName);
  552. }
  553. }
  554. return hr;
  555. }
  556. //+---------------------------------------------------------------------------
  557. //
  558. // Function: CIntelliName::GenerateHomeNetName
  559. //
  560. // Purpose: Generate a name with " on my Home Network" appened to it
  561. //
  562. // Arguments:
  563. // guid [in] GUID of connection
  564. // ncm [in] NetCon Media Type of Connection
  565. // dwCharacteristics [in] NCCF_ Characteristics of Connection (Pass 0 if you don't know)
  566. // szName [out] Resulting connection name - free with CoTaskMemFree
  567. //
  568. // Returns: HRESULT
  569. //
  570. // Author: deonb 27 Feb 2001
  571. //
  572. // Notes: Will append " on my Home Network" to a name
  573. //
  574. HRESULT CIntelliName::GenerateHomeNetName(REFGUID guid, NETCON_MEDIATYPE ncm, DWORD dwCharacteristics, OUT LPWSTR * szName)
  575. {
  576. LPWSTR szTmpName;
  577. WCHAR szBuffer[MAX_PATH];
  578. WCHAR szHint[MAX_PATH];
  579. HRESULT hr = E_FAIL;
  580. CIntelliName IntelliNameNoDupCheck(m_hInstance, NULL); // Generate the original name
  581. hr = IntelliNameNoDupCheck.GenerateName(guid, ncm, dwCharacteristics, szHint, &szTmpName);
  582. if (SUCCEEDED(hr))
  583. {
  584. int nSiz = LoadString(m_hInstance, IDS_ON_THE_HOMENET, szBuffer, MAX_PATH);
  585. AssertSz(nSiz, "Resource string IDS_ON_THE_HOMENET not found");
  586. if (nSiz)
  587. {
  588. wcsncpy(szHint, szTmpName, MAX_PATH - nSiz);
  589. wcsncat(szHint, szBuffer, MAX_PATH);
  590. CoTaskMemFree(szTmpName);
  591. return GenerateName(guid, ncm, dwCharacteristics, szHint, szName);
  592. }
  593. }
  594. return hr;
  595. }
  596. //+---------------------------------------------------------------------------
  597. //
  598. // Function: OpenDevice
  599. //
  600. // Purpose: Open a Driver
  601. //
  602. // Arguments:
  603. // DeviceName [in] Name of device
  604. //
  605. // Returns: HANDLE of Device or NULL
  606. //
  607. // Author: deonb 27 Feb 2001
  608. //
  609. // Notes: Use GetLastError() for error info
  610. //
  611. HANDLE OpenDevice(IN PUNICODE_STRING DeviceName)
  612. {
  613. OBJECT_ATTRIBUTES ObjAttr;
  614. NTSTATUS Status;
  615. IO_STATUS_BLOCK IoStsBlk;
  616. HANDLE Handle;
  617. InitializeObjectAttributes(&ObjAttr,
  618. DeviceName,
  619. OBJ_CASE_INSENSITIVE,
  620. NULL,
  621. NULL);
  622. Status = NtOpenFile(&Handle,
  623. FILE_GENERIC_READ | FILE_GENERIC_WRITE,
  624. &ObjAttr,
  625. &IoStsBlk,
  626. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  627. FILE_SYNCHRONOUS_IO_NONALERT);
  628. if (Status != STATUS_SUCCESS)
  629. {
  630. SetLastError(RtlNtStatusToDosError(Status));
  631. }
  632. return(Handle);
  633. }
  634. //+---------------------------------------------------------------------------
  635. //
  636. // Function: HrQueryDeviceOIDByName
  637. //
  638. // Purpose: Query an driver for an IOCTL & OID
  639. //
  640. // Arguments:
  641. // Device [in] Name of device
  642. // NDIS_OID [in] OID to query for
  643. // pnSize [in out] pnSize - size of buffer
  644. // pBuffer [out] Buffer
  645. //
  646. // Returns: HRESULT
  647. //
  648. // Author: deonb 4 April 2001
  649. //
  650. // Notes:
  651. //
  652. HRESULT HrQueryDeviceOIDByName(IN LPCWSTR szDeviceName,
  653. IN DWORD dwIoControlCode,
  654. IN ULONG Oid,
  655. IN OUT LPDWORD pnSize,
  656. OUT LPVOID pbValue)
  657. {
  658. HRESULT hr = S_OK;
  659. NDIS_STATISTICS_VALUE StatsBuf;
  660. HANDLE hDevice;
  661. BOOL fResult = FALSE;
  662. UNICODE_STRING ustrDevice;
  663. ::RtlInitUnicodeString(&ustrDevice, szDeviceName);
  664. Assert(pbValue);
  665. ZeroMemory(pbValue, *pnSize);
  666. hDevice = OpenDevice(&ustrDevice);
  667. if (hDevice != NULL)
  668. {
  669. ULONG cb;
  670. DWORD dwStatsBufLen = sizeof(NDIS_STATISTICS_VALUE) - sizeof(UCHAR) + *pnSize;
  671. PNDIS_STATISTICS_VALUE pStatsBuf = reinterpret_cast<PNDIS_STATISTICS_VALUE>(new BYTE[dwStatsBufLen]);
  672. if (pStatsBuf)
  673. {
  674. fResult = DeviceIoControl(hDevice,
  675. dwIoControlCode, // IOCTL code
  676. &Oid, // input buffer
  677. sizeof(ULONG), // input buffer size
  678. pStatsBuf, // output buffer
  679. dwStatsBufLen, // output buffer size
  680. &cb, // bytes returned
  681. NULL); // OVERLAPPED structure
  682. if (fResult)
  683. {
  684. *pnSize = cb;
  685. if (0 == cb)
  686. {
  687. hr = S_FALSE;
  688. }
  689. else
  690. {
  691. if (pStatsBuf->DataLength > *pnSize)
  692. {
  693. AssertSz(FALSE, "Pass a larger buffer for this OID");
  694. hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  695. *pnSize = 0;
  696. }
  697. else
  698. {
  699. memcpy(pbValue, &(pStatsBuf->Data), pStatsBuf->DataLength);
  700. }
  701. }
  702. }
  703. else
  704. {
  705. hr = HrFromLastWin32Error();
  706. }
  707. delete pStatsBuf;
  708. }
  709. else
  710. {
  711. hr = E_OUTOFMEMORY;
  712. }
  713. CloseHandle(hDevice);
  714. }
  715. else
  716. {
  717. hr = HrFromLastWin32Error();
  718. }
  719. TraceHr(ttidError, FAL, hr, S_FALSE == hr, "HrQueryDeviceOIDByName could not read the device properties for device %S", szDeviceName);
  720. return hr;
  721. }
  722. //+---------------------------------------------------------------------------
  723. //
  724. // Function: HrQueryNDISAdapterOID
  725. //
  726. // Purpose: Query an NDIS Driver for an OID
  727. //
  728. // Arguments:
  729. // Device [in] Name of device
  730. // NDIS_OID [in] OID to query for
  731. // pnSize [in out] pnSize - size of buffer
  732. // pBuffer [out] Buffer
  733. //
  734. // Returns: HRESULT
  735. //
  736. // Author: deonb 4 April 2001
  737. //
  738. // Notes:
  739. //
  740. HRESULT HrQueryNDISAdapterOID(IN REFGUID guidId,
  741. IN NDIS_OID Oid,
  742. IN OUT LPDWORD pnSize,
  743. OUT LPVOID pbValue)
  744. {
  745. WCHAR szDeviceName[c_cchGuidWithTerm + celems(c_szDevice)];
  746. wcscpy(szDeviceName, c_szDevice);
  747. ::StringFromGUID2(guidId, szDeviceName + (celems(c_szDevice)-1), c_cchGuidWithTerm);
  748. Assert(wcslen(szDeviceName) < c_cchGuidWithTerm + celems(c_szDevice));
  749. return HrQueryDeviceOIDByName(szDeviceName, IOCTL_NDIS_QUERY_SELECTED_STATS, Oid, pnSize, pbValue);
  750. }
  751. //+---------------------------------------------------------------------------
  752. //
  753. // Function: CIntelliName::IsMediaWireless
  754. //
  755. // Purpose: Queries a LAN Card to see if it's 802.1x
  756. //
  757. // Arguments:
  758. // gdDevice [in] GUID of Network Card
  759. //
  760. // Returns: TRUE if WireLess, FALSE if not
  761. //
  762. // Author: deonb 27 Feb 2001
  763. //
  764. // Notes:
  765. //
  766. BOOL IsMediaWireless(NETCON_MEDIATYPE ncm, const GUID &gdDevice)
  767. {
  768. BOOL bRet;
  769. Assert(gdDevice != GUID_NULL);
  770. bRet = FALSE;
  771. // Prime the structure
  772. switch( ncm )
  773. {
  774. case NCM_LAN:
  775. // Retrieve the statistics
  776. DWORD dwMediaType;
  777. DWORD dwMediaTypeSize = sizeof(dwMediaType);
  778. HRESULT hr = HrQueryNDISAdapterOID(gdDevice,
  779. OID_GEN_PHYSICAL_MEDIUM,
  780. &dwMediaTypeSize,
  781. &dwMediaType);
  782. if (SUCCEEDED(hr))
  783. {
  784. bRet = (dwMediaType == NdisPhysicalMediumWirelessLan) ||
  785. (dwMediaType == NdisPhysicalMediumWirelessWan);
  786. }
  787. }
  788. return bRet;
  789. }
  790. //+---------------------------------------------------------------------------
  791. //
  792. // Function: CIntelliName::IsMedia1394
  793. //
  794. // Purpose: Queries a LAN Card to see if it's 1394 (FireWire / iLink)
  795. //
  796. // Arguments:
  797. // gdDevice [in] GUID of Network Card
  798. //
  799. // Returns: TRUE if WireLess, FALSE if not
  800. //
  801. // Author: deonb 27 Feb 2001
  802. //
  803. // Notes:
  804. //
  805. BOOL IsMedia1394(NETCON_MEDIATYPE ncm, const GUID &gdDevice)
  806. {
  807. BOOL bRet;
  808. Assert(gdDevice != GUID_NULL);
  809. bRet = FALSE;
  810. // Prime the structure
  811. switch( ncm )
  812. {
  813. case NCM_LAN:
  814. // Retrieve the statistics
  815. DWORD dwMediaType;
  816. DWORD dwMediaTypeSize = sizeof(DWORD);
  817. HRESULT hr = HrQueryNDISAdapterOID(gdDevice,
  818. OID_GEN_PHYSICAL_MEDIUM,
  819. &dwMediaTypeSize,
  820. &dwMediaType);
  821. if (SUCCEEDED(hr))
  822. {
  823. bRet = (dwMediaType == NdisPhysicalMedium1394);
  824. }
  825. }
  826. return bRet;
  827. }