553 lines
20 KiB
C++
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;
|
|
}
|