#include "setupntp.h" #pragma hdrstop // // Location in registry where per-system MRU list is stored // (relative to HKEY_LOCAL_MACHINE). // PCTSTR pszPerSystemKey = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup"); PCTSTR pszPerSystemVal = TEXT("Installation Sources"); // // Location in registry where per-user MRU list is stored. // (relative to HKEY_CURRENT_USER). // PCTSTR pszPerUserKey = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup"); PCTSTR pszPerUserVal = TEXT("Installation Sources"); CRITICAL_SECTION MruCritSect; typedef PTSTR *APTSTR; // // Platform strings we recognize. // PCTSTR PlatformPathComponents[] = { TEXT("\\alpha"), TEXT("\\i386"),TEXT("\\x86"), TEXT("\\mips"), TEXT("\\ppc"), NULL }; // // These are guarded by MruCritSect. // PTSTR *TemporarySourceList; UINT TemporarySourceCount; BOOL MruNoBrowse; VOID pSetupStripTrailingPlatformComponent( IN OUT PTSTR *Paths, IN OUT PDWORD NumPaths ); BOOL _SetupSetSourceList( IN DWORD Flags, IN PCTSTR *SourceList, IN UINT SourceCount ) /*++ Routine Description: This routine allows the caller to set the list of installation sources for either the current user or the system (common to all users). Arguments: Flags - a combination of the following values: SRCLIST_SYSTEM - specify that the list is to become the per-system list. The caller must be administrator. SRCLIST_USER - specify that the list is to become the per-user list. SRCLIST_TEMPORARY - specify that the list is to become the entire list for the duration of the current process, or until this routine is called again to change the behavior. Exactly one of SRCLIST_SYSTEM, SRCLIST_USER, and SRCLIST_TEMPORARY must be specified. SRCLIST_NOBROWSE - specify that the user is not allowed to add or change sources when the SetupPromptForDisk API is used. Typically used in combination with SRCLIST_TEMPORARY. SourceList - supplies array of strings that are to become the source list, as described by the Flags parameter. SourceCount - specifies number of elements in the SourceList array. Return Value: --*/ { DWORD flags; DWORD d; UINT u,v; // // Check flags. Only one of system, user, or temporary may be set. // flags = Flags & (SRCLIST_SYSTEM | SRCLIST_USER | SRCLIST_TEMPORARY); if((flags != SRCLIST_SYSTEM) && (flags != SRCLIST_USER) && (flags != SRCLIST_TEMPORARY)) { SetLastError(ERROR_INVALID_PARAMETER); return(FALSE); } // // User must be admin for system flag to work. // if((flags == SRCLIST_SYSTEM) && !IsUserAdmin()) { SetLastError(ERROR_ACCESS_DENIED); return(FALSE); } // // Only allow one thread at a time in this process to access // the temporary source list. // EnterCriticalSection(&MruCritSect); if(Flags & SRCLIST_NOBROWSE) { MruNoBrowse = TRUE; } d = NO_ERROR; if(flags == SRCLIST_TEMPORARY) { if(TemporarySourceList) { SetupFreeSourceList(&TemporarySourceList,TemporarySourceCount); } // // Duplicate the list the caller passed in. // if(TemporarySourceList = MyMalloc(SourceCount * sizeof(PTSTR))) { TemporarySourceCount = SourceCount; for(u=0; uInfSourcePath) { InfSourcePath = DuplicateString(((PLOADED_INF)InfHandle)->InfSourcePath); } UnlockInf((PLOADED_INF)InfHandle); } if(!InfSourcePath) { // // There's not an oem location associated with this INF, so use our default // source path. // InfSourcePath = DuplicateString(SystemSourcePath); } return InfSourcePath; } VOID pSetupStripTrailingPlatformComponent( IN OUT PTSTR *Paths, IN OUT PDWORD NumPaths ) { DWORD PathCount; PTSTR Path; UINT PathIndex; UINT PathLength; PCTSTR Component; UINT ComponentLength; UINT ComponentIndex; int i; // // Do this for all paths in the array passed in by the caller. // PathCount = *NumPaths; for(PathIndex=0; PathIndex 0) && !lstrcmpi(Path+i,Component)) { // // Got a match. Strip off the final component. // Leave a trailing backslash if we're dealing with the root. // *(Path+i) = 0; if((Path[1] == TEXT(':')) && !Path[2]) { Path[2] = TEXT('\\'); Path[3] = 0; } // // Look through the rest of the paths to see whether this is // a duplicate, and if so, eliminate it. We assume there can be // at most one duplicate at this stage. // for(i=0; i<(int)PathCount; i++) { if((i != (int)PathIndex) && !lstrcmpi(Paths[i],Path)) { // // Eliminate the 'higher' one to preserve order. // Free ther string and close up the hole in the array. // i = max(i,(int)PathIndex); MyFree(Paths[i]); MoveMemory(&Paths[i],&Paths[i+1],((PathCount-i)-1)*sizeof(PTSTR)); PathCount--; break; // // We might have changed Paths[PathIndex], so recheck it. // PathIndex--; } } break; } } } *NumPaths = PathCount; }