|
|
#include "setupp.h"
#pragma hdrstop
#define INTL_ANSWER_FILE L"intl.txt"
#define INTL_LANG_SECTION L"regionalsettings"
#define INTL_LOCALE L"userlocale"
#define INTL_KEYBOARD L"inputlocale"
// This turns on some debug spew that lists all the available locales, geo
// locations, and keyboards.
#define INTL_LIST_OPTIONS 0
#define LANG_LIST_INCREMENT 10
POOBE_LOCALE_INFO LanguageList = NULL; DWORD LanguageListSize; DWORD LanguageIndex; DWORD DefaultID; DWORD DefaultIndex;
typedef struct tagPHONEENTRY { LPWSTR Country; LPWSTR TollFreeNumber; LPWSTR TollNumber; } PHONEENTRY, *PPHONEENTRY;
PWSTR PhoneList = NULL; DWORD PhoneListSize; DWORD PhoneListLength;
//
// Boolean value indicating whether we're doing a subset of gui-mode setup.
//
BOOL OobeSetup = FALSE;
//
// We need a global variable for OCM, coresponding to the local variable in
// InstallWindowsNT().
//
#ifdef _OCM
PVOID g_OcManagerContext; #endif
BOOL WINAPI SetupGetProductType( PWSTR Product, PDWORD pSkuFlags ) { Product[0] = 0; *pSkuFlags = 0; return TRUE; }
PID3_RESULT WINAPI SetupPidGen3( PWSTR Pid3, DWORD SkuFlags, PWSTR OemId, BOOL Batch, PWSTR Pid2, LPBYTE lpPid3, LPBOOL Compliance ) { if ( !InitializePidVariables() ) { SetupDebugPrint( L"SETUP: InitializePidVariables failed" ); return PID_INVALID; }
if ( !SetPid30Variables( Pid3 ) ) { SetupDebugPrint( L"SETUP: SetPid30Variables failed" ); return PID_INVALID; }
if ( !ValidateAndSetPid30() ) { SetupDebugPrint( L"SETUP: ValidateAndSetPid30 failed" ); return PID_INVALID; }
if(!SetProductIdInRegistry()) { SetupDebugPrint( L"SETUP: SetProductIdInRegistry failed" ); return PID_INVALID; }
return PID_VALID; }
BOOL WINAPI SetupGetValidEula( PCWSTR Eula, PWSTR Path ) { return TRUE; }
BOOL CheckLangListSize( DWORD StructSize ) { PVOID NewList;
//
// Check to make sure the LanguageList has at least 1 unused element.
// If not, make it bigger.
//
if ( LanguageIndex == LanguageListSize ) {
LanguageListSize *= 2; NewList = MyRealloc( LanguageList, LanguageListSize * StructSize );
if ( NewList ) { LanguageList = NewList; } else { return FALSE; } } return TRUE; }
VOID WINAPI SetupDestroyLanguageList( IN POOBE_LOCALE_INFO LanguageList, IN DWORD Count ) { DWORD i;
if ( LanguageList ) { for ( i=0; i < Count; i++ ) { if ( LanguageList + i ) { MyFree( LanguageList[i].Name ); } }
MyFree( LanguageList ); } }
BOOL CALLBACK EnumLocalesProc( PWSTR pszLocale ) { BOOL b; LCID Locale; TCHAR LanguageName[128]; POOBE_LOCALE_INFO pLocaleInfo;
Locale = wcstoul (pszLocale, NULL, 16);
b = GetLocaleInfo ( Locale, LOCALE_SLANGUAGE | LOCALE_NOUSEROVERRIDE, LanguageName, sizeof(LanguageName) / sizeof(TCHAR) ); MYASSERT(b); if ( !b ) { return FALSE; }
//
// Add it to our global array
//
if ( !CheckLangListSize( sizeof(OOBE_LOCALE_INFO) ) ) { SetupDestroyLanguageList( LanguageList, LanguageIndex ); LanguageList = NULL; return FALSE; } pLocaleInfo = (POOBE_LOCALE_INFO)LanguageList + LanguageIndex; pLocaleInfo->Name = MyMalloc( (lstrlen(LanguageName) + 1) * sizeof(TCHAR) ); if ( !pLocaleInfo->Name ) { SetupDestroyLanguageList( LanguageList, LanguageIndex ); LanguageList = NULL; return FALSE; }
lstrcpy( pLocaleInfo->Name, LanguageName ); pLocaleInfo->Id = Locale; pLocaleInfo->Installed = IsValidLocale( Locale, LCID_INSTALLED );
if ( Locale == DefaultID ) { DefaultIndex = LanguageIndex; }
LanguageIndex++;
return TRUE; }
int __cdecl LocaleCompare( const void *arg1, const void *arg2 ) { return lstrcmp( ((POOBE_LOCALE_INFO)arg1)->Name, ((POOBE_LOCALE_INFO)arg2)->Name ); }
BOOL WINAPI SetupGetLocaleOptions( IN DWORD OptionalDefault, OUT POOBE_LOCALE_INFO *ReturnList, OUT PDWORD Items, OUT PDWORD Default ) { BOOL bReturn = FALSE; DWORD i;
//
// Init our global variables
//
ASSERT_HEAP_IS_VALID(); *ReturnList = NULL;
MYASSERT( LanguageList == NULL ); LanguageListSize = LANG_LIST_INCREMENT; LanguageList = MyMalloc( LanguageListSize * sizeof(OOBE_LOCALE_INFO)); if ( !LanguageList ) { goto exit; } LanguageIndex = 0; DefaultID = OptionalDefault ? OptionalDefault : GetUserDefaultLCID(); DefaultIndex = 0;
EnumSystemLocales ( EnumLocalesProc , LCID_INSTALLED );
if ( LanguageList ) {
// Success
qsort( LanguageList, LanguageIndex, sizeof( OOBE_LOCALE_INFO ), LocaleCompare ); for (i=0; i<LanguageIndex; i++) { if (LanguageList[i].Id == DefaultID) { DefaultIndex = i; break; } }
#if INTL_LIST_OPTIONS
for (i=0; i<LanguageIndex; i++) { SetupDebugPrint2( L"Setup: SetupGetLocaleOptions|%x|%s", LanguageList[i].Id, LanguageList[i].Name );
} #endif
*ReturnList = LanguageList; LanguageList = NULL; *Items = LanguageIndex; *Default = DefaultIndex; bReturn = TRUE; }
exit: ASSERT_HEAP_IS_VALID(); return bReturn; }
BOOL CALLBACK EnumGeoInfoProc( GEOID GeoID ) { TCHAR pData[128]; POOBE_LOCALE_INFO pGeoInfo;
//
// Add it to our global array
//
if ( !CheckLangListSize( sizeof(OOBE_LOCALE_INFO) ) ) { SetupDestroyLanguageList( LanguageList, LanguageIndex ); LanguageList = NULL; return FALSE; }
if( !GetGeoInfo( GeoID, GEO_FRIENDLYNAME, pData, sizeof(pData) / sizeof(TCHAR), 0 )) {
// Skip this one.
MYASSERT(0); return TRUE; }
pGeoInfo = (POOBE_LOCALE_INFO)LanguageList + LanguageIndex; pGeoInfo->Name = MyMalloc( (lstrlen(pData) + 1) * sizeof(TCHAR) ); if ( !pGeoInfo->Name ) { SetupDestroyLanguageList( LanguageList, LanguageIndex ); LanguageList = NULL; return FALSE; }
lstrcpy( pGeoInfo->Name, pData ); pGeoInfo->Id = GeoID; pGeoInfo->Installed = TRUE;
if ( GeoID == (GEOID)DefaultID ) { DefaultIndex = LanguageIndex; } LanguageIndex++;
return TRUE; }
BOOL WINAPI SetupGetGeoOptions( IN DWORD OptionalDefault, OUT POOBE_LOCALE_INFO *ReturnList, OUT PDWORD Items, OUT PDWORD Default ) { BOOL bReturn = FALSE; DWORD i;
//
// Init our global variables
//
ASSERT_HEAP_IS_VALID(); *ReturnList = NULL;
MYASSERT( LanguageList == NULL ); LanguageListSize = LANG_LIST_INCREMENT; LanguageList = MyMalloc( LanguageListSize * sizeof(OOBE_LOCALE_INFO)); if ( !LanguageList ) { goto exit; } LanguageIndex = 0; DefaultID = OptionalDefault ? OptionalDefault : GetUserGeoID( GEOCLASS_NATION ); DefaultIndex = 0;
bReturn = EnumSystemGeoID( GEOCLASS_NATION, 0, EnumGeoInfoProc ); MYASSERT(bReturn);
if ( bReturn && LanguageList ) { // Success
qsort( LanguageList, LanguageIndex, sizeof( OOBE_LOCALE_INFO ), LocaleCompare ); for (i=0; i<LanguageIndex; i++) { if (LanguageList[i].Id == DefaultID) { DefaultIndex = i; break; } } #if INTL_LIST_OPTIONS
for (i=0; i<LanguageIndex; i++) { SetupDebugPrint2( L"Setup: SetupGetGeoOptions|%d|%s", LanguageList[i].Id, LanguageList[i].Name ); } #endif
bReturn = TRUE; *ReturnList = LanguageList; LanguageList = NULL; *Items = LanguageIndex; *Default = DefaultIndex; }
exit: ASSERT_HEAP_IS_VALID(); return bReturn; }
BOOL WINAPI SetupGetKeyboardOptions( IN DWORD OptionalDefault, OUT POOBE_LOCALE_INFO *ReturnList, OUT PDWORD Items, OUT PDWORD Default ) { DWORD DefaultKeyboard; DWORD i; BOOL bReturn = FALSE; TCHAR pData[128]; TCHAR Substitute[9]; POOBE_LOCALE_INFO pLocaleInfo; DWORD rc; HKEY hLangKey = NULL; HKEY hLangSubKey = NULL; DWORD Index; TCHAR SubKeyName[9]; DWORD SubKeyNameLength; DWORD DataSize; DWORD Type;
//
// Initialize our variables
//
ASSERT_HEAP_IS_VALID(); *ReturnList = NULL;
MYASSERT( LanguageList == NULL ); LanguageListSize = LANG_LIST_INCREMENT; LanguageList = MyMalloc( LanguageListSize * sizeof(OOBE_LOCALE_INFO)); if ( !LanguageList ) { goto exit; } LanguageIndex = 0; // DefaultIndex = -1;
*Default = 0;
if (OptionalDefault) { DefaultKeyboard = OptionalDefault;
} else { //
// Lookup default keyboard in the registry
//
rc = RegOpenKeyEx( HKEY_USERS, L".DEFAULT\\Keyboard Layout\\Preload", 0, KEY_READ, &hLangKey ); if( rc != NO_ERROR ) { SetupDebugPrint1( L"Setup: SetupGetKeyboardOptions - RegOpenKeyEx(.DEFAULT\\Keyboard Layout\\Preload) failed (%d)", rc ); MYASSERT(0); goto exit; }
DataSize = sizeof(pData); rc = RegQueryValueEx( hLangKey, L"1", NULL, &Type, (LPBYTE)pData, &DataSize ); RegCloseKey( hLangKey ); hLangKey = NULL;
if( rc != NO_ERROR ) { SetupDebugPrint1( L"Setup: SetupGetKeyboardOptions - RegQueryValueEx(1) failed (%d)", rc ); MYASSERT(0); goto exit; }
DefaultKeyboard = wcstoul( pData, NULL, 16 );
//
// Now we look in the Substitutes key to see whether there is a
// substitute there.
//
if( RegOpenKeyEx( HKEY_USERS, L".DEFAULT\\Keyboard Layout\\Substitutes", 0, KEY_READ, &hLangKey ) == NO_ERROR) {
DataSize = sizeof(Substitute); if( (RegQueryValueEx( hLangKey, pData, NULL, &Type, (LPBYTE)Substitute, &DataSize ) == NO_ERROR) && (Type == REG_SZ) ) {
DefaultKeyboard = wcstoul( Substitute, NULL, 16 ); }
RegCloseKey(hLangKey); hLangKey = NULL; } }
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Keyboard Layouts", 0, KEY_ENUMERATE_SUB_KEYS | KEY_READ, &hLangKey ); if( rc != NO_ERROR ) { SetupDebugPrint1( L"Setup: SetupGetKeyboardOptions - RegOpenKeyEx(System\\CurrentControlSet\\Control\\Keyboard Layouts) failed (%d)", rc ); goto exit; }
for( Index = 0; ; Index++ ) {
SubKeyNameLength = sizeof(SubKeyName) / sizeof(TCHAR);
rc = RegEnumKeyEx( hLangKey, Index, SubKeyName, &SubKeyNameLength, NULL, NULL, NULL, NULL );
//
// Did we error?
//
if( rc != ERROR_SUCCESS ) {
//
// Are we done?
//
if( rc != ERROR_NO_MORE_ITEMS ) { SetupDebugPrint2( L"Setup: SetupGetKeyboardOptions - RegEnumKeyEx failed (%d). Index = %d", rc, Index ); MYASSERT(0); } break; }
rc = RegOpenKeyEx( hLangKey, SubKeyName, 0, KEY_READ, &hLangSubKey ); if( rc != NO_ERROR ) { SetupDebugPrint2( L"Setup: SetupGetKeyboardOptions - RegOpenKeyEx(%s) failed (%d)", SubKeyName, rc ); MYASSERT(0); continue; }
DataSize = sizeof(pData); rc = RegQueryValueEx( hLangSubKey, L"Layout Text", NULL, &Type, (LPBYTE)pData, &DataSize ); RegCloseKey( hLangSubKey ); hLangSubKey = NULL;
if( rc != NO_ERROR ) { SetupDebugPrint2( L"Setup: SetupGetKeyboardOptions - RegQueryValueEx(Layout Text) for %s failed (%d)", SubKeyName, rc ); continue; }
//
// Add it to our global array
//
if ( !CheckLangListSize( sizeof(OOBE_LOCALE_INFO) ) ) { SetupDestroyLanguageList( LanguageList, LanguageIndex ); LanguageList = NULL; goto exit; } pLocaleInfo = (POOBE_LOCALE_INFO)LanguageList + LanguageIndex; pLocaleInfo->Name = MyMalloc( (lstrlen(pData) + 1) * sizeof(TCHAR) ); if ( !pLocaleInfo->Name ) { SetupDestroyLanguageList( LanguageList, LanguageIndex ); LanguageList = NULL; goto exit; }
lstrcpy( pLocaleInfo->Name, pData ); pLocaleInfo->Id = wcstoul( SubKeyName, NULL, 16 ); pLocaleInfo->Installed = TRUE;
LanguageIndex++; }
RegCloseKey( hLangKey ); hLangKey = NULL;
qsort( LanguageList, LanguageIndex, sizeof( OOBE_LOCALE_INFO ), LocaleCompare ); for (i=0; i<LanguageIndex; i++) { if (LanguageList[i].Id == DefaultKeyboard) { *Default = i; break; } }
#if INTL_LIST_OPTIONS
for (i=0; i<LanguageIndex; i++) { SetupDebugPrint2( L"Setup: SetupGetKeyboardOptions|%x|%s", LanguageList[i].Id, LanguageList[i].Name ); } #endif
bReturn = TRUE; *ReturnList = LanguageList; LanguageList = NULL; *Items = LanguageIndex;
exit: if ( hLangKey ) { RegCloseKey( hLangKey ); } if ( hLangSubKey ) { RegCloseKey( hLangSubKey ); } ASSERT_HEAP_IS_VALID(); return bReturn; }
BOOL WINAPI SetupSetIntlOptions( DWORD LocationIndex, DWORD LanguageIndex, DWORD KeyboardIndex ) { WCHAR PathBuffer[MAX_PATH]; WCHAR KeyValue[128]; WCHAR CmdLine[MAX_PATH]; BOOL bResult;
SetupDebugPrint3( L"SetupSetIntlOptions: Location = %d, Language = 0x%08x, Keyboard = 0x%08x", LocationIndex, LanguageIndex, KeyboardIndex ); GetSystemDirectory( PathBuffer, MAX_PATH ); pSetupConcatenatePaths( PathBuffer, INTL_ANSWER_FILE, MAX_PATH, NULL ); DeleteFile( PathBuffer );
//
// Write language value
//
wsprintf( KeyValue, L"\"%08x\"", LanguageIndex );
WritePrivateProfileString( INTL_LANG_SECTION, INTL_LOCALE, KeyValue, PathBuffer );
//
// Write keyboard value
//
wsprintf( KeyValue, L"\"%04x:%08x\"", KeyboardIndex & 0x0000ffff, KeyboardIndex );
WritePrivateProfileString( INTL_LANG_SECTION, INTL_KEYBOARD, KeyValue, PathBuffer );
//
// Call intl.cpl to do the work
//
wsprintf( CmdLine, L"/f:\"%s\" /s:\"%s\"", PathBuffer, LegacySourcePath );
InvokeControlPanelApplet(L"intl.cpl",L"",0,CmdLine); DeleteFile( PathBuffer );
//
// Set the GEO location
//
bResult = SetUserGeoID( LocationIndex );
if ( !bResult ) {
SetupDebugPrint1( L"SetupSetIntlOptions: SetUserGeoID failed. Status = %d.", GetLastError() ); } MYASSERT( bResult );
return bResult; }
//+---------------------------------------------------------------------------
//
// Function: CompareCntryNameLookUpElements()
//
// Synopsis: Function to compare names used by sort
//
//+---------------------------------------------------------------------------
int __cdecl ComparePhoneEntry(const void *e1, const void *e2) { PPHONEENTRY pPhone1 = (PPHONEENTRY)e1; PPHONEENTRY pPhone2 = (PPHONEENTRY)e2;
return CompareStringW(LOCALE_USER_DEFAULT, 0, pPhone1->Country, -1, pPhone2->Country, -1 ) - 2; }
VOID WINAPI SetupDestroyPhoneList( ) { if ( PhoneList ) { MyFree( PhoneList ); } PhoneList = NULL; }
VOID WINAPI SetupFreePhoneList(PPHONEENTRY PhoneList, DWORD cbEntries) { DWORD i; if ( PhoneList ) { for( i=0; i < cbEntries; i++ ) { if (PhoneList[i].Country) { GlobalFree(PhoneList[i].Country); } if (PhoneList[i].TollFreeNumber) { GlobalFree(PhoneList[i].TollFreeNumber); } if (PhoneList[i].TollNumber) { GlobalFree(PhoneList[i].TollNumber); } } GlobalFree(PhoneList); } PhoneList = NULL; }
BOOL AddToPhoneList( LPCWSTR Item ) { PVOID NewList; DWORD ItemLength = lstrlen(Item);
if ( !PhoneList ) {
PhoneListLength = 0; PhoneListSize = 1024; PhoneList = MyMalloc( PhoneListSize * sizeof(TCHAR) ); if (!PhoneList) { return FALSE; }
} else if ( PhoneListLength + ItemLength > PhoneListSize ) {
PhoneListSize *= 2; NewList = MyRealloc( PhoneList, PhoneListSize * sizeof(TCHAR) );
if ( NewList ) { PhoneList = NewList; } else { MyFree(PhoneList); return FALSE; } }
memcpy( PhoneList + PhoneListLength, Item, ItemLength * sizeof(TCHAR) );
PhoneListLength += ItemLength;
return TRUE; }
BOOL MakePhoneListForScript(PPHONEENTRY PhoneList, DWORD cbEntries) { BOOL bRet = FALSE; DWORD i; if ( PhoneList ) { for( i=0; i < cbEntries; i++ ) { if (!AddToPhoneList(PhoneList[i].Country) || !AddToPhoneList( TEXT("\t") ) || !AddToPhoneList(PhoneList[i].TollFreeNumber) || !AddToPhoneList( TEXT("\t") ) || !AddToPhoneList(PhoneList[i].TollNumber) || !AddToPhoneList( TEXT("\t") ) ) { goto ExitMakePhoneListForScript; } } bRet = TRUE; } ExitMakePhoneListForScript: return bRet; }
BOOL AddItemToPhoneEntry(LPCWSTR Item, LPWSTR *pPointer) { BOOL bRet = FALSE; if ((Item) && (pPointer)) { *pPointer = (LPWSTR)GlobalAlloc(GPTR, (lstrlen(Item) + 1)*sizeof(TCHAR)); if (*pPointer) { lstrcpy(*pPointer, Item); bRet = TRUE; } } return bRet; }
PTSTR WINAPI SetupReadPhoneList( PWSTR PhoneInfName ) { HINF PhoneInf = NULL; DWORD LineCount; DWORD ItemNo; LPCTSTR SectionName; INFCONTEXT InfContext; BOOL bSucceeded = FALSE; PPHONEENTRY pPhoneList = NULL;
SetupDebugPrint( L"START: SetupReadPhoneList"); PhoneList = NULL;
PhoneInf = SetupOpenInfFile( PhoneInfName, NULL, INF_STYLE_WIN4, NULL ); if( PhoneInf == INVALID_HANDLE_VALUE ) { return NULL; }
SectionName = TEXT("IsoCodes"); LineCount = SetupGetLineCount( PhoneInf, SectionName ); if ( !LineCount ) {
goto ReadPhoneListCleanup; }
pPhoneList = (PPHONEENTRY)GlobalAlloc(GPTR, (int)(sizeof(PHONEENTRY) * LineCount));
if (!pPhoneList ) { goto ReadPhoneListCleanup; } ZeroMemory( pPhoneList, sizeof(PHONEENTRY) * LineCount );
for( ItemNo=0; ItemNo<LineCount; ItemNo++ ) { if( SetupGetLineByIndex( PhoneInf, SectionName, ItemNo, &InfContext )) {
if ( !AddItemToPhoneEntry( pSetupGetField( &InfContext, 4 ), &pPhoneList[ItemNo].Country ) ) {
goto ReadPhoneListCleanup; } if ( !AddItemToPhoneEntry( pSetupGetField( &InfContext, 5 ), &pPhoneList[ItemNo].TollFreeNumber ) ) {
goto ReadPhoneListCleanup; } if ( !AddItemToPhoneEntry( pSetupGetField( &InfContext, 6 ), &pPhoneList[ItemNo].TollNumber ) ) {
goto ReadPhoneListCleanup; } } }
// sort the array
qsort(pPhoneList, (int)LineCount,sizeof(PHONEENTRY), ComparePhoneEntry);
// Convert the array into a TAB delimited list for script.
if (MakePhoneListForScript(pPhoneList,LineCount)) { //
// Replace the final TAB with a NUL.
//
PhoneList[PhoneListLength-1] = '\0';
bSucceeded = TRUE; }
ReadPhoneListCleanup:
if (pPhoneList) { SetupFreePhoneList(pPhoneList,LineCount); } SetupCloseInfFile( PhoneInf );
SetupDebugPrint( L"END: SetupReadPhoneList"); if ( bSucceeded ) { return PhoneList; } else { SetupDestroyPhoneList(); return NULL; } }
//
// Read INF to map a TAPI country id to a 3 letter ISO code.
//
VOID SetupMapTapiToIso ( IN PWSTR PhoneInfName, IN DWORD dwCountryID, OUT PWSTR szIsoCode ) { HINF PhoneInf; WCHAR szCountryID[9]; BOOL bResult; INFCONTEXT Context;
szIsoCode[0] = L'\0'; PhoneInf = SetupOpenInfFile( PhoneInfName, NULL, INF_STYLE_WIN4, NULL ); if( PhoneInf == INVALID_HANDLE_VALUE ) { return; }
wsprintf ( szCountryID, L"%d", dwCountryID);
bResult = SetupFindFirstLine ( PhoneInf, L"TapiCodes", szCountryID, &Context );
if (bResult) { SetupGetStringField ( &Context, 1, szIsoCode, 4, NULL ); SetupDebugPrint2 ( L"SetupMapTapiToIso: %d mapped to %s", dwCountryID, szIsoCode ); }
SetupCloseInfFile( PhoneInf ); }
BOOL WINAPI SetupGetSetupInfo( PWSTR Name, OPTIONAL DWORD cbName, PWSTR Org, OPTIONAL DWORD cbOrg, PWSTR OemId, OPTIONAL DWORD cbOemId, LPBOOL IntlSet OPTIONAL ) { BOOL b = TRUE; HKEY hkey = NULL; DWORD Size; DWORD Type;
//
// Open the key if we need it
//
if( (Name || Org) && RegOpenKeyEx(HKEY_LOCAL_MACHINE,WinntSoftwareKeyName,0, KEY_QUERY_VALUE,&hkey) != NO_ERROR) {
return FALSE; }
//
// Get Name
//
if (Name) { Size = cbName; if((RegQueryValueEx(hkey,szRegisteredOwner,NULL,&Type, (LPBYTE)Name,&Size) != NO_ERROR) || (Type != REG_SZ) ) {
b = FALSE; } }
//
// Get Org
//
if (Org) { Size = cbOrg; if((RegQueryValueEx(hkey,szRegisteredOrganization,NULL,&Type, (LPBYTE)Org,&Size) != NO_ERROR) || (Type != REG_SZ) ) {
b = FALSE; } }
// TBD: figure out what this is for
if (OemId) { OemId[0] = 0; cbOemId = 0; }
//
// Note: IntlSet is not used currently
//
if (hkey) { RegCloseKey(hkey); } return b; }
BOOL WINAPI SetupSetSetupInfo( PCWSTR Name, PCWSTR Org ) { BOOL b;
b = StoreNameOrgInRegistry( (PWSTR)Name, (PWSTR)Org ); return b; }
BOOL WINAPI SetupSetAdminPassword( PCWSTR OldPassword, PCWSTR NewPassword ) { WCHAR AdminName[MAX_USERNAME+1]; BOOL Status;
GetAdminAccountName( AdminName ); Status = SetLocalUserPassword( AdminName, OldPassword, NewPassword );
if ( !Status ) { SetupDebugPrint( L"SetupSetAdminPassword: SetLocalUserPassword failed."); }
return Status; }
VOID WINAPI SetupOobeInitDebugLog( ) { //
// Do no UI. Note that we must set OobeSetup before our first call to
// SetupDebugPrint.
//
OobeSetup = TRUE; SetupDebugPrint( L"SetupOobeInitDebugLog" ); }
// Run initialization that is known not to requires services to run.
//
VOID WINAPI SetupOobeInitPreServices( IN BOOL DoMiniSetupStuff ) { //
// Turn off logging.
//
// IsSetup = FALSE;
SetupDebugPrint( L"SetupOobeInitPreServices" );
if ( DoMiniSetupStuff ) { //
// Act like the miniwizard (except with no UI)
//
MiniSetup = TRUE; Preinstall = TRUE;
//
// Tell SetupAPI not to bother backing up files and not to verify
// that any INFs are digitally signed.
//
pSetupSetGlobalFlags(pSetupGetGlobalFlags()|PSPGF_NO_BACKUP|PSPGF_NO_VERIFY_INF);
CommonInitialization();
SetUpDataBlock(); InternalSetupData.CallSpecificData1 = 0;
#if 0
//
// We aren't going to do this for rev 1.
//
if( PnPReEnumeration ) { //
// The user wants us to do PnP re-enumeration.
// Go do it.
//
InstallPnpDevices( hdlg, SyssetupInf, GetDlgItem(hdlg,IDC_PROGRESS1), StartAtPercent, StopAtPercent ); } #endif
} else { // DoMiniSetupStuff
//
// Get handle to heap so we can periodically validate it.
//
#if DBG
g_hSysSetupHeap = GetProcessHeap(); #endif
} }
// Run initialization that may or does require services.
//
VOID WINAPI SetupOobeInitPostServices( IN BOOL DoMiniSetupStuff ) { InitializeExternalModules( DoMiniSetupStuff, &g_OcManagerContext ); }
VOID WINAPI SetupOobeCleanup( IN BOOL DoMiniSetupStuff ) { static FINISH_THREAD_PARAMS Context;
SetupDebugPrint( L"SetupOobeCleanup" );
if ( DoMiniSetupStuff ) {
RestoreBootTimeout();
Context.ThreadId = GetCurrentThreadId(); Context.OcManagerContext = g_OcManagerContext; FinishThread( &Context ); } }
// Resets the activation days (allowed 3 times only)
//
DWORD SetupReArmWPA( VOID ) { LPCSTR lpszReArmInterface = (LPCSTR)124; typedef HRESULT (WINAPI* lpReArmEntryPoint) (); HMODULE hRearmdll = NULL; DWORD dwError = ERROR_SUCCESS; hRearmdll = LoadLibraryA("licdll.dll");
if (hRearmdll) { lpReArmEntryPoint pReArmEntry = (lpReArmEntryPoint) GetProcAddress(hRearmdll,lpszReArmInterface);
if (pReArmEntry) { //
// ValidateDigitalPid returns zero if success, otherwise its custom error code
//
HRESULT hr = (*pReArmEntry )();
if (FAILED(hr)) { // If PID cannot be validated we should force activation/PID reentry.
SetupDebugPrint1(L"SETUP: Rollback WPA failed! HRESULT=%ld", hr); dwError = (DWORD)hr; } else SetupDebugPrint(L"SETUP: Rollback WPA succeeded."); } else { SetupDebugPrint(L"SETUP: Failed to get WPA entry point!"); dwError = ERROR_INVALID_FUNCTION; } FreeLibrary (hRearmdll); } else { SetupDebugPrint(L"SETUP: Failed to load WPA library!"); dwError = ERROR_FILE_NOT_FOUND; }
// Return error code or success
//
return dwError; }
// Once Windows is activated the Activate Windows shortcut is removed by msoobe.exe /a.
// If OEMs sysprep a machine they will need to re-activate Windows and the shortcut
// needs to be restored. Msoobe.exe cannot restore it because it does not
// run in server skus.
//
DWORD SetupRestoreWPAShortcuts( VOID ) { DWORD dwError = ERROR_SUCCESS; HINF hinf; hinf = SetupOpenInfFile(L"syssetup.inf",NULL,INF_STYLE_WIN4,NULL); if(hinf != INVALID_HANDLE_VALUE) { if (SetupInstallFromInfSection(NULL, hinf, L"RESTORE_OOBE_ACTIVATE", SPINST_PROFILEITEMS , //SPINST_ALL,
NULL, NULL, 0, NULL, NULL, NULL, NULL) != 0) { // Success
SetupDebugPrint(L"SETUP: Restore Activation shortcut succeeded"); } else { // Failure
dwError = GetLastError(); SetupDebugPrint1(L"SETUP: Restore Activation shortcut failed. GetLastError=%ld",dwError); } SetupCloseInfFile(hinf); } else { dwError = GetLastError(); SetupDebugPrint1(L"SETUP: Restore Activation shortcut failed to open syssetup.inf. GetLastError=%ld",dwError); }
return dwError; }
BOOL Activationrequired(VOID);
// Rollback the activation days and put back the activate windows shortcut(s). X86 only.
//
DWORD WINAPI SetupOobeBnk( LPBYTE pDummy ) { DWORD dwError = ERROR_SUCCESS;
// Return if we failed to rollback so we don'put the shortcut back
// On volume license skus this always returns successful
//
if (ERROR_SUCCESS != (dwError = SetupReArmWPA())) return dwError;
// If not activated, restore the shortcuts, or if we don't
// require activation (for volume license skus)
//
if (Activationrequired()) { // Restore the Activate Windows shortcut(s)
//
dwError = SetupRestoreWPAShortcuts(); } return dwError; }
static LPTSTR NextNumber( LPTSTR lpString, BOOL bSkipFirst ) { // The first time we just want to walk past any non-numbers,
// we don't want to skip any numbers if they are right at the
// begining of the string.
//
if ( bSkipFirst ) { // Walk past the first number in the string.
//
while ( ( *lpString >= _T('0') ) && ( *lpString <= _T('9') ) ) { lpString++; } }
// Now walk till we get to the next number or we reach the end.
//
while ( ( *lpString ) && ( ( *lpString < _T('0') ) || ( *lpString > _T('9') ) ) ) { lpString++; }
return lpString; }
BOOL WINAPI SetupSetDisplay( LPCTSTR lpszUnattend, LPCTSTR lpszSection, LPCTSTR lpszResolutionKey, LPCTSTR lpszRefreshKey, DWORD dwMinWidth, DWORD dwMinHeight, DWORD dwMinBits ) { DEVMODE devmode; DWORD dwVal; TCHAR szText[256]; LPTSTR lpDisplay; BOOL bRet = TRUE;
ZeroMemory(&devmode, sizeof(DEVMODE)); devmode.dmSize = sizeof(DEVMODE);
// Check the current resolution, make sure it meets our mins.
//
if ( EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, &devmode) ) { if ( devmode.dmPelsWidth < dwMinWidth ) { devmode.dmPelsWidth = dwMinWidth; devmode.dmFields |= DM_PELSWIDTH; }
if ( devmode.dmPelsHeight < dwMinHeight ) { devmode.dmPelsHeight = dwMinHeight; devmode.dmFields |= DM_PELSHEIGHT; }
if ( devmode.dmBitsPerPel < dwMinBits ) { devmode.dmBitsPerPel = dwMinBits; devmode.dmFields |= DM_BITSPERPEL; } }
// Make sure they passed in an unattend and section to look in.
//
if ( lpszUnattend && *lpszUnattend && lpszSection && *lpszSection ) { // Now check in the winbom to see if they want to change the current resolution.
//
szText[0] = _T('\0'); if ( ( lpszResolutionKey ) && ( *lpszResolutionKey ) && ( GetPrivateProfileString(lpszSection, lpszResolutionKey, _T(""), szText, sizeof(szText) / sizeof(szText[0]), lpszUnattend) ) && ( szText[0] ) ) { bRet = FALSE;
lpDisplay = NextNumber(szText, FALSE); if ( dwVal = (DWORD) _ttoi(lpDisplay) ) { devmode.dmFields |= DM_PELSWIDTH; devmode.dmPelsWidth = dwVal; }
lpDisplay = NextNumber(lpDisplay, TRUE); if ( dwVal = (DWORD) _ttoi(lpDisplay) ) { devmode.dmFields |= DM_PELSHEIGHT; devmode.dmPelsHeight = dwVal; }
lpDisplay = NextNumber(lpDisplay, TRUE); if ( dwVal = (DWORD) _ttoi(lpDisplay) ) { devmode.dmFields |= DM_BITSPERPEL; devmode.dmBitsPerPel = dwVal; } }
// Now check in the winbom to see if they want to change the default refresh rate.
//
szText[0] = _T('\0'); if ( ( lpszRefreshKey ) && ( *lpszRefreshKey ) && ( GetPrivateProfileString(lpszSection, lpszRefreshKey, _T(""), szText, sizeof(szText) / sizeof(szText[0]), lpszUnattend) ) && ( szText[0] ) ) { bRet = FALSE;
if ( dwVal = (DWORD) _ttoi(szText) ) { devmode.dmFields |= DM_DISPLAYFREQUENCY; devmode.dmDisplayFrequency = dwVal; } } }
// If we have anything to change, change it now.
//
if ( devmode.dmFields ) { DWORD dwRet = ChangeDisplaySettings(&devmode, CDS_UPDATEREGISTRY | CDS_GLOBAL);
switch ( dwRet ) { case DISP_CHANGE_SUCCESSFUL: case DISP_CHANGE_RESTART: bRet = TRUE; break;
//case DISP_CHANGE_BADFLAGS:
//case DISP_CHANGE_BADPARAM:
//case DISP_CHANGE_FAILED:
//case DISP_CHANGE_BADMODE
//case DISP_CHANGE_NOTUPDATED:
//bRet = FALSE;
} }
return bRet; }
typedef struct _OEM_FINISH_APPS { LPTSTR szApp; LPTSTR szArgs; } OEM_FINISH_APPS;
OEM_FINISH_APPS OEM_Finish_Apps[] = { { L"Rundll32.exe", L"fldrclnr.dll,Wizard_RunDLL silent"}, { NULL, NULL} // End of list.
};
void RunOEMExtraTasks() { LPTSTR pApp = NULL; LPTSTR pArgs = NULL; DWORD dwSize; DWORD dwCode; int i;
BEGIN_SECTION(L"RunOEMExtraTasks"); i = 0; while (OEM_Finish_Apps[i].szApp != NULL) { // Get the size we need to the expanded app
dwSize = ExpandEnvironmentStrings( OEM_Finish_Apps[i].szApp , NULL, 0); if (dwSize) { pApp = (LPTSTR)GlobalAlloc(GPTR, sizeof(TCHAR) * dwSize); if (pApp) { ExpandEnvironmentStrings( OEM_Finish_Apps[i].szApp , pApp, dwSize);
if (OEM_Finish_Apps[i].szArgs) { // Get the size we need to the expanded arguments
dwSize = ExpandEnvironmentStrings( OEM_Finish_Apps[i].szArgs , NULL, 0); if (dwSize) { pArgs = (LPTSTR)GlobalAlloc(GPTR, sizeof(TCHAR) * dwSize); if (pArgs) { ExpandEnvironmentStrings( OEM_Finish_Apps[i].szArgs, pArgs, dwSize); } } } // Log what we will start
if (pArgs) { SetupDebugPrint2(L"Start command :%s: with arguments :%s:", pApp, pArgs); } else { SetupDebugPrint1(L"Start command :%s: with no arguments", pApp); }
// Start the app.
dwCode = 0; if (pArgs) { InvokeExternalApplicationEx(pApp, pArgs, &dwCode, INFINITE, TRUE); } else { // If we don't have args. the first parameter is NULL
InvokeExternalApplicationEx(NULL, pApp, &dwCode, INFINITE, TRUE); } } } if (pApp) { GlobalFree(pApp); pApp = NULL; } if (pArgs) { GlobalFree(pArgs); pArgs = NULL; } i++; } END_SECTION(L"RunOEMExtraTasks"); }
static BOOL SetupCheckRegValue( IN HKEY hKey, IN LPTSTR lpszValueName, IN DWORD dwCompareValue ) { BOOL fRet = FALSE; DWORD dwData = 0, dwType, cbSize = sizeof(dwData);
if ( ( ERROR_SUCCESS == RegQueryValueEx( hKey, lpszValueName, 0, &dwType, (LPBYTE) &dwData, &cbSize ) ) && ( REG_DWORD == dwType) && ( dwData == dwCompareValue ) ) { fRet = TRUE; }
return fRet; }
BOOL SetupGetInstallMode( OUT LPDWORD lpdwMode, OUT LPDWORD lpdwFlags ) { BOOL fRet = FALSE; HKEY hKeySetup;
//
// Make sure the caller is actually checking for something.
//
if ( lpdwMode || lpdwFlags ) { //
// Also make sure we can open the "HKLM\System\Setup" key.
//
if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("System\\Setup"), 0, KEY_READ, &hKeySetup ) ) { DWORD dwMode = SETUP_MODE_NONE, dwFlags = 0; BOOL fSetup, fOobe, fAudit, fMini, fFactory;
//
// Check all of the registry values we might care about...
//
fSetup = SetupCheckRegValue( hKeySetup, TEXT("SystemSetupInProgress"), 1 ); fOobe = SetupCheckRegValue( hKeySetup, TEXT("OobeInProgress"), 1 ); fAudit = SetupCheckRegValue( hKeySetup, TEXT("AuditInProgress"), 1 ); fMini = SetupCheckRegValue( hKeySetup, TEXT("MiniSetupInProgress"), 1 ); fFactory = SetupCheckRegValue( hKeySetup, TEXT("FactoryPreInstallInProgress"), 1 );
//
// We are in OOBE if the OobeInProgress value is non-zero...
//
if ( fOobe ) { dwMode = SETUP_MODE_OOBE; if ( fMini ) { dwFlags |= SETUP_FLAG_OEM; } } else { //
// We are in MiniSetup if the MiniSetupInProgress value is non-zero...
//
if ( fMini ) { dwMode = SETUP_MODE_MINI; dwFlags |= SETUP_FLAG_OEM; } else { //
// We are in Audit mode if the AuditInProgress value is non-zero...
//
if ( fAudit ) { dwMode = SETUP_MODE_AUDIT; dwFlags |= (SETUP_FLAG_OEM | SETUP_FLAG_UNATTENDED);
//
// If the FactoryPreInstallInProgress flag is non-zero, then we are delaying PNP...
//
if ( fFactory ) { dwFlags |= SETUP_FLAG_DELAYPNP; } } else { //
// We are in Setup if the SystemSetupInProgress and SetupType values are non-zero...
//
if ( fSetup ) { dwMode = SETUP_MODE_SETUP; } } } }
//
// Now put our values into the caller's buffers...
//
if ( lpdwMode ) { *lpdwMode = dwMode; }
if ( lpdwFlags ) { *lpdwFlags = dwFlags; }
//
// We were able to open the Setup key... so return TRUE.
//
fRet = TRUE;
//
// We're done, so close the Setup key.
//
RegCloseKey( hKeySetup ); } }
return fRet; }
|