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.

618 lines
18 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. atlkenv.cpp
  7. FILE HISTORY:
  8. */
  9. #include "stdafx.h"
  10. #include <netcfgx.h>
  11. #include <atalkwsh.h>
  12. #include "atlkenv.h"
  13. #include "ndisutil.h"
  14. //****************************************************************
  15. //
  16. //****************************************************************
  17. CATLKEnv::~CATLKEnv()
  18. {
  19. for ( AI p=m_adapterinfolist.begin(); p!= m_adapterinfolist.end() ; p++ )
  20. {
  21. delete *p;
  22. }
  23. }
  24. HRESULT CATLKEnv::FetchRegInit()
  25. {
  26. RegKey regkey;
  27. RegKey regkeyA;
  28. RegKeyIterator regIter;
  29. CString szDefAdapter;
  30. CString szKey;
  31. CAdapterInfo* pAdapInfo;
  32. if ( ERROR_SUCCESS == regkey.Open(HKEY_LOCAL_MACHINE,c_szAppleTalkService,KEY_READ,m_szServerName) )
  33. {
  34. regkey.QueryValue( c_szRegValDefaultPort, szDefAdapter);
  35. }
  36. if ( (ERROR_SUCCESS == regkey.Open(HKEY_LOCAL_MACHINE,c_szRegKeyAppletalkAdapter,KEY_READ, m_szServerName)) )
  37. {
  38. m_adapterinfolist.clear();
  39. regIter.Init(&regkey);
  40. while ( regIter.Next(&szKey, NULL)==hrOK )
  41. {
  42. if ( szKey.Find( (TCHAR) '{') == -1 ) //not an adapter interface
  43. continue;
  44. pAdapInfo = new CAdapterInfo;
  45. Assert(pAdapInfo);
  46. pAdapInfo->m_fNotifyPnP=false;
  47. pAdapInfo->m_fModified=false;
  48. pAdapInfo->m_fReloadDyn=true;
  49. pAdapInfo->m_fReloadReg=true;
  50. if ( FHrSucceeded(regkeyA.Open(regkey, szKey)) )
  51. {
  52. regkeyA.QueryValue( c_szDefaultZone, pAdapInfo->m_regInfo.m_szDefaultZone);
  53. regkeyA.QueryValue( c_szRegValNetRangeLower, pAdapInfo->m_regInfo.m_dwRangeLower);
  54. regkeyA.QueryValue( c_szRegValNetRangeUpper, pAdapInfo->m_regInfo.m_dwRangeUpper);
  55. regkeyA.QueryValue( c_szPortName, pAdapInfo->m_regInfo.m_szPortName);
  56. regkeyA.QueryValue( c_szSeedingNetwork, pAdapInfo->m_regInfo.m_dwSeedingNetwork);
  57. regkeyA.QueryValue( c_szZoneList, pAdapInfo->m_regInfo.m_listZones);
  58. // optional value
  59. if(ERROR_SUCCESS != regkeyA.QueryValue( c_szMediaType, pAdapInfo->m_regInfo.m_dwMediaType))
  60. pAdapInfo->m_regInfo.m_dwMediaType = MEDIATYPE_ETHERNET;
  61. }
  62. pAdapInfo->m_dynInfo.m_dwRangeLower=0;
  63. pAdapInfo->m_dynInfo.m_dwRangeUpper=0;
  64. pAdapInfo->m_regInfo.m_szAdapter = szKey;
  65. pAdapInfo->m_regInfo.m_szDevAdapter = c_szDevice;
  66. pAdapInfo->m_regInfo.m_szDevAdapter += szKey;
  67. pAdapInfo->m_regInfo.m_fDefAdapter= (szDefAdapter==pAdapInfo->m_regInfo.m_szDevAdapter);
  68. m_adapterinfolist.push_back(pAdapInfo);
  69. }
  70. }
  71. return hrOK;
  72. }
  73. extern BOOL FIsAppletalkBoundToAdapter(INetCfg * pnc, LPWSTR pszwInstanceGuid);
  74. extern HRESULT HrReleaseINetCfg(BOOL fHasWriteLock, INetCfg* pnc);
  75. extern HRESULT HrGetINetCfg(IN BOOL fGetWriteLock, INetCfg** ppnc);
  76. HRESULT CATLKEnv::IsAdapterBoundToAtlk(LPWSTR szAdapter, BOOL* pbBound)
  77. {
  78. INetCfg* pnc;
  79. HRESULT hr = HrGetINetCfg(FALSE, &pnc);
  80. if(FAILED(hr))
  81. return hr;
  82. *pbBound = FIsAppletalkBoundToAdapter(pnc, szAdapter);
  83. hr = HrReleaseINetCfg(FALSE, pnc);
  84. return hr;
  85. }
  86. CAdapterInfo* CATLKEnv::FindAdapter(CString& szAdapter)
  87. {
  88. CAdapterInfo* pA=NULL;
  89. for ( AI p=m_adapterinfolist.begin(); p!= m_adapterinfolist.end() ; p++ )
  90. {
  91. if ( (*p)->m_regInfo.m_szAdapter==szAdapter )
  92. {
  93. pA=*p;
  94. break;
  95. }
  96. }
  97. return pA;
  98. }
  99. HRESULT CATLKEnv::SetAdapterInfo()
  100. {
  101. RegKey regkey;
  102. RegKey regkeyA;
  103. RegKeyIterator regIter;
  104. CString szDefAdapter;
  105. CString szKey;
  106. CAdapterInfo* pAdapInfo;
  107. bool fATLKChanged=false;
  108. HRESULT hr=S_OK;
  109. if ( (ERROR_SUCCESS == regkey.Open(HKEY_LOCAL_MACHINE,c_szRegKeyAppletalkAdapter,KEY_READ, m_szServerName)) )
  110. {
  111. regIter.Init(&regkey);
  112. while ( regIter.Next(&szKey, NULL)==hrOK )
  113. {
  114. if ( szKey.Find( (TCHAR) '{') == -1 ) //not an adapter interface
  115. continue;
  116. CAdapterInfo* pAdapInfo=NULL;
  117. if ( (pAdapInfo=FindAdapter(szKey))==NULL )
  118. continue;
  119. if ( pAdapInfo->m_fModified && FHrSucceeded(regkeyA.Open(regkey, szKey)) )
  120. {
  121. regkeyA.SetValue( c_szDefaultZone, pAdapInfo->m_regInfo.m_szDefaultZone);
  122. regkeyA.SetValue( c_szRegValNetRangeLower, pAdapInfo->m_regInfo.m_dwRangeLower);
  123. regkeyA.SetValue( c_szRegValNetRangeUpper, pAdapInfo->m_regInfo.m_dwRangeUpper);
  124. regkeyA.SetValue( c_szPortName, pAdapInfo->m_regInfo.m_szPortName);
  125. regkeyA.SetValue( c_szSeedingNetwork, pAdapInfo->m_regInfo.m_dwSeedingNetwork);
  126. regkeyA.SetValue( c_szZoneList, pAdapInfo->m_regInfo.m_listZones);
  127. pAdapInfo->m_fModified=false;
  128. pAdapInfo->m_fNotifyPnP=true;
  129. fATLKChanged=true;
  130. }
  131. }
  132. if (fATLKChanged)
  133. {
  134. CStop_StartAppleTalkPrint MacPrint;
  135. hr=HrAtlkPnPReconfigParams();
  136. }
  137. }
  138. return hr;
  139. }
  140. HRESULT CATLKEnv::GetAdapterInfo(bool fReloadReg/*=true*/)
  141. {
  142. SOCKADDR_AT address;
  143. SOCKET mysocket = INVALID_SOCKET;
  144. WSADATA wsadata;
  145. BOOL fWSInitialized = FALSE;
  146. HRESULT hr= S_OK;
  147. DWORD wsaerr = 0;
  148. bool fWSInit = false;
  149. CString szPortName;
  150. BOOL fSucceeded = FALSE;
  151. AI p;
  152. if (fReloadReg)
  153. { //load container of adapters & registry information
  154. if ( FHrFailed( hr=FetchRegInit()) )
  155. return hr;
  156. }
  157. // Create the socket/bind
  158. wsaerr = WSAStartup(0x0101, &wsadata);
  159. if ( 0 != wsaerr )
  160. goto Error;
  161. // Winsock successfully initialized
  162. fWSInitialized = TRUE;
  163. mysocket = socket(AF_APPLETALK, SOCK_DGRAM, DDPPROTO_ZIP);
  164. if ( mysocket == INVALID_SOCKET )
  165. goto Error;
  166. address.sat_family = AF_APPLETALK;
  167. address.sat_net = 0;
  168. address.sat_node = 0;
  169. address.sat_socket = 0;
  170. wsaerr = bind(mysocket, (struct sockaddr *)&address, sizeof(address));
  171. if ( wsaerr != 0 )
  172. goto Error;
  173. for ( p=m_adapterinfolist.begin(); p!= m_adapterinfolist.end() ; p++ )
  174. {
  175. // Failures from query the zone list for a given adapter can be from
  176. // the adapter not connected to the network, zone seeder not running, etc.
  177. // Because we want to process all the adapters, we ignore these errors.
  178. if ( (*p)->m_fReloadDyn )
  179. {
  180. hr=_HrGetAndSetNetworkInformation( mysocket, *p );
  181. if (FHrSucceeded(hr))
  182. fSucceeded = TRUE;
  183. }
  184. }
  185. Done:
  186. if ( INVALID_SOCKET != mysocket )
  187. closesocket(mysocket);
  188. if ( fWSInitialized )
  189. WSACleanup();
  190. return fSucceeded ? hrOK : hr;
  191. Error:
  192. wsaerr = ::WSAGetLastError();
  193. hr= HRESULT_FROM_WIN32(wsaerr);
  194. goto Done;
  195. }
  196. /* // new registry key "MediaType" created to show the media type, so the code is not necessary
  197. //----------------------------------------------------------------------------
  198. // Data used for finding the other components we have to deal with.
  199. //
  200. static const GUID* c_guidAtlkComponentClasses [1] =
  201. {
  202. &GUID_DEVCLASS_NETTRANS // Atalk
  203. };
  204. static const LPCTSTR c_apszAtlkComponentIds [1] =
  205. {
  206. c_szInfId_MS_AppleTalk //NETCFG_TRANS_CID_MS_APPLETALK
  207. };
  208. HRESULT CATLKEnv::IsLocalTalkAdaptor(CAdapterInfo* pAdapterInfo, BOOL* pbIsLocalTalk)
  209. // S_OK: LOCALTALK
  210. // S_FALSE: Not
  211. // ERRORs
  212. {
  213. HRESULT hr = S_OK;
  214. CComPtr<INetCfg> spINetCfg;
  215. INetCfgComponent* apINetCfgComponent[1];
  216. apINetCfgComponent[0] = NULL;
  217. BOOL bInitCom = FALSE;
  218. CComPtr<INetCfgComponentBindings> spBindings;
  219. LPCTSTR pszInterface = TEXT("localtalk");
  220. *pbLocalTalk = FALSE;
  221. CHECK_HR(hr = HrCreateAndInitializeINetCfg(
  222. &bInitCom,
  223. (INetCfg**)&spINetCfg,
  224. FALSE, // not to write
  225. 0, // only for write
  226. NULL, // only for write
  227. NULL));
  228. ASSERT(spINetCfg.p);
  229. CHECK_HR(hr = HrFindComponents (
  230. spINetCfg,
  231. 1, // # of components
  232. c_guidAtlkComponentClasses,
  233. c_apszAtlkComponentIds,
  234. (INetCfgComponent**)apINetCfgComponent));
  235. ASSERT(apINetCfgComponent[0]);
  236. CHECK_HR(hr = apINetCfgComponent[0]->QueryInterface(IID_INetCfgComponentBindings, reinterpret_cast<void**>(&spBindings)));
  237. ASSERT(spBindings.p);
  238. hr = pnccBindings->SupportsBindingInterface( NCF_LOWER, pszInterface);
  239. if (S_OK == hr)
  240. {
  241. *pbIsLocalTalk = TRUE;
  242. }
  243. // ignore other values except errors
  244. if(!FAILED(hr))
  245. hr = S_OK;
  246. L_ERR:
  247. if(apINetCfgComponent[0])
  248. {
  249. apINetCfgComponent[0]->Release();
  250. apINetCfgComponent[0] = NULL;
  251. }
  252. return hr;
  253. }
  254. */
  255. HRESULT CATLKEnv::ReloadAdapter(CAdapterInfo* pAdapInfo, bool fOnlyDyn /*=false*/)
  256. {
  257. SOCKADDR_AT address;
  258. SOCKET mysocket = INVALID_SOCKET;
  259. WSADATA wsadata;
  260. BOOL fWSInitialized = FALSE;
  261. HRESULT hr= hrOK;
  262. DWORD wsaerr = 0;
  263. bool fWSInit = false;
  264. CString szPortName;
  265. AI p;
  266. CWaitCursor wait;
  267. Assert(pAdapInfo);
  268. pAdapInfo->m_dynInfo.m_listZones.RemoveAll();
  269. if (!fOnlyDyn)
  270. { //reload registry zone & default zone
  271. RegKey regkey;
  272. CString sz=c_szRegKeyAppletalkAdapter;
  273. sz+=pAdapInfo->m_regInfo.m_szAdapter;
  274. if (ERROR_SUCCESS == regkey.Open(HKEY_LOCAL_MACHINE,
  275. sz, KEY_READ,NULL) )
  276. {
  277. pAdapInfo->m_regInfo.m_listZones.RemoveAll();
  278. regkey.QueryValue( c_szZoneList, pAdapInfo->m_regInfo.m_listZones);
  279. regkey.QueryValue( c_szDefaultZone, pAdapInfo->m_regInfo.m_szDefaultZone);
  280. }
  281. }
  282. // Create the socket/bind
  283. wsaerr = WSAStartup(0x0101, &wsadata);
  284. if ( 0 != wsaerr )
  285. goto Error;
  286. // Winsock successfully initialized
  287. fWSInitialized = TRUE;
  288. mysocket = socket(AF_APPLETALK, SOCK_DGRAM, DDPPROTO_ZIP);
  289. if ( mysocket == INVALID_SOCKET )
  290. {
  291. AddHighLevelErrorStringId(IDS_ERR_FAILED_CONNECT_NETWORK);
  292. goto Error;
  293. }
  294. address.sat_family = AF_APPLETALK;
  295. address.sat_net = 0;
  296. address.sat_node = 0;
  297. address.sat_socket = 0;
  298. wsaerr = bind(mysocket, (struct sockaddr *)&address, sizeof(address));
  299. if ( wsaerr != 0 )
  300. {
  301. AddHighLevelErrorStringId(IDS_ERR_FAILED_CONNECT_NETWORK);
  302. goto Error;
  303. }
  304. hr=_HrGetAndSetNetworkInformation( mysocket, pAdapInfo );
  305. Done:
  306. if ( INVALID_SOCKET != mysocket )
  307. closesocket(mysocket);
  308. if ( fWSInitialized )
  309. WSACleanup();
  310. return hr;
  311. Error:
  312. wsaerr = ::WSAGetLastError();
  313. hr= HRESULT_FROM_WIN32(wsaerr);
  314. AddSystemErrorMessage(hr);
  315. goto Done;
  316. }
  317. HRESULT CATLKEnv::_HrGetAndSetNetworkInformation(SOCKET socket, CAdapterInfo* pAdapInfo)
  318. {
  319. HRESULT hr = FALSE;
  320. CHAR *pZoneBuffer = NULL;
  321. CHAR *pDefParmsBuffer = NULL;
  322. CHAR *pZoneListStart = NULL;
  323. INT BytesNeeded ;
  324. WCHAR *pwDefZone = NULL;
  325. INT ZoneLen = 0;
  326. DWORD wsaerr = 0;
  327. CHAR *pDefZone = NULL;
  328. Assert(pAdapInfo);
  329. LPCTSTR szDevName=pAdapInfo->m_regInfo.m_szDevAdapter;
  330. PWSH_LOOKUP_ZONES pGetNetZones;
  331. PWSH_LOOKUP_NETDEF_ON_ADAPTER pGetNetDefaults;
  332. Assert(NULL != szDevName);
  333. pZoneBuffer = new CHAR [ZONEBUFFER_LEN + sizeof(WSH_LOOKUP_ZONES)];
  334. Assert(NULL != pZoneBuffer);
  335. pGetNetZones = (PWSH_LOOKUP_ZONES)pZoneBuffer;
  336. wcscpy((WCHAR *)(pGetNetZones+1),szDevName);
  337. BytesNeeded = ZONEBUFFER_LEN;
  338. if (m_dwF & ATLK_ONLY_ONADAPTER)
  339. wsaerr = getsockopt(socket, SOL_APPLETALK, SO_LOOKUP_ZONES_ON_ADAPTER,
  340. (char *)pZoneBuffer, &BytesNeeded);
  341. else
  342. wsaerr = getsockopt(socket, SOL_APPLETALK, SO_LOOKUP_ZONES,
  343. (char *)pZoneBuffer, &BytesNeeded);
  344. if ( 0 != wsaerr )
  345. {
  346. int err = WSAGetLastError();
  347. Panic1("WSAGetLastError is %08lx", err);
  348. hr = HRESULT_FROM_WIN32(err);
  349. goto Error;
  350. }
  351. pZoneListStart = pZoneBuffer + sizeof(WSH_LOOKUP_ZONES);
  352. if ( !lstrcmpA(pZoneListStart, "*" ) )
  353. {
  354. goto Done;
  355. }
  356. _AddZones(pZoneListStart,((PWSH_LOOKUP_ZONES)pZoneBuffer)->NoZones,pAdapInfo);
  357. // Get the DefaultZone/NetworkRange Information
  358. pDefParmsBuffer = new CHAR[PARM_BUF_LEN+sizeof(WSH_LOOKUP_NETDEF_ON_ADAPTER)];
  359. Assert(NULL != pDefParmsBuffer);
  360. pGetNetDefaults = (PWSH_LOOKUP_NETDEF_ON_ADAPTER)pDefParmsBuffer;
  361. BytesNeeded = PARM_BUF_LEN + sizeof(WSH_LOOKUP_NETDEF_ON_ADAPTER);
  362. wcscpy((WCHAR*)(pGetNetDefaults+1), szDevName);
  363. pGetNetDefaults->NetworkRangeLowerEnd = pGetNetDefaults->NetworkRangeUpperEnd = 0;
  364. wsaerr = getsockopt(socket, SOL_APPLETALK, SO_LOOKUP_NETDEF_ON_ADAPTER,
  365. (char*)pDefParmsBuffer, &BytesNeeded);
  366. if ( 0 != wsaerr )
  367. {
  368. int err = WSAGetLastError();
  369. Panic1("WSAGetLastError is %08lx", err);
  370. hr = HRESULT_FROM_WIN32(err);
  371. goto Error;
  372. }
  373. pAdapInfo->m_dynInfo.m_dwRangeUpper=pGetNetDefaults->NetworkRangeUpperEnd;
  374. pAdapInfo->m_dynInfo.m_dwRangeLower=pGetNetDefaults->NetworkRangeLowerEnd;
  375. pDefZone = pDefParmsBuffer + sizeof(WSH_LOOKUP_NETDEF_ON_ADAPTER);
  376. ZoneLen = lstrlenA(pDefZone) + 1;
  377. pwDefZone = new WCHAR [sizeof(WCHAR) * ZoneLen];
  378. Assert(NULL != pwDefZone);
  379. // mbstowcs does not work well on FE platforms
  380. // mbstowcs(pwDefZone, pDefZone, ZoneLen);
  381. MultiByteToWideChar(CP_ACP, 0, pDefZone, -1, pwDefZone, ZoneLen);
  382. pAdapInfo->m_dynInfo.m_szDefaultZone=pwDefZone;
  383. Done:
  384. if ( pZoneBuffer != NULL )
  385. delete [] pZoneBuffer;
  386. if ( pwDefZone != NULL )
  387. delete [] pwDefZone;
  388. if ( pDefParmsBuffer != NULL )
  389. delete [] pDefParmsBuffer;
  390. Error:
  391. return hr;
  392. }
  393. void CATLKEnv::_AddZones(
  394. CHAR * szZoneList,
  395. ULONG NumZones,
  396. CAdapterInfo* pAdapterinfo)
  397. {
  398. INT cbAscii = 0;
  399. WCHAR *pszZone = NULL;
  400. CString sz;
  401. Assert(NULL != szZoneList);
  402. Assert(pAdapterinfo);
  403. while ( NumZones-- )
  404. {
  405. cbAscii = lstrlenA(szZoneList) + 1;
  406. pszZone = new WCHAR [sizeof(WCHAR) * cbAscii];
  407. Assert(NULL != pszZone);
  408. // mbstowcs does not work well on FE platforms
  409. // mbstowcs(pszZone, szZoneList, cbAscii);
  410. MultiByteToWideChar(CP_ACP, 0, szZoneList, -1, pszZone, cbAscii);
  411. sz=pszZone;
  412. pAdapterinfo->m_dynInfo.m_listZones.AddTail(sz);
  413. szZoneList += cbAscii;
  414. delete [] pszZone;
  415. }
  416. }
  417. HRESULT CATLKEnv::HrAtlkPnPSwithRouting()
  418. {
  419. HRESULT hr=S_OK;
  420. CServiceManager csm;
  421. CService svr;
  422. ATALK_PNP_EVENT Config;
  423. bool fStartMacPrint = false;
  424. bool fStopMacPrint = false;
  425. memset(&Config, 0, sizeof(ATALK_PNP_EVENT));
  426. CWaitCursor wait;
  427. // notify atlk
  428. Config.PnpMessage = AT_PNP_SWITCH_ROUTING;
  429. if (FAILED(hr=HrSendNdisHandlePnpEvent(NDIS, RECONFIGURE, c_szAtlk, c_szBlank, c_szBlank,
  430. &Config, sizeof(ATALK_PNP_EVENT))))
  431. {
  432. return hr;
  433. }
  434. return hr;
  435. }
  436. HRESULT CATLKEnv::HrAtlkPnPReconfigParams(BOOL bForcePnPOnDefault)
  437. {
  438. HRESULT hr=S_OK;
  439. CServiceManager csm;
  440. CService svr;
  441. ATALK_PNP_EVENT Config;
  442. bool fStartMacPrint = false;
  443. bool fStopMacPrint = false;
  444. AI p;
  445. CAdapterInfo* pAI=NULL;
  446. memset(&Config, 0, sizeof(ATALK_PNP_EVENT));
  447. if ( m_adapterinfolist.empty())
  448. return hr;
  449. //find the default adapter
  450. for ( p=m_adapterinfolist.begin(); p!= m_adapterinfolist.end() ; p++ )
  451. {
  452. pAI = *p;
  453. if (pAI->m_regInfo.m_fDefAdapter)
  454. {
  455. break;
  456. }
  457. }
  458. if(bForcePnPOnDefault && pAI)
  459. {
  460. Config.PnpMessage = AT_PNP_RECONFIGURE_PARMS;
  461. CWaitCursor wait;
  462. // Now submit the reconfig notification
  463. if (FAILED(hr=HrSendNdisHandlePnpEvent(NDIS, RECONFIGURE, c_szAtlk, pAI->m_regInfo.m_szDevAdapter,
  464. c_szBlank,&Config, sizeof(ATALK_PNP_EVENT))))
  465. {
  466. return hr;
  467. }
  468. }
  469. //reconfigure adapters
  470. Config.PnpMessage = AT_PNP_RECONFIGURE_PARMS;
  471. for ( p=m_adapterinfolist.begin(); p!= m_adapterinfolist.end() ; p++ )
  472. {
  473. pAI = *p;
  474. if (pAI->m_fNotifyPnP)
  475. {
  476. // Now submit the reconfig notification
  477. if (FAILED(hr=HrSendNdisHandlePnpEvent(NDIS, RECONFIGURE, c_szAtlk, pAI->m_regInfo.m_szDevAdapter,
  478. c_szBlank,&Config, sizeof(ATALK_PNP_EVENT))))
  479. {
  480. return hr;
  481. }
  482. // Clear the dirty state
  483. pAI->m_fNotifyPnP=false;
  484. }
  485. }
  486. Trace1("CATLKEnv::HrAtlkReconfig",hr);
  487. return hr;
  488. }