391 lines
7.4 KiB
C++
391 lines
7.4 KiB
C++
/*
|
|
* Copyright (c) 1996 Microsoft Corporation
|
|
*
|
|
* Module Name:
|
|
*
|
|
* oc.cpp
|
|
*
|
|
* Abstract:
|
|
*
|
|
* This file handles all messages passed by the OC Manager
|
|
*
|
|
* Author:
|
|
*
|
|
* Kazuhiko Matsubara (kazum) June-16-1999
|
|
*
|
|
* Environment:
|
|
*
|
|
* User Mode
|
|
*/
|
|
|
|
#define _OC_CPP_
|
|
#include <stdlib.h>
|
|
#include "oc.h"
|
|
#include "fsconins.h"
|
|
|
|
#pragma hdrstop
|
|
|
|
|
|
/*
|
|
* called by CRT when _DllMainCRTStartup is the DLL entry point
|
|
*/
|
|
|
|
BOOL
|
|
WINAPI
|
|
DllMain(
|
|
IN HINSTANCE hinstance,
|
|
IN DWORD reason,
|
|
IN LPVOID reserved
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(reserved);
|
|
|
|
if (reason == DLL_PROCESS_ATTACH) {
|
|
ghinst = hinstance;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DWORD_PTR
|
|
FsConInstallProc(
|
|
IN LPCTSTR ComponentId,
|
|
IN LPCTSTR SubcomponentId,
|
|
IN UINT Function,
|
|
IN UINT Param1,
|
|
IN OUT PVOID Param2
|
|
)
|
|
{
|
|
DWORD_PTR rc;
|
|
|
|
switch(Function)
|
|
{
|
|
case OC_PREINITIALIZE:
|
|
rc = OCFLAG_UNICODE;
|
|
break;
|
|
|
|
case OC_INIT_COMPONENT:
|
|
rc = OnInitComponent(ComponentId, (PSETUP_INIT_COMPONENT)Param2);
|
|
break;
|
|
|
|
case OC_EXTRA_ROUTINES:
|
|
rc = OnExtraRoutines(ComponentId, (PEXTRA_ROUTINES)Param2);
|
|
break;
|
|
|
|
case OC_QUERY_CHANGE_SEL_STATE:
|
|
rc = OnQuerySelStateChange(ComponentId, SubcomponentId, Param1, (UINT)((UINT_PTR)Param2));
|
|
break;
|
|
|
|
case OC_CALC_DISK_SPACE:
|
|
rc = OnCalcDiskSpace(ComponentId, SubcomponentId, Param1, Param2);
|
|
break;
|
|
|
|
case OC_QUERY_STEP_COUNT:
|
|
rc = 0;
|
|
break;
|
|
|
|
case OC_COMPLETE_INSTALLATION:
|
|
rc = OnCompleteInstallation(ComponentId, SubcomponentId);
|
|
break;
|
|
|
|
case OC_QUERY_STATE:
|
|
rc = OnQueryState(ComponentId, SubcomponentId, Param1);
|
|
break;
|
|
|
|
default:
|
|
rc = NO_ERROR;
|
|
break;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*-------------------------------------------------------*/
|
|
/*
|
|
* OC Manager message handlers
|
|
*
|
|
*-------------------------------------------------------*/
|
|
|
|
|
|
|
|
/*
|
|
* OnInitComponent()
|
|
*
|
|
* handler for OC_INIT_COMPONENT
|
|
*/
|
|
|
|
DWORD
|
|
OnInitComponent(
|
|
LPCTSTR ComponentId,
|
|
PSETUP_INIT_COMPONENT psc
|
|
)
|
|
{
|
|
PPER_COMPONENT_DATA cd;
|
|
TCHAR buf[256];
|
|
HINF hinf;
|
|
BOOL rc;
|
|
|
|
// add component to linked list
|
|
|
|
if (!(cd = AddNewComponent(ComponentId)))
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
// store component inf handle
|
|
|
|
cd->hinf = (psc->ComponentInfHandle == INVALID_HANDLE_VALUE)
|
|
? NULL
|
|
: psc->ComponentInfHandle;
|
|
|
|
// open the inf
|
|
|
|
if (cd->hinf)
|
|
SetupOpenAppendInfFile(NULL, cd->hinf,NULL);
|
|
|
|
// copy helper routines and flags
|
|
|
|
cd->HelperRoutines = psc->HelperRoutines;
|
|
|
|
cd->Flags = psc->SetupData.OperationFlags;
|
|
|
|
cd->SourcePath = NULL;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/*
|
|
* OnExtraRoutines()
|
|
*
|
|
* handler for OC_EXTRA_ROUTINES
|
|
*/
|
|
|
|
DWORD
|
|
OnExtraRoutines(
|
|
LPCTSTR ComponentId,
|
|
PEXTRA_ROUTINES per
|
|
)
|
|
{
|
|
PPER_COMPONENT_DATA cd;
|
|
|
|
if (!(cd = LocateComponent(ComponentId)))
|
|
return NO_ERROR;
|
|
|
|
memcpy(&cd->ExtraRoutines, per, per->size);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/*
|
|
* OnQuerySelStateChange()
|
|
*
|
|
* don't let the user deselect the sam component
|
|
*/
|
|
|
|
DWORD
|
|
OnQuerySelStateChange(
|
|
LPCTSTR ComponentId,
|
|
LPCTSTR SubcomponentId,
|
|
UINT state,
|
|
UINT flags
|
|
)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
/*
|
|
* OnCalcDiskSpace()
|
|
*
|
|
* handler for OC_ON_CALC_DISK_SPACE
|
|
*/
|
|
|
|
DWORD
|
|
OnCalcDiskSpace(
|
|
LPCTSTR ComponentId,
|
|
LPCTSTR SubcomponentId,
|
|
DWORD addComponent,
|
|
HDSKSPC dspace
|
|
)
|
|
{
|
|
DWORD rc = NO_ERROR;
|
|
TCHAR section[S_SIZE];
|
|
PPER_COMPONENT_DATA cd;
|
|
|
|
//
|
|
// Param1 = 0 if for removing component or non-0 if for adding component
|
|
// Param2 = HDSKSPC to operate on
|
|
//
|
|
// Return value is Win32 error code indicating outcome.
|
|
//
|
|
// In our case the private section for this component/subcomponent pair
|
|
// is a simple standard inf install section, so we can use the high-level
|
|
// disk space list api to do what we want.
|
|
//
|
|
|
|
if (!(cd = LocateComponent(ComponentId)))
|
|
return NO_ERROR;
|
|
|
|
_tcscpy(section, SubcomponentId);
|
|
|
|
if (addComponent)
|
|
{
|
|
rc = SetupAddInstallSectionToDiskSpaceList(dspace,
|
|
cd->hinf,
|
|
NULL,
|
|
section,
|
|
0,
|
|
0);
|
|
}
|
|
else
|
|
{
|
|
rc = SetupRemoveInstallSectionFromDiskSpaceList(dspace,
|
|
cd->hinf,
|
|
NULL,
|
|
section,
|
|
0,
|
|
0);
|
|
}
|
|
|
|
if (!rc)
|
|
rc = GetLastError();
|
|
else
|
|
rc = NO_ERROR;
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* OnCompleteInstallation
|
|
*
|
|
* handler for OC_COMPLETE_INSTALLATION
|
|
*/
|
|
|
|
DWORD
|
|
OnCompleteInstallation(
|
|
LPCTSTR ComponentId,
|
|
LPCTSTR SubcomponentId
|
|
)
|
|
{
|
|
PPER_COMPONENT_DATA cd;
|
|
BOOL rc;
|
|
|
|
// Do post-installation processing in the cleanup section.
|
|
// This way we know all compoents queued for installation
|
|
// have beein installed before we do our stuff.
|
|
|
|
if (!(cd = LocateComponent(ComponentId)))
|
|
return NO_ERROR;
|
|
|
|
if (!SubcomponentId || !*SubcomponentId)
|
|
return NO_ERROR;
|
|
|
|
rc = TRUE;
|
|
|
|
FsConInstall* pFsCon = new FsConInstall(cd);
|
|
if (pFsCon == NULL)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
if (pFsCon->QueryStateInfo(SubcomponentId)) {
|
|
//
|
|
// installation
|
|
//
|
|
rc = pFsCon->GUIModeSetupInstall();
|
|
}
|
|
else {
|
|
//
|
|
// uninstallation
|
|
//
|
|
rc = pFsCon->GUIModeSetupUninstall();
|
|
//
|
|
// Remove any registry settings and files by Uninstall section on OC INF file.
|
|
//
|
|
if (rc) {
|
|
rc = pFsCon->InfSectionRegistryAndFiles(SubcomponentId, TEXT("Uninstall"));
|
|
}
|
|
}
|
|
|
|
delete pFsCon;
|
|
|
|
if (rc) {
|
|
return NO_ERROR;
|
|
}
|
|
else {
|
|
return GetLastError();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* OnQueryState()
|
|
*
|
|
* handler for OC_QUERY_STATE
|
|
*/
|
|
|
|
DWORD
|
|
OnQueryState(
|
|
LPCTSTR ComponentId,
|
|
LPCTSTR SubcomponentId,
|
|
UINT state
|
|
)
|
|
{
|
|
return SubcompUseOcManagerDefault;
|
|
}
|
|
|
|
/*
|
|
* AddNewComponent()
|
|
*
|
|
* add new compononent to the top of the component list
|
|
*/
|
|
|
|
PPER_COMPONENT_DATA
|
|
AddNewComponent(
|
|
LPCTSTR ComponentId
|
|
)
|
|
{
|
|
PPER_COMPONENT_DATA data;
|
|
|
|
data = (PPER_COMPONENT_DATA)LocalAlloc(LPTR,sizeof(PER_COMPONENT_DATA));
|
|
if (!data)
|
|
return data;
|
|
|
|
data->ComponentId = (TCHAR *)LocalAlloc(LMEM_FIXED,
|
|
(_tcslen(ComponentId) + 1) * sizeof(TCHAR));
|
|
|
|
if(data->ComponentId)
|
|
{
|
|
_tcscpy((TCHAR *)data->ComponentId, ComponentId);
|
|
|
|
// Stick at head of list
|
|
data->Next = gcd;
|
|
gcd = data;
|
|
}
|
|
else
|
|
{
|
|
LocalFree((HLOCAL)data);
|
|
data = NULL;
|
|
}
|
|
|
|
return(data);
|
|
}
|
|
|
|
/*
|
|
* LocateComponent()
|
|
*
|
|
* returns a compoent struct that matches the
|
|
* passed component id.
|
|
*/
|
|
|
|
PPER_COMPONENT_DATA
|
|
LocateComponent(
|
|
LPCTSTR ComponentId
|
|
)
|
|
{
|
|
PPER_COMPONENT_DATA p;
|
|
|
|
for (p = gcd; p; p=p->Next)
|
|
{
|
|
if (!_tcsicmp(p->ComponentId, ComponentId))
|
|
return p;
|
|
}
|
|
|
|
return NULL;
|
|
}
|