|
|
/*
* 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;
_tcsncpy(section, SubcomponentId, S_SIZE - 1); section[S_SIZE - 1] = L'\0';
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; }
|