|
|
#include "stdafx.h"
#include "theapp.h"
#include "netconn.h"
#include "netapi.h"
#include "prnutil.h"
#include "install.h"
#include "mydocs.h"
#include "comctlwrap.h"
#include "icsinst.h"
#include "defconn.h"
#include "initguid.h"
DEFINE_GUID(CLSID_FolderItem, 0xfef10fa2, 0x355e, 0x4e06, 0x93, 0x81, 0x9b, 0x24, 0xd7, 0xf7, 0xcc, 0x88); DEFINE_GUID(CLSID_SharedAccessConnectionManager, 0xBA126AE0,0x2166,0x11D1,0xB1,0xD0,0x00,0x80,0x5F,0xC1,0x27,0x0E); // this doesn't exist in the shell tree
#include "resource.h"
#include "newapi.h"
#include "shgina.h"
#include "hnetcfg.h"
#include "netconp.h"
#include "hnetbcon.h" // ICSLapCtl.h
#include "Lm.h"
#include "htmlhelp.h"
#include "nla.h"
#include "netinet.h"
#include "netip.h"
#include "netras.h"
#include "netutil.h"
// include files necessary for showing diagrams using ShowHTMLDialog. TinQian
#include <urlmon.h>
#include <mshtmhst.h>
#include <mshtml.h>
#include <atlbase.h>
// Debugging #defines:
// Uncomment NO_CHECK_DOMAIN when you want to test the wizard on a domain machine - just don't apply changes ;)
// #define NO_CHECK_DOMAIN
// Uncomment NO_CONFIG to neuter the wizard for UI-only testing
// #define NO_CONFIG
// Uncomment FAKE_ICS to simulate the "ICS machine" state
// #define FAKE_ICS
// Uncomment FAKE_UNPLUGGED to simulate unplugged connections
// #define FAKE_UNPLUGGED
// Uncomment FAKE_REBOOTREQUIRED to simulate reboot required
// #define FAKE_REBOOTREQUIRED
// Delay Load ole32.dll function CoSetProxyBlanket since it isn't on W95 Gold
// and it's only used by the wizard on NT
#define CoSetProxyBlanket CoSetProxyBlanket_NT
EXTERN_C STDAPI CoSetProxyBlanket_NT(IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc, OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel, RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities);
// Functions not in any include file yet
extern int AdapterIndexFromClass(LPTSTR szClass, BOOL bSkipClass);
#define LWS_IGNORERETURN 0x0002
#define MAX_HNW_PAGES 30
#define MAX_WORKGROUPS 20
#define CONN_EXTERNAL 0x00000001
#define CONN_INTERNAL 0x00000002
#define CONN_UNPLUGGED 0x00000004
// Return value to use for sharing configuration conflict
#define HNETERRORSTART 0x200
#define E_ANOTHERADAPTERSHARED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, HNETERRORSTART+1)
#define E_ICSADDRESSCONFLICT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, HNETERRORSTART+2)
class CEnsureSingleInstance { public: CEnsureSingleInstance(LPCTSTR szCaption); ~CEnsureSingleInstance();
BOOL ShouldExit() { return m_fShouldExit;}
private: BOOL m_fShouldExit; HANDLE m_hEvent; };
CEnsureSingleInstance::CEnsureSingleInstance(LPCTSTR szCaption) { // Create an event
m_hEvent = CreateEvent(NULL, TRUE, FALSE, szCaption);
// If any weird errors occur, default to running the instance
m_fShouldExit = FALSE;
if (NULL != m_hEvent) { // If our event isn't signaled, we're the first instance
m_fShouldExit = (WAIT_OBJECT_0 == WaitForSingleObject(m_hEvent, 0));
if (m_fShouldExit) { // app should exit after calling ShouldExit()
// Find and show the caption'd window
HWND hwndActivate = FindWindow(NULL, szCaption); if (IsWindow(hwndActivate)) { SetForegroundWindow(hwndActivate); } } else { // Signal that event
SetEvent(m_hEvent); } } }
CEnsureSingleInstance::~CEnsureSingleInstance() { if (NULL != m_hEvent) { CloseHandle(m_hEvent); } }
typedef struct _tagHOMENETSETUPINFO { HWND hwnd;
DWORD cbSize; DWORD dwFlags;
// Data for NT - NetConnections are temporarily represented by their corresponding GUIDs to cross the
// thread boundary for asynchronous configuration.
BOOL fAsync; GUID guidExternal; GUID* prgguidInternal; DWORD cguidInternal; UINT umsgAsyncNotify;
INetConnection* pncExternal; INetConnection** prgncInternal; DWORD cncInternal;
// Data for Win9x
const NETADAPTER* pNA; // list of adapters.
UINT cNA; // count of entries in pNA.
RASENTRYNAME* pRas; // list of RAS connectoids.
UINT cRas; // count of RAS connectoids.
UINT ipaExternal; UINT ipaInternal;
// Data for both NT and Win9x
TCHAR szComputer[CNLEN + 1]; TCHAR szComputerDescription[256]; TCHAR szWorkgroup[LM20_DNLEN + 1];
// Out-data
BOOL fRebootRequired; } HOMENETSETUPINFO, *PHOMENETSETUPINFO;
// Function prototypes
void HelpCenter(HWND hwnd, LPCWSTR pszTopic); void BoldControl(HWND hwnd, int id); void ShowControls(HWND hwndParent, const int *prgControlIDs, DWORD nControls, int nCmdShow); HRESULT ConfigureHomeNetwork(PHOMENETSETUPINFO pInfo); DWORD WINAPI ConfigureHomeNetworkThread(void* pData); HRESULT ConfigureHomeNetworkSynchronous(PHOMENETSETUPINFO pInfo); HRESULT ConfigureICSBridgeFirewall(PHOMENETSETUPINFO pInfo); HRESULT EnableSimpleSharing(); HRESULT GetConnections(HDPA* phdpa); int FreeConnectionDPACallback(LPVOID pFreeMe, LPVOID pData); HRESULT GetConnectionsFolder(IShellFolder** ppsfConnections); //HRESULT GetConnectionIconIndex(GUID& guidConnection, IShellFolder* psfConnections, int* pIndex, HIMAGELIST imgList);
HRESULT GetDriveNameAndIconIndex(LPWSTR pszDrive, LPWSTR pszDisplayName, DWORD cchDisplayName, int* pIndex); void W9xGetNetTypeName(BYTE bNicType, WCHAR* pszBuff, UINT cchBuff); BOOL W9xIsValidAdapter(const NETADAPTER* pNA, DWORD dwFlags); BOOL W9xIsAdapterDialUp(const NETADAPTER* pAdapter); BOOL IsEqualConnection(INetConnection* pnc1, INetConnection* pnc2); void GetTitleFont(LPTSTR pszFaceName, DWORD cch); LONG GetTitlePointSize(void); BOOL FormatMessageString(UINT idTemplate, LPTSTR pszStrOut, DWORD cchSize, ...); int DisplayFormatMessage(HWND hwnd, UINT idCaption, UINT idFormatString, UINT uType, ...); HRESULT SetProxyBlanket(IUnknown * pUnk); HRESULT MakeUniqueShareName(LPCTSTR pszBaseName, LPTSTR pszUniqueName, DWORD cchName); HRESULT WriteSetupInfoToRegistry(PHOMENETSETUPINFO pInfo); HRESULT ReadSetupInfoFromRegistry(PHOMENETSETUPINFO pInfo); HRESULT ShareWellKnownFolders(PHOMENETSETUPINFO pInfo); HRESULT ShareAllPrinters(); HRESULT DeleteSetupInfoFromRegistry(); HRESULT IsUserLocalAdmin(HANDLE TokenHandle, BOOL* pfIsAdmin); BOOL AllPlatformGetComputerName(LPWSTR pszName, DWORD cchName); BOOL AllPlatformSetComputerName(LPCWSTR pszName); void FreeInternalConnections(PHOMENETSETUPINFO pInfo); void FreeInternalGUIDs(PHOMENETSETUPINFO pInfo); void FreeExternalConnection(PHOMENETSETUPINFO pInfo); HRESULT GetConnectionByGUID(HDPA hdpaConnections, const GUID* pguid, INetConnection** ppnc); HRESULT GUIDsToConnections(PHOMENETSETUPINFO pInfo); HRESULT GetConnectionGUID(INetConnection* pnc, GUID* pguid); HRESULT ConnectionsToGUIDs(PHOMENETSETUPINFO pInfo); BOOL IsValidNameSyntax(LPCWSTR pszName, NETSETUP_NAME_TYPE type); void STDMETHODCALLTYPE ConfigurationLogCallback(LPCWSTR pszLogEntry, LPARAM lParam);
// Home network wizard class
class CHomeNetworkWizard : public IHomeNetworkWizard { friend HRESULT CHomeNetworkWizard_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi);
public: // IUnknown
STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppvObj); STDMETHOD_(ULONG, AddRef) (); STDMETHOD_(ULONG, Release) ();
// IHomeNetworkWizard
STDMETHOD(ConfigureSilently)(LPCWSTR pszPublicConnection, DWORD hnetFlags, BOOL* pfRebootRequired); STDMETHOD(ShowWizard)(HWND hwnd, BOOL* pfRebootRequired);
protected: CHomeNetworkWizard(); HRESULT Initialize(); HRESULT Uninitialize();
private: // Shared functions
void DestroyConnectionList(HWND hwndList); void InitializeConnectionList(HWND hwndList, DWORD dwFlags); void FillConnectionList(HWND hwndList, INetConnection* pncExcludeFromList, DWORD dwFlags); BOOL ShouldShowConnection(INetConnection* pnc, INetConnection* pncExcludeFromList, DWORD dwFlags); BOOL IsConnectionICSPublic(INetConnection* pnc); BOOL IsConnectionUnplugged(INetConnection* pnc); BOOL W9xAddAdapterToList(const NETADAPTER* pNA, const WCHAR* pszDesc, UINT uiAdapterIndex, UINT uiDialupIndex, HWND hwndList, DWORD dwFlags); UINT W9xEnumRasEntries(void); HRESULT GetConnectionByName(LPCWSTR pszName, INetConnection** ppncOut); HRESULT GetInternalConnectionArray(INetConnection* pncExclude, INetConnection*** pprgncArray, DWORD* pcncArray); DWORD GetConnectionCount(INetConnection* pncExclude, DWORD dwFlags); void ReplaceStaticWithLink(HWND hwndStatic, UINT idcLinkControl, UINT idsLinkText); BOOL IsMachineOnDomain(); BOOL IsMachineWrongOS(); BOOL IsICSIPInUse( WCHAR** ppszHost, PDWORD pdwSize );
// Per-Page functions
// Welcome
static INT_PTR CALLBACK WelcomePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void WelcomeSetTitleFont(HWND hwnd);
// No home network hardware
static INT_PTR CALLBACK NoHardwareWelcomePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Page with instructions for manual configuration of the network
void ManualRefreshConnectionList(); static INT_PTR CALLBACK ManualConfigPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// User has some network hardware unplugged
BOOL UnpluggedFillList(HWND hwnd); static INT_PTR CALLBACK UnpluggedPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Found ICS (Internet connection sharing)
static INT_PTR CALLBACK FoundIcsPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void FoundIcsSetText(HWND hwnd); BOOL GetICSMachine(LPTSTR pszICSMachineName, DWORD cch);
// Connect
static INT_PTR CALLBACK ConnectPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void ConnectSetDefault(HWND hwnd); void ConnectNextPage(HWND hwnd);
// Show Me Links
void ShowMeLink(HWND hwnd, LPCWSTR pszTopic);
// Connect other (alternative methods for connection)
static INT_PTR CALLBACK ConnectOtherPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Public
static INT_PTR CALLBACK PublicPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void PublicSetActive(HWND hwnd); void PublicSetControlState(HWND hwnd); void PublicNextPage(HWND hwnd); void PublicGetControlPositions(HWND hwnd); void PublicResetControlPositions(HWND hwnd); void PublicMoveControls(HWND hwnd, BOOL fItemPreselected);
// File sharing
static INT_PTR CALLBACK EdgelessPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void EdgelessSetActive(HWND hwnd);
// ICS conflict
void ICSConflictSetActive(HWND hwnd); static INT_PTR CALLBACK ICSConflictPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// BridgeWarning (do you want to manually configure the bridge? Are you crazy !?)
static INT_PTR CALLBACK BridgeWarningPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Private
static INT_PTR CALLBACK PrivatePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void PrivateNextPage(HWND hwnd); void PrivateSetControlState(HWND hwnd);
// Name (computer and workgroup)
static INT_PTR CALLBACK NamePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void NameInitDialog(HWND hwnd); void NameSetControlState(HWND hwnd); HRESULT NameNextPage(HWND hwnd);
// Workgroup name
void WorkgroupSetControlState(HWND hwnd); HRESULT WorkgroupNextPage(HWND hwnd); static INT_PTR CALLBACK WorkgroupPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Summary
static INT_PTR CALLBACK SummaryPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void SummarySetActive(HWND hwnd);
// Progress (while the configuration is taking place)
static INT_PTR CALLBACK ProgressPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Almost done (after configuration but before the "completed" page)
static INT_PTR CALLBACK AlmostDonePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Choose disk drive
void FillDriveList(HWND hwndList); void ChooseDiskSetControlState(HWND hwnd); static INT_PTR CALLBACK ChooseDiskPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Insert disk
static HRESULT GetSourceFilePath(LPSTR pszSource, DWORD cch); static INT_PTR CALLBACK InsertDiskPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Floppy and XP CD "run the wizard" instructions
static INT_PTR CALLBACK InstructionsPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Finish
static INT_PTR CALLBACK FinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Error finish
static INT_PTR CALLBACK ErrorFinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// No Hardware Finish
// An alternate finish if they have a LAN card ONLY, and its used for an INet connection,
// so therefore they have no LAN cards connecting to other computers...
static INT_PTR CALLBACK NoHardwareFinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Can't Run Wizard Pages
// An alternate welcome page when the user isn't an adminm or doesn't have permissions,
static INT_PTR CALLBACK CantRunWizardPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static CHomeNetworkWizard* GetThis(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Get Icon Index for network connections based on GUIDs
HRESULT GetConnectionIconIndex(GUID& guidConnection, IShellFolder* psfConnections, int* pIndex);
// Helpers
UINT PopPage() { ASSERT(_iPageStackTop); return _rguiPageStack[--_iPageStackTop]; }
void PushPage(UINT uiPageId) { ASSERT(_iPageStackTop < MAX_HNW_PAGES); _rguiPageStack[_iPageStackTop++] = uiPageId; }
// Data
HDPA _hdpaConnections; HOMENETSETUPINFO _hnetInfo;
// even though CNLEN+1 is the limit of a name buffer, friendly names can be longer
TCHAR _szICSMachineName[MAX_PATH]; // Machine on the network doing ICS, if applicable
UINT _rguiPageStack[MAX_HNW_PAGES]; // Stackopages
int _iPageStackTop; // Current top of the stack
BOOL _fManualBridgeConfig; // The user wants to manuall configure the bridge
BOOL _fICSClient;// This computer will connect through an ICS machine or another sharing device
// Shell image lists - never free these
HIMAGELIST _himlSmall; HIMAGELIST _himlLarge;
LONG _cRef;
BOOL _fShowPublicPage; BOOL _fShowSharingPage; BOOL _fNoICSQuestion; BOOL _fNoHomeNetwork; BOOL _fExternalOnly;
UINT _iDrive; // Ordinal of removable drive for floppy creation
WCHAR _szDrive[256]; // Name of removable drive
BOOL _fCancelCopy; BOOL _fFloppyInstructions; // Show the floppy, as opposed to CD, instructions
// data structure used by show me links
HINSTANCE hinstMSHTML; SHOWHTMLDIALOGEXFN * pfnShowHTMLDialog; IHTMLWindow2 * showMeDlgWnd, * pFrameWindow;
// Network Connection folder and folder view call back. Used by Connection List Views.
IShellFolder *_psfConnections; IShellFolderViewCB *_pConnViewCB;
struct PUBLICCONTROLPOSITIONS { RECT _rcSelectMessage; RECT _rcListLabel; RECT _rcList; RECT _rcHelpIcon; RECT _rcHelpText; } PublicControlPositions; };
int FreeConnectionDPACallback(LPVOID pFreeMe, LPVOID pData) { ((INetConnection*) pFreeMe)->Release(); return 1; }
void InitHnetInfo(HOMENETSETUPINFO* pInfo) { ZeroMemory(pInfo, sizeof (HOMENETSETUPINFO)); pInfo->cbSize = sizeof (HOMENETSETUPINFO); pInfo->ipaExternal = -1; pInfo->ipaInternal = -1; }
// Creation function
HRESULT HomeNetworkWizard_RunFromRegistry(HWND hwnd, BOOL* pfRebootRequired) { HOMENETSETUPINFO setupInfo;
InitHnetInfo(&setupInfo);
HRESULT hr = ReadSetupInfoFromRegistry(&setupInfo);
if (S_OK == hr) { setupInfo.dwFlags = HNET_SHAREPRINTERS | HNET_SHAREFOLDERS; setupInfo.hwnd = hwnd; hr = ConfigureHomeNetwork(&setupInfo); *pfRebootRequired = setupInfo.fRebootRequired; }
DeleteSetupInfoFromRegistry();
return hr; }
HRESULT HomeNetworkWizard_ShowWizard(HWND hwnd, BOOL* pfRebootRequired) { if (*pfRebootRequired) *pfRebootRequired = FALSE;
HRESULT hr = HomeNetworkWizard_RunFromRegistry(hwnd, pfRebootRequired);
if (S_FALSE == hr) { IUnknown* punk; hr = CHomeNetworkWizard_CreateInstance(NULL, &punk, NULL);
if (SUCCEEDED(hr)) { IHomeNetworkWizard* pwizard; hr = punk->QueryInterface(IID_PPV_ARG(IHomeNetworkWizard, &pwizard));
if (SUCCEEDED(hr)) { hr = pwizard->ShowWizard(hwnd, pfRebootRequired); pwizard->Release(); }
punk->Release(); } }
return hr; }
HRESULT CHomeNetworkWizard_CreateInstance(IUnknown *punkOuter, IUnknown **ppunk, LPCOBJECTINFO poi) { *ppunk = NULL;
if (punkOuter) return CLASS_E_NOAGGREGATION;
CHomeNetworkWizard* pwiz = new CHomeNetworkWizard(); if (!pwiz) return E_OUTOFMEMORY;
HRESULT hr = pwiz->QueryInterface(IID_PPV_ARG(IUnknown, ppunk)); pwiz->Release(); return hr; }
// IUnknown
HRESULT CHomeNetworkWizard::QueryInterface(REFIID riid, LPVOID* ppvObj) { if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IHomeNetworkWizard)) { AddRef(); *ppvObj = static_cast<IHomeNetworkWizard *>(this); } else { *ppvObj = NULL; }
return *ppvObj ? S_OK : E_NOINTERFACE; }
ULONG CHomeNetworkWizard::AddRef() { return (ULONG) InterlockedIncrement(&_cRef); }
ULONG CHomeNetworkWizard::Release() { ASSERT( 0 != _cRef ); ULONG cRef = InterlockedDecrement(&_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
HRESULT CHomeNetworkWizard::GetConnectionByName(LPCWSTR pszName, INetConnection** ppncOut) { *ppncOut = NULL; DWORD cItems = DPA_GetPtrCount(_hdpaConnections); DWORD iItem = 0; while ((iItem < cItems) && (NULL == *ppncOut)) { INetConnection* pnc = (INetConnection*) DPA_GetPtr(_hdpaConnections, iItem);
NETCON_PROPERTIES* pncprops; HRESULT hr = pnc->GetProperties(&pncprops); if (SUCCEEDED(hr)) { if (0 == StrCmpIW(pszName, pncprops->pszwName)) { *ppncOut = pnc; (*ppncOut)->AddRef(); }
NcFreeNetconProperties(pncprops); }
iItem ++; }
return (*ppncOut) ? S_OK : E_FAIL; }
HRESULT CHomeNetworkWizard::GetInternalConnectionArray(INetConnection* pncExclude, INetConnection*** pprgncArray, DWORD* pcncArray) { HRESULT hr = S_OK; *pprgncArray = NULL;
DWORD cTotalConnections = DPA_GetPtrCount(_hdpaConnections); DWORD cInternalConnections = GetConnectionCount(pncExclude, CONN_INTERNAL);
if (cInternalConnections) { (*pprgncArray) = (INetConnection**) LocalAlloc(LPTR, (cInternalConnections + 1) * sizeof (INetConnection*)); // Note that we allocated an extra entry since this is a null-terminated array
if (*pprgncArray) { DWORD nInternalConnection = 0; for (DWORD n = 0; n < cTotalConnections; n++) { INetConnection* pnc = (INetConnection*) DPA_GetPtr(_hdpaConnections, n); if (ShouldShowConnection(pnc, pncExclude, CONN_INTERNAL)) { pnc->AddRef(); (*pprgncArray)[nInternalConnection++] = pnc; } }
ASSERT(nInternalConnection == cInternalConnections); } else { hr = E_OUTOFMEMORY; } }
if (SUCCEEDED(hr)) { *pcncArray = cInternalConnections; }
return hr; }
HRESULT CHomeNetworkWizard::ConfigureSilently(LPCWSTR pszPublicConnection, DWORD hnetFlags, BOOL* pfRebootRequired) { // Never set workgroup name
hnetFlags &= (~HNET_SETWORKGROUPNAME); if (!g_fRunningOnNT) return E_NOTIMPL;
HRESULT hr = Initialize();
if (SUCCEEDED(hr)) { _hnetInfo.dwFlags = hnetFlags; // Calculate what the external and internal adapters will be...
if (pszPublicConnection) { hr = GetConnectionByName(pszPublicConnection, &_hnetInfo.pncExternal); } else { _hnetInfo.pncExternal = NULL; }
if (SUCCEEDED(hr)) { // Get all LAN connections except the public connection
if (_hnetInfo.dwFlags & HNET_BRIDGEPRIVATE) { hr = GetInternalConnectionArray(_hnetInfo.pncExternal, &(_hnetInfo.prgncInternal), &_hnetInfo.cncInternal); }
if (SUCCEEDED(hr)) { hr = ConfigureHomeNetwork(&_hnetInfo); *pfRebootRequired = _hnetInfo.fRebootRequired; } }
Uninitialize(); }
return hr; }
CHomeNetworkWizard::CHomeNetworkWizard() : _cRef(1) {}
HRESULT CHomeNetworkWizard::Initialize() { _fExternalOnly = FALSE; _fNoICSQuestion = FALSE; _hdpaConnections = NULL; _iPageStackTop = 0; _fManualBridgeConfig = FALSE; _fICSClient = FALSE; _psfConnections = NULL; _pConnViewCB = NULL;
InitHnetInfo(&_hnetInfo); *_szICSMachineName = 0;
HRESULT hr; if (g_fRunningOnNT) { hr = GetConnections(&_hdpaConnections); } else { _hnetInfo.cNA = EnumCachedNetAdapters(&_hnetInfo.pNA); hr = S_OK; if ( _hnetInfo.cNA > 0 ) { _hnetInfo.ipaInternal = 0; } }
// Get the shell image lists - never free these
if (!Shell_GetImageLists(&_himlLarge, &_himlSmall)) { hr = E_FAIL; }
// variables used by displaying show me links
hinstMSHTML = NULL; pfnShowHTMLDialog = NULL; showMeDlgWnd = NULL; pFrameWindow = NULL;
return hr; }
HRESULT CHomeNetworkWizard::Uninitialize() { if (g_fRunningOnNT) { if (_hdpaConnections) { DPA_DestroyCallback(_hdpaConnections, FreeConnectionDPACallback, NULL); _hdpaConnections = NULL; }
// Free public lan information
FreeExternalConnection(&_hnetInfo);
// Free private lan information
FreeInternalConnections(&_hnetInfo); if (_psfConnections != NULL) _psfConnections->Release();
if (_pConnViewCB != NULL) _pConnViewCB->Release(); } else { if (_hnetInfo.pNA) { FlushNetAdapterCache(); _hnetInfo.pNA = NULL; }
if (_hnetInfo.pRas) { LocalFree(_hnetInfo.pRas); _hnetInfo.pRas = NULL; } }
// release resources used by show me links
if (hinstMSHTML) FreeLibrary(hinstMSHTML);
if (showMeDlgWnd != NULL) showMeDlgWnd->Release(); if (pFrameWindow != NULL) pFrameWindow->Release();
return S_OK; }
// TODO: Move the formatting functions here to a util file or something...
BOOL FormatMessageString(UINT idTemplate, LPTSTR pszStrOut, DWORD cchSize, ...) { BOOL fResult = FALSE;
va_list vaParamList;
TCHAR szFormat[1024]; if (LoadString(g_hinst, idTemplate, szFormat, ARRAYSIZE(szFormat))) { va_start(vaParamList, cchSize);
fResult = FormatMessage(FORMAT_MESSAGE_FROM_STRING, szFormat, 0, 0, pszStrOut, cchSize, &vaParamList);
va_end(vaParamList); }
return fResult; }
int DisplayFormatMessage(HWND hwnd, UINT idCaption, UINT idFormatString, UINT uType, ...) { int iResult = IDCANCEL; TCHAR szError[512]; *szError = 0; TCHAR szCaption[256]; TCHAR szFormat[512]; *szFormat = 0;
// Load and format the error body
if (LoadString(g_hinst, idFormatString, szFormat, ARRAYSIZE(szFormat))) { va_list arguments; va_start(arguments, uType);
if (FormatMessage(FORMAT_MESSAGE_FROM_STRING, szFormat, 0, 0, szError, ARRAYSIZE(szError), &arguments)) { // Load the caption
if (LoadString(g_hinst, idCaption, szCaption, ARRAYSIZE(szCaption))) { iResult = MessageBox(hwnd, szError, szCaption, uType); } }
va_end(arguments); } return iResult; }
BOOL CHomeNetworkWizard::GetICSMachine(LPTSTR pszICSMachineName, DWORD cch) { #ifdef FAKE_ICS
lstrcpyn(pszICSMachineName, L"COMPNAME", cch); return TRUE; #endif
SetCursor(LoadCursor(NULL, IDC_WAIT));
BOOL fICSInstalled = FALSE;
HRESULT hr = S_OK;
INetConnectionManager* pSharedAccessConnectionManager; hr = CoCreateInstance(CLSID_SharedAccessConnectionManager, NULL, CLSCTX_LOCAL_SERVER, IID_INetConnectionManager, reinterpret_cast<void**>(&pSharedAccessConnectionManager)); if(SUCCEEDED(hr)) { IEnumNetConnection* pEnumerator; hr = pSharedAccessConnectionManager->EnumConnections(NCME_DEFAULT, &pEnumerator); if(SUCCEEDED(hr)) { INetConnection* pNetConnection; ULONG ulFetched; hr = pEnumerator->Next(1, &pNetConnection, &ulFetched); // HNW only cares about >= 1 beacon
if(SUCCEEDED(hr) && 1 == ulFetched) { fICSInstalled = TRUE;
// found the beacon, now recover the machine name if supported
INetSharedAccessConnection* pNetSharedAccessConnection; hr = pNetConnection->QueryInterface(IID_INetSharedAccessConnection, reinterpret_cast<void**>(&pNetSharedAccessConnection)); if(SUCCEEDED(hr)) { IUPnPService* pOSInfoService; hr = pNetSharedAccessConnection->GetService(SAHOST_SERVICE_OSINFO, &pOSInfoService); if(SUCCEEDED(hr)) { VARIANT Variant; VariantInit(&Variant); BSTR VariableName; VariableName = SysAllocString(L"OSMachineName"); if(NULL != VariableName) { hr = pOSInfoService->QueryStateVariable(VariableName, &Variant); if(SUCCEEDED(hr)) { if(V_VT(&Variant) == VT_BSTR) { lstrcpyn(pszICSMachineName, V_BSTR(&Variant), cch); } else { hr = E_UNEXPECTED; } VariantClear(&Variant); } SysFreeString(VariableName); } else { hr = E_OUTOFMEMORY; } pOSInfoService->Release(); } pNetSharedAccessConnection->Release(); }
if(FAILED(hr)) { if (!LoadString(g_hinst, IDS_UNIDENTIFIED_ICS_DEVICE, pszICSMachineName, cch)) *pszICSMachineName = TEXT('\0'); } pNetConnection->Release(); } pEnumerator->Release(); } pSharedAccessConnectionManager->Release(); } return fICSInstalled; }
void CHomeNetworkWizard::InitializeConnectionList(HWND hwndList, DWORD dwFlags) { // Set up the columns of the list
LVCOLUMN lvc; lvc.mask = LVCF_SUBITEM | LVCF_WIDTH;
lvc.iSubItem = 0; lvc.cx = 10; ListView_InsertColumn(hwndList, 0, &lvc);
lvc.iSubItem = 1; lvc.cx = 10; ListView_InsertColumn(hwndList, 1, &lvc);
DWORD dwStyles = LVS_EX_FULLROWSELECT; if (dwFlags & CONN_INTERNAL) dwStyles |= LVS_EX_CHECKBOXES;
// Consider disabling the list or something for CONN_UNPLUGGED
ListView_SetExtendedListViewStyleEx(hwndList, dwStyles, dwStyles);
ListView_SetImageList(hwndList, _himlSmall, LVSIL_SMALL); _psfConnections = NULL; _pConnViewCB = NULL;
if (g_fRunningOnNT) { HRESULT hr = GetConnectionsFolder(&_psfConnections); if (SUCCEEDED(hr)) { IShellView *pConnView = NULL; hr = _psfConnections->CreateViewObject(hwndList, IID_IShellView, reinterpret_cast<LPVOID *>(&pConnView)); if (SUCCEEDED(hr)) { hr = _psfConnections->QueryInterface(IID_IShellFolderViewCB, reinterpret_cast<LPVOID *>(&_pConnViewCB)); if (SUCCEEDED(hr)) { HWND hWndParent = GetParent(hwndList); hr = _pConnViewCB->MessageSFVCB(SFVM_HWNDMAIN, NULL, reinterpret_cast<LPARAM>(hWndParent)); } }
if (pConnView != NULL) pConnView->Release(); } } }
BOOL CHomeNetworkWizard::IsConnectionUnplugged(INetConnection* pnc) { BOOL fUnplugged = FALSE; if ( g_fRunningOnNT ) { HRESULT hr; NETCON_PROPERTIES* pncprops; hr = pnc->GetProperties(&pncprops); if (SUCCEEDED(hr)) { ASSERT(pncprops); fUnplugged = (NCS_MEDIA_DISCONNECTED == pncprops->Status);
NcFreeNetconProperties(pncprops); } }
return fUnplugged; }
BOOL CHomeNetworkWizard::ShouldShowConnection(INetConnection* pnc, INetConnection* pncExcludeFromList, DWORD dwFlags) { BOOL fShow = FALSE;
if (!IsEqualConnection(pnc, pncExcludeFromList)) { NETCON_PROPERTIES* pprops; HRESULT hr = pnc->GetProperties(&pprops);
// Is this the kind of connection we want to show based on whether its external or internal list?
if (SUCCEEDED(hr)) { // Note: The bridge is a virtual and not a real connection. If it exists, it will have
// NCM_BRIDGE, and so it won't get shown here, which is correct.
if (dwFlags & CONN_EXTERNAL) { if ((pprops->MediaType == NCM_LAN) || (pprops->MediaType == NCM_PHONE) || (pprops->MediaType == NCM_TUNNEL) || (pprops->MediaType == NCM_ISDN) || (pprops->MediaType == NCM_PPPOE)) { fShow = TRUE; } }
if (dwFlags & CONN_INTERNAL) { if (pprops->MediaType == NCM_LAN) { // Note: In this case pncExcludeFromList is the shared adapter.
// If this is a VPN(NCM_TUNNEL) connection then we want to make
// sure its pszPrerequisiteEntry is connected.
BOOL fAssociated; HRESULT hr; hr = HrConnectionAssociatedWithSharedConnection( pnc, pncExcludeFromList, &fAssociated ); if ( SUCCEEDED(hr) ) { fShow = !fAssociated; } else { fShow = TRUE; } } }
if (dwFlags & CONN_UNPLUGGED) { if (IsConnectionUnplugged(pnc)) { fShow = TRUE; } }
NcFreeNetconProperties(pprops); } }
return fShow; }
BOOL CHomeNetworkWizard::IsConnectionICSPublic(INetConnection* pnc) { BOOL fShared = FALSE;
NETCON_PROPERTIES* pprops; HRESULT hr = pnc->GetProperties(&pprops);
// Is this the kind of connection we want to show based on whether its external or internal list?
if (SUCCEEDED(hr)) { // Note: Don't check pprops->MediaType == NCM_SHAREDACCESSHOST. SHAREDACCESSHOST is the connectoid
// representing a host's shared connection from the point of view of an ICS client, and not what we're
// interested in.
if (pprops->dwCharacter & NCCF_SHARED) { fShared = TRUE; }
NcFreeNetconProperties(pprops); }
return fShared; }
void CHomeNetworkWizard::FillConnectionList(HWND hwndList, INetConnection* pncExcludeFromList, DWORD dwFlags) { DestroyConnectionList(hwndList);
BOOL fSelected = FALSE; // Has an entry in the list been selected
if (g_fRunningOnNT) { HRESULT hr = 0;
if (_pConnViewCB != NULL) _pConnViewCB->MessageSFVCB(DVM_REFRESH, TRUE, TRUE); if (SUCCEEDED(hr)) { // Enumerate each net connection
DWORD cItems = DPA_GetPtrCount(_hdpaConnections);
for (DWORD iItem = 0; iItem < cItems; iItem ++) { INetConnection* pnc = (INetConnection*) DPA_GetPtr(_hdpaConnections, iItem);
ASSERT(pnc);
// Is this the kind of connection we want to show?
if (ShouldShowConnection(pnc, pncExcludeFromList, dwFlags)) { NETCON_PROPERTIES* pncprops;
hr = pnc->GetProperties(&pncprops);
if (SUCCEEDED(hr)) { LVITEM lvi = {0}; if ((dwFlags & CONN_EXTERNAL) && fSelected) { // If we have a default public adapter, insert other adapters
// after it so the default appears at the top of the list.
lvi.iItem = 1; } lvi.mask = LVIF_PARAM | LVIF_TEXT; lvi.pszText = pncprops->pszwName; lvi.lParam = (LPARAM) pnc; // We addref this guy when/if we actually add this item
// Get the icon index for this connection
int iIndex;
hr = GetConnectionIconIndex(pncprops->guidId, _psfConnections, &iIndex); if (SUCCEEDED(hr)) { lvi.iImage = iIndex; if (-1 != lvi.iImage) lvi.mask |= LVIF_IMAGE; }
// Its ok if the icon stuff failed for now
hr = S_OK;
int iItem = ListView_InsertItem(hwndList, &lvi);
if (-1 != iItem) { pnc->AddRef();
ListView_SetItemText(hwndList, iItem, 1, pncprops->pszwDeviceName);
if (dwFlags & CONN_EXTERNAL) { // Select the connection that is already ICS public, if applicable, or
// Use network location awareness to guess at a connection type - TODO
if (pncprops->dwCharacter & NCCF_SHARED || NLA_INTERNET_YES == GetConnectionInternetType(&pncprops->guidId)) { ListView_SetItemState(hwndList, iItem, LVIS_SELECTED, LVIS_SELECTED); fSelected = TRUE; } }
if (dwFlags & CONN_INTERNAL) { ListView_SetItemState(hwndList, iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK); fSelected = TRUE; } }
NcFreeNetconProperties(pncprops); } } } }
} else { if (_hnetInfo.cNA && _hnetInfo.pNA) { const NETADAPTER* pNA = _hnetInfo.pNA;
for (UINT i = 0; i < _hnetInfo.cNA; i++, pNA++) { // Check if the NIC is working.
if (W9xIsValidAdapter(pNA, dwFlags)) { fSelected = W9xAddAdapterToList(pNA, pNA->szDisplayName, i, 0, hwndList, dwFlags); } else if (W9xIsAdapterDialUp(pNA)) { _hnetInfo.cRas = W9xEnumRasEntries();
for (UINT j = 0; j < _hnetInfo.cRas; j++) { // W9xAddAdapterToList ALWAYS adds the adapter regardless of the
// state of the connection. So we do not have the equivalent of
// the Whistler "ShouldShowConnection". Here we need to check
// the flags to exclude listing inappropriate adapters.
if ( ~CONN_UNPLUGGED & dwFlags ) // Never show RAS Entry's as Unplugged
{ fSelected = W9xAddAdapterToList( pNA, _hnetInfo.pRas[j].szEntryName, i, j, hwndList, dwFlags ); } } } } } }
ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE); ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); }
BOOL CHomeNetworkWizard::W9xAddAdapterToList(const NETADAPTER* pNA, const WCHAR* pszDesc, UINT uiAdapterIndex, UINT uiDialupIndex, HWND hwndList, DWORD dwFlags) { BOOL fSelected = FALSE;
LVITEM lvi = {0}; lvi.mask = LVIF_PARAM | LVIF_TEXT;
WCHAR szNicType[MAX_PATH]; W9xGetNetTypeName(pNA->bNetType, szNicType, ARRAYSIZE(szNicType)); lvi.pszText = szNicType;
lvi.lParam = MAKELONG(LOWORD(uiAdapterIndex), LOWORD(uiDialupIndex));
int iItem = ListView_InsertItem(hwndList, &lvi);
if (-1 != iItem) { ListView_SetItemText(hwndList, iItem, 1, (LPWSTR)pszDesc);
if (dwFlags & CONN_EXTERNAL) { if (NETTYPE_DIALUP == pNA->bNetType || NETTYPE_PPTP == pNA->bNetType || NETTYPE_ISDN == pNA->bNetType ) { ListView_SetItemState(hwndList, iItem, LVIS_SELECTED, LVIS_SELECTED); fSelected = TRUE; }
}
if (dwFlags & CONN_INTERNAL) { if (NETTYPE_LAN == pNA->bNetType || NETTYPE_IRDA == pNA->bNetType || // ISSUE-2000/05/31-edwardp: Internal?
NETTYPE_TV == pNA->bNetType ) // ISSUE-2000/05/31-edwardp: Internal?
{ ListView_SetItemState(hwndList, iItem, INDEXTOSTATEIMAGEMASK(2), LVIS_STATEIMAGEMASK); fSelected = TRUE; } } }
return fSelected; }
UINT CHomeNetworkWizard::W9xEnumRasEntries() { UINT uiRet = 0;
if (!_hnetInfo.pRas) { DWORD cDUNs = 0; DWORD cb = 0;
RasEnumEntries(NULL, NULL, NULL, &cb, &cDUNs);
if (cb > 0) { _hnetInfo.pRas = (RASENTRYNAME*)LocalAlloc(LPTR, cb);
if (_hnetInfo.pRas) { _hnetInfo.pRas->dwSize = sizeof(RASENTRYNAME);
if (RasEnumEntries(NULL, NULL, _hnetInfo.pRas, &cb, &cDUNs) == 0) { uiRet = cDUNs; } } } }
return uiRet; }
typedef struct { LPCWSTR idPage; DLGPROC pDlgProc; LPCWSTR pHeading; LPCWSTR pSubHeading; DWORD dwFlags; } WIZPAGE;
#define MAKEWIZPAGE(name, dlgproc, dwFlags) \
{ MAKEINTRESOURCE(IDD_WIZ_##name##), dlgproc, MAKEINTRESOURCE(IDS_HEADER_##name##), MAKEINTRESOURCE(IDS_SUBHEADER_##name##), dwFlags }
INT_PTR MyPropertySheet(LPCPROPSHEETHEADER pHeader); HPROPSHEETPAGE MyCreatePropertySheetPage(LPPROPSHEETPAGE psp);
HRESULT DoesUserHaveHNetPermissions(BOOL* pfHasPermission) { HRESULT hr;
if (g_fRunningOnNT) { // TODO: We need to check this stuff in once the net team RI's
INetConnectionUiUtilities* pNetConnUiUtil; *pfHasPermission = FALSE;
hr = CoCreateInstance(CLSID_NetConnectionUiUtilities, NULL, CLSCTX_INPROC, IID_PPV_ARG(INetConnectionUiUtilities, &pNetConnUiUtil));
if (SUCCEEDED(hr)) { if (pNetConnUiUtil->UserHasPermission(NCPERM_ShowSharedAccessUi) && #if 0 // NYI
pNetConnUiUtil->UserHasPermission(NCPERM_AllowNetBridge_NLA) && #endif
pNetConnUiUtil->UserHasPermission(NCPERM_ICSClientApp) && pNetConnUiUtil->UserHasPermission(NCPERM_PersonalFirewallConfig)) { *pfHasPermission = TRUE; }
pNetConnUiUtil->Release(); } else { TraceMsg(TF_WARNING, "Could not cocreate CLSID_NetConnectionUIUtilities"); } } else { // Windows 9x
*pfHasPermission = TRUE; hr = S_OK; }
return hr; }
BOOL CHomeNetworkWizard::IsMachineOnDomain() { BOOL fDomain = FALSE;
#ifdef NO_CHECK_DOMAIN
return fDomain; #endif
NETSETUP_JOIN_STATUS njs;
//
// Make sure to initialize pszName to NULL. On W9x NetJoinInformation returns NERR_Success
// but doesn't allocate pszName. On retail builds the stack garbage in pszName happened to
// be the this pointer for CHomeNetworkWizard and NetApiBufferFreeWrap called LocalFree
// on it.
//
LPWSTR pszName = NULL; // init to NULL! See comment above.
if (NERR_Success == NetGetJoinInformation(NULL, &pszName, &njs)) { fDomain = (NetSetupDomainName == njs); NetApiBufferFree(pszName); }
return fDomain; }
BOOL CHomeNetworkWizard::IsMachineWrongOS() { BOOL fWrongOS = TRUE;
if (IsOS(OS_WINDOWS)) { if (IsOS(OS_WIN98ORGREATER)) { fWrongOS = FALSE; } } else { if (IsOS(OS_WHISTLERORGREATER)) { fWrongOS = FALSE; } }
return fWrongOS; }
// The page indices for the possible start pages (three error and one real start page)
#define PAGE_NOTADMIN 0
#define PAGE_NOPERMISSIONS 1
#define PAGE_NOHARDWARE 2
#define PAGE_WRONGOS 3
#define PAGE_DOMAIN 4
#define PAGE_WELCOME 5
#define PAGE_CONNECT 9
#define PAGE_FINISH 25
HRESULT CHomeNetworkWizard::ShowWizard(HWND hwnd, BOOL* pfRebootRequired) { HRESULT hr = S_OK; TCHAR szCaption[256]; LoadString(g_hinst, IDS_WIZ_CAPTION, szCaption, ARRAYSIZE(szCaption)); CEnsureSingleInstance ESI(szCaption);
if (!ESI.ShouldExit()) { if (g_fRunningOnNT) { LinkWindow_RegisterClass_NT(); }
*pfRebootRequired = FALSE; hr = Initialize(); if (SUCCEEDED(hr)) { WIZPAGE c_wpPages[] = { // Error start pages
MAKEWIZPAGE(NOTADMIN, CantRunWizardPageProc, PSP_HIDEHEADER), MAKEWIZPAGE(NOPERMISSIONS, CantRunWizardPageProc, PSP_HIDEHEADER), MAKEWIZPAGE(NOHARDWARE, NoHardwareWelcomePageProc, PSP_HIDEHEADER), MAKEWIZPAGE(WRONGOS, CantRunWizardPageProc, PSP_HIDEHEADER), MAKEWIZPAGE(DOMAINWELCOME, CantRunWizardPageProc, PSP_HIDEHEADER), // Real start page
MAKEWIZPAGE(WELCOME, WelcomePageProc, PSP_HIDEHEADER), MAKEWIZPAGE(MANUALCONFIG, ManualConfigPageProc, 0), MAKEWIZPAGE(UNPLUGGED, UnpluggedPageProc, 0), MAKEWIZPAGE(FOUNDICS, FoundIcsPageProc, 0), MAKEWIZPAGE(CONNECT, ConnectPageProc, 0), MAKEWIZPAGE(CONNECTOTHER, ConnectOtherPageProc, 0), MAKEWIZPAGE(PUBLIC, PublicPageProc, 0), MAKEWIZPAGE(EDGELESS, EdgelessPageProc, 0), MAKEWIZPAGE(ICSCONFLICT, ICSConflictPageProc, 0), MAKEWIZPAGE(BRIDGEWARNING, BridgeWarningPageProc, 0), MAKEWIZPAGE(PRIVATE, PrivatePageProc, 0), MAKEWIZPAGE(NAME, NamePageProc, 0), MAKEWIZPAGE(WORKGROUP, WorkgroupPageProc, 0), MAKEWIZPAGE(SUMMARY, SummaryPageProc, 0), MAKEWIZPAGE(PROGRESS, ProgressPageProc, 0), MAKEWIZPAGE(ALMOSTDONE, AlmostDonePageProc, 0), MAKEWIZPAGE(CHOOSEDISK, ChooseDiskPageProc, 0), MAKEWIZPAGE(INSERTDISK, InsertDiskPageProc, 0), MAKEWIZPAGE(FLOPPYINST, InstructionsPageProc, 0), MAKEWIZPAGE(CDINST, InstructionsPageProc, 0), MAKEWIZPAGE(FINISH, FinishPageProc, PSP_HIDEHEADER), MAKEWIZPAGE(CONFIGERROR, ErrorFinishPageProc, PSP_HIDEHEADER), MAKEWIZPAGE(NOHARDWAREFINISH, NoHardwareFinishPageProc, PSP_HIDEHEADER), };
// Sanity check to make sure we haven't added new error pages without updating the
// welcome page number
ASSERT(c_wpPages[PAGE_WELCOME].idPage == MAKEINTRESOURCE(IDD_WIZ_WELCOME)); ASSERT(c_wpPages[PAGE_CONNECT].idPage == MAKEINTRESOURCE(IDD_WIZ_CONNECT)); ASSERT(c_wpPages[PAGE_FINISH].idPage == MAKEINTRESOURCE(IDD_WIZ_FINISH));
if (!g_fRunningOnNT) { c_wpPages[PAGE_WELCOME].idPage = MAKEINTRESOURCE(IDD_WIZ_WIN9X_WELCOME); c_wpPages[PAGE_FINISH].idPage = MAKEINTRESOURCE(IDD_WIZ_WIN9X_FINISH);
CICSInst* pICS = new CICSInst; if (pICS) { if (!pICS->IsInstalled()) { c_wpPages[PAGE_CONNECT].idPage = MAKEINTRESOURCE(IDD_WIZ_WIN9X_CONNECT); _fNoICSQuestion = TRUE; }
delete pICS; } }
HPROPSHEETPAGE rghpage[MAX_HNW_PAGES]; int cPages;
for (cPages = 0; cPages < ARRAYSIZE(c_wpPages); cPages ++) { PROPSHEETPAGE psp = { 0 };
psp.dwSize = SIZEOF(PROPSHEETPAGE); psp.hInstance = g_hinst; psp.lParam = (LPARAM)this; psp.dwFlags = PSP_USETITLE | PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE | c_wpPages[cPages].dwFlags; psp.pszTemplate = c_wpPages[cPages].idPage; psp.pfnDlgProc = c_wpPages[cPages].pDlgProc; psp.pszTitle = MAKEINTRESOURCE(IDS_WIZ_CAPTION); psp.pszHeaderTitle = c_wpPages[cPages].pHeading; psp.pszHeaderSubTitle = c_wpPages[cPages].pSubHeading;
rghpage[cPages] = MyCreatePropertySheetPage(&psp); }
ASSERT(cPages < MAX_HNW_PAGES);
PROPSHEETHEADER psh = { 0 }; psh.dwSize = SIZEOF(PROPSHEETHEADER); psh.hwndParent = hwnd; psh.hInstance = g_hinst; psh.dwFlags = PSH_USEICONID | PSH_WIZARD | PSH_WIZARD97 | PSH_WATERMARK | PSH_STRETCHWATERMARK | PSH_HEADER; psh.pszbmHeader = MAKEINTRESOURCE(IDB_HEADER); psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK); psh.nPages = cPages; psh.phpage = rghpage; psh.pszIcon = MAKEINTRESOURCE(IDI_APPICON);
// Check for administrator and policy (permissions)
BOOL fUserIsAdmin = FALSE; BOOL fUserHasPermissions = FALSE;
IsUserLocalAdmin(NULL, &fUserIsAdmin); DoesUserHaveHNetPermissions(&fUserHasPermissions);
if (!fUserIsAdmin) { // Not admin error page
psh.nStartPage = PAGE_NOTADMIN; } else if (!fUserHasPermissions) { // No permissions error page
psh.nStartPage = PAGE_NOPERMISSIONS; } else if (GetConnectionCount(NULL, CONN_INTERNAL) < 1) { if ( g_fRunningOnNT && ( GetConnectionCount(NULL, CONN_EXTERNAL) > 0 ) ) { TraceMsg(TF_WARNING, "External Adapters Only");
psh.nStartPage = PAGE_WELCOME; _fExternalOnly = TRUE; } else { // No hardware error page
psh.nStartPage = PAGE_NOHARDWARE; } } else if (IsMachineWrongOS()) { psh.nStartPage = PAGE_WRONGOS; } else if (IsMachineOnDomain()) { psh.nStartPage = PAGE_DOMAIN; } else { // Run the real wizard
psh.nStartPage = PAGE_WELCOME; }
INT_PTR iReturn = MyPropertySheet(&psh); *pfRebootRequired = ((iReturn == ID_PSRESTARTWINDOWS) || (iReturn == ID_PSREBOOTSYSTEM));
Uninitialize(); } }
return hr; }
void GetTitleFont(LPTSTR pszFaceName, DWORD cch) { if (!LoadString(g_hinst, IDS_TITLE_FONT, pszFaceName, cch)) { lstrcpyn(pszFaceName, TEXT("Verdana"), cch); } }
LONG GetTitlePointSize() { LONG lPointSize = 0; TCHAR szPointSize[20];
if (LoadString(g_hinst, IDS_TITLE_POINTSIZE, szPointSize, ARRAYSIZE(szPointSize))) { lPointSize = StrToInt(szPointSize); }
if (!lPointSize) { lPointSize = 12; }
return lPointSize; }
void CHomeNetworkWizard::WelcomeSetTitleFont(HWND hwnd) { HWND hwndTitle = GetDlgItem(hwnd, IDC_TITLE);
// Get the existing font
HFONT hfontOld = (HFONT) SendMessage(hwndTitle, WM_GETFONT, 0, 0);
LOGFONT lf = {0}; if (GetObject(hfontOld, sizeof(lf), &lf)) { GetTitleFont(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName));
HDC hDC = GetDC(hwndTitle); if (hDC) { lf.lfHeight = -MulDiv(GetTitlePointSize(), GetDeviceCaps(hDC, LOGPIXELSY), 72); lf.lfWeight = FW_BOLD;
HFONT hfontNew = CreateFontIndirect(&lf); if (hfontNew) { SendMessage(hwndTitle, WM_SETFONT, (WPARAM) hfontNew, FALSE);
// Don't do this, its shared.
// DeleteObject(hfontOld);
}
ReleaseDC(hwndTitle, hDC); } }
LONG lStyle = GetWindowLong(GetParent(hwnd), GWL_STYLE); SetWindowLong(GetParent(hwnd), GWL_STYLE, lStyle & ~WS_SYSMENU); }
INT_PTR CHomeNetworkWizard::WelcomePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->WelcomeSetTitleFont(hwnd); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_NEXT); return TRUE; case PSN_WIZNEXT: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_MANUALCONFIG); if (!g_fRunningOnNT) pthis->PushPage(IDD_WIZ_WIN9X_WELCOME); else pthis->PushPage(IDD_WIZ_WELCOME); return TRUE; } } return FALSE; }
return FALSE; }
INT_PTR CHomeNetworkWizard::NoHardwareWelcomePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->WelcomeSetTitleFont(hwnd); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_HARDWAREREQ); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, 0); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_requirements.htm"); } return TRUE; } } } return FALSE; }
return FALSE; }
void CHomeNetworkWizard::ReplaceStaticWithLink(HWND hwndStatic, UINT idcLinkControl, UINT idsLinkText) { if (g_fRunningOnNT) { RECT rcStatic; HWND hwndParent = GetParent(hwndStatic); if (GetWindowRect(hwndStatic, &rcStatic) && MapWindowPoints(NULL, hwndParent, (LPPOINT) &rcStatic, 2)) { WCHAR szLinkText[256]; if (LoadString(g_hinst, idsLinkText, szLinkText, ARRAYSIZE(szLinkText))) { HWND hwndLink = CreateWindowEx(0, TEXT("SysLink"), szLinkText, WS_CHILD | WS_TABSTOP | LWS_IGNORERETURN, rcStatic.left, rcStatic.top, (rcStatic.right - rcStatic.left), (rcStatic.bottom - rcStatic.top), hwndParent, NULL, g_hinst, NULL);
if (hwndLink) { SetWindowLongPtr(hwndLink, GWLP_ID, (LONG_PTR) idcLinkControl); ShowWindow(hwndLink, SW_SHOW); ShowWindow(hwndStatic, SW_HIDE); } } } } }
void CHomeNetworkWizard::ManualRefreshConnectionList() { if (g_fRunningOnNT) { // Refresh connection DPA in case the user plugged in more connections
HDPA hdpaConnections2; if (SUCCEEDED(GetConnections(&hdpaConnections2))) { // Replace the real list with our new one
DPA_DestroyCallback(_hdpaConnections, FreeConnectionDPACallback, NULL); _hdpaConnections = hdpaConnections2;
// Ensure we remove our other holds to the INetConnections
// Free public lan information
FreeExternalConnection(&_hnetInfo);
// Free private lan information
FreeInternalConnections(&_hnetInfo); } } }
INT_PTR CHomeNetworkWizard::ManualConfigPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_INSTALLATION); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT); return TRUE; case PSN_WIZNEXT: // pthis->ManualRefreshConnectionList();
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_UNPLUGGED); pthis->PushPage(IDD_WIZ_MANUALCONFIG); return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { if (IsOS(OS_PERSONAL)) { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_checklistP.htm"); } else { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_checklistW.htm"); } } return TRUE; } } } return FALSE; }
return FALSE; }
// Returns TRUE if there are some unplugged connections, FALSE o/w
BOOL CHomeNetworkWizard::UnpluggedFillList(HWND hwnd) { BOOL fSomeUnpluggedConnections = FALSE;
HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST); FillConnectionList(hwndList, NULL, CONN_UNPLUGGED);
// and if there actually are unplugged connections...
if (0 != ListView_GetItemCount(hwndList)) { // Show this page
fSomeUnpluggedConnections = TRUE; }
return fSomeUnpluggedConnections; }
INT_PTR CHomeNetworkWizard::UnpluggedPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->InitializeConnectionList(GetDlgItem(hwnd, IDC_CONNLIST), CONN_UNPLUGGED); SendDlgItemMessage(hwnd, IDC_IGNORE, BM_SETCHECK, BST_UNCHECKED, 0); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { // If we don't need to show this page
if (!pthis->UnpluggedFillList(hwnd)) { // Don't push ourselves on the stack
// But navigate to the next page...
SetWindowLongPtr( hwnd, DWLP_MSGRESULT, (pthis->_fExternalOnly) ? IDD_WIZ_CONNECTOTHER : IDD_WIZ_FOUNDICS ); } } return TRUE; case PSN_WIZNEXT: { BOOL fStillUnplugged = pthis->UnpluggedFillList(hwnd); int idNext; if (!fStillUnplugged) { // User fixed the problem. Go forward and don't store this
// error page on the pagestack
idNext = (pthis->_fExternalOnly) ? IDD_WIZ_CONNECTOTHER : IDD_WIZ_FOUNDICS; } else if (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_IGNORE, BM_GETCHECK, 0, 0)) { // User wants to go on, but store this page on the pagestack
// so they can "back" up to it.
pthis->PushPage(IDD_WIZ_UNPLUGGED); idNext = (pthis->_fExternalOnly) ? IDD_WIZ_CONNECTOTHER : IDD_WIZ_FOUNDICS; } else { // User still has disconnected net hardware they don't want to ignore. Tell them and keep them on this page.
DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, IDS_STILLUNPLUGGED, MB_ICONERROR | MB_OK); idNext = -1; }
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, idNext); } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; } } return FALSE; case WM_DESTROY: pthis->DestroyConnectionList(GetDlgItem(hwnd, IDC_CONNLIST)); return TRUE; }
return FALSE; }
void CHomeNetworkWizard::PublicSetControlState(HWND hwnd) { BOOL fSelection = ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_CONNLIST)); PropSheet_SetWizButtons(GetParent(hwnd), fSelection ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK); }
void FreeExternalConnection(PHOMENETSETUPINFO pInfo) { if (pInfo->pncExternal) { pInfo->pncExternal->Release(); pInfo->pncExternal = NULL; } }
void CHomeNetworkWizard::PublicNextPage(HWND hwnd) { FreeExternalConnection(&_hnetInfo);
// Get the selected external adapter
HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST);
int iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
// We can assert here since Next should be disabled if there is no selection!
ASSERT(-1 != iItem);
LVITEM lvi = {0}; lvi.iItem = iItem; lvi.mask = LVIF_PARAM;
if (ListView_GetItem(hwndList, &lvi)) { if (g_fRunningOnNT) { _hnetInfo.pncExternal = (INetConnection*) (lvi.lParam); _hnetInfo.pncExternal->AddRef(); } else { _hnetInfo.ipaExternal = lvi.lParam; } }
// Do the real wizard navigation
UINT idPage = IDD_WIZ_NAME;
if (g_fRunningOnNT) { idPage = _fShowSharingPage ? IDD_WIZ_EDGELESS : IDD_WIZ_ICSCONFLICT; }
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, idPage); }
void CHomeNetworkWizard::FoundIcsSetText(HWND hwnd) { if (GetICSMachine(_szICSMachineName, ARRAYSIZE(_szICSMachineName))) { TCHAR szMsg[256]; if (FormatMessageString(IDS_ICSMSG, szMsg, ARRAYSIZE(szMsg), _szICSMachineName)) { SetWindowText(GetDlgItem(hwnd, IDC_ICSMSG), szMsg); } } else { // No ICS beacon - ask the user how they connect
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) _fNoICSQuestion ? IDD_WIZ_WIN9X_CONNECT : IDD_WIZ_CONNECT); } }
INT_PTR CHomeNetworkWizard::FoundIcsPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: SendMessage(GetDlgItem(hwnd, IDC_SHARECONNECT), BM_SETCHECK, BST_CHECKED, 0); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT); pthis->FoundIcsSetText(hwnd); return TRUE; case PSN_WIZNEXT: { UINT idNext; if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_SHARECONNECT), BM_GETCHECK, 0, 0)) { // This machine should be an ICS Client and won't have a public connection
pthis->_hnetInfo.dwFlags = HNET_SHAREPRINTERS | HNET_SHAREFOLDERS | HNET_ICSCLIENT;
pthis->_fShowPublicPage = FALSE; pthis->_fShowSharingPage = FALSE; pthis->_fICSClient = TRUE;
idNext = g_fRunningOnNT ? IDD_WIZ_ICSCONFLICT : IDD_WIZ_NAME; } else { idNext = pthis->_fNoICSQuestion ? IDD_WIZ_WIN9X_CONNECT : IDD_WIZ_CONNECT; }
pthis->PushPage(IDD_WIZ_FOUNDICS); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, idNext); } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; } } return FALSE; }
return FALSE; }
void CHomeNetworkWizard::ConnectSetDefault(HWND hwnd) { UINT idSelect = IDC_ICSHOST;
if ((!g_fRunningOnNT) || (GetConnectionCount(NULL, CONN_INTERNAL | CONN_EXTERNAL) == 1)) { idSelect = IDC_ICSCLIENT; }
SendDlgItemMessage(hwnd, idSelect, BM_SETCHECK, BST_CHECKED, 0); }
void CHomeNetworkWizard::ConnectNextPage(HWND hwnd) { _fICSClient = FALSE; _fNoHomeNetwork = FALSE;
if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_ICSHOST), BM_GETCHECK, 0, 0)) { // This machine will need a firewalled, public connection, and should be ICS Host.
_hnetInfo.dwFlags = HNET_SHARECONNECTION | HNET_FIREWALLCONNECTION | HNET_SHAREPRINTERS | HNET_SHAREFOLDERS;
_fShowPublicPage = TRUE; _fShowSharingPage = FALSE; } else if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_ICSCLIENT), BM_GETCHECK, 0, 0)) { // This machine should be an ICS Client and won't have a public connection
_hnetInfo.dwFlags = HNET_SHAREPRINTERS | HNET_SHAREFOLDERS | HNET_ICSCLIENT;
_fShowPublicPage = FALSE; _fShowSharingPage = FALSE; _fICSClient = TRUE; } else if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_ALLCOMPUTERSDIRECT), BM_GETCHECK, 0, 0)) { // This machine will need a public connection, and we should ask before sharing files
_hnetInfo.dwFlags = HNET_FIREWALLCONNECTION | HNET_SHAREPRINTERS | HNET_SHAREFOLDERS;
_fShowPublicPage = TRUE; _fShowSharingPage = TRUE; } else if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_NOHOMENETWORK), BM_GETCHECK, 0, 0)) { // This machine needs a firewalled, public connection and not much else
_hnetInfo.dwFlags = HNET_FIREWALLCONNECTION | HNET_SHAREPRINTERS | HNET_SHAREFOLDERS;
_fShowPublicPage = TRUE; _fShowSharingPage = FALSE; _fNoHomeNetwork = TRUE; } else if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_NOINTERNET), BM_GETCHECK, 0, 0)) { // No internet box
_hnetInfo.dwFlags = HNET_SHAREPRINTERS | HNET_SHAREFOLDERS; _fShowPublicPage = FALSE; _fShowSharingPage = FALSE; }
UINT idNext; if (g_fRunningOnNT) { if (BST_CHECKED == SendMessage(GetDlgItem(hwnd, IDC_OTHER), BM_GETCHECK, 0, 0)) { idNext = IDD_WIZ_CONNECTOTHER; } else { idNext = _fShowPublicPage ? IDD_WIZ_PUBLIC : IDD_WIZ_ICSCONFLICT; } } else { // For now - TODO: Ed and I need to figure out what we need to do downlevel (9x + 2k)
idNext = IDD_WIZ_NAME; }
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, idNext); }
INT_PTR CHomeNetworkWizard::ConnectPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_HNCONFIG); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC1), IDC_SHOWMELINK1, IDS_SHOWME); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC2), IDC_SHOWMELINK2, IDS_SHOWME); pthis->ConnectSetDefault(hwnd); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT); return TRUE; case PSN_WIZNEXT: { pthis->PushPage(pthis->_fNoICSQuestion ? IDD_WIZ_WIN9X_CONNECT : IDD_WIZ_CONNECT); pthis->ConnectNextPage(hwnd); } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { if (IsOS(OS_PERSONAL)) { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_howto_connectP.htm"); } else { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_howto_connectW.htm"); }
} return TRUE; case IDC_SHOWMELINK1: { pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme1.htm"); } return TRUE; case IDC_SHOWMELINK2: { pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme2.htm"); } return TRUE; } } } return FALSE; }
return FALSE; }
INT_PTR CHomeNetworkWizard::ConnectOtherPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: if ( pthis->_fExternalOnly ) { TraceMsg(TF_WARNING, "External Adapters Only"); }
SendDlgItemMessage(hwnd, IDC_ALLCOMPUTERSDIRECT, BM_SETCHECK, (WPARAM) BST_CHECKED, 0); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_HNCONFIG); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC3), IDC_SHOWMELINK3, IDS_SHOWME); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC4), IDC_SHOWMELINK4, IDS_SHOWME); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_SHOWMESTATIC5), IDC_SHOWMELINK5, IDS_SHOWME); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT); return TRUE; case PSN_WIZNEXT: { pthis->PushPage(IDD_WIZ_CONNECTOTHER); pthis->ConnectNextPage(hwnd); } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { HelpCenter(hwnd, L"netcfg.chm%3A%3A/share_conn_overvw.htm"); } return TRUE; case IDC_SHOWMELINK3: { pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme3.htm"); } return TRUE; case IDC_SHOWMELINK4: { pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme4.htm"); } return TRUE; case IDC_SHOWMELINK5: { pthis->ShowMeLink(hwnd, L"ntart.chm::/hn_showme5.htm"); } return TRUE; } } } return FALSE; }
return FALSE; }
void CHomeNetworkWizard::DestroyConnectionList(HWND hwndList) { if (g_fRunningOnNT) { int nItems = ListView_GetItemCount(hwndList);
for (int iItem = 0; iItem < nItems; iItem ++) { // Get our stashed INetConnection for each item in the list and free it
LVITEM lvi = {0}; lvi.mask = LVIF_PARAM; lvi.iItem = iItem;
if (ListView_GetItem(hwndList, &lvi)) { ((INetConnection*) lvi.lParam)->Release(); } } }
ListView_DeleteAllItems(hwndList); }
inline void _SetDlgItemRect(HWND hwnd, UINT id, RECT* pRect) { SetWindowPos(GetDlgItem(hwnd, id), NULL, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top, SWP_NOZORDER | SWP_SHOWWINDOW); }
void _OffsetDlgItem(HWND hwnd, UINT id, int xOffset, int yOffset, BOOL fAdjustWidth, BOOL fAdjustHeight) { RECT rc; HWND hwndControl = GetDlgItem(hwnd, id); GetWindowRect(hwndControl, &rc); MapWindowPoints(NULL, hwnd, (LPPOINT) &rc, 2); OffsetRect(&rc, xOffset, yOffset);
if (fAdjustWidth) { rc.right -= xOffset; }
if (fAdjustHeight) { rc.bottom -= yOffset; }
_SetDlgItemRect(hwnd, id, &rc); }
void CHomeNetworkWizard::PublicMoveControls(HWND hwnd, BOOL fItemPreselected) { // We need to move controls around on this page depending on whether or not an item is preselected or not
// Reset the dialog so that all controls are in their default positions
PublicResetControlPositions(hwnd);
if (fItemPreselected) { // We are transitioning from the "default" position to one where an item is preselected.
// The only work we do here is to hide the help icon and move over the help text a bit to the left
int xOffset = (PublicControlPositions._rcHelpIcon.left) - (PublicControlPositions._rcHelpText.left); UINT idHelp = IsWindowVisible(GetDlgItem(hwnd, IDC_HELPSTATIC)) ? IDC_HELPSTATIC : IDC_HELPLINK; _OffsetDlgItem(hwnd, idHelp, xOffset, 0, TRUE, FALSE); ShowWindow(GetDlgItem(hwnd, IDC_HELPICON), SW_HIDE); } else { // We are transitioning from the "default" position to the one where we don't have a preselection
// We need to hide the "we've automatically selected..." message and move up the list label,
// and expand the connection list.
int yOffset = (PublicControlPositions._rcSelectMessage.top) - (PublicControlPositions._rcListLabel.top); _OffsetDlgItem(hwnd, IDC_LISTLABEL, 0, yOffset, FALSE, FALSE); _OffsetDlgItem(hwnd, IDC_CONNLIST, 0, yOffset, FALSE, TRUE); ShowWindow(GetDlgItem(hwnd, IDC_SELECTMSG), SW_HIDE); } }
void CHomeNetworkWizard::PublicSetActive(HWND hwnd) { HCURSOR hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT)); FreeExternalConnection(&_hnetInfo);
HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST); FillConnectionList(hwndList, NULL, CONN_EXTERNAL);
// Auto-select if there is only one connection listed
if (ListView_GetItemCount(hwndList) == 1 #ifdef DEBUG
&& !(GetKeyState(VK_CONTROL) < 0) // don't do this if CTRL is down for debugging
#endif
) { ListView_SetItemState(hwndList, 0, LVIS_SELECTED, LVIS_SELECTED);
// PublicNextPage will set DWLP_MSGRESULT and tell the wizard to skip this page
// and go on to the next.
PublicNextPage(hwnd); } else { // If there is a selected item
int iSelectedItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); if (-1 != iSelectedItem) { // Read the item name and set the alternate "Windows recommends this connection." text
WCHAR szItem[256], szMsg[256]; ListView_GetItemText(hwndList, iSelectedItem, 0, szItem, ARRAYSIZE(szItem)); FormatMessageString(IDS_RECOMMENDEDCONN, szMsg, ARRAYSIZE(szMsg), szItem); SetDlgItemText(hwnd, IDC_SELECTMSG, szMsg);
BoldControl(hwnd, IDC_SELECTMSG); }
PublicMoveControls(hwnd, (-1 != iSelectedItem)); PublicSetControlState(hwnd); }
if(NULL != hOldCursor) { SetCursor(hOldCursor); } }
void CHomeNetworkWizard::PublicGetControlPositions(HWND hwnd) { // Remember the default positions of the controls that will move as we reorganize this dialog
GetWindowRect(GetDlgItem(hwnd, IDC_SELECTMSG), &PublicControlPositions._rcSelectMessage); GetWindowRect(GetDlgItem(hwnd, IDC_LISTLABEL), &PublicControlPositions._rcListLabel); GetWindowRect(GetDlgItem(hwnd, IDC_CONNLIST), &PublicControlPositions._rcList); GetWindowRect(GetDlgItem(hwnd, IDC_HELPICON), &PublicControlPositions._rcHelpIcon); GetWindowRect(GetDlgItem(hwnd, IDC_HELPSTATIC), &PublicControlPositions._rcHelpText);
// We actually need them in client coords
// Map 2 points (1 rect) at a time since Mirrored points get screwed up with more
MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcSelectMessage, 2); MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcListLabel, 2); MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcList, 2); MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcHelpIcon, 2); MapWindowPoints(NULL, hwnd, (LPPOINT) &PublicControlPositions._rcHelpText, 2); }
void CHomeNetworkWizard::PublicResetControlPositions(HWND hwnd) { // Set the controls back to their default positions
_SetDlgItemRect(hwnd, IDC_SELECTMSG, &PublicControlPositions._rcSelectMessage); _SetDlgItemRect(hwnd, IDC_LISTLABEL, &PublicControlPositions._rcListLabel); _SetDlgItemRect(hwnd, IDC_CONNLIST, &PublicControlPositions._rcList); _SetDlgItemRect(hwnd, IDC_HELPICON, &PublicControlPositions._rcHelpIcon);
UINT idHelp = IsWindowVisible(GetDlgItem(hwnd, IDC_HELPSTATIC)) ? IDC_HELPSTATIC : IDC_HELPLINK; _SetDlgItemRect(hwnd, idHelp, &PublicControlPositions._rcHelpText); }
INT_PTR CHomeNetworkWizard::PublicPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->InitializeConnectionList(GetDlgItem(hwnd, IDC_CONNLIST), CONN_EXTERNAL); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_SELECTPUBLIC); pthis->PublicGetControlPositions(hwnd); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { pthis->PublicSetActive(hwnd); return TRUE; } case PSN_WIZNEXT: pthis->PushPage(IDD_WIZ_PUBLIC); pthis->PublicNextPage(hwnd); return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case LVN_ITEMCHANGED: pthis->PublicSetControlState(hwnd); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_determine_internet_connection.htm"); } return TRUE; } } } return FALSE; case WM_DESTROY: pthis->DestroyConnectionList(GetDlgItem(hwnd, IDC_CONNLIST)); return TRUE; }
return FALSE; }
void CHomeNetworkWizard::EdgelessSetActive(HWND hwnd) { PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK | PSWIZB_NEXT); // _hnetInfo.dwFlags &= (~(HNET_SHAREFOLDERS | HNET_SHAREPRINTERS));
if (!ShouldShowConnection(_hnetInfo.pncExternal, NULL, CONN_INTERNAL)) { // External connection is a modem or such - no file sharing necessary (user already said they didn't have a home network)
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_ICSCONFLICT); } }
INT_PTR CHomeNetworkWizard::EdgelessPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_RECOMMENDED); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: pthis->EdgelessSetActive(hwnd); return TRUE; case PSN_WIZNEXT: pthis->_hnetInfo.dwFlags |= (HNET_SHAREFOLDERS | HNET_SHAREPRINTERS); pthis->PushPage(IDD_WIZ_EDGELESS); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) IDD_WIZ_BRIDGEWARNING); return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { if (IsOS(OS_PERSONAL)) { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_nohost_computerP.htm"); } else { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_nohost_computerW.htm"); } } return TRUE; } } } return FALSE; } return FALSE; }
BOOL CHomeNetworkWizard::IsICSIPInUse( WCHAR** ppszHost, PDWORD pdwSize ) { HRESULT hr; INetConnection** ppArray = NULL; DWORD dwItems = 0; BOOL bExists = FALSE;
if ( ppszHost ) *ppszHost = NULL;
if ( pdwSize ) *pdwSize = 0;
hr = GetInternalConnectionArray( _hnetInfo.pncExternal, &ppArray, &dwItems ); if ( SUCCEEDED(hr) ) { hr = E_FAIL; for( DWORD i=0; i<dwItems; i++ ) { if ( S_OK != hr ) { hr = HrLookupForIpAddress( ppArray[i], DEFAULT_SCOPE_ADDRESS, &bExists, ppszHost, pdwSize ); } ppArray[i]->Release(); } // for( DWORD i=0; i<dwItems; i++ )
LocalFree( ppArray );
} // if ( SUCCEEDED(hr) )
return bExists; }
void CHomeNetworkWizard::ICSConflictSetActive(HWND hwnd) { WCHAR* pszConflictingHost = NULL; DWORD dwSize = 0;
PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK | PSWIZB_NEXT);
static const int _KnownControls[] = { IDC_KNOWNCONFLICT1, IDC_KNOWNCONFLICT2, IDC_KNOWNCONFLICT3, IDC_KNOWNCONFLICT4, IDC_KNOWNCONFLICT5, IDC_KNOWNCONFLICT6, IDC_KNOWNCONFLICT7, IDC_KNOWNCONFLICT8, IDC_COMPUTERNAME };
static const int _UnknownControls[] = { IDC_UNKNOWNCONFLICT1, IDC_UNKNOWNCONFLICT2 }; if ((_hnetInfo.dwFlags & HNET_SHARECONNECTION) && IsICSIPInUse(&pszConflictingHost, &dwSize)) { // We show and hide controls depending on if we already know about an ICS machine name
WCHAR szICSHost[MAX_PATH]; if (GetICSMachine(szICSHost, ARRAYSIZE(szICSHost))) { // We know this is a UPnP ICS host - show the "known conflict" set of controls
ShowControls(hwnd, _KnownControls, ARRAYSIZE(_KnownControls), SW_SHOWNORMAL); ShowControls(hwnd, _UnknownControls, ARRAYSIZE(_UnknownControls), SW_HIDE); SetDlgItemText(hwnd, IDC_COMPUTERNAME, szICSHost); } else { // We have no idea what's hogging our IP - show a very generic set of controls
ShowControls(hwnd, _UnknownControls, ARRAYSIZE(_UnknownControls), SW_SHOWNORMAL); ShowControls(hwnd, _KnownControls, ARRAYSIZE(_KnownControls), SW_HIDE); } } else { // Go on to the next screen
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_BRIDGEWARNING); }
if ( pszConflictingHost ) delete [] pszConflictingHost; }
INT_PTR CHomeNetworkWizard::ICSConflictPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_ICSCONFLICT); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam; WCHAR* pszConflictingHost = NULL; DWORD dwSize = 0;
switch (pnmh->code) { case PSN_SETACTIVE: pthis->ICSConflictSetActive(hwnd); return TRUE; case PSN_WIZNEXT: if (pthis->IsICSIPInUse(&pszConflictingHost, &dwSize)) { DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, IDS_STILLICSCONFLICT, MB_ICONERROR | MB_OK); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, -1); } else { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) IDD_WIZ_BRIDGEWARNING); } if ( pszConflictingHost ) delete [] pszConflictingHost; return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_change_ics_host.htm"); } return TRUE; } } } return FALSE; } return FALSE; }
DWORD CHomeNetworkWizard::GetConnectionCount(INetConnection* pncExclude, DWORD dwFlags) { DWORD dwCount = 0;
if (g_fRunningOnNT) { DWORD cItems = DPA_GetPtrCount(_hdpaConnections); for (DWORD iItem = 0; iItem < cItems; iItem ++) { INetConnection* pnc = (INetConnection*) DPA_GetPtr(_hdpaConnections, iItem); if (ShouldShowConnection(pnc, pncExclude, dwFlags)) { dwCount++; } } } else { const NETADAPTER* pNA = _hnetInfo.pNA;
for (UINT i = 0; i < _hnetInfo.cNA; i++, pNA++) { // Check if the NIC is working.
if (W9xIsValidAdapter(pNA, dwFlags)) { dwCount++; } } }
return dwCount; }
INT_PTR CHomeNetworkWizard::BridgeWarningPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: SendDlgItemMessage(hwnd, IDC_AUTOBRIDGE, BM_SETCHECK, (WPARAM) BST_CHECKED, 0); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_BRIDGE); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { if (pthis->_fNoHomeNetwork) { FreeInternalConnections(&pthis->_hnetInfo); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_NAME); } else { DWORD nInternal = pthis->GetConnectionCount(pthis->_hnetInfo.pncExternal, CONN_INTERNAL); if (1 < nInternal) { // We show this page if there are two or more internal connections (which is this case)
PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT); } else if ((pthis->_hnetInfo.dwFlags & HNET_SHARECONNECTION) && (0 == nInternal)) { // We are sharing the public connection, and there are no other connections left
// over for home networking. Show error page
pthis->_fManualBridgeConfig = FALSE; SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_NOHARDWAREFINISH); } else { // There are either zero or one internal connections. If zero, then we aren't sharing the connection
// Skip the bridge warning page and go to the private page
pthis->_fManualBridgeConfig = FALSE; SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_PRIVATE); } }
return TRUE; } case PSN_WIZNEXT: { pthis->_fManualBridgeConfig = (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_MANUALBRIDGE, BM_GETCHECK, 0, 0)); pthis->PushPage(IDD_WIZ_BRIDGEWARNING); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_PRIVATE); } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { HelpCenter(hwnd, L"netcfg.chm%3A%3A/hnw_understanding_bridge.htm"); } return TRUE; } } } return FALSE; }
return FALSE; }
void FreeInternalConnections(PHOMENETSETUPINFO pInfo) { // Delete any existing private connection information
if (pInfo->prgncInternal) { for (DWORD i = 0; i < pInfo->cncInternal; i++) { INetConnection* pnc = pInfo->prgncInternal[i]; pnc->Release(); }
LocalFree(pInfo->prgncInternal); pInfo->prgncInternal = NULL; }
pInfo->cncInternal = 0; }
void FreeInternalGUIDs(PHOMENETSETUPINFO pInfo) { if (pInfo->prgguidInternal) { LocalFree(pInfo->prgguidInternal); pInfo->prgguidInternal = NULL; }
pInfo->cguidInternal = 0; }
DWORD _ListView_GetCheckedCount(HWND hwndList) { int nItems = ListView_GetItemCount(hwndList); DWORD nCheckedItems = 0; if (-1 != nItems) { for(int iItem = 0; iItem < nItems; iItem ++) { if (ListView_GetCheckState(hwndList, iItem)) { nCheckedItems ++; } } }
return nCheckedItems; }
void CHomeNetworkWizard::PrivateSetControlState(HWND hwnd) { BOOL fEnableNext = TRUE;
// If the user is sharing a connection, they must specify at least one private connection
if (_hnetInfo.dwFlags & HNET_SHARECONNECTION) { fEnableNext = (0 != _ListView_GetCheckedCount(GetDlgItem(hwnd, IDC_CONNLIST))); }
PropSheet_SetWizButtons(GetParent(hwnd), fEnableNext ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK); }
void CHomeNetworkWizard::PrivateNextPage(HWND hwnd) { FreeInternalConnections(&_hnetInfo);
// Figure out the number of connections we'll need
HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST); int nItems = ListView_GetItemCount(hwndList); DWORD nCheckedItems = _ListView_GetCheckedCount(hwndList);
if (nCheckedItems) { _hnetInfo.prgncInternal = (INetConnection**) LocalAlloc(LPTR, (nCheckedItems + 1) * sizeof (INetConnection*)); // Alloc one extra INetConnection* and Null-terminate this array so we can pass it to HNet config api
if (_hnetInfo.prgncInternal) { _hnetInfo.cncInternal = 0; // Get the INetConnection for each checked item
for (int iItem = 0; iItem < nItems; iItem ++) { if (ListView_GetCheckState(hwndList, iItem)) { LVITEM lvi = {0}; lvi.iItem = iItem; lvi.mask = LVIF_PARAM; ListView_GetItem(hwndList, &lvi);
if (g_fRunningOnNT) { _hnetInfo.prgncInternal[_hnetInfo.cncInternal] = (INetConnection*) lvi.lParam; _hnetInfo.prgncInternal[_hnetInfo.cncInternal]->AddRef(); } else { // TODO W9x
} _hnetInfo.cncInternal ++; } }
// Assert since if we messed something up there might not be enough space allocated in the buffer!
ASSERT(nCheckedItems == _hnetInfo.cncInternal); } }
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_NAME); }
INT_PTR CHomeNetworkWizard::PrivatePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->InitializeConnectionList(GetDlgItem(hwnd, IDC_CONNLIST), CONN_INTERNAL); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_BRIDGE); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { FreeInternalConnections(&(pthis->_hnetInfo));
HWND hwndList = GetDlgItem(hwnd, IDC_CONNLIST); pthis->FillConnectionList(hwndList, pthis->_hnetInfo.pncExternal, CONN_INTERNAL);
// If the user hasn't select manual bridge and/or there is less than 2 items,
// then _fManualBridgeConfig will be FALSE and we'll autobridge
if (!pthis->_fManualBridgeConfig) { // PrivateNextPage will set DWLP_MSGRESULT and tell the wizard to skip this page
// and go on to the next.
pthis->PrivateNextPage(hwnd); }
pthis->PrivateSetControlState(hwnd); return TRUE; } case PSN_WIZNEXT: pthis->PrivateNextPage(hwnd); pthis->PushPage(IDD_WIZ_PRIVATE); return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { HelpCenter(hwnd, L"netcfg.chm%3A%3A/hnw_understanding_bridge.htm"); } return TRUE; } case LVN_ITEMCHANGED: pthis->PrivateSetControlState(hwnd); return TRUE; } } return FALSE; case WM_DESTROY: pthis->DestroyConnectionList(GetDlgItem(hwnd, IDC_CONNLIST)); return FALSE; }
return FALSE; }
void CHomeNetworkWizard::NameSetControlState(HWND hwnd) { BOOL fEnableNext = (0 != GetWindowTextLength(GetDlgItem(hwnd, IDC_COMPUTERNAME))); PropSheet_SetWizButtons(GetParent(hwnd), fEnableNext ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK); }
HRESULT CHomeNetworkWizard::NameNextPage(HWND hwnd) { HRESULT hr = E_FAIL; GetDlgItemText(hwnd, IDC_COMPUTERDESC, _hnetInfo.szComputerDescription, ARRAYSIZE(_hnetInfo.szComputerDescription)); GetDlgItemText(hwnd, IDC_COMPUTERNAME, _hnetInfo.szComputer, ARRAYSIZE(_hnetInfo.szComputer)); // There are two errors that we show for computer name: INVALID and DUPLICATE
// TODO: We only detect duplicate for NT so far!!!
UINT idError = IDS_COMPNAME_INVALID;
// Test to see if the name is more than 15 OEM bytes
int iBytes = WideCharToMultiByte(CP_OEMCP, 0, _hnetInfo.szComputer, -1, NULL, 0, NULL, NULL) - 1; if (iBytes <= LM20_DNLEN) { if (IsValidNameSyntax(_hnetInfo.szComputer, NetSetupMachine)) { if (g_fRunningOnNT) { SetCursor(LoadCursor(NULL, IDC_WAIT)); NET_API_STATUS nas = NetValidateName(NULL, _hnetInfo.szComputer, NULL, NULL, NetSetupMachine); if (ERROR_DUP_NAME == nas) { ASSERT(E_FAIL == hr); idError = IDS_COMPNAME_DUPLICATE; } else if (NERR_InvalidComputer == nas) { ASSERT(E_FAIL == hr); idError = IDS_COMPNAME_INVALID; } else { // if there is any other failure we just go ahead. If the Client For MS Networks is not installed we
// can't validate the name, but it should be fine to use what we have
hr = S_OK; _hnetInfo.dwFlags |= HNET_SETCOMPUTERNAME; } } else { // TODO: Win9x!!!
hr = S_OK; _hnetInfo.dwFlags |= HNET_SETCOMPUTERNAME; } } } else { ASSERT(E_FAIL == hr); idError = IDS_COMPNAME_TOOMANYBYTES; }
// If the computer name didn't validate, don't change pages and show an error.
if(FAILED(hr)) { SetFocus(GetDlgItem(hwnd, IDC_COMPUTERNAME)); PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK); DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, idError, MB_ICONERROR | MB_OK, _hnetInfo.szComputer); }
return hr; }
void CHomeNetworkWizard::NameInitDialog(HWND hwnd) { // Limit the edit fields
SendDlgItemMessage(hwnd, IDC_COMPUTERDESC, EM_SETLIMITTEXT, ARRAYSIZE(_hnetInfo.szComputerDescription) - 1, NULL); SendDlgItemMessage(hwnd, IDC_COMPUTERNAME, EM_SETLIMITTEXT, ARRAYSIZE(_hnetInfo.szComputer) - 1, NULL);
// Set the current name as the default
WCHAR szComputerName[ARRAYSIZE(_hnetInfo.szComputer)]; *szComputerName = 0;
WCHAR szDescription[ARRAYSIZE(_hnetInfo.szComputerDescription)]; *szDescription = 0;
if (g_fRunningOnNT) { SERVER_INFO_101_NT* psv101 = NULL; if (NERR_Success == NetServerGetInfo_NT(NULL, 101, (LPBYTE*) &psv101)) { if (psv101->sv101_comment && psv101->sv101_comment[0]) { StrCpyN(szDescription, psv101->sv101_comment, ARRAYSIZE(szDescription)); }
ASSERT(psv101->sv101_name); StrCpyN(szComputerName, psv101->sv101_name, ARRAYSIZE(szComputerName)); NetApiBufferFree(psv101); } } else { AllPlatformGetComputerName(szComputerName, ARRAYSIZE(szComputerName));
CRegistry reg; if (reg.OpenKey(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\VxD\\VNETSUP", KEY_READ)) { reg.QueryStringValue(L"Comment", szDescription, ARRAYSIZE(szDescription)); } }
SetDlgItemText(hwnd, IDC_COMPUTERNAME, szComputerName); SetDlgItemText(hwnd, IDC_COMPUTERDESC, szDescription);
WCHAR szNameMessage[256]; if (FormatMessageString(IDS_CURRENTNAME, szNameMessage, ARRAYSIZE(szNameMessage), szComputerName)) { SetDlgItemText(hwnd, IDC_CURRENTNAME, szNameMessage); } }
INT_PTR CHomeNetworkWizard::NamePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->NameInitDialog(hwnd); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_COMPNAME); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { // Show the ISP Warning if this computer connects directly to the Internet
int nShowISPWarning = (NULL != pthis->_hnetInfo.pncExternal) ? SW_SHOW : SW_HIDE; ShowWindow(GetDlgItem(hwnd, IDC_ISPWARN1), nShowISPWarning); ShowWindow(GetDlgItem(hwnd, IDC_ISPWARN2), nShowISPWarning);
pthis->NameSetControlState(hwnd); } return TRUE; case PSN_WIZNEXT: if (SUCCEEDED(pthis->NameNextPage(hwnd))) { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) IDD_WIZ_WORKGROUP); pthis->PushPage(IDD_WIZ_NAME); } else { // else not changing pages; don't push
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1); } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: { HelpCenter(hwnd, L"network.chm%3A%3A/hnw_comp_name_description.htm"); } return TRUE; } } } return FALSE; case WM_COMMAND: { switch (HIWORD(wParam)) { case EN_CHANGE: if (LOWORD(wParam) == IDC_COMPUTERNAME) { pthis->NameSetControlState(hwnd); } return FALSE; } } return FALSE; }
return FALSE; }
void CHomeNetworkWizard::WorkgroupSetControlState(HWND hwnd) { BOOL fNext = (0 != SendDlgItemMessage(hwnd, IDC_WORKGROUP, WM_GETTEXTLENGTH, 0, 0)); PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK | (fNext ? PSWIZB_NEXT : 0)); }
HRESULT CHomeNetworkWizard::WorkgroupNextPage(HWND hwnd) { HRESULT hr = E_FAIL;
UINT idError = IDS_WORKGROUP_INVALID; if (GetDlgItemText(hwnd, IDC_WORKGROUP, _hnetInfo.szWorkgroup, ARRAYSIZE(_hnetInfo.szWorkgroup))) { // Test to see if the name is more than 15 OEM bytes
int iBytes = WideCharToMultiByte(CP_OEMCP, 0, _hnetInfo.szWorkgroup, -1, NULL, 0, NULL, NULL) - 1; if (iBytes <= LM20_DNLEN) { // Remove any preceding blanks
size_t szLen = wcslen( _hnetInfo.szWorkgroup ) + 1; LPWSTR szTemp = new WCHAR[ szLen ]; if ( szTemp ) { WCHAR* pch; for ( pch = _hnetInfo.szWorkgroup; *pch && (L' ' == *pch); ) pch++; wcsncpy( szTemp, pch, szLen ); wcsncpy( _hnetInfo.szWorkgroup, szTemp, szLen ); delete [] szTemp; } // Use the computer name check for workgroups too
if (IsValidNameSyntax(_hnetInfo.szWorkgroup, NetSetupWorkgroup)) { if (g_fRunningOnNT) { SetCursor(LoadCursor(NULL, IDC_WAIT)); NET_API_STATUS nas = NetValidateName(NULL, _hnetInfo.szWorkgroup, NULL, NULL, NetSetupWorkgroup); if (NERR_InvalidWorkgroupName != nas) // we only put up a invalid name dialog if the name was invalid.
{ hr = S_OK; _hnetInfo.dwFlags |= HNET_SETWORKGROUPNAME; } } else { // TODO: Win9x!!!
hr = S_OK; _hnetInfo.dwFlags |= HNET_SETWORKGROUPNAME; } } } else { ASSERT(E_FAIL == hr); idError = IDS_WORKGROUP_TOOMANYBYTES; }
// If the computer name didn't validate, don't change pages and show an error.
if(FAILED(hr)) { SetFocus(GetDlgItem(hwnd, IDC_WORKGROUP)); PropSheet_SetWizButtons(GetParent(hwnd), PSWIZB_BACK); DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, idError, MB_ICONERROR | MB_OK, _hnetInfo.szWorkgroup); } }
return hr; }
INT_PTR CHomeNetworkWizard::WorkgroupPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: { WCHAR szWorkgroup[LM20_DNLEN + 1]; *szWorkgroup = 0; LoadString(g_hinst, IDS_DEFAULT_WORKGROUP1, szWorkgroup, ARRAYSIZE(szWorkgroup)); SetDlgItemText(hwnd, IDC_WORKGROUP, szWorkgroup); SendDlgItemMessage(hwnd, IDC_WORKGROUP, EM_LIMITTEXT, ARRAYSIZE(pthis->_hnetInfo.szWorkgroup) - 1, 0); } return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { pthis->WorkgroupSetControlState(hwnd); pthis->_hnetInfo.dwFlags &= (~HNET_SETWORKGROUPNAME); } return TRUE; case PSN_WIZNEXT: { if (SUCCEEDED(pthis->WorkgroupNextPage(hwnd))) { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) IDD_WIZ_SUMMARY); pthis->PushPage(IDD_WIZ_WORKGROUP); } else { // else not changing pages; don't push
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1); } } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; } } return FALSE; case WM_COMMAND: { switch (HIWORD(wParam)) { case EN_CHANGE: if (LOWORD(wParam) == IDC_WORKGROUP) { pthis->WorkgroupSetControlState(hwnd); } return FALSE; } } return FALSE; }
return FALSE; }
INT_PTR CHomeNetworkWizard::SummaryPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: { return TRUE; } case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_QUERYINITIALFOCUS: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) GetDlgItem(hwnd, IDC_TITLE)); return TRUE; case PSN_SETACTIVE: pthis->SummarySetActive(hwnd); PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT); return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case PSN_WIZNEXT: pthis->PushPage(IDD_WIZ_SUMMARY); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_PROGRESS); return TRUE; } } return FALSE; }
return FALSE; }
#define WM_CONFIGDONE (WM_USER + 0x100)
INT_PTR CHomeNetworkWizard::ProgressPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: { return TRUE; } case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { PropSheet_CancelToClose(GetParent(hwnd)); PropSheet_SetWizButtons(pnmh->hwndFrom, 0);
pthis->_hnetInfo.fAsync = TRUE; pthis->_hnetInfo.hwnd = hwnd; pthis->_hnetInfo.umsgAsyncNotify = WM_CONFIGDONE;
ConfigureHomeNetwork(&(pthis->_hnetInfo));
HWND hwndAnimate = GetDlgItem(hwnd, IDC_PROGRESS); Animate_Open(hwndAnimate, g_fRunningOnNT ? IDA_CONFIG : IDA_LOWCOLORCONFIG); Animate_Play(hwndAnimate, 0, -1, -1); }
return TRUE; } } return FALSE; case WM_CONFIGDONE: { Animate_Stop(GetDlgItem(hwnd, IDC_PROGRESS));
// The config thread has finished. We assert that the thread has freed/nulled out
// all of his INetConnection*'s since otherwise the UI thread will try to use/free them!
ASSERT(NULL == pthis->_hnetInfo.pncExternal); ASSERT(NULL == pthis->_hnetInfo.prgncInternal);
if (pthis->_hnetInfo.fRebootRequired) { PropSheet_RebootSystem(GetParent(hwnd)); }
// The HRESULT from the configuration is stored in wParam
HRESULT hr = (HRESULT) wParam; UINT idFinishPage;
if (SUCCEEDED(hr)) { idFinishPage = IDD_WIZ_ALMOSTDONE; } else { idFinishPage = IDD_WIZ_CONFIGERROR; }
PropSheet_SetCurSelByID(GetParent(hwnd), idFinishPage); } return TRUE; }
return FALSE; }
INT_PTR CHomeNetworkWizard::AlmostDonePageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: { SendDlgItemMessage(hwnd, IDC_CREATEDISK, BM_SETCHECK, BST_CHECKED, 0); return TRUE; } case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { if (g_fRunningOnNT) { PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_NEXT); } else { // Skip this page on 9x
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_WIN9X_FINISH); } } return TRUE; case PSN_WIZNEXT: { // This page only shows on NT
ASSERT(g_fRunningOnNT); pthis->_fFloppyInstructions = TRUE; pthis->PushPage(IDD_WIZ_ALMOSTDONE);
UINT idNext = IDD_WIZ_FINISH; if (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_CREATEDISK, BM_GETCHECK, 0, 0)) { idNext = IDD_WIZ_CHOOSEDISK; } else if (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_HAVEDISK, BM_GETCHECK, 0, 0)) { idNext = IDD_WIZ_FLOPPYINST; } else if (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_HAVECD, BM_GETCHECK, 0, 0)) { idNext = IDD_WIZ_CDINST; pthis->_fFloppyInstructions = FALSE; }
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) idNext); } return TRUE; } } return FALSE; }
return FALSE; }
void CHomeNetworkWizard::FillDriveList(HWND hwndList) { ListView_SetImageList(hwndList, _himlLarge, LVSIL_NORMAL);
ListView_DeleteAllItems(hwndList);
WCHAR szDrive[] = L"A:\\"; for (UINT i = 0; i < 26; i++) { szDrive[0] = L'A' + i;
if (DRIVE_REMOVABLE == GetDriveType(szDrive)) { LVITEM lvi = {0}; lvi.mask = LVIF_PARAM | LVIF_TEXT; lvi.lParam = i;
int iIndex; WCHAR szDriveDisplay[256]; HRESULT hr = GetDriveNameAndIconIndex(szDrive, szDriveDisplay, ARRAYSIZE(szDriveDisplay), &iIndex); if (SUCCEEDED(hr)) { lvi.iImage = iIndex; if (-1 != lvi.iImage) lvi.mask |= LVIF_IMAGE;
lvi.pszText = szDriveDisplay;
int iItem = ListView_InsertItem(hwndList, &lvi); } } }
ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE); ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); }
void CHomeNetworkWizard::ChooseDiskSetControlState(HWND hwnd) { BOOL fSelection = ListView_GetSelectedCount(GetDlgItem(hwnd, IDC_DEVICELIST)); PropSheet_SetWizButtons(GetParent(hwnd), fSelection ? PSWIZB_BACK | PSWIZB_NEXT : PSWIZB_BACK); }
INT_PTR CHomeNetworkWizard::ChooseDiskPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: ASSERT(g_fRunningOnNT); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_QUERYINITIALFOCUS: SetFocus(GetDlgItem(hwnd, IDC_DEVICELIST)); return TRUE; case PSN_SETACTIVE: { HWND hwndList = GetDlgItem(hwnd, IDC_DEVICELIST); pthis->FillDriveList(hwndList); pthis->ChooseDiskSetControlState(hwnd);
int cDrives = ListView_GetItemCount(hwndList);
if (0 >= cDrives) { // There are no removable drives or an error occurred
DisplayFormatMessage(hwnd, IDS_WIZ_CAPTION, IDS_NOREMOVABLEDRIVES, MB_ICONINFORMATION | MB_OK); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); } else if (1 == cDrives) { // One drive - autoselect it and go to the next page
LVITEM lvi = {0}; lvi.mask = LVIF_PARAM; ListView_GetItem(hwndList, &lvi); pthis->_iDrive = lvi.lParam; ListView_GetItemText(hwndList, lvi.iItem, 0, pthis->_szDrive, ARRAYSIZE(pthis->_szDrive)); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_INSERTDISK); } } return TRUE; case PSN_WIZNEXT: { HWND hwndList = GetDlgItem(hwnd, IDC_DEVICELIST); pthis->_iDrive = 0; LVITEM lvi = {0}; lvi.mask = LVIF_PARAM; lvi.iItem = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); if (-1 != lvi.iItem && ListView_GetItem(hwndList, &lvi)) { pthis->_iDrive = lvi.lParam; ListView_GetItemText(hwndList, lvi.iItem, 0, pthis->_szDrive, ARRAYSIZE(pthis->_szDrive)); pthis->PushPage(IDD_WIZ_CHOOSEDISK); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_INSERTDISK); } } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case LVN_ITEMCHANGED: pthis->ChooseDiskSetControlState(hwnd); return TRUE; } } return FALSE; }
return FALSE; }
#define SOURCE_FILE "%windir%\\system32\\netsetup.exe"
HRESULT CHomeNetworkWizard::GetSourceFilePath(LPSTR pszSource, DWORD cch) { HRESULT hr = E_FAIL;
if (ExpandEnvironmentStringsA(SOURCE_FILE, pszSource, cch)) { DWORD c = lstrlenA(pszSource); if (c + 2 <= cch) { // Add double NULL since we'll be passing this to SHFileOperation
pszSource[c + 1] = '\0'; hr = S_OK; } }
return hr; }
INT_PTR CHomeNetworkWizard::InsertDiskPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: ASSERT(g_fRunningOnNT); return TRUE; case WM_COMMAND: if (IDC_FORMAT == LOWORD(wParam)) { SHFormatDrive(hwnd, pthis->_iDrive, 0, 0); return TRUE; } return FALSE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { SetDlgItemText(hwnd, IDC_DISK, pthis->_szDrive); PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT); } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case PSN_WIZNEXT: { CHAR szSource[MAX_PATH]; if (SUCCEEDED(GetSourceFilePath(szSource, ARRAYSIZE(szSource)))) { // Double-null since we'll be passing this to SHFileOperation
CHAR szDest[] = "a:\\netsetup.exe\0"; szDest[0] = 'A' + pthis->_iDrive;
SHFILEOPSTRUCTA shfo = {0}; shfo.wFunc = FO_COPY; shfo.pFrom = szSource; shfo.pTo = szDest; shfo.fFlags = FOF_SIMPLEPROGRESS | FOF_NOCONFIRMATION; CHAR szTitle[256]; LoadStringA(g_hinst, IDS_COPYING, szTitle, ARRAYSIZE(szTitle)); shfo.lpszProgressTitle = szTitle;
int i = SHFileOperationA(&shfo); if (i || shfo.fAnyOperationsAborted) { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, -1); } else { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_FLOPPYINST); } } } return TRUE; } } return FALSE; }
return FALSE; }
INT_PTR CHomeNetworkWizard::InstructionsPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: ASSERT(g_fRunningOnNT); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: { PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
// If we aren't going to need to reboot
if (!pthis->_hnetInfo.fRebootRequired) { // Then we don't want to tell the user to reboot in the text
UINT idNoReboot = IDS_CD_NOREBOOT;
if (pthis->_fFloppyInstructions) { // We're on the floppy instructions page
idNoReboot = IDS_FLOPPY_NOREBOOT; }
WCHAR szLine[256]; LoadString(g_hinst, idNoReboot, szLine, ARRAYSIZE(szLine)); SetDlgItemText(hwnd, IDC_INSTRUCTIONS, szLine); } } return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case PSN_WIZNEXT: pthis->PushPage(pthis->_fFloppyInstructions ? IDD_WIZ_FLOPPYINST : IDD_WIZ_CDINST); SetWindowLongPtr(hwnd, DWLP_MSGRESULT, IDD_WIZ_FINISH); return TRUE; } } return FALSE; }
return FALSE; }
void _AddLineToBuffer(LPCWSTR pszLine, LPWSTR pszBuffer, DWORD cchBuffer, DWORD* piChar) { lstrcpyn(pszBuffer + (*piChar), pszLine, cchBuffer - (*piChar)); *piChar += lstrlen(pszLine); lstrcpyn(pszBuffer + (*piChar), L"\r\n", cchBuffer - (*piChar)); *piChar += 2; }
void CHomeNetworkWizard::SummarySetActive(HWND hwnd) { WCHAR szText[2048]; WCHAR szLine[256]; DWORD iChar = 0;
// Fill the list with some information based on what things we're going to do to
// configure their home network.
if (_hnetInfo.pncExternal) { // "Internet connection settings:"
LoadString(g_hinst, IDS_SUMMARY_INETSETTINGS, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
NETCON_PROPERTIES* pncprops; HRESULT hr = _hnetInfo.pncExternal->GetProperties(&pncprops); if (SUCCEEDED(hr)) { // Internet connection:\t%1
if (FormatMessageString(IDS_SUMMARY_INETCON, szLine, ARRAYSIZE(szLine), pncprops->pszwName)) { _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); }
// Internet connection sharing:\tenabled
if (_hnetInfo.dwFlags & HNET_SHARECONNECTION) { LoadString(g_hinst, IDS_SUMMARY_ICSENABLED, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); }
// Personal firewall:\tenabled
if (_hnetInfo.dwFlags & HNET_FIREWALLCONNECTION) { LoadString(g_hinst, IDS_SUMMARY_FIREWALLENABLED, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); }
NcFreeNetconProperties(pncprops); }
LoadString(g_hinst, IDS_SUMMARY_UNDERLINE, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); } else { if (_fICSClient) { // "Internet connection settings:"
LoadString(g_hinst, IDS_SUMMARY_INETSETTINGS, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
if (*_szICSMachineName) { // Connecting via ICS through:\t%1
if (FormatMessageString(IDS_sUMMARY_CONNECTTHROUGH, szLine, ARRAYSIZE(szLine), _szICSMachineName)) { _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); } } else { // Connecting through another device or computer.
LoadString(g_hinst, IDS_SUMMARY_CONNECTTHROUGH2, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); }
LoadString(g_hinst, IDS_SUMMARY_UNDERLINE, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); } else { // Not connecting to the Internet - display nothing
} }
// Home network settings:
LoadString(g_hinst, IDS_SUMMARY_HNETSETTINGS, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
if (_hnetInfo.dwFlags & HNET_SETCOMPUTERNAME) { // Computer description:\t%1
if (FormatMessageString(IDS_SUMMARY_COMPDESC, szLine, ARRAYSIZE(szLine), _hnetInfo.szComputerDescription)) { _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); }
// Computer name:\t%1
if (FormatMessageString(IDS_SUMMARY_COMPNAME, szLine, ARRAYSIZE(szLine), _hnetInfo.szComputer)) { _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); } }
if (_hnetInfo.dwFlags & HNET_SETWORKGROUPNAME) { // Workgroup name:\t%1
if (FormatMessageString(IDS_SUMMARY_WORKGROUP, szLine, ARRAYSIZE(szLine), _hnetInfo.szWorkgroup)) { _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); } }
// The Shared Documents folder and any printers connected to this computer have been shared.
_AddLineToBuffer(L"", szText, ARRAYSIZE(szText), &iChar); LoadString(g_hinst, IDS_SUMMARY_SHARING, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); LoadString(g_hinst, IDS_SUMMARY_UNDERLINE, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
if ((_hnetInfo.prgncInternal) && (_hnetInfo.cncInternal)) { if (_hnetInfo.cncInternal > 1) { // Bridged connections:\r\n
LoadString(g_hinst, IDS_SUMMARY_BRIDGESETTINGS, szLine, ARRAYSIZE(szLine)); _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar);
// Now list the connections...
for (DWORD i = 0; i < _hnetInfo.cncInternal; i++) { NETCON_PROPERTIES* pncprops; HRESULT hr = _hnetInfo.prgncInternal[i]->GetProperties(&pncprops); if (SUCCEEDED(hr)) { _AddLineToBuffer(pncprops->pszwName, szText, ARRAYSIZE(szText), &iChar); NcFreeNetconProperties(pncprops); } } } else // Single internal connection case
{ // Home network connection:\t%1
NETCON_PROPERTIES* pncprops; HRESULT hr = _hnetInfo.prgncInternal[0]->GetProperties(&pncprops); if (SUCCEEDED(hr)) { if (FormatMessageString(IDS_SUMMARY_HOMENETCON, szLine, ARRAYSIZE(szLine), pncprops->pszwName)) { _AddLineToBuffer(szLine, szText, ARRAYSIZE(szText), &iChar); }
NcFreeNetconProperties(pncprops); } } }
ASSERT(iChar < ARRAYSIZE(szText));
UINT iTabDistance = 150; SendDlgItemMessage(hwnd, IDC_CHANGELIST, EM_SETTABSTOPS, (WPARAM) 1, (LPARAM) &iTabDistance); SetDlgItemText(hwnd, IDC_CHANGELIST, szText); }
INT_PTR CHomeNetworkWizard::FinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: { pthis->WelcomeSetTitleFont(hwnd); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC), IDC_HELPLINK, IDS_HELP_SHARING); pthis->ReplaceStaticWithLink(GetDlgItem(hwnd, IDC_HELPSTATIC2), IDC_HELPLINK2, IDS_HELP_SHAREDDOCS); return TRUE; }
case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_CancelToClose(GetParent(hwnd)); PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK | PSWIZB_FINISH); return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case PSN_WIZFINISH: return TRUE; case NM_CLICK: case NM_RETURN: switch ((int) wParam) { case IDC_HELPLINK: // help on sharing
{ if (IsOS(OS_PERSONAL)) { HelpCenter(hwnd, L"filefold.chm%3A%3A/sharing_files_overviewP.htm"); } else { HelpCenter(hwnd, L"filefold.chm%3A%3A/sharing_files_overviewW.htm"); } } return TRUE; case IDC_HELPLINK2: // help on Shared Documents
{ HelpCenter(hwnd, L"filefold.chm%3A%3A/windows_shared_documents.htm"); } return TRUE; } } } return FALSE; }
return FALSE; }
INT_PTR CHomeNetworkWizard::ErrorFinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->WelcomeSetTitleFont(hwnd); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_FINISH); return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case PSN_WIZFINISH: return TRUE; } } return FALSE; }
return FALSE; }
INT_PTR CHomeNetworkWizard::NoHardwareFinishPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: { pthis->WelcomeSetTitleFont(hwnd); return TRUE; } case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, PSWIZB_BACK); return TRUE; case PSN_WIZBACK: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, pthis->PopPage()); return TRUE; case PSN_WIZFINISH: return TRUE; } } return FALSE; }
return FALSE; }
INT_PTR CHomeNetworkWizard::CantRunWizardPageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = GetThis(hwnd, uMsg, wParam, lParam);
switch (uMsg) { case WM_INITDIALOG: pthis->WelcomeSetTitleFont(hwnd); return TRUE; case WM_NOTIFY: { LPNMHDR pnmh = (LPNMHDR) lParam;
switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(pnmh->hwndFrom, 0); return TRUE; } } return FALSE; }
return FALSE; }
HRESULT GetConnections(HDPA* phdpa) { HRESULT hr = S_OK; *phdpa = DPA_Create(5); if (*phdpa) { // Initialize the net connection enumeration
INetConnectionManager* pmgr;
hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER | CLSCTX_NO_CODE_DOWNLOAD, IID_PPV_ARG(INetConnectionManager, &pmgr));
if (SUCCEEDED(hr)) { hr = SetProxyBlanket(pmgr);
if (SUCCEEDED(hr)) { IEnumNetConnection* penum; hr = pmgr->EnumConnections(NCME_DEFAULT, &penum);
if (SUCCEEDED(hr)) { hr = SetProxyBlanket(penum);
if (SUCCEEDED(hr)) { // Fill in our DPA will the connections
hr = penum->Reset(); while (S_OK == hr) { INetConnection* pnc; ULONG ulISuck; hr = penum->Next(1, &pnc, &ulISuck);
if (S_OK == hr) { hr = SetProxyBlanket(pnc);
if (SUCCEEDED(hr)) { if (-1 != DPA_AppendPtr(*phdpa, pnc)) { pnc->AddRef(); } else { hr = E_OUTOFMEMORY; } }
pnc->Release(); } } }
penum->Release(); } } pmgr->Release(); }
if (FAILED(hr)) { DPA_DestroyCallback(*phdpa, FreeConnectionDPACallback, NULL); *phdpa = NULL; } } else { hr = E_OUTOFMEMORY; }
return hr; }
CHomeNetworkWizard* CHomeNetworkWizard::GetThis(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CHomeNetworkWizard* pthis = NULL;
if (uMsg == WM_INITDIALOG) { PROPSHEETPAGE* psp = (PROPSHEETPAGE*) lParam; pthis = (CHomeNetworkWizard*) psp->lParam; SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pthis); } else { pthis = (CHomeNetworkWizard*) GetWindowLongPtr(hwnd, GWLP_USERDATA); }
return pthis; }
// Utility functions
HRESULT GetConnectionsFolder(IShellFolder** ppsfConnections) { LPITEMIDLIST pidlFolder; HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_CONNECTIONS, &pidlFolder);
if (SUCCEEDED(hr)) { IShellFolder* pshDesktop; hr = SHGetDesktopFolder(&pshDesktop);
if (SUCCEEDED(hr)) { hr = pshDesktop->BindToObject(pidlFolder, NULL, IID_PPV_ARG(IShellFolder, ppsfConnections));
#if 0
/*
We need to do an IEnumIDList::Reset to set up internal data structures so that ::ParseDisplayName works later. Remove this once DaveA's stuff gets in the desktop build. TODO */ if (SUCCEEDED(hr)) { IEnumIDList* penum; hr = (*ppsfConnections)->EnumObjects(NULL, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &penum);
if (SUCCEEDED(hr)) { penum->Reset(); penum->Release(); } } #endif
pshDesktop->Release(); }
ILFree(pidlFolder); }
return hr; }
void W9xGetNetTypeName(BYTE bNicType, WCHAR* pszBuff, UINT cchBuff) { COMPILETIME_ASSERT(IDS_NETTYPE_START == IDS_NETTYPE_LAN); COMPILETIME_ASSERT(IDS_NETTYPE_LAN - IDS_NETTYPE_START == NETTYPE_LAN); COMPILETIME_ASSERT(IDS_NETTYPE_DIALUP - IDS_NETTYPE_START == NETTYPE_DIALUP); COMPILETIME_ASSERT(IDS_NETTYPE_IRDA - IDS_NETTYPE_START == NETTYPE_IRDA); COMPILETIME_ASSERT(IDS_NETTYPE_PPTP - IDS_NETTYPE_START == NETTYPE_PPTP); COMPILETIME_ASSERT(IDS_NETTYPE_TV - IDS_NETTYPE_START == NETTYPE_TV); COMPILETIME_ASSERT(IDS_NETTYPE_ISDN - IDS_NETTYPE_START == NETTYPE_ISDN); COMPILETIME_ASSERT(IDS_NETTYPE_LAN - IDS_NETTYPE_START == NETTYPE_LAN);
if (bNicType >= NETTYPE_LAN && bNicType <= NETTYPE_ISDN) { LoadString(g_hinst, IDS_NETTYPE_START + bNicType, pszBuff, cchBuff); } else { LoadString(g_hinst, IDS_NETTYPE_UNKNOWN, pszBuff, cchBuff); }
return; }
BOOL W9xIsValidAdapter(const NETADAPTER* pNA, DWORD dwFlags) { BOOL fRet = FALSE;
if (dwFlags & CONN_EXTERNAL) { fRet = (pNA->bError == NICERR_NONE && pNA->bNetType == NETTYPE_LAN && pNA->bNetSubType != SUBTYPE_ICS && pNA->bNetSubType != SUBTYPE_AOL && pNA->bNicType != NIC_1394 ); } else if (dwFlags & CONN_INTERNAL) { fRet = (pNA->bError == NICERR_NONE && pNA->bNetType == NETTYPE_LAN && pNA->bNetSubType != SUBTYPE_ICS && pNA->bNetSubType != SUBTYPE_AOL ); } /* else if ( dwFlags & CONN_UNPLUGGED )
{ if ( IsOS(OS_MILLENNIUM) ) { fRet = IsAdapterDisconnected( (void*)pNA ); } } */
return fRet; }
BOOL W9xIsAdapterDialUp(const NETADAPTER* pAdapter) { return (pAdapter->bNetType == NETTYPE_DIALUP && pAdapter->bNetSubType == SUBTYPE_NONE); }
HRESULT CHomeNetworkWizard::GetConnectionIconIndex(GUID& guidConnection, IShellFolder* psfConnections, int* pIndex) { *pIndex = -1; OLECHAR szGUID[40]; HRESULT hr = E_FAIL; if (StringFromGUID2(guidConnection, szGUID, ARRAYSIZE(szGUID))) { LPITEMIDLIST pidlConn = NULL; ULONG cchEaten = 0; hr = psfConnections->ParseDisplayName(NULL, NULL, szGUID, &cchEaten, &pidlConn, NULL); if (SUCCEEDED(hr)) { IExtractIconW *pExtractIconW; LPCITEMIDLIST pcidl = pidlConn;
hr = psfConnections->GetUIObjectOf(NULL, 1, &pcidl, IID_IExtractIconW, 0, (LPVOID *)(&pExtractIconW)); if (SUCCEEDED(hr)) { WCHAR szIconLocation[MAX_PATH]; INT iIndex; UINT wFlags;
hr = pExtractIconW->GetIconLocation(GIL_FORSHELL, szIconLocation, MAX_PATH, &iIndex, &wFlags);
if (SUCCEEDED(hr)) { HICON hIconLarge; HICON hIconSmall;
hr = pExtractIconW->Extract(szIconLocation, iIndex, &hIconLarge, &hIconSmall, 0x00100010); if (SUCCEEDED(hr)) { *pIndex = ImageList_AddIcon(_himlSmall, hIconSmall); } DestroyIcon(hIconLarge); DestroyIcon(hIconSmall); } }
if(pExtractIconW != NULL) pExtractIconW->Release();
ILFree(pidlConn); } }
return hr; }
HRESULT GetDriveNameAndIconIndex(LPWSTR pszDrive, LPWSTR pszDisplayName, DWORD cchDisplayName, int* pIndex) { SHFILEINFO fi = {0}; if (SHGetFileInfoW_NT(pszDrive, 0, &fi, sizeof (fi), SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX)) { *pIndex = fi.iIcon; lstrcpyn(pszDisplayName, fi.szDisplayName, cchDisplayName); return S_OK; }
return E_FAIL; }
BOOL IsEqualConnection(INetConnection* pnc1, INetConnection* pnc2) { BOOL fEqual = FALSE;
if ((pnc1) && (pnc2)) { NETCON_PROPERTIES *pprops1, *pprops2;
if (SUCCEEDED(pnc1->GetProperties(&pprops1))) { if (SUCCEEDED(pnc2->GetProperties(&pprops2))) { fEqual = (pprops1->guidId == pprops2->guidId);
NcFreeNetconProperties(pprops2); }
NcFreeNetconProperties(pprops1); } }
return fEqual; }
HRESULT ShareAllPrinters() { PRINTER_ENUM* pPrinters; int nPrinters = MyEnumLocalPrinters(&pPrinters);
if (nPrinters) { int iPrinterNumber = 1; for (int iPrinter = 0; iPrinter < nPrinters; iPrinter ++) { TCHAR szShare[NNLEN + 1];
do { FormatMessageString(IDS_PRINTER, szShare, ARRAYSIZE(szShare), iPrinterNumber); if (1 == iPrinterNumber) { szShare[lstrlen(szShare) - 1] = 0; // Remove the "1" from the end since this is the first printer
// ie: "Printer1" --> "Printer"
}
if (!g_fRunningOnNT) { CharUpper(szShare); }
iPrinterNumber ++; } while (IsShareNameInUse(szShare));
if (SharePrinter(pPrinters[iPrinter].pszPrinterName, szShare, NULL)) { g_logFile.Write("Shared Printer: "); } else { g_logFile.Write("Failed to share Printer: "); }
g_logFile.Write(pPrinters[iPrinter].pszPrinterName); g_logFile.Write("\r\n"); }
free(pPrinters); }
return S_OK; }
BOOL AllPlatformGetComputerName(LPWSTR pszName, DWORD cchName) { if (g_fRunningOnNT) { return GetComputerNameExW_NT(ComputerNamePhysicalNetBIOS, pszName, &cchName); } else { return GetComputerName(pszName, &cchName); } }
BOOL _IsTCPIPAvailable(void) { BOOL fTCPIPAvailable = FALSE; HKEY hk; DWORD dwSize;
// we check to see if the TCP/IP stack is installed and which object it is
// bound to, this is a string, we don't check the value only that the
// length is non-zero.
if ( ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Services\\Tcpip\\Linkage"), 0x0, KEY_QUERY_VALUE, &hk) ) { if ( ERROR_SUCCESS == RegQueryValueEx(hk, TEXT("Export"), 0x0, NULL, NULL, &dwSize) ) { if ( dwSize > 2 ) { fTCPIPAvailable = TRUE; } } RegCloseKey(hk); }
return (fTCPIPAvailable); }
BOOL AllPlatformSetComputerName(LPCWSTR pszComputerName) { // NetBIOS computer name is set even on NT for completeness
BOOL fSuccess;
if (g_fRunningOnNT) { if (_IsTCPIPAvailable()) { fSuccess = SetComputerNameExW_NT(ComputerNamePhysicalDnsHostname, pszComputerName); } else { fSuccess = SetComputerNameExW_NT(ComputerNamePhysicalNetBIOS, pszComputerName); } } else { // Windows 9x
fSuccess = SetComputerName(pszComputerName); }
return fSuccess; }
BOOL SetComputerNameIfNecessary(LPCWSTR pszComputerName, BOOL* pfRebootRequired) { g_logFile.Write("Attempting to set computer name\r\n");
WCHAR szOldComputerName[LM20_CNLEN + 1]; AllPlatformGetComputerName(szOldComputerName, ARRAYSIZE(szOldComputerName));
if (0 != StrCmpIW(szOldComputerName, pszComputerName)) { if (AllPlatformSetComputerName(pszComputerName)) { g_logFile.Write("Computer name set successfully: "); g_logFile.Write(pszComputerName); g_logFile.Write("\r\n"); *pfRebootRequired = TRUE; } else { g_logFile.Write("Computer name set failed.\r\n"); return FALSE; } } else { g_logFile.Write("Old computer name is the same as new computer name - not setting.\r\n"); }
return TRUE; }
BOOL SetComputerDescription(LPCWSTR pszComputerDescription) { BOOL fRet;
if (g_fRunningOnNT) { g_logFile.Write("Setting server description (comment): "); g_logFile.Write(pszComputerDescription); g_logFile.Write("\r\n");
// Set comment (for now, NT only) win9x - TODO
SERVER_INFO_1005_NT sv1005; sv1005.sv1005_comment = const_cast<LPWSTR>(pszComputerDescription); fRet = (NERR_Success == NetServerSetInfo_NT(NULL, 1005, (LPBYTE) &sv1005, NULL)); } else { CRegistry reg; fRet = reg.OpenKey(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\VxD\\VNETSUP"); if (fRet) { fRet = reg.SetStringValue(L"Comment", pszComputerDescription); } }
return fRet; }
HRESULT ShareWellKnownFolders(PHOMENETSETUPINFO pInfo) { if (!NetConn_IsSharedDocumentsShared()) { NetConn_CreateSharedDocuments(NULL, g_hinst, NULL, 0);
if (NetConn_IsSharedDocumentsShared()) { g_logFile.Write("'Shared Documents' shared.\r\n"); } else { g_logFile.Write("Failed to share 'Shared Documents'\r\n"); return E_FAIL; } }
return S_OK; }
HRESULT SetProxyBlanket(IUnknown * pUnk) { HRESULT hr; hr = CoSetProxyBlanket ( pUnk, RPC_C_AUTHN_WINNT, // use NT default security
RPC_C_AUTHZ_NONE, // use NT default authentication
NULL, // must be null if default
RPC_C_AUTHN_LEVEL_CALL, // call
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, // use process token
EOAC_NONE);
if(SUCCEEDED(hr)) { IUnknown * pUnkSet = NULL; hr = pUnk->QueryInterface(IID_PPV_ARG(IUnknown, &pUnkSet)); if(SUCCEEDED(hr)) { hr = CoSetProxyBlanket ( pUnkSet, RPC_C_AUTHN_WINNT, // use NT default security
RPC_C_AUTHZ_NONE, // use NT default authentication
NULL, // must be null if default
RPC_C_AUTHN_LEVEL_CALL, // call
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, // use process token
EOAC_NONE); pUnkSet->Release(); } } return hr; }
HRESULT WriteSetupInfoToRegistry(PHOMENETSETUPINFO pInfo) { HKEY hkey; if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szAppRegKey, 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL)) { // Write information telling the home network wizard to run silently on next boot, and what to share
DWORD dwRun = 1; RegSetValueEx(hkey, TEXT("RunWizardFromRegistry"), NULL, REG_DWORD, (CONST BYTE*) &dwRun, sizeof (dwRun)); RegCloseKey(hkey); }
// Add a runonce entry for this wizard
TCHAR szProcess[MAX_PATH]; if (0 != GetModuleFileName(NULL, szProcess, ARRAYSIZE(szProcess))) { TCHAR szModule[MAX_PATH]; if (0 != GetModuleFileName(g_hinst, szModule, ARRAYSIZE(szModule))) { const TCHAR szRunDllFormat[] = TEXT("%s %s,HomeNetWizardRunDll"); TCHAR szRunDllLine[MAX_PATH]; if (0 < wnsprintf(szRunDllLine, ARRAYSIZE(szRunDllLine), szRunDllFormat, szProcess, szModule)) { if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_RUNONCE, 0, NULL, 0, KEY_WRITE, NULL, &hkey, NULL)) { RegSetValueEx(hkey, TEXT("Network Setup Wizard"), 0, REG_SZ, (LPBYTE) szRunDllLine, ARRAYSIZE(szRunDllLine)); RegCloseKey(hkey); } } } }
return S_OK; }
HRESULT DeleteSetupInfoFromRegistry() { RegDeleteKeyAndSubKeys(HKEY_LOCAL_MACHINE, c_szAppRegKey); return S_OK; }
HRESULT ReadSetupInfoFromRegistry(PHOMENETSETUPINFO pInfo) { BOOL fRunFromRegistry = FALSE;
HKEY hkey; if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szAppRegKey, 0, KEY_READ, &hkey)) { DWORD dwType; DWORD cbData = sizeof (fRunFromRegistry); if (ERROR_SUCCESS != RegQueryValueEx(hkey, TEXT("RunWizardFromRegistry"), NULL, &dwType, (LPBYTE) &fRunFromRegistry, &cbData)) { fRunFromRegistry = FALSE; }
RegCloseKey(hkey); }
// S_FALSE indicates we're not running silently from infromation in the registry.
return fRunFromRegistry ? S_OK : S_FALSE; }
HRESULT MakeUniqueShareName(LPCTSTR pszBaseName, LPTSTR pszUniqueName, DWORD cchName) { if (!IsShareNameInUse(pszBaseName)) { lstrcpyn(pszUniqueName, pszBaseName, cchName); return S_OK; } else { int i = 2; while (TRUE) { if (0 > wnsprintf(pszUniqueName, cchName, TEXT("%s%d"), pszBaseName, i)) { return E_FAIL; }
if (!IsShareNameInUse(pszUniqueName)) { return S_OK; } } } }
// Pass NULL as TokenHandle to see if thread token is admin
HRESULT IsUserLocalAdmin(HANDLE TokenHandle, BOOL* pfIsAdmin) { if (g_fRunningOnNT) { // First we must check if the current user is a local administrator; if this is
// the case, our dialog doesn't even display
PSID psidAdminGroup = NULL; SID_IDENTIFIER_AUTHORITY security_nt_authority = SECURITY_NT_AUTHORITY;
BOOL fSuccess = ::AllocateAndInitializeSid_NT(&security_nt_authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdminGroup); if (fSuccess) { // See if the user for this process is a local admin
fSuccess = CheckTokenMembership_NT(TokenHandle, psidAdminGroup, pfIsAdmin); FreeSid_NT(psidAdminGroup); }
return fSuccess ? S_OK:E_FAIL; } else { // Win9x - every user is an admin
*pfIsAdmin = TRUE; return S_OK; } }
HRESULT GetConnectionByGUID(HDPA hdpaConnections, const GUID* pguid, INetConnection** ppnc) { *ppnc = NULL; DWORD nItems = DPA_GetPtrCount(hdpaConnections); HRESULT hr = E_FAIL;
if (nItems) { DWORD iItem = 0; while (iItem < nItems) { INetConnection* pnc = (INetConnection*) DPA_GetPtr(hdpaConnections, iItem); if (pnc) { GUID guidMatch; hr = GetConnectionGUID(pnc, &guidMatch); if (SUCCEEDED(hr)) { if (*pguid == guidMatch) { *ppnc = pnc; (*ppnc)->AddRef(); break; } } // Don't pnc->Release() - its coming from the DPA
}
iItem ++; }
if (iItem == nItems) { // We searched and didn't find
hr = E_FAIL; } }
return hr; }
HRESULT GUIDsToConnections(PHOMENETSETUPINFO pInfo) { ASSERT(NULL == pInfo->prgncInternal); ASSERT(NULL == pInfo->pncExternal);
HDPA hdpaConnections; HRESULT hr = GetConnections(&hdpaConnections); if (SUCCEEDED(hr)) { // Get internal connections by GUID (allocate an extra one for null-terminated array, as elsewhere)
pInfo->prgncInternal = (INetConnection**) LocalAlloc(LPTR, (pInfo->cguidInternal + 1) * sizeof (INetConnection*));
if (pInfo->prgncInternal) { DWORD iConnection = 0; while ((iConnection < pInfo->cguidInternal) && SUCCEEDED(hr)) { hr = GetConnectionByGUID(hdpaConnections, pInfo->prgguidInternal + iConnection, pInfo->prgncInternal + iConnection); iConnection++; }
pInfo->cncInternal = iConnection; } else { hr = E_OUTOFMEMORY; }
if (SUCCEEDED(hr) && (GUID_NULL != pInfo->guidExternal)) { // Get external connection
hr = GetConnectionByGUID(hdpaConnections, &(pInfo->guidExternal), &(pInfo->pncExternal)); }
DPA_DestroyCallback(hdpaConnections, FreeConnectionDPACallback, NULL); hdpaConnections = NULL; }
if (FAILED(hr)) { FreeExternalConnection(pInfo); FreeInternalConnections(pInfo); }
pInfo->guidExternal = GUID_NULL; FreeInternalGUIDs(pInfo);
return hr; }
HRESULT GetConnectionGUID(INetConnection* pnc, GUID* pguid) { NETCON_PROPERTIES* pncprops; HRESULT hr = pnc->GetProperties(&pncprops); if (SUCCEEDED(hr)) { *pguid = pncprops->guidId; NcFreeNetconProperties(pncprops); }
return hr; }
HRESULT ConnectionsToGUIDs(PHOMENETSETUPINFO pInfo) { HRESULT hr = S_OK; ASSERT(NULL == pInfo->prgguidInternal); ASSERT(GUID_NULL == pInfo->guidExternal);
// Allocate the private connection guid array
if (pInfo->cncInternal) { pInfo->prgguidInternal = (GUID*) LocalAlloc(LPTR, pInfo->cncInternal * sizeof (GUID)); if (pInfo->prgguidInternal) { // Get each connection's GUID and fill in the array
DWORD i = 0; while ((i < pInfo->cncInternal) && (SUCCEEDED(hr))) { hr = GetConnectionGUID(pInfo->prgncInternal[i], &(pInfo->prgguidInternal[i]));
i++; }
pInfo->cguidInternal = i; } else { hr = E_OUTOFMEMORY; } }
if (SUCCEEDED(hr)) { if (pInfo->pncExternal) { hr = GetConnectionGUID(pInfo->pncExternal, &(pInfo->guidExternal)); } }
if (FAILED(hr) && pInfo->prgguidInternal) { FreeInternalGUIDs(pInfo); pInfo->guidExternal = GUID_NULL; }
FreeExternalConnection(pInfo); FreeInternalConnections(pInfo);
return hr; }
HRESULT ConfigureHomeNetwork(PHOMENETSETUPINFO pInfo) { HRESULT hr = E_FAIL;
if (pInfo->fAsync) { if (g_fRunningOnNT) { // Bundle up NT specific data for cross-thread
hr = ConnectionsToGUIDs(pInfo); } else { // TODO: Anything necessary on win9x
hr = S_OK; }
if (SUCCEEDED(hr)) { if (SHCreateThread(ConfigureHomeNetworkThread, pInfo, CTF_COINIT, NULL)) { hr = S_FALSE; } else { hr = E_FAIL; } } } else { hr = ConfigureHomeNetworkSynchronous(pInfo); }
return hr; }
DWORD WINAPI ConfigureHomeNetworkThread(void* pvData) { PHOMENETSETUPINFO pInfo = (PHOMENETSETUPINFO) pvData;
// Before creating this thread, the caller MUST have freed his INetConnection*'s or
// else the thread might touch/free them, which it must not do. Assert this.
ASSERT(NULL == pInfo->pncExternal); ASSERT(NULL == pInfo->prgncInternal);
HRESULT hr;
if (g_fRunningOnNT) { // Unbundle data after crossing the thread boundary
hr = GUIDsToConnections(pInfo); } else { // TODO: Anything necessary for Win9x
hr = S_OK; }
if (SUCCEEDED(hr)) { hr = ConfigureHomeNetworkSynchronous(pInfo);
FreeExternalConnection(pInfo); FreeInternalConnections(pInfo);
if ((pInfo->hwnd) && (pInfo->umsgAsyncNotify)) { // The HRESULT from the configuration is passed in WPARAM
PostMessage(pInfo->hwnd, pInfo->umsgAsyncNotify, (WPARAM) hr, 0); } }
return 0; }
HRESULT ConfigureHomeNetworkSynchronous(PHOMENETSETUPINFO pInfo) { g_logFile.Initialize("%systemroot%\\nsw.log");
HRESULT hr = S_OK;
#ifdef NO_CONFIG
g_logFile.Write("UI Test only - no configuration\r\n"); g_logFile.Uninitialize(); Sleep(2000);
#ifdef FAKE_REBOOTREQUIRED
pInfo->fRebootRequired = TRUE; #endif
return S_OK; #endif
BOOL fInstallSharing = TRUE; BOOL fSharingAlreadyInstalled = IsSharingInstalled(TRUE); BOOL fInstalledWorkgroup = FALSE;
// We don't need to install sharing unless we're sharing something
if (!(pInfo->dwFlags & (HNET_SHAREFOLDERS | HNET_SHAREPRINTERS))) { g_logFile.Write("No file or printer sharing requested\r\n"); fInstallSharing = FALSE; }
// Worker function for the whole wizard
// Computer name
if ((pInfo->dwFlags & HNET_SETCOMPUTERNAME) && (*(pInfo->szComputer))) { SetComputerNameIfNecessary(pInfo->szComputer, &(pInfo->fRebootRequired)); SetComputerDescription(pInfo->szComputerDescription); }
// Workgroup name
if ((pInfo->dwFlags & HNET_SETWORKGROUPNAME) && (*(pInfo->szWorkgroup))) { Install_SetWorkgroupName(pInfo->szWorkgroup, &(pInfo->fRebootRequired));
fInstalledWorkgroup = TRUE; }
// Install TCP/IP
hr = InstallTCPIP(pInfo->hwnd, NULL, NULL); if (NETCONN_NEED_RESTART == hr) { pInfo->fRebootRequired = TRUE; hr = S_OK; }
if (FAILED(hr)) { g_logFile.Write("Failed to install TCP/IP\r\n"); }
// Install Client for Microsoft Networks
// TODO: figure out what to do if NetWare client is installed!?!?
hr = InstallMSClient(pInfo->hwnd, NULL, NULL); if (NETCONN_NEED_RESTART == hr) { pInfo->fRebootRequired = TRUE; hr = S_OK; }
if (FAILED(hr)) { g_logFile.Write("Failed to install Client for Microsoft Networks.\r\n"); }
// Install sharing
if (fInstallSharing) { hr = InstallSharing(pInfo->hwnd, NULL, NULL); if (NETCONN_NEED_RESTART == hr) { pInfo->fRebootRequired = TRUE; hr = S_OK; }
if (FAILED(hr)) { g_logFile.Write("Failed to install File and Printer Sharing.\r\n"); } }
// TODO: What to do about share level vs. user level access control on windows 9x???
// TODO: What to do about autodialing? Are we assuming this will already be done for us? 9x and NT? I think so!
if ( g_fRunningOnNT ) { // We only set autodial here if we are configuring an ICS Client
// In the case that we explicitly set a public adapter then ConfigureICSBridgeFirewall
// will set autodial if required.
if ( pInfo->dwFlags & HNET_ICSCLIENT ) { hr = HrSetAutodial( AUTODIAL_MODE_NO_NETWORK_PRESENT ); } } else { if ( pInfo->ipaExternal != -1 ) { if (W9xIsAdapterDialUp(&pInfo->pNA[LOWORD(pInfo->ipaExternal)])) // Dialup adapter for connecting to internet
{ g_logFile.Write("Setting default dial-up connection to autodial.\r\n"); SetDefaultDialupConnection((pInfo->pRas[HIWORD(pInfo->ipaExternal)]).szEntryName); EnableAutodial(TRUE); } else { g_logFile.Write("Disabling autodial since default connection isn't dial-up.\r\n"); SetDefaultDialupConnection(NULL); EnableAutodial(FALSE); } } }
// Configure ICS, the Bridge and the personal firewall
if (g_fRunningOnNT) { hr = ConfigureICSBridgeFirewall(pInfo); } else { // ICS client or no internet connection.
if ((pInfo->dwFlags & HNET_ICSCLIENT) || (pInfo->pNA && pInfo->ipaExternal == -1)) { CICSInst* pICS = new CICSInst; if (pICS) { if (pICS->IsInstalled()) { pICS->m_option = ICS_UNINSTALL;
g_logFile.Write("Uninstalling ICS Client.\r\n");
pICS->DoInstallOption(&(pInfo->fRebootRequired), pInfo->ipaInternal); }
delete pICS; } if ( (pInfo->dwFlags & HNET_ICSCLIENT) && (pInfo->pNA && pInfo->ipaInternal != -1)) { UINT ipa; for ( ipa=0; ipa<pInfo->cNA; ipa++ ) { const NETADAPTER* pNA = &pInfo->pNA[ ipa ]; if ( W9xIsValidAdapter( pNA, CONN_INTERNAL ) && !W9xIsValidAdapter( pNA, CONN_UNPLUGGED ) ) { HrEnableDhcp( (void*)pNA, HNW_ED_RELEASE|HNW_ED_RENEW ); } } }
g_logFile.Write("Disabling autodial.\r\n"); SetDefaultDialupConnection(NULL); EnableAutodial(FALSE); } }
// NOTE: we might want to split HNET_SHAREFOLDERS out into two
// bits: HNET_CREATESHAREDFOLDERS and HNET_SHARESHAREDFOLDERS
//
if (pInfo->dwFlags & (HNET_SHAREPRINTERS | HNET_SHAREFOLDERS)) { // Due to domain/corporate security concerns, share things
// iff we're setting up a workgroup, or we're already on one
//
BOOL fOnWorkgroup = fInstalledWorkgroup; if (!fOnWorkgroup) { if (g_fRunningOnNT) { LPTSTR pszDomain; NETSETUP_JOIN_STATUS njs; if (NERR_Success == NetGetJoinInformation(NULL, &pszDomain, &njs)) { NetApiBufferFree(pszDomain);
fOnWorkgroup = (NetSetupWorkgroupName == njs); } } else { fOnWorkgroup = TRUE; // there may be some registry key we can check for this
} }
if (fOnWorkgroup) { EnableSimpleSharing();
if (fSharingAlreadyInstalled) { if (pInfo->dwFlags & HNET_SHAREPRINTERS) { ShareAllPrinters(); }
if (pInfo->dwFlags & HNET_SHAREFOLDERS) { ShareWellKnownFolders(pInfo); } } else { // Write the sharing info to the registry - do required work on reboot
g_logFile.Write("Sharing isn't installed. Will share folders and printers on reboot.\r\n"); pInfo->fRebootRequired = TRUE; WriteSetupInfoToRegistry(pInfo); } } }
if (pInfo->fRebootRequired) { g_logFile.Write("Reboot is required for changes to take effect.\r\n"); }
g_logFile.Uninitialize();
// Kick off the netcrawler
INetCrawler *pnc; if (SUCCEEDED(CoCreateInstance(CLSID_NetCrawler, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARG(INetCrawler, &pnc)))) { pnc->Update(0x0); pnc->Release(); }
#ifdef FAKE_REBOOTREQUIRED
pInfo->fRebootRequired = TRUE; #endif
return hr; }
void STDMETHODCALLTYPE ConfigurationLogCallback(LPCWSTR pszLogEntry, LPARAM lParam) { g_logFile.Write(pszLogEntry); }
typedef BOOL (APIENTRY* PFNNETSETUPICSUPGRADE)(BOOL); HRESULT ConfigureICSBridgeFirewall(PHOMENETSETUPINFO pInfo) { HRESULT hr = E_FAIL;
// Call HNetSetShareAndBridgeSettings directly
BOOLEAN fSharePublicConnection = (pInfo->pncExternal && (pInfo->dwFlags & HNET_SHARECONNECTION)) ? TRUE : FALSE; BOOLEAN fFirewallPublicConnection = (pInfo->pncExternal && (pInfo->dwFlags & HNET_FIREWALLCONNECTION)) ? TRUE : FALSE;
if (fSharePublicConnection) { g_logFile.Write("Will attempt to share public connection.\r\n"); }
if (fFirewallPublicConnection) { g_logFile.Write("Will attempt to firewall public connection.\r\n"); }
HMODULE hHNetCfg = LoadLibrary(L"hnetcfg.dll"); if (hHNetCfg) { INetConnection* pncPrivate = NULL;
LPFNHNETSETSHAREANDBRIDGESETTINGS pfnHNetSetShareAndBridgeSettings
= reinterpret_cast<LPFNHNETSETSHAREANDBRIDGESETTINGS>
(GetProcAddress(hHNetCfg, "HNetSetShareAndBridgeSettings"));
if (pfnHNetSetShareAndBridgeSettings) { hr = (*pfnHNetSetShareAndBridgeSettings)( pInfo->pncExternal, pInfo->prgncInternal, fSharePublicConnection, fFirewallPublicConnection, ConfigurationLogCallback, 0, &pncPrivate ); if (SUCCEEDED(hr)) { if ( ( HNET_ICSCLIENT & pInfo->dwFlags ) && ( NULL == pInfo->prgncInternal[1] ) ) { HrEnableDhcp( pInfo->prgncInternal[0], HNW_ED_RELEASE|HNW_ED_RENEW ); } // If we are sharing an external adapter then set WinInet settings to allow
// for an existing connection created from ICS client traffic.
if ( pInfo->pncExternal ) { hr = HrSetAutodial( AUTODIAL_MODE_NO_NETWORK_PRESENT ); } if ( pncPrivate ) { pncPrivate->Release(); } } else { g_logFile.Write("Adapter Configuration for Home Networking failed.\r\n"); } } else { TraceMsg(TF_WARNING, "HNetCfg.DLL could not find HNetSetShareAndBridgeSettings"); }
FreeLibrary(hHNetCfg); } else { TraceMsg(TF_WARNING, "HNetCfg.DLL could not be loaded"); }
return hr; }
BOOL MachineHasNetShares() { SHARE_INFO* prgShares; int cShares = EnumLocalShares(&prgShares); // See if there are any file or print shares, which are the ones we care about
BOOL fHasShares = FALSE; for (int i = 0; i < cShares; i++) { if ((STYPE_DISKTREE == prgShares[i].bShareType) || (STYPE_PRINTQ == prgShares[i].bShareType)) { fHasShares = TRUE; break; } } NetApiBufferFree(prgShares); return fHasShares; }
// Checks if guest access mode is enabled. If guest access mode is OFF but
// in the indeterminate state (ForceGuest is not set), and the m/c has no net shares,
// then we set ForceGuest to 1 and return TRUE.
//
// This indeterminate state occurs only on win2k->XP upgrade.
BOOL EnsureGuestAccessMode( VOID ) { BOOL fIsGuestAccessMode = FALSE;
if (IsOS(OS_PERSONAL)) { // Guest mode is always on for Personal
fIsGuestAccessMode = TRUE; } else if (IsOS(OS_PROFESSIONAL) && !IsOS(OS_DOMAINMEMBER)) { LONG ec; HKEY hkey;
// Professional, not in a domain. Check the ForceGuest value.
ec = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\LSA"), 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hkey );
if (ec == NO_ERROR) { DWORD dwValue; DWORD dwValueSize = sizeof(dwValue);
ec = RegQueryValueEx(hkey, TEXT("ForceGuest"), NULL, NULL, (LPBYTE)&dwValue, &dwValueSize);
if (ec == NO_ERROR) { if (1 == dwValue) { // ForceGuest is already on
fIsGuestAccessMode = TRUE; } } else { // Value doesn't exist
if (!MachineHasNetShares()) { // Machine has no shares
dwValue = 1; ec = RegSetValueEx(hkey, TEXT("ForceGuest"), 0, REG_DWORD, (BYTE*) &dwValue, sizeof (dwValue));
if (ec == NO_ERROR) { // Write succeeded - guest access mode is enabled
fIsGuestAccessMode = TRUE; } } }
RegCloseKey(hkey); } }
return fIsGuestAccessMode; }
// It is assumed the machine is not joined to a domain when this is called!
HRESULT EnableSimpleSharing() { HRESULT hr = S_FALSE;
if (EnsureGuestAccessMode()) { ILocalMachine *pLM; hr = CoCreateInstance(CLSID_ShellLocalMachine, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(ILocalMachine, &pLM));
if (SUCCEEDED(hr)) { TraceMsg(TF_ALWAYS, "Enabling Guest Account");
hr = pLM->EnableGuest(ILM_GUEST_NETWORK_LOGON); pLM->Release();
SendNotifyMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0); } }
return hr; }
#define INVALID_COMPUTERNAME_CHARS L" {|}~[\\]^':;<=>?@!\"#$%^`()+/*&"
#define INVALID_WORKGROUP_CHARS L"{|}~[\\]^':;<=>?!\"#$%^`()+/*&"
#define INVALID_TRAILING_CHAR L' '
BOOL IsValidNameSyntax(LPCWSTR pszName, NETSETUP_NAME_TYPE type) { // Only support workgroup and machine - need to add new charsets if
// required
ASSERT(type == NetSetupWorkgroup || type == NetSetupMachine);
LPCWSTR pszInvalid = (type == NetSetupWorkgroup) ? INVALID_WORKGROUP_CHARS : INVALID_COMPUTERNAME_CHARS; BOOL fValid = TRUE; WCHAR* pch = (LPWSTR) pszName; if ( *pch && ( NetSetupWorkgroup == type ) ) { // remove trailing blanks
WCHAR* pchLast = pch + wcslen(pch) - 1; while ( (INVALID_TRAILING_CHAR == *pchLast) && (pchLast >= pch) ) { *pchLast = NULL; pchLast--; } } fValid = ( *pch ) ? TRUE : FALSE;
while (*pch && fValid) { fValid = (NULL == StrChrW(pszInvalid, *pch)); pch ++; } return fValid; }
void BoldControl(HWND hwnd, int id) { HWND hwndTitle = GetDlgItem(hwnd, id);
// Get the existing font
HFONT hfontOld = (HFONT) SendMessage(hwndTitle, WM_GETFONT, 0, 0);
LOGFONT lf = {0}; if (GetObject(hfontOld, sizeof(lf), &lf)) { lf.lfWeight = FW_BOLD;
HFONT hfontNew = CreateFontIndirect(&lf); if (hfontNew) { SendMessage(hwndTitle, WM_SETFONT, (WPARAM) hfontNew, FALSE);
// Don't do this, its shared.
// DeleteObject(hfontOld);
} } }
void ShowControls(HWND hwndParent, const int *prgControlIDs, DWORD nControls, int nCmdShow) { for (DWORD i = 0; i < nControls; i++) ShowWindow(GetDlgItem(hwndParent, prgControlIDs[i]), nCmdShow); }
void HelpCenter(HWND hwnd, LPCWSTR pszTopic) { // use ShellExecuteExA for w98 compat.
CHAR szURL[1024]; wsprintfA(szURL, "hcp://services/layout/contentonly?topic=ms-its%%3A%%25help_location%%25\\%S", pszTopic);
SHELLEXECUTEINFOA shexinfo = {0}; shexinfo.cbSize = sizeof (shexinfo); shexinfo.fMask = SEE_MASK_FLAG_NO_UI; shexinfo.nShow = SW_SHOWNORMAL; shexinfo.lpFile = szURL; shexinfo.lpVerb = "open";
// since help center doesn't properly call AllowSetForegroundWindow when it defers to an existing process we just give it to the next taker.
HMODULE hUser32 = GetModuleHandleA("user32.dll"); if(NULL != hUser32) { BOOL (WINAPI *pAllowSetForegroundWindow)(DWORD); pAllowSetForegroundWindow = reinterpret_cast<BOOL (WINAPI*)(DWORD)>(GetProcAddress(hUser32, "AllowSetForegroundWindow")); if(NULL != pAllowSetForegroundWindow) { pAllowSetForegroundWindow(-1); } }
ShellExecuteExA(&shexinfo); }
void CHomeNetworkWizard::ShowMeLink(HWND hwnd, LPCWSTR pszTopic) {
if (pfnShowHTMLDialog == NULL) { hinstMSHTML = LoadLibrary(TEXT("MSHTML.DLL"));
if (hinstMSHTML) { pfnShowHTMLDialog = (SHOWHTMLDIALOGEXFN*)GetProcAddress(hinstMSHTML, "ShowHTMLDialogEx"); }
// can not find ShowHTMLDialog API. Do nothing.
if (pfnShowHTMLDialog == NULL) return; }
WCHAR szURL[1024]; HRESULT hr; VARIANT_BOOL isClosed = VARIANT_FALSE;
// check to see if the dialog window is closed. If so, release it so that a new one
// will be created.
if (showMeDlgWnd != NULL) { if (SUCCEEDED(showMeDlgWnd->get_closed(&isClosed))) { if (isClosed == VARIANT_TRUE) { showMeDlgWnd->Release(); showMeDlgWnd = NULL;
if (pFrameWindow != NULL) { pFrameWindow->Release(); pFrameWindow = NULL; } } } else { return; } }
const char *helpLoc = getenv("help_location"); LPWSTR lpszWinDir; // pointer to system information string
WCHAR tchBuffer[MAX_PATH]; // buffer for concatenated string
// if unset use the default location.
lpszWinDir = tchBuffer; GetWindowsDirectory(lpszWinDir, MAX_PATH); if (showMeDlgWnd == NULL) { BSTR bstrFrameURL; // need to create a new dialog window.
if (helpLoc != NULL) wnsprintfW(szURL, 1024, L"ms-its:%S\\ntart.chm::/hn_ShowMeFrame.htm", helpLoc); else wnsprintfW(szURL, 1024, L"ms-its:%s\\help\\ntart.chm::/hn_ShowMeFrame.htm", lpszWinDir);
bstrFrameURL = SysAllocString((const LPCWSTR)szURL);
if (bstrFrameURL == NULL) return;
IMoniker * pURLMoniker = NULL;
CreateURLMoniker(NULL, bstrFrameURL, &pURLMoniker);
if (pURLMoniker != NULL) { VARIANT varReturn; VariantInit(&varReturn); DWORD dwFlags = HTMLDLG_MODELESS | HTMLDLG_VERIFY;
hr = (*pfnShowHTMLDialog)( NULL, pURLMoniker, dwFlags, NULL, L"scroll:no;help:no;status:no;dialogHeight:394px;dialogWidth:591px;", &varReturn);
if (SUCCEEDED(hr)) { hr = V_UNKNOWN(&varReturn)->QueryInterface(__uuidof(IHTMLWindow2), (void**)&showMeDlgWnd);
} pURLMoniker->Release(); VariantClear(&varReturn); }
SysFreeString(bstrFrameURL); }
// we don't have a dialog window to work with so quit silently.
if (showMeDlgWnd == NULL) { return; }
// we need get the frame window where the actual html page will be displayed.
if (pFrameWindow == NULL) { VARIANT index; VARIANT frameOut; long frameLen = 0;
VariantInit(&index); VariantInit(&frameOut);
IHTMLFramesCollection2* pFramesCol = NULL; // we may not be able to get the frames the first time around. So try some more.
int i = 5; while (i-- > 0) {
if(!SUCCEEDED(showMeDlgWnd->get_frames(&pFramesCol))) { // can not get frames. so quit.
break; } else if (!SUCCEEDED(pFramesCol->get_length(&frameLen))) { // can not determine how many frames it has. so quit.
break; } else { if (frameLen > 0) { V_VT(&index) = VT_I4; V_I4(&index) = 0; if (SUCCEEDED(pFramesCol->item(&index, &frameOut))) { if (V_VT(&frameOut) == VT_DISPATCH && V_DISPATCH(&frameOut) != NULL) { hr = V_DISPATCH(&frameOut)->QueryInterface(__uuidof(IHTMLWindow2), (void**)&pFrameWindow);
} } // found at least one frame. jump out of the loop.
break; } }
if (pFramesCol != NULL) pFramesCol->Release();
Sleep(1000); }
if (pFramesCol != NULL) pFramesCol->Release();
VariantClear(&index); VariantClear(&frameOut); } if (pFrameWindow == NULL) return;
// now to load in the actual html page
BSTR bstrURL; if (helpLoc != NULL) wnsprintf(szURL, 1024, L"ms-its:%S\\%s", helpLoc, pszTopic); else wnsprintf(szURL, 1024, L"ms-its:%s\\help\\%s", lpszWinDir, pszTopic);
bstrURL = SysAllocString((const LPCWSTR)szURL); if (bstrURL == NULL) return; hr = pFrameWindow->navigate(bstrURL); hr = showMeDlgWnd->focus(); SysFreeString(bstrURL); }
|