190 likes | 312 Views
Windows Events. Log. Sources. Source. CategoryCount. Message Files. Event. Type. Category. Strings. EventId. Raw Data. User. Success. (16-bit). (32-bit). i. Audit Failure. Severity:2. Customer :1. Reserved :1. Facility:12. Status:16. Audit Success. Error. Success.
E N D
Windows Events Log ... Sources Source ... CategoryCount Message Files Event ... Type Category Strings EventId Raw Data User Success (16-bit) (32-bit) i Audit Failure Severity:2 Customer :1 Reserved :1 Facility:12 Status:16 Audit Success Error Success HKEY_LOCAL_MACHINES SYSTEM CurrentControlSet Services Eventlog LogName SourceName ! Information Info i Warning Warning ! Error
From ID to Message CategoryMessageFile Category Error 3 EventID EventMessageFile AAA_LOGIN_OK Strings NTU-NURSE-12345 NTU_NURSE-12345 Login Success
CartUserEventLogger Log iNuC Source AAA, CUEL, DRM, iMAN, iNuCCore, LIM, RG, RK, UI, WTM Category Emergency, Critical, Error, Warning, Info, Debug static CreateEventLogger( String LogName, String SourceName, String categoryFile, String eventFile ) 1. Setup an Event Logger CartUserEventLogger( String SourceName ) 2. Open an Event Logger
Report an Event LogType Success ReportEvent ( Audit Failure Type EventLogTypeeventLogType, Audit Success Category LogLevellogLevel, Error EventId Uint32 eventId, Information Raw Data byte[] eventData, Warning Strings params String[] stringParams ) LogLevel Type ReportEvent ( Category LogLevellogLevel, EventId UInt32 eventId, Strings String logDesription )
Build Message Files Event ID MessageId=0x100 Severity=Success Facility=AAA SymbolicName=MSG_STRING_LOGIN_OK Language=English %1 Login Success . Status Severity Message Text File (.mc) Facility Message Compiler C include File (.h) Resource Script File (.rc) #define MSG_STRING_LOGIN_OK \ ((DWORD)0x00000100L) Binary resource for each language (.bin) Use ReportEvent( MSG_STRING_LOGIN_OK, "NTU_NURSE-12345" ); Source Files Resources Compiler Resource File (.res) Event Viewer Linker Portable Executable (.dll, .exe) (with embedded resource) 1 MESSAGETABLE { 256, "%1 Login Success" -1073741568, "%1 Login Fail" Use
Custom Build Rules 1. Tools 2. Options 3. Projects and Solutions 4. VC++ Project Settings 5. Rule File Search Paths
Enable MessageFile Build Rules 1. Project 2. Custom Build Rules 3. Available Rule Files 4. Check "Message File"
CUEL in Action (C#) Create event loggers string appDir = Path.GetDirectoryName(Application.ExecutablePath); string categoryFile = Path.Combine(appDir, "CUELCategory.dll"); string eventFile = Path.Combine(appDir, "CUELEvent.dll"); CartUserEventLogger.CreateEventLogger( "iNuC", Module.iNuCCore.ToString(), categoryFile, eventFile ); LogName SourceName CategoryFile EventFile Open an Event Logger • CartUserEventLogger logger = • new CartUserEventLogger( • Module.iNuCCore.ToString() • ); SourceName
CUEL in Action (C) Open an Event Logger HANDLE hLogger = INVALID_HANDLE_VALUE; hLogger = CUELRegisterEventSource(L"AAA"); Report an Event • if(hLogger!=INVALID_HANDLE_VALUE) { • LPWSTR strs[1]; • strs[0] = L"Complete Phase 1 Initialization"; • CUELReportEvent( • hLogger, • EVENTLOG_INFORMATION_TYPE, • CUEL_CATEGORY_INFO, • 0, • 0, • 1, • 0, • strs, • NULL); • }
References • Steve McConnell . Defensive Programming. Code Complete. Microsoft Press • Andrew Hunt. Pragmatic Paranoia. The Pragmatic Programmer. Addison-Wesley Professional • Robert C. Martin. Error Handling. Clean Code. Prentice Hall PTR • Raymond Chen. The Old New Thing • Cleaner, more elegant, and wronghttp://blogs.msdn.com/oldnewthing/archive/2004/04/22/118161.aspx • Cleaner, more elegant, and harder to recognizehttp://blogs.msdn.com/oldnewthing/archive/2005/01/14/352949.aspx • A rant against flow control macroshttp://blogs.msdn.com/oldnewthing/archive/2005/01/06/347666.aspx • Joel Spolsky. Joel On Software • Exceptionshttp://www.joelonsoftware.com/items/2003/10/13.html • Making Wrong Code Look Wronghttp://www.joelonsoftware.com/articles/Wrong.html • Joshua Bloch . How to Design a Good API and Why it Mattershttp://www.youtube.com/watch?v=aAb7hSCtvGw • Exceptions. Effective Java, Addison Wesley • Herb Sutter, and Andrei Alexandrescu. C++ Coding Standards. Addison Wesley • David Abrahams, Exception-Safety in Generic Componentshttp://www.boost.org/community/exception_safety.html
Use Assertion to Trap Bug in Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <windows.h> #include <assert.h> voidShowMessage(LPWSTR message) { assert(message!=NULL); MessageBoxW(0, message, L"ShowMessage", 0); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, intnCmdShow ) { LPWSTR msg = NULL; // ............... ShowMessage(msg); }
assert() #ifdef _DEBUG if(condition!=true) { ShowMessage("Assertion Failed!"); abort(); } #endif • When assertion failed • Abort - abort() is called to terminate the program execution • Retry - the debugger is called and the user can debug the program • Ignore - assert continues with its normal execution
Conditional Compilation C/C++ #ifdef_DEBUG // assertion code #endif C# #if DEBUG // assertion code #endif [Conditional("DEBUG")] voidAssertCode() { // Do Something } voidShowMessage() {AssertCode(); // do other thing}
When to Use Assertion • Use assertions • to validate and document pre-conditions, invariants, and post-conditions of a function • for conditions should never happen (use error handling code for conditions expected to happen) • for internal data (use correction code for external data) • to detect impossible condition
Prevent Use-After-Free struct NURSESTRUCTURE { PERSONALINFORMATION *PersonalInformation; HOSPITALINFORMATION *HospitalInformation; WORKASSIGNMENT *WorkAssignment; LIST_ENTRY PatientListHead; LIST_ENTRY *PersonalSchedule; LIST_ENTRY NurseInSameWard; LIST_ENTRY NurseInSameShift; }; memset( pNurse, 0, sizeof(*pNurse) ); free( pNurse );
Prevent Use-After-Dispose (C#) Dispose() is just a method, and should be called explicitly obj.Dispose(); obj = null; protected virtual void Dispose(Boolean disposing) { Debug.Assert(!isDisposed, "Already Disposed"); if (!isDisposed) { if (moduleAsyncAPIResult != IntPtr.Zero) { Marshal.FreeHGlobal(moduleAsyncAPIResult); moduleAsyncAPIResult = IntPtr.Zero; } } isDisposed = true; }