mirror of https://github.com/tongzx/nt5src
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.
372 lines
9.4 KiB
372 lines
9.4 KiB
//Copyright (c) 1998 - 1999 Microsoft Corporation
|
|
|
|
// subcomp.cpp
|
|
// implementation a default sub component
|
|
|
|
#include "stdafx.h"
|
|
#include "subcomp.h"
|
|
|
|
|
|
OCMSubComp::OCMSubComp ()
|
|
{
|
|
m_lTicks = 0;
|
|
}
|
|
|
|
BOOL OCMSubComp::Initialize ()
|
|
{
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL OCMSubComp::GetCurrentSubCompState () const
|
|
{
|
|
return GetHelperRoutines().QuerySelectionState(
|
|
GetHelperRoutines().OcManagerContext,
|
|
GetSubCompID(),
|
|
OCSELSTATETYPE_CURRENT);
|
|
}
|
|
|
|
BOOL OCMSubComp::GetOriginalSubCompState () const
|
|
{
|
|
return GetHelperRoutines().QuerySelectionState(
|
|
GetHelperRoutines().OcManagerContext,
|
|
GetSubCompID(),
|
|
OCSELSTATETYPE_ORIGINAL);
|
|
}
|
|
|
|
BOOL OCMSubComp::HasStateChanged () const
|
|
{
|
|
//
|
|
// returns true if current selection state is different from previous.
|
|
//
|
|
return GetCurrentSubCompState() != GetOriginalSubCompState();
|
|
|
|
}
|
|
|
|
//
|
|
// this functions ticks the gauge for the specified count
|
|
// keep traks of the count reported to the OC_QUERY_STEP_COUNT
|
|
//
|
|
void OCMSubComp::Tick (DWORD dwTickCount /* = 1 */)
|
|
{
|
|
if (m_lTicks > 0)
|
|
{
|
|
m_lTicks -= dwTickCount;
|
|
while(dwTickCount--)
|
|
GetHelperRoutines().TickGauge( GetHelperRoutines().OcManagerContext );
|
|
|
|
}
|
|
else
|
|
{
|
|
m_lTicks = 0;
|
|
}
|
|
}
|
|
|
|
//
|
|
// completes the remaining ticks.
|
|
//
|
|
void OCMSubComp::TickComplete ()
|
|
{
|
|
ASSERT(m_lTicks >= 0);
|
|
while (m_lTicks--)
|
|
GetHelperRoutines().TickGauge( GetHelperRoutines().OcManagerContext );
|
|
}
|
|
|
|
DWORD OCMSubComp::OnQueryStepCount()
|
|
{
|
|
m_lTicks = GetStepCount() + 2;
|
|
return m_lTicks;
|
|
}
|
|
|
|
DWORD OCMSubComp::GetStepCount () const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD OCMSubComp::OnQueryState ( UINT uiWhichState ) const
|
|
{
|
|
LOGMESSAGE1(_T("In OCMSubComp::OnQueryState for %s"), GetSubCompID());
|
|
|
|
ASSERT(OCSELSTATETYPE_ORIGINAL == uiWhichState ||
|
|
OCSELSTATETYPE_CURRENT == uiWhichState ||
|
|
OCSELSTATETYPE_FINAL == uiWhichState );
|
|
|
|
return SubcompUseOcManagerDefault;
|
|
|
|
}
|
|
|
|
DWORD OCMSubComp::OnQuerySelStateChange (BOOL /* bNewState */, BOOL /* bDirectSelection */) const
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD OCMSubComp::LookupTargetSection(LPTSTR szTargetSection, DWORD dwSize, LPCTSTR lookupSection)
|
|
{
|
|
DWORD dwError = GetStringValue(GetComponentInfHandle(), GetSubCompID(), lookupSection, szTargetSection, dwSize);
|
|
if (dwError == ERROR_SUCCESS)
|
|
{
|
|
LOGMESSAGE2(_T("sectionname = <%s>, actual section = <%s>"), lookupSection, szTargetSection);
|
|
}
|
|
else
|
|
{
|
|
AssertFalse();
|
|
LOGMESSAGE1(_T("ERROR:GetSectionToBeProcess:GetStringValue failed GetLastError() = %lu"), dwError);
|
|
}
|
|
|
|
return dwError;
|
|
}
|
|
|
|
DWORD OCMSubComp::GetTargetSection(LPTSTR szTargetSection, DWORD dwSize, ESections eSectionType, BOOL *pbNoSection)
|
|
{
|
|
ASSERT(szTargetSection);
|
|
ASSERT(pbNoSection);
|
|
|
|
//
|
|
// get section to be processed
|
|
//
|
|
LPCTSTR szSection = GetSectionToBeProcessed( eSectionType );
|
|
|
|
if (szSection == NULL)
|
|
{
|
|
*pbNoSection = TRUE;
|
|
return NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// there is a section to be processed.
|
|
//
|
|
*pbNoSection = FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// look for the target section
|
|
//
|
|
return LookupTargetSection(szTargetSection, dwSize, szSection);
|
|
|
|
}
|
|
|
|
DWORD OCMSubComp::OnCalcDiskSpace ( DWORD addComponent, HDSKSPC dspace )
|
|
{
|
|
LOGMESSAGE1(_T("In OCMSubComp::OnCalcDiskSpace for %s"), GetSubCompID());
|
|
|
|
TCHAR TargetSection[S_SIZE];
|
|
BOOL bNoSection = FALSE;
|
|
|
|
DWORD rc = GetTargetSection(TargetSection, S_SIZE, kDiskSpaceAddSection, &bNoSection);
|
|
|
|
//
|
|
// if there is no section to be processed. just return success.
|
|
//
|
|
if (bNoSection)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
if (rc == NO_ERROR)
|
|
{
|
|
if (addComponent)
|
|
{
|
|
LOGMESSAGE1(_T("Calculating disk space for add section = %s"), TargetSection);
|
|
rc = SetupAddInstallSectionToDiskSpaceList(
|
|
dspace,
|
|
GetComponentInfHandle(),
|
|
NULL,
|
|
TargetSection,
|
|
0,
|
|
0);
|
|
}
|
|
else
|
|
{
|
|
LOGMESSAGE1(_T("Calculating disk space for remove section = %s"), TargetSection);
|
|
rc = SetupRemoveInstallSectionFromDiskSpaceList(
|
|
dspace,
|
|
GetComponentInfHandle(),
|
|
NULL,
|
|
TargetSection,
|
|
0,
|
|
0);
|
|
}
|
|
|
|
if (!rc)
|
|
rc = GetLastError();
|
|
else
|
|
rc = NO_ERROR;
|
|
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
DWORD OCMSubComp::OnQueueFiles ( HSPFILEQ queue )
|
|
{
|
|
LOGMESSAGE1(_T("In OCMSubComp::OnQueueFiles for %s"), GetSubCompID());
|
|
|
|
TCHAR TargetSection[S_SIZE];
|
|
BOOL bNoSection = FALSE;
|
|
DWORD rc = GetTargetSection(TargetSection, S_SIZE, kFileSection, &bNoSection);
|
|
|
|
//
|
|
// if there is no section to be processed. just return success.
|
|
//
|
|
if (bNoSection)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
if (rc == NO_ERROR)
|
|
{
|
|
LOGMESSAGE1(_T("Queuing Files from Section = %s"), TargetSection);
|
|
if (!SetupInstallFilesFromInfSection(
|
|
GetComponentInfHandle(),
|
|
NULL,
|
|
queue,
|
|
TargetSection,
|
|
NULL,
|
|
0 // this should eliminate the warning about overwriting newer file.
|
|
))
|
|
{
|
|
rc = GetLastError();
|
|
LOGMESSAGE2(_T("ERROR:OnQueueFileOps::SetupInstallFilesFromInfSection <%s> failed.GetLastError() = <%ul)"), TargetSection, rc);
|
|
}
|
|
else
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
DWORD OCMSubComp::OnCompleteInstall ()
|
|
{
|
|
LOGMESSAGE1(_T("In OCMSubComp::OnCompleteInstall for %s"), GetSubCompID());
|
|
if (!BeforeCompleteInstall ())
|
|
{
|
|
LOGMESSAGE0(_T("ERROR:BeforeCompleteInstall failed!"));
|
|
}
|
|
|
|
TCHAR TargetSection[S_SIZE];
|
|
BOOL bNoSection = FALSE;
|
|
DWORD dwError = GetTargetSection(TargetSection, S_SIZE, kRegistrySection, &bNoSection);
|
|
|
|
//
|
|
// if there is no section to be processed. just go ahead.
|
|
//
|
|
if (!bNoSection)
|
|
{
|
|
LOGMESSAGE1(_T("Setting up Registry/Links/RegSvrs from section = %s"), TargetSection);
|
|
dwError = SetupInstallFromInfSection(
|
|
NULL, // hwndOwner
|
|
GetComponentInfHandle(), // inf handle
|
|
TargetSection, //
|
|
SPINST_ALL & ~SPINST_FILES, // operation flags
|
|
NULL, // relative key root
|
|
NULL, // source root path
|
|
0, // copy flags
|
|
NULL, // callback routine
|
|
NULL, // callback routine context
|
|
NULL, // device info set
|
|
NULL // device info struct
|
|
);
|
|
|
|
if (dwError == 0)
|
|
LOGMESSAGE1(_T("ERROR:while installating section <%lu>"), GetLastError());
|
|
}
|
|
|
|
Tick();
|
|
|
|
if (!AfterCompleteInstall ())
|
|
{
|
|
LOGMESSAGE0(_T("ERROR:AfterCompleteInstall failed!"));
|
|
}
|
|
|
|
TickComplete();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
BOOL OCMSubComp::BeforeCompleteInstall ()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL OCMSubComp::AfterCompleteInstall ()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD OCMSubComp::OnAboutToCommitQueue ()
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
void
|
|
OCMSubComp::SetupRunOnce( HINF hInf, LPCTSTR SectionName )
|
|
{
|
|
INFCONTEXT sic;
|
|
TCHAR CommandLine[ RUNONCE_CMDBUFSIZE ];
|
|
BOOL b;
|
|
STARTUPINFO startupinfo;
|
|
PROCESS_INFORMATION process_information;
|
|
DWORD dwErr;
|
|
|
|
if (!SetupFindFirstLine( hInf, SectionName, NULL , &sic))
|
|
{
|
|
LOGMESSAGE1(_T("WARNING: nothing in %s to be processed."), SectionName);
|
|
}
|
|
else
|
|
{
|
|
do {
|
|
if (!SetupGetStringField(&sic, 1, CommandLine, RUNONCE_CMDBUFSIZE, NULL))
|
|
{
|
|
LOGMESSAGE1(_T("WARNING: No command to be processed."), SectionName);
|
|
break;
|
|
}
|
|
|
|
LOGMESSAGE1(_T("RunOnce: spawning process %s"), CommandLine);
|
|
|
|
|
|
ZeroMemory( &startupinfo, sizeof(startupinfo) );
|
|
startupinfo.cb = sizeof(startupinfo);
|
|
startupinfo.dwFlags = STARTF_USESHOWWINDOW;
|
|
startupinfo.wShowWindow = SW_HIDE | SW_SHOWMINNOACTIVE;
|
|
|
|
b = CreateProcess( NULL,
|
|
CommandLine,
|
|
NULL,
|
|
NULL,
|
|
FALSE,
|
|
CREATE_DEFAULT_ERROR_MODE,
|
|
NULL,
|
|
NULL,
|
|
&startupinfo,
|
|
&process_information );
|
|
if ( !b )
|
|
{
|
|
LOGMESSAGE1(_T("ERROR: failed to spawn %s process."), CommandLine);
|
|
continue;
|
|
}
|
|
|
|
dwErr = WaitForSingleObject( process_information.hProcess, RUNONCE_DEFAULTWAIT );
|
|
if ( dwErr != NO_ERROR )
|
|
{
|
|
LOGMESSAGE1(_T("ERROR: process %s failed to complete in time."), CommandLine);
|
|
|
|
// Don't terminate process, just go on to next one.
|
|
}
|
|
else
|
|
{
|
|
LOGMESSAGE1(_T("INFO: process %s completed successfully."), CommandLine);
|
|
}
|
|
|
|
CloseHandle( process_information.hProcess );
|
|
CloseHandle( process_information.hThread );
|
|
} while ( SetupFindNextLine( &sic, &sic ) );
|
|
}
|
|
|
|
return;
|
|
}
|