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.

1085 lines
28 KiB

  1. /******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 2000
  4. *
  5. * TITLE: Portsel.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: KeisukeT
  10. *
  11. * DATE: 27 Mar, 2000
  12. *
  13. * DESCRIPTION:
  14. * port selection page of WIA class installer.
  15. *
  16. * 1. Create CDevice object of selected device.
  17. * 2. Process INF of selected device thru CDevice.
  18. * 3. Get all Port's CreatFile name and Friendly name, store locally.
  19. * 4. Handle Port selection UI and set CreateFile name thru CDevice.
  20. * 5. Delele CDevice object if user re-select another device.
  21. *
  22. *******************************************************************************/
  23. //
  24. // Precompiled header
  25. //
  26. #include "precomp.h"
  27. #pragma hdrstop
  28. //
  29. // Include
  30. //
  31. #include "portsel.h"
  32. #include <sti.h>
  33. #include <setupapi.h>
  34. //
  35. // Extern
  36. //
  37. extern HINSTANCE g_hDllInstance;
  38. //
  39. // Function
  40. //
  41. CPortSelectPage::CPortSelectPage(PINSTALLER_CONTEXT pInstallerContext) :
  42. CInstallWizardPage(pInstallerContext, IDD_DYNAWIZ_SELECT_NEXTPAGE)
  43. {
  44. //
  45. // Set link to previous/next page. This page should show up.
  46. //
  47. m_uPreviousPage = IDD_DYNAWIZ_SELECTDEV_PAGE;
  48. m_uNextPage = NameTheDevice;
  49. //
  50. // Initialize member.
  51. //
  52. m_hDevInfo = pInstallerContext->hDevInfo;
  53. m_pspDevInfoData = &(pInstallerContext->spDevInfoData);
  54. m_pInstallerContext = pInstallerContext;
  55. m_bPortEnumerated = FALSE;
  56. m_dwNumberOfPort = 0;
  57. m_dwCapabilities = 0;
  58. m_csConnection = BOTH;
  59. }
  60. CPortSelectPage::~CPortSelectPage()
  61. {
  62. } // CPortSelectPage::CPortSelectPage(PINSTALLER_CONTEXT pInstallerContext)
  63. BOOL
  64. CPortSelectPage::OnCommand(
  65. WORD wItem,
  66. WORD wNotifyCode,
  67. HWND hwndItem
  68. )
  69. {
  70. LRESULT lResult;
  71. BOOL bRet;
  72. DebugTrace(TRACE_PROC_ENTER,(("CPortSelectPage::OnCommand: Enter... \r\n")));
  73. //
  74. // Initialize local.
  75. //
  76. bRet = FALSE;
  77. lResult = 0;
  78. //
  79. // Dispatch message.
  80. //
  81. switch (wNotifyCode) {
  82. case LBN_SELCHANGE: {
  83. int ItemData = (int) SendMessage(hwndItem, LB_GETCURSEL, 0, 0);
  84. //
  85. // Check the existance of CDevice.
  86. //
  87. if(NULL == m_pCDevice){
  88. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnCommand: CDevice doesn't exist yet.\r\n")));
  89. bRet = TRUE;
  90. goto OnCommand_return;
  91. }
  92. if (ItemData >= 0) {
  93. LONG lPortIndex;
  94. lPortIndex = (LONG)SendMessage(hwndItem, LB_GETITEMDATA, ItemData, 0);
  95. if(ID_AUTO == lPortIndex){
  96. //
  97. // This is "AUTO" port.
  98. //
  99. m_pCDevice->SetPort(AUTO);
  100. DebugTrace(TRACE_STATUS,(("CPortSelectPage::OnCommand: Setting portname to %ws.\r\n"), AUTO));
  101. } else if (lPortIndex >= 0 ) {
  102. //
  103. // Set port name.
  104. //
  105. m_pCDevice->SetPort(m_csaPortName[lPortIndex]);
  106. DebugTrace(TRACE_STATUS,(("CPortSelectPage::OnCommand: Setting portname to %ws.\r\n"), m_csaPortName[lPortIndex]));
  107. } else { // if (lPortIndex >= 0 )
  108. //
  109. // Shouldn't come here, id < -1. Use AUTO.
  110. //
  111. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnCommand: Got improper id(0x%x). Use AUTO.\r\n"), lPortIndex));
  112. m_pCDevice->SetPort(AUTO);
  113. } // if (lPortIndex >= 0 )
  114. bRet = TRUE;
  115. goto OnCommand_return;
  116. } // if (ItemData >= 0)
  117. } // case LBN_SELCHANGE:
  118. } // switch (wNotifyCode)
  119. OnCommand_return:
  120. DebugTrace(TRACE_PROC_LEAVE,(("CPortSelectPage::OnCommand: Leaving... Ret=0x%x.\r\n"), bRet));
  121. return bRet;
  122. }
  123. BOOL
  124. CPortSelectPage::OnNotify(
  125. LPNMHDR lpnmh
  126. )
  127. {
  128. DWORD Idx;
  129. DWORD dwPortSelectMode;
  130. BOOL bRet;
  131. DebugTrace(TRACE_PROC_ENTER,(("CPortSelectPage::OnNotify: Enter... \r\n")));
  132. //
  133. // Initialize locals.
  134. //
  135. Idx = 0;
  136. dwPortSelectMode = 0;
  137. bRet = FALSE;
  138. if (lpnmh->code == PSN_SETACTIVE) {
  139. DebugTrace(TRACE_STATUS,(("CPortSelectPage::OnNotify: PSN_SETACTIVE.\r\n")));
  140. //
  141. // Create CDevice object.
  142. //
  143. if(!CreateCDeviceObject()){
  144. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnNotify: ERROR!! Unable to create CDeviceobject.\r\n")));
  145. bRet = FALSE;
  146. goto OnNotify_return;
  147. }
  148. //
  149. // See if need to show port selection page.
  150. //
  151. dwPortSelectMode = m_pCDevice->GetPortSelectMode();
  152. switch(dwPortSelectMode){
  153. case PORTSELMODE_NORMAL:
  154. {
  155. //
  156. // Set proper message.
  157. //
  158. if(!SetDialogText(PortSelectMessage0)){
  159. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnNotify: ERROR!! Unable to set dialog text.\r\n")));
  160. } // if(!SetDialogText(PortSelectMessage0)
  161. //
  162. // Make all cotrol visible.
  163. //
  164. if(!ShowControl(TRUE)){
  165. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnNotify: ERROR!! Port listbox can't be visible.\r\n")));
  166. } // ShowControl(TRUE)
  167. //
  168. // Enumerate all Ports.
  169. //
  170. if(!EnumPort()){
  171. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnNotify: ERROR!! Unable to enumerate ports.\r\n")));
  172. bRet = FALSE;
  173. goto OnNotify_return;
  174. }
  175. //
  176. // Update port list.
  177. //
  178. UpdatePortList();
  179. //
  180. // Focus the first item.
  181. //
  182. SendDlgItemMessage(m_hwnd,
  183. LocalPortList,
  184. LB_SETCURSEL,
  185. 0,
  186. 0);
  187. //
  188. // Store the current selection.
  189. //
  190. Idx = (DWORD)SendDlgItemMessage(m_hwnd,
  191. LocalPortList,
  192. LB_GETITEMDATA,
  193. 0,
  194. 0);
  195. if(ID_AUTO == Idx){
  196. m_pCDevice->SetPort(AUTO);
  197. } else {
  198. m_pCDevice->SetPort(m_csaPortName[Idx]);
  199. }
  200. //
  201. // Let the default handler do its job.
  202. //
  203. bRet = FALSE;
  204. goto OnNotify_return;
  205. } // case PORTSELMODE_NORMAL:
  206. case PORTSELMODE_SKIP:
  207. {
  208. //
  209. // "PortSelect = no" specified. Set port to "AUTO" and skip to the next page.
  210. //
  211. m_pCDevice->SetPort(AUTO);
  212. SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, m_uNextPage);
  213. bRet = TRUE;
  214. goto OnNotify_return;
  215. } // case PORTSELMODE_SKIP:
  216. case PORTSELMODE_MESSAGE1:{
  217. //
  218. // Set proper message.
  219. //
  220. if(!SetDialogText(PortSelectMessage1)){
  221. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnNotify: ERROR!! Unable to set dialog text.\r\n")));
  222. } // if(!SetDialogText(PortSelectMessage0)
  223. //
  224. // Make all cotrol invisible.
  225. //
  226. if(!ShowControl(FALSE)){
  227. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnNotify: ERROR!! Port listbox can't be invisible.\r\n")));
  228. } // if(!ShowControl(FALSE))
  229. //
  230. // Set port name.
  231. //
  232. m_pCDevice->SetPort(AUTO);
  233. bRet = FALSE;
  234. goto OnNotify_return;
  235. } // case PORTSELMODE_MESSAGE1:
  236. default:
  237. DebugTrace(TRACE_ERROR,(("CPortSelectPage::OnNotify: ERROR!! undefined PortSelect mode(0x%x).\r\n"), dwPortSelectMode));
  238. bRet = FALSE;
  239. goto OnNotify_return;
  240. } // switch(m_pCDevice->GetPortSelectMode())
  241. } // if (lpnmh->code == PSN_SETACTIVE)
  242. if (lpnmh->code == PSN_KILLACTIVE){
  243. if(!m_bNextButtonPushed){
  244. //
  245. // It's getting back to DeviceSelection page. Delete craeted CDevice object.
  246. //
  247. delete m_pCDevice;
  248. m_pCDevice = NULL;
  249. m_pInstallerContext->pDevice = NULL;
  250. } // if(!m_bNextButtonPushed)
  251. } // if (lpnmh->code == PSN_KILLACTIVE)
  252. OnNotify_return:
  253. DebugTrace(TRACE_PROC_LEAVE,(("CPortSelectPage::OnNotify: Leaving... Ret=0x%x.\r\n"), bRet));
  254. return bRet;
  255. }
  256. VOID
  257. CPortSelectPage::UpdatePortList(
  258. VOID
  259. )
  260. {
  261. DWORD Idx;
  262. DebugTrace(TRACE_PROC_ENTER,(("CPortSelectPage::UpdatePortList: Enter... \r\n")));
  263. //
  264. // Initialize local.
  265. //
  266. Idx = 0;
  267. //
  268. // Reset port list.
  269. //
  270. SendDlgItemMessage(m_hwnd,
  271. LocalPortList,
  272. LB_RESETCONTENT,
  273. 0,
  274. 0);
  275. //
  276. // Add "AUTO" port if capable.
  277. //
  278. if(m_dwCapabilities & STI_GENCAP_AUTO_PORTSELECT){
  279. TCHAR szTemp[MAX_DESCRIPTION];
  280. //
  281. // Load localized "Automatic Port Select" from resource.
  282. //
  283. LoadString(g_hDllInstance,
  284. AutoPortSelect,
  285. (TCHAR *)szTemp,
  286. sizeof(szTemp) / sizeof(TCHAR));
  287. //
  288. // Add to the list with special index number. (ID_AUTO = -1)
  289. //
  290. AddItemToPortList(szTemp, ID_AUTO);
  291. } // if(dwCapabilities & STI_GENCAP_AUTO_PORTSELECT)
  292. //
  293. // Add all port FriendlyName to the list.
  294. //
  295. for(Idx = 0; Idx < m_dwNumberOfPort; Idx++){
  296. AddItemToPortList(m_csaPortFriendlyName[Idx], Idx);
  297. }
  298. DebugTrace(TRACE_PROC_LEAVE,(("CPortSelectPage::UpdatePortList: Leaving... Ret=VOID.\r\n")));
  299. } // CPortSelectPage::UpdatePortList()
  300. VOID
  301. CPortSelectPage::AddItemToPortList(
  302. LPTSTR szPortFriendlyName,
  303. DWORD Idx
  304. )
  305. {
  306. LRESULT lResult;
  307. DebugTrace(TRACE_PROC_ENTER,(("CPortSelectPage::AddItemToPortList: Enter... \r\n")));
  308. //
  309. // Initialize local.
  310. //
  311. lResult = LB_ERR;
  312. //
  313. // See if we can add this item to list. It depends on its ConnectionType.
  314. //
  315. if(_tcsstr((const TCHAR *)szPortFriendlyName, TEXT("COM"))) {
  316. //
  317. // This is Communications Port.
  318. //
  319. if(_tcsicmp(m_csConnection, PARALLEL)){
  320. lResult = SendDlgItemMessage(m_hwnd,
  321. LocalPortList,
  322. LB_ADDSTRING,
  323. 0,
  324. (LPARAM)szPortFriendlyName);
  325. } else {
  326. lResult = LB_ERR;
  327. }
  328. } else if(_tcsstr((const TCHAR *)szPortFriendlyName, TEXT("LPT"))){
  329. //
  330. // This is Printer Port.
  331. //
  332. if(_tcsicmp(m_csConnection, SERIAL)){
  333. lResult = SendDlgItemMessage(m_hwnd,
  334. LocalPortList,
  335. LB_ADDSTRING,
  336. 0,
  337. (LPARAM)szPortFriendlyName);
  338. } else {
  339. lResult = LB_ERR;
  340. }
  341. } else {
  342. //
  343. // This is Unknown port. Add to the list anyway.
  344. //
  345. lResult = SendDlgItemMessage(m_hwnd,
  346. LocalPortList,
  347. LB_ADDSTRING,
  348. 0,
  349. (LPARAM)szPortFriendlyName);
  350. }
  351. //
  352. // If it has proper capability, add the item to the list.
  353. //
  354. if (lResult != LB_ERR) {
  355. SendDlgItemMessage(m_hwnd,
  356. LocalPortList,
  357. LB_SETITEMDATA,
  358. lResult,
  359. (LPARAM)Idx);
  360. } // if (lResult != LB_ERR)
  361. DebugTrace(TRACE_PROC_LEAVE,(("CPortSelectPage::AddItemToPortList: Leaving... Ret=VOID.\r\n")));
  362. } // CPortSelectPage::AddItemToPortList()
  363. BOOL
  364. CPortSelectPage::EnumPort(
  365. VOID
  366. )
  367. {
  368. BOOL bRet;
  369. GUID Guid;
  370. DWORD dwRequired;
  371. HDEVINFO hPortDevInfo;
  372. DWORD Idx;
  373. TCHAR szPortName[MAX_DESCRIPTION];
  374. TCHAR szPortFriendlyName[MAX_DESCRIPTION];
  375. DebugTrace(TRACE_PROC_ENTER,(("CPortSelectPage::EnumPort: Enter... \r\n")));
  376. //
  377. // Initialize local.
  378. //
  379. bRet = FALSE;
  380. dwRequired = 0;
  381. Idx = 0;
  382. hPortDevInfo = NULL;
  383. memset(szPortName, 0, sizeof(szPortName));
  384. memset(szPortFriendlyName, 0, sizeof(szPortFriendlyName));
  385. //
  386. // If it's already enumerated, just return success.
  387. //
  388. if(m_bPortEnumerated){
  389. bRet = TRUE;
  390. goto EnumPort_return;
  391. }
  392. //
  393. // Initialize Port CreateFile/Friendly Name string array.
  394. //
  395. m_dwNumberOfPort = 0;
  396. m_csaPortName.Cleanup();
  397. m_csaPortFriendlyName.Cleanup();
  398. //
  399. // Get GUID of port device.
  400. //
  401. if(!SetupDiClassGuidsFromName (PORTS, &Guid, sizeof(GUID), &dwRequired)){
  402. DebugTrace(TRACE_ERROR,(("CPortSelectPage::EnumPort: ERROR!! SetupDiClassGuidsFromName Failed. Err=0x%lX\r\n"), GetLastError()));
  403. bRet = FALSE;
  404. goto EnumPort_return;
  405. }
  406. //
  407. // Get device info set of port devices.
  408. //
  409. hPortDevInfo = SetupDiGetClassDevs (&Guid,
  410. NULL,
  411. NULL,
  412. DIGCF_PRESENT | DIGCF_PROFILE);
  413. if (hPortDevInfo == INVALID_HANDLE_VALUE) {
  414. DebugTrace(TRACE_ERROR,(("CPortSelectPage::EnumPort: ERROR!! SetupDiGetClassDevs Failed. Err=0x%lX\r\n"), GetLastError()));
  415. bRet = FALSE;
  416. goto EnumPort_return;
  417. }
  418. //
  419. // Process all of device element listed in device info set.
  420. //
  421. for(Idx = 0; GetPortNamesFromIndex(hPortDevInfo, Idx, szPortName, szPortFriendlyName); Idx++){
  422. //
  423. // Add valid Port CreateFile/Friendly Name to array.
  424. //
  425. if( (0 == lstrlen(szPortName))
  426. || (0 == lstrlen(szPortFriendlyName)) )
  427. {
  428. DebugTrace(TRACE_ERROR,(("CPortSelectPage::EnumPort: ERROR!! Invalid Port/Friendly Name.\r\n")));
  429. szPortName[0] = TEXT('\0');
  430. szPortFriendlyName[0] = TEXT('\0');
  431. continue;
  432. }
  433. DebugTrace(TRACE_STATUS,(("CPortSelectPage::EnumPort: Found Port %d: %ws(%ws).\r\n"), Idx, szPortName, szPortFriendlyName));
  434. m_dwNumberOfPort++;
  435. m_csaPortName.Add(szPortName);
  436. m_csaPortFriendlyName.Add(szPortFriendlyName);
  437. szPortName[0] = TEXT('\0');
  438. szPortFriendlyName[0] = TEXT('\0');
  439. } // for(Idx = 0; GetPortNamesFromIndex(hPortDevInfo, Idx, szPortName, szPortFriendlyName); Idx++)
  440. //
  441. // Operation succeeded.
  442. //
  443. bRet = TRUE;
  444. m_bPortEnumerated = TRUE;
  445. EnumPort_return:
  446. //
  447. // Cleanup
  448. //
  449. if(NULL != hPortDevInfo){
  450. SetupDiDestroyDeviceInfoList(hPortDevInfo);
  451. }
  452. DebugTrace(TRACE_PROC_LEAVE,(("CPortSelectPage::EnumPort: Leaving... Ret=0x%x.\r\n"), bRet));
  453. return bRet;
  454. } // CPortSelectPage::EnumPort()
  455. BOOL
  456. CPortSelectPage::CreateCDeviceObject(
  457. VOID
  458. )
  459. {
  460. BOOL bRet;
  461. DebugTrace(TRACE_PROC_ENTER,(("CPortSelectPage::CreateCDeviceObject: Enter... \r\n")));
  462. //
  463. // Initialize local.
  464. //
  465. bRet = FALSE;
  466. //
  467. // If CDevice already exists, see if we can reuse it.
  468. //
  469. if(NULL != m_pCDevice){
  470. SP_DEVINFO_DATA spDevInfoData;
  471. memset(&spDevInfoData, 0, sizeof(SP_DEVINFO_DATA));
  472. spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  473. if(!SetupDiGetSelectedDevice(m_hDevInfo, &spDevInfoData)){
  474. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Can't get selected device element. Err=0x%x\n"), GetLastError()));
  475. bRet = FALSE;
  476. goto CreateCDeviceObject_return;
  477. }
  478. if(!(m_pCDevice->IsSameDevice(m_hDevInfo, &spDevInfoData))){
  479. //
  480. // User changed selected device. Delete the object.
  481. //
  482. delete m_pCDevice;
  483. m_pCDevice = NULL;
  484. m_pInstallerContext->pDevice = NULL;
  485. m_csConnection = BOTH;
  486. m_dwCapabilities = NULL;
  487. } // if(!(m_pCDevice->IsSameDevice(m_hDevInfo, &spDevInfoData)))
  488. } // if(NULL != m_pCDevice)
  489. //
  490. // Create CDevice object here if it doesn't exist.
  491. //
  492. if(NULL == m_pCDevice){
  493. //
  494. // Get selected device.
  495. //
  496. memset(m_pspDevInfoData, 0, sizeof(SP_DEVINFO_DATA));
  497. m_pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
  498. if(!SetupDiGetSelectedDevice(m_hDevInfo, m_pspDevInfoData)){
  499. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Can't get selected device element. Err=0x%x\n"), GetLastError()));
  500. bRet = FALSE;
  501. goto CreateCDeviceObject_return;
  502. }
  503. //
  504. // Create CDevice object for installing device.
  505. //
  506. m_pCDevice = new CDevice(m_hDevInfo, m_pspDevInfoData, FALSE);
  507. if(NULL == m_pCDevice){
  508. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Can't create CDevice object.\r\n")));
  509. bRet = FALSE;
  510. goto CreateCDeviceObject_return;
  511. } // if(NULL == m_pCDevice)
  512. //
  513. // Name default unique name.
  514. //
  515. if(!m_pCDevice->NameDefaultUniqueName()){
  516. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Unable to get default name.\r\n")));
  517. }
  518. //
  519. // Pre-process INF.
  520. //
  521. if(!m_pCDevice->PreprocessInf()){
  522. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Unable to process INF.\r\n")));
  523. }
  524. //
  525. // Save created CDevice object into installer context.
  526. //
  527. m_pInstallerContext->pDevice = (PVOID)m_pCDevice;
  528. //
  529. // Get ConnectionType/Capabilities.
  530. //
  531. m_dwCapabilities = m_pCDevice->GetCapabilities();
  532. m_csConnection = m_pCDevice->GetConnection();
  533. if(m_csConnection.IsEmpty()){
  534. m_csConnection = BOTH;
  535. } // if(m_csConnection.IsEmpty())
  536. } // if(NULL == m_pCDevice)
  537. //
  538. // Operation succeeded.
  539. //
  540. bRet = TRUE;
  541. CreateCDeviceObject_return:
  542. DebugTrace(TRACE_PROC_LEAVE,(("CPortSelectPage::CreateCDeviceObject: Leaving... Ret=0x%x.\r\n"), bRet));
  543. return bRet;
  544. } // CPortSelectPage::CreateCDeviceObject()
  545. BOOL
  546. CPortSelectPage::SetDialogText(
  547. UINT uiMessageId
  548. )
  549. {
  550. BOOL bRet;
  551. TCHAR szStringBuffer[MAX_STRING_LENGTH];
  552. HWND hwndMessage;
  553. //
  554. // Initialize local.
  555. //
  556. bRet = FALSE;
  557. hwndMessage = (HWND)NULL;
  558. memset(szStringBuffer, 0, sizeof(szStringBuffer));
  559. //
  560. // Load message string.
  561. //
  562. if(0 == LoadString(g_hDllInstance,
  563. uiMessageId,
  564. szStringBuffer,
  565. sizeof(szStringBuffer)/sizeof(TCHAR)))
  566. {
  567. //
  568. // Unable to load specified string.
  569. //
  570. bRet = FALSE;
  571. goto SetDialogText_return;
  572. } // if(0 == LoadString()
  573. //
  574. // Get window handle the control
  575. //
  576. hwndMessage = GetDlgItem(m_hwnd, IDC_PORTSEL_MESSAGE);
  577. //
  578. // Set loaded string to the dialog.
  579. //
  580. SetWindowText(hwndMessage, (LPCTSTR)szStringBuffer);
  581. bRet = TRUE;
  582. SetDialogText_return:
  583. return bRet;
  584. } // CPortSelectPage::SetDialogText()
  585. BOOL
  586. CPortSelectPage::ShowControl(
  587. BOOL bShow
  588. )
  589. {
  590. BOOL bRet;
  591. HWND hwndString;
  592. HWND hwndListBox;
  593. int nCmdShow;
  594. //
  595. // Initialize local.
  596. //
  597. bRet = FALSE;
  598. hwndString = (HWND)NULL;
  599. hwndListBox = (HWND)NULL;
  600. if(bShow){
  601. nCmdShow = SW_SHOW;
  602. } else {
  603. nCmdShow = SW_HIDE;
  604. }
  605. //
  606. // Get window handle the control
  607. //
  608. hwndString = GetDlgItem(m_hwnd, IDC_PORTSEL_AVAILABLEPORTS);
  609. hwndListBox = GetDlgItem(m_hwnd, LocalPortList);
  610. //
  611. // Make them in/visible.
  612. //
  613. if(NULL != hwndString){
  614. ShowWindow(hwndString, nCmdShow);
  615. } // if(NULL != hwndString)
  616. if(NULL != hwndListBox){
  617. ShowWindow(hwndListBox, nCmdShow);
  618. } // if(NULL != hwndListBox)
  619. bRet = TRUE;
  620. // ShowControl_return:
  621. return bRet;
  622. } // CPortSelectPage::ShowControl()
  623. BOOL
  624. GetDevinfoFromPortName(
  625. LPTSTR szPortName,
  626. HDEVINFO *phDevInfo,
  627. PSP_DEVINFO_DATA pspDevInfoData
  628. )
  629. {
  630. BOOL bRet;
  631. BOOL bFound;
  632. HDEVINFO hPortDevInfo;
  633. SP_DEVINFO_DATA spDevInfoData;
  634. GUID Guid;
  635. DWORD dwRequired;
  636. DWORD Idx;
  637. TCHAR szTempPortName[MAX_DESCRIPTION];
  638. TCHAR szPortFriendlyName[MAX_DESCRIPTION];
  639. DebugTrace(TRACE_PROC_ENTER,(("GetDevinfoFromPortName: Enter... \r\n")));
  640. //
  641. // Initialize local.
  642. //
  643. bRet = FALSE;
  644. bFound = FALSE;
  645. hPortDevInfo = INVALID_HANDLE_VALUE;
  646. dwRequired = 0;
  647. memset(&spDevInfoData, 0, sizeof(spDevInfoData));
  648. memset(&szTempPortName, 0, sizeof(szTempPortName));
  649. memset(&szPortFriendlyName, 0, sizeof(szPortFriendlyName));
  650. //
  651. // Get GUID of port device.
  652. //
  653. if(!SetupDiClassGuidsFromName (PORTS, &Guid, sizeof(GUID), &dwRequired)){
  654. DebugTrace(TRACE_ERROR,(("GetDevinfoFromPortName: ERROR!! SetupDiClassGuidsFromName Failed. Err=0x%lX\r\n"), GetLastError()));
  655. goto GetDevinfoFromPortName_return;
  656. }
  657. //
  658. // Get device info set of port devices.
  659. //
  660. hPortDevInfo = SetupDiGetClassDevs (&Guid,
  661. NULL,
  662. NULL,
  663. DIGCF_PRESENT | DIGCF_PROFILE);
  664. if (hPortDevInfo == INVALID_HANDLE_VALUE) {
  665. DebugTrace(TRACE_ERROR,(("GetDevinfoFromPortName: ERROR!! SetupDiGetClassDevs Failed. Err=0x%lX\r\n"), GetLastError()));
  666. goto GetDevinfoFromPortName_return;
  667. }
  668. //
  669. // If portname is AUTO, use the first port no matter what it is.
  670. //
  671. if(0 == _tcsicmp(szPortName, AUTO)){
  672. DebugTrace(TRACE_STATUS,(("GetDevinfoFromPortName: Portname is AUTO. The first port found will be returned,\r\n")));
  673. Idx = 0;
  674. bFound = TRUE;
  675. goto GetDevinfoFromPortName_return;
  676. } // if(0 == _tcsicmp(szPortName, AUTO))
  677. //
  678. // Enum all ports and find specified port.
  679. //
  680. for(Idx = 0; GetPortNamesFromIndex(hPortDevInfo, Idx, szTempPortName, szPortFriendlyName); Idx++){
  681. //
  682. // Find specified portname..
  683. //
  684. if( (0 == lstrlen(szTempPortName))
  685. || (0 == lstrlen(szPortFriendlyName)) )
  686. {
  687. DebugTrace(TRACE_ERROR,(("GetDevinfoFromPortName: ERROR!! Invalid Port/Friendly Name.\r\n")));
  688. szTempPortName[0] = TEXT('\0');
  689. szPortFriendlyName[0] = TEXT('\0');
  690. continue;
  691. }
  692. DebugTrace(TRACE_STATUS,(("GetDevinfoFromPortName: Found Port %d: %ws(%ws). Comparing w/ %ws\r\n"), Idx, szTempPortName, szPortFriendlyName, szPortName));
  693. if(0 == _tcsicmp(szPortName, szTempPortName)){
  694. //
  695. // Specified portname found.
  696. //
  697. bFound = TRUE;
  698. break;
  699. }
  700. szTempPortName[0] = TEXT('\0');
  701. szPortFriendlyName[0] = TEXT('\0');
  702. } // for(Idx = 0; GetPortNamesFromIndex(hPortDevInfo, Idx, szPortName, szPortFriendlyName); Idx++)
  703. GetDevinfoFromPortName_return:
  704. if(FALSE == bFound){
  705. if(INVALID_HANDLE_VALUE != hPortDevInfo){
  706. SetupDiDestroyDeviceInfoList(hPortDevInfo);
  707. }
  708. *phDevInfo = NULL;
  709. } else {
  710. *phDevInfo = hPortDevInfo;
  711. pspDevInfoData->cbSize = sizeof (SP_DEVINFO_DATA);
  712. if(!SetupDiEnumDeviceInfo(hPortDevInfo, Idx, pspDevInfoData)){
  713. DebugTrace(TRACE_ERROR,(("GetDevinfoFromPortName: Unable to get specified devnode. Err=0x%x\n"), GetLastError()));
  714. } //if(!SetupDiEnumDeviceInfo(hDevInfo, Idx, pspDevInfoData))
  715. } // if(FALSE == bFound)
  716. bRet = bFound;
  717. DebugTrace(TRACE_PROC_LEAVE,(("GetDevinfoFromPortName: Leaving... Ret=0x%x.\r\n"), bRet));
  718. return bRet;
  719. } // GetDevinfoFromPortName()
  720. BOOL
  721. GetPortNamesFromIndex(
  722. HDEVINFO hPortDevInfo,
  723. DWORD dwPortIndex,
  724. LPTSTR szPortName,
  725. LPTSTR szPortFriendlyName
  726. )
  727. {
  728. HKEY hkPort;
  729. SP_DEVINFO_DATA spDevInfoData;
  730. DWORD dwSize;
  731. BOOL bRet;
  732. DebugTrace(TRACE_PROC_ENTER,(("GetPortNamesFromIndex: Enter... \r\n")));
  733. //
  734. // Initialize local.
  735. //
  736. hkPort = NULL;
  737. dwSize = 0;
  738. bRet = TRUE;
  739. memset(&spDevInfoData, 0, sizeof(spDevInfoData));
  740. //
  741. // Get specified device info data.
  742. //
  743. spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
  744. if (!SetupDiEnumDeviceInfo (hPortDevInfo, dwPortIndex, &spDevInfoData)) {
  745. DWORD dwError;
  746. dwError = GetLastError();
  747. if(ERROR_NO_MORE_ITEMS == dwError){
  748. DebugTrace(TRACE_STATUS,(("GetPortNamesFromIndex: Hits end of enumeration. Index=0x%x.\r\n"), dwPortIndex));
  749. } else {
  750. DebugTrace(TRACE_ERROR,(("GetPortNamesFromIndex: ERROR!! SetupDiEnumDeviceInfo() failed. Err=0x%x\n"), dwError));
  751. }
  752. bRet = FALSE;
  753. goto GetPortNamesFromIndex_return;
  754. }
  755. //
  756. // Open port device registry.
  757. //
  758. hkPort = SetupDiOpenDevRegKey (hPortDevInfo,
  759. &spDevInfoData,
  760. DICS_FLAG_GLOBAL,
  761. 0,
  762. DIREG_DEV, KEY_READ);
  763. if (hkPort == INVALID_HANDLE_VALUE) {
  764. DebugTrace(TRACE_ERROR,(("GetPortNamesFromIndex: SetupDiOpenDevRegKey() failed.Err=0x%x\n"), GetLastError()));
  765. goto GetPortNamesFromIndex_return;
  766. }
  767. //
  768. // Get portname from device key.
  769. //
  770. if(!GetStringFromRegistry(hkPort, PORTNAME, szPortName)){
  771. DebugTrace(TRACE_ERROR,(("GetPortNamesFromIndex: Can't get portname from registry.\r\n")));
  772. goto GetPortNamesFromIndex_return;
  773. }
  774. //
  775. // Get port FriendlyName from registry.
  776. //
  777. if (!SetupDiGetDeviceRegistryProperty (hPortDevInfo,
  778. &spDevInfoData,
  779. SPDRP_FRIENDLYNAME,
  780. NULL,
  781. (LPBYTE)szPortFriendlyName,
  782. MAX_DESCRIPTION,
  783. NULL) )
  784. {
  785. DebugTrace(TRACE_ERROR,(("GetPortNamesFromIndex: SetupDiGetDeviceRegistryProperty() failed. Err=0x%x\n"), GetLastError()));
  786. goto GetPortNamesFromIndex_return;
  787. } // if (SetupDiGetDeviceRegistryProperty())
  788. //
  789. // Operation succeeded.
  790. //
  791. bRet = TRUE;
  792. GetPortNamesFromIndex_return:
  793. //
  794. // Clean up.
  795. //
  796. if(NULL != hkPort){
  797. RegCloseKey(hkPort);
  798. }
  799. DebugTrace(TRACE_PROC_LEAVE,(("GetPortNamesFromIndex: Leaving... Ret=0x%x.\r\n"), bRet));
  800. return bRet;
  801. } // CPortSelectPage::GetPortNamesFromIndex()