mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2527 lines
65 KiB
2527 lines
65 KiB
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
#if INIT_REGISTRY
|
|
|
|
VOID
|
|
TmppSetUnsecureDefaultDacl( VOID );
|
|
|
|
PGLOBALS pLocalGlobals;
|
|
|
|
BOOL RunNetDetect = 0;
|
|
BOOL ExtendedNetSetup = FALSE;
|
|
BOOL NetSetupGoingToRun = FALSE;
|
|
BOOL NetFound = FALSE;
|
|
BOOL KeepScript = FALSE;
|
|
char WinlogonSystemVariable[ 1024 ];
|
|
PCHAR WinlogonShellVariable = NULL;
|
|
|
|
char InputFileName[ MAX_PATH ];
|
|
FILE *fh;
|
|
char LineBuffer[ 1024 ];
|
|
int LineIndent;
|
|
int LineNumber;
|
|
|
|
char MessageBuffer[ 512 ];
|
|
char AnsiWinlogon[] = "Winlogon";
|
|
WCHAR WideWinlogon[] = L"Winlogon";
|
|
|
|
BOOL
|
|
DeclareError(
|
|
char *Format,
|
|
...
|
|
);
|
|
|
|
BOOL
|
|
DeclareError(
|
|
char *Format,
|
|
...
|
|
)
|
|
{
|
|
char *s;
|
|
size_t cb;
|
|
va_list arglist;
|
|
|
|
va_start(arglist, Format);
|
|
|
|
cb = _snprintf( MessageBuffer,
|
|
sizeof( MessageBuffer ),
|
|
"Winlogon: %s(%u)",
|
|
InputFileName,
|
|
LineNumber
|
|
);
|
|
s = MessageBuffer + cb;
|
|
*s++ = '\0';
|
|
cb = sizeof( MessageBuffer ) - cb;
|
|
|
|
_vsnprintf( s, cb, Format, arglist );
|
|
|
|
#if DBG
|
|
DebugLog((DEB_TRACE_SETUP, "%s\n", s ));
|
|
#endif
|
|
|
|
if (MessageBoxA( NULL, s, MessageBuffer, MB_OKCANCEL | MB_SETFOREGROUND )) {
|
|
return TRUE;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
GetLine( void )
|
|
{
|
|
char *s, *s1;
|
|
|
|
while (TRUE) {
|
|
s = fgets( LineBuffer, sizeof( LineBuffer ), fh );
|
|
if (s == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
LineNumber++;
|
|
if (s1 = strchr( s, '\r' )) {
|
|
*s1 = '\0';
|
|
}
|
|
else
|
|
if (s1 = strchr( s, '\n' )) {
|
|
*s1 = '\0';
|
|
}
|
|
else {
|
|
s1 = strchr( s, '\0' );
|
|
}
|
|
while (s1 > s && *--s1 <= ' ') {
|
|
*s1 = '\0';
|
|
}
|
|
|
|
while (*s && (*s <= ' ')) {
|
|
s++;
|
|
}
|
|
|
|
//
|
|
// If not a blank line or a comment line, then return to caller.
|
|
//
|
|
|
|
if (*s && *s != ';' && strncmp( s, "//", 2 )) {
|
|
LineIndent = s - LineBuffer;
|
|
strcpy( LineBuffer, s );
|
|
// DebugLog((DEB_TRACE_SETUP, " (%u)'%s'\n", LineIndent, LineBuffer ));
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
typedef BOOL (*PREG_INI_ROUTINE)(
|
|
struct _REG_INI_TABLE *TableEntry
|
|
);
|
|
|
|
#define REG_INI_NONE 0
|
|
#define REG_INI_VALUE 1
|
|
#define REG_INI_MULTI_VALUE 2
|
|
#define REG_INI_NAME_EQ_VALUE 3
|
|
#define REG_INI_NAME_BOOLEAN 4
|
|
#define REG_INI_DWORD 5
|
|
#define REG_INI_NAME_EQ_MULTI 6
|
|
|
|
#define REG_INI_FLAG_SKIP_FOR_NETSETUP (USHORT)0x0001
|
|
#define REG_INI_FLAG_IGNORE_NOT_FOUND (USHORT)0x0002
|
|
|
|
typedef struct _REG_INI_TABLE {
|
|
char *Name;
|
|
USHORT ValueType;
|
|
USHORT Flags;
|
|
PREG_INI_ROUTINE Routine;
|
|
char *RegistryPath;
|
|
char *RegistryValueName;
|
|
} REG_INI_TABLE, *PREG_INI_TABLE;
|
|
|
|
BOOL
|
|
ProcessMachineType(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessDisabledDrivers(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessEnabledDrivers(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessProgramGroups(
|
|
PREG_INI_TABLE TableEntry,
|
|
BOOL PersonalGroups
|
|
);
|
|
|
|
BOOL
|
|
ProcessPersonalProgramGroups(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessCommonProgramGroups(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
SaveUserName(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
SaveMachineName(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
SavePassword(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
SaveTimeZone(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
SaveDomainName(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
SaveProductType(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
SaveScriptCommands(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
REG_INI_TABLE RegistryIniTable[] = {
|
|
{"MachineType", REG_INI_NONE, 0, ProcessMachineType,
|
|
NULL, NULL
|
|
},
|
|
|
|
{"DisabledDrivers", REG_INI_NONE, 0, ProcessDisabledDrivers,
|
|
NULL, NULL
|
|
},
|
|
|
|
{"EnabledDrivers", REG_INI_NONE, 0, ProcessEnabledDrivers,
|
|
NULL, NULL
|
|
},
|
|
|
|
{"ProductType", REG_INI_VALUE, 0, SaveProductType,
|
|
"SYS:Control\\ProductOptions", "ProductType"
|
|
},
|
|
|
|
{"Domain", REG_INI_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, SaveDomainName,
|
|
"SYS:Services\\LanmanWorkstation\\Parameters", "Domain"
|
|
},
|
|
|
|
{"DomainId", REG_INI_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\LanmanWorkstation\\Parameters", "DomainId"
|
|
},
|
|
|
|
{"AccountDomainId", REG_INI_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\LanmanWorkstation\\Parameters", "AccountDomainId"
|
|
},
|
|
|
|
{"MachineName", REG_INI_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, SaveMachineName,
|
|
"SYS:Control\\ComputerName\\ComputerName", "ComputerName"
|
|
},
|
|
|
|
{"Password", REG_INI_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, SavePassword,
|
|
NULL, NULL
|
|
},
|
|
|
|
{"TimeZone", REG_INI_VALUE, 0, SaveTimeZone,
|
|
NULL, NULL
|
|
},
|
|
|
|
{"InsertScript", REG_INI_NONE, 0, SaveScriptCommands,
|
|
NULL, NULL
|
|
},
|
|
|
|
{"DosDevices", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Control\\Session Manager\\DOS Devices", NULL
|
|
},
|
|
|
|
{"Serial0", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial0", NULL
|
|
},
|
|
|
|
{"Serial1", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial1", NULL
|
|
},
|
|
|
|
{"Serial2", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial2", NULL
|
|
},
|
|
|
|
{"Serial3", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial3", NULL
|
|
},
|
|
|
|
{"Serial4", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial4", NULL
|
|
},
|
|
|
|
{"Serial5", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial5", NULL
|
|
},
|
|
|
|
{"Serial6", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial6", NULL
|
|
},
|
|
|
|
{"Serial7", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial7", NULL
|
|
},
|
|
|
|
{"Serial8", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial8", NULL
|
|
},
|
|
|
|
{"Serial9", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Services\\Serial\\Parameters\\Serial9", NULL
|
|
},
|
|
|
|
{"UserName", REG_INI_VALUE, 0, SaveUserName,
|
|
"SYS:Services", "CurrentUser"
|
|
},
|
|
|
|
{"DisablePasswordChange", REG_INI_DWORD, 0, NULL,
|
|
"SYS:Services\\NetLogon\\Parameters", "DisablePasswordChange"
|
|
},
|
|
|
|
{"GlobalFlags", REG_INI_DWORD, 0, NULL,
|
|
"SYS:Control\\Session Manager", "GlobalFlag"
|
|
},
|
|
|
|
{"ProtectionMode", REG_INI_DWORD, 0, NULL,
|
|
"SYS:Control\\Session Manager", "ProtectionMode"
|
|
},
|
|
|
|
{"CriticalSectionTimeout", REG_INI_DWORD, 0, NULL,
|
|
"SYS:Control\\Session Manager", "CriticalSectionTimeout"
|
|
},
|
|
|
|
{"ResourceTimeout", REG_INI_DWORD, 0, NULL,
|
|
"SYS:Control\\Session Manager", "ResourceTimeout"
|
|
},
|
|
|
|
{"WOW", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"SYS:Control\\WOW", NULL
|
|
},
|
|
|
|
{"PagingFiles", REG_INI_MULTI_VALUE, 0, NULL,
|
|
"SYS:Control\\Session Manager\\Memory Management", "PagingFiles"
|
|
},
|
|
|
|
{"InitialCommand", REG_INI_MULTI_VALUE, 0, NULL,
|
|
"SYS:Control\\Session Manager", "Execute"
|
|
},
|
|
|
|
{"SubSystems", REG_INI_MULTI_VALUE, 0, NULL,
|
|
"SYS:Control\\Session Manager\\SubSystems", "Optional"
|
|
},
|
|
|
|
{"ProgramGroups", REG_INI_NONE, 0, ProcessPersonalProgramGroups,
|
|
"USR:UNICODE Program Groups", NULL
|
|
},
|
|
|
|
{"CommonProgramGroups", REG_INI_NONE, 0, ProcessCommonProgramGroups,
|
|
"\\Registry\\Machine\\Software\\Program Groups", NULL
|
|
},
|
|
|
|
{"ProgramManager", REG_INI_NAME_BOOLEAN, 0, NULL,
|
|
"USR:Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager\\Settings", NULL
|
|
},
|
|
|
|
{"Environment", REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
"USR:Environment", NULL
|
|
},
|
|
|
|
{"Server", REG_INI_NAME_EQ_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\LanmanServer\\Parameters", NULL
|
|
},
|
|
|
|
{"ServerShares", REG_INI_NAME_EQ_MULTI, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\LanmanServer\\Shares", NULL
|
|
},
|
|
|
|
{"ServerLinkage", REG_INI_NAME_EQ_MULTI, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\LanmanServer\\Linkage", NULL
|
|
},
|
|
|
|
{"Nbf", REG_INI_NAME_EQ_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\Nbf\\Parameters", NULL
|
|
},
|
|
|
|
{"NbfLinkage", REG_INI_NAME_EQ_MULTI, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\Nbf\\Linkage", NULL
|
|
},
|
|
|
|
{"NetBios", REG_INI_NAME_EQ_MULTI, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\NetBiosInformation\\Parameters", NULL
|
|
},
|
|
|
|
{"NetBiosLinkage", REG_INI_NAME_EQ_MULTI, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\NetBios\\Linkage", NULL
|
|
},
|
|
|
|
{"Elnkii01", REG_INI_NAME_EQ_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\Elnkii01\\Parameters", NULL
|
|
},
|
|
|
|
{"ElnkMc01", REG_INI_NAME_EQ_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\ElnkMc01\\Parameters", NULL
|
|
},
|
|
|
|
{"UBAdapter", REG_INI_NAME_EQ_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\Xns\\Parameters", NULL
|
|
},
|
|
|
|
{"Lance01", REG_INI_NAME_EQ_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\Lance01\\Parameters", NULL
|
|
},
|
|
|
|
{"NE320001", REG_INI_NAME_EQ_VALUE, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\NE320001\\Parameters", NULL
|
|
},
|
|
|
|
{"WorkstationLinkage", REG_INI_NAME_EQ_MULTI, REG_INI_FLAG_SKIP_FOR_NETSETUP, NULL,
|
|
"SYS:Services\\LanmanWorkstation\\Linkage", NULL
|
|
},
|
|
|
|
{"Shell", REG_INI_VALUE, 0, NULL,
|
|
"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultShell"
|
|
},
|
|
|
|
{NULL, REG_INI_NAME_EQ_VALUE, 0, NULL,
|
|
NULL, NULL
|
|
}
|
|
};
|
|
|
|
|
|
BOOL
|
|
ProcessNone(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessValue(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessMultiValue(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessNameEqValue(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessNameBoolean(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessDWord(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
BOOL
|
|
ProcessNameEqMulti(
|
|
PREG_INI_TABLE TableEntry
|
|
);
|
|
|
|
PREG_INI_ROUTINE RegistryIniRoutines[] = {
|
|
ProcessNone, // REG_INI_NONE
|
|
ProcessValue, // REG_INI_VALUE
|
|
ProcessMultiValue, // REG_INI_MULTI_VALUE
|
|
ProcessNameEqValue, // REG_INI_NAME_EQ_VALUE
|
|
ProcessNameBoolean, // REG_INI_NAME_BOOLEAN
|
|
ProcessDWord, // REG_INI_DWORD
|
|
ProcessNameEqMulti // REG_INI_NAME_EQ_MULTI
|
|
};
|
|
|
|
|
|
BOOL
|
|
OpenRegistryKey(
|
|
PREG_INI_TABLE TableEntry,
|
|
PHANDLE Handle
|
|
);
|
|
|
|
char CurrentIniFileName[ 256 ] = "win.ini";
|
|
|
|
PREG_INI_TABLE
|
|
FindTableEntry(
|
|
char *Name
|
|
)
|
|
{
|
|
PREG_INI_TABLE TableEntry;
|
|
|
|
TableEntry = RegistryIniTable;
|
|
while (TableEntry->Name) {
|
|
if (!_stricmp( TableEntry->Name, Name )) {
|
|
break;
|
|
}
|
|
else {
|
|
TableEntry++;
|
|
}
|
|
}
|
|
|
|
return TableEntry;
|
|
}
|
|
|
|
BOOL
|
|
WriteWinIni(
|
|
char *Section,
|
|
char *Key,
|
|
char *Value,
|
|
BOOL AppendToValue
|
|
)
|
|
{
|
|
DWORD cbValue;
|
|
char *NewValue;
|
|
char *FileName;
|
|
BOOL Result;
|
|
|
|
FileName = CurrentIniFileName;
|
|
if (!_strnicmp( Value, "REG_DWORD ", 10 )) {
|
|
Value += 10;
|
|
}
|
|
|
|
if (AppendToValue) {
|
|
cbValue = 1024;
|
|
NewValue = (char *)LocalAlloc( LMEM_ZEROINIT, cbValue + strlen( Value ) + 1 );
|
|
if (NewValue) {
|
|
cbValue = GetPrivateProfileStringA( Section, Key, NULL, NewValue, cbValue, FileName );
|
|
if (cbValue) {
|
|
strcat( NewValue, Value );
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
NewValue = Value;
|
|
}
|
|
|
|
Result = WritePrivateProfileStringA( Section, Key, NewValue, FileName );
|
|
if (!Result) {
|
|
DeclareError( "WritePrivateProfileString( %s, %s, %s, %s ) - failed (rc == %u)\n",
|
|
Section,
|
|
Key,
|
|
NewValue,
|
|
FileName ? FileName : "win.ini",
|
|
GetLastError()
|
|
);
|
|
|
|
}
|
|
|
|
if (NewValue != Value) {
|
|
LocalFree( NewValue );
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
OpenRegistryKey(
|
|
PREG_INI_TABLE TableEntry,
|
|
PHANDLE Handle
|
|
)
|
|
{
|
|
char *Path, FullPath[ 2 * MAX_PATH ];
|
|
ANSI_STRING AnsiPath;
|
|
UNICODE_STRING UnicodePath;
|
|
NTSTATUS Status;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
Path = TableEntry->RegistryPath;
|
|
*Handle = NULL;
|
|
if (Path == NULL) {
|
|
return TRUE;
|
|
}
|
|
else
|
|
if (NetSetupGoingToRun && (TableEntry->Flags & REG_INI_FLAG_SKIP_FOR_NETSETUP)) {
|
|
return TRUE;
|
|
}
|
|
|
|
if (!_strnicmp( Path, "USR:", 4 )) {
|
|
strcpy( FullPath, "\\Registry\\User\\.Default\\" );
|
|
Path += 4;
|
|
}
|
|
else
|
|
if (!_strnicmp( Path, "SYS:", 4 )) {
|
|
strcpy( FullPath, "\\Registry\\Machine\\System\\CurrentControlSet\\" );
|
|
Path += 4;
|
|
}
|
|
else {
|
|
FullPath[ 0 ] = '\0';
|
|
}
|
|
strcat( FullPath, Path );
|
|
RtlInitAnsiString( &AnsiPath, FullPath );
|
|
RtlAnsiStringToUnicodeString( &UnicodePath, &AnsiPath, TRUE );
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
&UnicodePath,
|
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
|
NULL,
|
|
NULL
|
|
);
|
|
Status = NtOpenKey( Handle,
|
|
MAXIMUM_ALLOWED,
|
|
&ObjectAttributes
|
|
);
|
|
|
|
RtlFreeUnicodeString( &UnicodePath );
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
return TRUE;
|
|
}
|
|
else {
|
|
if (!(TableEntry->Flags & REG_INI_FLAG_IGNORE_NOT_FOUND)) {
|
|
DeclareError( "NtOpenKey( %s ) failed (Status == %lx)\n",
|
|
FullPath,
|
|
Status
|
|
);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
WriteRegistryKey(
|
|
HANDLE KeyHandle,
|
|
char *ValueName,
|
|
DWORD ValueType,
|
|
char *ValueData,
|
|
DWORD ValueLength
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
ANSI_STRING AnsiString;
|
|
UNICODE_STRING UnicodeKeyName;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE KeyHandle1;
|
|
|
|
RtlInitAnsiString( &AnsiString, ValueName );
|
|
RtlAnsiStringToUnicodeString( &UnicodeKeyName, &AnsiString, TRUE );
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
&UnicodeKeyName,
|
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
|
KeyHandle,
|
|
NULL
|
|
);
|
|
Status = NtCreateKey( &KeyHandle1,
|
|
MAXIMUM_ALLOWED,
|
|
&ObjectAttributes,
|
|
0,
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
RtlFreeUnicodeString( &UnicodeKeyName );
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
Status = WriteRegistry( KeyHandle1,
|
|
NULL,
|
|
ValueType,
|
|
ValueData,
|
|
ValueLength
|
|
);
|
|
(void) NtClose( KeyHandle1 );
|
|
|
|
return( Status );
|
|
|
|
}
|
|
else {
|
|
DeclareError( "NtCreateKey( %s ) failed (Status == %lx)\n",
|
|
ValueName,
|
|
Status
|
|
);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
ProcessNone(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
ProcessValue(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
HANDLE Handle;
|
|
BOOL Result;
|
|
|
|
if (!GetLine()) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (!OpenRegistryKey( TableEntry, &Handle )) {
|
|
return FALSE;
|
|
}
|
|
|
|
Result = TRUE;
|
|
if (Handle) {
|
|
Result &= WriteRegistry( Handle,
|
|
TableEntry->RegistryValueName,
|
|
REG_SZ,
|
|
LineBuffer,
|
|
0
|
|
);
|
|
NtClose( Handle );
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ProcessMultiValue(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
HANDLE Handle;
|
|
BOOL Result;
|
|
DWORD ValueLength, cb;
|
|
char *ValueData;
|
|
|
|
if (!OpenRegistryKey( TableEntry, &Handle )) {
|
|
return FALSE;
|
|
}
|
|
|
|
Result = TRUE;
|
|
ValueLength = 0;
|
|
ValueData = (char *)LocalAlloc( LMEM_ZEROINIT, ValueLength );
|
|
if (!ValueData)
|
|
{
|
|
NtClose( Handle );
|
|
return( FALSE );
|
|
}
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
if (Handle) {
|
|
cb = strlen( LineBuffer ) + 1;
|
|
ValueData = (char *)LocalReAlloc( ValueData, ValueLength + cb, LMEM_ZEROINIT | LMEM_MOVEABLE );
|
|
if (!ValueData)
|
|
{
|
|
NtClose( Handle );
|
|
return( FALSE );
|
|
|
|
}
|
|
strcpy( ValueData + ValueLength, LineBuffer );
|
|
ValueLength += cb;
|
|
}
|
|
|
|
}
|
|
|
|
if (Handle) {
|
|
cb = sizeof( '\0' );
|
|
ValueData = (char *)LocalReAlloc( ValueData, ValueLength + cb, LMEM_ZEROINIT | LMEM_MOVEABLE );
|
|
if (!ValueData)
|
|
{
|
|
NtClose( Handle );
|
|
return( FALSE );
|
|
}
|
|
ValueLength += cb;
|
|
Result &= WriteRegistry( Handle,
|
|
TableEntry->RegistryValueName,
|
|
REG_MULTI_SZ,
|
|
ValueData,
|
|
ValueLength
|
|
);
|
|
NtClose( Handle );
|
|
}
|
|
|
|
LocalFree( ValueData );
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ProcessNameEqValue(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
char MessageBuffer[ 128 ];
|
|
char SectionNameBuffer[ MAX_PATH ];
|
|
char *SectionName;
|
|
char *Equal, *Value;
|
|
HANDLE Handle;
|
|
BOOL AppendToValue;
|
|
BOOL Result;
|
|
|
|
if (!_strnicmp( LineBuffer, "-f ", 3)) {
|
|
Value = LineBuffer + 3;
|
|
while (*Value == ' ') {
|
|
Value++;
|
|
}
|
|
|
|
strcpy( CurrentIniFileName, Value );
|
|
return TRUE;
|
|
}
|
|
|
|
if (!OpenRegistryKey( TableEntry, &Handle )) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (TableEntry->Name == NULL) {
|
|
SectionName = SectionNameBuffer;
|
|
strcpy( SectionName, LineBuffer );
|
|
}
|
|
else {
|
|
SectionName = NULL;
|
|
}
|
|
strcpy( MessageBuffer, LineBuffer );
|
|
|
|
Result = TRUE;
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
Equal = strchr( LineBuffer, '=' );
|
|
if (Equal == NULL) {
|
|
strcat( MessageBuffer, " - Expecting NAME=VALUE" );
|
|
DeclareError( MessageBuffer );
|
|
Result = FALSE;
|
|
break;
|
|
}
|
|
*Equal = '\0';
|
|
Value = Equal + 1;
|
|
if (Equal[ -1 ] == '+') {
|
|
AppendToValue = TRUE;
|
|
*--Equal = '\0';
|
|
}
|
|
else {
|
|
AppendToValue = FALSE;
|
|
}
|
|
|
|
while (Equal > LineBuffer && *--Equal <= ' ') {
|
|
*Equal = '\0';
|
|
}
|
|
while (*Value && *Value <= ' ') {
|
|
Value++;
|
|
}
|
|
|
|
if (Handle) {
|
|
Result &= WriteRegistry( Handle,
|
|
LineBuffer,
|
|
REG_SZ,
|
|
Value,
|
|
0
|
|
);
|
|
}
|
|
|
|
if (SectionName) {
|
|
Result &= WriteWinIni( SectionName,
|
|
LineBuffer,
|
|
Value,
|
|
AppendToValue
|
|
);
|
|
}
|
|
}
|
|
|
|
if (Handle) {
|
|
NtClose( Handle );
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
BOOL
|
|
ProcessNameBoolean(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
HANDLE Handle;
|
|
BOOL Result;
|
|
|
|
if (!OpenRegistryKey( TableEntry, &Handle )) {
|
|
return FALSE;
|
|
}
|
|
|
|
Result = TRUE;
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
if (Handle) {
|
|
Result &= WriteRegistry( Handle,
|
|
LineBuffer,
|
|
REG_DWORD,
|
|
"1",
|
|
0
|
|
);
|
|
}
|
|
}
|
|
|
|
if (Handle) {
|
|
NtClose( Handle );
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
BOOL
|
|
ProcessDWord(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
HANDLE Handle;
|
|
BOOL Result;
|
|
|
|
if (!GetLine()) {
|
|
return FALSE;
|
|
}
|
|
|
|
Result = TRUE;
|
|
if (!OpenRegistryKey( TableEntry, &Handle )) {
|
|
Result = FALSE;
|
|
}
|
|
else
|
|
if (Handle != NULL) {
|
|
Result &= WriteRegistry( Handle,
|
|
TableEntry->RegistryValueName,
|
|
REG_DWORD,
|
|
LineBuffer,
|
|
0
|
|
);
|
|
NtClose( Handle );
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
BOOL
|
|
ProcessNameEqMulti(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
char *Equal, *Value;
|
|
char *Src, *Dst;
|
|
HANDLE Handle;
|
|
BOOL Result;
|
|
|
|
if (!TableEntry->RegistryPath) {
|
|
DeclareError( "RegistryPath must be specified for NAME_EQ_MULTI" );
|
|
return FALSE;
|
|
}
|
|
if (TableEntry->RegistryValueName) {
|
|
DeclareError( "RegistryValueName must be NULL for NAME_EQ_MULTI" );
|
|
return FALSE;
|
|
}
|
|
|
|
if (!OpenRegistryKey( TableEntry, &Handle )) {
|
|
return FALSE;
|
|
}
|
|
|
|
Result = TRUE;
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
Equal = strchr( LineBuffer, '=' );
|
|
if (Equal == NULL) {
|
|
DeclareError( "Expecting NAME=MULTI_SZ" );
|
|
Result = FALSE;
|
|
break;
|
|
}
|
|
*Equal = '\0';
|
|
Value = Equal + 1;
|
|
if (Equal[ -1 ] == '+') {
|
|
DeclareError( "+= not allowed for MULTI_SZ values" );
|
|
Result = FALSE;
|
|
break;
|
|
}
|
|
|
|
while (Equal > LineBuffer && *--Equal <= ' ') {
|
|
*Equal = '\0';
|
|
}
|
|
while (*Value && *Value <= ' ') {
|
|
Value++;
|
|
}
|
|
|
|
//
|
|
// Strip " from strings and put NULs in between.
|
|
//
|
|
|
|
Src = Dst = Value;
|
|
while (*Src) {
|
|
if (*Src++ != '"') {
|
|
DeclareError( "Expected '\"' to start MULTI_SZ string" );
|
|
Result = FALSE;
|
|
break;
|
|
}
|
|
while (*Src && (*Src != '"' || Src[1] == '"')) {
|
|
if ((*Dst++ = *Src++) == '"') {
|
|
Src++;
|
|
}
|
|
}
|
|
if (*Src++ != '"') {
|
|
DeclareError( "Missing '\"' at end of MULTI_SZ string" );
|
|
Result = FALSE;
|
|
break;
|
|
}
|
|
*Dst++ = '\0';
|
|
while (*Src && *Src <= ' ') {
|
|
Src++;
|
|
}
|
|
}
|
|
*Dst = '\0';
|
|
|
|
if (!Result) {
|
|
break;
|
|
}
|
|
|
|
if (Handle) {
|
|
Result &= WriteRegistry( Handle,
|
|
LineBuffer,
|
|
REG_MULTI_SZ,
|
|
Value,
|
|
0
|
|
);
|
|
}
|
|
}
|
|
|
|
if (Handle) {
|
|
NtClose( Handle );
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ProcessPersonalProgramGroups(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
return ProcessProgramGroups( TableEntry, TRUE );
|
|
}
|
|
|
|
|
|
BOOL
|
|
ProcessCommonProgramGroups(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
return ProcessProgramGroups( TableEntry, FALSE );
|
|
}
|
|
|
|
BOOL
|
|
ProcessProgramGroups(
|
|
PREG_INI_TABLE TableEntry,
|
|
BOOL PersonalGroups
|
|
)
|
|
{
|
|
HANDLE ProgramGroupsHandle;
|
|
HANDLE GroupsHandle;
|
|
HANDLE SettingsHandle;
|
|
REG_INI_TABLE TempEntry;
|
|
char *Equal, *Value, *ExpandedValue;
|
|
BOOL Result;
|
|
int GroupNumber;
|
|
int GroupFileHandle;
|
|
char GroupNumberKey[ MAX_PATH ];
|
|
char GroupOrderList[ MAX_PATH ] = " ";
|
|
char *GroupFileData;
|
|
struct _finddata_t GroupFileInfo;
|
|
long FindHandle;
|
|
DWORD cb;
|
|
|
|
OpenRegistryKey( TableEntry, &ProgramGroupsHandle );
|
|
if (ProgramGroupsHandle == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (PersonalGroups) {
|
|
TempEntry.Flags = 0;
|
|
TempEntry.RegistryPath = "USR:Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager\\UNICODE Groups";
|
|
OpenRegistryKey( &TempEntry, &GroupsHandle );
|
|
if (GroupsHandle == NULL) {
|
|
NtClose( ProgramGroupsHandle );
|
|
return FALSE;
|
|
}
|
|
|
|
TempEntry.RegistryPath = "USR:Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager\\Settings";
|
|
OpenRegistryKey( &TempEntry, &SettingsHandle );
|
|
if (SettingsHandle == NULL) {
|
|
NtClose( GroupsHandle );
|
|
NtClose( ProgramGroupsHandle );
|
|
return FALSE;
|
|
}
|
|
}
|
|
else {
|
|
GroupsHandle = NULL;
|
|
SettingsHandle = NULL;
|
|
}
|
|
|
|
Result = TRUE;
|
|
GroupNumber = 0;
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
Equal = strchr( LineBuffer, '=' );
|
|
if (Equal == NULL) {
|
|
DeclareError( "Expecting NAME=VALUE" );
|
|
Result = FALSE;
|
|
break;
|
|
}
|
|
*Equal = '\0';
|
|
Value = Equal + 1;
|
|
while (Equal > LineBuffer && *--Equal <= ' ') {
|
|
*Equal = '\0';
|
|
}
|
|
while (*Value && *Value <= ' ') {
|
|
Value++;
|
|
}
|
|
|
|
if (strchr( Value, '%' )) {
|
|
cb = 4 * strlen( Value );
|
|
ExpandedValue = (char *)LocalAlloc( 0, cb );
|
|
ExpandEnvironmentStringsA( Value, ExpandedValue, cb );
|
|
Value = ExpandedValue;
|
|
}
|
|
else {
|
|
ExpandedValue = NULL;
|
|
}
|
|
|
|
cb = 0;
|
|
FindHandle = _findfirst( Value, &GroupFileInfo );
|
|
if (FindHandle != -1) {
|
|
GroupFileData = (char *)LocalAlloc( 0, GroupFileInfo.size );
|
|
_findclose( FindHandle );
|
|
GroupFileHandle = _open( Value, _O_BINARY | _O_RDONLY, _A_NORMAL );
|
|
if (GroupFileHandle != -1) {
|
|
cb = _read( GroupFileHandle, GroupFileData, GroupFileInfo.size );
|
|
if (cb != GroupFileInfo.size) {
|
|
cb = 0;
|
|
}
|
|
_close( GroupFileHandle );
|
|
}
|
|
}
|
|
|
|
if (ExpandedValue) {
|
|
LocalFree( ExpandedValue );
|
|
}
|
|
|
|
if (cb == 0) {
|
|
DeclareError( "Unable to open or access group file - %s", Value );
|
|
Result = FALSE;
|
|
}
|
|
else {
|
|
if (PersonalGroups) {
|
|
GroupNumber += 1;
|
|
sprintf( GroupNumberKey, "Group%u", GroupNumber );
|
|
Result &= WriteRegistry( GroupsHandle,
|
|
GroupNumberKey,
|
|
REG_SZ,
|
|
LineBuffer,
|
|
0
|
|
);
|
|
}
|
|
|
|
Result &= WriteRegistryKey( ProgramGroupsHandle,
|
|
LineBuffer,
|
|
REG_BINARY,
|
|
GroupFileData,
|
|
cb
|
|
);
|
|
|
|
|
|
LocalFree( GroupFileData );
|
|
GroupFileData = NULL;
|
|
}
|
|
}
|
|
|
|
if (Result && PersonalGroups) {
|
|
char *s;
|
|
int i;
|
|
|
|
s = GroupOrderList;
|
|
for (i=0; i<GroupNumber; i++) {
|
|
if (i) {
|
|
*s++ = ' ' ;
|
|
}
|
|
|
|
s += sprintf( s, "%d", i+1 );
|
|
}
|
|
|
|
Result &= WriteRegistry( SettingsHandle,
|
|
"UNICODE Order",
|
|
REG_SZ,
|
|
GroupOrderList,
|
|
0
|
|
);
|
|
|
|
|
|
Result &= WriteRegistry( SettingsHandle,
|
|
"Startup",
|
|
REG_SZ,
|
|
"Startup",
|
|
0
|
|
);
|
|
}
|
|
|
|
if (PersonalGroups) {
|
|
NtClose( SettingsHandle );
|
|
NtClose( GroupsHandle );
|
|
}
|
|
|
|
NtClose( ProgramGroupsHandle );
|
|
return Result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
EnableDisableDriver(
|
|
char *ModuleName,
|
|
BOOL EnableLoad
|
|
);
|
|
|
|
BOOL
|
|
EnableDisableDriver(
|
|
char *ModuleName,
|
|
BOOL EnableLoad
|
|
)
|
|
{
|
|
BOOL Result;
|
|
char RegistryPath[ MAX_PATH ];
|
|
HANDLE KeyHandle;
|
|
char StartValue[ 16 ];
|
|
REG_INI_TABLE TempEntry;
|
|
|
|
|
|
//
|
|
// Never ever disable VgaStart and VgaSave drivers.
|
|
//
|
|
|
|
if ( (_strnicmp(ModuleName, "Vga", 3) == 0) &&
|
|
!EnableLoad) {
|
|
return FALSE;
|
|
}
|
|
|
|
_snprintf( RegistryPath, sizeof( RegistryPath ), "SYS:Services\\%s", ModuleName );
|
|
TempEntry.RegistryPath = RegistryPath;
|
|
TempEntry.Flags = REG_INI_FLAG_IGNORE_NOT_FOUND;
|
|
OpenRegistryKey( &TempEntry, &KeyHandle );
|
|
if (KeyHandle != NULL) {
|
|
_snprintf( StartValue, sizeof( StartValue ), "%u",
|
|
EnableLoad ? SERVICE_SYSTEM_START : SERVICE_DISABLED
|
|
);
|
|
Result = WriteRegistry( KeyHandle,
|
|
"Start",
|
|
REG_DWORD,
|
|
StartValue,
|
|
0
|
|
);
|
|
if (Result && EnableLoad) {
|
|
_snprintf( StartValue, sizeof( StartValue ), "%u", SERVICE_ERROR_IGNORE );
|
|
Result = WriteRegistry( KeyHandle,
|
|
"ErrorControl",
|
|
REG_DWORD,
|
|
StartValue,
|
|
0
|
|
);
|
|
}
|
|
|
|
NtClose( KeyHandle );
|
|
Result = TRUE;
|
|
}
|
|
else {
|
|
Result = FALSE;
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ProcessREGINI(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
ProcessMachineType(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
if (GetLine()) {
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
ProcessDisabledDrivers(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
if (EnableDisableDriver( LineBuffer, FALSE )) {
|
|
DebugLog((DEB_TRACE_SETUP, " Disabled load of %s driver.\n", LineBuffer ));
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
ProcessEnabledDrivers(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
if (EnableDisableDriver( LineBuffer, TRUE )) {
|
|
DebugLog((DEB_TRACE_SETUP, " Enabled load of %s driver.\n", LineBuffer ));
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
DoFile( void )
|
|
{
|
|
PREG_INI_TABLE TableEntry;
|
|
BOOL Result;
|
|
|
|
fh = fopen( InputFileName, "rb" );
|
|
if (fh == NULL) {
|
|
DeclareError( "Unable to open input file (rc == %u)\n", GetLastError() );
|
|
return FALSE;
|
|
}
|
|
|
|
Result = TRUE;
|
|
while (GetLine()) {
|
|
while (!LineIndent) {
|
|
TableEntry = FindTableEntry( LineBuffer );
|
|
LineIndent = 1;
|
|
if ((RegistryIniRoutines[ TableEntry->ValueType ])( TableEntry )) {
|
|
if (TableEntry->Routine) {
|
|
Result &= (TableEntry->Routine)( TableEntry );
|
|
}
|
|
}
|
|
else {
|
|
Result = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
#if 0
|
|
BOOL
|
|
SaveDefaultProfile( void )
|
|
{
|
|
char DefaultPath[ 2 * MAX_PATH ];
|
|
char ProfileKey[ 2 * MAX_PATH ];
|
|
ANSI_STRING AnsiPath;
|
|
UNICODE_STRING UnicodePath;
|
|
NTSTATUS Status;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE KeyHandle;
|
|
HANDLE FileHandle;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
RTL_RELATIVE_NAME RelativeName;
|
|
UNICODE_STRING FileName;
|
|
PVOID FreeBuffer;
|
|
BOOLEAN ErrorFlag;
|
|
|
|
strcpy( ProfileKey, "\\Registry\\User\\The_User" );
|
|
RtlInitAnsiString( &AnsiPath, ProfileKey );
|
|
RtlAnsiStringToUnicodeString( &UnicodePath, &AnsiPath, TRUE );
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
&UnicodePath,
|
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
|
NULL,
|
|
NULL
|
|
);
|
|
Status = NtOpenKey( &KeyHandle,
|
|
MAXIMUM_ALLOWED,
|
|
&ObjectAttributes
|
|
);
|
|
|
|
RtlFreeUnicodeString( &UnicodePath );
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
DebugLog((DEB_ERROR, " Could not open key 'THE_USER' Status = 0x%lx\n\r", Status));
|
|
return FALSE;
|
|
}
|
|
|
|
ExpandEnvironmentStringsA("%systemRoot%\\system32\\config\\DEFAULT", DefaultPath, sizeof(DefaultPath));
|
|
RtlInitAnsiString( &AnsiPath, DefaultPath );
|
|
RtlAnsiStringToUnicodeString( &UnicodePath, &AnsiPath, TRUE );
|
|
|
|
//
|
|
// Convert the DOS path name to a canonical Nt path name.
|
|
//
|
|
|
|
ErrorFlag = RtlDosPathNameToNtPathName_U(
|
|
UnicodePath.Buffer,
|
|
&FileName,
|
|
NULL,
|
|
&RelativeName
|
|
);
|
|
|
|
RtlFreeUnicodeString( &UnicodePath );
|
|
|
|
//
|
|
// If the name was not succesfully converted assume it was invalid.
|
|
//
|
|
if( ! ErrorFlag ) {
|
|
DebugLog((DEB_ERROR, " Could not create default profile - RtlDosPathNameToNtPathName_U FAILED error = %d\n\r", ErrorFlag));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Remember the buffer allocatted by RtlDosPathNameToNtPathName_U.
|
|
//
|
|
FreeBuffer = FileName.Buffer;
|
|
|
|
//
|
|
// If a relative name and directory handle will work, use those.
|
|
//
|
|
if( RelativeName.RelativeName.Length ) {
|
|
|
|
//
|
|
// Replace the full path with the relative path.
|
|
//
|
|
FileName = *(PUNICODE_STRING)&RelativeName.RelativeName;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Using the full path - no containing directory.
|
|
//
|
|
RelativeName.ContainingDirectory = NULL;
|
|
}
|
|
|
|
//
|
|
// Initialize the Obja structure for the save file.
|
|
//
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&FileName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
RelativeName.ContainingDirectory,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Create the file - fail if the file exists.
|
|
//
|
|
Status = NtCreateFile(
|
|
&FileHandle,
|
|
GENERIC_WRITE | SYNCHRONIZE,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
NULL,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
FILE_SHARE_READ,
|
|
FILE_CREATE,
|
|
FILE_SYNCHRONOUS_IO_NONALERT,
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
//
|
|
// Free the buffer allocatted by RtlDosPathNameToNtPathName_U.
|
|
//
|
|
RtlFreeHeap( RtlProcessHeap(), 0, FreeBuffer );
|
|
|
|
//
|
|
// Check the results of the NtCreateFile.
|
|
//
|
|
if( ! NT_SUCCESS( Status )) {
|
|
DebugLog((DEB_ERROR, " Could not create default profile - Status == 0x%lx\n\r", Status));
|
|
return FALSE;
|
|
}
|
|
|
|
EnablePrivilege(SE_BACKUP_PRIVILEGE, TRUE);
|
|
EnablePrivilege(SE_RESTORE_PRIVILEGE, TRUE);
|
|
|
|
Status = NtSaveKey( KeyHandle, FileHandle );
|
|
if (!NT_SUCCESS(Status)) {
|
|
DebugLog((DEB_ERROR, " Could not save default profile - Status == 0x%lx\n\r", Status));
|
|
}
|
|
else {
|
|
DebugLog((DEB_ERROR, " Created the default profile DEFAULT\n\r"));
|
|
}
|
|
|
|
EnablePrivilege(SE_BACKUP_PRIVILEGE, FALSE);
|
|
EnablePrivilege(SE_RESTORE_PRIVILEGE, FALSE);
|
|
|
|
//
|
|
// Close the file.
|
|
//
|
|
NtClose( FileHandle );
|
|
return(NT_SUCCESS(Status));
|
|
}
|
|
#endif
|
|
|
|
char SavedUserName[ MAX_COMPUTERNAME_LENGTH ];
|
|
char SavedMachineName[ MAX_COMPUTERNAME_LENGTH ];
|
|
char SavedDomainName[ MAX_COMPUTERNAME_LENGTH ];
|
|
char SavedPassword[ 64 ];
|
|
char SavedTimeZone[ 64 ];
|
|
NT_PRODUCT_TYPE SavedProductType;
|
|
char *CommandsToInsertAtBegOfScript;
|
|
char *CommandsToInsertAtEndOfScript;
|
|
|
|
BOOL
|
|
SaveUserName(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
strcpy( SavedUserName, LineBuffer );
|
|
_strlwr( SavedUserName );
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
SaveMachineName(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
strcpy( SavedMachineName, LineBuffer );
|
|
_strupr( SavedMachineName );
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
SavePassword(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
strcpy( SavedPassword, LineBuffer );
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
SaveTimeZone(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
strcpy( SavedTimeZone, LineBuffer );
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
SaveDomainName(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
strcpy( SavedDomainName, LineBuffer );
|
|
_strupr( SavedDomainName );
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
SaveProductType(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
TableEntry;
|
|
|
|
if (_strcmpi(LineBuffer, "LanmanNt") == 0) {
|
|
SavedProductType = NtProductLanManNt;
|
|
} else if (_strcmpi(LineBuffer, "ServerNt") == 0) {
|
|
SavedProductType = NtProductServer;
|
|
} else {
|
|
SavedProductType = NtProductWinNt;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
SaveScriptCommands(
|
|
PREG_INI_TABLE TableEntry
|
|
)
|
|
{
|
|
char *s, **pp, *Src;
|
|
DWORD cb;
|
|
|
|
while (GetLine()) {
|
|
if (!LineIndent) {
|
|
break;
|
|
}
|
|
|
|
if (!_stricmp( LineBuffer, "KeepScript" )) {
|
|
KeepScript = TRUE;
|
|
}
|
|
else
|
|
if (!_stricmp( LineBuffer, "ExtendedNetSetup" )) {
|
|
ExtendedNetSetup = TRUE;
|
|
if (NetSetupGoingToRun) {
|
|
SetSetupType( SETUPTYPE_NETSRW );
|
|
}
|
|
}
|
|
else
|
|
if (!_stricmp( LineBuffer, "RunNetDetect" )) {
|
|
if (NetSetupGoingToRun) {
|
|
RunNetDetect = TRUE;
|
|
}
|
|
}
|
|
else {
|
|
Src = LineBuffer;
|
|
if (*Src == '!') {
|
|
pp = &CommandsToInsertAtEndOfScript;
|
|
Src++;
|
|
}
|
|
else {
|
|
pp = &CommandsToInsertAtBegOfScript;
|
|
}
|
|
|
|
if (*pp != NULL) {
|
|
cb = strlen( *pp );
|
|
}
|
|
else {
|
|
cb = 0;
|
|
}
|
|
cb += strlen( Src ) + 4;
|
|
s = RtlAllocateHeap( RtlProcessHeap(), 0, cb );
|
|
if (s == NULL) {
|
|
return FALSE;
|
|
}
|
|
sprintf( s, "%s%s\r\n", *pp != NULL ? *pp : "", Src );
|
|
if (*pp != NULL) {
|
|
RtlFreeHeap( RtlProcessHeap(), 0, *pp );
|
|
}
|
|
*pp = s;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GenerateInitialCommandScript( void )
|
|
{
|
|
FILE *fh;
|
|
char ScriptFileName[ MAX_PATH ];
|
|
char SetupArguments[ 256];
|
|
|
|
GetEnvironmentVariableA( "SystemRoot", ScriptFileName, sizeof( ScriptFileName ) );
|
|
strcat( ScriptFileName, "\\winlogon.cmd" );
|
|
_unlink( ScriptFileName );
|
|
|
|
if (fh = fopen( ScriptFileName, "wb" )) {
|
|
fprintf( fh, "ini winlogon.Shell = \"progman.exe\"\r\n" );
|
|
fprintf( fh, "@ech ;\r\n" );
|
|
fprintf( fh, "@ech ;\r\n" );
|
|
fprintf( fh, "@ech This command will finish the initialization of your accounts database ;\r\n" );
|
|
fprintf( fh, "@ech and will not execute again the next time you boot. ;\r\n" );
|
|
fprintf( fh, "@ech ;\r\n" );
|
|
fprintf( fh, "@ech ;\r\n" );
|
|
|
|
if (CommandsToInsertAtBegOfScript != NULL) {
|
|
fprintf( fh, "%s", CommandsToInsertAtBegOfScript );
|
|
}
|
|
|
|
if (!NetSetupGoingToRun) {
|
|
if ( SavedTimeZone[0] ) {
|
|
fprintf( fh, "control main.cpl /INSTALL=%s\r\n", SavedTimeZone );
|
|
}
|
|
else {
|
|
fprintf( fh, "control main.cpl /INSTALL=Pacific\r\n");
|
|
}
|
|
}
|
|
|
|
fprintf( fh, "ini winlogon.DefaultUserName = %s\r\n", SavedUserName );
|
|
if ( NetFound ) {
|
|
if (SavedPassword[ 0 ]) {
|
|
fprintf( fh, "ini winlogon.AutoAdminLogon = 1\r\n" );
|
|
fprintf( fh, "ini winlogon.DefaultPassword = %s\r\n", SavedPassword );
|
|
}
|
|
|
|
if (SavedProductType != NtProductLanManNt) {
|
|
fprintf( fh, "ini winlogon.DefaultDomainName = %s\r\n", SavedDomainName );
|
|
if (!NetSetupGoingToRun) {
|
|
fprintf( fh, "netjoin\r\n" );
|
|
}
|
|
else {
|
|
fprintf( fh, "erase %%SystemRoot%%\\system32\\config\\userdef.*\r\n" );
|
|
}
|
|
fprintf( fh, "net localgroup Administrators %s\\%s /add\r\n", SavedDomainName, SavedUserName );
|
|
if (NetSetupGoingToRun) {
|
|
if (ExtendedNetSetup) {
|
|
sprintf( SetupArguments, " /t STF_COMPUTERNAME = %s", SavedMachineName );
|
|
AppendToSetupCommandLine( SetupArguments );
|
|
}
|
|
|
|
if (RunNetDetect) {
|
|
sprintf( SetupArguments, " /t STF_RUNNETDETECT = %u", RunNetDetect );
|
|
AppendToSetupCommandLine( SetupArguments );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (SavedPassword[ 0 ]) {
|
|
fprintf( fh, "ini winlogon.AutoAdminLogon = 1\r\n" );
|
|
fprintf( fh, "ini winlogon.DefaultPassword = %s\r\n", SavedPassword );
|
|
fprintf( fh, "adduser %s %s\r\n", SavedUserName, SavedPassword );
|
|
}
|
|
else {
|
|
fprintf( fh, "adduser %s localuser\r\n", SavedUserName );
|
|
}
|
|
}
|
|
|
|
if (!SavedPassword[ 0 ]) {
|
|
fprintf( fh, "@echo ;\r\n" );
|
|
fprintf( fh, "@echo Ready to reboot and logon as %s\r\n", SavedUserName );
|
|
fprintf( fh, "@echo ;\r\n" );
|
|
fprintf( fh, "@echo Pressing any key except Ctrl-C will reboot the machine.\r\n", SavedUserName );
|
|
fprintf( fh, "@pause\r\n" );
|
|
}
|
|
|
|
if (CommandsToInsertAtEndOfScript != NULL) {
|
|
fprintf( fh, "%s", CommandsToInsertAtEndOfScript );
|
|
}
|
|
|
|
if (!KeepScript) {
|
|
fprintf( fh, "erase %s && ", ScriptFileName );
|
|
}
|
|
fprintf( fh, "shutdown -r -f -t 0\r\n" );
|
|
fclose( fh );
|
|
WriteProfileStringA( AnsiWinlogon,
|
|
"Shell",
|
|
ScriptFileName
|
|
);
|
|
WriteProfileStringA( AnsiWinlogon, "AutoAdminLogon", "1" );
|
|
return TRUE;
|
|
}
|
|
else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
DisableFailedBuiltInDrivers(
|
|
PRTL_PROCESS_MODULES *ModuleList
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
RTL_PROCESS_MODULES ModuleInfoBuffer;
|
|
PRTL_PROCESS_MODULES ModuleInfo;
|
|
PRTL_PROCESS_MODULE_INFORMATION ModuleInfo1;
|
|
ULONG RequiredLength, ModuleNumber;
|
|
|
|
ModuleInfo = &ModuleInfoBuffer;
|
|
RequiredLength = sizeof( *ModuleInfo );
|
|
while (TRUE) {
|
|
Status = NtQuerySystemInformation( SystemModuleInformation,
|
|
ModuleInfo,
|
|
RequiredLength,
|
|
&RequiredLength
|
|
);
|
|
if (Status == STATUS_INFO_LENGTH_MISMATCH) {
|
|
if (ModuleInfo != &ModuleInfoBuffer) {
|
|
DebugLog((DEB_TRACE_SETUP, " QueryModuleInformation returned incorrect result.\n" ));
|
|
VirtualFree( ModuleInfo, 0, MEM_RELEASE );
|
|
return FALSE;
|
|
}
|
|
|
|
RequiredLength += 4096;
|
|
ModuleInfo = (PRTL_PROCESS_MODULES)VirtualAlloc( NULL,
|
|
RequiredLength,
|
|
MEM_COMMIT,
|
|
PAGE_READWRITE
|
|
);
|
|
if (ModuleInfo == NULL) {
|
|
DebugLog((DEB_TRACE_SETUP, " No memory for QueryModuleInformation (%lx).\n", RequiredLength ));
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
if (!NT_SUCCESS( Status )) {
|
|
if (ModuleInfo != &ModuleInfoBuffer) {
|
|
VirtualFree( ModuleInfo, 0, MEM_RELEASE );
|
|
}
|
|
|
|
DebugLog((DEB_TRACE_SETUP, " QueryModuleInformation failed - %lx.\n", Status ));
|
|
return FALSE;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
ModuleInfo1 = &ModuleInfo->Modules[ 0 ];
|
|
for (ModuleNumber=0; ModuleNumber<ModuleInfo->NumberOfModules; ModuleNumber++) {
|
|
if ((ModuleInfo1->Flags & LDRP_FAILED_BUILTIN_LOAD) &&
|
|
ModuleInfo1->LoadCount <= 1
|
|
) {
|
|
char *ModuleName, *s;
|
|
|
|
ModuleName = &ModuleInfo1->FullPathName[ ModuleInfo1->OffsetToFileName ];
|
|
if (s = strchr( ModuleName, '.' )) {
|
|
*s = '\0';
|
|
}
|
|
|
|
if (EnableDisableDriver( ModuleName, FALSE )) {
|
|
DebugLog((DEB_TRACE_SETUP, " Disabled load of %s builtin driver.\n", ModuleName ));
|
|
}
|
|
}
|
|
|
|
ModuleInfo1++;
|
|
}
|
|
|
|
*ModuleList = ModuleInfo;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
LookupModuleName(
|
|
CHAR *DriverName,
|
|
PRTL_PROCESS_MODULES ModuleInfo
|
|
)
|
|
{
|
|
PRTL_PROCESS_MODULE_INFORMATION moduleInfo1;
|
|
ULONG moduleNumber;
|
|
|
|
moduleInfo1 = &ModuleInfo->Modules[ 0 ];
|
|
for (moduleNumber=0; moduleNumber<ModuleInfo->NumberOfModules; moduleNumber++) {
|
|
if (!(moduleInfo1->Flags & LDRP_FAILED_BUILTIN_LOAD)) {
|
|
|
|
CHAR *moduleName, *s;
|
|
|
|
moduleName = &moduleInfo1->FullPathName[ moduleInfo1->OffsetToFileName ];
|
|
if (s = strchr( moduleName, '.' )) {
|
|
*s = '\0';
|
|
}
|
|
|
|
if (!_stricmp( moduleName, DriverName )) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
moduleInfo1++;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
DisableFailedSysInitDrivers(
|
|
PRTL_PROCESS_MODULES ModuleInfo
|
|
)
|
|
{
|
|
HANDLE keyHandle;
|
|
HANDLE subkeyHandle;
|
|
BOOL result;
|
|
CHAR registryPath[ MAX_PATH ];
|
|
ULONG subkey;
|
|
CHAR subkeyName[ MAX_PATH ];
|
|
ULONG subkeyNameLength;
|
|
FILETIME fileTime;
|
|
WCHAR startValue[ 16 ];
|
|
ULONG startValueLength;
|
|
ULONG status;
|
|
REG_INI_TABLE TempEntry;
|
|
|
|
//
|
|
// Get a handle to the Services entry in the registry to walk
|
|
// its tree.
|
|
//
|
|
|
|
TempEntry.RegistryPath = "SYS:Services";
|
|
TempEntry.Flags = 0;
|
|
OpenRegistryKey( &TempEntry, &keyHandle );
|
|
if (keyHandle != NULL) {
|
|
result = TRUE;
|
|
status = 0;
|
|
subkey = 0;
|
|
while (status == 0) {
|
|
subkeyNameLength = sizeof( subkeyName );
|
|
status = RegEnumKeyExA( keyHandle,
|
|
subkey,
|
|
subkeyName,
|
|
&subkeyNameLength,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&fileTime );
|
|
if (status == 0) {
|
|
if (!(strstr( subkeyName, "_Rec" ))) {
|
|
_snprintf( registryPath, sizeof( registryPath ), "SYS:Services\\%s", subkeyName );
|
|
TempEntry.RegistryPath = registryPath;
|
|
OpenRegistryKey( &TempEntry, &subkeyHandle );
|
|
if (subkeyHandle != NULL) {
|
|
startValueLength = sizeof( startValue );
|
|
if (ReadRegistry( subkeyHandle,
|
|
L"Start",
|
|
REG_DWORD,
|
|
startValue,
|
|
&startValueLength )) {
|
|
NtClose( subkeyHandle );
|
|
if (startValueLength == SERVICE_SYSTEM_START ||
|
|
startValueLength == SERVICE_BOOT_START
|
|
) {
|
|
|
|
//
|
|
// Driver located that should have been loaded at
|
|
// initialization time. Ensure in loaded module
|
|
// list.
|
|
//
|
|
|
|
if (!LookupModuleName( subkeyName, ModuleInfo )) {
|
|
if (EnableDisableDriver( subkeyName, FALSE )) {
|
|
DebugLog((DEB_TRACE_SETUP, " Disabled load of %s system init driver.\n", subkeyName ));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
subkey++;
|
|
}
|
|
NtClose( keyHandle );
|
|
}
|
|
else {
|
|
result = FALSE;
|
|
}
|
|
|
|
VirtualFree( ModuleInfo, 0, MEM_RELEASE );
|
|
return result;
|
|
}
|
|
|
|
|
|
BOOL bDebugCSRSS;
|
|
|
|
BOOL
|
|
InitializeDefaultRegistry(
|
|
PGLOBALS pGlobals
|
|
)
|
|
{
|
|
DWORD cb;
|
|
CHAR cbuff[512];
|
|
PRTL_PROCESS_MODULES moduleInfo;
|
|
|
|
|
|
//
|
|
// See if we have done first boot of triple boot sequence.
|
|
//
|
|
|
|
|
|
cb = GetProfileStringA( AnsiWinlogon,
|
|
"DefaultSystem",
|
|
NULL,
|
|
WinlogonSystemVariable,
|
|
sizeof( WinlogonSystemVariable )
|
|
);
|
|
|
|
if (cb == 0) {
|
|
|
|
//
|
|
// Yes, see if we are doing second boot of triple boot
|
|
// sequence.
|
|
//
|
|
|
|
cbuff[ 0 ] = '\0';
|
|
cb = GetProfileStringA( AnsiWinlogon,
|
|
"Shell",
|
|
NULL,
|
|
cbuff,
|
|
sizeof( cbuff )
|
|
);
|
|
|
|
if (cb != 0 && !_stricmp( cbuff, "progman.exe" )) {
|
|
|
|
//
|
|
// No must be third or greater boot. See if they
|
|
// want to disable debugging the server.
|
|
//
|
|
|
|
cb = GetProfileStringA( AnsiWinlogon,
|
|
"DebugServerCommand",
|
|
"ntsd -p -1 -g -G",
|
|
cbuff,
|
|
sizeof( cbuff )
|
|
);
|
|
|
|
if (cb != 0 && (_stricmp( cbuff, "no" ) || bDebugCSRSS)) {
|
|
//
|
|
// No, start the debugger
|
|
//
|
|
UNICODE_STRING UniString;
|
|
STRING String;
|
|
|
|
if (bDebugCSRSS) {
|
|
strcpy( cbuff, "ntsd -p -1 -g -G" );
|
|
}
|
|
|
|
RtlInitAnsiString(&String,cbuff);
|
|
RtlAnsiStringToUnicodeString(&UniString,&String,TRUE);
|
|
#if 0
|
|
ExecProcesses(L"DebugServerCommand",
|
|
UniString.Buffer,
|
|
APPLICATION_DESKTOP_NAME,
|
|
&pGlobals->UserProcessData,
|
|
HIGH_PRIORITY_CLASS,
|
|
STARTF_FORCEOFFFEEDBACK);
|
|
#endif
|
|
RtlFreeUnicodeString(&UniString);
|
|
}
|
|
}
|
|
else
|
|
if (cb != 0 && strstr( cbuff, "winlogon.cmd" )) {
|
|
WriteProfileStringA( AnsiWinlogon, "AutoAdminLogon", "1" );
|
|
|
|
WriteProfileStringA( AnsiWinlogon,
|
|
"DefaultUserName",
|
|
"Administrator"
|
|
);
|
|
|
|
WriteProfileStringA( AnsiWinlogon,
|
|
"DefaultPassword",
|
|
""
|
|
);
|
|
|
|
cb = sizeof( cbuff );
|
|
if (GetComputerNameA( cbuff, &cb )) {
|
|
WriteProfileStringA( AnsiWinlogon,
|
|
"DefaultDomainName",
|
|
cbuff
|
|
);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
TmppSetUnsecureDefaultDacl();
|
|
pLocalGlobals = pGlobals;
|
|
NetSetupGoingToRun = pGlobals->fExecuteSetup;
|
|
|
|
//
|
|
// Make sure we can see user (.default) portion of win.ini
|
|
//
|
|
|
|
if (!OpenProfileUserMapping()) {
|
|
DebugLog((DEB_TRACE_SETUP, " Unable to enable access to user specific portion of win.ini\n" ));
|
|
}
|
|
|
|
cb = SearchPathA(
|
|
NULL,
|
|
"net",
|
|
".exe",
|
|
512,
|
|
cbuff,
|
|
NULL
|
|
);
|
|
if ( cb && cb <= 512 ) {
|
|
NetFound = TRUE;
|
|
}
|
|
else {
|
|
NetFound = FALSE;
|
|
}
|
|
|
|
WriteProfileStringA( AnsiWinlogon,
|
|
"DefaultSystem",
|
|
NULL
|
|
);
|
|
WriteProfileStringA( AnsiWinlogon,
|
|
"System",
|
|
WinlogonSystemVariable
|
|
);
|
|
|
|
GetEnvironmentVariableA( "SystemRoot", InputFileName, sizeof( InputFileName ) );
|
|
strcat( InputFileName, "\\registry.ini" );
|
|
|
|
DebugLog((DEB_TRACE_SETUP, " Updating \\Registry and win.ini\n" ));
|
|
DebugLog((DEB_TRACE_SETUP, " with information from %s\n", InputFileName ));
|
|
|
|
if (!DisableFailedBuiltInDrivers( &moduleInfo )) {
|
|
DebugLog((DEB_TRACE_SETUP, " Failed to disable builtin drivers.\n" ));
|
|
}
|
|
else {
|
|
if (!DisableFailedSysInitDrivers( moduleInfo )) {
|
|
DebugLog((DEB_TRACE_SETUP, " Failed to disable system init drivers.\n" ));
|
|
}
|
|
}
|
|
|
|
DoFile();
|
|
|
|
//
|
|
// Set up the default username and domain so we logon as admin on next boot
|
|
//
|
|
|
|
WriteProfileStringA( AnsiWinlogon,
|
|
"DefaultUserName",
|
|
"Administrator"
|
|
);
|
|
|
|
WriteProfileStringA( AnsiWinlogon,
|
|
"DefaultDomainName",
|
|
SavedProductType == NtProductLanManNt ?
|
|
SavedDomainName : SavedMachineName
|
|
);
|
|
|
|
GenerateInitialCommandScript();
|
|
|
|
//
|
|
// All done accessing user (.default) portion of win.ini
|
|
//
|
|
|
|
CloseProfileUserMapping();
|
|
|
|
DebugLog((DEB_TRACE_SETUP, "Done updating. Rebooting to get changes.\n" ));
|
|
QuickReboot( pGlobals, FALSE );
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
QuickReboot(
|
|
PGLOBALS pGlobals,
|
|
BOOL RebootToAlternateOS
|
|
)
|
|
{
|
|
#ifdef i386
|
|
TCHAR szBuffer[ 64 ];
|
|
|
|
//
|
|
// Debug reboot facility to reboot directly into DOS by editing
|
|
// the users c:\boot.ini and changing the default boot OS to be
|
|
// whatever is in the root of C:, which is most likely DOS for
|
|
// people that are using NTLDR to dual boot. Only works for x86
|
|
// as MIPS uses ARCLOADER and it is not defined how to change its
|
|
// default operating system to load, other than through jzsetup.exe
|
|
//
|
|
|
|
if (RebootToAlternateOS) {
|
|
if (GetPrivateProfileString(TEXT("boot loader"),
|
|
TEXT("default"),
|
|
NULL,
|
|
szBuffer,
|
|
64,
|
|
TEXT("c:\\boot.ini")
|
|
)
|
|
) {
|
|
if (GetPrivateProfileString(WideWinlogon,
|
|
TEXT("DefaultAlternateOS"),
|
|
TEXT(""),
|
|
szBuffer,
|
|
64,
|
|
NULL
|
|
)
|
|
) {
|
|
WritePrivateProfileString(TEXT("boot loader"),
|
|
TEXT("default"),
|
|
szBuffer,
|
|
TEXT("c:\\boot.ini")
|
|
);
|
|
} else {
|
|
#if DBG
|
|
DbgPrint( "WINLOGON: GetPrivateProfileString( %ws, %ws ) failed (%u)\n",
|
|
WideWinlogon,
|
|
TEXT("DefaultAlternateOS"),
|
|
GetLastError()
|
|
);
|
|
#endif
|
|
}
|
|
}
|
|
else {
|
|
#if DBG
|
|
DbgPrint( "WINLOGON: GetPrivateProfileString( %ws, %ws ) failed (%u)\n",
|
|
TEXT("boot loader"),
|
|
TEXT("default"),
|
|
GetLastError()
|
|
);
|
|
#endif
|
|
}
|
|
}
|
|
#endif // i386
|
|
|
|
WriteProfileStringW( NULL, NULL, NULL );
|
|
EnablePrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE);
|
|
NtShutdownSystem(TRUE);
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
VOID
|
|
TmppSetUnsecureDefaultDacl( VOID )
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
PSID WorldSid;
|
|
PACL Dacl;
|
|
HANDLE Token;
|
|
|
|
TOKEN_DEFAULT_DACL DefaultDacl;
|
|
|
|
SID_IDENTIFIER_AUTHORITY
|
|
WorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
|
|
|
|
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(
|
|
&WorldSidAuthority,
|
|
1, //Sub authority count
|
|
SECURITY_WORLD_RID, //Sub authorities (up to 8)
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
&WorldSid
|
|
);
|
|
|
|
|
|
//
|
|
// Set our default protection so that regini won't protect
|
|
// registry keys it creates.
|
|
//
|
|
|
|
Dacl = RtlAllocateHeap( RtlProcessHeap(), 0, 256 );
|
|
ASSERT(Dacl != NULL);
|
|
|
|
Status = RtlCreateAcl( Dacl, 256, ACL_REVISION2);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(
|
|
Dacl,
|
|
ACL_REVISION2,
|
|
(GENERIC_ALL ),
|
|
WorldSid
|
|
);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
DefaultDacl.DefaultDacl = Dacl;
|
|
|
|
|
|
Status = NtOpenProcessToken(
|
|
NtCurrentProcess(),
|
|
(TOKEN_ADJUST_DEFAULT),
|
|
&Token
|
|
);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
|
|
Status = NtSetInformationToken(
|
|
Token,
|
|
TokenDefaultDacl,
|
|
&DefaultDacl,
|
|
(ULONG)sizeof(TOKEN_DEFAULT_DACL)
|
|
);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
Status = NtClose( Token );
|
|
|
|
RtlFreeHeap( RtlProcessHeap(), 0, Dacl );
|
|
RtlFreeSid( WorldSid );
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif // INIT_REGISTRY
|
|
|
|
|
|
//
|
|
// Open Registry key use base API. Same as OpenRegistryKey(),
|
|
// but without error handling (since GUI may not be active).
|
|
//
|
|
|
|
HANDLE
|
|
OpenNtRegKey(
|
|
WCHAR *UPath
|
|
)
|
|
{
|
|
char *Path;
|
|
char FullPath[ 2 * MAX_PATH ];
|
|
ANSI_STRING AnsiPath;
|
|
UNICODE_STRING UnicodePath;
|
|
NTSTATUS Status;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
HANDLE Handle;
|
|
UNICODE_STRING UString;
|
|
ANSI_STRING AString;
|
|
|
|
RtlInitUnicodeString( &UString, UPath);
|
|
RtlUnicodeStringToAnsiString( &AString, &UString, TRUE);
|
|
Path = AString.Buffer;
|
|
if (!_strnicmp( Path, "USR:", 4 )) {
|
|
strcpy( FullPath, "\\Registry\\User\\.Default\\" );
|
|
Path += 4;
|
|
}
|
|
else
|
|
if (!_strnicmp( Path, "SYS:", 4 )) {
|
|
strcpy( FullPath, "\\Registry\\Machine\\System\\CurrentControlSet\\" );
|
|
Path += 4;
|
|
}
|
|
else {
|
|
FullPath[ 0 ] = '\0';
|
|
}
|
|
strcat( FullPath, Path );
|
|
RtlInitAnsiString( &AnsiPath, FullPath );
|
|
RtlAnsiStringToUnicodeString( &UnicodePath, &AnsiPath, TRUE );
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
&UnicodePath,
|
|
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
|
NULL,
|
|
NULL
|
|
);
|
|
Status = NtOpenKey( &Handle,
|
|
MAXIMUM_ALLOWED,
|
|
&ObjectAttributes
|
|
);
|
|
|
|
RtlFreeUnicodeString( &UnicodePath );
|
|
RtlFreeAnsiString( &AString );
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
return Handle;
|
|
} else {
|
|
return NULL ;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL
|
|
ReadRegistry(
|
|
HANDLE KeyHandle, // Registry handle
|
|
WCHAR *ValueName, // Value to query
|
|
DWORD ValueType, // Value type expected
|
|
WCHAR *ValueData, // Value data if (multi-)string
|
|
DWORD *ValueLength // Length if string or value if REG_DWORD
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
UNICODE_STRING UnicodeString;
|
|
WCHAR ValueBuffer[ 512 ];
|
|
PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
|
|
ULONG ResultLength;
|
|
|
|
RtlInitUnicodeString( & UnicodeString, ValueName );
|
|
KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) ValueBuffer ;
|
|
Status = NtQueryValueKey( KeyHandle,
|
|
&UnicodeString,
|
|
KeyValuePartialInformation,
|
|
KeyValueInformation,
|
|
sizeof ValueBuffer,
|
|
&ResultLength
|
|
);
|
|
if (!NT_SUCCESS( Status )) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (KeyValueInformation->Type != ValueType) {
|
|
return FALSE ;
|
|
}
|
|
|
|
switch (KeyValueInformation->Type) {
|
|
case REG_MULTI_SZ:
|
|
case REG_SZ:
|
|
RtlMoveMemory( ValueData,
|
|
(PWSTR)KeyValueInformation->Data,
|
|
KeyValueInformation->DataLength
|
|
);
|
|
ValueData[ (KeyValueInformation->DataLength / sizeof( WCHAR )) - 1 ] = UNICODE_NULL;
|
|
*ValueLength = KeyValueInformation->DataLength;
|
|
break;
|
|
|
|
case REG_DWORD:
|
|
*ValueLength = *((DWORD *) KeyValueInformation->Data) ;
|
|
break;
|
|
|
|
default:
|
|
// We can't handle any other type.
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
WriteRegistry(
|
|
HANDLE KeyHandle,
|
|
char *ValueName,
|
|
DWORD ValueType,
|
|
char *ValueData,
|
|
DWORD ValueLength
|
|
)
|
|
{
|
|
char *s;
|
|
ANSI_STRING AnsiString;
|
|
UNICODE_STRING UnicodeString;
|
|
UNICODE_STRING UnicodeValueName;
|
|
DWORD ValueDword;
|
|
NTSTATUS Status;
|
|
|
|
if (ValueType == REG_SZ) {
|
|
if (!_strnicmp( ValueData, "REG_DWORD ", 10 )) {
|
|
Status = RtlCharToInteger( ValueData + 10, 0, &ValueDword );
|
|
if (!NT_SUCCESS( Status )) {
|
|
DeclareError( "Invalid integer\n" );
|
|
return FALSE;
|
|
}
|
|
|
|
ValueLength = sizeof( ValueDword );
|
|
ValueData = (char *)&ValueDword;
|
|
ValueType = REG_DWORD;
|
|
}
|
|
else {
|
|
if (strchr( ValueData, '%')) {
|
|
ValueType = REG_EXPAND_SZ;
|
|
}
|
|
|
|
RtlInitAnsiString( &AnsiString, ValueData );
|
|
ValueLength = 0;
|
|
}
|
|
}
|
|
else
|
|
if (ValueType == REG_MULTI_SZ) {
|
|
s = ValueData;
|
|
AnsiString.Buffer = ValueData;
|
|
while (*s) {
|
|
while (*s++) {
|
|
}
|
|
}
|
|
|
|
AnsiString.Length = (USHORT)(s - ValueData);
|
|
AnsiString.MaximumLength = (USHORT)(AnsiString.Length + 1);
|
|
ValueLength = 0;
|
|
}
|
|
else
|
|
if (ValueType == REG_BINARY) {
|
|
if (ValueLength == 0) {
|
|
DeclareError( "Invalid binary data\n" );
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
if (ValueType == REG_DWORD) {
|
|
Status = RtlCharToInteger( ValueData, 0, &ValueDword );
|
|
if (!NT_SUCCESS( Status )) {
|
|
DeclareError( "Invalid integer\n" );
|
|
return FALSE;
|
|
}
|
|
|
|
ValueLength = sizeof( ValueDword );
|
|
ValueData = (char *)&ValueDword;
|
|
}
|
|
else {
|
|
DeclareError( "Invalid data type == %lx for %s\n",
|
|
ValueType,
|
|
ValueName ? ValueName : "(null)"
|
|
);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if (ValueLength == 0) {
|
|
RtlAnsiStringToUnicodeString( &UnicodeString, &AnsiString, TRUE );
|
|
ValueLength = UnicodeString.MaximumLength;
|
|
ValueData = (char *)UnicodeString.Buffer;
|
|
}
|
|
else {
|
|
UnicodeString.Buffer = NULL;
|
|
}
|
|
|
|
if (ValueName == NULL) {
|
|
RtlInitUnicodeString( &UnicodeValueName, NULL );
|
|
}
|
|
else {
|
|
RtlInitAnsiString( &AnsiString, ValueName );
|
|
RtlAnsiStringToUnicodeString( &UnicodeValueName, &AnsiString, TRUE );
|
|
}
|
|
Status = NtSetValueKey( KeyHandle,
|
|
&UnicodeValueName,
|
|
0,
|
|
ValueType,
|
|
ValueData,
|
|
ValueLength
|
|
);
|
|
|
|
if (UnicodeValueName.Buffer != NULL) {
|
|
RtlFreeUnicodeString( &UnicodeValueName );
|
|
}
|
|
|
|
if (UnicodeString.Buffer != NULL) {
|
|
RtlFreeUnicodeString( &UnicodeString );
|
|
}
|
|
|
|
if (NT_SUCCESS( Status )) {
|
|
return TRUE;
|
|
}
|
|
else {
|
|
DeclareError( "NtSetValueKey( %wZ ) failed (Status == %lx)\n",
|
|
&UnicodeValueName,
|
|
Status
|
|
);
|
|
|
|
return FALSE;
|
|
}
|
|
}
|