/*++ Copyright (c) 1993 Microsoft Corporation Module Name: infline.c Abstract: Externally exposed INF routines for INF line retreival and information. Author: Ted Miller (tedm) 20-Jan-1995 Revision History: --*/ #include "precomp.h" #pragma hdrstop #ifdef UNICODE // // ANSI version // BOOL SetupFindFirstLineA( IN HINF InfHandle, IN PCSTR Section, IN PCSTR Key, OPTIONAL OUT PINFCONTEXT Context ) { PCTSTR section,key; BOOL b; DWORD d; if((d = pSetupCaptureAndConvertAnsiArg(Section,§ion)) != NO_ERROR) { // // Invalid arg. // SetLastError(d); return(FALSE); } if(Key) { if((d = pSetupCaptureAndConvertAnsiArg(Key,&key)) != NO_ERROR) { // // Invalid arg. // MyFree(section); SetLastError(d); return(FALSE); } } else { key = NULL; } b = SetupFindFirstLine(InfHandle,section,key,Context); // // We're safe in calling this here regardless of success or failure, since // we are ensured that SetupFindFirstLine will always call SetLastError(). // d = GetLastError(); if(key) { MyFree(key); } MyFree(section); SetLastError(d); return(b); } #else // // Unicode stub // BOOL SetupFindFirstLineW( IN HINF InfHandle, IN PCWSTR Section, IN PCWSTR Key, OPTIONAL OUT PINFCONTEXT Context ) { UNREFERENCED_PARAMETER(InfHandle); UNREFERENCED_PARAMETER(Section); UNREFERENCED_PARAMETER(Key); UNREFERENCED_PARAMETER(Context); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return(FALSE); } #endif BOOL SetupFindFirstLine( IN HINF InfHandle, IN PCTSTR Section, IN PCTSTR Key, OPTIONAL OUT PINFCONTEXT Context ) /*++ Routine Description: Arguments: Return Value: --*/ { PLOADED_INF CurInf; PINF_SECTION InfSection; PINF_LINE InfLine; UINT LineNumber; UINT SectionNumber; DWORD d; d = NO_ERROR; try { if(!LockInf((PLOADED_INF)InfHandle)) { d = ERROR_INVALID_HANDLE; } } except(EXCEPTION_EXECUTE_HANDLER) { // // Assume InfHandle was bad pointer // d = ERROR_INVALID_HANDLE; } if(d != NO_ERROR) { SetLastError(d); return(FALSE); } // // Traverse the linked list of loaded INFs, looking for the specified // section. // try { for(CurInf = (PLOADED_INF)InfHandle; CurInf; CurInf = CurInf->Next) { // // Locate the section. // if(!(InfSection = InfLocateSection(CurInf, Section, &SectionNumber))) { continue; } // // Attempt to locate the line within this section. // LineNumber = 0; if(InfLocateLine(CurInf, InfSection, Key, &LineNumber, &InfLine)) { break; } } } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_PARAMETER; } UnlockInf((PLOADED_INF)InfHandle); if(d != NO_ERROR) { SetLastError(d); return(FALSE); } if(CurInf) { // // Then we found the specified line. // MYASSERT(Key || !LineNumber); try { Context->Inf = (PVOID)InfHandle; Context->CurrentInf = (PVOID)CurInf; Context->Section = SectionNumber; Context->Line = LineNumber; } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_PARAMETER; } } else { d = ERROR_LINE_NOT_FOUND; } SetLastError(d); return(d == NO_ERROR); } BOOL SetupFindNextLine( IN PINFCONTEXT ContextIn, OUT PINFCONTEXT ContextOut ) /*++ Routine Description: Arguments: Return Value: --*/ { return(SetupFindNextMatchLine(ContextIn,NULL,ContextOut)); } #ifdef UNICODE // // ANSI version // BOOL SetupFindNextMatchLineA( IN PINFCONTEXT ContextIn, IN PCSTR Key, OPTIONAL OUT PINFCONTEXT ContextOut ) { PWSTR key; BOOL b; DWORD d; if(!Key) { key = NULL; d = NO_ERROR; } else { d = pSetupCaptureAndConvertAnsiArg(Key,&key); } if (d == NO_ERROR) { b = SetupFindNextMatchLineW(ContextIn,key,ContextOut); d = GetLastError(); if (key) { MyFree(key); } } else { b = FALSE; } SetLastError(d); return(b); } #else // // Unicode stub // BOOL SetupFindNextMatchLineW( IN PINFCONTEXT ContextIn, IN PCWSTR Key, OPTIONAL OUT PINFCONTEXT ContextOut ) { UNREFERENCED_PARAMETER(ContextIn); UNREFERENCED_PARAMETER(Key); UNREFERENCED_PARAMETER(ContextOut); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return(FALSE); } #endif BOOL SetupFindNextMatchLine( IN PINFCONTEXT ContextIn, IN PCTSTR Key, OPTIONAL OUT PINFCONTEXT ContextOut ) /*++ Routine Description: Arguments: Return Value: --*/ { PLOADED_INF CurInf; UINT LineNumber; UINT SectionNumber; PINF_LINE Line; PINF_SECTION Section; PCTSTR SectionName; DWORD d; d = NO_ERROR; try { if(!LockInf((PLOADED_INF)ContextIn->Inf)) { d = ERROR_INVALID_HANDLE; } } except(EXCEPTION_EXECUTE_HANDLER) { // // ContextIn is a bad pointer // d = ERROR_INVALID_PARAMETER; } if(d != NO_ERROR) { SetLastError(d); return(FALSE); } // // Fetch values from context // try { CurInf = ContextIn->CurrentInf; SectionNumber = ContextIn->Section; Section = &CurInf->SectionBlock[SectionNumber]; SectionName = pStringTableStringFromId(CurInf->StringTable, Section->SectionName); MYASSERT(SectionName); // // Either want next line, or to start searching for key on next line // LineNumber = ContextIn->Line+1; do { if(Section) { if(InfLocateLine(CurInf, Section, Key, &LineNumber, &Line)) { break; } } if(CurInf = CurInf->Next) { Section = InfLocateSection(CurInf, SectionName, &SectionNumber); LineNumber = 0; } } while(CurInf); } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_PARAMETER; } UnlockInf((PLOADED_INF)ContextIn->Inf); if(d != NO_ERROR) { SetLastError(d); return(FALSE); } if(CurInf) { // // Then we found the next line. // try { ContextOut->Inf = ContextIn->Inf; ContextOut->CurrentInf = CurInf; ContextOut->Section = SectionNumber; ContextOut->Line = LineNumber; } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_PARAMETER; } } else { d = ERROR_LINE_NOT_FOUND; } SetLastError(d); return(d == NO_ERROR); } #ifdef UNICODE // // ANSI version // BOOL SetupGetLineByIndexA( IN HINF InfHandle, IN PCSTR Section, IN DWORD Index, OUT PINFCONTEXT Context ) { PCWSTR section; DWORD d; BOOL b; if((d = pSetupCaptureAndConvertAnsiArg(Section,§ion)) == NO_ERROR) { b = SetupGetLineByIndexW(InfHandle,section,Index,Context); d = GetLastError(); MyFree(section); } else { b = FALSE; } SetLastError(d); return(b); } #else // // Unicode stub // BOOL SetupGetLineByIndexW( IN HINF InfHandle, IN PCWSTR Section, IN DWORD Index, OUT PINFCONTEXT Context ) { UNREFERENCED_PARAMETER(InfHandle); UNREFERENCED_PARAMETER(Section); UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(Context); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return(FALSE); } #endif BOOL SetupGetLineByIndex( IN HINF InfHandle, IN PCTSTR Section, IN DWORD Index, OUT PINFCONTEXT Context ) /*++ Routine Description: Arguments: Return Value: --*/ { PLOADED_INF CurInf; PINF_SECTION InfSection; PINF_LINE InfLine; UINT LineNumber, CurLineNumberUB; UINT SectionNumber; DWORD d; d = NO_ERROR; try { if(!LockInf((PLOADED_INF)InfHandle)) { d = ERROR_INVALID_HANDLE; } } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_HANDLE; } if(d != NO_ERROR) { SetLastError(d); return(FALSE); } try { // // Traverse the list of loaded INFs. For each INF that contains // the specified section, we check to see if the line number we're // looking for lies within its (adjusted) range of line numbers. // CurLineNumberUB = 0; for(CurInf = (PLOADED_INF)InfHandle; CurInf; CurInf = CurInf->Next) { // // Locate the section. // if(!(InfSection = InfLocateSection(CurInf, Section, &SectionNumber))) { continue; } // // See if the line number lies in this INF section's range. // MYASSERT(Index >= CurLineNumberUB); LineNumber = Index - CurLineNumberUB; if(InfLocateLine(CurInf, InfSection, NULL, &LineNumber, &InfLine)) { break; } else { // // Subtract the number of lines this INF contributes to the section's // total line count, and continue with the next one. // CurLineNumberUB += InfSection->LineCount; } } } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_PARAMETER; } UnlockInf((PLOADED_INF)InfHandle); if(d != NO_ERROR) { SetLastError(d); return(FALSE); } if(CurInf) { // // Then we found the specified line. // try { Context->Inf = (PVOID)InfHandle; Context->CurrentInf = (PVOID)CurInf; Context->Section = SectionNumber; Context->Line = LineNumber; } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_PARAMETER; } } else { d = ERROR_LINE_NOT_FOUND; } SetLastError(d); return(d == NO_ERROR); } #ifdef UNICODE // // ANSI version // LONG SetupGetLineCountA( IN HINF InfHandle, IN PCSTR Section ) { PCWSTR section; LONG l; DWORD d; if((d = pSetupCaptureAndConvertAnsiArg(Section,§ion)) == NO_ERROR) { l = SetupGetLineCountW(InfHandle,section); d = GetLastError(); MyFree(section); } else { l = -1; } SetLastError(d); return(l); } #else // // Unicode stub // LONG SetupGetLineCountW( IN HINF InfHandle, IN PCWSTR Section ) { UNREFERENCED_PARAMETER(InfHandle); UNREFERENCED_PARAMETER(Section); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return(-1); } #endif LONG SetupGetLineCount( IN HINF InfHandle, IN PCTSTR Section ) /*++ Routine Description: Arguments: Return Value: --*/ { PLOADED_INF CurInf; PINF_SECTION InfSection; LONG LineCount; DWORD d; d = NO_ERROR; try { if(!LockInf((PLOADED_INF)InfHandle)) { d = ERROR_INVALID_HANDLE; } } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_HANDLE; } if(d != NO_ERROR) { SetLastError(d); return(-1); } try { // // Traverse the linked list of loaded INFs, and sum up the section line // counts for each INF containing the specified section. // LineCount = -1; for(CurInf = (PLOADED_INF)InfHandle; CurInf; CurInf = CurInf->Next) { if(InfSection = InfLocateSection(CurInf, Section, NULL)) { if(LineCount == -1) { LineCount = InfSection->LineCount; } else { LineCount += InfSection->LineCount; } } } } except(EXCEPTION_EXECUTE_HANDLER) { d = ERROR_INVALID_PARAMETER; } UnlockInf((PLOADED_INF)InfHandle); if(d != NO_ERROR) { SetLastError(d); return(-1); } if(LineCount == -1) { SetLastError(ERROR_SECTION_NOT_FOUND); } else { SetLastError(NO_ERROR); } return LineCount; }