//+--------------------------------------------------------------------------- // // Microsoft Windows NT5.0 // Copyright (C) Microsoft Corporation, 1997. // // File: N U U T I L S . C P P // // Contents: Functions needed by OEM DLLs for OEM network upgrade // // Notes: // // Author: kumarp 16-October-97 // //---------------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "kkstl.h" #include "nustrs.h" #include "nuutils.h" #include "netupgrd.h" #include "kkutils.h" #include "ncreg.h" // ---------------------------------------------------------------------- extern const WCHAR c_szNetUpgradeDll[]; extern const WCHAR c_szRegValServiceName[]; static const WCHAR c_szComponent[] = L"Component"; // ---------------------------------------------------------------------- // // Function: HrGetWindowsDir // // Purpose: Return full path to %WINDIR% // // Arguments: // pstrWinDir [out] full path to windir // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 19-December-97 // // Notes: // HRESULT HrGetWindowsDir(OUT tstring* pstrWinDir) { DefineFunctionName("HrGetWindowsDir"); HRESULT hr=S_OK; WCHAR szWindowsDir[MAX_PATH+1]; DWORD cNumCharsReturned = GetWindowsDirectory(szWindowsDir, MAX_PATH); if (cNumCharsReturned) { *pstrWinDir = szWindowsDir; } else { hr = HrFromLastWin32Error(); } TraceError(__FUNCNAME__, hr); return hr; } //+--------------------------------------------------------------------------- // // Function: HrGetNetupgrdDir // // Purpose: Get the full path of directory containing netupgrd.dll // // Arguments: // pstrNetupgrdDir [out] the directory path is returned in this // // Returns: S_OK or an HRESULT_FROM_WIN32 error code. // // Author: kumarp 24-July-97 // // Notes: // HRESULT HrGetNetupgrdDir(OUT tstring* pstrNetupgrdDir) { DefineFunctionName("HrGetNetupgrdDir"); AssertValidWritePtr(pstrNetupgrdDir); HRESULT hr=S_OK; WCHAR szNetupgrd[MAX_PATH+1]; HMODULE hModule = GetModuleHandle(c_szNetUpgradeDll); DWORD cPathLen = GetModuleFileName(hModule, szNetupgrd, MAX_PATH); if (!cPathLen) { hr = ERROR_FILE_NOT_FOUND; goto return_from_function; } // split path into components WCHAR szDrive[_MAX_DRIVE+1]; WCHAR szDir[_MAX_DIR+1]; _wsplitpath(szNetupgrd, szDrive, szDir, NULL, NULL); *pstrNetupgrdDir = szDrive; *pstrNetupgrdDir += szDir; return_from_function: TraceError(__FUNCNAME__, hr); return hr; } // ====================================================================== // move to common code // ====================================================================== // ---------------------------------------------------------------------- // // Function: HrSetupGetLineText // // Purpose: Wrapper around SetupGetLineText // // Arguments: // Context [in] pointer to INFCONTEXT // hinf [in] handle of INF // pszSection [in] section name // pszKey [in] key name // pstrReturnedText [in] pointer to returned text // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 19-December-97 // // Notes: // HRESULT HrSetupGetLineText(PINFCONTEXT Context, HINF hinf, PCWSTR pszSection, PCWSTR pszKey, tstring* pstrReturnedText) { DefineFunctionName("HrSetupGetLineText"); BOOL fStatus; HRESULT hr; WCHAR szLineText[MAX_INF_STRING_LENGTH+1]; if (::SetupGetLineText(Context, hinf, pszSection, pszKey, szLineText, MAX_INF_STRING_LENGTH, NULL)) { hr = S_OK; *pstrReturnedText = szLineText; } else { hr = HrFromLastWin32Error (); } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrCopyFiles // // Purpose: Recursively copy all files in SrcDir to DstDir // // Arguments: // pszSrcDir [in] source dir // pszDstDir [in] dest. dir // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 19-December-97 // // Notes: // HRESULT HrCopyFiles(IN PCWSTR pszSrcDir, IN PCWSTR pszDstDir) { DefineFunctionName("HrCopyFiles"); HRESULT hr=S_OK; BOOL fStatus=FALSE; DWORD dwError=ERROR_SUCCESS; TraceTag(ttidNetUpgrade, "%s: Src: %S, Dst: %S", __FUNCNAME__, pszSrcDir, pszDstDir); HANDLE hFileContext; WIN32_FIND_DATA fd; tstring strSrcDirAllFiles; tstring strDstDir; tstring strSrcDir; tstring strFileSrcFullPath; tstring strFileDstFullPath; strSrcDir = pszSrcDir; AppendToPath(&strSrcDir, c_szEmpty); strDstDir = pszDstDir; AppendToPath(&strDstDir, c_szEmpty); strSrcDirAllFiles = pszSrcDir; AppendToPath(&strSrcDirAllFiles, L"*"); hFileContext = FindFirstFile(strSrcDirAllFiles.c_str(), &fd); if (hFileContext != INVALID_HANDLE_VALUE) { do { strFileSrcFullPath = strSrcDir + fd.cFileName; strFileDstFullPath = strDstDir + fd.cFileName; if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (!lstrcmpiW(fd.cFileName, L".") || !lstrcmpiW(fd.cFileName, L"..")) { hr = S_OK; TraceTag(ttidNetUpgrade, "%s: skipped %S", __FUNCNAME__, strFileSrcFullPath.c_str()); } else { TraceTag(ttidNetUpgrade, "%s: creating dir: %S", __FUNCNAME__, strFileDstFullPath.c_str()); fStatus = CreateDirectory(strFileDstFullPath.c_str(), NULL); if (!fStatus) { dwError = GetLastError(); } if (fStatus || (ERROR_ALREADY_EXISTS == dwError)) { hr = HrCopyFiles(strFileSrcFullPath.c_str(), strFileDstFullPath.c_str()); } else { hr = HrFromLastWin32Error(); } } } else if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE)) { TraceTag(ttidNetUpgrade, "%s: copying %S to %S", __FUNCNAME__, strFileSrcFullPath.c_str(), strFileDstFullPath.c_str()); if (CopyFile(strFileSrcFullPath.c_str(), strFileDstFullPath.c_str(), FALSE)) { hr = S_OK; } else { hr = HrFromLastWin32Error(); } } else { TraceTag(ttidNetUpgrade, "%s: skipped %S", __FUNCNAME__, strFileSrcFullPath.c_str()); } if ((S_OK == hr) && FindNextFile(hFileContext, &fd)) { hr = S_OK; } else { hr = HrFromLastWin32Error(); } } while (S_OK == hr); if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES)) { hr = S_OK; } FindClose(hFileContext); } else { hr = HrFromLastWin32Error(); } TraceError(__FUNCNAME__, hr); return hr; } // ---------------------------------------------------------------------- // // Function: HrGetNumNetCardsPreNT5 // // Purpose: Get number of netcards installed on a pre-NT5 system // // Arguments: // pcNetCards [out] pointer to num net cards value // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 13-April-98 // // Notes: Dont use it on NT5! // HRESULT HrGetNumNetCardsPreNT5(OUT UINT* pcNetCards) { DefineFunctionName("HrGetNumNetCardsPreNT5"); HRESULT hr=S_OK; HKEY hkeyAdapters; *pcNetCards = 0; hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyAdapterHome, KEY_READ, &hkeyAdapters); if (S_OK == hr) { WCHAR szBuf[MAX_PATH]; FILETIME time; DWORD dwSize = celems(szBuf); DWORD dwRegIndex = 0; while(S_OK == (hr = HrRegEnumKeyEx(hkeyAdapters, dwRegIndex++, szBuf, &dwSize, NULL, NULL, &time))) { Assert(*szBuf); dwSize = celems(szBuf); (*pcNetCards)++; } RegCloseKey(hkeyAdapters); } TraceErrorSkip2(__FUNCNAME__, hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)); return hr; } // ---------------------------------------------------------------------- // // Function: HrDirExists // // Purpose: Check if the given directory exists // // Arguments: // pszDir [in] full path to a directory // // Returns: S_OK if it exists, S_FALSE if not, otherwise an error code // // Author: kumarp 09-April-98 // // Notes: // HRESULT HrDirectoryExists(IN PCWSTR pszDir) { DefineFunctionName("HrDirExists"); HRESULT hr=S_FALSE; HANDLE hFile=0; BY_HANDLE_FILE_INFORMATION bhfi; hFile = CreateFile(pszDir, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if(INVALID_HANDLE_VALUE != hFile) { if(GetFileInformationByHandle(hFile, &bhfi)) { if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { hr = S_OK; } } else { hr = HrFromLastWin32Error(); } CloseHandle(hFile); } else { hr = HrFromLastWin32Error(); } if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) || (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)) { hr = S_FALSE; } TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE); return hr; } // ====================================================================== // ---------------------------------------------------------------------- // // Function: HrGetPreNT5InfIdAndDesc // // Purpose: Get pre-NT5 InfID and description of a net component // // Arguments: // hkeyCurrentVersion [in] handle of HKLM\Software\\\CurrentVersion // pstrInfId [out] InfID returned // pstrDescription [out] description returned // pstrServiceName [out] service name returned // // Returns: S_OK on success, otherwise an error code // // Author: kumarp 19-December-97 // // Notes: // HRESULT HrGetPreNT5InfIdAndDesc(IN HKEY hkeyCurrentVersion, OUT tstring* pstrInfId, OUT tstring* pstrDescription, OUT tstring* pstrServiceName) { DefineFunctionName("HrGetPreNT5InfIdAndDesc"); Assert(hkeyCurrentVersion); AssertValidWritePtr(pstrInfId); HRESULT hr=S_OK; HKEY hkeyNetRules; hr = HrRegOpenKeyEx(hkeyCurrentVersion, c_szRegKeyNetRules, KEY_READ, &hkeyNetRules); if (S_OK == hr) { hr = HrRegQueryString(hkeyNetRules, c_szRegValInfOption, pstrInfId); if ((S_OK == hr) && pstrDescription) { hr = HrRegQueryString(hkeyCurrentVersion, c_szRegValDescription, pstrDescription); } if ((S_OK == hr) && pstrServiceName) { hr = HrRegQueryString(hkeyCurrentVersion, c_szRegValServiceName, pstrServiceName); } RegCloseKey(hkeyNetRules); } if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { hr = S_FALSE; } TraceErrorOptional(__FUNCNAME__, hr, (hr == S_FALSE)); return hr; } // ---------------------------------------------------------------------- // // Function: GetUnsupportedMessage // // Purpose: Generate a message of the form: // Unsupported Net Card: DEC FDDIcontroller/PCI (DEFPA) // // Arguments: // pszComponentType [in] type of component (net card/service/proto) // pszPreNT5InfId [in] pre-NT5 InfID // pszDescription [in] description // pstrMsg [out] generated message // // Returns: None // // Author: kumarp 19-December-97 // // Notes: // void GetUnsupportedMessage(IN PCWSTR pszComponentType, IN PCWSTR pszPreNT5InfId, IN PCWSTR pszDescription, OUT tstring* pstrMsg) { AssertValidReadPtr(pszPreNT5InfId); AssertValidReadPtr(pszDescription); AssertValidWritePtr(pstrMsg); if (!pszComponentType) { pszComponentType = c_szComponent; } const WCHAR c_szUnsupported[] = L"Possibly unsupported "; *pstrMsg = c_szUnsupported; *pstrMsg = *pstrMsg + pszComponentType + L" : " + pszDescription + L" (" + pszPreNT5InfId + L")"; } // ---------------------------------------------------------------------- // // Function: GetUnsupportedMessageBool // // Purpose: Generate a message of the form: // Unsupported Net Card: DEC FDDIcontroller/PCI (DEFPA) // // Arguments: // fIsHardwareComponent [in] TRUE for a net card // pszPreNT5InfId [in] pre-NT5 InfID // pszDescription [in] description // pstrMsg [out] generated message // // Returns: None // // Author: kumarp 19-December-97 // // Notes: // void GetUnsupportedMessageBool(IN BOOL fIsHardwareComponent, IN PCWSTR pszPreNT5InfId, IN PCWSTR pszDescription, OUT tstring* pstrMsg) { AssertValidReadPtr(pszPreNT5InfId); AssertValidReadPtr(pszDescription); AssertValidWritePtr(pstrMsg); GetUnsupportedMessage(fIsHardwareComponent ? c_szNetCard : c_szComponent, pszPreNT5InfId, pszDescription, pstrMsg); } // ---------------------------------------------------------------------- // // Function: ConvertMultiSzToDelimitedList // // Purpose: Convert a multi-sz to a delimited list // // Arguments: // mszList [in] multi-sz // chDelimeter [in] delimiter // pstrList [out] delimited list // // Returns: None // // Author: kumarp 19-December-97 // // Notes: // void ConvertMultiSzToDelimitedList(IN PCWSTR mszList, IN WCHAR chDelimeter, OUT tstring* pstrList) { ULONG ulLen; *pstrList = c_szEmpty; if (mszList) { while (*mszList) { ulLen = lstrlen(mszList); *pstrList += mszList; *pstrList += chDelimeter; mszList += (ulLen + 1); } } } //+--------------------------------------------------------------------------- // // Function: FIsPreNT5NetworkingInstalled // // Purpose: Find out if atleast one networking component is installed // // Arguments: None // // Returns: TRUE on success, FALSE otherwise // // Author: kumarp 29-July-98 // // Notes: Valid only on pre NT5 versions // BOOL FIsPreNT5NetworkingInstalled() { DefineFunctionName("FIsPreNT5NetworkingInstalled"); HRESULT hr=S_OK; UINT cAdapters=0; if ((S_OK == HrGetNumNetCardsPreNT5(&cAdapters)) && (cAdapters > 0)) { return TRUE; } else { TraceTag(ttidNetUpgrade, "%s: no netcard found, trying to find other network components...", __FUNCNAME__); static const PCWSTR c_aszPreNt5NetworkingServices[] = { L"Alerter", L"Browser", L"DHCP", L"IpRip", L"LanmanServer", L"LanmanWorkstation", L"Messenger", L"NWCWorkstation", L"NetBIOS", L"NetBT", L"NtLmSsp", L"NwlnkIpx", L"NwlnkNb", L"NwlnkRip", L"NwlnkSpx", L"RasAuto", L"RasMan", L"Rdr", L"RelayAgent", L"RemoteAccess", L"Router", L"Rpclocator", L"Srv", L"Tcpip", }; for (int i = 0; i < celems(c_aszPreNt5NetworkingServices); i++) { if (FIsServiceKeyPresent(c_aszPreNt5NetworkingServices[i])) { return TRUE; } } } TraceTag(ttidNetUpgrade, "%s: no netcards or net components found", __FUNCNAME__); return FALSE; } #ifdef ENABLETRACE // ---------------------------------------------------------------------- // // Function: TraceStringList // // Purpose: Trace items of a TStringList // // Arguments: // ttid [in] trace tag id to use // pszMsgPrefix [in] prefix to use // sl [in] list // // Returns: None // // Author: kumarp 19-December-97 // // Notes: // void TraceStringList(IN TraceTagId ttid, IN PCWSTR pszMsgPrefix, IN TStringList& sl) { tstring strTemp; ConvertStringListToCommaList(sl, strTemp); TraceTag(ttid, "%S : %S", pszMsgPrefix, strTemp.c_str()); } // ---------------------------------------------------------------------- // // Function: TraceMultiSz // // Purpose: Trace elements of a multi-sz // // Arguments: // ttid [in] trace tag id to use // pszMsgPrefix [in] prefix to use // msz [in] multi-sz // // Returns: None // // Author: kumarp 19-December-97 // // Notes: // void TraceMultiSz(IN TraceTagId ttid, IN PCWSTR pszMsgPrefix, IN PCWSTR msz) { tstring strTemp; ConvertMultiSzToDelimitedList(msz, ',', &strTemp); TraceTag(ttid, "%S : %S", pszMsgPrefix, strTemp.c_str()); } #endif