// // Copyright (c) 1996 Microsoft Corporation // // // INF.CPP -- Implemtation for Classes: // CInfFile // // History: // 05/21/96 JosephJ Created // // #include "common.h" #include "ini.h" #include "inf.h" // Version-related constants LPCTSTR lpctszVersion = TEXT("Version"); LPCTSTR lpctszLayoutFile = TEXT("LayoutFile"); LPCTSTR lpctszSignature = TEXT("Signature"); LPCTSTR lpctszClass = TEXT("Class"); LPCTSTR lpctszClassGUID = TEXT("ClassGUID"); LPCTSTR lpctszProvider = TEXT("Provider"); LPCTSTR lpctszManufacturer = TEXT("Manufacturer"); LPCTSTR lpctszControlFlags = TEXT("ControlFlags"); LPCTSTR lpctszStrings = TEXT("Strings"); /////////////////////////////////////////////////////////////////////////// // CLASS CInfFile /////////////////////////////////////////////////////////////////////////// CInfFile::CInfFile(void) { m_pVersion=NULL; m_pFirstManuE=NULL; m_pSymFileName=NULL; m_pIniFile=NULL; } CInfFile::~CInfFile() { mfn_EnterCrit(); // Free resources -- there should be none to free... ASSERT(!m_pVersion); ASSERT(!m_pFirstManuE); ASSERT(!m_pIniFile); } //-------------- Load ------------------ // Loads the specified file. (Obviously) only one file can be loaded at // a time. BOOL CInfFile::Load (const TCHAR rgchPathname[]) { BOOL fRet = FALSE; mfn_EnterCrit(); // TODO: call m_sync.BeginLoad ASSERT(!m_pVersion); ASSERT(!m_pFirstManuE); ASSERT(!m_pIniFile); // Save file name m_pSymFileName = gSymtab.Lookup(rgchPathname, TRUE); if (!m_pSymFileName) goto end; // Create and Load Ini File m_pIniFile = new CIniFile; if (m_pIniFile) { if (!m_pIniFile->Load(rgchPathname)) { delete m_pIniFile; m_pIniFile=NULL; } } if (!m_pIniFile) goto end; // Create and Load version { CInfVersionSection *pVS = new CInfVersionSection; if (pVS) { // Override const * declaration of m_pVersion if (!pVS->Load(m_pIniFile)) { delete pVS; pVS=NULL; } } m_pVersion = pVS; } if (!m_pVersion) goto end; // Create and load Manufacturer list... m_pFirstManuE = sfn_CreateManufacturerList(m_pIniFile); if (!m_pFirstManuE) goto end; fRet = TRUE; end: if (!fRet) { mfn_Cleanup(); } mfn_LeaveCrit(); return fRet; } //-------------- Unload ------------------ // Unloads a previously loaded file. If there are open sessions to this // object, Unload returns a handle which will be signalled when all // sessions are closed. New sessions will not be allowed after this // function returns. The call should free the handle. HANDLE CInfFile::Unload (void) { HANDLE hUnload = NULL; mfn_EnterCrit(); // TODO: call m_sync.BeginUnload to try to put us in unloadable state. mfn_Cleanup(); mfn_LeaveCrit(); return hUnload; } /////////////////////////////////////////////////////////////////////////// // CLASS CInfVersionSection /////////////////////////////////////////////////////////////////////////// // Sample Version section: // [Version] // LayoutFile=layout.inf // Signature="$CHICAGO$" // Class=Modem // ClassGUID={4D36E96D-E325-11CE-BFC1-08002BE10318} // Provider=%MS% //-------------- Load ------------------ // TODO: unimplemented BOOL CInfVersionSection::Load (const CIniFile *pIniFile) { BOOL fRet = FALSE; const CIniFileSection *pISVer = pIniFile->LookupSection(lpctszVersion); const CIniFileSection *pISStr = pIniFile->LookupSection(lpctszStrings); const CIniFileEntry *pIE = NULL; #if 0 m_pSymLayoutFile = gSymtab.Lookup(TEXT("layout.inf"), TRUE); m_pSymSignature = gSymtab.Lookup(TEXT("\"$CHICAGO$\""), TRUE); m_pSymClass = gSymtab.Lookup(TEXT("Modem"), TRUE); m_pSymClassGUID = gSymtab.Lookup ( TEXT("{4D36E96D-E325-11CE-BFC1-08002BE10318}"), TRUE ); m_pSymProvider = gSymtab.Lookup(TEXT("Microsoft"), TRUE); m_dwChecksum = 0x12345678L; #endif ASSERT ( !m_pSymLayoutFile && !m_pSymSignature && !m_pSymClass && !m_pSymClassGUID && !m_pSymProvider && !m_dwChecksum ); if (!pISVer || !pISStr) goto end; // LayoutFile=layout.inf pIE = pISVer->LookupEntry(lpctszLayoutFile); if (pIE) { m_pSymLayoutFile = pIE->GetRHS(); pIE->Release();pIE=NULL; // TODO: further checks here } // Signature="$CHICAGO$" pIE = pISVer->LookupEntry(lpctszSignature); if (pIE) { m_pSymSignature = pIE->GetRHS(); pIE->Release();pIE=NULL; // TODO: further checks here } // Class=Modem pIE = pISVer->LookupEntry(lpctszClass); if (pIE) { m_pSymClass = pIE->GetRHS(); pIE->Release();pIE=NULL; // TODO: further checks here } // ClassGUID={4D36E96D-E325-11CE-BFC1-08002BE10318} pIE = pISVer->LookupEntry(lpctszClassGUID); if (pIE) { m_pSymClassGUID = pIE->GetRHS(); pIE->Release();pIE=NULL; // TODO: further checks here } // Provider=%MS% pIE = pISVer->LookupEntry(lpctszProvider); if (pIE) { const CInfSymbol *pSymLHS = pIE->GetLHS(); pIE->Release();pIE=NULL; if (pSymLHS) { pIE = pISStr->LookupEntry(pSymLHS->GetText()); if (pIE) { m_pSymProvider = pIE->GetRHS(); pIE->Release();pIE=NULL; } } // TODO: further checks here } // Compute checksum of entire version structure m_dwChecksum = m_pSymLayoutFile->Checksum(); AddToChecksumDW(&m_dwChecksum, m_pSymSignature->Checksum()); AddToChecksumDW(&m_dwChecksum, m_pSymClass->Checksum()); AddToChecksumDW(&m_dwChecksum, m_pSymClassGUID->Checksum()); AddToChecksumDW(&m_dwChecksum, m_pSymProvider->Checksum()); fRet =TRUE; end: if (pIE) { pIE->Release(); pIE=NULL; } if (pISVer) { pISVer->Release(); pISVer=NULL; } if (pISStr) { pISStr->Release(); pISStr=NULL; } if (!fRet) { mfn_Cleanup(); } return fRet; } //-------------- Unload ------------------ void CInfVersionSection::Unload (void) { // TODO: call m_sync.BeginUnload to try to put us in unloadable state. mfn_Cleanup(); return; } //-------------- Dump ------------------ // Dump state void CInfVersionSection::Dump(void) const { } // Cleanup by freeing any allocated resources. void CInfVersionSection::mfn_Cleanup (void) { m_pSymLayoutFile = NULL; m_pSymSignature = NULL; m_pSymClass = NULL;; m_pSymClassGUID = NULL; m_pSymProvider = NULL; m_dwChecksum = 0; } /////////////////////////////////////////////////////////////////////////// // CLASS CInfManufacturerEntry /////////////////////////////////////////////////////////////////////////// // Sample Manufacturer list section: // [Manufacturer] // %Generic% = Generic // %MagicRam% = MagicRam // .. /////////////////////////////////////////////////////////////////////////// // CLASS CInfManufacturerSection /////////////////////////////////////////////////////////////////////////// // Sample Manufacturer section: // [Generic] // %Gen% = Gen, MDMGEN // %Gen3% = Gen3, MDMGEN3 // %Gen12% = Gen12, MDMGEN12 // %Gen24% = Gen24, MDMGEN24 // ... // --------------- GetFirstModelEntry -------------- // Get first model entry const CInfModelEntry * CInfManufacturerSection::GetFirstModelEntry (void) const { return m_pFirstModelE; } /////////////////////////////////////////////////////////////////////////// // CLASS CInfInstallSection /////////////////////////////////////////////////////////////////////////// // Sample Install section: // [Modem29] // AddReg=All, MfgAddReg, ROCK_VOICE_ALL, ROCK_VOICE_SERWAVE, INTERNAL // CopyFiles = VV_Sys, VV_Sock_Sys, VV_App, VV_Help // UpdateInis = VView.Inis // Uninstall = VoiceView_remove // // Also contains info from the related PosDup and NoResDup sections. // --------------- GetAddRegSectionList ---------- // Get generic list whose data items are pointers to // CInfAddRegSection objects const CInfList * CInfInstallSection::GetAddRegSectionList (void) const { // TODO: unimplemented static const CInfAddRegSection AddRegSection; static const CInfList AddRegSectionList((void *) &AddRegSection, NULL); return &AddRegSectionList; } // --------------- GetCopyFilesSectionList ---------- // Get generic list whose data items are pointers to // CInfCopyFilesSection objects const CInfList * CInfInstallSection::GetCopyFilesSectionList (void) const { // TODO: unimplemented static const CInfCopyFilesSection CopyFilesSection; static const CInfList CopyFilesSectionList((void *) &CopyFilesSection, NULL); return &CopyFilesSectionList; } // --------------- GetNoResDupIDList ---------- // Get generic list whose data items are pointers to // InfSymbol objects representing the Rank0 IDs in the corresponding // NoResDup section. const CInfList * CInfInstallSection::GetNoResDupIDList (void) const { // TODO: unimplemented static const CInfList NoResDupIDList ( (void *) gSymtab.Lookup(TEXT("NORESDUP-ID"), TRUE), NULL ); return &NoResDupIDList; } // --------------- GetPosDupIDList ---------- // Get generic list whose data items are pointers to // InfSymbol objects representing the Rank0 IDs in the corresponding // PosDup section. // const CInfList * GetPosDupIDList (void) const; const CInfList * CInfInstallSection::GetPosDupIDList (void) const { // TODO: unimplemented static const CInfList PosDupIDList1 ( (void *) gSymtab.Lookup(TEXT("POSDUP-ID1"), TRUE), NULL ); static const CInfList PosDupIDList ( (void *) gSymtab.Lookup(TEXT("POSDUP-ID0"), TRUE), &PosDupIDList1 ); return &PosDupIDList; } /////////////////////////////////////////////////////////////////////////// // CLASS CInfAddRegSection /////////////////////////////////////////////////////////////////////////// // Sample AddReg section: // [All] // HKR,,FriendlyDriver,,Unimodem.vxd // HKR,,DevLoader,,*vcomm // HKR,,ConfigDialog,,modemui.dll // HKR,,EnumPropPages,,"modemui.dll,EnumPropPages" // HKR,,PortSubClass,1,02 // HKR, Init, 1,, "AT" // HKR, Responses, "OK", 1, 00, 00, 00,00,00,00, ...etc. // HKR, Responses, "ERROR", 1, 03, 00, 00,00,00, ...etc. // Get first addreg entry const CInfAddRegEntry * CInfAddRegSection::GetFirstAddRegEntry (void) const { // TODO -- fake static entries static const CInfAddRegEntry FirstAddRegEntry; return &FirstAddRegEntry; } /////////////////////////////////////////////////////////////////////////// // CLASS CInfCopyFilesSection /////////////////////////////////////////////////////////////////////////// // Sample DestinationDirs section: // [DestinationDirs] // Register.Copy = 17 ;LDID_INF // VV_Sys = 11 // VV_Sock_Sys = 11 ;LDID_SYS \Windows\system dir // VV_Sock_Win = 10 ;LDID_WIN \Windows dir // VV_App = 10 // VV_Help = 18 ;LDID_HELP // Sample Copyfiles section: // [VV_Sys] // fte.dll // vvexe32.exe // wsvv.vxd // --------------- GetFirstCopyFilesEntry ---------- // Get first copyfiles entry const CInfCopyFilesEntry * CInfCopyFilesSection::GetFirstCopyFilesEntry (void) const { // TODO -- fake static entries static const CInfCopyFilesEntry FirstCopyFilesEntry; return &FirstCopyFilesEntry; } // Cleanup by freeing any allocated resources. // TODO: unimplemented void CInfFile::mfn_Cleanup (void) { mfn_EnterCrit(); // TODO: ASSERT(state == loading or state == unloading) // Unload and free version if (m_pVersion) { // override const * CInfVersionSection *pVS = (CInfVersionSection *) m_pVersion; pVS->Unload(); delete pVS; m_pVersion=NULL; } // Unload and free Manufacturerlist. if (m_pFirstManuE) { sfn_DeleteManufacturerList(m_pFirstManuE); m_pFirstManuE=NULL; } if (m_pIniFile) { m_pIniFile->Unload(); delete (CIniFile *) m_pIniFile; // override const * m_pIniFile=NULL; } m_pSymFileName=NULL; mfn_LeaveCrit(); } // static helper function... const CInfManufacturerEntry * CInfFile::sfn_CreateManufacturerList (CIniFile *pIniFile) { CInfManufacturerEntry * pManuE = NULL; const CIniFileSection *pISStr = pIniFile->LookupSection(lpctszStrings); const CIniFileSection *pISManL = pIniFile->LookupSection(lpctszManufacturer); CIniFileEntry *pIE = NULL; if (!pISManL || !pISStr) goto end; pIE = pISManL->GetFirstEntry(); if (!pIE) goto end; // Iterate through manufacturers, building manufacturer entries... do { pManuE = new CInfManufacturerEntry(pManuE); if (!pManuE || !pManuE->Load(pIniFile, pISStr, pIE)) { // TODO: warning; for now break out. if (pManuE) { // TODO delete previously-created elements of the list as well! // (Or leave them there and deal with a partial list). delete pManuE; pManuE = NULL; } goto end; } } while(pIE->BecomeNext()); // Reverse list CInfManufacturerEntry::ReverseList(&pManuE); end: if (pIE) {pIE->Release(); pIE=NULL;} if (pISManL) { pISManL->Release(); pISManL=NULL; } if (pISStr) { pISStr->Release(); pISStr=NULL; } return pManuE; } // Static helper function void CInfFile::sfn_DeleteManufacturerList ( const CInfManufacturerEntry * pManuEFirst ) { // TODO } // --------------- Load ------------------ BOOL CInfManufacturerEntry::Load ( const CIniFile *pIniFile, const CIniFileSection *pISStr, const CIniFileEntry *pIE ) { BOOL fRet = FALSE; const CInfSymbol *pSymLHS = pIE->GetLHS(); const CInfSymbol *pSymManuName = NULL; // TODO need to make manu-section case insensitive! // Basically pSymManuSection should be created based on an upper-case'd // version of pIE->GetRHS(). const CInfSymbol *pSymManuSection = pIE->GetRHS(); CInfManufacturerSection *pManuS = NULL; BOOL fNew=FALSE; ASSERT(!m_pManuS); ASSERT(!m_pSymManuName); // Get manufacturer name ... if (pSymLHS) { const CIniFileEntry *pIEStr = pISStr->LookupEntry(pSymLHS->GetText()); if (pIEStr) { pSymManuName = pIE->GetRHS(); pIEStr->Release();pIEStr=NULL; } } pManuS=NULL; // Look up/create manufacturer section { void **ppv=NULL; BOOL fExists=FALSE; BOOL fRet = pSymManuSection->GetOrCreatePropLoc( PROP_INFSECTION_MANUFACTURER, &ppv, &fExists); if (fRet) { if (fExists) { // This section already exists... pManuS = (CInfManufacturerSection *) *ppv; ASSERT(pManuS->Validate()); } else { // This section doesn't exist -- create it. pManuS = new CInfManufacturerSection(); if (pManuS) { if (pManuS->Load(pIniFile, pISStr, pSymManuSection)) { // set the property data *ppv = (void *) pManuS; } else { delete pManuS; pManuS=NULL; pSymManuSection->DelProp(PROP_INFSECTION_MANUFACTURER); } } } } } if (pManuS) { m_pManuS = pManuS; m_pSymManuName = pSymManuName; fRet = TRUE; } if (!fRet) { mfn_Cleanup(); } return fRet; } // --------------- Unload ------------------ void CInfManufacturerEntry::Unload(void) // TODO { m_pManuS = NULL; m_pSymManuName = NULL; // TODO: decrement ref count for the section and delete it and delprop // it when done. mfn_Cleanup(); } // --------------- Cleanup ------------------ // Cleanup by freeing any allocated resources. void CInfManufacturerEntry::mfn_Cleanup (void) { m_pManuS = NULL; m_pSymManuName = NULL; } // --------------- Load ------------------ BOOL CInfManufacturerSection::Load ( const CIniFile *pIniFile, const CIniFileSection *pISStr, const CInfSymbol *pSymManuSection ) { BOOL fRet = FALSE; const CIniFileSection *pIS = pIniFile->LookupSection(pSymManuSection->GetText()); ASSERT(!m_pSymSectionName); ASSERT(!m_pFirstModelE); ASSERT(m_eObjSig==eOBJSIG_CInfManufacturerSection); if (!pIS) { goto end; } m_pSymSectionName = pSymManuSection; // Create and load model list m_pFirstModelE = sfn_CreateModelList(pIniFile, pISStr, pIS); if (!m_pFirstModelE) { goto end; } fRet = TRUE; end: if (!fRet) { mfn_Cleanup(); } return fRet; } // --------------- Unload ------------------ void CInfManufacturerSection::Unload(void) { mfn_Cleanup(); } // --------------- Cleanup ------------------ // Cleanup by freeing any allocated resources. void CInfManufacturerSection::mfn_Cleanup (void) // TODO { m_pSymSectionName = NULL; m_pFirstModelE = NULL; } // Static helper function to create the list of models for this manufacturer const CInfModelEntry * CInfManufacturerSection::sfn_CreateModelList ( const CIniFile *pIniFile, const CIniFileSection *pISStr, const CIniFileSection *pISManuS ) { CInfModelEntry * pModelE = NULL; CIniFileEntry *pIE = NULL; if (!pISManuS || !pISStr) goto end; pIE = pISManuS->GetFirstEntry(); if (!pIE) goto end; // Iterate through models, building model entries... do { pModelE = new CInfModelEntry(pModelE); if (!pModelE || !pModelE->Load(pIniFile, pISStr, pIE)) { // TODO: warning; for now break out. if (pModelE) { // TODO delete previously-created elements of the list as well! // (Or leave them there and deal with a partial list). delete pModelE; pModelE = NULL; } goto end; } } while(pIE->BecomeNext()); // Reverse list CInfModelEntry::ReverseList(&pModelE); end: if (pIE) {pIE->Release(); pIE=NULL;} //if (pISManL) { pISManL->Release(); pISManL=NULL; } //if (pISStr) { pISStr->Release(); pISStr=NULL; } return pModelE; } // --------------- Cleanup ------------------ // Cleanup by freeing any allocated resources. void CInfModelEntry::mfn_Cleanup (void) // TODO { } // --------------- Load ------------------ BOOL CInfModelEntry::Load ( const CIniFile *pIniFile, const CIniFileSection *pISStr, const CIniFileEntry *pIE ) // TODO { return TRUE; #if 0 BOOL fRet = FALSE; const CInfSymbol *pSymLHS = pIE->GetLHS(); const CInfSymbol *pSymManuName = NULL; // TODO need to make manu-section case insensitive! // Basically pSymManuSection should be created based on an upper-case'd // version of pIE->GetRHS(). const CInfSymbol *pSymManuSection = pIE->GetRHS(); CInfManufacturerSection *pManuS = NULL; BOOL fNew=FALSE; ASSERT(!m_pManuS); ASSERT(!m_pSymManuName); // Get manufacturer name ... if (pSymLHS) { const CIniFileEntry *pIEStr = pISStr->LookupEntry(pSymLHS->GetText()); if (pIEStr) { pSymManuName = pIE->GetRHS(); pIEStr->Release();pIEStr=NULL; } } pManuS=NULL; // Look up/create manufacturer section { void **ppv=NULL; BOOL fExists=FALSE; BOOL fRet = pSymManuSection->GetOrCreatePropLoc( PROP_INFSECTION_MANUFACTURER, &ppv, &fExists); if (fRet) { if (fExists) { // This section already exists... pManuS = (CInfManufacturerSection *) *ppv; ASSERT(pManuS->Validate()); } else { // This section doesn't exist -- create it. pManuS = new CInfManufacturerSection(); if (pManuS) { if (pManuS->Load(pIniFile, pISStr, pSymManuSection)) { // set the property data *ppv = (void *) pManuS; } else { delete pManuS; pManuS=NULL; pSymManuSection->DelProp(PROP_INFSECTION_MANUFACTURER); } } } } } if (pManuS) { m_pManuS = pManuS; m_pSymManuName = pSymManuName; fRet = TRUE; } if (!fRet) { mfn_Cleanup(); } return fRet; #endif } // --------------- Unload ------------------ void CInfModelEntry::Unload(void) // TODO { mfn_Cleanup(); }