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.

901 lines
22 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : Devices.cpp //
  3. // //
  4. // DESCRIPTION : Fax Devices MMC node. //
  5. // //
  6. // AUTHOR : yossg //
  7. // //
  8. // HISTORY : //
  9. // Sep 22 1999 yossg Create //
  10. // Dec 1 1999 yossg Change totaly for new mockup version 0.7 //
  11. // Aug 3 2000 yossg Add Device status real-time notification //
  12. // Oct 17 2000 yossg //
  13. // Windows XP //
  14. // Feb 14 2001 yossg Add Manual Receive support //
  15. // //
  16. // Copyright (C) 1999 - 2000 Microsoft Corporation All Rights Reserved //
  17. /////////////////////////////////////////////////////////////////////////////
  18. #include "StdAfx.h"
  19. #include "FaxServer.h"
  20. #include "FaxServerNode.h"
  21. #include "DevicesAndProviders.h"
  22. #include "Devices.h"
  23. #include "Device.h"
  24. #include "FaxMMCPropertyChange.h"
  25. #include "Icons.h"
  26. #include "oaidl.h"
  27. /////////////////////////////////////////////////////////////////////////////
  28. // {E6246051-92B4-42d1-9EA4-A7FD132A63F0}
  29. static const GUID CFaxDevicesNodeGUID_NODETYPE =
  30. { 0xe6246051, 0x92b4, 0x42d1, { 0x9e, 0xa4, 0xa7, 0xfd, 0x13, 0x2a, 0x63, 0xf0 } };
  31. const GUID* CFaxDevicesNode::m_NODETYPE = &CFaxDevicesNodeGUID_NODETYPE;
  32. const OLECHAR* CFaxDevicesNode::m_SZNODETYPE = OLESTR("E6246051-92B4-42d1-9EA4-A7FD132A63F0");
  33. const CLSID* CFaxDevicesNode::m_SNAPIN_CLASSID = &CLSID_Snapin;
  34. CColumnsInfo CFaxDevicesNode::m_ColsInfo;
  35. /*
  36. - CFaxDevicesNode::InsertColumns
  37. -
  38. * Purpose:
  39. * Adds columns to the default result pane.
  40. *
  41. * Arguments:
  42. * [in] pHeaderCtrl - IHeaderCtrl in the console-provided default result view pane
  43. *
  44. * Return:
  45. * OLE error code
  46. */
  47. HRESULT
  48. CFaxDevicesNode::InsertColumns(IHeaderCtrl *pHeaderCtrl)
  49. {
  50. HRESULT hRc = S_OK;
  51. DEBUG_FUNCTION_NAME( _T("CFaxDevicesNode::InsertColumns"));
  52. static ColumnsInfoInitData ColumnsInitData[] =
  53. {
  54. {IDS_DEVICES_COL1, FXS_WIDE_COLUMN_WIDTH},
  55. {IDS_DEVICES_COL2, AUTO_WIDTH},
  56. {IDS_DEVICES_COL3, AUTO_WIDTH},
  57. {IDS_DEVICES_COL4, AUTO_WIDTH},
  58. {IDS_DEVICES_COL5, AUTO_WIDTH},
  59. {IDS_DEVICES_COL6, AUTO_WIDTH},
  60. {IDS_DEVICES_COL7, AUTO_WIDTH},
  61. {LAST_IDS, 0}
  62. };
  63. hRc = m_ColsInfo.InsertColumnsIntoMMC(pHeaderCtrl,
  64. _Module.GetResourceInstance(),
  65. ColumnsInitData);
  66. CHECK_RETURN_VALUE_AND_PRINT_DEBUG (_T("m_ColsInfo.InsertColumnsIntoMMC"))
  67. Cleanup:
  68. return(hRc);
  69. }
  70. /*
  71. - CFaxDevicesNode::initRPC
  72. -
  73. * Purpose:
  74. * Initiates the configuration structure from RPC get Call.
  75. *
  76. * Arguments:
  77. *
  78. * Return:
  79. * OLE error code
  80. */
  81. HRESULT CFaxDevicesNode::InitRPC( )
  82. {
  83. DEBUG_FUNCTION_NAME( _T("CppFaxDevicesNode::InitRPC"));
  84. HRESULT hRc = S_OK;
  85. DWORD ec = ERROR_SUCCESS;
  86. CFaxServer * pFaxServer = NULL;
  87. //
  88. // get Fax Handle
  89. //
  90. pFaxServer = ((CFaxServerNode *)GetRootNode())->GetFaxServer();
  91. ATLASSERT(pFaxServer);
  92. if (!pFaxServer->GetFaxServerHandle())
  93. {
  94. ec= GetLastError();
  95. DebugPrintEx(
  96. DEBUG_ERR,
  97. _T("Failed to GetFaxServerHandle. (ec: %ld)"),
  98. ec);
  99. goto Error;
  100. }
  101. //
  102. // Retrieve the fax devices configuration
  103. //
  104. if (!FaxEnumPortsEx(pFaxServer->GetFaxServerHandle(),
  105. &m_pFaxDevicesConfig,
  106. &m_dwNumOfDevices))
  107. {
  108. ec = GetLastError();
  109. DebugPrintEx(
  110. DEBUG_ERR,
  111. _T("Fail to get devices configuration. (ec: %ld)"),
  112. ec);
  113. if (IsNetworkError(ec))
  114. {
  115. DebugPrintEx(
  116. DEBUG_ERR,
  117. _T("Network Error was found. (ec: %ld)"),
  118. ec);
  119. pFaxServer->Disconnect();
  120. }
  121. goto Error;
  122. }
  123. //For max verification
  124. ATLASSERT(m_pFaxDevicesConfig);
  125. ATLASSERT(FXS_ITEMS_NEVER_COUNTED != m_dwNumOfDevices);
  126. ATLASSERT(ERROR_SUCCESS == ec);
  127. DebugPrintEx( DEBUG_MSG,
  128. _T("Succeed to get devices configuration."));
  129. goto Exit;
  130. Error:
  131. ATLASSERT(ERROR_SUCCESS != ec);
  132. hRc = HRESULT_FROM_WIN32(ec);
  133. //
  134. // allow refresh in case of failure
  135. //
  136. m_dwNumOfDevices = 0;
  137. NodeMsgBox(GetFaxServerErrorMsg(ec));
  138. Exit:
  139. return (hRc);
  140. }
  141. /*
  142. - CFaxDevicesNode::PopulateScopeChildrenList
  143. -
  144. * Purpose:
  145. * Create all the Fax Devices nodes
  146. *
  147. * Arguments:
  148. *
  149. * Return:
  150. * OLE error code
  151. * Actually it is the last OLE error code that ocoured
  152. * during processing this method.
  153. */
  154. HRESULT CFaxDevicesNode::PopulateScopeChildrenList()
  155. {
  156. DEBUG_FUNCTION_NAME( _T("CFaxDevicesNode::PopulateScopeChildrenList"));
  157. HRESULT hRc = S_OK;
  158. CFaxServer * pFaxServer = NULL;
  159. CFaxDeviceNode * pDevice;
  160. DWORD i;
  161. //
  162. // Get the Config. structure
  163. //
  164. hRc = InitRPC();
  165. if (FAILED(hRc))
  166. {
  167. //DebugPrint and MsgBox by called func.
  168. //to be safe actually done by InitRPC on error.
  169. m_pFaxDevicesConfig = NULL;
  170. goto Exit; //!!!
  171. }
  172. ATLASSERT(NULL != m_pFaxDevicesConfig);
  173. for ( i = 0; i < m_dwNumOfDevices; i++ )
  174. {
  175. pDevice = NULL;
  176. pDevice = new CFaxDeviceNode(
  177. this,
  178. m_pComponentData);
  179. if (!pDevice)
  180. {
  181. hRc = E_OUTOFMEMORY;
  182. NodeMsgBox(IDS_MEMORY);
  183. DebugPrintEx(
  184. DEBUG_ERR,
  185. TEXT("Out of memory. (hRc: %08X)"),
  186. hRc);
  187. goto Error;
  188. }
  189. else
  190. {
  191. hRc = pDevice->Init( &m_pFaxDevicesConfig[i]);
  192. if (FAILED(hRc))
  193. {
  194. DebugPrintEx(
  195. DEBUG_ERR,
  196. TEXT("Fail to Init() device members. (hRc: %08X)"),
  197. hRc);
  198. // NodeMsgBox(IDS_FAILTOADD_DEVICES); by called func.
  199. goto Error;
  200. }
  201. pDevice->InitParentNode(this);
  202. //
  203. // Get correct icon
  204. //
  205. if ( m_pFaxDevicesConfig[i].dwStatus & FAX_DEVICE_STATUS_POWERED_OFF)
  206. {
  207. pDevice->SetIcons(IMAGE_DEVICE_POWERED_OFF, IMAGE_DEVICE_POWERED_OFF);
  208. }
  209. else
  210. {
  211. pDevice->SetIcons(IMAGE_DEVICE, IMAGE_DEVICE);
  212. }
  213. hRc = AddChild(pDevice, &pDevice->m_scopeDataItem);
  214. if (FAILED(hRc))
  215. {
  216. DebugPrintEx(
  217. DEBUG_ERR,
  218. TEXT("Fail to add device to the scope pane. (hRc: %08X)"),
  219. hRc);
  220. NodeMsgBox(IDS_FAILTOADD_DEVICES);
  221. goto Error;
  222. }
  223. else
  224. {
  225. pDevice = NULL;
  226. }
  227. }
  228. }
  229. //
  230. // Create the Server Device changes notification window
  231. //
  232. if (!m_bIsCollectingDeviceNotification)
  233. {
  234. pFaxServer = ((CFaxServerNode *)GetRootNode())->GetFaxServer();
  235. ATLASSERT(pFaxServer);
  236. //
  237. // set pointer to device node
  238. // Try to create the window
  239. // and Register to Event Notifications
  240. //
  241. hRc = pFaxServer->RegisterForDeviceNotifications(this);
  242. if (S_OK != hRc)
  243. {
  244. DebugPrintEx(
  245. DEBUG_ERR,
  246. TEXT("Fail to RegisterForDeviceNotifications"));
  247. //
  248. // Populate should succeed here
  249. //
  250. hRc = S_OK;
  251. goto Exit;
  252. }
  253. //
  254. // Update boolean member
  255. //
  256. m_bIsCollectingDeviceNotification = TRUE;
  257. DebugPrintEx(
  258. DEBUG_MSG,
  259. _T("Succeed to create Device Status Server Event notification window"));
  260. }
  261. ATLASSERT(S_OK == hRc);
  262. goto Exit;
  263. Error:
  264. ATLASSERT(S_OK != hRc);
  265. //
  266. //Get Rid
  267. //
  268. {
  269. //from the last one
  270. if ( NULL != pDevice ) //(if new succeeded)
  271. {
  272. delete pDevice;
  273. }
  274. //from all the previous (if there are)
  275. int j = m_ScopeChildrenList.GetSize();
  276. for (int index = 0; index < j; index++)
  277. {
  278. pDevice = (CFaxDeviceNode *)m_ScopeChildrenList[0];
  279. hRc = RemoveChild(pDevice);
  280. if (FAILED(hRc))
  281. {
  282. DebugPrintEx(DEBUG_ERR,
  283. _T("Fail to delete device. (hRc: %08X)"),
  284. hRc);
  285. goto Error;
  286. }
  287. delete pDevice;
  288. }
  289. // Empty the list of all Devices added before the one who failed
  290. // already done one by one inside RemoveChild
  291. // m_ScopeChildrenList.RemoveAll();
  292. m_bScopeChildrenListPopulated = FALSE;
  293. }
  294. Exit:
  295. return hRc;
  296. }
  297. /*
  298. - CFaxDevicesNode::SetVerbs
  299. -
  300. * Purpose:
  301. * What verbs to enable/disable when this object is selected
  302. *
  303. * Arguments:
  304. * [in] pConsoleVerb - MMC ConsoleVerb interface
  305. *
  306. * Return:
  307. * OLE Error code
  308. */
  309. HRESULT CFaxDevicesNode::SetVerbs(IConsoleVerb *pConsoleVerb)
  310. {
  311. HRESULT hRc = S_OK;
  312. //
  313. // Refersh
  314. //
  315. hRc = pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE);
  316. //
  317. // We want the default verb to be expand node children
  318. //
  319. hRc = pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  320. return hRc;
  321. }
  322. /*
  323. - CFaxDevicesNode::OnRefresh
  324. -
  325. * Purpose:
  326. * Called when refreshing the object.
  327. *
  328. * Arguments:
  329. *
  330. * Return:
  331. * OLE error code
  332. */
  333. HRESULT
  334. CFaxDevicesNode::OnRefresh(LPARAM arg,
  335. LPARAM param,
  336. IComponentData *pComponentData,
  337. IComponent * pComponent,
  338. DATA_OBJECT_TYPES type)
  339. {
  340. DEBUG_FUNCTION_NAME( _T("CFaxDevicesNode::OnRefresh"));
  341. HRESULT hRc = S_OK;
  342. SCOPEDATAITEM* pScopeData;
  343. CComPtr<IConsole> spConsole;
  344. if (FXS_ITEMS_NEVER_COUNTED != m_dwNumOfDevices)//already Expanded before.
  345. {
  346. //
  347. // Repopulate Scope Children List
  348. //
  349. hRc = RepopulateScopeChildrenList();
  350. if (S_OK != hRc)
  351. {
  352. DebugPrintEx(
  353. DEBUG_ERR,
  354. TEXT("Fail to RepopulateScopeChildrenList(). (hRc: %08X)"),
  355. hRc);
  356. // Done by called func. NodeMsgBox(FAIL2REPOPULATE_DEVICES_LIST);
  357. goto Exit;
  358. }
  359. }
  360. else //never expanded before.
  361. {
  362. DebugPrintEx(
  363. DEBUG_MSG,
  364. _T("User call refresh before expand node's children."));
  365. //continue to reselect the node.
  366. }
  367. //
  368. // Get the updated SCOPEDATAITEM
  369. //
  370. hRc = GetScopeData( &pScopeData );
  371. if (FAILED(hRc))
  372. {
  373. DebugPrintEx(
  374. DEBUG_ERR,
  375. TEXT("Fail to get pScopeData. (hRc: %08X)"),
  376. hRc);
  377. NodeMsgBox(IDS_FAIL2REDRAW_DEVICESNODE);
  378. goto Exit;
  379. }
  380. //
  381. // This will force MMC to redraw the scope node
  382. //
  383. spConsole = m_pComponentData->m_spConsole;
  384. ATLASSERT(spConsole);
  385. hRc = spConsole->SelectScopeItem( pScopeData->ID );
  386. if (FAILED(hRc))
  387. {
  388. DebugPrintEx(
  389. DEBUG_ERR,
  390. TEXT("Fail to select scope Item. (hRc: %08X)"),
  391. hRc);
  392. NodeMsgBox(IDS_FAIL2REDRAW_DEVICESNODE);
  393. }
  394. Exit:
  395. return hRc;
  396. }
  397. /*
  398. - CFaxDevicesNode::UpdateTheView
  399. -
  400. * Purpose:
  401. * Refresh the view
  402. *
  403. * Arguments:
  404. * [in] pRoot - The root node
  405. *
  406. * Return:
  407. * OLE Error code
  408. */
  409. HRESULT
  410. CFaxDevicesNode::UpdateTheView()
  411. {
  412. DEBUG_FUNCTION_NAME( _T("CFaxDevicesNode::UpdateTheView()"));
  413. HRESULT hRc = S_OK;
  414. CComPtr<IConsole> spConsole;
  415. ATLASSERT( m_pComponentData != NULL );
  416. ATLASSERT( m_pComponentData->m_spConsole != NULL );
  417. hRc = m_pComponentData->m_spConsole->UpdateAllViews( NULL, NULL, NULL);
  418. if (S_OK != hRc)
  419. {
  420. DebugPrintEx( DEBUG_ERR,
  421. _T("Unexpected error - Fail to UpdateAllViews."));
  422. NodeMsgBox(IDS_FAIL2REFRESH_THEVIEW);
  423. }
  424. return hRc;
  425. }
  426. /*
  427. - CFaxDevicesNode::DoRefresh
  428. -
  429. * Purpose:
  430. * Refresh the view
  431. *
  432. * Arguments:
  433. * [in] pRoot - The root node
  434. *
  435. * Return:
  436. * OLE Error code
  437. */
  438. HRESULT
  439. CFaxDevicesNode::DoRefresh()
  440. {
  441. DEBUG_FUNCTION_NAME( _T("CFaxDevicesNode::DoRefresh()"));
  442. HRESULT hRc = S_OK;
  443. CComPtr<IConsole> spConsole;
  444. //
  445. // Repopulate childs
  446. //
  447. hRc = RepopulateScopeChildrenList();
  448. if (S_OK != hRc)
  449. {
  450. DebugPrintEx( DEBUG_ERR,
  451. _T("Fail to RepopulateScopeChildrenList."));
  452. //NodeMsgBox by called func.
  453. goto Exit;
  454. }
  455. //
  456. // Refresh Result pane views
  457. //
  458. hRc = UpdateTheView();
  459. if (FAILED(hRc))
  460. {
  461. DebugPrintEx( DEBUG_ERR,
  462. _T(" Fail to UpdateTheView."));
  463. //NodeMsgBox by called func.
  464. }
  465. Exit:
  466. return hRc;
  467. }
  468. /*
  469. - CFaxDevicesNode::RepopulateScopeChildrenList
  470. -
  471. * Purpose:
  472. * RePopulateScopeChildrenList
  473. *
  474. * Arguments:
  475. *
  476. * Return:
  477. * OLE Error code
  478. */
  479. HRESULT CFaxDevicesNode::RepopulateScopeChildrenList()
  480. {
  481. DEBUG_FUNCTION_NAME( _T("CFaxDevicesNode::RepopulateScopeChildrenList"));
  482. HRESULT hRc = S_OK;
  483. CFaxDeviceNode * pChildNode ;
  484. CComPtr<IConsole> spConsole;
  485. ATLASSERT(m_pComponentData);
  486. spConsole = ((CSnapin*)m_pComponentData)->m_spConsole;
  487. ATLASSERT( spConsole != NULL );
  488. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(spConsole);
  489. //
  490. // Remove device objects from list
  491. //
  492. for (int i = 0; i < m_ScopeChildrenList.GetSize(); i++)
  493. {
  494. pChildNode = (CFaxDeviceNode *)m_ScopeChildrenList[i];
  495. hRc = spConsoleNameSpace->DeleteItem(pChildNode->m_scopeDataItem.ID, TRUE);
  496. if (FAILED(hRc))
  497. {
  498. DebugPrintEx(DEBUG_ERR,
  499. _T("Fail to delete device. (hRc: %08X)"),
  500. hRc);
  501. goto Error;
  502. }
  503. delete pChildNode;
  504. }
  505. //
  506. // Empty the list object itself and change it's status
  507. //
  508. m_ScopeChildrenList.RemoveAll();
  509. m_bScopeChildrenListPopulated = FALSE;
  510. //
  511. // Rebuild the list
  512. //
  513. hRc = PopulateScopeChildrenList();
  514. if (FAILED(hRc))
  515. {
  516. DebugPrintEx(DEBUG_ERR,
  517. _T("Fail to populate Devices. (hRc: %08X)"),
  518. hRc);
  519. goto Error;
  520. }
  521. m_bScopeChildrenListPopulated = TRUE;
  522. ATLASSERT(S_OK == hRc);
  523. DebugPrintEx(DEBUG_MSG,
  524. _T("Succeeded to Re Populate Devices. (hRc: %08X)"),
  525. hRc);
  526. goto Cleanup;
  527. Error:
  528. NodeMsgBox(IDS_FAIL2REPOPULATE_DEVICES);
  529. Cleanup:
  530. return hRc;
  531. }
  532. /*
  533. - CFaxDevicesNode::UpdateDeviceStatusChange
  534. -
  535. * Purpose:
  536. * Update a specific device status or disable its Manual Receive option.
  537. * If device not found repopulate all devices.
  538. *
  539. * Arguments:
  540. *
  541. * Return:
  542. * OLE error code
  543. */
  544. HRESULT CFaxDevicesNode::UpdateDeviceStatusChange( DWORD dwDeviceId, DWORD dwNewStatus)
  545. {
  546. DEBUG_FUNCTION_NAME(_T("CFaxDevicesNode::UpdateDeviceStatusChange"));
  547. HRESULT hRc = S_OK;
  548. CFaxDeviceNode * pDeviceNode = NULL;
  549. DWORD dwNodeDeviceID = 0;
  550. BOOL fIsDeviceFound = FALSE;
  551. for (int i = 0; i < m_ScopeChildrenList.GetSize(); i++)
  552. {
  553. pDeviceNode = (CFaxDeviceNode *)m_ScopeChildrenList[i];
  554. dwNodeDeviceID = pDeviceNode->GetDeviceID();
  555. if ( dwNodeDeviceID == dwDeviceId )
  556. {
  557. fIsDeviceFound = TRUE;
  558. hRc = pDeviceNode->UpdateDeviceStatus(dwNewStatus);
  559. ATLASSERT(S_OK == hRc);
  560. break;
  561. }
  562. }
  563. if (fIsDeviceFound) //update single device view.
  564. {
  565. //
  566. // Refresh Result pane views
  567. //
  568. hRc = pDeviceNode->RefreshTheView();
  569. if (FAILED(hRc))
  570. {
  571. DebugPrintEx( DEBUG_ERR,
  572. _T("Failed to RefreshTheView."));
  573. //NodeMsgBox by called func.
  574. }
  575. }
  576. else //(!fIsDeviceFound) >>> RepopulateScopeChildrenList
  577. {
  578. DebugPrintEx(DEBUG_MSG,
  579. _T(">>>> Notification for a non peresented device was acheived.\n Retreived updated device list.\n"));
  580. hRc = DoRefresh();
  581. if (FAILED(hRc))
  582. {
  583. DebugPrintEx( DEBUG_ERR,
  584. _T("Failed to DoRefresh."));
  585. //NodeMsgBox by called func.
  586. }
  587. }
  588. return hRc;
  589. }
  590. /*
  591. - CFaxDevicesNode::InitDisplayName
  592. -
  593. * Purpose:
  594. * To load the node's Displaed-Name string.
  595. *
  596. * Arguments:
  597. *
  598. * Return:
  599. * OLE error code
  600. */
  601. HRESULT CFaxDevicesNode::InitDisplayName()
  602. {
  603. DEBUG_FUNCTION_NAME(_T("CFaxDevicesNode::InitDisplayName"));
  604. HRESULT hRc = S_OK;
  605. if (!m_bstrDisplayName.LoadString(_Module.GetResourceInstance(),
  606. IDS_DISPLAY_STR_DEVICESNODE))
  607. {
  608. hRc = E_OUTOFMEMORY;
  609. goto Error;
  610. }
  611. ATLASSERT( S_OK == hRc);
  612. goto Exit;
  613. Error:
  614. ATLASSERT( S_OK != hRc);
  615. m_bstrDisplayName = L"";
  616. DebugPrintEx(
  617. DEBUG_ERR,
  618. TEXT("Fail to Load server name string."));
  619. NodeMsgBox(IDS_MEMORY);
  620. Exit:
  621. return hRc;
  622. }
  623. /////////////////////////////////////////////////////////////////////////////
  624. /*
  625. +
  626. +
  627. *
  628. * CFaxDevicesNode::OnPropertyChange
  629. *
  630. *
  631. * In our implementation, this method gets called when the
  632. * MMCN_PROPERTY_CHANGE
  633. * Notify message is sent for this node.
  634. *
  635. * When the snap-in uses the MMCPropertyChangeNotify function to notify it's
  636. * views about changes, MMC_PROPERTY_CHANGE is sent to the snap-in's
  637. * IComponentData and IComponent implementations.
  638. *
  639. * For each device property page, when property page submitted the notification passed to
  640. * to the Devices parent node. This node Refresh all devices if needed (when manual Receive was taken by a device)
  641. * or try to locate specific device by its ID from current children list.
  642. *
  643. * Prameters
  644. *
  645. * arg
  646. * [in] TRUE if the property change is for a scope pane item.
  647. *
  648. * lParam
  649. * This is the param passed into MMCPropertyChangeNotify.
  650. *
  651. *
  652. * Return Values
  653. *
  654. -
  655. -
  656. */
  657. //////////////////////////////////////////////////////////////////////////////
  658. HRESULT CFaxDevicesNode::OnPropertyChange(
  659. LPARAM arg
  660. , LPARAM param
  661. , IComponentData * pComponentData
  662. , IComponent * pComponent
  663. , DATA_OBJECT_TYPES type
  664. )
  665. {
  666. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::OnPropertyChange"));
  667. HRESULT hRc = S_OK;
  668. CComPtr<IConsole> spConsole;
  669. CFaxDevicePropertyChangeNotification * pNotification;
  670. //
  671. // Encode Property Change Notification data
  672. //
  673. pNotification = reinterpret_cast<CFaxDevicePropertyChangeNotification *>(param);
  674. ATLASSERT( pNotification );
  675. ATLASSERT( DeviceFaxPropNotification == pNotification->enumType );
  676. BOOL fIsDeviceFound = FALSE;
  677. if ( !pNotification->fIsToNotifyAdditionalDevices)
  678. {
  679. //
  680. // try to find the device and refresh it only
  681. // from all the scope children list
  682. //
  683. DebugPrintEx(
  684. DEBUG_MSG,
  685. _T("Try to locate device by ID"));
  686. CFaxDeviceNode * pDevice;
  687. int j = m_ScopeChildrenList.GetSize();
  688. for (int i = 0; i < j; i++)
  689. {
  690. pDevice = (CFaxDeviceNode *)m_ScopeChildrenList[i];
  691. ATLASSERT( pDevice);
  692. if ( pDevice->GetDeviceID() == pNotification->dwDeviceID )
  693. {
  694. DebugPrintEx(
  695. DEBUG_MSG,
  696. _T("Succeed to locate device by ID"));
  697. fIsDeviceFound = TRUE;
  698. hRc = pDevice->DoRefresh();
  699. if (S_OK != hRc)
  700. {
  701. DebugPrintEx(
  702. DEBUG_ERR,
  703. _T("Failed to call OnRefresh()"));
  704. //NodeMsgBox called if needed by the called func
  705. goto Exit;
  706. }
  707. break;
  708. }
  709. pDevice = NULL;
  710. }
  711. }
  712. if ( pNotification->fIsToNotifyAdditionalDevices || !fIsDeviceFound)
  713. {
  714. DebugPrintEx(
  715. DEBUG_MSG,
  716. _T("Decide to refresh all devices"));
  717. //
  718. // Refresh all devices
  719. //
  720. hRc = DoRefresh();
  721. if (S_OK != hRc)
  722. {
  723. DebugPrintEx(
  724. DEBUG_ERR,
  725. _T("Failed to call DoRefresh()"));
  726. //NodeMsgBox called if needed by the called func
  727. goto Exit;
  728. }
  729. }
  730. Exit:
  731. //
  732. // Anyway
  733. //
  734. delete pNotification;
  735. return hRc;
  736. }
  737. /*
  738. +
  739. + CFaxDevicesNode::OnShowContextHelp
  740. *
  741. * Purpose:
  742. * Overrides CSnapinNode::OnShowContextHelp.
  743. *
  744. * Arguments:
  745. *
  746. * Return:
  747. - OLE error code
  748. -
  749. */
  750. HRESULT CFaxDevicesNode::OnShowContextHelp(
  751. IDisplayHelp* pDisplayHelp, LPOLESTR helpFile)
  752. {
  753. return DisplayContextHelp(pDisplayHelp, helpFile, HLP_DEVICES);
  754. }