1 // ==++== 2 // 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // 5 // ==--== 6 /*============================================================ 7 ** 8 ** Class: NativeWrapper 9 ** 10 ** Purpose: 11 ** This internal class contains wrapper methods over the Native 12 ** Methods of the Eventlog API. Unlike the raw Native Methods, 13 ** these methods throw EventLogExceptions, check platform 14 ** availablity and perform additional helper functionality 15 ** specific to function. Also, all methods of this class expose 16 ** the Link Demand for Unmanaged Permission to callers. 17 ** 18 ============================================================*/ 19 20 using System; 21 using System.Collections; 22 using System.Collections.Generic; 23 using System.Runtime.InteropServices; 24 using System.Text; 25 using System.Security.Principal; 26 using System.Security.Permissions; 27 using Microsoft.Win32.SafeHandles; 28 using Microsoft.Win32; 29 30 namespace System.Diagnostics.Eventing.Reader { 31 internal class NativeWrapper { 32 private static bool s_platformNotSupported = (Environment.OSVersion.Version.Major < 6); 33 34 [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] 35 public class SystemProperties { 36 //indicates if the SystemProperties values were already computed (for this event Instance, surely). 37 public bool filled = false; 38 39 public ushort? Id = null; 40 public byte? Version = null; 41 public ushort? Qualifiers = null; 42 public byte? Level = null; 43 public ushort? Task = null; 44 public byte? Opcode = null; 45 public ulong? Keywords = null; 46 public ulong? RecordId = null; 47 public string ProviderName = null; 48 public Guid? ProviderId = null; 49 public string ChannelName = null; 50 public uint? ProcessId = null; 51 public uint? ThreadId = null; 52 public string ComputerName = null; 53 public System.Security.Principal.SecurityIdentifier UserId = null; 54 public DateTime? TimeCreated = null; 55 public Guid? ActivityId = null; 56 public Guid? RelatedActivityId = null; 57 SystemProperties()58 public SystemProperties() { 59 } 60 } 61 62 [System.Security.SecurityCritical] EvtQuery( EventLogHandle session, string path, string query, int flags)63 public static EventLogHandle EvtQuery( 64 EventLogHandle session, 65 string path, 66 string query, 67 int flags) { 68 if (s_platformNotSupported) 69 throw new System.PlatformNotSupportedException(); 70 EventLogHandle handle = UnsafeNativeMethods.EvtQuery(session, path, query, flags); 71 int win32Error = Marshal.GetLastWin32Error(); 72 if (handle.IsInvalid) 73 EventLogException.Throw(win32Error); 74 return handle; 75 } 76 77 78 [System.Security.SecurityCritical] EvtSeek( EventLogHandle resultSet, long position, EventLogHandle bookmark, int timeout, UnsafeNativeMethods.EvtSeekFlags flags)79 public static void EvtSeek( 80 EventLogHandle resultSet, 81 long position, 82 EventLogHandle bookmark, 83 int timeout, 84 UnsafeNativeMethods.EvtSeekFlags flags) { 85 bool status = UnsafeNativeMethods.EvtSeek(resultSet, position, bookmark, timeout, flags); 86 int win32Error = Marshal.GetLastWin32Error(); 87 if (!status) 88 EventLogException.Throw(win32Error); 89 } 90 91 [System.Security.SecurityCritical] EvtSubscribe( EventLogHandle session, SafeWaitHandle signalEvent, string path, string query, EventLogHandle bookmark, IntPtr context, IntPtr callback, int flags)92 public static EventLogHandle EvtSubscribe( 93 EventLogHandle session, 94 SafeWaitHandle signalEvent, 95 string path, 96 string query, 97 EventLogHandle bookmark, 98 IntPtr context, 99 IntPtr callback, 100 int flags) { 101 if (s_platformNotSupported) 102 throw new System.PlatformNotSupportedException(); 103 104 EventLogHandle handle = UnsafeNativeMethods.EvtSubscribe( 105 session, 106 signalEvent, 107 path, 108 query, 109 bookmark, 110 context, 111 callback, 112 flags); 113 114 int win32Error = Marshal.GetLastWin32Error(); 115 if (handle.IsInvalid) 116 EventLogException.Throw(win32Error); 117 118 return handle; 119 } 120 121 [System.Security.SecurityCritical] EvtNext( EventLogHandle queryHandle, int eventSize, IntPtr[] events, int timeout, int flags, ref int returned)122 public static bool EvtNext( 123 EventLogHandle queryHandle, 124 int eventSize, 125 IntPtr[] events, 126 int timeout, 127 int flags, 128 ref int returned) { 129 bool status = UnsafeNativeMethods.EvtNext(queryHandle, eventSize, events, timeout, flags, ref returned); 130 int win32Error = Marshal.GetLastWin32Error(); 131 if (!status && win32Error != UnsafeNativeMethods.ERROR_NO_MORE_ITEMS) 132 EventLogException.Throw(win32Error); 133 return win32Error == 0; 134 } 135 136 [System.Security.SecuritySafeCritical] EvtCancel(EventLogHandle handle)137 public static void EvtCancel(EventLogHandle handle) { 138 139 EventLogPermissionHolder.GetEventLogPermission().Demand(); 140 141 if (!UnsafeNativeMethods.EvtCancel(handle)) { 142 int win32Error = Marshal.GetLastWin32Error(); 143 EventLogException.Throw(win32Error); 144 } 145 } 146 147 148 [System.Security.SecurityCritical] EvtClose(IntPtr handle)149 public static void EvtClose(IntPtr handle) { 150 // 151 // purposely don't check and throw - this is 152 // always called in cleanup / finalize / etc.. 153 // 154 UnsafeNativeMethods.EvtClose(handle); 155 } 156 157 [System.Security.SecurityCritical] EvtOpenProviderMetadata( EventLogHandle session, string ProviderId, string logFilePath, int locale, int flags)158 public static EventLogHandle EvtOpenProviderMetadata( 159 EventLogHandle session, 160 string ProviderId, 161 string logFilePath, 162 int locale, 163 int flags) { 164 165 if (s_platformNotSupported) 166 throw new System.PlatformNotSupportedException(); 167 168 // 169 // ignore locale and pass 0 instead: that way, the thread locale will be retrieved in the API layer 170 // and the "strict rendering" flag will NOT be set. Otherwise, the fall back logic is broken and the descriptions 171 // are not returned if the exact locale is not present on the server. 172 // 173 EventLogHandle handle = UnsafeNativeMethods.EvtOpenPublisherMetadata(session, ProviderId, logFilePath, 0, flags); 174 175 int win32Error = Marshal.GetLastWin32Error(); 176 if (handle.IsInvalid) 177 EventLogException.Throw(win32Error); 178 return handle; 179 } 180 181 [System.Security.SecurityCritical] EvtGetObjectArraySize(EventLogHandle objectArray)182 public static int EvtGetObjectArraySize(EventLogHandle objectArray) { 183 int arraySize; 184 bool status = UnsafeNativeMethods.EvtGetObjectArraySize(objectArray, out arraySize); 185 int win32Error = Marshal.GetLastWin32Error(); 186 if (!status) 187 EventLogException.Throw(win32Error); 188 return arraySize; 189 } 190 191 [System.Security.SecurityCritical] EvtOpenEventMetadataEnum(EventLogHandle ProviderMetadata, int flags)192 public static EventLogHandle EvtOpenEventMetadataEnum(EventLogHandle ProviderMetadata, int flags) { 193 EventLogHandle emEnumHandle = UnsafeNativeMethods.EvtOpenEventMetadataEnum(ProviderMetadata, flags); 194 int win32Error = Marshal.GetLastWin32Error(); 195 if (emEnumHandle.IsInvalid) 196 EventLogException.Throw(win32Error); 197 return emEnumHandle; 198 } 199 200 // returns null if EOF 201 [System.Security.SecurityCritical] EvtNextEventMetadata(EventLogHandle eventMetadataEnum, int flags)202 public static EventLogHandle EvtNextEventMetadata(EventLogHandle eventMetadataEnum, int flags) { 203 EventLogHandle emHandle = UnsafeNativeMethods.EvtNextEventMetadata(eventMetadataEnum, flags); 204 int win32Error = Marshal.GetLastWin32Error(); 205 206 if (emHandle.IsInvalid) { 207 if (win32Error != UnsafeNativeMethods.ERROR_NO_MORE_ITEMS) 208 EventLogException.Throw(win32Error); 209 return null; 210 } 211 212 return emHandle; 213 } 214 215 [System.Security.SecurityCritical] EvtOpenChannelEnum(EventLogHandle session, int flags)216 public static EventLogHandle EvtOpenChannelEnum(EventLogHandle session, int flags) { 217 if (s_platformNotSupported) 218 throw new System.PlatformNotSupportedException(); 219 220 EventLogHandle channelEnum = UnsafeNativeMethods.EvtOpenChannelEnum(session, flags); 221 int win32Error = Marshal.GetLastWin32Error(); 222 if (channelEnum.IsInvalid) 223 EventLogException.Throw(win32Error); 224 return channelEnum; 225 } 226 227 [System.Security.SecurityCritical] EvtOpenProviderEnum(EventLogHandle session, int flags)228 public static EventLogHandle EvtOpenProviderEnum(EventLogHandle session, int flags) { 229 if (s_platformNotSupported) 230 throw new System.PlatformNotSupportedException(); 231 232 EventLogHandle pubEnum = UnsafeNativeMethods.EvtOpenPublisherEnum(session, flags); 233 int win32Error = Marshal.GetLastWin32Error(); 234 if (pubEnum.IsInvalid) 235 EventLogException.Throw(win32Error); 236 return pubEnum; 237 } 238 239 [System.Security.SecurityCritical] EvtOpenChannelConfig(EventLogHandle session, String channelPath, int flags)240 public static EventLogHandle EvtOpenChannelConfig(EventLogHandle session, String channelPath, int flags) { 241 if (s_platformNotSupported) 242 throw new System.PlatformNotSupportedException(); 243 244 EventLogHandle handle = UnsafeNativeMethods.EvtOpenChannelConfig(session, channelPath, flags); 245 int win32Error = Marshal.GetLastWin32Error(); 246 if (handle.IsInvalid) 247 EventLogException.Throw(win32Error); 248 return handle; 249 } 250 251 [System.Security.SecuritySafeCritical] EvtSaveChannelConfig(EventLogHandle channelConfig, int flags)252 public static void EvtSaveChannelConfig(EventLogHandle channelConfig, int flags) { 253 EventLogPermissionHolder.GetEventLogPermission().Demand(); 254 bool status = UnsafeNativeMethods.EvtSaveChannelConfig(channelConfig, flags); 255 int win32Error = Marshal.GetLastWin32Error(); 256 if (!status) 257 EventLogException.Throw(win32Error); 258 } 259 260 261 [System.Security.SecurityCritical] EvtOpenLog(EventLogHandle session, string path, PathType flags)262 public static EventLogHandle EvtOpenLog(EventLogHandle session, string path, PathType flags) { 263 if (s_platformNotSupported) 264 throw new System.PlatformNotSupportedException(); 265 266 EventLogHandle logHandle = UnsafeNativeMethods.EvtOpenLog(session, path, flags); 267 int win32Error = Marshal.GetLastWin32Error(); 268 if (logHandle.IsInvalid) 269 EventLogException.Throw(win32Error); 270 return logHandle; 271 } 272 273 [System.Security.SecuritySafeCritical] EvtExportLog( EventLogHandle session, string channelPath, string query, string targetFilePath, int flags)274 public static void EvtExportLog( 275 EventLogHandle session, 276 string channelPath, 277 string query, 278 string targetFilePath, 279 int flags) { 280 281 if (s_platformNotSupported) 282 throw new System.PlatformNotSupportedException(); 283 284 EventLogPermissionHolder.GetEventLogPermission().Demand(); 285 286 bool status; 287 status = UnsafeNativeMethods.EvtExportLog(session, channelPath, query, targetFilePath, flags); 288 int win32Error = Marshal.GetLastWin32Error(); 289 if (!status) 290 EventLogException.Throw(win32Error); 291 } 292 293 [System.Security.SecuritySafeCritical] EvtArchiveExportedLog( EventLogHandle session, string logFilePath, int locale, int flags)294 public static void EvtArchiveExportedLog( 295 EventLogHandle session, 296 string logFilePath, 297 int locale, 298 int flags) { 299 300 if (s_platformNotSupported) 301 throw new System.PlatformNotSupportedException(); 302 303 EventLogPermissionHolder.GetEventLogPermission().Demand(); 304 305 bool status; 306 status = UnsafeNativeMethods.EvtArchiveExportedLog(session, logFilePath, locale, flags); 307 int win32Error = Marshal.GetLastWin32Error(); 308 if (!status) 309 EventLogException.Throw(win32Error); 310 } 311 312 [System.Security.SecuritySafeCritical] EvtClearLog( EventLogHandle session, string channelPath, string targetFilePath, int flags)313 public static void EvtClearLog( 314 EventLogHandle session, 315 string channelPath, 316 string targetFilePath, 317 int flags) { 318 319 if (s_platformNotSupported) 320 throw new System.PlatformNotSupportedException(); 321 322 EventLogPermissionHolder.GetEventLogPermission().Demand(); 323 324 bool status; 325 status = UnsafeNativeMethods.EvtClearLog(session, channelPath, targetFilePath, flags); 326 int win32Error = Marshal.GetLastWin32Error(); 327 if (!status) 328 EventLogException.Throw(win32Error); 329 } 330 331 [System.Security.SecurityCritical] EvtCreateRenderContext( Int32 valuePathsCount, String[] valuePaths, UnsafeNativeMethods.EvtRenderContextFlags flags)332 public static EventLogHandle EvtCreateRenderContext( 333 Int32 valuePathsCount, 334 String[] valuePaths, 335 UnsafeNativeMethods.EvtRenderContextFlags flags) { 336 if (s_platformNotSupported) 337 throw new System.PlatformNotSupportedException(); 338 339 EventLogHandle renderContextHandleValues = UnsafeNativeMethods.EvtCreateRenderContext(valuePathsCount, valuePaths, flags); 340 int win32Error = Marshal.GetLastWin32Error(); 341 if (renderContextHandleValues.IsInvalid) 342 EventLogException.Throw(win32Error); 343 return renderContextHandleValues; 344 } 345 346 [System.Security.SecurityCritical] EvtRender( EventLogHandle context, EventLogHandle eventHandle, UnsafeNativeMethods.EvtRenderFlags flags, StringBuilder buffer)347 public static void EvtRender( 348 EventLogHandle context, 349 EventLogHandle eventHandle, 350 UnsafeNativeMethods.EvtRenderFlags flags, 351 StringBuilder buffer) { 352 if (s_platformNotSupported) 353 throw new System.PlatformNotSupportedException(); 354 355 int buffUsed; 356 int propCount; 357 bool status = UnsafeNativeMethods.EvtRender(context, eventHandle, flags, buffer.Capacity, buffer, out buffUsed, out propCount); 358 int win32Error = Marshal.GetLastWin32Error(); 359 360 if (!status) { 361 if (win32Error == UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) { 362 //reallocate the new RenderBuffer with the right size. 363 buffer.Capacity = buffUsed; 364 status = UnsafeNativeMethods.EvtRender(context, eventHandle, flags, buffer.Capacity, buffer, out buffUsed, out propCount); 365 win32Error = Marshal.GetLastWin32Error(); 366 } 367 if (!status) { 368 EventLogException.Throw(win32Error); 369 } 370 } 371 } 372 373 [System.Security.SecurityCritical] EvtOpenSession(UnsafeNativeMethods.EvtLoginClass loginClass, ref UnsafeNativeMethods.EvtRpcLogin login, int timeout, int flags)374 public static EventLogHandle EvtOpenSession(UnsafeNativeMethods.EvtLoginClass loginClass, ref UnsafeNativeMethods.EvtRpcLogin login, int timeout, int flags) { 375 if (s_platformNotSupported) 376 throw new System.PlatformNotSupportedException(); 377 378 EventLogHandle handle = UnsafeNativeMethods.EvtOpenSession(loginClass, ref login, timeout, flags); 379 int win32Error = Marshal.GetLastWin32Error(); 380 if (handle.IsInvalid) 381 EventLogException.Throw(win32Error); 382 return handle; 383 } 384 385 [System.Security.SecurityCritical] EvtCreateBookmark(string bookmarkXml)386 public static EventLogHandle EvtCreateBookmark(string bookmarkXml) { 387 if (s_platformNotSupported) 388 throw new System.PlatformNotSupportedException(); 389 390 EventLogHandle handle = UnsafeNativeMethods.EvtCreateBookmark(bookmarkXml); 391 int win32Error = Marshal.GetLastWin32Error(); 392 if (handle.IsInvalid) 393 EventLogException.Throw(win32Error); 394 return handle; 395 } 396 397 [System.Security.SecurityCritical] EvtUpdateBookmark(EventLogHandle bookmark, EventLogHandle eventHandle)398 public static void EvtUpdateBookmark(EventLogHandle bookmark, EventLogHandle eventHandle) { 399 bool status = UnsafeNativeMethods.EvtUpdateBookmark(bookmark, eventHandle); 400 int win32Error = Marshal.GetLastWin32Error(); 401 if (!status) 402 EventLogException.Throw(win32Error); 403 } 404 405 [System.Security.SecuritySafeCritical] EvtGetEventInfo(EventLogHandle handle, UnsafeNativeMethods.EvtEventPropertyId enumType)406 public static object EvtGetEventInfo(EventLogHandle handle, UnsafeNativeMethods.EvtEventPropertyId enumType) { 407 IntPtr buffer = IntPtr.Zero; 408 int bufferNeeded; 409 410 EventLogPermissionHolder.GetEventLogPermission().Demand(); 411 412 try { 413 bool status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, 0, IntPtr.Zero, out bufferNeeded); 414 int error = Marshal.GetLastWin32Error(); 415 if (!status) { 416 if (error == UnsafeNativeMethods.ERROR_SUCCESS) { } 417 else 418 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 419 EventLogException.Throw(error); 420 } 421 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 422 status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, bufferNeeded, buffer, out bufferNeeded); 423 error = Marshal.GetLastWin32Error(); 424 if (!status) 425 EventLogException.Throw(error); 426 427 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.EvtVariant)); 428 return ConvertToObject(varVal); 429 430 } 431 finally { 432 if (buffer != IntPtr.Zero) 433 Marshal.FreeHGlobal(buffer); 434 } 435 } 436 437 [System.Security.SecurityCritical] EvtGetQueryInfo(EventLogHandle handle, UnsafeNativeMethods.EvtQueryPropertyId enumType)438 public static object EvtGetQueryInfo(EventLogHandle handle, UnsafeNativeMethods.EvtQueryPropertyId enumType) { 439 IntPtr buffer = IntPtr.Zero; 440 int bufferNeeded = 0; 441 try { 442 bool status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, 0, IntPtr.Zero, ref bufferNeeded); 443 int error = Marshal.GetLastWin32Error(); 444 if (!status) { 445 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 446 EventLogException.Throw(error); 447 } 448 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 449 status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, bufferNeeded, buffer, ref bufferNeeded); 450 error = Marshal.GetLastWin32Error(); 451 if (!status) 452 EventLogException.Throw(error); 453 454 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.EvtVariant)); 455 return ConvertToObject(varVal); 456 } 457 finally { 458 if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); 459 } 460 } 461 462 [System.Security.SecuritySafeCritical] EvtGetPublisherMetadataProperty(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId)463 public static object EvtGetPublisherMetadataProperty(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId) { 464 IntPtr buffer = IntPtr.Zero; 465 int bufferNeeded; 466 467 EventLogPermissionHolder.GetEventLogPermission().Demand(); 468 469 try { 470 bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, IntPtr.Zero, out bufferNeeded); 471 int error = Marshal.GetLastWin32Error(); 472 if (!status) { 473 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 474 EventLogException.Throw(error); 475 } 476 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 477 status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, buffer, out bufferNeeded); 478 error = Marshal.GetLastWin32Error(); 479 if (!status) 480 EventLogException.Throw(error); 481 482 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.EvtVariant)); 483 return ConvertToObject(varVal); 484 } 485 finally { 486 if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); 487 } 488 } 489 490 491 [System.Security.SecurityCritical] EvtGetPublisherMetadataPropertyHandle(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId)492 internal static EventLogHandle EvtGetPublisherMetadataPropertyHandle(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId) { 493 IntPtr buffer = IntPtr.Zero; 494 try { 495 int bufferNeeded; 496 bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, IntPtr.Zero, out bufferNeeded); 497 int error = Marshal.GetLastWin32Error(); 498 if (!status) { 499 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 500 EventLogException.Throw(error); 501 } 502 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 503 status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, buffer, out bufferNeeded); 504 error = Marshal.GetLastWin32Error(); 505 if (!status) 506 EventLogException.Throw(error); 507 508 // 509 // note: there is a case where returned variant does have allocated native resources 510 // associated with (e.g. ConfigArrayHandle). If PtrToStructure throws, then we would 511 // leak that resource - fortunately PtrToStructure only throws InvalidArgument which 512 // is a logic error - not a possible runtime condition here. Other System exceptions 513 // shouldn't be handled anyhow and the application will terminate. 514 // 515 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.EvtVariant)); 516 return ConvertToSafeHandle(varVal); 517 } 518 finally { 519 if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); 520 } 521 } 522 523 524 // implies UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId flag. 525 [System.Security.SecurityCritical] EvtFormatMessage(EventLogHandle handle, uint msgId)526 public static string EvtFormatMessage(EventLogHandle handle, uint msgId) { 527 if (s_platformNotSupported) 528 throw new System.PlatformNotSupportedException(); 529 530 int bufferNeeded; 531 532 StringBuilder sb = new StringBuilder(null); 533 bool status = UnsafeNativeMethods.EvtFormatMessage(handle, EventLogHandle.Zero, msgId, 0, null, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId, 0, sb, out bufferNeeded); 534 int error = Marshal.GetLastWin32Error(); 535 536 // ERROR_EVT_UNRESOLVED_VALUE_INSERT and its cousins are commonly returned for raw message text. 537 if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT 538 && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT 539 && error != UnsafeNativeMethods.ERROR_EVT_MAX_INSERTS_REACHED ) { 540 switch (error) { 541 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND: 542 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND: 543 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: 544 case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND: 545 case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND: 546 return null; 547 } 548 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 549 EventLogException.Throw(error); 550 } 551 552 sb.EnsureCapacity(bufferNeeded); 553 status = UnsafeNativeMethods.EvtFormatMessage(handle, EventLogHandle.Zero, msgId, 0, null, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId, bufferNeeded, sb, out bufferNeeded); 554 error = Marshal.GetLastWin32Error(); 555 556 if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT 557 && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT 558 && error != UnsafeNativeMethods.ERROR_EVT_MAX_INSERTS_REACHED ) { 559 switch (error) { 560 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND: 561 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND: 562 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: 563 case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND: 564 case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND: 565 return null; 566 } 567 if (error == UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT) { 568 return null; 569 } 570 EventLogException.Throw(error); 571 } 572 return sb.ToString(); 573 } 574 575 [System.Security.SecurityCritical] EvtGetObjectArrayProperty(EventLogHandle objArrayHandle, int index, int thePropertyId)576 public static object EvtGetObjectArrayProperty(EventLogHandle objArrayHandle, int index, int thePropertyId) { 577 IntPtr buffer = IntPtr.Zero; 578 int bufferNeeded; 579 580 try { 581 bool status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, 0, IntPtr.Zero, out bufferNeeded); 582 int error = Marshal.GetLastWin32Error(); 583 584 if (!status) { 585 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 586 EventLogException.Throw(error); 587 } 588 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 589 status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, bufferNeeded, buffer, out bufferNeeded); 590 error = Marshal.GetLastWin32Error(); 591 if (!status) 592 EventLogException.Throw(error); 593 594 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.EvtVariant)); 595 return ConvertToObject(varVal); 596 } 597 finally { 598 if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer); 599 } 600 } 601 602 [System.Security.SecurityCritical] EvtGetEventMetadataProperty(EventLogHandle handle, UnsafeNativeMethods.EvtEventMetadataPropertyId enumType)603 public static object EvtGetEventMetadataProperty(EventLogHandle handle, UnsafeNativeMethods.EvtEventMetadataPropertyId enumType) { 604 IntPtr buffer = IntPtr.Zero; 605 int bufferNeeded; 606 607 try { 608 bool status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, 0, IntPtr.Zero, out bufferNeeded); 609 int win32Error = Marshal.GetLastWin32Error(); 610 if (!status) { 611 if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 612 EventLogException.Throw(win32Error); 613 } 614 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 615 status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, bufferNeeded, buffer, out bufferNeeded); 616 win32Error = Marshal.GetLastWin32Error(); 617 if (!status) 618 EventLogException.Throw(win32Error); 619 620 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.EvtVariant)); 621 return ConvertToObject(varVal); 622 } 623 finally { 624 if (buffer != IntPtr.Zero) 625 Marshal.FreeHGlobal(buffer); 626 } 627 } 628 629 [System.Security.SecuritySafeCritical] EvtGetChannelConfigProperty(EventLogHandle handle, UnsafeNativeMethods.EvtChannelConfigPropertyId enumType)630 public static object EvtGetChannelConfigProperty(EventLogHandle handle, UnsafeNativeMethods.EvtChannelConfigPropertyId enumType) { 631 IntPtr buffer = IntPtr.Zero; 632 int bufferNeeded; 633 634 EventLogPermissionHolder.GetEventLogPermission().Demand(); 635 636 try { 637 638 bool status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, 0, IntPtr.Zero, out bufferNeeded); 639 int win32Error = Marshal.GetLastWin32Error(); 640 if (!status) { 641 if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 642 EventLogException.Throw(win32Error); 643 } 644 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 645 status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, bufferNeeded, buffer, out bufferNeeded); 646 win32Error = Marshal.GetLastWin32Error(); 647 if (!status) 648 EventLogException.Throw(win32Error); 649 650 // 651 // note: there is a case where returned variant does have allocated native resources 652 // associated with (e.g. ConfigArrayHandle). If PtrToStructure throws, then we would 653 // leak that resource - fortunately PtrToStructure only throws InvalidArgument which 654 // is a logic error - not a possible runtime condition here. Other System exceptions 655 // shouldn't be handled anyhow and the application will terminate. 656 // 657 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.EvtVariant)); 658 return ConvertToObject(varVal); 659 } 660 finally { 661 if (buffer != IntPtr.Zero) 662 Marshal.FreeHGlobal(buffer); 663 } 664 } 665 666 [System.Security.SecuritySafeCritical] EvtSetChannelConfigProperty(EventLogHandle handle, UnsafeNativeMethods.EvtChannelConfigPropertyId enumType, object val)667 public static void EvtSetChannelConfigProperty(EventLogHandle handle, UnsafeNativeMethods.EvtChannelConfigPropertyId enumType, object val) { 668 669 EventLogPermissionHolder.GetEventLogPermission().Demand(); 670 671 UnsafeNativeMethods.EvtVariant varVal = new UnsafeNativeMethods.EvtVariant(); 672 673 CoTaskMemSafeHandle taskMem = new CoTaskMemSafeHandle(); 674 675 using (taskMem) { 676 677 if (val != null) { 678 679 switch (enumType) { 680 case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigEnabled: { 681 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBoolean; 682 if ((bool)val == true) varVal.Bool = 1; 683 else varVal.Bool = 0; 684 } 685 break; 686 case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigAccess: { 687 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeString; 688 taskMem.SetMemory(Marshal.StringToCoTaskMemAuto((string)val)); 689 varVal.StringVal = taskMem.GetMemory(); 690 } 691 break; 692 case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigLogFilePath: { 693 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeString; 694 taskMem.SetMemory(Marshal.StringToCoTaskMemAuto((string)val)); 695 varVal.StringVal = taskMem.GetMemory(); 696 } 697 break; 698 case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigMaxSize: { 699 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64; 700 varVal.ULong = (ulong)((long)val); 701 } 702 break; 703 case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigLevel: { 704 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32; 705 varVal.UInteger = (uint)((int)val); 706 } 707 break; 708 case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigKeywords: { 709 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64; 710 varVal.ULong = (ulong)((long)val); 711 } 712 break; 713 case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigRetention: { 714 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBoolean; 715 if ((bool)val == true) varVal.Bool = 1; 716 else varVal.Bool = 0; 717 } 718 break; 719 case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigAutoBackup: { 720 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBoolean; 721 if ((bool)val == true) varVal.Bool = 1; 722 else varVal.Bool = 0; 723 } 724 break; 725 default: 726 throw new InvalidOperationException(); 727 } 728 } 729 else { 730 varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeNull; 731 } 732 bool status = UnsafeNativeMethods.EvtSetChannelConfigProperty(handle, enumType, 0, ref varVal); 733 int win32Error = Marshal.GetLastWin32Error(); 734 if (!status) 735 EventLogException.Throw(win32Error); 736 } 737 } 738 739 [System.Security.SecurityCritical] EvtNextChannelPath(EventLogHandle handle, ref bool finish)740 public static string EvtNextChannelPath(EventLogHandle handle, ref bool finish) { 741 StringBuilder sb = new StringBuilder(null); 742 int channelNameNeeded; 743 744 bool status = UnsafeNativeMethods.EvtNextChannelPath(handle, 0, sb, out channelNameNeeded); 745 int win32Error = Marshal.GetLastWin32Error(); 746 if (!status) { 747 if (win32Error == UnsafeNativeMethods.ERROR_NO_MORE_ITEMS) { 748 finish = true; 749 return null; 750 } 751 752 if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 753 EventLogException.Throw(win32Error); 754 } 755 756 sb.EnsureCapacity(channelNameNeeded); 757 status = UnsafeNativeMethods.EvtNextChannelPath(handle, channelNameNeeded, sb, out channelNameNeeded); 758 win32Error = Marshal.GetLastWin32Error(); 759 if (!status) 760 EventLogException.Throw(win32Error); 761 762 return sb.ToString(); 763 } 764 765 [System.Security.SecurityCritical] EvtNextPublisherId(EventLogHandle handle, ref bool finish)766 public static string EvtNextPublisherId(EventLogHandle handle, ref bool finish) { 767 StringBuilder sb = new StringBuilder(null); 768 int ProviderIdNeeded; 769 770 bool status = UnsafeNativeMethods.EvtNextPublisherId(handle, 0, sb, out ProviderIdNeeded); 771 int win32Error = Marshal.GetLastWin32Error(); 772 if (!status) { 773 if (win32Error == UnsafeNativeMethods.ERROR_NO_MORE_ITEMS) { 774 finish = true; 775 return null; 776 } 777 778 if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 779 EventLogException.Throw(win32Error); 780 } 781 782 sb.EnsureCapacity(ProviderIdNeeded); 783 status = UnsafeNativeMethods.EvtNextPublisherId(handle, ProviderIdNeeded, sb, out ProviderIdNeeded); 784 win32Error = Marshal.GetLastWin32Error(); 785 if (!status) 786 EventLogException.Throw(win32Error); 787 788 return sb.ToString(); 789 } 790 791 [System.Security.SecurityCritical] EvtGetLogInfo(EventLogHandle handle, UnsafeNativeMethods.EvtLogPropertyId enumType)792 public static object EvtGetLogInfo(EventLogHandle handle, UnsafeNativeMethods.EvtLogPropertyId enumType) { 793 IntPtr buffer = IntPtr.Zero; 794 int bufferNeeded; 795 796 try { 797 bool status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, 0, IntPtr.Zero, out bufferNeeded); 798 int win32Error = Marshal.GetLastWin32Error(); 799 if (!status) { 800 if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 801 EventLogException.Throw(win32Error); 802 } 803 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 804 status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, bufferNeeded, buffer, out bufferNeeded); 805 win32Error = Marshal.GetLastWin32Error(); 806 if (!status) 807 EventLogException.Throw(win32Error); 808 809 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(buffer, typeof(UnsafeNativeMethods.EvtVariant)); 810 return ConvertToObject(varVal); 811 } 812 finally { 813 if (buffer != IntPtr.Zero) 814 Marshal.FreeHGlobal(buffer); 815 } 816 } 817 818 [System.Security.SecuritySafeCritical] EvtRenderBufferWithContextSystem(EventLogHandle contextHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtRenderFlags flag, SystemProperties systemProperties, int SYSTEM_PROPERTY_COUNT)819 public static void EvtRenderBufferWithContextSystem(EventLogHandle contextHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtRenderFlags flag, SystemProperties systemProperties, int SYSTEM_PROPERTY_COUNT) { 820 IntPtr buffer = IntPtr.Zero; 821 IntPtr pointer = IntPtr.Zero; 822 int bufferNeeded; 823 int propCount; 824 825 EventLogPermissionHolder.GetEventLogPermission().Demand(); 826 827 try { 828 bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); 829 if (!status) { 830 int error = Marshal.GetLastWin32Error(); 831 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 832 EventLogException.Throw(error); 833 } 834 835 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 836 status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); 837 int win32Error = Marshal.GetLastWin32Error(); 838 if (!status) 839 EventLogException.Throw(win32Error); 840 841 if (propCount != SYSTEM_PROPERTY_COUNT) 842 throw new InvalidOperationException("We do not have " + SYSTEM_PROPERTY_COUNT + " variants given for the UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues flag. (System Properties)"); 843 844 pointer = buffer; 845 //read each Variant structure 846 for (int i = 0; i < propCount; i++) { 847 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(pointer, typeof(UnsafeNativeMethods.EvtVariant)); 848 switch (i) { 849 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderName: 850 systemProperties.ProviderName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); 851 break; 852 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderGuid: 853 systemProperties.ProviderId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); 854 break; 855 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventID: 856 systemProperties.Id = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); 857 break; 858 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemQualifiers: 859 systemProperties.Qualifiers = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); 860 break; 861 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemLevel: 862 systemProperties.Level = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); 863 break; 864 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemTask: 865 systemProperties.Task = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16); 866 break; 867 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemOpcode: 868 systemProperties.Opcode = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); 869 break; 870 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemKeywords: 871 systemProperties.Keywords = (ulong?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeHexInt64); 872 break; 873 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemTimeCreated: 874 systemProperties.TimeCreated = (DateTime?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeFileTime); 875 break; 876 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventRecordId: 877 systemProperties.RecordId = (ulong?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64); 878 break; 879 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemActivityID: 880 systemProperties.ActivityId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); 881 break; 882 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemRelatedActivityID: 883 systemProperties.RelatedActivityId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid); 884 break; 885 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProcessID: 886 systemProperties.ProcessId = (uint?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32); 887 break; 888 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemThreadID: 889 systemProperties.ThreadId = (uint?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32); 890 break; 891 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemChannel: 892 systemProperties.ChannelName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); 893 break; 894 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemComputer: 895 systemProperties.ComputerName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString); 896 break; 897 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemUserID: 898 systemProperties.UserId = (SecurityIdentifier)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeSid); 899 break; 900 case (int) UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemVersion: 901 systemProperties.Version = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte); 902 break; 903 } 904 pointer = new IntPtr(((Int64)pointer + Marshal.SizeOf(varVal))); 905 } 906 } 907 finally { 908 if (buffer != IntPtr.Zero) 909 Marshal.FreeHGlobal(buffer); 910 } 911 } 912 913 //EvtRenderContextFlags can be both: EvtRenderContextFlags.EvtRenderContextUser and EvtRenderContextFlags.EvtRenderContextValues 914 //Render with Context = ContextUser or ContextValues (with user defined Xpath query strings) 915 [System.Security.SecuritySafeCritical] EvtRenderBufferWithContextUserOrValues(EventLogHandle contextHandle, EventLogHandle eventHandle)916 public static IList<object> EvtRenderBufferWithContextUserOrValues(EventLogHandle contextHandle, EventLogHandle eventHandle) { 917 IntPtr buffer = IntPtr.Zero; 918 IntPtr pointer = IntPtr.Zero; 919 int bufferNeeded; 920 int propCount; 921 UnsafeNativeMethods.EvtRenderFlags flag = UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues; 922 923 EventLogPermissionHolder.GetEventLogPermission().Demand(); 924 925 try { 926 bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); 927 if (!status) { 928 int error = Marshal.GetLastWin32Error(); 929 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 930 EventLogException.Throw(error); 931 } 932 933 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 934 status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); 935 int win32Error = Marshal.GetLastWin32Error(); 936 if (!status) 937 EventLogException.Throw(win32Error); 938 939 List<object> valuesList = new List<object>(propCount); 940 if (propCount > 0) { 941 pointer = buffer; 942 for (int i = 0; i < propCount; i++) { 943 UnsafeNativeMethods.EvtVariant varVal = (UnsafeNativeMethods.EvtVariant)Marshal.PtrToStructure(pointer, typeof(UnsafeNativeMethods.EvtVariant)); 944 valuesList.Add(ConvertToObject(varVal)); 945 pointer = new IntPtr(((Int64)pointer + Marshal.SizeOf(varVal))); 946 } 947 } 948 return valuesList; 949 } 950 finally { 951 if (buffer != IntPtr.Zero) 952 Marshal.FreeHGlobal(buffer); 953 } 954 } 955 956 [System.Security.SecuritySafeCritical] EvtFormatMessageRenderName(EventLogHandle pmHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtFormatMessageFlags flag)957 public static string EvtFormatMessageRenderName(EventLogHandle pmHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtFormatMessageFlags flag) { 958 959 EventLogPermissionHolder.GetEventLogPermission().Demand(); 960 961 int bufferNeeded; 962 StringBuilder sb = new StringBuilder(null); 963 964 bool status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, 0, sb, out bufferNeeded); 965 int error = Marshal.GetLastWin32Error(); 966 967 if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT) { 968 // 969 // ERROR_EVT_UNRESOLVED_VALUE_INSERT can be returned. It means 970 // message may have one or more unsubstitued strings. This is 971 // not an exception, but we have no way to convey the partial 972 // success out to enduser. 973 // 974 switch (error) { 975 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND: 976 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND: 977 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: 978 case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND: 979 case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND: 980 return null; 981 } 982 if (error != (int)UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 983 EventLogException.Throw(error); 984 } 985 986 sb.EnsureCapacity(bufferNeeded); 987 status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, bufferNeeded, sb, out bufferNeeded); 988 error = Marshal.GetLastWin32Error(); 989 990 if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT) 991 { 992 switch (error) { 993 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND: 994 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND: 995 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: 996 case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND: 997 case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND: 998 return null; 999 } 1000 EventLogException.Throw(error); 1001 } 1002 return sb.ToString(); 1003 } 1004 1005 1006 //The EvtFormatMessage used for the obtaining of the Keywords names. 1007 [System.Security.SecuritySafeCritical] EvtFormatMessageRenderKeywords(EventLogHandle pmHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtFormatMessageFlags flag)1008 public static IEnumerable<string> EvtFormatMessageRenderKeywords(EventLogHandle pmHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtFormatMessageFlags flag) { 1009 1010 EventLogPermissionHolder.GetEventLogPermission().Demand(); 1011 1012 IntPtr buffer = IntPtr.Zero; 1013 int bufferNeeded; 1014 1015 try { 1016 List<string> keywordsList = new List<string>(); 1017 bool status = UnsafeNativeMethods.EvtFormatMessageBuffer(pmHandle, eventHandle, 0, 0, IntPtr.Zero, flag, 0, IntPtr.Zero, out bufferNeeded); 1018 int error = Marshal.GetLastWin32Error(); 1019 1020 if (!status) { 1021 switch (error) { 1022 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND: 1023 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND: 1024 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: 1025 case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND: 1026 case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND: 1027 return keywordsList.AsReadOnly(); 1028 } 1029 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 1030 EventLogException.Throw(error); 1031 } 1032 1033 buffer = Marshal.AllocHGlobal(bufferNeeded * 2); 1034 status = UnsafeNativeMethods.EvtFormatMessageBuffer(pmHandle, eventHandle, 0, 0, IntPtr.Zero, flag, bufferNeeded, buffer, out bufferNeeded); 1035 error = Marshal.GetLastWin32Error(); 1036 if (!status) { 1037 switch (error) 1038 { 1039 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND: 1040 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND: 1041 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: 1042 case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND: 1043 case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND: 1044 return keywordsList; 1045 } 1046 EventLogException.Throw(error); 1047 } 1048 1049 IntPtr pointer = buffer; 1050 1051 while (true) { 1052 string s = Marshal.PtrToStringAuto(pointer); 1053 if (String.IsNullOrEmpty(s)) 1054 break; 1055 keywordsList.Add(s); 1056 //nr of bytes = # chars * 2 + 2 bytes for character '\0'. 1057 pointer = new IntPtr((Int64)pointer + (s.Length * 2) + 2); 1058 } 1059 1060 return keywordsList.AsReadOnly(); 1061 } 1062 finally { 1063 if (buffer != IntPtr.Zero) 1064 Marshal.FreeHGlobal(buffer); 1065 } 1066 } 1067 1068 [System.Security.SecurityCritical] EvtRenderBookmark(EventLogHandle eventHandle)1069 public static string EvtRenderBookmark(EventLogHandle eventHandle) { 1070 IntPtr buffer = IntPtr.Zero; 1071 int bufferNeeded; 1072 int propCount; 1073 UnsafeNativeMethods.EvtRenderFlags flag = UnsafeNativeMethods.EvtRenderFlags.EvtRenderBookmark; 1074 1075 try { 1076 bool status = UnsafeNativeMethods.EvtRender(EventLogHandle.Zero, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount); 1077 int error = Marshal.GetLastWin32Error(); 1078 if (!status) { 1079 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 1080 EventLogException.Throw(error); 1081 } 1082 1083 buffer = Marshal.AllocHGlobal((int)bufferNeeded); 1084 status = UnsafeNativeMethods.EvtRender(EventLogHandle.Zero, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount); 1085 error = Marshal.GetLastWin32Error(); 1086 if (!status) 1087 EventLogException.Throw(error); 1088 1089 return Marshal.PtrToStringAuto(buffer); 1090 } 1091 finally { 1092 if (buffer != IntPtr.Zero) 1093 Marshal.FreeHGlobal(buffer); 1094 } 1095 } 1096 1097 1098 //Get the formatted description, using the msgId for FormatDescription(string []) 1099 [System.Security.SecuritySafeCritical] EvtFormatMessageFormatDescription(EventLogHandle handle, EventLogHandle eventHandle, string[] values)1100 public static string EvtFormatMessageFormatDescription(EventLogHandle handle, EventLogHandle eventHandle, string[] values) { 1101 if (s_platformNotSupported) 1102 throw new System.PlatformNotSupportedException(); 1103 1104 EventLogPermissionHolder.GetEventLogPermission().Demand(); 1105 1106 int bufferNeeded; 1107 1108 UnsafeNativeMethods.EvtStringVariant [] stringVariants = new UnsafeNativeMethods.EvtStringVariant[values.Length]; 1109 for (int i = 0; i < values.Length; i++) { 1110 stringVariants[i].Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeString; 1111 stringVariants[i].StringVal = values[i]; 1112 } 1113 1114 StringBuilder sb = new StringBuilder(null); 1115 bool status = UnsafeNativeMethods.EvtFormatMessage(handle, eventHandle, 0xffffffff, values.Length, stringVariants, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageEvent, 0, sb, out bufferNeeded); 1116 int error = Marshal.GetLastWin32Error(); 1117 1118 if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT) { 1119 // 1120 // ERROR_EVT_UNRESOLVED_VALUE_INSERT can be returned. It means 1121 // message may have one or more unsubstitued strings. This is 1122 // not an exception, but we have no way to convey the partial 1123 // success out to enduser. 1124 // 1125 switch (error) 1126 { 1127 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND: 1128 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND: 1129 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: 1130 case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND: 1131 case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND: 1132 return null; 1133 } 1134 if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER) 1135 EventLogException.Throw(error); 1136 } 1137 1138 sb.EnsureCapacity(bufferNeeded); 1139 status = UnsafeNativeMethods.EvtFormatMessage(handle, eventHandle, 0xffffffff, values.Length, stringVariants, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageEvent, bufferNeeded, sb, out bufferNeeded); 1140 error = Marshal.GetLastWin32Error(); 1141 1142 if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT) { 1143 switch (error) 1144 { 1145 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND: 1146 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND: 1147 case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: 1148 case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND: 1149 case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND: 1150 return null; 1151 } 1152 EventLogException.Throw(error); 1153 } 1154 return sb.ToString(); 1155 1156 } 1157 1158 [System.Security.SecurityCritical] ConvertToObject(UnsafeNativeMethods.EvtVariant val)1159 private static object ConvertToObject(UnsafeNativeMethods.EvtVariant val) { 1160 1161 switch (val.Type) { 1162 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32: 1163 return val.UInteger; 1164 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeInt32: 1165 return val.Integer; 1166 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16: 1167 return val.UShort; 1168 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeInt16: 1169 return val.SByte; 1170 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte: 1171 return val.UInt8; 1172 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSByte: 1173 return val.SByte; 1174 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64: 1175 return val.ULong; 1176 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeInt64: 1177 return val.Long; 1178 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeHexInt64: 1179 return val.ULong; 1180 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeHexInt32: 1181 return val.Integer; 1182 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSingle: 1183 return val.Single; 1184 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeDouble: 1185 return val.Double; 1186 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeNull: 1187 return null; 1188 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeString: 1189 return ConvertToString(val); 1190 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeAnsiString: 1191 return ConvertToAnsiString(val); 1192 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSid: 1193 return (val.SidVal == IntPtr.Zero) ? null : new SecurityIdentifier(val.SidVal); 1194 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid: 1195 return (val.GuidReference == IntPtr.Zero) ? Guid.Empty : Marshal.PtrToStructure(val.GuidReference, typeof(Guid)); 1196 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeEvtHandle: 1197 return ConvertToSafeHandle(val); 1198 case (int)(int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeFileTime: 1199 return DateTime.FromFileTime((long)val.FileTime); 1200 case (int)(int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSysTime: 1201 UnsafeNativeMethods.SystemTime sysTime = (UnsafeNativeMethods.SystemTime)Marshal.PtrToStructure(val.SystemTime, typeof(UnsafeNativeMethods.SystemTime)); 1202 return new DateTime(sysTime.Year, sysTime.Month, sysTime.Day, sysTime.Hour, sysTime.Minute, sysTime.Second, sysTime.Milliseconds); 1203 case (int)(int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSizeT: 1204 return val.SizeT; 1205 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBoolean: 1206 if (val.Bool != 0) return true; 1207 else return false; 1208 case (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBinary: 1209 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte): 1210 if (val.Reference == IntPtr.Zero) return new Byte[0]; 1211 Byte[] arByte = new Byte[val.Count]; 1212 Marshal.Copy(val.Reference, arByte, 0, (int)val.Count); 1213 return arByte; 1214 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeInt16): 1215 if (val.Reference == IntPtr.Zero) return new Int16[0]; 1216 Int16[] arInt16 = new Int16[val.Count]; 1217 Marshal.Copy(val.Reference, arInt16, 0, (int)val.Count); 1218 return arInt16; 1219 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeInt32): 1220 if (val.Reference == IntPtr.Zero) return new Int32[0]; 1221 Int32[] arInt32 = new Int32[val.Count]; 1222 Marshal.Copy(val.Reference, arInt32, 0, (int)val.Count); 1223 return arInt32; 1224 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeInt64): 1225 if (val.Reference == IntPtr.Zero) return new Int64[0]; 1226 Int64[] arInt64 = new Int64[val.Count]; 1227 Marshal.Copy(val.Reference, arInt64, 0, (int)val.Count); 1228 return arInt64; 1229 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSingle): 1230 if (val.Reference == IntPtr.Zero) return new Single[0]; 1231 Single[] arSingle = new Single[val.Count]; 1232 Marshal.Copy(val.Reference, arSingle, 0, (int)val.Count); 1233 return arSingle; 1234 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeDouble): 1235 if (val.Reference == IntPtr.Zero) return new Double[0]; 1236 Double[] arDouble = new Double[val.Count]; 1237 Marshal.Copy(val.Reference, arDouble, 0, (int)val.Count); 1238 return arDouble; 1239 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSByte): 1240 return ConvertToArray (val,typeof(SByte), sizeof(SByte)); // not CLS-compliant 1241 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16): 1242 return ConvertToArray (val,typeof(UInt16), sizeof(UInt16)); 1243 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64): 1244 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeHexInt64): 1245 return ConvertToArray (val,typeof(UInt64), sizeof(UInt64)); 1246 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32): 1247 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeHexInt32): 1248 return ConvertToArray (val,typeof(UInt32), sizeof(UInt32)); 1249 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeString): 1250 return ConvertToStringArray(val, false); 1251 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeAnsiString): 1252 return ConvertToStringArray(val, true); 1253 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBoolean): 1254 return ConvertToBoolArray(val); 1255 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid): 1256 return ConvertToArray (val, typeof(Guid), 16 * sizeof(byte)); 1257 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeFileTime): 1258 return ConvertToFileTimeArray(val); 1259 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSysTime): 1260 return ConvertToSysTimeArray(val); 1261 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBinary): //both length and count in the manifest: tracrpt supports, Crimson APIs don't 1262 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSizeT): //unused: array of win:pointer is returned as HexIntXX 1263 case ((int) UnsafeNativeMethods.EvtMasks.EVT_VARIANT_TYPE_ARRAY | (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeSid): //unsupported by native APIs 1264 default: 1265 throw new EventLogInvalidDataException(); 1266 } 1267 } 1268 1269 [System.Security.SecurityCritical] ConvertToObject(UnsafeNativeMethods.EvtVariant val, UnsafeNativeMethods.EvtVariantType desiredType)1270 public static object ConvertToObject(UnsafeNativeMethods.EvtVariant val, UnsafeNativeMethods.EvtVariantType desiredType) { 1271 if (val.Type == (int)UnsafeNativeMethods.EvtVariantType.EvtVarTypeNull) return null; 1272 if (val.Type != (int)desiredType) 1273 throw new EventLogInvalidDataException(); 1274 1275 1276 return ConvertToObject(val); 1277 } 1278 1279 [System.Security.SecurityCritical] ConvertToString(UnsafeNativeMethods.EvtVariant val)1280 public static string ConvertToString(UnsafeNativeMethods.EvtVariant val) { 1281 if (val.StringVal == IntPtr.Zero) 1282 return string.Empty; 1283 else 1284 return Marshal.PtrToStringAuto(val.StringVal); 1285 } 1286 1287 [System.Security.SecurityCritical] ConvertToAnsiString(UnsafeNativeMethods.EvtVariant val)1288 public static string ConvertToAnsiString(UnsafeNativeMethods.EvtVariant val) { 1289 if (val.AnsiString == IntPtr.Zero) 1290 return string.Empty; 1291 else 1292 return Marshal.PtrToStringAnsi(val.AnsiString); 1293 } 1294 1295 1296 [System.Security.SecurityCritical] ConvertToSafeHandle(UnsafeNativeMethods.EvtVariant val)1297 public static EventLogHandle ConvertToSafeHandle(UnsafeNativeMethods.EvtVariant val) { 1298 if (val.Handle == IntPtr.Zero) 1299 return EventLogHandle.Zero; 1300 else 1301 return new EventLogHandle(val.Handle, true); 1302 } 1303 1304 1305 [System.Security.SecurityCritical] ConvertToArray(UnsafeNativeMethods.EvtVariant val, Type objType, int size)1306 public static Array ConvertToArray(UnsafeNativeMethods.EvtVariant val, Type objType, int size) { 1307 IntPtr ptr = val.Reference; 1308 if (ptr == IntPtr.Zero) { 1309 return Array.CreateInstance(objType, 0); 1310 } 1311 else { 1312 Array array = Array.CreateInstance(objType, val.Count); 1313 for (int i = 0; i < val.Count; i++) { 1314 array.SetValue(Marshal.PtrToStructure(ptr, objType), i); 1315 ptr = new IntPtr ((Int64)ptr + size); 1316 } 1317 return array; 1318 } 1319 } 1320 1321 [System.Security.SecurityCritical] ConvertToBoolArray(UnsafeNativeMethods.EvtVariant val)1322 public static Array ConvertToBoolArray(UnsafeNativeMethods.EvtVariant val) { 1323 1324 //NOTE: booleans are padded to 4 bytes in ETW 1325 IntPtr ptr = val.Reference; 1326 if (ptr == IntPtr.Zero) { 1327 return new bool[0]; 1328 } 1329 else { 1330 bool[] array = new bool[val.Count]; 1331 for (int i = 0; i < val.Count; i++) { 1332 bool value = (Marshal.ReadInt32(ptr) != 0) ? true : false; 1333 array[i] = value; 1334 ptr = new IntPtr ((Int64)ptr + 4); 1335 } 1336 return array; 1337 } 1338 } 1339 1340 [System.Security.SecurityCritical] ConvertToFileTimeArray(UnsafeNativeMethods.EvtVariant val)1341 public static Array ConvertToFileTimeArray(UnsafeNativeMethods.EvtVariant val) { 1342 IntPtr ptr = val.Reference; 1343 if (ptr == IntPtr.Zero) { 1344 return new DateTime[0]; 1345 } 1346 else { 1347 DateTime[] array = new DateTime[val.Count]; 1348 for (int i = 0; i < val.Count; i++) { 1349 array[i] = DateTime.FromFileTime(Marshal.ReadInt64(ptr)); 1350 ptr = new IntPtr((Int64)ptr + 8*sizeof(byte)); // FILETIME values are 8 bytes 1351 } 1352 return array; 1353 } 1354 } 1355 1356 [System.Security.SecurityCritical] ConvertToSysTimeArray(UnsafeNativeMethods.EvtVariant val)1357 public static Array ConvertToSysTimeArray(UnsafeNativeMethods.EvtVariant val) { 1358 IntPtr ptr = val.Reference; 1359 if (ptr == IntPtr.Zero) { 1360 return new DateTime[0]; 1361 } 1362 else { 1363 DateTime[] array = new DateTime[val.Count]; 1364 for (int i = 0; i < val.Count; i++) { 1365 1366 UnsafeNativeMethods.SystemTime sysTime = (UnsafeNativeMethods.SystemTime)Marshal.PtrToStructure(ptr, typeof(UnsafeNativeMethods.SystemTime)); 1367 array[i] = new DateTime(sysTime.Year, sysTime.Month, sysTime.Day, sysTime.Hour, sysTime.Minute, sysTime.Second, sysTime.Milliseconds); 1368 ptr = new IntPtr((Int64)ptr + 16*sizeof(byte)); // SystemTime values are 16 bytes 1369 1370 } 1371 return array; 1372 } 1373 } 1374 1375 1376 [System.Security.SecurityCritical] ConvertToStringArray(UnsafeNativeMethods.EvtVariant val, bool ansi)1377 public static string[] ConvertToStringArray(UnsafeNativeMethods.EvtVariant val, bool ansi) { 1378 if (val.Reference == IntPtr.Zero) { 1379 return new string[0]; 1380 } 1381 else { 1382 IntPtr ptr = val.Reference; 1383 IntPtr[] pointersToString = new IntPtr[val.Count]; 1384 Marshal.Copy(ptr, pointersToString, 0, (int)val.Count); 1385 string[] stringArray = new string[val.Count]; 1386 for (int i = 0; i < val.Count; i++) { 1387 stringArray[i] = ansi ? Marshal.PtrToStringAnsi(pointersToString[i]) : Marshal.PtrToStringAuto(pointersToString[i]); 1388 } 1389 return stringArray; 1390 } 1391 } 1392 1393 } 1394 } 1395