|
|
/****************************************************************************
Copyright (c) Microsoft Corporation 1998 All rights reserved
File: CALLBACK.CPP
***************************************************************************/
#include "pch.h"
#include "utils.h"
#include "tasks.h"
#include "setup.h"
#include "callback.h"
#include "logging.h"
#include "userenv.h"
// Must have this...
extern "C" { #include <sysprep_.h>
//
// SYSPREP globals
//
extern BOOL NoSidGen; extern BOOL PnP; }
DEFINE_MODULE("RIPREP")
DWORD g_WorkerThreadId = 0; HANDLE g_WorkerThreadHandle = INVALID_HANDLE_VALUE; HWND g_hMainWindow = NULL; HWND g_hTasksDialog = NULL; DWORD g_NeedDlg = NULL;
#define NCOLORSHADES 32
//
// Spin( )
//
DWORD Spin( ) { TraceFunc( "Spin( )\n" ); DWORD dwResult; MSG Msg;
// We will spin in here until the end
while ( WAIT_TIMEOUT == (dwResult = WaitForSingleObject( g_WorkerThreadHandle, 50 )) ) { while ( PeekMessage( &Msg, NULL, NULL, NULL, PM_REMOVE ) ) { if (Msg.message == WM_SYSKEYUP) continue; // ignore
if (Msg.message == WM_KEYDOWN) continue; // ignore
if (Msg.message == WM_KEYUP) continue; // ignore
TranslateMessage( &Msg ); DispatchMessage( &Msg ); } }
RETURN(dwResult); } //
// WorkerThreadProc( )
//
DWORD WorkerThreadProc( LPVOID lParam ) { UNREFERENCED_PARAMETER(lParam); // Place in the log all the gathered information for the wizard
// as well as system APIs.
LogMsg( L"Server : %s\r\n", g_ServerName ); LogMsg( L"Image Dir : %s\r\n", g_MirrorDir ); LogMsg( L"Language : %s\r\n", g_Language ); LogMsg( L"Architecture: %s\r\n", g_Architecture ); LogMsg( L"Description : %s\r\n", g_Description ); LogMsg( L"HelpText : %s\r\n", g_HelpText ); LogMsg( L"SystemRoot : %s\r\n", g_SystemRoot ); LogMsg( L"Winnt Dir : %s\r\n", g_WinntDirectory );
// Start the IMIRROR task list
DWORD dw = ProcessToDoItems( ); DebugMsg( "ProcessToDoItems( ) completed: 0x%08x\n", dw ); return dw; }
HWND g_hParent = NULL;
//
// MainWindowProc ( )
//
LRESULT CALLBACK MainWindowProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { static WCHAR szTitle[ 256 ]; static DWORD dwTitleLength; static HFONT BigBoldFont = NULL;
switch(uMsg) { case WM_NCCREATE: return TRUE; // keep going
case WM_CREATE: { DWORD dw; dw = LoadString( g_hinstance, IDS_APPNAME, szTitle, ARRAYSIZE(szTitle)); Assert(dw); dwTitleLength = wcslen( szTitle ); } break;
case WM_PAINT: { PAINTSTRUCT ps; RECT rc; LOGBRUSH brush; HBRUSH hBrush; HBRUSH hOldBrush; INT n = 0;
BeginPaint( hDlg, &ps ); rc.left = 0; rc.right = GetSystemMetrics(SM_CXVIRTUALSCREEN); rc.bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN); INT yDelta= max(rc.bottom/NCOLORSHADES,1); // height of one shade band
rc.top = rc.bottom - yDelta;
// Shade the background
while (rc.top >= 0) { brush.lbColor = RGB(0, 0, (256*n)/NCOLORSHADES); brush.lbStyle = BS_SOLID; hBrush = (HBRUSH) CreateBrushIndirect( &brush ); hOldBrush = (HBRUSH) SelectObject(ps.hdc, hBrush); FillRect( ps.hdc, &rc, hBrush ); SelectObject(ps.hdc, hOldBrush); DeleteObject(hBrush); rc.top -= yDelta; rc.bottom -= yDelta; n++; }
if ( !BigBoldFont ) { HFONT Font; LOGFONT LogFont; INT FontSize;
Font = (HFONT) GetStockObject( SYSTEM_FONT ); if ( (Font ) && GetObject( Font, sizeof(LOGFONT), &LogFont) ) { DWORD dw; dw = LoadString( g_hinstance, IDS_LARGEFONTNAME, LogFont.lfFaceName, LF_FACESIZE); Assert( dw );
LogFont.lfWeight = 700; FontSize = yDelta;
LogFont.lfHeight = 0 - (GetDeviceCaps(ps.hdc,LOGPIXELSY) * FontSize / 72); LogFont.lfWidth = 0;
BigBoldFont = CreateFontIndirect(&LogFont);
} }
// Redraw the title
SetBkMode( ps.hdc, TRANSPARENT ); SelectObject( ps.hdc, BigBoldFont ); SetTextColor( ps.hdc, RGB( 255, 255, 255 ) ); TextOut(ps.hdc, yDelta, yDelta, szTitle, dwTitleLength );
EndPaint( hDlg, &ps ); } break;
case WM_CHAR: case WM_KEYDOWN: case WM_KEYUP: case WM_MOUSEACTIVATE: case WM_MOUSEMOVE: case WM_MOUSEWHEEL: break; // ignore
case WM_DESTROY: if ( BigBoldFont ) DeleteObject( BigBoldFont ); break;
case WM_ERASEBKGND: // Don't waste time erasing
return TRUE; // non-zero
default: return DefWindowProc( hDlg, uMsg, wParam, lParam ); }
return FALSE; }
//
// BeginProcess( )
//
HRESULT BeginProcess( HWND hParent) { TraceFunc( "BeginProcess( )\n" );
WNDCLASSEX wndClass; ATOM atom; RECT rc; HWND hwndDesktop = GetDesktopWindow( ); DWORD dwExStyle; GetWindowRect( hwndDesktop, &rc );
// Create our window class
ZeroMemory( &wndClass, sizeof(wndClass) ); wndClass.cbSize = sizeof(wndClass); wndClass.hbrBackground = (HBRUSH) COLOR_BACKGROUND; wndClass.hInstance = g_hinstance; wndClass.lpfnWndProc = MainWindowProc; wndClass.lpszClassName = L"MondoWindow"; wndClass.style = CS_CLASSDC | CS_NOCLOSE;
atom = RegisterClassEx( &wndClass ); Assert( atom );
g_hParent = hParent; #ifdef DEBUG
dwExStyle = ( g_dwTraceFlags ? 0 : WS_EX_TOPMOST ); #else
dwExStyle = WS_EX_TOPMOST; #endif
g_hMainWindow = CreateWindowEx( dwExStyle, L"MondoWindow", L"", WS_POPUP | WS_VISIBLE, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), NULL, NULL, g_hinstance, NULL ); Assert( g_hMainWindow ); g_hTasksDialog = CreateDialog(g_hinstance, MAKEINTRESOURCE(IDD_TASKS), g_hMainWindow, TasksDlgProc );
if ( g_hTasksDialog ) { g_WorkerThreadHandle = CreateThread( NULL, NULL, WorkerThreadProc, NULL, 0, &g_WorkerThreadId ); Spin( ); SendMessage( g_hTasksDialog, WM_DESTROY, 0, 0 ); }
HRETURN(S_OK); }
//
// IsFileInExclusionList()
//
BOOLEAN IsFileInExclusionList( IN PCWSTR FileName ) /*++
Description:
This routine searches the exclusion list in our INF file.
Parameters:
FileName : File to search the INF for.
Return Value:
TRUE - The file does exist in the INF FALSE - The file does not exist in the INF
++*/ { #define SKIPFLAG_DIRECTORY 1
#define SKIPFLAG_FILTEREXTENSION 2
PWSTR FullPath = NULL; PWSTR DirectoryName = NULL; INFCONTEXT Context; INT Flags = 0; WCHAR FilterExtension[10]; BOOLEAN ReturnValue = FALSE;
//
// Make sure we have our INF.
//
if( g_hCompatibilityInf == INVALID_HANDLE_VALUE ) {
//
// Probably hasn't been initialized yet. Assume the
// file isn't in the INF.
//
return FALSE; }
if( FileName == NULL ) { return FALSE; }
//
// Get a local copy of the filename so we can operate on it
// without worry of corrupting the caller's data.
//
if( wcsncmp(FileName, L"\\\\?\\", 4) == 0 ) { FullPath = (PWSTR)TraceStrDup( FileName+4 ); } else { FullPath = (PWSTR)TraceStrDup( FileName ); }
if( FullPath == NULL ) { DebugMsg( "IsFileInExclusionList: Odd pathname %s.\n", FileName ); return FALSE; }
//
// See if it's explicitly listed in the INF
//
if (SetupFindFirstLine( g_hCompatibilityInf, L"FilesToSkipCopy", FullPath, &Context)) { DebugMsg( "IsFileInExclusionList: Found file %s in the INF exclusion list.\n", FullPath ); ReturnValue = TRUE; goto Cleanup; }
//
// The file isn't specifically listed in the INF. See if
// the directory this file is in is listed.
//
// Start whacking file/directory names off the end of the
// path to see if the result is in our exclusion list.
//
//
// Remember the filename.
//
FileName = wcsrchr(FullPath, L'\\');
if( FileName == NULL ) { DebugMsg( "IsFileInExclusionList: File isn't in exclusion list and has no directory path.\n" ); ReturnValue = FALSE; goto Cleanup; }
FileName++;
while( DirectoryName = wcsrchr(FullPath, L'\\') ) { *DirectoryName = NULL;
if( SetupFindFirstLine( g_hCompatibilityInf, L"FilesToSkipCopy", FullPath, &Context)) {
//
// The directory name *IS* in there. See if we need to
// skip all files in this directory, or only some.
//
Flags = 0; if( SetupGetIntField( &Context, 1, &Flags) && ((Flags & SKIPFLAG_FILTEREXTENSION) == 0)) {
//
// We don't have the filter flag, so we will just
// skip all files in this directory.
//
DebugMsg( "IsFileInExclusionList: Found file %s in %s in the exclusion list (based on the name of his directory).\n", FileName, FullPath );
ReturnValue = TRUE; goto Cleanup; }
//
// See if we should skip files with a specified extension.
//
if( SetupGetStringField( &Context, 2, FilterExtension, ARRAYSIZE(FilterExtension), NULL )) { PCWSTR q = wcsrchr( FileName, L'.' ); if (q) { q++; if (_wcsicmp(q, FilterExtension) == 0) { DebugMsg( "IsFileInExclusionList: Found file %s in %s with extension %s in the exclusion list (based on the directory and extension of the file).\n", FileName, FullPath, q ); ReturnValue = TRUE; goto Cleanup; } } } } }
Cleanup: if( FullPath ) { DebugMemoryDelete( FullPath ); }
return ReturnValue; }
//
// ConvTestErrorFn()
//
NTSTATUS ConvTestErrorFn( IN PVOID Context, IN NTSTATUS Status, IN IMIRROR_TODO IMirrorFunctionId ) { TraceFunc( "ConvTestErrorFn( ... )\n" );
WCHAR szMessage[ 256 ]; DWORD dw;
LBITEMDATA item;
if ( Status != ERROR_SUCCESS ) { DebugMsg("ERROR REPORTED! : Context 0x%x, Status 0x%x, In Func 0x%x\n", Context, Status, IMirrorFunctionId );
// Error will be logged in TASKS.CPP
item.fSeen = FALSE; item.pszText = (IMirrorFunctionId == CheckPartitions) ? NULL : (LPWSTR)Context; item.uState = Status; // used as input and output
item.todo = IMirrorFunctionId;
BOOL b = (BOOL)SendMessage( g_hTasksDialog, WM_ERROR, 0, (LPARAM) &item ); if ( !b ) { Status = ERROR_REQUEST_ABORTED; } else { Status = item.uState; }
if ( Status == ERROR_SUCCESS ) { dw = LoadString( g_hinstance, IDS_ERROR_IGNORED, szMessage, ARRAYSIZE( szMessage )); Assert( dw ); } else if ( (Status == STATUS_RETRY) || (Status == ERROR_RETRY) ) { dw = LoadString( g_hinstance, IDS_STATUS_RETRY, szMessage, ARRAYSIZE( szMessage )); Assert( dw ); } else // other should be abort
{ Assert( Status == ERROR_REQUEST_ABORTED ); dw = LoadString( g_hinstance, IDS_OPERATION_ABORTED, szMessage, ARRAYSIZE( szMessage )); Assert( dw ); ClearAllToDoItems(FALSE); }
Assert( dw ); LogMsg( szMessage ); }
RETURN(Status); }
NTSTATUS ConvTestNowDoingFn( IN PVOID Context, IN IMIRROR_TODO Function, IN PWSTR String ) { UNREFERENCED_PARAMETER(Context); TraceFunc( "ConvTestNowDoingFn( )\n" ); LPWSTR pszMessage; WCHAR szMessage[ 256 ]; LPWSTR pszString; HWND hwnd = GetDlgItem( g_hTasksDialog, IDC_L_TASKS ); INT uCount; DWORD dw; LPLBITEMDATA pitem = NULL; NTSTATUS Status = ERROR_SUCCESS;
static lastToDo = IMirrorNone;
static BOOL fAlreadyAdjusted = FALSE;
if ( String ) { pszString = (LPWSTR)TraceStrDup( String ); } else { pszString = NULL; }
// if we are onto another task, mark the previous one done
// and mark this one as started.
if ( lastToDo != Function ) { uCount = ListBox_GetCount( hwnd ); while (uCount>=0) { LRESULT lResult = ListBox_GetItemData( hwnd, uCount ); uCount--; if ( lResult == LB_ERR ) continue;
pitem = (LPLBITEMDATA) lResult; pitem->fSeen = TRUE;
if ( pitem->todo == Function ) { if ( pitem->uState == STATE_NOTSTARTED ) { pitem->uState = STATE_STARTED; InvalidateRect( hwnd, NULL, TRUE ); // force redraw
} } else { if ( pitem->uState == STATE_STARTED ) { pitem->uState = STATE_DONE; InvalidateRect( hwnd, NULL, TRUE ); // force redraw
} } }
lastToDo = Function; }
switch (Function) { case IMirrorInitialize: dw = LoadString( g_hinstance, IDS_INITIALIZING, szMessage, ARRAYSIZE(szMessage) ); Assert(dw); break; case VerifySystemIsNt5: dw = LoadString( g_hinstance, IDS_VERIFYING_WINDOWS_VERSION, szMessage, ARRAYSIZE(szMessage) ); Assert(dw); break; case CheckPartitions: dw = LoadString( g_hinstance, IDS_ANALYZING_PARTITIONS, szMessage, ARRAYSIZE(szMessage) ); Assert(dw); break; case CopyPartitions: dw = LoadString( g_hinstance, IDS_COPYING_PARTITIONS, szMessage, ARRAYSIZE(szMessage) ); Assert(dw); break; case CopyFiles: if ( pszString == NULL ) { // Only need to do this once.
WCHAR ProfilesDirectory[MAX_PATH]; DWORD rc; DWORD disp; HKEY hKey;
//
// Begin SYSPREP ops
//
//
// Fix the registry so that the desktop doesn't get cleared up.
//
if( !g_OEMDesktop ) {
//
// The user hasn't asked us to clean the desktop, so by default,
// we're going to assume he wants to keep it.
//
//
// Create HKLM\Software\Microsoft\Windows\CurrentVersion\OemStartMenuData
//
rc = RegCreateKeyEx( HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\OemStartMenuData"), 0L, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &disp );
if( rc == ERROR_SUCCESS ) {
//
// Create the value DesktopShortcutsCleanupDisable (DWORD) = 1
//
disp = 1; rc = RegSetValueEx( hKey, TEXT("DesktopShortcutsCleanupDisable"), 0, REG_DWORD, (CONST BYTE *)&disp, sizeof(DWORD));
RegCloseKey( hKey ); } } else {
//
// Try to delete the key.
//
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\OemStartMenuData"), 0L, KEY_READ | KEY_WRITE, &hKey );
if( rc == ERROR_SUCCESS ) {
//
// Delete DesktopShortcutsCleanupDisable
//
rc = RegDeleteValue( hKey, TEXT("DesktopShortcutsCleanupDisable") );
RegCloseKey( hKey ); } }
if( !NoSidGen && !IsSetupClPresent() ) { LBITEMDATA item;
// Error will be logged in TASKS.CPP
item.fSeen = FALSE; item.pszText = L"SETUPCL.EXE"; item.uState = ERROR_FILE_NOT_FOUND; item.todo = Function;
SendMessage( g_hTasksDialog, WM_ERROR_OK, 0, (LPARAM) &item ); Status = STATUS_REQUEST_ABORTED; }
//
// Prepare to run Setupcl. This will also call into
// RunExternalUniqueness which gives others a chance to save
// any info that needs to be copied to the server.
//
if (!NoSidGen && !PrepForSidGen()) { LBITEMDATA item;
// Error will be logged in TASKS.CPP
item.fSeen = FALSE; item.pszText = L"Preparing SIDs error"; item.uState = ERROR_FILE_NOT_FOUND; item.todo = Function;
SendMessage( g_hTasksDialog, WM_ERROR_OK, 0, (LPARAM) &item ); Status = STATUS_REQUEST_ABORTED; } //
// Syprep cleanup which updates files that are required to be copied
// over to the server.
//
if (!AdjustFiles()) { LBITEMDATA item;
// Error will be logged in TASKS.CPP
item.fSeen = FALSE; item.pszText = L"Adjusting files error"; item.uState = ERROR_FILE_NOT_FOUND; item.todo = Function;
SendMessage( g_hTasksDialog, WM_ERROR_OK, 0, (LPARAM) &item ); Status = STATUS_REQUEST_ABORTED; }
#ifndef _IA64_
//
// Make sure we're on something reasonably current before
// we attempt to ReArm the license. The APIs just didn't
// exist on win2k.
//
if( (OsVersion.dwMajorVersion >= 5) && (OsVersion.dwMinorVersion >= 1) ) {
dw = ReArm(); if( dw != ERROR_SUCCESS ) {
MessageBoxFromStrings( g_hTasksDialog, IDS_ACCESS_DENIED_TITLE, IDS_ACTIVIATION_COUNT_EXCEEDED, MB_OK | MB_ICONSTOP ); }
} #endif
//
// We need to assign a DirectoryID to the directory containing
// the user profiles. There is no hardcoded DirID for this, so
// we'll make one up and tell Setupapi about it.
//
dw = MAX_PATH; if( !GetProfilesDirectory( ProfilesDirectory, &dw ) ) {
//
// We should never get here, but just in case.
//
wcscpy( ProfilesDirectory, L"C:\\Documents and Settings" ); }
if (g_hCompatibilityInf != INVALID_HANDLE_VALUE) {
if( !SetupSetDirectoryId( g_hCompatibilityInf, PROFILES_DIRID, ProfilesDirectory ) ) {
ASSERT( FALSE && L"Unable to SetupSetDirectoryId for user profiles" ); } }
//
// End SYSPREP ops
//
} else // if ( pszString )
{
// Sanity
ASSERT( wcslen(String) < MAX_PATH );
if( IsFileInExclusionList(pszString) ) {
//
// It's in the exclusion list.
//
DebugMsg( "ConvTestNowDoingFn: Skipping file %s because it's in the INF exclusion list.\n", pszString ); RETURN(E_FAIL); } else { DebugMsg( "ConvTestNowDoingFn: Processing file %s\n", pszString ); } } dw = LoadString( g_hinstance, IDS_COPYING_FILES, szMessage, ARRAYSIZE(szMessage) ); Assert(dw); break;
case CopyRegistry: //
// Begin SYSPREP ops
//
Status = ERROR_SUCCESS; if ( IsDomainMember( ) ) { RetryUnjoin: Status = NetUnjoinDomain( NULL, NULL, NULL, 0 ); if ( Status != NERR_Success ) { LBITEMDATA item;
// Error will be logged in TASKS.CPP
item.fSeen = FALSE; item.pszText = L"Remove from Domain Error"; item.uState = Status; item.todo = Function;
SendMessage( g_hTasksDialog, WM_ERROR, 0, (LPARAM) &item );
if ( Status == ERROR_SUCCESS ) { dw = LoadString( g_hinstance, IDS_ERROR_IGNORED, szMessage, ARRAYSIZE( szMessage )); } else if ( Status == STATUS_RETRY ) { dw = LoadString( g_hinstance, IDS_STATUS_RETRY, szMessage, ARRAYSIZE( szMessage )); } else // other should be abort
{ Assert( Status == ERROR_REQUEST_ABORTED ); dw = LoadString( g_hinstance, IDS_OPERATION_ABORTED, szMessage, ARRAYSIZE( szMessage )); }
Assert( dw ); LogMsg( szMessage );
if ( Status == STATUS_RETRY ) { goto RetryUnjoin; } } }
if( !fAlreadyAdjusted ) { WCHAR szSrcPath[MAX_PATH]; fAlreadyAdjusted = TRUE;
_snwprintf( szSrcPath, ARRAYSIZE(szSrcPath), L"%s\\ristndrd.sif", g_ImageName ); TERMINATE_BUFFER(szSrcPath);
//
// We are going to munge some system values. Prevent us for bailing
// without a reboot.
//
g_fRebootOnExit = TRUE; if ( Status != ERROR_SUCCESS || !RemoveNetworkSettings(szSrcPath) || !AdjustRegistry( FALSE /* no, do not remove networking*/) ) { LBITEMDATA item;
// Error will be logged in TASKS.CPP
item.fSeen = FALSE; item.pszText = L"Registry Error"; item.uState = GetLastError( ); item.todo = Function;
SendMessage( g_hTasksDialog, WM_ERROR_OK, 0, (LPARAM) &item ); Status = STATUS_REQUEST_ABORTED; } }
if ( Status == ERROR_SUCCESS ) { NukeMruList(); } else { ClearAllToDoItems(FALSE); }
//
// End SYSPREP ops
//
dw = LoadString( g_hinstance, IDS_COPYING_REGISTRY, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case PatchDSEntries: dw = LoadString( g_hinstance, IDS_UPDATING_DS_ENTRIES, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case RebootSystem: dw = LoadString( g_hinstance, IDS_REBOOTING_SYSTEM, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; default: dw = LoadString( g_hinstance, IDS_DOING_UNKNOWN_TASK, szMessage, ARRAYSIZE( szMessage )); Assert(dw); }
pszMessage = (LPWSTR) TraceStrDup( szMessage ); if ( !pszMessage ) RETURN(E_OUTOFMEMORY);
PostMessage( g_hTasksDialog, WM_UPDATE, (WPARAM)pszMessage, (LPARAM)pszString ); // These were handed off to another thread. Don't track them anymore in
// this thread.
DebugMemoryDelete( pszMessage ); if (pszString) { DebugMemoryDelete( pszString ); }
if ( Status != NO_ERROR ) { if( pitem ) { pitem->uState = STATE_ERROR; } InvalidateRect( hwnd, NULL, TRUE ); // force redraw
ClearAllToDoItems(FALSE); }
RETURN(Status); }
NTSTATUS ConvTestGetMirrorDirFn( IN PVOID Context, OUT PWSTR Mirror, IN OUT PULONG Length ) { UNREFERENCED_PARAMETER(Context);
TraceFunc( "ConvTestGetMirrorDirFn( )\n" ); Assert( Length && *Length );
_snwprintf( Mirror, *Length, L"\\\\%s\\REMINST\\Setup\\%s\\%s\\%s", g_ServerName, g_Language, REMOTE_INSTALL_IMAGE_DIR_W, g_MirrorDir ); Mirror[*Length-1] = L'\0'; CreateDirectory( Mirror, NULL );
_snwprintf( Mirror, *Length, L"\\\\%s\\REMINST\\Setup\\%s\\%s\\%s\\%s", g_ServerName, g_Language, REMOTE_INSTALL_IMAGE_DIR_W, g_MirrorDir, g_Architecture ); Mirror[*Length-1] = L'\0'; CreateDirectory( Mirror, NULL );
*Length = (wcslen(Mirror) + 1) * sizeof(WCHAR);
DebugMsg( "Sending: %s\n", Mirror );
RETURN((*Length == sizeof(WCHAR)) ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS); }
NTSTATUS ConvTestFileCreateFn( IN PVOID Context, IN PWSTR FileName, IN ULONG FileAction, IN ULONG Status ) { UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(FileAction); TraceFunc( "ConvTestFileCreateFn( )\n" );
if (Status != 0) {
if( IsFileInExclusionList( FileName ) ) { //
// It's in the exclusion list.
//
DebugMsg( "ConvTestFileCreateFn: Skipping file %s because it's in the INF exclusion list.\n", FileName ); Status = 0; }
if (Status != 0) { Status = ConvTestErrorFn( FileName, Status, CopyFiles ); } } else {
DebugMsg("created %s\n", FileName); }
RETURN(Status); }
NTSTATUS ConvTestReinitFn( IN PVOID Context ) { UNREFERENCED_PARAMETER(Context); TraceFunc( "ConvTestReinitFn()\n" );
RETURN(STATUS_SUCCESS); }
NTSTATUS ConvTestGetSetupFn( IN PVOID Context, IN PWSTR Server, OUT PWSTR SetupPath, IN OUT PULONG Length ) { UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(Server); TraceFunc( "ConvTestGetSetupFn()\n" );
lstrcpyn( SetupPath, g_ImageName, *Length ); *Length = wcslen( SetupPath );
DebugMsg( "Sending: %s\n", SetupPath );
RETURN(STATUS_SUCCESS); }
NTSTATUS ConvTestSetSystemFn( IN PVOID Context, IN PWSTR SystemPath, IN ULONG Length ) { NTSTATUS err;
UNREFERENCED_PARAMETER(Context); TraceFunc( "ConvTestSetSystemFn()\n" );
if (Length <= ARRAYSIZE(g_SystemRoot)) {
wcscpy( g_SystemRoot, SystemPath ); err = STATUS_SUCCESS;
} else {
err = ERROR_BAD_LENGTH; }
RETURN(err); }
NTSTATUS ConvAddToDoItemFn( IN PVOID Context, IN IMIRROR_TODO Function, IN PWSTR String, IN ULONG Length ) { LPLBITEMDATA pitem; HWND hwnd = GetDlgItem( g_hTasksDialog, IDC_L_TASKS ); WCHAR szMessage[ 256 ]; DWORD dw; INT uCount;
UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(String); UNREFERENCED_PARAMETER(Length);
TraceFunc( "ConvAddToDoItemFn()\n" );
pitem = (LPLBITEMDATA) TraceAlloc( LMEM_FIXED, sizeof(LBITEMDATA)); if ( !pitem) RETURN(E_OUTOFMEMORY);
switch (Function) { case IMirrorInitialize: dw = LoadString( g_hinstance, IDS_INITIALIZE, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case VerifySystemIsNt5: dw = LoadString( g_hinstance, IDS_VERIFY_WINDOWS_VERSION, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case CheckPartitions: dw = LoadString( g_hinstance, IDS_ANALYZE_PARTITIONS, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case CopyPartitions: dw = LoadString( g_hinstance, IDS_COPY_PARTITIONS, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case CopyFiles: dw = LoadString( g_hinstance, IDS_COPY_FILES, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case CopyRegistry: dw = LoadString( g_hinstance, IDS_COPY_REGISTRY, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case PatchDSEntries: dw = LoadString( g_hinstance, IDS_PATH_DS_ENTRIES, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; case RebootSystem: dw = LoadString( g_hinstance, IDS_REBOOT_SYSTEM, szMessage, ARRAYSIZE( szMessage )); Assert(dw); break; default: dw = LoadString( g_hinstance, IDS_UNKNOWN_TASK, szMessage, ARRAYSIZE( szMessage )); Assert(dw); }
pitem->pszText = (LPWSTR) TraceStrDup( szMessage ); pitem->uState = STATE_NOTSTARTED; pitem->todo = Function; pitem->fSeen = FALSE;
if ( !pitem->pszText ) { TraceFree( pitem ); RETURN(E_OUTOFMEMORY); }
// skip the "done" items
uCount = 0; while (uCount>=0) { LRESULT lResult = ListBox_GetItemData( hwnd, uCount ); if ( lResult == LB_ERR ) break;
LPLBITEMDATA panitem = (LPLBITEMDATA) lResult;
if ( panitem->uState == STATE_STARTED ) { uCount++; break; } if ( panitem->uState != STATE_DONE ) break;
uCount++; }
// go to end of the "unseen" items
while (uCount>=0) { LRESULT lResult = ListBox_GetItemData( hwnd, uCount ); if ( lResult == LB_ERR ) break;
LPLBITEMDATA panitem = (LPLBITEMDATA) lResult;
uCount++;
if ( panitem->fSeen ) { uCount--; break; } }
ListBox_InsertString( hwnd, uCount, pitem ); InvalidateRect( hwnd, NULL, TRUE ); // force redraw
DebugMsg( "Added ToDo Item (%d): %s\n", uCount, pitem->pszText );
RETURN(STATUS_SUCCESS); }
NTSTATUS ConvRemoveToDoItemFn( IN PVOID Context, IN IMIRROR_TODO Function, IN PWSTR String, IN ULONG Length ) { LPLBITEMDATA pitem; HWND hwnd = GetDlgItem( g_hTasksDialog, IDC_L_TASKS ); INT uCount;
UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(String); UNREFERENCED_PARAMETER(Length);
TraceFunc( "ConvRemoveToDoItemFn()\n" );
uCount = ListBox_GetCount( hwnd ); while (uCount>=0) { LRESULT lResult = ListBox_GetItemData( hwnd, uCount ); uCount--; if ( lResult == LB_ERR ) continue;
pitem = (LPLBITEMDATA) lResult;
if ( pitem->todo == Function ) { pitem->uState = STATE_STARTED; break; } }
RETURN(STATUS_SUCCESS); }
NTSTATUS ConvRebootFn( IN PVOID Context ) {
UNREFERENCED_PARAMETER(Context);
// do the last minute things
EndProcess( g_hTasksDialog );
#ifdef DEBUG
// if Debugging, don't reboot
if ( !g_dwTraceFlags ) { #endif
if (!DoShutdown(FALSE)) { LBITEMDATA item;
// Error will be logged in TASKS.CPP
item.fSeen = FALSE; item.pszText = L"Shutdown Error"; item.uState = GetLastError( ); item.todo = RebootSystem;
SendMessage( g_hTasksDialog, WM_ERROR_OK, 0, (LPARAM) &item ); return item.uState; }
//
// Prevent the error log from being displayed twice. Since
// we are set to reboot/shutdown now, this flag can be
// safely reset.
//
g_fRebootOnExit = FALSE;
#ifdef DEBUG
} #endif
return STATUS_SUCCESS; }
BOOL DoShutdown( IN BOOL Restart ) { NTSTATUS Status; BOOLEAN WasEnabled;
Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE, (BOOLEAN)TRUE, TRUE, &WasEnabled );
if (Status == STATUS_NO_TOKEN) {
//
// No thread token, use the process token
//
Status = RtlAdjustPrivilege( SE_SHUTDOWN_PRIVILEGE, (BOOLEAN)TRUE, FALSE, &WasEnabled ); }
if (Restart) { return ExitWindowsEx( EWX_REBOOT | EWX_FORCEIFHUNG, SHTDN_REASON_FLAG_PLANNED | SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_INSTALLATION ); } else { return InitiateSystemShutdownEx(NULL, NULL, 0, TRUE, FALSE, SHTDN_REASON_FLAG_PLANNED | SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_INSTALLATION); } }
|