public static SafeEventLogHandle Construct() { SafeEventLogHandle h = RegisterEventSource(null, InfoCardTrace.InfoCardEventSource); if (null == h || h.IsInvalid) { int error = Marshal.GetLastWin32Error(); TraceDebug("failed to registereventsource with error {0}", error); } return(h); }
private static void LogEvent(EventCode code, string message, EventLogEntryType type) { using (SafeEventLogHandle handle = SafeEventLogHandle.Construct()) { string str = message; if (handle != null) { if (string.IsNullOrEmpty(str)) { str = Microsoft.InfoCards.SR.GetString("GeneralExceptionMessage"); } IntPtr[] ptrArray = new IntPtr[1]; GCHandle handle2 = new GCHandle(); GCHandle handle3 = new GCHandle(); try { handle3 = GCHandle.Alloc(ptrArray, GCHandleType.Pinned); handle2 = GCHandle.Alloc(str, GCHandleType.Pinned); ptrArray[0] = handle2.AddrOfPinnedObject(); HandleRef strings = new HandleRef(handle, handle3.AddrOfPinnedObject()); SecurityIdentifier user = WindowsIdentity.GetCurrent().User; byte[] binaryForm = new byte[user.BinaryLength]; user.GetBinaryForm(binaryForm, 0); if (!ReportEvent(handle, (short)type, 1, (uint)code, binaryForm, 1, 0, strings, null)) { Marshal.GetLastWin32Error(); } } finally { if (handle3.IsAllocated) { handle3.Free(); } if (handle2.IsAllocated) { handle2.Free(); } } } } }
// // Summary: // Logs the event for the appropriate infocard error code. This code should // match the entries in messages,mc // Parameters: // code - the event code to log // Notes: // This code may need to be extended to support an array of string parameters. We will do this if our event // log messages require it. // private static void LogEvent(EventCode code, string message, EventLogEntryType type) { using (SafeEventLogHandle handle = SafeEventLogHandle.Construct()) { string parameter = message; if (null != handle) { if (String.IsNullOrEmpty(parameter)) { parameter = SR.GetString(SR.GeneralExceptionMessage); } // // Report event expects a LPCTSTR* lpStrings. Use GCHandle, instead // of writing code with unsafe because InfoCard client uses this // and our client cannot contain any unsafe code. // // // This is the array of LPCTSTRs // IntPtr[] stringRoots = new IntPtr[1]; // // This is to pin the parameter string itself. Use an array here if you want more than 1 string // GCHandle stringParamHandle = new GCHandle(); // // This is to pin the pointer to the array of LPCTSTRs // GCHandle stringsRootHandle = new GCHandle(); try { // // Pin the IntPtrs (ie array of LPCTSTRs) // stringsRootHandle = GCHandle.Alloc(stringRoots, GCHandleType.Pinned); // // Pin the parameter string itself // stringParamHandle = GCHandle.Alloc(parameter, GCHandleType.Pinned); // // Give the intptr address of the pinned string // stringRoots[0] = stringParamHandle.AddrOfPinnedObject(); // // From msdn: The interop marshaler passes only the handle [2nd arg to constructor in our case] // to unmanaged code, and guarantees that the wrapper (passed as the first parameter // to the constructor of the HandleRef) remains alive for the duration of the [PInvoke] call. // HandleRef data = new HandleRef(handle, stringsRootHandle.AddrOfPinnedObject()); SecurityIdentifier sid = WindowsIdentity.GetCurrent().User; byte[] sidBA = new byte[sid.BinaryLength]; sid.GetBinaryForm(sidBA, 0); if (!ReportEvent( handle, (short)type, (ushort)InfoCardEventCategory.General, (uint)code, sidBA, 1, 0, data, null)) { // // Errors in the eventlog API should be ignored by applications // int error = Marshal.GetLastWin32Error(); TraceDebug("Failed to report the event with error {0}", error); } } finally { if (stringsRootHandle.IsAllocated) { stringsRootHandle.Free(); } if (stringParamHandle.IsAllocated) { stringParamHandle.Free(); } } } } }