//---[ sfninf.cpp ]----------------------------------------------------------- // // NetWare client configuration notify object. // Functionality from old INF // //----------------------------------------------------------------------------- #include "pch.h" #pragma hdrstop #include "sfndef.h" #include "sfnobj.h" #include "ncreg.h" #include "ncsetup.h" //---[ Constants ]------------------------------------------------------------- const WCHAR g_szConfigDLLName[] = NW_CONFIG_DLL_NAME; // sfndef.h const WCHAR c_szLogin[] = L"\\Login"; const WCHAR c_szPublic[] = L"\\Public"; const WCHAR c_szCopyFilesLogin[] = L"CpyFiles_Login"; const WCHAR c_szCopyFilesPublic[] = L"CpyFiles_Public"; extern const WCHAR c_szFPNWVolumes[] = L"System\\CurrentControlSet\\Services\\FPNW\\Volumes"; extern const WCHAR c_szSys[] = L"Sys"; extern const WCHAR c_szPath[] = L"Path="; //---[ Typedefs ]-------------------------------------------------------------- //---[ Prototypes ]------------------------------------------------------------ HRESULT HrInstallFPNWPerfmonCounters(); //----------------------------------------------------------------------------- //---[ CSFNCfg::HrCodeFromOldINF ]------------------------------------------- // // This contains all of the logic from the old oemnsvnw.inf, or at least // calls to helper functions that perform all of the logic. This runs pretty // much straight through the old installadapter code. // // Parameters - None // //----------------------------------------------------------------------------- HRESULT CSFNCfg::HrCodeFromOldINF() { HRESULT hr = S_OK; BOOL fResult = TRUE; hr = HrLoadConfigDLL(); if (FAILED(hr)) { goto Exit; } // Call the FPNWCFG function that tests for a running spooler. fResult = m_pfnIsSpoolerRunning(); if (!fResult) { hr = E_FAIL; TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrCodeFromOldINF failed in SpoolerRunning"); goto Exit; } hr = HrDoConfigDialog(); if (FAILED(hr)) { TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrCodeFromOldINF failed in HrDoConfigDialog"); goto Exit; } hr = HrInstallFPNWPerfmonCounters(); if (FAILED(hr)) { TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrCodeFromOldINF failed in HrInstallFPNWPerfmonCounters"); goto Exit; } Exit: TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrCodeFromOldINF"); return hr; } //---[ CSFNCfg::HrLoadConfigDLL ]---------------------------------------------- // // Load nwcfg.dll, so we can call some of the functions within. Also, do the // GetProcAddress calls for all of the functions that we might need. // // Parameters - None // //----------------------------------------------------------------------------- HRESULT CSFNCfg::HrLoadConfigDLL() { HRESULT hr = S_OK; AssertSz(!m_hlibConfig, "This should not be getting initialized twice"); m_hlibConfig = LoadLibrary(g_szConfigDLLName); if (!m_hlibConfig) { DWORD dwLastError = GetLastError(); TraceHr(ttidSFNCfg, FAL, hr, FALSE, "Failed to LoadLib the config DLL"); hr = E_FAIL; goto Exit; } // Get DLL entry point for the IsSpoolerRunning API // m_pfnIsSpoolerRunning = (FPNWCFG_ISSPOOLERRUNNING_PROC) GetProcAddress(m_hlibConfig, "IsSpoolerRunning"); // Get DLL entry point for the RunNcpDlg API // m_pfnRunNcpDlg = (FPNWCFG_RUNNCPDLG_PROC) GetProcAddress(m_hlibConfig, "RunNcpDlg"); // Get DLL entry point for the CommitNcpDlg API // m_pfnCommitNcpDlg = (FPNWCFG_COMMITNCPDLG_PROC) GetProcAddress(m_hlibConfig, "FCommitNcpDlg"); // Get DLL entry point for the RemoveNcpServer API // m_pfnRemoveNcpServer = (FPNWCFG_REMOVENCPSERVER_PROC) GetProcAddress(m_hlibConfig, "RemoveNcpServer"); // If any of these are bogus, then we need to fail out. // if (!m_pfnIsSpoolerRunning || !m_pfnRunNcpDlg || !m_pfnCommitNcpDlg || !m_pfnRemoveNcpServer) { TraceHr(ttidSFNCfg, FAL, hr, FALSE, "Failed to load one of the config DLL functions"); hr = E_FAIL; goto Exit; } Exit: TraceHr(ttidSFNCfg, FAL, hr, FALSE, "CSFNCfg::HrLoadConfigDLL()"); return hr; } //---[ CSFNCfg::FreeConfigDLL ]---------------------------------------------- // // Free nwcfg.dll, and NULL out the function pointers. // // Parameters - None // //----------------------------------------------------------------------------- VOID CSFNCfg::FreeConfigDLL() { // If we successfully loaded the library, free it. if (m_hlibConfig) { // Free up the library resources. FreeLibrary(m_hlibConfig); m_hlibConfig = NULL; m_pfnIsSpoolerRunning = NULL; m_pfnRunNcpDlg = NULL; m_pfnCommitNcpDlg = NULL; } } //+--------------------------------------------------------------------------- // // Function: HrInstallFPNWPerfmonCounters // // Purpose: Install FPNW perfmon counters (what did you think it did?) // // Arguments: // (none) // // Returns: // // Author: jeffspr 5 Feb 1998 // // Notes: // HRESULT HrInstallFPNWPerfmonCounters() { HRESULT hr = NOERROR; BOOL fResult = FALSE; STARTUPINFO si; PROCESS_INFORMATION pi; WCHAR szIniPath[MAX_PATH+1]; WCHAR szCmdLine[MAX_PATH+1]; ZeroMemory((LPVOID) &si, sizeof(si)); si.cb = sizeof(STARTUPINFO); if (GetSystemDirectory(szIniPath, MAX_PATH+1)) { wsprintfW(szCmdLine, L"lodctr %s\\fpnwperf.ini", szIniPath); fResult = CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (!fResult) { hr = HrFromLastWin32Error(); } } else { hr = E_FAIL; } TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrInstallFPNWPerfmonCounters"); return hr; } HRESULT HrCopySysVolFiles2(INetCfgComponent * pncc, PWSTR pszPath) { TraceFileFunc(ttidSFNCfg); HWND hwndParent = GetActiveWindow(); HRESULT hr; CSetupInfFile csif; PSP_FILE_CALLBACK pfc; PVOID pvCtx; HSPFILEQ hfq; tstring str; // Open the answer file. hr = csif.HrOpen(L"netsfn.inf", NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL); if (FAILED(hr)) { goto Error; } TraceTag(ttidSFNCfg, "Calling SetupOpenFileQueue"); hr = HrSetupOpenFileQueue(&hfq); if (SUCCEEDED(hr)) { TraceTag(ttidSFNCfg, "Calling HrAddSectionFilesToQueue - Login"); str = pszPath; str += c_szLogin; if (!SetupSetDirectoryId(csif.Hinf(), 32768, str.c_str())) { hr = ::HrFromLastWin32Error(); } if (SUCCEEDED(hr)) { TraceTag(ttidSFNCfg, "Calling SetupInstallFilesFromInfSection - Login"); hr = HrSetupInstallFilesFromInfSection(csif.Hinf(), NULL, hfq, c_szCopyFilesLogin, NULL, 0); } TraceTag(ttidSFNCfg, "Calling SetupSetDirectoryId - Public"); str = pszPath; str += c_szPublic; if (!SetupSetDirectoryId(csif.Hinf(), 32769, str.c_str())) { hr = ::HrFromLastWin32Error(); } if (SUCCEEDED(hr)) { TraceTag(ttidSFNCfg, "Calling SetupInstallFilesFromInfSection - Public"); hr = HrSetupInstallFilesFromInfSection(csif.Hinf(), NULL, hfq, c_szCopyFilesPublic, NULL, 0); } // Set the default callback context // If the install is quiet, we need to make sure the callback // doesn't display UI // if (SUCCEEDED(hr)) { TraceTag(ttidSFNCfg, "Calling SetupInitDefaultQueueCallbackEx"); hr = HrSetupInitDefaultQueueCallbackEx(hwndParent, NULL, 0, 0, NULL, &pvCtx); } if (SUCCEEDED(hr)) { // Not doing anything special so use SetupApi default handler // for file copy pfc = SetupDefaultQueueCallback; // Scan the queue to see if the files are already in the // destination and if so, ask the user if he/she wants to // use what's there (provided we are not doing a quiet install) // Note: we only scan the queue if we are not in Gui mode setup // DWORD dwScanResult; TraceTag(ttidSFNCfg, "Scanning queue for validity"); hr = HrSetupScanFileQueueWithNoCallback(hfq, SPQ_SCAN_FILE_VALIDITY | SPQ_SCAN_INFORM_USER, hwndParent, &dwScanResult); // Now commit the queue so any files needing to be // copied, will be // if (SUCCEEDED(hr)) { TraceTag(ttidSFNCfg, "Calling SetupCommitFileQueue"); hr = HrSetupCommitFileQueue(hwndParent, hfq, pfc, pvCtx); } TraceTag(ttidSFNCfg, "Closing queue"); // We need to release the default context // SetupTermDefaultQueueCallback(pvCtx); } // close the file queue // SetupCloseFileQueue(hfq); // Unregister the copy directories // SetupSetDirectoryId(csif.Hinf(), 8001, NULL); SetupSetDirectoryId(csif.Hinf(), 8002, NULL); } Error: TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrCopySysVolFiles2"); return hr; } HRESULT HrCopySysVolFiles(INetCfgComponent * pncc) { HRESULT hr = S_OK; HKEY hkey = NULL; PWSTR psz = NULL; PWSTR pszTmp; Assert(NULL != pncc); // Open the HKLM "System\\CurrentControlSet\\Services\\FPNW\\Volumes" key // hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szFPNWVolumes, KEY_ALL_ACCESS, &hkey); if (FAILED(hr)) { TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrCopySysVolFiles - Volumes key open failed"); goto Error; } // Get the "Sys" value hr = HrRegQueryMultiSzWithAlloc(hkey, c_szSys, &psz); if (FAILED(hr) || !psz || !(*psz)) { TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrCopySysVolFiles - Sys value open failed"); goto Error; } // Find the "Path=" multi-sz entry // for (pszTmp = psz; (*pszTmp); pszTmp += wcslen(pszTmp)) { if (0 == _wcsnicmp(pszTmp, c_szPath, wcslen(c_szPath))) { pszTmp += wcslen(c_szPath); break; } } // If the pszPath points to a character then we found the path // Assert(pszTmp); if (*pszTmp) { hr = HrCopySysVolFiles2(pncc, pszTmp); } else { TraceHr(ttidSFNCfg, FAL, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), FALSE, "HrCopySysVolFiles - Sys volume path is missing!"); } Error: RegSafeCloseKey(hkey); MemFree(psz); // Normalize return code. File not found can occur if the Volumes key // is not present or if the Sys value is missing. The original NT 4 inf // code treated these as acceptable. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { hr = S_OK; } TraceHr(ttidSFNCfg, FAL, hr, FALSE, "HrCopySysVolFiles"); return hr; } HRESULT CSFNCfg::HrDoConfigDialog() { HRESULT hr = S_OK; BOOL fResult = FALSE; BOOL fConfigChanged = FALSE; fResult = m_pfnRunNcpDlg(NULL, TRUE, &m_pNcpInfoHandle, &fConfigChanged); if (!fResult) { hr = E_FAIL; goto Exit; } Exit: return hr; }