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.

5614 lines
181 KiB

  1. #include "stdafx.h"
  2. #include "theapp.h"
  3. #include "netconn.h"
  4. #include "netapi.h"
  5. #include "prnutil.h"
  6. #include "install.h"
  7. #include "mydocs.h"
  8. #include "comctlwrap.h"
  9. #include "icsinst.h"
  10. #include "defconn.h"
  11. #include "initguid.h"
  12. DEFINE_GUID(CLSID_FolderItem, 0xfef10fa2, 0x355e, 0x4e06, 0x93, 0x81, 0x9b, 0x24, 0xd7, 0xf7, 0xcc, 0x88);
  13. DEFINE_GUID(CLSID_SharedAccessConnectionManager, 0xBA126AE0,0x2166,0x11D1,0xB1,0xD0,0x00,0x80,0x5F,0xC1,0x27,0x0E); // this doesn't exist in the shell tree
  14. #include "resource.h"
  15. #include "newapi.h"
  16. #include "shgina.h"
  17. #include "hnetcfg.h"
  18. #include "netconp.h"
  19. #include "hnetbcon.h" // ICSLapCtl.h
  20. #include "Lm.h"
  21. #include "htmlhelp.h"
  22. #include "nla.h"
  23. #include "netinet.h"
  24. #include "netip.h"
  25. #include "netras.h"
  26. #include "netutil.h"
  27. // include files necessary for showing diagrams using ShowHTMLDialog. TinQian
  28. #include <urlmon.h>
  29. #include <mshtmhst.h>
  30. #include <mshtml.h>
  31. #include <atlbase.h>
  32. // Debugging #defines:
  33. // Uncomment NO_CHECK_DOMAIN when you want to test the wizard on a domain machine - just don't apply changes ;)
  34. // #define NO_CHECK_DOMAIN
  35. // Uncomment NO_CONFIG to neuter the wizard for UI-only testing
  36. // #define NO_CONFIG
  37. // Uncomment FAKE_ICS to simulate the "ICS machine" state
  38. // #define FAKE_ICS
  39. // Uncomment FAKE_UNPLUGGED to simulate unplugged connections
  40. // #define FAKE_UNPLUGGED
  41. // Uncomment FAKE_REBOOTREQUIRED to simulate reboot required
  42. // #define FAKE_REBOOTREQUIRED
  43. // Delay Load ole32.dll function CoSetProxyBlanket since it isn't on W95 Gold
  44. // and it's only used by the wizard on NT
  45. #define CoSetProxyBlanket CoSetProxyBlanket_NT
  46. EXTERN_C STDAPI CoSetProxyBlanket_NT(IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel, RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities);
  47. // Functions not in any include file yet
  48. extern int AdapterIndexFromClass(LPTSTR szClass, BOOL bSkipClass);
  49. #define LWS_IGNORERETURN 0x0002
  50. #define MAX_HNW_PAGES 30
  51. #define MAX_WORKGROUPS 20
  52. #define CONN_EXTERNAL 0x00000001
  53. #define CONN_INTERNAL 0x00000002
  54. #define CONN_UNPLUGGED 0x00000004
  55. // Return value to use for sharing configuration conflict
  56. #define HNETERRORSTART 0x200
  57. #define E_ANOTHERADAPTERSHARED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, HNETERRORSTART+1)
  58. #define E_ICSADDRESSCONFLICT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, HNETERRORSTART+2)
  59. class CEnsureSingleInstance
  60. {
  61. public:
  62. CEnsureSingleInstance(LPCTSTR szCaption);
  63. ~CEnsureSingleInstance();
  64. BOOL ShouldExit() { return m_fShouldExit;}
  65. private:
  66. BOOL m_fShouldExit;
  67. HANDLE m_hEvent;
  68. };
  69. CEnsureSingleInstance::CEnsureSingleInstance(LPCTSTR szCaption)
  70. {
  71. // Create an event
  72. m_hEvent = CreateEvent(NULL, TRUE, FALSE, szCaption);
  73. // If any weird errors occur, default to running the instance
  74. m_fShouldExit = FALSE;
  75. if (NULL != m_hEvent)
  76. {
  77. // If our event isn't signaled, we're the first instance
  78. m_fShouldExit = (WAIT_OBJECT_0 == WaitForSingleObject(m_hEvent, 0));
  79. if (m_fShouldExit)
  80. {
  81. // app should exit after calling ShouldExit()
  82. // Find and show the caption'd window
  83. HWND hwndActivate = FindWindow(NULL, szCaption);
  84. if (IsWindow(hwndActivate))
  85. {
  86. SetForegroundWindow(hwndActivate);
  87. }
  88. }
  89. else
  90. {
  91. // Signal that event
  92. SetEvent(m_hEvent);
  93. }
  94. }
  95. }
  96. CEnsureSingleInstance::~CEnsureSingleInstance()
  97. {
  98. if (NULL != m_hEvent)
  99. {
  100. CloseHandle(m_hEvent);
  101. }
  102. }
  103. typedef struct _tagHOMENETSETUPINFO
  104. {
  105. HWND hwnd;
  106. DWORD cbSize;
  107. DWORD dwFlags;
  108. // Data for NT - NetConnections are temporarily represented by their corresponding GUIDs to cross the
  109. // thread boundary for asynchronous configuration.
  110. BOOL fAsync;
  111. GUID guidExternal;
  112. GUID* prgguidInternal;
  113. DWORD cguidInternal;
  114. UINT umsgAsyncNotify;
  115. INetConnection* pncExternal;
  116. INetConnection** prgncInternal;
  117. DWORD cncInternal;
  118. // Data for Win9x
  119. const NETADAPTER* pNA; // list of adapters.
  120. UINT cNA; // count of entries in pNA.
  121. RASENTRYNAME* pRas; // list of RAS connectoids.
  122. UINT cRas; // count of RAS connectoids.
  123. UINT ipaExternal;
  124. UINT ipaInternal;
  125. // Data for both NT and Win9x
  126. TCHAR szComputer[CNLEN + 1];
  127. TCHAR szComputerDescription[256];
  128. TCHAR szWorkgroup[LM20_DNLEN + 1];
  129. // Out-data
  130. BOOL fRebootRequired;
  131. } HOMENETSETUPINFO, *PHOMENETSETUPINFO;
  132. // Function prototypes
  133. void HelpCenter(HWND hwnd, LPCWSTR pszTopic);
  134. void BoldControl(HWND hwnd, int id);
  135. void ShowControls(HWND hwndParent, const int *prgControlIDs, DWORD nControls, int nCmdShow);
  136. HRESULT ConfigureHomeNetwork(PHOMENETSETUPINFO pInfo);
  137. DWORD WINAPI ConfigureHomeNetworkThread(void* pData);
  138. HRESULT ConfigureHomeNetworkSynchronous(PHOMENETSETUPINFO pInfo);
  139. HRESULT ConfigureICSBridgeFirewall(PHOMENETSETUPINFO pInfo);
  140. HRESULT EnableSimpleSharing();
  141. HRESULT GetConnections(HDPA* phdpa);
  142. int FreeConnectionDPACallback(LPVOID pFreeMe, LPVOID pData);
  143. HRESULT GetConnectionsFolder(IShellFolder** ppsfConnections);
  144. //HRESULT GetConnectionIconIndex(GUID& guidConnection, IShellFolder* psfConnections, int* pIndex, HIMAGELIST imgList);
  145. HRESULT GetDriveNameAndIconIndex(LPWSTR pszDrive, LPWSTR pszDisplayName, DWORD cchDisplayName, int* pIndex);
  146. void W9xGetNetTypeName(BYTE bNicType, WCHAR* pszBuff, UINT cchBuff);
  147. BOOL W9xIsValidAdapter(const NETADAPTER* pNA, DWORD dwFlags);
  148. BOOL W9xIsAdapterDialUp(const NETADAPTER* pAdapter);
  149. BOOL IsEqualConnection(INetConnection* pnc1, INetConnection* pnc2);
  150. void GetTitleFont(LPTSTR pszFaceName, DWORD cch);
  151. LONG GetTitlePointSize(void);
  152. BOOL FormatMessageString(UINT idTemplate, LPTSTR pszStrOut, DWORD cchSize, ...);
  153. int DisplayFormatMessage(HWND hwnd, UINT idCaption, UINT idFormatString, UINT uType, ...);
  154. HRESULT SetProxyBlanket(IUnknown * pUnk);
  155. HRESULT MakeUniqueShareName(LPCTSTR pszBaseName, LPTSTR pszUniqueName, DWORD cchName);
  156. HRESULT WriteSetupInfoToRegistry(PHOMENETSETUPINFO pInfo);
  157. HRESULT ReadSetupInfoFromRegistry(PHOMENETSETUPINFO pInfo);
  158. HRESULT ShareWellKnownFolders(PHOMENETSETUPINFO pInfo);
  159. HRESULT ShareAllPrinters();
  160. HRESULT DeleteSetupInfoFromRegistry();
  161. HRESULT IsUserLocalAdmin(HANDLE TokenHandle, BOOL* pfIsAdmin);
  162. BOOL AllPlatformGetComputerName(LPWSTR pszName, DWORD cchName);
  163. BOOL AllPlatformSetComputerName(LPCWSTR pszName);
  164. void FreeInternalConnections(PHOMENETSETUPINFO pInfo);
  165. void FreeInternalGUIDs(PHOMENETSETUPINFO pInfo);
  166. void FreeExternalConnection(PHOMENETSETUPINFO pInfo);
  167. HRESULT GetConnectionByGUID(HDPA hdpaConnections, const GUID* pguid, INetConnection** ppnc);
  168. HRESULT GUIDsToConnections(PHOMENETSETUPINFO pInfo);
  169. HRESULT GetConnectionGUID(INetConnection* pnc, GUID* pguid);
  170. HRESULT ConnectionsToGUIDs(PHOMENETSETUPINFO pInfo);
  171. BOOL IsValidNameSyntax(LPCWSTR pszName, NETSETUP_NAME_TYPE type);
  172. void STDMETHODCALLTYPE ConfigurationLogCallback(LPCWSTR pszLogEntry, LPARAM lParam);
  173. // Home network wizard class
  174. class CHomeNetworkWizard : public IHomeNetworkWizard
  175. {
  176. friend HRESULT CHomeNetworkWizard_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
  177. public:
  178. // IUnknown
  179. STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObj);
  180. STDMETHOD_(ULONG, AddRef) ();
  181. STDMETHOD_(ULONG, Release) ();
  182. // IHomeNetworkWizard
  183. STDMETHOD(ConfigureSilently)(LPCWSTR pszPublicConnection, DWORD hnetFlags, BOOL* pfRebootRequired);
  184. STDMETHOD(ShowWizard)(HWND hwnd, BOOL* pfRebootRequired);
  185. protected:
  186. CHomeNetworkWizard();
  187. HRESULT Initialize();
  188. HRESULT Uninitialize();
  189. private:
  190. // Shared functions
  191. void DestroyConnectionList(HWND hwndList);
  192. void InitializeConnectionList(HWND hwndList, DWORD dwFlags);
  193. void FillConnectionList(HWND hwndList, INetConnection* pncExcludeFromList, DWORD dwFlags);
  194. BOOL ShouldShowConnection(INetConnection* pnc, INetConnection* pncExcludeFromList, DWORD dwFlags);
  195. BOOL IsConnectionICSPublic(INetConnection* pnc);
  196. BOOL IsConnectionUnplugged(INetConnection* pnc);
  197. BOOL W9xAddAdapterToList(const NETADAPTER* pNA, const WCHAR* pszDesc, UINT uiAdapterIndex, UINT uiDialupIndex, HWND hwndList, DWORD dwFlags);
  198. UINT W9xEnumRasEntries(void);
  199. HRESULT GetConnectionByName(LPCWSTR pszName, INetConnection** ppncOut);
  200. HRESULT GetInternalConnectionArray(INetConnection* pncExclude, INetConnection*** pprgncArray, DWORD* pcncArray);
  201. DWORD GetConnectionCount(INetConnection* pncExclude, DWORD dwFlags);
  202. void ReplaceStaticWithLink(HWND hwndStatic, UINT idcLinkControl, UINT idsLinkText);
  203. BOOL IsMachineOnDomain();
  204. BOOL IsMachineWrongOS();
  205. BOOL IsICSIPInUse( WCHAR** ppszHost, PDWORD pdwSize );
  206. // Per-Page functions
  207. // Welcome
  208. static INT_PTR CALLBACK WelcomePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  209. void WelcomeSetTitleFont(HWND hwnd);
  210. // No home network hardware
  211. static INT_PTR CALLBACK NoHardwareWelcomePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  212. // Page with instructions for manual configuration of the network
  213. void ManualRefreshConnectionList();
  214. static INT_PTR CALLBACK ManualConfigPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  215. // User has some network hardware unplugged
  216. BOOL UnpluggedFillList(HWND hwnd);
  217. static INT_PTR CALLBACK UnpluggedPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  218. // Found ICS (Internet connection sharing)
  219. static INT_PTR CALLBACK FoundIcsPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  220. void FoundIcsSetText(HWND hwnd);
  221. BOOL GetICSMachine(LPTSTR pszICSMachineName, DWORD cch);
  222. // Connect
  223. static INT_PTR CALLBACK ConnectPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  224. void ConnectSetDefault(HWND hwnd);
  225. void ConnectNextPage(HWND hwnd);
  226. // Show Me Links
  227. void ShowMeLink(HWND hwnd, LPCWSTR pszTopic);
  228. // Connect other (alternative methods for connection)
  229. static INT_PTR CALLBACK ConnectOtherPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  230. // Public
  231. static INT_PTR CALLBACK PublicPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  232. void PublicSetActive(HWND hwnd);
  233. void PublicSetControlState(HWND hwnd);
  234. void PublicNextPage(HWND hwnd);
  235. void PublicGetControlPositions(HWND hwnd);
  236. void PublicResetControlPositions(HWND hwnd);
  237. void PublicMoveControls(HWND hwnd, BOOL fItemPreselected);
  238. // File sharing
  239. static INT_PTR CALLBACK EdgelessPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  240. void EdgelessSetActive(HWND hwnd);
  241. // ICS conflict
  242. void ICSConflictSetActive(HWND hwnd);
  243. static INT_PTR CALLBACK ICSConflictPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  244. // BridgeWarning (do you want to manually configure the bridge? Are you crazy !?)
  245. static INT_PTR CALLBACK BridgeWarningPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  246. // Private
  247. static INT_PTR CALLBACK PrivatePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  248. void PrivateNextPage(HWND hwnd);
  249. void PrivateSetControlState(HWND hwnd);
  250. // Name (computer and workgroup)
  251. static INT_PTR CALLBACK NamePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  252. void NameInitDialog(HWND hwnd);
  253. void NameSetControlState(HWND hwnd);
  254. HRESULT NameNextPage(HWND hwnd);
  255. // Workgroup name
  256. void WorkgroupSetControlState(HWND hwnd);
  257. HRESULT WorkgroupNextPage(HWND hwnd);
  258. static INT_PTR CALLBACK WorkgroupPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  259. // Summary
  260. static INT_PTR CALLBACK SummaryPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  261. void SummarySetActive(HWND hwnd);
  262. // Progress (while the configuration is taking place)
  263. static INT_PTR CALLBACK ProgressPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  264. // Almost done (after configuration but before the "completed" page)
  265. static INT_PTR CALLBACK AlmostDonePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  266. // Choose disk drive
  267. void FillDriveList(HWND hwndList);
  268. void ChooseDiskSetControlState(HWND hwnd);
  269. static INT_PTR CALLBACK ChooseDiskPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  270. // Insert disk
  271. static HRESULT GetSourceFilePath(LPSTR pszSource, DWORD cch);
  272. static INT_PTR CALLBACK InsertDiskPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  273. // Floppy and XP CD "run the wizard" instructions
  274. static INT_PTR CALLBACK InstructionsPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  275. // Finish
  276. static INT_PTR CALLBACK FinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  277. // Error finish
  278. static INT_PTR CALLBACK ErrorFinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  279. // No Hardware Finish
  280. // An alternate finish if they have a LAN card ONLY, and its used for an INet connection,
  281. // so therefore they have no LAN cards connecting to other computers...
  282. static INT_PTR CALLBACK NoHardwareFinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  283. // Can't Run Wizard Pages
  284. // An alternate welcome page when the user isn't an adminm or doesn't have permissions,
  285. static INT_PTR CALLBACK CantRunWizardPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  286. static CHomeNetworkWizard* GetThis(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  287. // Get Icon Index for network connections based on GUIDs
  288. HRESULT GetConnectionIconIndex(GUID& guidConnection, IShellFolder* psfConnections, int* pIndex);
  289. // Helpers
  290. UINT PopPage()
  291. {
  292. ASSERT(_iPageStackTop);
  293. return _rguiPageStack[--_iPageStackTop];
  294. }
  295. void PushPage(UINT uiPageId)
  296. {
  297. ASSERT(_iPageStackTop < MAX_HNW_PAGES);
  298. _rguiPageStack[_iPageStackTop++] = uiPageId;
  299. }
  300. // Data
  301. HDPA _hdpaConnections;
  302. HOMENETSETUPINFO _hnetInfo;
  303. // even though CNLEN+1 is the limit of a name buffer, friendly names can be longer
  304. TCHAR _szICSMachineName[MAX_PATH]; // Machine on the network doing ICS, if applicable
  305. UINT _rguiPageStack[MAX_HNW_PAGES]; // Stackopages
  306. int _iPageStackTop; // Current top of the stack
  307. BOOL _fManualBridgeConfig; // The user wants to manuall configure the bridge
  308. BOOL _fICSClient;// This computer will connect through an ICS machine or another sharing device
  309. // Shell image lists - never free these
  310. HIMAGELIST _himlSmall;
  311. HIMAGELIST _himlLarge;
  312. LONG _cRef;
  313. BOOL _fShowPublicPage;
  314. BOOL _fShowSharingPage;
  315. BOOL _fNoICSQuestion;
  316. BOOL _fNoHomeNetwork;
  317. BOOL _fExternalOnly;
  318. UINT _iDrive; // Ordinal of removable drive for floppy creation
  319. WCHAR _szDrive[256]; // Name of removable drive
  320. BOOL _fCancelCopy;
  321. BOOL _fFloppyInstructions; // Show the floppy, as opposed to CD, instructions
  322. // data structure used by show me links
  323. HINSTANCE hinstMSHTML;
  324. SHOWHTMLDIALOGEXFN * pfnShowHTMLDialog;
  325. IHTMLWindow2 * showMeDlgWnd, * pFrameWindow;
  326. // Network Connection folder and folder view call back. Used by Connection List Views.
  327. IShellFolder *_psfConnections;
  328. IShellFolderViewCB *_pConnViewCB;
  329. struct PUBLICCONTROLPOSITIONS
  330. {
  331. RECT _rcSelectMessage;
  332. RECT _rcListLabel;
  333. RECT _rcList;
  334. RECT _rcHelpIcon;
  335. RECT _rcHelpText;
  336. } PublicControlPositions;
  337. };
  338. int FreeConnectionDPACallback(LPVOID pFreeMe, LPVOID pData)
  339. {
  340. ((INetConnection*) pFreeMe)->Release();
  341. return 1;
  342. }
  343. void InitHnetInfo(HOMENETSETUPINFO* pInfo)
  344. {
  345. ZeroMemory(pInfo, sizeof (HOMENETSETUPINFO));
  346. pInfo->cbSize = sizeof (HOMENETSETUPINFO);
  347. pInfo->ipaExternal = -1;
  348. pInfo->ipaInternal = -1;
  349. }
  350. // Creation function
  351. HRESULT HomeNetworkWizard_RunFromRegistry(HWND hwnd, BOOL* pfRebootRequired)
  352. {
  353. HOMENETSETUPINFO setupInfo;
  354. InitHnetInfo(&setupInfo);
  355. HRESULT hr = ReadSetupInfoFromRegistry(&setupInfo);
  356. if (S_OK == hr)
  357. {
  358. setupInfo.dwFlags = HNET_SHAREPRINTERS | HNET_SHAREFOLDERS;
  359. setupInfo.hwnd = hwnd;
  360. hr = ConfigureHomeNetwork(&setupInfo);
  361. *pfRebootRequired = setupInfo.fRebootRequired;
  362. }
  363. DeleteSetupInfoFromRegistry();
  364. return hr;
  365. }
  366. HRESULT HomeNetworkWizard_ShowWizard(HWND hwnd, BOOL* pfRebootRequired)
  367. {
  368. if (*pfRebootRequired)
  369. *pfRebootRequired = FALSE;
  370. HRESULT hr = HomeNetworkWizard_RunFromRegistry(hwnd, pfRebootRequired);
  371. if (S_FALSE == hr)
  372. {
  373. IUnknown* punk;
  374. hr = CHomeNetworkWizard_CreateInstance(NULL, &punk, NULL);
  375. if (SUCCEEDED(hr))
  376. {
  377. IHomeNetworkWizard* pwizard;
  378. hr = punk->QueryInterface(IID_PPV_ARG(IHomeNetworkWizard, &pwizard));
  379. if (SUCCEEDED(hr))
  380. {
  381. hr = pwizard->ShowWizard(hwnd, pfRebootRequired);
  382. pwizard->Release();
  383. }
  384. punk->Release();
  385. }
  386. }
  387. return hr;
  388. }
  389. HRESULT CHomeNetworkWizard_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi)
  390. {
  391. *ppunk = NULL;
  392. if (punkOuter)
  393. return CLASS_E_NOAGGREGATION;
  394. CHomeNetworkWizard* pwiz = new CHomeNetworkWizard();
  395. if (!pwiz)
  396. return E_OUTOFMEMORY;
  397. HRESULT hr = pwiz->QueryInterface(IID_PPV_ARG(IUnknown, ppunk));
  398. pwiz->Release();
  399. return hr;
  400. }
  401. // IUnknown
  402. HRESULT CHomeNetworkWizard::QueryInterface(REFIID riid, LPVOID* ppvObj)
  403. {
  404. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IHomeNetworkWizard))
  405. {
  406. AddRef();
  407. *ppvObj = static_cast<IHomeNetworkWizard *>(this);
  408. }
  409. else
  410. {
  411. *ppvObj = NULL;
  412. }
  413. return *ppvObj ? S_OK : E_NOINTERFACE;
  414. }
  415. ULONG CHomeNetworkWizard::AddRef()
  416. {
  417. return (ULONG) InterlockedIncrement(&_cRef);
  418. }
  419. ULONG CHomeNetworkWizard::Release()
  420. {
  421. ASSERT( 0 != _cRef );
  422. ULONG cRef = InterlockedDecrement(&_cRef);
  423. if ( 0 == cRef )
  424. {
  425. delete this;
  426. }
  427. return cRef;
  428. }
  429. HRESULT CHomeNetworkWizard::GetConnectionByName(LPCWSTR pszName, INetConnection** ppncOut)
  430. {
  431. *ppncOut = NULL;
  432. DWORD cItems = DPA_GetPtrCount(_hdpaConnections);
  433. DWORD iItem = 0;
  434. while ((iItem < cItems) && (NULL == *ppncOut))
  435. {
  436. INetConnection* pnc = (INetConnection*) DPA_GetPtr(_hdpaConnections, iItem);
  437. NETCON_PROPERTIES* pncprops;
  438. HRESULT hr = pnc->GetProperties(&pncprops);
  439. if (SUCCEEDED(hr))
  440. {
  441. if (0 == StrCmpIW(pszName, pncprops->pszwName))
  442. {
  443. *ppncOut = pnc;
  444. (*ppncOut)->AddRef();
  445. }
  446. NcFreeNetconProperties(pncprops);
  447. }
  448. iItem ++;
  449. }
  450. return (*ppncOut) ? S_OK : E_FAIL;
  451. }
  452. HRESULT CHomeNetworkWizard::GetInternalConnectionArray(INetConnection* pncExclude, INetConnection*** pprgncArray, DWORD* pcncArray)
  453. {
  454. HRESULT hr = S_OK;
  455. *pprgncArray = NULL;
  456. DWORD cTotalConnections = DPA_GetPtrCount(_hdpaConnections);
  457. DWORD cInternalConnections = GetConnectionCount(pncExclude, CONN_INTERNAL);
  458. if (cInternalConnections)
  459. {
  460. (*pprgncArray) = (INetConnection**) LocalAlloc(LPTR, (cInternalConnections + 1) * sizeof (INetConnection*));
  461. // Note that we allocated an extra entry since this is a null-terminated array
  462. if (*pprgncArray)
  463. {
  464. DWORD nInternalConnection = 0;
  465. for (DWORD n = 0; n < cTotalConnections; n++)
  466. {
  467. INetConnection* pnc = (INetConnection*) DPA_GetPtr(_hdpaConnections, n);
  468. if (ShouldShowConnection(pnc, pncExclude, CONN_INTERNAL))
  469. {
  470. pnc->AddRef();
  471. (*pprgncArray)[nInternalConnection++] = pnc;
  472. }
  473. }
  474. ASSERT(nInternalConnection == cInternalConnections);
  475. }
  476. else
  477. {
  478. hr = E_OUTOFMEMORY;
  479. }
  480. }
  481. if (SUCCEEDED(hr))
  482. {
  483. *pcncArray = cInternalConnections;
  484. }
  485. return hr;
  486. }
  487. HRESULT CHomeNetworkWizard::ConfigureSilently(LPCWSTR pszPublicConnection, DWORD hnetFlags, BOOL* pfRebootRequired)
  488. {
  489. // Never set workgroup name
  490. hnetFlags &= (~HNET_SETWORKGROUPNAME);
  491. if (!g_fRunningOnNT)
  492. return E_NOTIMPL;
  493. HRESULT hr = Initialize();
  494. if (SUCCEEDED(hr))
  495. {
  496. _hnetInfo.dwFlags = hnetFlags;
  497. // Calculate what the external and internal adapters will be...
  498. if (pszPublicConnection)
  499. {
  500. hr = GetConnectionByName(pszPublicConnection, &_hnetInfo.pncExternal);
  501. }
  502. else
  503. {
  504. _hnetInfo.pncExternal = NULL;
  505. }
  506. if (SUCCEEDED(hr))
  507. {
  508. // Get all LAN connections except the public connection
  509. if (_hnetInfo.dwFlags & HNET_BRIDGEPRIVATE)
  510. {
  511. hr = GetInternalConnectionArray(_hnetInfo.pncExternal, &(_hnetInfo.prgncInternal), &_hnetInfo.cncInternal);
  512. }
  513. if (SUCCEEDED(hr))
  514. {
  515. hr = ConfigureHomeNetwork(&_hnetInfo);
  516. *pfRebootRequired = _hnetInfo.fRebootRequired;
  517. }
  518. }
  519. Uninitialize();
  520. }
  521. return hr;
  522. }
  523. CHomeNetworkWizard::CHomeNetworkWizard() :
  524. _cRef(1)
  525. {}
  526. HRESULT CHomeNetworkWizard::Initialize()
  527. {
  528. _fExternalOnly = FALSE;
  529. _fNoICSQuestion = FALSE;
  530. _hdpaConnections = NULL;
  531. _iPageStackTop = 0;
  532. _fManualBridgeConfig = FALSE;
  533. _fICSClient = FALSE;
  534. _psfConnections = NULL;
  535. _pConnViewCB = NULL;
  536. InitHnetInfo(&_hnetInfo);
  537. *_szICSMachineName = 0;
  538. HRESULT hr;
  539. if (g_fRunningOnNT)
  540. {
  541. hr = GetConnections(&_hdpaConnections);
  542. }
  543. else
  544. {
  545. _hnetInfo.cNA = EnumCachedNetAdapters(&_hnetInfo.pNA);
  546. hr = S_OK;
  547. if ( _hnetInfo.cNA > 0 )
  548. {
  549. _hnetInfo.ipaInternal = 0;
  550. }
  551. }
  552. // Get the shell image lists - never free these
  553. if (!Shell_GetImageLists(&_himlLarge, &_himlSmall))
  554. {
  555. hr = E_FAIL;
  556. }
  557. // variables used by displaying show me links
  558. hinstMSHTML = NULL;
  559. pfnShowHTMLDialog = NULL;
  560. showMeDlgWnd = NULL;
  561. pFrameWindow = NULL;
  562. return hr;
  563. }
  564. HRESULT CHomeNetworkWizard::Uninitialize()
  565. {
  566. if (g_fRunningOnNT)
  567. {
  568. if (_hdpaConnections)
  569. {
  570. DPA_DestroyCallback(_hdpaConnections, FreeConnectionDPACallback, NULL);
  571. _hdpaConnections = NULL;
  572. }
  573. // Free public lan information
  574. FreeExternalConnection(&_hnetInfo);
  575. // Free private lan information
  576. FreeInternalConnections(&_hnetInfo);
  577. if (_psfConnections != NULL)
  578. _psfConnections->Release();
  579. if (_pConnViewCB != NULL)
  580. _pConnViewCB->Release();
  581. }
  582. else
  583. {
  584. if (_hnetInfo.pNA)
  585. {
  586. FlushNetAdapterCache();
  587. _hnetInfo.pNA = NULL;
  588. }
  589. if (_hnetInfo.pRas)
  590. {
  591. LocalFree(_hnetInfo.pRas);
  592. _hnetInfo.pRas = NULL;
  593. }
  594. }
  595. // release resources used by show me links
  596. if (hinstMSHTML)
  597. FreeLibrary(hinstMSHTML);
  598. if (showMeDlgWnd != NULL)
  599. showMeDlgWnd->Release();
  600. if (pFrameWindow != NULL)
  601. pFrameWindow->Release();
  602. return S_OK;
  603. }
  604. // TODO: Move the formatting functions here to a util file or something...
  605. BOOL FormatMessageString(UINT idTemplate, LPTSTR pszStrOut, DWORD cchSize, ...)
  606. {
  607. BOOL fResult = FALSE;
  608. va_list vaParamList;
  609. TCHAR szFormat[1024];
  610. if (LoadString(g_hinst, idTemplate, szFormat, ARRAYSIZE(szFormat)))
  611. {
  612. va_start(vaParamList, cchSize);
  613. fResult = FormatMessage(FORMAT_MESSAGE_FROM_STRING, szFormat, 0, 0, pszStrOut, cchSize, &vaParamList);
  614. va_end(vaParamList);
  615. }
  616. return fResult;
  617. }
  618. int DisplayFormatMessage(HWND hwnd, UINT idCaption, UINT idFormatString, UINT uType, ...)
  619. {
  620. int iResult = IDCANCEL;
  621. TCHAR szError[512]; *szError = 0;
  622. TCHAR szCaption[256];
  623. TCHAR szFormat[512]; *szFormat = 0;
  624. // Load and format the error body
  625. if (LoadString(g_hinst, idFormatString, szFormat, ARRAYSIZE(szFormat)))
  626. {
  627. va_list arguments;
  628. va_start(arguments, uType);
  629. if (FormatMessage(FORMAT_MESSAGE_FROM_STRING, szFormat, 0, 0, szError, ARRAYSIZE(szError), &arguments))
  630. {
  631. // Load the caption
  632. if (LoadString(g_hinst, idCaption, szCaption, ARRAYSIZE(szCaption)))
  633. {
  634. iResult = MessageBox(hwnd, szError, szCaption, uType);
  635. }
  636. }
  637. va_end(arguments);
  638. }
  639. return iResult;
  640. }
  641. BOOL CHomeNetworkWizard::GetICSMachine(LPTSTR pszICSMachineName, DWORD cch)
  642. {
  643. #ifdef FAKE_ICS
  644. lstrcpyn(pszICSMachineName, L"COMPNAME", cch);
  645. return TRUE;
  646. #endif
  647. SetCursor(LoadCursor(NULL, IDC_WAIT));
  648. BOOL fICSInstalled = FALSE;
  649. HRESULT hr = S_OK;
  650. INetConnectionManager* pSharedAccessConnectionManager;
  651. hr = CoCreateInstance(CLSID_SharedAccessConnectionManager, NULL, CLSCTX_LOCAL_SERVER, IID_INetConnectionManager, reinterpret_cast<void**>(&pSharedAccessConnectionManager));
  652. if(SUCCEEDED(hr))
  653. {
  654. IEnumNetConnection* pEnumerator;
  655. hr = pSharedAccessConnectionManager->EnumConnections(NCME_DEFAULT, &pEnumerator);
  656. if(SUCCEEDED(hr))
  657. {
  658. INetConnection* pNetConnection;
  659. ULONG ulFetched;
  660. hr = pEnumerator->Next(1, &pNetConnection, &ulFetched); // HNW only cares about >= 1 beacon
  661. if(SUCCEEDED(hr) && 1 == ulFetched)
  662. {
  663. fICSInstalled = TRUE;
  664. // found the beacon, now recover the machine name if supported
  665. INetSharedAccessConnection* pNetSharedAccessConnection;
  666. hr = pNetConnection->QueryInterface(IID_INetSharedAccessConnection, reinterpret_cast<void**>(&pNetSharedAccessConnection));
  667. if(SUCCEEDED(hr))
  668. {
  669. IUPnPService* pOSInfoService;
  670. hr = pNetSharedAccessConnection->GetService(SAHOST_SERVICE_OSINFO, &pOSInfoService);
  671. if(SUCCEEDED(hr))
  672. {
  673. VARIANT Variant;
  674. VariantInit(&Variant);
  675. BSTR VariableName;
  676. VariableName = SysAllocString(L"OSMachineName");
  677. if(NULL != VariableName)
  678. {
  679. hr = pOSInfoService->QueryStateVariable(VariableName, &Variant);
  680. if(SUCCEEDED(hr))
  681. {
  682. if(V_VT(&Variant) == VT_BSTR)
  683. {
  684. lstrcpyn(pszICSMachineName, V_BSTR(&Variant), cch);
  685. }
  686. else
  687. {
  688. hr = E_UNEXPECTED;
  689. }
  690. VariantClear(&Variant);
  691. }
  692. SysFreeString(VariableName);
  693. }
  694. else
  695. {
  696. hr = E_OUTOFMEMORY;
  697. }
  698. pOSInfoService->Release();
  699. }
  700. pNetSharedAccessConnection->Release();
  701. }
  702. if(FAILED(hr))
  703. {
  704. if (!LoadString(g_hinst, IDS_UNIDENTIFIED_ICS_DEVICE, pszICSMachineName, cch))
  705. *pszICSMachineName = TEXT('\0');
  706. }
  707. pNetConnection->Release();
  708. }
  709. pEnumerator->Release();
  710. }
  711. pSharedAccessConnectionManager->Release();
  712. }
  713. return fICSInstalled;
  714. }
  715. void CHomeNetworkWizard::InitializeConnectionList(HWND hwndList, DWORD dwFlags)
  716. {
  717. // Set up the columns of the list
  718. LVCOLUMN lvc;
  719. lvc.mask = LVCF_SUBITEM | LVCF_WIDTH;
  720. lvc.iSubItem = 0;
  721. lvc.cx = 10;
  722. ListView_InsertColumn(hwndList, 0, &lvc);
  723. lvc.iSubItem = 1;
  724. lvc.cx = 10;
  725. ListView_InsertColumn(hwndList, 1, &lvc);
  726. DWORD dwStyles = LVS_EX_FULLROWSELECT;
  727. if (dwFlags & CONN_INTERNAL)
  728. dwStyles |= LVS_EX_CHECKBOXES;
  729. // Consider disabling the list or something for CONN_UNPLUGGED
  730. ListView_SetExtendedListViewStyleEx(hwndList, dwStyles, dwStyles);
  731. ListView_SetImageList(hwndList, _himlSmall, LVSIL_SMALL);
  732. _psfConnections = NULL;
  733. _pConnViewCB = NULL;
  734. if (g_fRunningOnNT)
  735. {
  736. HRESULT hr = GetConnectionsFolder(&_psfConnections);
  737. if (SUCCEEDED(hr))
  738. {
  739. IShellView *pConnView = NULL;
  740. hr = _psfConnections->CreateViewObject(hwndList, IID_IShellView, reinterpret_cast<LPVOID *>(&pConnView));
  741. if (SUCCEEDED(hr))
  742. {
  743. hr = _psfConnections->QueryInterface(IID_IShellFolderViewCB, reinterpret_cast<LPVOID *>(&_pConnViewCB));
  744. if (SUCCEEDED(hr))
  745. {
  746. HWND hWndParent = GetParent(hwndList);
  747. hr = _pConnViewCB->MessageSFVCB(SFVM_HWNDMAIN, NULL, reinterpret_cast<LPARAM>(hWndParent));
  748. }
  749. }
  750. if (pConnView != NULL)
  751. pConnView->Release();
  752. }
  753. }
  754. }
  755. BOOL CHomeNetworkWizard::IsConnectionUnplugged(INetConnection* pnc)
  756. {
  757. BOOL fUnplugged = FALSE;
  758. if ( g_fRunningOnNT )
  759. {
  760. HRESULT hr;
  761. NETCON_PROPERTIES* pncprops;
  762. hr = pnc->GetProperties(&pncprops);
  763. if (SUCCEEDED(hr))
  764. {
  765. ASSERT(pncprops);
  766. fUnplugged = (NCS_MEDIA_DISCONNECTED == pncprops->Status);
  767. NcFreeNetconProperties(pncprops);
  768. }
  769. }
  770. return fUnplugged;
  771. }
  772. BOOL CHomeNetworkWizard::ShouldShowConnection(INetConnection* pnc, INetConnection* pncExcludeFromList, DWORD dwFlags)
  773. {
  774. BOOL fShow = FALSE;
  775. if (!IsEqualConnection(pnc, pncExcludeFromList))
  776. {
  777. NETCON_PROPERTIES* pprops;
  778. HRESULT hr = pnc->GetProperties(&pprops);
  779. // Is this the kind of connection we want to show based on whether its external or internal list?
  780. if (SUCCEEDED(hr))
  781. {
  782. // Note: The bridge is a virtual and not a real connection. If it exists, it will have
  783. // NCM_BRIDGE, and so it won't get shown here, which is correct.
  784. if (dwFlags & CONN_EXTERNAL)
  785. {
  786. if ((pprops->MediaType == NCM_LAN) ||
  787. (pprops->MediaType == NCM_PHONE) ||
  788. (pprops->MediaType == NCM_TUNNEL) ||
  789. (pprops->MediaType == NCM_ISDN) ||
  790. (pprops->MediaType == NCM_PPPOE))
  791. {
  792. fShow = TRUE;
  793. }
  794. }
  795. if (dwFlags & CONN_INTERNAL)
  796. {
  797. if (pprops->MediaType == NCM_LAN)
  798. {
  799. // Note: In this case pncExcludeFromList is the shared adapter.
  800. // If this is a VPN(NCM_TUNNEL) connection then we want to make
  801. // sure its pszPrerequisiteEntry is connected.
  802. BOOL fAssociated;
  803. HRESULT hr;
  804. hr = HrConnectionAssociatedWithSharedConnection( pnc, pncExcludeFromList, &fAssociated );
  805. if ( SUCCEEDED(hr) )
  806. {
  807. fShow = !fAssociated;
  808. }
  809. else
  810. {
  811. fShow = TRUE;
  812. }
  813. }
  814. }
  815. if (dwFlags & CONN_UNPLUGGED)
  816. {
  817. if (IsConnectionUnplugged(pnc))
  818. {
  819. fShow = TRUE;
  820. }
  821. }
  822. NcFreeNetconProperties(pprops);
  823. }
  824. }
  825. return fShow;
  826. }
  827. BOOL CHomeNetworkWizard::IsConnectionICSPublic(INetConnection* pnc)
  828. {
  829. BOOL fShared = FALSE;
  830. NETCON_PROPERTIES* pprops;
  831. HRESULT hr = pnc->GetProperties(&pprops);
  832. // Is this the kind of connection we want to show based on whether its external or internal list?
  833. if (SUCCEEDED(hr))
  834. {
  835. // Note: Don't check pprops->MediaType == NCM_SHAREDACCESSHOST. SHAREDACCESSHOST is the connectoid
  836. // representing a host's shared connection from the point of view of an ICS client, and not what we're
  837. // interested in.
  838. if (pprops->dwCharacter & NCCF_SHARED)
  839. {
  840. fShared = TRUE;
  841. }
  842. NcFreeNetconProperties(pprops);
  843. }
  844. return fShared;
  845. }
  846. void CHomeNetworkWizard::FillConnectionList(HWND hwndList, INetConnection* pncExcludeFromList, DWORD dwFlags)
  847. {
  848. DestroyConnectionList(hwndList);
  849. BOOL fSelected = FALSE; // Has an entry in the list been selected
  850. if (g_fRunningOnNT)
  851. {
  852. HRESULT hr = 0;
  853. if (_pConnViewCB != NULL)
  854. _pConnViewCB->MessageSFVCB(DVM_REFRESH, TRUE, TRUE);
  855. if (SUCCEEDED(hr))
  856. {
  857. // Enumerate each net connection
  858. DWORD cItems = DPA_GetPtrCount(_hdpaConnections);
  859. for (DWORD iItem = 0; iItem < cItems; iItem ++)
  860. {
  861. INetConnection* pnc = (INetConnection*) DPA_GetPtr(_hdpaConnections, iItem);
  862. ASSERT(pnc);
  863. // Is this the kind of connection we want to show?
  864. if (ShouldShowConnection(pnc, pncExcludeFromList, dwFlags))
  865. {
  866. NETCON_PROPERTIES* pncprops;
  867. hr = pnc->GetProperties(&pncprops);
  868. if (SUCCEEDED(hr))
  869. {
  870. LVITEM lvi = {0};
  871. if ((dwFlags & CONN_EXTERNAL) && fSelected)
  872. {
  873. // If we have a default public adapter, insert other adapters
  874. // after it so the default appears at the top of the list.
  875. lvi.iItem = 1;
  876. }
  877. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  878. lvi.pszText = pncprops->pszwName;
  879. lvi.lParam = (LPARAM) pnc; // We addref this guy when/if we actually add this item
  880. // Get the icon index for this connection
  881. int iIndex;
  882. hr = GetConnectionIconIndex(pncprops->guidId, _psfConnections, &iIndex);
  883. if (SUCCEEDED(hr))
  884. {
  885. lvi.iImage = iIndex;
  886. if (-1 != lvi.iImage)
  887. lvi.mask |= LVIF_IMAGE;
  888. }
  889. // Its ok if the icon stuff failed for now
  890. hr = S_OK;
  891. int iItem = ListView_InsertItem(hwndList, &lvi);
  892. if (-1 != iItem)
  893. {
  894. pnc->AddRef();
  895. ListView_SetItemText(hwndList, iItem, 1, pncprops->pszwDeviceName);
  896. if (dwFlags & CONN_EXTERNAL)
  897. {
  898. // Select the connection that is already ICS public, if applicable, or
  899. // Use network location awareness to guess at a connection type - TODO
  900. if (pncprops->dwCharacter & NCCF_SHARED || NLA_INTERNET_YES == GetConnectionInternetType(&pncprops->guidId))
  901. {
  902. ListView_SetItemState(hwndList, iItem, LVIS_SELECTED, LVIS_SELECTED);
  903. fSelected = TRUE;
  904. }
  905. }
  906. if (dwFlags & CONN_INTERNAL)
  907. {
  908. ListView_SetItemState(hwndList, iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK);
  909. fSelected = TRUE;
  910. }
  911. }
  912. NcFreeNetconProperties(pncprops);
  913. }
  914. }
  915. }
  916. }
  917. }
  918. else
  919. {
  920. if (_hnetInfo.cNA && _hnetInfo.pNA)
  921. {
  922. const NETADAPTER* pNA = _hnetInfo.pNA;
  923. for (UINT i = 0; i < _hnetInfo.cNA; i++, pNA++)
  924. {
  925. // Check if the NIC is working.
  926. if (W9xIsValidAdapter(pNA, dwFlags))
  927. {
  928. fSelected = W9xAddAdapterToList(pNA, pNA->szDisplayName, i, 0, hwndList, dwFlags);
  929. }
  930. else if (W9xIsAdapterDialUp(pNA))
  931. {
  932. _hnetInfo.cRas = W9xEnumRasEntries();
  933. for (UINT j = 0; j < _hnetInfo.cRas; j++)
  934. {
  935. // W9xAddAdapterToList ALWAYS adds the adapter regardless of the
  936. // state of the connection. So we do not have the equivalent of
  937. // the Whistler "ShouldShowConnection". Here we need to check
  938. // the flags to exclude listing inappropriate adapters.
  939. if ( ~CONN_UNPLUGGED & dwFlags ) // Never show RAS Entry's as Unplugged
  940. {
  941. fSelected = W9xAddAdapterToList( pNA,
  942. _hnetInfo.pRas[j].szEntryName,
  943. i, j,
  944. hwndList,
  945. dwFlags );
  946. }
  947. }
  948. }
  949. }
  950. }
  951. }
  952. ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
  953. ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE);
  954. }
  955. BOOL CHomeNetworkWizard::W9xAddAdapterToList(const NETADAPTER* pNA, const WCHAR* pszDesc, UINT uiAdapterIndex, UINT uiDialupIndex, HWND hwndList, DWORD dwFlags)
  956. {
  957. BOOL fSelected = FALSE;
  958. LVITEM lvi = {0};
  959. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  960. WCHAR szNicType[MAX_PATH];
  961. W9xGetNetTypeName(pNA->bNetType, szNicType, ARRAYSIZE(szNicType));
  962. lvi.pszText = szNicType;
  963. lvi.lParam = MAKELONG(LOWORD(uiAdapterIndex), LOWORD(uiDialupIndex));
  964. int iItem = ListView_InsertItem(hwndList, &lvi);
  965. if (-1 != iItem)
  966. {
  967. ListView_SetItemText(hwndList, iItem, 1, (LPWSTR)pszDesc);
  968. if (dwFlags & CONN_EXTERNAL)
  969. {
  970. if (NETTYPE_DIALUP == pNA->bNetType ||
  971. NETTYPE_PPTP == pNA->bNetType ||
  972. NETTYPE_ISDN == pNA->bNetType )
  973. {
  974. ListView_SetItemState(hwndList, iItem, LVIS_SELECTED, LVIS_SELECTED);
  975. fSelected = TRUE;
  976. }
  977. }
  978. if (dwFlags & CONN_INTERNAL)
  979. {
  980. if (NETTYPE_LAN == pNA->bNetType ||
  981. NETTYPE_IRDA == pNA->bNetType || // ISSUE-2000/05/31-edwardp: Internal?
  982. NETTYPE_TV == pNA->bNetType ) // ISSUE-2000/05/31-edwardp: Internal?
  983. {
  984. ListView_SetItemState(hwndList, iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK);
  985. fSelected = TRUE;
  986. }
  987. }
  988. }
  989. return fSelected;
  990. }
  991. UINT CHomeNetworkWizard::W9xEnumRasEntries()
  992. {
  993. UINT uiRet = 0;
  994. if (!_hnetInfo.pRas)
  995. {
  996. DWORD cDUNs = 0;
  997. DWORD cb = 0;
  998. RasEnumEntries(NULL, NULL, NULL, &cb, &cDUNs);
  999. if (cb > 0)
  1000. {
  1001. _hnetInfo.pRas = (RASENTRYNAME*)LocalAlloc(LPTR, cb);
  1002. if (_hnetInfo.pRas)
  1003. {
  1004. _hnetInfo.pRas->dwSize = sizeof(RASENTRYNAME);
  1005. if (RasEnumEntries(NULL, NULL, _hnetInfo.pRas, &cb, &cDUNs) == 0)
  1006. {
  1007. uiRet = cDUNs;
  1008. }
  1009. }
  1010. }
  1011. }
  1012. return uiRet;
  1013. }
  1014. typedef struct
  1015. {
  1016. LPCWSTR idPage;
  1017. DLGPROC pDlgProc;
  1018. LPCWSTR pHeading;
  1019. LPCWSTR pSubHeading;
  1020. DWORD dwFlags;
  1021. } WIZPAGE;
  1022. #define MAKEWIZPAGE(name, dlgproc, dwFlags) \
  1023. { MAKEINTRESOURCE(IDD_WIZ_##name##), dlgproc, MAKEINTRESOURCE(IDS_HEADER_##name##), MAKEINTRESOURCE(IDS_SUBHEADER_##name##), dwFlags }
  1024. INT_PTR MyPropertySheet(LPCPROPSHEETHEADER pHeader);
  1025. HPROPSHEETPAGE MyCreatePropertySheetPage(LPPROPSHEETPAGE psp);
  1026. HRESULT DoesUserHaveHNetPermissions(BOOL* pfHasPermission)
  1027. {
  1028. HRESULT hr;
  1029. if (g_fRunningOnNT)
  1030. {
  1031. // TODO: We need to check this stuff in once the net team RI's
  1032. INetConnectionUiUtilities* pNetConnUiUtil;
  1033. *pfHasPermission = FALSE;
  1034. hr = CoCreateInstance(CLSID_NetConnectionUiUtilities, NULL, CLSCTX_INPROC, IID_PPV_ARG(INetConnectionUiUtilities, &pNetConnUiUtil));
  1035. if (SUCCEEDED(hr))
  1036. {
  1037. if (pNetConnUiUtil->UserHasPermission(NCPERM_ShowSharedAccessUi) &&
  1038. #if 0 // NYI
  1039. pNetConnUiUtil->UserHasPermission(NCPERM_AllowNetBridge_NLA) &&
  1040. #endif
  1041. pNetConnUiUtil->UserHasPermission(NCPERM_ICSClientApp) &&
  1042. pNetConnUiUtil->UserHasPermission(NCPERM_PersonalFirewallConfig))
  1043. {
  1044. *pfHasPermission = TRUE;
  1045. }
  1046. pNetConnUiUtil->Release();
  1047. }
  1048. else
  1049. {
  1050. TraceMsg(TF_WARNING, "Could not cocreate CLSID_NetConnectionUIUtilities");
  1051. }
  1052. }
  1053. else
  1054. {
  1055. // Windows 9x
  1056. *pfHasPermission = TRUE;
  1057. hr = S_OK;
  1058. }
  1059. return hr;
  1060. }
  1061. BOOL CHomeNetworkWizard::IsMachineOnDomain()
  1062. {
  1063. BOOL fDomain = FALSE;
  1064. #ifdef NO_CHECK_DOMAIN
  1065. return fDomain;
  1066. #endif
  1067. NETSETUP_JOIN_STATUS njs;
  1068. //
  1069. // Make sure to initialize pszName to NULL. On W9x NetJoinInformation returns NERR_Success
  1070. // but doesn't allocate pszName. On retail builds the stack garbage in pszName happened to
  1071. // be the this pointer for CHomeNetworkWizard and NetApiBufferFreeWrap called LocalFree
  1072. // on it.
  1073. //
  1074. LPWSTR pszName = NULL; // init to NULL! See comment above.
  1075. if (NERR_Success == NetGetJoinInformation(NULL, &pszName, &njs))
  1076. {
  1077. fDomain = (NetSetupDomainName == njs);
  1078. NetApiBufferFree(pszName);
  1079. }
  1080. return fDomain;
  1081. }
  1082. BOOL CHomeNetworkWizard::IsMachineWrongOS()
  1083. {
  1084. BOOL fWrongOS = TRUE;
  1085. if (IsOS(OS_WINDOWS))
  1086. {
  1087. if (IsOS(OS_WIN98ORGREATER))
  1088. {
  1089. fWrongOS = FALSE;
  1090. }
  1091. }
  1092. else
  1093. {
  1094. if (IsOS(OS_WHISTLERORGREATER))
  1095. {
  1096. fWrongOS = FALSE;
  1097. }
  1098. }
  1099. return fWrongOS;
  1100. }
  1101. // The page indices for the possible start pages (three error and one real start page)
  1102. #define PAGE_NOTADMIN 0
  1103. #define PAGE_NOPERMISSIONS 1
  1104. #define PAGE_NOHARDWARE 2
  1105. #define PAGE_WRONGOS 3
  1106. #define PAGE_DOMAIN 4
  1107. #define PAGE_WELCOME 5
  1108. #define PAGE_CONNECT 9
  1109. #define PAGE_FINISH 25
  1110. HRESULT CHomeNetworkWizard::ShowWizard(HWND hwnd, BOOL* pfRebootRequired)
  1111. {
  1112. HRESULT hr = S_OK;
  1113. TCHAR szCaption[256];
  1114. LoadString(g_hinst, IDS_WIZ_CAPTION, szCaption, ARRAYSIZE(szCaption));
  1115. CEnsureSingleInstance ESI(szCaption);
  1116. if (!ESI.ShouldExit())
  1117. {
  1118. if (g_fRunningOnNT)
  1119. {
  1120. LinkWindow_RegisterClass_NT();
  1121. }
  1122. *pfRebootRequired = FALSE;
  1123. hr = Initialize();
  1124. if (SUCCEEDED(hr))
  1125. {
  1126. WIZPAGE c_wpPages[] =
  1127. {
  1128. // Error start pages
  1129. MAKEWIZPAGE(NOTADMIN, CantRunWizardPageProc, PSP_HIDEHEADER),
  1130. MAKEWIZPAGE(NOPERMISSIONS, CantRunWizardPageProc, PSP_HIDEHEADER),
  1131. MAKEWIZPAGE(NOHARDWARE, NoHardwareWelcomePageProc, PSP_HIDEHEADER),
  1132. MAKEWIZPAGE(WRONGOS, CantRunWizardPageProc, PSP_HIDEHEADER),
  1133. MAKEWIZPAGE(DOMAINWELCOME, CantRunWizardPageProc, PSP_HIDEHEADER),
  1134. // Real start page
  1135. MAKEWIZPAGE(WELCOME, WelcomePageProc, PSP_HIDEHEADER),
  1136. MAKEWIZPAGE(MANUALCONFIG, ManualConfigPageProc, 0),
  1137. MAKEWIZPAGE(UNPLUGGED, UnpluggedPageProc, 0),
  1138. MAKEWIZPAGE(FOUNDICS, FoundIcsPageProc, 0),
  1139. MAKEWIZPAGE(CONNECT, ConnectPageProc, 0),
  1140. MAKEWIZPAGE(CONNECTOTHER, ConnectOtherPageProc, 0),
  1141. MAKEWIZPAGE(PUBLIC, PublicPageProc, 0),
  1142. MAKEWIZPAGE(EDGELESS, EdgelessPageProc, 0),
  1143. MAKEWIZPAGE(ICSCONFLICT, ICSConflictPageProc, 0),
  1144. MAKEWIZPAGE(BRIDGEWARNING, BridgeWarningPageProc, 0),
  1145. MAKEWIZPAGE(PRIVATE, PrivatePageProc, 0),
  1146. MAKEWIZPAGE(NAME, NamePageProc, 0),
  1147. MAKEWIZPAGE(WORKGROUP, WorkgroupPageProc, 0),
  1148. MAKEWIZPAGE(SUMMARY, SummaryPageProc, 0),
  1149. MAKEWIZPAGE(PROGRESS, ProgressPageProc, 0),
  1150. MAKEWIZPAGE(ALMOSTDONE, AlmostDonePageProc, 0),
  1151. MAKEWIZPAGE(CHOOSEDISK, ChooseDiskPageProc, 0),
  1152. MAKEWIZPAGE(INSERTDISK, InsertDiskPageProc, 0),
  1153. MAKEWIZPAGE(FLOPPYINST, InstructionsPageProc, 0),
  1154. MAKEWIZPAGE(CDINST, InstructionsPageProc, 0),
  1155. MAKEWIZPAGE(FINISH, FinishPageProc, PSP_HIDEHEADER),
  1156. MAKEWIZPAGE(CONFIGERROR, ErrorFinishPageProc, PSP_HIDEHEADER),
  1157. MAKEWIZPAGE(NOHARDWAREFINISH, NoHardwareFinishPageProc, PSP_HIDEHEADER),
  1158. };
  1159. // Sanity check to make sure we haven't added new error pages without updating the
  1160. // welcome page number
  1161. ASSERT(c_wpPages[PAGE_WELCOME].idPage == MAKEINTRESOURCE(IDD_WIZ_WELCOME));
  1162. ASSERT(c_wpPages[PAGE_CONNECT].idPage == MAKEINTRESOURCE(IDD_WIZ_CONNECT));
  1163. ASSERT(c_wpPages[PAGE_FINISH].idPage == MAKEINTRESOURCE(IDD_WIZ_FINISH));
  1164. if (!g_fRunningOnNT)
  1165. {
  1166. c_wpPages[PAGE_WELCOME].idPage = MAKEINTRESOURCE(IDD_WIZ_WIN9X_WELCOME);
  1167. c_wpPages[PAGE_FINISH].idPage = MAKEINTRESOURCE(IDD_WIZ_WIN9X_FINISH);
  1168. CICSInst* pICS = new CICSInst;
  1169. if (pICS)
  1170. {
  1171. if (!pICS->IsInstalled())
  1172. {
  1173. c_wpPages[PAGE_CONNECT].idPage = MAKEINTRESOURCE(IDD_WIZ_WIN9X_CONNECT);
  1174. _fNoICSQuestion = TRUE;
  1175. }
  1176. delete pICS;
  1177. }
  1178. }
  1179. HPROPSHEETPAGE rghpage[MAX_HNW_PAGES];
  1180. int cPages;
  1181. for (cPages = 0; cPages < ARRAYSIZE(c_wpPages); cPages ++)
  1182. {
  1183. PROPSHEETPAGE psp = { 0 };
  1184. psp.dwSize = SIZEOF(PROPSHEETPAGE);
  1185. psp.hInstance = g_hinst;
  1186. psp.lParam = (LPARAM)this;
  1187. psp.dwFlags = PSP_USETITLE | PSP_DEFAULT | PSP_USEHEADERTITLE |
  1188. PSP_USEHEADERSUBTITLE | c_wpPages[cPages].dwFlags;
  1189. psp.pszTemplate = c_wpPages[cPages].idPage;
  1190. psp.pfnDlgProc = c_wpPages[cPages].pDlgProc;
  1191. psp.pszTitle = MAKEINTRESOURCE(IDS_WIZ_CAPTION);
  1192. psp.pszHeaderTitle = c_wpPages[cPages].pHeading;
  1193. psp.pszHeaderSubTitle = c_wpPages[cPages].pSubHeading;
  1194. rghpage[cPages] = MyCreatePropertySheetPage(&psp);
  1195. }
  1196. ASSERT(cPages < MAX_HNW_PAGES);
  1197. PROPSHEETHEADER psh = { 0 };
  1198. psh.dwSize = SIZEOF(PROPSHEETHEADER);
  1199. psh.hwndParent = hwnd;
  1200. psh.hInstance = g_hinst;
  1201. psh.dwFlags = PSH_USEICONID | PSH_WIZARD | PSH_WIZARD97 | PSH_WATERMARK | PSH_STRETCHWATERMARK | PSH_HEADER;
  1202. psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER);
  1203. psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
  1204. psh.nPages = cPages;
  1205. psh.phpage = rghpage;
  1206. psh.pszIcon = MAKEINTRESOURCE(IDI_APPICON);
  1207. // Check for administrator and policy (permissions)
  1208. BOOL fUserIsAdmin = FALSE;
  1209. BOOL fUserHasPermissions = FALSE;
  1210. IsUserLocalAdmin(NULL, &fUserIsAdmin);
  1211. DoesUserHaveHNetPermissions(&fUserHasPermissions);
  1212. if (!fUserIsAdmin)
  1213. {
  1214. // Not admin error page
  1215. psh.nStartPage = PAGE_NOTADMIN;
  1216. }
  1217. else if (!fUserHasPermissions)
  1218. {
  1219. // No permissions error page
  1220. psh.nStartPage = PAGE_NOPERMISSIONS;
  1221. }
  1222. else if (GetConnectionCount(NULL, CONN_INTERNAL) < 1)
  1223. {
  1224. if ( g_fRunningOnNT && ( GetConnectionCount(NULL, CONN_EXTERNAL) > 0 ) )
  1225. {
  1226. TraceMsg(TF_WARNING, "External Adapters Only");
  1227. psh.nStartPage = PAGE_WELCOME;
  1228. _fExternalOnly = TRUE;
  1229. }
  1230. else
  1231. {
  1232. // No hardware error page
  1233. psh.nStartPage = PAGE_NOHARDWARE;
  1234. }
  1235. }
  1236. else if (IsMachineWrongOS())
  1237. {
  1238. psh.nStartPage = PAGE_WRONGOS;
  1239. }
  1240. else if (IsMachineOnDomain())
  1241. {
  1242. psh.nStartPage = PAGE_DOMAIN;
  1243. }
  1244. else
  1245. {
  1246. // Run the real wizard
  1247. psh.nStartPage = PAGE_WELCOME;
  1248. }
  1249. INT_PTR iReturn = MyPropertySheet(&psh);
  1250. *pfRebootRequired = ((iReturn == ID_PSRESTARTWINDOWS) || (iReturn == ID_PSREBOOTSYSTEM));
  1251. Uninitialize();
  1252. }
  1253. }
  1254. return hr;
  1255. }
  1256. void GetTitleFont(LPTSTR pszFaceName, DWORD cch)
  1257. {
  1258. if (!LoadString(g_hinst, IDS_TITLE_FONT, pszFaceName, cch))
  1259. {
  1260. lstrcpyn(pszFaceName, TEXT("Verdana"), cch);
  1261. }
  1262. }
  1263. LONG GetTitlePointSize()
  1264. {
  1265. LONG lPointSize = 0;
  1266. TCHAR szPointSize[20];
  1267. if (LoadString(g_hinst, IDS_TITLE_POINTSIZE, szPointSize, ARRAYSIZE(szPointSize)))
  1268. {
  1269. lPointSize = StrToInt(szPointSize);
  1270. }
  1271. if (!lPointSize)
  1272. {
  1273. lPointSize = 12;
  1274. }
  1275. return lPointSize;
  1276. }
  1277. void CHomeNetworkWizard::WelcomeSetTitleFont(HWND hwnd)
  1278. {
  1279. HWND hwndTitle = GetDlgItem(hwnd, IDC_TITLE);
  1280. // Get the existing font
  1281. HFONT hfontOld = (HFONT) SendMessage(hwndTitle, WM_GETFONT, 0, 0);
  1282. LOGFONT lf = {0};
  1283. if (GetObject(hfontOld, sizeof(lf), &lf))
  1284. {
  1285. GetTitleFont(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName));
  1286. HDC hDC = GetDC(hwndTitle);
  1287. if (hDC)
  1288. {
  1289. lf.lfHeight = -MulDiv(GetTitlePointSize(), GetDeviceCaps(hDC, LOGPIXELSY), 72);
  1290. lf.lfWeight = FW_BOLD;
  1291. HFONT hfontNew = CreateFontIndirect(&lf);
  1292. if (hfontNew)
  1293. {
  1294. SendMessage(hwndTitle, WM_SETFONT, (WPARAM) hfontNew, FALSE);
  1295. // Don't do this, its shared.
  1296. // DeleteObject(hfontOld);
  1297. }
  1298. ReleaseDC(hwndTitle, hDC);
  1299. }
  1300. }
  1301. LONG lStyle = GetWindowLong(GetParent(hwnd), GWL_STYLE);
  1302. SetWindowLong(GetParent(hwnd), GWL_STYLE, lStyle & ~WS_SYSMENU);
  1303. }
  1304. INT_PTR CHomeNetworkWizard::WelcomePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1305. {
  1306. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  1307. switch (uMsg)
  1308. {
  1309. case WM_INITDIALOG:
  1310. pthis->WelcomeSetTitleFont(hwnd);
  1311. return TRUE;
  1312. case WM_NOTIFY:
  1313. {
  1314. LPNMHDR pnmh = (LPNMHDR) lParam;
  1315. switch (pnmh->code)
  1316. {
  1317. case PSN_SETACTIVE:
  1318. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_NEXT);
  1319. return TRUE;
  1320. case PSN_WIZNEXT:
  1321. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_MANUALCONFIG);
  1322. if (!g_fRunningOnNT)
  1323. pthis->PushPage(IDD_WIZ_WIN9X_WELCOME);
  1324. else
  1325. pthis->PushPage(IDD_WIZ_WELCOME);
  1326. return TRUE;
  1327. }
  1328. }
  1329. return FALSE;
  1330. }
  1331. return FALSE;
  1332. }
  1333. INT_PTR CHomeNetworkWizard::NoHardwareWelcomePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1334. {
  1335. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  1336. switch (uMsg)
  1337. {
  1338. case WM_INITDIALOG:
  1339. pthis->WelcomeSetTitleFont(hwnd);
  1340. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_HARDWAREREQ);
  1341. return TRUE;
  1342. case WM_NOTIFY:
  1343. {
  1344. LPNMHDR pnmh = (LPNMHDR) lParam;
  1345. switch (pnmh->code)
  1346. {
  1347. case PSN_SETACTIVE:
  1348. PropSheet_SetWizButtons(pnmh->hwndFrom, 0);
  1349. return TRUE;
  1350. case NM_CLICK:
  1351. case NM_RETURN:
  1352. switch ((int) wParam)
  1353. {
  1354. case IDC_HELPLINK:
  1355. {
  1356. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_requirements.htm");
  1357. }
  1358. return TRUE;
  1359. }
  1360. }
  1361. }
  1362. return FALSE;
  1363. }
  1364. return FALSE;
  1365. }
  1366. void CHomeNetworkWizard::ReplaceStaticWithLink(HWND hwndStatic, UINT idcLinkControl, UINT idsLinkText)
  1367. {
  1368. if (g_fRunningOnNT)
  1369. {
  1370. RECT rcStatic;
  1371. HWND hwndParent = GetParent(hwndStatic);
  1372. if (GetWindowRect(hwndStatic, &rcStatic) &&
  1373. MapWindowPoints(NULL, hwndParent, (LPPOINT) &rcStatic, 2))
  1374. {
  1375. WCHAR szLinkText[256];
  1376. if (LoadString(g_hinst, idsLinkText, szLinkText, ARRAYSIZE(szLinkText)))
  1377. {
  1378. HWND hwndLink = CreateWindowEx(0, TEXT("SysLink"), szLinkText, WS_CHILD | WS_TABSTOP | LWS_IGNORERETURN,
  1379. rcStatic.left, rcStatic.top, (rcStatic.right - rcStatic.left), (rcStatic.bottom - rcStatic.top),
  1380. hwndParent, NULL, g_hinst, NULL);
  1381. if (hwndLink)
  1382. {
  1383. SetWindowLongPtr(hwndLink, GWLP_ID, (LONG_PTR) idcLinkControl);
  1384. ShowWindow(hwndLink, SW_SHOW);
  1385. ShowWindow(hwndStatic, SW_HIDE);
  1386. }
  1387. }
  1388. }
  1389. }
  1390. }
  1391. void CHomeNetworkWizard::ManualRefreshConnectionList()
  1392. {
  1393. if (g_fRunningOnNT)
  1394. {
  1395. // Refresh connection DPA in case the user plugged in more connections
  1396. HDPA hdpaConnections2;
  1397. if (SUCCEEDED(GetConnections(&hdpaConnections2)))
  1398. {
  1399. // Replace the real list with our new one
  1400. DPA_DestroyCallback(_hdpaConnections, FreeConnectionDPACallback, NULL);
  1401. _hdpaConnections = hdpaConnections2;
  1402. // Ensure we remove our other holds to the INetConnections
  1403. // Free public lan information
  1404. FreeExternalConnection(&_hnetInfo);
  1405. // Free private lan information
  1406. FreeInternalConnections(&_hnetInfo);
  1407. }
  1408. }
  1409. }
  1410. INT_PTR CHomeNetworkWizard::ManualConfigPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1411. {
  1412. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  1413. switch (uMsg)
  1414. {
  1415. case WM_INITDIALOG:
  1416. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_INSTALLATION);
  1417. return TRUE;
  1418. case WM_NOTIFY:
  1419. {
  1420. LPNMHDR pnmh = (LPNMHDR) lParam;
  1421. switch (pnmh->code)
  1422. {
  1423. case PSN_SETACTIVE:
  1424. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
  1425. return TRUE;
  1426. case PSN_WIZNEXT:
  1427. // pthis->ManualRefreshConnectionList();
  1428. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_UNPLUGGED);
  1429. pthis->PushPage(IDD_WIZ_MANUALCONFIG);
  1430. return TRUE;
  1431. case PSN_WIZBACK:
  1432. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  1433. return TRUE;
  1434. case NM_CLICK:
  1435. case NM_RETURN:
  1436. switch ((int) wParam)
  1437. {
  1438. case IDC_HELPLINK:
  1439. {
  1440. if (IsOS(OS_PERSONAL))
  1441. {
  1442. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_checklistP.htm");
  1443. }
  1444. else
  1445. {
  1446. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_checklistW.htm");
  1447. }
  1448. }
  1449. return TRUE;
  1450. }
  1451. }
  1452. }
  1453. return FALSE;
  1454. }
  1455. return FALSE;
  1456. }
  1457. // Returns TRUE if there are some unplugged connections, FALSE o/w
  1458. BOOL CHomeNetworkWizard::UnpluggedFillList(HWND hwnd)
  1459. {
  1460. BOOL fSomeUnpluggedConnections = FALSE;
  1461. HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST);
  1462. FillConnectionList(hwndList, NULL, CONN_UNPLUGGED);
  1463. // and if there actually are unplugged connections...
  1464. if (0 != ListView_GetItemCount(hwndList))
  1465. {
  1466. // Show this page
  1467. fSomeUnpluggedConnections = TRUE;
  1468. }
  1469. return fSomeUnpluggedConnections;
  1470. }
  1471. INT_PTR CHomeNetworkWizard::UnpluggedPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1472. {
  1473. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  1474. switch (uMsg)
  1475. {
  1476. case WM_INITDIALOG:
  1477. pthis->InitializeConnectionList(GetDlgItem(hwnd, IDC_CONNLIST), CONN_UNPLUGGED);
  1478. SendDlgItemMessage(hwnd, IDC_IGNORE, BM_SETCHECK, BST_UNCHECKED, 0);
  1479. return TRUE;
  1480. case WM_NOTIFY:
  1481. {
  1482. LPNMHDR pnmh = (LPNMHDR) lParam;
  1483. switch (pnmh->code)
  1484. {
  1485. case PSN_SETACTIVE:
  1486. {
  1487. // If we don't need to show this page
  1488. if (!pthis->UnpluggedFillList(hwnd))
  1489. {
  1490. // Don't push ourselves on the stack
  1491. // But navigate to the next page...
  1492. SetWindowLongPtr( hwnd, DWLP_MSGRESULT,
  1493. (pthis->_fExternalOnly) ? IDD_WIZ_CONNECTOTHER : IDD_WIZ_FOUNDICS );
  1494. }
  1495. }
  1496. return TRUE;
  1497. case PSN_WIZNEXT:
  1498. {
  1499. BOOL fStillUnplugged = pthis->UnpluggedFillList(hwnd);
  1500. int idNext;
  1501. if (!fStillUnplugged)
  1502. {
  1503. // User fixed the problem. Go forward and don't store this
  1504. // error page on the pagestack
  1505. idNext = (pthis->_fExternalOnly) ? IDD_WIZ_CONNECTOTHER : IDD_WIZ_FOUNDICS;
  1506. }
  1507. else if (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_IGNORE, BM_GETCHECK, 0, 0))
  1508. {
  1509. // User wants to go on, but store this page on the pagestack
  1510. // so they can "back" up to it.
  1511. pthis->PushPage(IDD_WIZ_UNPLUGGED);
  1512. idNext = (pthis->_fExternalOnly) ? IDD_WIZ_CONNECTOTHER : IDD_WIZ_FOUNDICS;
  1513. }
  1514. else
  1515. {
  1516. // User still has disconnected net hardware they don't want to ignore. Tell them and keep them on this page.
  1517. DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, IDS_STILLUNPLUGGED, MB_ICONERROR | MB_OK);
  1518. idNext = -1;
  1519. }
  1520. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, idNext);
  1521. }
  1522. return TRUE;
  1523. case PSN_WIZBACK:
  1524. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  1525. return TRUE;
  1526. }
  1527. }
  1528. return FALSE;
  1529. case WM_DESTROY:
  1530. pthis->DestroyConnectionList(GetDlgItem(hwnd, IDC_CONNLIST));
  1531. return TRUE;
  1532. }
  1533. return FALSE;
  1534. }
  1535. void CHomeNetworkWizard::PublicSetControlState(HWND hwnd)
  1536. {
  1537. BOOL fSelection = ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_CONNLIST));
  1538. PropSheet_SetWizButtons(GetParent(hwnd), fSelection ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK);
  1539. }
  1540. void FreeExternalConnection(PHOMENETSETUPINFO pInfo)
  1541. {
  1542. if (pInfo->pncExternal)
  1543. {
  1544. pInfo->pncExternal->Release();
  1545. pInfo->pncExternal = NULL;
  1546. }
  1547. }
  1548. void CHomeNetworkWizard::PublicNextPage(HWND hwnd)
  1549. {
  1550. FreeExternalConnection(&_hnetInfo);
  1551. // Get the selected external adapter
  1552. HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST);
  1553. int iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
  1554. // We can assert here since Next should be disabled if there is no selection!
  1555. ASSERT(-1 != iItem);
  1556. LVITEM lvi = {0};
  1557. lvi.iItem = iItem;
  1558. lvi.mask = LVIF_PARAM;
  1559. if (ListView_GetItem(hwndList, &lvi))
  1560. {
  1561. if (g_fRunningOnNT)
  1562. {
  1563. _hnetInfo.pncExternal = (INetConnection*) (lvi.lParam);
  1564. _hnetInfo.pncExternal->AddRef();
  1565. }
  1566. else
  1567. {
  1568. _hnetInfo.ipaExternal = lvi.lParam;
  1569. }
  1570. }
  1571. // Do the real wizard navigation
  1572. UINT idPage = IDD_WIZ_NAME;
  1573. if (g_fRunningOnNT)
  1574. {
  1575. idPage = _fShowSharingPage ? IDD_WIZ_EDGELESS : IDD_WIZ_ICSCONFLICT;
  1576. }
  1577. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, idPage);
  1578. }
  1579. void CHomeNetworkWizard::FoundIcsSetText(HWND hwnd)
  1580. {
  1581. if (GetICSMachine(_szICSMachineName, ARRAYSIZE(_szICSMachineName)))
  1582. {
  1583. TCHAR szMsg[256];
  1584. if (FormatMessageString(IDS_ICSMSG, szMsg, ARRAYSIZE(szMsg), _szICSMachineName))
  1585. {
  1586. SetWindowText(GetDlgItem(hwnd, IDC_ICSMSG), szMsg);
  1587. }
  1588. }
  1589. else
  1590. {
  1591. // No ICS beacon - ask the user how they connect
  1592. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) _fNoICSQuestion ? IDD_WIZ_WIN9X_CONNECT : IDD_WIZ_CONNECT);
  1593. }
  1594. }
  1595. INT_PTR CHomeNetworkWizard::FoundIcsPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1596. {
  1597. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  1598. switch (uMsg)
  1599. {
  1600. case WM_INITDIALOG:
  1601. SendMessage(GetDlgItem(hwnd, IDC_SHARECONNECT), BM_SETCHECK, BST_CHECKED, 0);
  1602. return TRUE;
  1603. case WM_NOTIFY:
  1604. {
  1605. LPNMHDR pnmh = (LPNMHDR) lParam;
  1606. switch (pnmh->code)
  1607. {
  1608. case PSN_SETACTIVE:
  1609. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
  1610. pthis->FoundIcsSetText(hwnd);
  1611. return TRUE;
  1612. case PSN_WIZNEXT:
  1613. {
  1614. UINT idNext;
  1615. if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_SHARECONNECT), BM_GETCHECK, 0, 0))
  1616. {
  1617. // This machine should be an ICS Client and won't have a public connection
  1618. pthis->_hnetInfo.dwFlags = HNET_SHAREPRINTERS |
  1619. HNET_SHAREFOLDERS |
  1620. HNET_ICSCLIENT;
  1621. pthis->_fShowPublicPage = FALSE;
  1622. pthis->_fShowSharingPage = FALSE;
  1623. pthis->_fICSClient = TRUE;
  1624. idNext = g_fRunningOnNT ? IDD_WIZ_ICSCONFLICT : IDD_WIZ_NAME;
  1625. }
  1626. else
  1627. {
  1628. idNext = pthis->_fNoICSQuestion ? IDD_WIZ_WIN9X_CONNECT : IDD_WIZ_CONNECT;
  1629. }
  1630. pthis->PushPage(IDD_WIZ_FOUNDICS);
  1631. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, idNext);
  1632. }
  1633. return TRUE;
  1634. case PSN_WIZBACK:
  1635. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  1636. return TRUE;
  1637. }
  1638. }
  1639. return FALSE;
  1640. }
  1641. return FALSE;
  1642. }
  1643. void CHomeNetworkWizard::ConnectSetDefault(HWND hwnd)
  1644. {
  1645. UINT idSelect = IDC_ICSHOST;
  1646. if ((!g_fRunningOnNT) || (GetConnectionCount(NULL, CONN_INTERNAL | CONN_EXTERNAL) == 1))
  1647. {
  1648. idSelect = IDC_ICSCLIENT;
  1649. }
  1650. SendDlgItemMessage(hwnd, idSelect, BM_SETCHECK, BST_CHECKED, 0);
  1651. }
  1652. void CHomeNetworkWizard::ConnectNextPage(HWND hwnd)
  1653. {
  1654. _fICSClient = FALSE;
  1655. _fNoHomeNetwork = FALSE;
  1656. if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_ICSHOST), BM_GETCHECK, 0, 0))
  1657. {
  1658. // This machine will need a firewalled, public connection, and should be ICS Host.
  1659. _hnetInfo.dwFlags = HNET_SHARECONNECTION |
  1660. HNET_FIREWALLCONNECTION |
  1661. HNET_SHAREPRINTERS |
  1662. HNET_SHAREFOLDERS;
  1663. _fShowPublicPage = TRUE;
  1664. _fShowSharingPage = FALSE;
  1665. }
  1666. else if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_ICSCLIENT), BM_GETCHECK, 0, 0))
  1667. {
  1668. // This machine should be an ICS Client and won't have a public connection
  1669. _hnetInfo.dwFlags = HNET_SHAREPRINTERS |
  1670. HNET_SHAREFOLDERS |
  1671. HNET_ICSCLIENT;
  1672. _fShowPublicPage = FALSE;
  1673. _fShowSharingPage = FALSE;
  1674. _fICSClient = TRUE;
  1675. }
  1676. else if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_ALLCOMPUTERSDIRECT), BM_GETCHECK, 0, 0))
  1677. {
  1678. // This machine will need a public connection, and we should ask before sharing files
  1679. _hnetInfo.dwFlags = HNET_FIREWALLCONNECTION |
  1680. HNET_SHAREPRINTERS |
  1681. HNET_SHAREFOLDERS;
  1682. _fShowPublicPage = TRUE;
  1683. _fShowSharingPage = TRUE;
  1684. }
  1685. else if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_NOHOMENETWORK), BM_GETCHECK, 0, 0))
  1686. {
  1687. // This machine needs a firewalled, public connection and not much else
  1688. _hnetInfo.dwFlags = HNET_FIREWALLCONNECTION |
  1689. HNET_SHAREPRINTERS |
  1690. HNET_SHAREFOLDERS;
  1691. _fShowPublicPage = TRUE;
  1692. _fShowSharingPage = FALSE;
  1693. _fNoHomeNetwork = TRUE;
  1694. }
  1695. else if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_NOINTERNET), BM_GETCHECK, 0, 0))
  1696. {
  1697. // No internet box
  1698. _hnetInfo.dwFlags = HNET_SHAREPRINTERS |
  1699. HNET_SHAREFOLDERS;
  1700. _fShowPublicPage = FALSE;
  1701. _fShowSharingPage = FALSE;
  1702. }
  1703. UINT idNext;
  1704. if (g_fRunningOnNT)
  1705. {
  1706. if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_OTHER), BM_GETCHECK, 0, 0))
  1707. {
  1708. idNext = IDD_WIZ_CONNECTOTHER;
  1709. }
  1710. else
  1711. {
  1712. idNext = _fShowPublicPage ? IDD_WIZ_PUBLIC : IDD_WIZ_ICSCONFLICT;
  1713. }
  1714. }
  1715. else
  1716. {
  1717. // For now - TODO: Ed and I need to figure out what we need to do downlevel (9x + 2k)
  1718. idNext = IDD_WIZ_NAME;
  1719. }
  1720. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, idNext);
  1721. }
  1722. INT_PTR CHomeNetworkWizard::ConnectPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1723. {
  1724. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  1725. switch (uMsg)
  1726. {
  1727. case WM_INITDIALOG:
  1728. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_HNCONFIG);
  1729. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC1), IDC_SHOWMELINK1, IDS_SHOWME);
  1730. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC2), IDC_SHOWMELINK2, IDS_SHOWME);
  1731. pthis->ConnectSetDefault(hwnd);
  1732. return TRUE;
  1733. case WM_NOTIFY:
  1734. {
  1735. LPNMHDR pnmh = (LPNMHDR) lParam;
  1736. switch (pnmh->code)
  1737. {
  1738. case PSN_SETACTIVE:
  1739. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
  1740. return TRUE;
  1741. case PSN_WIZNEXT:
  1742. {
  1743. pthis->PushPage(pthis->_fNoICSQuestion ? IDD_WIZ_WIN9X_CONNECT : IDD_WIZ_CONNECT);
  1744. pthis->ConnectNextPage(hwnd);
  1745. }
  1746. return TRUE;
  1747. case PSN_WIZBACK:
  1748. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  1749. return TRUE;
  1750. case NM_CLICK:
  1751. case NM_RETURN:
  1752. switch ((int) wParam)
  1753. {
  1754. case IDC_HELPLINK:
  1755. {
  1756. if (IsOS(OS_PERSONAL))
  1757. {
  1758. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_howto_connectP.htm");
  1759. }
  1760. else
  1761. {
  1762. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_howto_connectW.htm");
  1763. }
  1764. }
  1765. return TRUE;
  1766. case IDC_SHOWMELINK1:
  1767. {
  1768. pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme1.htm");
  1769. }
  1770. return TRUE;
  1771. case IDC_SHOWMELINK2:
  1772. {
  1773. pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme2.htm");
  1774. }
  1775. return TRUE;
  1776. }
  1777. }
  1778. }
  1779. return FALSE;
  1780. }
  1781. return FALSE;
  1782. }
  1783. INT_PTR CHomeNetworkWizard::ConnectOtherPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1784. {
  1785. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  1786. switch (uMsg)
  1787. {
  1788. case WM_INITDIALOG:
  1789. if ( pthis->_fExternalOnly )
  1790. {
  1791. TraceMsg(TF_WARNING, "External Adapters Only");
  1792. }
  1793. SendDlgItemMessage(hwnd, IDC_ALLCOMPUTERSDIRECT, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
  1794. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_HNCONFIG);
  1795. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC3), IDC_SHOWMELINK3, IDS_SHOWME);
  1796. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC4), IDC_SHOWMELINK4, IDS_SHOWME);
  1797. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC5), IDC_SHOWMELINK5, IDS_SHOWME);
  1798. return TRUE;
  1799. case WM_NOTIFY:
  1800. {
  1801. LPNMHDR pnmh = (LPNMHDR) lParam;
  1802. switch (pnmh->code)
  1803. {
  1804. case PSN_SETACTIVE:
  1805. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
  1806. return TRUE;
  1807. case PSN_WIZNEXT:
  1808. {
  1809. pthis->PushPage(IDD_WIZ_CONNECTOTHER);
  1810. pthis->ConnectNextPage(hwnd);
  1811. }
  1812. return TRUE;
  1813. case PSN_WIZBACK:
  1814. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  1815. return TRUE;
  1816. case NM_CLICK:
  1817. case NM_RETURN:
  1818. switch ((int) wParam)
  1819. {
  1820. case IDC_HELPLINK:
  1821. {
  1822. HelpCenter(hwnd, L"netcfg.chm%3A%3A/share_conn_overvw.htm");
  1823. }
  1824. return TRUE;
  1825. case IDC_SHOWMELINK3:
  1826. {
  1827. pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme3.htm");
  1828. }
  1829. return TRUE;
  1830. case IDC_SHOWMELINK4:
  1831. {
  1832. pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme4.htm");
  1833. }
  1834. return TRUE;
  1835. case IDC_SHOWMELINK5:
  1836. {
  1837. pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme5.htm");
  1838. }
  1839. return TRUE;
  1840. }
  1841. }
  1842. }
  1843. return FALSE;
  1844. }
  1845. return FALSE;
  1846. }
  1847. void CHomeNetworkWizard::DestroyConnectionList(HWND hwndList)
  1848. {
  1849. if (g_fRunningOnNT)
  1850. {
  1851. int nItems = ListView_GetItemCount(hwndList);
  1852. for (int iItem = 0; iItem < nItems; iItem ++)
  1853. {
  1854. // Get our stashed INetConnection for each item in the list and free it
  1855. LVITEM lvi = {0};
  1856. lvi.mask = LVIF_PARAM;
  1857. lvi.iItem = iItem;
  1858. if (ListView_GetItem(hwndList, &lvi))
  1859. {
  1860. ((INetConnection*) lvi.lParam)->Release();
  1861. }
  1862. }
  1863. }
  1864. ListView_DeleteAllItems(hwndList);
  1865. }
  1866. inline void _SetDlgItemRect(HWND hwnd, UINT id, RECT* pRect)
  1867. {
  1868. SetWindowPos(GetDlgItem(hwnd, id), NULL, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, SWP_NOZORDER | SWP_SHOWWINDOW);
  1869. }
  1870. void _OffsetDlgItem(HWND hwnd, UINT id, int xOffset, int yOffset, BOOL fAdjustWidth, BOOL fAdjustHeight)
  1871. {
  1872. RECT rc;
  1873. HWND hwndControl = GetDlgItem(hwnd, id);
  1874. GetWindowRect(hwndControl, &rc);
  1875. MapWindowPoints(NULL, hwnd, (LPPOINT) &rc, 2);
  1876. OffsetRect(&rc, xOffset, yOffset);
  1877. if (fAdjustWidth)
  1878. {
  1879. rc.right -= xOffset;
  1880. }
  1881. if (fAdjustHeight)
  1882. {
  1883. rc.bottom -= yOffset;
  1884. }
  1885. _SetDlgItemRect(hwnd, id, &rc);
  1886. }
  1887. void CHomeNetworkWizard::PublicMoveControls(HWND hwnd, BOOL fItemPreselected)
  1888. {
  1889. // We need to move controls around on this page depending on whether or not an item is preselected or not
  1890. // Reset the dialog so that all controls are in their default positions
  1891. PublicResetControlPositions(hwnd);
  1892. if (fItemPreselected)
  1893. {
  1894. // We are transitioning from the "default" position to one where an item is preselected.
  1895. // The only work we do here is to hide the help icon and move over the help text a bit to the left
  1896. int xOffset = (PublicControlPositions._rcHelpIcon.left) - (PublicControlPositions._rcHelpText.left);
  1897. UINT idHelp = IsWindowVisible(GetDlgItem(hwnd, IDC_HELPSTATIC)) ? IDC_HELPSTATIC : IDC_HELPLINK;
  1898. _OffsetDlgItem(hwnd, idHelp, xOffset, 0, TRUE, FALSE);
  1899. ShowWindow(GetDlgItem(hwnd, IDC_HELPICON), SW_HIDE);
  1900. }
  1901. else
  1902. {
  1903. // We are transitioning from the "default" position to the one where we don't have a preselection
  1904. // We need to hide the "we've automatically selected..." message and move up the list label,
  1905. // and expand the connection list.
  1906. int yOffset = (PublicControlPositions._rcSelectMessage.top) - (PublicControlPositions._rcListLabel.top);
  1907. _OffsetDlgItem(hwnd, IDC_LISTLABEL, 0, yOffset, FALSE, FALSE);
  1908. _OffsetDlgItem(hwnd, IDC_CONNLIST, 0, yOffset, FALSE, TRUE);
  1909. ShowWindow(GetDlgItem(hwnd, IDC_SELECTMSG), SW_HIDE);
  1910. }
  1911. }
  1912. void CHomeNetworkWizard::PublicSetActive(HWND hwnd)
  1913. {
  1914. HCURSOR hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1915. FreeExternalConnection(&_hnetInfo);
  1916. HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST);
  1917. FillConnectionList(hwndList, NULL, CONN_EXTERNAL);
  1918. // Auto-select if there is only one connection listed
  1919. if (ListView_GetItemCount(hwndList) == 1
  1920. #ifdef DEBUG
  1921. && !(GetKeyState(VK_CONTROL) < 0) // don't do this if CTRL is down for debugging
  1922. #endif
  1923. )
  1924. {
  1925. ListView_SetItemState(hwndList, 0, LVIS_SELECTED, LVIS_SELECTED);
  1926. // PublicNextPage will set DWLP_MSGRESULT and tell the wizard to skip this page
  1927. // and go on to the next.
  1928. PublicNextPage(hwnd);
  1929. }
  1930. else
  1931. {
  1932. // If there is a selected item
  1933. int iSelectedItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
  1934. if (-1 != iSelectedItem)
  1935. {
  1936. // Read the item name and set the alternate "Windows recommends this connection." text
  1937. WCHAR szItem[256], szMsg[256];
  1938. ListView_GetItemText(hwndList, iSelectedItem, 0, szItem, ARRAYSIZE(szItem));
  1939. FormatMessageString(IDS_RECOMMENDEDCONN, szMsg, ARRAYSIZE(szMsg), szItem);
  1940. SetDlgItemText(hwnd, IDC_SELECTMSG, szMsg);
  1941. BoldControl(hwnd, IDC_SELECTMSG);
  1942. }
  1943. PublicMoveControls(hwnd, (-1 != iSelectedItem));
  1944. PublicSetControlState(hwnd);
  1945. }
  1946. if(NULL != hOldCursor)
  1947. {
  1948. SetCursor(hOldCursor);
  1949. }
  1950. }
  1951. void CHomeNetworkWizard::PublicGetControlPositions(HWND hwnd)
  1952. {
  1953. // Remember the default positions of the controls that will move as we reorganize this dialog
  1954. GetWindowRect(GetDlgItem(hwnd, IDC_SELECTMSG), &PublicControlPositions._rcSelectMessage);
  1955. GetWindowRect(GetDlgItem(hwnd, IDC_LISTLABEL), &PublicControlPositions._rcListLabel);
  1956. GetWindowRect(GetDlgItem(hwnd, IDC_CONNLIST), &PublicControlPositions._rcList);
  1957. GetWindowRect(GetDlgItem(hwnd, IDC_HELPICON), &PublicControlPositions._rcHelpIcon);
  1958. GetWindowRect(GetDlgItem(hwnd, IDC_HELPSTATIC), &PublicControlPositions._rcHelpText);
  1959. // We actually need them in client coords
  1960. // Map 2 points (1 rect) at a time since Mirrored points get screwed up with more
  1961. MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcSelectMessage, 2);
  1962. MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcListLabel, 2);
  1963. MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcList, 2);
  1964. MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcHelpIcon, 2);
  1965. MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcHelpText, 2);
  1966. }
  1967. void CHomeNetworkWizard::PublicResetControlPositions(HWND hwnd)
  1968. {
  1969. // Set the controls back to their default positions
  1970. _SetDlgItemRect(hwnd, IDC_SELECTMSG, &PublicControlPositions._rcSelectMessage);
  1971. _SetDlgItemRect(hwnd, IDC_LISTLABEL, &PublicControlPositions._rcListLabel);
  1972. _SetDlgItemRect(hwnd, IDC_CONNLIST, &PublicControlPositions._rcList);
  1973. _SetDlgItemRect(hwnd, IDC_HELPICON, &PublicControlPositions._rcHelpIcon);
  1974. UINT idHelp = IsWindowVisible(GetDlgItem(hwnd, IDC_HELPSTATIC)) ? IDC_HELPSTATIC : IDC_HELPLINK;
  1975. _SetDlgItemRect(hwnd, idHelp, &PublicControlPositions._rcHelpText);
  1976. }
  1977. INT_PTR CHomeNetworkWizard::PublicPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1978. {
  1979. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  1980. switch (uMsg)
  1981. {
  1982. case WM_INITDIALOG:
  1983. pthis->InitializeConnectionList(GetDlgItem(hwnd, IDC_CONNLIST), CONN_EXTERNAL);
  1984. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_SELECTPUBLIC);
  1985. pthis->PublicGetControlPositions(hwnd);
  1986. return TRUE;
  1987. case WM_NOTIFY:
  1988. {
  1989. LPNMHDR pnmh = (LPNMHDR) lParam;
  1990. switch (pnmh->code)
  1991. {
  1992. case PSN_SETACTIVE:
  1993. {
  1994. pthis->PublicSetActive(hwnd);
  1995. return TRUE;
  1996. }
  1997. case PSN_WIZNEXT:
  1998. pthis->PushPage(IDD_WIZ_PUBLIC);
  1999. pthis->PublicNextPage(hwnd);
  2000. return TRUE;
  2001. case PSN_WIZBACK:
  2002. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2003. return TRUE;
  2004. case LVN_ITEMCHANGED:
  2005. pthis->PublicSetControlState(hwnd);
  2006. return TRUE;
  2007. case NM_CLICK:
  2008. case NM_RETURN:
  2009. switch ((int) wParam)
  2010. {
  2011. case IDC_HELPLINK:
  2012. {
  2013. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_determine_internet_connection.htm");
  2014. }
  2015. return TRUE;
  2016. }
  2017. }
  2018. }
  2019. return FALSE;
  2020. case WM_DESTROY:
  2021. pthis->DestroyConnectionList(GetDlgItem(hwnd, IDC_CONNLIST));
  2022. return TRUE;
  2023. }
  2024. return FALSE;
  2025. }
  2026. void CHomeNetworkWizard::EdgelessSetActive(HWND hwnd)
  2027. {
  2028. PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK | PSWIZB_NEXT);
  2029. // _hnetInfo.dwFlags &= (~(HNET_SHAREFOLDERS | HNET_SHAREPRINTERS));
  2030. if (!ShouldShowConnection(_hnetInfo.pncExternal, NULL, CONN_INTERNAL))
  2031. {
  2032. // External connection is a modem or such - no file sharing necessary (user already said they didn't have a home network)
  2033. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_ICSCONFLICT);
  2034. }
  2035. }
  2036. INT_PTR CHomeNetworkWizard::EdgelessPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2037. {
  2038. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2039. switch (uMsg)
  2040. {
  2041. case WM_INITDIALOG:
  2042. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_RECOMMENDED);
  2043. return TRUE;
  2044. case WM_NOTIFY:
  2045. {
  2046. LPNMHDR pnmh = (LPNMHDR) lParam;
  2047. switch (pnmh->code)
  2048. {
  2049. case PSN_SETACTIVE:
  2050. pthis->EdgelessSetActive(hwnd);
  2051. return TRUE;
  2052. case PSN_WIZNEXT:
  2053. pthis->_hnetInfo.dwFlags |= (HNET_SHAREFOLDERS | HNET_SHAREPRINTERS);
  2054. pthis->PushPage(IDD_WIZ_EDGELESS);
  2055. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) IDD_WIZ_BRIDGEWARNING);
  2056. return TRUE;
  2057. case PSN_WIZBACK:
  2058. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2059. return TRUE;
  2060. case NM_CLICK:
  2061. case NM_RETURN:
  2062. switch ((int) wParam)
  2063. {
  2064. case IDC_HELPLINK:
  2065. {
  2066. if (IsOS(OS_PERSONAL))
  2067. {
  2068. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_nohost_computerP.htm");
  2069. }
  2070. else
  2071. {
  2072. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_nohost_computerW.htm");
  2073. }
  2074. }
  2075. return TRUE;
  2076. }
  2077. }
  2078. }
  2079. return FALSE;
  2080. }
  2081. return FALSE;
  2082. }
  2083. BOOL CHomeNetworkWizard::IsICSIPInUse( WCHAR** ppszHost, PDWORD pdwSize )
  2084. {
  2085. HRESULT hr;
  2086. INetConnection** ppArray = NULL;
  2087. DWORD dwItems = 0;
  2088. BOOL bExists = FALSE;
  2089. if ( ppszHost )
  2090. *ppszHost = NULL;
  2091. if ( pdwSize )
  2092. *pdwSize = 0;
  2093. hr = GetInternalConnectionArray( _hnetInfo.pncExternal, &ppArray, &dwItems );
  2094. if ( SUCCEEDED(hr) )
  2095. {
  2096. hr = E_FAIL;
  2097. for( DWORD i=0; i<dwItems; i++ )
  2098. {
  2099. if ( S_OK != hr )
  2100. {
  2101. hr = HrLookupForIpAddress( ppArray[i],
  2102. DEFAULT_SCOPE_ADDRESS,
  2103. &bExists,
  2104. ppszHost,
  2105. pdwSize );
  2106. }
  2107. ppArray[i]->Release();
  2108. } // for( DWORD i=0; i<dwItems; i++ )
  2109. LocalFree( ppArray );
  2110. } // if ( SUCCEEDED(hr) )
  2111. return bExists;
  2112. }
  2113. void CHomeNetworkWizard::ICSConflictSetActive(HWND hwnd)
  2114. {
  2115. WCHAR* pszConflictingHost = NULL;
  2116. DWORD dwSize = 0;
  2117. PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK | PSWIZB_NEXT);
  2118. static const int _KnownControls[] =
  2119. {
  2120. IDC_KNOWNCONFLICT1,
  2121. IDC_KNOWNCONFLICT2,
  2122. IDC_KNOWNCONFLICT3,
  2123. IDC_KNOWNCONFLICT4,
  2124. IDC_KNOWNCONFLICT5,
  2125. IDC_KNOWNCONFLICT6,
  2126. IDC_KNOWNCONFLICT7,
  2127. IDC_KNOWNCONFLICT8,
  2128. IDC_COMPUTERNAME
  2129. };
  2130. static const int _UnknownControls[] =
  2131. {
  2132. IDC_UNKNOWNCONFLICT1,
  2133. IDC_UNKNOWNCONFLICT2
  2134. };
  2135. if ((_hnetInfo.dwFlags & HNET_SHARECONNECTION) && IsICSIPInUse(&pszConflictingHost, &dwSize))
  2136. {
  2137. // We show and hide controls depending on if we already know about an ICS machine name
  2138. WCHAR szICSHost[MAX_PATH];
  2139. if (GetICSMachine(szICSHost, ARRAYSIZE(szICSHost)))
  2140. {
  2141. // We know this is a UPnP ICS host - show the "known conflict" set of controls
  2142. ShowControls(hwnd, _KnownControls, ARRAYSIZE(_KnownControls), SW_SHOWNORMAL);
  2143. ShowControls(hwnd, _UnknownControls, ARRAYSIZE(_UnknownControls), SW_HIDE);
  2144. SetDlgItemText(hwnd, IDC_COMPUTERNAME, szICSHost);
  2145. }
  2146. else
  2147. {
  2148. // We have no idea what's hogging our IP - show a very generic set of controls
  2149. ShowControls(hwnd, _UnknownControls, ARRAYSIZE(_UnknownControls), SW_SHOWNORMAL);
  2150. ShowControls(hwnd, _KnownControls, ARRAYSIZE(_KnownControls), SW_HIDE);
  2151. }
  2152. }
  2153. else
  2154. {
  2155. // Go on to the next screen
  2156. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_BRIDGEWARNING);
  2157. }
  2158. if ( pszConflictingHost )
  2159. delete [] pszConflictingHost;
  2160. }
  2161. INT_PTR CHomeNetworkWizard::ICSConflictPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2162. {
  2163. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2164. switch (uMsg)
  2165. {
  2166. case WM_INITDIALOG:
  2167. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_ICSCONFLICT);
  2168. return TRUE;
  2169. case WM_NOTIFY:
  2170. {
  2171. LPNMHDR pnmh = (LPNMHDR) lParam;
  2172. WCHAR* pszConflictingHost = NULL;
  2173. DWORD dwSize = 0;
  2174. switch (pnmh->code)
  2175. {
  2176. case PSN_SETACTIVE:
  2177. pthis->ICSConflictSetActive(hwnd);
  2178. return TRUE;
  2179. case PSN_WIZNEXT:
  2180. if (pthis->IsICSIPInUse(&pszConflictingHost, &dwSize))
  2181. {
  2182. DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, IDS_STILLICSCONFLICT, MB_ICONERROR | MB_OK);
  2183. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, -1);
  2184. }
  2185. else
  2186. {
  2187. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) IDD_WIZ_BRIDGEWARNING);
  2188. }
  2189. if ( pszConflictingHost )
  2190. delete [] pszConflictingHost;
  2191. return TRUE;
  2192. case PSN_WIZBACK:
  2193. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2194. return TRUE;
  2195. case NM_CLICK:
  2196. case NM_RETURN:
  2197. switch ((int) wParam)
  2198. {
  2199. case IDC_HELPLINK:
  2200. {
  2201. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_change_ics_host.htm");
  2202. }
  2203. return TRUE;
  2204. }
  2205. }
  2206. }
  2207. return FALSE;
  2208. }
  2209. return FALSE;
  2210. }
  2211. DWORD CHomeNetworkWizard::GetConnectionCount(INetConnection* pncExclude, DWORD dwFlags)
  2212. {
  2213. DWORD dwCount = 0;
  2214. if (g_fRunningOnNT)
  2215. {
  2216. DWORD cItems = DPA_GetPtrCount(_hdpaConnections);
  2217. for (DWORD iItem = 0; iItem < cItems; iItem ++)
  2218. {
  2219. INetConnection* pnc = (INetConnection*) DPA_GetPtr(_hdpaConnections, iItem);
  2220. if (ShouldShowConnection(pnc, pncExclude, dwFlags))
  2221. {
  2222. dwCount++;
  2223. }
  2224. }
  2225. }
  2226. else
  2227. {
  2228. const NETADAPTER* pNA = _hnetInfo.pNA;
  2229. for (UINT i = 0; i < _hnetInfo.cNA; i++, pNA++)
  2230. {
  2231. // Check if the NIC is working.
  2232. if (W9xIsValidAdapter(pNA, dwFlags))
  2233. {
  2234. dwCount++;
  2235. }
  2236. }
  2237. }
  2238. return dwCount;
  2239. }
  2240. INT_PTR CHomeNetworkWizard::BridgeWarningPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2241. {
  2242. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2243. switch (uMsg)
  2244. {
  2245. case WM_INITDIALOG:
  2246. SendDlgItemMessage(hwnd, IDC_AUTOBRIDGE, BM_SETCHECK, (WPARAM) BST_CHECKED, 0);
  2247. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_BRIDGE);
  2248. return TRUE;
  2249. case WM_NOTIFY:
  2250. {
  2251. LPNMHDR pnmh = (LPNMHDR) lParam;
  2252. switch (pnmh->code)
  2253. {
  2254. case PSN_SETACTIVE:
  2255. {
  2256. if (pthis->_fNoHomeNetwork)
  2257. {
  2258. FreeInternalConnections(&pthis->_hnetInfo);
  2259. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_NAME);
  2260. }
  2261. else
  2262. {
  2263. DWORD nInternal = pthis->GetConnectionCount(pthis->_hnetInfo.pncExternal, CONN_INTERNAL);
  2264. if (1 < nInternal)
  2265. {
  2266. // We show this page if there are two or more internal connections (which is this case)
  2267. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
  2268. }
  2269. else if ((pthis->_hnetInfo.dwFlags & HNET_SHARECONNECTION) && (0 == nInternal))
  2270. {
  2271. // We are sharing the public connection, and there are no other connections left
  2272. // over for home networking. Show error page
  2273. pthis->_fManualBridgeConfig = FALSE;
  2274. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_NOHARDWAREFINISH);
  2275. }
  2276. else
  2277. {
  2278. // There are either zero or one internal connections. If zero, then we aren't sharing the connection
  2279. // Skip the bridge warning page and go to the private page
  2280. pthis->_fManualBridgeConfig = FALSE;
  2281. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_PRIVATE);
  2282. }
  2283. }
  2284. return TRUE;
  2285. }
  2286. case PSN_WIZNEXT:
  2287. {
  2288. pthis->_fManualBridgeConfig = (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_MANUALBRIDGE, BM_GETCHECK, 0, 0));
  2289. pthis->PushPage(IDD_WIZ_BRIDGEWARNING);
  2290. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_PRIVATE);
  2291. }
  2292. return TRUE;
  2293. case PSN_WIZBACK:
  2294. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2295. return TRUE;
  2296. case NM_CLICK:
  2297. case NM_RETURN:
  2298. switch ((int) wParam)
  2299. {
  2300. case IDC_HELPLINK:
  2301. {
  2302. HelpCenter(hwnd, L"netcfg.chm%3A%3A/hnw_understanding_bridge.htm");
  2303. }
  2304. return TRUE;
  2305. }
  2306. }
  2307. }
  2308. return FALSE;
  2309. }
  2310. return FALSE;
  2311. }
  2312. void FreeInternalConnections(PHOMENETSETUPINFO pInfo)
  2313. {
  2314. // Delete any existing private connection information
  2315. if (pInfo->prgncInternal)
  2316. {
  2317. for (DWORD i = 0; i < pInfo->cncInternal; i++)
  2318. {
  2319. INetConnection* pnc = pInfo->prgncInternal[i];
  2320. pnc->Release();
  2321. }
  2322. LocalFree(pInfo->prgncInternal);
  2323. pInfo->prgncInternal = NULL;
  2324. }
  2325. pInfo->cncInternal = 0;
  2326. }
  2327. void FreeInternalGUIDs(PHOMENETSETUPINFO pInfo)
  2328. {
  2329. if (pInfo->prgguidInternal)
  2330. {
  2331. LocalFree(pInfo->prgguidInternal);
  2332. pInfo->prgguidInternal = NULL;
  2333. }
  2334. pInfo->cguidInternal = 0;
  2335. }
  2336. DWORD _ListView_GetCheckedCount(HWND hwndList)
  2337. {
  2338. int nItems = ListView_GetItemCount(hwndList);
  2339. DWORD nCheckedItems = 0;
  2340. if (-1 != nItems)
  2341. {
  2342. for(int iItem = 0; iItem < nItems; iItem ++)
  2343. {
  2344. if (ListView_GetCheckState(hwndList, iItem))
  2345. {
  2346. nCheckedItems ++;
  2347. }
  2348. }
  2349. }
  2350. return nCheckedItems;
  2351. }
  2352. void CHomeNetworkWizard::PrivateSetControlState(HWND hwnd)
  2353. {
  2354. BOOL fEnableNext = TRUE;
  2355. // If the user is sharing a connection, they must specify at least one private connection
  2356. if (_hnetInfo.dwFlags & HNET_SHARECONNECTION)
  2357. {
  2358. fEnableNext = (0 != _ListView_GetCheckedCount(GetDlgItem(hwnd, IDC_CONNLIST)));
  2359. }
  2360. PropSheet_SetWizButtons(GetParent(hwnd), fEnableNext ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK);
  2361. }
  2362. void CHomeNetworkWizard::PrivateNextPage(HWND hwnd)
  2363. {
  2364. FreeInternalConnections(&_hnetInfo);
  2365. // Figure out the number of connections we'll need
  2366. HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST);
  2367. int nItems = ListView_GetItemCount(hwndList);
  2368. DWORD nCheckedItems = _ListView_GetCheckedCount(hwndList);
  2369. if (nCheckedItems)
  2370. {
  2371. _hnetInfo.prgncInternal = (INetConnection**) LocalAlloc(LPTR, (nCheckedItems + 1) * sizeof (INetConnection*));
  2372. // Alloc one extra INetConnection* and Null-terminate this array so we can pass it to HNet config api
  2373. if (_hnetInfo.prgncInternal)
  2374. {
  2375. _hnetInfo.cncInternal = 0;
  2376. // Get the INetConnection for each checked item
  2377. for (int iItem = 0; iItem < nItems; iItem ++)
  2378. {
  2379. if (ListView_GetCheckState(hwndList, iItem))
  2380. {
  2381. LVITEM lvi = {0};
  2382. lvi.iItem = iItem;
  2383. lvi.mask = LVIF_PARAM;
  2384. ListView_GetItem(hwndList, &lvi);
  2385. if (g_fRunningOnNT)
  2386. {
  2387. _hnetInfo.prgncInternal[_hnetInfo.cncInternal] = (INetConnection*) lvi.lParam;
  2388. _hnetInfo.prgncInternal[_hnetInfo.cncInternal]->AddRef();
  2389. }
  2390. else
  2391. {
  2392. // TODO W9x
  2393. }
  2394. _hnetInfo.cncInternal ++;
  2395. }
  2396. }
  2397. // Assert since if we messed something up there might not be enough space allocated in the buffer!
  2398. ASSERT(nCheckedItems == _hnetInfo.cncInternal);
  2399. }
  2400. }
  2401. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_NAME);
  2402. }
  2403. INT_PTR CHomeNetworkWizard::PrivatePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2404. {
  2405. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2406. switch (uMsg)
  2407. {
  2408. case WM_INITDIALOG:
  2409. pthis->InitializeConnectionList(GetDlgItem(hwnd, IDC_CONNLIST), CONN_INTERNAL);
  2410. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_BRIDGE);
  2411. return TRUE;
  2412. case WM_NOTIFY:
  2413. {
  2414. LPNMHDR pnmh = (LPNMHDR) lParam;
  2415. switch (pnmh->code)
  2416. {
  2417. case PSN_SETACTIVE:
  2418. {
  2419. FreeInternalConnections(&(pthis->_hnetInfo));
  2420. HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST);
  2421. pthis->FillConnectionList(hwndList, pthis->_hnetInfo.pncExternal, CONN_INTERNAL);
  2422. // If the user hasn't select manual bridge and/or there is less than 2 items,
  2423. // then _fManualBridgeConfig will be FALSE and we'll autobridge
  2424. if (!pthis->_fManualBridgeConfig)
  2425. {
  2426. // PrivateNextPage will set DWLP_MSGRESULT and tell the wizard to skip this page
  2427. // and go on to the next.
  2428. pthis->PrivateNextPage(hwnd);
  2429. }
  2430. pthis->PrivateSetControlState(hwnd);
  2431. return TRUE;
  2432. }
  2433. case PSN_WIZNEXT:
  2434. pthis->PrivateNextPage(hwnd);
  2435. pthis->PushPage(IDD_WIZ_PRIVATE);
  2436. return TRUE;
  2437. case PSN_WIZBACK:
  2438. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2439. return TRUE;
  2440. case NM_CLICK:
  2441. case NM_RETURN:
  2442. switch ((int) wParam)
  2443. {
  2444. case IDC_HELPLINK:
  2445. {
  2446. HelpCenter(hwnd, L"netcfg.chm%3A%3A/hnw_understanding_bridge.htm");
  2447. }
  2448. return TRUE;
  2449. }
  2450. case LVN_ITEMCHANGED:
  2451. pthis->PrivateSetControlState(hwnd);
  2452. return TRUE;
  2453. }
  2454. }
  2455. return FALSE;
  2456. case WM_DESTROY:
  2457. pthis->DestroyConnectionList(GetDlgItem(hwnd, IDC_CONNLIST));
  2458. return FALSE;
  2459. }
  2460. return FALSE;
  2461. }
  2462. void CHomeNetworkWizard::NameSetControlState(HWND hwnd)
  2463. {
  2464. BOOL fEnableNext = (0 != GetWindowTextLength(GetDlgItem(hwnd, IDC_COMPUTERNAME)));
  2465. PropSheet_SetWizButtons(GetParent(hwnd), fEnableNext ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK);
  2466. }
  2467. HRESULT CHomeNetworkWizard::NameNextPage(HWND hwnd)
  2468. {
  2469. HRESULT hr = E_FAIL;
  2470. GetDlgItemText(hwnd, IDC_COMPUTERDESC, _hnetInfo.szComputerDescription, ARRAYSIZE(_hnetInfo.szComputerDescription));
  2471. GetDlgItemText(hwnd, IDC_COMPUTERNAME, _hnetInfo.szComputer, ARRAYSIZE(_hnetInfo.szComputer));
  2472. // There are two errors that we show for computer name: INVALID and DUPLICATE
  2473. // TODO: We only detect duplicate for NT so far!!!
  2474. UINT idError = IDS_COMPNAME_INVALID;
  2475. // Test to see if the name is more than 15 OEM bytes
  2476. int iBytes = WideCharToMultiByte(CP_OEMCP, 0, _hnetInfo.szComputer, -1, NULL, 0, NULL, NULL) - 1;
  2477. if (iBytes <= LM20_DNLEN)
  2478. {
  2479. if (IsValidNameSyntax(_hnetInfo.szComputer, NetSetupMachine))
  2480. {
  2481. if (g_fRunningOnNT)
  2482. {
  2483. SetCursor(LoadCursor(NULL, IDC_WAIT));
  2484. NET_API_STATUS nas = NetValidateName(NULL, _hnetInfo.szComputer, NULL, NULL, NetSetupMachine);
  2485. if (ERROR_DUP_NAME == nas)
  2486. {
  2487. ASSERT(E_FAIL == hr);
  2488. idError = IDS_COMPNAME_DUPLICATE;
  2489. }
  2490. else if (NERR_InvalidComputer == nas)
  2491. {
  2492. ASSERT(E_FAIL == hr);
  2493. idError = IDS_COMPNAME_INVALID;
  2494. }
  2495. else
  2496. {
  2497. // if there is any other failure we just go ahead. If the Client For MS Networks is not installed we
  2498. // can't validate the name, but it should be fine to use what we have
  2499. hr = S_OK;
  2500. _hnetInfo.dwFlags |= HNET_SETCOMPUTERNAME;
  2501. }
  2502. }
  2503. else
  2504. {
  2505. // TODO: Win9x!!!
  2506. hr = S_OK;
  2507. _hnetInfo.dwFlags |= HNET_SETCOMPUTERNAME;
  2508. }
  2509. }
  2510. }
  2511. else
  2512. {
  2513. ASSERT(E_FAIL == hr);
  2514. idError = IDS_COMPNAME_TOOMANYBYTES;
  2515. }
  2516. // If the computer name didn't validate, don't change pages and show an error.
  2517. if(FAILED(hr))
  2518. {
  2519. SetFocus(GetDlgItem(hwnd, IDC_COMPUTERNAME));
  2520. PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK);
  2521. DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, idError, MB_ICONERROR | MB_OK, _hnetInfo.szComputer);
  2522. }
  2523. return hr;
  2524. }
  2525. void CHomeNetworkWizard::NameInitDialog(HWND hwnd)
  2526. {
  2527. // Limit the edit fields
  2528. SendDlgItemMessage(hwnd, IDC_COMPUTERDESC, EM_SETLIMITTEXT, ARRAYSIZE(_hnetInfo.szComputerDescription) - 1, NULL);
  2529. SendDlgItemMessage(hwnd, IDC_COMPUTERNAME, EM_SETLIMITTEXT, ARRAYSIZE(_hnetInfo.szComputer) - 1, NULL);
  2530. // Set the current name as the default
  2531. WCHAR szComputerName[ARRAYSIZE(_hnetInfo.szComputer)];
  2532. *szComputerName = 0;
  2533. WCHAR szDescription[ARRAYSIZE(_hnetInfo.szComputerDescription)];
  2534. *szDescription = 0;
  2535. if (g_fRunningOnNT)
  2536. {
  2537. SERVER_INFO_101_NT* psv101 = NULL;
  2538. if (NERR_Success == NetServerGetInfo_NT(NULL, 101, (LPBYTE*) &psv101))
  2539. {
  2540. if (psv101->sv101_comment && psv101->sv101_comment[0])
  2541. {
  2542. StrCpyN(szDescription, psv101->sv101_comment, ARRAYSIZE(szDescription));
  2543. }
  2544. ASSERT(psv101->sv101_name);
  2545. StrCpyN(szComputerName, psv101->sv101_name, ARRAYSIZE(szComputerName));
  2546. NetApiBufferFree(psv101);
  2547. }
  2548. }
  2549. else
  2550. {
  2551. AllPlatformGetComputerName(szComputerName, ARRAYSIZE(szComputerName));
  2552. CRegistry reg;
  2553. if (reg.OpenKey(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\VxD\\VNETSUP", KEY_READ))
  2554. {
  2555. reg.QueryStringValue(L"Comment", szDescription, ARRAYSIZE(szDescription));
  2556. }
  2557. }
  2558. SetDlgItemText(hwnd, IDC_COMPUTERNAME, szComputerName);
  2559. SetDlgItemText(hwnd, IDC_COMPUTERDESC, szDescription);
  2560. WCHAR szNameMessage[256];
  2561. if (FormatMessageString(IDS_CURRENTNAME, szNameMessage, ARRAYSIZE(szNameMessage), szComputerName))
  2562. {
  2563. SetDlgItemText(hwnd, IDC_CURRENTNAME, szNameMessage);
  2564. }
  2565. }
  2566. INT_PTR CHomeNetworkWizard::NamePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2567. {
  2568. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2569. switch (uMsg)
  2570. {
  2571. case WM_INITDIALOG:
  2572. pthis->NameInitDialog(hwnd);
  2573. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_COMPNAME);
  2574. return TRUE;
  2575. case WM_NOTIFY:
  2576. {
  2577. LPNMHDR pnmh = (LPNMHDR) lParam;
  2578. switch (pnmh->code)
  2579. {
  2580. case PSN_SETACTIVE:
  2581. {
  2582. // Show the ISP Warning if this computer connects directly to the Internet
  2583. int nShowISPWarning = (NULL != pthis->_hnetInfo.pncExternal) ? SW_SHOW : SW_HIDE;
  2584. ShowWindow(GetDlgItem(hwnd, IDC_ISPWARN1), nShowISPWarning);
  2585. ShowWindow(GetDlgItem(hwnd, IDC_ISPWARN2), nShowISPWarning);
  2586. pthis->NameSetControlState(hwnd);
  2587. }
  2588. return TRUE;
  2589. case PSN_WIZNEXT:
  2590. if (SUCCEEDED(pthis->NameNextPage(hwnd)))
  2591. {
  2592. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) IDD_WIZ_WORKGROUP);
  2593. pthis->PushPage(IDD_WIZ_NAME);
  2594. }
  2595. else
  2596. {
  2597. // else not changing pages; don't push
  2598. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1);
  2599. }
  2600. return TRUE;
  2601. case PSN_WIZBACK:
  2602. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2603. return TRUE;
  2604. case NM_CLICK:
  2605. case NM_RETURN:
  2606. switch ((int) wParam)
  2607. {
  2608. case IDC_HELPLINK:
  2609. {
  2610. HelpCenter(hwnd, L"network.chm%3A%3A/hnw_comp_name_description.htm");
  2611. }
  2612. return TRUE;
  2613. }
  2614. }
  2615. }
  2616. return FALSE;
  2617. case WM_COMMAND:
  2618. {
  2619. switch (HIWORD(wParam))
  2620. {
  2621. case EN_CHANGE:
  2622. if (LOWORD(wParam) == IDC_COMPUTERNAME)
  2623. {
  2624. pthis->NameSetControlState(hwnd);
  2625. }
  2626. return FALSE;
  2627. }
  2628. }
  2629. return FALSE;
  2630. }
  2631. return FALSE;
  2632. }
  2633. void CHomeNetworkWizard::WorkgroupSetControlState(HWND hwnd)
  2634. {
  2635. BOOL fNext = (0 != SendDlgItemMessage(hwnd, IDC_WORKGROUP, WM_GETTEXTLENGTH, 0, 0));
  2636. PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK | (fNext ? PSWIZB_NEXT : 0));
  2637. }
  2638. HRESULT CHomeNetworkWizard::WorkgroupNextPage(HWND hwnd)
  2639. {
  2640. HRESULT hr = E_FAIL;
  2641. UINT idError = IDS_WORKGROUP_INVALID;
  2642. if (GetDlgItemText(hwnd, IDC_WORKGROUP, _hnetInfo.szWorkgroup, ARRAYSIZE(_hnetInfo.szWorkgroup)))
  2643. {
  2644. // Test to see if the name is more than 15 OEM bytes
  2645. int iBytes = WideCharToMultiByte(CP_OEMCP, 0, _hnetInfo.szWorkgroup, -1, NULL, 0, NULL, NULL) - 1;
  2646. if (iBytes <= LM20_DNLEN)
  2647. {
  2648. // Remove any preceding blanks
  2649. size_t szLen = wcslen( _hnetInfo.szWorkgroup ) + 1;
  2650. LPWSTR szTemp = new WCHAR[ szLen ];
  2651. if ( szTemp )
  2652. {
  2653. WCHAR* pch;
  2654. for ( pch = _hnetInfo.szWorkgroup; *pch && (L' ' == *pch); )
  2655. pch++;
  2656. wcsncpy( szTemp, pch, szLen );
  2657. wcsncpy( _hnetInfo.szWorkgroup, szTemp, szLen );
  2658. delete [] szTemp;
  2659. }
  2660. // Use the computer name check for workgroups too
  2661. if (IsValidNameSyntax(_hnetInfo.szWorkgroup, NetSetupWorkgroup))
  2662. {
  2663. if (g_fRunningOnNT)
  2664. {
  2665. SetCursor(LoadCursor(NULL, IDC_WAIT));
  2666. NET_API_STATUS nas = NetValidateName(NULL, _hnetInfo.szWorkgroup, NULL, NULL, NetSetupWorkgroup);
  2667. if (NERR_InvalidWorkgroupName != nas) // we only put up a invalid name dialog if the name was invalid.
  2668. {
  2669. hr = S_OK;
  2670. _hnetInfo.dwFlags |= HNET_SETWORKGROUPNAME;
  2671. }
  2672. }
  2673. else
  2674. {
  2675. // TODO: Win9x!!!
  2676. hr = S_OK;
  2677. _hnetInfo.dwFlags |= HNET_SETWORKGROUPNAME;
  2678. }
  2679. }
  2680. }
  2681. else
  2682. {
  2683. ASSERT(E_FAIL == hr);
  2684. idError = IDS_WORKGROUP_TOOMANYBYTES;
  2685. }
  2686. // If the computer name didn't validate, don't change pages and show an error.
  2687. if(FAILED(hr))
  2688. {
  2689. SetFocus(GetDlgItem(hwnd, IDC_WORKGROUP));
  2690. PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK);
  2691. DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, idError, MB_ICONERROR | MB_OK, _hnetInfo.szWorkgroup);
  2692. }
  2693. }
  2694. return hr;
  2695. }
  2696. INT_PTR CHomeNetworkWizard::WorkgroupPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2697. {
  2698. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2699. switch (uMsg)
  2700. {
  2701. case WM_INITDIALOG:
  2702. {
  2703. WCHAR szWorkgroup[LM20_DNLEN + 1]; *szWorkgroup = 0;
  2704. LoadString(g_hinst, IDS_DEFAULT_WORKGROUP1, szWorkgroup, ARRAYSIZE(szWorkgroup));
  2705. SetDlgItemText(hwnd, IDC_WORKGROUP, szWorkgroup);
  2706. SendDlgItemMessage(hwnd, IDC_WORKGROUP, EM_LIMITTEXT, ARRAYSIZE(pthis->_hnetInfo.szWorkgroup) - 1, 0);
  2707. }
  2708. return TRUE;
  2709. case WM_NOTIFY:
  2710. {
  2711. LPNMHDR pnmh = (LPNMHDR) lParam;
  2712. switch (pnmh->code)
  2713. {
  2714. case PSN_SETACTIVE:
  2715. {
  2716. pthis->WorkgroupSetControlState(hwnd);
  2717. pthis->_hnetInfo.dwFlags &= (~HNET_SETWORKGROUPNAME);
  2718. }
  2719. return TRUE;
  2720. case PSN_WIZNEXT:
  2721. {
  2722. if (SUCCEEDED(pthis->WorkgroupNextPage(hwnd)))
  2723. {
  2724. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) IDD_WIZ_SUMMARY);
  2725. pthis->PushPage(IDD_WIZ_WORKGROUP);
  2726. }
  2727. else
  2728. {
  2729. // else not changing pages; don't push
  2730. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1);
  2731. }
  2732. }
  2733. return TRUE;
  2734. case PSN_WIZBACK:
  2735. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2736. return TRUE;
  2737. }
  2738. }
  2739. return FALSE;
  2740. case WM_COMMAND:
  2741. {
  2742. switch (HIWORD(wParam))
  2743. {
  2744. case EN_CHANGE:
  2745. if (LOWORD(wParam) == IDC_WORKGROUP)
  2746. {
  2747. pthis->WorkgroupSetControlState(hwnd);
  2748. }
  2749. return FALSE;
  2750. }
  2751. }
  2752. return FALSE;
  2753. }
  2754. return FALSE;
  2755. }
  2756. INT_PTR CHomeNetworkWizard::SummaryPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2757. {
  2758. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2759. switch (uMsg)
  2760. {
  2761. case WM_INITDIALOG:
  2762. {
  2763. return TRUE;
  2764. }
  2765. case WM_NOTIFY:
  2766. {
  2767. LPNMHDR pnmh = (LPNMHDR) lParam;
  2768. switch (pnmh->code)
  2769. {
  2770. case PSN_QUERYINITIALFOCUS:
  2771. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) GetDlgItem(hwnd, IDC_TITLE));
  2772. return TRUE;
  2773. case PSN_SETACTIVE:
  2774. pthis->SummarySetActive(hwnd);
  2775. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
  2776. return TRUE;
  2777. case PSN_WIZBACK:
  2778. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2779. return TRUE;
  2780. case PSN_WIZNEXT:
  2781. pthis->PushPage(IDD_WIZ_SUMMARY);
  2782. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_PROGRESS);
  2783. return TRUE;
  2784. }
  2785. }
  2786. return FALSE;
  2787. }
  2788. return FALSE;
  2789. }
  2790. #define WM_CONFIGDONE (WM_USER + 0x100)
  2791. INT_PTR CHomeNetworkWizard::ProgressPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2792. {
  2793. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2794. switch (uMsg)
  2795. {
  2796. case WM_INITDIALOG:
  2797. {
  2798. return TRUE;
  2799. }
  2800. case WM_NOTIFY:
  2801. {
  2802. LPNMHDR pnmh = (LPNMHDR) lParam;
  2803. switch (pnmh->code)
  2804. {
  2805. case PSN_SETACTIVE:
  2806. {
  2807. PropSheet_CancelToClose(GetParent(hwnd));
  2808. PropSheet_SetWizButtons(pnmh->hwndFrom, 0);
  2809. pthis->_hnetInfo.fAsync = TRUE;
  2810. pthis->_hnetInfo.hwnd = hwnd;
  2811. pthis->_hnetInfo.umsgAsyncNotify = WM_CONFIGDONE;
  2812. ConfigureHomeNetwork(&(pthis->_hnetInfo));
  2813. HWND hwndAnimate = GetDlgItem(hwnd, IDC_PROGRESS);
  2814. Animate_Open(hwndAnimate, g_fRunningOnNT ? IDA_CONFIG : IDA_LOWCOLORCONFIG);
  2815. Animate_Play(hwndAnimate, 0, -1, -1);
  2816. }
  2817. return TRUE;
  2818. }
  2819. }
  2820. return FALSE;
  2821. case WM_CONFIGDONE:
  2822. {
  2823. Animate_Stop(GetDlgItem(hwnd, IDC_PROGRESS));
  2824. // The config thread has finished. We assert that the thread has freed/nulled out
  2825. // all of his INetConnection*'s since otherwise the UI thread will try to use/free them!
  2826. ASSERT(NULL == pthis->_hnetInfo.pncExternal);
  2827. ASSERT(NULL == pthis->_hnetInfo.prgncInternal);
  2828. if (pthis->_hnetInfo.fRebootRequired)
  2829. {
  2830. PropSheet_RebootSystem(GetParent(hwnd));
  2831. }
  2832. // The HRESULT from the configuration is stored in wParam
  2833. HRESULT hr = (HRESULT) wParam;
  2834. UINT idFinishPage;
  2835. if (SUCCEEDED(hr))
  2836. {
  2837. idFinishPage = IDD_WIZ_ALMOSTDONE;
  2838. }
  2839. else
  2840. {
  2841. idFinishPage = IDD_WIZ_CONFIGERROR;
  2842. }
  2843. PropSheet_SetCurSelByID(GetParent(hwnd), idFinishPage);
  2844. }
  2845. return TRUE;
  2846. }
  2847. return FALSE;
  2848. }
  2849. INT_PTR CHomeNetworkWizard::AlmostDonePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2850. {
  2851. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2852. switch (uMsg)
  2853. {
  2854. case WM_INITDIALOG:
  2855. {
  2856. SendDlgItemMessage(hwnd, IDC_CREATEDISK, BM_SETCHECK, BST_CHECKED, 0);
  2857. return TRUE;
  2858. }
  2859. case WM_NOTIFY:
  2860. {
  2861. LPNMHDR pnmh = (LPNMHDR) lParam;
  2862. switch (pnmh->code)
  2863. {
  2864. case PSN_SETACTIVE:
  2865. {
  2866. if (g_fRunningOnNT)
  2867. {
  2868. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_NEXT);
  2869. }
  2870. else
  2871. {
  2872. // Skip this page on 9x
  2873. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_WIN9X_FINISH);
  2874. }
  2875. }
  2876. return TRUE;
  2877. case PSN_WIZNEXT:
  2878. {
  2879. // This page only shows on NT
  2880. ASSERT(g_fRunningOnNT);
  2881. pthis->_fFloppyInstructions = TRUE;
  2882. pthis->PushPage(IDD_WIZ_ALMOSTDONE);
  2883. UINT idNext = IDD_WIZ_FINISH;
  2884. if (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_CREATEDISK, BM_GETCHECK, 0, 0))
  2885. {
  2886. idNext = IDD_WIZ_CHOOSEDISK;
  2887. }
  2888. else if (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_HAVEDISK, BM_GETCHECK, 0, 0))
  2889. {
  2890. idNext = IDD_WIZ_FLOPPYINST;
  2891. }
  2892. else if (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_HAVECD, BM_GETCHECK, 0, 0))
  2893. {
  2894. idNext = IDD_WIZ_CDINST;
  2895. pthis->_fFloppyInstructions = FALSE;
  2896. }
  2897. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) idNext);
  2898. }
  2899. return TRUE;
  2900. }
  2901. }
  2902. return FALSE;
  2903. }
  2904. return FALSE;
  2905. }
  2906. void CHomeNetworkWizard::FillDriveList(HWND hwndList)
  2907. {
  2908. ListView_SetImageList(hwndList, _himlLarge, LVSIL_NORMAL);
  2909. ListView_DeleteAllItems(hwndList);
  2910. WCHAR szDrive[] = L"A:\\";
  2911. for (UINT i = 0; i < 26; i++)
  2912. {
  2913. szDrive[0] = L'A' + i;
  2914. if (DRIVE_REMOVABLE == GetDriveType(szDrive))
  2915. {
  2916. LVITEM lvi = {0};
  2917. lvi.mask = LVIF_PARAM | LVIF_TEXT;
  2918. lvi.lParam = i;
  2919. int iIndex;
  2920. WCHAR szDriveDisplay[256];
  2921. HRESULT hr = GetDriveNameAndIconIndex(szDrive, szDriveDisplay, ARRAYSIZE(szDriveDisplay), &iIndex);
  2922. if (SUCCEEDED(hr))
  2923. {
  2924. lvi.iImage = iIndex;
  2925. if (-1 != lvi.iImage)
  2926. lvi.mask |= LVIF_IMAGE;
  2927. lvi.pszText = szDriveDisplay;
  2928. int iItem = ListView_InsertItem(hwndList, &lvi);
  2929. }
  2930. }
  2931. }
  2932. ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);
  2933. ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE);
  2934. }
  2935. void CHomeNetworkWizard::ChooseDiskSetControlState(HWND hwnd)
  2936. {
  2937. BOOL fSelection = ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_DEVICELIST));
  2938. PropSheet_SetWizButtons(GetParent(hwnd), fSelection ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK);
  2939. }
  2940. INT_PTR CHomeNetworkWizard::ChooseDiskPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2941. {
  2942. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  2943. switch (uMsg)
  2944. {
  2945. case WM_INITDIALOG:
  2946. ASSERT(g_fRunningOnNT);
  2947. return TRUE;
  2948. case WM_NOTIFY:
  2949. {
  2950. LPNMHDR pnmh = (LPNMHDR) lParam;
  2951. switch (pnmh->code)
  2952. {
  2953. case PSN_QUERYINITIALFOCUS:
  2954. SetFocus(GetDlgItem(hwnd, IDC_DEVICELIST));
  2955. return TRUE;
  2956. case PSN_SETACTIVE:
  2957. {
  2958. HWND hwndList = GetDlgItem(hwnd, IDC_DEVICELIST);
  2959. pthis->FillDriveList(hwndList);
  2960. pthis->ChooseDiskSetControlState(hwnd);
  2961. int cDrives = ListView_GetItemCount(hwndList);
  2962. if (0 >= cDrives)
  2963. {
  2964. // There are no removable drives or an error occurred
  2965. DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, IDS_NOREMOVABLEDRIVES, MB_ICONINFORMATION | MB_OK);
  2966. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2967. }
  2968. else if (1 == cDrives)
  2969. {
  2970. // One drive - autoselect it and go to the next page
  2971. LVITEM lvi = {0};
  2972. lvi.mask = LVIF_PARAM;
  2973. ListView_GetItem(hwndList, &lvi);
  2974. pthis->_iDrive = lvi.lParam;
  2975. ListView_GetItemText(hwndList, lvi.iItem, 0, pthis->_szDrive, ARRAYSIZE(pthis->_szDrive));
  2976. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_INSERTDISK);
  2977. }
  2978. }
  2979. return TRUE;
  2980. case PSN_WIZNEXT:
  2981. {
  2982. HWND hwndList = GetDlgItem(hwnd, IDC_DEVICELIST);
  2983. pthis->_iDrive = 0;
  2984. LVITEM lvi = {0};
  2985. lvi.mask = LVIF_PARAM;
  2986. lvi.iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
  2987. if (-1 != lvi.iItem && ListView_GetItem(hwndList, &lvi))
  2988. {
  2989. pthis->_iDrive = lvi.lParam;
  2990. ListView_GetItemText(hwndList, lvi.iItem, 0, pthis->_szDrive, ARRAYSIZE(pthis->_szDrive));
  2991. pthis->PushPage(IDD_WIZ_CHOOSEDISK);
  2992. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_INSERTDISK);
  2993. }
  2994. }
  2995. return TRUE;
  2996. case PSN_WIZBACK:
  2997. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  2998. return TRUE;
  2999. case LVN_ITEMCHANGED:
  3000. pthis->ChooseDiskSetControlState(hwnd);
  3001. return TRUE;
  3002. }
  3003. }
  3004. return FALSE;
  3005. }
  3006. return FALSE;
  3007. }
  3008. #define SOURCE_FILE "%windir%\\system32\\netsetup.exe"
  3009. HRESULT CHomeNetworkWizard::GetSourceFilePath(LPSTR pszSource, DWORD cch)
  3010. {
  3011. HRESULT hr = E_FAIL;
  3012. if (ExpandEnvironmentStringsA(SOURCE_FILE, pszSource, cch))
  3013. {
  3014. DWORD c = lstrlenA(pszSource);
  3015. if (c + 2 <= cch)
  3016. {
  3017. // Add double NULL since we'll be passing this to SHFileOperation
  3018. pszSource[c + 1] = '\0';
  3019. hr = S_OK;
  3020. }
  3021. }
  3022. return hr;
  3023. }
  3024. INT_PTR CHomeNetworkWizard::InsertDiskPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3025. {
  3026. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  3027. switch (uMsg)
  3028. {
  3029. case WM_INITDIALOG:
  3030. ASSERT(g_fRunningOnNT);
  3031. return TRUE;
  3032. case WM_COMMAND:
  3033. if (IDC_FORMAT == LOWORD(wParam))
  3034. {
  3035. SHFormatDrive(hwnd, pthis->_iDrive, 0, 0);
  3036. return TRUE;
  3037. }
  3038. return FALSE;
  3039. case WM_NOTIFY:
  3040. {
  3041. LPNMHDR pnmh = (LPNMHDR) lParam;
  3042. switch (pnmh->code)
  3043. {
  3044. case PSN_SETACTIVE:
  3045. {
  3046. SetDlgItemText(hwnd, IDC_DISK, pthis->_szDrive);
  3047. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
  3048. }
  3049. return TRUE;
  3050. case PSN_WIZBACK:
  3051. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  3052. return TRUE;
  3053. case PSN_WIZNEXT:
  3054. {
  3055. CHAR szSource[MAX_PATH];
  3056. if (SUCCEEDED(GetSourceFilePath(szSource, ARRAYSIZE(szSource))))
  3057. {
  3058. // Double-null since we'll be passing this to SHFileOperation
  3059. CHAR szDest[] = "a:\\netsetup.exe\0";
  3060. szDest[0] = 'A' + pthis->_iDrive;
  3061. SHFILEOPSTRUCTA shfo = {0};
  3062. shfo.wFunc = FO_COPY;
  3063. shfo.pFrom = szSource;
  3064. shfo.pTo = szDest;
  3065. shfo.fFlags = FOF_SIMPLEPROGRESS | FOF_NOCONFIRMATION;
  3066. CHAR szTitle[256];
  3067. LoadStringA(g_hinst, IDS_COPYING, szTitle, ARRAYSIZE(szTitle));
  3068. shfo.lpszProgressTitle = szTitle;
  3069. int i = SHFileOperationA(&shfo);
  3070. if (i || shfo.fAnyOperationsAborted)
  3071. {
  3072. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, -1);
  3073. }
  3074. else
  3075. {
  3076. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_FLOPPYINST);
  3077. }
  3078. }
  3079. }
  3080. return TRUE;
  3081. }
  3082. }
  3083. return FALSE;
  3084. }
  3085. return FALSE;
  3086. }
  3087. INT_PTR CHomeNetworkWizard::InstructionsPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3088. {
  3089. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  3090. switch (uMsg)
  3091. {
  3092. case WM_INITDIALOG:
  3093. ASSERT(g_fRunningOnNT);
  3094. return TRUE;
  3095. case WM_NOTIFY:
  3096. {
  3097. LPNMHDR pnmh = (LPNMHDR) lParam;
  3098. switch (pnmh->code)
  3099. {
  3100. case PSN_SETACTIVE:
  3101. {
  3102. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
  3103. // If we aren't going to need to reboot
  3104. if (!pthis->_hnetInfo.fRebootRequired)
  3105. {
  3106. // Then we don't want to tell the user to reboot in the text
  3107. UINT idNoReboot = IDS_CD_NOREBOOT;
  3108. if (pthis->_fFloppyInstructions)
  3109. {
  3110. // We're on the floppy instructions page
  3111. idNoReboot = IDS_FLOPPY_NOREBOOT;
  3112. }
  3113. WCHAR szLine[256];
  3114. LoadString(g_hinst, idNoReboot, szLine, ARRAYSIZE(szLine));
  3115. SetDlgItemText(hwnd, IDC_INSTRUCTIONS, szLine);
  3116. }
  3117. }
  3118. return TRUE;
  3119. case PSN_WIZBACK:
  3120. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  3121. return TRUE;
  3122. case PSN_WIZNEXT:
  3123. pthis->PushPage(pthis->_fFloppyInstructions ? IDD_WIZ_FLOPPYINST : IDD_WIZ_CDINST);
  3124. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_FINISH);
  3125. return TRUE;
  3126. }
  3127. }
  3128. return FALSE;
  3129. }
  3130. return FALSE;
  3131. }
  3132. void _AddLineToBuffer(LPCWSTR pszLine, LPWSTR pszBuffer, DWORD cchBuffer, DWORD* piChar)
  3133. {
  3134. lstrcpyn(pszBuffer + (*piChar), pszLine, cchBuffer - (*piChar));
  3135. *piChar += lstrlen(pszLine);
  3136. lstrcpyn(pszBuffer + (*piChar), L"\r\n", cchBuffer - (*piChar));
  3137. *piChar += 2;
  3138. }
  3139. void CHomeNetworkWizard::SummarySetActive(HWND hwnd)
  3140. {
  3141. WCHAR szText[2048];
  3142. WCHAR szLine[256];
  3143. DWORD iChar = 0;
  3144. // Fill the list with some information based on what things we're going to do to
  3145. // configure their home network.
  3146. if (_hnetInfo.pncExternal)
  3147. {
  3148. // "Internet connection settings:"
  3149. LoadString(g_hinst, IDS_SUMMARY_INETSETTINGS, szLine, ARRAYSIZE(szLine));
  3150. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3151. NETCON_PROPERTIES* pncprops;
  3152. HRESULT hr = _hnetInfo.pncExternal->GetProperties(&pncprops);
  3153. if (SUCCEEDED(hr))
  3154. {
  3155. // Internet connection:\t%1
  3156. if (FormatMessageString(IDS_SUMMARY_INETCON, szLine, ARRAYSIZE(szLine), pncprops->pszwName))
  3157. {
  3158. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3159. }
  3160. // Internet connection sharing:\tenabled
  3161. if (_hnetInfo.dwFlags & HNET_SHARECONNECTION)
  3162. {
  3163. LoadString(g_hinst, IDS_SUMMARY_ICSENABLED, szLine, ARRAYSIZE(szLine));
  3164. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3165. }
  3166. // Personal firewall:\tenabled
  3167. if (_hnetInfo.dwFlags & HNET_FIREWALLCONNECTION)
  3168. {
  3169. LoadString(g_hinst, IDS_SUMMARY_FIREWALLENABLED, szLine, ARRAYSIZE(szLine));
  3170. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3171. }
  3172. NcFreeNetconProperties(pncprops);
  3173. }
  3174. LoadString(g_hinst, IDS_SUMMARY_UNDERLINE, szLine, ARRAYSIZE(szLine));
  3175. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3176. }
  3177. else
  3178. {
  3179. if (_fICSClient)
  3180. {
  3181. // "Internet connection settings:"
  3182. LoadString(g_hinst, IDS_SUMMARY_INETSETTINGS, szLine, ARRAYSIZE(szLine));
  3183. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3184. if (*_szICSMachineName)
  3185. {
  3186. // Connecting via ICS through:\t%1
  3187. if (FormatMessageString(IDS_sUMMARY_CONNECTTHROUGH, szLine, ARRAYSIZE(szLine), _szICSMachineName))
  3188. {
  3189. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3190. }
  3191. }
  3192. else
  3193. {
  3194. // Connecting through another device or computer.
  3195. LoadString(g_hinst, IDS_SUMMARY_CONNECTTHROUGH2, szLine, ARRAYSIZE(szLine));
  3196. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3197. }
  3198. LoadString(g_hinst, IDS_SUMMARY_UNDERLINE, szLine, ARRAYSIZE(szLine));
  3199. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3200. }
  3201. else
  3202. {
  3203. // Not connecting to the Internet - display nothing
  3204. }
  3205. }
  3206. // Home network settings:
  3207. LoadString(g_hinst, IDS_SUMMARY_HNETSETTINGS, szLine, ARRAYSIZE(szLine));
  3208. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3209. if (_hnetInfo.dwFlags & HNET_SETCOMPUTERNAME)
  3210. {
  3211. // Computer description:\t%1
  3212. if (FormatMessageString(IDS_SUMMARY_COMPDESC, szLine, ARRAYSIZE(szLine), _hnetInfo.szComputerDescription))
  3213. {
  3214. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3215. }
  3216. // Computer name:\t%1
  3217. if (FormatMessageString(IDS_SUMMARY_COMPNAME, szLine, ARRAYSIZE(szLine), _hnetInfo.szComputer))
  3218. {
  3219. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3220. }
  3221. }
  3222. if (_hnetInfo.dwFlags & HNET_SETWORKGROUPNAME)
  3223. {
  3224. // Workgroup name:\t%1
  3225. if (FormatMessageString(IDS_SUMMARY_WORKGROUP, szLine, ARRAYSIZE(szLine), _hnetInfo.szWorkgroup))
  3226. {
  3227. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3228. }
  3229. }
  3230. // The Shared Documents folder and any printers connected to this computer have been shared.
  3231. _AddLineToBuffer(L"", szText, ARRAYSIZE(szText), &iChar);
  3232. LoadString(g_hinst, IDS_SUMMARY_SHARING, szLine, ARRAYSIZE(szLine));
  3233. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3234. LoadString(g_hinst, IDS_SUMMARY_UNDERLINE, szLine, ARRAYSIZE(szLine));
  3235. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3236. if ((_hnetInfo.prgncInternal) && (_hnetInfo.cncInternal))
  3237. {
  3238. if (_hnetInfo.cncInternal > 1)
  3239. {
  3240. // Bridged connections:\r\n
  3241. LoadString(g_hinst, IDS_SUMMARY_BRIDGESETTINGS, szLine, ARRAYSIZE(szLine));
  3242. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3243. // Now list the connections...
  3244. for (DWORD i = 0; i < _hnetInfo.cncInternal; i++)
  3245. {
  3246. NETCON_PROPERTIES* pncprops;
  3247. HRESULT hr = _hnetInfo.prgncInternal[i]->GetProperties(&pncprops);
  3248. if (SUCCEEDED(hr))
  3249. {
  3250. _AddLineToBuffer(pncprops->pszwName, szText, ARRAYSIZE(szText), &iChar);
  3251. NcFreeNetconProperties(pncprops);
  3252. }
  3253. }
  3254. }
  3255. else // Single internal connection case
  3256. {
  3257. // Home network connection:\t%1
  3258. NETCON_PROPERTIES* pncprops;
  3259. HRESULT hr = _hnetInfo.prgncInternal[0]->GetProperties(&pncprops);
  3260. if (SUCCEEDED(hr))
  3261. {
  3262. if (FormatMessageString(IDS_SUMMARY_HOMENETCON, szLine, ARRAYSIZE(szLine), pncprops->pszwName))
  3263. {
  3264. _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
  3265. }
  3266. NcFreeNetconProperties(pncprops);
  3267. }
  3268. }
  3269. }
  3270. ASSERT(iChar < ARRAYSIZE(szText));
  3271. UINT iTabDistance = 150;
  3272. SendDlgItemMessage(hwnd, IDC_CHANGELIST, EM_SETTABSTOPS, (WPARAM) 1, (LPARAM) &iTabDistance);
  3273. SetDlgItemText(hwnd, IDC_CHANGELIST, szText);
  3274. }
  3275. INT_PTR CHomeNetworkWizard::FinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3276. {
  3277. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  3278. switch (uMsg)
  3279. {
  3280. case WM_INITDIALOG:
  3281. {
  3282. pthis->WelcomeSetTitleFont(hwnd);
  3283. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_SHARING);
  3284. pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC2), IDC_HELPLINK2, IDS_HELP_SHAREDDOCS);
  3285. return TRUE;
  3286. }
  3287. case WM_NOTIFY:
  3288. {
  3289. LPNMHDR pnmh = (LPNMHDR) lParam;
  3290. switch (pnmh->code)
  3291. {
  3292. case PSN_SETACTIVE:
  3293. PropSheet_CancelToClose(GetParent(hwnd));
  3294. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_FINISH);
  3295. return TRUE;
  3296. case PSN_WIZBACK:
  3297. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  3298. return TRUE;
  3299. case PSN_WIZFINISH:
  3300. return TRUE;
  3301. case NM_CLICK:
  3302. case NM_RETURN:
  3303. switch ((int) wParam)
  3304. {
  3305. case IDC_HELPLINK:
  3306. // help on sharing
  3307. {
  3308. if (IsOS(OS_PERSONAL))
  3309. {
  3310. HelpCenter(hwnd, L"filefold.chm%3A%3A/sharing_files_overviewP.htm");
  3311. }
  3312. else
  3313. {
  3314. HelpCenter(hwnd, L"filefold.chm%3A%3A/sharing_files_overviewW.htm");
  3315. }
  3316. }
  3317. return TRUE;
  3318. case IDC_HELPLINK2:
  3319. // help on Shared Documents
  3320. {
  3321. HelpCenter(hwnd, L"filefold.chm%3A%3A/windows_shared_documents.htm");
  3322. }
  3323. return TRUE;
  3324. }
  3325. }
  3326. }
  3327. return FALSE;
  3328. }
  3329. return FALSE;
  3330. }
  3331. INT_PTR CHomeNetworkWizard::ErrorFinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3332. {
  3333. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  3334. switch (uMsg)
  3335. {
  3336. case WM_INITDIALOG:
  3337. pthis->WelcomeSetTitleFont(hwnd);
  3338. return TRUE;
  3339. case WM_NOTIFY:
  3340. {
  3341. LPNMHDR pnmh = (LPNMHDR) lParam;
  3342. switch (pnmh->code)
  3343. {
  3344. case PSN_SETACTIVE:
  3345. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_FINISH);
  3346. return TRUE;
  3347. case PSN_WIZBACK:
  3348. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  3349. return TRUE;
  3350. case PSN_WIZFINISH:
  3351. return TRUE;
  3352. }
  3353. }
  3354. return FALSE;
  3355. }
  3356. return FALSE;
  3357. }
  3358. INT_PTR CHomeNetworkWizard::NoHardwareFinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3359. {
  3360. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  3361. switch (uMsg)
  3362. {
  3363. case WM_INITDIALOG:
  3364. {
  3365. pthis->WelcomeSetTitleFont(hwnd);
  3366. return TRUE;
  3367. }
  3368. case WM_NOTIFY:
  3369. {
  3370. LPNMHDR pnmh = (LPNMHDR) lParam;
  3371. switch (pnmh->code)
  3372. {
  3373. case PSN_SETACTIVE:
  3374. PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK);
  3375. return TRUE;
  3376. case PSN_WIZBACK:
  3377. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage());
  3378. return TRUE;
  3379. case PSN_WIZFINISH:
  3380. return TRUE;
  3381. }
  3382. }
  3383. return FALSE;
  3384. }
  3385. return FALSE;
  3386. }
  3387. INT_PTR CHomeNetworkWizard::CantRunWizardPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3388. {
  3389. CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
  3390. switch (uMsg)
  3391. {
  3392. case WM_INITDIALOG:
  3393. pthis->WelcomeSetTitleFont(hwnd);
  3394. return TRUE;
  3395. case WM_NOTIFY:
  3396. {
  3397. LPNMHDR pnmh = (LPNMHDR) lParam;
  3398. switch (pnmh->code)
  3399. {
  3400. case PSN_SETACTIVE:
  3401. PropSheet_SetWizButtons(pnmh->hwndFrom, 0);
  3402. return TRUE;
  3403. }
  3404. }
  3405. return FALSE;
  3406. }
  3407. return FALSE;
  3408. }
  3409. HRESULT GetConnections(HDPA* phdpa)
  3410. {
  3411. HRESULT hr = S_OK;
  3412. *phdpa = DPA_Create(5);
  3413. if (*phdpa)
  3414. {
  3415. // Initialize the net connection enumeration
  3416. INetConnectionManager* pmgr;
  3417. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  3418. IID_PPV_ARG(INetConnectionManager, &pmgr));
  3419. if (SUCCEEDED(hr))
  3420. {
  3421. hr = SetProxyBlanket(pmgr);
  3422. if (SUCCEEDED(hr))
  3423. {
  3424. IEnumNetConnection* penum;
  3425. hr = pmgr->EnumConnections(NCME_DEFAULT, &penum);
  3426. if (SUCCEEDED(hr))
  3427. {
  3428. hr = SetProxyBlanket(penum);
  3429. if (SUCCEEDED(hr))
  3430. {
  3431. // Fill in our DPA will the connections
  3432. hr = penum->Reset();
  3433. while (S_OK == hr)
  3434. {
  3435. INetConnection* pnc;
  3436. ULONG ulISuck;
  3437. hr = penum->Next(1, &pnc, &ulISuck);
  3438. if (S_OK == hr)
  3439. {
  3440. hr = SetProxyBlanket(pnc);
  3441. if (SUCCEEDED(hr))
  3442. {
  3443. if (-1 != DPA_AppendPtr(*phdpa, pnc))
  3444. {
  3445. pnc->AddRef();
  3446. }
  3447. else
  3448. {
  3449. hr = E_OUTOFMEMORY;
  3450. }
  3451. }
  3452. pnc->Release();
  3453. }
  3454. }
  3455. }
  3456. penum->Release();
  3457. }
  3458. }
  3459. pmgr->Release();
  3460. }
  3461. if (FAILED(hr))
  3462. {
  3463. DPA_DestroyCallback(*phdpa, FreeConnectionDPACallback, NULL);
  3464. *phdpa = NULL;
  3465. }
  3466. }
  3467. else
  3468. {
  3469. hr = E_OUTOFMEMORY;
  3470. }
  3471. return hr;
  3472. }
  3473. CHomeNetworkWizard* CHomeNetworkWizard::GetThis(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3474. {
  3475. CHomeNetworkWizard* pthis = NULL;
  3476. if (uMsg == WM_INITDIALOG)
  3477. {
  3478. PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lParam;
  3479. pthis = (CHomeNetworkWizard*) psp->lParam;
  3480. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pthis);
  3481. }
  3482. else
  3483. {
  3484. pthis = (CHomeNetworkWizard*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
  3485. }
  3486. return pthis;
  3487. }
  3488. // Utility functions
  3489. HRESULT GetConnectionsFolder(IShellFolder** ppsfConnections)
  3490. {
  3491. LPITEMIDLIST pidlFolder;
  3492. HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_CONNECTIONS, &pidlFolder);
  3493. if (SUCCEEDED(hr))
  3494. {
  3495. IShellFolder* pshDesktop;
  3496. hr = SHGetDesktopFolder(&pshDesktop);
  3497. if (SUCCEEDED(hr))
  3498. {
  3499. hr = pshDesktop->BindToObject(pidlFolder, NULL, IID_PPV_ARG(IShellFolder, ppsfConnections));
  3500. #if 0
  3501. /*
  3502. We need to do an IEnumIDList::Reset to set up internal data structures so that ::ParseDisplayName
  3503. works later. Remove this once DaveA's stuff gets in the desktop build. TODO
  3504. */
  3505. if (SUCCEEDED(hr))
  3506. {
  3507. IEnumIDList* penum;
  3508. hr = (*ppsfConnections)->EnumObjects(NULL, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &penum);
  3509. if (SUCCEEDED(hr))
  3510. {
  3511. penum->Reset();
  3512. penum->Release();
  3513. }
  3514. }
  3515. #endif
  3516. pshDesktop->Release();
  3517. }
  3518. ILFree(pidlFolder);
  3519. }
  3520. return hr;
  3521. }
  3522. void W9xGetNetTypeName(BYTE bNicType, WCHAR* pszBuff, UINT cchBuff)
  3523. {
  3524. COMPILETIME_ASSERT(IDS_NETTYPE_START == IDS_NETTYPE_LAN);
  3525. COMPILETIME_ASSERT(IDS_NETTYPE_LAN - IDS_NETTYPE_START == NETTYPE_LAN);
  3526. COMPILETIME_ASSERT(IDS_NETTYPE_DIALUP - IDS_NETTYPE_START == NETTYPE_DIALUP);
  3527. COMPILETIME_ASSERT(IDS_NETTYPE_IRDA - IDS_NETTYPE_START == NETTYPE_IRDA);
  3528. COMPILETIME_ASSERT(IDS_NETTYPE_PPTP - IDS_NETTYPE_START == NETTYPE_PPTP);
  3529. COMPILETIME_ASSERT(IDS_NETTYPE_TV - IDS_NETTYPE_START == NETTYPE_TV);
  3530. COMPILETIME_ASSERT(IDS_NETTYPE_ISDN - IDS_NETTYPE_START == NETTYPE_ISDN);
  3531. COMPILETIME_ASSERT(IDS_NETTYPE_LAN - IDS_NETTYPE_START == NETTYPE_LAN);
  3532. if (bNicType >= NETTYPE_LAN && bNicType <= NETTYPE_ISDN)
  3533. {
  3534. LoadString(g_hinst, IDS_NETTYPE_START + bNicType, pszBuff, cchBuff);
  3535. }
  3536. else
  3537. {
  3538. LoadString(g_hinst, IDS_NETTYPE_UNKNOWN, pszBuff, cchBuff);
  3539. }
  3540. return;
  3541. }
  3542. BOOL W9xIsValidAdapter(const NETADAPTER* pNA, DWORD dwFlags)
  3543. {
  3544. BOOL fRet = FALSE;
  3545. if (dwFlags & CONN_EXTERNAL)
  3546. {
  3547. fRet = (pNA->bError == NICERR_NONE &&
  3548. pNA->bNetType == NETTYPE_LAN &&
  3549. pNA->bNetSubType != SUBTYPE_ICS &&
  3550. pNA->bNetSubType != SUBTYPE_AOL &&
  3551. pNA->bNicType != NIC_1394 );
  3552. }
  3553. else if (dwFlags & CONN_INTERNAL)
  3554. {
  3555. fRet = (pNA->bError == NICERR_NONE &&
  3556. pNA->bNetType == NETTYPE_LAN &&
  3557. pNA->bNetSubType != SUBTYPE_ICS &&
  3558. pNA->bNetSubType != SUBTYPE_AOL );
  3559. }
  3560. /* else if ( dwFlags & CONN_UNPLUGGED )
  3561. {
  3562. if ( IsOS(OS_MILLENNIUM) )
  3563. {
  3564. fRet = IsAdapterDisconnected( (void*)pNA );
  3565. }
  3566. }
  3567. */
  3568. return fRet;
  3569. }
  3570. BOOL W9xIsAdapterDialUp(const NETADAPTER* pAdapter)
  3571. {
  3572. return (pAdapter->bNetType == NETTYPE_DIALUP && pAdapter->bNetSubType == SUBTYPE_NONE);
  3573. }
  3574. HRESULT CHomeNetworkWizard::GetConnectionIconIndex(GUID& guidConnection, IShellFolder* psfConnections, int* pIndex)
  3575. {
  3576. *pIndex = -1;
  3577. OLECHAR szGUID[40];
  3578. HRESULT hr = E_FAIL;
  3579. if (StringFromGUID2(guidConnection, szGUID, ARRAYSIZE(szGUID)))
  3580. {
  3581. LPITEMIDLIST pidlConn = NULL;
  3582. ULONG cchEaten = 0;
  3583. hr = psfConnections->ParseDisplayName(NULL, NULL, szGUID, &cchEaten, &pidlConn, NULL);
  3584. if (SUCCEEDED(hr))
  3585. {
  3586. IExtractIconW *pExtractIconW;
  3587. LPCITEMIDLIST pcidl = pidlConn;
  3588. hr = psfConnections->GetUIObjectOf(NULL, 1, &pcidl, IID_IExtractIconW, 0, (LPVOID *)(&pExtractIconW));
  3589. if (SUCCEEDED(hr))
  3590. {
  3591. WCHAR szIconLocation[MAX_PATH];
  3592. INT iIndex;
  3593. UINT wFlags;
  3594. hr = pExtractIconW->GetIconLocation(GIL_FORSHELL, szIconLocation, MAX_PATH, &iIndex, &wFlags);
  3595. if (SUCCEEDED(hr))
  3596. {
  3597. HICON hIconLarge;
  3598. HICON hIconSmall;
  3599. hr = pExtractIconW->Extract(szIconLocation, iIndex, &hIconLarge, &hIconSmall, 0x00100010);
  3600. if (SUCCEEDED(hr))
  3601. {
  3602. *pIndex = ImageList_AddIcon(_himlSmall, hIconSmall);
  3603. }
  3604. DestroyIcon(hIconLarge);
  3605. DestroyIcon(hIconSmall);
  3606. }
  3607. }
  3608. if(pExtractIconW != NULL)
  3609. pExtractIconW->Release();
  3610. ILFree(pidlConn);
  3611. }
  3612. }
  3613. return hr;
  3614. }
  3615. HRESULT GetDriveNameAndIconIndex(LPWSTR pszDrive, LPWSTR pszDisplayName, DWORD cchDisplayName, int* pIndex)
  3616. {
  3617. SHFILEINFO fi = {0};
  3618. if (SHGetFileInfoW_NT(pszDrive, 0, &fi, sizeof (fi), SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX))
  3619. {
  3620. *pIndex = fi.iIcon;
  3621. lstrcpyn(pszDisplayName, fi.szDisplayName, cchDisplayName);
  3622. return S_OK;
  3623. }
  3624. return E_FAIL;
  3625. }
  3626. BOOL IsEqualConnection(INetConnection* pnc1, INetConnection* pnc2)
  3627. {
  3628. BOOL fEqual = FALSE;
  3629. if ((pnc1) && (pnc2))
  3630. {
  3631. NETCON_PROPERTIES *pprops1, *pprops2;
  3632. if (SUCCEEDED(pnc1->GetProperties(&pprops1)))
  3633. {
  3634. if (SUCCEEDED(pnc2->GetProperties(&pprops2)))
  3635. {
  3636. fEqual = (pprops1->guidId == pprops2->guidId);
  3637. NcFreeNetconProperties(pprops2);
  3638. }
  3639. NcFreeNetconProperties(pprops1);
  3640. }
  3641. }
  3642. return fEqual;
  3643. }
  3644. HRESULT ShareAllPrinters()
  3645. {
  3646. PRINTER_ENUM* pPrinters;
  3647. int nPrinters = MyEnumLocalPrinters(&pPrinters);
  3648. if (nPrinters)
  3649. {
  3650. int iPrinterNumber = 1;
  3651. for (int iPrinter = 0; iPrinter < nPrinters; iPrinter ++)
  3652. {
  3653. TCHAR szShare[NNLEN + 1];
  3654. do
  3655. {
  3656. FormatMessageString(IDS_PRINTER, szShare, ARRAYSIZE(szShare), iPrinterNumber);
  3657. if (1 == iPrinterNumber)
  3658. {
  3659. szShare[lstrlen(szShare) - 1] = 0;
  3660. // Remove the "1" from the end since this is the first printer
  3661. // ie: "Printer1" --> "Printer"
  3662. }
  3663. if (!g_fRunningOnNT)
  3664. {
  3665. CharUpper(szShare);
  3666. }
  3667. iPrinterNumber ++;
  3668. } while (IsShareNameInUse(szShare));
  3669. if (SharePrinter(pPrinters[iPrinter].pszPrinterName, szShare, NULL))
  3670. {
  3671. g_logFile.Write("Shared Printer: ");
  3672. }
  3673. else
  3674. {
  3675. g_logFile.Write("Failed to share Printer: ");
  3676. }
  3677. g_logFile.Write(pPrinters[iPrinter].pszPrinterName);
  3678. g_logFile.Write("\r\n");
  3679. }
  3680. free(pPrinters);
  3681. }
  3682. return S_OK;
  3683. }
  3684. BOOL AllPlatformGetComputerName(LPWSTR pszName, DWORD cchName)
  3685. {
  3686. if (g_fRunningOnNT)
  3687. {
  3688. return GetComputerNameExW_NT(ComputerNamePhysicalNetBIOS, pszName, &cchName);
  3689. }
  3690. else
  3691. {
  3692. return GetComputerName(pszName, &cchName);
  3693. }
  3694. }
  3695. BOOL _IsTCPIPAvailable(void)
  3696. {
  3697. BOOL fTCPIPAvailable = FALSE;
  3698. HKEY hk;
  3699. DWORD dwSize;
  3700. // we check to see if the TCP/IP stack is installed and which object it is
  3701. // bound to, this is a string, we don't check the value only that the
  3702. // length is non-zero.
  3703. if ( ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  3704. TEXT("System\\CurrentControlSet\\Services\\Tcpip\\Linkage"),
  3705. 0x0,
  3706. KEY_QUERY_VALUE, &hk) )
  3707. {
  3708. if ( ERROR_SUCCESS == RegQueryValueEx(hk, TEXT("Export"), 0x0, NULL, NULL, &dwSize) )
  3709. {
  3710. if ( dwSize > 2 )
  3711. {
  3712. fTCPIPAvailable = TRUE;
  3713. }
  3714. }
  3715. RegCloseKey(hk);
  3716. }
  3717. return (fTCPIPAvailable);
  3718. }
  3719. BOOL AllPlatformSetComputerName(LPCWSTR pszComputerName)
  3720. {
  3721. // NetBIOS computer name is set even on NT for completeness
  3722. BOOL fSuccess;
  3723. if (g_fRunningOnNT)
  3724. {
  3725. if (_IsTCPIPAvailable())
  3726. {
  3727. fSuccess = SetComputerNameExW_NT(ComputerNamePhysicalDnsHostname, pszComputerName);
  3728. }
  3729. else
  3730. {
  3731. fSuccess = SetComputerNameExW_NT(ComputerNamePhysicalNetBIOS, pszComputerName);
  3732. }
  3733. }
  3734. else
  3735. {
  3736. // Windows 9x
  3737. fSuccess = SetComputerName(pszComputerName);
  3738. }
  3739. return fSuccess;
  3740. }
  3741. BOOL SetComputerNameIfNecessary(LPCWSTR pszComputerName, BOOL* pfRebootRequired)
  3742. {
  3743. g_logFile.Write("Attempting to set computer name\r\n");
  3744. WCHAR szOldComputerName[LM20_CNLEN + 1];
  3745. AllPlatformGetComputerName(szOldComputerName, ARRAYSIZE(szOldComputerName));
  3746. if (0 != StrCmpIW(szOldComputerName, pszComputerName))
  3747. {
  3748. if (AllPlatformSetComputerName(pszComputerName))
  3749. {
  3750. g_logFile.Write("Computer name set successfully: ");
  3751. g_logFile.Write(pszComputerName);
  3752. g_logFile.Write("\r\n");
  3753. *pfRebootRequired = TRUE;
  3754. }
  3755. else
  3756. {
  3757. g_logFile.Write("Computer name set failed.\r\n");
  3758. return FALSE;
  3759. }
  3760. }
  3761. else
  3762. {
  3763. g_logFile.Write("Old computer name is the same as new computer name - not setting.\r\n");
  3764. }
  3765. return TRUE;
  3766. }
  3767. BOOL SetComputerDescription(LPCWSTR pszComputerDescription)
  3768. {
  3769. BOOL fRet;
  3770. if (g_fRunningOnNT)
  3771. {
  3772. g_logFile.Write("Setting server description (comment): ");
  3773. g_logFile.Write(pszComputerDescription);
  3774. g_logFile.Write("\r\n");
  3775. // Set comment (for now, NT only) win9x - TODO
  3776. SERVER_INFO_1005_NT sv1005;
  3777. sv1005.sv1005_comment = const_cast<LPWSTR>(pszComputerDescription);
  3778. fRet = (NERR_Success == NetServerSetInfo_NT(NULL, 1005, (LPBYTE) &sv1005, NULL));
  3779. }
  3780. else
  3781. {
  3782. CRegistry reg;
  3783. fRet = reg.OpenKey(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\VxD\\VNETSUP");
  3784. if (fRet)
  3785. {
  3786. fRet = reg.SetStringValue(L"Comment", pszComputerDescription);
  3787. }
  3788. }
  3789. return fRet;
  3790. }
  3791. HRESULT ShareWellKnownFolders(PHOMENETSETUPINFO pInfo)
  3792. {
  3793. if (!NetConn_IsSharedDocumentsShared())
  3794. {
  3795. NetConn_CreateSharedDocuments(NULL, g_hinst, NULL, 0);
  3796. if (NetConn_IsSharedDocumentsShared())
  3797. {
  3798. g_logFile.Write("'Shared Documents' shared.\r\n");
  3799. }
  3800. else
  3801. {
  3802. g_logFile.Write("Failed to share 'Shared Documents'\r\n");
  3803. return E_FAIL;
  3804. }
  3805. }
  3806. return S_OK;
  3807. }
  3808. HRESULT SetProxyBlanket(IUnknown * pUnk)
  3809. {
  3810. HRESULT hr;
  3811. hr = CoSetProxyBlanket (
  3812. pUnk,
  3813. RPC_C_AUTHN_WINNT, // use NT default security
  3814. RPC_C_AUTHZ_NONE, // use NT default authentication
  3815. NULL, // must be null if default
  3816. RPC_C_AUTHN_LEVEL_CALL, // call
  3817. RPC_C_IMP_LEVEL_IMPERSONATE,
  3818. NULL, // use process token
  3819. EOAC_NONE);
  3820. if(SUCCEEDED(hr))
  3821. {
  3822. IUnknown * pUnkSet = NULL;
  3823. hr = pUnk->QueryInterface(IID_PPV_ARG(IUnknown, &pUnkSet));
  3824. if(SUCCEEDED(hr))
  3825. {
  3826. hr = CoSetProxyBlanket (
  3827. pUnkSet,
  3828. RPC_C_AUTHN_WINNT, // use NT default security
  3829. RPC_C_AUTHZ_NONE, // use NT default authentication
  3830. NULL, // must be null if default
  3831. RPC_C_AUTHN_LEVEL_CALL, // call
  3832. RPC_C_IMP_LEVEL_IMPERSONATE,
  3833. NULL, // use process token
  3834. EOAC_NONE);
  3835. pUnkSet->Release();
  3836. }
  3837. }
  3838. return hr;
  3839. }
  3840. HRESULT WriteSetupInfoToRegistry(PHOMENETSETUPINFO pInfo)
  3841. {
  3842. HKEY hkey;
  3843. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szAppRegKey, 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL))
  3844. {
  3845. // Write information telling the home network wizard to run silently on next boot, and what to share
  3846. DWORD dwRun = 1;
  3847. RegSetValueEx(hkey, TEXT("RunWizardFromRegistry"), NULL, REG_DWORD, (CONST BYTE*) &dwRun, sizeof (dwRun));
  3848. RegCloseKey(hkey);
  3849. }
  3850. // Add a runonce entry for this wizard
  3851. TCHAR szProcess[MAX_PATH];
  3852. if (0 != GetModuleFileName(NULL, szProcess, ARRAYSIZE(szProcess)))
  3853. {
  3854. TCHAR szModule[MAX_PATH];
  3855. if (0 != GetModuleFileName(g_hinst, szModule, ARRAYSIZE(szModule)))
  3856. {
  3857. const TCHAR szRunDllFormat[] = TEXT("%s %s,HomeNetWizardRunDll");
  3858. TCHAR szRunDllLine[MAX_PATH];
  3859. if (0 < wnsprintf(szRunDllLine, ARRAYSIZE(szRunDllLine), szRunDllFormat, szProcess, szModule))
  3860. {
  3861. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_RUNONCE, 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL))
  3862. {
  3863. RegSetValueEx(hkey, TEXT("Network Setup Wizard"), 0, REG_SZ, (LPBYTE) szRunDllLine, ARRAYSIZE(szRunDllLine));
  3864. RegCloseKey(hkey);
  3865. }
  3866. }
  3867. }
  3868. }
  3869. return S_OK;
  3870. }
  3871. HRESULT DeleteSetupInfoFromRegistry()
  3872. {
  3873. RegDeleteKeyAndSubKeys(HKEY_LOCAL_MACHINE, c_szAppRegKey);
  3874. return S_OK;
  3875. }
  3876. HRESULT ReadSetupInfoFromRegistry(PHOMENETSETUPINFO pInfo)
  3877. {
  3878. BOOL fRunFromRegistry = FALSE;
  3879. HKEY hkey;
  3880. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szAppRegKey, 0, KEY_READ, &hkey))
  3881. {
  3882. DWORD dwType;
  3883. DWORD cbData = sizeof (fRunFromRegistry);
  3884. if (ERROR_SUCCESS != RegQueryValueEx(hkey, TEXT("RunWizardFromRegistry"), NULL, &dwType, (LPBYTE) &fRunFromRegistry, &cbData))
  3885. {
  3886. fRunFromRegistry = FALSE;
  3887. }
  3888. RegCloseKey(hkey);
  3889. }
  3890. // S_FALSE indicates we're not running silently from infromation in the registry.
  3891. return fRunFromRegistry ? S_OK : S_FALSE;
  3892. }
  3893. HRESULT MakeUniqueShareName(LPCTSTR pszBaseName, LPTSTR pszUniqueName, DWORD cchName)
  3894. {
  3895. if (!IsShareNameInUse(pszBaseName))
  3896. {
  3897. lstrcpyn(pszUniqueName, pszBaseName, cchName);
  3898. return S_OK;
  3899. }
  3900. else
  3901. {
  3902. int i = 2;
  3903. while (TRUE)
  3904. {
  3905. if (0 > wnsprintf(pszUniqueName, cchName, TEXT("%s%d"), pszBaseName, i))
  3906. {
  3907. return E_FAIL;
  3908. }
  3909. if (!IsShareNameInUse(pszUniqueName))
  3910. {
  3911. return S_OK;
  3912. }
  3913. }
  3914. }
  3915. }
  3916. // Pass NULL as TokenHandle to see if thread token is admin
  3917. HRESULT IsUserLocalAdmin(HANDLE TokenHandle, BOOL* pfIsAdmin)
  3918. {
  3919. if (g_fRunningOnNT)
  3920. {
  3921. // First we must check if the current user is a local administrator; if this is
  3922. // the case, our dialog doesn't even display
  3923. PSID psidAdminGroup = NULL;
  3924. SID_IDENTIFIER_AUTHORITY security_nt_authority = SECURITY_NT_AUTHORITY;
  3925. BOOL fSuccess = ::AllocateAndInitializeSid_NT(&security_nt_authority, 2,
  3926. SECURITY_BUILTIN_DOMAIN_RID,
  3927. DOMAIN_ALIAS_RID_ADMINS,
  3928. 0, 0, 0, 0, 0, 0,
  3929. &psidAdminGroup);
  3930. if (fSuccess)
  3931. {
  3932. // See if the user for this process is a local admin
  3933. fSuccess = CheckTokenMembership_NT(TokenHandle, psidAdminGroup, pfIsAdmin);
  3934. FreeSid_NT(psidAdminGroup);
  3935. }
  3936. return fSuccess ? S_OK:E_FAIL;
  3937. }
  3938. else
  3939. {
  3940. // Win9x - every user is an admin
  3941. *pfIsAdmin = TRUE;
  3942. return S_OK;
  3943. }
  3944. }
  3945. HRESULT GetConnectionByGUID(HDPA hdpaConnections, const GUID* pguid, INetConnection** ppnc)
  3946. {
  3947. *ppnc = NULL;
  3948. DWORD nItems = DPA_GetPtrCount(hdpaConnections);
  3949. HRESULT hr = E_FAIL;
  3950. if (nItems)
  3951. {
  3952. DWORD iItem = 0;
  3953. while (iItem < nItems)
  3954. {
  3955. INetConnection* pnc = (INetConnection*) DPA_GetPtr(hdpaConnections, iItem);
  3956. if (pnc)
  3957. {
  3958. GUID guidMatch;
  3959. hr = GetConnectionGUID(pnc, &guidMatch);
  3960. if (SUCCEEDED(hr))
  3961. {
  3962. if (*pguid == guidMatch)
  3963. {
  3964. *ppnc = pnc;
  3965. (*ppnc)->AddRef();
  3966. break;
  3967. }
  3968. }
  3969. // Don't pnc->Release() - its coming from the DPA
  3970. }
  3971. iItem ++;
  3972. }
  3973. if (iItem == nItems)
  3974. {
  3975. // We searched and didn't find
  3976. hr = E_FAIL;
  3977. }
  3978. }
  3979. return hr;
  3980. }
  3981. HRESULT GUIDsToConnections(PHOMENETSETUPINFO pInfo)
  3982. {
  3983. ASSERT(NULL == pInfo->prgncInternal);
  3984. ASSERT(NULL == pInfo->pncExternal);
  3985. HDPA hdpaConnections;
  3986. HRESULT hr = GetConnections(&hdpaConnections);
  3987. if (SUCCEEDED(hr))
  3988. {
  3989. // Get internal connections by GUID (allocate an extra one for null-terminated array, as elsewhere)
  3990. pInfo->prgncInternal = (INetConnection**) LocalAlloc(LPTR, (pInfo->cguidInternal + 1) * sizeof (INetConnection*));
  3991. if (pInfo->prgncInternal)
  3992. {
  3993. DWORD iConnection = 0;
  3994. while ((iConnection < pInfo->cguidInternal) && SUCCEEDED(hr))
  3995. {
  3996. hr = GetConnectionByGUID(hdpaConnections, pInfo->prgguidInternal + iConnection, pInfo->prgncInternal + iConnection);
  3997. iConnection++;
  3998. }
  3999. pInfo->cncInternal = iConnection;
  4000. }
  4001. else
  4002. {
  4003. hr = E_OUTOFMEMORY;
  4004. }
  4005. if (SUCCEEDED(hr) && (GUID_NULL != pInfo->guidExternal))
  4006. {
  4007. // Get external connection
  4008. hr = GetConnectionByGUID(hdpaConnections, &(pInfo->guidExternal), &(pInfo->pncExternal));
  4009. }
  4010. DPA_DestroyCallback(hdpaConnections, FreeConnectionDPACallback, NULL);
  4011. hdpaConnections = NULL;
  4012. }
  4013. if (FAILED(hr))
  4014. {
  4015. FreeExternalConnection(pInfo);
  4016. FreeInternalConnections(pInfo);
  4017. }
  4018. pInfo->guidExternal = GUID_NULL;
  4019. FreeInternalGUIDs(pInfo);
  4020. return hr;
  4021. }
  4022. HRESULT GetConnectionGUID(INetConnection* pnc, GUID* pguid)
  4023. {
  4024. NETCON_PROPERTIES* pncprops;
  4025. HRESULT hr = pnc->GetProperties(&pncprops);
  4026. if (SUCCEEDED(hr))
  4027. {
  4028. *pguid = pncprops->guidId;
  4029. NcFreeNetconProperties(pncprops);
  4030. }
  4031. return hr;
  4032. }
  4033. HRESULT ConnectionsToGUIDs(PHOMENETSETUPINFO pInfo)
  4034. {
  4035. HRESULT hr = S_OK;
  4036. ASSERT(NULL == pInfo->prgguidInternal);
  4037. ASSERT(GUID_NULL == pInfo->guidExternal);
  4038. // Allocate the private connection guid array
  4039. if (pInfo->cncInternal)
  4040. {
  4041. pInfo->prgguidInternal = (GUID*) LocalAlloc(LPTR, pInfo->cncInternal * sizeof (GUID));
  4042. if (pInfo->prgguidInternal)
  4043. {
  4044. // Get each connection's GUID and fill in the array
  4045. DWORD i = 0;
  4046. while ((i < pInfo->cncInternal) && (SUCCEEDED(hr)))
  4047. {
  4048. hr = GetConnectionGUID(pInfo->prgncInternal[i], &(pInfo->prgguidInternal[i]));
  4049. i++;
  4050. }
  4051. pInfo->cguidInternal = i;
  4052. }
  4053. else
  4054. {
  4055. hr = E_OUTOFMEMORY;
  4056. }
  4057. }
  4058. if (SUCCEEDED(hr))
  4059. {
  4060. if (pInfo->pncExternal)
  4061. {
  4062. hr = GetConnectionGUID(pInfo->pncExternal, &(pInfo->guidExternal));
  4063. }
  4064. }
  4065. if (FAILED(hr) && pInfo->prgguidInternal)
  4066. {
  4067. FreeInternalGUIDs(pInfo);
  4068. pInfo->guidExternal = GUID_NULL;
  4069. }
  4070. FreeExternalConnection(pInfo);
  4071. FreeInternalConnections(pInfo);
  4072. return hr;
  4073. }
  4074. HRESULT ConfigureHomeNetwork(PHOMENETSETUPINFO pInfo)
  4075. {
  4076. HRESULT hr = E_FAIL;
  4077. if (pInfo->fAsync)
  4078. {
  4079. if (g_fRunningOnNT)
  4080. {
  4081. // Bundle up NT specific data for cross-thread
  4082. hr = ConnectionsToGUIDs(pInfo);
  4083. }
  4084. else
  4085. {
  4086. // TODO: Anything necessary on win9x
  4087. hr = S_OK;
  4088. }
  4089. if (SUCCEEDED(hr))
  4090. {
  4091. if (SHCreateThread(ConfigureHomeNetworkThread, pInfo, CTF_COINIT, NULL))
  4092. {
  4093. hr = S_FALSE;
  4094. }
  4095. else
  4096. {
  4097. hr = E_FAIL;
  4098. }
  4099. }
  4100. }
  4101. else
  4102. {
  4103. hr = ConfigureHomeNetworkSynchronous(pInfo);
  4104. }
  4105. return hr;
  4106. }
  4107. DWORD WINAPI ConfigureHomeNetworkThread(void* pvData)
  4108. {
  4109. PHOMENETSETUPINFO pInfo = (PHOMENETSETUPINFO) pvData;
  4110. // Before creating this thread, the caller MUST have freed his INetConnection*'s or
  4111. // else the thread might touch/free them, which it must not do. Assert this.
  4112. ASSERT(NULL == pInfo->pncExternal);
  4113. ASSERT(NULL == pInfo->prgncInternal);
  4114. HRESULT hr;
  4115. if (g_fRunningOnNT)
  4116. {
  4117. // Unbundle data after crossing the thread boundary
  4118. hr = GUIDsToConnections(pInfo);
  4119. }
  4120. else
  4121. {
  4122. // TODO: Anything necessary for Win9x
  4123. hr = S_OK;
  4124. }
  4125. if (SUCCEEDED(hr))
  4126. {
  4127. hr = ConfigureHomeNetworkSynchronous(pInfo);
  4128. FreeExternalConnection(pInfo);
  4129. FreeInternalConnections(pInfo);
  4130. if ((pInfo->hwnd) && (pInfo->umsgAsyncNotify))
  4131. {
  4132. // The HRESULT from the configuration is passed in WPARAM
  4133. PostMessage(pInfo->hwnd, pInfo->umsgAsyncNotify, (WPARAM) hr, 0);
  4134. }
  4135. }
  4136. return 0;
  4137. }
  4138. HRESULT ConfigureHomeNetworkSynchronous(PHOMENETSETUPINFO pInfo)
  4139. {
  4140. g_logFile.Initialize("%systemroot%\\nsw.log");
  4141. HRESULT hr = S_OK;
  4142. #ifdef NO_CONFIG
  4143. g_logFile.Write("UI Test only - no configuration\r\n");
  4144. g_logFile.Uninitialize();
  4145. Sleep(2000);
  4146. #ifdef FAKE_REBOOTREQUIRED
  4147. pInfo->fRebootRequired = TRUE;
  4148. #endif
  4149. return S_OK;
  4150. #endif
  4151. BOOL fInstallSharing = TRUE;
  4152. BOOL fSharingAlreadyInstalled = IsSharingInstalled(TRUE);
  4153. BOOL fInstalledWorkgroup = FALSE;
  4154. // We don't need to install sharing unless we're sharing something
  4155. if (!(pInfo->dwFlags & (HNET_SHAREFOLDERS | HNET_SHAREPRINTERS)))
  4156. {
  4157. g_logFile.Write("No file or printer sharing requested\r\n");
  4158. fInstallSharing = FALSE;
  4159. }
  4160. // Worker function for the whole wizard
  4161. // Computer name
  4162. if ((pInfo->dwFlags & HNET_SETCOMPUTERNAME) && (*(pInfo->szComputer)))
  4163. {
  4164. SetComputerNameIfNecessary(pInfo->szComputer, &(pInfo->fRebootRequired));
  4165. SetComputerDescription(pInfo->szComputerDescription);
  4166. }
  4167. // Workgroup name
  4168. if ((pInfo->dwFlags & HNET_SETWORKGROUPNAME) && (*(pInfo->szWorkgroup)))
  4169. {
  4170. Install_SetWorkgroupName(pInfo->szWorkgroup, &(pInfo->fRebootRequired));
  4171. fInstalledWorkgroup = TRUE;
  4172. }
  4173. // Install TCP/IP
  4174. hr = InstallTCPIP(pInfo->hwnd, NULL, NULL);
  4175. if (NETCONN_NEED_RESTART == hr)
  4176. {
  4177. pInfo->fRebootRequired = TRUE;
  4178. hr = S_OK;
  4179. }
  4180. if (FAILED(hr))
  4181. {
  4182. g_logFile.Write("Failed to install TCP/IP\r\n");
  4183. }
  4184. // Install Client for Microsoft Networks
  4185. // TODO: figure out what to do if NetWare client is installed!?!?
  4186. hr = InstallMSClient(pInfo->hwnd, NULL, NULL);
  4187. if (NETCONN_NEED_RESTART == hr)
  4188. {
  4189. pInfo->fRebootRequired = TRUE;
  4190. hr = S_OK;
  4191. }
  4192. if (FAILED(hr))
  4193. {
  4194. g_logFile.Write("Failed to install Client for Microsoft Networks.\r\n");
  4195. }
  4196. // Install sharing
  4197. if (fInstallSharing)
  4198. {
  4199. hr = InstallSharing(pInfo->hwnd, NULL, NULL);
  4200. if (NETCONN_NEED_RESTART == hr)
  4201. {
  4202. pInfo->fRebootRequired = TRUE;
  4203. hr = S_OK;
  4204. }
  4205. if (FAILED(hr))
  4206. {
  4207. g_logFile.Write("Failed to install File and Printer Sharing.\r\n");
  4208. }
  4209. }
  4210. // TODO: What to do about share level vs. user level access control on windows 9x???
  4211. // TODO: What to do about autodialing? Are we assuming this will already be done for us? 9x and NT? I think so!
  4212. if ( g_fRunningOnNT )
  4213. {
  4214. // We only set autodial here if we are configuring an ICS Client
  4215. // In the case that we explicitly set a public adapter then ConfigureICSBridgeFirewall
  4216. // will set autodial if required.
  4217. if ( pInfo->dwFlags & HNET_ICSCLIENT )
  4218. {
  4219. hr = HrSetAutodial( AUTODIAL_MODE_NO_NETWORK_PRESENT );
  4220. }
  4221. }
  4222. else
  4223. {
  4224. if ( pInfo->ipaExternal != -1 )
  4225. {
  4226. if (W9xIsAdapterDialUp(&pInfo->pNA[LOWORD(pInfo->ipaExternal)])) // Dialup adapter for connecting to internet
  4227. {
  4228. g_logFile.Write("Setting default dial-up connection to autodial.\r\n");
  4229. SetDefaultDialupConnection((pInfo->pRas[HIWORD(pInfo->ipaExternal)]).szEntryName);
  4230. EnableAutodial(TRUE);
  4231. }
  4232. else
  4233. {
  4234. g_logFile.Write("Disabling autodial since default connection isn't dial-up.\r\n");
  4235. SetDefaultDialupConnection(NULL);
  4236. EnableAutodial(FALSE);
  4237. }
  4238. }
  4239. }
  4240. // Configure ICS, the Bridge and the personal firewall
  4241. if (g_fRunningOnNT)
  4242. {
  4243. hr = ConfigureICSBridgeFirewall(pInfo);
  4244. }
  4245. else
  4246. {
  4247. // ICS client or no internet connection.
  4248. if ((pInfo->dwFlags & HNET_ICSCLIENT) || (pInfo->pNA && pInfo->ipaExternal == -1))
  4249. {
  4250. CICSInst* pICS = new CICSInst;
  4251. if (pICS)
  4252. {
  4253. if (pICS->IsInstalled())
  4254. {
  4255. pICS->m_option = ICS_UNINSTALL;
  4256. g_logFile.Write("Uninstalling ICS Client.\r\n");
  4257. pICS->DoInstallOption(&(pInfo->fRebootRequired), pInfo->ipaInternal);
  4258. }
  4259. delete pICS;
  4260. }
  4261. if ( (pInfo->dwFlags & HNET_ICSCLIENT) && (pInfo->pNA && pInfo->ipaInternal != -1))
  4262. {
  4263. UINT ipa;
  4264. for ( ipa=0; ipa<pInfo->cNA; ipa++ )
  4265. {
  4266. const NETADAPTER* pNA = &pInfo->pNA[ ipa ];
  4267. if ( W9xIsValidAdapter( pNA, CONN_INTERNAL ) &&
  4268. !W9xIsValidAdapter( pNA, CONN_UNPLUGGED ) )
  4269. {
  4270. HrEnableDhcp( (void*)pNA, HNW_ED_RELEASE|HNW_ED_RENEW );
  4271. }
  4272. }
  4273. }
  4274. g_logFile.Write("Disabling autodial.\r\n");
  4275. SetDefaultDialupConnection(NULL);
  4276. EnableAutodial(FALSE);
  4277. }
  4278. }
  4279. // NOTE: we might want to split HNET_SHAREFOLDERS out into two
  4280. // bits: HNET_CREATESHAREDFOLDERS and HNET_SHARESHAREDFOLDERS
  4281. //
  4282. if (pInfo->dwFlags & (HNET_SHAREPRINTERS | HNET_SHAREFOLDERS))
  4283. {
  4284. // Due to domain/corporate security concerns, share things
  4285. // iff we're setting up a workgroup, or we're already on one
  4286. //
  4287. BOOL fOnWorkgroup = fInstalledWorkgroup;
  4288. if (!fOnWorkgroup)
  4289. {
  4290. if (g_fRunningOnNT)
  4291. {
  4292. LPTSTR pszDomain;
  4293. NETSETUP_JOIN_STATUS njs;
  4294. if (NERR_Success == NetGetJoinInformation(NULL, &pszDomain, &njs))
  4295. {
  4296. NetApiBufferFree(pszDomain);
  4297. fOnWorkgroup = (NetSetupWorkgroupName == njs);
  4298. }
  4299. }
  4300. else
  4301. {
  4302. fOnWorkgroup = TRUE; // there may be some registry key we can check for this
  4303. }
  4304. }
  4305. if (fOnWorkgroup)
  4306. {
  4307. EnableSimpleSharing();
  4308. if (fSharingAlreadyInstalled)
  4309. {
  4310. if (pInfo->dwFlags & HNET_SHAREPRINTERS)
  4311. {
  4312. ShareAllPrinters();
  4313. }
  4314. if (pInfo->dwFlags & HNET_SHAREFOLDERS)
  4315. {
  4316. ShareWellKnownFolders(pInfo);
  4317. }
  4318. }
  4319. else
  4320. {
  4321. // Write the sharing info to the registry - do required work on reboot
  4322. g_logFile.Write("Sharing isn't installed. Will share folders and printers on reboot.\r\n");
  4323. pInfo->fRebootRequired = TRUE;
  4324. WriteSetupInfoToRegistry(pInfo);
  4325. }
  4326. }
  4327. }
  4328. if (pInfo->fRebootRequired)
  4329. {
  4330. g_logFile.Write("Reboot is required for changes to take effect.\r\n");
  4331. }
  4332. g_logFile.Uninitialize();
  4333. // Kick off the netcrawler
  4334. INetCrawler *pnc;
  4335. if (SUCCEEDED(CoCreateInstance(CLSID_NetCrawler, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARG(INetCrawler, &pnc))))
  4336. {
  4337. pnc->Update(0x0);
  4338. pnc->Release();
  4339. }
  4340. #ifdef FAKE_REBOOTREQUIRED
  4341. pInfo->fRebootRequired = TRUE;
  4342. #endif
  4343. return hr;
  4344. }
  4345. void STDMETHODCALLTYPE ConfigurationLogCallback(LPCWSTR pszLogEntry, LPARAM lParam)
  4346. {
  4347. g_logFile.Write(pszLogEntry);
  4348. }
  4349. typedef BOOL (APIENTRY* PFNNETSETUPICSUPGRADE)(BOOL);
  4350. HRESULT ConfigureICSBridgeFirewall(PHOMENETSETUPINFO pInfo)
  4351. {
  4352. HRESULT hr = E_FAIL;
  4353. // Call HNetSetShareAndBridgeSettings directly
  4354. BOOLEAN fSharePublicConnection = (pInfo->pncExternal && (pInfo->dwFlags & HNET_SHARECONNECTION)) ? TRUE : FALSE;
  4355. BOOLEAN fFirewallPublicConnection = (pInfo->pncExternal && (pInfo->dwFlags & HNET_FIREWALLCONNECTION)) ? TRUE : FALSE;
  4356. if (fSharePublicConnection)
  4357. {
  4358. g_logFile.Write("Will attempt to share public connection.\r\n");
  4359. }
  4360. if (fFirewallPublicConnection)
  4361. {
  4362. g_logFile.Write("Will attempt to firewall public connection.\r\n");
  4363. }
  4364. HMODULE hHNetCfg = LoadLibrary(L"hnetcfg.dll");
  4365. if (hHNetCfg)
  4366. {
  4367. INetConnection* pncPrivate = NULL;
  4368. LPFNHNETSETSHAREANDBRIDGESETTINGS pfnHNetSetShareAndBridgeSettings
  4369. = reinterpret_cast<LPFNHNETSETSHAREANDBRIDGESETTINGS>
  4370. (GetProcAddress(hHNetCfg, "HNetSetShareAndBridgeSettings"));
  4371. if (pfnHNetSetShareAndBridgeSettings)
  4372. {
  4373. hr = (*pfnHNetSetShareAndBridgeSettings)( pInfo->pncExternal,
  4374. pInfo->prgncInternal,
  4375. fSharePublicConnection,
  4376. fFirewallPublicConnection,
  4377. ConfigurationLogCallback,
  4378. 0,
  4379. &pncPrivate );
  4380. if (SUCCEEDED(hr))
  4381. {
  4382. if ( ( HNET_ICSCLIENT & pInfo->dwFlags ) &&
  4383. ( NULL == pInfo->prgncInternal[1] ) )
  4384. {
  4385. HrEnableDhcp( pInfo->prgncInternal[0], HNW_ED_RELEASE|HNW_ED_RENEW );
  4386. }
  4387. // If we are sharing an external adapter then set WinInet settings to allow
  4388. // for an existing connection created from ICS client traffic.
  4389. if ( pInfo->pncExternal )
  4390. {
  4391. hr = HrSetAutodial( AUTODIAL_MODE_NO_NETWORK_PRESENT );
  4392. }
  4393. if ( pncPrivate )
  4394. {
  4395. pncPrivate->Release();
  4396. }
  4397. }
  4398. else
  4399. {
  4400. g_logFile.Write("Adapter Configuration for Home Networking failed.\r\n");
  4401. }
  4402. }
  4403. else
  4404. {
  4405. TraceMsg(TF_WARNING, "HNetCfg.DLL could not find HNetSetShareAndBridgeSettings");
  4406. }
  4407. FreeLibrary(hHNetCfg);
  4408. }
  4409. else
  4410. {
  4411. TraceMsg(TF_WARNING, "HNetCfg.DLL could not be loaded");
  4412. }
  4413. return hr;
  4414. }
  4415. BOOL MachineHasNetShares()
  4416. {
  4417. SHARE_INFO* prgShares;
  4418. int cShares = EnumLocalShares(&prgShares);
  4419. // See if there are any file or print shares, which are the ones we care about
  4420. BOOL fHasShares = FALSE;
  4421. for (int i = 0; i < cShares; i++)
  4422. {
  4423. if ((STYPE_DISKTREE == prgShares[i].bShareType) ||
  4424. (STYPE_PRINTQ == prgShares[i].bShareType))
  4425. {
  4426. fHasShares = TRUE;
  4427. break;
  4428. }
  4429. }
  4430. NetApiBufferFree(prgShares);
  4431. return fHasShares;
  4432. }
  4433. // Checks if guest access mode is enabled. If guest access mode is OFF but
  4434. // in the indeterminate state (ForceGuest is not set), and the m/c has no net shares,
  4435. // then we set ForceGuest to 1 and return TRUE.
  4436. //
  4437. // This indeterminate state occurs only on win2k->XP upgrade.
  4438. BOOL
  4439. EnsureGuestAccessMode(
  4440. VOID
  4441. )
  4442. {
  4443. BOOL fIsGuestAccessMode = FALSE;
  4444. if (IsOS(OS_PERSONAL))
  4445. {
  4446. // Guest mode is always on for Personal
  4447. fIsGuestAccessMode = TRUE;
  4448. }
  4449. else if (IsOS(OS_PROFESSIONAL) && !IsOS(OS_DOMAINMEMBER))
  4450. {
  4451. LONG ec;
  4452. HKEY hkey;
  4453. // Professional, not in a domain. Check the ForceGuest value.
  4454. ec = RegOpenKeyEx(
  4455. HKEY_LOCAL_MACHINE,
  4456. TEXT("SYSTEM\\CurrentControlSet\\Control\\LSA"),
  4457. 0,
  4458. KEY_QUERY_VALUE | KEY_SET_VALUE,
  4459. &hkey
  4460. );
  4461. if (ec == NO_ERROR)
  4462. {
  4463. DWORD dwValue;
  4464. DWORD dwValueSize = sizeof(dwValue);
  4465. ec = RegQueryValueEx(hkey,
  4466. TEXT("ForceGuest"),
  4467. NULL,
  4468. NULL,
  4469. (LPBYTE)&dwValue,
  4470. &dwValueSize);
  4471. if (ec == NO_ERROR)
  4472. {
  4473. if (1 == dwValue)
  4474. {
  4475. // ForceGuest is already on
  4476. fIsGuestAccessMode = TRUE;
  4477. }
  4478. }
  4479. else
  4480. {
  4481. // Value doesn't exist
  4482. if (!MachineHasNetShares())
  4483. {
  4484. // Machine has no shares
  4485. dwValue = 1;
  4486. ec = RegSetValueEx(hkey,
  4487. TEXT("ForceGuest"),
  4488. 0,
  4489. REG_DWORD,
  4490. (BYTE*) &dwValue,
  4491. sizeof (dwValue));
  4492. if (ec == NO_ERROR)
  4493. {
  4494. // Write succeeded - guest access mode is enabled
  4495. fIsGuestAccessMode = TRUE;
  4496. }
  4497. }
  4498. }
  4499. RegCloseKey(hkey);
  4500. }
  4501. }
  4502. return fIsGuestAccessMode;
  4503. }
  4504. // It is assumed the machine is not joined to a domain when this is called!
  4505. HRESULT EnableSimpleSharing()
  4506. {
  4507. HRESULT hr = S_FALSE;
  4508. if (EnsureGuestAccessMode())
  4509. {
  4510. ILocalMachine *pLM;
  4511. hr = CoCreateInstance(CLSID_ShellLocalMachine, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(ILocalMachine, &pLM));
  4512. if (SUCCEEDED(hr))
  4513. {
  4514. TraceMsg(TF_ALWAYS, "Enabling Guest Account");
  4515. hr = pLM->EnableGuest(ILM_GUEST_NETWORK_LOGON);
  4516. pLM->Release();
  4517. SendNotifyMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);
  4518. }
  4519. }
  4520. return hr;
  4521. }
  4522. #define INVALID_COMPUTERNAME_CHARS L" {|}~[\\]^':;<=>?@!\"#$%^`()+/*&"
  4523. #define INVALID_WORKGROUP_CHARS L"{|}~[\\]^':;<=>?!\"#$%^`()+/*&"
  4524. #define INVALID_TRAILING_CHAR L' '
  4525. BOOL IsValidNameSyntax(LPCWSTR pszName, NETSETUP_NAME_TYPE type)
  4526. {
  4527. // Only support workgroup and machine - need to add new charsets if
  4528. // required
  4529. ASSERT(type == NetSetupWorkgroup || type == NetSetupMachine);
  4530. LPCWSTR pszInvalid = (type == NetSetupWorkgroup) ? INVALID_WORKGROUP_CHARS : INVALID_COMPUTERNAME_CHARS;
  4531. BOOL fValid = TRUE;
  4532. WCHAR* pch = (LPWSTR) pszName;
  4533. if ( *pch && ( NetSetupWorkgroup == type ) )
  4534. {
  4535. // remove trailing blanks
  4536. WCHAR* pchLast = pch + wcslen(pch) - 1;
  4537. while ( (INVALID_TRAILING_CHAR == *pchLast) && (pchLast >= pch) )
  4538. {
  4539. *pchLast = NULL;
  4540. pchLast--;
  4541. }
  4542. }
  4543. fValid = ( *pch ) ? TRUE : FALSE;
  4544. while (*pch && fValid)
  4545. {
  4546. fValid = (NULL == StrChrW(pszInvalid, *pch));
  4547. pch ++;
  4548. }
  4549. return fValid;
  4550. }
  4551. void BoldControl(HWND hwnd, int id)
  4552. {
  4553. HWND hwndTitle = GetDlgItem(hwnd, id);
  4554. // Get the existing font
  4555. HFONT hfontOld = (HFONT) SendMessage(hwndTitle, WM_GETFONT, 0, 0);
  4556. LOGFONT lf = {0};
  4557. if (GetObject(hfontOld, sizeof(lf), &lf))
  4558. {
  4559. lf.lfWeight = FW_BOLD;
  4560. HFONT hfontNew = CreateFontIndirect(&lf);
  4561. if (hfontNew)
  4562. {
  4563. SendMessage(hwndTitle, WM_SETFONT, (WPARAM) hfontNew, FALSE);
  4564. // Don't do this, its shared.
  4565. // DeleteObject(hfontOld);
  4566. }
  4567. }
  4568. }
  4569. void ShowControls(HWND hwndParent, const int *prgControlIDs, DWORD nControls, int nCmdShow)
  4570. {
  4571. for (DWORD i = 0; i < nControls; i++)
  4572. ShowWindow(GetDlgItem(hwndParent, prgControlIDs[i]), nCmdShow);
  4573. }
  4574. void HelpCenter(HWND hwnd, LPCWSTR pszTopic)
  4575. {
  4576. // use ShellExecuteExA for w98 compat.
  4577. CHAR szURL[1024];
  4578. wsprintfA(szURL, "hcp://services/layout/contentonly?topic=ms-its%%3A%%25help_location%%25\\%S", pszTopic);
  4579. SHELLEXECUTEINFOA shexinfo = {0};
  4580. shexinfo.cbSize = sizeof (shexinfo);
  4581. shexinfo.fMask = SEE_MASK_FLAG_NO_UI;
  4582. shexinfo.nShow = SW_SHOWNORMAL;
  4583. shexinfo.lpFile = szURL;
  4584. shexinfo.lpVerb = "open";
  4585. // since help center doesn't properly call AllowSetForegroundWindow when it defers to an existing process we just give it to the next taker.
  4586. HMODULE hUser32 = GetModuleHandleA("user32.dll");
  4587. if(NULL != hUser32)
  4588. {
  4589. BOOL (WINAPI *pAllowSetForegroundWindow)(DWORD);
  4590. pAllowSetForegroundWindow = reinterpret_cast<BOOL (WINAPI*)(DWORD)>(GetProcAddress(hUser32, "AllowSetForegroundWindow"));
  4591. if(NULL != pAllowSetForegroundWindow)
  4592. {
  4593. pAllowSetForegroundWindow(-1);
  4594. }
  4595. }
  4596. ShellExecuteExA(&shexinfo);
  4597. }
  4598. void CHomeNetworkWizard::ShowMeLink(HWND hwnd, LPCWSTR pszTopic)
  4599. {
  4600. if (pfnShowHTMLDialog == NULL)
  4601. {
  4602. hinstMSHTML = LoadLibrary(TEXT("MSHTML.DLL"));
  4603. if (hinstMSHTML)
  4604. {
  4605. pfnShowHTMLDialog = (SHOWHTMLDIALOGEXFN*)GetProcAddress(hinstMSHTML, "ShowHTMLDialogEx");
  4606. }
  4607. // can not find ShowHTMLDialog API. Do nothing.
  4608. if (pfnShowHTMLDialog == NULL)
  4609. return;
  4610. }
  4611. WCHAR szURL[1024];
  4612. HRESULT hr;
  4613. VARIANT_BOOL isClosed = VARIANT_FALSE;
  4614. // check to see if the dialog window is closed. If so, release it so that a new one
  4615. // will be created.
  4616. if (showMeDlgWnd != NULL)
  4617. {
  4618. if (SUCCEEDED(showMeDlgWnd->get_closed(&isClosed)))
  4619. {
  4620. if (isClosed == VARIANT_TRUE)
  4621. {
  4622. showMeDlgWnd->Release();
  4623. showMeDlgWnd = NULL;
  4624. if (pFrameWindow != NULL)
  4625. {
  4626. pFrameWindow->Release();
  4627. pFrameWindow = NULL;
  4628. }
  4629. }
  4630. }
  4631. else
  4632. {
  4633. return;
  4634. }
  4635. }
  4636. const char *helpLoc = getenv("help_location");
  4637. LPWSTR lpszWinDir; // pointer to system information string
  4638. WCHAR tchBuffer[MAX_PATH]; // buffer for concatenated string
  4639. // if unset use the default location.
  4640. lpszWinDir = tchBuffer;
  4641. GetWindowsDirectory(lpszWinDir, MAX_PATH);
  4642. if (showMeDlgWnd == NULL)
  4643. {
  4644. BSTR bstrFrameURL;
  4645. // need to create a new dialog window.
  4646. if (helpLoc != NULL)
  4647. wnsprintfW(szURL, 1024, L"ms-its:%S\\ntart.chm::/hn_ShowMeFrame.htm", helpLoc);
  4648. else
  4649. wnsprintfW(szURL, 1024, L"ms-its:%s\\help\\ntart.chm::/hn_ShowMeFrame.htm", lpszWinDir);
  4650. bstrFrameURL = SysAllocString((const LPCWSTR)szURL);
  4651. if (bstrFrameURL == NULL)
  4652. return;
  4653. IMoniker * pURLMoniker = NULL;
  4654. CreateURLMoniker(NULL, bstrFrameURL, &pURLMoniker);
  4655. if (pURLMoniker != NULL)
  4656. {
  4657. VARIANT varReturn;
  4658. VariantInit(&varReturn);
  4659. DWORD dwFlags = HTMLDLG_MODELESS | HTMLDLG_VERIFY;
  4660. hr = (*pfnShowHTMLDialog)(
  4661. NULL,
  4662. pURLMoniker,
  4663. dwFlags,
  4664. NULL,
  4665. L"scroll:no;help:no;status:no;dialogHeight:394px;dialogWidth:591px;",
  4666. &varReturn);
  4667. if (SUCCEEDED(hr))
  4668. {
  4669. hr = V_UNKNOWN(&varReturn)->QueryInterface(__uuidof(IHTMLWindow2), (void**)&showMeDlgWnd);
  4670. }
  4671. pURLMoniker->Release();
  4672. VariantClear(&varReturn);
  4673. }
  4674. SysFreeString(bstrFrameURL);
  4675. }
  4676. // we don't have a dialog window to work with so quit silently.
  4677. if (showMeDlgWnd == NULL)
  4678. {
  4679. return;
  4680. }
  4681. // we need get the frame window where the actual html page will be displayed.
  4682. if (pFrameWindow == NULL)
  4683. {
  4684. VARIANT index;
  4685. VARIANT frameOut;
  4686. long frameLen = 0;
  4687. VariantInit(&index);
  4688. VariantInit(&frameOut);
  4689. IHTMLFramesCollection2* pFramesCol = NULL;
  4690. // we may not be able to get the frames the first time around. So try some more.
  4691. int i = 5;
  4692. while (i-- > 0)
  4693. {
  4694. if(!SUCCEEDED(showMeDlgWnd->get_frames(&pFramesCol)))
  4695. {
  4696. // can not get frames. so quit.
  4697. break;
  4698. }
  4699. else
  4700. if (!SUCCEEDED(pFramesCol->get_length(&frameLen)))
  4701. {
  4702. // can not determine how many frames it has. so quit.
  4703. break;
  4704. }
  4705. else
  4706. {
  4707. if (frameLen > 0)
  4708. {
  4709. V_VT(&index) = VT_I4;
  4710. V_I4(&index) = 0;
  4711. if (SUCCEEDED(pFramesCol->item(&index, &frameOut)))
  4712. {
  4713. if (V_VT(&frameOut) == VT_DISPATCH && V_DISPATCH(&frameOut) != NULL)
  4714. {
  4715. hr = V_DISPATCH(&frameOut)->QueryInterface(__uuidof(IHTMLWindow2), (void**)&pFrameWindow);
  4716. }
  4717. }
  4718. // found at least one frame. jump out of the loop.
  4719. break;
  4720. }
  4721. }
  4722. if (pFramesCol != NULL)
  4723. pFramesCol->Release();
  4724. Sleep(1000);
  4725. }
  4726. if (pFramesCol != NULL)
  4727. pFramesCol->Release();
  4728. VariantClear(&index);
  4729. VariantClear(&frameOut);
  4730. }
  4731. if (pFrameWindow == NULL)
  4732. return;
  4733. // now to load in the actual html page
  4734. BSTR bstrURL;
  4735. if (helpLoc != NULL)
  4736. wnsprintf(szURL, 1024, L"ms-its:%S\\%s", helpLoc, pszTopic);
  4737. else
  4738. wnsprintf(szURL, 1024, L"ms-its:%s\\help\\%s", lpszWinDir, pszTopic);
  4739. bstrURL = SysAllocString((const LPCWSTR)szURL);
  4740. if (bstrURL == NULL)
  4741. return;
  4742. hr = pFrameWindow->navigate(bstrURL);
  4743. hr = showMeDlgWnd->focus();
  4744. SysFreeString(bstrURL);
  4745. }