PageRenderTime 78ms CodeModel.GetById 41ms RepoModel.GetById 0ms app.codeStats 1ms

/src/Microsoft.PowerShell.CoreCLR.Eventing/DotNetCode/Eventing/Reader/NativeWrapper.cs

https://gitlab.com/unofficial-mirrors/PowerShell
C# | 1045 lines | 899 code | 93 blank | 53 comment | 160 complexity | 8dd67da435d6376410612ef18176be20 MD5 | raw file
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License.
  3. /*============================================================
  4. **
  5. **
  6. ** Purpose:
  7. ** This internal class contains wrapper methods over the Native
  8. ** Methods of the Eventlog API. Unlike the raw Native Methods,
  9. ** these methods throw EventLogExceptions, check platform
  10. ** availability and perform additional helper functionality
  11. ** specific to function. Also, all methods of this class expose
  12. ** the Link Demand for Unmanaged Permission to callers.
  13. **
  14. ============================================================*/
  15. using System.Collections.Generic;
  16. using System.Runtime.InteropServices;
  17. using System.Text;
  18. using System.Security.Principal;
  19. namespace System.Diagnostics.Eventing.Reader
  20. {
  21. internal class NativeWrapper
  22. {
  23. public class SystemProperties
  24. {
  25. //indicates if the SystemProperties values were already computed (for this event Instance, surely).
  26. public bool filled = false;
  27. public ushort? Id = null;
  28. public byte? Version = null;
  29. public ushort? Qualifiers = null;
  30. public byte? Level = null;
  31. public ushort? Task = null;
  32. public byte? Opcode = null;
  33. public ulong? Keywords = null;
  34. public ulong? RecordId = null;
  35. public string ProviderName = null;
  36. public Guid? ProviderId = null;
  37. public string ChannelName = null;
  38. public uint? ProcessId = null;
  39. public uint? ThreadId = null;
  40. public string ComputerName = null;
  41. public System.Security.Principal.SecurityIdentifier UserId = null;
  42. public DateTime? TimeCreated = null;
  43. public Guid? ActivityId = null;
  44. public Guid? RelatedActivityId = null;
  45. public SystemProperties()
  46. {
  47. }
  48. }
  49. [System.Security.SecurityCritical]
  50. public static EventLogHandle EvtQuery(
  51. EventLogHandle session,
  52. string path,
  53. string query,
  54. int flags)
  55. {
  56. EventLogHandle handle = UnsafeNativeMethods.EvtQuery(session, path, query, flags);
  57. int win32Error = Marshal.GetLastWin32Error();
  58. if (handle.IsInvalid)
  59. EventLogException.Throw(win32Error);
  60. return handle;
  61. }
  62. [System.Security.SecurityCritical]
  63. public static void EvtSeek(
  64. EventLogHandle resultSet,
  65. long position,
  66. EventLogHandle bookmark,
  67. int timeout,
  68. UnsafeNativeMethods.EvtSeekFlags flags)
  69. {
  70. bool status = UnsafeNativeMethods.EvtSeek(resultSet, position, bookmark, timeout, flags);
  71. int win32Error = Marshal.GetLastWin32Error();
  72. if (!status)
  73. EventLogException.Throw(win32Error);
  74. }
  75. [System.Security.SecurityCritical]
  76. public static bool EvtNext(
  77. EventLogHandle queryHandle,
  78. int eventSize,
  79. IntPtr[] events,
  80. int timeout,
  81. int flags,
  82. ref int returned)
  83. {
  84. bool status = UnsafeNativeMethods.EvtNext(queryHandle, eventSize, events, timeout, flags, ref returned);
  85. int win32Error = Marshal.GetLastWin32Error();
  86. if (!status && win32Error != UnsafeNativeMethods.ERROR_NO_MORE_ITEMS)
  87. EventLogException.Throw(win32Error);
  88. return win32Error == 0;
  89. }
  90. [System.Security.SecuritySafeCritical]
  91. public static void EvtCancel(EventLogHandle handle)
  92. {
  93. if (!UnsafeNativeMethods.EvtCancel(handle))
  94. {
  95. int win32Error = Marshal.GetLastWin32Error();
  96. EventLogException.Throw(win32Error);
  97. }
  98. }
  99. [System.Security.SecurityCritical]
  100. public static void EvtClose(IntPtr handle)
  101. {
  102. //
  103. // purposely don't check and throw - this is
  104. // always called in cleanup / finalize / etc..
  105. //
  106. UnsafeNativeMethods.EvtClose(handle);
  107. }
  108. [System.Security.SecurityCritical]
  109. public static EventLogHandle EvtOpenProviderMetadata(
  110. EventLogHandle session,
  111. string ProviderId,
  112. string logFilePath,
  113. int locale,
  114. int flags)
  115. {
  116. //
  117. // ignore locale and pass 0 instead: that way, the thread locale will be retrieved in the API layer
  118. // and the "strict rendering" flag will NOT be set. Otherwise, the fall back logic is broken and the descriptions
  119. // are not returned if the exact locale is not present on the server.
  120. //
  121. EventLogHandle handle = UnsafeNativeMethods.EvtOpenPublisherMetadata(session, ProviderId, logFilePath, 0, flags);
  122. int win32Error = Marshal.GetLastWin32Error();
  123. if (handle.IsInvalid)
  124. EventLogException.Throw(win32Error);
  125. return handle;
  126. }
  127. [System.Security.SecurityCritical]
  128. public static int EvtGetObjectArraySize(EventLogHandle objectArray)
  129. {
  130. int arraySize;
  131. bool status = UnsafeNativeMethods.EvtGetObjectArraySize(objectArray, out arraySize);
  132. int win32Error = Marshal.GetLastWin32Error();
  133. if (!status)
  134. EventLogException.Throw(win32Error);
  135. return arraySize;
  136. }
  137. [System.Security.SecurityCritical]
  138. public static EventLogHandle EvtOpenEventMetadataEnum(EventLogHandle ProviderMetadata, int flags)
  139. {
  140. EventLogHandle emEnumHandle = UnsafeNativeMethods.EvtOpenEventMetadataEnum(ProviderMetadata, flags);
  141. int win32Error = Marshal.GetLastWin32Error();
  142. if (emEnumHandle.IsInvalid)
  143. EventLogException.Throw(win32Error);
  144. return emEnumHandle;
  145. }
  146. // returns null if EOF
  147. [System.Security.SecurityCritical]
  148. public static EventLogHandle EvtNextEventMetadata(EventLogHandle eventMetadataEnum, int flags)
  149. {
  150. EventLogHandle emHandle = UnsafeNativeMethods.EvtNextEventMetadata(eventMetadataEnum, flags);
  151. int win32Error = Marshal.GetLastWin32Error();
  152. if (emHandle.IsInvalid)
  153. {
  154. if (win32Error != UnsafeNativeMethods.ERROR_NO_MORE_ITEMS)
  155. EventLogException.Throw(win32Error);
  156. return null;
  157. }
  158. return emHandle;
  159. }
  160. [System.Security.SecurityCritical]
  161. public static EventLogHandle EvtOpenChannelEnum(EventLogHandle session, int flags)
  162. {
  163. EventLogHandle channelEnum = UnsafeNativeMethods.EvtOpenChannelEnum(session, flags);
  164. int win32Error = Marshal.GetLastWin32Error();
  165. if (channelEnum.IsInvalid)
  166. EventLogException.Throw(win32Error);
  167. return channelEnum;
  168. }
  169. [System.Security.SecurityCritical]
  170. public static EventLogHandle EvtOpenProviderEnum(EventLogHandle session, int flags)
  171. {
  172. EventLogHandle pubEnum = UnsafeNativeMethods.EvtOpenPublisherEnum(session, flags);
  173. int win32Error = Marshal.GetLastWin32Error();
  174. if (pubEnum.IsInvalid)
  175. EventLogException.Throw(win32Error);
  176. return pubEnum;
  177. }
  178. [System.Security.SecurityCritical]
  179. public static EventLogHandle EvtOpenChannelConfig(EventLogHandle session, String channelPath, int flags)
  180. {
  181. EventLogHandle handle = UnsafeNativeMethods.EvtOpenChannelConfig(session, channelPath, flags);
  182. int win32Error = Marshal.GetLastWin32Error();
  183. if (handle.IsInvalid)
  184. EventLogException.Throw(win32Error);
  185. return handle;
  186. }
  187. [System.Security.SecuritySafeCritical]
  188. public static void EvtSaveChannelConfig(EventLogHandle channelConfig, int flags)
  189. {
  190. bool status = UnsafeNativeMethods.EvtSaveChannelConfig(channelConfig, flags);
  191. int win32Error = Marshal.GetLastWin32Error();
  192. if (!status)
  193. EventLogException.Throw(win32Error);
  194. }
  195. [System.Security.SecurityCritical]
  196. public static EventLogHandle EvtOpenLog(EventLogHandle session, string path, PathType flags)
  197. {
  198. EventLogHandle logHandle = UnsafeNativeMethods.EvtOpenLog(session, path, flags);
  199. int win32Error = Marshal.GetLastWin32Error();
  200. if (logHandle.IsInvalid)
  201. EventLogException.Throw(win32Error);
  202. return logHandle;
  203. }
  204. [System.Security.SecuritySafeCritical]
  205. public static void EvtExportLog(
  206. EventLogHandle session,
  207. string channelPath,
  208. string query,
  209. string targetFilePath,
  210. int flags)
  211. {
  212. bool status;
  213. status = UnsafeNativeMethods.EvtExportLog(session, channelPath, query, targetFilePath, flags);
  214. int win32Error = Marshal.GetLastWin32Error();
  215. if (!status)
  216. EventLogException.Throw(win32Error);
  217. }
  218. [System.Security.SecuritySafeCritical]
  219. public static void EvtArchiveExportedLog(
  220. EventLogHandle session,
  221. string logFilePath,
  222. int locale,
  223. int flags)
  224. {
  225. bool status;
  226. status = UnsafeNativeMethods.EvtArchiveExportedLog(session, logFilePath, locale, flags);
  227. int win32Error = Marshal.GetLastWin32Error();
  228. if (!status)
  229. EventLogException.Throw(win32Error);
  230. }
  231. [System.Security.SecuritySafeCritical]
  232. public static void EvtClearLog(
  233. EventLogHandle session,
  234. string channelPath,
  235. string targetFilePath,
  236. int flags)
  237. {
  238. bool status;
  239. status = UnsafeNativeMethods.EvtClearLog(session, channelPath, targetFilePath, flags);
  240. int win32Error = Marshal.GetLastWin32Error();
  241. if (!status)
  242. EventLogException.Throw(win32Error);
  243. }
  244. [System.Security.SecurityCritical]
  245. public static EventLogHandle EvtCreateRenderContext(
  246. Int32 valuePathsCount,
  247. String[] valuePaths,
  248. UnsafeNativeMethods.EvtRenderContextFlags flags)
  249. {
  250. EventLogHandle renderContextHandleValues = UnsafeNativeMethods.EvtCreateRenderContext(valuePathsCount, valuePaths, flags);
  251. int win32Error = Marshal.GetLastWin32Error();
  252. if (renderContextHandleValues.IsInvalid)
  253. EventLogException.Throw(win32Error);
  254. return renderContextHandleValues;
  255. }
  256. [System.Security.SecurityCritical]
  257. public static void EvtRender(
  258. EventLogHandle context,
  259. EventLogHandle eventHandle,
  260. UnsafeNativeMethods.EvtRenderFlags flags,
  261. StringBuilder buffer)
  262. {
  263. int buffUsed;
  264. int propCount;
  265. bool status = UnsafeNativeMethods.EvtRender(context, eventHandle, flags, buffer.Capacity, buffer, out buffUsed, out propCount);
  266. int win32Error = Marshal.GetLastWin32Error();
  267. if (!status)
  268. {
  269. if (win32Error == UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  270. {
  271. //reallocate the new RenderBuffer with the right size.
  272. buffer.Capacity = buffUsed;
  273. status = UnsafeNativeMethods.EvtRender(context, eventHandle, flags, buffer.Capacity, buffer, out buffUsed, out propCount);
  274. win32Error = Marshal.GetLastWin32Error();
  275. }
  276. if (!status)
  277. {
  278. EventLogException.Throw(win32Error);
  279. }
  280. }
  281. }
  282. [System.Security.SecurityCritical]
  283. public static EventLogHandle EvtOpenSession(UnsafeNativeMethods.EvtLoginClass loginClass, ref UnsafeNativeMethods.EvtRpcLogin login, int timeout, int flags)
  284. {
  285. EventLogHandle handle = UnsafeNativeMethods.EvtOpenSession(loginClass, ref login, timeout, flags);
  286. int win32Error = Marshal.GetLastWin32Error();
  287. if (handle.IsInvalid)
  288. EventLogException.Throw(win32Error);
  289. return handle;
  290. }
  291. [System.Security.SecurityCritical]
  292. public static EventLogHandle EvtCreateBookmark(string bookmarkXml)
  293. {
  294. EventLogHandle handle = UnsafeNativeMethods.EvtCreateBookmark(bookmarkXml);
  295. int win32Error = Marshal.GetLastWin32Error();
  296. if (handle.IsInvalid)
  297. EventLogException.Throw(win32Error);
  298. return handle;
  299. }
  300. [System.Security.SecurityCritical]
  301. public static void EvtUpdateBookmark(EventLogHandle bookmark, EventLogHandle eventHandle)
  302. {
  303. bool status = UnsafeNativeMethods.EvtUpdateBookmark(bookmark, eventHandle);
  304. int win32Error = Marshal.GetLastWin32Error();
  305. if (!status)
  306. EventLogException.Throw(win32Error);
  307. }
  308. [System.Security.SecuritySafeCritical]
  309. public static object EvtGetEventInfo(EventLogHandle handle, UnsafeNativeMethods.EvtEventPropertyId enumType)
  310. {
  311. IntPtr buffer = IntPtr.Zero;
  312. int bufferNeeded;
  313. try
  314. {
  315. bool status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, 0, IntPtr.Zero, out bufferNeeded);
  316. int error = Marshal.GetLastWin32Error();
  317. if (!status)
  318. {
  319. if (error == UnsafeNativeMethods.ERROR_SUCCESS) { }
  320. else
  321. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  322. EventLogException.Throw(error);
  323. }
  324. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  325. status = UnsafeNativeMethods.EvtGetEventInfo(handle, enumType, bufferNeeded, buffer, out bufferNeeded);
  326. error = Marshal.GetLastWin32Error();
  327. if (!status)
  328. EventLogException.Throw(error);
  329. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(buffer);
  330. return ConvertToObject(varVal);
  331. }
  332. finally
  333. {
  334. if (buffer != IntPtr.Zero)
  335. Marshal.FreeHGlobal(buffer);
  336. }
  337. }
  338. [System.Security.SecurityCritical]
  339. public static object EvtGetQueryInfo(EventLogHandle handle, UnsafeNativeMethods.EvtQueryPropertyId enumType)
  340. {
  341. IntPtr buffer = IntPtr.Zero;
  342. int bufferNeeded = 0;
  343. try
  344. {
  345. bool status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, 0, IntPtr.Zero, ref bufferNeeded);
  346. int error = Marshal.GetLastWin32Error();
  347. if (!status)
  348. {
  349. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  350. EventLogException.Throw(error);
  351. }
  352. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  353. status = UnsafeNativeMethods.EvtGetQueryInfo(handle, enumType, bufferNeeded, buffer, ref bufferNeeded);
  354. error = Marshal.GetLastWin32Error();
  355. if (!status)
  356. EventLogException.Throw(error);
  357. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(buffer);
  358. return ConvertToObject(varVal);
  359. }
  360. finally
  361. {
  362. if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer);
  363. }
  364. }
  365. [System.Security.SecuritySafeCritical]
  366. public static object EvtGetPublisherMetadataProperty(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId)
  367. {
  368. IntPtr buffer = IntPtr.Zero;
  369. int bufferNeeded;
  370. try
  371. {
  372. bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, IntPtr.Zero, out bufferNeeded);
  373. int error = Marshal.GetLastWin32Error();
  374. if (!status)
  375. {
  376. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  377. EventLogException.Throw(error);
  378. }
  379. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  380. status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, buffer, out bufferNeeded);
  381. error = Marshal.GetLastWin32Error();
  382. if (!status)
  383. EventLogException.Throw(error);
  384. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(buffer);
  385. return ConvertToObject(varVal);
  386. }
  387. finally
  388. {
  389. if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer);
  390. }
  391. }
  392. [System.Security.SecurityCritical]
  393. internal static EventLogHandle EvtGetPublisherMetadataPropertyHandle(EventLogHandle pmHandle, UnsafeNativeMethods.EvtPublisherMetadataPropertyId thePropertyId)
  394. {
  395. IntPtr buffer = IntPtr.Zero;
  396. try
  397. {
  398. int bufferNeeded;
  399. bool status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, 0, IntPtr.Zero, out bufferNeeded);
  400. int error = Marshal.GetLastWin32Error();
  401. if (!status)
  402. {
  403. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  404. EventLogException.Throw(error);
  405. }
  406. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  407. status = UnsafeNativeMethods.EvtGetPublisherMetadataProperty(pmHandle, thePropertyId, 0, bufferNeeded, buffer, out bufferNeeded);
  408. error = Marshal.GetLastWin32Error();
  409. if (!status)
  410. EventLogException.Throw(error);
  411. //
  412. // note: there is a case where returned variant does have allocated native resources
  413. // associated with (e.g. ConfigArrayHandle). If PtrToStructure throws, then we would
  414. // leak that resource - fortunately PtrToStructure only throws InvalidArgument which
  415. // is a logic error - not a possible runtime condition here. Other System exceptions
  416. // shouldn't be handled anyhow and the application will terminate.
  417. //
  418. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(buffer);
  419. return ConvertToSafeHandle(varVal);
  420. }
  421. finally
  422. {
  423. if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer);
  424. }
  425. }
  426. // implies UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId flag.
  427. [System.Security.SecurityCritical]
  428. public static string EvtFormatMessage(EventLogHandle handle, uint msgId)
  429. {
  430. int bufferNeeded;
  431. StringBuilder sb = new StringBuilder(null);
  432. bool status = UnsafeNativeMethods.EvtFormatMessage(handle, EventLogHandle.Zero, msgId, 0, null, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId, 0, sb, out bufferNeeded);
  433. int error = Marshal.GetLastWin32Error();
  434. // ERROR_EVT_UNRESOLVED_VALUE_INSERT and its cousins are commonly returned for raw message text.
  435. if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT
  436. && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT
  437. && error != UnsafeNativeMethods.ERROR_EVT_MAX_INSERTS_REACHED)
  438. {
  439. switch (error)
  440. {
  441. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND:
  442. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND:
  443. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
  444. case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND:
  445. case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND:
  446. return null;
  447. }
  448. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  449. EventLogException.Throw(error);
  450. }
  451. sb.EnsureCapacity(bufferNeeded);
  452. status = UnsafeNativeMethods.EvtFormatMessage(handle, EventLogHandle.Zero, msgId, 0, null, UnsafeNativeMethods.EvtFormatMessageFlags.EvtFormatMessageId, bufferNeeded, sb, out bufferNeeded);
  453. error = Marshal.GetLastWin32Error();
  454. if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT
  455. && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_PARAMETER_INSERT
  456. && error != UnsafeNativeMethods.ERROR_EVT_MAX_INSERTS_REACHED)
  457. {
  458. switch (error)
  459. {
  460. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND:
  461. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND:
  462. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
  463. case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND:
  464. case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND:
  465. return null;
  466. }
  467. if (error == UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT)
  468. {
  469. return null;
  470. }
  471. EventLogException.Throw(error);
  472. }
  473. return sb.ToString();
  474. }
  475. [System.Security.SecurityCritical]
  476. public static object EvtGetObjectArrayProperty(EventLogHandle objArrayHandle, int index, int thePropertyId)
  477. {
  478. IntPtr buffer = IntPtr.Zero;
  479. int bufferNeeded;
  480. try
  481. {
  482. bool status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, 0, IntPtr.Zero, out bufferNeeded);
  483. int error = Marshal.GetLastWin32Error();
  484. if (!status)
  485. {
  486. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  487. EventLogException.Throw(error);
  488. }
  489. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  490. status = UnsafeNativeMethods.EvtGetObjectArrayProperty(objArrayHandle, thePropertyId, index, 0, bufferNeeded, buffer, out bufferNeeded);
  491. error = Marshal.GetLastWin32Error();
  492. if (!status)
  493. EventLogException.Throw(error);
  494. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(buffer);
  495. return ConvertToObject(varVal);
  496. }
  497. finally
  498. {
  499. if (buffer != IntPtr.Zero) Marshal.FreeHGlobal(buffer);
  500. }
  501. }
  502. [System.Security.SecurityCritical]
  503. public static object EvtGetEventMetadataProperty(EventLogHandle handle, UnsafeNativeMethods.EvtEventMetadataPropertyId enumType)
  504. {
  505. IntPtr buffer = IntPtr.Zero;
  506. int bufferNeeded;
  507. try
  508. {
  509. bool status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, 0, IntPtr.Zero, out bufferNeeded);
  510. int win32Error = Marshal.GetLastWin32Error();
  511. if (!status)
  512. {
  513. if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  514. EventLogException.Throw(win32Error);
  515. }
  516. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  517. status = UnsafeNativeMethods.EvtGetEventMetadataProperty(handle, enumType, 0, bufferNeeded, buffer, out bufferNeeded);
  518. win32Error = Marshal.GetLastWin32Error();
  519. if (!status)
  520. EventLogException.Throw(win32Error);
  521. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(buffer);
  522. return ConvertToObject(varVal);
  523. }
  524. finally
  525. {
  526. if (buffer != IntPtr.Zero)
  527. Marshal.FreeHGlobal(buffer);
  528. }
  529. }
  530. [System.Security.SecuritySafeCritical]
  531. public static object EvtGetChannelConfigProperty(EventLogHandle handle, UnsafeNativeMethods.EvtChannelConfigPropertyId enumType)
  532. {
  533. IntPtr buffer = IntPtr.Zero;
  534. int bufferNeeded;
  535. try
  536. {
  537. bool status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, 0, IntPtr.Zero, out bufferNeeded);
  538. int win32Error = Marshal.GetLastWin32Error();
  539. if (!status)
  540. {
  541. if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  542. EventLogException.Throw(win32Error);
  543. }
  544. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  545. status = UnsafeNativeMethods.EvtGetChannelConfigProperty(handle, enumType, 0, bufferNeeded, buffer, out bufferNeeded);
  546. win32Error = Marshal.GetLastWin32Error();
  547. if (!status)
  548. EventLogException.Throw(win32Error);
  549. //
  550. // note: there is a case where returned variant does have allocated native resources
  551. // associated with (e.g. ConfigArrayHandle). If PtrToStructure throws, then we would
  552. // leak that resource - fortunately PtrToStructure only throws InvalidArgument which
  553. // is a logic error - not a possible runtime condition here. Other System exceptions
  554. // shouldn't be handled anyhow and the application will terminate.
  555. //
  556. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(buffer);
  557. return ConvertToObject(varVal);
  558. }
  559. finally
  560. {
  561. if (buffer != IntPtr.Zero)
  562. Marshal.FreeHGlobal(buffer);
  563. }
  564. }
  565. [System.Security.SecuritySafeCritical]
  566. public static void EvtSetChannelConfigProperty(EventLogHandle handle, UnsafeNativeMethods.EvtChannelConfigPropertyId enumType, object val)
  567. {
  568. UnsafeNativeMethods.EvtVariant varVal = new UnsafeNativeMethods.EvtVariant();
  569. CoTaskMemSafeHandle taskMem = new CoTaskMemSafeHandle();
  570. using (taskMem)
  571. {
  572. if (val != null)
  573. {
  574. switch (enumType)
  575. {
  576. case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigEnabled:
  577. {
  578. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBoolean;
  579. if ((bool)val == true) varVal.Bool = 1;
  580. else varVal.Bool = 0;
  581. }
  582. break;
  583. case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelConfigAccess:
  584. {
  585. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeString;
  586. taskMem.SetMemory(Marshal.StringToCoTaskMemUni((string)val));
  587. varVal.StringVal = taskMem.GetMemory();
  588. }
  589. break;
  590. case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigLogFilePath:
  591. {
  592. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeString;
  593. taskMem.SetMemory(Marshal.StringToCoTaskMemUni((string)val));
  594. varVal.StringVal = taskMem.GetMemory();
  595. }
  596. break;
  597. case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigMaxSize:
  598. {
  599. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64;
  600. varVal.ULong = (ulong)((long)val);
  601. }
  602. break;
  603. case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigLevel:
  604. {
  605. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32;
  606. varVal.UInteger = (uint)((int)val);
  607. }
  608. break;
  609. case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelPublishingConfigKeywords:
  610. {
  611. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64;
  612. varVal.ULong = (ulong)((long)val);
  613. }
  614. break;
  615. case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigRetention:
  616. {
  617. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBoolean;
  618. if ((bool)val == true) varVal.Bool = 1;
  619. else varVal.Bool = 0;
  620. }
  621. break;
  622. case UnsafeNativeMethods.EvtChannelConfigPropertyId.EvtChannelLoggingConfigAutoBackup:
  623. {
  624. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeBoolean;
  625. if ((bool)val == true) varVal.Bool = 1;
  626. else varVal.Bool = 0;
  627. }
  628. break;
  629. default:
  630. throw new InvalidOperationException();
  631. }
  632. }
  633. else
  634. {
  635. varVal.Type = (uint)UnsafeNativeMethods.EvtVariantType.EvtVarTypeNull;
  636. }
  637. bool status = UnsafeNativeMethods.EvtSetChannelConfigProperty(handle, enumType, 0, ref varVal);
  638. int win32Error = Marshal.GetLastWin32Error();
  639. if (!status)
  640. EventLogException.Throw(win32Error);
  641. }
  642. }
  643. [System.Security.SecurityCritical]
  644. public static string EvtNextChannelPath(EventLogHandle handle, ref bool finish)
  645. {
  646. StringBuilder sb = new StringBuilder(null);
  647. int channelNameNeeded;
  648. bool status = UnsafeNativeMethods.EvtNextChannelPath(handle, 0, sb, out channelNameNeeded);
  649. int win32Error = Marshal.GetLastWin32Error();
  650. if (!status)
  651. {
  652. if (win32Error == UnsafeNativeMethods.ERROR_NO_MORE_ITEMS)
  653. {
  654. finish = true;
  655. return null;
  656. }
  657. if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  658. EventLogException.Throw(win32Error);
  659. }
  660. sb.EnsureCapacity(channelNameNeeded);
  661. status = UnsafeNativeMethods.EvtNextChannelPath(handle, channelNameNeeded, sb, out channelNameNeeded);
  662. win32Error = Marshal.GetLastWin32Error();
  663. if (!status)
  664. EventLogException.Throw(win32Error);
  665. return sb.ToString();
  666. }
  667. [System.Security.SecurityCritical]
  668. public static string EvtNextPublisherId(EventLogHandle handle, ref bool finish)
  669. {
  670. StringBuilder sb = new StringBuilder(null);
  671. int ProviderIdNeeded;
  672. bool status = UnsafeNativeMethods.EvtNextPublisherId(handle, 0, sb, out ProviderIdNeeded);
  673. int win32Error = Marshal.GetLastWin32Error();
  674. if (!status)
  675. {
  676. if (win32Error == UnsafeNativeMethods.ERROR_NO_MORE_ITEMS)
  677. {
  678. finish = true;
  679. return null;
  680. }
  681. if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  682. EventLogException.Throw(win32Error);
  683. }
  684. sb.EnsureCapacity(ProviderIdNeeded);
  685. status = UnsafeNativeMethods.EvtNextPublisherId(handle, ProviderIdNeeded, sb, out ProviderIdNeeded);
  686. win32Error = Marshal.GetLastWin32Error();
  687. if (!status)
  688. EventLogException.Throw(win32Error);
  689. return sb.ToString();
  690. }
  691. [System.Security.SecurityCritical]
  692. public static object EvtGetLogInfo(EventLogHandle handle, UnsafeNativeMethods.EvtLogPropertyId enumType)
  693. {
  694. IntPtr buffer = IntPtr.Zero;
  695. int bufferNeeded;
  696. try
  697. {
  698. bool status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, 0, IntPtr.Zero, out bufferNeeded);
  699. int win32Error = Marshal.GetLastWin32Error();
  700. if (!status)
  701. {
  702. if (win32Error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  703. EventLogException.Throw(win32Error);
  704. }
  705. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  706. status = UnsafeNativeMethods.EvtGetLogInfo(handle, enumType, bufferNeeded, buffer, out bufferNeeded);
  707. win32Error = Marshal.GetLastWin32Error();
  708. if (!status)
  709. EventLogException.Throw(win32Error);
  710. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(buffer);
  711. return ConvertToObject(varVal);
  712. }
  713. finally
  714. {
  715. if (buffer != IntPtr.Zero)
  716. Marshal.FreeHGlobal(buffer);
  717. }
  718. }
  719. [System.Security.SecuritySafeCritical]
  720. public static void EvtRenderBufferWithContextSystem(EventLogHandle contextHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtRenderFlags flag, SystemProperties systemProperties, int SYSTEM_PROPERTY_COUNT)
  721. {
  722. IntPtr buffer = IntPtr.Zero;
  723. IntPtr pointer = IntPtr.Zero;
  724. int bufferNeeded;
  725. int propCount;
  726. try
  727. {
  728. bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount);
  729. if (!status)
  730. {
  731. int error = Marshal.GetLastWin32Error();
  732. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  733. EventLogException.Throw(error);
  734. }
  735. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  736. status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount);
  737. int win32Error = Marshal.GetLastWin32Error();
  738. if (!status)
  739. EventLogException.Throw(win32Error);
  740. if (propCount != SYSTEM_PROPERTY_COUNT)
  741. throw new InvalidOperationException("We do not have " + SYSTEM_PROPERTY_COUNT + " variants given for the UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues flag. (System Properties)");
  742. pointer = buffer;
  743. //read each Variant structure
  744. for (int i = 0; i < propCount; i++)
  745. {
  746. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(pointer);
  747. switch (i)
  748. {
  749. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderName:
  750. systemProperties.ProviderName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString);
  751. break;
  752. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProviderGuid:
  753. systemProperties.ProviderId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid);
  754. break;
  755. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventID:
  756. systemProperties.Id = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16);
  757. break;
  758. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemQualifiers:
  759. systemProperties.Qualifiers = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16);
  760. break;
  761. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemLevel:
  762. systemProperties.Level = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte);
  763. break;
  764. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemTask:
  765. systemProperties.Task = (ushort?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt16);
  766. break;
  767. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemOpcode:
  768. systemProperties.Opcode = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte);
  769. break;
  770. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemKeywords:
  771. systemProperties.Keywords = (ulong?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeHexInt64);
  772. break;
  773. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemTimeCreated:
  774. systemProperties.TimeCreated = (DateTime?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeFileTime);
  775. break;
  776. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemEventRecordId:
  777. systemProperties.RecordId = (ulong?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt64);
  778. break;
  779. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemActivityID:
  780. systemProperties.ActivityId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid);
  781. break;
  782. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemRelatedActivityID:
  783. systemProperties.RelatedActivityId = (Guid?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeGuid);
  784. break;
  785. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemProcessID:
  786. systemProperties.ProcessId = (uint?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32);
  787. break;
  788. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemThreadID:
  789. systemProperties.ThreadId = (uint?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeUInt32);
  790. break;
  791. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemChannel:
  792. systemProperties.ChannelName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString);
  793. break;
  794. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemComputer:
  795. systemProperties.ComputerName = (string)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeString);
  796. break;
  797. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemUserID:
  798. systemProperties.UserId = (SecurityIdentifier)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeSid);
  799. break;
  800. case (int)UnsafeNativeMethods.EvtSystemPropertyId.EvtSystemVersion:
  801. systemProperties.Version = (byte?)ConvertToObject(varVal, UnsafeNativeMethods.EvtVariantType.EvtVarTypeByte);
  802. break;
  803. }
  804. pointer = new IntPtr(((Int64)pointer + Marshal.SizeOf(varVal)));
  805. }
  806. }
  807. finally
  808. {
  809. if (buffer != IntPtr.Zero)
  810. Marshal.FreeHGlobal(buffer);
  811. }
  812. }
  813. //EvtRenderContextFlags can be both: EvtRenderContextFlags.EvtRenderContextUser and EvtRenderContextFlags.EvtRenderContextValues
  814. //Render with Context = ContextUser or ContextValues (with user defined Xpath query strings)
  815. [System.Security.SecuritySafeCritical]
  816. public static IList<object> EvtRenderBufferWithContextUserOrValues(EventLogHandle contextHandle, EventLogHandle eventHandle)
  817. {
  818. IntPtr buffer = IntPtr.Zero;
  819. IntPtr pointer = IntPtr.Zero;
  820. int bufferNeeded;
  821. int propCount;
  822. UnsafeNativeMethods.EvtRenderFlags flag = UnsafeNativeMethods.EvtRenderFlags.EvtRenderEventValues;
  823. try
  824. {
  825. bool status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, 0, IntPtr.Zero, out bufferNeeded, out propCount);
  826. if (!status)
  827. {
  828. int error = Marshal.GetLastWin32Error();
  829. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  830. EventLogException.Throw(error);
  831. }
  832. buffer = Marshal.AllocHGlobal((int)bufferNeeded);
  833. status = UnsafeNativeMethods.EvtRender(contextHandle, eventHandle, flag, bufferNeeded, buffer, out bufferNeeded, out propCount);
  834. int win32Error = Marshal.GetLastWin32Error();
  835. if (!status)
  836. EventLogException.Throw(win32Error);
  837. List<object> valuesList = new List<object>(propCount);
  838. if (propCount > 0)
  839. {
  840. pointer = buffer;
  841. for (int i = 0; i < propCount; i++)
  842. {
  843. UnsafeNativeMethods.EvtVariant varVal = Marshal.PtrToStructure<UnsafeNativeMethods.EvtVariant>(pointer);
  844. valuesList.Add(ConvertToObject(varVal));
  845. pointer = new IntPtr(((Int64)pointer + Marshal.SizeOf(varVal)));
  846. }
  847. }
  848. return valuesList;
  849. }
  850. finally
  851. {
  852. if (buffer != IntPtr.Zero)
  853. Marshal.FreeHGlobal(buffer);
  854. }
  855. }
  856. [System.Security.SecuritySafeCritical]
  857. public static string EvtFormatMessageRenderName(EventLogHandle pmHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtFormatMessageFlags flag)
  858. {
  859. int bufferNeeded;
  860. StringBuilder sb = new StringBuilder(null);
  861. bool status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, 0, sb, out bufferNeeded);
  862. int error = Marshal.GetLastWin32Error();
  863. if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT)
  864. {
  865. //
  866. // ERROR_EVT_UNRESOLVED_VALUE_INSERT can be returned. It means
  867. // message may have one or more unsubstituted strings. This is
  868. // not an exception, but we have no way to convey the partial
  869. // success out to enduser.
  870. //
  871. switch (error)
  872. {
  873. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND:
  874. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND:
  875. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
  876. case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND:
  877. case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND:
  878. return null;
  879. }
  880. if (error != (int)UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  881. EventLogException.Throw(error);
  882. }
  883. sb.EnsureCapacity(bufferNeeded);
  884. status = UnsafeNativeMethods.EvtFormatMessage(pmHandle, eventHandle, 0, 0, null, flag, bufferNeeded, sb, out bufferNeeded);
  885. error = Marshal.GetLastWin32Error();
  886. if (!status && error != UnsafeNativeMethods.ERROR_EVT_UNRESOLVED_VALUE_INSERT)
  887. {
  888. switch (error)
  889. {
  890. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND:
  891. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND:
  892. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
  893. case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND:
  894. case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND:
  895. return null;
  896. }
  897. EventLogException.Throw(error);
  898. }
  899. return sb.ToString();
  900. }
  901. //The EvtFormatMessage used for the obtaining of the Keywords names.
  902. [System.Security.SecuritySafeCritical]
  903. public static IEnumerable<string> EvtFormatMessageRenderKeywords(EventLogHandle pmHandle, EventLogHandle eventHandle, UnsafeNativeMethods.EvtFormatMessageFlags flag)
  904. {
  905. IntPtr buffer = IntPtr.Zero;
  906. int bufferNeeded;
  907. try
  908. {
  909. List<string> keywordsList = new List<string>();
  910. bool status = UnsafeNativeMethods.EvtFormatMessageBuffer(pmHandle, eventHandle, 0, 0, IntPtr.Zero, flag, 0, IntPtr.Zero, out bufferNeeded);
  911. int error = Marshal.GetLastWin32Error();
  912. if (!status)
  913. {
  914. switch (error)
  915. {
  916. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND:
  917. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND:
  918. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
  919. case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND:
  920. case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND:
  921. return keywordsList.AsReadOnly();
  922. }
  923. if (error != UnsafeNativeMethods.ERROR_INSUFFICIENT_BUFFER)
  924. EventLogException.Throw(error);
  925. }
  926. buffer = Marshal.AllocHGlobal(bufferNeeded * 2);
  927. status = UnsafeNativeMethods.EvtFormatMessageBuffer(pmHandle, eventHandle, 0, 0, IntPtr.Zero, flag, bufferNeeded, buffer, out bufferNeeded);
  928. error = Marshal.GetLastWin32Error();
  929. if (!status)
  930. {
  931. switch (error)
  932. {
  933. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_NOT_FOUND:
  934. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_ID_NOT_FOUND:
  935. case UnsafeNativeMethods.ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
  936. case UnsafeNativeMethods.ERROR_RESOURCE_LANG_NOT_FOUND:
  937. case UnsafeNativeMethods.ERROR_MUI_FILE_NOT_FOUND:
  938. return keywordsList;
  939. }
  940. EventLogException.Throw(error);
  941. }
  942. IntPtr pointer = buffer;
  943. while (true)
  944. {
  945. string s = Marshal.PtrToStringUni(pointer);
  946. if (String.IsNullOrEmpty(s))
  947. break;
  948. keywordsList.Add(s);
  949. //nr of bytes = # chars * 2 + 2 bytes for character '\0'.
  950. pointer = new IntPtr((Int64)pointer + (s.Length * 2) + 2);
  951. }
  952. return ke