/**************************************************************************** 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; }