//+---------------------------------------------------------------------------- // // File: CompChck.cpp // // Module: CMDIAL32.DLL // // Synopsis: This module contains win32 only conponents checking and installing // // Copyright (c) 1998-1999 Microsoft Corporation // // Author: Fengsun Created 10/21/97 // //+---------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////// // // All the functions in this file are WIN32 implementation only // #include "cmmaster.h" #include "CompChck.h" #include "cmexitwin.cpp" #include "winuserp.h" // // CSDVersion key contains the service pack that has been installed // const TCHAR* const c_pszRegRas = TEXT("SOFTWARE\\Microsoft\\RAS"); const TCHAR* const c_pszCheckComponentsMutex = TEXT("Connection Manager Components Checking"); const TCHAR* const c_pszRegComponentsChecked = TEXT("ComponentsChecked"); const TCHAR* const c_pszSetupPPTPCommand = TEXT("rundll.exe rnasetup.dll,InstallOptionalComponent VPN"); // // Functions internal to this file // static HRESULT CheckComponents(HWND hWndParent, LPCTSTR pszServiceName, DWORD dwComponentsToCheck, OUT DWORD& dwComponentsMissed, BOOL fIgnoreRegKey, BOOL fUnattended ); static BOOL InstallComponents(DWORD dwComponentsToInstall, HWND hWndParent, LPCTSTR pszServiceName); static BOOL MarkComponentsChecked(DWORD dwComponentsChecked); static BOOL ReadComponentsChecked(LPDWORD pdwComponentsChecked); static BOOL IsPPTPInstalled(void); static BOOL InstallPPTP(void); static BOOL IsScriptingInstalled(void); static HRESULT ConfigSystem(HWND hwndParent, DWORD dwfOptions, LPBOOL pbReboot); static HRESULT InetNeedSystemComponents(DWORD dwfOptions, LPBOOL pbNeedSysComponents); static HRESULT InetNeedModem(LPBOOL pbNeedModem); static void DisplayMessageToInstallServicePack(HWND hWndParent, LPCTSTR pszServiceName); static inline HINSTANCE LoadInetCfg(void) { return (LoadLibraryExA("cnetcfg.dll", NULL, 0)); } //+---------------------------------------------------------------------------- // // Function IsPPTPInstalled // // Synopsis Check to see if PPTP is already installed // // Arguments None // // Returns TRUE - PPTP has been installed // FALSE - otherwise // // History 3/25/97 VetriV Created // //----------------------------------------------------------------------------- BOOL IsPPTPInstalled(void) { BOOL bReturnCode = FALSE; HKEY hKey = NULL; DWORD dwSize = 0, dwType = 0; LONG lrc = 0; TCHAR szData[MAX_PATH+1]; if (OS_NT) { if (GetOSMajorVersion() >= 5) { // // PPTP is always installed on NT5 // bReturnCode = TRUE; } else { if (RegOpenKeyExU(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\RASPPTP"), 0, KEY_READ, &hKey) == 0) { RegCloseKey(hKey); bReturnCode = TRUE; } } } else { hKey = NULL; lrc = RegOpenKeyExU(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OptionalComponents\\VPN"), 0, KEY_READ, &hKey); if (ERROR_SUCCESS == lrc) { dwSize = MAX_PATH; lrc = RegQueryValueExU(hKey, TEXT("Installed"), 0, &dwType, (LPBYTE)szData, &dwSize); if (ERROR_SUCCESS == lrc) { if (0 == lstrcmpiU(szData, TEXT("1"))) { // // On 9X, we need to check for Dial-Up Adapter #2. If its // not present then tunneling won't work unless we install // PPTP to install the Adapter #2. // // // On early versions of Win9x Dial-up Adapter was localized, but on WinME, WinSE, // or machines that have DUN 1.3 installed it isn't. Thus, lets try the unlocalized // first and then if that fails we can try the localized version. // const TCHAR * const c_pszDialupAdapter = TEXT("Dial-up Adapter"); LPTSTR pszAdapter = NULL; LPTSTR pszKey = CmStrCpyAlloc(TEXT("System\\CurrentControlSet\\Control\\PerfStats\\Enum\\")); CmStrCatAlloc(&pszKey, c_pszDialupAdapter); CmStrCatAlloc(&pszKey, TEXT(" #2")); // // Close the key that we opened above, and try the one for the adapter // RegCloseKey(hKey); hKey = NULL; if (ERROR_SUCCESS == RegOpenKeyExU(HKEY_LOCAL_MACHINE, pszKey, 0, KEY_QUERY_VALUE, &hKey)) { bReturnCode = TRUE; } else { CmFree (pszKey); pszAdapter = CmLoadString(g_hInst, IDS_REG_DIALUP_ADAPTER); pszKey = CmStrCpyAlloc(TEXT("System\\CurrentControlSet\\Control\\PerfStats\\Enum\\")); CmStrCatAlloc(&pszKey, pszAdapter); CmStrCatAlloc(&pszKey, TEXT(" #2")); // // Close the key that we opened above, and try the one for the adapter // RegCloseKey(hKey); hKey = NULL; if (ERROR_SUCCESS == RegOpenKeyExU(HKEY_LOCAL_MACHINE, pszKey, 0, KEY_QUERY_VALUE, &hKey)) { bReturnCode = TRUE; } } CmFree(pszKey); CmFree(pszAdapter); } } } if (hKey) { RegCloseKey(hKey); hKey = NULL; } } return bReturnCode; } //+---------------------------------------------------------------------------- // // Function InstallPPTP // // Synopsis Install PPTP on Windows 95 and NT // // Arguments None // // Returns TRUE -- if was successfully installed // FALSE -- Otherwise // // History 3/25/97 VetriV Created // 7/8/97 VetriV Added code to setup PPTP on Memphis // //----------------------------------------------------------------------------- BOOL InstallPPTP(void) { BOOL bReturnCode = FALSE; STARTUPINFO si; PROCESS_INFORMATION pi; MSG msg ; if (OS_NT || OS_W95) { // // Don't know how to install/configure PPTP on NT. // We let the admin wrestle with MSDUNXX on W95 // return FALSE; } else { TCHAR szCommand[128]; ZeroMemory(&pi, sizeof(pi)); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(STARTUPINFO); // // NOTE: The original version called "msdun12.exe /q /R:N" to install tunneling // on Windows 95. Now we use 98 approach only and call the following: // "rundll.exe rnasetup.dll,InstallOptionalComponent VPN". // MYDBGASSERT(1353 < LOWORD(GetOSBuildNumber())); lstrcpyU(szCommand, c_pszSetupPPTPCommand); if (NULL == CreateProcessU(NULL, szCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { CMTRACE1(TEXT("InstallPPTP() CreateProcess() failed, GLE=%u."), GetLastError()); } else { CMTRACE(TEXT("InstallPPTP() Launched PPTP Install. Waiting for exit.")); // // wait for event or msgs. Dispatch msgs. Exit when event is signalled. // while((MsgWaitForMultipleObjects(1, &pi.hProcess, FALSE, INFINITE, QS_ALLINPUT) == (WAIT_OBJECT_0 + 1))) { // // read all of the messages in this next loop // removing each message as we read it // while (PeekMessageU(&msg, NULL, 0, 0, PM_REMOVE)) { CMTRACE(TEXT("InstallPPTP() Got Message")); // // how to handle quit message? // DispatchMessageU(&msg); if (msg.message == WM_QUIT) { CMTRACE(TEXT("InstallPPTP() Got Quit Message")); goto done; } } } done: CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // // PPTP was successfully installed // bReturnCode = TRUE; CMTRACE(TEXT("InstallPPTP() done")); } } return bReturnCode; } //+---------------------------------------------------------------------------- // // Function IsMSDUN12Installed // // Synopsis Check if MSDUN 1.2 or higher is installed. // // Arguments none // // Returns TRUE - MSDUN 1.2 is installed // // History 8/12/97 nickball from ICW for 11900 // //----------------------------------------------------------------------------- #define DUN_12_Version "1.2" BOOL IsMSDUN12Installed() { CHAR szBuffer[MAX_PATH] = {"\0"}; HKEY hkey = NULL; BOOL bRC = FALSE; DWORD dwType = 0; DWORD dwSize = sizeof(szBuffer); // // Try to open the Version key // if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\RemoteAccess", 0, KEY_READ, &hkey)) { return FALSE; } // // The key exists, check the value // if (ERROR_SUCCESS == RegQueryValueExA(hkey, "Version", NULL, &dwType, (LPBYTE)szBuffer, &dwSize)) { // // If the entry starts with "1.2", (eg. "1.2c") its a hit // bRC = (szBuffer == CmStrStrA(szBuffer, DUN_12_Version)); } RegCloseKey(hkey); return bRC; } //+---------------------------------------------------------------------------- // // Function IsISDN11Installed // // Synopsis Check if ISDN 1.1 is installed // // Arguments none // // Returns TRUE - ISDN 1.1 is installed // // Note: MSDUN12 superscedes ISDN1.1, but ISDN1.1 does provide scripting // // History 8/12/97 nickball // //----------------------------------------------------------------------------- BOOL IsISDN11Installed() { CHAR szBuffer[MAX_PATH] = {"\0"}; HKEY hkey = NULL; BOOL bRC = FALSE; DWORD dwType = 0; DWORD dwSize = sizeof(szBuffer); if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\OptionalComponents\\MSISDN", 0, KEY_READ, &hkey)) { goto IsISDN11InstalledExit; } if (ERROR_SUCCESS != RegQueryValueExA(hkey, "Installed", NULL, &dwType, (LPBYTE)szBuffer, &dwSize)) { goto IsISDN11InstalledExit; } if (0 == lstrcmpA("1", szBuffer)) { bRC = TRUE; } IsISDN11InstalledExit: return bRC; } //+---------------------------------------------------------------------------- // // Function IsScriptingInstalled // // Synopsis Check to see if scripting is already installed // // Arguments None // // Returns TRUE - scripting has been installed // // History 3/5/97 VetriV From ICW code // //----------------------------------------------------------------------------- BOOL IsScriptingInstalled(void) { BOOL bReturnCode = FALSE; HKEY hkey = NULL; DWORD dwSize = 0, dwType = 0; LONG lrc = 0; HINSTANCE hInst = NULL; CHAR szData[MAX_PATH+1]; if (OS_NT) { // // NT comes with Scripting installed // bReturnCode = TRUE; } else { // // OSR2 and higher releases of Windows 95 have scripting installed // if (1111 <= LOWORD(GetOSBuildNumber())) { bReturnCode = TRUE; } else { // // Must be Gold 95, check for installed scripting // if (IsMSDUN12Installed() || IsISDN11Installed()) { bReturnCode = TRUE; } else { hkey = NULL; lrc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\RemoteAccess\\Authentication\\SMM_FILES\\PPP", 0, KEY_READ, &hkey); if (ERROR_SUCCESS == lrc) { dwSize = MAX_PATH; lrc = RegQueryValueExA(hkey, "Path", 0, &dwType, (LPBYTE)szData, &dwSize); if (ERROR_SUCCESS == lrc) { if (0 == lstrcmpiA(szData,"smmscrpt.dll")) { bReturnCode = TRUE; } } } if (hkey) { RegCloseKey(hkey); hkey = NULL; } // // Verify that the DLL can be loaded // if (bReturnCode) { hInst = LoadLibraryExA("smmscrpt.dll", NULL, 0); if (hInst) { FreeLibrary(hInst); } else { bReturnCode = FALSE; } hInst = NULL; } } } } return bReturnCode; } //+---------------------------------------------------------------------------- // Function VerifyRasServicesRunning // // Synopsis Make sure that the RAS services are enabled and running // // Arguments hWndDlg: - Window Handle of parent window // pszServiceName - Service name for titles // fUnattended: - if TRUE, do not do not popup any UI // // Return FALSE - if the services couldn't be started // // History 2/26/97 VetriV Copied from ICW code //----------------------------------------------------------------------------- BOOL VerifyRasServicesRunning(HWND hWndDlg, LPCTSTR pszServiceName, BOOL fUnattended) { BOOL bReturnCode = FALSE; HINSTANCE hInstance = NULL; HRESULT (WINAPI *pfn)(void); hInstance = LoadInetCfg(); if (!hInstance) { CMTRACE1(TEXT("VerifyRasServicesRunning() LoadLibrary() failed, GLE=%u."), GetLastError()); } else { pfn = (HRESULT (WINAPI *)(void))GetProcAddress(hInstance, "InetStartServices"); if (pfn) { LPTSTR pszDisabledMsg; LPTSTR pszExitMsg; pszDisabledMsg = CmFmtMsg(g_hInst, IDS_SERVICEDISABLED); pszExitMsg = CmFmtMsg(g_hInst, IDS_WANTTOEXIT); // // Check RAS Services // do { HRESULT hr = pfn(); if (ERROR_SUCCESS == hr) { bReturnCode = TRUE; break; } else { CMTRACE1(TEXT("VerifyRasServicesRunning() InetStartServices() failed, GLE=%u."), hr); } // // Do not retry if unattended // if (!fUnattended) { bReturnCode = FALSE; break; } // // Check the error code of OpenService // Do not ask user to retry for certain errors // if (hr == ERROR_SERVICE_DOES_NOT_EXIST || hr == ERROR_FILE_NOT_FOUND || hr == ERROR_ACCESS_DENIED) { LPTSTR pszNotInstalledMsg = CmFmtMsg(g_hInst, IDS_SERVICENOTINSTALLED); // // Report the error and Exit // MessageBoxEx(hWndDlg, pszNotInstalledMsg, pszServiceName, MB_OK|MB_ICONSTOP, LANG_USER_DEFAULT); CmFree(pszNotInstalledMsg); bReturnCode = FALSE; break; } // // Report the error and allow the user to retry // if (IDYES != MessageBoxEx(hWndDlg,pszDisabledMsg,pszServiceName, MB_YESNO | MB_DEFBUTTON1 | MB_ICONWARNING, LANG_USER_DEFAULT)) { // // Confirm Exit // if (IDYES == MessageBoxEx(hWndDlg, pszExitMsg, pszServiceName, MB_APPLMODAL | MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, LANG_USER_DEFAULT)) { bReturnCode = FALSE; break; } } } while (1); CmFree(pszDisabledMsg); CmFree(pszExitMsg); } else { CMTRACE1(TEXT("VerifyRasServicesRunning() GetProcAddress() failed, GLE=%u."), GetLastError()); } FreeLibrary(hInstance); } return bReturnCode; } //+---------------------------------------------------------------------------- // Function CheckAndInstallComponents // // Synopsis Make sure the system is setup for dialing // // Arguments dwComponentsToCheck - Components to be checked // hWndParent - Window Handle of parent window // pszServiceName - Long service name for error titles // fIgnoreRegKey: - Whether ignore ComponetsChecked registry key // Default is TRUE, check the components even if their bit is set // in registry // fUnattended: if TRUE, do not try to install missed components, // do not popup any UI // Defualt is FALSE, install. // // Return Other - if system could not be configured // or if the we have to reboot to continue // ERROR_SUCCESS - Check and install successfully // // History 3/13/97 VetriV // 6/24/97 byao Modified. Set pArgs->dwExitCode accordingly // 11/6/97 fengsun changed parameters, do not pass pArgs //----------------------------------------------------------------------------- DWORD CheckAndInstallComponents(DWORD dwComponentsToCheck, HWND hWndParent, LPCTSTR pszServiceName, BOOL fIgnoreRegKey, BOOL fUnattended) { MYDBGASSERT( (dwComponentsToCheck & ~(CC_RNA | CC_TCPIP | CC_MODEM | CC_PPTP | CC_SCRIPTING | CC_RASRUNNING | CC_CHECK_BINDINGS) ) == 0 ); if (dwComponentsToCheck == 0) { return ERROR_SUCCESS; } // // Open the mutex, so only one CM instance can call this function. // The destructor of CNamedMutex will release the mutex // CNamedMutex theMutex; if (!theMutex.Lock(c_pszCheckComponentsMutex)) { // // Another instance of cm is checking components. Return here // LPTSTR pszMsg = CmLoadString(g_hInst, IDMSG_COMPONENTS_CHECKING_INPROCESS); MessageBoxEx(hWndParent, pszMsg, pszServiceName, MB_OK | MB_ICONERROR, LANG_USER_DEFAULT); CmFree(pszMsg); return ERROR_CANCELLED; } // // Find components missed // DWORD dwComponentsMissed = 0; DWORD dwRet = CheckComponents(hWndParent, pszServiceName, dwComponentsToCheck, dwComponentsMissed, fIgnoreRegKey, fUnattended); if (dwRet == ERROR_SUCCESS) { MYDBGASSERT(dwComponentsMissed == 0); return ERROR_SUCCESS; } if (dwRet == E_ACCESSDENIED && OS_NT5) { // // On NT5, non-admin user does not have access to check components // Continue. // return ERROR_SUCCESS; } if (fUnattended) { // // Do not try to install if fUnattended is TRUE // return dwRet; } if (dwComponentsMissed & ~CC_RASRUNNING) { // // Prompt user before configuring system // If modem is not installed, expilitly say that // LPTSTR pszMsg; if (dwComponentsMissed == CC_MODEM) { // // On NT4, if RAS is installed and modem is not installed or // not configured for dialout, then we cannot programmatically // install and configure modem for the user (limitation of NT RAS // install/configuration). So, we will display a message to user // to manually go and install and/or configure modem from NCPA // if (OS_NT4) { pszMsg = CmFmtMsg(g_hInst, IDMSG_INSTALLMODEM_MANUALLY_MSG); MessageBoxEx(hWndParent, pszMsg, pszServiceName, MB_OK | MB_ICONERROR, LANG_USER_DEFAULT); CmFree(pszMsg); return ERROR_CANCELLED; } else { pszMsg = CmFmtMsg(g_hInst, IDMSG_NOMODEM_MSG); } } else { pszMsg = CmFmtMsg(g_hInst, IDMSG_NORAS_MSG); } int iRes = MessageBoxEx(hWndParent, pszMsg, pszServiceName, MB_YESNO | MB_DEFBUTTON1 | MB_ICONWARNING, LANG_USER_DEFAULT); CmFree(pszMsg); if (IDYES != iRes) { return ERROR_CANCELLED; } if (!InstallComponents(dwComponentsMissed, hWndParent, pszServiceName)) { // // Some time, GetLastError returns ERROR_SUCCESS // return (GetLastError() == ERROR_SUCCESS ? ERROR_CANCELLED : GetLastError()); } } // // We can not do anything if RAS can not be started on NT // if (dwComponentsMissed & CC_RASRUNNING) { return dwRet; } else { return ERROR_SUCCESS; } } //+---------------------------------------------------------------------------- // Function MarkComponentsChecked // // Synopsis Mark(in registry) what components have been checked. // // Arguments DWORD dwComponentsInstalled - a dword(bitwise OR'ed) // // Return TRUE - success // FALSE - otherwise // // History 08/07/97 Fengsun - created // 08/11/97 henryt - changed return type. // 07/03/98 nickball - create if can't open //----------------------------------------------------------------------------- BOOL MarkComponentsChecked(DWORD dwComponentsChecked) { HKEY hKeyCm; // // Try to open the key for writing // LONG lRes = RegOpenKeyExU(HKEY_LOCAL_MACHINE, c_pszRegCmRoot, 0, KEY_SET_VALUE , &hKeyCm); // // If we can't open it the key may not be there, try to create it. // if (ERROR_SUCCESS != lRes) { DWORD dwDisposition; lRes = RegCreateKeyExU(HKEY_LOCAL_MACHINE, c_pszRegCmRoot, 0, TEXT(""), REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKeyCm, &dwDisposition); } // // On success, update the ComponentsChecked value, then close // if (ERROR_SUCCESS == lRes) { lRes = RegSetValueExU(hKeyCm, c_pszRegComponentsChecked, NULL, REG_DWORD, (BYTE*)&dwComponentsChecked, sizeof(dwComponentsChecked)); RegCloseKey(hKeyCm); } return (ERROR_SUCCESS == lRes); } //+---------------------------------------------------------------------------- // Function ReadComponentsChecked // // Synopsis Read(from registry) what components have been checked. // // Arguments LPDWORD pdwComponentsInstalled - a ptr dword(bitwise OR'ed) // // Return TRUE - success // FALSE - otherwise // // History 8/7/97 fengsun original code // 8/11/97 henryt created the func. //----------------------------------------------------------------------------- BOOL ReadComponentsChecked( LPDWORD pdwComponentsChecked ) { BOOL fSuccess = FALSE; HKEY hKeyCm; DWORD dwType; DWORD dwSize = sizeof(DWORD); *pdwComponentsChecked = 0; if (RegOpenKeyExU(HKEY_LOCAL_MACHINE, c_pszRegCmRoot, 0, KEY_QUERY_VALUE , &hKeyCm) == ERROR_SUCCESS) { if ((RegQueryValueExU(hKeyCm, c_pszRegComponentsChecked, NULL, &dwType, (BYTE*)pdwComponentsChecked, &dwSize) == ERROR_SUCCESS) && (dwType == REG_DWORD) && (dwSize == sizeof(DWORD))) { fSuccess = TRUE; } RegCloseKey(hKeyCm); } return fSuccess; } //+---------------------------------------------------------------------------- // // Function: ClearComponentsChecked // // Synopsis: Clear the component checked flag in registry back to 0 // // Arguments: None // // Returns: Nothing // // History: fengsun Created Header 2/19/98 // //+---------------------------------------------------------------------------- void ClearComponentsChecked() { MarkComponentsChecked(0); } //+---------------------------------------------------------------------------- // Function CheckComponents // // Synopsis Checks to see if the system has all the components // required of the service profile (like PPTP, TCP,...) // installed and configured // // Arguments hWndParent -Window Handle of parent window // pszServiceName - Service Name for title // dwComponentsToCheck:- Components to check // dwComponentsMissed: - OUT components missed // fIgnoreRegKey: - Whether ignore ComponetsChecked registry key // Default is FALSE, not check the components whose bit is set // in registry // fUnattended: if TRUE, do not do not popup any UI // // Return ERROR_SUCCESS- system does not need configuration // Other - otherwise // // History 5/5/97 VetriV // 6/26/97 byao Modified: update pArgs->dwExitCode when // components needed // 8/11/97 henryt Performance changes. Added CC_* flags. // 9/30/97 henryt added pfPptpNotInstalled // 11/6/97 fengsun changed parameters, do not pass pArgs //----------------------------------------------------------------------------- HRESULT CheckComponents(HWND hWndParent, LPCTSTR pszServiceName, DWORD dwComponentsToCheck, OUT DWORD& dwComponentsMissed, BOOL fIgnoreRegKey, BOOL fUnattended ) { DWORD dwComponentsAlreadyChecked = 0; // Components already checked, to be saved into registry ReadComponentsChecked(&dwComponentsAlreadyChecked); CMTRACE1(TEXT("CheckComponents: dwComponentsToCheck = 0x%x"), dwComponentsToCheck); CMTRACE1(TEXT("CheckComponents: dwComponentsAlreadyChecked = 0x%x"), dwComponentsAlreadyChecked); // // If this is NT4 and we have successfully checked RAS installation // previously, double-check by examining Reg key. We do this because // the user may have removed RAS since our last component check in // which case an unpleasant message is displayed to the user when // we try to load RASAPI32.DLL // if (dwComponentsAlreadyChecked & CC_RNA) { if (OS_NT4) { // // RAS was installed properly at some point, but if // we can't open the key, then mark it as un-checked. // HKEY hKeyCm; DWORD dwRes = RegOpenKeyExU(HKEY_LOCAL_MACHINE, c_pszRegRas, 0, KEY_QUERY_VALUE , &hKeyCm); if (ERROR_SUCCESS == dwRes) { RegCloseKey(hKeyCm); } else { dwComponentsAlreadyChecked &= ~CC_RNA; } } } if (!fIgnoreRegKey) { // // Do not check those components already marked as checked in the registry // dwComponentsToCheck &= ~dwComponentsAlreadyChecked; } CMTRACE1(TEXT("CheckComponents: Now only checking components = 0x%x"), dwComponentsToCheck); HRESULT hrRet = S_OK; // return value dwComponentsMissed = 0; // Components not installed // // Check for DUN and TCP // if (dwComponentsToCheck & (CC_RNA | CC_TCPIP | CC_CHECK_BINDINGS)) { BOOL bNeedSystemComponents = FALSE; if (dwComponentsToCheck & CC_CHECK_BINDINGS) { // // If we to check if PPP is bound to TCP // hrRet = InetNeedSystemComponents(INETCFG_INSTALLRNA | INETCFG_INSTALLTCP, &bNeedSystemComponents); } else { // // If we do not want to check if TCP is bound (in case of shims) // check just if TCP is installed // hrRet = InetNeedSystemComponents(INETCFG_INSTALLRNA | INETCFG_INSTALLTCPONLY, &bNeedSystemComponents); } if ((FAILED(hrRet)) || (TRUE == bNeedSystemComponents)) { // // Set the Missing components properly - RNA and/or TCP missing // whether binding is missing or not depends on // if CC_REVIEW_BINDINGS was set or not // dwComponentsMissed |= (CC_RNA | CC_TCPIP); if (dwComponentsToCheck & CC_CHECK_BINDINGS) { dwComponentsMissed |= CC_CHECK_BINDINGS; } if (SUCCEEDED(hrRet)) { hrRet = HRESULT_FROM_WIN32(ERROR_PROTOCOL_NOT_CONFIGURED); } } } // // Check for Modem // Note: Should not even run the modem check is RNA is not installed // if (dwComponentsToCheck & CC_MODEM) { BOOL bNeedModem = FALSE; hrRet = InetNeedModem(&bNeedModem); if (FAILED(hrRet)) { dwComponentsMissed |= (CC_MODEM | CC_RNA); } else { if (TRUE == bNeedModem) { dwComponentsMissed |= CC_MODEM; hrRet = HRESULT_FROM_WIN32(ERROR_PROTOCOL_NOT_CONFIGURED); } } } // // Check if PPTP is installed, IsPPTPInstalled always returns TRUE for NT5 // if (dwComponentsToCheck & CC_PPTP) { if (FALSE == IsPPTPInstalled()) { dwComponentsMissed |= CC_PPTP; hrRet = HRESULT_FROM_WIN32(ERROR_PROTOCOL_NOT_CONFIGURED); } } // // Check for scripting // if PPTP is installed then we have scripting also // - msdun12.exe (used to install PPTP on Win95 contains scripting) if (dwComponentsToCheck & CC_SCRIPTING) { if ((FALSE == IsScriptingInstalled()) && (FALSE == IsPPTPInstalled())) { dwComponentsMissed |= CC_SCRIPTING; hrRet = HRESULT_FROM_WIN32(ERROR_PROTOCOL_NOT_CONFIGURED); } } // // Check if RAS services are running // This is basically for NT4 and becomes a NOP on Windows 95 or NT5 // On NT5, CM is started by Connection Folder. RAS is automaticlly // started when ConnFolder is launched or CM desktop icon is clicked. If RAS service // failed to launch, CM will not be execute at all. // if (OS_NT && (dwComponentsToCheck & CC_RASRUNNING)) { if (FALSE == VerifyRasServicesRunning(hWndParent, pszServiceName, !fUnattended)) { // // Don't let the user continue if RAS is not running // dwComponentsMissed |= CC_RASRUNNING; DWORD dwRet = ( GetLastError() == ERROR_SUCCESS )? ERROR_PROTOCOL_NOT_CONFIGURED : GetLastError(); hrRet = HRESULT_FROM_WIN32(dwRet); } } // // Update the components already checked // Plus Components just checked, including those failed // Minus components missed // DWORD dwComponentsCheckedNew = (dwComponentsAlreadyChecked | dwComponentsToCheck) & ~dwComponentsMissed; // // Update only if there is some change // if (dwComponentsCheckedNew != dwComponentsAlreadyChecked) { MarkComponentsChecked(dwComponentsCheckedNew); } return hrRet; } //+---------------------------------------------------------------------------- // Function InstallComponents // // Synopsis Installs all components required for the profile // (PPTP, TCP, DUN, Modem,...) // // Arguments hWndDlg - Window Handle of parent window // pszServiceName - Name of the service for title // dwComponentsToInstall - Componets to install // // Return FALSE - if system could not be configured // TRUE - otherwise // // History 3/13/97 VetriV Created // 5/5/97 VetriV Renamed function as InstallComponents // (used to be ConfigureSystemForDialing) // 9/30/97 henryt added fInstallPptpOnly // 11/6/97 fengsun changed parameters, do not pass pArgs // 2/3/98 VetriV changed code to inform user to reinstall // service pack if any component was installed // by this function and user had some SP // installed in the system //----------------------------------------------------------------------------- BOOL InstallComponents(DWORD dwComponentsToInstall, HWND hWndDlg, LPCTSTR pszServiceName) { // // We are not allowed to configure the system at WinLogon because we have // no idea who the user is. It could be just a random person walking up to the box. // if (!IsLogonAsSystem()) { BOOL bReboot = FALSE; CMTRACE1(TEXT("InstallComponents: dwComponentsToInstall = 0x%x"), dwComponentsToInstall); // // We can not do any thing if RAS is not running // MYDBGASSERT(!(dwComponentsToInstall & CC_RASRUNNING)); // // Disable the window, and enable it on return // The property sheet also need to be disabled // CFreezeWindow FreezeWindow(hWndDlg, TRUE); DWORD hRes = ERROR_SUCCESS; // // Do not install modem here. Install modem after reboot // if (dwComponentsToInstall & (CC_RNA | CC_MODEM | INETCFG_INSTALLTCP | INETCFG_INSTALLTCPONLY)) { DWORD dwInetComponent = 0; dwInetComponent |= (dwComponentsToInstall & CC_RNA ? INETCFG_INSTALLRNA :0) | (dwComponentsToInstall & CC_MODEM ? INETCFG_INSTALLMODEM :0); // // Only way to check bindings is by installing TCP // This case will also cover the more common case of installing TCP // and checking for bindings // if (CC_CHECK_BINDINGS & dwComponentsToInstall) { dwInetComponent |= INETCFG_INSTALLTCP; } else if (CC_TCPIP & dwComponentsToInstall) { // // If bindings check is not turned on // dwInetComponent |= INETCFG_INSTALLTCPONLY; } if (dwInetComponent) { hRes = ConfigSystem(hWndDlg,dwInetComponent, &bReboot); } } if (ERROR_SUCCESS == hRes) { // // Check for scripting // if PPTP is installed than we have scripting also // - because msdun12.exe (used to install PPTP on Win95 // contains scripting) // and install if it is needed // if ((dwComponentsToInstall & CC_SCRIPTING) && !(dwComponentsToInstall & CC_PPTP) ) { LPTSTR pszNoScriptMsg = CmFmtMsg(g_hInst, IDMSG_NO_SCRIPT_INST_MSG_95); if (pszNoScriptMsg) { MessageBoxEx(hWndDlg, pszNoScriptMsg, pszServiceName, MB_OK | MB_ICONSTOP, LANG_USER_DEFAULT); CmFree(pszNoScriptMsg); } return FALSE; } // // Check if PPTP is required and not already installed install it // if (dwComponentsToInstall & CC_PPTP) { if (TRUE == InstallPPTP()) // Note: Always fails on 95 by design { // // We have to reboot after installing PPTP // bReboot = TRUE; } else { LPTSTR pszMsg; // // Don't let the user continue PPTP is not installed // if (OS_NT) { if (IsServicePackInstalled()) { // // we need to tell the user to re-apply the service pack after manual // install of PPTP. // pszMsg = CmFmtMsg(g_hInst, IDMSG_NOPPTPINST_MSG_NT_SP); // NT } else { pszMsg = CmFmtMsg(g_hInst, IDMSG_NOPPTPINST_MSG_NT); // NT } } else if (OS_W98) { pszMsg = CmFmtMsg(g_hInst, IDMSG_NOPPTPINST_MSG_98); // W98 } else { pszMsg = CmFmtMsg(g_hInst, IDMSG_NOPPTPINST_MSG_95); // default } if (pszMsg) { MessageBoxEx(hWndDlg, pszMsg, pszServiceName, MB_OK | MB_ICONSTOP, LANG_USER_DEFAULT); CmFree(pszMsg); } return FALSE; } } } if ((ERROR_SUCCESS == hRes) && bReboot) { if (OS_NT && (TRUE == IsServicePackInstalled())) { // // If service pack is installed, then display message asking // user to re-install the service pack and exit without rebooting // We do this because rebooting after installing RAS, without // reinstalling the service pack can cause BlueScreen! // DisplayMessageToInstallServicePack(hWndDlg, pszServiceName); return FALSE; } else { // // Display reboot message and is user wants reboot the sytem // LPTSTR pszMsg = CmFmtMsg(g_hInst,IDMSG_REBOOT_MSG); int iRes = IDNO; if (pszMsg) { iRes = MessageBoxEx(hWndDlg, pszMsg, pszServiceName, MB_YESNO | MB_DEFBUTTON1 | MB_ICONWARNING | MB_SETFOREGROUND, LANG_USER_DEFAULT); CmFree(pszMsg); } else { CMASSERTMSG(FALSE, TEXT("InstallComponents: CmFmtMsg failed to load IDMSG_REBOOT_MSG")); } if (IDYES == iRes) { // // Shutdown Windows, CM will quit gracefully on // WM_ENDSESSION message // What shall we do if MyExitWindowsEx() fialed // DWORD dwReason = OS_NT51 ? (SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_RECONFIG) : 0; MyExitWindowsEx(EWX_REBOOT, dwReason); // // Caller will return failed // return FALSE; } else { // // If user do not want to reboot, shall we quit CM // } } } if (ERROR_SUCCESS == hRes) { return TRUE; } } // // Configuration check failed message, if install is not canceled // LPTSTR pszMsg = CmFmtMsg(g_hInst,IDMSG_CONFIG_FAILED_MSG); if (pszMsg) { MessageBoxEx(hWndDlg, pszMsg, pszServiceName, MB_OK|MB_ICONSTOP, LANG_USER_DEFAULT); CmFree(pszMsg); } else { CMASSERTMSG(FALSE, TEXT("InstallComponents: CmFmtMsg failed to load IDMSG_CONFIG_FAILED_MSG")); } return FALSE; } //+---------------------------------------------------------------------------- // Function ConfigSystem // // Synopsis Use inetcfg.dll to configure system settings, // like install modem, rna etc. // // Arguments hWndDlg - Window Handle of parent window // dwfOptions - Components to be configured // pbReboot - Will be set to true if system has to rebooted // as result of the configuration // // Returns ERROR_SUCCESS if successful // Failure code otherwise // // History Old code //----------------------------------------------------------------------------- HRESULT ConfigSystem(HWND hwndParent, DWORD dwfOptions, LPBOOL pbReboot) { HRESULT hRes = ERROR_SUCCESS; HINSTANCE hLibrary = NULL; HRESULT (WINAPI *pfn)(HWND,DWORD,LPBOOL); hLibrary = LoadInetCfg(); if (!hLibrary) { CMTRACE1(TEXT("ConfigSystem() LoadLibrary() failed, GLE=%u."), GetLastError()); hRes = GetLastError(); goto done; } pfn = (HRESULT (WINAPI *)(HWND,DWORD,LPBOOL)) GetProcAddress(hLibrary, "InetConfigSystem"); if (!pfn) { CMTRACE1(TEXT("ConfigSystem() GetProcAddress() failed, GLE=%u."), GetLastError()); hRes = GetLastError(); goto done; } hRes = pfn(hwndParent,dwfOptions,pbReboot); #ifdef DEBUG if (hRes != ERROR_SUCCESS) { CMTRACE1(TEXT("ConfigSystem() InetConfigSystem() failed, GLE=%u."), hRes); } #endif done: if (hLibrary) { FreeLibrary(hLibrary); hLibrary = NULL; } return (hRes); } //+---------------------------------------------------------------------------- // Function InetNeedSystemComponents // // Synopsis Use inetcfg.dll to check if we need to configure system settings // like rna etc. // // Arguments dwfOptions - Components to be configured // pbNeedSysComponents - Will be set to true if we need to // configure system settings // // Returns ERROR_SUCCESS if successful // Failure code otherwise // // History 5/5/97 VetriV Created //----------------------------------------------------------------------------- HRESULT InetNeedSystemComponents(DWORD dwfOptions, LPBOOL pbNeedSysComponents) { HRESULT hRes = ERROR_SUCCESS; HINSTANCE hLibrary = NULL; HRESULT (WINAPI *pfnInetNeedSystemComponents)(DWORD, LPBOOL); hLibrary = LoadInetCfg(); if (!hLibrary) { hRes = GetLastError(); CMTRACE1(TEXT("InetNeedSystemComponents() LoadLibrary() failed, GLE=%u."), hRes); goto done; } pfnInetNeedSystemComponents = (HRESULT (WINAPI *)(DWORD,LPBOOL)) GetProcAddress(hLibrary, "InetNeedSystemComponents"); if (!pfnInetNeedSystemComponents) { hRes = GetLastError(); CMTRACE1(TEXT("InetNeedSystemComponents() GetProcAddress() failed, GLE=%u."), hRes); goto done; } hRes = pfnInetNeedSystemComponents(dwfOptions, pbNeedSysComponents); #ifdef DEBUG if (hRes != ERROR_SUCCESS) { CMTRACE1(TEXT("InetNeedSystemComponents() failed, GLE=%u."), hRes); } #endif done: if (hLibrary) { FreeLibrary(hLibrary); hLibrary = NULL; } return (hRes); } //+---------------------------------------------------------------------------- // Function InetNeedModem // // Synopsis Use inetcfg.dll to check if we need to install/configure modem // // Arguments pbNeedModem - Will be set to true if we need to // install/configure modem // // Returns ERROR_SUCCESS if successful // Failure code otherwise // // History 5/5/97 VetriV Created //----------------------------------------------------------------------------- HRESULT InetNeedModem(LPBOOL pbNeedModem) { HRESULT hRes = ERROR_SUCCESS; HINSTANCE hLibrary = NULL; HRESULT (WINAPI *pfnInetNeedModem)(LPBOOL); hLibrary = LoadInetCfg(); if (!hLibrary) { hRes = GetLastError(); CMTRACE1(TEXT("InetNeedModem() LoadLibrary() failed, GLE=%u."), hRes); goto done; } pfnInetNeedModem = (HRESULT (WINAPI *)(LPBOOL)) GetProcAddress(hLibrary, "InetNeedModem"); if (!pfnInetNeedModem) { hRes = GetLastError(); CMTRACE1(TEXT("InetNeedModem() GetProcAddress() failed, GLE=%u."), hRes); goto done; } hRes = pfnInetNeedModem(pbNeedModem); #ifdef DEBUG if (hRes != ERROR_SUCCESS) { CMTRACE1(TEXT("InetNeedModem() failed, GLE=%u."), hRes); } #endif done: if (hLibrary) { FreeLibrary(hLibrary); hLibrary = NULL; } return (hRes); } //+---------------------------------------------------------------------------- // Function DisplayMessageToInstallServicePack // // Synopsis Display a message to user informing them to reinstall // Service Pack // // Arguments hWndParent - Window handle to parent // pszServiceName - Service name for title // // Returns None // // History 2/4/98 VetriV Created //----------------------------------------------------------------------------- void DisplayMessageToInstallServicePack(HWND hWndParent, LPCTSTR pszServiceName) { LPTSTR pszMsg = CmFmtMsg(g_hInst,IDMSG_INSTALLSP_MSG); if (pszMsg) { MessageBoxEx(hWndParent, pszMsg, pszServiceName, MB_OK | MB_ICONINFORMATION, LANG_USER_DEFAULT); CmFree(pszMsg); } else { CMASSERTMSG(FALSE, TEXT("DisplayMessageToInstallServicePack: CmFmtMsg failed to load IDMSG_INSTALLSP_MSG")); } return; }