1 /* 2 * ReactOS Win32 Applications 3 * Copyright (C) 2007 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* 20 * COPYRIGHT : See COPYING in the top level directory 21 * PROJECT : Event Log Viewer 22 * FILE : eventvwr.c 23 * PROGRAMMER: Marc Piulachs (marc.piulachs at codexchange [dot] net) 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <windef.h> 29 #include <winbase.h> 30 #include <winuser.h> 31 #include <wingdi.h> 32 #include <winnls.h> 33 #include <winreg.h> 34 #include <commctrl.h> 35 #include <commdlg.h> 36 #include <strsafe.h> 37 38 #include "resource.h" 39 40 #if _MSC_VER 41 #pragma warning(disable: 4996) /* 'strdup' was declared deprecated */ 42 #define _CRT_SECURE_NO_DEPRECATE /* all deprecated unsafe string functions */ 43 #endif 44 45 static const WCHAR szWindowClass[] = L"EVENTVWR"; /* the main window class name*/ 46 static const WCHAR EVENTLOG_BASE_KEY[] = L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\"; 47 48 // MessageFile message buffer size 49 #define EVENT_MESSAGE_EVENTTEXT_BUFFER 1024*10 50 #define EVENT_MESSAGE_FILE_BUFFER 1024*10 51 #define EVENT_DLL_SEPARATOR L";" 52 #define EVENT_MESSAGE_FILE L"EventMessageFile" 53 #define EVENT_CATEGORY_MESSAGE_FILE L"CategoryMessageFile" 54 #define EVENT_PARAMETER_MESSAGE_FILE L"ParameterMessageFile" 55 56 #define MAX_LOADSTRING 255 57 #define ENTRY_SIZE 2056 58 59 /* Globals */ 60 HINSTANCE hInst; /* current instance */ 61 WCHAR szTitle[MAX_LOADSTRING]; /* The title bar text */ 62 WCHAR szTitleTemplate[MAX_LOADSTRING]; /* The logged-on title bar text */ 63 WCHAR szSaveFilter[MAX_LOADSTRING]; /* Filter Mask for the save Dialog */ 64 HWND hwndMainWindow; /* Main window */ 65 HWND hwndListView; /* ListView control */ 66 HWND hwndStatus; /* Status bar */ 67 HMENU hMainMenu; /* The application's main menu */ 68 WCHAR szStatusBarTemplate[MAX_LOADSTRING]; /* The status bar text */ 69 PEVENTLOGRECORD *g_RecordPtrs = NULL; 70 DWORD g_TotalRecords = 0; 71 OPENFILENAMEW sfn; 72 73 LPWSTR lpSourceLogName = NULL; 74 LPWSTR lpComputerName = NULL; 75 76 DWORD dwNumLogs = 0; 77 WCHAR **LogNames; 78 79 /* Forward declarations of functions included in this code module: */ 80 ATOM MyRegisterClass(HINSTANCE hInstance); 81 BOOL InitInstance(HINSTANCE, int); 82 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 83 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 84 INT_PTR CALLBACK EventDetails(HWND, UINT, WPARAM, LPARAM); 85 static INT_PTR CALLBACK StatusMessageWindowProc (HWND, UINT, WPARAM, LPARAM); 86 87 88 int APIENTRY 89 wWinMain(HINSTANCE hInstance, 90 HINSTANCE hPrevInstance, 91 LPWSTR lpCmdLine, 92 int nCmdShow) 93 { 94 MSG msg; 95 HACCEL hAccelTable; 96 INITCOMMONCONTROLSEX iccx; 97 98 UNREFERENCED_PARAMETER(hPrevInstance); 99 UNREFERENCED_PARAMETER(lpCmdLine); 100 101 /* Whenever any of the common controls are used in your app, 102 * you must call InitCommonControlsEx() to register the classes 103 * for those controls. */ 104 iccx.dwSize = sizeof(INITCOMMONCONTROLSEX); 105 iccx.dwICC = ICC_LISTVIEW_CLASSES; 106 InitCommonControlsEx(&iccx); 107 108 /* Initialize global strings */ 109 LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 110 LoadStringW(hInstance, IDS_APP_TITLE_EX, szTitleTemplate, MAX_LOADSTRING); 111 LoadStringW(hInstance, IDS_STATUS_MSG, szStatusBarTemplate, MAX_LOADSTRING); 112 MyRegisterClass(hInstance); 113 114 /* Perform application initialization: */ 115 if (!InitInstance(hInstance, nCmdShow)) 116 { 117 return FALSE; 118 } 119 120 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_EVENTVWR)); 121 122 /* Main message loop: */ 123 while (GetMessageW(&msg, NULL, 0, 0)) 124 { 125 if (!TranslateAcceleratorW(msg.hwnd, hAccelTable, &msg)) 126 { 127 TranslateMessage(&msg); 128 DispatchMessage(&msg); 129 } 130 } 131 132 return (int)msg.wParam; 133 } 134 135 static void FreeRecords(void) 136 { 137 DWORD iIndex; 138 139 if (!g_RecordPtrs) 140 return; 141 142 for (iIndex = 0; iIndex < g_TotalRecords; iIndex++) 143 HeapFree(GetProcessHeap(), 0, g_RecordPtrs[iIndex]); 144 HeapFree(GetProcessHeap(), 0, g_RecordPtrs); 145 g_RecordPtrs = NULL; 146 } 147 148 VOID 149 ShowLastWin32Error(VOID) 150 { 151 DWORD dwError; 152 LPWSTR lpMessageBuffer; 153 154 dwError = GetLastError(); 155 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 156 NULL, 157 dwError, 158 0, 159 (LPWSTR)&lpMessageBuffer, 160 0, 161 NULL); 162 163 MessageBoxW(hwndMainWindow, lpMessageBuffer, szTitle, MB_OK | MB_ICONERROR); 164 LocalFree(lpMessageBuffer); 165 } 166 167 VOID 168 EventTimeToSystemTime(DWORD EventTime, 169 SYSTEMTIME *pSystemTime) 170 { 171 SYSTEMTIME st1970 = { 1970, 1, 0, 1, 0, 0, 0, 0 }; 172 FILETIME ftLocal; 173 union 174 { 175 FILETIME ft; 176 ULONGLONG ll; 177 } u1970, uUCT; 178 179 uUCT.ft.dwHighDateTime = 0; 180 uUCT.ft.dwLowDateTime = EventTime; 181 SystemTimeToFileTime(&st1970, &u1970.ft); 182 uUCT.ll = uUCT.ll * 10000000 + u1970.ll; 183 FileTimeToLocalFileTime(&uUCT.ft, &ftLocal); 184 FileTimeToSystemTime(&ftLocal, pSystemTime); 185 } 186 187 188 void 189 TrimNulls(LPWSTR s) 190 { 191 WCHAR *c; 192 193 if (s != NULL) 194 { 195 c = s + wcslen(s) - 1; 196 while (c >= s && iswspace(*c)) 197 --c; 198 *++c = L'\0'; 199 } 200 } 201 202 203 BOOL 204 GetEventMessageFileDLL(IN LPCWSTR lpLogName, 205 IN LPCWSTR SourceName, 206 IN LPCWSTR EntryName, 207 OUT PWCHAR ExpandedName) 208 { 209 DWORD dwSize; 210 BYTE szModuleName[MAX_PATH]; 211 WCHAR szKeyName[MAX_PATH]; 212 HKEY hAppKey = NULL; 213 HKEY hSourceKey = NULL; 214 BOOL bReturn = FALSE; 215 216 StringCbCopyW(szKeyName, sizeof(szKeyName), L"SYSTEM\\CurrentControlSet\\Services\\EventLog\\"); 217 StringCbCatW(szKeyName, sizeof(szKeyName), lpLogName); 218 219 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, 220 szKeyName, 221 0, 222 KEY_READ, 223 &hAppKey) == ERROR_SUCCESS) 224 { 225 if (RegOpenKeyExW(hAppKey, 226 SourceName, 227 0, 228 KEY_READ, 229 &hSourceKey) == ERROR_SUCCESS) 230 { 231 dwSize = MAX_PATH; 232 if (RegQueryValueExW(hSourceKey, 233 EntryName, 234 NULL, 235 NULL, 236 (LPBYTE)szModuleName, 237 &dwSize) == ERROR_SUCCESS) 238 { 239 /* Returns a string containing the requested substituted environment variable. */ 240 ExpandEnvironmentStringsW((LPCWSTR)szModuleName, ExpandedName, MAX_PATH); 241 242 /* Successful */ 243 bReturn = TRUE; 244 } 245 } 246 } 247 else 248 { 249 ShowLastWin32Error(); 250 } 251 252 if (hSourceKey != NULL) 253 RegCloseKey(hSourceKey); 254 255 if (hAppKey != NULL) 256 RegCloseKey(hAppKey); 257 258 return bReturn; 259 } 260 261 262 BOOL 263 GetEventCategory(IN LPCWSTR KeyName, 264 IN LPCWSTR SourceName, 265 IN EVENTLOGRECORD *pevlr, 266 OUT PWCHAR CategoryName) 267 { 268 HANDLE hLibrary = NULL; 269 WCHAR szMessageDLL[MAX_PATH]; 270 LPVOID lpMsgBuf = NULL; 271 272 if (GetEventMessageFileDLL (KeyName, SourceName, EVENT_CATEGORY_MESSAGE_FILE , szMessageDLL)) 273 { 274 hLibrary = LoadLibraryExW(szMessageDLL, 275 NULL, 276 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); 277 if (hLibrary != NULL) 278 { 279 /* Retrieve the message string. */ 280 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY, 281 hLibrary, 282 pevlr->EventCategory, 283 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 284 (LPWSTR)&lpMsgBuf, 285 EVENT_MESSAGE_FILE_BUFFER, 286 NULL) != 0) 287 { 288 /* Trim the string */ 289 TrimNulls(lpMsgBuf); 290 291 /* Copy the category name */ 292 StringCchCopyW(CategoryName, MAX_PATH, lpMsgBuf); 293 } 294 else 295 { 296 LoadStringW(hInst, IDS_NONE, CategoryName, MAX_PATH); 297 } 298 299 if (hLibrary != NULL) 300 FreeLibrary(hLibrary); 301 302 /* Free the buffer allocated by FormatMessage */ 303 if (lpMsgBuf) 304 LocalFree(lpMsgBuf); 305 306 return TRUE; 307 } 308 } 309 310 LoadStringW(hInst, IDS_NONE, CategoryName, MAX_PATH); 311 312 return FALSE; 313 } 314 315 316 BOOL 317 GetEventMessage(IN LPCWSTR KeyName, 318 IN LPCWSTR SourceName, 319 IN EVENTLOGRECORD *pevlr, 320 OUT PWCHAR EventText) 321 { 322 DWORD i; 323 HANDLE hLibrary = NULL; 324 WCHAR SourceModuleName[1000]; 325 WCHAR ParameterModuleName[1000]; 326 LPWSTR lpMsgBuf = NULL; 327 WCHAR szStringIDNotFound[MAX_LOADSTRING]; 328 LPWSTR szDll; 329 LPWSTR szMessage; 330 LPWSTR *szArguments; 331 BOOL bDone = FALSE; 332 333 /* TODO : GetEventMessageFileDLL can return a comma separated list of DLLs */ 334 if (GetEventMessageFileDLL (KeyName, SourceName, EVENT_MESSAGE_FILE, SourceModuleName)) 335 { 336 /* Get the event message */ 337 szMessage = (LPWSTR)((LPBYTE)pevlr + pevlr->StringOffset); 338 339 /* Allocate space for parameters */ 340 szArguments = malloc(sizeof(LPVOID) * pevlr->NumStrings); 341 if (!szArguments) 342 { 343 return FALSE; 344 } 345 346 for (i = 0; i < pevlr->NumStrings ; i++) 347 { 348 if (wcsstr(szMessage , L"%%")) 349 { 350 if (GetEventMessageFileDLL(KeyName, SourceName, EVENT_PARAMETER_MESSAGE_FILE, ParameterModuleName)) 351 { 352 /* Not yet support for reading messages from parameter message DLL */ 353 } 354 } 355 356 szArguments[i] = szMessage; 357 szMessage += wcslen(szMessage) + 1; 358 } 359 360 szDll = wcstok(SourceModuleName, EVENT_DLL_SEPARATOR); 361 while ((szDll != NULL) && (!bDone)) 362 { 363 hLibrary = LoadLibraryExW(szDll, 364 NULL, 365 DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); 366 if (hLibrary == NULL) 367 { 368 /* The DLL could not be loaded try the next one (if any) */ 369 szDll = wcstok(NULL, EVENT_DLL_SEPARATOR); 370 } 371 else 372 { 373 /* Retrieve the message string. */ 374 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | 375 FORMAT_MESSAGE_ALLOCATE_BUFFER | 376 FORMAT_MESSAGE_FROM_HMODULE | 377 FORMAT_MESSAGE_ARGUMENT_ARRAY, 378 hLibrary, 379 pevlr->EventID, 380 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 381 (LPWSTR)&lpMsgBuf, 382 0, 383 (va_list*)szArguments) == 0) 384 { 385 /* We haven't found the string , get next DLL (if any) */ 386 szDll = wcstok(NULL, EVENT_DLL_SEPARATOR); 387 } 388 else 389 { 390 if (lpMsgBuf) 391 { 392 /* The ID was found and the message was formated */ 393 bDone = TRUE; 394 395 /* Trim the string */ 396 TrimNulls((LPWSTR)lpMsgBuf); 397 398 /* Copy the event text */ 399 StringCchCopyW(EventText, EVENT_MESSAGE_EVENTTEXT_BUFFER, lpMsgBuf); 400 } 401 } 402 403 FreeLibrary(hLibrary); 404 } 405 } 406 407 if (!bDone) 408 { 409 LoadStringW(hInst, IDS_EVENTSTRINGIDNOTFOUND, szStringIDNotFound, MAX_LOADSTRING); 410 StringCchPrintfW(EventText, EVENT_MESSAGE_EVENTTEXT_BUFFER, szStringIDNotFound, (pevlr->EventID & 0xFFFF), SourceName); 411 } 412 413 free(szArguments); 414 415 /* No more dlls to try, return result */ 416 return bDone; 417 } 418 419 LoadStringW(hInst, IDS_EVENTSTRINGIDNOTFOUND, szStringIDNotFound, MAX_LOADSTRING); 420 StringCchPrintfW(EventText, EVENT_MESSAGE_EVENTTEXT_BUFFER, szStringIDNotFound, (pevlr->EventID & 0xFFFF), SourceName); 421 422 return FALSE; 423 } 424 425 426 VOID 427 GetEventType(IN WORD dwEventType, 428 OUT PWCHAR eventTypeText) 429 { 430 switch (dwEventType) 431 { 432 case EVENTLOG_ERROR_TYPE: 433 LoadStringW(hInst, IDS_EVENTLOG_ERROR_TYPE, eventTypeText, MAX_LOADSTRING); 434 break; 435 case EVENTLOG_WARNING_TYPE: 436 LoadStringW(hInst, IDS_EVENTLOG_WARNING_TYPE, eventTypeText, MAX_LOADSTRING); 437 break; 438 case EVENTLOG_INFORMATION_TYPE: 439 LoadStringW(hInst, IDS_EVENTLOG_INFORMATION_TYPE, eventTypeText, MAX_LOADSTRING); 440 break; 441 case EVENTLOG_AUDIT_SUCCESS: 442 LoadStringW(hInst, IDS_EVENTLOG_AUDIT_SUCCESS, eventTypeText, MAX_LOADSTRING); 443 break; 444 case EVENTLOG_AUDIT_FAILURE: 445 LoadStringW(hInst, IDS_EVENTLOG_AUDIT_FAILURE, eventTypeText, MAX_LOADSTRING); 446 break; 447 case EVENTLOG_SUCCESS: 448 LoadStringW(hInst, IDS_EVENTLOG_SUCCESS, eventTypeText, MAX_LOADSTRING); 449 break; 450 default: 451 LoadStringW(hInst, IDS_EVENTLOG_UNKNOWN_TYPE, eventTypeText, MAX_LOADSTRING); 452 break; 453 } 454 } 455 456 BOOL 457 GetEventUserName(EVENTLOGRECORD *pelr, 458 OUT PWCHAR pszUser) 459 { 460 PSID lpSid; 461 WCHAR szName[1024]; 462 WCHAR szDomain[1024]; 463 SID_NAME_USE peUse; 464 DWORD cbName = 1024; 465 DWORD cbDomain = 1024; 466 467 /* Point to the SID. */ 468 lpSid = (PSID)((LPBYTE)pelr + pelr->UserSidOffset); 469 470 /* User SID */ 471 if (pelr->UserSidLength > 0) 472 { 473 if (LookupAccountSidW(NULL, 474 lpSid, 475 szName, 476 &cbName, 477 szDomain, 478 &cbDomain, 479 &peUse)) 480 { 481 StringCchCopyW(pszUser, MAX_PATH, szName); 482 return TRUE; 483 } 484 } 485 486 return FALSE; 487 } 488 489 490 static DWORD WINAPI 491 ShowStatusMessageThread(IN LPVOID lpParameter) 492 { 493 HWND *phWnd = (HWND *)lpParameter; 494 HWND hWnd; 495 MSG Msg; 496 497 hWnd = CreateDialogParam(hInst, 498 MAKEINTRESOURCE(IDD_PROGRESSBOX), 499 GetDesktopWindow(), 500 StatusMessageWindowProc, 501 (LPARAM)NULL); 502 if (!hWnd) 503 return 0; 504 505 *phWnd = hWnd; 506 507 ShowWindow(hWnd, SW_SHOW); 508 509 /* Message loop for the Status window */ 510 while (GetMessage(&Msg, NULL, 0, 0)) 511 { 512 TranslateMessage(&Msg); 513 DispatchMessage(&Msg); 514 } 515 516 return 0; 517 } 518 519 520 BOOL 521 QueryEventMessages(LPWSTR lpMachineName, 522 LPWSTR lpLogName) 523 { 524 HWND hwndDlg = NULL; 525 HANDLE hEventLog; 526 EVENTLOGRECORD *pevlr; 527 DWORD dwRead, dwNeeded, dwThisRecord, dwTotalRecords = 0, dwCurrentRecord = 0, dwRecordsToRead = 0, dwFlags, dwMaxLength; 528 size_t cchRemaining; 529 LPWSTR lpSourceName; 530 LPWSTR lpComputerName; 531 LPSTR lpData; 532 BOOL bResult = TRUE; /* Read succeeded. */ 533 534 WCHAR szWindowTitle[MAX_PATH]; 535 WCHAR szStatusText[MAX_PATH]; 536 WCHAR szLocalDate[MAX_PATH]; 537 WCHAR szLocalTime[MAX_PATH]; 538 WCHAR szEventID[MAX_PATH]; 539 WCHAR szEventTypeText[MAX_LOADSTRING]; 540 WCHAR szCategoryID[MAX_PATH]; 541 WCHAR szUsername[MAX_PATH]; 542 WCHAR szEventText[EVENT_MESSAGE_FILE_BUFFER]; 543 WCHAR szCategory[MAX_PATH]; 544 WCHAR szData[MAX_PATH]; 545 PWCHAR lpTitleTemplateEnd; 546 547 SYSTEMTIME time; 548 LVITEMW lviEventItem; 549 550 dwFlags = EVENTLOG_FORWARDS_READ | EVENTLOG_SEQUENTIAL_READ; 551 552 /* Open the event log. */ 553 hEventLog = OpenEventLogW(lpMachineName, 554 lpLogName); 555 if (hEventLog == NULL) 556 { 557 ShowLastWin32Error(); 558 return FALSE; 559 } 560 561 lpSourceLogName = lpLogName; 562 lpComputerName = lpMachineName; 563 564 /* Disable listview redraw */ 565 SendMessage(hwndListView, WM_SETREDRAW, FALSE, 0); 566 567 /* Clear the list view */ 568 (void)ListView_DeleteAllItems (hwndListView); 569 FreeRecords(); 570 571 GetOldestEventLogRecord(hEventLog, &dwThisRecord); 572 573 /* Get the total number of event log records. */ 574 GetNumberOfEventLogRecords (hEventLog , &dwTotalRecords); 575 g_TotalRecords = dwTotalRecords; 576 577 if (dwTotalRecords > 0) 578 { 579 EnableMenuItem(hMainMenu, IDM_CLEAR_EVENTS, MF_BYCOMMAND | MF_ENABLED); 580 EnableMenuItem(hMainMenu, IDM_SAVE_PROTOCOL, MF_BYCOMMAND | MF_ENABLED); 581 } 582 else 583 { 584 EnableMenuItem(hMainMenu, IDM_CLEAR_EVENTS, MF_BYCOMMAND | MF_GRAYED); 585 EnableMenuItem(hMainMenu, IDM_SAVE_PROTOCOL, MF_BYCOMMAND | MF_GRAYED); 586 } 587 588 g_RecordPtrs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwTotalRecords * sizeof(PVOID)); 589 590 /* If we have at least 1000 records show the waiting dialog */ 591 if (dwTotalRecords > 1000) 592 { 593 CloseHandle(CreateThread(NULL, 594 0, 595 ShowStatusMessageThread, 596 (LPVOID)&hwndDlg, 597 0, 598 NULL)); 599 } 600 601 while (dwCurrentRecord < dwTotalRecords) 602 { 603 pevlr = HeapAlloc(GetProcessHeap(), 0, sizeof(EVENTLOGRECORD)); 604 g_RecordPtrs[dwCurrentRecord] = pevlr; 605 606 bResult = ReadEventLog(hEventLog, // Event log handle 607 dwFlags, // Sequential read 608 0, // Ignored for sequential read 609 pevlr, // Pointer to buffer 610 sizeof(EVENTLOGRECORD), // Size of buffer 611 &dwRead, // Number of bytes read 612 &dwNeeded); // Bytes in the next record 613 if((!bResult) && (GetLastError () == ERROR_INSUFFICIENT_BUFFER)) 614 { 615 HeapFree(GetProcessHeap(), 0, pevlr); 616 pevlr = HeapAlloc(GetProcessHeap(), 0, dwNeeded); 617 g_RecordPtrs[dwCurrentRecord] = pevlr; 618 619 ReadEventLogW(hEventLog, // event log handle 620 dwFlags, // read flags 621 0, // offset; default is 0 622 pevlr, // pointer to buffer 623 dwNeeded, // size of buffer 624 &dwRead, // number of bytes read 625 &dwNeeded); // bytes in next record 626 } 627 628 while (dwRead > 0) 629 { 630 LoadStringW(hInst, IDS_NOT_AVAILABLE, szUsername, MAX_PATH); 631 LoadStringW(hInst, IDS_NOT_AVAILABLE, szEventText, MAX_PATH); 632 LoadStringW(hInst, IDS_NONE, szCategory, MAX_PATH); 633 634 // Get the event source name. 635 lpSourceName = (LPWSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD)); 636 637 // Get the computer name 638 lpComputerName = (LPWSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD) + (wcslen(lpSourceName) + 1) * sizeof(WCHAR)); 639 640 // This ist the data section of the current event 641 lpData = (LPSTR)((LPBYTE)pevlr + pevlr->DataOffset); 642 643 // Compute the event type 644 EventTimeToSystemTime(pevlr->TimeWritten, &time); 645 646 // Get the username that generated the event 647 GetEventUserName(pevlr, szUsername); 648 649 GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &time, NULL, szLocalDate, MAX_PATH); 650 GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &time, NULL, szLocalTime, MAX_PATH); 651 652 GetEventType(pevlr->EventType, szEventTypeText); 653 GetEventCategory(lpLogName, lpSourceName, pevlr, szCategory); 654 655 StringCbPrintfW(szEventID, sizeof(szEventID), L"%u", (pevlr->EventID & 0xFFFF)); 656 StringCbPrintfW(szCategoryID, sizeof(szCategoryID), L"%u", pevlr->EventCategory); 657 658 lviEventItem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM; 659 lviEventItem.iItem = 0; 660 lviEventItem.iSubItem = 0; 661 lviEventItem.lParam = (LPARAM)pevlr; 662 lviEventItem.pszText = szEventTypeText; 663 664 switch (pevlr->EventType) 665 { 666 case EVENTLOG_ERROR_TYPE: 667 lviEventItem.iImage = 2; 668 break; 669 670 case EVENTLOG_AUDIT_FAILURE: 671 lviEventItem.iImage = 2; 672 break; 673 674 case EVENTLOG_WARNING_TYPE: 675 lviEventItem.iImage = 1; 676 break; 677 678 case EVENTLOG_INFORMATION_TYPE: 679 lviEventItem.iImage = 0; 680 break; 681 682 case EVENTLOG_AUDIT_SUCCESS: 683 lviEventItem.iImage = 0; 684 break; 685 686 case EVENTLOG_SUCCESS: 687 lviEventItem.iImage = 0; 688 break; 689 } 690 691 lviEventItem.iItem = ListView_InsertItem(hwndListView, &lviEventItem); 692 693 ListView_SetItemText(hwndListView, lviEventItem.iItem, 1, szLocalDate); 694 ListView_SetItemText(hwndListView, lviEventItem.iItem, 2, szLocalTime); 695 ListView_SetItemText(hwndListView, lviEventItem.iItem, 3, lpSourceName); 696 ListView_SetItemText(hwndListView, lviEventItem.iItem, 4, szCategory); 697 ListView_SetItemText(hwndListView, lviEventItem.iItem, 5, szEventID); 698 ListView_SetItemText(hwndListView, lviEventItem.iItem, 6, szUsername); //User 699 ListView_SetItemText(hwndListView, lviEventItem.iItem, 7, lpComputerName); //Computer 700 MultiByteToWideChar(CP_ACP, 701 0, 702 lpData, 703 pevlr->DataLength, 704 szData, 705 MAX_PATH); 706 ListView_SetItemText(hwndListView, lviEventItem.iItem, 8, szData); //Event Text 707 708 dwRead -= pevlr->Length; 709 pevlr = (EVENTLOGRECORD *)((LPBYTE) pevlr + pevlr->Length); 710 } 711 712 dwRecordsToRead--; 713 dwCurrentRecord++; 714 } 715 716 // All events loaded 717 if(hwndDlg) 718 EndDialog(hwndDlg, 0); 719 720 StringCchPrintfExW(szWindowTitle, 721 sizeof(szWindowTitle) / sizeof(WCHAR), 722 &lpTitleTemplateEnd, 723 &cchRemaining, 724 0, 725 szTitleTemplate, szTitle, lpLogName); /* i = number of characters written */ 726 /* lpComputerName can be NULL here if no records was read */ 727 dwMaxLength = (DWORD)cchRemaining; 728 if (!lpComputerName) 729 GetComputerNameW(lpTitleTemplateEnd, &dwMaxLength); 730 else 731 StringCchCopyW(lpTitleTemplateEnd, dwMaxLength, lpComputerName); 732 733 StringCbPrintfW(szStatusText, sizeof(szStatusText), szStatusBarTemplate, lpLogName, dwTotalRecords); 734 735 // Update the status bar 736 SendMessageW(hwndStatus, SB_SETTEXT, (WPARAM)0, (LPARAM)szStatusText); 737 738 // Set the window title 739 SetWindowTextW(hwndMainWindow, szWindowTitle); 740 741 // Resume list view redraw 742 SendMessageW(hwndListView, WM_SETREDRAW, TRUE, 0); 743 744 // Close the event log. 745 CloseEventLog(hEventLog); 746 747 return TRUE; 748 } 749 750 751 VOID 752 SaveProtocol(VOID) 753 { 754 HANDLE hEventLog; 755 WCHAR szFileName[MAX_PATH]; 756 757 ZeroMemory(szFileName, sizeof(szFileName)); 758 759 sfn.lpstrFile = szFileName; 760 sfn.nMaxFile = MAX_PATH; 761 762 if (!GetSaveFileNameW(&sfn)) 763 { 764 return; 765 } 766 767 hEventLog = OpenEventLogW(lpComputerName, lpSourceLogName); 768 if (!hEventLog) 769 { 770 ShowLastWin32Error(); 771 return; 772 } 773 774 if (!BackupEventLogW(hEventLog, szFileName)) 775 { 776 ShowLastWin32Error(); 777 } 778 779 CloseEventLog(hEventLog); 780 } 781 782 783 BOOL 784 ClearEvents(VOID) 785 { 786 HANDLE hEventLog; 787 WCHAR szFileName[MAX_PATH]; 788 WCHAR szMessage[MAX_LOADSTRING]; 789 790 ZeroMemory(szFileName, sizeof(szFileName)); 791 ZeroMemory(szMessage, sizeof(szMessage)); 792 793 LoadStringW(hInst, IDS_CLEAREVENTS_MSG, szMessage, MAX_LOADSTRING); 794 795 sfn.lpstrFile = szFileName; 796 sfn.nMaxFile = MAX_PATH; 797 798 switch (MessageBoxW(hwndMainWindow, szMessage, szTitle, MB_YESNOCANCEL | MB_ICONINFORMATION)) 799 { 800 case IDCANCEL: 801 { 802 return FALSE; 803 } 804 805 case IDNO: 806 { 807 sfn.lpstrFile = NULL; 808 break; 809 } 810 811 case IDYES: 812 { 813 if (!GetSaveFileNameW(&sfn)) 814 { 815 return FALSE; 816 } 817 break; 818 } 819 } 820 821 hEventLog = OpenEventLogW(lpComputerName, lpSourceLogName); 822 if (!hEventLog) 823 { 824 ShowLastWin32Error(); 825 return FALSE; 826 } 827 828 if (!ClearEventLogW(hEventLog, sfn.lpstrFile)) 829 { 830 ShowLastWin32Error(); 831 CloseEventLog(hEventLog); 832 return FALSE; 833 } 834 835 CloseEventLog(hEventLog); 836 837 return TRUE; 838 } 839 840 841 VOID 842 Refresh(VOID) 843 { 844 QueryEventMessages(lpComputerName, 845 lpSourceLogName); 846 } 847 848 849 ATOM 850 MyRegisterClass(HINSTANCE hInstance) 851 { 852 WNDCLASSEXW wcex; 853 854 wcex.cbSize = sizeof(WNDCLASSEX); 855 wcex.style = 0; 856 wcex.lpfnWndProc = WndProc; 857 wcex.cbClsExtra = 0; 858 wcex.cbWndExtra = 0; 859 wcex.hInstance = hInstance; 860 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_EVENTVWR)); 861 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 862 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 863 wcex.lpszMenuName = MAKEINTRESOURCE(IDM_EVENTVWR); 864 wcex.lpszClassName = szWindowClass; 865 wcex.hIconSm = (HICON)LoadImage(hInstance, 866 MAKEINTRESOURCE(IDI_EVENTVWR), 867 IMAGE_ICON, 868 16, 869 16, 870 LR_SHARED); 871 872 return RegisterClassExW(&wcex); 873 } 874 875 876 VOID 877 GetDisplayNameFile(IN LPCWSTR lpLogName, 878 OUT PWCHAR lpModuleName) 879 { 880 HKEY hKey; 881 WCHAR *KeyPath; 882 WCHAR szModuleName[MAX_PATH]; 883 DWORD cbData; 884 SIZE_T cbKeyPath; 885 886 cbKeyPath = (wcslen(EVENTLOG_BASE_KEY) + wcslen(lpLogName) + 1) * sizeof(WCHAR); 887 KeyPath = HeapAlloc(GetProcessHeap(), 0, cbKeyPath); 888 if (!KeyPath) 889 { 890 return; 891 } 892 893 StringCbCopyW(KeyPath, cbKeyPath, EVENTLOG_BASE_KEY); 894 StringCbCatW(KeyPath, cbKeyPath, lpLogName); 895 896 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 897 { 898 HeapFree(GetProcessHeap(), 0, KeyPath); 899 return; 900 } 901 902 cbData = sizeof(szModuleName); 903 if (RegQueryValueExW(hKey, L"DisplayNameFile", NULL, NULL, (LPBYTE)szModuleName, &cbData) == ERROR_SUCCESS) 904 { 905 ExpandEnvironmentStringsW(szModuleName, lpModuleName, MAX_PATH); 906 } 907 908 RegCloseKey(hKey); 909 HeapFree(GetProcessHeap(), 0, KeyPath); 910 } 911 912 913 DWORD 914 GetDisplayNameID(IN LPCWSTR lpLogName) 915 { 916 HKEY hKey; 917 WCHAR *KeyPath; 918 DWORD dwMessageID = 0; 919 DWORD cbData; 920 SIZE_T cbKeyPath; 921 922 cbKeyPath = (wcslen(EVENTLOG_BASE_KEY) + wcslen(lpLogName) + 1) * sizeof(WCHAR); 923 KeyPath = HeapAlloc(GetProcessHeap(), 0, cbKeyPath); 924 if (!KeyPath) 925 { 926 return 0; 927 } 928 929 StringCbCopyW(KeyPath, cbKeyPath, EVENTLOG_BASE_KEY); 930 StringCbCatW(KeyPath, cbKeyPath, lpLogName); 931 932 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 933 { 934 HeapFree(GetProcessHeap(), 0, KeyPath); 935 return 0; 936 } 937 938 cbData = sizeof(dwMessageID); 939 RegQueryValueExW(hKey, L"DisplayNameID", NULL, NULL, (LPBYTE)&dwMessageID, &cbData); 940 941 RegCloseKey(hKey); 942 HeapFree(GetProcessHeap(), 0, KeyPath); 943 944 return dwMessageID; 945 } 946 947 948 VOID 949 BuildLogList(void) 950 { 951 HKEY hKey; 952 DWORD lpcName; 953 DWORD dwIndex; 954 DWORD dwMessageID; 955 DWORD dwMaxKeyLength; 956 WCHAR szModuleName[MAX_PATH]; 957 LPWSTR lpDisplayName; 958 HANDLE hLibrary = NULL; 959 960 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, EVENTLOG_BASE_KEY, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 961 { 962 return; 963 } 964 965 if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwNumLogs, &dwMaxKeyLength, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) 966 { 967 RegCloseKey(hKey); 968 return; 969 } 970 971 if (!dwNumLogs) 972 { 973 RegCloseKey(hKey); 974 return; 975 } 976 977 LogNames = HeapAlloc(GetProcessHeap(), 0, (dwNumLogs + 1) * sizeof(WCHAR*)); 978 979 if (!LogNames) 980 { 981 RegCloseKey(hKey); 982 return; 983 } 984 985 for (dwIndex = 0; dwIndex < dwNumLogs; dwIndex++) 986 { 987 LogNames[dwIndex] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((dwMaxKeyLength + 1) * sizeof(WCHAR))); 988 989 if (LogNames[dwIndex] != NULL) 990 { 991 lpcName = dwMaxKeyLength + 1; 992 993 if (RegEnumKeyExW(hKey, dwIndex, LogNames[dwIndex], &lpcName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) 994 { 995 lpDisplayName = NULL; 996 997 ZeroMemory(szModuleName, sizeof(szModuleName)); 998 GetDisplayNameFile(LogNames[dwIndex], szModuleName); 999 dwMessageID = GetDisplayNameID(LogNames[dwIndex]); 1000 1001 hLibrary = LoadLibraryExW(szModuleName, NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); 1002 if (hLibrary != NULL) 1003 { 1004 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, hLibrary, dwMessageID, 0, (LPWSTR)&lpDisplayName, 0, NULL); 1005 FreeLibrary(hLibrary); 1006 } 1007 1008 if (lpDisplayName) 1009 { 1010 InsertMenuW(hMainMenu, IDM_SAVE_PROTOCOL, MF_BYCOMMAND | MF_STRING, ID_FIRST_LOG + dwIndex, lpDisplayName); 1011 } 1012 else 1013 { 1014 InsertMenuW(hMainMenu, IDM_SAVE_PROTOCOL, MF_BYCOMMAND | MF_STRING, ID_FIRST_LOG + dwIndex, LogNames[dwIndex]); 1015 } 1016 1017 LocalFree(lpDisplayName); 1018 } 1019 } 1020 } 1021 1022 InsertMenuW(hMainMenu, IDM_SAVE_PROTOCOL, MF_BYCOMMAND | MF_SEPARATOR, ID_FIRST_LOG + dwIndex + 1, NULL); 1023 1024 RegCloseKey(hKey); 1025 1026 return; 1027 } 1028 1029 1030 VOID 1031 FreeLogList(void) 1032 { 1033 DWORD dwIndex; 1034 1035 if (!LogNames) 1036 { 1037 return; 1038 } 1039 1040 for (dwIndex = 0; dwIndex < dwNumLogs; dwIndex++) 1041 { 1042 if (LogNames[dwIndex]) 1043 { 1044 HeapFree(GetProcessHeap(), 0, LogNames[dwIndex]); 1045 } 1046 1047 DeleteMenu(hMainMenu, ID_FIRST_LOG + dwIndex, MF_BYCOMMAND); 1048 } 1049 1050 DeleteMenu(hMainMenu, ID_FIRST_LOG + dwIndex + 1, MF_BYCOMMAND); 1051 1052 HeapFree(GetProcessHeap(), 0, LogNames); 1053 1054 dwNumLogs = 0; 1055 1056 return; 1057 } 1058 1059 1060 BOOL 1061 InitInstance(HINSTANCE hInstance, 1062 int nCmdShow) 1063 { 1064 HIMAGELIST hSmall; 1065 LVCOLUMNW lvc = {0}; 1066 WCHAR szTemp[256]; 1067 1068 hInst = hInstance; // Store instance handle in our global variable 1069 1070 hwndMainWindow = CreateWindowW(szWindowClass, 1071 szTitle, 1072 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 1073 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 1074 NULL, 1075 NULL, 1076 hInstance, 1077 NULL); 1078 if (!hwndMainWindow) 1079 { 1080 return FALSE; 1081 } 1082 1083 hwndStatus = CreateWindowExW(0, // no extended styles 1084 STATUSCLASSNAMEW, // status bar 1085 L"Done.", // no text 1086 WS_CHILD | WS_BORDER | WS_VISIBLE, // styles 1087 0, 0, 0, 0, // x, y, cx, cy 1088 hwndMainWindow, // parent window 1089 (HMENU)100, // window ID 1090 hInstance, // instance 1091 NULL); // window data 1092 1093 // Create our listview child window. Note that I use WS_EX_CLIENTEDGE 1094 // and WS_BORDER to create the normal "sunken" look. Also note that 1095 // LVS_EX_ styles cannot be set in CreateWindowEx(). 1096 hwndListView = CreateWindowExW(WS_EX_CLIENTEDGE, 1097 WC_LISTVIEWW, 1098 L"", 1099 LVS_SHOWSELALWAYS | WS_CHILD | WS_VISIBLE | LVS_REPORT, 1100 0, 1101 0, 1102 243, 1103 200, 1104 hwndMainWindow, 1105 NULL, 1106 hInstance, 1107 NULL); 1108 1109 // After the ListView is created, we can add extended list view styles. 1110 (void)ListView_SetExtendedListViewStyle (hwndListView, LVS_EX_FULLROWSELECT); 1111 1112 // Create the ImageList 1113 hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), 1114 GetSystemMetrics(SM_CYSMICON), 1115 ILC_COLOR32, 1116 1, 1117 1); 1118 1119 // Add event type icons to ImageList 1120 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_INFORMATIONICON))); 1121 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WARNINGICON))); 1122 ImageList_AddIcon (hSmall, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ERRORICON))); 1123 1124 // Assign ImageList to List View 1125 (void)ListView_SetImageList (hwndListView, hSmall, LVSIL_SMALL); 1126 1127 // Now set up the listview with its columns. 1128 lvc.mask = LVCF_TEXT | LVCF_WIDTH; 1129 lvc.cx = 90; 1130 LoadStringW(hInstance, 1131 IDS_COLUMNTYPE, 1132 szTemp, 1133 sizeof(szTemp) / sizeof(WCHAR)); 1134 lvc.pszText = szTemp; 1135 (void)ListView_InsertColumn(hwndListView, 0, &lvc); 1136 1137 lvc.cx = 70; 1138 LoadStringW(hInstance, 1139 IDS_COLUMNDATE, 1140 szTemp, 1141 sizeof(szTemp) / sizeof(WCHAR)); 1142 lvc.pszText = szTemp; 1143 (void)ListView_InsertColumn(hwndListView, 1, &lvc); 1144 1145 lvc.cx = 70; 1146 LoadStringW(hInstance, 1147 IDS_COLUMNTIME, 1148 szTemp, 1149 sizeof(szTemp) / sizeof(WCHAR)); 1150 lvc.pszText = szTemp; 1151 (void)ListView_InsertColumn(hwndListView, 2, &lvc); 1152 1153 lvc.cx = 150; 1154 LoadStringW(hInstance, 1155 IDS_COLUMNSOURCE, 1156 szTemp, 1157 sizeof(szTemp) / sizeof(WCHAR)); 1158 lvc.pszText = szTemp; 1159 (void)ListView_InsertColumn(hwndListView, 3, &lvc); 1160 1161 lvc.cx = 100; 1162 LoadStringW(hInstance, 1163 IDS_COLUMNCATEGORY, 1164 szTemp, 1165 sizeof(szTemp) / sizeof(WCHAR)); 1166 lvc.pszText = szTemp; 1167 (void)ListView_InsertColumn(hwndListView, 4, &lvc); 1168 1169 lvc.cx = 60; 1170 LoadStringW(hInstance, 1171 IDS_COLUMNEVENT, 1172 szTemp, 1173 sizeof(szTemp) / sizeof(WCHAR)); 1174 lvc.pszText = szTemp; 1175 (void)ListView_InsertColumn(hwndListView, 5, &lvc); 1176 1177 lvc.cx = 120; 1178 LoadStringW(hInstance, 1179 IDS_COLUMNUSER, 1180 szTemp, 1181 sizeof(szTemp) / sizeof(WCHAR)); 1182 lvc.pszText = szTemp; 1183 (void)ListView_InsertColumn(hwndListView, 6, &lvc); 1184 1185 lvc.cx = 100; 1186 LoadStringW(hInstance, 1187 IDS_COLUMNCOMPUTER, 1188 szTemp, 1189 sizeof(szTemp) / sizeof(WCHAR)); 1190 lvc.pszText = szTemp; 1191 (void)ListView_InsertColumn(hwndListView, 7, &lvc); 1192 1193 lvc.cx = 0; 1194 LoadStringW(hInstance, 1195 IDS_COLUMNEVENTDATA, 1196 szTemp, 1197 sizeof(szTemp) / sizeof(WCHAR)); 1198 lvc.pszText = szTemp; 1199 (void)ListView_InsertColumn(hwndListView, 8, &lvc); 1200 1201 // Initialize the save Dialog 1202 ZeroMemory(&sfn, sizeof(sfn)); 1203 ZeroMemory(szSaveFilter, sizeof(szSaveFilter)); 1204 1205 LoadStringW(hInst, IDS_SAVE_FILTER, szSaveFilter, MAX_LOADSTRING); 1206 1207 sfn.lStructSize = sizeof(sfn); 1208 sfn.hwndOwner = hwndMainWindow; 1209 sfn.hInstance = hInstance; 1210 sfn.lpstrFilter = szSaveFilter; 1211 sfn.lpstrInitialDir = NULL; 1212 sfn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE; 1213 sfn.lpstrDefExt = NULL; 1214 1215 ShowWindow(hwndMainWindow, nCmdShow); 1216 UpdateWindow(hwndMainWindow); 1217 1218 BuildLogList(); 1219 1220 QueryEventMessages(lpComputerName, LogNames[0]); 1221 1222 CheckMenuRadioItem(GetMenu(hwndMainWindow), ID_FIRST_LOG, ID_FIRST_LOG + dwNumLogs, ID_FIRST_LOG, MF_BYCOMMAND); 1223 1224 return TRUE; 1225 } 1226 1227 1228 LRESULT CALLBACK 1229 WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 1230 { 1231 RECT rect; 1232 NMHDR *hdr; 1233 1234 switch (message) 1235 { 1236 case WM_CREATE: 1237 hMainMenu = GetMenu(hWnd); 1238 break; 1239 1240 case WM_NOTIFY: 1241 switch (((LPNMHDR)lParam)->code) 1242 { 1243 case NM_DBLCLK : 1244 hdr = (NMHDR FAR*)lParam; 1245 if (hdr->hwndFrom == hwndListView) 1246 { 1247 LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam; 1248 1249 if (lpnmitem->iItem != -1) 1250 { 1251 DialogBox(hInst, 1252 MAKEINTRESOURCE(IDD_EVENTPROPERTIES), 1253 hWnd, 1254 EventDetails); 1255 } 1256 } 1257 break; 1258 } 1259 break; 1260 1261 case WM_COMMAND: 1262 // Parse the menu selections: 1263 1264 if ((LOWORD(wParam) >= ID_FIRST_LOG) && (LOWORD(wParam) <= ID_FIRST_LOG + dwNumLogs)) 1265 { 1266 if (LogNames[LOWORD(wParam) - ID_FIRST_LOG]) 1267 { 1268 if (QueryEventMessages(lpComputerName, LogNames[LOWORD(wParam) - ID_FIRST_LOG])) 1269 { 1270 CheckMenuRadioItem(GetMenu(hWnd), ID_FIRST_LOG, ID_FIRST_LOG + dwNumLogs, LOWORD(wParam), MF_BYCOMMAND); 1271 } 1272 } 1273 } 1274 else 1275 1276 switch (LOWORD(wParam)) 1277 { 1278 case IDM_SAVE_PROTOCOL: 1279 SaveProtocol(); 1280 break; 1281 1282 case IDM_CLEAR_EVENTS: 1283 if (ClearEvents()) 1284 { 1285 Refresh(); 1286 } 1287 break; 1288 1289 case IDM_REFRESH: 1290 Refresh(); 1291 break; 1292 1293 case IDM_ABOUT: 1294 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); 1295 break; 1296 1297 case IDM_HELP: 1298 MessageBoxW(hwndMainWindow, 1299 L"Help not implemented yet!", 1300 L"Event Log", 1301 MB_OK | MB_ICONINFORMATION); 1302 break; 1303 1304 case IDM_EXIT: 1305 DestroyWindow(hWnd); 1306 break; 1307 1308 default: 1309 return DefWindowProc(hWnd, message, wParam, lParam); 1310 } 1311 break; 1312 1313 case WM_SIZE: 1314 // Gets the window rectangle 1315 GetClientRect(hWnd, &rect); 1316 1317 // Relocate the listview 1318 MoveWindow(hwndListView, 1319 0, 1320 0, 1321 rect.right, 1322 rect.bottom - 20, 1323 1); 1324 1325 // Resize the statusbar; 1326 SendMessage(hwndStatus, message, wParam, lParam); 1327 break; 1328 1329 case WM_DESTROY: 1330 FreeRecords(); 1331 FreeLogList(); 1332 PostQuitMessage(0); 1333 break; 1334 1335 default: 1336 return DefWindowProc(hWnd, message, wParam, lParam); 1337 } 1338 1339 return 0; 1340 } 1341 1342 1343 // Message handler for about box. 1344 INT_PTR CALLBACK 1345 About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 1346 { 1347 UNREFERENCED_PARAMETER(lParam); 1348 switch (message) 1349 { 1350 case WM_INITDIALOG: 1351 { 1352 return (INT_PTR)TRUE; 1353 } 1354 1355 case WM_COMMAND: 1356 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 1357 { 1358 EndDialog(hDlg, LOWORD(wParam)); 1359 return (INT_PTR)TRUE; 1360 } 1361 break; 1362 } 1363 1364 return (INT_PTR)FALSE; 1365 } 1366 1367 VOID 1368 DisplayEvent(HWND hDlg) 1369 { 1370 WCHAR szEventType[MAX_PATH]; 1371 WCHAR szTime[MAX_PATH]; 1372 WCHAR szDate[MAX_PATH]; 1373 WCHAR szUser[MAX_PATH]; 1374 WCHAR szComputer[MAX_PATH]; 1375 WCHAR szSource[MAX_PATH]; 1376 WCHAR szCategory[MAX_PATH]; 1377 WCHAR szEventID[MAX_PATH]; 1378 WCHAR szEventText[EVENT_MESSAGE_EVENTTEXT_BUFFER]; 1379 WCHAR szEventData[MAX_PATH]; 1380 BOOL bEventData = FALSE; 1381 LVITEMW li; 1382 EVENTLOGRECORD* pevlr; 1383 int iIndex; 1384 1385 // Get index of selected item 1386 iIndex = (int)SendMessage (hwndListView, LVM_GETNEXTITEM, -1, LVNI_SELECTED | LVNI_FOCUSED); 1387 1388 li.mask = LVIF_PARAM; 1389 li.iItem = iIndex; 1390 li.iSubItem = 0; 1391 1392 (void)ListView_GetItem(hwndListView, &li); 1393 1394 pevlr = (EVENTLOGRECORD*)li.lParam; 1395 1396 if (iIndex != -1) 1397 { 1398 ListView_GetItemText(hwndListView, iIndex, 0, szEventType, sizeof(szEventType) / sizeof(WCHAR)); 1399 ListView_GetItemText(hwndListView, iIndex, 1, szDate, sizeof(szDate) / sizeof(WCHAR)); 1400 ListView_GetItemText(hwndListView, iIndex, 2, szTime, sizeof(szTime) / sizeof(WCHAR)); 1401 ListView_GetItemText(hwndListView, iIndex, 3, szSource, sizeof(szSource) / sizeof(WCHAR)); 1402 ListView_GetItemText(hwndListView, iIndex, 4, szCategory, sizeof(szCategory) / sizeof(WCHAR)); 1403 ListView_GetItemText(hwndListView, iIndex, 5, szEventID, sizeof(szEventID) / sizeof(WCHAR)); 1404 ListView_GetItemText(hwndListView, iIndex, 6, szUser, sizeof(szUser) / sizeof(WCHAR)); 1405 ListView_GetItemText(hwndListView, iIndex, 7, szComputer, sizeof(szComputer) / sizeof(WCHAR)); 1406 1407 bEventData = !(pevlr->DataLength == 0); 1408 1409 if (pevlr->DataLength > 0) 1410 { 1411 MultiByteToWideChar(CP_ACP, 1412 0, 1413 (LPCSTR)((LPBYTE)pevlr + pevlr->DataOffset), 1414 pevlr->DataLength, 1415 szEventData, 1416 MAX_PATH); 1417 } 1418 1419 GetEventMessage(lpSourceLogName, szSource, pevlr, szEventText); 1420 1421 EnableWindow(GetDlgItem(hDlg, IDC_BYTESRADIO), bEventData); 1422 EnableWindow(GetDlgItem(hDlg, IDC_WORDRADIO), bEventData); 1423 1424 SetDlgItemTextW(hDlg, IDC_EVENTDATESTATIC, szDate); 1425 SetDlgItemTextW(hDlg, IDC_EVENTTIMESTATIC, szTime); 1426 1427 SetDlgItemTextW(hDlg, IDC_EVENTUSERSTATIC, szUser); 1428 SetDlgItemTextW(hDlg, IDC_EVENTSOURCESTATIC, szSource); 1429 SetDlgItemTextW(hDlg, IDC_EVENTCOMPUTERSTATIC, szComputer); 1430 SetDlgItemTextW(hDlg, IDC_EVENTCATEGORYSTATIC, szCategory); 1431 SetDlgItemTextW(hDlg, IDC_EVENTIDSTATIC, szEventID); 1432 SetDlgItemTextW(hDlg, IDC_EVENTTYPESTATIC, szEventType); 1433 SetDlgItemTextW(hDlg, IDC_EVENTTEXTEDIT, szEventText); 1434 SetDlgItemTextW(hDlg, IDC_EVENTDATAEDIT, szEventData); 1435 } 1436 else 1437 { 1438 MessageBoxW(NULL, 1439 L"No Items in ListView", 1440 L"Error", 1441 MB_OK | MB_ICONINFORMATION); 1442 } 1443 } 1444 1445 VOID 1446 CopyEventEntry(HWND hWnd) 1447 { 1448 WCHAR output[4130], tmpHeader[512]; 1449 WCHAR szEventType[MAX_PATH]; 1450 WCHAR szSource[MAX_PATH]; 1451 WCHAR szCategory[MAX_PATH]; 1452 WCHAR szEventID[MAX_PATH]; 1453 WCHAR szDate[MAX_PATH]; 1454 WCHAR szTime[MAX_PATH]; 1455 WCHAR szUser[MAX_PATH]; 1456 WCHAR szComputer[MAX_PATH]; 1457 WCHAR evtDesc[ENTRY_SIZE]; 1458 HGLOBAL hMem; 1459 1460 if (!OpenClipboard(hWnd)) 1461 return; 1462 1463 /* First, empty the clipboard before we begin to use it */ 1464 EmptyClipboard(); 1465 1466 /* Get the formatted text needed to place the content into */ 1467 LoadStringW(hInst, IDS_COPY, tmpHeader, sizeof(tmpHeader) / sizeof(WCHAR)); 1468 1469 /* Grabs all the information and get it ready for the clipboard */ 1470 GetDlgItemText(hWnd, IDC_EVENTTYPESTATIC, szEventType, MAX_PATH); 1471 GetDlgItemText(hWnd, IDC_EVENTSOURCESTATIC, szSource, MAX_PATH); 1472 GetDlgItemText(hWnd, IDC_EVENTCATEGORYSTATIC, szCategory, MAX_PATH); 1473 GetDlgItemText(hWnd, IDC_EVENTIDSTATIC, szEventID, MAX_PATH); 1474 GetDlgItemText(hWnd, IDC_EVENTDATESTATIC, szDate, MAX_PATH); 1475 GetDlgItemText(hWnd, IDC_EVENTTIMESTATIC, szTime, MAX_PATH); 1476 GetDlgItemText(hWnd, IDC_EVENTUSERSTATIC, szUser, MAX_PATH); 1477 GetDlgItemText(hWnd, IDC_EVENTCOMPUTERSTATIC, szComputer, MAX_PATH); 1478 GetDlgItemText(hWnd, IDC_EVENTTEXTEDIT, evtDesc, ENTRY_SIZE); 1479 1480 /* Consolidate the information into on big piece */ 1481 wsprintfW(output, tmpHeader, szEventType, szSource, szCategory, szEventID, szDate, szTime, szUser, szComputer, evtDesc); 1482 1483 /* Sort out the memory needed to write to the clipboard */ 1484 hMem = GlobalAlloc(GMEM_MOVEABLE, ENTRY_SIZE); 1485 memcpy(GlobalLock(hMem), output, ENTRY_SIZE); 1486 GlobalUnlock(hMem); 1487 1488 /* Write the final content to the clipboard */ 1489 SetClipboardData(CF_UNICODETEXT, hMem); 1490 1491 /* Close the clipboard once we're done with it */ 1492 CloseClipboard(); 1493 } 1494 1495 static 1496 INT_PTR CALLBACK 1497 StatusMessageWindowProc(IN HWND hwndDlg, 1498 IN UINT uMsg, 1499 IN WPARAM wParam, 1500 IN LPARAM lParam) 1501 { 1502 UNREFERENCED_PARAMETER(wParam); 1503 1504 switch (uMsg) 1505 { 1506 case WM_INITDIALOG: 1507 { 1508 return TRUE; 1509 } 1510 } 1511 return FALSE; 1512 } 1513 1514 static 1515 VOID 1516 InitDetailsDlg(HWND hDlg) 1517 { 1518 HANDLE nextIcon = LoadImage(hInst, MAKEINTRESOURCE(IDI_NEXT), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); 1519 HANDLE prevIcon = LoadImage(hInst, MAKEINTRESOURCE(IDI_PREV), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); 1520 HANDLE copyIcon = LoadImage(hInst, MAKEINTRESOURCE(IDI_COPY), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); 1521 1522 SendMessage(GetDlgItem(hDlg, IDC_NEXT), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)nextIcon); 1523 SendMessage(GetDlgItem(hDlg, IDC_PREVIOUS), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)prevIcon); 1524 SendMessage(GetDlgItem(hDlg, IDC_COPY), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)copyIcon); 1525 } 1526 1527 // Message handler for event details box. 1528 INT_PTR CALLBACK 1529 EventDetails(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 1530 { 1531 UNREFERENCED_PARAMETER(lParam); 1532 1533 switch (message) 1534 { 1535 case WM_INITDIALOG: 1536 InitDetailsDlg(hDlg); 1537 1538 // Show event info on dialog box 1539 DisplayEvent(hDlg); 1540 return (INT_PTR)TRUE; 1541 1542 case WM_COMMAND: 1543 switch (LOWORD(wParam)) 1544 { 1545 case IDOK: 1546 case IDCANCEL: 1547 EndDialog(hDlg, LOWORD(wParam)); 1548 return (INT_PTR)TRUE; 1549 1550 case IDC_PREVIOUS: 1551 SendMessage(hwndListView, WM_KEYDOWN, VK_UP, 0); 1552 1553 // Show event info on dialog box 1554 DisplayEvent(hDlg); 1555 return (INT_PTR)TRUE; 1556 1557 case IDC_NEXT: 1558 SendMessage(hwndListView, WM_KEYDOWN, VK_DOWN, 0); 1559 1560 // Show event info on dialog box 1561 DisplayEvent(hDlg); 1562 return (INT_PTR)TRUE; 1563 1564 case IDC_COPY: 1565 CopyEventEntry(hDlg); 1566 return (INT_PTR)TRUE; 1567 1568 case IDC_BYTESRADIO: 1569 return (INT_PTR)TRUE; 1570 1571 case IDC_WORDRADIO: 1572 return (INT_PTR)TRUE; 1573 1574 case IDHELP: 1575 MessageBoxW(hDlg, 1576 L"Help not implemented yet!", 1577 L"Event Log", 1578 MB_OK | MB_ICONINFORMATION); 1579 return (INT_PTR)TRUE; 1580 1581 default: 1582 break; 1583 } 1584 break; 1585 } 1586 1587 return (INT_PTR)FALSE; 1588 } 1589