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.

1086 lines
29 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(IS_VALID_HANDLE(hPortDevInfo)){
  450. SetupDiDestroyDeviceInfoList(hPortDevInfo);
  451. hPortDevInfo = INVALID_HANDLE_VALUE;
  452. }
  453. DebugTrace(TRACE_PROC_LEAVE,(("CPortSelectPage::EnumPort: Leaving... Ret=0x%x.\r\n"), bRet));
  454. return bRet;
  455. } // CPortSelectPage::EnumPort()
  456. BOOL
  457. CPortSelectPage::CreateCDeviceObject(
  458. VOID
  459. )
  460. {
  461. BOOL bRet;
  462. DebugTrace(TRACE_PROC_ENTER,(("CPortSelectPage::CreateCDeviceObject: Enter... \r\n")));
  463. //
  464. // Initialize local.
  465. //
  466. bRet = FALSE;
  467. //
  468. // If CDevice already exists, see if we can reuse it.
  469. //
  470. if(NULL != m_pCDevice){
  471. SP_DEVINFO_DATA spDevInfoData;
  472. memset(&spDevInfoData, 0, sizeof(SP_DEVINFO_DATA));
  473. spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  474. if(!SetupDiGetSelectedDevice(m_hDevInfo, &spDevInfoData)){
  475. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Can't get selected device element. Err=0x%x\n"), GetLastError()));
  476. bRet = FALSE;
  477. goto CreateCDeviceObject_return;
  478. }
  479. if(!(m_pCDevice->IsSameDevice(m_hDevInfo, &spDevInfoData))){
  480. //
  481. // User changed selected device. Delete the object.
  482. //
  483. delete m_pCDevice;
  484. m_pCDevice = NULL;
  485. m_pInstallerContext->pDevice = NULL;
  486. m_csConnection = BOTH;
  487. m_dwCapabilities = NULL;
  488. } // if(!(m_pCDevice->IsSameDevice(m_hDevInfo, &spDevInfoData)))
  489. } // if(NULL != m_pCDevice)
  490. //
  491. // Create CDevice object here if it doesn't exist.
  492. //
  493. if(NULL == m_pCDevice){
  494. //
  495. // Get selected device.
  496. //
  497. memset(m_pspDevInfoData, 0, sizeof(SP_DEVINFO_DATA));
  498. m_pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
  499. if(!SetupDiGetSelectedDevice(m_hDevInfo, m_pspDevInfoData)){
  500. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Can't get selected device element. Err=0x%x\n"), GetLastError()));
  501. bRet = FALSE;
  502. goto CreateCDeviceObject_return;
  503. }
  504. //
  505. // Create CDevice object for installing device.
  506. //
  507. m_pCDevice = new CDevice(m_hDevInfo, m_pspDevInfoData, FALSE);
  508. if(NULL == m_pCDevice){
  509. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Can't create CDevice object.\r\n")));
  510. bRet = FALSE;
  511. goto CreateCDeviceObject_return;
  512. } // if(NULL == m_pCDevice)
  513. //
  514. // Name default unique name.
  515. //
  516. if(!m_pCDevice->NameDefaultUniqueName()){
  517. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Unable to get default name.\r\n")));
  518. }
  519. //
  520. // Pre-process INF.
  521. //
  522. if(!m_pCDevice->PreprocessInf()){
  523. DebugTrace(TRACE_ERROR,(("CPortSelectPage::CreateCDeviceObject: ERROR!! Unable to process INF.\r\n")));
  524. }
  525. //
  526. // Save created CDevice object into installer context.
  527. //
  528. m_pInstallerContext->pDevice = (PVOID)m_pCDevice;
  529. //
  530. // Get ConnectionType/Capabilities.
  531. //
  532. m_dwCapabilities = m_pCDevice->GetCapabilities();
  533. m_csConnection = m_pCDevice->GetConnection();
  534. if(m_csConnection.IsEmpty()){
  535. m_csConnection = BOTH;
  536. } // if(m_csConnection.IsEmpty())
  537. } // if(NULL == m_pCDevice)
  538. //
  539. // Operation succeeded.
  540. //
  541. bRet = TRUE;
  542. CreateCDeviceObject_return:
  543. DebugTrace(TRACE_PROC_LEAVE,(("CPortSelectPage::CreateCDeviceObject: Leaving... Ret=0x%x.\r\n"), bRet));
  544. return bRet;
  545. } // CPortSelectPage::CreateCDeviceObject()
  546. BOOL
  547. CPortSelectPage::SetDialogText(
  548. UINT uiMessageId
  549. )
  550. {
  551. BOOL bRet;
  552. TCHAR szStringBuffer[MAX_STRING_LENGTH];
  553. HWND hwndMessage;
  554. //
  555. // Initialize local.
  556. //
  557. bRet = FALSE;
  558. hwndMessage = (HWND)NULL;
  559. memset(szStringBuffer, 0, sizeof(szStringBuffer));
  560. //
  561. // Load message string.
  562. //
  563. if(0 == LoadString(g_hDllInstance,
  564. uiMessageId,
  565. szStringBuffer,
  566. sizeof(szStringBuffer)/sizeof(TCHAR)))
  567. {
  568. //
  569. // Unable to load specified string.
  570. //
  571. bRet = FALSE;
  572. goto SetDialogText_return;
  573. } // if(0 == LoadString()
  574. //
  575. // Get window handle the control
  576. //
  577. hwndMessage = GetDlgItem(m_hwnd, IDC_PORTSEL_MESSAGE);
  578. //
  579. // Set loaded string to the dialog.
  580. //
  581. SetWindowText(hwndMessage, (LPCTSTR)szStringBuffer);
  582. bRet = TRUE;
  583. SetDialogText_return:
  584. return bRet;
  585. } // CPortSelectPage::SetDialogText()
  586. BOOL
  587. CPortSelectPage::ShowControl(
  588. BOOL bShow
  589. )
  590. {
  591. BOOL bRet;
  592. HWND hwndString;
  593. HWND hwndListBox;
  594. int nCmdShow;
  595. //
  596. // Initialize local.
  597. //
  598. bRet = FALSE;
  599. hwndString = (HWND)NULL;
  600. hwndListBox = (HWND)NULL;
  601. if(bShow){
  602. nCmdShow = SW_SHOW;
  603. } else {
  604. nCmdShow = SW_HIDE;
  605. }
  606. //
  607. // Get window handle the control
  608. //
  609. hwndString = GetDlgItem(m_hwnd, IDC_PORTSEL_AVAILABLEPORTS);
  610. hwndListBox = GetDlgItem(m_hwnd, LocalPortList);
  611. //
  612. // Make them in/visible.
  613. //
  614. if(NULL != hwndString){
  615. ShowWindow(hwndString, nCmdShow);
  616. } // if(NULL != hwndString)
  617. if(NULL != hwndListBox){
  618. ShowWindow(hwndListBox, nCmdShow);
  619. } // if(NULL != hwndListBox)
  620. bRet = TRUE;
  621. // ShowControl_return:
  622. return bRet;
  623. } // CPortSelectPage::ShowControl()
  624. BOOL
  625. GetDevinfoFromPortName(
  626. LPTSTR szPortName,
  627. HDEVINFO *phDevInfo,
  628. PSP_DEVINFO_DATA pspDevInfoData
  629. )
  630. {
  631. BOOL bRet;
  632. BOOL bFound;
  633. HDEVINFO hPortDevInfo;
  634. SP_DEVINFO_DATA spDevInfoData;
  635. GUID Guid;
  636. DWORD dwRequired;
  637. DWORD Idx;
  638. TCHAR szTempPortName[MAX_DESCRIPTION];
  639. TCHAR szPortFriendlyName[MAX_DESCRIPTION];
  640. DebugTrace(TRACE_PROC_ENTER,(("GetDevinfoFromPortName: Enter... \r\n")));
  641. //
  642. // Initialize local.
  643. //
  644. bRet = FALSE;
  645. bFound = FALSE;
  646. hPortDevInfo = INVALID_HANDLE_VALUE;
  647. dwRequired = 0;
  648. memset(&spDevInfoData, 0, sizeof(spDevInfoData));
  649. memset(szTempPortName, 0, sizeof(szTempPortName));
  650. memset(szPortFriendlyName, 0, sizeof(szPortFriendlyName));
  651. //
  652. // Get GUID of port device.
  653. //
  654. if(!SetupDiClassGuidsFromName (PORTS, &Guid, sizeof(GUID), &dwRequired)){
  655. DebugTrace(TRACE_ERROR,(("GetDevinfoFromPortName: ERROR!! SetupDiClassGuidsFromName Failed. Err=0x%lX\r\n"), GetLastError()));
  656. goto GetDevinfoFromPortName_return;
  657. }
  658. //
  659. // Get device info set of port devices.
  660. //
  661. hPortDevInfo = SetupDiGetClassDevs (&Guid,
  662. NULL,
  663. NULL,
  664. DIGCF_PRESENT | DIGCF_PROFILE);
  665. if (hPortDevInfo == INVALID_HANDLE_VALUE) {
  666. DebugTrace(TRACE_ERROR,(("GetDevinfoFromPortName: ERROR!! SetupDiGetClassDevs Failed. Err=0x%lX\r\n"), GetLastError()));
  667. goto GetDevinfoFromPortName_return;
  668. }
  669. //
  670. // If portname is AUTO, use the first port no matter what it is.
  671. //
  672. if(0 == _tcsicmp(szPortName, AUTO)){
  673. DebugTrace(TRACE_STATUS,(("GetDevinfoFromPortName: Portname is AUTO. The first port found will be returned,\r\n")));
  674. Idx = 0;
  675. bFound = TRUE;
  676. goto GetDevinfoFromPortName_return;
  677. } // if(0 == _tcsicmp(szPortName, AUTO))
  678. //
  679. // Enum all ports and find specified port.
  680. //
  681. for(Idx = 0; GetPortNamesFromIndex(hPortDevInfo, Idx, szTempPortName, szPortFriendlyName); Idx++){
  682. //
  683. // Find specified portname..
  684. //
  685. if( (0 == lstrlen(szTempPortName))
  686. || (0 == lstrlen(szPortFriendlyName)) )
  687. {
  688. DebugTrace(TRACE_ERROR,(("GetDevinfoFromPortName: ERROR!! Invalid Port/Friendly Name.\r\n")));
  689. szTempPortName[0] = TEXT('\0');
  690. szPortFriendlyName[0] = TEXT('\0');
  691. continue;
  692. }
  693. DebugTrace(TRACE_STATUS,(("GetDevinfoFromPortName: Found Port %d: %ws(%ws). Comparing w/ %ws\r\n"), Idx, szTempPortName, szPortFriendlyName, szPortName));
  694. if(0 == _tcsicmp(szPortName, szTempPortName)){
  695. //
  696. // Specified portname found.
  697. //
  698. bFound = TRUE;
  699. break;
  700. }
  701. szTempPortName[0] = TEXT('\0');
  702. szPortFriendlyName[0] = TEXT('\0');
  703. } // for(Idx = 0; GetPortNamesFromIndex(hPortDevInfo, Idx, szPortName, szPortFriendlyName); Idx++)
  704. GetDevinfoFromPortName_return:
  705. if(FALSE == bFound){
  706. if(INVALID_HANDLE_VALUE != hPortDevInfo){
  707. SetupDiDestroyDeviceInfoList(hPortDevInfo);
  708. }
  709. *phDevInfo = NULL;
  710. } else {
  711. *phDevInfo = hPortDevInfo;
  712. pspDevInfoData->cbSize = sizeof (SP_DEVINFO_DATA);
  713. if(!SetupDiEnumDeviceInfo(hPortDevInfo, Idx, pspDevInfoData)){
  714. DebugTrace(TRACE_ERROR,(("GetDevinfoFromPortName: Unable to get specified devnode. Err=0x%x\n"), GetLastError()));
  715. } //if(!SetupDiEnumDeviceInfo(hDevInfo, Idx, pspDevInfoData))
  716. } // if(FALSE == bFound)
  717. bRet = bFound;
  718. DebugTrace(TRACE_PROC_LEAVE,(("GetDevinfoFromPortName: Leaving... Ret=0x%x.\r\n"), bRet));
  719. return bRet;
  720. } // GetDevinfoFromPortName()
  721. BOOL
  722. GetPortNamesFromIndex(
  723. HDEVINFO hPortDevInfo,
  724. DWORD dwPortIndex,
  725. LPTSTR szPortName,
  726. LPTSTR szPortFriendlyName
  727. )
  728. {
  729. HKEY hkPort;
  730. SP_DEVINFO_DATA spDevInfoData;
  731. DWORD dwSize;
  732. BOOL bRet;
  733. DebugTrace(TRACE_PROC_ENTER,(("GetPortNamesFromIndex: Enter... \r\n")));
  734. //
  735. // Initialize local.
  736. //
  737. hkPort = NULL;
  738. dwSize = 0;
  739. bRet = TRUE;
  740. memset(&spDevInfoData, 0, sizeof(spDevInfoData));
  741. //
  742. // Get specified device info data.
  743. //
  744. spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
  745. if (!SetupDiEnumDeviceInfo (hPortDevInfo, dwPortIndex, &spDevInfoData)) {
  746. DWORD dwError;
  747. dwError = GetLastError();
  748. if(ERROR_NO_MORE_ITEMS == dwError){
  749. DebugTrace(TRACE_STATUS,(("GetPortNamesFromIndex: Hits end of enumeration. Index=0x%x.\r\n"), dwPortIndex));
  750. } else {
  751. DebugTrace(TRACE_ERROR,(("GetPortNamesFromIndex: ERROR!! SetupDiEnumDeviceInfo() failed. Err=0x%x\n"), dwError));
  752. }
  753. bRet = FALSE;
  754. goto GetPortNamesFromIndex_return;
  755. }
  756. //
  757. // Open port device registry.
  758. //
  759. hkPort = SetupDiOpenDevRegKey (hPortDevInfo,
  760. &spDevInfoData,
  761. DICS_FLAG_GLOBAL,
  762. 0,
  763. DIREG_DEV, KEY_READ);
  764. if (hkPort == INVALID_HANDLE_VALUE) {
  765. DebugTrace(TRACE_ERROR,(("GetPortNamesFromIndex: SetupDiOpenDevRegKey() failed.Err=0x%x\n"), GetLastError()));
  766. goto GetPortNamesFromIndex_return;
  767. }
  768. //
  769. // Get portname from device key.
  770. //
  771. if(!GetStringFromRegistry(hkPort, PORTNAME, szPortName)){
  772. DebugTrace(TRACE_ERROR,(("GetPortNamesFromIndex: Can't get portname from registry.\r\n")));
  773. goto GetPortNamesFromIndex_return;
  774. }
  775. //
  776. // Get port FriendlyName from registry.
  777. //
  778. if (!SetupDiGetDeviceRegistryProperty (hPortDevInfo,
  779. &spDevInfoData,
  780. SPDRP_FRIENDLYNAME,
  781. NULL,
  782. (LPBYTE)szPortFriendlyName,
  783. MAX_DESCRIPTION,
  784. NULL) )
  785. {
  786. DebugTrace(TRACE_ERROR,(("GetPortNamesFromIndex: SetupDiGetDeviceRegistryProperty() failed. Err=0x%x\n"), GetLastError()));
  787. goto GetPortNamesFromIndex_return;
  788. } // if (SetupDiGetDeviceRegistryProperty())
  789. //
  790. // Operation succeeded.
  791. //
  792. bRet = TRUE;
  793. GetPortNamesFromIndex_return:
  794. //
  795. // Clean up.
  796. //
  797. if(NULL != hkPort){
  798. RegCloseKey(hkPort);
  799. }
  800. DebugTrace(TRACE_PROC_LEAVE,(("GetPortNamesFromIndex: Leaving... Ret=0x%x.\r\n"), bRet));
  801. return bRet;
  802. } // CPortSelectPage::GetPortNamesFromIndex()