#include "component.h" #include #include #include #include #include #include ////////////////////////////////////////////////////////////////// // Implementation of the Component Class ////////////////////////////////////////////////////////////////// // Constructor Component::Component(){ tszComponentId[0] = 0; tszParentId[0] = 0; prlNeedList = new RelationList; prlExcludeList = new RelationList; prlChildrenList = new RelationList; } // Another constructor Component::Component(TCHAR *tszId){ _tcscpy(tszComponentId, tszId); tszParentId[0] = 0; prlNeedList = new RelationList; prlExcludeList = new RelationList; prlChildrenList = new RelationList; } // Destructor Component::~Component(){ if (prlNeedList) { delete prlNeedList; } if (prlExcludeList) { delete prlExcludeList; } if (prlChildrenList) { delete prlChildrenList; } } // Copy constructor Component::Component(const Component& source){ _tcscpy(tszComponentId, source.tszComponentId); _tcscpy(tszParentId, source.tszParentId); prlNeedList = source.prlNeedList; prlExcludeList = source.prlExcludeList; prlChildrenList = source.prlChildrenList; } // Assignment operator const Component& Component::operator=(const Component& source){ _tcscpy(tszComponentId, source.tszComponentId); _tcscpy(tszComponentId, source.tszParentId); if (prlNeedList) { delete prlNeedList; } if (prlExcludeList) { delete prlExcludeList; } if (prlChildrenList) { delete prlChildrenList; } prlNeedList = source.prlNeedList; prlExcludeList = source.prlExcludeList; prlChildrenList = source.prlChildrenList; return *this; } // Find the parent of this component // by searching a component list Component* Component::GetParent(ComponentList *pclHead){ Component *pcTemp = pclHead->pcCurrent; pclHead->ResetList(); while (!pclHead->Done()) { if (pclHead->GetNext()->IsParent(this)){ pclHead->pcCurrent = pcTemp; return (pclHead->GetNext()); } } pclHead->pcCurrent = pcTemp; return NULL; } // If this component is the parent of the parameter BOOL Component::IsParent(Component* pcChild){ if (_tcscmp(pcChild->tszParentId, this->tszComponentId) == 0) { if (_tcscmp(pcChild->tszComponentId, pcChild->tszParentId) == 0) { // the parameter is a top-level component return FALSE; } return TRUE; } return FALSE; } // If this component is the child of the parameter BOOL Component::IsChild(Component* pcParent){ if (_tcscmp(this->tszParentId, pcParent->tszComponentId) == 0) { if (_tcscmp(this->tszParentId, this->tszComponentId) == 0 ) { // This is a top-level component return FALSE; } return TRUE; } return FALSE; } // Check if this component is needed by the parameter BOOL Component::IsNeededBy(Component *pcComponent){ pcComponent->prlNeedList->ResetList(); while (!pcComponent->prlNeedList->Done()) { if (_tcscmp(pcComponent->prlNeedList->GetNext()->tszComponentId, this->tszComponentId) == 0){ return TRUE; } } return FALSE; } // Check if this component is excluded by the parameter BOOL Component::IsExcludeBy(Component *pcComponent){ pcComponent->prlExcludeList->ResetList(); while (!pcComponent->prlExcludeList->Done()) { if (_tcscmp(pcComponent->prlNeedList->GetNext()->tszComponentId, this->tszComponentId) == 0) { return TRUE; } } return FALSE; } // Get this component's parent id from INF file BOOL Component::GetParentIdFromINF(HINF hinfHandle){ INFCONTEXT infContext; BOOL bSuccess; bSuccess = SetupFindFirstLine(hinfHandle, tszComponentId, TEXT("Parent"), &infContext); if (bSuccess) { // Find the line bSuccess = SetupGetStringField(&infContext, 1, tszParentId, MaxBufferSize, NULL); if (bSuccess) { return TRUE; } else{ MessageBox(NULL, TEXT("Unexpected error happened"), TEXT("GetParentIdFromINF"), MB_ICONERROR | MB_OK); return FALSE; } } else{ // This is a top-level component _tcscpy(tszParentId, tszComponentId); return TRUE; } } // Check if this component is a toplevel compoent // Toplevel component means no parent BOOL Component::IsTopLevelComponent(){ if (_tcscmp(tszComponentId, tszParentId) == 0) { return TRUE; } return FALSE; } // Check if this component is a bottomlevel component // bottom level component doesn't have any child BOOL Component::IsBottomComponent(){ if (prlChildrenList == NULL || prlChildrenList->prHead == NULL) { return TRUE; } return FALSE; } // Check if this component is needed by others BOOL Component::IsNeededByOthers(ComponentList *pclList){ Component *pcTemp = pclList->pcCurrent; pclList->ResetList(); while (!pclList->Done()) { if (IsNeededBy(pclList->GetNext())){ pclList->pcCurrent = pcTemp; return TRUE; } } pclList->pcCurrent = pcTemp; return FALSE; } // Check if this component is excluded by others BOOL Component::IsExcludedByOthers(ComponentList *pclList){ Component *pcTemp = pclList->pcCurrent; pclList->ResetList(); while (!pclList->Done()) { if (IsExcludeBy(pclList->GetNext())){ pclList->pcCurrent = pcTemp; return TRUE; } } pclList->pcCurrent = pcTemp; return FALSE; } // Check if this component is parent of other components BOOL Component::IsParentOfOthers(){ if (prlChildrenList != NULL && prlChildrenList->prHead != NULL) { return TRUE; } return FALSE; } // Build the children list for this component BOOL Component::BuildChildrenList(ComponentList *pclList){ // We can't use the enumerate facility of pclList here Component *pcComponent = pclList->pcHead; while (pcComponent) { if (IsParent(pcComponent)) { if (!prlChildrenList) { prlChildrenList = new RelationList; } prlChildrenList->AddRelation(pcComponent->tszComponentId); } pcComponent = pcComponent->Next; } return TRUE; } // Check if this component has a need and exclude relation with other // component at the same time BOOL Component::NeedAndExcludeAtSameTime(ComponentList *pclList){ TCHAR tszMsg[MaxStringSize]; Component *pcComponent; const PTSTR tszFunctionName = TEXT("Component::NeedAndExcludeAtSameTime"); // Go through the list of component it excludes // check if any of them needs this one prlExcludeList->ResetList(); while (!prlExcludeList->Done()){ pcComponent = pclList->LookupComponent(prlExcludeList->GetNext()->GetComponentId()); // Check if this needs pcComponent if (pcComponent->IsNeededBy(this)){ _stprintf(tszMsg, TEXT("%s is needed and excluded by the same component"), this->tszComponentId); LogError(tszMsg, SEV2, tszFunctionName); return TRUE; } // Check if pcComponent needs this if (this->IsNeededBy(pcComponent)){ _stprintf(tszMsg, TEXT("%s is needed and excluded by the same component"), this->tszComponentId); LogError(tszMsg, SEV2, tszFunctionName); return TRUE; } } return FALSE; } // Check if this component needs other components BOOL Component::NeedOthers(){ if (prlNeedList != NULL && prlNeedList->prHead != NULL) { return TRUE; } return FALSE; } // Check if this component excludes other components BOOL Component::ExcludeOthers(){ if (prlExcludeList != NULL && prlExcludeList->prHead != NULL) { return TRUE; } return FALSE; } // Check if there is another component with the same // id as this component BOOL Component::IsThereSameId(ComponentList *pclList){ Component *pcCur; TCHAR tszMsg[MaxStringSize]; const PTSTR tszFunctionName = TEXT("Component::IsThereSameId"); pcCur = pclList->pcHead; while (pcCur) { if (pcCur != this) { if (_tcscmp(pcCur->tszComponentId, this->tszComponentId) == 0) { _stprintf(tszMsg, TEXT("There are two component with the same ID %s"), this->tszComponentId); LogError(tszMsg, SEV2, tszFunctionName); } } pcCur = pcCur->Next; } return TRUE; } // Not implemented yet UINT Component::GetDiskSpaceRequirement(HINF hinfHandle){ // Not implemented yet. return 0; } // Check if this another component with the same description BOOL Component::IsThereSameDesc(ComponentList *pclList){ const PTSTR tszFunctionName = TEXT("Component::IsThereSameDesc"); TCHAR tszMsg[MaxStringSize]; Component *pcCur = pclList->pcHead; while (pcCur) { if (pcCur != this) { if (_tcscmp(pcCur->pDescAndTip->tszDesc, this->pDescAndTip->tszDesc) == 0) { if ((this->IsTopLevelComponent() && pcCur->IsTopLevelComponent()) || this->HasSameParentWith(pcCur)) { // ahha, found one _stprintf(tszMsg, TEXT("Two components with the same description %s"), pDescAndTip->tszDesc); LogError(tszMsg, SEV2, tszFunctionName); } } } pcCur = pcCur->Next; } return TRUE; } // Check if this component has the same parent as the parameter BOOL Component::HasSameParentWith(Component *pcComponent){ if (_tcscmp(tszParentId, pcComponent->tszParentId) == 0) { return TRUE; } else{ return FALSE; } } ///////////////////////////////////////////////////////////////////// // Implementation of the ComponentList class ///////////////////////////////////////////////////////////////////// // Constructor ComponentList::ComponentList(){ pcHead = NULL; pcCurrent = NULL; } // destructor ComponentList::~ComponentList(){ // Go through the list and delete each component Component *pcComponent; if (pcHead == NULL) { // Empty list return; } while(pcHead != NULL){ pcComponent = pcHead->Next; delete pcHead; pcHead = pcComponent; } } // List iteration facility // reset the iterator void ComponentList::ResetList(){ pcCurrent = pcHead; } // Check if the iterator has reached the end BOOL ComponentList::Done(){ return (pcCurrent == NULL); } // Get the next node in the list Component* ComponentList::GetNext(){ Component *pcReturn; pcReturn = pcCurrent; if (pcCurrent != NULL) { pcCurrent = pcReturn->Next; return pcReturn; } else{ MessageBox(NULL, TEXT("Something is seriously wrong"), TEXT("ComponentList.GetNext()"), MB_ICONERROR | MB_OK); return NULL; } } // Add a component into the list Component* ComponentList::AddComponent(TCHAR *tszId){ if (tszId == NULL) { return NULL; } Component *pcNewComponent = new Component(tszId); if (!pcHead) { pcHead = pcNewComponent; pcNewComponent->Next = NULL; return pcNewComponent; } pcNewComponent->Next = pcHead; pcHead = pcNewComponent; return pcNewComponent; } // Remove a component from the list according to the id given BOOL ComponentList::RemoveComponent(TCHAR *tszId){ if (tszId == NULL) { return NULL; } // Find the component in the list Component *pcPrev = pcHead; Component *pcCur = pcHead; while (pcCur) { if (_tcscmp(pcCur->tszComponentId, tszId) == 0) { // Found the node to delete pcPrev->Next = pcCur->Next; delete pcCur; return TRUE; } pcPrev = pcCur; pcCur = pcCur->Next; } return FALSE; } // Find a component from the list Component* ComponentList::LookupComponent(TCHAR *tszId){ if (tszId == NULL) { return NULL; } Component *pcCur = pcHead; while (pcCur) { if (_tcscmp(pcCur->tszComponentId, tszId) == 0) { return pcCur; } pcCur = pcCur->Next; } return NULL; } ////////////////////////////////////////////////////////////////////// // Implementation of RelationList ////////////////////////////////////////////////////////////////////// // Constructor RelationList::RelationList(){ prHead = NULL; prCurrent = NULL; } // destructor RelationList::~RelationList(){ // deallocate all the memory Relation *prNext; if (prHead == NULL) { // The list is empty return; } while (prNext = prHead->Next) { delete prHead; prHead = prNext; } } // List iteration facility // reset the iterator void RelationList::ResetList(){ prCurrent = prHead; } // Check if the iterator has reached the end of the list BOOL RelationList::Done(){ if (prCurrent == NULL) { return TRUE; } else{ return FALSE; } } // Get the next node in the list Relation* RelationList::GetNext(){ Relation *prReturn = prCurrent; if (prCurrent != NULL) { prCurrent = prCurrent->Next; return prReturn; } else{ MessageBox(NULL, TEXT("Something is seriously wrong"), TEXT("RelationList::GetNext()"), MB_ICONERROR | MB_OK); return NULL; } } // Add a node to the list Relation* RelationList::AddRelation(TCHAR *tszId){ Relation *newRelation = new Relation; _tcscpy(newRelation->tszComponentId, tszId); if (!prHead) { prHead = newRelation; newRelation->Next = NULL; return newRelation; } newRelation->Next = prHead; prHead = newRelation; return newRelation; } // Remove a node from the list BOOL RelationList::RemoveRelation(TCHAR *tszId){ // First find the node from the list Relation *prPrev = prHead; prCurrent = prHead; while (prCurrent) { if (_tcscmp(prCurrent->tszComponentId, tszId) == 0) { prPrev->Next = prCurrent->Next; delete prCurrent; return TRUE; } prPrev = prCurrent; prCurrent = prCurrent->Next; } return FALSE; }