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.

845 lines
22 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2001.
  5. //
  6. // File: I N B O U N D . C P P
  7. //
  8. // Contents: Implements the inbound connection object.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 12 Nov 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "inbound.h"
  18. #include "nccom.h"
  19. #include "ncnetcon.h"
  20. #include "..\conman\conman.h"
  21. LONG g_CountIncomingConnectionObjects;
  22. static const CLSID CLSID_InboundConnectionUi =
  23. {0x7007ACC3,0x3202,0x11D1,{0xAA,0xD2,0x00,0x80,0x5F,0xC1,0x27,0x0E}};
  24. extern const GUID GUID_InboundConfigConnectionId =
  25. { /* 89150b9f-9b5c-11d1-a91f-00805fc1270e */
  26. 0x89150b9f,
  27. 0x9b5c,
  28. 0x11d1,
  29. {0xa9, 0x1f, 0x00, 0x80, 0x5f, 0xc1, 0x27, 0x0e}
  30. };
  31. //+---------------------------------------------------------------------------
  32. //
  33. // Member: CInboundConnection::CreateInstance
  34. //
  35. // Purpose: Creates an inbound connection object.
  36. //
  37. // Arguments:
  38. // fIsConfigConnection [in]
  39. // hRasSrvConn [in]
  40. // pszwName [in]
  41. // pguidId [in]
  42. // riid [in]
  43. // ppv [in]
  44. //
  45. // Returns: S_OK or an error code.
  46. //
  47. // Author: shaunco 12 Nov 1997
  48. //
  49. // Notes:
  50. //
  51. HRESULT
  52. CInboundConnection::CreateInstance (
  53. BOOL fIsConfigConnection,
  54. HRASSRVCONN hRasSrvConn,
  55. PCWSTR pszwName,
  56. PCWSTR pszwDeviceName,
  57. DWORD dwType,
  58. const GUID* pguidId,
  59. REFIID riid,
  60. void** ppv)
  61. {
  62. Assert (FIff(fIsConfigConnection, !hRasSrvConn));
  63. Assert (pguidId);
  64. HRESULT hr = E_OUTOFMEMORY;
  65. CInboundConnection* pObj;
  66. pObj = new CComObject <CInboundConnection>;
  67. if (pObj)
  68. {
  69. if (fIsConfigConnection)
  70. {
  71. // No need to start the service (FALSE) since we're being
  72. // created as a result of the service running.
  73. //
  74. pObj->InitializeAsConfigConnection (FALSE);
  75. }
  76. else
  77. {
  78. // Initialize our members.
  79. //
  80. pObj->m_fIsConfigConnection = FALSE;
  81. pObj->m_hRasSrvConn = hRasSrvConn;
  82. pObj->SetName (pszwName);
  83. pObj->SetDeviceName (pszwDeviceName);
  84. switch (dwType)
  85. {
  86. case RASSRVUI_MODEM:
  87. pObj->m_MediaType = NCM_PHONE;
  88. break;
  89. case RASSRVUI_VPN:
  90. pObj->m_MediaType = NCM_TUNNEL;
  91. break;
  92. case RASSRVUI_DCC:
  93. pObj->m_MediaType = NCM_DIRECT;
  94. break;
  95. default:
  96. pObj->m_MediaType = NCM_PHONE;
  97. break;
  98. }
  99. pObj->m_guidId = *pguidId;
  100. // We are now a full-fledged object.
  101. //
  102. pObj->m_fInitialized = TRUE;
  103. }
  104. // Do the standard CComCreator::CreateInstance stuff.
  105. //
  106. pObj->SetVoid (NULL);
  107. pObj->InternalFinalConstructAddRef ();
  108. hr = pObj->FinalConstruct ();
  109. pObj->InternalFinalConstructRelease ();
  110. if (SUCCEEDED(hr))
  111. {
  112. INetConnection* pCon = static_cast<INetConnection*>(pObj);
  113. hr = pCon->QueryInterface (riid, ppv);
  114. }
  115. if (FAILED(hr))
  116. {
  117. delete pObj;
  118. }
  119. }
  120. TraceError ("CInboundConnection::CreateInstance", hr);
  121. return hr;
  122. }
  123. CInboundConnection::CInboundConnection()
  124. {
  125. InterlockedIncrement (&g_CountIncomingConnectionObjects);
  126. m_fIsConfigConnection = FALSE;
  127. m_hRasSrvConn = NULL;
  128. m_MediaType = NCM_NONE;
  129. m_fInitialized = FALSE;
  130. }
  131. CInboundConnection::~CInboundConnection()
  132. {
  133. InterlockedDecrement (&g_CountIncomingConnectionObjects);
  134. }
  135. HRESULT
  136. CInboundConnection::GetCharacteristics (
  137. DWORD* pdwFlags)
  138. {
  139. HRESULT hr = S_OK;
  140. // Validate parameters.
  141. //
  142. if (!pdwFlags)
  143. {
  144. hr = E_POINTER;
  145. }
  146. else if (!m_fInitialized)
  147. {
  148. hr = E_UNEXPECTED;
  149. }
  150. else
  151. {
  152. *pdwFlags = NCCF_INCOMING_ONLY | NCCF_ALL_USERS;
  153. // For the configuration connection, we only allow removal.
  154. // Don't query for NCCF_SHOW_ICON (below) because this connection
  155. // never get's connected.
  156. //
  157. if (m_fIsConfigConnection)
  158. {
  159. *pdwFlags |= NCCF_ALLOW_REMOVAL;
  160. }
  161. else
  162. {
  163. BOOL fShowIcon;
  164. DWORD dwErr = RasSrvQueryShowIcon (&fShowIcon);
  165. TraceError ("RasSrvQueryShowIcon", HRESULT_FROM_WIN32(dwErr));
  166. if ((ERROR_SUCCESS == dwErr) && fShowIcon)
  167. {
  168. *pdwFlags |= NCCF_SHOW_ICON;
  169. }
  170. }
  171. }
  172. TraceError ("CInboundConnection::GetCharacteristics", hr);
  173. return hr;
  174. }
  175. HRESULT
  176. CInboundConnection::GetStatus (
  177. NETCON_STATUS* pStatus)
  178. {
  179. Assert (pStatus);
  180. HRESULT hr = S_OK;
  181. // Initialize the output parameter.
  182. //
  183. *pStatus = NCS_DISCONNECTED;
  184. if (!m_fIsConfigConnection)
  185. {
  186. BOOL fConnected;
  187. DWORD dwErr = RasSrvIsConnectionConnected (m_hRasSrvConn,
  188. &fConnected);
  189. TraceError ("RasSrvIsConnectionConnected",
  190. HRESULT_FROM_WIN32(dwErr));
  191. if ((ERROR_SUCCESS == dwErr) && fConnected)
  192. {
  193. *pStatus = NCS_CONNECTED;
  194. }
  195. }
  196. TraceError ("CInboundConnection::GetStatus", hr);
  197. return hr;
  198. }
  199. //+---------------------------------------------------------------------------
  200. // INetConnection
  201. //
  202. STDMETHODIMP
  203. CInboundConnection::Connect ()
  204. {
  205. return E_NOTIMPL;
  206. }
  207. STDMETHODIMP
  208. CInboundConnection::Disconnect ()
  209. {
  210. HRESULT hr;
  211. // We don't expect to be called on Disconnect if we are the
  212. // configuration connection object. Why? Because this object never
  213. // reports itself as connected through GetStatus.
  214. //
  215. if (!m_fInitialized || m_fIsConfigConnection)
  216. {
  217. hr = E_UNEXPECTED;
  218. }
  219. else
  220. {
  221. DWORD dwErr = RasSrvHangupConnection (m_hRasSrvConn);
  222. hr = HRESULT_FROM_WIN32 (dwErr);
  223. TraceError ("RasSrvHangupConnection", hr);
  224. // Disconnect means this object is no longer valid.
  225. // Indicate so by uniniatializing ourselves (so subsequent
  226. // method calls will fail) and returning S_OBJECT_NO_LONGER_VALID.
  227. //
  228. m_fInitialized = FALSE;
  229. hr = S_OBJECT_NO_LONGER_VALID;
  230. }
  231. TraceError ("CInboundConnection::Disconnect",
  232. (S_OBJECT_NO_LONGER_VALID == hr) ? S_OK : hr);
  233. return hr;
  234. }
  235. STDMETHODIMP
  236. CInboundConnection::Delete ()
  237. {
  238. HRESULT hr;
  239. // We don't expect to be called on Remove if we are not the
  240. // configuration connection object. Why? Because connected objects never
  241. // report themselves as removeable through GetCharacteristics.
  242. //
  243. if (!m_fInitialized || !m_fIsConfigConnection)
  244. {
  245. hr = E_UNEXPECTED;
  246. }
  247. else
  248. {
  249. DWORD dwErr = RasSrvCleanupService ();
  250. hr = HRESULT_FROM_WIN32 (dwErr);
  251. TraceError ("RasSrvCleanupService", hr);
  252. }
  253. TraceError ("CInboundConnection::Delete", hr);
  254. return hr;
  255. }
  256. STDMETHODIMP
  257. CInboundConnection::Duplicate (
  258. PCWSTR pszwDuplicateName,
  259. INetConnection** ppCon)
  260. {
  261. return E_NOTIMPL;
  262. }
  263. STDMETHODIMP
  264. CInboundConnection::GetProperties (
  265. NETCON_PROPERTIES** ppProps)
  266. {
  267. HRESULT hr = S_OK;
  268. // Validate parameters.
  269. //
  270. if (!ppProps)
  271. {
  272. hr = E_POINTER;
  273. }
  274. else if (!m_fInitialized)
  275. {
  276. hr = E_UNEXPECTED;
  277. }
  278. else
  279. {
  280. // Initialize the output parameter.
  281. //
  282. *ppProps = NULL;
  283. NETCON_PROPERTIES* pProps;
  284. hr = HrCoTaskMemAlloc (sizeof (NETCON_PROPERTIES),
  285. reinterpret_cast<void**>(&pProps));
  286. if (SUCCEEDED(hr))
  287. {
  288. HRESULT hrT;
  289. ZeroMemory (pProps, sizeof (NETCON_PROPERTIES));
  290. // guidId
  291. //
  292. pProps->guidId = m_guidId;
  293. // pszwName
  294. //
  295. hrT = HrCoTaskMemAllocAndDupSz (PszwName(),
  296. &pProps->pszwName);
  297. if (FAILED(hrT))
  298. {
  299. hr = hrT;
  300. }
  301. // pszwDeviceName
  302. //
  303. if (!m_fIsConfigConnection)
  304. {
  305. hrT = HrCoTaskMemAllocAndDupSz (PszwDeviceName(),
  306. &pProps->pszwDeviceName);
  307. if (FAILED(hrT))
  308. {
  309. hr = hrT;
  310. }
  311. }
  312. // Status
  313. //
  314. hrT = GetStatus (&pProps->Status);
  315. if (FAILED(hrT))
  316. {
  317. hr = hrT;
  318. }
  319. // MediaType
  320. //
  321. pProps->MediaType = m_MediaType;
  322. // dwCharacter
  323. //
  324. hrT = GetCharacteristics (&pProps->dwCharacter);
  325. if (FAILED(hrT))
  326. {
  327. hr = hrT;
  328. }
  329. // clsidThisObject
  330. //
  331. pProps->clsidThisObject = CLSID_InboundConnection;
  332. // clsidUiObject
  333. //
  334. pProps->clsidUiObject = CLSID_InboundConnectionUi;
  335. // Assign the output parameter or cleanup if we had any failures.
  336. //
  337. if (SUCCEEDED(hr))
  338. {
  339. *ppProps = pProps;
  340. }
  341. else
  342. {
  343. Assert (NULL == *ppProps);
  344. FreeNetconProperties (pProps);
  345. }
  346. }
  347. }
  348. TraceError ("CInboundConnection::GetProperties", hr);
  349. return hr;
  350. }
  351. STDMETHODIMP
  352. CInboundConnection::GetUiObjectClassId (
  353. CLSID* pclsid)
  354. {
  355. HRESULT hr = S_OK;
  356. // Validate parameters.
  357. //
  358. if (!pclsid)
  359. {
  360. hr = E_POINTER;
  361. }
  362. else if (!m_fInitialized)
  363. {
  364. hr = E_UNEXPECTED;
  365. }
  366. else
  367. {
  368. *pclsid = CLSID_InboundConnectionUi;
  369. }
  370. TraceError ("CInboundConnection::GetUiObjectClassId", hr);
  371. return hr;
  372. }
  373. STDMETHODIMP
  374. CInboundConnection::Rename (
  375. PCWSTR pszwNewName)
  376. {
  377. return E_NOTIMPL;
  378. }
  379. //+---------------------------------------------------------------------------
  380. // INetInboundConnection
  381. //
  382. STDMETHODIMP
  383. CInboundConnection::GetServerConnectionHandle (
  384. ULONG_PTR* phRasSrvConn)
  385. {
  386. HRESULT hr = S_OK;
  387. // If this is the configuration connection, the server connection
  388. // handle better be zero. This is used by the UI object so that it
  389. // knows it is the configuration connection.
  390. //
  391. Assert (FIff (m_fIsConfigConnection, !m_hRasSrvConn));
  392. // Because MIDL doesn't know about HRASSRVCONN's, just make sure
  393. // it is the same size as the ULONG_PTR we pass it as.
  394. //
  395. Assert (sizeof (m_hRasSrvConn) == sizeof (*phRasSrvConn));
  396. *phRasSrvConn = reinterpret_cast<ULONG_PTR>(m_hRasSrvConn);
  397. TraceError ("CInboundConnection::GetServerConnectionHandle", hr);
  398. return hr;
  399. }
  400. STDMETHODIMP
  401. CInboundConnection::InitializeAsConfigConnection (
  402. BOOL fStartRemoteAccess)
  403. {
  404. Assert (!m_fInitialized);
  405. // Initialize our members.
  406. //
  407. m_fIsConfigConnection = TRUE;
  408. m_hRasSrvConn = 0;
  409. SetName (SzLoadIds (IDS_INBOUND_CONFIG_CONNECTION_NAME));
  410. SetDeviceName (NULL);
  411. m_MediaType = NCM_NONE;
  412. m_guidId = GUID_InboundConfigConnectionId;
  413. // We are now a full-fledged object.
  414. //
  415. m_fInitialized = TRUE;
  416. // Start the service if we were told.
  417. //
  418. HRESULT hr = S_OK;
  419. if (fStartRemoteAccess)
  420. {
  421. DWORD dwErr = RasSrvInitializeService ();
  422. hr = HRESULT_FROM_WIN32 (dwErr);
  423. TraceError ("RasSrvInitializeService", hr);
  424. }
  425. TraceError ("CInboundConnection::InitializeAsConfigConnection", hr);
  426. return hr;
  427. }
  428. //+---------------------------------------------------------------------------
  429. // IPersistNetConnection
  430. //
  431. STDMETHODIMP
  432. CInboundConnection::GetClassID (
  433. CLSID* pclsid)
  434. {
  435. HRESULT hr = S_OK;
  436. // Validate parameters.
  437. //
  438. if (!pclsid)
  439. {
  440. hr = E_POINTER;
  441. }
  442. else
  443. {
  444. *pclsid = CLSID_InboundConnection;
  445. }
  446. TraceError ("CInboundConnection::GetClassID", hr);
  447. return hr;
  448. }
  449. static const WCHAR c_chwLead = 0x19;
  450. static const WCHAR c_chwTrail = 0x07;
  451. STDMETHODIMP
  452. CInboundConnection::GetSizeMax (
  453. ULONG* pcbSize)
  454. {
  455. HRESULT hr = S_OK;
  456. // Validate parameters.
  457. //
  458. if (!pcbSize)
  459. {
  460. hr = E_POINTER;
  461. }
  462. else if (!m_fInitialized)
  463. {
  464. hr = E_UNEXPECTED;
  465. }
  466. else
  467. {
  468. // Size the buffer for the following form:
  469. // +--------------------------------------------------------------+
  470. // |0x19<m_fIsConfigConnection><m_hRasSrvConn><m_strName>...\00x07|
  471. // +--------------------------------------------------------------+
  472. //
  473. // m_strDeviceName may be empty, in which case we want to still
  474. // store the null-terminator. Don't use PszwDeviceName() as it
  475. // returns NULL when m_strDeviceName is empty.
  476. //
  477. *pcbSize = sizeof (c_chwLead) +
  478. sizeof (m_fIsConfigConnection) +
  479. sizeof (m_hRasSrvConn) +
  480. CbOfSzAndTerm (PszwName()) +
  481. CbOfSzAndTerm (m_strDeviceName.c_str()) +
  482. sizeof (m_MediaType) +
  483. sizeof (m_guidId) +
  484. sizeof (c_chwTrail);
  485. }
  486. TraceError ("CInboundConnection::GetSizeMax", hr);
  487. return hr;
  488. }
  489. STDMETHODIMP
  490. CInboundConnection::Load (
  491. const BYTE* pbBuf,
  492. ULONG cbSize)
  493. {
  494. // The theoretical minimum size for the buffer. Computed
  495. // as the number of bytes in the following minimum string:
  496. //
  497. const ULONG c_cbSizeMin = sizeof (c_chwLead) +
  498. sizeof (m_fIsConfigConnection) +
  499. sizeof (m_hRasSrvConn) +
  500. 4 + // 4 bytes for 1 UNICODE char and NULL
  501. 2 + // 1 UNICODE NULL for empty device name
  502. sizeof (m_MediaType) +
  503. sizeof (m_guidId) +
  504. sizeof (c_chwTrail);
  505. HRESULT hr = E_INVALIDARG;
  506. // Validate parameters.
  507. //
  508. if (!pbBuf)
  509. {
  510. hr = E_POINTER;
  511. }
  512. else if (cbSize < c_cbSizeMin)
  513. {
  514. hr = E_INVALIDARG;
  515. }
  516. // We can only accept one call on this method and only if we're not
  517. // already initialized.
  518. //
  519. else if (m_fInitialized)
  520. {
  521. hr = E_UNEXPECTED;
  522. }
  523. else
  524. {
  525. // The buffer *should* look like this:
  526. // +--------------------------------------------------------------+
  527. // |0x19<m_fIsConfigConnection><m_hRasSrvConn><m_strName>...\00x07|
  528. // +--------------------------------------------------------------+
  529. //
  530. const WCHAR* pchw;
  531. const WCHAR* pchwMax;
  532. const BOOL* pfIsConfigConnection;
  533. BOOL fIsConfigConnection;
  534. const HRASSRVCONN* phRasSrvCon;
  535. HRASSRVCONN hRasSrvConn;
  536. PCWSTR pszwName;
  537. PCWSTR pszwDeviceName;
  538. const NETCON_MEDIATYPE* pMediaType;
  539. const GUID* pguidTemp;
  540. const GUID* pguidId;
  541. NETCON_MEDIATYPE MediaType;
  542. pchw = reinterpret_cast<const WCHAR*>(pbBuf);
  543. // The last valid pointer for the embedded strings.
  544. //
  545. pchwMax = reinterpret_cast<const WCHAR*>(pbBuf + cbSize
  546. - (sizeof (m_MediaType) +
  547. sizeof (m_guidId) +
  548. sizeof (c_chwTrail)));
  549. // Check our lead byte.
  550. //
  551. if (c_chwLead != *pchw)
  552. {
  553. goto finished;
  554. }
  555. pchw++;
  556. // Get m_fIsConfigConnection.
  557. //
  558. pfIsConfigConnection = reinterpret_cast<const BOOL*>(pchw);
  559. CopyMemory(&fIsConfigConnection, pfIsConfigConnection, sizeof(fIsConfigConnection));
  560. pfIsConfigConnection++;
  561. // Get m_hRasSrvConn.
  562. //
  563. phRasSrvCon = reinterpret_cast<const HRASSRVCONN*>(pfIsConfigConnection);
  564. CopyMemory(&hRasSrvConn, phRasSrvCon, sizeof(hRasSrvConn));
  565. phRasSrvCon++;
  566. // Get m_strName. Search for the terminating null and make sure
  567. // we find it before the end of the buffer. Using lstrlen to skip
  568. // the string can result in an AV in the event the string is not
  569. // actually null-terminated.
  570. //
  571. pchw = reinterpret_cast<const WCHAR*>(phRasSrvCon);
  572. for (pszwName = pchw; ; pchw++)
  573. {
  574. if (pchw >= pchwMax)
  575. {
  576. goto finished;
  577. }
  578. if (0 == *pchw)
  579. {
  580. pchw++;
  581. break;
  582. }
  583. }
  584. // Get m_strDeviceName. Search for the terminating null and make
  585. // sure we find it before the end of the buffer.
  586. //
  587. for (pszwDeviceName = pchw; ; pchw++)
  588. {
  589. if (pchw >= pchwMax)
  590. {
  591. goto finished;
  592. }
  593. if (0 == *pchw)
  594. {
  595. pchw++;
  596. break;
  597. }
  598. }
  599. // Get m_MediaType.
  600. //
  601. pMediaType = reinterpret_cast<const NETCON_MEDIATYPE*>(pchw);
  602. CopyMemory(&MediaType, pMediaType, sizeof(MediaType));
  603. pMediaType++;
  604. // Get m_guidId.
  605. //
  606. pguidTemp = reinterpret_cast<const GUID*>(pMediaType);
  607. pguidId = pguidTemp;
  608. pguidTemp++;
  609. // Check our trail byte.
  610. //
  611. pchw = reinterpret_cast<const WCHAR*>(pguidTemp);
  612. if (c_chwTrail != *pchw)
  613. {
  614. goto finished;
  615. }
  616. // If we're the configuration object, we can't have a connection
  617. // HANDLE and vice-versa.
  618. //
  619. if ((fIsConfigConnection && hRasSrvConn) ||
  620. (!fIsConfigConnection && !hRasSrvConn))
  621. {
  622. goto finished;
  623. }
  624. // We are now a full-fledged object.
  625. //
  626. m_fIsConfigConnection = fIsConfigConnection;
  627. m_hRasSrvConn = hRasSrvConn;
  628. SetName (pszwName);
  629. SetDeviceName (pszwDeviceName);
  630. m_MediaType = MediaType;
  631. CopyMemory(&m_guidId, pguidId, sizeof(m_guidId));
  632. m_fInitialized = TRUE;
  633. hr = S_OK;
  634. finished:
  635. ;
  636. }
  637. TraceError ("CInboundConnection::Load", hr);
  638. return hr;
  639. }
  640. STDMETHODIMP
  641. CInboundConnection::Save (
  642. BYTE* pbBuf,
  643. ULONG cbSize)
  644. {
  645. HRESULT hr = S_OK;
  646. // Validate parameters.
  647. //
  648. if (!pbBuf)
  649. {
  650. hr = E_POINTER;
  651. }
  652. else if (!m_fInitialized)
  653. {
  654. hr = E_UNEXPECTED;
  655. }
  656. else
  657. {
  658. // Make sure the user's buffer is big enough.
  659. //
  660. ULONG cbSizeRequired;
  661. SideAssert (SUCCEEDED(GetSizeMax(&cbSizeRequired)));
  662. if (cbSize < cbSizeRequired)
  663. {
  664. hr = E_INVALIDARG;
  665. }
  666. else
  667. {
  668. // Make the buffer look like this when we're done:
  669. // +--------------------------------------------------------------+
  670. // |0x19<m_fIsConfigConnection><m_hRasSrvConn><m_strName>...\00x07|
  671. // +--------------------------------------------------------------+
  672. //
  673. WCHAR* pchw = reinterpret_cast<WCHAR*>(pbBuf);
  674. // Put our lead byte.
  675. //
  676. *pchw = c_chwLead;
  677. pchw++;
  678. // Put m_fIsConfigConnection.
  679. //
  680. BOOL* pfIsConfigConnection =
  681. reinterpret_cast<BOOL*>(pchw);
  682. CopyMemory(pfIsConfigConnection, &m_fIsConfigConnection, sizeof(m_fIsConfigConnection));
  683. pfIsConfigConnection++;
  684. // Put m_hRasSrvConn.
  685. //
  686. HRASSRVCONN* phRasSrvCon =
  687. reinterpret_cast<HRASSRVCONN*>(pfIsConfigConnection);
  688. CopyMemory(phRasSrvCon, &m_hRasSrvConn, sizeof(m_hRasSrvConn));
  689. phRasSrvCon++;
  690. // Put m_strName.
  691. //
  692. pchw = reinterpret_cast<WCHAR*>(phRasSrvCon);
  693. lstrcpyW (pchw, PszwName());
  694. pchw += lstrlenW (PszwName()) + 1;
  695. // Put m_strDeviceName.
  696. //
  697. lstrcpyW (pchw, m_strDeviceName.c_str());
  698. pchw += m_strDeviceName.length() + 1;
  699. // Put m_MediaType.
  700. //
  701. NETCON_MEDIATYPE* pMediaType = reinterpret_cast<NETCON_MEDIATYPE*>(pchw);
  702. CopyMemory(pMediaType, &m_MediaType, sizeof(m_MediaType));
  703. pMediaType++;
  704. // Put m_guidId.
  705. //
  706. GUID* pguidId = reinterpret_cast<GUID*>(pMediaType);
  707. CopyMemory(pguidId, &m_guidId, sizeof(m_guidId));
  708. pguidId++;
  709. // Put our trail byte.
  710. //
  711. pchw = reinterpret_cast<WCHAR*>(pguidId);
  712. *pchw = c_chwTrail;
  713. pchw++;
  714. AssertSz (pbBuf + cbSizeRequired == (BYTE*)pchw,
  715. "pch isn't pointing where it should be.");
  716. }
  717. }
  718. TraceError ("CInboundConnection::Save", hr);
  719. return hr;
  720. }
  721. #define ID_DEVICE_DATABASE 1
  722. #define ID_MISC_DATABASE 8
  723. //+---------------------------------------------------------------------------
  724. //
  725. // Function: IconStateChanged
  726. //
  727. // Purpose: Fires an event to notify NetShell of a Change occuring in an
  728. // incoming connection.
  729. //
  730. // Arguments:
  731. //
  732. // Returns: S_OK on success; error otherwise
  733. //
  734. // Author: ckotze 25 September 2000
  735. //
  736. // Notes:
  737. //
  738. HRESULT CInboundConnection::IconStateChanged()
  739. {
  740. HRESULT hr = S_OK;
  741. IncomingEventNotify(REFRESH_ALL, NULL, NULL, NULL);
  742. return hr;
  743. }