|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
win31io.c
Abstract:
This file contains Win 3.1 Inter-Operability functions.
Author:
Steve Wood (stevewo) 21-Feb-1993
Revision History:
--*/
#include "advapi.h"
#include <stdio.h>
#include <winbasep.h>
#include "win31io.h"
#define EVENTLOG_SOURCE "Windows 3.1 Migration"
BOOL WaitForEventLogToStart( VOID );
#define SIZE_OF_TOKEN_INFORMATION \
sizeof( TOKEN_USER ) \ + sizeof( SID ) \ + sizeof( ULONG ) * SID_MAX_SUB_AUTHORITIES
typedef struct _WIN31IO_STATE { HANDLE EventLog; HANDLE SoftwareRoot; HANDLE UserRoot; HANDLE Win31IOKey; BOOL QueryOnly; PWSTR WindowsPath; PWSTR FileNamePart; PWSTR WorkBuffer; ULONG cchWorkBuffer; PWIN31IO_STATUS_CALLBACK StatusCallback; PVOID CallbackParameter; WCHAR szWindowsDirectory[ MAX_PATH ]; PSID UserSid; UCHAR TokenInformation[ SIZE_OF_TOKEN_INFORMATION ]; WCHAR QueryBuffer[ 64 ]; } WIN31IO_STATE, *PWIN31IO_STATE;
HANDLE OpenCreateKey( IN HANDLE Root, IN PWSTR Path, IN BOOL WriteAccess );
BOOL SnapShotWin31IniFilesToRegistry( IN OUT PWIN31IO_STATE State );
BOOL SnapShotWin31GroupsToRegistry( IN OUT PWIN31IO_STATE State );
BOOL SnapShotWin31RegDatToRegistry( IN OUT PWIN31IO_STATE State );
BOOL InitializeWin31State( IN WIN31IO_EVENT EventType, OUT PWIN31IO_STATE State );
VOID TerminateWin31State( IN WIN31IO_EVENT EventType, IN OUT PWIN31IO_STATE State );
BOOL InitializeWin31State( IN WIN31IO_EVENT EventType, OUT PWIN31IO_STATE State ) { NTSTATUS Status; ULONG cch; HANDLE TokenHandle; ULONG ReturnLength;
memset( State, 0, sizeof( *State ) ); cch = GetWindowsDirectoryW( State->szWindowsDirectory, sizeof( State->szWindowsDirectory ) / sizeof (WCHAR) ); State->WindowsPath = State->szWindowsDirectory; State->FileNamePart = State->WindowsPath + cch; *State->FileNamePart++ = OBJ_NAME_PATH_SEPARATOR;
if (EventType == Win31SystemStartEvent) { State->SoftwareRoot = OpenCreateKey( NULL, L"\\Registry\\Machine\\Software", FALSE ); if (State->SoftwareRoot == NULL) { return FALSE; } } else { Status = RtlOpenCurrentUser( GENERIC_READ, &State->UserRoot ); if (!NT_SUCCESS( Status )) { BaseSetLastNTError( Status ); return FALSE; }
if (OpenThreadToken( GetCurrentThread(), TOKEN_READ, TRUE, &TokenHandle ) || OpenProcessToken( GetCurrentProcess(), TOKEN_READ, &TokenHandle ) ) { if (GetTokenInformation( TokenHandle, TokenUser, &State->TokenInformation, sizeof( State->TokenInformation ), &ReturnLength ) ) { PTOKEN_USER UserToken = (PTOKEN_USER)&State->TokenInformation;
State->UserSid = UserToken->User.Sid; }
CloseHandle( TokenHandle ); } }
State->Win31IOKey = OpenCreateKey( EventType == Win31SystemStartEvent ? State->SoftwareRoot : State->UserRoot, L"Windows 3.1 Migration Status", TRUE ); if (State->Win31IOKey == NULL) { if (State->SoftwareRoot != NULL) { NtClose( State->SoftwareRoot ); }
if (State->UserRoot != NULL) { NtClose( State->UserRoot ); }
if (State->EventLog != NULL) { DeregisterEventSource( State->EventLog ); }
return FALSE; } else { return TRUE; }
return TRUE; }
VOID TerminateWin31State( IN WIN31IO_EVENT EventType, IN OUT PWIN31IO_STATE State ) { if (State->Win31IOKey != NULL) { NtClose( State->Win31IOKey ); }
if (State->SoftwareRoot != NULL) { NtClose( State->SoftwareRoot ); }
if (State->UserRoot != NULL) { NtClose( State->UserRoot ); }
if (State->EventLog != NULL && State->EventLog != INVALID_HANDLE_VALUE) { DeregisterEventSource( State->EventLog ); }
return; }
#define MAX_EVENT_STRINGS 8
VOID ReportWin31IOEvent( IN PWIN31IO_STATE State, IN WORD EventType, IN DWORD EventId, IN DWORD SizeOfRawData, IN PVOID RawData, IN DWORD NumberOfStrings, ... ) { va_list arglist; ULONG i; PWSTR Strings[ MAX_EVENT_STRINGS ];
va_start( arglist, NumberOfStrings );
if (NumberOfStrings > MAX_EVENT_STRINGS) { NumberOfStrings = MAX_EVENT_STRINGS; }
for (i=0; i<NumberOfStrings; i++) { Strings[ i ] = va_arg( arglist, PWSTR ); }
if (State->EventLog == NULL) { State->EventLog = RegisterEventSource( NULL, EVENTLOG_SOURCE ); if (State->EventLog == NULL) { if (WaitForEventLogToStart()) { State->EventLog = RegisterEventSource( NULL, EVENTLOG_SOURCE ); }
if (State->EventLog == NULL) { KdPrint(( "WIN31IO: RegisterEventSource( %s ) failed - %u\n", EVENTLOG_SOURCE, GetLastError() )); State->EventLog = INVALID_HANDLE_VALUE; return; } } }
if (State->EventLog != INVALID_HANDLE_VALUE) { if (!ReportEventW( State->EventLog, EventType, 0, // event category
EventId, State->UserSid, (WORD)NumberOfStrings, SizeOfRawData, Strings, RawData ) ) { KdPrint(( "WIN31IO: ReportEvent( %u ) failed - %u\n", EventId, GetLastError() )); } } }
int Win31IOExceptionHandler( IN DWORD ExceptionCode, IN PEXCEPTION_POINTERS ExceptionInfo, IN OUT PWIN31IO_STATE State );
int Win31IOExceptionHandler( IN DWORD ExceptionCode, IN PEXCEPTION_POINTERS ExceptionInfo, IN OUT PWIN31IO_STATE State ) { KdPrint(( "WIN31IO: Unexpected exception %08x at %08x referencing %08x\n", ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress, ExceptionInfo->ExceptionRecord->ExceptionInformation[ 1 ] ));
//
// Unexpected exception. Log the event with the exception record
// so we can figure it out later.
//
ReportWin31IOEvent( State, EVENTLOG_ERROR_TYPE, WIN31IO_EVENT_EXCEPTION, sizeof( *(ExceptionInfo->ExceptionRecord) ), ExceptionInfo->ExceptionRecord, 0 );
return EXCEPTION_EXECUTE_HANDLER; }
DWORD WINAPI QueryWindows31FilesMigration( IN WIN31IO_EVENT EventType ) { DWORD Flags; WIN31IO_STATE State;
if (EventType == Win31LogoffEvent) { return 0; }
if (!InitializeWin31State( EventType, &State )) { return 0; }
State.QueryOnly = TRUE; State.WorkBuffer = State.QueryBuffer; State.cchWorkBuffer = sizeof( State.QueryBuffer ) / sizeof( WCHAR ); Flags = 0;
try { try { if (EventType == Win31SystemStartEvent) { if (SnapShotWin31IniFilesToRegistry( &State )) { Flags |= WIN31_MIGRATE_INIFILES; }
if (SnapShotWin31RegDatToRegistry( &State )) { Flags |= WIN31_MIGRATE_REGDAT; } } else { if (SnapShotWin31IniFilesToRegistry( &State )) { Flags |= WIN31_MIGRATE_INIFILES; }
if (SnapShotWin31GroupsToRegistry( &State )) { Flags |= WIN31_MIGRATE_GROUPS; } } } except( Win31IOExceptionHandler( GetExceptionCode(), GetExceptionInformation(), &State ) ) { BaseSetLastNTError( GetExceptionCode() ); } } finally { TerminateWin31State( EventType, &State ); }
return Flags; }
BOOL WINAPI SynchronizeWindows31FilesAndWindowsNTRegistry( IN WIN31IO_EVENT EventType, IN DWORD Flags, IN PWIN31IO_STATUS_CALLBACK StatusCallback, IN PVOID CallbackParameter ) { BOOL Result; VIRTUAL_BUFFER Buffer; ULONG cch; WIN31IO_STATE State;
if (Flags == 0 || EventType == Win31LogoffEvent) { return TRUE; }
if (!InitializeWin31State( EventType, &State )) { return TRUE; } State.QueryOnly = FALSE; State.StatusCallback = StatusCallback; State.CallbackParameter = CallbackParameter;
Result = FALSE; try { try { try { cch = ((64 * 1024) / sizeof( WCHAR )) - 1; if (!CreateVirtualBuffer( &Buffer, cch * sizeof( WCHAR ), cch * sizeof( WCHAR ) )) { leave; }
State.WorkBuffer = Buffer.Base; State.cchWorkBuffer = cch;
Result = TRUE; if (EventType == Win31SystemStartEvent) { if (Flags & WIN31_MIGRATE_INIFILES) { Result &= SnapShotWin31IniFilesToRegistry( &State ); }
if (Flags & WIN31_MIGRATE_REGDAT) { Result &= SnapShotWin31RegDatToRegistry( &State ); } } else { if (Flags & WIN31_MIGRATE_INIFILES) { Result &= SnapShotWin31IniFilesToRegistry( &State ); }
if (Flags & WIN31_MIGRATE_GROUPS) { Result &= SnapShotWin31GroupsToRegistry( &State ); } } } except( VirtualBufferExceptionHandler( GetExceptionCode(), GetExceptionInformation(), &Buffer ) ) { if (GetExceptionCode() == STATUS_ACCESS_VIOLATION) { BaseSetLastNTError( STATUS_NO_MEMORY ); } else { BaseSetLastNTError( GetExceptionCode() ); }
Result = FALSE; } } except( Win31IOExceptionHandler( GetExceptionCode(), GetExceptionInformation(), &State ) ) { BaseSetLastNTError( GetExceptionCode() ); Result = FALSE; } } finally { TerminateWin31State( EventType, &State ); FreeVirtualBuffer( &Buffer ); }
return Result; }
BOOL SnapShotWin31IniFileKey( IN OUT PWIN31IO_STATE State, IN PWSTR TempFileName, IN PWSTR FileName, IN PWSTR ApplicationName, IN PWSTR KeyName );
BOOL SnapShotWin31IniFileSection( IN OUT PWIN31IO_STATE State, IN PWSTR TempFileName, IN PWSTR FileName, IN PWSTR ApplicationName );
BOOL SnapShotWin31IniFileSections( IN OUT PWIN31IO_STATE State, IN PWSTR TempFileName, IN PWSTR FileName );
BOOL SnapShotWin31IniFilesToRegistry( IN OUT PWIN31IO_STATE State ) { BOOL Result; PWSTR s, s1, FileName, ApplicationName, KeyName; ULONG n; PWSTR CurrentFileName; WCHAR Win31IniFileName[ MAX_PATH ]; WCHAR TempIniFileName[ MAX_PATH ]; HANDLE FindHandle; WIN32_FIND_DATAW FindFileData; HANDLE MigrationKey, Key; ULONG cchBufferUsed;
MigrationKey = OpenCreateKey( State->Win31IOKey, L"IniFiles", !State->QueryOnly ); if (State->QueryOnly) { if (MigrationKey != NULL) { NtClose( MigrationKey ); return FALSE; } } else { if (MigrationKey == NULL) { return FALSE; } }
Result = FALSE; wcscpy( State->FileNamePart, L"system.ini" ); FindHandle = FindFirstFileW( State->WindowsPath, &FindFileData ); if (FindHandle != INVALID_HANDLE_VALUE) { FindClose( FindHandle ); if (FindFileData.nFileSizeLow > 1024) { Result = TRUE; } }
if (!Result || State->QueryOnly) { if (MigrationKey == NULL) { MigrationKey = OpenCreateKey( State->Win31IOKey, L"IniFiles", TRUE ); }
if (MigrationKey != NULL) { NtClose( MigrationKey ); }
return Result; }
cchBufferUsed = 0; if (State->UserRoot != NULL) { Result = QueryWin31IniFilesMappedToRegistry( WIN31_INIFILES_MAPPED_TO_USER, State->WorkBuffer, State->cchWorkBuffer, &cchBufferUsed ); } else { Result = QueryWin31IniFilesMappedToRegistry( WIN31_INIFILES_MAPPED_TO_SYSTEM, State->WorkBuffer, State->cchWorkBuffer, &cchBufferUsed ); }
if (Result) { s = State->WorkBuffer; State->WorkBuffer += cchBufferUsed; State->cchWorkBuffer -= cchBufferUsed; CurrentFileName = NULL; TempIniFileName[ 0 ] = UNICODE_NULL; do { FileName = (PWSTR)((*s == UNICODE_NULL) ? NULL : s); while (*s++) { ; } ApplicationName = (PWSTR)((*s == UNICODE_NULL) ? NULL : s); while (*s++) { ; } KeyName = (PWSTR)((*s == UNICODE_NULL) ? NULL : s); while (*s++) { ; }
if (FileName) { if (!CurrentFileName || _wcsicmp( FileName, CurrentFileName )) { if (TempIniFileName[ 0 ] != UNICODE_NULL) { WritePrivateProfileStringW( NULL, NULL, NULL, L"" ); if (!DeleteFileW( TempIniFileName )) { KdPrint(( "WIN31IO: DeleteFile( %ws ) - failed (%u)\n", TempIniFileName, GetLastError() )); }
TempIniFileName[ 0 ] = UNICODE_NULL; }
CurrentFileName = NULL; GetWindowsDirectoryW( Win31IniFileName, sizeof( Win31IniFileName ) / sizeof (WCHAR) ); wcscat( Win31IniFileName, L"\\" ); wcscat( Win31IniFileName, FileName ); wcscpy( TempIniFileName, Win31IniFileName ); _wcslwr( TempIniFileName ); s1 = wcsstr( TempIniFileName, L".ini" ); if (!s1) { s1 = wcschr( TempIniFileName, UNICODE_NULL ); if (s1[-1] == L'.') { s1--; } } n = 0; while (n < 1000) { swprintf( s1, L".%03u", n++ ); if (CopyFileW( Win31IniFileName, TempIniFileName, TRUE )) { if (State->StatusCallback != NULL) { (State->StatusCallback)( FileName, State->CallbackParameter ); } Key = OpenCreateKey( MigrationKey, FileName, TRUE ); if (Key != NULL) { NtClose( Key ); } CurrentFileName = FileName; break; } else if (GetLastError() != ERROR_FILE_EXISTS) { if (GetLastError() != ERROR_FILE_NOT_FOUND) { KdPrint(("WIN31IO: CopyFile( %ws, %ws ) failed - %u\n", Win31IniFileName, TempIniFileName, GetLastError() )); } break; } }
if (CurrentFileName == NULL) { TempIniFileName[ 0 ] = UNICODE_NULL; CurrentFileName = FileName; } }
if (TempIniFileName[ 0 ] != UNICODE_NULL) { if (ApplicationName) { if (KeyName) { if (SnapShotWin31IniFileKey( State, TempIniFileName, FileName, ApplicationName, KeyName ) ) { ReportWin31IOEvent( State, EVENTLOG_INFORMATION_TYPE, WIN31IO_EVENT_MIGRATE_INI_VARIABLE, 0, NULL, 3, KeyName, ApplicationName, FileName ); } else { ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_INI_VARIABLE_FAILED, 0, NULL, 3, KeyName, ApplicationName, FileName ); }
} else { if (SnapShotWin31IniFileSection( State, TempIniFileName, FileName, ApplicationName ) ) { ReportWin31IOEvent( State, EVENTLOG_INFORMATION_TYPE, WIN31IO_EVENT_MIGRATE_INI_SECTION, 0, NULL, 2, ApplicationName, FileName ); } else { ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_INI_SECTION_FAILED, 0, NULL, 2, ApplicationName, FileName ); }
} } else { if (SnapShotWin31IniFileSections( State, TempIniFileName, FileName ) ) { ReportWin31IOEvent( State, EVENTLOG_INFORMATION_TYPE, WIN31IO_EVENT_MIGRATE_INI_FILE, 0, NULL, 1, FileName ); } else { ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_INI_FILE_FAILED, 0, NULL, 1, FileName ); } } } } } while (*s != UNICODE_NULL);
State->WorkBuffer -= cchBufferUsed; State->cchWorkBuffer += cchBufferUsed; }
if (TempIniFileName[ 0 ] != UNICODE_NULL) { WritePrivateProfileStringW( NULL, NULL, NULL, L"" ); if (!DeleteFileW( TempIniFileName )) { KdPrint(( "WIN31IO: DeleteFile( %ws ) - failed (%u)\n", TempIniFileName, GetLastError() )); } }
if (MigrationKey != NULL) { NtClose( MigrationKey ); } return Result; }
BOOL SnapShotWin31IniFileKey( IN OUT PWIN31IO_STATE State, IN PWSTR TempFileName, IN PWSTR FileName, IN PWSTR ApplicationName, IN PWSTR KeyName ) { ULONG cch;
cch = GetPrivateProfileStringW( ApplicationName, KeyName, NULL, State->WorkBuffer, State->cchWorkBuffer, TempFileName ); if (cch != 0) { if (WritePrivateProfileStringW( ApplicationName, KeyName, State->WorkBuffer, FileName ) ) { return TRUE; } else { KdPrint(( "WIN31IO: Copy to %ws [%ws].%ws == %ws (failed - %u)\n", FileName, ApplicationName, KeyName, State->WorkBuffer, GetLastError() )); return FALSE; } } else { return TRUE; } }
BOOL SnapShotWin31IniFileSection( IN OUT PWIN31IO_STATE State, IN PWSTR TempFileName, IN PWSTR FileName, IN PWSTR ApplicationName ) { BOOL Result; PWSTR KeyName; ULONG cch;
Result = TRUE; cch = GetPrivateProfileStringW( ApplicationName, NULL, NULL, State->WorkBuffer, State->cchWorkBuffer, TempFileName ); if (cch != 0) { KeyName = State->WorkBuffer; cch += 1; // Account for extra null
State->WorkBuffer += cch; State->cchWorkBuffer -= cch; while (*KeyName != UNICODE_NULL) { Result &= SnapShotWin31IniFileKey( State, TempFileName, FileName, ApplicationName, KeyName );
while (*KeyName++) { ; } }
State->WorkBuffer -= cch; State->cchWorkBuffer += cch; }
return Result; }
BOOL SnapShotWin31IniFileSections( IN OUT PWIN31IO_STATE State, IN PWSTR TempFileName, IN PWSTR FileName ) { BOOL Result; PWSTR ApplicationName; ULONG cch;
Result = TRUE; cch = GetPrivateProfileStringW( NULL, NULL, NULL, State->WorkBuffer, State->cchWorkBuffer, TempFileName ); if (cch != 0) { ApplicationName = State->WorkBuffer; cch += 1; // Account for extra null
State->WorkBuffer += cch; State->cchWorkBuffer -= cch; while (*ApplicationName != UNICODE_NULL) { Result &= SnapShotWin31IniFileSection( State, TempFileName, FileName, ApplicationName );
while (*ApplicationName++) { ; } }
State->WorkBuffer -= cch; State->cchWorkBuffer += cch; }
return Result; }
BOOL ConvertWindows31GroupsToRegistry( IN OUT PWIN31IO_STATE State, IN HANDLE MigrationKey, IN HANDLE CommonGroupsKey, IN HANDLE PersonalGroupsKey, IN PWSTR IniFileName, IN PWSTR GroupNames, IN ULONG nGroupNames );
BOOL SnapShotWin31GroupsToRegistry( IN OUT PWIN31IO_STATE State ) { BOOL Result; PWSTR GroupNames, s; DWORD nGroupNames, cchGroupNames; HANDLE MigrationKey, PersonalGroupsKey, CommonGroupsKey;
MigrationKey = OpenCreateKey( State->Win31IOKey, L"Groups", !State->QueryOnly ); if (State->QueryOnly) { if (MigrationKey != NULL) { NtClose( MigrationKey ); return FALSE; } } else { if (MigrationKey == NULL) { return FALSE; } }
Result = FALSE; wcscpy( State->FileNamePart, L"progman.ini" ); if (GetFileAttributesW( State->WindowsPath ) != 0xFFFFFFFF) { cchGroupNames = GetPrivateProfileStringW( L"Groups", NULL, L"", State->WorkBuffer, State->cchWorkBuffer, State->WindowsPath ); if (cchGroupNames != 0) { Result = TRUE; } }
if (!Result || State->QueryOnly) { if (MigrationKey == NULL) { MigrationKey = OpenCreateKey( State->Win31IOKey, L"Groups", TRUE ); }
if (MigrationKey != NULL) { NtClose( MigrationKey ); }
return Result; }
if (cchGroupNames) { PersonalGroupsKey = OpenCreateKey( State->UserRoot, L"UNICODE Program Groups", !State->QueryOnly ); if (PersonalGroupsKey == NULL) { if (MigrationKey != NULL) { NtClose( MigrationKey ); }
return FALSE; }
CommonGroupsKey = OpenCreateKey( NULL, L"\\Registry\\Machine\\Software\\Program Groups", FALSE ); GroupNames = s = State->WorkBuffer; nGroupNames = 0; while (*s) { while (*s++) { ; }
nGroupNames += 1; } State->WorkBuffer = s + 1; State->cchWorkBuffer -= cchGroupNames + 1;
ConvertWindows31GroupsToRegistry( State, MigrationKey, CommonGroupsKey, PersonalGroupsKey, State->WindowsPath, GroupNames, nGroupNames );
State->WorkBuffer = GroupNames, State->cchWorkBuffer += cchGroupNames + 1;
NtClose( PersonalGroupsKey ); if (CommonGroupsKey != NULL) { NtClose( CommonGroupsKey ); } }
if (MigrationKey != NULL) { NtClose( MigrationKey ); }
return TRUE; }
BOOL ConvertWindows31GroupsToRegistry( IN OUT PWIN31IO_STATE State, IN HANDLE MigrationKey, IN HANDLE CommonGroupsKey, IN HANDLE PersonalGroupsKey, IN PWSTR IniFileName, IN PWSTR GroupNames, IN ULONG nGroupNames ) { BOOL Result; NTSTATUS Status; PGROUP_DEF16 Group16; PGROUP_DEF Group32; UNICODE_STRING Group32Name; PWSTR Group16PathName; PWSTR Group16FileName; PWSTR s; ANSI_STRING AnsiString; ULONG NumberOfPersonalGroupNames; ULONG OldNumberOfPersonalGroupNames; HANDLE GroupNamesKey, SettingsKey, Key;
NumberOfPersonalGroupNames = QueryNumberOfPersonalGroupNames( State->UserRoot, &GroupNamesKey, &SettingsKey ); OldNumberOfPersonalGroupNames = NumberOfPersonalGroupNames;
Result = TRUE; while (*GroupNames) { //
// Get the group file (.grp) name
//
if (GetPrivateProfileStringW( L"Groups", GroupNames, L"", State->WorkBuffer, State->cchWorkBuffer, IniFileName ) ) { Group16PathName = State->WorkBuffer; Group16 = LoadGroup16( Group16PathName ); if (Group16 != NULL) { Group16FileName = Group16PathName + wcslen( Group16PathName ); while (Group16FileName > Group16PathName) { if (Group16FileName[ -1 ] == OBJ_NAME_PATH_SEPARATOR) { break; }
Group16FileName -= 1; }
//
// Get the group name.
//
if (Group16->pName == 0) { RtlInitUnicodeString( &Group32Name, Group16FileName ); Status = STATUS_SUCCESS; } else { RtlInitAnsiString( &AnsiString, (PSZ)PTR( Group16, Group16->pName ) ); Status = RtlAnsiStringToUnicodeString( &Group32Name, &AnsiString, TRUE ); s = Group32Name.Buffer; while (*s) { if (*s == OBJ_NAME_PATH_SEPARATOR) { *s = L'/'; } s += 1; } }
if (NT_SUCCESS( Status )) { if (DoesExistGroup( PersonalGroupsKey, Group32Name.Buffer )) { ReportWin31IOEvent( State, EVENTLOG_INFORMATION_TYPE, WIN31IO_EVENT_MIGRATE_GROUP_EXISTS, 0, NULL, 2, Group16PathName, Group32Name.Buffer ); } else if (DoesExistGroup( CommonGroupsKey, Group32Name.Buffer )) { ReportWin31IOEvent( State, EVENTLOG_INFORMATION_TYPE, WIN31IO_EVENT_MIGRATE_GROUP_EXISTS, 0, NULL, 2, Group16PathName, Group32Name.Buffer ); } else { // DumpGroup16( State->WorkBuffer, Group16 );
Group32 = CreateGroupFromGroup16( AnsiString.Buffer, Group16 ); if (Group32 != NULL) { if (Group32 == (PGROUP_DEF)-1) { ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_GROUP_FAILED4, 0, NULL, 1, Group32Name.Buffer ); Group32 = NULL; } else { // DumpGroup( Group32Name.Buffer, Group32 );
if (!SaveGroup( PersonalGroupsKey, Group32Name.Buffer, Group32 ) ) { ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_GROUP_FAILED, 0, NULL, 1, Group32Name.Buffer ); } else if (!NewPersonalGroupName( GroupNamesKey, Group32Name.Buffer, NumberOfPersonalGroupNames+1 ) ) { DeleteGroup( PersonalGroupsKey, Group32Name.Buffer ); ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_GROUP_FAILED, 0, NULL, 1, Group32Name.Buffer ); } else { if (State->StatusCallback != NULL) { (State->StatusCallback)( Group16FileName, State->CallbackParameter ); } ReportWin31IOEvent( State, EVENTLOG_INFORMATION_TYPE, WIN31IO_EVENT_MIGRATE_GROUP, 0, NULL, 1, Group32Name.Buffer ); NumberOfPersonalGroupNames += 1; Key = OpenCreateKey( MigrationKey, Group16FileName, TRUE ); if (Key != NULL) { NtClose( Key ); } else { KdPrint(("WIN31IO: (3)Unable to create sub migration key for %ws (%u)\n", State->WorkBuffer, GetLastError() )); } }
UnloadGroup( Group32 ); } } else { WCHAR ErrorCode[ 32 ];
_snwprintf( ErrorCode, sizeof( ErrorCode ) / sizeof( WCHAR ), L"%u", GetLastError() ); ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_GROUP_FAILED1, 0, NULL, 2, State->WorkBuffer, ErrorCode ); } }
RtlFreeUnicodeString( &Group32Name ); }
UnloadGroup16( Group16 ); } else { WCHAR ErrorCode[ 32 ];
_snwprintf( ErrorCode, sizeof( ErrorCode ) / sizeof( WCHAR ), L"%u", GetLastError() ); ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_GROUP_FAILED1, 0, NULL, 2, State->WorkBuffer, ErrorCode ); } } else { ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_GROUP_FAILED2, 0, NULL, 2, IniFileName, GroupNames ); }
while (*GroupNames++) { ; } }
if (OldNumberOfPersonalGroupNames != NumberOfPersonalGroupNames) { UNICODE_STRING ValueName; ULONG ValueData = TRUE;
RtlInitUnicodeString( &ValueName, L"InitialArrange" ); Status = NtSetValueKey( SettingsKey, &ValueName, 0, REG_DWORD, &ValueData, sizeof( ValueData ) ); #if DBG
if (!NT_SUCCESS( Status )) { KdPrint(( "WIN31IO: Unable to set value of %wZ - Status == %x\n", &ValueName, Status )); } #endif
}
NtClose( SettingsKey ); NtClose( GroupNamesKey ); return Result; }
BOOL SnapShotWin31RegDatToRegistry( IN OUT PWIN31IO_STATE State ) { BOOL Result; HANDLE MigrationKey; PREG_HEADER16 RegDat16;
MigrationKey = OpenCreateKey( State->Win31IOKey, L"REG.DAT", !State->QueryOnly ); if (State->QueryOnly) { if (MigrationKey != NULL) { NtClose( MigrationKey ); return FALSE; } } else { if (MigrationKey == NULL) { return FALSE; } }
Result = FALSE; wcscpy( State->FileNamePart, L"reg.dat" ); if (GetFileAttributesW( State->WindowsPath ) != 0xFFFFFFFF) { Result = TRUE; }
if (!Result || State->QueryOnly) { if (MigrationKey == NULL) { MigrationKey = OpenCreateKey( State->Win31IOKey, L"REG.DAT", TRUE ); }
if (MigrationKey != NULL) { NtClose( MigrationKey ); }
return Result; }
RegDat16 = LoadRegistry16( State->WindowsPath ); if (RegDat16 != NULL) { if (State->StatusCallback != NULL) { (State->StatusCallback)( State->WindowsPath, State->CallbackParameter ); }
if (CreateRegistryClassesFromRegistry16( State->SoftwareRoot, RegDat16 )) { ReportWin31IOEvent( State, EVENTLOG_INFORMATION_TYPE, WIN31IO_EVENT_MIGRATE_REGDAT, 0, NULL, 1, State->WindowsPath ); } else { ReportWin31IOEvent( State, EVENTLOG_WARNING_TYPE, WIN31IO_EVENT_MIGRATE_REGDAT_FAILED, 0, NULL, 1, State->WindowsPath ); } UnloadRegistry16( RegDat16 ); }
if (MigrationKey != NULL) { NtClose( MigrationKey ); }
return TRUE; }
#define SERVICE_TO_WAIT_FOR "EventLog"
#define MAX_TICKS_WAIT 90000 // ms
BOOL WaitForEventLogToStart( VOID ) { BOOL bStarted = FALSE; DWORD StartTickCount; DWORD dwOldCheckPoint = (DWORD)-1; SC_HANDLE hScManager = NULL; SC_HANDLE hService = NULL; SERVICE_STATUS ServiceStatus;
if ((hScManager = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT ) ) == (SC_HANDLE) NULL ) { KdPrint(("WIN31IO: IsNetworkStarted: OpenSCManager failed, error = %d\n", GetLastError())); goto Exit; }
//
// OpenService
//
if ((hService = OpenService( hScManager, SERVICE_TO_WAIT_FOR, SERVICE_QUERY_STATUS ) ) == (SC_HANDLE) NULL ) { KdPrint(("WIN31IO: IsNetworkStarted: OpenService failed, error = %d\n", GetLastError())); goto Exit; }
//
// Loop until the service starts or we think it never will start
// or we've exceeded our maximum time delay.
//
StartTickCount = GetTickCount(); while (!bStarted) {
if ((GetTickCount() - StartTickCount) > MAX_TICKS_WAIT) { KdPrint(("WIN31IO: Max wait exceeded waiting for service <%s> to start\n", SERVICE_TO_WAIT_FOR)); break; }
if (!QueryServiceStatus( hService, &ServiceStatus )) { KdPrint(("WIN31IO: IsNetworkStarted: QueryServiceStatus failed, error = %d\n", GetLastError())); break; }
if (ServiceStatus.dwCurrentState == SERVICE_STOPPED) { KdPrint(("WIN31IO: Service STOPPED"));
if (ServiceStatus.dwWin32ExitCode == ERROR_SERVICE_NEVER_STARTED) { KdPrint(("WIN31IO: Waiting for 3 secs")); Sleep(3000); } else { KdPrint(("WIN31IO: Service exit code = %d, returning failure\n", ServiceStatus.dwWin32ExitCode)); break; } } else if ( (ServiceStatus.dwCurrentState == SERVICE_RUNNING) || (ServiceStatus.dwCurrentState == SERVICE_CONTINUE_PENDING) || (ServiceStatus.dwCurrentState == SERVICE_PAUSE_PENDING) || (ServiceStatus.dwCurrentState == SERVICE_PAUSED) ) { bStarted = TRUE; } else if (ServiceStatus.dwCurrentState == SERVICE_START_PENDING) {
//
// Wait to give a chance for the network to start.
//
Sleep( ServiceStatus.dwWaitHint ); } else { KdPrint(( "WIN31IO: Service in unknown state : %d\n", ServiceStatus.dwCurrentState )); } }
Exit: if (hScManager != NULL) { CloseServiceHandle( hScManager ); } if (hService != NULL) { CloseServiceHandle( hService ); }
return( bStarted ); }
HANDLE OpenCreateKey( IN HANDLE Root, IN PWSTR Path, IN BOOL WriteAccess ) { NTSTATUS Status; HANDLE Key; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; ULONG CreateDisposition;
RtlInitUnicodeString( &KeyName, Path ); InitializeObjectAttributes( &ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, Root, NULL ); Status = NtOpenKey( &Key, WriteAccess ? (STANDARD_RIGHTS_WRITE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_SET_VALUE | KEY_CREATE_SUB_KEY ) : GENERIC_READ, &ObjectAttributes ); if (NT_SUCCESS( Status )) { return Key; } else if (!WriteAccess) { BaseSetLastNTError( Status ); return NULL; }
Status = NtCreateKey( &Key, STANDARD_RIGHTS_WRITE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_SET_VALUE | KEY_CREATE_SUB_KEY, &ObjectAttributes, 0, NULL, 0, &CreateDisposition ); if (!NT_SUCCESS( Status )) { BaseSetLastNTError( Status ); return NULL; } else { return Key; } }
|