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.

724 lines
21 KiB

  1. //
  2. // includes
  3. //
  4. #include <nt.h>
  5. #include <ntrtl.h>
  6. #include <nturtl.h>
  7. #define INCL_WINDOWS
  8. #define INCL_NETERRORS
  9. #define INCL_NETLIB
  10. #include "lmui.hxx"
  11. #define INCL_BLT_MISC
  12. #include "blt.hxx" // AUTO_CURSOR
  13. #include "dbgstr.hxx"
  14. #include "strnumer.hxx"
  15. #include "uiassert.hxx"
  16. #include "lmobj.hxx"
  17. #include "lmoenum.hxx" // SERVICE_ENUM
  18. #include "lmoesvc.hxx" // SERVICE_ENUM
  19. #include "regkey.hxx" // REG_KEY
  20. #include "lmobjrc.h" // IDS_PROFEXT_*
  21. extern "C"
  22. {
  23. #include <prsht.h>
  24. #include "profext.h"
  25. #include <cfgmgr32.h> // CONFIGRET
  26. #include <regstr.h> // CSCONFIGFLAG_DISABLED
  27. // we have to do this for a clean compile
  28. #undef DBGOUT
  29. #include "sysdm.h" // IDH_HWPROFILE
  30. #include <regstr.h> // REGSTR_PATH_SERVICES
  31. #include <ntddndis.h> // NdisMedium* constants
  32. }
  33. //
  34. // global data
  35. //
  36. HINSTANCE hInst = NULL; // Module handle
  37. static int HwProfileHelpIds[] = {
  38. IDC_DISABLE, IDH_HWPROFILE+IDC_DISABLE,
  39. IDC_ENABLE, IDH_HWPROFILE+IDC_ENABLE,
  40. IDC_NONET, IDH_HWPROFILE+IDC_NONET,
  41. IDC_ERROR, IDH_HWPROFILE+IDC_ERROR,
  42. 0, 0
  43. };
  44. #define SZ_NDIS SZ("NDIS")
  45. #define TCH_REGSEPERATOR TCH('\\')
  46. #define SZ_REGSEPERATOR SZ("\\")
  47. #define SZ_REGPARAMETERS SZ("\\Parameters")
  48. #define SZ_REGLINKAGE SZ("\\Linkage")
  49. #define SZ_REGMEDIATYPE SZ("MediaType")
  50. #define SZ_REGBIND SZ("Bind")
  51. APIERR MapCfgMgr32Error( CONFIGRET dwCfgMgr32Error )
  52. {
  53. APIERR err = IDS_CFGMGR32_BASE + dwCfgMgr32Error;
  54. switch (dwCfgMgr32Error)
  55. {
  56. case CR_SUCCESS :
  57. // CR_NEED_RESTART is considered to be Success
  58. case CR_NEED_RESTART :
  59. err = NO_ERROR;
  60. break;
  61. // Just use the CFGMGR out-of-memory error
  62. //
  63. // case CR_OUT_OF_MEMORY :
  64. // err = ERROR_NOT_ENOUGH_MEMORY;
  65. // break;
  66. //
  67. // These are supposedly for Windows 95 only!
  68. //
  69. case CR_INVALID_ARBITRATOR :
  70. case CR_INVALID_NODELIST :
  71. case CR_DLVXD_NOT_FOUND :
  72. case CR_NOT_SYSTEM_VM :
  73. case CR_NO_ARBITRATOR :
  74. case CR_DEVLOADER_NOT_READY :
  75. ASSERT( FALSE );
  76. // fall through
  77. default :
  78. break;
  79. }
  80. return err;
  81. }
  82. VOID
  83. HandleError( HWND hDlg, APIERR err, HWND hwndEdit = NULL )
  84. {
  85. NLS_STR nlsError, nlsTitle;
  86. if ( nlsError.QueryError() != NERR_Success
  87. || nlsTitle.QueryError() != NERR_Success
  88. || nlsError.Load( err ) != NERR_Success
  89. || nlsTitle.Load( IDS_PROFEXT_ERROR ) != NERR_Success
  90. )
  91. {
  92. TRACEEOL( "PROFEXT.DLL: HandleError failure" );
  93. ASSERT( FALSE );
  94. return;
  95. }
  96. if (hwndEdit != NULL)
  97. {
  98. ::SetWindowText( hwndEdit, nlsError.QueryPch() );
  99. ::ShowWindow( hwndEdit, SW_SHOW );
  100. }
  101. if (err != IDS_PROFEXT_NOADAPTERS)
  102. {
  103. REQUIRE( IDOK == ::MessageBox( hDlg,
  104. nlsError.QueryPch(),
  105. nlsTitle.QueryPch(),
  106. MB_ICONSTOP | MB_OK ) );
  107. }
  108. }
  109. APIERR
  110. IsDisabled( ULONG ulProfileID, DEVINSTID devinst, BOOL* pfIsDisabled )
  111. {
  112. TRACEEOL( "IsDisabled( " << ulProfileID << ", \"" << devinst << "\") " );
  113. ASSERT( pfIsDisabled != NULL );
  114. APIERR err = NERR_Success;
  115. ULONG ulValue = 0;
  116. CONFIGRET configret = ::CM_Get_HW_Prof_Flags(
  117. devinst,
  118. ulProfileID,
  119. &ulValue,
  120. 0x0 );
  121. err = MapCfgMgr32Error( configret );
  122. if (err != NERR_Success)
  123. {
  124. TRACEEOL( "\terror " << configret );
  125. return err;
  126. }
  127. *pfIsDisabled = !!(ulValue & CSCONFIGFLAG_DISABLED);
  128. TRACEEOL( (CHAR*)((*pfIsDisabled)?"\tis disabled":"\tis enabled") );
  129. return err;
  130. }
  131. APIERR
  132. Disable( ULONG ulProfileID, DEVINSTID devinst, BOOL fDisable )
  133. {
  134. APIERR err = NERR_Success;
  135. ULONG ulValue = 0;
  136. CONFIGRET configret = ::CM_Get_HW_Prof_Flags(
  137. devinst,
  138. ulProfileID,
  139. &ulValue,
  140. 0x0 );
  141. err = MapCfgMgr32Error( configret );
  142. if (err != NERR_Success)
  143. {
  144. TRACEEOL( "\tEnable: CM_Get_HW_Prof_Flags error " << configret );
  145. return err;
  146. }
  147. if (fDisable)
  148. {
  149. if ( ulValue & CSCONFIGFLAG_DISABLED )
  150. {
  151. TRACEEOL( "Disable: \"" << devinst << "\" already disabled" );
  152. return err;
  153. }
  154. ulValue |= CSCONFIGFLAG_DISABLED;
  155. } else {
  156. if ( !(ulValue & CSCONFIGFLAG_DISABLED) )
  157. {
  158. TRACEEOL( "Disable: \"" << devinst << "\" already enabled" );
  159. return err;
  160. }
  161. ulValue &= ~CSCONFIGFLAG_DISABLED;
  162. }
  163. configret = ::CM_Set_HW_Prof_Flags(
  164. devinst,
  165. ulProfileID,
  166. ulValue,
  167. 0x0 );
  168. err = MapCfgMgr32Error( configret );
  169. if (err != NERR_Success)
  170. {
  171. TRACEEOL( "\tDisable: CM_Set_HW_Prof_Flags error " << configret );
  172. } else {
  173. TRACEEOL( "\tDisable: \"" << devinst
  174. << (CHAR*)((fDisable)?"\" now disabled":"\" now enabled") );
  175. }
  176. return err;
  177. }
  178. APIERR BoundServiceIsWanMediaType( NLS_STR& nlsBoundService,
  179. BOOL* pfWANMediaType,
  180. REG_KEY& regkeyHKLM )
  181. {
  182. const TCHAR * pchBoundService = nlsBoundService.QueryPch();
  183. ISTR istrBoundService( nlsBoundService );
  184. if ( nlsBoundService.strrchr( &istrBoundService, TCH_REGSEPERATOR ) )
  185. {
  186. ++istrBoundService;
  187. pchBoundService = nlsBoundService.QueryPch( istrBoundService );
  188. }
  189. // open HKLM\CurrentControlSet\Services\<bound service>\Parameters key
  190. NLS_STR nlsRegPath( REGSTR_PATH_SERVICES );
  191. nlsRegPath += SZ_REGSEPERATOR;
  192. nlsRegPath += pchBoundService;
  193. nlsRegPath += SZ_REGPARAMETERS;
  194. APIERR err = nlsRegPath.QueryError();
  195. if ( err != NERR_Success )
  196. {
  197. DBGEOL( "BoundServiceIsWanMediaType: string error " << err );
  198. return err;
  199. }
  200. TRACEEOL( "BoundServiceIsWanMediaType: key \"" << nlsRegPath << "\"" );
  201. REG_KEY regkeyParameters(regkeyHKLM, nlsRegPath, KEY_READ);
  202. if ( (err = regkeyParameters.QueryError()) != NERR_Success )
  203. {
  204. TRACEEOL( "BoundServiceIsWanMediaType: key \"" << nlsRegPath <<
  205. "\" error " << err );
  206. return err;
  207. }
  208. DWORD dwMediaType = 0;
  209. if ( (err = regkeyParameters.QueryValue( SZ_REGMEDIATYPE, &dwMediaType))
  210. != NERR_Success )
  211. {
  212. TRACEEOL( "BoundServiceIsWanMediaType: mediatype error " << err );
  213. return err;
  214. }
  215. TRACEEOL( "BoundServiceIsWanMediaType: media type " << dwMediaType );
  216. switch (dwMediaType-1)
  217. {
  218. case NdisMedium802_3:
  219. case NdisMedium802_5:
  220. case NdisMediumFddi:
  221. case NdisMediumLocalTalk:
  222. case NdisMediumDix:
  223. case NdisMediumArcnetRaw:
  224. case NdisMediumArcnet878_2:
  225. case NdisMediumAtm:
  226. *pfWANMediaType = FALSE;
  227. break;
  228. case NdisMediumWan:
  229. case NdisMediumWirelessWan:
  230. case NdisMediumIrda:
  231. *pfWANMediaType = TRUE;
  232. break;
  233. default:
  234. DBGEOL( "BoundServiceIsWanMediaType: invalid media type "
  235. << dwMediaType );
  236. *pfWANMediaType = TRUE;
  237. break;
  238. }
  239. return NERR_Success;
  240. }
  241. APIERR IsWanMediaType( const TCHAR * pszServiceName, BOOL* pfWANMediaType)
  242. {
  243. TRACEEOL( "IsWanMediaType: checking \"" << pszServiceName << "\"" );
  244. // open HKLM key
  245. REG_KEY regkeyHKLM(HKEY_LOCAL_MACHINE, NULL, KEY_READ);
  246. APIERR err = regkeyHKLM.QueryError();
  247. if ( err != NERR_Success )
  248. {
  249. DBGEOL( "IsWanMediaType: HKLM error " << err );
  250. return err;
  251. }
  252. // open HKLM\CurrentControlSet\Services\<service>\Linkage key
  253. NLS_STR nlsRegPath( REGSTR_PATH_SERVICES );
  254. nlsRegPath += SZ_REGSEPERATOR;
  255. nlsRegPath += pszServiceName;
  256. nlsRegPath += SZ_REGLINKAGE;
  257. if ( (err = nlsRegPath.QueryError()) != NERR_Success )
  258. {
  259. DBGEOL( "IsWanMediaType: string error " << err );
  260. return err;
  261. }
  262. TRACEEOL( "IsWanMediaType: key \"" << nlsRegPath << "\"" );
  263. REG_KEY regkeyLinkage(regkeyHKLM, nlsRegPath, KEY_READ);
  264. if ( (err = regkeyLinkage.QueryError()) != NERR_Success )
  265. {
  266. TRACEEOL( "IsWanMediaType: key \"" << nlsRegPath <<
  267. "\" error " << err );
  268. return err;
  269. }
  270. // get Bind parameter and extract service name(s)
  271. STRLIST* pstrlistBind = NULL;
  272. if ( (err = regkeyLinkage.QueryValue( SZ_REGBIND, &pstrlistBind ))
  273. != NERR_Success
  274. || (err = ((pstrlistBind != NULL)
  275. ? NERR_Success : ERROR_NOT_ENOUGH_MEMORY)) != NERR_Success
  276. )
  277. {
  278. TRACEEOL( "IsWanMediaType: bind value error " << err );
  279. return err;
  280. }
  281. ITER_STRLIST iterslBind( *pstrlistBind );
  282. NLS_STR* pnlsBind = NULL;
  283. *pfWANMediaType = FALSE;
  284. while ( (pnlsBind = iterslBind.Next()) != NULL )
  285. {
  286. err = BoundServiceIsWanMediaType( *pnlsBind,
  287. pfWANMediaType,
  288. regkeyHKLM );
  289. if (err != NERR_Success || *pfWANMediaType )
  290. break;
  291. }
  292. delete pstrlistBind; // CODEWORK I have seen problems with this line
  293. return err;
  294. }
  295. /*
  296. * if fSet is FALSE, set *pfNoNetworkProfile to TRUE if no network
  297. * device is enabled, set to FALSE otherwise
  298. *
  299. * if fSet is TRUE and *pfNoNetworkProfile is FALSE,
  300. * enable all network devices
  301. *
  302. * if fSet is TRUE and *pfNoNetworkProfile is TRUE,
  303. * disable all network devices
  304. */
  305. APIERR
  306. DoNetworkProfile( ULONG ulProfileID, BOOL fSet, BOOL* pfNoNetworkProfile )
  307. {
  308. AUTO_CURSOR autocur;
  309. ASSERT( pfNoNetworkProfile != NULL );
  310. APIERR err = NERR_Success;
  311. if (!fSet)
  312. *pfNoNetworkProfile=TRUE;
  313. do // false loop
  314. {
  315. TRACEEOL( "DoNetworkProfile: enumerating NDIS services");
  316. SERVICE_ENUM svcenum( NULL, TRUE, SERVICE_KERNEL_DRIVER, SZ_NDIS );
  317. if ( (err = svcenum.QueryError()) != NERR_Success
  318. || (err = svcenum.GetInfo()) != NERR_Success
  319. )
  320. {
  321. TRACEEOL( "DoNetworkProfile: error " << err << " opening svcenum" );
  322. break;
  323. }
  324. BOOL fFoundAdapter = FALSE;
  325. SERVICE_ENUM_ITER svciter( svcenum );
  326. const SERVICE_ENUM_OBJ* psvc;
  327. while( ( psvc = svciter() ) != NULL )
  328. {
  329. const TCHAR* pszServiceName = psvc->QueryServiceName();
  330. if ( 0 == ::stricmpf( pszServiceName, SZ_NDIS ) )
  331. continue;
  332. BOOL fWANMediaType = FALSE;
  333. if ( (err = IsWanMediaType(pszServiceName, &fWANMediaType))
  334. != NERR_Success)
  335. {
  336. //
  337. // All errors are ignored, and we assume WAN MediaType
  338. //
  339. TRACEEOL( "DoNetworkProfile: ignoring error " << err <<
  340. " checking mediatype of \"" << pszServiceName <<
  341. "\"" );
  342. err = NERR_Success;
  343. continue;
  344. } else if (fWANMediaType) {
  345. TRACEEOL( "DoNetworkProfile: skipping service \"" <<
  346. pszServiceName << "\" due to mediatype" );
  347. continue;
  348. }
  349. ULONG cch = 0;
  350. CONFIGRET configret = ::CM_Get_Device_ID_List_Size(
  351. &cch,
  352. pszServiceName,
  353. CM_GETIDLIST_FILTER_SERVICE );
  354. if ( (err = MapCfgMgr32Error( configret )) != NERR_Success )
  355. {
  356. TRACEEOL("DoNetworkProfile: Get_Device_ID_List_Size returned " << configret );
  357. if (configret == CR_NO_SUCH_VALUE)
  358. {
  359. ASSERT( FALSE );
  360. continue;
  361. }
  362. break;
  363. }
  364. BUFFER bufDeviceIDs( cch*sizeof(TCHAR) );
  365. if ( (err = bufDeviceIDs.QueryError()) != NERR_Success )
  366. break;
  367. do {
  368. configret = ::CM_Get_Device_ID_List(
  369. pszServiceName,
  370. (TCHAR *)(bufDeviceIDs.QueryPtr()),
  371. bufDeviceIDs.QuerySize() / sizeof(TCHAR),
  372. CM_GETIDLIST_FILTER_SERVICE );
  373. if (configret == CR_BUFFER_SMALL)
  374. {
  375. cch *= 2;
  376. if ( (err = bufDeviceIDs.Resize(cch*sizeof(TCHAR))) != NERR_Success )
  377. break;
  378. } else if (configret == CR_NO_SUCH_VALUE)
  379. {
  380. ASSERT( FALSE );
  381. continue;
  382. }
  383. } while (configret == CR_BUFFER_SMALL);
  384. const TCHAR * pchDeviceID = (const TCHAR *)bufDeviceIDs.QueryPtr();
  385. while ( *pchDeviceID != TCH('\0') )
  386. {
  387. fFoundAdapter = TRUE;
  388. DEVINSTID devinst = (DEVINSTID)pchDeviceID;
  389. if (fSet) {
  390. if ( (err = Disable( ulProfileID,
  391. devinst,
  392. *pfNoNetworkProfile)) != NERR_Success)
  393. break;
  394. } else {
  395. BOOL fIsDisabled = FALSE;
  396. if ( (err = IsDisabled( ulProfileID,
  397. devinst,
  398. &fIsDisabled)) != NERR_Success)
  399. break;
  400. if (!fIsDisabled)
  401. {
  402. *pfNoNetworkProfile = FALSE;
  403. break;
  404. }
  405. }
  406. pchDeviceID += ::strlenf(pchDeviceID) + 1;
  407. }
  408. }
  409. TRACEEOL( "DoNetworkProfile: enumerated NDIS services");
  410. if ( !fFoundAdapter && err == NERR_Success )
  411. {
  412. TRACEEOL( "DoNetworkProfile: no adapters found" );
  413. err = IDS_PROFEXT_NOADAPTERS;
  414. }
  415. } while (FALSE); // false loop
  416. return err;
  417. }
  418. BOOL
  419. DllMain(
  420. PVOID hModule,
  421. ULONG Reason,
  422. PCONTEXT pContext
  423. )
  424. /*++
  425. Routine Description:
  426. This is the standard DLL entrypoint routine, called whenever a process
  427. or thread attaches or detaches.
  428. Arguments:
  429. hModule - PVOID parameter that specifies the handle of the DLL
  430. Reason - ULONG parameter that specifies the reason this entrypoint
  431. was called (either PROCESS_ATTACH, PROCESS_DETACH,
  432. THREAD_ATTACH, or THREAD_DETACH).
  433. pContext - ???
  434. Return value:
  435. Returns true if initialization compeleted successfully, false is not.
  436. --*/
  437. {
  438. hInst = (HINSTANCE)hModule;
  439. DBG_UNREFERENCED_PARAMETER(pContext);
  440. switch(Reason) {
  441. case DLL_PROCESS_ATTACH:
  442. DisableThreadLibraryCalls(hInst);
  443. case DLL_PROCESS_DETACH:
  444. case DLL_THREAD_ATTACH:
  445. case DLL_THREAD_DETACH:
  446. break;
  447. }
  448. return TRUE;
  449. } // DllMain
  450. BOOL CALLBACK
  451. ExtensionPropSheetPageProc(
  452. LPVOID lpv,
  453. LPFNADDPROPSHEETPAGE lpfnAddPropSheetPageProc,
  454. LPARAM lParam
  455. )
  456. /*++
  457. Routine Description:
  458. Arguments:
  459. lpv Pointer to an application-defined value that
  460. describes an item for which a property sheet
  461. page is to be created. This parameter can be NULL.
  462. lpfnAddPropSheetPageProc Pointer to the AddPropSheetPageProc function.
  463. The extension dynamic-link library (DLL) calls
  464. this function to add a page to the property sheet.
  465. lParam Application-defined 32-bit value.
  466. Return Value:
  467. If the function succeeds, the return value is TRUE.
  468. If the function fails, the return value is FALSE.
  469. --*/
  470. {
  471. PROPSHEETPAGE PropPage;
  472. HPROPSHEETPAGE hPropPage;
  473. PropPage.dwSize = sizeof(PROPSHEETPAGE);
  474. PropPage.dwFlags = PSP_DEFAULT;
  475. PropPage.hInstance = hInst;
  476. PropPage.pszTemplate = MAKEINTRESOURCE(DLG_HWP_EXT);
  477. PropPage.pszIcon = NULL;
  478. PropPage.pszTitle = NULL;
  479. PropPage.pfnDlgProc = NetworkPropDlg;
  480. PropPage.lParam = lParam;
  481. PropPage.pfnCallback = NULL;
  482. hPropPage = CreatePropertySheetPage(&PropPage);
  483. if (hPropPage == NULL) {
  484. return FALSE;
  485. }
  486. (lpfnAddPropSheetPageProc)(hPropPage, 0);
  487. return TRUE;
  488. } // ExtensionPropSheetPageProc
  489. typedef struct {
  490. LONG ulProfile;
  491. BOOL fNoNet;
  492. BOOL fError;
  493. } PROFEXT_INTERNAL;
  494. BOOL
  495. APIENTRY
  496. NetworkPropDlg(
  497. HWND hDlg,
  498. UINT uMessage,
  499. WPARAM wParam,
  500. LPARAM lParam
  501. )
  502. {
  503. ULONG ulProfile = 0;
  504. APIERR err = NERR_Success;
  505. switch (uMessage)
  506. {
  507. case WM_INITDIALOG:
  508. {
  509. PROFEXT_INTERNAL* pprofext = new PROFEXT_INTERNAL;
  510. // CODEWORK I should free this at some point
  511. ASSERT( pprofext != NULL );
  512. ::memsetf( pprofext, '\0', sizeof(PROFEXT_INTERNAL) );
  513. ::SetWindowLong(hDlg, DWL_USER, (LONG)pprofext);
  514. //
  515. // on WM_INITDIALOG call, property sheet's lParam field
  516. // contains the profile ID, save it in window long word for
  517. // use with other messages later
  518. //
  519. ulProfile = (ULONG)((LPPROPSHEETPAGE)lParam)->lParam;
  520. ASSERT( (LONG)ulProfile >= 0 );
  521. pprofext->ulProfile = ulProfile;
  522. BOOL fNoNetworkProfile = FALSE;
  523. err = DoNetworkProfile( ulProfile,
  524. FALSE,
  525. &fNoNetworkProfile );
  526. if (err != NERR_Success) {
  527. HWND hwndEdit = ::GetDlgItem(hDlg, IDC_ERROR);
  528. ASSERT( hwndEdit != NULL );
  529. HandleError( hDlg, err, hwndEdit );
  530. pprofext->fError = TRUE;
  531. } else {
  532. pprofext->fNoNet = (fNoNetworkProfile)?1:0;
  533. }
  534. //
  535. // Call CM_Get_Hardware_Profile_Info to get info about
  536. // the specified profile (ulProfile).
  537. //
  538. return FALSE;
  539. }
  540. case WM_NOTIFY:
  541. if (!lParam) {
  542. break;
  543. }
  544. switch (((NMHDR *)lParam)->code) {
  545. case PSN_SETACTIVE:
  546. {
  547. PROFEXT_INTERNAL* pprofext =
  548. (PROFEXT_INTERNAL*)::GetWindowLong(hDlg, DWL_USER);
  549. ASSERT( pprofext != NULL );
  550. HWND hwndCheckbox = ::GetDlgItem(hDlg, IDC_NONET);
  551. HWND hwndEnableText = ::GetDlgItem(hDlg, IDC_ENABLE);
  552. HWND hwndDisableText = ::GetDlgItem(hDlg, IDC_DISABLE);
  553. ASSERT( hwndCheckbox
  554. && hwndEnableText && hwndDisableText );
  555. ::EnableWindow(
  556. hwndEnableText,
  557. pprofext->fNoNet && !(pprofext->fError) );
  558. ::EnableWindow(
  559. hwndDisableText,
  560. !(pprofext->fNoNet) && !(pprofext->fError) );
  561. if (pprofext->fError)
  562. {
  563. ::EnableWindow( hwndCheckbox, FALSE );
  564. } else {
  565. ::SendMessage( hwndCheckbox, BM_SETCHECK,
  566. (pprofext->fNoNet)?1:0, 0 );
  567. }
  568. }
  569. break;
  570. case PSN_KILLACTIVE:
  571. {
  572. PROFEXT_INTERNAL* pprofext =
  573. (PROFEXT_INTERNAL*)::GetWindowLong(hDlg, DWL_USER);
  574. ASSERT( pprofext != NULL );
  575. //
  576. // validate selections, this page is active until I return FALSE
  577. // in DWL_MSGRESULT
  578. //
  579. if (pprofext->fError)
  580. break; // error or no adapter as initial state
  581. TRACEEOL( "NetworkPropDlg: pprofext->fNoNet is "
  582. << pprofext->fNoNet );
  583. HWND hwnd = ::GetDlgItem(hDlg, IDC_NONET);
  584. ASSERT( hwnd != NULL );
  585. BOOL fCurrentNoNet = (::SendMessage(hwnd, BM_GETCHECK, 0, 0) != 0)
  586. ? TRUE : FALSE;
  587. TRACEEOL( "NetworkPropDlg: fCurrentNoNet is " << fCurrentNoNet );
  588. if (pprofext->fNoNet != fCurrentNoNet)
  589. {
  590. err = DoNetworkProfile(
  591. pprofext->ulProfile, TRUE, &fCurrentNoNet );
  592. if (err != NERR_Success) {
  593. HandleError( hDlg, err );
  594. ::SetWindowLong(hDlg, DWL_MSGRESULT, TRUE); // TRUE if error
  595. break;
  596. }
  597. }
  598. pprofext->fNoNet = fCurrentNoNet;
  599. ::SetWindowLong(hDlg, DWL_MSGRESULT, FALSE); // TRUE if error
  600. }
  601. break;
  602. case PSN_RESET:
  603. //
  604. // user canceled the property sheet
  605. //
  606. break;
  607. }
  608. break;
  609. case WM_HELP:
  610. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, HELP_FILE,
  611. HELP_WM_HELP, (DWORD)(LPTSTR)HwProfileHelpIds);
  612. break;
  613. case WM_CONTEXTMENU:
  614. WinHelp((HWND)wParam, HELP_FILE, HELP_CONTEXTMENU,
  615. (DWORD)(LPTSTR)HwProfileHelpIds);
  616. break;
  617. case WM_COMMAND:
  618. default:
  619. return FALSE;
  620. break;
  621. }
  622. return TRUE;
  623. } // NetworkPropDlg