#include "precomp.h" #pragma hdrstop // // x86 version (that deals with boot.ini) // is in i386 directory. This is the arc version, that // deals with nv-ram. // #ifndef _X86_ typedef enum { BootVarSystemPartition, BootVarOsLoader, BootVarOsLoadPartition, BootVarOsLoadFilename, BootVarOsLoadOptions, BootVarLoadIdentifier, BootVarMax } BOOT_VARS; PWSTR BootVarNames[BootVarMax] = { L"SYSTEMPARTITION", L"OSLOADER", L"OSLOADPARTITION", L"OSLOADFILENAME", L"OSLOADOPTIONS", L"LOADIDENTIFIER" }; DWORD BootVarComponentCount[BootVarMax]; PWSTR *BootVarComponents[BootVarMax]; DWORD LargestComponentCount; #define MAX_COMPONENTS 20 BOOL SetNvRamVar( IN PWSTR VarName, IN PWSTR VarValue ) { UNICODE_STRING VarNameU,VarValueU; NTSTATUS Status; BOOLEAN OldPriv,DontCare; // // Set up unicode strings. // RtlInitUnicodeString(&VarNameU ,VarName ); RtlInitUnicodeString(&VarValueU,VarValue); // // Make sure we have privilege to set nv-ram vars. // Note: ignore return value; if this fails then we'll catch // any problems when we actually try to set the var. // RtlAdjustPrivilege( SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE, FALSE, &OldPriv ); Status = NtSetSystemEnvironmentValue(&VarNameU,&VarValueU); // // Restore old privilege level. // RtlAdjustPrivilege( SE_SYSTEM_ENVIRONMENT_PRIVILEGE, OldPriv, FALSE, &DontCare ); return(NT_SUCCESS(Status)); } BOOL FChangeBootIniTimeout( IN INT Timeout ) { WCHAR TimeoutValue[24]; // // Form the timeout value. // wsprintfW(TimeoutValue,L"%u",Timeout); // // Set the vars // if(!SetNvRamVar(L"COUNTDOWN",TimeoutValue)) { return(FALSE); } return(SetNvRamVar(L"AUTOLOAD",L"YES")); } BOOL GetVarComponents( IN PWSTR VarValue, OUT PWSTR **Components, OUT PDWORD ComponentCount ) { PWSTR *components; DWORD componentCount; PWSTR p; PWSTR Var; PWSTR comp; DWORD len; components = SAlloc(MAX_COMPONENTS * sizeof(PWSTR)); if(!components) { return(FALSE); } for(Var=VarValue,componentCount=0; *Var; ) { // // Skip leading spaces. // while(iswspace(*Var)) { Var++; } if(*Var == 0) { break; } p = Var; while(*p && (*p != L';')) { p++; } len = (DWORD)((PUCHAR)p - (PUCHAR)Var); comp = SAlloc(len + sizeof(WCHAR)); if(!comp) { DWORD i; for(i=0; i<componentCount; i++) { SFree(components[i]); } SFree(components); return(FALSE); } len /= sizeof(WCHAR); wcsncpy(comp,Var,len); comp[len] = 0; components[componentCount] = comp; componentCount++; if(componentCount == MAX_COMPONENTS) { break; } Var = p; if(*Var) { Var++; // skip ; } } // // array is shrinking // *Components = SRealloc(components,componentCount*sizeof(PWSTR)); *ComponentCount = componentCount; return(TRUE); } BOOL DoRemoveWinntBootSet( VOID ) { DWORD set; DWORD var; WCHAR Buffer[2048]; BOOL rc; // // Find and remove any remnants of previously attempted // winnt32 runs. Such runs are identified by 'winnt32' // in their osloadoptions. // for(set=0; set<__min(LargestComponentCount,BootVarComponentCount[BootVarOsLoadOptions]); set++) { // // See if the os load options indicate that this is a winnt32 set. // if(!_wcsicmp(BootVarComponents[BootVarOsLoadOptions][set],L"WINNT32")) { // // Delete this boot set. // for(var=0; var<BootVarMax; var++) { if(set < BootVarComponentCount[var]) { SFree(BootVarComponents[var][set]); BootVarComponents[var][set] = NULL; } } } } // // Set each variable, constructing values by building up the // components into a semi-colon-delineated list. // rc = TRUE; for(var=0; var<BootVarMax; var++) { // // Clear out the buffer. // Buffer[0] = 0; // // Append all components that were not deleted. // for(set=0; set<BootVarComponentCount[var]; set++) { if(BootVarComponents[var][set]) { if(set) { wcscat(Buffer,L";"); } wcscat(Buffer,BootVarComponents[var][set]); // // Free the component, as we are done with it. // SFree(BootVarComponents[var][set]); BootVarComponents[var][set] = NULL; } } // // Write the var into nvram and return. // rc = rc && SetNvRamVar(BootVarNames[var],Buffer); // // Free array of components. // SFree(BootVarComponents[var]); BootVarComponents[var] = NULL; } return(rc); } BOOL RemoveWinntBootSet( VOID ) { DWORD var; UNICODE_STRING UnicodeString; NTSTATUS Status; BOOLEAN OldPriv,DontCare; WCHAR Buffer[1024]; BOOL b; // // Make sure we have privilege to get/set nvram vars. // RtlAdjustPrivilege( SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE, FALSE, &OldPriv ); // // Get boot vars and break into components. // for(var=0; var<BootVarMax; var++) { RtlInitUnicodeString(&UnicodeString,BootVarNames[var]); Status = NtQuerySystemEnvironmentValue( &UnicodeString, Buffer, sizeof(Buffer)/sizeof(WCHAR), NULL ); b = GetVarComponents( NT_SUCCESS(Status) ? Buffer : L"", &BootVarComponents[var], &BootVarComponentCount[var] ); if(!b) { return(FALSE); } // // Track the variable with the most number of components. // if(BootVarComponentCount[var] > LargestComponentCount) { LargestComponentCount = BootVarComponentCount[var]; } } b = DoRemoveWinntBootSet(); // // Restore previous privilege. // RtlAdjustPrivilege( SE_SYSTEM_ENVIRONMENT_PRIVILEGE, OldPriv, FALSE, &DontCare ); return(b); } #endif