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.

1733 lines
42 KiB

  1. // Copyright (c) 1995, Microsoft Corporation, all rights reserved
  2. //
  3. // util.c
  4. // Remote Access Common Dialog APIs
  5. // Utility routines
  6. // Listed alphabetically
  7. //
  8. // Steve Cobb 06/20/95
  9. #include "rasdlgp.h" // Our private header
  10. #include <dlgs.h> // Common dialog resource constants
  11. #include <lmwksta.h> // NetWkstaGetInfo
  12. #include <lmapibuf.h> // NetApiBufferFree
  13. #include <dsrole.h> // machine is a member of a workgroup or domain, etc.
  14. #include <tchar.h>
  15. typedef struct _COUNT_FREE_COM_PORTS_DATA
  16. {
  17. DTLLIST* pListPortsInUse;
  18. DWORD dwCount;
  19. } COUNT_FREE_COM_PORTS_DATA;
  20. const WCHAR c_szCurrentBuildNumber[] = L"CurrentBuildNumber";
  21. const WCHAR c_szWinVersionPath[] =
  22. L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
  23. const WCHAR c_szNt40BuildNumber[] = L"1381";
  24. //-----------------------------------------------------------------------------
  25. // Help maps
  26. //-----------------------------------------------------------------------------
  27. static DWORD g_adwPnHelp[] =
  28. {
  29. CID_LE_ST_Item, HID_PN_EB_NewNumber,
  30. CID_LE_EB_Item, HID_PN_EB_NewNumber,
  31. CID_LE_PB_Add, HID_PN_PB_Add,
  32. CID_LE_PB_Replace, HID_PN_PB_Replace,
  33. CID_LE_ST_List, HID_PN_LB_List,
  34. CID_LE_LB_List, HID_PN_LB_List,
  35. CID_LE_PB_Up, HID_PN_PB_Up,
  36. CID_LE_PB_Down, HID_PN_PB_Down,
  37. CID_LE_PB_Delete, HID_PN_PB_Delete,
  38. CID_LE_CB_Promote, HID_PN_CB_Promote,
  39. 0, 0
  40. };
  41. //-----------------------------------------------------------------------------
  42. // Local helper prototypes (alphabetically)
  43. //-----------------------------------------------------------------------------
  44. BOOL
  45. CountFreeComPorts(
  46. IN PWCHAR pszPort,
  47. IN HANDLE hData);
  48. //-----------------------------------------------------------------------------
  49. // Utility routines (alphabetically)
  50. //-----------------------------------------------------------------------------
  51. BOOL
  52. AllLinksAreModems(
  53. IN PBENTRY* pEntry )
  54. // Returns true if all links associated with the entry are modem links
  55. // (MXS or Unimodem), false otherwise.
  56. //
  57. {
  58. DTLNODE* pNode;
  59. if (pEntry->pdtllistLinks)
  60. {
  61. for (pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
  62. pNode;
  63. pNode = DtlGetNextNode( pNode ))
  64. {
  65. PBLINK* pLink = (PBLINK* )DtlGetData( pNode );
  66. if (pLink->pbport.pbdevicetype != PBDT_Modem)
  67. {
  68. return FALSE;
  69. }
  70. }
  71. }
  72. return TRUE;
  73. }
  74. BOOL
  75. AllowDccWizard(
  76. IN HANDLE hConnection)
  77. // Finds out if there are any dcc devices installed on the local
  78. // machine or if there are any available com ports. If neither
  79. // condition is satisfied, then we return FALSE, otherwise TRUE.
  80. {
  81. DWORD dwErr, dwUsedCount = 0;
  82. COUNT_FREE_COM_PORTS_DATA CountFreeComPortsData,
  83. *pCfcpd = &CountFreeComPortsData;
  84. DTLNODE* pNodeP, *pNodeL, *pNode;
  85. BOOL bRet = FALSE;
  86. // Initialize
  87. ZeroMemory(pCfcpd, sizeof(COUNT_FREE_COM_PORTS_DATA));
  88. do
  89. {
  90. // Load ras if it wasn't already loaded
  91. dwErr = LoadRas( g_hinstDll, NULL );
  92. if (dwErr != 0)
  93. {
  94. return FALSE;
  95. }
  96. // Load in all of the ports and count the number of
  97. // dcc devices
  98. dwErr = LoadPortsList2(
  99. hConnection,
  100. &(pCfcpd->pListPortsInUse),
  101. FALSE);
  102. if (dwErr != NO_ERROR)
  103. {
  104. bRet = FALSE;
  105. break;
  106. }
  107. // Count the dcc devices
  108. for (pNodeL = DtlGetFirstNode( pCfcpd->pListPortsInUse );
  109. pNodeL;
  110. pNodeL = DtlGetNextNode( pNodeL ))
  111. {
  112. PBLINK* pLink = (PBLINK* )DtlGetData( pNodeL );
  113. if (pLink->pbport.dwType == RASET_Direct)
  114. {
  115. bRet = TRUE;
  116. break;
  117. }
  118. }
  119. if (bRet == TRUE)
  120. {
  121. break;
  122. }
  123. // pmay: 249346
  124. //
  125. // Only merge the com ports if the user is an admin since
  126. // admin privilege is required to install a null modem.
  127. //
  128. if (FIsUserAdminOrPowerUser())
  129. {
  130. // Count the number of available com ports
  131. dwErr = MdmEnumComPorts (
  132. CountFreeComPorts,
  133. (HANDLE)pCfcpd);
  134. if (dwErr != NO_ERROR)
  135. {
  136. bRet = FALSE;
  137. break;
  138. }
  139. bRet = (pCfcpd->dwCount > 0) ? TRUE : FALSE;
  140. }
  141. } while (FALSE);
  142. // Cleanup
  143. {
  144. if ( pCfcpd->pListPortsInUse )
  145. {
  146. DtlDestroyList(pCfcpd->pListPortsInUse, DestroyPortNode);
  147. }
  148. }
  149. return bRet;
  150. }
  151. DWORD
  152. AuthRestrictionsFromTypicalAuth(
  153. IN DWORD dwTypicalAuth )
  154. // Return the AR_F_* flag corresponding to the TA_* value 'dwTypicalAuth',
  155. // i.e. convert a typical authentication selection to a bitmask of
  156. // authentication protocols.
  157. //
  158. {
  159. if (dwTypicalAuth == TA_Secure)
  160. {
  161. return AR_F_TypicalSecure;
  162. }
  163. else if (dwTypicalAuth == TA_CardOrCert)
  164. {
  165. return AR_F_TypicalCardOrCert;
  166. }
  167. else
  168. {
  169. return AR_F_TypicalUnsecure;
  170. }
  171. }
  172. ULONG
  173. CallbacksActive(
  174. INT nSetTerminateAsap,
  175. BOOL* pfTerminateAsap )
  176. // If 'fSetTerminateAsap' >= 0, sets 'g_fTerminateAsap' flag to 'nSetTerminateAsap'.
  177. // If non-NULL, caller's '*pfTerminateAsap' is filled with the current value of
  178. // 'g_fTerminateAsap'.
  179. //
  180. // Returns the number of Rasdial callback threads active.
  181. //
  182. {
  183. ULONG ul;
  184. TRACE1( "CallbacksActive(%d)", nSetTerminateAsap );
  185. ul = 0;
  186. if (WaitForSingleObject( g_hmutexCallbacks, INFINITE ) == WAIT_OBJECT_0)
  187. {
  188. if (pfTerminateAsap)
  189. {
  190. *pfTerminateAsap = g_fTerminateAsap;
  191. }
  192. if (nSetTerminateAsap >= 0)
  193. {
  194. g_fTerminateAsap = (BOOL )nSetTerminateAsap;
  195. }
  196. ul = g_ulCallbacksActive;
  197. ReleaseMutex( g_hmutexCallbacks );
  198. }
  199. TRACE1( "CallbacksActive=%d", ul );
  200. return ul;
  201. }
  202. VOID
  203. ContextHelp(
  204. IN const DWORD* padwMap,
  205. IN HWND hwndDlg,
  206. IN UINT unMsg,
  207. IN WPARAM wparam,
  208. IN LPARAM lparam)
  209. {
  210. ContextHelpX( padwMap, hwndDlg, unMsg, wparam, lparam, FALSE );
  211. }
  212. VOID
  213. ContextHelpX(
  214. IN const DWORD* padwMap,
  215. IN HWND hwndDlg,
  216. IN UINT unMsg,
  217. IN WPARAM wparam,
  218. IN LPARAM lparam,
  219. IN BOOL fRouter)
  220. // Calls WinHelp to popup context sensitive help. 'PadwMap' is an array
  221. // of control-ID help-ID pairs terminated with a 0,0 pair. 'UnMsg' is
  222. // WM_HELP or WM_CONTEXTMENU indicating the message received requesting
  223. // help. 'Wparam' and 'lparam' are the parameters of the message received
  224. // requesting help.
  225. //
  226. {
  227. HWND hwnd;
  228. UINT unType;
  229. TCHAR* pszHelpFile;
  230. ASSERT( unMsg==WM_HELP || unMsg==WM_CONTEXTMENU );
  231. // Don't try to do help if it won't work. See common\uiutil\ui.c.
  232. //
  233. {
  234. extern BOOL g_fNoWinHelp;
  235. if (g_fNoWinHelp)
  236. {
  237. return;
  238. }
  239. }
  240. if (unMsg == WM_HELP)
  241. {
  242. LPHELPINFO p = (LPHELPINFO )lparam;;
  243. TRACE3( "ContextHelp(WM_HELP,t=%d,id=%d,h=$%08x)",
  244. p->iContextType, p->iCtrlId,p->hItemHandle );
  245. if (p->iContextType != HELPINFO_WINDOW)
  246. {
  247. return;
  248. }
  249. hwnd = p->hItemHandle;
  250. ASSERT( hwnd );
  251. unType = HELP_WM_HELP;
  252. }
  253. else
  254. {
  255. // Standard Win95 method that produces a one-item "What's This?" menu
  256. // that user must click to get help.
  257. //
  258. TRACE1( "ContextHelp(WM_CONTEXTMENU,h=$%08x)", wparam );
  259. hwnd = (HWND )wparam;
  260. unType = HELP_CONTEXTMENU;
  261. };
  262. if (fRouter)
  263. {
  264. pszHelpFile = g_pszRouterHelpFile;
  265. }
  266. else
  267. {
  268. pszHelpFile = g_pszHelpFile;
  269. }
  270. TRACE1( "WinHelp(%s)", pszHelpFile );
  271. WinHelp( hwnd, pszHelpFile, unType, (ULONG_PTR ) padwMap );
  272. }
  273. VOID
  274. CopyLinkPhoneNumberInfo(
  275. OUT DTLNODE* pDstLinkNode,
  276. IN DTLNODE* pSrcLinkNode )
  277. // Copies the source link's phone number information to the destination
  278. // link. Any existing destination information is properly destroyed. The
  279. // arguments are DTLNODEs containing PBLINKs.
  280. //
  281. {
  282. PBLINK* pSrcLink;
  283. PBLINK* pDstLink;
  284. DTLLIST* pDstList;
  285. pSrcLink = (PBLINK* )DtlGetData( pSrcLinkNode );
  286. pDstLink = (PBLINK* )DtlGetData( pDstLinkNode );
  287. pDstList =
  288. DtlDuplicateList(
  289. pSrcLink->pdtllistPhones, DuplicatePhoneNode, DestroyPhoneNode );
  290. if (pDstList)
  291. {
  292. DtlDestroyList( pDstLink->pdtllistPhones, DestroyPhoneNode );
  293. pDstLink->pdtllistPhones = pDstList;
  294. pDstLink->fPromoteAlternates = pSrcLink->fPromoteAlternates;
  295. pDstLink->fTryNextAlternateOnFail = pSrcLink->fTryNextAlternateOnFail;
  296. }
  297. }
  298. VOID
  299. CopyPszListToPhoneList(
  300. IN OUT PBLINK* pLink,
  301. IN DTLLIST* pListPhoneNumbers )
  302. // Converts the phone number list of 'pLink' to be list created using the
  303. // the list of Psz phone numbers 'pListPhoneNumbers' for phone numbers.
  304. //
  305. {
  306. DTLNODE* pNodeP;
  307. DTLNODE* pNodeZ;
  308. // Empty the existing list of PBPHONE nodes.
  309. //
  310. while (pNodeP = DtlGetFirstNode( pLink->pdtllistPhones ))
  311. {
  312. DtlRemoveNode( pLink->pdtllistPhones, pNodeP );
  313. DestroyPhoneNode( pNodeP );
  314. }
  315. // Recreate the list of PBPHONE nodes from the list of PSZ nodes.
  316. //
  317. for (pNodeZ = DtlGetFirstNode( pListPhoneNumbers );
  318. pNodeZ;
  319. pNodeZ = DtlGetNextNode( pNodeZ ))
  320. {
  321. PBPHONE* pPhone;
  322. pNodeP = CreatePhoneNode();
  323. if (!pNodeP)
  324. {
  325. continue;
  326. }
  327. pPhone = (PBPHONE* )DtlGetData( pNodeP );
  328. ASSERT( pPhone );
  329. Free0( pPhone->pszPhoneNumber );
  330. pPhone->pszPhoneNumber =
  331. StrDup( (TCHAR* )DtlGetData( pNodeZ ) );
  332. DtlAddNodeLast( pLink->pdtllistPhones, pNodeP );
  333. }
  334. }
  335. BOOL
  336. CountFreeComPorts(
  337. IN PWCHAR pszPort,
  338. IN HANDLE hData)
  339. // Com port enumeration function that counts the list of
  340. // free com ports. Returns TRUE to stop enumeration (see
  341. // MdmEnumComPorts)
  342. {
  343. COUNT_FREE_COM_PORTS_DATA* pfcpData = (COUNT_FREE_COM_PORTS_DATA*)hData;
  344. DTLLIST* pListUsed = pfcpData->pListPortsInUse;
  345. DTLNODE* pNodeP, *pNodeL, *pNode;
  346. // If the given port is in the used list, then return
  347. // so that it is not added to the list of free ports and
  348. // so that enumeration continues.
  349. for (pNodeL = DtlGetFirstNode( pListUsed );
  350. pNodeL;
  351. pNodeL = DtlGetNextNode( pNodeL ))
  352. {
  353. PBLINK* pLink = (PBLINK* )DtlGetData( pNodeL );
  354. ASSERT( pLink->pbport.pszPort );
  355. // The port already appears in a link in the list.
  356. if (lstrcmp( pLink->pbport.pszPort, pszPort ) == 0)
  357. return FALSE;
  358. }
  359. // The port is not in use. Increment the count.
  360. pfcpData->dwCount += 1;
  361. return FALSE;
  362. }
  363. HWND
  364. CreateWizardBitmap(
  365. IN HWND hwndDlg,
  366. IN BOOL fPage )
  367. // Create a static control that displays the RAS wizard bitmap at the
  368. // standard place on dialog 'hwndDlg'. 'FPage' is set if the bitmap is
  369. // being placed on a property page, false for the equivalent placement on
  370. // a dialog.
  371. //
  372. // Returns the bitmap window handle or NULL or error.
  373. //
  374. {
  375. HWND hwnd;
  376. INT x;
  377. INT y;
  378. if (fPage)
  379. {
  380. x = y = 0;
  381. }
  382. else
  383. {
  384. x = y = 10;
  385. }
  386. hwnd =
  387. CreateWindowEx(
  388. 0,
  389. TEXT("static"),
  390. NULL,
  391. WS_VISIBLE | WS_CHILD | SS_SUNKEN | SS_BITMAP,
  392. x, y, 80, 140,
  393. hwndDlg,
  394. (HMENU )CID_BM_Wizard,
  395. g_hinstDll,
  396. NULL );
  397. if (hwnd)
  398. {
  399. if (!g_hbmWizard)
  400. {
  401. g_hbmWizard = LoadBitmap(
  402. g_hinstDll, MAKEINTRESOURCE( BID_Wizard ) );
  403. }
  404. SendMessage( hwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM )g_hbmWizard );
  405. }
  406. return hwnd;
  407. }
  408. TCHAR*
  409. DisplayPszFromDeviceAndPort(
  410. IN TCHAR* pszDevice,
  411. IN TCHAR* pszPort )
  412. // Returns address of heap block psz containing the MXS modem list display
  413. // form, i.e. the device name 'pszDevice' followed by the port name
  414. // 'pszPort'. It's caller's responsibility to Free the returned string.
  415. //
  416. {
  417. TCHAR* pszResult;
  418. TCHAR* pszD;
  419. if (pszDevice)
  420. {
  421. pszD = NULL;
  422. }
  423. else
  424. {
  425. pszD = pszDevice = PszFromId( g_hinstDll, SID_UnknownDevice );
  426. }
  427. pszResult = PszFromDeviceAndPort( pszDevice, pszPort );
  428. Free0( pszD );
  429. return pszResult;
  430. }
  431. TCHAR*
  432. DisplayPszFromPpbport(
  433. IN PBPORT* pPort,
  434. OUT DWORD* pdwDeviceIcon )
  435. // Returns address of heap block psz containing the device display form of
  436. // the 'pPort', e.g. "Modem - KTel 28.8 Fax Plus" It's caller's
  437. // responsibility to Free the returned string. If non-NULL,
  438. // '*pdwDeviceIcon' is set to the DI_* device icon code corresponding to
  439. // the device. DI_* codes are used with the RAS ListView extensions to
  440. // show the correct item icon.
  441. //
  442. {
  443. TCHAR* pszFormat;
  444. TCHAR* pszD;
  445. TCHAR* pszDT;
  446. TCHAR* pszDevice;
  447. TCHAR* pszDeviceType;
  448. TCHAR* pszResult;
  449. DWORD dwDeviceIcon;
  450. LPCTSTR pszChannel = NULL;
  451. // These are set if a resource string is read that must be Freed later.
  452. //
  453. pszDT = NULL;
  454. pszD = NULL;
  455. if (pPort->pszDevice)
  456. {
  457. pszDevice = pPort->pszDevice;
  458. }
  459. else
  460. {
  461. pszDevice = PszFromId( g_hinstDll, SID_UnknownDevice );
  462. if(NULL == pszDevice)
  463. {
  464. return NULL;
  465. }
  466. pszD = pszDevice;
  467. }
  468. // Set default format and device icon, though they may be changed below.
  469. //
  470. pszFormat = TEXT("%s - %s (%s)");
  471. dwDeviceIcon = DI_Adapter;
  472. if (pPort->pbdevicetype == PBDT_Modem
  473. && !(pPort->dwFlags & PBP_F_NullModem))
  474. {
  475. pszDeviceType = PszFromId( g_hinstDll, SID_Modem );
  476. pszDT = pszDeviceType;
  477. dwDeviceIcon = DI_Modem;
  478. }
  479. else if (pPort->pbdevicetype == PBDT_Isdn)
  480. {
  481. pszDeviceType = PszFromId( g_hinstDll, SID_Isdn );
  482. pszDT = pszDeviceType;
  483. pszFormat = TEXT("%s %s - %s");
  484. }
  485. else if (pPort->pbdevicetype == PBDT_X25)
  486. {
  487. pszDeviceType = PszFromId( g_hinstDll, SID_X25 );
  488. pszDT = pszDeviceType;
  489. }
  490. else if (pPort->pbdevicetype == PBDT_Pad)
  491. {
  492. pszDeviceType = PszFromId( g_hinstDll, SID_X25Pad );
  493. pszDT = pszDeviceType;
  494. }
  495. else
  496. {
  497. // Don't know the device type, so just bag the device descriptive word
  498. // and let the device name stand alone.
  499. //
  500. pszDeviceType = TEXT("");
  501. pszFormat = TEXT("%s%s (%s)");
  502. }
  503. if(NULL == pszDeviceType)
  504. {
  505. pszDeviceType = TEXT("");
  506. }
  507. if(pPort->pbdevicetype != PBDT_Isdn)
  508. {
  509. pszResult = Malloc(
  510. (lstrlen( pszFormat ) + lstrlen( pszDeviceType ) + lstrlen( pszDevice ) + lstrlen( pPort->pszPort ))
  511. * sizeof(TCHAR) );
  512. }
  513. else
  514. {
  515. pszChannel = PszLoadString( g_hinstDll, SID_Channel );
  516. if(NULL == pszChannel)
  517. {
  518. pszChannel = TEXT("");
  519. }
  520. // For isdn use the following format
  521. // "Isdn channel - <DeviceName>
  522. // Talk to steve falcon about this if you have issues
  523. // with special casing isdn.
  524. //
  525. pszResult = Malloc(
  526. (lstrlen( pszFormat ) + lstrlen( pszDeviceType ) + lstrlen(pszChannel) + lstrlen( pszDevice ))
  527. * sizeof(TCHAR));
  528. }
  529. if (pszResult)
  530. {
  531. if(pPort->pbdevicetype != PBDT_Isdn)
  532. {
  533. wsprintf( pszResult, pszFormat, pszDeviceType, pszDevice, pPort->pszPort);
  534. }
  535. else
  536. {
  537. ASSERT(NULL != pszChannel);
  538. wsprintf( pszResult, pszFormat, pszDeviceType, pszChannel, pszDevice);
  539. }
  540. }
  541. if (pdwDeviceIcon)
  542. {
  543. #if 1
  544. // Per SteveFal. Wants "modem" icon for all if Device-Manager-style
  545. // physically descriptive icons cannot be used.
  546. //
  547. dwDeviceIcon = DI_Modem;
  548. #endif
  549. *pdwDeviceIcon = dwDeviceIcon;
  550. }
  551. Free0( pszD );
  552. Free0( pszDT );
  553. return pszResult;
  554. }
  555. VOID
  556. EnableCbWithRestore(
  557. IN HWND hwndCb,
  558. IN BOOL fEnable,
  559. IN BOOL fDisabledCheck,
  560. IN OUT BOOL* pfRestore )
  561. // Enable/disable the checkbox 'hwndCb' based on the 'fEnable' flag
  562. // including stashing and restoring a cached value '*pfRestore' when
  563. // disabled. When disabling, the check value is set to 'fDisabledCheck'.
  564. //
  565. {
  566. if (fEnable)
  567. {
  568. if (!IsWindowEnabled( hwndCb ))
  569. {
  570. // Toggling to enabled. Restore the stashed check value.
  571. //
  572. Button_SetCheck( hwndCb, *pfRestore );
  573. EnableWindow( hwndCb, TRUE );
  574. }
  575. }
  576. else
  577. {
  578. if (IsWindowEnabled( hwndCb ))
  579. {
  580. // Toggling to disabled. Stashed the current check value.
  581. //
  582. *pfRestore = Button_GetCheck( hwndCb );
  583. Button_SetCheck( hwndCb, fDisabledCheck );
  584. EnableWindow( hwndCb, FALSE );
  585. }
  586. }
  587. }
  588. VOID
  589. EnableLbWithRestore(
  590. IN HWND hwndLb,
  591. IN BOOL fEnable,
  592. IN OUT INT* piRestore )
  593. // Enable/disable the combobox 'hwndLb' based on the 'fEnable' flag. If
  594. // disabling, '*piRestore' is loaded with the stashed selection index and
  595. // a blank item is added to the front of the list and selected. This is
  596. // undone if enabling.
  597. //
  598. {
  599. if (fEnable)
  600. {
  601. if (!IsWindowEnabled( hwndLb ))
  602. {
  603. // Toggling to enabled. Restore the stashed selection.
  604. //
  605. ComboBox_DeleteString( hwndLb, 0 );
  606. ComboBox_SetCurSelNotify( hwndLb, *piRestore );
  607. EnableWindow( hwndLb, TRUE );
  608. }
  609. }
  610. else
  611. {
  612. if (IsWindowEnabled( hwndLb ))
  613. {
  614. // Toggling to disabled. Stash the selection index.
  615. //
  616. *piRestore = ComboBox_GetCurSel( hwndLb );
  617. ComboBox_InsertString( hwndLb, 0, TEXT("") );
  618. ComboBox_SetItemData( hwndLb, 0, NULL );
  619. ComboBox_SetCurSelNotify( hwndLb, 0 );
  620. EnableWindow( hwndLb, FALSE );
  621. }
  622. }
  623. }
  624. DTLNODE*
  625. FirstPhoneNodeFromPhoneList(
  626. IN DTLLIST* pListPhones )
  627. // Return the first PBPHONE node in list of PBPHONEs 'pListPhones' or a
  628. // default node if none. Returns NULL if out of memory.
  629. //
  630. {
  631. DTLNODE* pFirstNode;
  632. DTLNODE* pNode;
  633. pFirstNode = DtlGetFirstNode( pListPhones );
  634. if (pFirstNode)
  635. {
  636. pNode = DuplicatePhoneNode( pFirstNode );
  637. }
  638. else
  639. {
  640. pNode = CreatePhoneNode();
  641. }
  642. return pNode;
  643. }
  644. VOID
  645. FirstPhoneNodeToPhoneList(
  646. IN DTLLIST* pListPhones,
  647. IN DTLNODE* pNewNode )
  648. // Replace the first PBPHONE node in list of PBPHONEs 'pListPhones' with
  649. // 'pNewNode', deleting any existing first node. Caller's actual
  650. // 'pNewNode', not a copy, is linked.
  651. //
  652. {
  653. DTLNODE* pFirstNode;
  654. DTLNODE* pNode;
  655. pFirstNode = DtlGetFirstNode( pListPhones );
  656. if (pFirstNode)
  657. {
  658. DtlRemoveNode( pListPhones, pFirstNode );
  659. DestroyPhoneNode( pFirstNode );
  660. }
  661. DtlAddNodeFirst( pListPhones, pNewNode );
  662. }
  663. #if 0 //!!!
  664. TCHAR*
  665. FirstPhoneNumberFromEntry(
  666. IN PBENTRY* pEntry )
  667. // Returns the first phone number of the first link of entry 'pEntry' or
  668. // an empty string if none. The returned address is into the list of
  669. // phone numbers and should be copied if it needs to be stored.
  670. //
  671. {
  672. TCHAR* pszPhoneNumber;
  673. DTLNODE* pNode;
  674. PBLINK* pLink;
  675. TRACE( "FirstPhoneNumberFromEntry" );
  676. ASSERT( pEntry->pdtllistLinks );
  677. pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
  678. ASSERT( pNode );
  679. pLink = (PBLINK* )DtlGetData( pNode );
  680. ASSERT( pLink );
  681. return FirstPszFromList( pLink->pdtllistPhoneNumbers );
  682. }
  683. #endif
  684. TCHAR*
  685. FirstPszFromList(
  686. IN DTLLIST* pPszList )
  687. // Returns the first string from the first node of 'pPszList' or an empty
  688. // string if none. The returned address is into the list and should be
  689. // copied if it needs to be stored.
  690. //
  691. {
  692. TCHAR* psz;
  693. DTLNODE* pNode;
  694. TRACE( "FirstPszFromList" );
  695. if (DtlGetNodes( pPszList ) > 0)
  696. {
  697. pNode = DtlGetFirstNode( pPszList );
  698. ASSERT( pNode );
  699. psz = (TCHAR* )DtlGetData( pNode );
  700. ASSERT( psz );
  701. }
  702. else
  703. {
  704. psz = TEXT("");
  705. }
  706. return psz;
  707. }
  708. #if 0 //!!!
  709. DWORD
  710. FirstPhoneNumberToEntry(
  711. IN PBENTRY* pEntry,
  712. IN TCHAR* pszPhoneNumber )
  713. // Sets the first phone number of the first link of entry 'pEntry' to
  714. // 'pszPhoneNumber'.
  715. //
  716. // Returns 0 if successful, or an error code.
  717. //
  718. {
  719. DTLNODE* pNode;
  720. PBLINK* pLink;
  721. TCHAR* pszNew;
  722. TRACE( "FirstPhoneNumberToEntry" );
  723. ASSERT( pEntry->pdtllistLinks );
  724. pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
  725. ASSERT( pNode );
  726. pLink = (PBLINK* )DtlGetData( pNode );
  727. ASSERT( pLink );
  728. ASSERT( pLink->pdtllistPhoneNumbers );
  729. return FirstPszToList( pLink->pdtllistPhoneNumbers, pszPhoneNumber );
  730. }
  731. #endif
  732. DWORD
  733. FirstPszToList(
  734. IN DTLLIST* pPszList,
  735. IN TCHAR* psz )
  736. // Sets the string of the first node of the list 'pPszList' to a copy of
  737. // 'psz'. If 'psz' is "" the first node is deleted.
  738. //
  739. // Returns 0 if successful, or an error code.
  740. //
  741. {
  742. DTLNODE* pNode;
  743. TCHAR* pszNew;
  744. ASSERT( pPszList );
  745. // Delete the existing first node, if any.
  746. //
  747. if (DtlGetNodes( pPszList ) > 0)
  748. {
  749. pNode = DtlGetFirstNode( pPszList );
  750. DtlRemoveNode( pPszList, pNode );
  751. DestroyPszNode( pNode );
  752. }
  753. // Create a new first node and link it. An empty string is not added.
  754. //
  755. if (*psz == TEXT('\0'))
  756. return 0;
  757. pszNew = StrDup( psz );
  758. pNode = DtlCreateNode( pszNew, 0 );
  759. if (!pszNew || !pNode)
  760. {
  761. Free0( pszNew );
  762. return ERROR_NOT_ENOUGH_MEMORY;
  763. }
  764. DtlAddNodeFirst( pPszList, pNode );
  765. return 0;
  766. }
  767. //
  768. // Function: GetBoldWindowFont
  769. //
  770. // Purpose: Generate bold or large bold fonts based on the font of the
  771. // window specified
  772. //
  773. // Parameters: hwnd [IN] - Handle of window to base font on
  774. // fLargeFont [IN] - If TRUE, generate a 12 point bold font for
  775. // use in the wizard "welcome" page.
  776. // pBoldFont [OUT] - The newly generated font, NULL if the
  777. //
  778. // Returns: nothing
  779. //
  780. VOID
  781. GetBoldWindowFont(
  782. IN HWND hwnd,
  783. IN BOOL fLargeFont,
  784. OUT HFONT * pBoldFont)
  785. {
  786. LOGFONT BoldLogFont;
  787. HFONT hFont;
  788. TCHAR FontSizeString[MAX_PATH];
  789. INT FontSize;
  790. HDC hdc;
  791. *pBoldFont = NULL;
  792. // Get the font used by the specified window
  793. //
  794. hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
  795. if (NULL == hFont)
  796. {
  797. // If not found then the control is using the system font
  798. //
  799. hFont = (HFONT)GetStockObject(SYSTEM_FONT);
  800. }
  801. if (hFont)
  802. {
  803. // Get the font info so we can generate the BOLD version
  804. //
  805. if (GetObject(hFont, sizeof(BoldLogFont), &BoldLogFont))
  806. {
  807. // Create the Bold Font
  808. //
  809. BoldLogFont.lfWeight = FW_BOLD;
  810. hdc = GetDC(hwnd);
  811. if (hdc)
  812. {
  813. // Large (tall) font is an option
  814. //
  815. if (fLargeFont)
  816. {
  817. // Load size and name from resources,
  818. // since these may change
  819. // from locale to locale based on the
  820. // size of the system font, etc.
  821. //
  822. UINT nLen;
  823. PWCHAR pszFontName = NULL, pszFontSize = NULL;
  824. pszFontName = (PWCHAR)PszLoadString(
  825. g_hinstDll,
  826. SID_LargeFontName);
  827. pszFontSize = (PWCHAR)PszLoadString(
  828. g_hinstDll,
  829. SID_LargeFontSize);
  830. if (pszFontName != NULL)
  831. {
  832. lstrcpyn(
  833. BoldLogFont.lfFaceName,
  834. pszFontName,
  835. sizeof(BoldLogFont.lfFaceName) / sizeof(TCHAR));
  836. }
  837. FontSize = 12;
  838. nLen = lstrlen(pszFontName);
  839. if (pszFontSize)
  840. {
  841. lstrcpyn(
  842. FontSizeString,
  843. pszFontSize,
  844. sizeof(FontSizeString) / sizeof(TCHAR));
  845. FontSize = wcstoul((const TCHAR*)FontSizeString, NULL, 10);
  846. }
  847. BoldLogFont.lfHeight =
  848. 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * FontSize / 72);
  849. //Free0(pszFontName);
  850. //Free0(pszFontSize);
  851. }
  852. *pBoldFont = CreateFontIndirect(&BoldLogFont);
  853. ReleaseDC(hwnd, hdc);
  854. }
  855. }
  856. }
  857. }
  858. DWORD
  859. GetDefaultEntryName(
  860. IN PBFILE* pFile,
  861. IN DWORD dwType,
  862. IN BOOL fRouter,
  863. OUT TCHAR** ppszName )
  864. // Loads a default entry name into '*ppszName' that is unique within open
  865. // phonebook 'pFile', or if NULL, in all default phonebooks. 'FRouter' is
  866. // set if a router-style name should be chosen rather than a client-style
  867. // name. It is caller's responsibility to Free the returned string.
  868. //
  869. // Returns 0 if successful or an error code.
  870. //
  871. {
  872. DWORD dwErr;
  873. TCHAR szBuf[ RAS_MaxEntryName + 1 ];
  874. UINT unSid;
  875. LPCTSTR pszDefault;
  876. DWORD dwDefaultLen;
  877. LONG lNum;
  878. PBFILE file;
  879. DTLNODE* pNode;
  880. *ppszName = NULL;
  881. if (fRouter)
  882. {
  883. unSid = SID_DefaultRouterEntryName;
  884. }
  885. else
  886. {
  887. unSid = SID_DefaultEntryName;
  888. if (RASET_Vpn == dwType)
  889. {
  890. unSid = SID_DefaultVpnEntryName;
  891. }
  892. else if (RASET_Direct == dwType)
  893. {
  894. unSid = SID_DefaultDccEntryName;
  895. }
  896. else if (RASET_Broadband == dwType)
  897. {
  898. unSid = SID_DefaultBbEntryName;
  899. }
  900. }
  901. pszDefault = PszLoadString( g_hinstDll, unSid );
  902. lstrcpyn( szBuf, pszDefault, sizeof(szBuf) / sizeof(TCHAR) );
  903. dwDefaultLen = lstrlen( pszDefault ) + 1; // +1 for extra space below
  904. lNum = 2;
  905. for (;;)
  906. {
  907. if (pFile)
  908. {
  909. if (!EntryNodeFromName( pFile->pdtllistEntries, szBuf ))
  910. {
  911. break;
  912. }
  913. }
  914. else
  915. {
  916. if (GetPbkAndEntryName(
  917. NULL, szBuf, RPBF_NoCreate, &file, &pNode ) == 0)
  918. {
  919. ClosePhonebookFile( &file );
  920. }
  921. else
  922. {
  923. break;
  924. }
  925. }
  926. // Duplicate entry found so increment the default name and try the
  927. // next one.
  928. //
  929. lstrcpyn( szBuf, pszDefault, sizeof(szBuf) / sizeof(TCHAR) );
  930. lstrcat( szBuf, TEXT(" "));
  931. LToT( lNum, szBuf + dwDefaultLen, 10 );
  932. ++lNum;
  933. }
  934. *ppszName = StrDup( szBuf );
  935. if (!*ppszName)
  936. {
  937. return ERROR_NOT_ENOUGH_MEMORY;
  938. }
  939. return ERROR_SUCCESS;
  940. }
  941. BOOL
  942. IsLocalPad(
  943. IN PBENTRY* pEntry )
  944. // Returns true if 'pEntry' is a local PAD device, i.e. the first link of
  945. // the entry has device type "pad", false otherwise.
  946. //
  947. {
  948. PBLINK* pLink;
  949. DTLNODE* pNode;
  950. if (!pEntry)
  951. {
  952. return FALSE;
  953. }
  954. ASSERT( pEntry->pdtllistLinks );
  955. pNode = DtlGetFirstNode( pEntry->pdtllistLinks );
  956. ASSERT( pNode );
  957. pLink = (PBLINK* )DtlGetData( pNode );
  958. ASSERT( pLink );
  959. return (pLink->pbport.pbdevicetype == PBDT_Pad);
  960. }
  961. #if 0
  962. //----------------------------------------------------------------------------
  963. // Function: IsNt40Machine
  964. //
  965. // Returns whether the given machine is running nt40
  966. //----------------------------------------------------------------------------
  967. DWORD
  968. IsNt40Machine (
  969. IN PWCHAR pszServer,
  970. OUT PBOOL pbIsNt40)
  971. {
  972. DWORD dwErr, dwType = REG_SZ, dwLength;
  973. HKEY hkMachine, hkVersion;
  974. WCHAR pszBuildNumber[64];
  975. PWCHAR pszMachine = NULL;
  976. //
  977. // Validate and initialize
  978. //
  979. if (!pbIsNt40)
  980. {
  981. return ERROR_INVALID_PARAMETER;
  982. }
  983. *pbIsNt40 = FALSE;
  984. do
  985. {
  986. // Format the machine name
  987. if ( (pszServer) && (wcslen(pszServer) > 0) )
  988. {
  989. dwLength = wcslen( pszServer ) + 3;
  990. pszMachine = (PWCHAR) Malloc ( dwLength * sizeof( WCHAR ) );
  991. if (pszMachine == NULL)
  992. {
  993. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  994. break;
  995. }
  996. if ( *pszMachine == L'\\' )
  997. {
  998. wcscpy( pszMachine, pszServer );
  999. }
  1000. else
  1001. {
  1002. wcscpy( pszMachine, L"\\\\" );
  1003. wcscat( pszMachine, pszServer );
  1004. }
  1005. }
  1006. else
  1007. {
  1008. pszMachine = NULL;
  1009. }
  1010. //
  1011. // Connect to the remote server
  1012. //
  1013. dwErr = RegConnectRegistry(
  1014. pszMachine,
  1015. HKEY_LOCAL_MACHINE,
  1016. &hkMachine);
  1017. if ( dwErr != ERROR_SUCCESS )
  1018. {
  1019. break;
  1020. }
  1021. //
  1022. // Open the windows version key
  1023. //
  1024. dwErr = RegOpenKeyEx(
  1025. hkMachine,
  1026. c_szWinVersionPath,
  1027. 0,
  1028. KEY_ALL_ACCESS,
  1029. &hkVersion
  1030. );
  1031. if ( dwErr != NO_ERROR )
  1032. {
  1033. break;
  1034. }
  1035. //
  1036. // Read in the current version key
  1037. //
  1038. dwLength = sizeof(pszBuildNumber);
  1039. dwErr = RegQueryValueEx (
  1040. hkVersion,
  1041. c_szCurrentBuildNumber,
  1042. NULL,
  1043. &dwType,
  1044. (BYTE*)pszBuildNumber,
  1045. &dwLength
  1046. );
  1047. if (dwErr != NO_ERROR)
  1048. {
  1049. break;
  1050. }
  1051. if (lstrcmp (pszBuildNumber, c_szNt40BuildNumber) == 0)
  1052. {
  1053. *pbIsNt40 = TRUE;
  1054. }
  1055. } while (FALSE);
  1056. // Cleanup
  1057. {
  1058. if ( hkVersion )
  1059. {
  1060. RegCloseKey( hkVersion );
  1061. }
  1062. if ( hkMachine )
  1063. {
  1064. RegCloseKey( hkMachine );
  1065. }
  1066. Free0( pszMachine );
  1067. }
  1068. return dwErr;
  1069. }
  1070. #endif
  1071. BOOL
  1072. PhoneNodeIsBlank(
  1073. IN DTLNODE* pNode )
  1074. // Returns true if the phone number in PBPHONE node 'pNode' is "blank",
  1075. // i.e. it contains no area code, phone number, or comment strings.
  1076. //
  1077. {
  1078. PBPHONE* pPhone;
  1079. pPhone = (PBPHONE* )DtlGetData( pNode );
  1080. ASSERT( pPhone );
  1081. if ((!pPhone->pszAreaCode || IsAllWhite( pPhone->pszAreaCode ))
  1082. && (!pPhone->pszPhoneNumber || IsAllWhite( pPhone->pszPhoneNumber ))
  1083. && (!pPhone->pszComment || IsAllWhite( pPhone->pszComment )))
  1084. {
  1085. return TRUE;
  1086. }
  1087. return FALSE;
  1088. }
  1089. BOOL
  1090. PhoneNumberDlg(
  1091. IN HWND hwndOwner,
  1092. IN BOOL fRouter,
  1093. IN OUT DTLLIST* pList,
  1094. IN OUT BOOL* pfCheck )
  1095. // Popup the phone number list dialog. 'HwndOwner' is the owner of the
  1096. // created dialog. 'FRouter' indicates router-style labels should be used
  1097. // rather than client-style. 'PList' is a list of Psz nodes containing
  1098. // the phone numbers. 'PfCheck' is the address that contains the initial
  1099. // "promote number" checkbox setting and which receives the value set by
  1100. // user.
  1101. //
  1102. // Returns true if user presses OK and succeeds, false if he presses
  1103. // Cancel or encounters an error.
  1104. //
  1105. {
  1106. DWORD sidHuntTitle;
  1107. DWORD sidHuntItemLabel;
  1108. DWORD sidHuntListLabel;
  1109. DWORD sidHuntCheckLabel;
  1110. //For whistler bug 227538
  1111. TCHAR *pszTitle = NULL, *pszItem = NULL, *pszList = NULL, *pszCheck = NULL;
  1112. DWORD dwErr = NO_ERROR;
  1113. TRACE( "PhoneNumberDlg" );
  1114. if (fRouter)
  1115. {
  1116. sidHuntTitle = SID_RouterHuntTitle;
  1117. sidHuntItemLabel = SID_RouterHuntItemLabel;
  1118. sidHuntListLabel = SID_RouterHuntListLabel;
  1119. sidHuntCheckLabel = SID_RouterHuntCheckLabel;
  1120. }
  1121. else
  1122. {
  1123. sidHuntTitle = SID_HuntTitle;
  1124. sidHuntItemLabel = SID_HuntItemLabel;
  1125. sidHuntListLabel = SID_HuntListLabel;
  1126. sidHuntCheckLabel = SID_HuntCheckLabel;
  1127. }
  1128. pszTitle = PszFromId( g_hinstDll, sidHuntTitle );
  1129. pszItem = PszFromId( g_hinstDll, sidHuntItemLabel );
  1130. pszList = PszFromId( g_hinstDll, sidHuntListLabel );
  1131. pszCheck = PszFromId( g_hinstDll, sidHuntCheckLabel );
  1132. dwErr=ListEditorDlg(
  1133. hwndOwner,
  1134. pList,
  1135. pfCheck,
  1136. RAS_MaxPhoneNumber,
  1137. pszTitle,
  1138. pszItem,
  1139. pszList,
  1140. pszCheck,
  1141. NULL,
  1142. 0,
  1143. g_adwPnHelp,
  1144. 0,
  1145. NULL );
  1146. Free0( pszTitle );
  1147. Free0( pszItem );
  1148. Free0( pszList );
  1149. Free0( pszCheck );
  1150. return dwErr;
  1151. }
  1152. VOID
  1153. PositionDlg(
  1154. IN HWND hwndDlg,
  1155. IN BOOL fPosition,
  1156. IN LONG xDlg,
  1157. IN LONG yDlg )
  1158. // Positions the dialog 'hwndDlg' based on caller's API settings, where
  1159. // 'fPosition' is the RASxxFLAG_PositionDlg flag and 'xDlg' and 'yDlg' are
  1160. // the coordinates.
  1161. //
  1162. {
  1163. if (fPosition)
  1164. {
  1165. // Move it to caller's coordinates.
  1166. //
  1167. SetWindowPos( hwndDlg, NULL, xDlg, yDlg, 0, 0,
  1168. SWP_NOZORDER + SWP_NOSIZE );
  1169. UnclipWindow( hwndDlg );
  1170. }
  1171. else
  1172. {
  1173. // Center it on the owner window, or on the screen if none.
  1174. //
  1175. CenterWindow( hwndDlg, GetParent( hwndDlg ) );
  1176. }
  1177. }
  1178. LRESULT CALLBACK
  1179. PositionDlgStdCallWndProc(
  1180. int code,
  1181. WPARAM wparam,
  1182. LPARAM lparam )
  1183. // Standard Win32 CallWndProc hook callback that positions the next dialog
  1184. // to start in this thread at our standard offset relative to owner.
  1185. //
  1186. {
  1187. // Arrive here when any window procedure associated with our thread is
  1188. // called.
  1189. //
  1190. if (!wparam)
  1191. {
  1192. CWPSTRUCT* p = (CWPSTRUCT* )lparam;
  1193. // The message is from outside our process. Look for the MessageBox
  1194. // dialog initialization message and take that opportunity to position
  1195. // the dialog at the standard place relative to the calling dialog.
  1196. //
  1197. if (p->message == WM_INITDIALOG)
  1198. {
  1199. RECT rect;
  1200. HWND hwndOwner;
  1201. hwndOwner = GetParent( p->hwnd );
  1202. GetWindowRect( hwndOwner, &rect );
  1203. SetWindowPos( p->hwnd, NULL,
  1204. rect.left + DXSHEET, rect.top + DYSHEET,
  1205. 0, 0, SWP_NOZORDER + SWP_NOSIZE );
  1206. UnclipWindow( p->hwnd );
  1207. }
  1208. }
  1209. return 0;
  1210. }
  1211. TCHAR*
  1212. PszFromPhoneNumberList(
  1213. IN DTLLIST* pList )
  1214. // Returns the phone numbers in phone number list 'pList' in a comma
  1215. // string or NULL on error. It is caller's responsiblity to Free the
  1216. // returned string.
  1217. //
  1218. {
  1219. TCHAR* pszResult, *pszTemp;
  1220. DTLNODE* pNode;
  1221. DWORD cb;
  1222. const TCHAR* pszSeparator = TEXT(", ");
  1223. cb = (DtlGetNodes( pList ) *
  1224. (RAS_MaxPhoneNumber + lstrlen( pszSeparator )) + 1)
  1225. * sizeof(TCHAR);
  1226. pszResult = Malloc( cb );
  1227. if (!pszResult)
  1228. {
  1229. return NULL;
  1230. }
  1231. *pszResult = TEXT('\0');
  1232. for (pNode = DtlGetFirstNode( pList );
  1233. pNode;
  1234. pNode = DtlGetNextNode( pNode ))
  1235. {
  1236. TCHAR* psz = (TCHAR* )DtlGetData( pNode );
  1237. ASSERT( psz );
  1238. if (*pszResult)
  1239. lstrcat( pszResult, pszSeparator );
  1240. lstrcat( pszResult, psz );
  1241. }
  1242. pszTemp = Realloc( pszResult,
  1243. (lstrlen( pszResult ) + 1) * sizeof(TCHAR) );
  1244. ASSERT( pszTemp );
  1245. if (pszTemp)
  1246. {
  1247. pszResult = pszTemp;
  1248. }
  1249. return pszResult;
  1250. }
  1251. #if 0
  1252. LRESULT CALLBACK
  1253. SelectDesktopCallWndRetProc(
  1254. int code,
  1255. WPARAM wparam,
  1256. LPARAM lparam )
  1257. // Standard Win32 CallWndRetProc hook callback that makes "Desktop" the
  1258. // initial selection of the FileOpen "Look in" combo-box.
  1259. //
  1260. {
  1261. // Arrive here when any window procedure associated with our thread is
  1262. // called.
  1263. //
  1264. if (!wparam)
  1265. {
  1266. CWPRETSTRUCT* p = (CWPRETSTRUCT* )lparam;
  1267. // The message is from outside our process. Look for the MessageBox
  1268. // dialog initialization message and take that opportunity to set the
  1269. // "Look in:" combo box to the first item, i.e. "Desktop". FileOpen
  1270. // keys off CBN_CLOSEUP rather than CBN_SELCHANGE to update the
  1271. // "contents" listbox.
  1272. //
  1273. if (p->message == WM_INITDIALOG)
  1274. {
  1275. HWND hwndLbLookIn;
  1276. hwndLbLookIn = GetDlgItem( p->hwnd, cmb2 );
  1277. ComboBox_SetCurSel( hwndLbLookIn, 0 );
  1278. SendMessage( p->hwnd, WM_COMMAND,
  1279. MAKELONG( cmb2, CBN_CLOSEUP ), (LPARAM )hwndLbLookIn );
  1280. }
  1281. }
  1282. return 0;
  1283. }
  1284. #endif
  1285. //We want to get rid of the Icon resources from rasdlg, they take too much
  1286. //memory resource. instead, we retrieve them from netman.dll, if failed, we
  1287. //use the default one IID_Broadband gangz
  1288. //Also, for whistler bug 372078 364763 364876
  1289. //
  1290. HICON
  1291. GetCurrentIconEntryType(
  1292. IN DWORD dwType,
  1293. IN BOOL fSmall)
  1294. {
  1295. HICON hIcon = NULL;
  1296. DWORD dwSize, dwConnectionIcon;
  1297. HRESULT hr = E_FAIL;
  1298. NETCON_MEDIATYPE ncm;
  1299. HMODULE hNetshell = NULL;
  1300. HRESULT (WINAPI * pHrGetIconFromMediaType) (DWORD ,
  1301. NETCON_MEDIATYPE ,
  1302. NETCON_SUBMEDIATYPE ,
  1303. DWORD ,
  1304. DWORD ,
  1305. HICON *);
  1306. dwSize = fSmall ? 16 : 32;
  1307. switch (dwType)
  1308. {
  1309. case RASET_Direct:
  1310. {
  1311. ncm = NCM_DIRECT;
  1312. break;
  1313. }
  1314. case RASET_Vpn:
  1315. {
  1316. ncm = NCM_TUNNEL;
  1317. break;
  1318. }
  1319. case RASET_Broadband:
  1320. {
  1321. ncm = NCM_PPPOE;
  1322. break;
  1323. }
  1324. case RASET_Phone:
  1325. default:
  1326. {
  1327. ncm = NCM_PHONE;
  1328. break;
  1329. }
  1330. }
  1331. hNetshell = LoadLibrary(TEXT("netshell.dll"));
  1332. if( hNetshell )
  1333. {
  1334. pHrGetIconFromMediaType =(HRESULT (WINAPI*)(
  1335. DWORD ,
  1336. NETCON_MEDIATYPE ,
  1337. NETCON_SUBMEDIATYPE ,
  1338. DWORD ,
  1339. DWORD ,
  1340. HICON *) )GetProcAddress(
  1341. hNetshell,
  1342. "HrGetIconFromMediaType");
  1343. if ( NULL != pHrGetIconFromMediaType )
  1344. {
  1345. /*******************************************************************
  1346. ** dwConnectionIcon - (This is the little Computer part of the icon):
  1347. ** 0 - no connection overlay
  1348. ** 4 - Connection Icon with both lights off (Disabled status)
  1349. ** 5 - Connection Icon with left light on (Transmitting Data)
  1350. ** 6 - Connection Icon with right light on (Receiving Data)
  1351. ** 7 - Connection Icon with both lights on (Enabled status)
  1352. *********************************************************************/
  1353. dwConnectionIcon = 7;
  1354. hr = pHrGetIconFromMediaType(dwSize,
  1355. ncm,
  1356. NCSM_NONE,
  1357. 7,
  1358. 0,
  1359. &hIcon);
  1360. }
  1361. FreeLibrary( hNetshell );
  1362. }
  1363. if ( !SUCCEEDED(hr) || !hIcon)
  1364. {
  1365. ICONINFO iInfo;
  1366. HICON hTemp;
  1367. hTemp = LoadIcon( g_hinstDll, MAKEINTRESOURCE( IID_Broadband ) );
  1368. if(hTemp)
  1369. {
  1370. if( GetIconInfo(hTemp, &iInfo) )
  1371. {
  1372. hIcon = CreateIconIndirect(&iInfo);
  1373. }
  1374. }
  1375. }
  1376. return hIcon;
  1377. }
  1378. VOID
  1379. SetIconFromEntryType(
  1380. IN HWND hwndIcon,
  1381. IN DWORD dwType,
  1382. IN BOOL fSmall)
  1383. // Set the icon image of icon control 'dwType' to the image corresponding
  1384. // to the entry type 'dwType'.
  1385. //
  1386. {
  1387. HICON hIcon = NULL;
  1388. hIcon = GetCurrentIconEntryType( dwType, fSmall );
  1389. if (hIcon)
  1390. {
  1391. Static_SetIcon( hwndIcon, hIcon );
  1392. }
  1393. }
  1394. VOID
  1395. TweakTitleBar(
  1396. IN HWND hwndDlg )
  1397. // Adjust the title bar to include an icon if unowned and the modal frame
  1398. // if not. 'HwndDlg' is the dialog window.
  1399. //
  1400. {
  1401. if (GetParent( hwndDlg ))
  1402. {
  1403. LONG lStyle;
  1404. LONG lStyleAdd;
  1405. // Drop the system menu and go for the dialog look.
  1406. //
  1407. lStyleAdd = WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE;;
  1408. lStyle = GetWindowLong( hwndDlg, GWL_EXSTYLE );
  1409. if (lStyle)
  1410. SetWindowLong( hwndDlg, GWL_EXSTYLE, lStyle | lStyleAdd );
  1411. }
  1412. else
  1413. {
  1414. // Stick a DUN1 icon in the upper left of the dialog, and more
  1415. // importantly on the task bar
  1416. //
  1417. // Whistler bug: 343455 RAS: Connection dialogs need to use new icons
  1418. //
  1419. //For whistler bug 381099 372078 gangz
  1420. //
  1421. HICON hIcon = NULL;
  1422. SendMessage( hwndDlg, WM_SETICON, ICON_SMALL,
  1423. (LPARAM )LoadIcon( g_hinstDll, MAKEINTRESOURCE( IID_Dun1 ) ) );
  1424. /*
  1425. //Use small Icon gangz
  1426. //Icon returned from GetCurrentIconEntryType() has to be destroyed after use
  1427. //In the future, Deonb will return a Icon for IID_Dun1 or dun1.ico for us.
  1428. hIcon = GetCurrentIconEntryType(RASET_Broadband , TRUE);
  1429. ASSERT(hIcon);
  1430. if(hIcon)
  1431. {
  1432. SendMessage( hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)(hIcon) );
  1433. SetProp( hwndDlg, TEXT("TweakTitleBar_Icon"), hIcon);
  1434. }
  1435. */
  1436. }
  1437. }
  1438. int CALLBACK
  1439. UnHelpCallbackFunc(
  1440. IN HWND hwndDlg,
  1441. IN UINT unMsg,
  1442. IN LPARAM lparam )
  1443. // A standard Win32 commctrl PropSheetProc. See MSDN documentation.
  1444. //
  1445. // Returns 0 always.
  1446. //
  1447. {
  1448. TRACE2( "UnHelpCallbackFunc(m=%d,l=%08x)",unMsg, lparam );
  1449. if (unMsg == PSCB_PRECREATE)
  1450. {
  1451. extern BOOL g_fNoWinHelp;
  1452. // Turn off context help button if WinHelp won't work. See
  1453. // common\uiutil\ui.c.
  1454. //
  1455. if (g_fNoWinHelp)
  1456. {
  1457. DLGTEMPLATE* pDlg = (DLGTEMPLATE* )lparam;
  1458. pDlg->style &= ~(DS_CONTEXTHELP);
  1459. }
  1460. }
  1461. return 0;
  1462. }