Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

552 lines
20 KiB

  1. /****************************************************************************
  2. Copyright (c) Microsoft Corporation 1998
  3. All rights reserved
  4. File: TASKS.CPP
  5. ***************************************************************************/
  6. #include "pch.h"
  7. #include "callback.h"
  8. #include "utils.h"
  9. #include "tasks.h"
  10. #include "logging.h"
  11. DEFINE_MODULE("RIPREP")
  12. extern HWND g_hTasksDialog;
  13. typedef struct {
  14. HANDLE hChecked;
  15. HANDLE hError;
  16. HANDLE hArrow;
  17. HANDLE hFontNormal;
  18. HANDLE hFontBold;
  19. int dwWidth;
  20. int dwHeight;
  21. } SETUPDLGDATA, *LPSETUPDLGDATA;
  22. //
  23. // TasksDlgProc()
  24. //
  25. INT_PTR CALLBACK
  26. TasksDlgProc(
  27. HWND hDlg,
  28. UINT uMsg,
  29. WPARAM wParam,
  30. LPARAM lParam )
  31. {
  32. static HBRUSH hBrush = NULL;
  33. LPSETUPDLGDATA psdd = (LPSETUPDLGDATA) GetWindowLongPtr( hDlg, GWLP_USERDATA );
  34. INT_PTR result;
  35. switch (uMsg)
  36. {
  37. default:
  38. return FALSE;
  39. case WM_INITDIALOG:
  40. {
  41. BITMAP bm;
  42. // grab the bitmaps
  43. psdd =
  44. (LPSETUPDLGDATA) TraceAlloc( GMEM_FIXED, sizeof(SETUPDLGDATA) );
  45. if ( psdd == NULL ) {
  46. // This returns FALSE at successful completion
  47. // So returning opposite
  48. return TRUE;
  49. }
  50. psdd->hChecked = LoadImage( g_hinstance,
  51. MAKEINTRESOURCE( IDB_CHECK ),
  52. IMAGE_BITMAP,
  53. 0, 0,
  54. LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
  55. DebugMemoryAddHandle( psdd->hChecked );
  56. GetObject( psdd->hChecked, sizeof(bm), &bm );
  57. psdd->dwWidth = bm.bmWidth;
  58. psdd->hError = LoadImage( g_hinstance,
  59. MAKEINTRESOURCE( IDB_X ),
  60. IMAGE_BITMAP,
  61. 0, 0,
  62. LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
  63. DebugMemoryAddHandle( psdd->hError );
  64. GetObject( psdd->hError, sizeof(bm), &bm );
  65. psdd->dwWidth = ( psdd->dwWidth > bm.bmWidth ? psdd->dwWidth : bm.bmWidth );
  66. psdd->hArrow = LoadImage( g_hinstance,
  67. MAKEINTRESOURCE( IDB_ARROW ),
  68. IMAGE_BITMAP,
  69. 0, 0,
  70. LR_DEFAULTSIZE | LR_LOADTRANSPARENT );
  71. DebugMemoryAddHandle( psdd->hArrow );
  72. GetObject( psdd->hArrow, sizeof(bm), &bm );
  73. psdd->dwWidth = ( psdd->dwWidth > bm.bmWidth ?
  74. psdd->dwWidth :
  75. bm.bmWidth );
  76. HWND hwnd = GetDlgItem( hDlg, IDC_L_TASKS );
  77. HFONT hFontOld = (HFONT) SendMessage( hwnd, WM_GETFONT, 0, 0);
  78. if(hFontOld != NULL)
  79. {
  80. LOGFONT lf;
  81. if ( GetObject( hFontOld, sizeof(LOGFONT), (LPSTR) &lf ) )
  82. {
  83. DWORD dw = LoadString( g_hinstance,
  84. IDS_LARGEFONTNAME,
  85. lf.lfFaceName,
  86. LF_FACESIZE);
  87. Assert( dw );
  88. lf.lfWidth = 0;
  89. lf.lfWeight = 400;
  90. lf.lfHeight -= 4;
  91. psdd->hFontNormal = CreateFontIndirect(&lf);
  92. DebugMemoryAddHandle( psdd->hFontNormal );
  93. lf.lfWeight = 700;
  94. psdd->hFontBold = CreateFontIndirect(&lf);
  95. DebugMemoryAddHandle( psdd->hFontBold );
  96. }
  97. }
  98. HDC hDC = GetDC( NULL );
  99. SelectObject( hDC, psdd->hFontBold );
  100. TEXTMETRIC tm;
  101. GetTextMetrics( hDC, &tm );
  102. psdd->dwHeight = tm.tmHeight;
  103. ReleaseDC( NULL, hDC );
  104. SetWindowLongPtr( hDlg, GWLP_USERDATA, (LONG_PTR) psdd );
  105. WCHAR szTitle[ 256 ];
  106. DWORD dw;
  107. dw = LoadString( g_hinstance, IDS_APPNAME, szTitle, ARRAYSIZE(szTitle));
  108. Assert( dw );
  109. SetWindowText( hDlg, szTitle );
  110. SetDlgItemText( hDlg, IDC_S_OPERATION, L"" );
  111. CenterDialog( hDlg );
  112. return FALSE;
  113. }
  114. break;
  115. case WM_MEASUREITEM:
  116. {
  117. LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT) lParam;
  118. RECT rc;
  119. if ( lpmis == NULL ) {
  120. // Breaks and returns TRUE at successful completion
  121. // So returning opposite
  122. return FALSE;
  123. }
  124. HWND hwnd = GetDlgItem( hDlg, IDC_L_TASKS );
  125. GetClientRect( hwnd, &rc );
  126. lpmis->itemWidth = rc.right - rc.left;
  127. lpmis->itemHeight = psdd->dwHeight;
  128. }
  129. break;
  130. case WM_DRAWITEM:
  131. {
  132. Assert( psdd );
  133. LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT) lParam;
  134. if ( !lpdis ) {
  135. // Below, another null pointer in the same
  136. // data field is taken care of. We are
  137. // duplicating the result here.
  138. break; // ignore
  139. }
  140. LPLBITEMDATA plbid = (LPLBITEMDATA)lpdis->itemData;
  141. RECT rc = lpdis->rcItem;
  142. HANDLE hOldFont = INVALID_HANDLE_VALUE;
  143. WCHAR szText[MAX_PATH];
  144. if ( !plbid )
  145. break; // ignore
  146. ListBox_GetText(lpdis->hwndItem, lpdis->itemID, szText);
  147. rc.right = rc.bottom = psdd->dwWidth;
  148. switch ( plbid->uState )
  149. {
  150. case STATE_NOTSTARTED:
  151. hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
  152. break;
  153. case STATE_STARTED:
  154. DrawBitmap( psdd->hArrow, lpdis, &rc );
  155. hOldFont = SelectObject( lpdis->hDC, psdd->hFontBold );
  156. break;
  157. case STATE_DONE:
  158. DrawBitmap( psdd->hChecked, lpdis, &rc );
  159. hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
  160. break;
  161. case STATE_ERROR:
  162. DrawBitmap( psdd->hError, lpdis, &rc );
  163. hOldFont = SelectObject( lpdis->hDC, psdd->hFontNormal );
  164. break;
  165. }
  166. rc = lpdis->rcItem;
  167. rc.left += psdd->dwHeight;
  168. DrawText( lpdis->hDC, plbid->pszText, -1, &rc, DT_LEFT | DT_VCENTER );
  169. if ( hOldFont != INVALID_HANDLE_VALUE )
  170. {
  171. SelectObject( lpdis->hDC, hOldFont );
  172. }
  173. }
  174. break;
  175. case WM_CTLCOLORLISTBOX:
  176. if ( hBrush == NULL )
  177. {
  178. LOGBRUSH brush;
  179. brush.lbColor = GetSysColor( COLOR_3DFACE );
  180. brush.lbStyle = BS_SOLID;
  181. hBrush = (HBRUSH) CreateBrushIndirect( &brush );
  182. DebugMemoryAddHandle( hBrush );
  183. }
  184. SetBkMode( (HDC) wParam, OPAQUE );
  185. SetBkColor( (HDC) wParam, GetSysColor( COLOR_3DFACE ) );
  186. return (INT_PTR)hBrush;
  187. case WM_DESTROY:
  188. if ( hBrush != NULL )
  189. {
  190. DebugMemoryDelete( hBrush );
  191. DeleteObject(hBrush);
  192. hBrush = NULL;
  193. }
  194. Assert( psdd );
  195. DeleteObject( psdd->hChecked );
  196. DebugMemoryDelete( psdd->hChecked );
  197. DeleteObject( psdd->hError );
  198. DebugMemoryDelete( psdd->hError );
  199. DeleteObject( psdd->hArrow );
  200. DebugMemoryDelete( psdd->hArrow );
  201. DeleteObject( psdd->hFontNormal );
  202. DebugMemoryDelete( psdd->hFontNormal );
  203. DeleteObject( psdd->hFontBold );
  204. DebugMemoryDelete( psdd->hFontBold );
  205. TraceFree( psdd );
  206. SetWindowLongPtr( hDlg, GWLP_USERDATA, NULL );
  207. EndDialog( g_hTasksDialog, 0 );
  208. break;
  209. case WM_SETTINGCHANGE:
  210. if ( hBrush != NULL )
  211. {
  212. DebugMemoryDelete( hBrush );
  213. DeleteObject(hBrush);
  214. hBrush = NULL;
  215. }
  216. break;
  217. case WM_UPDATE:
  218. {
  219. RECT rc;
  220. LPWSTR pszOperation = (LPWSTR) wParam;
  221. LPWSTR pszObject = (LPWSTR) lParam;
  222. LPWSTR pszTemp = NULL;
  223. LPWSTR psz;
  224. if ( lParam && wParam ) {
  225. RECT rect;
  226. SIZE size;
  227. HDC hdc = GetDC( hDlg );
  228. INT iLength = wcslen( pszOperation );
  229. psz = pszObject;
  230. if ( psz && StrCmpN( psz, L"\\\\?\\", 4) == 0 )
  231. {
  232. psz += 4;
  233. }
  234. GetWindowRect( GetDlgItem( hDlg, IDC_S_OPERATION ), &rect );
  235. if (hdc != NULL) {
  236. GetTextExtentPoint( hdc, pszOperation, iLength, &size );
  237. PathCompactPath( hdc, psz, rect.right - rect.left - size.cx );
  238. ReleaseDC( hDlg, hdc );
  239. }
  240. pszTemp = (LPWSTR) TraceAlloc( LMEM_FIXED, (iLength + wcslen(psz) + 2) * sizeof(WCHAR)); // +1 space +1 NULL
  241. if (!pszTemp )
  242. goto Update_Cleanup;
  243. wsprintf( pszTemp, pszOperation, psz );
  244. psz = pszTemp;
  245. } else if ( pszObject ) {
  246. psz = pszObject;
  247. } else if ( wParam ) {
  248. psz = pszOperation;
  249. } else {
  250. psz = L"";
  251. }
  252. Assert( psz );
  253. SetDlgItemText( hDlg, IDC_S_OPERATION, psz );
  254. Update_Cleanup:
  255. if ( pszTemp )
  256. TraceFree( pszTemp );
  257. if ( pszObject )
  258. TraceFree( pszObject );
  259. if ( pszOperation )
  260. TraceFree( pszOperation );
  261. }
  262. break;
  263. case WM_ERROR:
  264. case WM_ERROR_OK:
  265. //
  266. // Close the log file to prevent the "write-behind / data-loss" popups.
  267. //
  268. if ( g_hLogFile != INVALID_HANDLE_VALUE ) {
  269. CloseHandle( g_hLogFile );
  270. g_hLogFile = INVALID_HANDLE_VALUE;
  271. }
  272. // Signal that the error log should be displayed.
  273. g_fErrorOccurred = TRUE;
  274. result = TRUE; // message processed
  275. if ( lParam != NULL )
  276. {
  277. LBITEMDATA * pitem = (LBITEMDATA *) lParam;
  278. LPWSTR pszFile = pitem->pszText;
  279. DWORD Error = pitem->uState;
  280. // Remove the "\\?\" from the beginning of the line
  281. if ( pszFile != NULL
  282. && StrCmpN( pszFile, L"\\\\?\\", 4 ) == 0 )
  283. {
  284. pszFile = &pszFile[4];
  285. }
  286. switch (Error)
  287. {
  288. case ERROR_DISK_FULL:
  289. {
  290. WCHAR szTemplate[ 1024 ];
  291. INT i = MessageBoxFromStrings( hDlg, IDS_DISK_FULL_TITLE, IDS_DISK_FULL_TEXT, MB_ABORTRETRYIGNORE );
  292. DWORD dw = LoadString( g_hinstance, IDS_DISK_FULL_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
  293. Assert( dw );
  294. LogMsg( szTemplate );
  295. if ( i == IDABORT )
  296. {
  297. pitem->uState = ERROR_REQUEST_ABORTED;
  298. }
  299. else if ( i == IDRETRY )
  300. {
  301. pitem->uState = STATUS_RETRY;
  302. }
  303. else // ignore the error
  304. {
  305. pitem->uState = ERROR_SUCCESS;
  306. }
  307. }
  308. break;
  309. case ERROR_FILE_ENCRYPTED:
  310. {
  311. INT i = IDOK;
  312. WCHAR szTemplate[ 1024 ]; // random
  313. WCHAR szText[ ARRAYSIZE(szTemplate) + MAX_PATH ];
  314. WCHAR szTitle[ MAX_PATH ]; // random
  315. DWORD dw;
  316. dw = LoadString( g_hinstance, IDS_ENCRYPTED_FILE_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
  317. Assert( dw );
  318. dw = LoadString( g_hinstance, IDS_ENCRYPTED_FILE_TITLE, szTitle, ARRAYSIZE(szTitle) );
  319. Assert( dw );
  320. wsprintf( szText, szTemplate, pszFile );
  321. if ( !g_fQuietFlag ) {
  322. i = MessageBox( hDlg, szText, szTitle, MB_OKCANCEL );
  323. }
  324. dw = LoadString( g_hinstance, IDS_ENCRYPTED_FILE_LOG, szTemplate, ARRAYSIZE(szTemplate) );
  325. Assert( dw );
  326. LogMsg( szTemplate, pszFile );
  327. pitem->uState = ( i == IDOK ? ERROR_SUCCESS : ERROR_REQUEST_ABORTED );
  328. }
  329. break;
  330. case ERROR_SHARING_VIOLATION:
  331. {
  332. BOOL SkipCheck = FALSE;
  333. WCHAR szTemplate[ 1024 ]; // random
  334. WCHAR szText[ ARRAYSIZE(szTemplate) + MAX_PATH ];
  335. WCHAR szTitle[ MAX_PATH ]; // random
  336. DWORD dw;
  337. if (g_hCompatibilityInf != INVALID_HANDLE_VALUE) {
  338. INFCONTEXT Context;
  339. if (SetupFindFirstLine(
  340. g_hCompatibilityInf,
  341. L"FilesToIgnoreCopyErrors",
  342. pszFile,
  343. &Context)) {
  344. pitem->uState = ERROR_SUCCESS;
  345. SkipCheck = TRUE;
  346. }
  347. }
  348. if (!SkipCheck) {
  349. dw = LoadString( g_hinstance, IDS_SHARING_VIOLATION_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
  350. Assert( dw );
  351. dw = LoadString( g_hinstance, IDS_SHARING_VIOLATION_TITLE, szTitle, ARRAYSIZE(szTitle) );
  352. Assert( dw );
  353. wsprintf( szText, szTemplate, pszFile );
  354. if ( !g_fQuietFlag )
  355. {
  356. INT i = MessageBox( hDlg, szText, szTitle, MB_ABORTRETRYIGNORE );
  357. if ( i == IDABORT )
  358. {
  359. pitem->uState = ERROR_REQUEST_ABORTED;
  360. }
  361. else if ( i == IDRETRY )
  362. {
  363. pitem->uState = STATUS_RETRY;
  364. }
  365. else // ignore the error
  366. {
  367. pitem->uState = ERROR_SUCCESS;
  368. }
  369. }
  370. else // ignore the error - it will be logged
  371. {
  372. pitem->uState = ERROR_SUCCESS;
  373. }
  374. }
  375. dw = LoadString( g_hinstance, IDS_SHARING_VIOLATION_LOG, szTemplate, ARRAYSIZE(szTemplate) );
  376. Assert( dw );
  377. LogMsg( szTemplate, pszFile );
  378. }
  379. break;
  380. case ERROR_ACCESS_DENIED:
  381. {
  382. INT i = IDOK;
  383. WCHAR szTemplate[ 1024 ]; // random
  384. WCHAR szText[ ARRAYSIZE(szTemplate) + MAX_PATH ];
  385. WCHAR szTitle[ MAX_PATH ]; // random
  386. DWORD dw;
  387. dw = LoadString( g_hinstance, IDS_ACCESS_DENIED_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
  388. Assert( dw );
  389. dw = LoadString( g_hinstance, IDS_ACCESS_DENIED_TITLE, szTitle, ARRAYSIZE(szTitle) );
  390. Assert( dw );
  391. wsprintf( szText, szTemplate, pszFile );
  392. if ( !g_fQuietFlag ) {
  393. i = MessageBox( hDlg, szText, szTitle, MB_OKCANCEL );
  394. }
  395. dw = LoadString( g_hinstance, IDS_ACCESS_DENIED_LOG, szTemplate, ARRAYSIZE(szTemplate) );
  396. Assert( dw );
  397. LogMsg( szTemplate, pszFile );
  398. pitem->uState = ( i == IDOK ? ERROR_SUCCESS : ERROR_REQUEST_ABORTED );
  399. }
  400. break;
  401. case ERROR_INVALID_DRIVE: // special meaning multi-disk detected
  402. {
  403. INT i = IDOK;
  404. i = MessageBoxFromStrings( hDlg, IDS_MULTIPLE_DISK_TITLE, IDS_MULTIPLE_DISK_TEXT, MB_OKCANCEL );
  405. pitem->uState = ( i == IDOK ? ERROR_SUCCESS : ERROR_REQUEST_ABORTED );
  406. }
  407. break;
  408. case ERROR_REPARSE_ATTRIBUTE_CONFLICT:
  409. {
  410. INT i = IDOK;
  411. WCHAR szTemplate[ 1024 ]; // random
  412. WCHAR szText[ ARRAYSIZE(szTemplate) + MAX_PATH ];
  413. WCHAR szTitle[ MAX_PATH ]; // random
  414. DWORD dw;
  415. dw = LoadString( g_hinstance, IDS_NOT_COPYING_REPARSE_POINT_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
  416. Assert( dw );
  417. dw = LoadString( g_hinstance, IDS_NOT_COPYING_REPARSE_POINT_TITLE, szTitle, ARRAYSIZE(szTitle) );
  418. Assert( dw );
  419. wsprintf( szText, szTemplate, pszFile );
  420. if ( !g_fQuietFlag ) {
  421. i = MessageBox( hDlg, szText, szTitle, MB_OKCANCEL );
  422. }
  423. dw = LoadString( g_hinstance, IDS_NOT_COPYING_REPARSE_POINT_LOG, szTemplate, ARRAYSIZE(szTemplate) );
  424. Assert( dw );
  425. LogMsg( szTemplate, pszFile );
  426. pitem->uState = ( i == IDOK ? ERROR_SUCCESS : ERROR_REQUEST_ABORTED );
  427. }
  428. break;
  429. case STATUS_MISSING_SYSTEMFILE:
  430. MessageBoxFromStrings( hDlg, IDS_BOOT_PARTITION_TITLE, IDS_BOOT_PARTITION_TEXT, MB_OK );
  431. pitem->uState = ERROR_REQUEST_ABORTED; // stop copying
  432. break;
  433. case STATUS_OBJECT_TYPE_MISMATCH:
  434. MessageBoxFromStrings( hDlg, IDS_DYNAMIC_DISK_TITLE, IDS_DYNAMIC_DISK_TEXT, MB_OK );
  435. pitem->uState = ERROR_REQUEST_ABORTED; // stop copying
  436. break;
  437. case ERROR_OLD_WIN_VERSION:
  438. default:
  439. if ( Error != ERROR_SUCCESS )
  440. {
  441. if ( uMsg == WM_ERROR_OK || Error == ERROR_OLD_WIN_VERSION )
  442. {
  443. MessageBoxFromError( hDlg, (LPWSTR) pszFile, (DWORD) Error, NULL, MB_OK );
  444. pitem->uState = ERROR_REQUEST_ABORTED;
  445. }
  446. else // uMsg == WM_ERROR
  447. {
  448. WCHAR szTemplate[ 1024 ]; // random
  449. DWORD dw = LoadString( g_hinstance, IDS_RETRY_ABORT_IGNORE_TEXT, szTemplate, ARRAYSIZE(szTemplate) );
  450. if ( !g_fQuietFlag )
  451. {
  452. INT i = MessageBoxFromError(
  453. hDlg,
  454. (LPWSTR) pszFile,
  455. (DWORD) RtlNtStatusToDosError(Error),
  456. szTemplate,
  457. MB_ABORTRETRYIGNORE );
  458. if ( i == IDABORT )
  459. {
  460. pitem->uState = ERROR_REQUEST_ABORTED;
  461. }
  462. else if ( i == IDRETRY )
  463. {
  464. pitem->uState = STATUS_RETRY;
  465. }
  466. else // ignore the error
  467. {
  468. pitem->uState = ERROR_SUCCESS;
  469. }
  470. }
  471. else // ignore the error - it will be logged.
  472. {
  473. pitem->uState = ERROR_SUCCESS;
  474. }
  475. }
  476. LogMsg( L"Error 0x%08x: %s\r\n", Error, pszFile );
  477. }
  478. break;
  479. }
  480. }
  481. SetWindowLongPtr( hDlg, DWLP_MSGRESULT, result );
  482. break;
  483. }
  484. return TRUE;
  485. }