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.

728 lines
17 KiB

  1. #include "stdafx.h"
  2. #include "AtlkAdapter.h"
  3. #include "ndispnpevent.h"
  4. HRESULT CAtlkAdapter::Initialize()
  5. {
  6. HRESULT hr;
  7. hr = ValidateAdapGuid();
  8. if(hr != S_OK)
  9. return hr;
  10. hr = UpdateZoneList();
  11. if(hr != S_OK)
  12. return hr;
  13. UpdateDesiredZone();
  14. m_bstrNewDesiredZone = m_bstrDesiredZone;
  15. return hr;
  16. }
  17. VOID CAtlkAdapter::GetZoneList(TZoneListVector *pZonesList)
  18. {
  19. *pZonesList = m_ZonesList;
  20. }
  21. HRESULT CAtlkAdapter::SetAsDefaultPort()
  22. {
  23. HRESULT hr=S_OK;
  24. if(m_bDefaultPort)
  25. return hr;
  26. if( (hr = SetDefaultPortInReg()) != S_OK)
  27. return hr;
  28. m_bDefPortDirty = TRUE;
  29. return AtlkReconfig();
  30. }
  31. HRESULT CAtlkAdapter::SetDesiredZone(BSTR bstrZoneName)
  32. {
  33. HRESULT hr=S_OK;
  34. ULONG ulIndex;
  35. for(ulIndex=0; ulIndex < m_ZonesList.size(); ulIndex++)
  36. {
  37. wstring ZoneName;
  38. ZoneName = m_ZonesList[ulIndex];
  39. if(!lstrcmpi(ZoneName.c_str(), bstrZoneName))
  40. {
  41. break;
  42. }
  43. }
  44. if(ulIndex == m_ZonesList.size())
  45. return E_INVALIDARG; //invalid zone name specified
  46. if(!m_bDefaultPort)
  47. {
  48. if( (hr = SetDefaultPortInReg()) != S_OK)
  49. return hr;
  50. m_bDefPortDirty = TRUE;
  51. }
  52. if(!lstrcmpi(m_bstrDesiredZone.m_str, bstrZoneName))
  53. return hr; //already is the desired zone just return
  54. m_bstrNewDesiredZone = bstrZoneName;
  55. if( (hr=SetDesiredZoneInReg()) != S_OK)
  56. return hr;
  57. m_bDesZoneDirty = TRUE;
  58. return AtlkReconfig();
  59. }
  60. //private method
  61. //check whether this adapter is configured for appletalk
  62. HRESULT CAtlkAdapter::ValidateAdapGuid()
  63. {
  64. HKEY hAdRegKey = NULL;
  65. HRESULT hr = S_OK;
  66. DWORD dwDataSize, dwType;
  67. LPBYTE pDataBuffer = NULL;
  68. WCHAR *szAdapGuid;
  69. try
  70. {
  71. LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szATLKLinkage,0, KEY_QUERY_VALUE, &hAdRegKey);
  72. if(lRet != ERROR_SUCCESS)
  73. {
  74. hr = HRESULT_FROM_WIN32(lRet);
  75. throw hr;
  76. }
  77. lRet = RegQueryValueEx(hAdRegKey, c_szRoute, NULL, NULL, NULL, &dwDataSize);
  78. if(lRet != ERROR_SUCCESS)
  79. {
  80. hr = HRESULT_FROM_WIN32(lRet);
  81. throw hr;
  82. }
  83. pDataBuffer = new BYTE[dwDataSize];
  84. if(pDataBuffer == NULL)
  85. {
  86. hr = E_OUTOFMEMORY;
  87. throw hr;
  88. }
  89. lRet = RegQueryValueEx(hAdRegKey, c_szRoute, NULL, &dwType, pDataBuffer, &dwDataSize);
  90. if(lRet != ERROR_SUCCESS)
  91. {
  92. hr = HRESULT_FROM_WIN32(lRet);
  93. throw hr;
  94. }
  95. szAdapGuid = (WCHAR *) pDataBuffer;
  96. hr = E_INVALIDARG;
  97. while(szAdapGuid[0] != _TEXT('\0'))
  98. {
  99. if( wcsstr (szAdapGuid, m_bstrAdapGuid.m_str) )
  100. {
  101. hr = S_OK;
  102. break;
  103. }
  104. szAdapGuid = szAdapGuid + lstrlen(szAdapGuid) + 1;
  105. }
  106. }
  107. catch( ... )
  108. {
  109. }
  110. if ( pDataBuffer )
  111. delete [] pDataBuffer;
  112. return hr;
  113. }
  114. //private method
  115. HRESULT CAtlkAdapter::UpdateZoneList()
  116. {
  117. HRESULT hr = S_OK;
  118. WCHAR *szAppTalkAd = NULL;
  119. HKEY hAdRegKey = NULL;
  120. LPBYTE pZoneBuffer=NULL;
  121. DWORD dwDataSize;
  122. DWORD dwType;
  123. WCHAR *szZone;
  124. try
  125. {
  126. //read the zonelist from registry and add to global zone list
  127. szAppTalkAd = new WCHAR[m_bstrAdapGuid.Length() + lstrlen(c_szATLKAdapters) + 10];
  128. if(szAppTalkAd == NULL )
  129. {
  130. hr = E_OUTOFMEMORY;
  131. throw hr;
  132. }
  133. wsprintf(szAppTalkAd, L"%s\\%s",c_szATLKAdapters,m_bstrAdapGuid.m_str);
  134. LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szAppTalkAd,0, KEY_QUERY_VALUE, &hAdRegKey);
  135. if(lRet != ERROR_SUCCESS)
  136. {
  137. hr = HRESULT_FROM_WIN32(lRet);
  138. throw hr;
  139. }
  140. lRet = RegQueryValueEx(hAdRegKey, c_szZoneList, NULL, NULL, NULL, &dwDataSize);
  141. if(lRet != ERROR_SUCCESS)
  142. {
  143. hr = HRESULT_FROM_WIN32(lRet);
  144. throw hr;
  145. }
  146. pZoneBuffer = new BYTE[dwDataSize];
  147. if(pZoneBuffer == NULL)
  148. {
  149. hr = E_OUTOFMEMORY;
  150. throw hr;
  151. }
  152. lRet = RegQueryValueEx(hAdRegKey, c_szZoneList, NULL, &dwType, pZoneBuffer, &dwDataSize);
  153. if(lRet != ERROR_SUCCESS)
  154. {
  155. hr = HRESULT_FROM_WIN32(lRet);
  156. throw hr;
  157. }
  158. szZone = (WCHAR *) pZoneBuffer;
  159. while(szZone[0] != _TEXT('\0'))
  160. {
  161. wstring ZoneName(szZone);
  162. m_ZonesList.push_back(ZoneName);
  163. szZone = szZone + lstrlen(szZone) + 1;
  164. }
  165. /*if( (hr=UpdateZonesListFromSocket()) != S_OK)
  166. throw hr;*/
  167. //return value is not checked beacuse bind fails if the adapter is not the
  168. //default port, need to investigate
  169. UpdateZonesListFromSocket();
  170. }
  171. catch ( ... )
  172. {
  173. }
  174. if(szAppTalkAd != NULL)
  175. delete [] szAppTalkAd;
  176. if(pZoneBuffer != NULL)
  177. delete [] pZoneBuffer;
  178. if(hAdRegKey != NULL)
  179. RegCloseKey(hAdRegKey);
  180. return hr;
  181. }
  182. //private method
  183. VOID CAtlkAdapter::UpdateDesiredZone()
  184. {
  185. if(!GetDesiredZoneFromReg())
  186. m_bstrDesiredZone = m_bstrDefZone;
  187. }
  188. //private method
  189. BOOL CAtlkAdapter::GetDesiredZoneFromReg()
  190. {
  191. HKEY hParmRegKey=NULL;
  192. DWORD dwDataSize;
  193. DWORD dwType;
  194. LPBYTE pZoneData;
  195. BOOL bRetVal = FALSE;
  196. WCHAR *szAppTalkAd;
  197. HKEY hAdRegKey=NULL;
  198. try
  199. {
  200. LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szATLKParameters,0, KEY_QUERY_VALUE, &hParmRegKey);
  201. if(lRet != ERROR_SUCCESS)
  202. {
  203. throw bRetVal;
  204. }
  205. lRet = RegQueryValueEx(hParmRegKey, c_szDefaultPort, NULL, NULL, NULL, &dwDataSize);
  206. if(lRet != ERROR_SUCCESS)
  207. {
  208. throw bRetVal;
  209. }
  210. pZoneData = new BYTE[dwDataSize];
  211. if(pZoneData == NULL)
  212. {
  213. bRetVal = FALSE;
  214. throw bRetVal;
  215. }
  216. lRet = RegQueryValueExW(hParmRegKey, c_szDefaultPort, NULL, &dwType, pZoneData, &dwDataSize);
  217. if(lRet != ERROR_SUCCESS)
  218. {
  219. throw bRetVal;
  220. }
  221. if(!lstrcmpi(m_bstrPortName.m_str, (WCHAR*)pZoneData))
  222. {
  223. //this adapter is the default port, so also update the flag m_bDeafultPort to true
  224. delete [] pZoneData;
  225. pZoneData = NULL;
  226. m_bDefaultPort = TRUE;
  227. lRet = RegQueryValueEx(hParmRegKey, c_szDesiredZone, NULL, NULL, NULL, &dwDataSize);
  228. if(lRet != ERROR_SUCCESS)
  229. {
  230. throw bRetVal;
  231. }
  232. pZoneData = new BYTE[dwDataSize];
  233. lRet = RegQueryValueEx(hParmRegKey, c_szDesiredZone, NULL, &dwType, pZoneData, &dwDataSize);
  234. if(lRet == ERROR_SUCCESS)
  235. {
  236. if( ((WCHAR*)pZoneData)[0] != _TEXT('\0'))
  237. {
  238. bRetVal = TRUE;
  239. m_bstrDesiredZone = (WCHAR*)pZoneData;
  240. throw bRetVal;
  241. }
  242. }
  243. }
  244. delete [] pZoneData;
  245. pZoneData = NULL;
  246. //adapter is not the default one, so try to read the default zone from Adapters/GUID reg loc
  247. szAppTalkAd = new WCHAR[m_bstrAdapGuid.Length() + lstrlen(c_szATLKAdapters) + 10];
  248. wsprintf(szAppTalkAd, L"%s\\%s",c_szATLKAdapters,m_bstrAdapGuid.m_str);
  249. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szAppTalkAd,0, KEY_QUERY_VALUE, &hAdRegKey);
  250. if(lRet != ERROR_SUCCESS)
  251. {
  252. throw bRetVal;
  253. }
  254. lRet = RegQueryValueEx(hAdRegKey, c_szDefaultZone, NULL, NULL, NULL, &dwDataSize);
  255. if(lRet != ERROR_SUCCESS)
  256. {
  257. throw bRetVal;
  258. }
  259. pZoneData = new BYTE[dwDataSize];
  260. lRet = RegQueryValueEx(hAdRegKey, c_szDefaultZone, NULL, &dwType, pZoneData, &dwDataSize);
  261. if(lRet != ERROR_SUCCESS)
  262. {
  263. throw bRetVal;
  264. }
  265. if( ((WCHAR*)pZoneData)[0] != _TEXT('\0'))
  266. {
  267. bRetVal = TRUE;
  268. m_bstrDesiredZone = (WCHAR*)pZoneData;
  269. }
  270. }
  271. catch(...)
  272. {
  273. }
  274. if(hParmRegKey != NULL)
  275. RegCloseKey(hParmRegKey);
  276. if(pZoneData)
  277. delete [] pZoneData;
  278. return bRetVal;
  279. }
  280. //private method
  281. HRESULT CAtlkAdapter::UpdateZonesListFromSocket()
  282. {
  283. SOCKADDR_AT address;
  284. BOOL fWSInitialized = FALSE;
  285. SOCKET mysocket = INVALID_SOCKET;
  286. WSADATA wsadata;
  287. DWORD dwWsaerr;
  288. HRESULT hr = S_OK;
  289. try
  290. {
  291. // Create the socket/bind
  292. dwWsaerr = WSAStartup(0x0101, &wsadata);
  293. if (0 != dwWsaerr)
  294. {
  295. hr = HRESULT_FROM_WIN32(dwWsaerr);
  296. throw hr;
  297. }
  298. // Winsock successfully initialized
  299. fWSInitialized = TRUE;
  300. mysocket = socket(AF_APPLETALK, SOCK_DGRAM, DDPPROTO_ZIP);
  301. if (INVALID_SOCKET == mysocket)
  302. {
  303. dwWsaerr = ::WSAGetLastError();
  304. hr = HRESULT_FROM_WIN32(dwWsaerr);
  305. throw hr;
  306. }
  307. address.sat_family = AF_APPLETALK;
  308. address.sat_net = 0;
  309. address.sat_node = 0;
  310. address.sat_socket = 0;
  311. dwWsaerr = bind(mysocket, (struct sockaddr *)&address, sizeof(address));
  312. if (dwWsaerr != 0)
  313. {
  314. dwWsaerr = ::WSAGetLastError();
  315. hr = HRESULT_FROM_WIN32(dwWsaerr);
  316. throw hr;
  317. }
  318. // Failures from query the zone list for a given adapter can be from
  319. // the adapter not connected to the network, zone seeder not running, etc.
  320. // Because we want to process all the adapters, we ignore these errors.
  321. hr = UpdateDefZonesFromSocket(mysocket);
  322. }
  323. catch( ... )
  324. {
  325. }
  326. if (INVALID_SOCKET != mysocket)
  327. {
  328. closesocket(mysocket);
  329. }
  330. if (fWSInitialized)
  331. {
  332. WSACleanup();
  333. }
  334. return hr;
  335. }
  336. //private method
  337. //
  338. // Function: CAtlkAdapter::UpdateDefZonesFromSocket
  339. //
  340. // Purpose:
  341. //
  342. // Parameters:
  343. //
  344. // Returns: DWORD, ERROR_SUCCESS on success
  345. //
  346. #define PARM_BUF_LEN 512
  347. #define ASTERISK_CHAR "*"
  348. HRESULT CAtlkAdapter::UpdateDefZonesFromSocket ( SOCKET socket )
  349. {
  350. CHAR *pZoneBuffer = NULL;
  351. CHAR *pDefParmsBuffer = NULL;
  352. CHAR *pZoneListStart;
  353. INT BytesNeeded ;
  354. WCHAR *pwDefZone = NULL;
  355. INT ZoneLen = 0;
  356. DWORD dwWsaerr = ERROR_SUCCESS;
  357. CHAR *pDefZone = NULL;
  358. HRESULT hr = S_OK;
  359. PWSH_LOOKUP_ZONES pGetNetZones;
  360. PWSH_LOOKUP_NETDEF_ON_ADAPTER pGetNetDefaults;
  361. try
  362. {
  363. pZoneBuffer = new CHAR [ZONEBUFFER_LEN + sizeof(WSH_LOOKUP_ZONES)];
  364. pGetNetZones = (PWSH_LOOKUP_ZONES)pZoneBuffer;
  365. wcscpy((WCHAR *)(pGetNetZones+1), m_bstrPortName.m_str);
  366. BytesNeeded = ZONEBUFFER_LEN;
  367. dwWsaerr = getsockopt(socket, SOL_APPLETALK, SO_LOOKUP_ZONES_ON_ADAPTER,
  368. (char *)pZoneBuffer, &BytesNeeded);
  369. if (0 != dwWsaerr)
  370. {
  371. hr = HRESULT_FROM_WIN32(dwWsaerr);
  372. throw hr;
  373. }
  374. pZoneListStart = pZoneBuffer + sizeof(WSH_LOOKUP_ZONES);
  375. if (!lstrcmpA(pZoneListStart, ASTERISK_CHAR))
  376. {
  377. // Success, wildcard zone set.
  378. throw hr;
  379. }
  380. dwWsaerr = UpdateDefZonesToZoneList(pZoneListStart, ((PWSH_LOOKUP_ZONES)pZoneBuffer)->NoZones);
  381. if (dwWsaerr != ERROR_SUCCESS)
  382. {
  383. hr = HRESULT_FROM_WIN32(dwWsaerr);
  384. throw hr;
  385. }
  386. //
  387. // Get the DefaultZone/NetworkRange Information
  388. pDefParmsBuffer = new CHAR[PARM_BUF_LEN+sizeof(WSH_LOOKUP_NETDEF_ON_ADAPTER)];
  389. pGetNetDefaults = (PWSH_LOOKUP_NETDEF_ON_ADAPTER)pDefParmsBuffer;
  390. BytesNeeded = PARM_BUF_LEN + sizeof(WSH_LOOKUP_NETDEF_ON_ADAPTER);
  391. wcscpy((WCHAR*)(pGetNetDefaults+1), m_bstrPortName.m_str);
  392. pGetNetDefaults->NetworkRangeLowerEnd = pGetNetDefaults->NetworkRangeUpperEnd = 0;
  393. dwWsaerr = getsockopt(socket, SOL_APPLETALK, SO_LOOKUP_NETDEF_ON_ADAPTER,
  394. (char*)pDefParmsBuffer, &BytesNeeded);
  395. if (0 != dwWsaerr)
  396. {
  397. #ifdef DBG
  398. DWORD dwErr = WSAGetLastError();
  399. #endif
  400. hr = HRESULT_FROM_WIN32(dwWsaerr);
  401. throw hr;
  402. }
  403. pDefZone = pDefParmsBuffer + sizeof(WSH_LOOKUP_NETDEF_ON_ADAPTER);
  404. ZoneLen = lstrlenA(pDefZone) + 1;
  405. pwDefZone = new WCHAR [sizeof(WCHAR) * ZoneLen];
  406. //Assert(NULL != pwDefZone);
  407. mbstowcs(pwDefZone, pDefZone, ZoneLen);
  408. m_bstrDefZone = pwDefZone;
  409. }
  410. catch( ... )
  411. {
  412. if (pZoneBuffer != NULL)
  413. {
  414. delete [] pZoneBuffer;
  415. }
  416. if (pwDefZone != NULL)
  417. {
  418. delete [] pwDefZone;
  419. }
  420. if (pDefParmsBuffer != NULL)
  421. {
  422. delete [] pDefParmsBuffer;
  423. }
  424. }
  425. return hr;
  426. }
  427. //private method
  428. HRESULT CAtlkAdapter::UpdateDefZonesToZoneList(CHAR * szZoneList, ULONG NumZones)
  429. {
  430. INT cbAscii = 0;
  431. ULONG iIndex=0;
  432. WCHAR *pszZone = NULL;
  433. HRESULT hr = S_OK;
  434. while(NumZones--)
  435. {
  436. cbAscii = lstrlenA(szZoneList) + 1;
  437. pszZone = new WCHAR [sizeof(WCHAR) * cbAscii];
  438. if(pszZone == NULL)
  439. {
  440. hr = E_POINTER;
  441. return hr;
  442. }
  443. mbstowcs(pszZone, szZoneList, cbAscii);
  444. for(iIndex=0; iIndex<m_ZonesList.size(); iIndex++)
  445. {
  446. wstring ZoneName;
  447. ZoneName = m_ZonesList[iIndex];
  448. if(!lstrcmpi(pszZone, ZoneName.c_str()))
  449. break;
  450. }
  451. if(iIndex >= m_ZonesList.size())
  452. {
  453. wstring ZoneName(pszZone);
  454. m_ZonesList.push_back(ZoneName);
  455. }
  456. szZoneList += cbAscii;
  457. delete [] pszZone;
  458. }
  459. return hr;
  460. }
  461. //private method
  462. HRESULT CAtlkAdapter::AtlkReconfig()
  463. {
  464. HRESULT hrRet = S_OK;
  465. ATALK_PNP_EVENT Config;
  466. ZeroMemory(&Config, sizeof(Config));
  467. if(m_bDefPortDirty)
  468. {
  469. // notify atlk
  470. Config.PnpMessage = AT_PNP_SWITCH_DEFAULT_ADAPTER;
  471. hrRet = HrSendNdisPnpReconfig(NDIS, c_szAtlk, NULL,
  472. &Config, sizeof(ATALK_PNP_EVENT));
  473. if (FAILED(hrRet))
  474. {
  475. return hrRet;
  476. }
  477. }
  478. if(m_bDesZoneDirty)
  479. {
  480. Config.PnpMessage = AT_PNP_RECONFIGURE_PARMS;
  481. // Now submit the reconfig notification
  482. hrRet = HrSendNdisPnpReconfig(NDIS, c_szAtlk, m_bstrAdapGuid.m_str,
  483. &Config, sizeof(ATALK_PNP_EVENT));
  484. if (FAILED(hrRet))
  485. {
  486. return hrRet;
  487. }
  488. }
  489. return hrRet;
  490. }
  491. //private method
  492. HRESULT CAtlkAdapter::SetDefaultPortInReg()
  493. {
  494. HRESULT hr=S_OK;
  495. HKEY hParamRegKey = NULL;
  496. try
  497. {
  498. LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szATLKParameters,0, KEY_SET_VALUE, &hParamRegKey);
  499. if(lRet != ERROR_SUCCESS)
  500. {
  501. hr = HRESULT_FROM_WIN32(lRet);
  502. throw hr;
  503. }
  504. DWORD dwSize = m_bstrPortName.Length()*sizeof(WCHAR) + 2;
  505. lRet = RegSetValueEx(hParamRegKey,c_szDefaultPort,0,REG_SZ,(BYTE *) m_bstrPortName.m_str, dwSize);
  506. if(lRet != ERROR_SUCCESS)
  507. {
  508. hr = HRESULT_FROM_WIN32(lRet);
  509. throw hr;
  510. }
  511. }
  512. catch( ... )
  513. {
  514. }
  515. if(hParamRegKey)
  516. RegCloseKey(hParamRegKey);
  517. return hr;
  518. }
  519. //private method
  520. HRESULT CAtlkAdapter::SetDesiredZoneInReg()
  521. {
  522. HRESULT hr=S_OK;
  523. HKEY hParamRegKey = NULL;
  524. try
  525. {
  526. if(m_bstrNewDesiredZone[0] == _TEXT('\0'))
  527. throw hr;
  528. LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szATLKParameters,0, KEY_SET_VALUE, &hParamRegKey);
  529. if(lRet != ERROR_SUCCESS)
  530. {
  531. hr = HRESULT_FROM_WIN32(lRet);
  532. throw hr;
  533. }
  534. DWORD dwSize = m_bstrNewDesiredZone.Length()*sizeof(WCHAR) + 2;
  535. lRet = RegSetValueEx(hParamRegKey,c_szDesiredZone,0,REG_SZ,(BYTE *) m_bstrNewDesiredZone.m_str, dwSize);
  536. if(lRet != ERROR_SUCCESS)
  537. {
  538. hr = HRESULT_FROM_WIN32(lRet);
  539. throw hr;
  540. }
  541. }
  542. catch( ... )
  543. {
  544. }
  545. if(hParamRegKey)
  546. RegCloseKey(hParamRegKey);
  547. return hr;
  548. }