/* * 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 #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; }