Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

804 lines
22 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: N E T U P G R D . C P P
//
// Contents: DllMain and winnt32.exe plug-in exported functions
//
// Notes:
//
// Author: kumarp 25-Nov-1996
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include <winnt32p.h>
#include "afilestr.h"
#include "conflict.h"
#include "kkcwinf.h"
#include "kkutils.h"
#include "nceh.h"
#include "ncreg.h"
#include "netreg.h"
#include "netupgrd.h"
#include "nuutils.h"
#include "oemupg.h"
#include "resource.h"
#include "dhcpupg.h"
extern const WCHAR c_szNetUpgradeDll[];
extern const WCHAR c_szAfUnknown[];
//Global
WINNT32_PLUGIN_INIT_INFORMATION_BLOCK g_PlugInInfo;
NetUpgradeInfo g_NetUpgradeInfo;
CWInfFile* g_pwifAnswerFile;
HINSTANCE g_hinst;
DWORD g_dwUpgradeError;
void CleanupNetupgrdTempFiles();
void GetNetworkingSections(IN CWInfFile* pwif,
OUT TStringList* pslSections);
const WCHAR c_szExceptionInNetupgrd[] = L"netupgrd.dll threw an exception";
EXTERN_C
BOOL
WINAPI
DllMain (
HINSTANCE hInstance,
DWORD dwReason,
LPVOID /* lpReserved */)
{
if (DLL_PROCESS_ATTACH == dwReason)
{
g_hinst = hInstance;
DisableThreadLibraryCalls(hInstance);
EnableCPPExceptionHandling(); // Translate any SEH exceptions into CPP exceptions.
InitializeDebugging(FALSE); // We cannot disable fault injection on this binary since doing that will require
// us to load verifier.dll, which is not going to work on older builds of Windows.
}
else if (DLL_PROCESS_DETACH == dwReason)
{
UnInitializeDebugging();
DisableCPPExceptionHandling(); // Disable translation of SEH exceptions into CPP exceptions.
}
return TRUE;
}
//+---------------------------------------------------------------------------
//
// Function: HrGetProductTypeUpgradingFrom
//
// Purpose: Determine the product type of the current system
//
// Arguments:
// ppt [out] pointer to
//
// Returns: S_OK on success, otherwise an error code
//
HRESULT HrGetProductTypeUpgradingFrom(
OUT PRODUCTTYPE* ppt)
{
Assert (ppt);
*ppt = NT_WORKSTATION;
HRESULT hr;
HKEY hkeyProductOptions;
hr = HrRegOpenKeyEx(
HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Control\\ProductOptions",
KEY_READ, &hkeyProductOptions);
if (S_OK == hr)
{
WCHAR szProductType [64];
ULONG cbProductType = sizeof(szProductType);
hr = HrRegQuerySzBuffer(
hkeyProductOptions,
L"ProductType",
szProductType,
&cbProductType);
if (S_OK == hr)
{
if (0 != lstrcmpiW(szProductType, L"WinNT"))
{
*ppt = NT_SERVER;
}
}
RegCloseKey(hkeyProductOptions);
}
return hr;
}
//+---------------------------------------------------------------------------
// The following four functions are required to be exported so that
// winnt32.exe can correctly use this plug-in DLL during down level
// upgrade for description of each see winnt32p.h
//
//+---------------------------------------------------------------------------
//
// Function: Winnt32PluginInit
//
// Purpose: Initialize the DLL
//
// Arguments:
// pInfo [in] winnt32 plug-in initialization info
//
// Returns: ERROR_SUCCESS on success, else win32 error code
//
// Author: kumarp 19-December-97
//
// Notes: see winnt32p.h for more information
//
DWORD
CALLBACK
Winnt32PluginInit(
PWINNT32_PLUGIN_INIT_INFORMATION_BLOCK pInfo)
{
DefineFunctionName("Winnt32PluginInit");
TraceFunctionEntry(ttidNetUpgrade);
Assert (pInfo);
CopyMemory(&g_PlugInInfo, pInfo, sizeof(g_PlugInInfo));
// We should only be doing this once.
//
Assert (0 == g_NetUpgradeInfo.To.dwBuildNumber);
Assert (0 == g_NetUpgradeInfo.From.dwBuildNumber);
g_NetUpgradeInfo.To.ProductType = *g_PlugInInfo.ProductType;
g_NetUpgradeInfo.To.dwBuildNumber = g_PlugInInfo.BuildNumber;
g_dwUpgradeError = ERROR_OPERATION_ABORTED;
OSVERSIONINFO osv;
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&osv))
{
// This DLL doesn't upgrade anything but Windows NT.
//
if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
PRODUCTTYPE pt;
HRESULT hr = HrGetProductTypeUpgradingFrom(&pt);
if (S_OK == hr)
{
g_NetUpgradeInfo.From.dwBuildNumber = osv.dwBuildNumber;
g_NetUpgradeInfo.From.ProductType = pt;
NC_TRY
{
g_dwUpgradeError = NOERROR;
(void) HrInitNetUpgrade();
}
NC_CATCH_BAD_ALLOC
{
TraceTag(ttidNetUpgrade, "%s: exception!!", __FUNCNAME__);
g_dwUpgradeError = ERROR_NOT_ENOUGH_MEMORY;
AbortUpgradeFn(g_dwUpgradeError, c_szExceptionInNetupgrd);
}
}
}
}
TraceTag(ttidNetUpgrade, "%s: returning status code: %ld",
__FUNCNAME__, g_dwUpgradeError);
return g_dwUpgradeError;
}
//+---------------------------------------------------------------------------
//
// Function: Winnt32PluginGetPages
//
// Purpose: Supply wizard pages to winnt32.exe
//
// Arguments:
// PageCount1 [in] number of pages in group 1
// Pages1 [in] array of pages in group 1
// PageCount2 [in] number of pages in group 2
// Pages2 [in] array of pages in group 2
// PageCount3 [in] number of pages in group 3
// Pages3 [in] array of pages in group 3
//
// Returns: ERROR_SUCCESS on success, else win32 error code
//
// Author: kumarp 19-December-97
//
// Notes: see winnt32p.h for more information
//
DWORD
CALLBACK
Winnt32PluginGetPages(
PUINT PageCount1,
LPPROPSHEETPAGE *Pages1,
PUINT PageCount2,
LPPROPSHEETPAGE *Pages2,
PUINT PageCount3,
LPPROPSHEETPAGE *Pages3)
{
//We dont need any UI for upgrade and hence no pages
*PageCount1 = 0;
*PageCount2 = 0;
*PageCount3 = 0;
*Pages1 = NULL;
*Pages2 = NULL;
*Pages3 = NULL;
return NOERROR;
}
//+---------------------------------------------------------------------------
//
// Function: Winnt32WriteParams
//
// Purpose: Write network parameters to the answerfile
//
// Arguments:
// FileName [in] name of answerfile
//
// Returns: ERROR_SUCCESS on success, else win32 error code
//
// Author: kumarp 19-December-97
//
// Notes: see winnt32p.h for more information
//
DWORD
CALLBACK
Winnt32WriteParams(
PCWSTR FileName)
{
DefineFunctionName("Winnt32WriteParams");
TraceFunctionEntry(ttidNetUpgrade);
TraceTag(ttidNetUpgrade, "netupgrd.dll: Winnt32WriteParams(%S)", FileName);
NC_TRY
{
if (*g_PlugInInfo.UpgradeFlag && (!(*g_PlugInInfo.CancelledFlag)))
{
// g_pwifAnswerFile needs to be global since functions in
// oemnuex.cpp require it that way.
//
g_pwifAnswerFile = new CWInfFile();
// initialize answer file class
if ((g_pwifAnswerFile == NULL) ||
(g_pwifAnswerFile->Init() == FALSE))
{
AssertSz(FALSE,"Winnt32WriteParams 1 - Failed to initialize CWInfFile");
return(ERROR_OPERATION_ABORTED);
}
g_pwifAnswerFile->Open(FileName);
// ------------------------------------------------------------
//$ REVIEW kumarp 25-November-98
//
// the code between the two dashed lines in temporary.
//
// Currently we do not support merging of the system generated answerfile
// with the user supplied answerfile, because the code was never
// designed to handle that. This causes problem (#175623) when a user
// supplies an answerfile with "NtUpgrade = Yes" value. To get
// around this problem, we just remove all user supplied
// networking sections using the following code. As an additional
// special case, we preserve the key NetComponentsToRemove if
// present in the [Networking] section of the user supplied answerfile.
//
CWInfSection* pwisNetworking;
TStringList slNetComponentsToRemove;
// remember the value of NetComponentsToRemove
if (pwisNetworking =
g_pwifAnswerFile->FindSection(c_szAfSectionNetworking))
{
pwisNetworking->GetStringListValue(c_szAfNetComponentsToRemove,
slNetComponentsToRemove);
}
// get the list of networking sections in the user supplied file
TStringList slUserSuppliedNetworkingSections;
GetNetworkingSections(g_pwifAnswerFile,
&slUserSuppliedNetworkingSections);
TraceStringList(ttidNetUpgrade,
L"User supplied networking sections",
slUserSuppliedNetworkingSections);
// remove the user supplied networking sections
g_pwifAnswerFile->RemoveSections(slUserSuppliedNetworkingSections);
// if NetComponentsToRemove was specified, re-insert it
if (slNetComponentsToRemove.size())
{
pwisNetworking =
g_pwifAnswerFile->AddSection(c_szAfSectionNetworking);
pwisNetworking->AddKey(c_szAfNetComponentsToRemove,
slNetComponentsToRemove);
}
// 295708: cached ptrs may be trashed, so close and reopen the file
// Note: this fix is considered temporary for beta3. The right fix
// is to either fix up the trashed ptrs when removing the sections,
// or to check when accessing the ptrs later. The crash should be
// easy to repro by removing the block below and using the answerfile
// attached to the bug.
//
g_pwifAnswerFile->Close();
delete g_pwifAnswerFile;
g_pwifAnswerFile = NULL;
g_pwifAnswerFile = new CWInfFile();
// initialize answer file class
if ((g_pwifAnswerFile == NULL) ||
(g_pwifAnswerFile->Init() == FALSE))
{
AssertSz(FALSE,"Winnt32WriteParams 2 - Failed to initialize CWInfFile");
return(ERROR_OPERATION_ABORTED);
}
g_pwifAnswerFile->Open(FileName);
// ------------------------------------------------------------
WriteNetworkInfoToAnswerFile(g_pwifAnswerFile);
BOOL fStatus = g_pwifAnswerFile->Close();
delete g_pwifAnswerFile;
g_pwifAnswerFile = NULL;
if (!fStatus)
{
AbortUpgradeId(GetLastError(), IDS_E_WritingAnswerFile);
}
else if( DhcpUpgGetLastError() != NO_ERROR )
{
TraceTag(ttidNetUpgrade, "DhcpUpgGetLastError: %d", DhcpUpgGetLastError() );
AbortUpgradeId( DhcpUpgGetLastError(), IDS_E_DhcpServerUpgradeError);
}
}
else
{
TraceTag(ttidNetUpgrade, "%s: network parameters not written to answerfile: g_pfUpgrade is %d, g_pfCancelled is %d",
__FUNCNAME__, *g_PlugInInfo.UpgradeFlag,
*g_PlugInInfo.CancelledFlag);
}
}
NC_CATCH_BAD_ALLOC
{
TraceTag(ttidNetUpgrade, "%s: exception!!", __FUNCNAME__);
g_dwUpgradeError = ERROR_NOT_ENOUGH_MEMORY;
AbortUpgradeFn(g_dwUpgradeError, c_szExceptionInNetupgrd);
}
TraceTag(ttidNetUpgrade, "%s: returning status code: %ld, CancelledFlag: %ld",
__FUNCNAME__, g_dwUpgradeError, (DWORD) (*g_PlugInInfo.CancelledFlag));
return g_dwUpgradeError;
}
//+---------------------------------------------------------------------------
//
// Function: Winnt32Cleanup
//
// Purpose: Cleanup
//
// Arguments: None
//
// Returns: ERROR_SUCCESS on success, else win32 error code
//
// Author: kumarp 19-December-97
//
// Notes: see winnt32p.h for more information
//
DWORD
CALLBACK
Winnt32Cleanup(
VOID)
{
DefineFunctionName("Winnt32Cleanup");
TraceFunctionEntry(ttidNetUpgrade);
NC_TRY
{
// netmap-info and conflicts-list is initialized in
// HrInitNetUpgrade and destroyed here
//
UnInitNetMapInfo();
UninitConflictList();
if (*g_PlugInInfo.CancelledFlag)
{
CleanupNetupgrdTempFiles();
DhcpUpgCleanupDhcpTempFiles();
}
}
NC_CATCH_BAD_ALLOC
{
TraceTag(ttidNetUpgrade, "%s: exception!!", __FUNCNAME__);
g_dwUpgradeError = ERROR_NOT_ENOUGH_MEMORY;
}
TraceTag(ttidNetUpgrade, "%s: returning status code: %ld",
__FUNCNAME__, g_dwUpgradeError);
return g_dwUpgradeError;
}
//+---------------------------------------------------------------------------
//
// Function: GetSections
//
// Purpose: Enumerate over the keys in the specified section and
// return value of each key in a list.
//
// Arguments:
// pwif [in] answerfile
// pszSection [in] section to use
// pslSections [out] list of values of keys in that section
//
// Returns: None
//
// Author: kumarp 25-November-98
//
// Notes:
// For example:
// if pszSection == NetServices and the answerfile has the following section
//
// [NetServices]
// MS_Server = params.MS_Server
// MS_Foo = params.MS_Foo
// bar = p.bar
//
// then this function returns the following list:
// NetServices,params.MS_Server,params.MS_Foo,p.bar
//
void
GetSections(
IN CWInfFile* pwif,
IN PCWSTR pszSection,
OUT TStringList* pslSections)
{
AssertValidReadPtr(pwif);
AssertValidReadPtr(pszSection);
AssertValidWritePtr(pslSections);
PCWSTR pszParamsSection;
CWInfKey* pwik;
CWInfSection* pwis;
if (pwis = pwif->FindSection(pszSection))
{
pslSections->push_back(new tstring(pszSection));
pwik = pwis->FirstKey();
do
{
if (pszParamsSection = pwik->GetStringValue(NULL))
{
pslSections->push_back(new tstring(pszParamsSection));
}
}
while (pwik = pwis->NextKey());
}
}
//+---------------------------------------------------------------------------
//
// Function: GetNetworkingSections
//
// Purpose: Locate all networking related sections in the specified file
// and return their names in a list
//
// Arguments:
// pwif [in] answerfile
// pslSections [out] list of networking sections
//
// Returns: None
//
// Author: kumarp 25-November-98
//
// Notes:
//
void
GetNetworkingSections(
IN CWInfFile* pwif,
OUT TStringList* pslSections)
{
if (pwif->FindSection(c_szAfSectionNetworking))
{
pslSections->push_back(new tstring(c_szAfSectionNetworking));
}
if (pwif->FindSection(c_szAfSectionNetBindings))
{
pslSections->push_back(new tstring(c_szAfSectionNetBindings));
}
GetSections(pwif, c_szAfSectionNetAdapters, pslSections);
GetSections(pwif, c_szAfSectionNetServices, pslSections);
GetSections(pwif, c_szAfSectionNetClients, pslSections);
TStringList slProtocolSections;
TStringListIter pos;
tstring strSection;
CWInfSection* pwis;
TStringList slAdapterSections;
GetSections(pwif, c_szAfSectionNetProtocols, &slProtocolSections);
for (pos = slProtocolSections.begin();
pos != slProtocolSections.end(); )
{
strSection = **pos++;
if (pwis = pwif->FindSection(strSection.c_str()))
{
pslSections->push_back(new tstring(strSection));
pwis->GetStringListValue(c_szAfAdapterSections,
slAdapterSections);
pslSections->splice(pslSections->end(),
slAdapterSections,
slAdapterSections.begin(),
slAdapterSections.end());
}
}
}
//+---------------------------------------------------------------------------
//
// Function: CleanupNetupgrdTempFiles
//
// Purpose: Delete any temp files/dirs created
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 19-December-97
//
// Notes:
//
VOID
CleanupNetupgrdTempFiles(
VOID)
{
HRESULT hr=S_OK;
tstring strNetupgrdTempDir;
hr = HrGetNetUpgradeTempDir(&strNetupgrdTempDir);
if (S_OK == hr)
{
hr = HrDeleteDirectory(strNetupgrdTempDir.c_str(), TRUE);
}
}
//+---------------------------------------------------------------------------
//
// Function: AbortUpgradeFn
//
// Purpose: Helper function for aborting upgrade
//
// Arguments:
// dwErrorCode [in] win32 error code
// pszMessage [in] message to be traced
//
// Returns: None
//
// Author: kumarp 19-December-97
//
// Notes:
//
VOID
AbortUpgradeFn(
IN DWORD dwErrorCode,
IN PCWSTR pszMessage)
{
DefineFunctionName("AbortUpgradeFn");
g_dwUpgradeError = dwErrorCode;
if (g_PlugInInfo.CancelledFlag)
{
*g_PlugInInfo.CancelledFlag = TRUE;
}
else
{
TraceTag(ttidNetUpgrade, "%s: g_PlugInInfo.CancelledFlag is NULL!!",
__FUNCNAME__);
}
TraceTag(ttidError, "AbortUpgrade: %d: %S", dwErrorCode, pszMessage);
}
//+---------------------------------------------------------------------------
//
// Function: AbortUpgradeSz
//
// Purpose: Helper function for aborting upgrade
//
// Arguments:
// dwErrorCode [in] win32 error code
// pszMessage [in] message to be displayed and traced
//
// Returns: None
//
// Author: kumarp 19-December-97
//
// Notes:
//
VOID
AbortUpgradeSz(
IN DWORD dwErrorCode,
IN PCWSTR pszMessage)
{
AssertValidReadPtr(pszMessage);
tstring strMessage;
strMessage = pszMessage;
strMessage += L"\n\n";
strMessage += SzLoadString(g_hinst, IDS_E_SetupCannotContinue);
AbortUpgradeFn(dwErrorCode, pszMessage);
MessageBox (NULL, strMessage.c_str(),
SzLoadString(g_hinst, IDS_NetupgrdCaption),
MB_OK | MB_TASKMODAL);
}
//+---------------------------------------------------------------------------
//
// Function: AbortUpgradeId
//
// Purpose: Helper function for aborting upgrade
//
// Arguments:
// dwErrorCode [in] win32 error code
// dwResourceId [in] resource ID of message to be displayed
//
// Returns: None
//
// Author: kumarp 19-December-97
//
// Notes:
//
VOID
AbortUpgradeId (
IN DWORD dwErrorCode,
IN DWORD dwResourceId)
{
Assert(g_hinst);
PCWSTR pszMessage;
pszMessage = SzLoadString(g_hinst, dwResourceId);
AbortUpgradeSz(dwErrorCode, pszMessage);
}
//+---------------------------------------------------------------------------
//
// Function: FIsUpgradeAborted
//
// Purpose: Determine if the upgrade has been aborted
//
// Arguments: None
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 19-December-97
//
// Notes:
//
BOOL
FIsUpgradeAborted(
VOID)
{
return g_PlugInInfo.CancelledFlag && *g_PlugInInfo.CancelledFlag;
}
//+---------------------------------------------------------------------------
//
// Function: FGetConfirmationForAbortingUpgrade
//
// Purpose: Ask user confirmation for aborting upgrade
//
// Arguments:
// pszMessage [in] message prompt
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 19-December-97
//
// Notes:
//
BOOL
FGetConfirmationForAbortingUpgrade(
IN PCWSTR pszMessage)
{
tstring strMessage;
if (pszMessage)
{
strMessage = pszMessage;
strMessage += L"\n\n";
}
PCWSTR pszDoYouWantToAbortUpgrade =
SzLoadString(g_hinst, IDS_DoYouWantToAbortUpgrade);
strMessage += pszDoYouWantToAbortUpgrade;
DWORD dwRet = MessageBox (NULL, strMessage.c_str(),
SzLoadString(g_hinst, IDS_NetupgrdCaption),
MB_YESNO | MB_TASKMODAL);
return dwRet == IDYES;
}
//+---------------------------------------------------------------------------
//
// Function: FGetConfirmationAndAbortUpgrade
//
// Purpose: Abort upgrade if user confirms
//
// Arguments:
// pszMessage [in] message prompt
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 19-December-97
//
// Notes:
//
BOOL
FGetConfirmationAndAbortUpgrade(
IN PCWSTR pszMessage)
{
BOOL fUpgradeAborted=FALSE;
if (FGetConfirmationForAbortingUpgrade(pszMessage))
{
AbortUpgradeFn(ERROR_SUCCESS, pszMessage);
fUpgradeAborted = TRUE;
}
return fUpgradeAborted;
}
//+---------------------------------------------------------------------------
//
// Function: FGetConfirmationAndAbortUpgradeId
//
// Purpose: Abort upgrade if user confirms
//
// Arguments:
// dwErrorMessageId [in] message prompt
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 19-December-97
//
// Notes:
//
BOOL
FGetConfirmationAndAbortUpgradeId(
IN DWORD dwErrorMessageId)
{
return FGetConfirmationAndAbortUpgrade(SzLoadString(g_hinst,
dwErrorMessageId));
}