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.
632 lines
18 KiB
632 lines
18 KiB
//-----------------------------------------------------------------------------------------
|
|
// Go to "OCM" alias for assistance on this "technology"
|
|
//
|
|
//
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
|
#endif
|
|
|
|
#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
|
|
#define _WIN32_WINNT 0x0510 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
|
|
#endif
|
|
|
|
#include <windows.h>
|
|
#include <windef.h>
|
|
#include <tchar.h>
|
|
#include <setupapi.h>
|
|
#include <shellapi.h>
|
|
#include "ocmanage.h"
|
|
|
|
#include "uddiocm.h"
|
|
#include "uddiinst.h"
|
|
#include "ocmcallback.h"
|
|
#include "appcompat.h"
|
|
#include "..\shared\common.h"
|
|
#include "resource.h"
|
|
|
|
TCHAR *ocmmsg[100] =
|
|
{
|
|
TEXT( "OC_PREINITIALIZE" ),
|
|
TEXT( "OC_INIT_COMPONENT" ),
|
|
TEXT( "OC_SET_LANGUAGE" ),
|
|
TEXT( "OC_QUERY_IMAGE" ),
|
|
TEXT( "OC_REQUEST_PAGES" ),
|
|
TEXT( "OC_QUERY_CHANGE_SEL_STATE" ),
|
|
TEXT( "OC_CALC_DISK_SPACE" ),
|
|
TEXT( "OC_QUEUE_FILE_OPS" ),
|
|
TEXT( "OC_NOTIFICATION_FROM_QUEUE" ),
|
|
TEXT( "OC_QUERY_STEP_COUNT" ),
|
|
TEXT( "OC_COMPLETE_INSTALLATION" ),
|
|
TEXT( "OC_CLEANUP" ),
|
|
TEXT( "OC_QUERY_STATE" ),
|
|
TEXT( "OC_NEED_MEDIA" ),
|
|
TEXT( "OC_ABOUT_TO_COMMIT_QUEUE" ),
|
|
TEXT( "OC_QUERY_SKIP_PAGE" ),
|
|
TEXT( "OC_WIZARD_CREATED" ),
|
|
TEXT( "OC_FILE_BUSY" ),
|
|
TEXT( "OC_EXTRA_ROUTINES" ),
|
|
TEXT( "OC_QUERY_IMAGE_EX" )
|
|
};
|
|
|
|
TCHAR *ocmpage[100] =
|
|
{
|
|
TEXT("WizPagesWelcome"),
|
|
TEXT("WizPagesMode"),
|
|
TEXT("WizPagesEarly"),
|
|
TEXT("WizPagesPrenet"),
|
|
TEXT("WizPagesPostnet"),
|
|
TEXT("WizPagesLate"),
|
|
TEXT("WizPagesFinal")
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
LPCTSTR szComponentName;
|
|
LPCTSTR szSubcomponentName;
|
|
UINT_PTR Param1;
|
|
PVOID Param2;
|
|
} OCM_CALLBACK_ARGS, *POCM_CALLBACK_ARGS;
|
|
|
|
static DWORD UddiOcmPreinitialize ( OCM_CALLBACK_ARGS& args );
|
|
static DWORD UddiOcmInitComponent ( OCM_CALLBACK_ARGS& args );
|
|
static DWORD UddiOcmChangeSelectionState( OCM_CALLBACK_ARGS& args );
|
|
static DWORD UddiOcmInstallUninstall ( OCM_CALLBACK_ARGS& args );
|
|
static DWORD UddiOcmRequestPages ( OCM_CALLBACK_ARGS& args );
|
|
static DWORD UddiOcmQueryState ( OCM_CALLBACK_ARGS& args );
|
|
static DWORD UddiOcmCalcDiskSpace ( OCM_CALLBACK_ARGS& args );
|
|
static DWORD UddiOcmQueueUDDIFiles ( OCM_CALLBACK_ARGS& args );
|
|
static DWORD UddiOcmQueryStepCount ( OCM_CALLBACK_ARGS& args );
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
HINSTANCE g_hInstance = NULL;
|
|
CUDDIInstall g_uddiComponents;
|
|
|
|
static TCHAR g_szSetupPath[ MAX_PATH ];
|
|
static TCHAR g_szUnattendPath[ MAX_PATH ];
|
|
static HINF g_hComponent;
|
|
static bool g_bUnattendMode = false;
|
|
static bool g_bPerformedCompInstall = false;
|
|
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
BOOL APIENTRY DllMain( HINSTANCE hInstance,
|
|
DWORD ul_reason_for_call,
|
|
LPVOID lpReserved
|
|
)
|
|
{
|
|
switch (ul_reason_for_call)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
g_hInstance = hInstance;
|
|
g_uddiComponents.SetInstance( hInstance );
|
|
ClearLog();
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
case DLL_PROCESS_DETACH:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
DWORD __stdcall OcEntry(
|
|
IN LPCTSTR szComponentName,
|
|
IN LPCTSTR szSubcomponentName,
|
|
IN UINT uMsgID,
|
|
IN UINT_PTR Param1,
|
|
IN OUT PVOID Param2
|
|
)
|
|
{
|
|
if( g_bUnattendMode )
|
|
return NO_ERROR;
|
|
|
|
DWORD dwOcEntryReturn = 0;
|
|
|
|
OCM_CALLBACK_ARGS args;
|
|
args.Param1 = Param1;
|
|
args.Param2 = Param2;
|
|
args.szComponentName = szComponentName;
|
|
args.szSubcomponentName = szSubcomponentName;
|
|
|
|
MyOutputDebug( TEXT("--- Component: %15s Subcomponent: %15s Function: %s"),
|
|
szComponentName,
|
|
NULL == szSubcomponentName ? TEXT( "(NULL) ") : szSubcomponentName,
|
|
ocmmsg[uMsgID]);
|
|
|
|
switch(uMsgID)
|
|
{
|
|
case OC_PREINITIALIZE:
|
|
dwOcEntryReturn = UddiOcmPreinitialize( args );
|
|
break;
|
|
|
|
case OC_INIT_COMPONENT:
|
|
dwOcEntryReturn = UddiOcmInitComponent( args );
|
|
break;
|
|
|
|
case OC_CALC_DISK_SPACE:
|
|
dwOcEntryReturn = UddiOcmCalcDiskSpace( args );
|
|
break;
|
|
|
|
case OC_QUERY_STEP_COUNT:
|
|
dwOcEntryReturn = UddiOcmQueryStepCount( args );
|
|
break;
|
|
|
|
case OC_QUEUE_FILE_OPS:
|
|
dwOcEntryReturn = UddiOcmQueueUDDIFiles( args );
|
|
break;
|
|
|
|
case OC_ABOUT_TO_COMMIT_QUEUE:
|
|
break;
|
|
|
|
case OC_COMPLETE_INSTALLATION:
|
|
dwOcEntryReturn = UddiOcmInstallUninstall( args );
|
|
break;
|
|
|
|
case OC_WIZARD_CREATED:
|
|
break;
|
|
|
|
case OC_QUERY_STATE:
|
|
dwOcEntryReturn = UddiOcmQueryState( args );
|
|
break;
|
|
|
|
case OC_REQUEST_PAGES:
|
|
dwOcEntryReturn = UddiOcmRequestPages( args );
|
|
break;
|
|
|
|
case OC_QUERY_SKIP_PAGE:
|
|
break;
|
|
|
|
case OC_QUERY_CHANGE_SEL_STATE:
|
|
dwOcEntryReturn = UddiOcmChangeSelectionState( args );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return dwOcEntryReturn;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
static DWORD UddiOcmPreinitialize( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
DWORD dwOcEntryReturn = 0;
|
|
|
|
#ifdef UNICODE
|
|
dwOcEntryReturn = OCFLAG_UNICODE;
|
|
#else
|
|
dwOcEntryReturn = OCFLAG_ANSI;
|
|
#endif
|
|
|
|
return dwOcEntryReturn;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
static DWORD UddiOcmInitComponent( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
PSETUP_INIT_COMPONENT pSetupInitComp = (PSETUP_INIT_COMPONENT) args.Param2;
|
|
SETUP_DATA setupData = pSetupInitComp->SetupData;
|
|
|
|
//
|
|
// see if we are in unattended mode
|
|
//
|
|
if( SETUPOP_BATCH & setupData.OperationFlags )
|
|
{
|
|
_tcscpy( g_szUnattendPath, pSetupInitComp->SetupData.UnattendFile );
|
|
g_bUnattendMode = true;
|
|
Log( _T("*** UDDI does not install in unattended mode ***") );
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// grab the handle to the uddi.inf file
|
|
//
|
|
g_hComponent = pSetupInitComp->ComponentInfHandle;
|
|
|
|
//
|
|
// save a copy of the source path (to the CDROM drive)
|
|
//
|
|
// MessageBox(NULL, TEXT( "attach debugger" ), TEXT( "debug uddi" ), MB_OK);
|
|
_tcscpy( g_szSetupPath, pSetupInitComp->SetupData.SourcePath );
|
|
|
|
//
|
|
// save a copy of the callback pointers into the OCM
|
|
//
|
|
COCMCallback::SetOCMRoutines( &pSetupInitComp->HelperRoutines );
|
|
|
|
//
|
|
// if the db is already installed, the db instance name is stored in the registry.
|
|
// get it and set it for use by the web installer (if the user chooses to install the web component).
|
|
//
|
|
if( g_uddiComponents.IsInstalled( UDDI_DB ) )
|
|
{
|
|
CDBInstance dbinstances;
|
|
TCHAR szInstanceName[ 20 ];
|
|
ULONG uLen = 20;
|
|
bool bIsClustered = false;
|
|
|
|
if( dbinstances.GetUDDIDBInstanceName( NULL, szInstanceName, &uLen, &bIsClustered ) )
|
|
g_uddiComponents.SetDBInstanceName( NULL, szInstanceName, UDDI_NOT_INSTALLING_MSDE, bIsClustered );
|
|
}
|
|
|
|
//
|
|
// Finally, check the OS flavor (Enterprise, Datacenter etc.)
|
|
//
|
|
g_uddiComponents.DetectOSFlavor();
|
|
Log( _T( "OS Flavor Mask as reported by WMI: %#x" ), g_uddiComponents.GetOSSuiteMask() );
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
//
|
|
// this function is called for each component and subcomponent
|
|
//
|
|
static DWORD UddiOcmQueryState( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
if( args.szSubcomponentName && args.Param1 == OCSELSTATETYPE_ORIGINAL )
|
|
{
|
|
if ( g_uddiComponents.IsInstalled( (PTCHAR) args.szSubcomponentName ) )
|
|
{
|
|
MyOutputDebug( TEXT( "Reporting that component %s is ON"), args.szSubcomponentName );
|
|
return SubcompOn;
|
|
}
|
|
else
|
|
{
|
|
MyOutputDebug( TEXT( "Reporting that component %s is OFF"), args.szSubcomponentName );
|
|
return SubcompOff;
|
|
}
|
|
}
|
|
|
|
return SubcompUseOcManagerDefault;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
//
|
|
// This function is called for each component and subcomponent
|
|
// We need to verify that IIS, if installed is not setup for IIS 5 compatability mode.
|
|
// If so we will display a message to the user and uncheck the web component portion of the
|
|
// install.
|
|
//
|
|
static DWORD UddiOcmChangeSelectionState( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
bool bSelected = false;
|
|
COCMCallback::QuerySelectionState( args.szSubcomponentName, bSelected );
|
|
MyOutputDebug( TEXT( "requested selection state=%08x, flags=%08x, selected=%d" ), args.Param1 , args.Param2, bSelected );
|
|
|
|
//
|
|
// ignore if the component name is null
|
|
//
|
|
if( NULL == args.szSubcomponentName )
|
|
return 0;
|
|
|
|
//
|
|
// ignore if this is the parent component
|
|
//
|
|
if( 0 == _tcscmp( args.szSubcomponentName, TEXT( "uddiservices" ) ) )
|
|
return 1;
|
|
|
|
//
|
|
// if the user has selected the web component to install AND
|
|
// IIS is set to "IIS 5.0 Application Compatibility Mode" then
|
|
// raise an error and don't allow it
|
|
//
|
|
if( 1 == args.Param1 &&
|
|
( 0 == _tcscmp( args.szSubcomponentName, TEXT( "uddiweb" ) ) ||
|
|
( 0 == _tcscmp( args.szSubcomponentName, TEXT( "uddicombo" ) ) ) ) )
|
|
{
|
|
static bool bSkipOnce = false;
|
|
|
|
//
|
|
// if the web component was selected from the parent, then suppress one
|
|
// of the two error messages (it gets called twice for some reason)
|
|
//
|
|
if( OCQ_DEPENDENT_SELECTION & ( DWORD_PTR ) args.Param2 )
|
|
{
|
|
bSkipOnce = !bSkipOnce;
|
|
if( bSkipOnce )
|
|
return 0;
|
|
}
|
|
|
|
bool bIsIIS5CompatMode;
|
|
TCHAR szMsg[ 500 ];
|
|
TCHAR szTitle[ 50 ];
|
|
|
|
LoadString( g_hInstance, IDS_TITLE, szTitle, sizeof( szTitle ) / sizeof( TCHAR ) );
|
|
|
|
HRESULT hr = IsIIS5CompatMode( &bIsIIS5CompatMode );
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
if( bIsIIS5CompatMode )
|
|
{
|
|
//
|
|
// cannot install web component when IIS is in 5.0 compat mode
|
|
// raise error and do not accept the change
|
|
//
|
|
LoadString( g_hInstance, IDS_IIS_ISOLATION_MODE_ERROR, szMsg, sizeof( szMsg ) / sizeof( TCHAR ) );
|
|
MessageBox( NULL, szMsg, szTitle, MB_OK | MB_ICONWARNING );
|
|
Log( szMsg );
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// error occurred getting the app compat mode setting.
|
|
// tell the user why and tell OCM that we do not accept the change
|
|
//
|
|
// REGDB_E_CLASSNOTREG, CLASS_E_NOAGGREGATION, or E_NOINTERFACE
|
|
//
|
|
if( REGDB_E_CLASSNOTREG == hr )
|
|
{
|
|
Log( TEXT( "IIS is not installed on this machine" ) );
|
|
// This is ok 'cause IIS gets installed if the UDDI web component is selected.
|
|
}
|
|
else if( ERROR_PATH_NOT_FOUND == HRESULT_CODE( hr ) )
|
|
{
|
|
Log( TEXT( "WWW Services not installed on this machine." ) );
|
|
// This is ok 'cause WWW Services installed if the UDDI web component is selected.
|
|
}
|
|
else if( ERROR_SERVICE_DISABLED == HRESULT_CODE( hr ) )
|
|
{
|
|
LoadString( g_hInstance, IDS_IIS_SERVICE_DISABLED, szMsg, sizeof( szMsg ) / sizeof( TCHAR ) );
|
|
MessageBox( NULL, szMsg, szTitle, MB_OK | MB_ICONWARNING );
|
|
Log( szMsg );
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
LoadString( g_hInstance, IDS_IIS_UNKNOWN_ERROR, szMsg, sizeof( szMsg ) / sizeof( TCHAR ) );
|
|
MessageBox( NULL, szMsg, szTitle, MB_OK | MB_ICONWARNING );
|
|
Log( szMsg );
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1; // indicates that this state change was ACCEPTED
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
static DWORD UddiOcmRequestPages( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
DWORD dwOcEntryReturn = NO_ERROR;
|
|
|
|
dwOcEntryReturn = AddUDDIWizardPages(
|
|
args.szComponentName,
|
|
(WizardPagesType) args.Param1,
|
|
(PSETUP_REQUEST_PAGES) args.Param2 );
|
|
|
|
return dwOcEntryReturn; // return the number of pages that was added
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
static DWORD UddiOcmInstallUninstall( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
|
|
//
|
|
// for the root component OR if someone is trying
|
|
// to install us unattended, simply return
|
|
//
|
|
if( NULL == args.szSubcomponentName )
|
|
return ERROR_SUCCESS;
|
|
|
|
//
|
|
// uddiweb "needs" iis, as commanded in uddi.inf, and the only thing we know
|
|
// for sure about OCM install order is that OCM will install IIS before it
|
|
// installs uddiweb, so let's delay installing all the UDDI components until
|
|
// the OCM calls for the installation of uddiweb, 'cause that way we can be sure
|
|
// that IIS is already installed. No, that's not a hack.
|
|
//
|
|
|
|
//
|
|
// All installation/uninstallation is deferred until this component is referenced
|
|
// This ensures that the IIS dependency is in place prior to installation of any of our
|
|
// components.
|
|
//
|
|
// TODO: Review whether this is necessary anymore. We now declare proper dependencies on netfx (.NET Framework)
|
|
// that should make this synchronization unecessary.
|
|
//
|
|
if( !g_bPerformedCompInstall )
|
|
{
|
|
g_bPerformedCompInstall = true;
|
|
Log( _T("Installing...") );
|
|
|
|
//
|
|
// Even though this method name is Install it handles both install and
|
|
// uninstall.
|
|
//
|
|
dwRet = g_uddiComponents.Install();
|
|
|
|
//
|
|
// if we need a reboot, tell the OCM
|
|
//
|
|
if( ERROR_SUCCESS_REBOOT_REQUIRED == dwRet )
|
|
{
|
|
COCMCallback::SetReboot();
|
|
|
|
//
|
|
// mute the error, as it's actualy a "success with info" code
|
|
//
|
|
dwRet = ERROR_SUCCESS;
|
|
}
|
|
else if( ERROR_SUCCESS != dwRet )
|
|
{
|
|
TCHAR szWindowsDirectory[ MAX_PATH + 1 ];
|
|
if( 0 == GetWindowsDirectory( szWindowsDirectory, MAX_PATH + 1 ) )
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
tstring cLogFile = szWindowsDirectory;
|
|
cLogFile.append( TEXT( "\\" ) );
|
|
cLogFile.append( UDDI_SETUP_LOG );
|
|
|
|
TCHAR szMsg[ 500 ];
|
|
TCHAR szTitle[ 50 ];
|
|
if( !LoadString( g_hInstance, IDS_INSTALL_ERROR, szMsg, sizeof( szMsg ) / sizeof( TCHAR ) ) )
|
|
return GetLastError();
|
|
|
|
if( !LoadString( g_hInstance, IDS_TITLE, szTitle, sizeof( szTitle ) / sizeof( TCHAR ) ) )
|
|
return GetLastError();
|
|
|
|
tstring cMsg = szMsg;
|
|
cMsg.append( cLogFile );
|
|
|
|
MessageBox( NULL, cMsg.c_str(), szTitle, MB_OK | MB_ICONWARNING | MB_TOPMOST );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// if we installed the Web components only, show the post-install notes
|
|
//
|
|
if( g_uddiComponents.IsInstalling( UDDI_WEB ) || g_uddiComponents.IsInstalling( UDDI_DB ) )
|
|
{
|
|
HINSTANCE hInstance = ShellExecute(
|
|
GetActiveWindow(),
|
|
TEXT( "open" ),
|
|
TEXT( "postinstall.htm" ),
|
|
NULL,
|
|
TEXT( "\\inetpub\\uddi" ),
|
|
SW_SHOWNORMAL);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// on the Standard Server, we want to fail the whole installation if one component fails
|
|
//
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
static DWORD UddiOcmQueryStepCount( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
//
|
|
// if this is the main component, tell it we
|
|
// need four steps on the gauge
|
|
//
|
|
if( NULL == args.szSubcomponentName )
|
|
return 4;
|
|
|
|
return 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
static DWORD UddiOcmQueueUDDIFiles( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
if( !args.szSubcomponentName )
|
|
return 0;
|
|
|
|
HSPFILEQ hFileQueue = ( HSPFILEQ ) args.Param2;
|
|
BOOL bOK = TRUE;
|
|
DWORD dwErrCode = 0;
|
|
|
|
if( g_uddiComponents.IsInstalling( args.szSubcomponentName ) )
|
|
{
|
|
TCHAR szSectionName[ 100 ];
|
|
_stprintf( szSectionName, TEXT( "Install.%s" ), args.szSubcomponentName );
|
|
|
|
bOK = SetupInstallFilesFromInfSection(
|
|
g_hComponent, // handle to the UDDI INF file
|
|
NULL, // optional, layout INF handle
|
|
hFileQueue, // handle to the file queue
|
|
szSectionName, // name of the Install section
|
|
NULL, // optional, root path to source files
|
|
SP_COPY_NEWER | SP_COPY_NOSKIP // optional, specifies copy behavior
|
|
);
|
|
}
|
|
|
|
UDDI_PACKAGE_ID pkgSubcompID = g_uddiComponents.GetPackageID( args.szSubcomponentName );
|
|
if( pkgSubcompID == UDDI_DB || pkgSubcompID == UDDI_COMBO )
|
|
{
|
|
if( g_uddiComponents.IsInstalling( UDDI_MSDE ) )
|
|
{
|
|
//
|
|
// copy over the msde msi file, it is stored as a different
|
|
// name, and this will rename as it copies (and decomp if needed)
|
|
//
|
|
if( bOK )
|
|
{
|
|
//
|
|
// this will copy over the cab file but NOT decomp the file.
|
|
// the cab file MUST be named sqlrun.cab on the cd, because
|
|
// the SP_COPY_NODECOMP flag foils the renaming scheme built
|
|
// into the setup api's
|
|
//
|
|
bOK = SetupInstallFilesFromInfSection(
|
|
g_hComponent, // handle to the INF file
|
|
NULL, // optional, layout INF handle
|
|
hFileQueue, // handle to the file queue
|
|
TEXT( "Install.MSDE" ), // name of the Install section
|
|
NULL, // optional, root path to source files
|
|
SP_COPY_NEWER | SP_COPY_NODECOMP | SP_COPY_NOSKIP // optional, specifies copy behavior
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !bOK )
|
|
{
|
|
dwErrCode = GetLastError();
|
|
LogError( TEXT( "Error copying the UDDI files from the Windows CD:" ), dwErrCode );
|
|
}
|
|
|
|
return dwErrCode;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------
|
|
|
|
static DWORD UddiOcmCalcDiskSpace( OCM_CALLBACK_ARGS& args )
|
|
{
|
|
BOOL bOK;
|
|
HDSKSPC hDiskSpace = ( HDSKSPC ) args.Param2;
|
|
|
|
tstring cSection = TEXT( "Install." );
|
|
cSection += args.szSubcomponentName;
|
|
|
|
if( args.Param1 )
|
|
{
|
|
//
|
|
// add component
|
|
//
|
|
bOK = SetupAddInstallSectionToDiskSpaceList(
|
|
hDiskSpace,
|
|
g_hComponent,
|
|
NULL,
|
|
cSection.c_str(),
|
|
0, 0);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// remove component
|
|
//
|
|
bOK = SetupRemoveInstallSectionFromDiskSpaceList(
|
|
hDiskSpace,
|
|
g_hComponent,
|
|
NULL,
|
|
cSection.c_str(),
|
|
0, 0);
|
|
}
|
|
|
|
if( !bOK )
|
|
{
|
|
LogError( TEXT( "Error adding disk space requirements" ), GetLastError() ) ;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|