windows-nt/Source/XPSP1/NT/base/remoteboot/riprep/tasks.cpp
2020-09-26 16:20:57 +08:00

553 lines
20 KiB
C++

/****************************************************************************
Copyright (c) Microsoft Corporation 1998
All rights reserved
File: TASKS.CPP
***************************************************************************/
#include "pch.h"
#include "callback.h"
#include "utils.h"
#include "tasks.h"
#include "logging.h"
DEFINE_MODULE("RIPREP")
extern HWND g_hTasksDialog;
typedef struct {
HANDLE hChecked;
HANDLE hError;
HANDLE hArrow;
HANDLE hFontNormal;
HANDLE hFontBold;
int dwWidth;
int dwHeight;
} SETUPDLGDATA, *LPSETUPDLGDATA;
//
// TasksDlgProc()
//
INT_PTR CALLBACK
TasksDlgProc(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam )
{
static HBRUSH hBrush = NULL;
LPSETUPDLGDATA psdd = (LPSETUPDLGDATA) GetWindowLongPtr( hDlg, GWLP_USERDATA );
INT_PTR result;
switch (uMsg)
{
default:
return FALSE;
case WM_INITDIALOG:
{
BITMAP bm;
// grab the bitmaps
psdd =
(LPSETUPDLGDATA) TraceAlloc( GMEM_FIXED, sizeof(SETUPDLGDATA) );
if ( psdd == NULL ) {
// This returns FALSE at successful completion
// So returning opposite
return TRUE;
}
psdd->hChecked = LoadImage( g_hinstance,
MAKEINTRESOURCE( IDB_CHECK ),
IMAGE_BITMAP,
0, 0,
LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
DebugMemoryAddHandle( psdd->hChecked );
GetObject( psdd->hChecked, sizeof(bm), &bm );
psdd->dwWidth = bm.bmWidth;
psdd->hError = LoadImage( g_hinstance,
MAKEINTRESOURCE( IDB_X ),
IMAGE_BITMAP,
0, 0,
LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
DebugMemoryAddHandle( psdd->hError );
GetObject( psdd->hError, sizeof(bm), &bm );
psdd->dwWidth = ( psdd->dwWidth > bm.bmWidth ? psdd->dwWidth : bm.bmWidth );
psdd->hArrow = LoadImage( g_hinstance,
MAKEINTRESOURCE( IDB_ARROW ),
IMAGE_BITMAP,
0, 0,
LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
DebugMemoryAddHandle( psdd->hArrow );
GetObject( psdd->hArrow, sizeof(bm), &bm );
psdd->dwWidth = ( psdd->dwWidth > bm.bmWidth ?
psdd->dwWidth :
bm.bmWidth );
HWND hwnd = GetDlgItem( hDlg, IDC_L_TASKS );
HFONT hFontOld = (HFONT) SendMessage( hwnd, WM_GETFONT, 0, 0);
if(hFontOld != NULL)
{
LOGFONT lf;
if ( GetObject( hFontOld, sizeof(LOGFONT), (LPSTR) &lf ) )
{
DWORD dw = LoadString( g_hinstance,
IDS_LARGEFONTNAME,
lf.lfFaceName,
LF_FACESIZE);
Assert( dw );
lf.lfWidth = 0;
lf.lfWeight = 400;
lf.lfHeight -= 4;
psdd->hFontNormal = CreateFontIndirect(&lf);
DebugMemoryAddHandle( psdd->hFontNormal );
lf.lfWeight = 700;
psdd->hFontBold = CreateFontIndirect(&lf);
DebugMemoryAddHandle( psdd->hFontBold );
}
}
HDC hDC = GetDC( NULL );
SelectObject( hDC, psdd->hFontBold );
TEXTMETRIC tm;
GetTextMetrics( hDC, &tm );
psdd->dwHeight = tm.tmHeight;
ReleaseDC( NULL, hDC );
SetWindowLongPtr( hDlg, GWLP_USERDATA, (LONG_PTR) psdd );
WCHAR szTitle[ 256 ];
DWORD dw;
dw = LoadString( g_hinstance, IDS_APPNAME, szTitle, ARRAYSIZE(szTitle));
Assert( dw );
SetWindowText( hDlg, szTitle );
SetDlgItemText( hDlg, IDC_S_OPERATION, L"" );
CenterDialog( hDlg );
return FALSE;
}
break;
case WM_MEASUREITEM:
{
LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT) lParam;
RECT rc;
if ( lpmis == NULL ) {
// Breaks and returns TRUE at successful completion
// So returning opposite
return FALSE;
}
HWND hwnd = GetDlgItem( hDlg, IDC_L_TASKS );
GetClientRect( hwnd, &rc );
lpmis->itemWidth = rc.right - rc.left;
lpmis->itemHeight = psdd->dwHeight;
}
break;
case WM_DRAWITEM:
{
Assert( psdd );
LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam;
if ( !lpdis ) {
// Below, another null pointer in the same
// data field is taken care of. We are
// duplicating the result here.
break; // ignore
}
LPLBITEMDATA plbid = (LPLBITEMDATA)lpdis->itemData;
RECT rc = lpdis->rcItem;
HANDLE hOldFont = INVALID_HANDLE_VALUE;
WCHAR szText[MAX_PATH];
if ( !plbid )
break; // ignore
ListBox_GetText(lpdis->hwndItem, lpdis->itemID, szText);
rc.right = rc.bottom = psdd->dwWidth;
switch ( plbid->uState )
{
case STATE_NOTSTARTED:
hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
break;
case STATE_STARTED:
DrawBitmap( psdd->hArrow, lpdis, &rc );
hOldFont = SelectObject( lpdis->hDC, psdd->hFontBold );
break;
case STATE_DONE:
DrawBitmap( psdd->hChecked, lpdis, &rc );
hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
break;
case STATE_ERROR:
DrawBitmap( psdd->hError, lpdis, &rc );
hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
break;
}
rc = lpdis->rcItem;
rc.left += psdd->dwHeight;
DrawText( lpdis->hDC, plbid->pszText, -1, &rc, DT_LEFT | DT_VCENTER );
if ( hOldFont != INVALID_HANDLE_VALUE )
{
SelectObject( lpdis->hDC, hOldFont );
}
}
break;
case WM_CTLCOLORLISTBOX:
if ( hBrush == NULL )
{
LOGBRUSH brush;
brush.lbColor = GetSysColor( COLOR_3DFACE );
brush.lbStyle = BS_SOLID;
hBrush = (HBRUSH) CreateBrushIndirect( &brush );
DebugMemoryAddHandle( hBrush );
}
SetBkMode( (HDC) wParam, OPAQUE );
SetBkColor( (HDC) wParam, GetSysColor( COLOR_3DFACE ) );
return (INT_PTR)hBrush;
case WM_DESTROY:
if ( hBrush != NULL )
{
DebugMemoryDelete( hBrush );
DeleteObject(hBrush);
hBrush = NULL;
}
Assert( psdd );
DeleteObject( psdd->hChecked );
DebugMemoryDelete( psdd->hChecked );
DeleteObject( psdd->hError );
DebugMemoryDelete( psdd->hError );
DeleteObject( psdd->hArrow );
DebugMemoryDelete( psdd->hArrow );
DeleteObject( psdd->hFontNormal );
DebugMemoryDelete( psdd->hFontNormal );
DeleteObject( psdd->hFontBold );
DebugMemoryDelete( psdd->hFontBold );
TraceFree( psdd );
SetWindowLongPtr( hDlg, GWLP_USERDATA, NULL );
EndDialog( g_hTasksDialog, 0 );
break;
case WM_SETTINGCHANGE:
if ( hBrush != NULL )
{
DebugMemoryDelete( hBrush );
DeleteObject(hBrush);
hBrush = NULL;
}
break;
case WM_UPDATE:
{
RECT rc;
LPWSTR pszOperation = (LPWSTR) wParam;
LPWSTR pszObject = (LPWSTR) lParam;
LPWSTR pszTemp = NULL;
LPWSTR psz;
if ( lParam && wParam ) {
RECT rect;
SIZE size;
HDC hdc = GetDC( hDlg );
INT iLength = wcslen( pszOperation );
psz = pszObject;
if ( psz && StrCmpN( psz, L"\\\\?\\", 4) == 0 )
{
psz += 4;
}
GetWindowRect( GetDlgItem( hDlg, IDC_S_OPERATION ), &rect );
if (hdc != NULL) {
GetTextExtentPoint( hdc, pszOperation, iLength, &size );
PathCompactPath( hdc, psz, rect.right - rect.left - size.cx );
ReleaseDC( hDlg, hdc );
}
pszTemp = (LPWSTR) TraceAlloc( LMEM_FIXED, (iLength + wcslen(psz) + 2) * sizeof(WCHAR)); // +1 space +1 NULL
if (!pszTemp )
goto Update_Cleanup;
wsprintf( pszTemp, pszOperation, psz );
psz = pszTemp;
} else if ( pszObject ) {
psz = pszObject;
} else if ( wParam ) {
psz = pszOperation;
} else {
psz = L"";
}
Assert( psz );
SetDlgItemText( hDlg, IDC_S_OPERATION, psz );
Update_Cleanup:
if ( pszTemp )
TraceFree( pszTemp );
if ( pszObject )
TraceFree( pszObject );
if ( pszOperation )
TraceFree( pszOperation );
}
break;
case WM_ERROR:
case WM_ERROR_OK:
//
// Close the log file to prevent the "write-behind / data-loss" popups.
//
if ( g_hLogFile != INVALID_HANDLE_VALUE ) {
CloseHandle( g_hLogFile );
g_hLogFile = INVALID_HANDLE_VALUE;
}
// Signal that the error log should be displayed.
g_fErrorOccurred = TRUE;
result = TRUE; // message processed
if ( lParam != NULL )
{
LBITEMDATA * pitem = (LBITEMDATA *) lParam;
LPWSTR pszFile = pitem->pszText;
DWORD Error = pitem->uState;
// Remove the "\\?\" from the beginning of the line
if ( pszFile != NULL
&& StrCmpN( pszFile, L"\\\\?\\", 4 ) == 0 )
{
pszFile = &pszFile[4];
}
switch (Error)
{
case ERROR_DISK_FULL:
{
WCHAR szTemplate[ 1024 ];
INT i = MessageBoxFromStrings( hDlg, IDS_DISK_FULL_TITLE, IDS_DISK_FULL_TEXT, MB_ABORTRETRYIGNORE );
DWORD dw = LoadString( g_hinstance, IDS_DISK_FULL_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
LogMsg( szTemplate );
if ( i == IDABORT )
{
pitem->uState = ERROR_REQUEST_ABORTED;
}
else if ( i == IDRETRY )
{
pitem->uState = STATUS_RETRY;
}
else // ignore the error
{
pitem->uState = ERROR_SUCCESS;
}
}
break;
case ERROR_FILE_ENCRYPTED:
{
INT i = IDOK;
WCHAR szTemplate[ 1024 ]; // random
WCHAR szText[ ARRAYSIZE(szTemplate) + MAX_PATH ];
WCHAR szTitle[ MAX_PATH ]; // random
DWORD dw;
dw = LoadString( g_hinstance, IDS_ENCRYPTED_FILE_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
dw = LoadString( g_hinstance, IDS_ENCRYPTED_FILE_TITLE, szTitle, ARRAYSIZE(szTitle) );
Assert( dw );
wsprintf( szText, szTemplate, pszFile );
if ( !g_fQuietFlag ) {
i = MessageBox( hDlg, szText, szTitle, MB_OKCANCEL );
}
dw = LoadString( g_hinstance, IDS_ENCRYPTED_FILE_LOG, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
LogMsg( szTemplate, pszFile );
pitem->uState = ( i == IDOK ? ERROR_SUCCESS : ERROR_REQUEST_ABORTED );
}
break;
case ERROR_SHARING_VIOLATION:
{
BOOL SkipCheck = FALSE;
WCHAR szTemplate[ 1024 ]; // random
WCHAR szText[ ARRAYSIZE(szTemplate) + MAX_PATH ];
WCHAR szTitle[ MAX_PATH ]; // random
DWORD dw;
if (g_hCompatibilityInf != INVALID_HANDLE_VALUE) {
INFCONTEXT Context;
if (SetupFindFirstLine(
g_hCompatibilityInf,
L"FilesToIgnoreCopyErrors",
pszFile,
&Context)) {
pitem->uState = ERROR_SUCCESS;
SkipCheck = TRUE;
}
}
if (!SkipCheck) {
dw = LoadString( g_hinstance, IDS_SHARING_VIOLATION_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
dw = LoadString( g_hinstance, IDS_SHARING_VIOLATION_TITLE, szTitle, ARRAYSIZE(szTitle) );
Assert( dw );
wsprintf( szText, szTemplate, pszFile );
if ( !g_fQuietFlag )
{
INT i = MessageBox( hDlg, szText, szTitle, MB_ABORTRETRYIGNORE );
if ( i == IDABORT )
{
pitem->uState = ERROR_REQUEST_ABORTED;
}
else if ( i == IDRETRY )
{
pitem->uState = STATUS_RETRY;
}
else // ignore the error
{
pitem->uState = ERROR_SUCCESS;
}
}
else // ignore the error - it will be logged
{
pitem->uState = ERROR_SUCCESS;
}
}
dw = LoadString( g_hinstance, IDS_SHARING_VIOLATION_LOG, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
LogMsg( szTemplate, pszFile );
}
break;
case ERROR_ACCESS_DENIED:
{
INT i = IDOK;
WCHAR szTemplate[ 1024 ]; // random
WCHAR szText[ ARRAYSIZE(szTemplate) + MAX_PATH ];
WCHAR szTitle[ MAX_PATH ]; // random
DWORD dw;
dw = LoadString( g_hinstance, IDS_ACCESS_DENIED_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
dw = LoadString( g_hinstance, IDS_ACCESS_DENIED_TITLE, szTitle, ARRAYSIZE(szTitle) );
Assert( dw );
wsprintf( szText, szTemplate, pszFile );
if ( !g_fQuietFlag ) {
i = MessageBox( hDlg, szText, szTitle, MB_OKCANCEL );
}
dw = LoadString( g_hinstance, IDS_ACCESS_DENIED_LOG, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
LogMsg( szTemplate, pszFile );
pitem->uState = ( i == IDOK ? ERROR_SUCCESS : ERROR_REQUEST_ABORTED );
}
break;
case ERROR_INVALID_DRIVE: // special meaning multi-disk detected
{
INT i = IDOK;
i = MessageBoxFromStrings( hDlg, IDS_MULTIPLE_DISK_TITLE, IDS_MULTIPLE_DISK_TEXT, MB_OKCANCEL );
pitem->uState = ( i == IDOK ? ERROR_SUCCESS : ERROR_REQUEST_ABORTED );
}
break;
case ERROR_REPARSE_ATTRIBUTE_CONFLICT:
{
INT i = IDOK;
WCHAR szTemplate[ 1024 ]; // random
WCHAR szText[ ARRAYSIZE(szTemplate) + MAX_PATH ];
WCHAR szTitle[ MAX_PATH ]; // random
DWORD dw;
dw = LoadString( g_hinstance, IDS_NOT_COPYING_REPARSE_POINT_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
dw = LoadString( g_hinstance, IDS_NOT_COPYING_REPARSE_POINT_TITLE, szTitle, ARRAYSIZE(szTitle) );
Assert( dw );
wsprintf( szText, szTemplate, pszFile );
if ( !g_fQuietFlag ) {
i = MessageBox( hDlg, szText, szTitle, MB_OKCANCEL );
}
dw = LoadString( g_hinstance, IDS_NOT_COPYING_REPARSE_POINT_LOG, szTemplate, ARRAYSIZE(szTemplate) );
Assert( dw );
LogMsg( szTemplate, pszFile );
pitem->uState = ( i == IDOK ? ERROR_SUCCESS : ERROR_REQUEST_ABORTED );
}
break;
case STATUS_MISSING_SYSTEMFILE:
MessageBoxFromStrings( hDlg, IDS_BOOT_PARTITION_TITLE, IDS_BOOT_PARTITION_TEXT, MB_OK );
pitem->uState = ERROR_REQUEST_ABORTED; // stop copying
break;
case STATUS_OBJECT_TYPE_MISMATCH:
MessageBoxFromStrings( hDlg, IDS_DYNAMIC_DISK_TITLE, IDS_DYNAMIC_DISK_TEXT, MB_OK );
pitem->uState = ERROR_REQUEST_ABORTED; // stop copying
break;
case ERROR_OLD_WIN_VERSION:
default:
if ( Error != ERROR_SUCCESS )
{
if ( uMsg == WM_ERROR_OK || Error == ERROR_OLD_WIN_VERSION )
{
MessageBoxFromError( hDlg, (LPWSTR) pszFile, (DWORD) Error, NULL, MB_OK );
pitem->uState = ERROR_REQUEST_ABORTED;
}
else // uMsg == WM_ERROR
{
WCHAR szTemplate[ 1024 ]; // random
DWORD dw = LoadString( g_hinstance, IDS_RETRY_ABORT_IGNORE_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
if ( !g_fQuietFlag )
{
INT i = MessageBoxFromError(
hDlg,
(LPWSTR) pszFile,
(DWORD) RtlNtStatusToDosError(Error),
szTemplate,
MB_ABORTRETRYIGNORE );
if ( i == IDABORT )
{
pitem->uState = ERROR_REQUEST_ABORTED;
}
else if ( i == IDRETRY )
{
pitem->uState = STATUS_RETRY;
}
else // ignore the error
{
pitem->uState = ERROR_SUCCESS;
}
}
else // ignore the error - it will be logged.
{
pitem->uState = ERROR_SUCCESS;
}
}
LogMsg( L"Error 0x%08x: %s\r\n", Error, pszFile );
}
break;
}
}
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, result );
break;
}
return TRUE;
}