From 5ee2b906b751f655497d982029a1088ea4acd212 Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 4 Jun 2019 12:16:41 -0600 Subject: [PATCH] Completed work on AdvApi32 --- PInvoke/Security/AdvApi32/AppMgmt.cs | 556 +++ PInvoke/Security/AdvApi32/EvntProv.cs | 970 +++++ PInvoke/Security/AdvApi32/Evntrace.cs | 4458 ++++++++++++++++++++ PInvoke/Security/AdvApi32/ProcessThreadsApi.cs | 315 ++ PInvoke/Security/AdvApi32/WinBase.cs | 2485 ++++++++++- PInvoke/Security/AdvApi32/WinCrypt.cs | 4 +- PInvoke/Security/AdvApi32/WinSafer.cs | 1267 ++++++ PInvoke/Security/AdvApi32/WinSvc.cs | 47 + .../PInvoke/Security/AdvApi32/AppMgmtTests.cs | 38 + 9 files changed, 10023 insertions(+), 117 deletions(-) create mode 100644 PInvoke/Security/AdvApi32/AppMgmt.cs create mode 100644 PInvoke/Security/AdvApi32/EvntProv.cs create mode 100644 PInvoke/Security/AdvApi32/Evntrace.cs create mode 100644 PInvoke/Security/AdvApi32/WinSafer.cs create mode 100644 UnitTests/PInvoke/Security/AdvApi32/AppMgmtTests.cs diff --git a/PInvoke/Security/AdvApi32/AppMgmt.cs b/PInvoke/Security/AdvApi32/AppMgmt.cs new file mode 100644 index 00000000..ae93ed23 --- /dev/null +++ b/PInvoke/Security/AdvApi32/AppMgmt.cs @@ -0,0 +1,556 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using Vanara.Extensions; +using Vanara.InteropServices; + +namespace Vanara.PInvoke +{ + public static partial class AdvApi32 + { + /// + /// The INSTALLSPECTYPE enumeration values define the ways a group policy application can be specified to the + /// InstallApplication function. The values are used in the Type member of INSTALLDATA. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/ne-appmgmt-installspectype typedef enum _INSTALLSPECTYPE { APPNAME, + // FILEEXT, PROGID, COMCLASS } INSTALLSPECTYPE; + [PInvokeData("appmgmt.h", MSDNShortId = "9e62a22d-cae7-4b3e-9000-71eddb1f3cad")] + public enum INSTALLSPECTYPE + { + /// This constant equals 1. The application is specified by its display name and group policy GUID. + APPNAME = 1, + + /// The application is specified by its file name extension, for example, .jpg. + FILEEXT, + + /// + PROGID, + + /// + COMCLASS, + } + + /// + /// The GetLocalManagedApplications function can be run on the target computer to get a list of managed applications on that + /// computer. The function can also be called in the context of a user to get a list of managed applications for that user. This + /// function only returns applications that can be installed by the Windows Installer. + /// + /// + /// A value that, if TRUE, the prgLocalApps parameter contains a list of managed applications that applies to the user. If the + /// value of this parameter is FALSE, the prgLocalApps parameter contains a list of managed applications that applies to the + /// local computer. + /// + /// The address of a DWORD that specifies the number of applications in the list returned by prgLocalApps. + /// + /// The address of an array that contains the list of managed applications. You must call LocalFree to free this array when + /// its contents are no longer required. This parameter cannot be null. The list is returned as a LOCALMANAGEDAPPLICATION structure. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. Otherwise, the function returns one of the system error + /// codes. For a complete list of error codes, see System Error Codes or the header file WinError.h. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/nf-appmgmt-getlocalmanagedapplications DWORD + // GetLocalManagedApplications( BOOL bUserApps, LPDWORD pdwApps, PLOCALMANAGEDAPPLICATION *prgLocalApps ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("appmgmt.h", MSDNShortId = "4606ff09-7e23-4953-aeef-cac822995d35")] + public static extern Win32Error GetLocalManagedApplications([MarshalAs(UnmanagedType.Bool)] bool bUserApps, out uint pdwApps, out SafeLocalHandle prgLocalApps); + + /// + /// The GetLocalManagedApplications function can be run on the target computer to get a list of managed applications on that + /// computer. The function can also be called in the context of a user to get a list of managed applications for that user. This + /// function only returns applications that can be installed by the Windows Installer. + /// + /// + /// A value that, if TRUE, the prgLocalApps parameter contains a list of managed applications that applies to the user. If the + /// value of this parameter is FALSE, the prgLocalApps parameter contains a list of managed applications that applies to the + /// local computer. + /// + /// The list of managed applications. + [PInvokeData("appmgmt.h", MSDNShortId = "4606ff09-7e23-4953-aeef-cac822995d35")] + public static IEnumerable GetLocalManagedApplications(bool bUserApps) + { + GetLocalManagedApplications(bUserApps, out var c, out var p).ThrowIfFailed(); + return p.ToArray((int)c); + } + + /// + /// The GetManagedApplicationCategories function gets a list of application categories for a domain. The list is the same for + /// all users in the domain. + /// + /// This parameter is reserved. Its value must be 0. + /// + /// A APPCATEGORYINFOLIST structure that contains a list of application categories. This structure must be freed by calling LocalFree + /// when the list is no longer required. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. Otherwise, the function returns one of the system error + /// codes. For a complete list of error codes, see System Error Codes or the header file WinError.h. + /// + /// + /// The structure returned by GetManagedApplicationCategories must be freed by calling LocalFree when the list is no longer required. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/nf-appmgmt-getmanagedapplicationcategories DWORD + // GetManagedApplicationCategories( DWORD dwReserved, APPCATEGORYINFOLIST *pAppCategory ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("appmgmt.h", MSDNShortId = "10824852-7810-483a-91b3-2d9cc3d21934")] + public static extern Win32Error GetManagedApplicationCategories([Optional] uint dwReserved, IntPtr pAppCategory); + + /// + /// The GetManagedApplicationCategories function gets a list of application categories for a domain. The list is the same for + /// all users in the domain. + /// + /// A list of application categories. + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/nf-appmgmt-getmanagedapplicationcategories DWORD + // GetManagedApplicationCategories( DWORD dwReserved, APPCATEGORYINFOLIST *pAppCategory ); + [PInvokeData("appmgmt.h", MSDNShortId = "10824852-7810-483a-91b3-2d9cc3d21934")] + public static IEnumerable GetManagedApplicationCategories() + { + var h = IntPtr.Zero; + try + { + GetManagedApplicationCategories(0, h).ThrowIfFailed(); + var l = h.ToStructure(); + return l.pCategoryInfo.ToArray((int)l.cCategory) ?? new APPCATEGORYINFO[0]; + } + finally + { + Kernel32.LocalFree(h); + } + } + + /// + /// The GetManagedApplications function gets a list of applications that are displayed in the Add pane of Add/Remove + /// Programs (ARP) for a specified user context. + /// + /// + /// A pointer to a GUID that specifies the category + /// + /// of applications to be listed. If pCategory is not null, dwQueryFlags must contain MANAGED_APPS_FROMCATEGORY. If pCategory + /// is null, dwQueryFlags cannot contain MANAGED_APPS_FROMCATEGORY. + /// + /// + /// + /// This parameter can contain one or more of the following values. + /// MANAGED_APPS_USERAPPLICATIONS + /// Lists all applications that apply to the user. The parameter pCategory must be null. + /// MANAGED_APPS_FROMCATEGORY + /// Lists only applications in the category specified by pCategory. The pCategory parameter cannot be null. + /// + /// This parameter must be MANAGED_APPS_INFOLEVEL_DEFAULT. + /// The count of applications in the list returned by this function. + /// + /// This parameter is a pointer to an array of MANAGEDAPPLICATION structures. This array contains the list of applications listed in + /// the Add pane of Add/Remove Programs (ARP). You must call LocalFree to free the array when they array is no + /// longer required. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. Otherwise, the function returns one of the system error + /// codes. For a complete list of error codes, see System Error Codes or the header file WinError.h. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/nf-appmgmt-getmanagedapplications DWORD GetManagedApplications( GUID + // *pCategory, DWORD dwQueryFlags, DWORD dwInfoLevel, LPDWORD pdwApps, PMANAGEDAPPLICATION *prgManagedApps ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("appmgmt.h", MSDNShortId = "62e32f36-cbb2-4557-9773-8bd454870d55")] + public static extern Win32Error GetManagedApplications(IntPtr pCategory, uint dwQueryFlags, uint dwInfoLevel, out uint pdwApps, out SafeLocalHandle prgManagedApps); + + /// + /// The GetManagedApplications function gets a list of applications that are displayed in the Add pane of Add/Remove + /// Programs (ARP) for a specified user context. + /// + /// + /// A pointer to a GUID that specifies the category + /// + /// of applications to be listed. If pCategory is not null, dwQueryFlags must contain MANAGED_APPS_FROMCATEGORY. If pCategory + /// is null, dwQueryFlags cannot contain MANAGED_APPS_FROMCATEGORY. + /// + /// + /// + /// This parameter can contain one or more of the following values. + /// MANAGED_APPS_USERAPPLICATIONS + /// Lists all applications that apply to the user. The parameter pCategory must be null. + /// MANAGED_APPS_FROMCATEGORY + /// Lists only applications in the category specified by pCategory. The pCategory parameter cannot be null. + /// + /// This parameter must be MANAGED_APPS_INFOLEVEL_DEFAULT. + /// The count of applications in the list returned by this function. + /// + /// This parameter is a pointer to an array of MANAGEDAPPLICATION structures. This array contains the list of applications listed in + /// the Add pane of Add/Remove Programs (ARP). You must call LocalFree to free the array when they array is no + /// longer required. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. Otherwise, the function returns one of the system error + /// codes. For a complete list of error codes, see System Error Codes or the header file WinError.h. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/nf-appmgmt-getmanagedapplications DWORD GetManagedApplications( GUID + // *pCategory, DWORD dwQueryFlags, DWORD dwInfoLevel, LPDWORD pdwApps, PMANAGEDAPPLICATION *prgManagedApps ); + [PInvokeData("appmgmt.h", MSDNShortId = "62e32f36-cbb2-4557-9773-8bd454870d55")] + public static IEnumerable GetManagedApplications(Guid? pCategory) + { + var pGuid = pCategory.HasValue ? SafeLocalHandle.CreateFromStructure(pCategory.Value) : SafeLocalHandle.Null; + GetManagedApplications((IntPtr)pGuid, pCategory.HasValue ? 2U : 1U, 0x10000, out var c, out var h).ThrowIfFailed(); + return h.ToArray((int)c); + } + + /// + /// The InstallApplication function can install applications that have been deployed to target users that belong to a domain. + /// The security context of the user that is calling InstallApplication must be that of a domain user logged onto a computer + /// in a domain that trusts the target user's domain. Group Policy must be successfully applied when the target user logs on. + /// + /// A pointer to a INSTALLDATA structure that specifies the application to install. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. Otherwise, the function returns one of the system error + /// codes. For a complete list of error codes, see System Error Codes or the header file WinError.h. + /// + /// + /// + /// The InstallApplication function can only install applications that have been deployed by using Group Policy. A domain + /// administrator can deploy applications to target users by using the user configuration section of Group Policy Objects (GPO). The + /// target user must belong to the target domain and the GPO must apply to this user in the target domain. The + /// InstallApplication function installs applications according to standard Group Policy inheritance rules. If the same + /// application is deployed in multiple GPOs, the function installs the version of the application deployed in the highest precedence + /// GPO. After an application has been installed for a user, it is not visible to other users on the computer. This is standard for + /// applications that are deployed through user group policy. + /// + /// + /// The InstallApplication function can install deployed applications that use Windows Installer (.msi files) or software + /// installation settings (.zap files) to handle setup and installation. + /// + /// + /// The InstallApplication function can install applications that use a Windows Installer package for their installation. In + /// this case, the user calling InstallApplication is not required to have administrator privileges. The system can install + /// the application because the Windows Installer is a trusted application deployed by a domain administrator. The user that receives + /// the application must have access to the location of the .msi files. + /// + /// + /// Remove applications installed using .msi files by calling the Windows Installer function MsiConfigureProduct to uninstall the + /// application. Then call UninstallApplication to inform the system that the application is no longer managed on the client by Group + /// Policy. UninstallApplication should be called even if the uninstall fails because this enables the system to keep the + /// Resultant Set of Policy (RSoP) accurate. + /// + /// + /// The InstallApplication function can also install applications that use setup applications based on software installation + /// settings (.zap files). The user that receives the application must have access to the location of the .zap files. A .zap file is + /// a text file similar to an .ini file, which enables Windows to publish an application (for example, Setup.exe) for installation + /// with Add or Remove Programs. To publish applications that do not use the Windows Installer, you must create a .zap file, + /// copy the .zap file to the software distribution point servers, and then use Group Policy–based software deployment to publish the + /// application for users. If the application is deployed using .zap files, the user installing the application must have privileges + /// on the machine to install the software. You cannot use .zap files for assigned applications. + /// + /// + /// Remove applications using software installation settings (.zap files) by calling the uninstall function or a command specific for + /// the installation application. + /// + /// + /// For information about using installation applications other than the Windows Installer see article 231747, "How to Publish + /// non-MSI Programs with .zap Files," in the Microsoft Knowledge Base. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/nf-appmgmt-installapplication DWORD InstallApplication( PINSTALLDATA + // pInstallInfo ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("appmgmt.h", MSDNShortId = "5b2e1d82-a421-42af-9e1b-391ae9d4813e")] + public static extern Win32Error InstallApplication(in INSTALLDATA pInstallInfo); + + /// + /// + /// The UninstallApplication function uninstalls a group policy application that handles setup and installation using Windows + /// Installer .msi files. The UninstallApplication function should only be called in the context of the user for whom the user + /// group policy application has previously attempted an uninstall by calling the MsiConfigureProduct function. The + /// InstallApplication function can install group policy applications. + /// + /// + /// Note Failure to call UninstallApplication as part of the protocol for uninstalling a group policy-based application + /// can cause the Resultant Set of Policy (RSoP) to indicate inaccurate information. + /// + /// + /// + /// The Windows Installer product code of the product being uninstalled. The product code of the application should be provided in + /// the form of a Windows Installer GUID as a string with braces. + /// + /// + /// The status of the uninstall attempt. The dwStatus parameter is the Windows success code of the uninstall attempt returned by + /// MsiConfigureProduct. The system can use this to ensure that the Resultant Set of Policy (RSoP) indicates whether the uninstall + /// failed or succeeded. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. Otherwise, the function returns one of the system error + /// codes. For a complete list of error codes, see System Error Codes or the header file WinError.h. + /// + /// + /// + /// Remove a group policy application that uses .msi files by calling the Windows Installer function MsiConfigureProduct to uninstall + /// the application. Then call UninstallApplication to inform the system that the application is no longer managed on the + /// client by Group Policy. UninstallApplication should be called even if the uninstall fails because this enables the system + /// to keep the Resultant Set of Policy (RSoP) accurate. + /// + /// + /// Remove applications installed using software installation settings (.zap files) by calling the uninstall function or command + /// specific for the installation application. For information about using installation applications other than the Windows Installer + /// see article 231747, "How to Publish non-MSI Programs with .zap Files," in the Microsoft Knowledge Base. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/nf-appmgmt-uninstallapplication DWORD UninstallApplication( LPWSTR + // ProductCode, DWORD dwStatus ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("appmgmt.h", MSDNShortId = "d45494e2-d86e-4d94-a158-4024eacf46a2")] + public static extern Win32Error UninstallApplication([MarshalAs(UnmanagedType.LPWStr)] string ProductCode, Win32Error dwStatus); + + /// + /// Provides application category information to Add/Remove Programs in Control Panel. The APPCATEGORYINFOLIST structure is used + /// create a complete list of categories for an application publisher. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/ns-appmgmt-appcategoryinfo typedef struct _APPCATEGORYINFO { LCID + // Locale; LPWSTR pszDescription; GUID AppCategoryId; } APPCATEGORYINFO; + [PInvokeData("appmgmt.h", MSDNShortId = "7a0e61cb-97f8-4ca2-a85a-889e671099d0")] + [StructLayout(LayoutKind.Sequential)] + public struct APPCATEGORYINFO + { + /// + /// Type: LCID + /// Unused. + /// + public LCID Locale; + + /// + /// Type: LPWSTR + /// + /// A pointer to a string containing the display name of the category. This string displays in the Category list in + /// Add/Remove Programs. This string buffer must be allocated using CoTaskMemAlloc and freed using CoTaskMemFree. + /// + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string pszDescription; + + /// + /// Type: GUID + /// A GUID identifying the application category. + /// + public Guid AppCategoryId; + } + + /// + /// Provides a list of supported application categories from an application publisher to Add/Remove Programs in Control Panel. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/ns-appmgmt-appcategoryinfolist typedef struct _APPCATEGORYINFOLIST { + // DWORD cCategory; APPCATEGORYINFO *pCategoryInfo; } APPCATEGORYINFOLIST; + [PInvokeData("appmgmt.h", MSDNShortId = "c590d9ab-ab41-4192-a6c2-c6c2c931e873")] + [StructLayout(LayoutKind.Sequential)] + public struct APPCATEGORYINFOLIST + { + /// + /// Type: DWORD + /// A value of type DWORD that specifies the count of APPCATEGORYINFO elements in the array pointed to by pCategoryInfo. + /// + public uint cCategory; + + /// + /// Type: APPCATEGORYINFO* + /// + /// A pointer to an array of APPCATEGORYINFO structures. This array contains all the categories an application publisher supports + /// and must be allocated using CoTaskMemAlloc and freed using CoTaskMemFree. + /// + /// + public IntPtr pCategoryInfo; + } + + /// The INSTALLDATA structure specifies a group-policy application to be installed by InstallApplication. + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/ns-appmgmt-_installdata typedef struct _INSTALLDATA { INSTALLSPECTYPE + // Type; INSTALLSPEC Spec; } INSTALLDATA, *PINSTALLDATA; + [PInvokeData("appmgmt.h", MSDNShortId = "0c0570c6-f8f5-41e1-a1d2-d4e8c450f73c")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct INSTALLDATA + { + /// + /// Defines how Spec specifies the application to InstallApplication. Type can be one of the INSTALLSPECTYPE + /// enumeration values. Set Type to APPNAME to install an application specified by its user-friendly name and GPO GUID. + /// Set Type to FILEEXT to install an application specified by its file name extension. + /// + public INSTALLSPECTYPE Type; + + /// An INSTALLSPEC structure that specifies the application. + public INSTALLSPEC Spec; + } + + /// + /// The INSTALLSPEC structure specifies a group policy application by its user-friendly name and group policy GUID or by its + /// file name extension. The Spec member of the INSTALLDATA structure provides this information to the InstallApplication function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/ns-appmgmt-_installspec typedef union _INSTALLSPEC { struct { WCHAR + // *Name; GUID GPOId; } AppName; WCHAR *FileExt; WCHAR *ProgId; struct { GUID Clsid; DWORD ClsCtx; } COMClass; } INSTALLSPEC; + [PInvokeData("appmgmt.h", MSDNShortId = "e9c1b943-9cb0-480f-8ab7-0f439087216a")] + [StructLayout(LayoutKind.Explicit)] + public struct INSTALLSPEC + { + /// Structure that contains the following members. + [FieldOffset(0)] + public APPNAME AppName; + + /// + /// The file name extension, such as .jpg, of the application to be installed. + /// + /// Note InstallApplication fails if the Type member of INSTALLDATA equals FILEEXT and there is no + /// application deployed to the user with this file name extension. + /// + /// + [FieldOffset(0), MarshalAs(UnmanagedType.LPWStr)] + public string FileExt; + + /// + [FieldOffset(0), MarshalAs(UnmanagedType.LPWStr)] + public string ProgId; + + /// + [FieldOffset(0)] + public COMCLASS COMClass; + + /// Structure that contains the following members. + [StructLayout(LayoutKind.Sequential)] + public struct APPNAME + { + /// + /// The user-friendly name of the application as it appears in Add or Remove Programs and the Group Policy Object + /// Editor. You can obtain the name by calling GetManagedApplications. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string Name; + + /// + /// The GUID for the group policy object in which the application exists. You can obtain the group policy object + /// GUID by calling GetManagedApplications. + /// + public Guid GPOId; + } + + /// Structure that contains the following members. + [StructLayout(LayoutKind.Sequential)] + public struct COMCLASS + { + /// + public Guid Clsid; + + /// + public uint ClsCtx; + } + } + + /// + /// The LOCALMANAGEDAPPLICATION structure describes a managed application installed for a user or a computer. Returned by the + /// GetLocalManagedApplications function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/ns-appmgmt-_localmanagedapplication typedef struct + // _LOCALMANAGEDAPPLICATION { LPWSTR pszDeploymentName; LPWSTR pszPolicyName; LPWSTR pszProductId; DWORD dwState; } + // LOCALMANAGEDAPPLICATION, *PLOCALMANAGEDAPPLICATION; + [PInvokeData("appmgmt.h", MSDNShortId = "b2b7d209-76ee-4ba4-ac61-034d2c8e0689")] + [StructLayout(LayoutKind.Sequential)] + public struct LOCALMANAGEDAPPLICATION + { + /// + /// This is a Unicode string that gives the user friendly name of the application as it appears in the Application Deployment + /// Editor (ADE). + /// + [MarshalAs(UnmanagedType.LPWStr)] public string pszDeploymentName; + + /// This is the user-friendly name of the group policy object (GPO) from which the application originates. + [MarshalAs(UnmanagedType.LPWStr)] public string pszPolicyName; + + /// This is a Unicode string that gives the Windows Installer product code GUID for the application. + [MarshalAs(UnmanagedType.LPWStr)] public string pszProductId; + + /// + /// Indicates the state of the installed application. This parameter can contain one or more of the following values. + /// LOCAL_STATE_ASSIGNED + /// The application is installed in the assigned state. + /// LOCAL_STATE_PUBLISHED + /// The application is installed in the published state. + /// LOCAL_STATE_UNINSTALL_UNMANAGED + /// The installation of this application uninstalled an unmanaged application with a conflicting transform. + /// LOCAL_STATE_POLICYREMOVE_ORPHAN + /// If the policy from which this application originates is removed, the application is left on the computer. + /// LOCAL_STATE_POLICYREMOVE_UNINSTALL + /// If the policy from which this application originates is removed, the application is uninstalled from the computer. + /// + public uint dwState; + } + + /// + /// The MANAGEDAPPLICATION structure contains information about an application. The function GetManagedApplications returns an + /// array of MANAGEDAPPLICATION structures. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/appmgmt/ns-appmgmt-managedapplication typedef struct _MANAGEDAPPLICATION { + // LPWSTR pszPackageName; LPWSTR pszPublisher; DWORD dwVersionHi; DWORD dwVersionLo; DWORD dwRevision; GUID GpoId; LPWSTR + // pszPolicyName; GUID ProductId; LANGID Language; LPWSTR pszOwner; LPWSTR pszCompany; LPWSTR pszComments; LPWSTR pszContact; LPWSTR + // pszSupportUrl; DWORD dwPathType; BOOL bInstalled; } MANAGEDAPPLICATION, *PMANAGEDAPPLICATION; + [PInvokeData("appmgmt.h", MSDNShortId = "8ac78f92-e665-4dd0-b226-6bf41dcd050a")] + [StructLayout(LayoutKind.Sequential)] + public struct MANAGEDAPPLICATION + { + /// The user-friendly name of the application. + [MarshalAs(UnmanagedType.LPWStr)] + public string pszPackageName; + + /// The name of the application's publisher. + [MarshalAs(UnmanagedType.LPWStr)] + public string pszPublisher; + + /// The major version number of the application. + public uint dwVersionHi; + + /// The minor version number of the application. + public uint dwVersionLo; + + /// The version number of the deployment. The version changes each time an application gets patched. + public uint dwRevision; + + /// The GUID of the GPO from which this application is deployed. + public Guid GpoId; + + /// The user-friendly name for the GPO from which this application is deployed. + [MarshalAs(UnmanagedType.LPWStr)] + public string pszPolicyName; + + /// If this application is installed by Windows Installer, this member is the ProductId GUID. + public Guid ProductId; + + /// + /// The numeric language identifier that indicates the language version of the application. For a list of language numeric + /// identifiers, see the Language Identifier Constants and Strings topic. + /// + public ushort Language; + + /// This member is unused. + public StrPtrUni pszOwner; + + /// This member is unused. + [MarshalAs(UnmanagedType.LPWStr)] + public StrPtrUni pszCompany; + + /// This member is unused. + [MarshalAs(UnmanagedType.LPWStr)] + public StrPtrUni pszComments; + + /// This member is unused. + [MarshalAs(UnmanagedType.LPWStr)] + public StrPtrUni pszContact; + + /// This member is unused. + [MarshalAs(UnmanagedType.LPWStr)] + public StrPtrUni pszSupportUrl; + + /// + /// Indicates the type of package used to install the application. This member can have one of the following values. + /// MANAGED_APPTYPE_WINDOWSINSTALLER + /// The application is installed using the Windows Installer. + /// MANAGED_APPTYPE_SETUPEXE + /// The application is installed using a legacy setup application. + /// MANAGED_APPTYPE_UNSUPPORTED + /// The application is installed by an unsupported setup application. + /// + public uint dwPathType; + + /// This parameter is TRUE if the application is currently installed and is FALSE otherwise. + [MarshalAs(UnmanagedType.Bool)] + public bool bInstalled; + } + } +} \ No newline at end of file diff --git a/PInvoke/Security/AdvApi32/EvntProv.cs b/PInvoke/Security/AdvApi32/EvntProv.cs new file mode 100644 index 00000000..bf99b774 --- /dev/null +++ b/PInvoke/Security/AdvApi32/EvntProv.cs @@ -0,0 +1,970 @@ +using System; +using System.Runtime.InteropServices; + +namespace Vanara.PInvoke +{ + public static partial class AdvApi32 + { + /// + /// Providers implement this function to receive enable or disable notification requests. + /// + /// The PENABLECALLBACK type defines a pointer to this callback function. EnableCallback is a placeholder for the + /// application-defined function name. + /// + /// + /// + /// GUID that identifies the session that enabled the provider. The value is GUID_NULL if EnableTraceEx did not specify a source identifier. + /// + /// + /// + /// Indicates if the session is enabling or disabling the provider. A value of zero indicates that the session is disabling the + /// provider. A value of 1 indicates that the session is enabling the provider. Beginning with Windows 7, this value can be one of + /// the following values: + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// EVENT_CONTROL_CODE_DISABLE_PROVIDER 0 + /// The session is disabling the provider. + /// + /// + /// EVENT_CONTROL_CODE_ENABLE_PROVIDER 1 + /// The session is enabling the provider. + /// + /// + /// EVENT_CONTROL_CODE_CAPTURE_STATE 2 + /// + /// The session is requesting that the provider log its state information. The provider determines the state information that it logs. + /// + /// + /// + /// + /// If you receive a value (for example, EVENT_CONTROL_CODE_CAPTURE_STATE) that you do not support, ignore the value (do not fail). + /// + /// + /// + /// + /// Provider-defined value that specifies the verboseness of the events that the provider writes. The provider must write the event + /// if this value is less than or equal to the level value that the event defines. + /// + /// This value is passed in the Level parameter of the EnableTraceEx function or the EnableLevel parameter of EnableTrace. + /// + /// + /// Bitmask of keywords that the provider uses to determine the category of events that it writes. + /// This value is passed in the MatchAnyKeyword parameter of the EnableTraceEx function or the EnableFlag parameter of EnableTrace. + /// + /// + /// + /// + /// A list of filter data that one or more sessions passed to the provider. A session can specify only one filter but the list will + /// contain filters from all sessions that used filter data to enable the provider. + /// + /// The filter data is valid only within the callback, so providers should make a local copy of the data. + /// + /// Context of the callback defined when the provider called EventRegister to register itself. + /// This callback function does not return a value. + /// + /// + /// To specify that you want to receive notification when a session enables or disables your provider, set the EnableCallback + /// parameter when calling the EventRegister function. + /// + /// + /// Classic providers needed to specify and implement a callback because it used the information that was passed to the callback to + /// determine the types of events to log and the level of verboseness to use when logging the events. However, with manifest-based + /// providers, the callback is optional and is used for informational purposes; you do not need to specify or implement the callback + /// when registering the provider unless your provider supports filtering. Providers can now just write events and ETW will determine + /// if the event is logged to the session. If you want to verify that the event should be written before writing the event, you can + /// call either the EventEnabled or EventProviderEnabled function. + /// + /// + /// Each time a new session enables the provider or a current session updates the provider, ETW calls the provider's callback + /// function, if implemented. The level value that ETW passes to the callback is the highest level value specified amongst all the + /// sessions. For example, if session A enabled the provider for warning (3) events and then session B enabled the provider for + /// critical (1) events, the level value for the second callback is also 3, not 1. + /// + /// + /// The MatchAnyKeyword value that ETW passes to the callback is a composite value of all MatchAnyKeyword values specified for all + /// sessions that enabled the provider. The same is true for the MatchAllKeywords value. The SourceId and FilterData values are those + /// values passed to the EnableTraceEx call. + /// + /// + /// Your callback function must not call anything that may incur LoadLibrary (more specifically, anything that requires a loader lock). + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nc-evntprov-penablecallback PENABLECALLBACK Penablecallback; void + // Penablecallback( LPCGUID SourceId, ULONG IsEnabled, UCHAR Level, ULONGLONG MatchAnyKeyword, ULONGLONG MatchAllKeyword, + // PEVENT_FILTER_DESCRIPTOR FilterData, PVOID CallbackContext ) {...} + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + [PInvokeData("evntprov.h", MSDNShortId = "f339323e-9da9-495f-aac5-f44969a018eb")] + public delegate void EnableCallback(in Guid SourceId, [MarshalAs(UnmanagedType.Bool)] bool IsEnabled, byte Level, ulong MatchAnyKeyword, ulong MatchAllKeyword, IntPtr FilterData, IntPtr CallbackContext); + + /// A control code that specifies if you want to create, query or set the current activity identifier. + [PInvokeData("evntprov.h", MSDNShortId = "1c412909-bdff-4181-9750-f3444fda4c8f")] + public enum EVENT_ACTIVITY_CTRL + { + /// Sets the ActivityId parameter to the current identifier value from thread local storage. + EVENT_ACTIVITY_CTRL_GET_ID = 1, + + /// + /// Uses the identifier in the ActivityId parameter to set the value of the current identifier in the thread local storage. + /// + EVENT_ACTIVITY_CTRL_SET_ID = 2, + + /// Creates a new identifier and sets the ActivityId parameter to the value of the new identifier. + EVENT_ACTIVITY_CTRL_CREATE_ID = 3, + + /// + /// Performs the following: + /// + /// + /// Copies the current identifier from thread local storage. + /// + /// + /// Sets the current identifier in thread local storage to the new identifier specified in the ActivityId parameter. + /// + /// + /// Sets the ActivityId parameter to the copy of the previous current identifier. + /// + /// + /// + EVENT_ACTIVITY_CTRL_GET_SET_ID = 4, + + /// + /// Performs the following: + /// + /// + /// Copies the current identifier from thread local storage. + /// + /// + /// Creates a new identifier and sets the current identifier in thread local storage to the new identifier. + /// + /// + /// Sets the ActivityId parameter to the copy of the previous current identifier. + /// + /// + /// + EVENT_ACTIVITY_CTRL_CREATE_SET_ID = 5, + } + + /// The EVENT_INFO_CLASS enumerated type defines a type of operation to perform on a registration object. + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/ne-evntprov-_event_info_class typedef enum _EVENT_INFO_CLASS { + // EventProviderBinaryTrackInfo, EventProviderSetReserved1, EventProviderSetTraits, EventProviderUseDescriptorType, MaxEventInfo } EVENT_INFO_CLASS; + [PInvokeData("evntprov.h", MSDNShortId = "76ac2b93-d5df-4504-b36d-1530bbb12ab4")] + public enum EVENT_INFO_CLASS + { + /// Tracks the full path for the binary (DLL or EXE) from which the ETW registration was made. + EventProviderBinaryTrackInfo, + + /// + EventProviderSetReserved1, + + /// + /// Sets traits for the provider. Implicitly indicates that the provider correctly initializes the EVENT_DATA_DESCRIPTOR values + /// passed to EventWrite APIs, so the EVENT_DATA_DESCRIPTOR::Type field will be respected. For more information on the format of + /// the traits, see Provider Traits. + /// + EventProviderSetTraits, + + /// + /// Indicates whether the provider correctly initializes the EVENT_DATA_DESCRIPTOR values passed to EventWrite APIs, which in + /// turn indicates whether the EVENT_DATA_DESCRIPTOR::Type field will be respected by the EventWrite APIs. + /// + EventProviderUseDescriptorType, + + /// Maximum value for testing purposes. + MaxEventInfo, + } + + /// Creates, queries, and sets the current activity identifier used by the EventWriteTransfer function. + /// + /// A control code that specifies if you want to create, query or set the current activity identifier. You can specify one of the + /// following codes. + /// + /// + /// A GUID that uniquely identifies the activity. To determine when this parameter is an input parameter, an output parameter or + /// both, see the descriptions for the ControlCodes parameter. + /// + /// Returns ERROR_SUCCESS if successful. + /// + /// The EVENT_ACTIVITY_CTRL_GET_ID control code returns a GUID with all zeros (GUID_NULL) if the identifier has not been set. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventactivityidcontrol ULONG EVNTAPI + // EventActivityIdControl( ULONG ControlCode, LPGUID ActivityId ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "1c412909-bdff-4181-9750-f3444fda4c8f")] + public static extern Win32Error EventActivityIdControl(EVENT_ACTIVITY_CTRL ControlCode, in Guid ActivityId); + + /// Determines if the event is enabled for any session. + /// + /// Registration handle of the provider. The handle comes from EventRegister. + /// Note A valid registration handle must be used. + /// + /// Describes the event. For details, see EVENT_DESCRIPTOR. + /// Returns TRUE if the event is enabled for a session; otherwise, FALSE. + /// + /// + /// Typically, providers do not call this function to determine if a session is expecting this event, they simply write the event and + /// ETW determines if the event is logged to the session. + /// + /// + /// Providers may want to call this function if they need to perform extra work to generate the event. Calling this function first to + /// determine if a session is expecting this event or not, may save resources and time. + /// + /// + /// The provider would call this function if the provider generated an EVENT_DESCRIPTOR structure for the event from the manifest. If + /// the event descriptor is not available, call the EventProviderEnabled function. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventenabled BOOLEAN EVNTAPI EventEnabled( REGHANDLE + // RegHandle, PCEVENT_DESCRIPTOR EventDescriptor ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "b332b6d4-6921-40bd-bebc-6646b5b9bcde")] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool EventEnabled(REGHANDLE RegHandle, in EVENT_DESCRIPTOR EventDescriptor); + + /// Determines if the event is enabled for any session. + /// Registration handle of the provider. The handle comes from EventRegister. + /// + /// Level of detail included in the event. Specify one of the following levels that are defined in Winmeta.h. Higher numbers imply + /// that you get lower levels as well. For example, if you specify TRACE_LEVEL_WARNING, you also receive all warning, error, and + /// fatal events. + /// + /// + /// Bitmask that specifies the event category. This mask should be the same keyword mask that you defined in the manifest for the event. + /// + /// Returns TRUE if the event is enabled for a session; otherwise, returns FALSE. + /// + /// + /// Typically, providers do not call this function to determine if a session is expecting this event; they simply write the event and + /// ETW determines if the event is logged to the session. + /// + /// + /// Providers may want to call this function if they need to perform extra work to generate the event. In this case, calling this + /// function first (to determine if a session is expecting this event or not) may save resources and time. + /// + /// + /// The provider would call this function if the provider did not generate an EVENT_DESCRIPTOR structure for the event from the + /// manifest. If the event descriptor is available, call the EventEnabled function. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventproviderenabled BOOLEAN EVNTAPI + // EventProviderEnabled( REGHANDLE RegHandle, UCHAR Level, ULONGLONG Keyword ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "84c035b1-cdc7-47b7-b887-e5b508f17266")] + [return: MarshalAs(UnmanagedType.U1)] + public static extern bool EventProviderEnabled(REGHANDLE RegHandle, byte Level, ulong Keyword); + + /// Registers the provider. + /// GUID that uniquely identifies the provider. + /// + /// Callback that ETW calls to notify you when a session enables or disables your provider. Can be NULL. + /// + /// + /// Provider-defined context data to pass to the callback when the provider is enabled or disabled. Can be NULL. + /// + /// + /// Registration handle. The handle is used by most provider function calls. Before your provider exits, you must pass this handle to + /// EventUnregister to free the handle. + /// + /// Returns ERROR_SUCCESS if successful. + /// + /// Use this function to register your provider if you call EventWrite to write your events. + /// + /// A process can register up to 1,024 provider GUIDs; however, you should limit the number of providers that your process registers + /// to one or two. This limit includes those registered using this function and the RegisterTraceGuids function. + /// + /// Prior to Windows Vista: There is no limit to the number of providers that a process can register. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventregister ULONG EVNTAPI EventRegister( LPCGUID + // ProviderId, PENABLECALLBACK EnableCallback, PVOID CallbackContext, PREGHANDLE RegHandle ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "6025c3a6-7d88-49dc-bbc3-655c172dde3c")] + public static extern Win32Error EventRegister(in Guid ProviderId, EnableCallback EnableCallback, IntPtr CallbackContext, out SafeREGHANDLE RegHandle); + + /// Performs operations on a registration object. + /// + /// Type: REGHANDLE + /// Registration handle returned by EventRegister. + /// + /// + /// Type: EVENT_INFO_CLASS + /// Type of operation to be performed on the registration object. + /// + /// + /// Type: PVOID + /// The input buffer. + /// + /// + /// Type: ULONG + /// Size of the input buffer. + /// + /// + /// Type: ULONG + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is one of the following error codes. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// The parameter is incorrect. This error is returned if the RegHandle parameter is not a valid registration handle. + /// + /// + /// ERROR_NOT_SUPPORTED + /// The request is not supported. + /// + /// + /// Other + /// Use FormatMessage to obtain the message string for the returned error. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventsetinformation ULONG EVNTAPI EventSetInformation( + // REGHANDLE RegHandle, EVENT_INFO_CLASS InformationClass, PVOID EventInformation, ULONG InformationLength ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "e8b408ba-4bb5-4166-bf43-d18e4fe8de32")] + public static extern Win32Error EventSetInformation(REGHANDLE RegHandle, EVENT_INFO_CLASS InformationClass, IntPtr EventInformation, uint InformationLength); + + /// Removes the provider's registration. You must call this function before your process exits. + /// Registration handle returned by EventRegister. + /// Returns ERROR_SUCCESS if successful. + /// + /// For private sessions, you must stop the trace (call the ControlTrace function with the ControlCode parameter set to + /// EVENT_TRACE_CONTROL_STOP) before calling this function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventunregister ULONG EVNTAPI EventUnregister( REGHANDLE + // RegHandle ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "fdcccf6f-2f31-4356-a4ee-3b6229c01b75")] + public static extern Win32Error EventUnregister(REGHANDLE RegHandle); + + /// Use this function to write an event. + /// Registration handle of the provider. The handle comes from EventRegister. + /// Metadata that identifies the event to write. For details, see EVENT_DESCRIPTOR. + /// Number of EVENT_DATA_DESCRIPTOR structures in UserData. The maximum number is 128. + /// + /// The event data to write. Allocate a block of memory that contains one or more EVENT_DATA_DESCRIPTOR structures. Set this + /// parameter to NULL if UserDataCount is zero. The data must be in the order specified in the manifest. + /// + /// Returns ERROR_SUCCESS if successful or one of the following values on error. + /// + /// Event data written with this function requires a manifest to consume the data. + /// ETW decides based on the event descriptor if the event is written to a session (for details, see EnableTraceEx). + /// + /// If you call the EventActivityIdControl function to specify an activity identifier for the event, EventWrite retrieves the + /// identifier from thread local storage and includes it with the event. + /// + /// Examples + /// For an example that uses EventWrite, see Writing Manifest-based Events. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventwrite ULONG EVNTAPI EventWrite( REGHANDLE + // RegHandle, PCEVENT_DESCRIPTOR EventDescriptor, ULONG UserDataCount, PEVENT_DATA_DESCRIPTOR UserData ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "93070eb7-c167-4419-abff-e861877dad07")] + public static extern Win32Error EventWrite(REGHANDLE RegHandle, in EVENT_DESCRIPTOR EventDescriptor, uint UserDataCount, IntPtr UserData); + + /// Use this function to write an event. + /// Registration handle of the provider. The handle comes from EventRegister. + /// + /// A descriptor that contains the metadata that identifies the event to write. For details, see EVENT_DESCRIPTOR. + /// + /// + /// The instance identifiers that identify the session to which the event will not written. Use a bitwise OR to specify multiple + /// identifiers. Set to zero if you do not support filters or if the event is being written to all sessions (no filters failed). For + /// information on getting the identifier for a session, see the FilterData parameter of your EnableCallback callback. + /// + /// Reserved. Must be zero. + /// + /// GUID that uniquely identifies this activity. If NULL, ETW gets the identifier from the thread local storage. For details + /// on getting this identifier, see EventActivityIdControl. + /// + /// + /// Activity identifier from the previous component. Use this parameter to link your component's events to the previous component's + /// events. To get the activity identifier that was set for the previous component, see the descriptions for the ControlCode + /// parameter of the EventActivityIdControl function. + /// + /// Number of EVENT_DATA_DESCRIPTOR structures in UserData. The maximum number is 128. + /// + /// The event data to write. Allocate a block of memory that contains one or more EVENT_DATA_DESCRIPTOR structures. Set this + /// parameter to NULL if UserDataCount is zero. The data must be in the order specified in the manifest. + /// + /// Returns ERROR_SUCCESS if successful or one of the following values on error. + /// + /// + /// Event data written with this function requires a manifest. Since the manifest is embedded in the provider, the provider must be + /// available for a consumer to consume the data written by the provider. + /// + /// + /// Use the ActivityId and RelatedActivityId parameters when several components want to relate their events in an end-to-end tracing + /// scenario. For example, components A, B, and C perform work on a related activity and want to link their events so that a consumer + /// can consume all the events related to that activity. ETW uses thread local storage to make available to the next component the + /// previous component's activity identifier. The component retrieves from the local storage the previous component's identifier and + /// sets the related activity identifier to it. The consumer can then use the related activity identifier to walk the chain of the + /// events from one component to the next. + /// + /// If each component defined their own activity identifier, the components can make the following calls to link the events: + /// + /// + /// + /// Call the EventActivityIdControl function using the EVENT_ACTIVITY_CTRL_GET_SET_ID control code. The function uses your identifier + /// to set the activity identifier in the thread local storage and returns the activity identifier for the previous component, if set. + /// + /// + /// + /// + /// Set the RelatedActivityId parameter of this function to the ActivityId value that the EventActivityIdControl function returned. + /// Note that for the first component, the related identifier will be all zeros (GUID_NULL). + /// + /// + /// + /// Set the ActivityId of this function to NULL to use the activity identifier that you set in thread local storage. + /// + /// + /// + /// A provider can define filters that a session uses to filter events based on event data. With level and keywords, ETW determines + /// whether the event is written to the session but with filters, the provider uses the filter data to determine whether it writes + /// the event to the session. For example, if your provider generates process events, you could define a data filter that filters + /// process events based on the process identifier. If the identifier of the process did not match the identifier that the session + /// passed as filter data, you would set (perform a bitwise OR) the Filter parameter to the session's instance identifier to prevent + /// the event from being written to that session. + /// + /// Examples + /// For an example that uses EventWrite, see Writing Manifest-based Events. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventwriteex ULONG EVNTAPI EventWriteEx( REGHANDLE + // RegHandle, PCEVENT_DESCRIPTOR EventDescriptor, ULONG64 Filter, ULONG Flags, LPCGUID ActivityId, LPCGUID RelatedActivityId, ULONG + // UserDataCount, PEVENT_DATA_DESCRIPTOR UserData ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "00b907cb-45cd-48c7-bea4-4d8a39b4fa24")] + public static extern Win32Error EventWriteEx(REGHANDLE RegHandle, in EVENT_DESCRIPTOR EventDescriptor, ulong Filter, [Optional] uint Flags, in Guid ActivityId, in Guid RelatedActivityId, uint UserDataCount, IntPtr UserData); + + /// Use this function to write an event. + /// Registration handle of the provider. The handle comes from EventRegister. + /// + /// A descriptor that contains the metadata that identifies the event to write. For details, see EVENT_DESCRIPTOR. + /// + /// + /// The instance identifiers that identify the session to which the event will not written. Use a bitwise OR to specify multiple + /// identifiers. Set to zero if you do not support filters or if the event is being written to all sessions (no filters failed). For + /// information on getting the identifier for a session, see the FilterData parameter of your EnableCallback callback. + /// + /// Reserved. Must be zero. + /// + /// GUID that uniquely identifies this activity. If NULL, ETW gets the identifier from the thread local storage. For details + /// on getting this identifier, see EventActivityIdControl. + /// + /// + /// Activity identifier from the previous component. Use this parameter to link your component's events to the previous component's + /// events. To get the activity identifier that was set for the previous component, see the descriptions for the ControlCode + /// parameter of the EventActivityIdControl function. + /// + /// Number of EVENT_DATA_DESCRIPTOR structures in UserData. The maximum number is 128. + /// + /// The event data to write. Allocate a block of memory that contains one or more EVENT_DATA_DESCRIPTOR structures. Set this + /// parameter to NULL if UserDataCount is zero. The data must be in the order specified in the manifest. + /// + /// Returns ERROR_SUCCESS if successful or one of the following values on error. + /// + /// + /// Event data written with this function requires a manifest. Since the manifest is embedded in the provider, the provider must be + /// available for a consumer to consume the data written by the provider. + /// + /// + /// Use the ActivityId and RelatedActivityId parameters when several components want to relate their events in an end-to-end tracing + /// scenario. For example, components A, B, and C perform work on a related activity and want to link their events so that a consumer + /// can consume all the events related to that activity. ETW uses thread local storage to make available to the next component the + /// previous component's activity identifier. The component retrieves from the local storage the previous component's identifier and + /// sets the related activity identifier to it. The consumer can then use the related activity identifier to walk the chain of the + /// events from one component to the next. + /// + /// If each component defined their own activity identifier, the components can make the following calls to link the events: + /// + /// + /// + /// Call the EventActivityIdControl function using the EVENT_ACTIVITY_CTRL_GET_SET_ID control code. The function uses your identifier + /// to set the activity identifier in the thread local storage and returns the activity identifier for the previous component, if set. + /// + /// + /// + /// + /// Set the RelatedActivityId parameter of this function to the ActivityId value that the EventActivityIdControl function returned. + /// Note that for the first component, the related identifier will be all zeros (GUID_NULL). + /// + /// + /// + /// Set the ActivityId of this function to NULL to use the activity identifier that you set in thread local storage. + /// + /// + /// + /// A provider can define filters that a session uses to filter events based on event data. With level and keywords, ETW determines + /// whether the event is written to the session but with filters, the provider uses the filter data to determine whether it writes + /// the event to the session. For example, if your provider generates process events, you could define a data filter that filters + /// process events based on the process identifier. If the identifier of the process did not match the identifier that the session + /// passed as filter data, you would set (perform a bitwise OR) the Filter parameter to the session's instance identifier to prevent + /// the event from being written to that session. + /// + /// Examples + /// For an example that uses EventWrite, see Writing Manifest-based Events. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventwriteex ULONG EVNTAPI EventWriteEx( REGHANDLE + // RegHandle, PCEVENT_DESCRIPTOR EventDescriptor, ULONG64 Filter, ULONG Flags, LPCGUID ActivityId, LPCGUID RelatedActivityId, ULONG + // UserDataCount, PEVENT_DATA_DESCRIPTOR UserData ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "00b907cb-45cd-48c7-bea4-4d8a39b4fa24")] + public static extern Win32Error EventWriteEx(REGHANDLE RegHandle, in EVENT_DESCRIPTOR EventDescriptor, ulong Filter, [Optional] uint Flags, [Optional] IntPtr ActivityId, [Optional] IntPtr RelatedActivityId, uint UserDataCount, IntPtr UserData); + + /// Writes an event that contains a string as its data. + /// Registration handle of the provider. The handle comes from EventRegister. + /// + /// Level of detail included in the event. If the provider uses a manifest to define the event, set this value to the same level + /// defined in the manifest. If the event is not defined in a manifest, set this value to 0 to ensure the event is written, + /// otherwise, the event is written based on the level rule defined in EnableTraceEx. + /// + /// + /// Bitmask that specifies the event category. If the provider uses a manifest to define the event, set this value to the same + /// keyword mask defined in the manifest. If the event is not defined in a manifest, set this value to 0 to ensure the event is + /// written, otherwise, the event is written based on the keyword rules defined in EnableTraceEx. + /// + /// Null-terminated string to write as the event data. + /// Returns ERROR_SUCCESS if successful or one of the following values on error. + /// + /// + /// The provider does not need a manifest to use this function to write the event, unlike the EventWrite function which does require + /// a manifest. Consumers also do not need a manifest to consume events written with this function. + /// + /// This function gets the acitivity identifier from the thread local storage, if set. + /// ETW decides based on the level and keyword mask whether the event is written to a session (for details, see EnableTraceEx). + /// This function cannot be used to write events to the Admin or Operational channels. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventwritestring ULONG EVNTAPI EventWriteString( + // REGHANDLE RegHandle, UCHAR Level, ULONGLONG Keyword, PCWSTR String ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "ecdb0e92-fcc1-4b4f-99ea-6812b6b49381")] + public static extern Win32Error EventWriteString(REGHANDLE RegHandle, byte Level, ulong Keyword, [MarshalAs(UnmanagedType.LPWStr)] string String); + + /// Links events together when tracing events in an end-to-end scenario. + /// Registration handle of the provider. The handle comes from EventRegister. + /// Metadata that identifies the event to write. For details, see EVENT_DESCRIPTOR. + /// + /// GUID that uniquely identifies this activity. If NULL, ETW gets the identifier from the thread local storage. For details + /// on getting this identifier, see EventActivityIdControl. + /// + /// + /// Activity identifier from the previous component. Use this parameter to link your component's events to the previous component's + /// events. To get the activity identifier that was set for the previous component, see the descriptions for the ControlCode + /// parameter of the EventActivityIdControl function. + /// + /// Number of EVENT_DATA_DESCRIPTOR structures in UserData. The maximum number is 128. + /// + /// The event data to write. Allocate a block of memory that contains one or more EVENT_DATA_DESCRIPTOR structures. Set this + /// parameter to NULL if UserDataCount is zero. The data must be in the order specified in the manifest. + /// + /// Returns ERROR_SUCCESS if successful or one of the following values on error. + /// + /// Beginning with Windows 7 and Windows Server 2008 R2, use EventWriteEx to write transfer events in an end-to-end scenario. + /// + /// Use this function when several components want to relate their events in an end-to-end tracing scenario. For example, components + /// A, B, and C perform work on a related activity and want to link their events so that a consumer can consume all the events + /// related to that activity. ETW uses thread local storage to make available to the next component the previous component's activity + /// identifier. The component retrieves from the local storage the previous component's identifier and sets the related activity + /// identifier to it. The consumer can then use the related activity identifier to walk the chain of the events from one component to + /// the next. + /// + /// If each component defined their own activity identifier, the components can make the following calls to link the events: + /// + /// + /// + /// Call the EventActivityIdControl function using the EVENT_ACTIVITY_CTRL_GET_SET_ID control code. The function uses your identifier + /// to set the activity identifier in the thread local storage and returns the activity identifier for the previous component, if set. + /// + /// + /// + /// + /// Set the RelatedActivityId parameter of this function to the ActivityId value that the EventActivityIdControl function returned. + /// Note that for the first component, the related identifier will be all zeros (GUID_NULL). + /// + /// + /// + /// Set the ActivityId of this function to NULL to use the activity identifier that you set in thread local storage. + /// + /// + /// + /// Event data written with this function requires a manifest. Since the manifest is embedded in the provider, the provider must be + /// available for a consumer to consume the data written by the provider. + /// + /// ETW decides based on the event descriptor if the event is written to a session (for details, see EnableTraceEx). + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventwritetransfer ULONG EVNTAPI EventWriteTransfer( + // REGHANDLE RegHandle, PCEVENT_DESCRIPTOR EventDescriptor, LPCGUID ActivityId, LPCGUID RelatedActivityId, ULONG UserDataCount, + // PEVENT_DATA_DESCRIPTOR UserData ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "798cf3ba-e1cc-4eaf-a1d2-2313a64aab1a")] + public static extern Win32Error EventWriteTransfer(REGHANDLE RegHandle, in EVENT_DESCRIPTOR EventDescriptor, in Guid ActivityId, in Guid RelatedActivityId, uint UserDataCount, IntPtr UserData); + + /// Links events together when tracing events in an end-to-end scenario. + /// Registration handle of the provider. The handle comes from EventRegister. + /// Metadata that identifies the event to write. For details, see EVENT_DESCRIPTOR. + /// + /// GUID that uniquely identifies this activity. If NULL, ETW gets the identifier from the thread local storage. For details + /// on getting this identifier, see EventActivityIdControl. + /// + /// + /// Activity identifier from the previous component. Use this parameter to link your component's events to the previous component's + /// events. To get the activity identifier that was set for the previous component, see the descriptions for the ControlCode + /// parameter of the EventActivityIdControl function. + /// + /// Number of EVENT_DATA_DESCRIPTOR structures in UserData. The maximum number is 128. + /// + /// The event data to write. Allocate a block of memory that contains one or more EVENT_DATA_DESCRIPTOR structures. Set this + /// parameter to NULL if UserDataCount is zero. The data must be in the order specified in the manifest. + /// + /// Returns ERROR_SUCCESS if successful or one of the following values on error. + /// + /// Beginning with Windows 7 and Windows Server 2008 R2, use EventWriteEx to write transfer events in an end-to-end scenario. + /// + /// Use this function when several components want to relate their events in an end-to-end tracing scenario. For example, components + /// A, B, and C perform work on a related activity and want to link their events so that a consumer can consume all the events + /// related to that activity. ETW uses thread local storage to make available to the next component the previous component's activity + /// identifier. The component retrieves from the local storage the previous component's identifier and sets the related activity + /// identifier to it. The consumer can then use the related activity identifier to walk the chain of the events from one component to + /// the next. + /// + /// If each component defined their own activity identifier, the components can make the following calls to link the events: + /// + /// + /// + /// Call the EventActivityIdControl function using the EVENT_ACTIVITY_CTRL_GET_SET_ID control code. The function uses your identifier + /// to set the activity identifier in the thread local storage and returns the activity identifier for the previous component, if set. + /// + /// + /// + /// + /// Set the RelatedActivityId parameter of this function to the ActivityId value that the EventActivityIdControl function returned. + /// Note that for the first component, the related identifier will be all zeros (GUID_NULL). + /// + /// + /// + /// Set the ActivityId of this function to NULL to use the activity identifier that you set in thread local storage. + /// + /// + /// + /// Event data written with this function requires a manifest. Since the manifest is embedded in the provider, the provider must be + /// available for a consumer to consume the data written by the provider. + /// + /// ETW decides based on the event descriptor if the event is written to a session (for details, see EnableTraceEx). + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/nf-evntprov-eventwritetransfer ULONG EVNTAPI EventWriteTransfer( + // REGHANDLE RegHandle, PCEVENT_DESCRIPTOR EventDescriptor, LPCGUID ActivityId, LPCGUID RelatedActivityId, ULONG UserDataCount, + // PEVENT_DATA_DESCRIPTOR UserData ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntprov.h", MSDNShortId = "798cf3ba-e1cc-4eaf-a1d2-2313a64aab1a")] + public static extern Win32Error EventWriteTransfer(REGHANDLE RegHandle, in EVENT_DESCRIPTOR EventDescriptor, [Optional] IntPtr ActivityId, [Optional] IntPtr RelatedActivityId, uint UserDataCount, IntPtr UserData); + + /// + /// The EVENT_DATA_DESCRIPTOR structure is used with the user mode EventWrite and the kernel mode EtwWrite functions to send events. + /// The EVENT_DATA_DESCRIPTOR structure describes the event payload. + /// + /// + /// The most convenient method of populating the EVENT_DATA_DESCRIPTOR structure is to use the EventDataDescCreate macro. This + /// macro is declared in Evntprov.h and its use is documented in the Microsoft Windows SDK documentation. The following example uses + /// the EventDataDescCreate macro to populate an array of three EVENT_DATA_DESCRIPTOR structures. This array is then passed to + /// the EtwWrite function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/ns-evntprov-_event_data_descriptor typedef struct + // _EVENT_DATA_DESCRIPTOR { ULONGLONG Ptr; ULONG Size; union { ULONG Reserved; struct { UCHAR Type; UCHAR Reserved1; USHORT + // Reserved2; } DUMMYSTRUCTNAME; } DUMMYUNIONNAME; } EVENT_DATA_DESCRIPTOR, *PEVENT_DATA_DESCRIPTOR; + [PInvokeData("evntprov.h", MSDNShortId = "eb2b7ab6-52da-4d16-b315-6adab3131a05")] + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_DATA_DESCRIPTOR + { + /// A pointer to the event descriptor data. + public ulong Ptr; + + /// The size of the payload field, in bytes. + public uint Size; + + /// + public byte Type; + + /// + public byte Reserved1; + + /// + public ushort Reserved2; + + /// Initializes a new instance of the struct. + /// + /// A pointer to the event data used to set the Ptr member of EVENT_DATA_DESCRIPTOR. + /// If the event data's type is a NULL-terminated string, the DataPtr parameter must not be NULL. + /// + /// If the event data's type is a string whose size is described by some other field in the event, the DataPtr parameter may be NULL. + /// + /// + /// The size of the event data. The value is used to set the Size member of EVENT_DATA_DESCRIPTOR. + public EVENT_DATA_DESCRIPTOR(IntPtr DataPtr, uint DataSize) + { + Ptr = unchecked((ulong)DataPtr.ToInt64()); + Size = DataSize; + Reserved2 = Reserved1 = Type = 0; + } + } + + /// The EVENT_DESCRIPTOR structure identifies the description information that is available for each event. + /// + /// + /// The Id member is the event identifier. The structure members Id and Version can be used together to identify + /// all events for a specific provider. When the Id and Version are used in conjunction with the manifest, you can + /// precisely identify the structure and metadata of the event. + /// + /// + /// The pointer to the EVENT_DESCRIPTOR is passed to the EtwEventEnabled, EtwWrite, and EtwWriteTransfer functions. The most + /// convenient method of populating the EVENT_DESCRIPTOR structure is to use the EventDescCreate macro. This macro is declared + /// in Evntprov.h and its use is documented in the Microsoft Windows SDK. + /// + /// + /// The following is a list of the convenience macros that you can use to create the event descriptors and to extract and set fields + /// in the structure. For information on these macros, see Event Tracing Macros. + /// + /// Macros to create event descriptors: + /// + /// + /// EventDescCreate + /// + /// + /// EventDescZero + /// + /// + /// Macros to extract information from an event descriptor: + /// + /// + /// EventDescGetId + /// + /// + /// EventDescGetVersion + /// + /// + /// EventDescGetTask + /// + /// + /// EventDescGetOpcode + /// + /// + /// EventDescGetChannel + /// + /// + /// EventDescGetLevel + /// + /// + /// EventDescGetKeyword + /// + /// + /// Macros to set fields in an event descriptor: + /// + /// + /// EventDescSetId + /// + /// + /// EventDescSetVersion + /// + /// + /// EventDescSetTask + /// + /// + /// EventDescSetOpcode + /// + /// + /// EventDescSetLevel + /// + /// + /// EventDescSetChannel + /// + /// + /// EventDescSetKeyword + /// + /// + /// EventDescOrKeyword + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/ns-evntprov-_event_descriptor typedef struct _EVENT_DESCRIPTOR { + // USHORT Id; UCHAR Version; UCHAR Channel; UCHAR Level; UCHAR Opcode; USHORT Task; ULONGLONG Keyword; } EVENT_DESCRIPTOR, *PEVENT_DESCRIPTOR; + [PInvokeData("evntprov.h", MSDNShortId = "cfe84b3d-fed2-4624-9899-8451e5b39de0")] + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_DESCRIPTOR + { + /// The event identifier. Each event is associated with a 16-bit numeric value. + public ushort Id; + + /// + /// A numeric value that represents a version of the event. Component updates can change this value for a specific event. + /// + public byte Version; + + /// + /// The channel that the event is intended for. Note that the channel name is not stored here. The value of the channel is + /// assigned by the message compiler. + /// + public byte Channel; + + /// + /// The level of the event. The level indicates the severity or verbosity of the event. The level is used with earlier versions + /// of the ETW and WPP event fields. The levels have names with values, such as Error, Warning, Information, and so on. + /// + public byte Level; + + /// + /// The activity that the driver was performing at the time of the event. The Opcode member is defined by the provider or + /// is one of the system-defined values defined in the Winmeta.xml file that is provided with the Windows Driver Kit (WDK) in the + /// %Winddk%<i>version\inc\api directory. + /// + public byte Opcode; + + /// + /// The Task corresponds to the logical activity that the driver was performing when it raised the event. The + /// Opcode member refers to a specific action within that logical activity. + /// + public ushort Task; + + /// + /// The categories or tags assigned to the event. Each keyword categorizes the event in some way. For example, a category could + /// be Network, Storage, or Not Found. An event can belong to more then one category, in which case multiple + /// keywords are specified for the event. The keyword values are bitmasks and can be combined. + /// + public ulong Keyword; + + /// Initializes a new instance of the struct. + /// Event identifier. The value is used to set the Id member of EVENT_DESCRIPTOR. + /// Version of the event. The value is used to set the Version member of EVENT_DESCRIPTOR. + /// + /// The category of events to which this event belongs. The value is used to set the Channel member of EVENT_DESCRIPTOR. + /// + /// Specifies the severity of the event. The value is used to set the Level member of EVENT_DESCRIPTOR. + /// + /// Identifies a logical component of the application whose events you want to enable. The value is used to set the Task + /// member of EVENT_DESCRIPTOR. + /// + /// + /// Operation being performed at the time the event was written. The value is used to set the Opcode member of EVENT_DESCRIPTOR. + /// + /// + /// Bitmask that further defines the category of events to which the event belongs. The value is used to set the Keyword + /// member of EVENT_DESCRIPTOR. + /// + public EVENT_DESCRIPTOR(ushort Id, byte Version, byte Channel, byte Level, ushort Task, byte Opcode, ulong Keyword) + { + this.Channel = Channel; + this.Id = Id; + this.Keyword = Keyword; + this.Level = Level; + this.Opcode = Opcode; + this.Task = Task; + this.Version = Version; + } + } + + /// + /// The EVENT_FILTER_DESCRIPTOR structure supplements the event provider, level, and keyword data that determines which events are + /// reported and traced. The EVENT_FILTER_DESCRIPTOR structure gives the event provider greater control over the selection of events + /// for reporting and tracing. + /// + /// + /// You pass a pointer to the EVENT_FILTER_DESCRIPTOR structure when you create the optional driver-supplied + /// EtwEnableCallbackfunction. When you register the driver with ETW, the EtwRegister function takes a pointer to the + /// EtwEnableCallback function as a parameter. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntprov/ns-evntprov-_event_filter_descriptor typedef struct + // _EVENT_FILTER_DESCRIPTOR { ULONGLONG Ptr; ULONG Size; ULONG Type; } EVENT_FILTER_DESCRIPTOR, *PEVENT_FILTER_DESCRIPTOR; + [PInvokeData("evntprov.h", MSDNShortId = "3870a471-a3cf-424f-bba3-bc06de1ebecc")] + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_FILTER_DESCRIPTOR + { + /// A pointer to the filter data. + public ulong Ptr; + + /// The size of the filter data, in bytes. The maximum size is 1024 bytes. + public uint Size; + + /// + /// The type of filter data. The type is application-defined. An event controller that knows about the provider and knows details + /// about the provider's events can use the Type field to send the provider an arbitrary set of data for use as + /// enhancements to the filtering of events. + /// + public uint Type; + } + + /// Provides a handle to a provider registration handle. + [StructLayout(LayoutKind.Sequential)] + public struct REGHANDLE : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public REGHANDLE(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static REGHANDLE NULL => new REGHANDLE(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(REGHANDLE h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator REGHANDLE(IntPtr h) => new REGHANDLE(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(REGHANDLE h1, REGHANDLE h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(REGHANDLE h1, REGHANDLE h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is REGHANDLE h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// Provides a for that is disposed using . + public class SafeREGHANDLE : SafeHANDLE + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeREGHANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeREGHANDLE() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator REGHANDLE(SafeREGHANDLE h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => EventUnregister(handle).Succeeded; + } + } +} \ No newline at end of file diff --git a/PInvoke/Security/AdvApi32/Evntrace.cs b/PInvoke/Security/AdvApi32/Evntrace.cs new file mode 100644 index 00000000..a279b192 --- /dev/null +++ b/PInvoke/Security/AdvApi32/Evntrace.cs @@ -0,0 +1,4458 @@ +using System; +using System.Runtime.InteropServices; +using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; + +namespace Vanara.PInvoke +{ + public static partial class AdvApi32 + { + /// + /// + /// Consumers implement this function to receive statistics about each buffer of events that ETW delivers to an event trace consumer. + /// ETW calls this function after the events for each buffer are delivered. + /// + /// + /// The PEVENT_TRACE_BUFFER_CALLBACK type defines a pointer to this callback function. BufferCallback is a placeholder + /// for the application-defined function name. + /// + /// + /// + /// + /// To continue processing events, return TRUE. Otherwise, return FALSE. Returning FALSE will terminate the + /// ProcessTrace function. + /// + /// + /// + /// To specify the function that ETW calls to deliver the buffer statistics, set the BufferCallback member of the + /// EVENT_TRACE_LOGFILE structure that you pass to the OpenTrace function. + /// + /// Examples + /// For an example implementation of a BufferCallback function, see Retrieving Event Data Using MOF. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/nc-evntrace-pevent_trace_buffer_callbacka + // PEVENT_TRACE_BUFFER_CALLBACKA PeventTraceBufferCallbacka; ULONG PeventTraceBufferCallbacka( PEVENT_TRACE_LOGFILEA Logfile ) {...} + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + [PInvokeData("evntrace.h", MSDNShortId = "0cfe2f62-63dc-45a6-96ce-fb4bf458358f")] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool BufferCallback(in EVENT_TRACE_LOGFILE Logfile); + + /// + /// Providers implement this function to receive enable or disable notification requests from controllers. + /// + /// The WMIDPREQUEST type defines a pointer to this callback function. ControlCallback is a placeholder for the + /// application-defined function name. + /// + /// + /// Request code. Specify one of the following values. + /// + /// Provider-defined context. The provider uses the RequestContext parameter of RegisterTraceGuids to specify the context. + /// + /// Reserved for internal use. + /// + /// Pointer to a WNODE_HEADER structure that contains information about the event tracing session for which the provider is + /// being enabled or disabled. + /// + /// + /// You should return ERROR_SUCCESS if the callback succeeds. Note that ETW ignores the return value for this function except when a + /// controller calls EnableTrace to enable a provider and the provider has not yet called RegisterTraceGuids. When this + /// occurs, RegisterTraceGuids will return the return value of this callback if the registration was successful. + /// + /// + /// + /// This function is specified using the RegisterTraceGuids function. When the controller calls the EnableTrace + /// function to enable, disable, or change the enable flags or level, ETW calls this callback. The provider enables or disables + /// itself based the RequestCode value. Typically, the provider uses this value to set a global flag to indicate its enabled state. + /// + /// + /// The provider defines its interpretation of being enabled or disabled. Generally, if a provider is enabled, it generates events, + /// but while it is disabled, it does not. + /// + /// + /// ETW does not pass the enable flags and enable level that the controller passes to the EnableTrace function to this + /// callback. To retrieve this information, call the GetTraceEnableFlags and GetTraceEnableLevel functions, respectively. + /// + /// + /// You also need to retrieve the session handle in this callback for future calls. To retrieve the session handle, call the + /// GetTraceLoggerHandle function. + /// + /// + /// Your callback function must not call anything that may incur LoadLibrary (more specifically, anything that requires a loader lock). + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/etw/controlcallback ULONG WINAPI ControlCallback( _In_ WMIDPREQUESTCODE + // RequestCode, _In_ PVOID Context, _In_ ULONG *Reserved, _In_ PVOID Buffer ); + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + [PInvokeData("evntrace.h", MSDNShortId = "e9f70ae6-906f-4e55-bca7-4355f1ca6091")] + public delegate Win32Error ControlCallback(WMIDPREQUESTCODE RequestCode, IntPtr Context, in uint Reserved, IntPtr Buffer); + + /// + /// [Do not implement this function; it may be unavailable in subsequent versions.] + /// + /// Consumers implement this function to receive events for a specific event trace class from a session. ETW calls this function + /// every time the ProcessTrace function process an event belonging to the event trace class. + /// + /// + /// The PEVENT_CALLBACK type defines a pointer to this callback function. EventClassCallback is a placeholder for the + /// application-defined function name. + /// + /// + /// Pointer to an EVENT_TRACE structure that contains the event information. + /// The function does not return a value. + /// + /// + /// To associate each EventClassCallback function with the class GUID of the event trace class it processes, use the + /// SetTraceCallback function. + /// + /// To stop the EventClassCallback from receiving events, call the RemoveTraceCallback function. + /// To processes all events that the session generates, see the EventCallback function. + /// + /// If you use both EventCallback and EventClassCallback to receive events, the event is always sent to + /// EventCallback and is only sent to EventClassCallback if the event matches the class GUID associated with the callback. + /// + /// + /// You use the Header.Class.Type member of EVENT_TRACE to determine the type of event you received. If you are + /// consuming events from your own provider and know the layout of the data, this is not an issue. Otherwise, to interpret the event, + /// the provider must have published their event schema in the \\root\wmi namespace. For information on using an event's MOF schema + /// to interpret the event, see Consuming Events. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/eventclasscallback VOID WINAPI EventClassCallback( _In_ PEVENT_TRACE pEvent ); + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + [PInvokeData("Evntrace.h", MSDNShortId = "32e94f58-b8b6-4e0a-b53b-716a534ac374")] + public delegate void EventClassCallback(in EVENT_TRACE pEvent); + + /// + /// Consumers implement this callback to receive events from a session. + /// + /// The PEVENT_RECORD_CALLBACK type defines a pointer to this callback function. EventRecordCallback is a placeholder + /// for the application-defined function name. + /// + /// + /// Pointer to an EVENT_RECORD structure that contains the event information. + /// The function does not return a value. + /// + /// + /// To specify the function that ETW calls to deliver events, set the EventRecordCallback member of the + /// EVENT_TRACE_LOGFILE structure (you pass this structure to the OpenTrace function). You must also set the + /// ProcessTraceMode member to PROCESS_TRACE_MODE_EVENT_RECORD. + /// + /// + /// This callback receives all events that the session generates from the time you call the OpenTrace function. Call the + /// ProcessTrace function to begin receiving the events. + /// + /// For information on parsing the event data, see Retrieving Event Data Using TDH. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/eventrecordcallback VOID WINAPI EventRecordCallback( _In_ PEVENT_RECORD + // EventRecord ); + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + [PInvokeData("", MSDNShortId = "80a30faf-af1f-4440-8a17-9df44bdb2291")] + public delegate void EventRecordCallback(in EVENT_RECORD EventRecord); + + /// + /// + /// [Some information relates to pre-released product which may be substantially modified before it's commercially released. + /// Microsoft makes no warranties, express or implied, with respect to the information provided here.] + /// + /// Specifies what kind of operation will be done on a handle. currently used with the QueryTraceProcessingHandle function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/ne-evntrace-etw_process_handle_info_type typedef enum + // _ETW_PROCESS_HANDLE_INFO_TYPE { EtwQueryPartitionInformation, EtwQueryProcessHandleInfoMax, EtwQueryPartitionInformationV2, + // EtwQueryLastDroppedTimes } ETW_PROCESS_HANDLE_INFO_TYPE; + [PInvokeData("evntrace.h", MSDNShortId = "92932E4C-0A06-4CDE-B14B-BF53226E133B")] + public enum ETW_PROCESS_HANDLE_INFO_TYPE + { + /// + /// Used to query partition identifying information. InBuffer should be Null. OutBuffer should be large enough to hold the + /// returned ETW_TRACE_PARTITION_INFORMATION structure. Note that this will only return a non-zero structure when the queried + /// handle is for a trace file generated from a non-host partition on Windows 10, version 1709. + /// + EtwQueryPartitionInformation, + /// Marks the last value in the enumeration for testing purposes. Should not be used. + EtwQueryProcessHandleInfoMax, + } + + /// Requested control function. + [PInvokeData("evntrace.h", MSDNShortId = "c39f669c-ff40-40ed-ba47-798474ec2de4")] + public enum EVENT_TRACE_CONTROL + { + /// Retrieves session properties and statistics. + EVENT_TRACE_CONTROL_QUERY = 0, + + /// Stops the session. The session handle is no longer valid. + EVENT_TRACE_CONTROL_STOP = 1, + + /// Updates the session properties. + EVENT_TRACE_CONTROL_UPDATE = 2, + + /// + /// Flushes the session's active buffers. Typically, you do not need to flush buffers yourself. However, you may want to flush + /// buffers if the event rate is low and you are delivering events in real time. + /// Windows 2000: This value is not supported. + /// + EVENT_TRACE_CONTROL_FLUSH = 3, + + /// Undocumented. + EVENT_TRACE_CONTROL_INCREMENT_FILE = 4, + } + + /// Defines what component of the security descriptor that the EventAccessControl function modifies. + /// For information on DACLs and SACLs, see Access Control Lists. + // https://docs.microsoft.com/en-us/windows/desktop/api/evntcons/ne-evntcons-eventsecurityoperation typedef enum { + // EventSecuritySetDACL, EventSecuritySetSACL, EventSecurityAddDACL, EventSecurityAddSACL, EventSecurityMax } ; + [PInvokeData("evntcons.h", MSDNShortId = "81f6cf07-2705-4075-b085-d5aebba17121")] + public enum EVENTSECURITYOPERATION + { + /// + /// Clears the current discretionary access control list (DACL) and adds an ACE to the DACL. The Sid, Rights, and AllowOrDeny + /// parameters of the EventAccessControl function determine the contents of the ACE (who has access to the provider or session + /// and the type of access). To add a new ACE to the DACL without clearing the existing DACL, specify EventSecurityAddDACL. + /// + EventSecuritySetDACL, + /// + /// Clears the current system access control list (SACL) and adds an audit ACE to the SACL. The Sid and Rights parameters of the + /// EventAccessControl function determine the contents of the ACE (who generates an audit record when attempting the specified + /// access). To add a new ACE to the SACL without clearing the existing SACL, specify EventSecurityAddSACL. + /// + EventSecuritySetSACL, + /// + /// Adds an ACE to the current DACL. The Sid, Rights, and AllowOrDeny parameters of the EventAccessControl function determine the + /// contents of the ACE (who has access to the provider or session and the type of access). + /// + EventSecurityAddDACL, + /// + /// Adds an ACE to the current SACL. The Sid and Rights parameters of the EventAccessControl function determine the contents of + /// the ACE (who generates an audit record when attempting the specified access). + /// + EventSecurityAddSACL, + /// Reserved. + EventSecurityMax, + } + + /// Provider-defined value that specifies the level of information the event generates. + [PInvokeData("evntrace.h", MSDNShortId = "d75f18e1-e5fa-4039-bb74-76dea334b0fd")] + public enum TRACE_LEVEL + { + /// Abnormal exit or termination events + TRACE_LEVEL_CRITICAL = 1, + + /// Severe error events + TRACE_LEVEL_ERROR = 2, + + /// Warning events such as allocation failures + TRACE_LEVEL_WARNING = 3, + + /// Non-error events such as entry or exit events + TRACE_LEVEL_INFORMATION = 4, + + /// Detailed trace events + TRACE_LEVEL_VERBOSE = 5, + } + + /// Adds additional information to the beginning of the provider-specific data section of the event. + [PInvokeData("Evntrace.h", MSDNShortId = "5d81c851-d47e-43f8-97b0-87156f36119a")] + [Flags] + public enum TRACE_MESSAGE : uint + { + /// + /// Include a sequence number in the message. The sequence number starts at one. To use this flag, the controller must have set + /// the EVENT_TRACE_USE_GLOBAL_SEQUENCE or EVENT_TRACE_USE_LOCAL_SEQUENCE log file mode when creating the session. + /// + TRACE_MESSAGE_SEQUENCE = 1, + /// + /// Include the event trace class GUID in the message. The MessageGuid parameter contains the event trace class GUID. + /// + TRACE_MESSAGE_GUID = 2, + /// Include the component identifier in the message. The MessageGuid parameter contains the component identifier. + TRACE_MESSAGE_COMPONENTID = 4, + /// Include a time stamp in the message. + TRACE_MESSAGE_TIMESTAMP = 8, + TRACE_MESSAGE_PERFORMANCE_TIMESTAMP = 16, + /// Include the thread identifier and process identifier in the message. + TRACE_MESSAGE_SYSTEMINFO = 32, + TRACE_MESSAGE_POINTER32 = 0x0040, + TRACE_MESSAGE_POINTER64 = 0x0080, + TRACE_MESSAGE_FLAG_MASK = 0xFFFF, + } + + /// Determines the type of information to include with the trace. + /// + /// The TRACE_INFO_CLASS and TRACE_QUERY_INFO_CLASS enumerations both define the same values. Use both enumerations + /// with the EnumerateTraceGuidsEx function or the TraceSetInformation function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/ne-evntrace-trace_query_info_class typedef enum + // _TRACE_QUERY_INFO_CLASS { TraceGuidQueryList, TraceGuidQueryInfo, TraceGuidQueryProcess, TraceStackTracingInfo, + // TraceSystemTraceEnableFlagsInfo, TraceSampledProfileIntervalInfo, TraceProfileSourceConfigInfo, TraceProfileSourceListInfo, + // TracePmcEventListInfo, TracePmcCounterListInfo, TraceSetDisallowList, TraceVersionInfo, TraceGroupQueryList, TraceGroupQueryInfo, + // TraceDisallowListQuery, TraceInfoReserved15, TracePeriodicCaptureStateListInfo, TracePeriodicCaptureStateInfo, + // TraceProviderBinaryTracking, TraceMaxLoggersQuery, MaxTraceSetInfoClass, TraceLbrConfigurationInfo, TraceLbrEventListInfo, + // TraceMaxPmcCounterQuery } TRACE_QUERY_INFO_CLASS, TRACE_INFO_CLASS; + [PInvokeData("evntrace.h", MSDNShortId = "b163e120-454a-48ba-93a9-71351fc3f2c2")] + public enum TRACE_QUERY_INFO_CLASS + { + /// Query an array of GUIDs of the providers that are registered on the computer. + TraceGuidQueryList, + + /// Query information that each session used to enable the provider. + TraceGuidQueryInfo, + + /// Query an array of GUIDs of the providers that registered themselves in the same process as the calling process. + TraceGuidQueryProcess, + + /// + /// Query the setting for call stack tracing for kernel events. The value is supported on Windows 7, Windows Server 2008 R2, and later. + /// + TraceStackTracingInfo, + + /// + /// Query the setting for the EnableFlags for the system trace provider. For more information, see the EVENT_TRACE_PROPERTIES + /// structure. The value is supported on Windows 8, Windows Server 2012, and later. + /// + TraceSystemTraceEnableFlagsInfo, + + /// + /// Queries the setting for the sampling profile interval for the supplied source. The value is supported on Windows 8, Windows + /// Server 2012, and later. + /// + TraceSampledProfileIntervalInfo, + + /// + /// Query the setting for sampled profile list information. The value is supported on Windows 8, Windows Server 2012, and later. + /// + TraceProfileSourceListInfo, + + /// + /// Query the list of performance monitoring counters to collect The value is supported on Windows 8, Windows Server 2012, and later. + /// + TracePmcCounterListInfo, + + /// Query the trace file version information. The value is supported on Windows 10. + TraceVersionInfo, + + /// + /// Queries the currently-configured maximum number of system loggers allowed by the operating system. Returns a ULONG. Used with + /// EnumerateTraceGuidsEx. The value is supported on Windows 10, version 1709 and later. + /// + TraceMaxLoggersQuery, + + /// Marks the last value in the enumeration. Do not use. + MaxTraceSetInfoClass, + } + + /// Specific rights for WMI guid objects. + [PInvokeData("evntcons.h", MSDNShortId = "699bb165-680f-4d3b-8859-959f319ca4be")] + [Flags] + public enum TRACELOG_RIGHTS : uint + { + /// Allows the user to query information about the trace session. Set this permission on the session's GUID. + WMIGUID_QUERY = 0x0001, + /// + WMIGUID_SET = 0x0002, + /// + WMIGUID_NOTIFICATION = 0x0004, + /// + WMIGUID_READ_DESCRIPTION = 0x0008, + /// + WMIGUID_EXECUTE = 0x0010, + /// Allows the user to start or update a real-time session. Set this permission on the session's GUID. + TRACELOG_CREATE_REALTIME = 0x0020, + /// + /// Allows the user to start or update a session that writes events to a log file. Set this permission on the session's GUID. + /// + TRACELOG_CREATE_ONDISK = 0x0040, + /// Allows the user to enable the provider. Set this permission on the provider's GUID. + TRACELOG_GUID_ENABLE = 0x0080, + /// Not used. + TRACELOG_ACCESS_KERNEL_LOGGER = 0x0100, + /// + /// Allows the user to log events to a trace session if session is running in SECURE mode (the session set the + /// EVENT_TRACE_SECURE_MODE flag in the LogFileMode member of EVENT_TRACE_PROPERTIES). + /// + TRACELOG_LOG_EVENT = 0x0200, + /// + TRACELOG_CREATE_INPROC = 0x0200, + /// Allows a user to consume events in real-time. Set this permission on the session's GUID. + TRACELOG_ACCESS_REALTIME = 0x0400, + /// Allows the user to register the provider. Set this permission on the provider's GUID. + TRACELOG_REGISTER_GUIDS = 0x0800, + /// + TRACELOG_JOIN_GROUP = 0x1000, + } + + /// Request code. + [PInvokeData("wmistr.h")] + public enum WMIDPREQUESTCODE + { + WMI_GET_ALL_DATA = 0, + WMI_GET_SINGLE_INSTANCE = 1, + WMI_SET_SINGLE_INSTANCE = 2, + WMI_SET_SINGLE_ITEM = 3, + /// Enables the provider. + WMI_ENABLE_EVENTS = 4, + /// Disables the provider. + WMI_DISABLE_EVENTS = 5, + WMI_ENABLE_COLLECTION = 6, + WMI_DISABLE_COLLECTION = 7, + WMI_REGINFO = 8, + WMI_EXECUTE_METHOD = 9, + WMI_CAPTURE_STATE = 10 + } + + [Flags] + public enum WNODE_FLAG : uint + { + WNODE_FLAG_ALL_DATA = 0x00000001, + WNODE_FLAG_SINGLE_INSTANCE = 0x00000002, + WNODE_FLAG_SINGLE_ITEM = 0x00000004, + WNODE_FLAG_EVENT_ITEM = 0x00000008, + WNODE_FLAG_FIXED_INSTANCE_SIZE = 0x00000010, + WNODE_FLAG_TOO_SMALL = 0x00000020, + WNODE_FLAG_INSTANCES_SAME = 0x00000040, + WNODE_FLAG_STATIC_INSTANCE_NAMES = 0x00000080, + WNODE_FLAG_INTERNAL = 0x00000100, + WNODE_FLAG_USE_TIMESTAMP = 0x00000200, + WNODE_FLAG_PERSIST_EVENT = 0x00000400, + WNODE_FLAG_EVENT_REFERENCE = 0x00002000, + WNODE_FLAG_ANSI_INSTANCENAMES = 0x00004000, + WNODE_FLAG_METHOD_ITEM = 0x00008000, + WNODE_FLAG_PDO_INSTANCE_NAMES = 0x00010000, + WNODE_FLAG_TRACED_GUID = 0x00020000, + WNODE_FLAG_LOG_WNODE = 0x00040000, + WNODE_FLAG_USE_GUID_PTR = 0x00080000, + WNODE_FLAG_USE_MOF_PTR = 0x00100000, + WNODE_FLAG_NO_HEADER = 0x00200000, + WNODE_FLAG_SEND_DATA_BLOCK = 0x00400000, + WNODE_FLAG_VERSIONED_PROPERTIES = 0x00800000, + WNODE_FLAG_SEVERITY_MASK = 0xff000000, + } + + /// The CloseTrace function closes a trace. + /// Handle to the trace to close. The OpenTrace function returns this handle. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// One of the following is true: + /// + /// + /// ERROR_BUSY + /// Prior to Windows Vista, you cannot close the trace until the ProcessTrace function completes. + /// + /// + /// ERROR_CTX_CLOSE_PENDING + /// + /// The call was successful. The ProcessTrace function will stop after it has processed all real-time events in its buffers (it will + /// not receive any new events). + /// + /// + /// + /// + /// + /// Consumers call this function. + /// + /// If you are processing events from a log file, you call this function only after the ProcessTrace function returns. + /// However, if you are processing real-time events, you can call this function before ProcessTrace returns. If you call this + /// function before ProcessTrace returns, the CloseTrace function returns ERROR_CTX_CLOSE_PENDING. The + /// ERROR_CTX_CLOSE_PENDING code indicates that the CloseTrace function call was successful; the ProcessTrace function + /// will stop processing events after it processes all events in its buffers ( ProcessTrace will not receive any new events + /// after you call the CloseTrace function). You can call the CloseTrace function from your BufferCallback, + /// EventCallback, or EventClassCallback callback. + /// + /// Prior to Windows Vista: You can call CloseTrace only after ProcessTrace returns. + /// + // https://docs.microsoft.com/en-us/windows/desktop/etw/closetrace ULONG CloseTrace( _In_ TRACEHANDLE TraceHandle ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntrace.h", MSDNShortId = "25f4c4d3-0b70-40fe-bf03-8f9ffd82fbec")] + public static extern Win32Error CloseTrace(TRACEHANDLE TraceHandle); + + /// The ControlTrace function flushes, queries, updates, or stops the specified event tracing session. + /// + /// Handle to an event tracing session, or NULL. You must specify SessionHandle if SessionName is NULL. However, ETW + /// ignores the handle if SessionName is not NULL. The handle is returned by the StartTrace function. + /// + /// + /// Name of an event tracing session, or NULL. You must specify SessionName if SessionHandle is NULL. + /// To specify the NT Kernel Logger session, set SessionName to KERNEL_LOGGER_NAME. + /// + /// + /// Pointer to an initialized EVENT_TRACE_PROPERTIES structure. This structure should be zeroed out before it is used. + /// + /// If ControlCode specifies EVENT_TRACE_CONTROL_STOP, EVENT_TRACE_CONTROL_QUERY or EVENT_TRACE_CONTROL_FLUSH, + /// you only need to set the Wnode.BufferSize, Wnode.Guid, LoggerNameOffset, and LogFileNameOffset + /// members of the EVENT_TRACE_PROPERTIES structure. If the session is a private session, you also need to set + /// LogFileMode. You can use the maximum session name (1024 characters) and maximum log file name (1024 characters) lengths to + /// calculate the buffer size and offsets if not known. + /// + /// + /// If ControlCode specifies EVENT_TRACE_CONTROL_UPDATE, on input, the members must specify the new values for the properties + /// to update. On output, Properties contains the properties and statistics for the event tracing session. You can update the + /// following properties. + /// + /// + /// + /// Member + /// Use + /// + /// + /// EnableFlags + /// + /// Set this member to 0 to disable all kernel providers. Otherwise, you must specify the kernel providers that you want to enable or + /// keep enabled. Applies only to NT Kernel Logger sessions. + /// + /// + /// + /// FlushTimer + /// + /// Set this member if you want to change the time to wait before flushing buffers. If this member is 0, the member is not updated. + /// + /// + /// + /// LogFileNameOffset + /// + /// Set this member if you want to switch to another log file. If this member is 0, the file name is not updated. If the offset is + /// not zero and you do not change the log file name, the function returns an error. + /// + /// + /// + /// LogFileMode + /// + /// Set this member if you want to turn EVENT_TRACE_REAL_TIME_MODE on and off. To turn real time consuming off, set this member to 0. + /// To turn real time consuming on, set this member to EVENT_TRACE_REAL_TIME_MODE and it will be OR'd with the current modes. + /// + /// + /// + /// MaximumBuffers + /// + /// Set this member if you want to change the maximum number of buffers that ETW uses. If this member is 0, the member is not updated. + /// + /// + /// + /// For private logger sessions, you can update only the LogFileNameOffset and FlushTimer members. + /// + /// If you are using a newly initialized EVENT_TRACE_PROPERTIES structure, the only members you need to specify, other than + /// the members you are updating, are Wnode.BufferSize, Wnode.Guid, and Wnode.Flags. + /// + /// + /// If you use the property structure you passed to StartTrace, make sure the LogFileNameOffset member is 0 unless you + /// are changing the log file name. + /// + /// + /// If you call the ControlTrace function to query the current session properties and then update those properties to update + /// the session, make sure you set LogFileNameOffset to 0 (unless you are changing the log file name) and set + /// EVENT_TRACE_PROPERTIES.Wnode.Flags to WNODE_FLAG_TRACED_GUID. + /// + /// + /// Starting with Windows 10, version 1703: For better performance in cross process scenarios, you can now pass filtering in + /// to ControlTrace for system wide private loggers. You will need to pass in the new EVENT_TRACE_PROPERTIES_V2 + /// structure to include filtering information. See Configuring and Starting a Private Logger Session for more details. + /// + /// + /// + /// Requested control function. You can specify one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// EVENT_TRACE_CONTROL_FLUSH + /// + /// Flushes the session's active buffers. Typically, you do not need to flush buffers yourself. However, you may want to flush + /// buffers if the event rate is low and you are delivering events in real time. Windows 2000: This value is not supported. + /// + /// + /// + /// EVENT_TRACE_CONTROL_QUERY + /// Retrieves session properties and statistics. + /// + /// + /// EVENT_TRACE_CONTROL_STOP + /// Stops the session. The session handle is no longer valid. + /// + /// + /// EVENT_TRACE_CONTROL_UPDATE + /// Updates the session properties. + /// + /// + /// Note that it is not safe to flush buffers or stop a trace session from DllMain. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// One of the following is true: + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_BAD_PATHNAME + /// Another session is already using the file name specified by the LogFileNameOffset member of the Properties structure. + /// + /// + /// ERROR_MORE_DATA + /// + /// The buffer for EVENT_TRACE_PROPERTIES is too small to hold all the information for the session. If you do not need the session's + /// property information, you can ignore this error. If you receive this error when stopping the session, ETW will have already + /// stopped the session before generating this error. + /// + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users running with elevated administrative privileges, users in the Performance Log Users group, and services running as + /// LocalSystem, LocalService, NetworkService can control event tracing sessions. To grant a restricted user the ability to control + /// trace sessions, add them to the Performance Log Users group. Only users with administrative privileges and services running as + /// LocalSystem can control an NT Kernel Logger session. Windows XP and Windows 2000: Anyone can control a trace session. + /// + /// + /// + /// ERROR_WMI_INSTANCE_NOT_FOUND + /// The given session is not running. + /// + /// + /// + /// + /// Event trace controllers call this function. + /// This function supersedes the FlushTrace, QueryTrace, StopTrace, and UpdateTrace functions. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/controltrace ULONG ControlTrace( _In_ TRACEHANDLE SessionHandle, _In_ LPCTSTR + // SessionName, _Inout_ PEVENT_TRACE_PROPERTIES Properties, _In_ ULONG ControlCode ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("evntrace.h", MSDNShortId = "c39f669c-ff40-40ed-ba47-798474ec2de4")] + public static extern Win32Error ControlTrace([Optional] TRACEHANDLE SessionHandle, [Optional] string SessionName, ref EVENT_TRACE_PROPERTIES Properties, EVENT_TRACE_CONTROL ControlCode); + + /// + /// The CreateTraceInstanceId function creates a unique transaction identifier and maps it to a class GUID registration + /// handle. You then use the transaction identifier when calling the TraceEventInstance function. + /// + /// + /// Handle to a registered event trace class. The RegisterTraceGuids function returns this handle in the RegHandle member of + /// the TRACE_GUID_REGISTRATION structure. + /// + /// + /// Pointer to an EVENT_INSTANCE_INFO structure. The InstanceId member of this structure contains the transaction identifier. + /// + /// + /// If the function is successful, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// + /// + /// Providers call this function. + /// + /// ETW creates the identifier in the user-mode process, thus it can return the same number for different processes. The value starts + /// over at one when InstanceId reaches the maximum value for a ULONG. Only user-mode providers can call the + /// CreateTraceInstanceId function; drivers cannot call this function. + /// + /// Examples + /// For an example that uses CreateTraceInstanceId, see Tracing Event Instances. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/nf-evntrace-createtraceinstanceid ULONG WMIAPI + // CreateTraceInstanceId( HANDLE RegHandle, PEVENT_INSTANCE_INFO InstInfo ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntrace.h", MSDNShortId = "ab890392-f1e4-4b4e-a46c-8c7c2bfd3897")] + public static extern Win32Error CreateTraceInstanceId(HANDLE RegHandle, ref EVENT_INSTANCE_INFO InstInfo); + + /// + /// Enables or disables the specified classic event trace provider. + /// On Windows Vista and later, call the EnableTraceEx function to enable or disable a provider. + /// + /// If TRUE, the provider is enabled; otherwise, the provider is disabled. + /// + /// + /// Provider-defined value that specifies the class of events for which the provider generates events. A provider that generates only + /// one class of events will typically ignore this flag. If the provider is more complex, the provider could use the TraceGuidReg + /// parameter of RegisterTraceGuids to register more than one class of events. For example, if the provider has a database + /// component, a UI component, and a general processing component, the provider could register separate event classes for these + /// components. This would then allow the controller the ability to turn on tracing in only the database component. + /// + /// The provider calls GetTraceEnableFlags from its ControlCallback function to obtain the enable flags. + /// + /// + /// + /// Provider-defined value that specifies the level of information the event generates. For example, you can use this value to + /// indicate the severity level of the events (informational, warning, error) you want the provider to generate. + /// + /// + /// Specify a value from zero to 255. ETW defines the following severity levels that you can use. Higher numbers imply that you get + /// lower levels as well. For example, if you specify TRACE_LEVEL_WARNING, you also receive all warning, error, and fatal events. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// TRACE_LEVEL_CRITICAL 1 + /// Abnormal exit or termination events + /// + /// + /// TRACE_LEVEL_ERROR 2 + /// Severe error events + /// + /// + /// TRACE_LEVEL_WARNING 3 + /// Warning events such as allocation failures + /// + /// + /// TRACE_LEVEL_INFORMATION 4 + /// Non-error events such as entry or exit events + /// + /// + /// TRACE_LEVEL_VERBOSE 5 + /// Detailed trace events + /// + /// + /// + /// GUID of the event trace provider that you want to enable or disable. + /// + /// Handle of the event tracing session to which you want to enable, disable, or change the logging level of the provider. The + /// StartTrace function returns this handle. + /// + /// + /// If the function is successful, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_INVALID_FUNCTION + /// You cannot change the enable flags and level when the provider is not registered. + /// + /// + /// ERROR_WMI_GUID_NOT_FOUND + /// + /// The provider is not registered. Occurs when KB307331 or Windows 2000 Service Pack 4 is installed and the provider is not + /// registered. To avoid this error, the provider must first be registered. + /// + /// + /// + /// ERROR_NO_SYSTEM_RESOURCES + /// Exceeded the number of trace sessions that can enable the provider. + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, + /// LocalService, NetworkService can enable trace providers. To grant a restricted user the ability to enable a trace provider, add + /// them to the Performance Log Users group or see EventAccessControl. Windows XP and Windows 2000: Anyone can enable a trace provider. + /// + /// + /// + /// + /// + /// Event trace controllers call this function. + /// + /// Up to eight trace sessions can enable and receive events from the same manifest-based provider; however, only one trace session + /// can enable a classic provider. If more than one session tried to enable a classic provider, the first session would stop + /// receiving events when the second session enabled the same provider. For example, if Session A enabled Provider 1 and then Session + /// B enabled Provider 1, only Session B would receive events from Provider 1. + /// + /// + /// The provider remains enabled for the session until the session disables the provider. If the application that started the session + /// ends without disabling the provider, the provider remains enabled. + /// + /// + /// The EnableTrace function calls the ControlCallback function implemented by the event trace provider, if defined. + /// The provider defines its interpretation of being enabled or disabled. Typically, if a provider has been enabled, it generates + /// events, but while it is disabled, it does not. The ControlCallback function can call the GetTraceEnableFlags, + /// GetTraceEnableLevel, and GetTraceLoggerHandle functions to obtain the values specified for the EnableFlag, + /// EnableLevel, and SessionHandle parameters, respectively. + /// + /// + /// You can call this function one time to enable a provider before the provider registers itself. After the provider registers + /// itself, ETW calls the provider's ControlCallback function. If you try to enable the provider for multiple sessions before + /// the provider registers itself, ETW will only enable the provider for the last session. For example, if you enable the provider to + /// Session A and then enable the provider to Session B, when the provider registers itself, the provider is only enabled for Session B. + /// + /// + /// You do not call EnableTrace to enable kernel providers. To enable kernel providers, set the EnableFlags member of + /// EVENT_TRACE_PROPERTIES which you then pass to StartTrace. The StartTrace function enables the selected + /// kernel providers. + /// + /// To determine the level and keywords used to enable a manifest-based provider, use one of the following commands: + /// + /// + /// Logman query providers + /// + /// + /// Wevtutil gp + /// + /// + /// + /// For classic providers, it is up to the provider to document and make available to potential controllers the severity levels or + /// enable flags that it supports. If the provider wants to be enabled by any controller, the provider should accept 0 for the + /// severity level and enable flags and interpret 0 as a request to perform default logging (whatever that may be). + /// + /// If you use EnableTrace to enable a manifest-based provider, the following translation occurs: + /// + /// + /// The EnableLevel parameter is the same as setting the Level parameter in EnableTraceEx. + /// + /// + /// The EnableFlag is the same as setting the MatchAnyKeyword parameter in EnableTraceEx. + /// + /// + /// + /// In the EnableCallback callback, the SourceId parameter will be NULL, Level will be set to the value in + /// EnableTrace, MatchAnyKeyword will be set to the value of EnableFlag in EventTrace, MatchAllKeyword will be 0, and + /// FilterData will be NULL. + /// + /// + /// + /// + /// On Windows 8.1,Windows Server 2012 R2, and later, payload filters can be used by the EnableTraceEx2 function to filter on + /// specific conditions in a logger session. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/enabletrace ULONG EnableTrace( _In_ ULONG Enable, _In_ ULONG EnableFlag, _In_ + // ULONG EnableLevel, _In_ LPCGUID ControlGuid, _In_ TRACEHANDLE SessionHandle ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntrace.h", MSDNShortId = "d75f18e1-e5fa-4039-bb74-76dea334b0fd")] + public static extern Win32Error EnableTrace([MarshalAs(UnmanagedType.Bool)] bool Enable, uint EnableFlag, TRACE_LEVEL EnableLevel, in Guid ControlGuid, TRACEHANDLE SessionHandle); + + /// + /// Enables or disables the specified event trace provider. + /// The EnableTraceEx2 function supersedes this function. + /// + /// GUID of the event trace provider that you want to enable or disable. + /// + /// GUID that uniquely identifies the session that is enabling or disabling the provider. Can be NULL. If the provider does + /// not implement EnableCallback, the GUID is not used. + /// + /// + /// Handle of the event tracing session to which you want to enable or disable the provider. The StartTrace function returns + /// this handle. + /// + /// + /// Set to 1 to receive events when the provider is registered; otherwise, set to 0 to no longer receive events from the provider. + /// + /// + /// Provider-defined value that specifies the level of detail included in the event. Specify one of the following levels that are + /// defined in Winmeta.h. Higher numbers imply that you get lower levels as well. For example, if you specify TRACE_LEVEL_WARNING, + /// you also receive all warning, error, and critical events. + /// + /// + /// Bitmask of keywords that determine the category of events that you want the provider to write. The provider writes the event if + /// any of the event's keyword bits match any of the bits set in this mask. See Remarks. + /// + /// + /// This bitmask is optional. This mask further restricts the category of events that you want the provider to write. If the event's + /// keyword meets the MatchAnyKeyword condition, the provider will write the event only if all of the bits in this mask exist in the + /// event's keyword. This mask is not used if MatchAnyKeyword is zero. See Remarks. + /// + /// + /// Optional information that ETW can include when writing the event. The data is written to the extended data item section of + /// the event. To include the optional information, specify one or more of the following flags; otherwise, set to zero. + /// + /// + /// + /// An EVENT_FILTER_DESCRIPTOR structure that points to the filter data. The provider uses to filter data to prevent events + /// that match the filter criteria from being written to the session; the provider determines the layout of the data and how it + /// applies the filter to the event's data. A session can pass only one filter to the provider. + /// + /// A session can call the TdhEnumerateProviderFilters function to determine the filters that it can pass to the provider. + /// + /// + /// If the function is successful, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_INVALID_FUNCTION + /// You cannot update the level when the provider is not registered. + /// + /// + /// ERROR_NO_SYSTEM_RESOURCES + /// Exceeded the number of trace sessions that can enable the provider. + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, + /// LocalService, NetworkService can enable trace providers. To grant a restricted user the ability to enable a trace provider, add + /// them to the Performance Log Users group or see EventAccessControl. Windows XP and Windows 2000: Anyone can enable a trace provider. + /// + /// + /// + /// + /// + /// Event trace controllers call this function. + /// + /// The provider defines its interpretation of being enabled or disabled. Typically, if a provider has been enabled, it generates + /// events, but while it is disabled, it does not. + /// + /// + /// To include all events that a provider provides, set MatchAnyKeyword to zero (for a manifest-based provider and 0xFFFFFFFF for a + /// classic provider). To include specific events, set the MatchAnyKeyword mask to those specific events. For example, if the + /// provider defines an event for its initialization and cleanup routines (set keyword bit 0), an event for its file operations (set + /// keyword bit 1), and an event for its calculation operations (set keyword bit 2), you can set MatchAnyKeyword to 5 to receive + /// initialization and cleanup events and calculation events. + /// + /// + /// If the provider defines more complex event keywords, for example, the provider defines an event that sets bit 0 for read and bit + /// 1 for local access and a second event that sets bit 0 for read and bit 2 for remote access, you could set MatchAnyKeyword to 1 to + /// receive all read events, or you could set MatchAnykeyword to 1 and MatchAllKeywords to 3 to receive local reads only. + /// + /// + /// If an event's keyword is zero, the provider will write the event to the session, regardless of the MatchAnyKeyword and + /// MatchAllKeyword masks. + /// + /// + /// When you call EnableTraceEx the provider may or may not be registered. If the provider is registered, ETW calls the + /// provider's callback function, if it implements one, and the session begins receiving events. If the provider is not registered, + /// ETW will call the provider's callback function when it registers itself, if it implements one, and the session will begin + /// receiving events. If the provider is not registered, the provider's callback function will not receive the source ID or filter + /// data. You can call EnableTraceEx one time to enable a provider before the provider registers itself. + /// + /// + /// If the provider is registered and already enabled to your session, you can also use this function to update the Level, + /// MatchAnyKeyword, MatchAllKeyword, EnableProperty and EnableFilterDesc parameters that determine which events the provider writes. + /// + /// + /// You do not call EnableTraceEx to enable kernel providers. To enable kernel providers, set the EnableFlags member of + /// EVENT_TRACE_PROPERTIES which you then pass to StartTrace. The StartTrace function enables the selected + /// kernel providers. + /// + /// + /// Up to eight trace sessions can enable and receive events from the same manifest-based provider; however, only one trace session + /// can enable a classic provider. If more than one session tried to enable a classic provider, the first session would stop + /// receiving events when the second session enabled the same provider. For example, if Session A enabled Provider 1 and then Session + /// B enabled Provider 1, only Session B would receive events from Provider 1. + /// + /// + /// The provider remains enabled for the session until the session disables the provider. If the application that started the session + /// ends without disabling the provider, the provider remains enabled. + /// + /// To determine the level and keywords used to enable a manifest-based provider, use one of the following commands: + /// + /// + /// Logman query providers + /// + /// + /// Wevtutil gp + /// + /// + /// + /// For classic providers, it is up to the provider to document and make available to potential controllers the severity levels or + /// enable flags that it supports. If the provider wants to be enabled by any controller, the provider should accept 0 for the + /// severity level and enable flags and interpret 0 as a request to perform default logging (whatever that may be). + /// + /// If you use EnableTraceEx to enable a classic provider, the following translation occurs: + /// + /// + /// The Level parameter is the same as setting the EnableLevel parameter in EnableTrace. + /// + /// + /// + /// The MatchAnyKeyword is the same as setting the EnableFlag parameter in EnableTrace except that the keyword value is + /// truncated from a ULONGLONG to a ULONG value. + /// + /// + /// + /// + /// In the ControlCallback callback, the provider can call GetTraceEnableLevel to get the level and GetTraceEnableFlags + /// to get the enable flag. + /// + /// + /// + /// The other parameter are not used. + /// + /// + /// + /// A provider can define filters that a session uses to filter events based on event data. With the level and keywords that you + /// provide, ETW determines whether the event is written to the session but with filters, the provider uses the filter data to + /// determine whether it writes the event to the session. For example, if the provider generates process events, it could define a + /// data filter that filters process events based on the process identifier. If the identifier of the process did not match the + /// identifier that you passed as filter data, the provider would prevent event from being written to your session. + /// + /// + /// On Windows 8.1,Windows Server 2012 R2, and later, payload filters can be used by the EnableTraceEx2 function to filter on + /// specific conditions in a logger session. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/enabletraceex-func ULONG EnableTraceEx( _In_ LPCGUID ProviderId, _In_opt_ + // LPCGUID SourceId, _In_ TRACEHANDLE TraceHandle, _In_ ULONG IsEnabled, _In_ UCHAR Level, _In_ ULONGLONG MatchAnyKeyword, _In_ + // ULONGLONG MatchAllKeyword, _In_ ULONG EnableProperty, _In_opt_ PEVENT_FILTER_DESCRIPTOR EnableFilterDesc ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntrace.h", MSDNShortId = "1c675bf7-f292-49b1-8b60-720499a497fd")] + public static extern Win32Error EnableTraceEx(in Guid ProviderId, in Guid SourceId, TRACEHANDLE TraceHandle, [MarshalAs(UnmanagedType.Bool)] bool IsEnabled, byte Level, ulong MatchAnyKeyword, ulong MatchAllKeyword, uint EnableProperty, in EVENT_FILTER_DESCRIPTOR EnableFilterDesc); + + /// + /// The EnableTraceEx2 function enables or disables the specified event trace provider. + /// This function supersedes the EnableTraceEx function. + /// + /// + /// A handle of the event tracing session to which you want to enable or disable the provider. The StartTrace function returns + /// this handle. + /// + /// A GUID of the event trace provider that you want to enable or disable. + /// You can specify one of the following control codes: + /// + /// A provider-defined value that specifies the level of detail included in the event. Specify one of the following levels that are + /// defined in the Winmeta.h header file. Higher numbers imply that you get lower levels as well. For example, if you specify + /// TRACE_LEVEL_WARNING, you also receive all warning, error, and critical events. + /// + /// + /// A bitmask of keywords that determine the category of events that you want the provider to write. The provider writes the event if + /// any of the event's keyword bits match any of the bits set in this mask. See Remarks. + /// + /// + /// This bitmask is optional. This mask further restricts the category of events that you want the provider to write. If the event's + /// keyword meets the MatchAnyKeyword condition, the provider will write the event only if all of the bits in this mask exist in the + /// event's keyword. This mask is not used if MatchAnyKeyword is zero. See Remarks. + /// + /// + /// Set to zero to enable the trace asynchronously; this is the default. If the timeout value is zero, this function calls the + /// provider's enable callback and returns immediately. To enable the trace synchronously, specify a timeout value, in milliseconds. + /// If you specify a timeout value, this function calls the provider's enable callback and waits until the callback exits or the + /// timeout expires. To wait forever, set to INFINITE. + /// + /// + /// The trace parameters used to enable the provider. For details, see ENABLE_TRACE_PARAMETERS and ENABLE_TRACE_PARAMETERS_V1. + /// + /// + /// If the function is successful, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is incorrect. This can occur if any of the following are true: + /// + /// + /// ERROR_TIMEOUT + /// The timeout value expired before the enable callback completed. For details, see the Timeout parameter. + /// + /// + /// ERROR_INVALID_FUNCTION + /// You cannot update the level when the provider is not registered. + /// + /// + /// ERROR_NO_SYSTEM_RESOURCES + /// Exceeded the number of trace sessions that can enable the provider. + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, + /// LocalService, or NetworkService can enable trace providers. To grant a restricted user the ability to enable a trace provider, + /// add them to the Performance Log Users group or see EventAccessControl. Windows XP and Windows 2000: Anyone can enable a trace provider. + /// + /// + /// + /// + /// + /// Event trace controllers call this function. + /// + /// The provider defines its interpretation of being enabled or disabled. Typically, if a provider has been enabled, it generates + /// events, but while it is disabled, it does not. + /// + /// Event Tracing for Windows (ETW) supports several categories of filtering. + /// + /// + /// + /// Schematized filtering - This is the traditional filtering setup also called provider-side filtering. The controller defines a + /// custom set of filters as a binary object that is passed to the provider in the EnableTrace call. It is incumbent on the + /// controller and provider to define and interpret these filters and the controller should only log applicable events. This requires + /// a close coupling of the controller and provider since the type and format of the binary object of what can be filtered is not + /// defined. The TdhEnumerateProviderFilters function can be used to retrieve the filters defined in a manifest. + /// + /// + /// + /// + /// Scope filtering - Certain providers are enabled or not enabled to a session based on whether or not they meet the criteria + /// specified by the scope filters. There are several types of scope filters that allow filtering based on the event ID, the process + /// ID (PID), executable filename, the app ID, and the app package name. This feature is supported on Windows 8.1,Windows Server 2012 + /// R2, and later. + /// + /// + /// + /// + /// Stackwalk filtering - This notifies ETW to only perform a stack walk for a given set of event IDs. This feature is supported on + /// Windows 8.1,Windows Server 2012 R2, and later. + /// + /// + /// + /// + /// Event payload filtering - For manifest providers, events can be filtered on-the-fly based on whether or not they satisfy a + /// logical expression based on one or more predicates. + /// + /// + /// + /// + /// Every time EnableTraceEx2 is called, the filters for the provider in that session are replaced by the new parameters + /// defined by the parameters passed to the EnableTraceEx2 function. Multiple filters passed in a single EnableTraceEx2 + /// call can be combined with an additive effect. To disable filtering and thereby enable all providers/events in the logging + /// session, call EnableTraceEx2 with the EnableParameters parameter pointed to an ENABLE_TRACE_PARAMETERS structure + /// with the FilterDescCount member set to 0. + /// + /// + /// Each filter passed to the EnableTraceEx2 function is specified by a Type member in the + /// EVENT_FILTER_DESCRIPTOR. An array of EVENT_FILTER_DESCRIPTOR structures is passed in the + /// ENABLE_TRACE_PARAMETERS structure passed in the EnableParameters parameter to the EnableTraceEx2 function. + /// + /// + /// Each type of filter (a specific Type member) may only appear once in a call to the EnableTraceEx2 function, + /// however, some filter types allow multiple conditions to be included in a single filter. The maximum number of filters that can be + /// included in a call to EnableTraceEx2 is set by MAX_EVENT_FILTERS_COUNT defined to be 8 in the Evntprov.h header file. + /// + /// + /// Each filter type has its own size or entity limits based on the specific Type member in the EVENT_FILTER_DESCRIPTOR + /// structure. The list below indicates these limits. + /// + /// + /// + /// Term + /// Description + /// + /// + /// EVENT_FILTER_TYPE_SCHEMATIZED + /// Filter size limit: MAX_EVENT_FILTER_DATA_SIZE (1024) Number of elements allowed: Defined by provider and controller + /// + /// + /// EVENT_FILTER_TYPE_PID + /// Filter size limit: MAX_EVENT_FILTER_DATA_SIZE (1024) Number of elements allowed: MAX_EVENT_FILTER_PID_COUNT (8) + /// + /// + /// EVENT_FILTER_TYPE_EXECUTABLE_NAME + /// + /// Filter size limit: MAX_EVENT_FILTER_DATA_SIZE (1024) Number of elements allowed: A single string that can contain multiple + /// executable file names separated by semicolons. + /// + /// + /// + /// EVENT_FILTER_TYPE_PACKAGE_ID + /// + /// Filter size limit: MAX_EVENT_FILTER_DATA_SIZE (1024) Number of elements allowed: A single string that can contain multiple + /// package IDs separated by semicolons. + /// + /// + /// + /// EVENT_FILTER_TYPE_PACKAGE_APP_ID + /// + /// Filter size limit: MAX_EVENT_FILTER_DATA_SIZE (1024) Number of elements allowed: A single string that can contain multiple + /// package relative app IDs (PRAIDs) separated by semicolons. + /// + /// + /// + /// EVENT_FILTER_TYPE_PAYLOAD + /// Filter size limit: 1MAX_EVENT_FILTER_PAYLOAD_SIZE (4096) Number of elements allowed: 1 + /// + /// + /// EVENT_FILTER_TYPE_EVENT_ID + /// Filter size limit: Not defined Number of elements allowed: MAX_EVENT_FILTER_EVENT_ID_COUNT (64) + /// + /// + /// EVENT_FILTER_TYPE_STACKWALK + /// Filter size limit: Not defined Number of elements allowed: MAX_EVENT_FILTER_EVENT_ID_COUNT (64) + /// + /// + /// + /// To include all events that a provider provides, set MatchAnyKeyword to zero (for a manifest-based provider or TraceLogging + /// provider and 0xFFFFFFFF for a classic provider). To include specific events, set the MatchAnyKeyword mask to those specific + /// events. To indicate that you wish to enable a Provider Group, use the EVENT_ENABLE_PROPERTY_PROVIDER_GROUP flag on the + /// EnableProperty member of EnableParameters. For example, if the provider defines an event for its initialization and + /// cleanup routines (set keyword bit 0), an event for its file operations (set keyword bit 1), and an event for its calculation + /// operations (set keyword bit 2), you can set MatchAnyKeyword to 5 to receive initialization and cleanup events and calculation events. + /// + /// + /// If the provider defines more complex event keywords, for example, the provider defines an event that sets bit 0 for read and bit + /// 1 for local access and a second event that sets bit 0 for read and bit 2 for remote access, you could set MatchAnyKeyword to 1 to + /// receive all read events, or you could set MatchAnykeyword to 1 and MatchAllKeywords to 3 to receive local reads only. + /// + /// + /// If an event's keyword is zero, the provider will write the event to the session, regardless of the MatchAnyKeyword and + /// MatchAllKeyword masks. + /// + /// + /// When you call EnableTraceEx2 the provider may or may not be registered. If the provider is registered, ETW calls the + /// provider's callback function, if it implements one, and the session begins receiving events. If the provider is not registered, + /// ETW will call the provider's callback function when it registers itself, if it implements one, and the session will begin + /// receiving events. If the provider is not registered, the provider's callback function will not receive the source ID or filter + /// data. You can call EnableTraceEx2 one time to enable a provider before the provider registers itself. + /// + /// + /// If the provider is registered and already enabled to your session, you can also use this function to update the Level, + /// MatchAnyKeyword, MatchAllKeyword parameters, and the EnableProperty and EnableFilterDesc members of EnableParameters. + /// + /// + /// On Windows 8.1,Windows Server 2012 R2, and later, event payload , scope, and stack walk filters can be used by the + /// EnableTraceEx2 function and the ENABLE_TRACE_PARAMETERS and EVENT_FILTER_DESCRIPTOR structures to filter on + /// specific conditions in a logger session. For more information on event payload filters, see the TdhCreatePayloadFilter, + /// and TdhAggregatePayloadFilters functions and the ENABLE_TRACE_PARAMETERS, EVENT_FILTER_DESCRIPTOR, and + /// PAYLOAD_FILTER_PREDICATE structures. + /// + /// + /// You do not call EnableTraceEx2 to enable kernel providers. To enable kernel providers, set the EnableFlags member + /// of EVENT_TRACE_PROPERTIES which you then pass to StartTrace. The StartTrace function enables the selected + /// kernel providers. + /// + /// + /// Up to eight trace sessions can enable and receive events from the same manifest-based provider or TraceLogging provider; however, + /// only one trace session can enable a classic provider. If more than one session tried to enable a classic provider, the first + /// session would stop receiving events when the second session enabled the same provider. For example, if Session A enabled Provider + /// 1 and then Session B enabled Provider 1, only Session B would receive events from Provider 1. + /// + /// + /// The provider remains enabled for the session until the session disables the provider. If the application that started the session + /// ends without disabling the provider, the provider remains enabled. + /// + /// To determine the level and keywords used to enable a manifest-based provider, use one of the following commands: + /// + /// + /// Logman query providers + /// + /// + /// Wevtutil gp + /// + /// + /// + /// For classic providers, it is up to the provider to document and make available to potential controllers the severity levels or + /// enable flags that it supports. If the provider wants to be enabled by any controller, the provider should accept 0 for the + /// severity level and enable flags and interpret 0 as a request to perform default logging (whatever that may be). + /// + /// If you use EnableTraceEx2 to enable a classic provider, the following translation occurs: + /// + /// + /// The Level parameter is the same as setting the EnableLevel parameter in EnableTrace. + /// + /// + /// + /// The MatchAnyKeyword is the same as setting the EnableFlag parameter in EnableTrace except that the keyword value is + /// truncated from a ULONGLONG to a ULONG value. + /// + /// + /// + /// + /// In the ControlCallback callback, the provider can call GetTraceEnableLevel to get the level and GetTraceEnableFlags + /// to get the enable flag. + /// + /// + /// + /// The other parameter are not used. + /// + /// + /// + /// If EnableTraceEx2 returns ERROR_INVALID_PARAMETER when enabling filtering, you can turn on tracing to view + /// debugging messages about the failure. This requires a checked build. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/enabletraceex2 ULONG EnableTraceEx2( _In_ TRACEHANDLE TraceHandle, _In_ + // LPCGUID ProviderId, _In_ ULONG ControlCode, _In_ UCHAR Level, _In_ ULONGLONG MatchAnyKeyword, _In_ ULONGLONG MatchAllKeyword, _In_ + // ULONG Timeout, _In_opt_ PENABLE_TRACE_PARAMETERS EnableParameters ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntrace.h", MSDNShortId = "3aceffb6-614f-4cad-bbec-f181f0cbdbff")] + public static extern Win32Error EnableTraceEx2(TRACEHANDLE TraceHandle, in Guid ProviderId, EVENT_TRACE_CONTROL ControlCode, byte Level, ulong MatchAnyKeyword, ulong MatchAllKeyword, uint Timeout, in ENABLE_TRACE_PARAMETERS EnableParameters); + + /// + /// The EnumerateTraceGuids function retrieves information about registered event trace providers that are running on the computer. + /// + /// An array of pointers to TRACE_GUID_PROPERTIES structures. + /// Number of elements in the GuidPropertiesArray array. + /// Actual number of event tracing providers registered on the computer. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_MORE_DATA + /// + /// The property array is too small to receive information for all registered providers (GuidCount is greater than + /// PropertyArrayCount). The function fills the GUID property array with the number of structures specified in PropertyArrayCount. + /// + /// + /// + /// + /// + /// Event trace controllers call this function. + /// For information on registering event trace providers, see RegisterTraceGuids. + /// + /// You can use the TRACE_GUID_PROPERTIES.LoggerId member to determine which session enabled the provider if + /// TRACE_GUID_PROPERTIES.IsEnable is TRUE. + /// + /// The list will not include kernel providers. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/enumeratetraceguids ULONG EnumerateTraceGuids( _Inout_ PTRACE_GUID_PROPERTIES + // *GuidPropertiesArray, _In_ ULONG PropertyArrayCount, _Out_ PULONG GuidCount ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntrace.h", MSDNShortId = "9a9e2f53-9916-4a9c-a08e-c8affd5fc4c9")] + public static extern Win32Error EnumerateTraceGuids([In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] TRACE_GUID_PROPERTIES[] GuidPropertiesArray, uint PropertyArrayCount, out uint GuidCount); + + /// Use this function to retrieve information about trace providers that are registered on the computer. + /// + /// Determines the type of information to include with the list of registered providers. For possible values, see the + /// TRACE_QUERY_INFO_CLASS enumeration. + /// + /// + /// GUID of the provider or provider group whose information you want to retrieve. Specify the GUID only if TraceQueryInfoClass is + /// TraceGuidQueryInfo or TraceGroupQueryInfo. + /// + /// Size, in bytes, of the data InBuffer. + /// + /// Application-allocated buffer that contains the enumerated information. The format of the information depends on the value of + /// TraceQueryInfoClass. For details, see Remarks. + /// + /// + /// Size, in bytes, of the OutBuffer buffer. If the function succeeds, the ReturnLength parameter receives the size of the buffer + /// used. If the buffer is too small, the function returns ERROR_INSUFFICIENT_BUFFER and the ReturnLength parameter receives the + /// required buffer size. If the buffer size is zero on input, no data is returned in the buffer and the ReturnLength parameter + /// receives the required buffer size. + /// + /// Actual size of the data in OutBuffer, in bytes. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the parameters is not valid. + /// + /// + /// ERROR_INSUFFICIENT_BUFFER + /// + /// The OutBuffer buffer is too small to receive information for all registered providers. Reallocate the buffer using the size + /// returned in ReturnLength. + /// + /// + /// + /// + /// + /// Event trace controllers call this function. + /// + /// If TraceQueryInfoClass is TraceGuidQueryInfo, ETW returns the data in a TRACE_GUID_INFO block that is a header to + /// the information. The info block contains a TRACE_PROVIDER_INSTANCE_INFO block for each provider that uses the same GUID. + /// Each instance info block contains a TRACE_ENABLE_INFO structure for each session that enabled the provider. + /// + /// For information on registering event trace providers, see EventRegister and RegisterTraceGuids. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/enumeratetraceguidsex ULONG WINAPI EnumerateTraceGuidsEx( _In_ + // TRACE_QUERY_INFO_CLASS TraceQueryInfoClass, _In_ PVOID InBuffer, _In_ ULONG InBufferSize, _Out_ PVOID OutBuffer, _In_ ULONG + // OutBufferSize, _Out_ PULONG ReturnLength ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntrace.h", MSDNShortId = "9d70fe21-1750-4d60-a825-2004f7d666c7")] + public static extern Win32Error EnumerateTraceGuidsEx(TRACE_QUERY_INFO_CLASS TraceQueryInfoClass, IntPtr InBuffer, uint InBufferSize, IntPtr OutBuffer, uint OutBufferSize, out uint ReturnLength); + + /// Adds or modifies the permissions of the specified provider or session. + /// GUID that uniquely identifies the provider or session whose permissions you want to add or modify. + /// + /// Type of operation to perform, for example, add a DACL to the session's GUID or provider's GUID. For possible values, see the + /// EVENTSECURITYOPERATION enumeration. + /// + /// The security identifier (SID) of the user or group to whom you want to grant or deny permissions. + /// You can specify one or more of the following permissions: + /// + /// If TRUE, grant the user permissions to the session or provider; otherwise, deny permissions. This value is ignored if the + /// value of Operation is EventSecuritySetSACL or EventSecurityAddSACL. + /// + /// Returns ERROR_SUCCESS if successful. + /// + /// + /// By default, only the administrator of the computer, users in the Performance Log Users group, and services running as + /// LocalSystem, LocalService, NetworkService can control trace sessions and provide and consume event data. Only users with + /// administrative privileges and services running as LocalSystem can start and control an NT Kernel Logger session. + /// + /// + /// Windows Server 2003: Only users with administrator privileges can control trace sessions and consume event data; any user + /// can provide event data. + /// + /// Windows XP and Windows 2000: Any user can control trace sessions and provide and consume event data. + /// + /// Users with administrator privileges can control trace sessions if the tool that they use to control the session is started from a + /// Command Prompt window that is opened with Run as administrator.... + /// + /// + /// To grant a restricted user the ability to control trace sessions, you can add them to the Performance Log Users group or call + /// this function to grant them permission. For example, you can grant user A permission to start and stop a trace session and grant + /// user B permission to only query the session. + /// + /// To restrict who can log events to the session, see the TRACELOG_LOG_EVENT permission. + /// + /// The ACL on the log file determines who can consume event data from the log file. To consume events from a session in real-time, + /// you must grant the user TRACELOG_ACCESS_REALTIME permission or the user must be a member of the Performance Log Users group. + /// + /// You can also specify the provider's GUID to restrict who can register the provider and who can enable the provider. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntcons/nf-evntcons-eventaccesscontrol ULONG EVNTAPI EventAccessControl( + // LPGUID Guid, ULONG Operation, PSID Sid, ULONG Rights, BOOLEAN AllowOrDeny ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntcons.h", MSDNShortId = "699bb165-680f-4d3b-8859-959f319ca4be")] + public static extern Win32Error EventAccessControl(in Guid Guid, EVENTSECURITYOPERATION Operation, PSID Sid, TRACELOG_RIGHTS Rights, [MarshalAs(UnmanagedType.U1)] bool AllowOrDeny); + + /// Retrieves the permissions for the specified controller or provider. + /// GUID that uniquely identifies the provider or session. + /// Application-allocated buffer that will contain the security descriptor of the controller or provider. + /// + /// Size of the security descriptor buffer, in bytes. If the function succeeds, this parameter receives the size of the buffer used. + /// If the buffer is too small, the function returns ERROR_MORE_DATA and this parameter receives the required buffer size. If the + /// buffer size is zero on input, no data is returned in the buffer and this parameter receives the required buffer size. + /// + /// + /// Returns ERROR_SUCCESS if successful. + /// The function returns the following return code if an error occurs: + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_MORE_DATA + /// The buffer is too small to receive the security descriptor. Reallocate the buffer using the size returned in BufferSize. + /// + /// + /// + /// + /// + /// If the GUID does not exist in the registry, ETW returns the default permissions for a provider or controller. For details on + /// specifying the GUID in the registry, see EventAccessControl. + /// + /// + /// For information on accessing the components of the security descriptor, see Getting Information from an ACL, the + /// GetSecurityDescriptorDacl, GetSecurityDescriptorSacl, and GetAce functions, and the ACE structure. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntcons/nf-evntcons-eventaccessquery ULONG EVNTAPI EventAccessQuery( LPGUID + // Guid, PSECURITY_DESCRIPTOR Buffer, PULONG BufferSize ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntcons.h", MSDNShortId = "21c87137-0e8f-43d1-9dad-9f2b4fc591a3")] + public static extern Win32Error EventAccessQuery(in Guid Guid, SafeSECURITY_DESCRIPTOR Buffer, ref uint BufferSize); + + /// Removes the permissions defined in the registry for the specified provider or session. + /// GUID that uniquely identifies the provider or session whose permissions you want to remove from the registry. + /// Returns ERROR_SUCCESS if successful. + /// + /// After removing the permission from the registry, the default permissions apply to the provider or session. For details on the + /// default permissions, see EventAccessControl. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntcons/nf-evntcons-eventaccessremove ULONG EVNTAPI EventAccessRemove( + // LPGUID Guid ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntcons.h", MSDNShortId = "9f25f163-046c-41b0-82f9-0b214b74b87e")] + public static extern Win32Error EventAccessRemove(in Guid Guid); + + /// + /// + /// The FlushTrace function causes an event tracing session to immediately deliver buffered events for the specified session. + /// (An event tracing session does not deliver events until an active buffer is full.) + /// + /// The ControlTrace function supersedes this function. + /// + /// + /// Handle to the event tracing session for whose buffers you want to flush, or NULL. You must specify SessionHandle if + /// SessionName is NULL. However, ETW ignores the handle if SessionName is not NULL. The handle is returned by the + /// StartTrace function. + /// + /// + /// + /// Pointer to a null-terminated string that specifies the name of the event tracing session whose buffers you want to flush, or + /// NULL. You must specify SessionName if SessionHandle is NULL. + /// + /// To specify the NT Kernel Logger session, set SessionName to KERNEL_LOGGER_NAME. + /// + /// + /// Pointer to an initialized EVENT_TRACE_PROPERTIES structure. + /// + /// If you are using a newly initialized structure, you only need to set the Wnode.BufferSize, Wnode.Guid, + /// LoggerNameOffset, and LogFileNameOffset members of the structure. You can use the maximum session name (1024 + /// characters) and maximum log file name (1024 characters) lengths to calculate the buffer size and offsets if not known. + /// + /// + /// On output, the structure receives the property settings and session statistics of the event tracing session, which reflect the + /// state of the session after the flush. + /// + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_BAD_LENGTH + /// One of the following is true: + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, + /// LocalService, NetworkService can control event tracing sessions. To grant a restricted user the ability to control trace + /// sessions, add them to the Performance Log Users group. Windows XP and Windows 2000: Anyone can control a trace session. + /// + /// + /// + /// + /// + /// Controllers call this function. + /// + /// Typically, you do not need to flush buffers yourself. However, you may want to flush buffers if the event rate is low and you are + /// delivering events in real time. + /// + /// Note that it is not safe to flush buffers from DllMain. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/nf-evntrace-flushtracea ULONG WMIAPI FlushTraceA( TRACEHANDLE + // TraceHandle, LPCSTR InstanceName, PEVENT_TRACE_PROPERTIES Properties ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("evntrace.h", MSDNShortId = "bc7d0dac-93d9-4614-9cb6-fee99765eb39")] + public static extern Win32Error FlushTrace(TRACEHANDLE TraceHandle, string InstanceName, ref EVENT_TRACE_PROPERTIES Properties); + + /// + /// + /// The GetTraceEnableFlags function retrieves the enable flags passed by the controller to indicate which category of events + /// to trace. + /// + /// Providers can only call this function from their ControlCallback function. + /// + /// Handle to an event tracing session, obtained by calling the GetTraceLoggerHandle function. + /// + /// Returns the value the controller specified in the EnableFlag parameter when calling the EnableTrace function. + /// To determine if the function failed or the controller set the enable flags to 0, follow these steps: + /// + /// + /// Call the SetLastError function to set the last error to ERROR_SUCCESS. + /// + /// + /// Call the GetTraceEnableFlags function to retrieve the enable flags. + /// + /// + /// If the enable flags value is 0, call the GetLastError function to retrieve the last known error. + /// + /// + /// + /// If the last known error is ERROR_SUCCESS, the controller set the enable flags to 0; otherwise, the + /// GetTraceEnableFlags function failed with the last known error. + /// + /// + /// + /// + /// + /// Providers can use this value to control which events that it generates. For example, a provider can group events into logical + /// categories of events and use this value to enable or disable their generation. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/gettraceenableflags ULONG GetTraceEnableFlags( _In_ TRACEHANDLE SessionHandle ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "e5c0f2bf-34da-4555-9556-4c79ee9a73ab")] + public static extern uint GetTraceEnableFlags(TRACEHANDLE SessionHandle); + + /// + /// + /// The GetTraceEnableLevel function retrieves the severity level passed by the controller to indicate the level of logging + /// the provider should perform. + /// + /// Providers can only call this function from their ControlCallback function. + /// + /// Handle to an event tracing session, obtained by calling the GetTraceLoggerHandle function. + /// + /// Returns the value the controller specified in the EnableLevel parameter when calling the EnableTrace function. + /// To determine if the function failed or the controller set the enable flags to 0, follow these steps: + /// + /// + /// Call the SetLastError function to set the last error to ERROR_SUCCESS. + /// + /// + /// Call the GetTraceEnableLevel function to retrieve the enable level. + /// + /// + /// If the enable level value is 0, call the GetLastError function to retrieve the last known error. + /// + /// + /// + /// If the last known error is ERROR_SUCCESS, the controller set the enable level to 0; otherwise, the + /// GetTraceEnableLevel function failed with the last known error. + /// + /// + /// + /// + /// + /// Providers use this value to control the severity of events that it generates. For example, providers can use this value to + /// determine if it should generate informational, warning, or error events. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/gettraceenablelevel UCHAR GetTraceEnableLevel( _In_ TRACEHANDLE SessionHandle ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "22326fd9-c428-4430-8a92-978d005f6705")] + public static extern byte GetTraceEnableLevel(TRACEHANDLE SessionHandle); + + /// + /// The GetTraceLoggerHandle function retrieves the handle of the event tracing session. + /// Providers can only call this function from their ControlCallback function. + /// + /// + /// + /// Pointer to a WNODE_HEADER structure. ETW passes this structure to the provider's ControlCallback function in the + /// Buffer parameter. + /// + /// The HistoricalContext member of WNODE_HEADER contains the session's handle. + /// + /// + /// If the function succeeds, it returns the event tracing session handle. + /// + /// If the function fails, it returns INVALID_HANDLE_VALUE. To get extended error information, call the GetLastError function. + /// + /// + /// + /// You use the handle when calling the GetTraceEnableFlags and GetTraceEnableLevel functions to retrieve the enable + /// flags and level values passed to the EnableTrace function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/gettraceloggerhandle TRACEHANDLE GetTraceLoggerHandle( _In_ PVOID Buffer ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "050d3a01-0087-40f1-af35-b9ceeaf47813")] + public static extern TRACEHANDLE GetTraceLoggerHandle(IntPtr Buffer); + + /// The OpenTrace function opens a real-time trace session or log file for consuming. + /// + /// Pointer to an EVENT_TRACE_LOGFILE structure. The structure specifies the source from which to consume events (from a log file or + /// the session in real time) and specifies the callbacks the consumer wants to use to receive the events. + /// + /// + /// If the function succeeds, it returns a handle to the trace. + /// If the function fails, it returns INVALID_PROCESSTRACE_HANDLE. + /// + /// Note If your code base supports Windows 7 and Windows Vista, and also supports earlier operating systems such as Windows + /// XP and Windows Server 2003, do not use the constants described above. Instead, determine the operating system on which you are + /// running and compare the return value to the following values. + /// + /// + /// If the function returns INVALID_PROCESSTRACE_HANDLE, you can use the GetLastError function to obtain extended error information. + /// The following table lists some common errors and their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// The Logfile parameter is NULL. + /// + /// + /// ERROR_BAD_PATHNAME + /// If you did not specify the LoggerName member of EVENT_TRACE_LOGFILE, you must specify a valid log file name. + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, + /// LocalService, NetworkService can consume events in real time. To grant a restricted user the ability to consume events in real + /// time, add them to the Performance Log Users group. Windows XP and Windows 2000: Anyone can consume real time events. + /// + /// + /// + /// + /// + /// Consumers call this function. + /// + /// After calling OpenTrace, call the ProcessTrace function to process the events. When you have finished processing events, + /// call the CloseTrace function. + /// + /// Note that you can process events from only one real-time session. + /// + /// Windows Vista and earlier: If the function fails it will returns INVALID_HANDLE_VALUE. To avoid compile-time errors, cast + /// INVALID_HANDLE_VALUE to TRACEHANDLE as follows: . + /// + /// Examples + /// + /// For an example that uses OpenTrace, see Using TdhFormatProperty to Consume Event Data or Retrieving Event Data Using MOF. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/nf-evntrace-opentracea TRACEHANDLE WMIAPI OpenTraceA( + // PEVENT_TRACE_LOGFILEA Logfile ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("evntrace.h", MSDNShortId = "505e643b-6b4f-4f93-96c8-7fe8abdd6234")] + public static extern TRACEHANDLE OpenTrace(in EVENT_TRACE_LOGFILE Logfile); + + /// The ProcessTrace function delivers events from one or more event tracing sessions to the consumer. + /// + /// + /// Pointer to an array of trace handles obtained from earlier calls to the OpenTrace function. The number of handles that you + /// can specify is limited to 64. + /// + /// The array can contain the handles to multiple log files, but only one real-time trace session. + /// + /// Number of elements in HandleArray. + /// + /// Pointer to an optional FILETIME structure that specifies the beginning time period for which you want to receive events. + /// The function does not deliver events recorded prior to StartTime. + /// + /// + /// + /// Pointer to an optional FILETIME structure that specifies the ending time period for which you want to receive events. The + /// function does not deliver events recorded after EndTime. + /// + /// Windows Server 2003: This value is ignored for real-time event delivery. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// HandleCount is not valid or the number of handles is greater than 64. + /// + /// + /// ERROR_INVALID_HANDLE + /// An element of HandleArray is not a valid event tracing session handle. + /// + /// + /// ERROR_INVALID_TIME + /// EndTime is less than StartTime. + /// + /// + /// ERROR_INVALID_PARAMETER + /// HandleArray is NULL. + /// + /// + /// ERROR_NOACCESS + /// An exception occurred in one of the callback functions that receives the events. + /// + /// + /// ERROR_CANCELLED + /// Indicates the consumer canceled processing by returning FALSE in their BufferCallback function. + /// + /// + /// ERROR_WMI_INSTANCE_NOT_FOUND + /// + /// The session from which you are trying to consume events in real time is not running or does not have the real-time trace mode enabled. + /// + /// + /// + /// ERROR_WMI_ALREADY_ENABLED + /// The HandleArray parameter contains the handle to more than one real-time session. + /// + /// + /// + /// + /// Consumers call this function. + /// You must call the OpenTrace function prior to calling ProcessTrace. + /// + /// The ProcessTrace function delivers the events to the consumer's BufferCallback, EventCallback, and + /// EventClassCallback callback functions. + /// + /// + /// The ProcessTrace function sorts the events chronologically and delivers all events generated between StartTime and + /// EndTime. Note that events can appear out of order if the session specifies system time as the clock (low resolution) and the + /// volume of events is high. In this case, it is possible for multiple events to contain the same time stamp. If multiple events + /// contain the same time stamp, ETW cannot guarantee the order of those events. + /// + /// + /// The ProcessTrace function blocks the thread until it delivers all events, the BufferCallback function returns + /// FALSE, or you call CloseTrace. If the consumer is consuming events in real time, the ProcessTrace function + /// returns after the controller stops the trace session. (Note that there may be a several-second delay before the function returns.) + /// + /// Windows Server 2003: You can call CloseTrace only after ProcessTrace returns. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/processtrace ULONG ProcessTrace( _In_ PTRACEHANDLE HandleArray, _In_ ULONG + // HandleCount, _In_ LPFILETIME StartTime, _In_ LPFILETIME EndTime ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "aea25a95-f435-4068-9b15-7473f31ebf16")] + public static extern Win32Error ProcessTrace([In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] TRACEHANDLE[] HandleArray, uint HandleCount, in FILETIME StartTime, in FILETIME EndTime); + + /// The ProcessTrace function delivers events from one or more event tracing sessions to the consumer. + /// + /// + /// Pointer to an array of trace handles obtained from earlier calls to the OpenTrace function. The number of handles that you + /// can specify is limited to 64. + /// + /// The array can contain the handles to multiple log files, but only one real-time trace session. + /// + /// Number of elements in HandleArray. + /// + /// Pointer to an optional FILETIME structure that specifies the beginning time period for which you want to receive events. + /// The function does not deliver events recorded prior to StartTime. + /// + /// + /// + /// Pointer to an optional FILETIME structure that specifies the ending time period for which you want to receive events. The + /// function does not deliver events recorded after EndTime. + /// + /// Windows Server 2003: This value is ignored for real-time event delivery. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// HandleCount is not valid or the number of handles is greater than 64. + /// + /// + /// ERROR_INVALID_HANDLE + /// An element of HandleArray is not a valid event tracing session handle. + /// + /// + /// ERROR_INVALID_TIME + /// EndTime is less than StartTime. + /// + /// + /// ERROR_INVALID_PARAMETER + /// HandleArray is NULL. + /// + /// + /// ERROR_NOACCESS + /// An exception occurred in one of the callback functions that receives the events. + /// + /// + /// ERROR_CANCELLED + /// Indicates the consumer canceled processing by returning FALSE in their BufferCallback function. + /// + /// + /// ERROR_WMI_INSTANCE_NOT_FOUND + /// + /// The session from which you are trying to consume events in real time is not running or does not have the real-time trace mode enabled. + /// + /// + /// + /// ERROR_WMI_ALREADY_ENABLED + /// The HandleArray parameter contains the handle to more than one real-time session. + /// + /// + /// + /// + /// Consumers call this function. + /// You must call the OpenTrace function prior to calling ProcessTrace. + /// + /// The ProcessTrace function delivers the events to the consumer's BufferCallback, EventCallback, and + /// EventClassCallback callback functions. + /// + /// + /// The ProcessTrace function sorts the events chronologically and delivers all events generated between StartTime and + /// EndTime. Note that events can appear out of order if the session specifies system time as the clock (low resolution) and the + /// volume of events is high. In this case, it is possible for multiple events to contain the same time stamp. If multiple events + /// contain the same time stamp, ETW cannot guarantee the order of those events. + /// + /// + /// The ProcessTrace function blocks the thread until it delivers all events, the BufferCallback function returns + /// FALSE, or you call CloseTrace. If the consumer is consuming events in real time, the ProcessTrace function + /// returns after the controller stops the trace session. (Note that there may be a several-second delay before the function returns.) + /// + /// Windows Server 2003: You can call CloseTrace only after ProcessTrace returns. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/processtrace ULONG ProcessTrace( _In_ PTRACEHANDLE HandleArray, _In_ ULONG + // HandleCount, _In_ LPFILETIME StartTime, _In_ LPFILETIME EndTime ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "aea25a95-f435-4068-9b15-7473f31ebf16")] + public static extern Win32Error ProcessTrace([In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] TRACEHANDLE[] HandleArray, uint HandleCount, IntPtr StartTime = default, IntPtr EndTime = default); + + /// + /// The QueryAllTraces function retrieves the properties and statistics for all event tracing sessions started on the computer + /// for which the caller has permissions to query. + /// + /// + /// + /// An array of pointers to EVENT_TRACE_PROPERTIES structures that receive session properties and statistics for the event tracing sessions. + /// + /// + /// You only need to set the Wnode.BufferSize, LoggerNameOffset , and LogFileNameOffset members of the + /// EVENT_TRACE_PROPERTIES structure. The other members should all be set to zero. + /// + /// + /// + /// Number of structures in the PropertyArray array. This value must be less than or equal to 64, the maximum number of event tracing + /// sessions that ETW supports. + /// + /// Actual number of event tracing sessions started on the computer. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_MORE_DATA + /// + /// The property array is too small to receive information for all sessions (SessionCount is greater than PropertyArrayCount). The + /// function fills the property array with the number of property structures specified in PropertyArrayCount. + /// + /// + /// + /// + /// + /// Event trace controllers call this function. + /// + /// This function retrieves the trace sessions that the caller has permissions to query. Users running with elevated administrative + /// privileges, users in the Performance Log Users group, and services running as LocalSystem, LocalService, NetworkService can view + /// all tracing sessions. + /// + /// This function does not return private logging sessions. + /// To retrieve information for a single session, use the ControlTrace function and set the ControlCode parameter to EVENT_TRACE_CONTROL_QUERY. + /// Examples + /// The following example shows how to call this function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/nf-evntrace-queryalltracesa ULONG WMIAPI QueryAllTracesA( + // PEVENT_TRACE_PROPERTIES *PropertyArray, ULONG PropertyArrayCount, PULONG LoggerCount ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("evntrace.h", MSDNShortId = "6b6144b0-9152-4b5e-863d-06e823fbe084")] + public static extern Win32Error QueryAllTraces([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] EVENT_TRACE_PROPERTIES[] PropertyArray, uint PropertyArrayCount, out uint LoggerCount); + + /// + /// + /// The QueryTrace function retrieves the property settings and session statistics for the specified event tracing session. + /// + /// The ControlTrace function supersedes this function. + /// + /// TBD + /// TBD + /// TBD + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// One of the following is true: + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users running with elevated administrative privileges, users in the Performance Log Users group, and services running as + /// LocalSystem, LocalService, NetworkService can query event tracing sessions. To grant a restricted user the ability to query trace + /// sessions, add them to the Performance Log Users group or see EventAccessControl. Windows XP and Windows 2000: Anyone can control + /// a trace session. + /// + /// + /// + /// ERROR_WMI_INSTANCE_NOT_FOUND + /// The given session is not running. + /// + /// + /// + /// + /// Controllers call this function. + /// To update the property settings and session statistics for an event tracing session, call the UpdateTrace function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/nf-evntrace-querytracea ULONG WMIAPI QueryTraceA( TRACEHANDLE + // TraceHandle, LPCSTR InstanceName, PEVENT_TRACE_PROPERTIES Properties ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("evntrace.h", MSDNShortId = "8ad0f4f6-902c-490e-b26e-7499dd99fc95")] + public static extern Win32Error QueryTrace(TRACEHANDLE TraceHandle, string InstanceName, ref EVENT_TRACE_PROPERTIES Properties); + + /// Queries the system for the trace processing handle. + /// A valid handle created with OpenTrace that the data should be queried from. + /// + /// An ETW_PROCESS_HANDLE_INFO_TYPE value that specifies what kind of operation will be done on the handle. + /// + /// Reserved for future use. May be null. + /// Size in bytes of the InBuffer. + /// Buffer provided by the caller to contain output data. + /// Size in bytes of OutBuffer. + /// The size in bytes of the data that the API wrote into OutBuffer. Important for variable length returns. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is one of the system error codes. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/querytraceprocessinghandle ULONG WINAPI QueryTraceProcessingHandle( _In_ + // TRACEHANDLE ProcessingHandle, _In_ ETW_PROCESS_HANDLE_INFO_TYPE InformationClass, _In_opt_ PVOID InBuffer, _In_ ULONG + // InBufferSize, _Out_opt_ PVOID OutBuffer, _In_ ULONG OutBufferSize, _Out_ PULONG ReturnLength ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("evntrace.h", MSDNShortId = "87666275-8752-4EC8-9C01-16D36AE4C5E8")] + public static extern Win32Error QueryTraceProcessingHandle(TRACEHANDLE ProcessingHandle, ETW_PROCESS_HANDLE_INFO_TYPE InformationClass, [In, Optional] IntPtr InBuffer, uint InBufferSize, [Out, Optional] IntPtr OutBuffer, uint OutBufferSize, out uint ReturnLength); + + /// + /// The RegisterTraceGuids function registers an event trace provider and the event trace classes that it uses to generate + /// events. This function also specifies the function the provider uses to enable and disable tracing. + /// + /// + /// Pointer to a ControlCallback function that receives notification when the provider is enabled or disabled by an event + /// tracing session. The EnableTrace function calls the callback. + /// + /// Pointer to an optional provider-defined context that ETW passes to the function specified by RequestAddress. + /// GUID of the registering provider. + /// + /// Number of elements in the TraceGuidReg array. If TraceGuidReg is NULL, set this parameter to 0. + /// + /// + /// + /// Pointer to an array of TRACE_GUID_REGISTRATION structures. Each element identifies a category of events that the provider provides. + /// + /// + /// On input, the Guid member of each structure contains an event trace class GUID assigned by the registering provider. The + /// class GUID identifies a category of events that the provider provides. Providers use the same class GUID to set the Guid member + /// of EVENT_TRACE_HEADER when calling the TraceEvent function to log the event. + /// + /// + /// On output, the RegHandle member receives a handle to the event's class GUID registration. If the provider calls the + /// TraceEventInstance function, use the RegHandle member of TRACE_GUID_REGISTRATION to set the RegHandle + /// member of EVENT_INSTANCE_HEADER. + /// + /// + /// This parameter can be NULL if the provider calls only the TraceEvent function to log events. If the provider calls + /// the TraceEventInstance function to log events, this parameter cannot be NULL. + /// + /// + /// + /// + /// This parameter is not supported, set to NULL. You should use Mofcomp.exe to register the MOF resource during the setup of + /// your application. For more information see, Publishing Your Event Schema. + /// + /// + /// Windows XP with SP1, Windows XP and Windows 2000: Pointer to an optional string that specifies the path of the DLL or + /// executable program that contains the resource specified by MofResourceName. This parameter can be NULL if the event + /// provider and consumer use another mechanism to share information about the event trace classes used by the provider. + /// + /// + /// + /// + /// This parameter is not supported, set to NULL. You should use Mofcomp.exe to register the MOF resource during the setup of + /// your application. For more information see, Publishing Your Event Schema. + /// + /// + /// Windows XP with SP1, Windows XP and Windows 2000: Pointer to an optional string that specifies the string resource of + /// MofImagePath. The string resource contains the name of the binary MOF file that describes the event trace classes supported by + /// the provider. + /// + /// + /// + /// Pointer to the provider's registration handle. Use this handle when you call the UnregisterTraceGuids function. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// One of the following is true: Windows XP and Windows 2000: TraceGuidReg is NULL or GuidCount is less than or equal to zero. + /// + /// + /// + /// + /// + /// Providers call this function. + /// + /// If the provider's ControlGuid has been previously registered and enabled, subsequent registrations that reference the same + /// ControlGuid are automatically enabled. + /// + /// + /// A process can register up to 1,024 provider GUIDs; however, you should limit the number of providers that your process registers + /// to one or two. This limit includes those registered using this function and the EventRegister function. + /// + /// Prior to Windows Vista: There is no limit to the number of providers that a process can register. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/registertraceguids ULONG RegisterTraceGuids( _In_ WMIDPREQUEST + // RequestAddress, _In_ PVOID RequestContext, _In_ LPCGUID ControlGuid, _In_ ULONG GuidCount, _Inout_ PTRACE_GUID_REGISTRATION + // TraceGuidReg, _In_ LPCTSTR MofImagePath, _In_ LPCTSTR MofResourceName, _Out_ PTRACEHANDLE RegistrationHandle ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("evntrace.h", MSDNShortId = "c9158292-281b-4a02-b280-956e340d225c")] + public static extern Win32Error RegisterTraceGuids([MarshalAs(UnmanagedType.FunctionPtr)] ControlCallback RequestAddress, IntPtr RequestContext, in Guid ControlGuid, uint GuidCount, ref TRACE_GUID_REGISTRATION TraceGuidReg, string MofImagePath, string MofResourceName, out TRACEHANDLE RegistrationHandle); + + /// + /// [Do not use this function; it may be unavailable in subsequent versions.] + /// + /// The RemoveTraceCallback function stops an EventClassCallback function from receiving events for an event trace class. + /// + /// + /// + /// Pointer to the class GUID of the event trace class for which the callback receives events. Use the same class GUID that you + /// passed to the SetTraceCallback to begin receiving the events. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// The pGuid parameter is NULL. + /// + /// + /// ERROR_WMI_GUID_NOT_FOUND + /// There is no EventClassCallback function associated with the event trace class. + /// + /// + /// + /// Consumers call this function. + // https://docs.microsoft.com/en-us/windows/desktop/ETW/removetracecallback ULONG RemoveTraceCallback( _In_ LPCGUID pGuid ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "da779e8d-4984-44e3-8731-647a422b55b2")] + public static extern Win32Error RemoveTraceCallback(in Guid pGuid); + + /// + /// + /// [Do not use this function; it may be unavailable in subsequent versions. Instead, filter for the event trace class in your + /// EventRecordCallback function.] + /// + /// + /// The SetTraceCallback function specifies an EventClassCallback function to process events for the specified event + /// trace class. + /// + /// + /// + /// Pointer to the class GUID of an event trace class for which you want to receive events. For a list of kernel provider class + /// GUIDs, see NT Kernel Logger Constants. + /// + /// + /// Pointer to an EventClassCallback function used to process events belonging to the event trace class. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// + /// + /// Consumers call this function. + /// + /// You can only specify one callback function for an event trace class. If you specify more than one callback function for the even + /// trace class, the last callback function receives the events for that event trace class. + /// + /// + /// To stop the callback function from receiving events for the event trace class, call the RemoveTraceCallback function. The + /// callback automatically stops receiving callbacks when you close the trace. + /// + /// + /// You can use this function to receive events written using one of the TraceEvent functions. You cannot use this function to + /// consume events from a provider that used one of the EventWrite functions to log events. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/settracecallback ULONG SetTraceCallback( _In_ LPCGUID pGuid, _In_ + // PEVENT_CALLBACK EventCallback ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "8663f64f-a203-43e5-94e8-337f2d81c3a0")] + public static extern Win32Error SetTraceCallback(in Guid pGuid, EventClassCallback EventCallback); + + /// The StartTrace function registers and starts an event tracing session. + /// + /// Handle to the event tracing session. + /// + /// Do not use this handle if the function fails. Do not compare the session handle to INVALID_HANDLE_VALUE; the session handle is 0 + /// if the handle is not valid. + /// + /// + /// + /// + /// Null-terminated string that contains the name of the event tracing session. The session name is limited to 1,024 characters, is + /// case-insensitive, and must be unique. + /// + /// + /// Windows 2000: Session names are case-sensitive. As a result, duplicate session names are allowed. However, to reduce + /// confusion, you should make sure your session names are unique. + /// + /// + /// This function copies the session name that you provide to the offset that the LoggerNameOffset member of Properties points to. + /// + /// + /// + /// + /// Pointer to an EVENT_TRACE_PROPERTIES structure that specifies the behavior of the session. The following are key members of the + /// structure to set: + /// + /// + /// + /// Wnode.BufferSize + /// + /// + /// Wnode.Guid + /// + /// + /// Wnode.ClientContext + /// + /// + /// Wnode.Flags + /// + /// + /// LogFileMode + /// + /// + /// LogFileNameOffset + /// + /// + /// LoggerNameOffset + /// + /// + /// Depending on the type of log file you choose to create, you may also need to specify a value for + /// MaximumFileSize + /// . See the Remarks section for more information on setting the + /// Properties + /// parameter and the behavior of the session. + /// + /// Starting with Windows 10, version 1703: For better performance in cross process scenarios, you can now pass filtering in + /// to StartTrace when starting system wide private loggers. You will need to pass in the new EVENT_TRACE_PROPERTIES_V2 + /// structure to include filtering information. See Configuring and Starting a Private Logger Session for more details. + /// + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// One of the following is true: + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_ALREADY_EXISTS + /// A session with the same name or GUID is already running. + /// + /// + /// ERROR_BAD_PATHNAME + /// You can receive this error for one of the following reasons: + /// + /// + /// ERROR_DISK_FULL + /// + /// There is not enough free space on the drive for the log file. This occurs if: Choose a drive with more space, or decrease the + /// size specified in MaximumFileSize (if used). Windows 2000: Does not require an additional 200 MB available disk space. + /// + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, + /// LocalService, NetworkService can control event tracing sessions. To grant a restricted user the ability to control trace + /// sessions, add them to the Performance Log Users group. Only users with administrative privileges and services running as + /// LocalSystem can control an NT Kernel Logger session. Windows XP and Windows 2000: Anyone can control a trace session. If the user + /// is a member of the Performance Log Users group, they may not have permission to create the log file in the specified folder. + /// + /// + /// + /// ERROR_NO_SYSTEM_RESOURCES + /// + /// The maximum number of logging sessions on the system has been reached. No new loggers can be created until a logging session has + /// been stopped. This value defaults to 64 on most systems. You can change this value by editing the REG_DWORD key at + /// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\EtwMaxLoggers. Permissible values are 32 through 256, inclusive. A reboot + /// is required for any change to take effect. Note that Loggers use system resources. Increasing the number of loggers on the system + /// will come at a performance cost if those slots are filled. Prior to Windows 10, version 1709, this is a fixed cap of 64 loggers + /// for non-private loggers. + /// + /// + /// + /// + /// + /// Event trace controllers call this function. + /// + /// The session remains active until you stop the session, the computer is restarted or the maximum file size is reached for + /// non-circular logs. To stop an event tracing session, call the ControlTrace function and set the ControlCode parameter to EVENT_TRACE_CONTROL_STOP. + /// + /// You cannot start more than one session with the same session GUID. + /// Windows Server 2003: You can start more than one session with the same session GUID. + /// For the logger to be a system logger and receive events from SystemTraceProvider, any of the following must be true: + /// + /// + /// The Properties member Wnode.Guid is set to SystemTraceControlGuid or GlobalLoggerGuid. + /// + /// + /// The Properties member LogFileMode includes the EVENT_TRACE_SYSTEM_LOGGER_MODE flag. + /// + /// + /// SessionName is set to KERNEL_LOGGER_NAME. + /// + /// + /// + /// Note A system logger must set the EnableFlags member of the EVENT_TRACE_PROPERTIES structure to indicate which + /// SystemTraceProvider events should be included in the trace. + /// + /// Because system loggers receive special kernel events, they are subject to additional restrictions: + /// + /// + /// There can be no more than 8 system loggers active on the same system. + /// + /// + /// System loggers cannot be created within a Windows Server container. + /// + /// + /// System loggers cannot use the EVENT_TRACE_USE_PAGED_MEMORY flag. + /// + /// + /// + /// Prior to Windows 10, version 1703, no more than 2 distinct clock types can be used simultaneously by any system loggers. For + /// example, if one active system logger is using the "CPU cycle counter" clock type, and another active system logger is using the + /// "Query performance counter" clock type, then any attempt to start a system logger using the "System time" clock type will fail + /// because it would require the activation of a third clock type. Because of this limitation, Microsoft strongly recommends that + /// system loggers do not use the "System time" clock type. + /// + /// + /// + /// + /// Starting with Windows 10, version 1703, the clock type restriction has been removed. All three clock types can now be used + /// simultaneously by system loggers. + /// + /// + /// + /// + /// To specify an NT Kernel Logger session, set SessionName to KERNEL_LOGGER_NAME and the Wnode.Guid member of + /// Properties to SystemTraceControlGuid. If you do not specify the GUID as SystemTraceControlGuid, ETW will override + /// the GUID value and set it to SystemTraceControlGuid. + /// + /// + /// Windows 2000: To start the kernel session, the session name must be KERNEL_LOGGER_NAME and the GUID must be SystemTraceControlGuid. + /// + /// + /// To specify a private logger session, set Wnode.Guid member of Properties to the provider's control GUID, not the private + /// logger session's control GUID. The provider must have registered the GUID before you call StartTrace. + /// + /// + /// You do not use this function to start a global logger session. For details on starting a global logger session, see Configuring + /// and Starting the Global Logger Session. + /// + /// Examples + /// For an example that uses StartTrace, see Configuring and Starting an Event Tracing Session. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/nf-evntrace-starttracea ULONG WMIAPI StartTraceA( PTRACEHANDLE + // TraceHandle, LPCSTR InstanceName, PEVENT_TRACE_PROPERTIES Properties ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("evntrace.h", MSDNShortId = "c040514a-733d-44b9-8300-a8341d2630b3")] + public static extern Win32Error StartTrace(out TRACEHANDLE TraceHandle, string InstanceName, ref EVENT_TRACE_PROPERTIES Properties); + + /// + /// The StopTrace function stops the specified event tracing session. + /// The ControlTrace function supersedes this function. + /// + /// + /// Handle to the event tracing session that you want to stop, or NULL. You must specify SessionHandle if SessionName is + /// NULL. However, ETW ignores the handle if SessionName is not NULL. The handle is returned by the StartTrace function. + /// + /// + /// + /// Pointer to a null-terminated string that specifies the name of the event tracing session that you want to stop, or NULL. + /// You must specify SessionName if SessionHandle is NULL. + /// + /// To specify the NT Kernel Logger session, set SessionName to KERNEL_LOGGER_NAME. + /// + /// + /// Pointer to an EVENT_TRACE_PROPERTIES structure that receives the final properties and statistics for the session. + /// + /// If you are using a newly initialized structure, you only need to set the Wnode.BufferSize, Wnode.Guid, + /// LoggerNameOffset, and LogFileNameOffset members of the structure. You can use the maximum session name (1024 + /// characters) and maximum log file name (1024 characters) lengths to calculate the buffer size and offsets if not known. + /// + /// + /// Starting with Windows 10, version 1703: For better performance in cross process scenarios, you can now pass filtering in + /// to StopTrace for system wide private loggers. You will need to pass in the new EVENT_TRACE_PROPERTIES_V2 structure + /// to include filtering information. See Configuring and Starting a Private Logger Session for more details. + /// + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// One of the following is true: + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, + /// LocalService, NetworkService can control event tracing sessions. To grant a restricted user the ability to control trace + /// sessions, add them to the Performance Log Users group. Windows XP and Windows 2000: Anyone can control a trace session. + /// + /// + /// + /// + /// + /// Controllers call this function. + /// + /// If LogFileMode contains EVENT_TRACE_FILE_MODE_PREALLOCATE, StartTrace extends the log file to + /// MaximumFileSize bytes. The file occupies the entire space during logging, for both circular and sequential logs. When you + /// stop the logger, the log file is reduced to the size needed. + /// + /// Note that it is not safe to stop a trace session from DllMain. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/stoptrace ULONG StopTrace( _In_ TRACEHANDLE SessionHandle, _In_ LPCTSTR + // SessionName, _Out_ PEVENT_TRACE_PROPERTIES Properties ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("Evntrace.h", MSDNShortId = "604274a1-c4ed-4746-b69a-e18969f969db")] + public static extern Win32Error StopTrace(TRACEHANDLE SessionHandle, [Optional] string SessionName, ref EVENT_TRACE_PROPERTIES Properties); + + /// The TraceEvent function sends an event to an event tracing session. + /// + /// Handle to the event tracing session that records the event. The provider obtains the handle when it calls the + /// GetTraceLoggerHandle function in its ControlCallback implementation. + /// + /// + /// + /// Pointer to an EVENT_TRACE_HEADER structure. Event-specific data is optionally appended to the structure. The largest event + /// you can log is 64K. You must specify values for the following members of the EVENT_TRACE_HEADER structure. + /// + /// + /// + /// Size + /// + /// + /// Guid or GuidPtr + /// + /// + /// Flags + /// + /// + /// + /// Depending on the complexity of the information your provider provides, you should also consider specifying values for the + /// following members. + /// + /// + /// + /// Class.Type + /// + /// + /// Class.Level + /// + /// + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_FLAG_NUMBER + /// The Flags member of the EVENT_TRACE_HEADER structure is incorrect. + /// + /// + /// ERROR_INVALID_HANDLE + /// SessionHandle is not valid or specifies the NT Kernel Logger session handle. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// + /// The session ran out of free buffers to write to. This can occur during high event rates because the disk subsystem is overloaded + /// or the number of buffers is too small. Rather than blocking until more buffers become available, TraceEvent discards the event. + /// Consider increasing the number and size of the buffers for the session, or reducing the number of events written or the size of + /// the events. Windows 2000: Not supported. + /// + /// + /// + /// ERROR_OUTOFMEMORY + /// + /// The event is discarded because, although the buffer pool has not reached its maximum size, there is insufficient available memory + /// to allocate an additional buffer and there is no buffer available to receive the event. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_MORE_DATA + /// + /// Data from a single event cannot span multiple buffers. A trace event is limited to the size of the event tracing session's buffer + /// minus the size of the EVENT_TRACE_HEADER structure. + /// + /// + /// + /// + /// + /// Providers call this function. + /// Before the provider can call this function, the provider + /// + /// + /// Must call the RegisterTraceGuids function to register itself and the event trace class. + /// + /// + /// Must be enabled. A controller calls the EnableTrace function to enable a provider. + /// + /// + /// + /// The event is either written to a log file, sent to event trace consumers in real time, or both. The LogFileMode member of + /// the EVENT_TRACE_PROPERTIES structure passed to the StartTrace defines where the event is sent. + /// + /// The trace events are written in the order in which they occur. + /// To trace a set of related events, use the TraceEventInstance function. + /// On Windows Vista, you should use the EventWrite function to log events. + /// + // https://docs.microsoft.com/en-us/windows/desktop/etw/traceevent ULONG TraceEvent( _In_ TRACEHANDLE SessionHandle, _In_ + // PEVENT_TRACE_HEADER EventTrace ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "9b21f6f0-dd9b-4f9c-a879-846901a3bab7")] + public static extern Win32Error TraceEvent(TRACEHANDLE SessionHandle, in EVENT_TRACE_HEADER EventTrace); + + /// + /// The TraceEventInstance function sends an event to an event tracing session. The event uses an instance identifier to + /// associate the event with a transaction. This function may also be used to trace hierarchical relationships between related events. + /// + /// + /// Handle to the event tracing session that records the event instance. The provider obtains the handle when it calls the + /// GetTraceLoggerHandle function in its ControlCallback implementation. + /// + /// + /// + /// Pointer to an EVENT_INSTANCE_HEADER structure. Event-specific data is optionally appended to the structure. The largest + /// event you can log is 64K. You must specify values for the following members of the EVENT_INSTANCE_HEADER structure. + /// + /// + /// + /// Size + /// + /// + /// Flags + /// + /// + /// RegHandle + /// + /// + /// + /// Depending on the complexity of the information your provider provides, you should also consider specifying values for the + /// following members. + /// + /// + /// + /// Class.Type + /// + /// + /// Class.Level + /// + /// + /// To trace hierarchical relationships between related events, also set the ParentRegHandle member. + /// + /// + /// Pointer to an EVENT_INSTANCE_INFO structure, which contains the registration handle for this event trace class and the + /// instance identifier. Use the CreateTraceInstanceId function to initialize the structure. + /// + /// + /// Pointer to an EVENT_INSTANCE_INFO structure, which contains the registration handle for the parent event trace class and + /// its instance identifier. Use the CreateTraceInstanceId function to initialize the structure. Set to NULL if you are + /// not tracing a hierarchical relationship. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_FLAGS + /// The Flags member of the EVENT_INSTANCE_HEADER does not contain WNODE_FLAG_TRACED_GUID. + /// + /// + /// ERROR_OUTOFMEMORY + /// + /// There was insufficient memory to complete the function call. The causes for this error code are described in the following + /// Remarks section. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// One of the following is true: + /// + /// + /// ERROR_INVALID_HANDLE + /// SessionHandle is not valid or specifies the NT Kernel Logger session handle. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// + /// The session ran out of free buffers to write to. This can occur during high event rates because the disk subsystem is overloaded + /// or the number of buffers is too small. Rather than blocking until more buffers become available, TraceEvent discards the event. + /// Windows 2000 and Windows XP: Not supported. + /// + /// + /// + /// ERROR_OUTOFMEMORY + /// + /// The event is discarded because, although the buffer pool has not reached its maximum size, there is insufficient available memory + /// to allocate an additional buffer and there is no buffer available to receive the event. + /// + /// + /// + /// ERROR_MORE_DATA + /// + /// Data from a single event cannot span multiple buffers. A trace event is limited to the size of the event tracing session's buffer + /// minus the size of the EVENT_INSTANCE_HEADER structure. + /// + /// + /// + /// + /// + /// Providers call this function. + /// Before the provider can call this function, the provider + /// + /// + /// Must call the RegisterTraceGuids function to register itself and the event trace class. + /// + /// + /// Must call the CreateTraceInstanceId function to create an instance identifier for the registered event trace class. + /// + /// + /// Must be enabled. A controller calls the EnableTrace function to enable a provider. + /// + /// + /// + /// The event is either written to a log file, sent to event trace consumers in real time, or both. The LogFileMode member of + /// the EVENT_TRACE_PROPERTIES structure passed to the StartTrace defines where the event is sent. + /// + /// The trace events are written in the order in which they occur. + /// To trace unrelated events, use the TraceEvent function. + /// Windows XP: Does not work correctly. + /// + // https://docs.microsoft.com/en-us/windows/desktop/etw/traceeventinstance ULONG TraceEventInstance( _In_ TRACEHANDLE SessionHandle, + // _In_ PEVENT_INSTANCE_HEADER EventTrace, _In_ PEVENT_INSTANCE_INFO pInstInfo, _In_ PEVENT_INSTANCE_INFO pParentInstInfo ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "e8361bdc-21dd-47a0-bdbf-56f4d6195689")] + public static extern Win32Error TraceEventInstance(TRACEHANDLE SessionHandle, in EVENT_INSTANCE_HEADER EventTrace, in EVENT_INSTANCE_INFO pInstInfo, in EVENT_INSTANCE_INFO pParentInstInfo); + + /// The TraceMessage function sends an informational message to an event tracing session. + /// + /// Handle to the event tracing session that records the event. The provider obtains the handle when it calls the + /// GetTraceLoggerHandle function in its ControlCallback implementation. + /// + /// + /// + /// Adds additional information to the beginning of the provider-specific data section of the event. The provider-specific data + /// section of the event will contain data only for those flags that are set. The variable list of argument data will follow this + /// information. This parameter can be one or more of the following values. + /// + /// + /// + /// Flag + /// Meaning + /// + /// + /// TRACE_MESSAGE_COMPONENTID + /// Include the component identifier in the message. The MessageGuid parameter contains the component identifier. + /// + /// + /// TRACE_MESSAGE_GUID + /// Include the event trace class GUID in the message. The MessageGuid parameter contains the event trace class GUID. + /// + /// + /// TRACE_MESSAGE_SEQUENCE + /// + /// Include a sequence number in the message. The sequence number starts at one. To use this flag, the controller must have set the + /// EVENT_TRACE_USE_GLOBAL_SEQUENCE or EVENT_TRACE_USE_LOCAL_SEQUENCE log file mode when creating the session. + /// + /// + /// + /// TRACE_MESSAGE_SYSTEMINFO + /// Include the thread identifier and process identifier in the message. + /// + /// + /// TRACE_MESSAGE_TIMESTAMP + /// Include a time stamp in the message. + /// + /// + /// TRACE_MESSAGE_COMPONENTID and TRACE_MESSAGE_GUID are mutually exclusive. + /// The information is included in the event data in the following order: + /// + /// + /// Sequence number + /// + /// + /// Event trace class GUID (or component identifier) + /// + /// + /// Time stamp + /// + /// + /// Thread identifier + /// + /// + /// Process identifier + /// + /// + /// + /// + /// Class GUID or component ID that identifies the message. Depends if MessageFlags contains the TRACE_MESSAGE_COMPONENTID or + /// TRACE_MESSAGE_GUID flag. + /// + /// + /// Number that uniquely identifies each occurrence of the message. You must define the value specified for this parameter; the value + /// should be meaningful to the application. + /// + /// + /// + /// A list of variable arguments to be appended to the message. Use this list to specify your provider-specific event data. The list + /// must be composed of pairs of arguments, as described in the following table. + /// + /// + /// + /// Data Type + /// Meaning + /// + /// + /// PVOID + /// Pointer to the argument data. + /// + /// + /// size_t + /// The size of the argument data, in bytes. + /// + /// + /// Terminate the list using an argument pair consisting of a pointer to NULL and zero. + /// + /// The caller must ensure that the sum of the sizes of the arguments + 72 does not exceed the size of the event tracing session's buffer. + /// + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// Either the SessionHandle is NULL or specifies the NT Kernel Logger session handle. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// + /// The session ran out of free buffers to write to. This can occur during high event rates because the disk subsystem is overloaded + /// or the number of buffers is too small. Rather than blocking until more buffers become available, TraceMessage discards the event. + /// Windows 2000 and Windows XP: Not supported. + /// + /// + /// + /// ERROR_OUTOFMEMORY + /// + /// The event is discarded because, although the buffer pool has not reached its maximum size, there is insufficient available memory + /// to allocate an additional buffer and there is no buffer available to receive the event. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// MessageFlags contains a value that is not valid. + /// + /// + /// ERROR_MORE_DATA + /// + /// Data from a single event cannot span multiple buffers. A trace event is limited to the size of the event tracing session's buffer + /// minus the size of the EVENT_TRACE_HEADER structure. + /// + /// + /// + /// + /// + /// Providers call this function. + /// + /// Using the TraceEvent function is the preferred way to log an event. On Windows Vista, you should use the EventWrite + /// function to log events. + /// + /// The trace events are written in the order in which they occur. + /// + /// If you need to access message tracing functionality from a wrapper function, call the TraceMessageVa version of this function. + /// + /// + /// Consumers will have to use the EventCallback callback to receive and process the events if the MessageFlags parameter does not + /// contain the TRACE_MESSAGE_GUID flag. If you do not specify the TRACE_MESSAGE_GUID flag, the consumer will not be able to use the + /// EventClassCallback because the Header.Guid member of the EVENT_TRACE structure will not contain the event trace + /// class GUID. + /// + /// + /// Note that the members of the EVENT_TRACE and EVENT_TRACE_HEADER structures that correspond to the MessageFlags + /// flags are set only if the corresponding flag is specified. For example, the ThreadId and ProcessId members of + /// EVENT_TRACE_HEADER are populated only if you specify the TRACE_MESSAGE_SYSTEMINFO flag. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/etw/tracemessage ULONG TraceMessage( _In_ TRACEHANDLE SessionHandle, _In_ ULONG + // MessageFlags, _In_ LPGUID MessageGuid, _In_ USHORT MessageNumber, ... ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "5d81c851-d47e-43f8-97b0-87156f36119a")] + public static extern Win32Error TraceMessage(TRACEHANDLE SessionHandle, TRACE_MESSAGE MessageFlags, in Guid MessageGuid, ushort MessageNumber, IntPtr Arguments); + + /// The TraceMessageVa function sends an informational message with variable arguments to an event tracing session. + /// + /// Handle to the event tracing session that records the event. The provider obtains the handle when it calls the + /// GetTraceLoggerHandle function in its ControlCallback implementation. + /// + /// + /// + /// Adds additional information to the beginning of the provider-specific data section of the event. The provider-specific data + /// section of the event will contain data only for those flags that are set. The variable list of argument data will follow this + /// information. This parameter can be one or more of the following values. + /// + /// + /// + /// Flag + /// Meaning + /// + /// + /// TRACE_MESSAGE_GUID + /// Include the event trace class GUID in the message. The MessageGuid parameter contains the event trace class GUID. + /// + /// + /// TRACE_MESSAGE_SEQUENCE + /// + /// Include a sequence number in the message. The sequence number starts at one. To use this flag, the controller must have set the + /// EVENT_TRACE_USE_GLOBAL_SEQUENCE or EVENT_TRACE_USE_LOCAL_SEQUENCE log file mode when creating the session. + /// + /// + /// + /// TRACE_MESSAGE_SYSTEMINFO + /// Include the thread identifier and process identifier in the message. + /// + /// + /// TRACE_MESSAGE_TIMESTAMP + /// Include a time stamp in the message. + /// + /// + /// The information is included in the event data in the following order: + /// + /// + /// Sequence number + /// + /// + /// Event trace class GUID + /// + /// + /// Time stamp + /// + /// + /// Thread identifier + /// + /// + /// Process identifier + /// + /// + /// + /// Class GUID that identifies the event trace message. + /// + /// Number that uniquely identifies each occurrence of the message. You must define the value specified for this parameter; the value + /// should be meaningful to the application. + /// + /// + /// + /// List of variable arguments to be appended to the message. The list must be composed of pairs of arguments, as described in the + /// following table. + /// + /// + /// + /// Data Type + /// Meaning + /// + /// + /// PVOID + /// Pointer to the argument data. + /// + /// + /// size_t + /// The size of the argument data, in bytes. + /// + /// + /// Terminate the list using an argument pair consisting of a pointer to NULL and zero. + /// + /// The caller must ensure that the sum of the sizes of the arguments + 72 does not exceed the size of the event tracing session's buffer. + /// + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_HANDLE + /// Either the SessionHandle is NULL or specifies the NT Kernel Logger session handle. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// + /// The session ran out of free buffers to write to. This can occur during high event rates because the disk subsystem is overloaded + /// or the number of buffers is too small. Rather than blocking until more buffers become available, TraceMessage discards the event. + /// Windows 2000 and Windows XP: Not supported. + /// + /// + /// + /// ERROR_OUTOFMEMORY + /// + /// The event is discarded because, although the buffer pool has not reached its maximum size, there is insufficient available memory + /// to allocate an additional buffer and there is no buffer available to receive the event. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// MessageFlags contains a value that is not valid. + /// + /// + /// ERROR_MORE_DATA + /// + /// Data from a single event cannot span multiple buffers. A trace event is limited to the size of the event tracing session's buffer + /// minus the size of the EVENT_TRACE_HEADER structure. + /// + /// + /// + /// + /// + /// Providers call this function. + /// + /// Using the TraceEvent function is the preferred way to log an event. On Windows Vista, you should use the EventWrite + /// function to log events. + /// + /// The trace events are written in the order in which they occur. + /// + /// If you do not need to access the message tracing functionality from a wrapper function, you can call the TraceMessage + /// version of this function. + /// + /// + /// Consumers will have to use the EventCallback callback to receive and process the events if the MessageFlags parameter does not + /// contain the TRACE_MESSAGE_GUID flag. If you do not specify the TRACE_MESSAGE_GUID flag, the consumer will not be able to use the + /// EventClassCallback because the Header.Guid member of the EVENT_TRACE structure will not contain the event trace + /// class GUID. + /// + /// + /// Note that the members of the EVENT_TRACE and EVENT_TRACE_HEADER structures that correspond to the MessageFlags + /// flags are set only if the corresponding flag is specified. For example, the ThreadId and ProcessId members of + /// EVENT_TRACE_HEADER are populated only if you specify the TRACE_MESSAGE_SYSTEMINFO flag. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/tracemessageva ULONG TraceMessageVa( _In_ TRACEHANDLE SessionHandle, _In_ + // ULONG MessageFlags, _In_ LPGUID MessageGuid, _In_ USHORT MessageNumber, _In_ va_list MessageArgList ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "2cfb7226-fd29-432e-abfd-bd10c6344a67")] + public static extern Win32Error TraceMessageVa(TRACEHANDLE SessionHandle, TRACE_MESSAGE MessageFlags, in Guid MessageGuid, ushort MessageNumber, __arglist); + + /// The TraceQueryInformation function queries event tracing session settings for the specified information class. + /// + /// A handle of the event tracing session that wants to capture the specified information. The StartTrace function returns + /// this handle. + /// + /// + /// The information class to query. The information that the class captures is included in the extended data section of the event. + /// For a list of information classes that you can query, see the TRACE_QUERY_INFO_CLASS enumeration. + /// + /// + /// A pointer to a buffer to receive the returned information class specific data. The information class determines the contents of + /// this parameter. For example, for the TraceStackTracingInfo information class, this parameter is an array of + /// CLASSIC_EVENT_ID structures. The structures specify the event GUIDs for which stack tracing is enabled. The array is + /// limited to 256 elements. + /// + /// + /// The size, in bytes, of the data returned in the TraceInformation buffer. If the function fails, this value indicates the required + /// size of the TraceInformation buffer that is needed. + /// + /// + /// A pointer a value that receives the size, in bytes, of the specific data returned in the TraceInformation buffer. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is one of the following error codes. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// + /// The program issued a command but the command length is incorrect. This error is returned if the InformationLength parameter is + /// less than a minimum size. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// The parameter is incorrect. + /// + /// + /// ERROR_NOT_SUPPORTED + /// The request is not supported. + /// + /// + /// Other + /// Use FormatMessage to obtain the message string for the returned error. + /// + /// + /// + /// + /// The TraceQueryInformation function queries event tracing session settings for the specified information class. Call this + /// function after calling StartTrace. + /// + // https://docs.microsoft.com/en-us/windows/desktop/etw/tracequeryinformation ULONG WINAPI TraceQueryInformation( _In_ TRACEHANDLE + // SessionHandle, _In_ TRACE_QUERY_INFO_CLASS InformationClass, _Out_ PVOID TraceInformation, _In_ ULONG InformationLength, _Out_opt_ + // PULONG ReturnLength ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "3CC91F7C-7F82-4B3B-AA50-FE03CFEC0278")] + public static extern Win32Error TraceQueryInformation(TRACEHANDLE SessionHandle, TRACE_QUERY_INFO_CLASS InformationClass, IntPtr TraceInformation, uint InformationLength, out uint ReturnLength); + + /// + /// The TraceSetInformation function enables or disables event tracing session settings for the specified information class. + /// + /// + /// A handle of the event tracing session that wants to capture the specified information. The StartTrace function returns + /// this handle. + /// + /// + /// The information class to enable or disable. The information that the class captures is included in the extended data section of + /// the event. For a list of information classes that you can enable, see the TRACE_INFO_CLASS enumeration. + /// + /// + /// A pointer to information class specific data; the information class determines the contents of this parameter. For example, for + /// the TraceStackTracingInfo information class, this parameter is an array of CLASSIC_EVENT_ID structures. The + /// structures specify the event GUIDs for which stack tracing is enabled. The array is limited to 256 elements. + /// + /// The size, in bytes, of the data in the TraceInformation buffer. + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// If the function fails, the return value is one of the following error codes. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// + /// The program issued a command but the command length is incorrect. This error is returned if the InformationLength parameter is + /// less than a minimum size. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// The parameter is incorrect. + /// + /// + /// ERROR_NOT_SUPPORTED + /// The request is not supported. + /// + /// + /// Other + /// Use FormatMessage to obtain the message string for the returned error. + /// + /// + /// + /// + /// Call this function after calling StartTrace. + /// + /// If the InformationClass parameter is set to TraceStackTracingInfo, calling this function enables stack tracing of the + /// specified kernel events. Subsequent calls to this function overwrites the previous list of kernel events for which stack tracing + /// is enabled. To disable stack tracing, call this function with InformationClass set to TraceStackTracingInfo and + /// InformationLength set to 0. + /// + /// + /// The extended data section of the event will include the call stack. The StackWalk_Event MOF class defines the layout of + /// the extended data. + /// + /// + /// Typically, on 64-bit computers, you cannot capture the kernel stack in certain contexts when page faults are not allowed. To + /// enable walking the kernel stack on x64, set the DisablePagingExecutive Memory Management registry value to 1. The + /// DisablePagingExecutive registry value is located under the following registry key: + /// + /// HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management + /// You should consider the cost of setting this registry value before doing so. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/tracesetinformation ULONG WINAPI TraceSetInformation( _In_ TRACEHANDLE + // SessionHandle, _In_ TRACE_INFO_CLASS InformationClass, _In_ PVOID TraceInformation, _In_ ULONG InformationLength ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "f4cdbe32-6885-4844-add5-560961c3dd1d")] + public static extern Win32Error TraceSetInformation(TRACEHANDLE SessionHandle, TRACE_QUERY_INFO_CLASS InformationClass, IntPtr TraceInformation, uint InformationLength); + + /// The UnregisterTraceGuids function unregisters an event trace provider and its event trace classes. + /// + /// Handle to the event trace provider, obtained from an earlier call to the RegisterTraceGuids function. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INVALID_PARAMETER + /// The RegistrationHandle parameter does not specify the handle to a registered provider or is NULL. + /// + /// + /// + /// + /// Providers call this function. + /// The event trace provider must have been registered previously by calling the RegisterTraceGuids function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/unregistertraceguids ULONG UnregisterTraceGuids( _In_ TRACEHANDLE + // RegistrationHandle ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("Evntrace.h", MSDNShortId = "1fa10f66-a78b-4f40-9518-72d48365246e")] + public static extern Win32Error UnregisterTraceGuids(TRACEHANDLE RegistrationHandle); + + /// + /// The UpdateTrace function updates the property setting of the specified event tracing session. + /// The ControlTrace function supersedes this function. + /// + /// + /// Handle to the event tracing session to update, or NULL. You must specify SessionHandle if SessionName is NULL. + /// However, ETW ignores the handle if SessionName is not NULL. The handle is returned by the StartTrace function. + /// + /// + /// + /// Pointer to a null-terminated string that specifies the name of the event tracing session to update, or NULL. You must + /// specify SessionName if SessionHandle is NULL. + /// + /// To specify the NT Kernel Logger session, set SessionName to KERNEL_LOGGER_NAME. + /// + /// + /// Pointer to an initialized EVENT_TRACE_PROPERTIES structure. + /// + /// On input, the members must specify the new values for the properties to update. For information on which properties you can + /// update, see Remarks. + /// + /// On output, the structure members contains the updated settings and statistics for the event tracing session. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, the return value is one of the system error codes. The following table includes some common errors and + /// their causes. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_BAD_LENGTH + /// The BufferSize member of the Wnode member of Properties specifies an incorrect size. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// One of the following is true: Windows Server 2003 and Windows XP: The Guid member of the Wnode structure is + /// SystemTraceControlGuid, but the SessionName parameter is not KERNEL_LOGGER_NAME. + /// + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and services running as LocalSystem, + /// LocalService, NetworkService can control event tracing sessions. To grant a restricted user the ability to control trace + /// sessions, add them to the Performance Log Users group. Windows XP and Windows 2000: Anyone can control a trace session. + /// + /// + /// + /// + /// + /// Controllers call this function. + /// On input, the members must specify the new values for the properties to update. You can update the following properties. + /// + /// + /// Member + /// Use + /// + /// + /// EnableFlags + /// + /// Set this member to 0 to disable all kernel providers. Otherwise, you must specify the kernel providers that you want to enable or + /// keep enabled. Applies only to NT Kernel Logger sessions. + /// + /// + /// + /// FlushTimer + /// + /// Set this member if you want to change the time to wait before flushing buffers. If this member is 0, the member is not updated. + /// + /// + /// + /// LogFileNameOffset + /// + /// Set this member if you want to switch to another log file. If this member is 0, the file name is not updated. If the offset is + /// not zero and you do not change the log file name, the function returns an error. + /// + /// + /// + /// LogFileMode + /// + /// Set this member if you want to turn EVENT_TRACE_REAL_TIME_MODE on and off. To turn real time consuming off, set this member to 0. + /// To turn real time consuming on, set this member to EVENT_TRACE_REAL_TIME_MODE and it will be OR'd with the current modes. + /// + /// + /// + /// MaximumBuffers + /// + /// Set set this member if you want to change the maximum number of buffers that ETW uses. If this member is 0, the member is not updated. + /// + /// + /// + /// For private logger sessions, you can only update LogFileNameOffset and FlushTimer. + /// + /// If you are using a newly initialized EVENT_TRACE_PROPERTIES structure, the only members you need to specify, other than + /// the members you are updating, are Wnode.BufferSize, Wnode.Guid, and Wnode.Flags. + /// + /// + /// If you use the property structure you passed to StartTrace, make sure the LogFileNameOffset member is 0 unless you + /// are changing the log file name. + /// + /// + /// If you call the ControlTrace function to query the current session properties and then update those properties to update + /// the session, make sure you set LogFileNameOffset to 0 (unless you are changing the log file name) and set + /// EVENT_TRACE_PROPERTIES.Wnode.Flags to WNODE_FLAG_TRACED_GUID. + /// + /// To obtain the property settings and session statistics for an event tracing session, call the ControlTrace function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/updatetrace ULONG UpdateTrace( _In_ TRACEHANDLE SessionHandle, _In_ LPCTSTR + // SessionName, _Inout_ PEVENT_TRACE_PROPERTIES Properties ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("Evntrace.h", MSDNShortId = "40e6deaf-7363-45eb-80d0-bc3f33760875")] + public static extern Win32Error UpdateTrace(TRACEHANDLE TraceHandle, string InstanceName, ref EVENT_TRACE_PROPERTIES Properties); + + /// + /// The EVENT_INSTANCE_HEADER structure contains standard event tracing information common to all events. The structure also contains + /// registration handles for the event trace class and related parent event, which you use to trace instances of a transaction or + /// hierarchical relationships between related events. + /// + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_INSTANCE_HEADER + { + /// + /// Total number of bytes of the event. Size must include the size of the EVENT_INSTANCE_HEADER structure, plus the size of any + /// event-specific data appended to this structure. The size must be less than the size of the event tracing session's buffer + /// minus 72 (0x48). + /// + public ushort Size; + /// Reserved. + public ushort FieldTypeFlags; + /// Type of event. + public byte Type; + /// + /// Provider-defined value that defines the severity level used to generate the event. The value ranges from 0 to 255. The + /// controller specifies the severity level when it calls the EnableTrace function. The provider retrieves the severity level by + /// calling the GetTraceEnableLevel function from its ControlCallback implementation. The provider uses the value to set this member. + /// + public byte Level; + /// + /// Indicates the version of the event trace class that you are using to log the event. Specify zero if there is only one version + /// of your event trace class. The version tells the consumer which MOF class to use to decipher the event data. + /// + public ushort Version; + /// + /// On output, identifies the thread that generated the event. + /// Note that on Windows 2000, ThreadId was a ULONGLONG value. + /// + public uint ThreadId; + /// + /// On output, identifies the process that generated the event. + /// Windows 2000: This member is not supported. + /// + public uint ProcessId; + /// On output, contains the time the event occurred, in 100-nanosecond intervals since midnight, January 1, 1601. + public FILETIME TimeStamp; + /// Handle to a registered event trace class. Set this property before calling the TraceEventInstance function. + public ulong RegHandle; + /// On output, contains the event trace instance identifier associated with RegHandle. + public uint InstanceId; + /// On output, contains the event trace instance identifier associated with ParentRegHandle. + public uint ParentInstanceId; + /// The union + public DUMMYUNION Union; + /// + /// Handle to a registered event trace class of a parent event. Set this property before calling the TraceEventInstance function + /// if you want to trace a hierarchical relationship (parent element/child element) between related events. + /// The RegisterTraceGuids function creates this handle(see the TraceGuidReg parameter). + /// + public ulong ParentRegHandle; + + /// + [StructLayout(LayoutKind.Explicit)] + public struct DUMMYUNION + { + /// + /// Elapsed execution time for kernel-mode instructions, in CPU ticks. If you are using a private session, use the value in + /// the ProcessorTime member instead. + /// + [FieldOffset(0)] + public uint KernelTime; + /// + /// Elapsed execution time for user-mode instructions, in CPU ticks. If you are using a private session, use the value in the + /// ProcessorTime member instead. + /// + [FieldOffset(4)] + public uint UserTime; + /// For private sessions, the elapsed execution time for user-mode instructions, in CPU ticks. + [FieldOffset(0)] + public ulong ProcessorTime; + /// The event identifier + [FieldOffset(0)] + public uint EventId; + /// Must contain WNODE_FLAG_TRACED_GUID, and may also contain any combination of the following. + [FieldOffset(4)] + public WNODE_FLAG Flags; + } + } + + /// + /// + /// The EVENT_TRACE_LOGFILE structure specifies how the consumer wants to read events (from a log file or in real-time) and + /// the callbacks that will receive the events. + /// + /// + /// When ETW flushes a buffer, this structure contains information about the event tracing session and the buffer that ETW flushed. + /// + /// + /// + /// Be sure to initialize the memory for this structure to zero before setting any members. + /// Consumers pass this structure to the OpenTrace function. + /// When ETW flushes a buffer, it passes the structure to the consumer's BufferCallback function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/event-trace-logfile typedef struct _EVENT_TRACE_LOGFILE { LPTSTR LogFileName; + // LPTSTR LoggerName; LONGLONG CurrentTime; ULONG BuffersRead; union { ULONG LogFileMode; ULONG ProcessTraceMode; }; EVENT_TRACE + // CurrentEvent; TRACE_LOGFILE_HEADER LogfileHeader; PEVENT_TRACE_BUFFER_CALLBACK BufferCallback; ULONG BufferSize; ULONG Filled; + // ULONG EventsLost; union { PEVENT_CALLBACK EventCallback; PEVENT_RECORD_CALLBACK EventRecordCallback; }; ULONG IsKernelTrace; PVOID + // Context; } EVENT_TRACE_LOGFILE, *PEVENT_TRACE_LOGFILE; + [PInvokeData("Evntrace.h", MSDNShortId = "179451e9-7e3c-4d3a-bcc6-3ad9d382229a")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct EVENT_TRACE_LOGFILE + { + /// + /// + /// Name of the log file used by the event tracing session. Specify a value for this member if you are consuming from a log file. + /// This member must be NULL if LoggerName is specified. + /// + /// + /// You must know the log file name the controller specified. If the controller logged events to a private session (the + /// controller set the LogFileMode member of EVENT_TRACE_PROPERTIES to EVENT_TRACE_PRIVATE_LOGGER_MODE), the + /// file name must include the process identifier that ETW appended to the log file name. For example, if the controller named + /// the log file xyz.etl and the process identifier is 123, ETW uses xyz.etl_123 as the file name. + /// + /// + /// If the controller set the LogFileMode member of EVENT_TRACE_PROPERTIES to EVENT_TRACE_FILE_MODE_NEWFILE, + /// the log file name must include the sequential serial number used to create each new log file. + /// + /// The user consuming the events must have permissions to read the file. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string LogFileName; + /// + /// + /// Name of the event tracing session. Specify a value for this member if you want to consume events in real time. This member + /// must be NULL if LogFileName is specified. + /// + /// + /// You can only consume events in real time if the controller set the LogFileMode member of EVENT_TRACE_PROPERTIES + /// to EVENT_TRACE_REAL_TIME_MODE. + /// + /// + /// Only users with administrative privileges, users in the Performance Log Users group, and applications running as LocalSystem, + /// LocalService, NetworkService can consume events in real time. To grant a restricted user the ability to consume events in + /// real time, add them to the Performance Log Users group or call EventAccessControl. + /// + /// Windows XP and Windows 2000: Anyone can consume real time events. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string LoggerName; + /// On output, the current time, in 100-nanosecond intervals since midnight, January 1, 1601. + public FILETIME CurrentTime; + /// On output, the number of buffers processed. + public uint BuffersRead; + /// Reserved. Do not use. + public uint LogFileMode; + /// + /// Modes for processing events. The modes are defined in the Evntcons.h header file. You can specify one or more of the + /// following modes: + /// + public uint ProcessTraceMode; + /// On output, an EVENT_TRACE structure that contains the last event processed. + public EVENT_TRACE CurrentEvent; + /// + /// On output, a TRACE_LOGFILE_HEADER structure that contains general information about the session and the computer on + /// which the session ran. + /// + public TRACE_LOGFILE_HEADER LogfileHeader; + /// + /// Pointer to the BufferCallback function that receives buffer-related statistics for each buffer ETW flushes. ETW calls + /// this callback after it delivers all the events in the buffer. This callback is optional. + /// + [MarshalAs(UnmanagedType.FunctionPtr)] + public BufferCallback BufferCallback; + /// On output, contains the size of each buffer, in bytes. + public uint BufferSize; + /// On output, contains the number of bytes in the buffer that contain valid information. + public uint Filled; + /// Not used. + public uint EventsLost; + /// + /// Pointer to the EventCallback function that ETW calls for each event in the buffer. + /// + /// Specify this callback if you are consuming events from a provider that used one of the TraceEvent functions to log events. + /// + /// + [MarshalAs(UnmanagedType.FunctionPtr)] + public EventClassCallback EventCallback; + /// + /// Pointer to the EventRecordCallback function that ETW calls for each event in the buffer. + /// + /// Specify this callback if you are consuming events from a provider that used one of the EventWrite functions to log events. + /// + /// Prior to Windows Vista: Not supported. + /// + [MarshalAs(UnmanagedType.FunctionPtr)] + public EventRecordCallback EventRecordCallback; + /// + /// On output, if this member is TRUE, the event tracing session is the NT Kernel Logger. Otherwise, it is another event + /// tracing session. + /// + [MarshalAs(UnmanagedType.Bool)] + public bool IsKernelTrace; + /// + /// + /// Context data that a consumer can specify when calling OpenTrace. If the consumer uses EventRecordCallback to + /// consume events, ETW sets the UserContext member of the EVENT_RECORD structure to this value. + /// + /// Prior to Windows Vista: Not supported. + /// + public IntPtr Context; + } + + /// The EVENT_TRACE structure is used to deliver event information to an event trace consumer. + /// ETW passes this structure to the consumer's EventCallback callback function. + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/ns-evntrace-event_trace typedef struct _EVENT_TRACE { + // EVENT_TRACE_HEADER Header; ULONG InstanceId; ULONG ParentInstanceId; GUID ParentGuid; PVOID MofData; ULONG MofLength; union { + // ULONG ClientContext; ETW_BUFFER_CONTEXT BufferContext; } DUMMYUNIONNAME; } EVENT_TRACE, *PEVENT_TRACE; + [PInvokeData("evntrace.h", MSDNShortId = "d8a6b63e-0cd4-4d19-b0b3-16bb0d33e4c0")] + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_TRACE + { + /// An EVENT_TRACE_HEADER structure that contains standard event tracing information. + public EVENT_TRACE_HEADER Header; + /// + /// Instance identifier. Contains valid data when the provider calls the TraceEventInstance function to generate the event. + /// Otherwise, the value is zero. + /// + public uint InstanceId; + /// + /// Instance identifier for a parent event. Contains valid data when the provider calls the TraceEventInstance function to + /// generate the event. Otherwise, the value is zero. + /// + public uint ParentInstanceId; + /// + /// Class GUID of the parent event. Contains valid data when the provider calls the TraceEventInstance function to generate the + /// event. Otherwise, the value is zero. + /// + public Guid ParentGuid; + /// Pointer to the beginning of the event-specific data for this event. + public IntPtr MofData; + /// Number of bytes to which MofData points. + public uint MofLength; + /// + /// + /// Provides information about the event such as the session identifier and processor number of the CPU on which the provider + /// process ran. For details, see the ETW_BUFFER_CONTEXT structure. + /// + /// Prior to Windows Vista: Not supported. + /// + public ETW_BUFFER_CONTEXT BufferContext; + } + + /// The TRACE_LOGFILE_HEADER structure contains information about an event tracing session and its events. + /// + /// Be sure to initialize the memory for this structure to zero before setting any members. + /// + /// The first event from any log file contains the data defined in this structure. You can use this structure to access the event + /// data or you can use the EventTrace_Header MOF class to decode the event data. Using this structure to read the event data may + /// return unexpected results if the consumer is on a different computer from the one that generated the log file or the log file was + /// written in a WOW (32-bit) session on a 64-bit computer. This is because the LoggerName and LogFileName members are + /// pointers and can vary in size depending on the PointerSize member. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/ns-evntrace-trace_logfile_header typedef struct + // _TRACE_LOGFILE_HEADER { ULONG BufferSize; union { ULONG Version; struct { UCHAR MajorVersion; UCHAR MinorVersion; UCHAR + // SubVersion; UCHAR SubMinorVersion; } VersionDetail; } DUMMYUNIONNAME; ULONG ProviderVersion; ULONG NumberOfProcessors; + // LARGE_INTEGER EndTime; ULONG TimerResolution; ULONG MaximumFileSize; ULONG LogFileMode; ULONG BuffersWritten; union { GUID + // LogInstanceGuid; struct { ULONG StartBuffers; ULONG PointerSize; ULONG EventsLost; ULONG CpuSpeedInMHz; } DUMMYSTRUCTNAME; } + // DUMMYUNIONNAME2; #if ... PWCHAR LoggerName; #if ... PWCHAR LogFileName; #if ... RTL_TIME_ZONE_INFORMATION TimeZone; #else LPWSTR + // LoggerName; #endif #else LPWSTR LogFileName; #endif #else TIME_ZONE_INFORMATION TimeZone; #endif LARGE_INTEGER BootTime; + // LARGE_INTEGER PerfFreq; LARGE_INTEGER StartTime; ULONG ReservedFlags; ULONG BuffersLost; } TRACE_LOGFILE_HEADER, *PTRACE_LOGFILE_HEADER; + [PInvokeData("evntrace.h", MSDNShortId = "13fdabe6-c904-4546-b876-c145f6a6c345")] + [StructLayout(LayoutKind.Sequential)] + public struct TRACE_LOGFILE_HEADER + { + /// Size of the event tracing session's buffers, in bytes. + public uint BufferSize; + /// + /// Version number of the operating system. This is a roll-up of the members of VersionDetail. Starting with the low-order + /// bytes, the first two bytes contain MajorVersion, the next two bytes contain MinorVersion, the next two bytes + /// contain SubVersion, and the last two bytes contain SubMinorVersion. + /// + public VERSIONDETAIL VersionDetail; + /// Build number of the operating system. + public uint ProviderVersion; + /// Number of processors on the system. + public uint NumberOfProcessors; + /// + /// Time at which the event tracing session stopped, in 100-nanosecond intervals since midnight, January 1, 1601. This value may + /// be 0 if you are consuming events in real time or from a log file to which the provide is still logging events. + /// + public FILETIME EndTime; + /// Resolution of the hardware timer, in units of 100 nanoseconds. For usage, see the Remarks for EVENT_TRACE_HEADER. + public uint TimerResolution; + /// Maximum size of the log file, in megabytes. + public uint MaximumFileSize; + /// Current logging mode for the event tracing session. For a list of values, see Logging Mode Constants. + public uint LogFileMode; + /// Total number of buffers written by the event tracing session. + public uint BuffersWritten; + /// Reserved. + public uint StartBuffers; + /// Size of a pointer data type, in bytes. + public uint PointerSize; + /// + /// Number of events lost during the event tracing session. Events may be lost due to insufficient memory or a very high rate of + /// incoming events. + /// + public uint EventsLost; + /// + /// CPU speed, in megahertz. + /// Windows 2000: This member is not supported. + /// + public uint CpuSpeedInMHz; + /// + /// Do not use. + /// The name of the event tracing session is the first null-terminated string following this structure in memory. + /// + public IntPtr LoggerName; + /// + /// Do Not use. + /// + /// The name of the event tracing log file is the second null-terminated string following this structure in memory.The first + /// string is the name of the session. + /// + /// + public IntPtr LogFileName; + /// + /// Time at which the system was started, in 100-nanosecond intervals since midnight, January 1, 1601. BootTime is + /// supported only for traces written to the Global Logger session. + /// + public FILETIME BootTime; + /// Frequency of the high-resolution performance counter, if one exists. + public long PerfFreq; + /// Time at which the event tracing session started, in 100-nanosecond intervals since midnight, January 1, 1601. + public FILETIME StartTime; + /// Specifies the clock type. For details, see the ClientContext member of WNODE_HEADER. + public uint ReservedFlags; + /// Total number of buffers lost during the event tracing session. + public uint BuffersLost; + + /// + /// Version number of the operating system. This is a roll-up of the members of VersionDetail. Starting with the low-order + /// bytes, the first two bytes contain MajorVersion, the next two bytes contain MinorVersion, the next two bytes + /// contain SubVersion, and the last two bytes contain SubMinorVersion. + /// + [StructLayout(LayoutKind.Sequential)] + public struct VERSIONDETAIL + { + /// Major version number of the operating system. + public byte MajorVersion; + /// Minor version number of the operating system. + public byte MinorVersion; + /// Reserved. + public byte SubVersion; + /// Reserved. + public byte SubMinorVersion; + } + } + + /// The ETW_BUFFER_CONTEXT structure provides context information about the event. + // https://docs.microsoft.com/en-us/windows/desktop/api/relogger/ns-relogger-_etw_buffer_context typedef struct _ETW_BUFFER_CONTEXT { + // union { struct { UCHAR ProcessorNumber; UCHAR Alignment; } DUMMYSTRUCTNAME; USHORT ProcessorIndex; } DUMMYUNIONNAME; USHORT + // LoggerId; } ETW_BUFFER_CONTEXT, *PETW_BUFFER_CONTEXT; + [PInvokeData("relogger.h", MSDNShortId = "75577305-fb3f-40a2-8fe6-9cd82c3f4e69")] + [StructLayout(LayoutKind.Sequential)] + public struct ETW_BUFFER_CONTEXT + { + /// The number of the CPU on which the provider process was running. The number is zero on a single processor computer. + public byte ProcessorNumber; + /// Alignment between events (always eight). + public byte Alignment; + /// Identifier of the session that logged the event. + public ushort LoggerId; + } + + /// The EVENT_TRACE_HEADER structure contains standard event tracing information common to all events. + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_TRACE_HEADER + { + /// + /// Total number of bytes of the event. Size includes the size of the header structure, plus the size of any event-specific data + /// appended to the header. + /// On input, the size must be less than the size of the event tracing session's buffer minus 72 (0x48). + /// On output, do not use this number in calculations. + /// + public ushort Size; + + /// Reserved. + public ushort FieldTypeFlags; + + /// Type of event. + public byte Type; + /// + /// Provider-defined value that defines the severity level used to generate the event. The value ranges from 0 to 255. The + /// controller specifies the severity level when it calls the EnableTrace function. The provider retrieves the severity level by + /// calling the GetTraceEnableLevel function from its ControlCallback implementation. The provider uses the value to set this member. + /// + /// ETW defines the following severity levels.Selecting a level higher than 1 will also include events for lower levels. For + /// example, if the controller specifies TRACE_LEVEL_WARNING (3), the provider also generates TRACE_LEVEL_FATAL(1) and + /// TRACE_LEVEL_ERROR(2) events. + /// + /// + public byte Level; + + /// + /// Indicates the version of the event trace class that you are using to log the event. Specify zero if there is only one version + /// of your event trace class. The version tells the consumer which MOF class to use to decipher the event data. + /// + public ushort Version; + + /// + /// On output, identifies the thread that generated the event. + /// Note that on Windows 2000, ThreadId was a ULONGLONG value. + /// + public uint ThreadId; + + /// + /// On output, identifies the process that generated the event. + /// Note that on Windows 2000, ProcessId was a ULONGLONG value. + /// + public uint ProcessId; + + /// + /// On output, contains the time that the event occurred. The resolution is system time unless the ProcessTraceMode member of + /// EVENT_TRACE_LOGFILE contains the PROCESS_TRACE_MODE_RAW_TIMESTAMP flag, in which case the resolution depends on the value of + /// the Wnode.ClientContext member of EVENT_TRACE_PROPERTIES at the time the controller created the session. + /// + public long TimeStamp; + + /// + /// Event trace class GUID. You can use the class GUID to identify a category of events and the Class.Type member to identify an + /// event within the category of events. + /// Alternatively, you can use the GuidPtr member to specify the class GUID. + /// Windows XP and Windows 2000: The class GUID must have been registered previously using the RegisterTraceGuids function. + /// + public Guid Guid; + + /// + /// Elapsed execution time for kernel-mode instructions, in CPU time units. If you are using a private session, use the value in + /// the ProcessorTime member instead. For more information, see Remarks. + /// + public uint KernelTime; + + /// + /// Elapsed execution time for user-mode instructions, in CPU time units. If you are using a private session, use the value in + /// the ProcessorTime member instead. For more information, see Remarks. + /// + public uint UserTime; + + /// For private sessions, the elapsed execution time for user-mode instructions, in CPU ticks. + public ulong ProcessorTime; + } + + /// The EVENT_RECORD structure defines the layout of an event that ETW delivers. + /// + /// The EVENT_RECORD structure is passed to the consumer's implementation of the EventRecordCallback callback . + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntcons/ns-evntcons-_event_record typedef struct _EVENT_RECORD { + // EVENT_HEADER EventHeader; ETW_BUFFER_CONTEXT BufferContext; USHORT ExtendedDataCount; USHORT UserDataLength; + // PEVENT_HEADER_EXTENDED_DATA_ITEM ExtendedData; PVOID UserData; PVOID UserContext; } EVENT_RECORD, *PEVENT_RECORD; + [PInvokeData("evntcons.h", MSDNShortId = "e352c1a7-39a2-43e3-a723-5fc6a3921ee8")] + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_RECORD + { + /// + /// Information about the event such as the time stamp for when it was written. For details, see the EVENT_HEADER structure. + /// + public EVENT_HEADER EventHeader; + /// Defines information such as the session that logged the event. For details, see the ETW_BUFFER_CONTEXT structure. + public ETW_BUFFER_CONTEXT BufferContext; + /// The number of extended data structures in the ExtendedData member. + public ushort ExtendedDataCount; + /// The size, in bytes, of the data in the UserData member. + public ushort UserDataLength; + /// + /// One or more extended data items that ETW collects. The extended data includes some items, such as the security identifier + /// (SID) of the user that logged the event, only if the controller sets the EnableProperty parameter passed to the EnableTraceEx + /// or EnableTraceEx2 function. The extended data includes other items, such as the related activity identifier and decoding + /// information for trace logging, regardless whether the controller sets the EnableProperty parameter passed to + /// EnableTraceEx or EnableTraceEx2. For details, see the EVENT_HEADER_EXTENDED_DATA_ITEM structure . + /// + public IntPtr ExtendedData; + /// + /// Event specific data. To parse this data, see Retrieving Event Data Using TDH. If the Flags member of EVENT_HEADER + /// contains EVENT_HEADER_FLAG_STRING_ONLY, the data is a null-terminated Unicode string that you do not need TDH to parse. + /// + public IntPtr UserData; + /// + /// Th context specified in the Context member of the EVENT_TRACE_LOGFILE structure that is passed to the OpenTrace function. + /// + public IntPtr UserContext; + } + + /// Defines information about the event. + /// + /// + /// You can use the KernelTime and UserTime members to determine the CPU cost in units for a set of instructions (the + /// values indicate the CPU usage charged to that thread at the time of logging). For example, if Event A and Event B are + /// consecutively logged by the same thread and they have CPU usage numbers 150 and 175, then the activity that was performed by that + /// thread between events A and B cost 25 CPU time units (175 – 150). + /// + /// + /// The TimerResolution of the TRACE_LOGFILE_HEADER structure contains the resolution of the CPU usage timer in 100-nanosecond + /// units. You can use the timer resolution with the kernel time and user time values to determine the amount of CPU time that the + /// set of instructions used. For example, if the timer resolution is 156,250, then 25 CPU time units is 0.39 seconds (156,250 * 25 * + /// 100 / 1,000,000,000). This is the amount of CPU time (not elapsed wall clock time) used by the set of instructions between events + /// A and B. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/evntcons/ns-evntcons-_event_header typedef struct _EVENT_HEADER { USHORT + // Size; USHORT HeaderType; USHORT Flags; USHORT EventProperty; ULONG ThreadId; ULONG ProcessId; LARGE_INTEGER TimeStamp; GUID + // ProviderId; EVENT_DESCRIPTOR EventDescriptor; union { struct { ULONG KernelTime; ULONG UserTime; } DUMMYSTRUCTNAME; ULONG64 + // ProcessorTime; } DUMMYUNIONNAME; GUID ActivityId; } EVENT_HEADER, *PEVENT_HEADER; + [PInvokeData("evntcons.h", MSDNShortId = "479091ae-7229-433b-b93b-8da6cc18df89")] + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_HEADER + { + /// Size of the event record, in bytes. + public ushort Size; + /// Reserved. + public ushort HeaderType; + /// + /// Flags that provide information about the event such as the type of session it was logged to and if the event contains + /// extended data. This member can contain one or more of the following flags. + /// + public ushort Flags; + /// Indicates the source to use for parsing the event data. + public ushort EventProperty; + /// Identifies the thread that generated the event. + public uint ThreadId; + /// Identifies the process that generated the event. + public uint ProcessId; + /// + /// Contains the time that the event occurred. The resolution is system time unless the ProcessTraceMode member of + /// EVENT_TRACE_LOGFILE contains the PROCESS_TRACE_MODE_RAW_TIMESTAMP flag, in which case the resolution depends on the value of + /// the Wnode.ClientContext member of EVENT_TRACE_PROPERTIES at the time the controller created the session. + /// + public FILETIME TimeStamp; + /// GUID that uniquely identifies the provider that logged the event. + public Guid ProviderId; + /// Defines the information about the event such as the event identifier and severity level. For details, see EVENT_DESCRIPTOR. + public EVENT_DESCRIPTOR EventDescriptor; + /// + public DUMMYUNION Union; + /// Identifier that relates two events. For details, see EventWriteTransfer. + public Guid ActivityId; + + /// + [StructLayout(LayoutKind.Explicit)] + public struct DUMMYUNION + { + /// + /// Elapsed execution time for kernel-mode instructions, in CPU ticks. If you are using a private session, use the value in + /// the ProcessorTime member instead. + /// + [FieldOffset(0)] + public uint KernelTime; + /// + /// Elapsed execution time for user-mode instructions, in CPU ticks. If you are using a private session, use the value in the + /// ProcessorTime member instead. + /// + [FieldOffset(4)] + public uint UserTime; + /// For private sessions, the elapsed execution time for user-mode instructions, in CPU ticks. + [FieldOffset(0)] + public ulong ProcessorTime; + } + } + + /// The ENABLE_TRACE_PARAMETERS structure defines the information used to enable a provider. + /// + /// + /// The ENABLE_TRACE_PARAMETERS structure is a version 2 structure and replaces the ENABLE_TRACE_PARAMETERS_V1 + /// structure for use with the EnableTraceEx2 function. + /// + /// + /// On Windows 8.1,Windows Server 2012 R2, and later, event payload , scope, and stack walk filters can be used by the + /// EnableTraceEx2 function and the ENABLE_TRACE_PARAMETERS and EVENT_FILTER_DESCRIPTOR structures to filter on + /// specific conditions in a logger session. For more information on event payload filters, see the EnableTraceEx2, + /// TdhCreatePayloadFilter, and TdhAggregatePayloadFilters functions and the EVENT_FILTER_DESCRIPTOR and + /// PAYLOAD_FILTER_PREDICATE structures. + /// + /// + /// Typically, on 64-bit computers, you cannot capture the kernel stack in certain contexts when page faults are not allowed. To + /// enable walking the kernel stack on x64, set the DisablePagingExecutive Memory Management registry value to 1. The + /// DisablePagingExecutive registry value is located under the following registry key: + /// + /// HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management + /// You should consider the cost of setting this registry value before doing so. + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/enable-trace-parameters typedef struct _ENABLE_TRACE_PARAMETERS { ULONG + // Version; ULONG EnableProperty; ULONG ControlFlags; GUID SourceId; PEVENT_FILTER_DESCRIPTOR EnableFilterDesc; ULONG + // FilterDescCount; } ENABLE_TRACE_PARAMETERS, *PENABLE_TRACE_PARAMETERS; + [PInvokeData("evntrace.h", MSDNShortId = "bc7cf886-f763-428a-9e75-031e8df26554")] + [StructLayout(LayoutKind.Sequential)] + public struct ENABLE_TRACE_PARAMETERS + { + /// Set to ENABLE_TRACE_PARAMETERS_VERSION_2. + public uint Version; + + /// + /// Optional settings that ETW can include when writing the event. Some settings write extra data to the extended data + /// item section of each event. Other settings refine which events will be included. To use these optional settings, specify + /// one or more of the following flags; otherwise, set to zero. + /// + public uint EnableProperty; + + /// Reserved. Set to 0. + public uint ControlFlags; + + /// + /// A GUID that uniquely identifies the session that is enabling or disabling the provider. If the provider does not implement + /// EnableCallback, the GUID is not used. + /// + public Guid SourceId; + + /// + /// + /// A pointer to an array of EVENT_FILTER_DESCRIPTOR structures that points to the filter data. The number of elements in + /// the array is specified in the FilterDescCount member. There can only be one filter for a specific filter type as + /// specified by the Type member of the EVENT_FILTER_DESCRIPTOR structure. + /// + /// + /// For a schematized filter (a Type member equal to EVENT_FILTER_TYPE_SCHEMATIZED), the provider uses filter data + /// to prevent events that match the filter criteria from being written to the session. The provider determines the layout of the + /// data and how it applies the filter to the event's data. A session can pass only one schematized filter to the provider. + /// + /// + /// A session can call the TdhEnumerateProviderFilters function to determine the schematized filters that it can pass to + /// the provider. + /// + /// + public IntPtr EnableFilterDesc; + + /// + /// + /// The number of elements (filters) in the EVENT_FILTER_DESCRIPTOR array pointed to by EnableFilterDesc member. + /// + /// + /// The FilterDescCount member should match the number of EVENT_FILTER_DESCRIPTOR structures in the array pointed + /// to by the EnableFilterDesc member. + /// + /// . + /// + public uint FilterDescCount; + } + + /// The EVENT_INSTANCE_INFO structure maps a unique transaction identifier to a registered event trace class. + /// Be sure to initialize the memory for this structure to zero before setting any members. + // https://docs.microsoft.com/en-us/windows/desktop/api/evntrace/ns-evntrace-event_instance_info typedef struct EVENT_INSTANCE_INFO { + // HANDLE RegHandle; ULONG InstanceId; } EVENT_INSTANCE_INFO, *PEVENT_INSTANCE_INFO; + [PInvokeData("evntrace.h", MSDNShortId = "83a3802c-b992-43a2-a98a-bdee2ecfef24")] + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_INSTANCE_INFO + { + /// Handle to a registered event trace class. + public TRACEHANDLE RegHandle; + + /// Unique transaction identifier that maps an event to a specific transaction. + public uint InstanceId; + } + + /// + /// The EVENT_TRACE_PROPERTIES structure contains information about an event tracing session. You use this structure when you + /// define a session, change the properties of a session, or query for the properties of a session. + /// + /// + /// Be sure to initialize the memory for this structure to zero before setting any members. + /// + /// Events from providers are written to a session's buffers. When a buffer is full, the session flushes the buffer either by writing + /// the events to a log file, delivering them to a real-time consumer, or both. If the session's buffers are filled faster than they + /// can be flushed, new buffers are allocated and added to the session's buffer pool, up to the maximum number specified. Beyond this + /// limit, the session discards incoming events until a buffer becomes available. Each session keeps a record of the number of events + /// discarded (see the EventsLost member). + /// + /// ETW does not free unused buffers. + /// Windows 2000: ETW frees unused buffers based on the AgeLimit member value. + /// + /// You use the BufferSize, MinimumBuffers, and MaximumBuffers members to configure the buffers for an event + /// tracing session when you define the session or anytime during the tracing session. ETW uses the physical memory and number of + /// processors available on the computer to determine if the values are reasonable. If ETW determines the values are not reasonable, + /// ETW will determine the correct size and overwrite the values. + /// + /// Typically, you should not set these values and instead let ETW determine the size and number of buffers. + /// + /// To view session statistics, such as EventsLost while the session is running, call the ControlTrace function and set + /// the ControlCode parameter to EVENT_TRACE_CONTROL_QUERY. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/event-trace-properties typedef struct _EVENT_TRACE_PROPERTIES { WNODE_HEADER + // Wnode; ULONG BufferSize; ULONG MinimumBuffers; ULONG MaximumBuffers; ULONG MaximumFileSize; ULONG LogFileMode; ULONG FlushTimer; + // ULONG EnableFlags; LONG AgeLimit; ULONG NumberOfBuffers; ULONG FreeBuffers; ULONG EventsLost; ULONG BuffersWritten; ULONG + // LogBuffersLost; ULONG RealTimeBuffersLost; HANDLE LoggerThreadId; ULONG LogFileNameOffset; ULONG LoggerNameOffset; } + // EVENT_TRACE_PROPERTIES, *PEVENT_TRACE_PROPERTIES; + [PInvokeData("evntrace.h", MSDNShortId = "0c967971-8df1-4679-a8a9-a783f5b35860")] + [StructLayout(LayoutKind.Sequential)] + public struct EVENT_TRACE_PROPERTIES + { + /// + /// A WNODE_HEADER structure. You must specify the BufferSize, Flags, and Guid members, and + /// optionally the ClientContext member. + /// + public WNODE_HEADER Wnode; + + /// + /// + /// Amount of memory allocated for each event tracing session buffer, in kilobytes. The maximum buffer size is 1 MB. ETW uses the + /// size of physical memory to calculate this value. For more information, see Remarks. + /// + /// + /// If an application expects a relatively low event rate, the buffer size should be set to the memory page size. If the event + /// rate is expected to be relatively high, the application should specify a larger buffer size, and should increase the maximum + /// number of buffers. + /// + /// + /// The buffer size affects the rate at which buffers fill and must be flushed. Although a small buffer size requires less + /// memory, it increases the rate at which buffers must be flushed. + /// + /// + public uint BufferSize; + + /// + /// Minimum number of buffers allocated for the event tracing session's buffer pool. The minimum number of buffers that you can + /// specify is two buffers per processor. For example, on a single processor computer, the minimum number of buffers is two. Note + /// that if you use the EVENT_TRACE_NO_PER_PROCESSOR_BUFFERING logging mode, the number of processors is assumed to be 1. + /// + public uint MinimumBuffers; + + /// + /// Maximum number of buffers allocated for the event tracing session's buffer pool. Typically, this value is the minimum number + /// of buffers plus twenty. ETW uses the buffer size and the size of physical memory to calculate this value. This value must be + /// greater than or equal to the value for MinimumBuffers. Note that you do not need to set this value if + /// LogFileMode contains EVENT_TRACE_BUFFERING_MODE; instead, the total memory buffer size is instead the product + /// of MinimumBuffers and BufferSize. + /// + public uint MaximumBuffers; + + /// + /// + /// Maximum size of the file used to log events, in megabytes. Typically, you use this member to limit the size of a circular log + /// file when you set LogFileMode to EVENT_TRACE_FILE_MODE_CIRCULAR. This member must be specified if + /// LogFileMode contains EVENT_TRACE_FILE_MODE_PREALLOCATE, EVENT_TRACE_FILE_MODE_CIRCULAR or EVENT_TRACE_FILE_MODE_NEWFILE + /// + /// + /// If you are using the system drive (the drive that contains the operating system) for logging, ETW checks for an additional + /// 200MB of disk space, regardless of whether you are using the maximum file size parameter. Therefore, if you specify 100MB as + /// the maximum file size for the trace file in the system drive, you need to have 300MB of free space on the drive. + /// + /// + public uint MaximumFileSize; + + /// + /// + /// Logging modes for the event tracing session. You use this member to specify that you want events written to a log file, a + /// real-time consumer, or both. You can also use this member to specify that the session is a private logger session. You can + /// specify one or more modes. For a list of possible modes, see Logging Mode Constants. + /// + /// + /// Do not specify real-time logging unless there are real-time consumers ready to consume the events. If there are no real-time + /// consumers, ETW writes the events to a playback file. However, the size of the playback file is limited. If the limit is + /// reached, no new events are logged (to the log file or playback file) and the logging functions fail with STATUS_LOG_FILE_FULL. + /// + /// Prior to Windows Vista: If there was no real-time consumer, the events were discarded and logging continues. + /// + /// If a consumer begins processing real-time events, the events in the playback file are consumed first. After all events in the + /// playback file are consumed, the session will begin logging new events. + /// + /// + public uint LogFileMode; + + /// + /// + /// How often, in seconds, the trace buffers are forcibly flushed. The minimum flush time is 1 second. This forced flush is in + /// addition to the automatic flush that occurs whenever a buffer is full and when the trace session stops. + /// + /// + /// If zero, ETW flushes buffers as soon as they become full. If nonzero, ETW flushes all buffers that contain events based on + /// the timer value. Typically, you want to flush buffers only when they become full. Forcing the buffers to flush (either by + /// setting this member to a nonzero value or by calling FlushTrace) can increase the file size of the log file with + /// unfilled buffer space. + /// + /// + /// If the consumer is consuming events in real time, you may want to set this member to a nonzero value if the event rate is low + /// to force events to be delivered before the buffer is full. + /// + /// + /// For the case of a realtime logger, a value of zero (the default value) means that the flush time will be set to 1 second. A + /// realtime logger is when LogFileMode is set to EVENT_TRACE_REAL_TIME_MODE. + /// + /// + public uint FlushTimer; + + /// + /// A system logger must set EnableFlags to indicate which SystemTraceProvider events should be included in the trace. + /// This is also used for NT Kernel Logger sessions. This member can contain one or more of the following values. In addition to + /// the events you specify, the kernel logger also logs hardware configuration events on Windows XP or system configuration + /// events on Windows Server 2003. + /// + public uint EnableFlags; + + /// + /// Not used. + /// Windows 2000: Time delay before unused buffers are freed, in minutes. The default is 15 minutes. + /// + public int AgeLimit; + + /// On output, the number of buffers allocated for the event tracing session's buffer pool. + public uint NumberOfBuffers; + + /// On output, the number of buffers that are allocated but unused in the event tracing session's buffer pool. + public uint FreeBuffers; + + /// On output, the number of events that were not recorded. + public uint EventsLost; + + /// On output, the number of buffers written. + public uint BuffersWritten; + + /// On output, the number of buffers that could not be written to the log file. + public uint LogBuffersLost; + + /// On output, the number of buffers that could not be delivered in real-time to the consumer. + public uint RealTimeBuffersLost; + + /// On output, the thread identifier for the event tracing session. + public HANDLE LoggerThreadId; + + /// + /// + /// Offset from the start of the structure's allocated memory to beginning of the null-terminated string that contains the log + /// file name. + /// + /// + /// The file name should use the .etl extension. All folders in the path must exist. The path can be relative, absolute, local, + /// or remote. The path cannot contain environment variables (they are not expanded). The user must have permission to write to + /// the folder. + /// + /// + /// The log file name is limited to 1,024 characters. If you set LogFileMode to EVENT_TRACE_PRIVATE_LOGGER_MODE or + /// EVENT_TRACE_FILE_MODE_NEWFILE, be sure to allocate enough memory to include the process identifier that is appended to + /// the file name for private loggers sessions, and the sequential number that is added to log files created using the new file + /// log mode. + /// + /// + /// If you do not want to log events to a log file (for example, you specify EVENT_TRACE_REAL_TIME_MODE only), set + /// LogFileNameOffset to 0. If you specify only real-time logging and also provide an offset with a valid log file name, ETW will + /// use the log file name to create a sequential log file and log events to the log file. ETW also creates the sequential log + /// file if LogFileMode is 0 and you provide an offset with a valid log file name. + /// + /// + /// If you want to log events to a log file, you must allocate enough memory for this structure to include the log file name and + /// session name following the structure. The log file name must follow the session name in memory. + /// + /// + /// Trace files are created using the default security descriptor, meaning that the log file will have the same ACL as the parent + /// directory. If you want access to the files restricted, create a parent directory with the appropriate ACLs. + /// + /// + public uint LogFileNameOffset; + + /// + /// + /// Offset from the start of the structure's allocated memory to beginning of the null-terminated string that contains the + /// session name. + /// + /// The session name is limited to 1,024 characters. The session name is case-insensitive and must be unique. + /// + /// Windows 2000: Session names are case-sensitive. As a result, duplicate session names are allowed. However, to reduce + /// confusion, you should make sure your session names are unique. + /// + /// + /// When you allocate the memory for this structure, you must allocate enough memory to include the session name and log file + /// name following the structure. The session name must come before the log file name in memory. You must copy the log file name + /// to the offset but you do not copy the session name to the offset—the StartTrace function copies the name for you. + /// + /// + public uint LoggerNameOffset; + } + + /// The TRACE_GUID_PROPERTIES structure contains information about an event trace provider. + /// Be sure to initialize the memory for this structure to zero before setting any members or passing to any functions. + // https://docs.microsoft.com/en-us/windows/desktop/etw/trace-guid-properties typedef struct _TRACE_GUID_PROPERTIES { GUID Guid; + // ULONG GuidType; ULONG LoggerId; ULONG EnableLevel; ULONG EnableFlags; BOOLEAN IsEnable; } TRACE_GUID_PROPERTIES, *PTRACE_GUID_PROPERTIES; + [PInvokeData("evntrace.h", MSDNShortId = "849f2d34-14e0-43e8-a735-d46e94671725")] + [StructLayout(LayoutKind.Sequential)] + public struct TRACE_GUID_PROPERTIES + { + /// Control GUID of the event trace provider. + public Guid Guid; + + /// Not used. + public uint GuidType; + + /// Session handle that identifies the event tracing session. + public uint LoggerId; + + /// Value passed as the EnableLevel parameter to the EnableTrace function. + public uint EnableLevel; + + /// Value passed as the EnableFlag parameter to the EnableTrace function. + public uint EnableFlags; + + /// + /// If this member is TRUE, the element identified by the Guid member is currently enabled for the session identified by the + /// LoggerId member. If this member is FALSE, all other members have no meaning and should be zero. + /// + [MarshalAs(UnmanagedType.U1)] public bool IsEnable; + } + + /// The TRACE_GUID_REGISTRATION structure is used to register event trace classes. + /// Be sure to initialize the memory for this structure to zero before setting any members. + // https://docs.microsoft.com/en-us/windows/desktop/ETW/trace-guid-registration typedef struct _TRACE_GUID_REGISTRATION { LPCGUID + // Guid; HANDLE RegHandle; } TRACE_GUID_REGISTRATION; + [PInvokeData("Evntrace.h", MSDNShortId = "fc7b61fb-ef1c-48ec-8523-5f3114b5407a")] + [StructLayout(LayoutKind.Sequential)] + public struct TRACE_GUID_REGISTRATION + { + /// Class GUID of an event trace class that you are registering. + public IntPtr Guid; + /// + /// Handle to the registered event trace class. The RegisterTraceGuids function generates this value. + /// + /// Use this handle when you call the CreateTraceInstanceId function and to set the RegHandle member of + /// EVENT_INSTANCE_HEADER when calling the TraceEventInstance function. + /// + /// + public TRACEHANDLE RegHandle; + } + + /// Provides a handle to an event trace. + [PInvokeData("evntrace.h")] + [StructLayout(LayoutKind.Sequential)] + public struct TRACEHANDLE : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public TRACEHANDLE(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static TRACEHANDLE NULL => new TRACEHANDLE(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(TRACEHANDLE h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator TRACEHANDLE(IntPtr h) => new TRACEHANDLE(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(TRACEHANDLE h1, TRACEHANDLE h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(TRACEHANDLE h1, TRACEHANDLE h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is TRACEHANDLE h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// The WNODE_HEADER structure is a member of the EVENT_TRACE_PROPERTIES structure. + /// + /// Be sure to initialize the memory for this structure to zero before setting any members. + /// To convert an ETW timestamp into a FILETIME, use the following procedure: + /// + /// 1. For each session or log file being processed (i.e. for each EVENT\_TRACE\_LOGFILE), check the logFile.ProcessTraceMode field + /// to determine whether the PROCESS\_TRACE\_MODE\_RAW\_TIMESTAMP flag is set. By default, this flag is not set. If this flag is not + /// set, the ETW runtime will automatically convert the timestamp of each EVENT\_RECORD into a FILETIME before sending the + /// EVENT\_RECORD to your EventRecordCallback function, so no additional processing is needed. The following steps should only be + /// used if the trace is being processed with the PROCESS\_TRACE\_MODE\_RAW\_TIMESTAMP flag set. 2. For each session or log file + /// being processed (i.e. for each EVENT\_TRACE\_LOGFILE), check the logFile.LogfileHeader.ReservedFlags field to determine the time + /// stamp scale for the log file. Based on the value of ReservedFlags, follow one of these steps to determine the value to use for + /// timeStampScale in the remaining steps: 3. On the FIRST call to your EventRecordCallback function for a particular log file, use + /// data from the logFile (EVENT\_TRACE\_LOGFILE) and from the eventRecord (EVENT\_RECORD) to compute the timeStampBase that will be + /// used for the remaining events in the log file: INT64 timeStampBase = logFile.LogfileHeader.StartTime.QuadPart - + /// (INT64)(timeStampScale \* eventRecord.EventHeader.TimeStamp.QuadPart); 4. For each eventRecord (EVENT\_RECORD), convert the + /// event’s timestamp into FILETIME as follows, using the timeStampScale and timeStampBase values calculated in steps 2 and 3: INT64 + /// timeStampInFileTime = timeStampBase + (INT64)(timeStampScale \* eventRecord.EventHeader.TimeStamp.QuadPart); + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/ETW/wnode-header typedef struct _WNODE_HEADER { ULONG BufferSize; ULONG + // ProviderId; union { ULONG64 HistoricalContext; struct { ULONG Version; ULONG Linkage; }; }; union { HANDLE KernelHandle; + // LARGE_INTEGER TimeStamp; }; GUID Guid; ULONG ClientContext; ULONG Flags; } WNODE_HEADER, *PWNODE_HEADER; + [PInvokeData("evntrace.h", MSDNShortId = "862a8f46-a326-48c6-92b7-8bb667837bb7")] + [StructLayout(LayoutKind.Sequential)] + public struct WNODE_HEADER + { + /// + /// Total size of memory allocated, in bytes, for the event tracing session properties. The size of memory must include the room + /// for the EVENT_TRACE_PROPERTIES structure plus the session name string and log file name string that follow the + /// structure in memory. + /// + public uint BufferSize; + + /// Reserved for internal use. + public uint ProviderId; + + /// On output, the handle to the event tracing session. + public ulong HistoricalContext; + + /// + /// Time at which the information in this structure was updated, in 100-nanosecond intervals since midnight, January 1, 1601. + /// + public FILETIME TimeStamp; + + /// + /// The GUID that you define for the session. + /// For an NT Kernel Logger session, set this member to SystemTraceControlGuid. + /// If this member is set to SystemTraceControlGuid or GlobalLoggerGuid, the logger will be a system logger. + /// For a private logger session, set this member to the provider's GUID that you are going to enable for the session. + /// + /// If you start a session that is not a kernel logger or private logger session, you do not have to specify a session GUID. If + /// you do not specify a GUID, ETW creates one for you. You need to specify a session GUID only if you want to change the default + /// permissions associated with a specific session. For details, see the EventAccessControl function. + /// + /// You cannot start more than one session with the same session GUID. + /// Prior to Windows Vista: You can start more than one session with the same session GUID. + /// + public Guid Guid; + + /// + /// Clock resolution to use when logging the time stamp for each event. The default is Query performance counter (QPC). + /// Prior to Windows Vista: The default is system time. + /// + /// Prior to Windows 10, version 1703: No more than 2 distinct clock types can be used simultaneously by any system loggers. + /// + /// + /// Starting with Windows 10, version 1703: The clock type restriction has been removed. All three clock types can now be + /// used simultaneously by system loggers. + /// + /// You can specify one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// 1 + /// + /// Query performance counter (QPC). The QPC counter provides a high-resolution time stamp that is not affected by adjustments to + /// the system clock. The time stamp stored in the event is equivalent to the value returned from the QueryPerformanceCounter + /// API. For more information on the characteristics of this time stamp, see Acquiring high-resolution time stamps. You should + /// use this resolution if you have high event rates or if the consumer merges events from different buffers. In these cases, the + /// precision and stability of the QPC time stamp allows for better accuracy in ordering the events from different buffers. + /// However, the QPC time stamp will not reflect updates to the system clock, e.g. if the system clock is adjusted forward due to + /// synchronization with an NTP server while the trace is in progress, the QPC time stamps in the trace will continue to reflect + /// time as if no update had occurred. To determine the resolution, use the PerfFreq member of TRACE_LOGFILE_HEADER when + /// consuming the event. To convert an event’s time stamp into 100-ns units, use the following conversion formula: + /// scaledTimestamp = eventRecord.EventHeader.TimeStamp.QuadPart * 10000000.0 / logfileHeader.PerfFreq.QuadPart Note that on + /// older computers, the time stamp may not be accurate because the counter sometimes skips forward due to hardware errors. + /// + /// + /// + /// 2 + /// + /// System time. The system time provides a time stamp that tracks changes to the system’s clock, e.g. if the system clock is + /// adjusted forward due to synchronization with an NTP server while the trace is in progress, the System Time time stamps in the + /// trace will also jump forward to match the new setting of the system clock. Prior to Windows 10, the resolution of this time + /// stamp was the resolution of a system clock tick, as indicated by the TimerResolution member of TRACE_LOGFILE_HEADER. Starting + /// with Windows 10, the resolution of this time stamp is the performance counter resolution, as indicated by the PerfFreq member + /// of TRACE_LOGFILE_HEADER. To convert an event’s time stamp into 100-ns units, use the following conversion formula: + /// scaledTimestamp = eventRecord.EventHeader.TimeStamp.QuadPart Note that when events are captured on a system running an OS + /// prior to Windows 10, if the volume of events is high, the resolution for system time may not be fine enough to determine the + /// sequence of events. In this case, a set of events will have the same time stamp, but the order in which ETW delivers the + /// events may not be correct. Starting with Windows 10, the time stamp is captured with additional precision, though some + /// instability may still occur in cases where the system clock was adjusted while the trace was being captured. + /// + /// + /// + /// 3 + /// + /// CPU cycle counter. The CPU counter provides the highest resolution time stamp and is the least resource-intensive to + /// retrieve. However, the CPU counter is unreliable and should not be used in production. For example, on some computers, the + /// timers will change frequency due to thermal and power changes, in addition to stopping in some states. To determine the + /// resolution, use the CpuSpeedInMHz member of TRACE_LOGFILE_HEADER when consuming the event. If your hardware does not support + /// this clock type, ETW uses system time. Windows Server 2003, Windows XP with SP1 and Windows XP: This value is not supported, + /// it was introduced in Windows Server 2003 with SP1 and Windows XP with SP2. + /// + /// + /// + /// Windows 2000: The ClientContext member is not supported. + /// + public uint ClientContext; + + /// Must contain WNODE_FLAG_TRACED_GUID to indicate that the structure contains event tracing information. + public uint Flags; + } + } +} \ No newline at end of file diff --git a/PInvoke/Security/AdvApi32/ProcessThreadsApi.cs b/PInvoke/Security/AdvApi32/ProcessThreadsApi.cs index 271d7a5f..83dad63a 100644 --- a/PInvoke/Security/AdvApi32/ProcessThreadsApi.cs +++ b/PInvoke/Security/AdvApi32/ProcessThreadsApi.cs @@ -1,10 +1,325 @@ using System; using System.Runtime.InteropServices; +using System.Text; +using static Vanara.PInvoke.Kernel32; namespace Vanara.PInvoke { public static partial class AdvApi32 { + /// + /// + /// Creates a new process and its primary thread. The new process runs in the security context of the user represented by the + /// specified token. + /// + /// + /// Typically, the process that calls the CreateProcessAsUser function must have the SE_INCREASE_QUOTA_NAME privilege + /// and may require the SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable. If this function fails with + /// ERROR_PRIVILEGE_NOT_HELD (1314), use the CreateProcessWithLogonW function instead. CreateProcessWithLogonW requires + /// no special privileges, but the specified user account must be allowed to log on interactively. Generally, it is best to use + /// CreateProcessWithLogonW to create a process with alternate credentials. + /// + /// + /// + /// + /// A handle to the primary token that represents a user. The handle must have the TOKEN_QUERY, TOKEN_DUPLICATE, and + /// TOKEN_ASSIGN_PRIMARY access rights. For more information, see Access Rights for Access-Token Objects. The user represented + /// by the token must have read and execute access to the application specified by the lpApplicationName or the lpCommandLine parameter. + /// + /// + /// To get a primary token that represents the specified user, call the LogonUser function. Alternatively, you can call the + /// DuplicateTokenEx function to convert an impersonation token into a primary token. This allows a server application that is + /// impersonating a client to create a process that has the security context of the client. + /// + /// + /// If hToken is a restricted version of the caller's primary token, the SE_ASSIGNPRIMARYTOKEN_NAME privilege is not required. + /// If the necessary privileges are not already enabled, CreateProcessAsUser enables them for the duration of the call. For + /// more information, see Running with Special Privileges. + /// + /// + /// Terminal Services: The process is run in the session specified in the token. By default, this is the same session that + /// called LogonUser. To change the session, use the SetTokenInformation function. + /// + /// + /// + /// + /// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for + /// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer. + /// + /// + /// The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a + /// partial name, the function uses the current drive and current directory to complete the specification. The function will not use + /// the search path. This parameter must include the file name extension; no default extension is assumed. + /// + /// + /// The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token + /// in the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the + /// file name ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program + /// files\sub dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities + /// in the following order: + /// + /// + /// c:\program.exec:\program files\sub.exec:\program files\sub dir\program.exec:\program files\sub + /// dir\program name.exe If the executable module is a 16-bit application, lpApplicationName should be NULL, and the + /// string pointed to by lpCommandLine should specify the executable module as well as its arguments. By default, all 16-bit + /// Windows-based applications created by CreateProcessAsUser are run in a separate VDM (equivalent to + /// CREATE_SEPARATE_WOW_VDM in CreateProcess). + /// + /// + /// + /// + /// The command line to be executed. The maximum length of this string is 32K characters. If lpApplicationName is NULL, the + /// module name portion of lpCommandLine is limited to MAX_PATH characters. + /// + /// + /// The Unicode version of this function, CreateProcessAsUserW, can modify the contents of this string. Therefore, this + /// parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a + /// constant string, the function may cause an access violation. + /// + /// + /// The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the + /// command line. + /// + /// + /// If both lpApplicationName and lpCommandLine are non- NULL, *lpApplicationName specifies the module to execute, and + /// *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console + /// processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C + /// programmers generally repeat the module name as the first token in the command line. + /// + /// + /// If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name. If you + /// are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin + /// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. + /// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period + /// (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory + /// path, the system searches for the executable file in the following sequence: + /// + /// + /// + /// The directory from which the application loaded. + /// + /// + /// The current directory for the parent process. + /// + /// + /// The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. + /// + /// + /// The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. + /// + /// + /// The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. + /// + /// + /// + /// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application + /// path specified by the App Paths registry key. To include this per-application path in the search sequence, use the + /// ShellExecute function. + /// + /// + /// + /// + /// The system adds a null character to the command line string to separate the file name from the arguments. This divides the + /// original string into two strings for internal processing. + /// + /// + /// + /// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new process object and determines + /// whether child processes can inherit the returned handle to the process. If lpProcessAttributes is NULL or + /// lpSecurityDescriptor is NULL, the process gets a default security descriptor and the handle cannot be inherited. + /// The default security descriptor is that of the user referenced in the hToken parameter. This security descriptor may not allow + /// access for the caller, in which case the process may not be opened again after it is run. The process handle is valid and will + /// continue to have full access rights. + /// + /// + /// A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new thread object and determines + /// whether child processes can inherit the returned handle to the thread. If lpThreadAttributes is NULL or + /// lpSecurityDescriptor is NULL, the thread gets a default security descriptor and the handle cannot be inherited. The + /// default security descriptor is that of the user referenced in the hToken parameter. This security descriptor may not allow access + /// for the caller. + /// + /// + /// + /// If this parameter is TRUE, each inheritable handle in the calling process is inherited by the new process. If the + /// parameter is FALSE, the handles are not inherited. Note that inherited handles have the same value and access rights as + /// the original handles. + /// + /// + /// Terminal Services: You cannot inherit handles across sessions. Additionally, if this parameter is TRUE, you must + /// create the process in the same session as the caller. + /// + /// + /// Protected Process Light (PPL) processes: The generic handle inheritance is blocked when a PPL process creates a non-PPL + /// process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights + /// + /// + /// + /// + /// The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags. + /// + /// + /// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the + /// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority + /// class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS or + /// BELOW_NORMAL_PRIORITY_CLASS. In this case, the child process receives the default priority class of the calling process. + /// + /// + /// + /// + /// A pointer to an environment block for the new process. If this parameter is NULL, the new process uses the environment of + /// the calling process. + /// + /// An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form: + /// name=value\0 + /// Because the equal sign is used as a separator, it must not be used in the name of an environment variable. + /// + /// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains + /// Unicode characters, be sure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. If this parameter is NULL and + /// the environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. + /// + /// + /// The ANSI version of this function, CreateProcessAsUserA fails if the total size of the environment block for the process + /// exceeds 32,767 characters. + /// + /// + /// Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A + /// Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block. + /// + /// + /// Windows Server 2003 and Windows XP: If the size of the combined user and system environment variable exceeds 8192 bytes, + /// the process created by CreateProcessAsUser no longer runs with the environment block passed to the function by the parent + /// process. Instead, the child process runs with the environment block returned by the CreateEnvironmentBlock function. + /// + /// To retrieve a copy of the environment block for a given user, use the CreateEnvironmentBlock function. + /// + /// + /// The full path to the current directory for the process. The string can also specify a UNC path. + /// + /// If this parameter is NULL, the new process will have the same current drive and directory as the calling process. (This feature + /// is provided primarily for shells that need to start an application and specify its initial drive and working directory.) + /// + /// + /// + /// A pointer to a STARTUPINFO or STARTUPINFOEX structure. + /// + /// The user must have full access to both the specified window station and desktop. If you want the process to be interactive, + /// specify winsta0\default. If the lpDesktop member is NULL, the new process inherits the desktop and window station of its + /// parent process. If this member is an empty string, "", the new process connects to a window station using the rules described in + /// Process Connection to a Window Station. + /// + /// + /// To set extended attributes, use a STARTUPINFOEX structure and specify EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter. + /// + /// Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed. + /// + /// Important The caller is responsible for ensuring that the standard handle fields in STARTUPINFO contain valid handle + /// values. These fields are copied unchanged to the child process without validation, even when the dwFlags member specifies + /// STARTF_USESTDHANDLES. Incorrect values can cause the child process to misbehave or crash. Use the Application Verifier + /// runtime verification tool to detect invalid handles. + /// + /// + /// + /// A pointer to a PROCESS_INFORMATION structure that receives identification information about the new process. + /// Handles in PROCESS_INFORMATION must be closed with CloseHandle when they are no longer needed. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to + /// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess. + /// + /// + /// + /// + /// CreateProcessAsUser must be able to open the primary token of the calling process with the TOKEN_DUPLICATE and + /// TOKEN_IMPERSONATE access rights. + /// + /// + /// By default, CreateProcessAsUser creates the new process on a noninteractive window station with a desktop that is not + /// visible and cannot receive user input. To enable user interaction with the new process, you must specify the name of the default + /// interactive window station and desktop, "winsta0\default", in the lpDesktop member of the STARTUPINFO structure. In + /// addition, before calling CreateProcessAsUser, you must change the discretionary access control list (DACL) of both the + /// default interactive window station and the default desktop. The DACLs for the window station and desktop must grant access to the + /// user or the logon session represented by the hToken parameter. + /// + /// + /// CreateProcessAsUser does not load the specified user's profile into the HKEY_USERS registry key. Therefore, to + /// access the information in the HKEY_CURRENT_USER registry key, you must load the user's profile information into + /// HKEY_USERS with the LoadUserProfile function before calling CreateProcessAsUser. Be sure to call UnloadUserProfile + /// after the new process exits. + /// + /// + /// If the lpEnvironment parameter is NULL, the new process inherits the environment of the calling process. + /// CreateProcessAsUser does not automatically modify the environment block to include environment variables specific to the + /// user represented by hToken. For example, the USERNAME and USERDOMAIN variables are inherited from the calling process if + /// lpEnvironment is NULL. It is your responsibility to prepare the environment block for the new process and specify it in lpEnvironment. + /// + /// + /// The CreateProcessWithLogonW and CreateProcessWithTokenW functions are similar to CreateProcessAsUser, except that the + /// caller does not need to call the LogonUser function to authenticate the user and get a token. + /// + /// + /// CreateProcessAsUser allows you to access the specified directory and executable image in the security context of the + /// caller or the target user. By default, CreateProcessAsUser accesses the directory and executable image in the security + /// context of the caller. In this case, if the caller does not have access to the directory and executable image, the function + /// fails. To access the directory and executable image using the security context of the target user, specify hToken in a call to + /// the ImpersonateLoggedOnUser function before calling CreateProcessAsUser. + /// + /// + /// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify + /// the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also + /// assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The identifier is + /// valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are + /// returned in the PROCESS_INFORMATION structure. + /// + /// + /// The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is + /// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because + /// CreateProcessAsUser returns without waiting for the new process to finish its initialization. For example, the creating + /// process would use WaitForInputIdle before trying to find a window associated with the new process. + /// + /// + /// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of + /// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached + /// DLLs. Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to + /// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process. + /// + /// Security Remarks + /// + /// The lpApplicationName parameter can be NULL, in which case the executable name must be the first white space–delimited string in + /// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because + /// of the way the function parses spaces. The following example is dangerous because the function will attempt to run "Program.exe", + /// if it exists, instead of "MyApp.exe". + /// + /// + /// If a malicious user were to create an application called "Program.exe" on a system, any program that incorrectly calls + /// CreateProcessAsUser using the Program Files directory will run this application instead of the intended application. + /// + /// + /// To avoid this problem, do not pass NULL for lpApplicationName. If you do pass NULL for lpApplicationName, use quotation + /// marks around the executable path in lpCommandLine, as shown in the example below. + /// + /// + /// PowerShell: When the CreateProcessAsUser function is used to implement a cmdlet in PowerShell version 2.0, the + /// cmdlet operates correctly for both fan-in and fan-out remote sessions. Because of certain security scenarios, however, a cmdlet + /// implemented with CreateProcessAsUser only operates correctly in PowerShell version 3.0 for fan-in remote sessions; fan-out + /// remote sessions will fail because of insufficient client security privileges. To implement a cmdlet that works for both fan-in + /// and fan-out remote sessions in PowerShell version 3.0, use the CreateProcess function. + /// + /// Examples + /// For an example, see Starting an Interactive Client Process. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessasusera BOOL + // CreateProcessAsUserA( HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, + // LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR + // lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("processthreadsapi.h", MSDNShortId = "6b3f4dd9-500b-420e-804a-401a9e188be8")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CreateProcessAsUser(HTOKEN hToken, [Optional] string lpApplicationName, [Optional] StringBuilder lpCommandLine, [Optional] SECURITY_ATTRIBUTES lpProcessAttributes, [Optional] SECURITY_ATTRIBUTES lpThreadAttributes, + [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles, CREATE_PROCESS dwCreationFlags, [Optional] IntPtr lpEnvironment, [Optional] string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, [Out] PROCESS_INFORMATION lpProcessInformation); + /// The OpenProcessToken function opens the access token associated with a process. /// /// A handle to the process whose access token is opened. The process must have the PROCESS_QUERY_INFORMATION access permission. diff --git a/PInvoke/Security/AdvApi32/WinBase.cs b/PInvoke/Security/AdvApi32/WinBase.cs index d23ff338..ebfee152 100644 --- a/PInvoke/Security/AdvApi32/WinBase.cs +++ b/PInvoke/Security/AdvApi32/WinBase.cs @@ -1,11 +1,1616 @@ using System; using System.Runtime.InteropServices; +using System.Security.AccessControl; using System.Text; +using static Vanara.PInvoke.Kernel32; namespace Vanara.PInvoke { public static partial class AdvApi32 { + /// + /// + /// An application-defined callback function used with ReadEncryptedFileRaw. The system calls ExportCallback one or more + /// times, each time with a block of the encrypted file's data, until it has received all of the file data. ExportCallback + /// writes the encrypted file's data to another storage media, usually for purposes of backing up the file. + /// + /// + /// The PFE_EXPORT_FUNC type defines a pointer to the callback function. ExportCallback is a placeholder for the + /// application-defined function name. + /// + /// + /// + /// A pointer to a block of the encrypted file's data to be backed up. This block of data is allocated by the system. + /// + /// + /// A pointer to an application-defined and allocated context block. The application passes this pointer to ReadEncryptedFileRaw, and + /// ReadEncryptedFileRaw passes this pointer to the callback function so that it can have access to application-specific data. + /// This data can be a structure and can contain any data the application needs, such as the handle to the file that contains the + /// backup copy of the encrypted file. + /// + /// The size of the data pointed to by the pbData parameter, in bytes. + /// + /// If the function succeeds, it must set the return value to ERROR_SUCCESS. + /// + /// If the function fails, set the return value to a nonzero error code defined in WinError.h. For example, if this function fails + /// because an API that it calls fails, you can set the return value to the value returned by GetLastError for the failed API. + /// + /// + /// + /// You can use the application-defined context block for internal tracking of information such as the file handle and the current + /// offset in the file. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nc-winbase-pfe_export_func PFE_EXPORT_FUNC PfeExportFunc; DWORD + // PfeExportFunc( PBYTE pbData, PVOID pvCallbackContext, ULONG ulLength ) {...} + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + [PInvokeData("winbase.h", MSDNShortId = "156948c9-d7b4-4491-bdb1-e1864a32caab")] + public delegate Win32Error ExportCallback(IntPtr pbData, IntPtr pvCallbackContext, uint ulLength); + + /// + /// + /// An application-defined callback function used with WriteEncryptedFileRaw. The system calls ImportCallback one or more + /// times, each time to retrieve a portion of a backup file's data. ImportCallback reads the data from a backup file + /// sequentially and restores the data, and the system continues calling it until it has read all of the backup file data. + /// + /// + /// The PFE_IMPORT_FUNC type defines a pointer to this callback function. ImportCallback is a placeholder for the + /// application-defined function name. + /// + /// + /// A pointer to a system-supplied buffer that will receive a block of data to be restored. + /// + /// A pointer to an application-defined and allocated context block. The application passes this pointer to WriteEncryptedFileRaw, + /// and it passes this pointer to the callback function so that the callback function can have access to application-specific data. + /// This data can be a structure and can contain any data the application needs, such as the handle to the file that contains the + /// backup copy of the encrypted file. + /// + /// + /// + /// On function entry, this parameter specifies the length of the buffer the system has supplied. The callback function must write no + /// more than this many bytes to the buffer pointed to by the pbData parameter. + /// + /// On exit, the function must set this to the number of bytes of data written into the pbData. + /// + /// + /// + /// If the function succeeds, it must set the return value to ERROR_SUCCESS, and set the value pointed to by the ulLength + /// parameter to the number of bytes copied into pbData. + /// + /// When the end of the backup file is reached, set ulLength to zero to tell the system that the entire file has been processed. + /// + /// If the function fails, set the return value to a nonzero error code defined in WinError.h. For example, if this function fails + /// because an API that it calls fails, you can set the return value to the value returned by GetLastError for the failed API. + /// + /// + /// + /// The system calls the ImportCallback function until the callback function indicates there is no more data to restore. To + /// indicate that there is no more data to be restored, set *ulLength to 0 and use a return code of ERROR_SUCCESS. You can use + /// the application-defined context block for internal tracking of information such as the file handle and the current offset in the file. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nc-winbase-pfe_import_func PFE_IMPORT_FUNC PfeImportFunc; DWORD + // PfeImportFunc( PBYTE pbData, PVOID pvCallbackContext, PULONG ulLength ) {...} + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + [PInvokeData("winbase.h", MSDNShortId = "4c951e44-15d8-43c8-bd3d-293a1ec9d444")] + public delegate Win32Error ImportCallback(IntPtr pbData, IntPtr pvCallbackContext, ref uint ulLength); + + /// Flags used by . + [PInvokeData("winbase.h", MSDNShortId = "ea14fd55-e0e4-4bf2-b20e-5874783c16c3")] + [Flags] + public enum AccessCheckFlags + { + /// The function performs the access check without generating audit messages when the privilege is not enabled. + AUDIT_ALLOW_NO_PRIVILEGE = 1 + } + + /// + /// The AUDIT_EVENT_TYPE enumeration type defines values that indicate the type of object being audited. The + /// AccessCheckByTypeAndAuditAlarm and AccessCheckByTypeResultListAndAuditAlarm functions use these values. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ne-winnt-_audit_event_type typedef enum _AUDIT_EVENT_TYPE { + // AuditEventObjectAccess, AuditEventDirectoryServiceAccess } AUDIT_EVENT_TYPE, *PAUDIT_EVENT_TYPE; + [PInvokeData("winnt.h", MSDNShortId = "7dc21840-6dcc-445b-a254-f8ca27008d63")] + public enum AUDIT_EVENT_TYPE + { + /// + /// Indicates an object that generates audit messages only if the system administrator has enabled auditing access to files and objects. + /// + AuditEventObjectAccess, + + /// + /// Indicates a directory service object that generates audit messages only if the system administrator has enabled auditing + /// access to directory service objects. + /// + AuditEventDirectoryServiceAccess, + } + + /// The reported docking state of the computer. + [PInvokeData("winbase.h", MSDNShortId = "b1c8eb4c-8c62-4e3e-a7d2-0888512b3d4c")] + [Flags] + public enum DOCKINFO : uint + { + /// The computer is undocked. This flag is always set for desktop systems that cannot be undocked. + DOCKINFO_UNDOCKED = 0x1, + + /// The computer is docked. + DOCKINFO_DOCKED = 0x2, + + /// + /// If this flag is set, GetCurrentHwProfile retrieved the current docking state from information provided by the user in the + /// Hardware Profiles page of the System control panel application. + /// If there is no such value or the value is set to 0, this flag is set. + /// + DOCKINFO_USER_SUPPLIED = 0x4, + + /// + /// The computer is docked, according to information provided by the user. This value is a combination of the + /// DOCKINFO_USER_SUPPLIED and DOCKINFO_DOCKED flags. + /// + DOCKINFO_USER_DOCKED = DOCKINFO_UNDOCKED | DOCKINFO_USER_SUPPLIED, + + /// + /// The computer is undocked, according to information provided by the user. This value is a combination of the + /// DOCKINFO_USER_SUPPLIED and DOCKINFO_UNDOCKED flags. + /// + DOCKINFO_USER_UNDOCKED = DOCKINFO_DOCKED | DOCKINFO_USER_SUPPLIED, + } + + /// The encryption status of the file. + [PInvokeData("winbase.h", MSDNShortId = "96efe065-de62-4941-811d-610465cd7ef5")] + public enum EncryptionStatus + { + /// + /// The file can be encrypted. + /// + /// Home, Home Premium, Starter, and ARM Editions of Windows: FILE_ENCRYPTABLE may be returned but EFS does not support + /// encrypting files on these editions of Windows. + /// + /// + FILE_ENCRYPTABLE = 0, + + /// The file is encrypted. + FILE_IS_ENCRYPTED = 1, + + /// The file is a read-only file. + FILE_READ_ONLY = 8, + + /// The file is a root directory. Root directories cannot be encrypted. + FILE_ROOT_DIR = 3, + + /// The file is a system file. System files cannot be encrypted. + FILE_SYSTEM_ATTR = 2, + + /// The file is a system directory. System directories cannot be encrypted. + FILE_SYSTEM_DIR = 4, + + /// The file system does not support file encryption. + FILE_SYSTEM_NOT_SUPPORT = 6, + + /// The encryption status is unknown. The file may be encrypted. + FILE_UNKNOWN = 5, + + /// Reserved for future use. + FILE_USER_DISALLOWED = 7, + + /// Reserved for future use. + FILE_DIR_DISALLOWED = 9, + } + + /// Flags used by . + [Flags] + public enum IS_TEXT_UNICODE : uint + { + IS_TEXT_UNICODE_ASCII16 = 0x0001, + IS_TEXT_UNICODE_STATISTICS = 0x0002, + IS_TEXT_UNICODE_REVERSE_ASCII16 = 0x0010, + IS_TEXT_UNICODE_REVERSE_STATISTICS = 0x0020, + IS_TEXT_UNICODE_CONTROLS = 0x0004, + IS_TEXT_UNICODE_REVERSE_CONTROLS = 0x0040, + IS_TEXT_UNICODE_SIGNATURE = 0x0008, + IS_TEXT_UNICODE_REVERSE_SIGNATURE = 0x0080, + IS_TEXT_UNICODE_ILLEGAL_CHARS = 0x0100, + IS_TEXT_UNICODE_ODD_LENGTH = 0x0200, + IS_TEXT_UNICODE_DBCS_LEADBYTE = 0x0400, + IS_TEXT_UNICODE_NULL_BYTES = 0x1000, + IS_TEXT_UNICODE_UNICODE_MASK = 0x000F, + IS_TEXT_UNICODE_REVERSE_MASK = 0x00F0, + IS_TEXT_UNICODE_NOT_UNICODE_MASK = 0x0F00, + IS_TEXT_UNICODE_NOT_ASCII_MASK = 0xF000, + } + + /// The operation to perform when calling OpenEncryptedFileRaw. + [PInvokeData("winbase.h", MSDNShortId = "f792f38d-783e-4f39-a9d8-0c378d508d97")] + public enum OpenRawFlags + { + /// The file is being opened for import (restore). + CREATE_FOR_IMPORT = 1, + + /// + /// Import (restore) a directory containing encrypted files. This must be combined with one of the previous two flags to indicate + /// the operation. + /// + CREATE_FOR_DIR = 2, + + /// Overwrite a hidden file on import. + OVERWRITE_HIDDEN = 4, + + /// + EFSRPC_SECURE_ONLY = 8, + + /// + EFS_DROP_ALTERNATE_STREAMS = 0x10 + } + + /// The logon option. + [PInvokeData("winbase.h", MSDNShortId = "dcfdcd5b-0269-4081-b1db-e272171c27a2")] + [Flags] + public enum ProcessLogonFlags : uint + { + /// + /// Log on, then load the user profile in the HKEY_USERS registry key. The function returns after the profile is loaded. Loading + /// the profile can be time-consuming, so it is best to use this value only if you must access the information in the + /// HKEY_CURRENT_USER registry key. + /// + /// Windows Server 2003: The profile is unloaded after the new process is terminated, whether or not it has created child processes. + /// + /// Windows XP: The profile is unloaded after the new process and all child processes it has created are terminated. + /// + LOGON_WITH_PROFILE = 0x00000001, + + /// + /// Log on, but use the specified credentials on the network only. The new process uses the same token as the caller, but the + /// system creates a new logon session within LSA, and the process uses the specified credentials as the default credentials. + /// + /// This value can be used to create a process that uses a different set of credentials locally than it does remotely. This is + /// useful in inter-domain scenarios where there is no trust relationship. + /// + /// + /// The system does not validate the specified credentials. Therefore, the process can start, but it may not have access to + /// network resources. + /// + /// + LOGON_NETCREDENTIALS_ONLY = 0x00000002, + + /// The logon zero password buffer + LOGON_ZERO_PASSWORD_BUFFER = 0x80000000 + } + + /// + /// + /// The AccessCheckByTypeAndAuditAlarm function determines whether a security descriptor grants a specified set of access + /// rights to the client being impersonated by the calling thread. The function can check the client's access to a hierarchy of + /// objects, such as an object, its property sets, and properties. The function grants or denies access to the hierarchy as a whole. + /// If the security descriptor has a system access control list (SACL) with access control entries (ACEs) that apply to the client, + /// the function generates any necessary audit messages in the security event log. + /// + /// Alarms are not currently supported. + /// + /// + /// A pointer to a null-terminated string that specifies the name of the subsystem calling the function. This string appears in any + /// audit message that the function generates. + /// + /// + /// A pointer to a unique value that represents the client's handle to the object. If the access is denied, the system ignores this value. + /// + /// + /// A pointer to a null-terminated string that specifies the type of object being created or accessed. This string appears in any + /// audit message that the function generates. + /// + /// + /// A pointer to a null-terminated string that specifies the name of the object being created or accessed. This string appears in any + /// audit message that the function generates. + /// + /// A pointer to a SECURITY_DESCRIPTOR structure against which access is checked. + /// + /// + /// A pointer to a security identifier (SID). If the security descriptor is associated with an object that represents a principal + /// (for example, a user object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID + /// logically replaces the SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10). For information about well-known + /// SIDs, see Well-known SIDs. + /// + /// If the protected object does not represent a principal, set this parameter to NULL. + /// + /// + /// + /// An access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to + /// contain no generic access rights. + /// + /// + /// If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the + /// security descriptor allows the client. + /// + /// + /// + /// The type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type. + /// + /// + /// A flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the + /// AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege + /// is not enabled. If this parameter is zero, the function fails if the privilege is not enabled. + /// + /// + /// + /// A pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each + /// element in the array specifies a GUID that identifies the object type and a value that indicates the level of the object type in + /// the hierarchy of object types. The array should not have two elements with the same GUID. + /// + /// + /// The array must have at least one element. The first element in the array must be at level zero and identify the object itself. + /// The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following + /// each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array + /// might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeAndAuditAlarm fails and + /// GetLastError returns ERROR_INVALID_PARAMETER. + /// + /// + /// The number of elements in the ObjectTypeList array. + /// + /// A pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked. + /// + /// + /// A flag that determines whether the calling application will create a new object when access is granted. A value of TRUE + /// indicates the application will create a new object. A value of FALSE indicates the application will open an existing object. + /// + /// + /// A pointer to an access mask that receives the granted access rights. If AccessStatus is set to FALSE, the function sets + /// the access mask to zero. If the function fails, it does not set the access mask. + /// + /// + /// A pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access + /// rights to the client, AccessStatus is set to TRUE. Otherwise, AccessStatus is set to FALSE and you can call + /// GetLastError to get extended error information. + /// + /// + /// A pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm + /// function when the object handle is closed. + /// + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// + /// For more information, see the How AccessCheck Works overview. + /// + /// If the PrincipalSelfSid and ObjectTypeList parameters are NULL, the AuditType parameter is AuditEventObjectAccess, and the + /// Flags parameter is zero, AccessCheckByTypeAndAuditAlarm performs in the same way as the AccessCheckAndAuditAlarm function. + /// + /// + /// The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the + /// object for which to check access. For instance, to check access to two properties in a property set, specify an object type list + /// with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2. + /// + /// + /// The AccessCheckByTypeAndAuditAlarm function evaluates ACEs that apply to the object itself and object-specific ACEs for + /// the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for object types not listed in the + /// ObjectTypeList array. Thus, the results returned in the AccessStatus parameter indicate the access allowed to the subset of the + /// object defined by the ObjectTypeList parameter, not to the entire object. + /// + /// + /// For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to + /// an Object's Properties. + /// + /// + /// To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The + /// system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the + /// Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit + /// messages when the privilege is not enabled. + /// + /// The AccessCheckByTypeAndAuditAlarm function fails if the calling thread is not impersonating a client. + /// If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeAndAuditAlarm fails with ERROR_INVALID_SECURITY_DESCR. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-accesscheckbytypeandauditalarma BOOL + // AccessCheckByTypeAndAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, LPCSTR ObjectTypeName, LPCSTR ObjectName, + // PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, DWORD DesiredAccess, AUDIT_EVENT_TYPE AuditType, DWORD Flags, + // POBJECT_TYPE_LIST ObjectTypeList, DWORD ObjectTypeListLength, PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD + // GrantedAccess, LPBOOL AccessStatus, LPBOOL pfGenerateOnClose ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "ea14fd55-e0e4-4bf2-b20e-5874783c16c3")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AccessCheckByTypeAndAuditAlarm(string SubsystemName, [In] IntPtr HandleId, string ObjectTypeName, [Optional] string ObjectName, [In] PSECURITY_DESCRIPTOR SecurityDescriptor, + [In, Optional] PSID PrincipalSelfSid, ACCESS_MASK DesiredAccess, AUDIT_EVENT_TYPE AuditType, AccessCheckFlags Flags, [In, Out, MarshalAs(UnmanagedType.LPArray)] OBJECT_TYPE_LIST[] ObjectTypeList, uint ObjectTypeListLength, + in GENERIC_MAPPING GenericMapping, [MarshalAs(UnmanagedType.Bool)] bool ObjectCreation, out ACCESS_MASK GrantedAccess, [MarshalAs(UnmanagedType.Bool)] out bool AccessStatus, [MarshalAs(UnmanagedType.Bool)] out bool pfGenerateOnClose); + + /// + /// + /// The AccessCheckByTypeResultListAndAuditAlarmByHandle function determines whether a security descriptor grants a specified + /// set of access rights to the client that the calling thread is impersonating. The difference between this function and + /// AccessCheckByTypeResultListAndAuditAlarm is that this function allows the calling thread to perform the access check before + /// impersonating the client. + /// + /// + /// The function can check access to a hierarchy of objects, such as an object, its property sets, and properties. The function + /// reports the access rights granted or denied to each object type in the hierarchy. If the security descriptor has a system access + /// control list (SACL) with access control entries (ACEs) that apply to the client, the function generates any necessary audit + /// messages in the security event log. Alarms are not currently supported. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the name of the subsystem calling the function. This string appears in any + /// audit message that the function generates. + /// + /// + /// A pointer to a unique value that represents the client's handle to the object. If the access is denied, the system ignores this value. + /// + /// + /// A handle to a token object that represents the client that requested the operation. This handle must be obtained through a + /// communication session layer, such as a local named pipe, to prevent possible security policy violations. The caller must have + /// TOKEN_QUERY access for the specified token. + /// + /// + /// A pointer to a null-terminated string that specifies the type of object being created or accessed. This string appears in any + /// audit message that the function generates. + /// + /// + /// A pointer to a null-terminated string that specifies the name of the object being created or accessed. This string appears in any + /// audit message that the function generates. + /// + /// A pointer to a SECURITY_DESCRIPTOR structure against which access is checked. + /// + /// + /// A pointer to a SID. If the security descriptor is associated with an object that represents a principal (for example, a user + /// object), the PrincipalSelfSid parameter should be the SID of the object. When evaluating access, this SID logically replaces the + /// SID in any ACE containing the well-known PRINCIPAL_SELF SID (S-1-5-10). For information about well-known SIDs, see Well-known SIDs. + /// + /// Set this parameter to NULL if the protected object does not represent a principal. + /// + /// + /// + /// An access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function so that + /// it contains no generic access rights. + /// + /// + /// If this parameter is MAXIMUM_ALLOWED, the function sets the access mask in GrantedAccess to indicate the maximum access rights + /// the security descriptor allows the client. + /// + /// + /// + /// The type of audit to be generated. This can be one of the values from the AUDIT_EVENT_TYPE enumeration type. + /// + /// + /// A flag that controls the function's behavior if the calling process does not have the SE_AUDIT_NAME privilege enabled. If the + /// AUDIT_ALLOW_NO_PRIVILEGE flag is set, the function performs the access check without generating audit messages when the privilege + /// is not enabled. If this parameter is zero, the function fails if the privilege is not enabled. + /// + /// + /// + /// A pointer to an array of OBJECT_TYPE_LIST structures that identify the hierarchy of object types for which to check access. Each + /// element in the array specifies a GUID that identifies the object type and a value that indicates the level of the object type in + /// the hierarchy of object types. The array should not have two elements with the same GUID. + /// + /// + /// The array must have at least one element. The first element in the array must be at level zero and identify the object itself. + /// The array can have only one level zero element. The second element is a subobject, such as a property set, at level 1. Following + /// each level 1 entry are subordinate entries for the level 2 through 4 subobjects. Thus, the levels for the elements in the array + /// might be {0, 1, 2, 2, 1, 2, 3}. If the object type list is out of order, AccessCheckByTypeResultListAndAuditAlarmByHandle + /// fails, and GetLastError returns ERROR_INVALID_PARAMETER. + /// + /// + /// The number of elements in the ObjectTypeList array. + /// + /// A pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked. + /// + /// + /// A flag that determines whether the calling application will create a new object when access is granted. A value of TRUE + /// indicates the application will create a new object. A value of FALSE indicates the application will open an existing object. + /// + /// + /// A pointer to an array of access masks. The function sets each access mask to indicate the access rights granted to the + /// corresponding element in the object type list. If the function fails, it does not set the access masks. + /// + /// + /// A pointer to an array of status codes for the corresponding elements in the object type list. The function sets an element to + /// zero to indicate success or to a nonzero value to indicate the specific error during the access check. If the function fails, it + /// does not set any of the elements in the array. + /// + /// + /// A pointer to a flag set by the audit-generation routine when the function returns. Pass this flag to the ObjectCloseAuditAlarm + /// function when the object handle is closed. + /// + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// + /// For more information, see the How AccessCheck Works overview. + /// + /// Like AccessCheckByTypeResultListAndAuditAlarm, the AccessCheckByTypeResultListAndAuditAlarmByHandle function is a + /// combination of the AccessCheckByTypeResultList and AccessCheckAndAuditAlarm functions. However, + /// AccessCheckByTypeResultListAndAuditAlarmByHandle also requires a client token handle to provide security information on + /// the client. + /// + /// + /// The ObjectTypeList array does not necessarily represent the entire defined object. Rather, it represents that subset of the + /// object for which to check access. For instance, to check access to two properties in a property set, specify an object type list + /// with four elements: the object itself at level zero, the property set at level 1, and the two properties at level 2. + /// + /// + /// The AccessCheckByTypeResultListAndAuditAlarmByHandle function evaluates ACEs that apply to the object itself and + /// object-specific ACEs for the object types listed in the ObjectTypeList array. The function ignores object-specific ACEs for + /// object types not listed in the ObjectTypeList array. + /// + /// + /// For more information about how a hierarchy of ACEs controls access to an object and its subobjects, see ACEs to Control Access to + /// an Object's Properties. + /// + /// + /// To generate audit messages in the security event log, the calling process must have the SE_AUDIT_NAME privilege enabled. The + /// system checks for this privilege in the primary token of the calling process, not the impersonation token of the thread. If the + /// Flags parameter includes the AUDIT_ALLOW_NO_PRIVILEGE flag, the function performs the access check without generating audit + /// messages when the privilege is not enabled. + /// + /// + /// The AccessCheckByTypeResultListAndAuditAlarmByHandle function fails if the calling thread is not impersonating a client. + /// + /// + /// If the security descriptor does not contain owner and group SIDs, AccessCheckByTypeResultListAndAuditAlarmByHandle fails + /// with ERROR_INVALID_SECURITY_DESCR. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-accesscheckbytyperesultlistandauditalarmbyhandlea BOOL + // AccessCheckByTypeResultListAndAuditAlarmByHandleA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken, LPCSTR + // ObjectTypeName, LPCSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, DWORD DesiredAccess, + // AUDIT_EVENT_TYPE AuditType, DWORD Flags, POBJECT_TYPE_LIST ObjectTypeList, DWORD ObjectTypeListLength, PGENERIC_MAPPING + // GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess, LPDWORD AccessStatusList, LPBOOL pfGenerateOnClose ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "7d3ddce4-40a2-483d-8cff-48d89313b383")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AccessCheckByTypeResultListAndAuditAlarmByHandle(string SubsystemName, [In] IntPtr HandleId, [In] HTOKEN ClientToken, string ObjectTypeName, [Optional] string ObjectName, + [In] PSECURITY_DESCRIPTOR SecurityDescriptor, [Optional] PSID PrincipalSelfSid, ACCESS_MASK DesiredAccess, AUDIT_EVENT_TYPE AuditType, AccessCheckFlags Flags, + [In, Out, MarshalAs(UnmanagedType.LPArray)] OBJECT_TYPE_LIST[] ObjectTypeList, uint ObjectTypeListLength, in GENERIC_MAPPING GenericMapping, [MarshalAs(UnmanagedType.Bool)] bool ObjectCreation, + [In, Out, MarshalAs(UnmanagedType.LPArray)] ACCESS_MASK[] GrantedAccess, [In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] AccessStatusList, [MarshalAs(UnmanagedType.Bool)] out bool pfGenerateOnClose); + + /// + /// The AddConditionalAce function adds a conditional access control entry (ACE) to the specified access control list (ACL). A + /// conditional ACE specifies a logical condition that is evaluated during access checks. + /// + /// + /// A pointer to an ACL. This function adds an ACE to this ACL. + /// The value of this parameter cannot be NULL. + /// + /// + /// Specifies the revision level of the ACL being modified. This value can be ACL_REVISION or ACL_REVISION_DS. Use ACL_REVISION_DS if + /// the ACL contains object-specific ACEs. + /// + /// + /// A set of bit flags that control ACE inheritance. The function sets these flags in the AceFlags member of the ACE_HEADER + /// structure of the new ACE. This parameter can be a combination of the following values. + /// + /// + /// The type of the ACE. + /// This can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// ACCESS_ALLOWED_CALLBACK_ACE_TYPE 0x9 + /// Access-allowed callback ACE that uses the ACCESS_ALLOWED_CALLBACK_ACE structure. + /// + /// + /// ACCESS_DENIED_CALLBACK_ACE_TYPE 0xA + /// Access-denied callback ACE that uses the ACCESS_DENIED_CALLBACK_ACE structure. + /// + /// + /// SYSTEM_AUDIT_CALLBACK_ACE_TYPE 0xD + /// System audit callback ACE that uses the SYSTEM_AUDIT_CALLBACK_ACE structure. + /// + /// + /// + /// Specifies the mask of access rights to be granted to the specified SID. + /// A pointer to the SID that represents a user, group, or logon account being granted access. + /// A string that specifies the conditional statement to be evaluated for the ACE. + /// + /// The size, in bytes, of the ACL. If the buffer specified by the pACL parameter is not of sufficient size, the value of this + /// parameter is the required size. + /// + /// + /// If the function succeeds, it returns TRUE. + /// + /// If the function fails, it returns FALSE. For extended error information, call GetLastError. The following are possible + /// error values. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_INSUFFICIENT_BUFFER + /// The new ACE does not fit into the pAcl buffer. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-addconditionalace BOOL AddConditionalAce( PACL pAcl, DWORD + // dwAceRevision, DWORD AceFlags, UCHAR AceType, DWORD AccessMask, PSID pSid, PWCHAR ConditionStr, DWORD *ReturnLength ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winbase.h", MSDNShortId = "89f038be-d15c-4c0b-8145-ba531bdf87ce")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AddConditionalAce([In, Out] PACL pAcl, uint dwAceRevision, AceFlags AceFlags, AceType AceType, ACCESS_MASK AccessMask, PSID pSid, [MarshalAs(UnmanagedType.LPWStr)] string ConditionStr, out uint ReturnLength); + + /// + /// Closes an encrypted file after a backup or restore operation, and frees associated system resources. This is one of a group of + /// Encrypted File System (EFS) functions that is intended to implement backup and restore functionality, while maintaining files in + /// their encrypted state. + /// + /// + /// A pointer to a system-defined context block. The OpenEncryptedFileRaw function returns the context block. + /// + /// This function does not return a value. + /// + /// + /// The CloseEncryptedFileRaw function frees allocated system resources such as the system-defined context block and closes + /// the file. + /// + /// The BackupRead and BackupWrite functions handle backup and restore of unencrypted files. + /// In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies. + /// + /// + /// Technology + /// Supported + /// + /// + /// Server Message Block (SMB) 3.0 protocol + /// Yes + /// + /// + /// SMB 3.0 Transparent Failover (TFO) + /// No + /// + /// + /// SMB 3.0 with Scale-out File Shares (SO) + /// No + /// + /// + /// Cluster Shared Volume File System (CsvFS) + /// No + /// + /// + /// Resilient File System (ReFS) + /// No + /// + /// + /// Note that SMB 3.0 does not support EFS on shares with continuous availability capability. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-closeencryptedfileraw void CloseEncryptedFileRaw( PVOID + // pvContext ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winbase.h", MSDNShortId = "54bf7114-0ebb-4d9c-bc67-2ac351dbe55d")] + public static extern void CloseEncryptedFileRaw(IntPtr pvContext); + + /// + /// + /// Creates a new process and its primary thread. Then the new process runs the specified executable file in the security context of + /// the specified credentials (user, domain, and password). It can optionally load the user profile for a specified user. + /// + /// + /// This function is similar to the CreateProcessAsUser and CreateProcessWithTokenW functions, except that the caller does not need + /// to call the LogonUser function to authenticate the user and get a token. + /// + /// + /// + /// + /// The name of the user. This is the name of the user account to log on to. If you use the UPN format, user@DNS_domain_name, the + /// lpDomain parameter must be NULL. + /// + /// + /// The user account must have the Log On Locally permission on the local computer. This permission is granted to all users on + /// workstations and servers, but only to administrators on domain controllers. + /// + /// + /// + /// The name of the domain or server whose account database contains the lpUsername account. If this parameter is NULL, the user name + /// must be specified in UPN format. + /// + /// The clear-text password for the lpUsername account. + /// The logon option. This parameter can be 0 (zero) or one of the following values. + /// + /// + /// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for + /// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer. + /// + /// + /// The string can specify the full path and file name of the module to execute or it can specify a partial name. If it is a partial + /// name, the function uses the current drive and current directory to complete the specification. The function does not use the + /// search path. This parameter must include the file name extension; no default extension is assumed. + /// + /// + /// The lpApplicationName parameter can be NULL, and the module name must be the first white space–delimited token in the + /// lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name + /// ends and the arguments begin; otherwise, the file name is ambiguous. + /// + /// For example, the following string can be interpreted in different ways: + /// "c:\program files\sub dir\program name" + /// The system tries to interpret the possibilities in the following order: + /// + /// + /// c:\program.exe files\sub dir\program name + /// + /// + /// c:\program files\sub.exe dir\program name + /// + /// + /// c:\program files\sub dir\program.exe name + /// + /// + /// c:\program files\sub dir\program name.exe + /// + /// + /// + /// If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string pointed to by lpCommandLine + /// should specify the executable module and its arguments. + /// + /// + /// + /// + /// The command line to be executed. The maximum length of this string is 1024 characters. If lpApplicationName is NULL, the + /// module name portion of lpCommandLine is limited to MAX_PATH characters. + /// + /// + /// The function can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a + /// const variable or a literal string). If this parameter is a constant string, the function may cause an access violation. + /// + /// + /// The lpCommandLine parameter can be NULL, and the function uses the string pointed to by lpApplicationName as the command line. + /// + /// + /// If both lpApplicationName and lpCommandLine are non- NULL, *lpApplicationName specifies the module to execute, and + /// *lpCommandLine specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console + /// processes written in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C + /// programmers typically repeat the module name as the first token in the command line. + /// + /// + /// If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name. If you + /// are using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin + /// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. + /// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period + /// with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, + /// the system searches for the executable file in the following sequence: + /// + /// + /// + /// The directory from which the application loaded. + /// + /// + /// The current directory for the parent process. + /// + /// + /// The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. + /// + /// + /// The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. + /// + /// + /// The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. + /// + /// + /// + /// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application + /// path specified by the App Paths registry key. To include this per-application path in the search sequence, use the + /// ShellExecute function. + /// + /// + /// + /// + /// The system adds a null character to the command line string to separate the file name from the arguments. This divides the + /// original string into two strings for internal processing. + /// + /// + /// + /// + /// The flags that control how the process is created. The CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE, and + /// CREATE_NEW_PROCESS_GROUP flags are enabled by default— even if you do not set the flag, the system functions as if it were + /// set. You can specify additional flags as noted. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// CREATE_DEFAULT_ERROR_MODE 0x04000000 + /// + /// The new process does not inherit the error mode of the calling process. Instead, CreateProcessWithLogonW gives the new process + /// the current default error mode. An application sets the current default error mode by calling SetErrorMode. This flag is enabled + /// by default. + /// + /// + /// + /// CREATE_NEW_CONSOLE 0x00000010 + /// + /// The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS + /// flag. This flag is enabled by default. + /// + /// + /// + /// CREATE_NEW_PROCESS_GROUP 0x00000200 + /// + /// The new process is the root process of a new process group. The process group includes all processes that are descendants of this + /// root process. The process identifier of the new process group is the same as the process identifier, which is returned in the + /// lpProcessInfo parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+C or + /// CTRL+BREAK signal to a group of console processes. This flag is enabled by default. + /// + /// + /// + /// CREATE_SEPARATE_WOW_VDM 0x00000800 + /// + /// This flag is only valid starting a 16-bit Windows-based application. If set, the new process runs in a private Virtual DOS + /// Machine (VDM). By default, all 16-bit Windows-based applications run in a single, shared VDM. The advantage of running separately + /// is that a crash only terminates the single VDM; any other programs running in distinct VDMs continue to function normally. Also, + /// 16-bit Windows-based applications that run in separate VDMs have separate input queues, which means that if one application stops + /// responding momentarily, applications in separate VDMs continue to receive input. + /// + /// + /// + /// CREATE_SUSPENDED 0x00000004 + /// + /// The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called. + /// + /// + /// + /// CREATE_UNICODE_ENVIRONMENT 0x00000400 + /// + /// Indicates the format of the lpEnvironment parameter. If this flag is set, the environment block pointed to by lpEnvironment uses + /// Unicode characters. Otherwise, the environment block uses ANSI characters. + /// + /// + /// + /// + /// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the + /// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority + /// class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS or + /// BELOW_NORMAL_PRIORITY_CLASS. In this case, the child process receives the default priority class of the calling process. + /// + /// + /// + /// + /// A pointer to an environment block for the new process. If this parameter is NULL, the new process uses an environment + /// created from the profile of the user specified by lpUsername. + /// + /// An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form: + /// name=value + /// Because the equal sign (=) is used as a separator, it must not be used in the name of an environment variable. + /// + /// An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains + /// Unicode characters, ensure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. If this parameter is NULL and the + /// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. + /// + /// + /// An ANSI environment block is terminated by two 0 (zero) bytes: one for the last string and one more to terminate the block. A + /// Unicode environment block is terminated by four zero bytes: two for the last string and two more to terminate the block. + /// + /// To retrieve a copy of the environment block for a specific user, use the CreateEnvironmentBlock function. + /// + /// + /// The full path to the current directory for the process. The string can also specify a UNC path. + /// + /// If this parameter is NULL, the new process has the same current drive and directory as the calling process. This feature + /// is provided primarily for shells that need to start an application, and specify its initial drive and working directory. + /// + /// + /// + /// A pointer to a STARTUPINFO structure. + /// + /// The application must add permission for the specified user account to the specified window station and desktop, even for WinSta0\Default. + /// + /// + /// If the lpDesktop member is NULL or an empty string, the new process inherits the desktop and window station of its + /// parent process. The application must add permission for the specified user account to the inherited window station and desktop. + /// + /// + /// Windows XP:CreateProcessWithLogonW adds permission for the specified user account to the inherited window station + /// and desktop. + /// + /// Handles in STARTUPINFO must be closed with CloseHandle when they are no longer needed. + /// + /// Important If the dwFlags member of the STARTUPINFO structure specifies STARTF_USESTDHANDLES, the standard + /// handle fields are copied unchanged to the child process without validation. The caller is responsible for ensuring that these + /// fields contain valid handle values. Incorrect values can cause the child process to misbehave or crash. Use the Application + /// Verifier runtime verification tool to detect invalid handles. + /// + /// + /// + /// + /// A pointer to a PROCESS_INFORMATION structure that receives identification information for the new process, including a handle to + /// the process. + /// + /// Handles in PROCESS_INFORMATION must be closed with the CloseHandle function when they are not needed. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError. + /// + /// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to + /// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess. + /// + /// + /// + /// + /// By default, CreateProcessWithLogonW does not load the specified user profile into the HKEY_USERS registry key. This + /// means that access to information in the HKEY_CURRENT_USER registry key may not produce results that are consistent with a + /// normal interactive logon. It is your responsibility to load the user registry hive into HKEY_USERS before calling + /// CreateProcessWithLogonW, by using LOGON_WITH_PROFILE, or by calling the LoadUserProfile function. + /// + /// + /// If the lpEnvironment parameter is NULL, the new process uses an environment block created from the profile of the user specified + /// by lpUserName. If the HOMEDRIVE and HOMEPATH variables are not set, CreateProcessWithLogonW modifies the environment block + /// to use the drive and path of the user's working directory. + /// + /// + /// When created, the new process and thread handles receive full access rights ( PROCESS_ALL_ACCESS and + /// THREAD_ALL_ACCESS). For either handle, if a security descriptor is not provided, the handle can be used in any function + /// that requires an object handle of that type. When a security descriptor is provided, an access check is performed on all + /// subsequent uses of the handle before access is granted. If access is denied, the requesting process cannot use the handle to gain + /// access to the process or thread. + /// + /// To retrieve a security token, pass the process handle in the PROCESS_INFORMATION structure to the OpenProcessToken function. + /// + /// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify + /// the process, or it can be specified in the OpenProcess function to open a handle to the process. The initial thread in the + /// process is also assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The + /// identifier is valid until the thread terminates and can be used to uniquely identify the thread within the system. These + /// identifiers are returned in PROCESS_INFORMATION. + /// + /// + /// The calling thread can use the WaitForInputIdle function to wait until the new process has completed its initialization and is + /// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because + /// CreateProcessWithLogonW returns without waiting for the new process to finish its initialization. For example, the + /// creating process would use WaitForInputIdle before trying to find a window that is associated with the new process. + /// + /// + /// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of + /// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached + /// DLLs. Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to + /// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process. + /// + /// + /// CreateProcessWithLogonW accesses the specified directory and executable image in the security context of the target user. + /// If the executable image is on a network and a network drive letter is specified in the path, the network drive letter is not + /// available to the target user, as network drive letters can be assigned for each logon. If a network drive letter is specified, + /// this function fails. If the executable image is on a network, use the UNC path. + /// + /// + /// There is a limit to the number of child processes that can be created by this function and run simultaneously. For example, on + /// Windows XP, this limit is MAXIMUM_WAIT_OBJECTS*4. However, you may not be able to create this many processes due to + /// system-wide quota limits. + /// + /// + /// Windows XP with SP2,Windows Server 2003, or later: You cannot call CreateProcessWithLogonW from a process that is + /// running under the "LocalSystem" account, because the function uses the logon SID in the caller token, and the token for the + /// "LocalSystem" account does not contain this SID. As an alternative, use the CreateProcessAsUser and LogonUser functions. + /// + /// + /// To compile an application that uses this function, define _WIN32_WINNT as 0x0500 or later. For more information, see Using + /// the Windows Headers. + /// + /// Security Remarks + /// + /// The lpApplicationName parameter can be NULL, and the executable name must be the first white space–delimited string in + /// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because + /// of the way the function parses spaces. Avoid the following example, because the function attempts to run "Program.exe", if it + /// exists, instead of "MyApp.exe". + /// + /// + /// If a malicious user creates an application called "Program.exe" on a system, any program that incorrectly calls + /// CreateProcessWithLogonW using the Program Files directory runs the malicious user application instead of the intended application. + /// + /// + /// To avoid this issue, do not pass NULL for lpApplicationName. If you pass NULL for lpApplicationName, use quotation + /// marks around the executable path in lpCommandLine, as shown in the following example: + /// + /// Examples + /// The following example demonstrates how to call this function. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createprocesswithlogonw BOOL CreateProcessWithLogonW( + // LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, + // DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION + // lpProcessInformation ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)] + [PInvokeData("winbase.h", MSDNShortId = "dcfdcd5b-0269-4081-b1db-e272171c27a2")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CreateProcessWithLogonW(string lpUsername, [Optional] string lpDomain, string lpPassword, ProcessLogonFlags dwLogonFlags, [Optional] string lpApplicationName, [Optional] StringBuilder lpCommandLine, + CREATE_PROCESS dwCreationFlags, [Optional] IntPtr lpEnvironment, [Optional] string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, [Out] PROCESS_INFORMATION lpProcessInformation); + + /// + /// + /// Creates a new process and its primary thread. The new process runs in the security context of the specified token. It can + /// optionally load the user profile for the specified user. + /// + /// + /// The process that calls CreateProcessWithTokenW must have the SE_IMPERSONATE_NAME privilege. If this function fails with + /// ERROR_PRIVILEGE_NOT_HELD (1314), use the CreateProcessAsUser or CreateProcessWithLogonW function instead. Typically, the process + /// that calls CreateProcessAsUser must have the SE_INCREASE_QUOTA_NAME privilege and may require the + /// SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable. CreateProcessWithLogonW requires no special + /// privileges, but the specified user account must be allowed to log on interactively. Generally, it is best to use + /// CreateProcessWithLogonW to create a process with alternate credentials. + /// + /// + /// + /// + /// A handle to the primary token that represents a user. The handle must have the TOKEN_QUERY, TOKEN_DUPLICATE, and + /// TOKEN_ASSIGN_PRIMARY access rights. For more information, see Access Rights for Access-Token Objects. The user represented by the + /// token must have read and execute access to the application specified by the lpApplicationName or the lpCommandLine parameter. + /// + /// + /// To get a primary token that represents the specified user, call the LogonUser function. Alternatively, you can call the + /// DuplicateTokenEx function to convert an impersonation token into a primary token. This allows a server application that is + /// impersonating a client to create a process that has the security context of the client. + /// + /// + /// Terminal Services: The process is run in the session specified in the token. By default, this is the same session that + /// called LogonUser. To change the session, use the SetTokenInformation function. + /// + /// + /// The logon option. This parameter can be zero or one of the following values. + /// + /// + /// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for + /// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer. + /// + /// + /// The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a + /// partial name, the function uses the current drive and current directory to complete the specification. The function will not use + /// the search path. This parameter must include the file name extension; no default extension is assumed. + /// + /// + /// The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the + /// lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name + /// ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub + /// dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the + /// following order: + /// + /// + /// c:\program.exec:\program files\sub.exec:\program files\sub dir\program.exec:\program files\sub + /// dir\program name.exe If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string + /// pointed to by lpCommandLine should specify the executable module as well as its arguments. + /// + /// + /// + /// The command line to be executed. + /// + /// The maximum length of this string is 1024 characters. If lpApplicationName is NULL, the module name portion of lpCommandLine is + /// limited to MAX_PATH characters. + /// + /// + /// The function can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a + /// const variable or a literal string). If this parameter is a constant string, the function may cause an access violation. + /// + /// + /// The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the + /// command line. + /// + /// + /// If both lpApplicationName and lpCommandLine are non-NULL, *lpApplicationName specifies the module to execute, and *lpCommandLine + /// specifies the command line. The new process can use GetCommandLine to retrieve the entire command line. Console processes written + /// in C can use the argc and argv arguments to parse the command line. Because argv[0] is the module name, C programmers generally + /// repeat the module name as the first token in the command line. + /// + /// + /// If lpApplicationName is NULL, the first white space–delimited token of the command line specifies the module name. If you are + /// using a long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin + /// (see the explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. + /// Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period + /// (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory + /// path, the system searches for the executable file in the following sequence: + /// + /// + /// + /// The directory from which the application loaded. + /// + /// + /// The current directory for the parent process. + /// + /// + /// The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory. + /// + /// + /// The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. + /// + /// + /// The Windows directory. Use the GetWindowsDirectory function to get the path of this directory. + /// + /// + /// + /// The directories that are listed in the PATH environment variable. Note that this function does not search the per-application + /// path specified by the App Paths registry key. To include this per-application path in the search sequence, use the + /// ShellExecute function. + /// + /// + /// + /// + /// The system adds a null character to the command line string to separate the file name from the arguments. This divides the + /// original string into two strings for internal processing. + /// + /// + /// + /// + /// The flags that control how the process is created. The CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE, and + /// CREATE_NEW_PROCESS_GROUP flags are enabled by default. You can specify additional flags as noted. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// CREATE_DEFAULT_ERROR_MODE 0x04000000 + /// + /// The new process does not inherit the error mode of the calling process. Instead, the new process gets the current default error + /// mode. An application sets the current default error mode by calling SetErrorMode. This flag is enabled by default. + /// + /// + /// + /// CREATE_NEW_CONSOLE 0x00000010 + /// + /// The new process has a new console, instead of inheriting the parent's console. This flag cannot be used with the DETACHED_PROCESS + /// flag. This flag is enabled by default. + /// + /// + /// + /// CREATE_NEW_PROCESS_GROUP 0x00000200 + /// + /// The new process is the root process of a new process group. The process group includes all processes that are descendants of this + /// root process. The process identifier of the new process group is the same as the process identifier, which is returned in the + /// lpProcessInfo parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+C or + /// CTRL+BREAK signal to a group of console processes. This flag is enabled by default. + /// + /// + /// + /// CREATE_SEPARATE_WOW_VDM 0x00000800 + /// + /// This flag is only valid starting a 16-bit Windows-based application. If set, the new process runs in a private Virtual DOS + /// Machine (VDM). By default, all 16-bit Windows-based applications run in a single, shared VDM. The advantage of running separately + /// is that a crash only terminates the single VDM; any other programs running in distinct VDMs continue to function normally. Also, + /// 16-bit Windows-based applications that run in separate VDMs have separate input queues. That means that if one application stops + /// responding momentarily, applications in separate VDMs continue to receive input. + /// + /// + /// + /// CREATE_SUSPENDED 0x00000004 + /// + /// The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called. + /// + /// + /// + /// CREATE_UNICODE_ENVIRONMENT 0x00000400 + /// + /// Indicates the format of the lpEnvironment parameter. If this flag is set, the environment block pointed to by lpEnvironment uses + /// Unicode characters. Otherwise, the environment block uses ANSI characters. + /// + /// + /// + /// EXTENDED_STARTUPINFO_PRESENT 0x00080000 + /// + /// The process is created with extended startup information; the lpStartupInfo parameter specifies a STARTUPINFOEX structure. + /// Windows Server 2003: This value is not supported. + /// + /// + /// + /// + /// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the + /// process's threads. For a list of values, see GetPriorityClass. If none of the priority class flags is specified, the priority + /// class defaults to NORMAL_PRIORITY_CLASS unless the priority class of the creating process is IDLE_PRIORITY_CLASS or + /// BELOW_NORMAL_PRIORITY_CLASS. In this case, the child process receives the default priority class of the calling process. + /// + /// + /// + /// + /// A pointer to an environment block for the new process. If this parameter is NULL, the new process uses an environment created + /// from the profile of the user specified by lpUsername. + /// + /// An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form: + /// name=value + /// Because the equal sign (=) is used as a separator, it must not be used in the name of an environment variable. + /// + /// An environment block can contain Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains + /// Unicode characters, be sure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. If this parameter is NULL and the + /// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes CREATE_UNICODE_ENVIRONMENT. + /// + /// + /// An ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A Unicode + /// environment block is terminated by four zero bytes: two for the last string and two more to terminate the block. + /// + /// To retrieve a copy of the environment block for a specific user, use the CreateEnvironmentBlock function. + /// + /// + /// The full path to the current directory for the process. The string can also specify a UNC path. + /// + /// If this parameter is NULL, the new process will have the same current drive and directory as the calling process. (This feature + /// is provided primarily for shells that need to start an application and specify its initial drive and working directory.) + /// + /// + /// + /// A pointer to a STARTUPINFO or STARTUPINFOEX structure. + /// + /// If the lpDesktop member is NULL or an empty string, the new process inherits the desktop and window station of its parent + /// process. The function adds permission for the specified user account to the inherited window station and desktop. Otherwise, if + /// this member specifies a desktop, it is the responsibility of the application to add permission for the specified user account to + /// the specified window station and desktop, even for WinSta0\Default. + /// + /// Handles in STARTUPINFO or STARTUPINFOEX must be closed with CloseHandle when they are no longer needed. + /// + /// Important If the dwFlags member of the STARTUPINFO structure specifies STARTF_USESTDHANDLES, the standard + /// handle fields are copied unchanged to the child process without validation. The caller is responsible for ensuring that these + /// fields contain valid handle values. Incorrect values can cause the child process to misbehave or crash. Use the Application + /// Verifier runtime verification tool to detect invalid handles. + /// + /// + /// + /// + /// A pointer to a PROCESS_INFORMATION structure that receives identification information for the new process, including a handle to + /// the process. + /// + /// Handles in PROCESS_INFORMATION must be closed with the CloseHandle function when they are no longer needed. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to + /// initialize, the process is terminated. To get the termination status of a process, call GetExitCodeProcess. + /// + /// + /// + /// + /// By default, CreateProcessWithTokenW does not load the specified user's profile into the HKEY_USERS registry key. + /// This means that access to information in the HKEY_CURRENT_USER registry key may not produce results consistent with a + /// normal interactive logon. It is your responsibility to load the user's registry hive into HKEY_USERS by either using + /// LOGON_WITH_PROFILE, or by calling the LoadUserProfile function before calling this function. + /// + /// + /// If the lpEnvironment parameter is NULL, the new process uses an environment block created from the profile of the user specified + /// by lpUserName. If the HOMEDRIVE and HOMEPATH variables are not set, CreateProcessWithTokenW modifies the environment block + /// to use the drive and path of the user's working directory. + /// + /// + /// When created, the new process and thread handles receive full access rights (PROCESS_ALL_ACCESS and THREAD_ALL_ACCESS). For + /// either handle, if a security descriptor is not provided, the handle can be used in any function that requires an object handle of + /// that type. When a security descriptor is provided, an access check is performed on all subsequent uses of the handle before + /// access is granted. If access is denied, the requesting process cannot use the handle to gain access to the process or thread. + /// + /// To retrieve a security token, pass the process handle in the PROCESS_INFORMATION structure to the OpenProcessToken function. + /// + /// The process is assigned a process identifier. The identifier is valid until the process terminates. It can be used to identify + /// the process, or specified in the OpenProcess function to open a handle to the process. The initial thread in the process is also + /// assigned a thread identifier. It can be specified in the OpenThread function to open a handle to the thread. The identifier is + /// valid until the thread terminates and can be used to uniquely identify the thread within the system. These identifiers are + /// returned in PROCESS_INFORMATION. + /// + /// + /// The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is + /// waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because + /// CreateProcessWithTokenW returns without waiting for the new process to finish its initialization. For example, the + /// creating process would use WaitForInputIdle before trying to find a window associated with the new process. + /// + /// + /// The preferred way to shut down a process is by using the ExitProcess function, because this function sends notification of + /// approaching termination to all DLLs attached to the process. Other means of shutting down a process do not notify the attached + /// DLLs. Note that when a thread calls ExitProcess, other threads of the process are terminated without an opportunity to + /// execute any additional code (including the thread termination code of attached DLLs). For more information, see Terminating a Process. + /// + /// + /// To compile an application that uses this function, define _WIN32_WINNT as 0x0500 or later. For more information, see Using the + /// Windows Headers. + /// + /// Security Remarks + /// + /// The lpApplicationName parameter can be NULL, in which case the executable name must be the first white space–delimited string in + /// lpCommandLine. If the executable or path name has a space in it, there is a risk that a different executable could be run because + /// of the way the function parses spaces. The following example is dangerous because the function will attempt to run "Program.exe", + /// if it exists, instead of "MyApp.exe". + /// + /// + /// If a malicious user were to create an application called "Program.exe" on a system, any program that incorrectly calls + /// CreateProcessWithTokenW using the Program Files directory will run this application instead of the intended application. + /// + /// + /// To avoid this problem, do not pass NULL for lpApplicationName. If you do pass NULL for lpApplicationName, use quotation marks + /// around the executable path in lpCommandLine, as shown in the example below. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createprocesswithtokenw BOOL CreateProcessWithTokenW( + // HANDLE hToken, DWORD dwLogonFlags, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment, + // LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)] + [PInvokeData("winbase.h", MSDNShortId = "b329866a-0c0d-4cb3-838c-36aac17c87ed")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CreateProcessWithTokenW(HTOKEN hToken, ProcessLogonFlags dwLogonFlags, string lpApplicationName, [Optional] StringBuilder lpCommandLine, CREATE_PROCESS dwCreationFlags, + [Optional] IntPtr lpEnvironment, [Optional] string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, [Out] PROCESS_INFORMATION lpProcessInformation); + + /// Decrypts an encrypted file or directory. + /// + /// The name of the file or directory to be decrypted. + /// + /// The caller must have the FILE_READ_DATA, FILE_WRITE_DATA, FILE_READ_ATTRIBUTES, + /// FILE_WRITE_ATTRIBUTES, and SYNCHRONIZE access rights. For more information, see File Security and Access Rights. + /// + /// + /// Reserved; must be zero. + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// + /// The DecryptFile function requires exclusive access to the file being decrypted, and will fail if another process is using + /// the file. If the file is not encrypted, DecryptFile simply returns a nonzero value, which indicates success. + /// + /// + /// If lpFileName specifies a read-only file, the function fails and GetLastError returns ERROR_FILE_READ_ONLY. If lpFileName + /// specifies a directory that contains a read-only file, the functions succeeds but the directory is not decrypted. + /// + /// In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies. + /// + /// + /// Technology + /// Supported + /// + /// + /// Server Message Block (SMB) 3.0 protocol + /// Yes + /// + /// + /// SMB 3.0 Transparent Failover (TFO) + /// No + /// + /// + /// SMB 3.0 with Scale-out File Shares (SO) + /// No + /// + /// + /// Cluster Shared Volume File System (CsvFS) + /// No + /// + /// + /// Resilient File System (ReFS) + /// No + /// + /// + /// SMB 3.0 does not support EFS on shares with continuous availability capability. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-decryptfilea BOOL DecryptFileA( LPCSTR lpFileName, DWORD + // dwReserved ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "6b8f0ed0-8825-4c84-bf58-3a89cda882b4")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool DecryptFile(string lpFileName, uint dwReserved = 0); + + /// + /// Encrypts a file or directory. All data streams in a file are encrypted. All new files created in an encrypted directory are encrypted. + /// + /// + /// The name of the file or directory to be encrypted. + /// + /// The caller must have the FILE_READ_DATA, FILE_WRITE_DATA, FILE_READ_ATTRIBUTES, + /// FILE_WRITE_ATTRIBUTES, and SYNCHRONIZE access rights. For more information, see File Security and Access Rights. + /// + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// + /// The EncryptFile function requires exclusive access to the file being encrypted, and will fail if another process is using + /// the file. + /// + /// + /// If the file is already encrypted, EncryptFile simply returns a nonzero value, which indicates success. If the file is + /// compressed, EncryptFile will decompress the file before encrypting it. + /// + /// + /// If lpFileName specifies a read-only file, the function fails and GetLastError returns ERROR_FILE_READ_ONLY. If lpFileName + /// specifies a directory that contains a read-only file, the functions succeeds but the directory is not encrypted. + /// + /// To decrypt an encrypted file, use the DecryptFile function. + /// In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies. + /// + /// + /// Technology + /// Supported + /// + /// + /// Server Message Block (SMB) 3.0 protocol + /// Yes + /// + /// + /// SMB 3.0 Transparent Failover (TFO) + /// No + /// + /// + /// SMB 3.0 with Scale-out File Shares (SO) + /// No + /// + /// + /// Cluster Shared Volume File System (CsvFS) + /// No + /// + /// + /// Resilient File System (ReFS) + /// No + /// + /// + /// SMB 3.0 does not support EFS on shares with continuous availability capability. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-encryptfilea BOOL EncryptFileA( LPCSTR lpFileName ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "7620e9fa-74d6-4b41-93db-4a562be63202")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool EncryptFile(string lpFileName); + + /// Retrieves the encryption status of the specified file. + /// The name of the file. + /// + /// A pointer to a variable that receives the encryption status of the file. This parameter can be one of the following values. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// In Windows 8 and Windows Server 2012, this function is supported by the following technologies. + /// + /// + /// Technology + /// Supported + /// + /// + /// Server Message Block (SMB) 3.0 protocol + /// Yes + /// + /// + /// SMB 3.0 Transparent Failover (TFO) + /// No + /// + /// + /// SMB 3.0 with Scale-out File Shares (SO) + /// No + /// + /// + /// Cluster Shared Volume File System (CsvFS) + /// No + /// + /// + /// Resilient File System (ReFS) + /// No + /// + /// + /// SMB 3.0 does not support EFS on shares with continuous availability capability. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-fileencryptionstatusa BOOL FileEncryptionStatusA( LPCSTR + // lpFileName, LPDWORD lpStatus ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "96efe065-de62-4941-811d-610465cd7ef5")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool FileEncryptionStatus(string lpFileName, out EncryptionStatus lpStatus); + + /// Retrieves information about the current hardware profile for the local computer. + /// + /// A pointer to an HW_PROFILE_INFO structure that receives information about the current hardware profile. + /// + /// + /// If the function succeeds, the return value is a nonzero value. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// + /// The GetCurrentHwProfile function retrieves the display name and globally unique identifier (GUID) string for the hardware + /// profile. The function also retrieves the reported docking state for portable computers with docking stations. + /// + /// + /// The system generates a GUID for each hardware profile and stores it as a string in the registry. You can use + /// GetCurrentHwProfile to retrieve the GUID string to use as a registry subkey under your application's configuration + /// settings key in HKEY_CURRENT_USER. This enables you to store each user's settings for each hardware profile. For example, + /// the Colors control panel application could use the subkey to store each user's color preferences for different hardware profiles, + /// such as profiles for the docked and undocked states. Applications that use this functionality can check the current hardware + /// profile when they start up, and update their settings accordingly. + /// + /// + /// Applications can also update their settings when a system device message, such as DBT_CONFIGCHANGED, indicates that the hardware + /// profile has changed. + /// + /// + /// To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0400 or later. For more information, see + /// Using the Windows Headers. + /// + /// Examples + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getcurrenthwprofilea BOOL GetCurrentHwProfileA( + // LPHW_PROFILE_INFOA lpHwProfileInfo ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "152067bb-3896-43ef-a882-12a159f92cc7")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetCurrentHwProfile(out HW_PROFILE_INFO lpHwProfileInfo); + + /// + /// + /// The GetFileSecurity function obtains specified information about the security of a file or directory. The information + /// obtained is constrained by the caller's access rights and privileges. + /// + /// + /// The GetNamedSecurityInfo function provides functionality similar to GetFileSecurity for files as well as other types of objects. + /// + /// + /// + /// A pointer to a null-terminated string that specifies the file or directory for which security information is retrieved. + /// + /// A SECURITY_INFORMATION value that identifies the security information being requested. + /// + /// A pointer to a buffer that receives a copy of the security descriptor of the object specified by the lpFileName parameter. The + /// calling process must have permission to view the specified aspects of the object's security status. The SECURITY_DESCRIPTOR + /// structure is returned in self-relative security descriptor format. + /// + /// Specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter. + /// + /// A pointer to the variable that receives the number of bytes necessary to store the complete security descriptor. If the returned + /// number of bytes is less than or equal to nLength, the entire security descriptor is returned in the output buffer; otherwise, + /// none of the descriptor is returned. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// + /// To read the owner, group, or DACL from the security descriptor for the specified file or directory, the DACL for the file or + /// directory must grant READ_CONTROL access to the caller, or the caller must be the owner of the file or directory. + /// + /// To read the SACL of a file or directory, the SE_SECURITY_NAME privilege must be enabled for the calling process. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getfilesecuritya BOOL GetFileSecurityA( LPCSTR lpFileName, + // SECURITY_INFORMATION RequestedInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD nLength, LPDWORD lpnLengthNeeded ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "4043b76b-76b9-4111-8a29-a808b2412be0")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetFileSecurity(string lpFileName, SECURITY_INFORMATION RequestedInformation, SafeSECURITY_DESCRIPTOR pSecurityDescriptor, uint nLength, out uint lpnLengthNeeded); + + /// + /// Retrieves the name of the user associated with the current thread. + /// + /// Use the GetUserNameEx function to retrieve the user name in a specified format. Additional information is provided by the + /// IADsADSystemInfo interface. + /// + /// + /// + /// A pointer to the buffer to receive the user's logon name. If this buffer is not large enough to contain the entire user name, the + /// function fails. A buffer size of (UNLEN + 1) characters will hold the maximum length user name including the terminating null + /// character. UNLEN is defined in Lmcons.h. + /// + /// + /// + /// On input, this variable specifies the size of the lpBuffer buffer, in TCHARs. On output, the variable receives the number + /// of TCHARs copied to the buffer, including the terminating null character. + /// + /// + /// If lpBuffer is too small, the function fails and GetLastError returns ERROR_INSUFFICIENT_BUFFER. This parameter receives the + /// required buffer size, including the terminating null character. + /// + /// + /// + /// + /// If the function succeeds, the return value is a nonzero value, and the variable pointed to by lpnSize contains the number of + /// TCHARs copied to the buffer specified by lpBuffer, including the terminating null character. + /// + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// + /// If the current thread is impersonating another client, the GetUserName function returns the user name of the client that + /// the thread is impersonating. + /// + /// + /// If GetUserName is called from a process that is running under the "NETWORK SERVICE" account, the string returned in + /// lpBuffer may be different depending on the version of Windows. On Windows XP, the "NETWORK SERVICE" string is returned. On + /// Windows Vista, the “<HOSTNAME>$” string is returned. + /// + /// Examples + /// For an example, see Getting System Information. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getusernamea BOOL GetUserNameA( LPSTR lpBuffer, LPDWORD + // pcbBuffer ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "87adc46a-c069-4ee5-900a-03b646306e64")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetUserName(StringBuilder lpBuffer, ref uint pcbBuffer); + /// The ImpersonateNamedPipeClient function impersonates a named-pipe client application. /// A handle to a named pipe. /// @@ -18,6 +1623,125 @@ namespace Vanara.PInvoke [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ImpersonateNamedPipeClient(HFILE hNamedPipe); + /// Determines if a buffer is likely to contain a form of Unicode text. + /// Pointer to the input buffer to examine. + /// Size, in bytes, of the input buffer indicated by lpv. + /// + /// + /// On input, pointer to the tests to apply to the input buffer text. On output, this parameter receives the results of the specified + /// tests: 1 if the contents of the buffer pass a test, 0 for failure. Only flags that are set upon input to the function are + /// significant upon output. + /// + /// + /// If lpiResult is NULL, the function uses all available tests to determine if the data in the buffer is likely to be Unicode text. + /// + /// This parameter can be one or more of the following values. Values can be combined with binary "OR". + /// + /// + /// Value + /// Meaning + /// + /// + /// IS_TEXT_UNICODE_ASCII16 + /// The text is Unicode, and contains only zero-extended ASCII values/characters. + /// + /// + /// IS_TEXT_UNICODE_REVERSE_ASCII16 + /// Same as the preceding, except that the Unicode text is byte-reversed. + /// + /// + /// IS_TEXT_UNICODE_STATISTICS + /// + /// The text is probably Unicode, with the determination made by applying statistical analysis. Absolute certainty is not guaranteed. + /// See the Remarks section. + /// + /// + /// + /// IS_TEXT_UNICODE_REVERSE_STATISTICS + /// Same as the preceding, except that the text that is probably Unicode is byte-reversed. + /// + /// + /// IS_TEXT_UNICODE_CONTROLS + /// + /// The text contains Unicode representations of one or more of these nonprinting characters: RETURN, LINEFEED, SPACE, CJK_SPACE, TAB. + /// + /// + /// + /// IS_TEXT_UNICODE_REVERSE_CONTROLS + /// Same as the preceding, except that the Unicode characters are byte-reversed. + /// + /// + /// IS_TEXT_UNICODE_BUFFER_TOO_SMALL + /// There are too few characters in the buffer for meaningful analysis (fewer than two bytes). + /// + /// + /// IS_TEXT_UNICODE_SIGNATURE + /// The text contains the Unicode byte-order mark (BOM) 0xFEFF as its first character. + /// + /// + /// IS_TEXT_UNICODE_REVERSE_SIGNATURE + /// The text contains the Unicode byte-reversed byte-order mark (Reverse BOM) 0xFFFE as its first character. + /// + /// + /// IS_TEXT_UNICODE_ILLEGAL_CHARS + /// + /// The text contains one of these Unicode-illegal characters: embedded Reverse BOM, UNICODE_NUL, CRLF (packed into one word), or 0xFFFF. + /// + /// + /// + /// IS_TEXT_UNICODE_ODD_LENGTH + /// The number of characters in the string is odd. A string of odd length cannot (by definition) be Unicode text. + /// + /// + /// IS_TEXT_UNICODE_NULL_BYTES + /// The text contains null bytes, which indicate non-ASCII text. + /// + /// + /// IS_TEXT_UNICODE_UNICODE_MASK + /// The value is a combination of IS_TEXT_UNICODE_ASCII16, IS_TEXT_UNICODE_STATISTICS, IS_TEXT_UNICODE_CONTROLS, IS_TEXT_UNICODE_SIGNATURE. + /// + /// + /// IS_TEXT_UNICODE_REVERSE_MASK + /// + /// The value is a combination of IS_TEXT_UNICODE_REVERSE_ASCII16, IS_TEXT_UNICODE_REVERSE_STATISTICS, + /// IS_TEXT_UNICODE_REVERSE_CONTROLS, IS_TEXT_UNICODE_REVERSE_SIGNATURE. + /// + /// + /// + /// IS_TEXT_UNICODE_NOT_UNICODE_MASK + /// + /// The value is a combination of IS_TEXT_UNICODE_ILLEGAL_CHARS, IS_TEXT_UNICODE_ODD_LENGTH, and two currently unused bit flags. + /// + /// + /// + /// IS_TEXT_UNICODE_NOT_ASCII_MASK + /// The value is a combination of IS_TEXT_UNICODE_NULL_BYTES and three currently unused bit flags. + /// + /// + /// + /// + /// Returns a nonzero value if the data in the buffer passes the specified tests. The function returns 0 if the data in the buffer + /// does not pass the specified tests. + /// + /// + /// + /// This function uses various statistical and deterministic methods to make its determination, under the control of flags passed in + /// the lpiResult parameter. When the function returns, the results of such tests are reported using the same parameter. + /// + /// + /// The IS_TEXT_UNICODE_STATISTICS and IS_TEXT_UNICODE_REVERSE_STATISTICS tests use statistical analysis. These tests are not + /// foolproof. The statistical tests assume certain amounts of variation between low and high bytes in a string, and some ASCII + /// strings can slip through. For example, if lpv indicates the ASCII string 0x41, 0x0A, 0x0D, 0x1D (A\n\r^Z), the string passes the + /// IS_TEXT_UNICODE_STATISTICS test, although failure would be preferable. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-istextunicode BOOL IsTextUnicode( const VOID *lpv, int + // iSize, LPINT lpiResult ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winbase.h", MSDNShortId = "47e05b5b-a16b-4957-bc86-ed3cef4968ee")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool IsTextUnicode(IntPtr lpv, int iSize, ref IS_TEXT_UNICODE lpiResult); + /// /// The LogonUser function attempts to log a user on to the local computer. The local computer is the computer from which LogonUser /// was called. You cannot use LogonUser to log on to a remote computer. You specify the user with a user name and domain and @@ -148,17 +1872,33 @@ namespace Vanara.PInvoke /// /// The type of logon operation to perform. /// The logon provider. - /// A pointer to a TOKEN_GROUPS structure that specifies a list of group SIDs that are added to the token that this function receives upon successful logon. Any SIDs added to the token also effect group expansion. For example, if the added SIDs are members of local groups, those groups are also added to the received access token. - /// If this parameter is not NULL, the caller of this function must have the SE_TCB_PRIVILEGE privilege granted and enabled. - /// A pointer to a handle variable that receives a handle to a token that represents the specified user. + /// + /// A pointer to a TOKEN_GROUPS structure that specifies a list of group SIDs that are added to the token that this function receives + /// upon successful logon. Any SIDs added to the token also effect group expansion. For example, if the added SIDs are members of + /// local groups, those groups are also added to the received access token. + /// If this parameter is not NULL, the caller of this function must have the SE_TCB_PRIVILEGE privilege granted and enabled. + /// + /// + /// A pointer to a handle variable that receives a handle to a token that represents the specified user. /// You can use the returned handle in calls to the ImpersonateLoggedOnUser function. - /// In most cases, the returned handle is a primary token that you can use in calls to the CreateProcessAsUser function.However, if you specify the LOGON32_LOGON_NETWORK flag, LogonUserExExW returns an impersonation token that you cannot use in CreateProcessAsUser unless you call DuplicateTokenEx to convert the impersonation token to a primary token. - /// When you no longer need this handle, close it by calling the CloseHandle function. - /// A pointer to a pointer to a SID that receives the SID of the user logged on. - /// When you have finished using the SID, free it by calling the LocalFree function. - /// A pointer to a pointer that receives the address of a buffer that contains the logged on user's profile. + /// + /// In most cases, the returned handle is a primary token that you can use in calls to the CreateProcessAsUser function.However, if + /// you specify the LOGON32_LOGON_NETWORK flag, LogonUserExExW returns an impersonation token that you cannot use in + /// CreateProcessAsUser unless you call DuplicateTokenEx to convert the impersonation token to a primary token. + /// + /// When you no longer need this handle, close it by calling the CloseHandle function. + /// + /// + /// A pointer to a pointer to a SID that receives the SID of the user logged on. + /// When you have finished using the SID, free it by calling the LocalFree function. + /// + /// + /// A pointer to a pointer that receives the address of a buffer that contains the logged on user's profile. + /// /// A pointer to a DWORD that receives the length of the profile buffer. - /// A pointer to a QUOTA_LIMITS structure that receives information about the quotas for the logged on user. + /// + /// A pointer to a QUOTA_LIMITS structure that receives information about the quotas for the logged on user. + /// /// /// If the function succeeds, the function returns nonzero. /// If the function fails, it returns zero. To get extended error information, call GetLastError. @@ -166,20 +1906,20 @@ namespace Vanara.PInvoke /// /// The LOGON32_LOGON_NETWORK logon type is fastest, but it has the following limitations: /// - /// - /// + /// + /// /// The function returns an impersonation token, not a primary token. You cannot use this token directly in the /// CreateProcessAsUser function. However, you can call the DuplicateTokenEx function to convert the token to a primary /// token, and then use it in CreateProcessAsUser. /// - /// - /// - /// + /// + /// + /// /// If you convert the token to a primary token and use it in CreateProcessAsUser to start a process, the new process cannot /// access other network resources, such as remote servers or printers, through the redirector. An exception is that if the network /// resource is not access controlled, then the new process will be able to access it. /// - /// + /// /// /// /// The account specified by lpszUsername must have the necessary account rights. For example, to log on a user with the @@ -193,8 +1933,10 @@ namespace Vanara.PInvoke /// /// If the optional pTokenGroups parameter is supplied, LSA will not add either the local SID or the logon SID automatically. /// - // https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/logonuserexexw - // BOOL WINAPI LogonUserExExW( _In_ LPTSTR lpszUsername, _In_opt_ LPTSTR lpszDomain, _In_opt_ LPTSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _In_opt_ PTOKEN_GROUPS pTokenGroups, _Out_opt_ PHANDLE phToken, _Out_opt_ PSID *ppLogonSid, _Out_opt_ PVOID *ppProfileBuffer, _Out_opt_ LPDWORD pdwProfileLength, _Out_opt_ PQUOTA_LIMITS pQuotaLimits ); + // https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/logonuserexexw BOOL WINAPI LogonUserExExW( _In_ LPTSTR lpszUsername, + // _In_opt_ LPTSTR lpszDomain, _In_opt_ LPTSTR lpszPassword, _In_ DWORD dwLogonType, _In_ DWORD dwLogonProvider, _In_opt_ + // PTOKEN_GROUPS pTokenGroups, _Out_opt_ PHANDLE phToken, _Out_opt_ PSID *ppLogonSid, _Out_opt_ PVOID *ppProfileBuffer, _Out_opt_ + // LPDWORD pdwProfileLength, _Out_opt_ PQUOTA_LIMITS pQuotaLimits ); [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("", MSDNShortId = "d90db4c6-a711-4519-8b91-5069cee07738")] [return: MarshalAs(UnmanagedType.Bool)] @@ -515,102 +2257,617 @@ namespace Vanara.PInvoke [return: MarshalAs(UnmanagedType.Bool)] public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid); - /* - AccessCheck - AccessCheckByType - AccessCheckByTypeResultList - AdjustTokenGroups - AdjustTokenPrivileges - AllocateAndInitializeSid - AllocateLocallyUniqueId - AuthzAccessCheck - AuthzAccessCheckCallback - AuthzAddSidsToContext - AuthzCachedAccessCheck - AuthzComputeGroupsCallback - AuthzEnumerateSecurityEventSources - AuthzFreeAuditEvent - AuthzFreeContext - AuthzFreeGroupsCallback - AuthzFreeHandle - AuthzFreeResourceManager - AuthzGetInformationFromContext - AuthzInitializeContextFromAuthzContext - AuthzInitializeContextFromSid - AuthzInitializeContextFromToken - AuthzInitializeObjectAccessAuditEvent - AuthzInitializeObjectAccessAuditEvent2 - AuthzInitializeResourceManager - AuthzInstallSecurityEventSource - AuthzOpenObjectAudit - AuthzRegisterSecurityEventSource - AuthzReportSecurityEvent - AuthzReportSecurityEventFromParams - AuthzUninstallSecurityEventSource - AuthzUnregisterSecurityEventSource - BuildExplicitAccessWithName - BuildImpersonateExplicitAccessWithName - BuildImpersonateTrustee - BuildTrusteeWithName - BuildTrusteeWithObjectsAndName - BuildTrusteeWithObjectsAndSid - BuildTrusteeWithSid - CheckTokenMembership - ConvertSecurityDescriptorToStringSecurityDescriptor - ConvertSidToStringSid - ConvertStringSecurityDescriptorToSecurityDescriptor - ConvertStringSidToSid - CopySid - CreateRestrictedToken - CreateWellKnownSid - DuplicateToken - DuplicateTokenEx - EqualDomainSid - EqualPrefixSid - EqualSid - FreeSid - GetAuditedPermissionsFromAcl - GetEffectiveRightsFromAcl - GetExplicitEntriesFromAcl - GetLengthSid - GetMultipleTrustee - GetMultipleTrusteeOperation - GetNamedSecurityInfo - GetSecurityDescriptorControl - GetSecurityInfo - GetSidIdentifierAuthority - GetSidLengthRequired - GetSidSubAuthority - GetSidSubAuthorityCount - GetTokenInformation - GetTrusteeForm - GetTrusteeName - GetTrusteeType - GetWindowsAccountDomainSid - InitializeSid - IsTokenRestricted - IsValidSid - IsWellKnownSid - LookupAccountName - LookupAccountSid - LookupAccountSidLocal - LookupPrivilegeDisplayName - LookupPrivilegeName - LookupPrivilegeValue - NtCompareTokens - OpenProcessToken - OpenThreadToken - QuerySecurityAccessMask - RtlConvertSidToUnicodeString - SetEntriesInAcl - SetNamedSecurityInfo - SetSecurityAccessMask - SetSecurityDescriptorControl - SetSecurityInfo - SetThreadToken - SetTokenInformation - TreeResetNamedSecurityInfo - TreeSetNamedSecurityInfo - */ + /// + /// The ObjectCloseAuditAlarm function generates an audit message in the security event log when a handle to a private object + /// is deleted. Alarms are not currently supported. + /// + /// + /// A pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in any audit + /// message that the function generates. + /// + /// + /// A unique value representing the client's handle to the object. This should be the same value that was passed to the + /// AccessCheckAndAuditAlarm or ObjectOpenAuditAlarm function. + /// + /// + /// Specifies a flag set by a call to the AccessCheckAndAuditAlarm or ObjectCloseAuditAlarm function when the object handle is + /// created. If this flag is TRUE, the function generates an audit message. If it is FALSE, the function does not + /// generate an audit message. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// The ObjectCloseAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test + /// for this privilege is always performed against the primary token of the calling process, allowing the calling process to + /// impersonate a client. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-objectcloseauditalarma BOOL ObjectCloseAuditAlarmA( LPCSTR + // SubsystemName, LPVOID HandleId, BOOL GenerateOnClose ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "274f3a62-1833-402b-b362-f526b2bee14b")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ObjectCloseAuditAlarm(string SubsystemName, IntPtr HandleId, [MarshalAs(UnmanagedType.Bool)] bool GenerateOnClose); + + /// + /// The ObjectOpenAuditAlarm function generates audit messages when a client application attempts to gain access to an object + /// or to create a new one. Alarms are not currently supported. + /// + /// + /// A pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in + /// any audit message that the function generates. + /// + /// + /// + /// A pointer to a unique value representing the client's handle to the object. If the access is denied, this parameter is ignored. + /// + /// For cross-platform compatibility, the value addressed by this pointer must be sizeof(LPVOID) bytes long. + /// + /// + /// A pointer to a null-terminated string specifying the type of object to which the client is requesting access. This string + /// appears in any audit message that the function generates. + /// + /// + /// A pointer to a null-terminated string specifying the name of the object to which the client is requesting access. This + /// string appears in any audit message that the function generates. + /// + /// A pointer to the SECURITY_DESCRIPTOR structure for the object being accessed. + /// + /// Identifies an access token representing the client requesting the operation. This handle must be obtained by opening the token of + /// a thread impersonating the client. The token must be open for TOKEN_QUERY access. + /// + /// + /// Specifies the desired access mask. This mask must have been previously mapped by the MapGenericMask function to contain no + /// generic access rights. + /// + /// + /// Specifies an access mask indicating which access rights are granted. This access mask is intended to be the same value set by one + /// of the access-checking functions in its GrantedAccess parameter. Examples of access-checking functions include + /// AccessCheckAndAuditAlarm and AccessCheck. + /// + /// + /// A pointer to a PRIVILEGE_SET structure that specifies the set of privileges required for the access attempt. This parameter can + /// be NULL. + /// + /// + /// Specifies a flag that determines whether the application creates a new object when access is granted. When this value is + /// TRUE, the application creates a new object; when it is FALSE, the application opens an existing object. + /// + /// + /// Specifies a flag indicating whether access was granted or denied in a previous call to an access-checking function, such as + /// AccessCheck. If access was granted, this value is TRUE. If not, it is FALSE. + /// + /// + /// A pointer to a flag set by the audit-generation routine when the function returns. This value must be passed to the + /// ObjectCloseAuditAlarm function when the object handle is closed. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// The ObjectOpenAuditAlarm function requires the calling application to have the SE_AUDIT_NAME privilege enabled. The test + /// for this privilege is always performed against the primary token of the calling process, not the impersonation token of the + /// thread. This allows the calling process to impersonate a client during the call. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-objectopenauditalarma BOOL ObjectOpenAuditAlarmA( LPCSTR + // SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName, LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE + // ClientToken, DWORD DesiredAccess, DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted, LPBOOL + // GenerateOnClose ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "f3cb607b-a8fd-4a1b-9361-7ccd7cd8aac2")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ObjectOpenAuditAlarm(string SubsystemName, IntPtr HandleId, string ObjectTypeName, string ObjectName, + PSECURITY_DESCRIPTOR pSecurityDescriptor, HTOKEN ClientToken, ACCESS_MASK DesiredAccess, ACCESS_MASK GrantedAccess, + in PRIVILEGE_SET Privileges, [MarshalAs(UnmanagedType.Bool)] bool ObjectCreation, [MarshalAs(UnmanagedType.Bool)] bool AccessGranted, + [MarshalAs(UnmanagedType.Bool)] out bool GenerateOnClose); + + /// + /// The ObjectPrivilegeAuditAlarm function generates an audit message in the security event log. A protected server can use + /// this function to log attempts by a client to use a specified set of privileges with an open handle to a private object. Alarms + /// are not currently supported. + /// + /// + /// A pointer to a null-terminated string specifying the name of the subsystem calling the function. This string appears in the audit message. + /// + /// A pointer to a unique value representing the client's handle to the object. + /// + /// Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening + /// the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access. The function uses this token to + /// get the identity of the client for the audit message. + /// + /// + /// Specifies an access mask indicating the privileged access types being used or whose use is being attempted. The access mask can + /// be mapped by the MapGenericMask function so it does not contain any generic access types. + /// + /// + /// A pointer to a PRIVILEGE_SET structure containing the privileges that the client attempted to use. The names of the privileges + /// appear in the audit message. + /// + /// + /// Indicates whether the client's attempt to use the privileges was successful. If this value is TRUE, the audit message + /// indicates success. If this value is FALSE, the audit message indicates failure. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// + /// The ObjectPrivilegeAuditAlarm function does not check the client's access to the object or check the client's access token + /// to determine whether the privileges are held or enabled. Typically, you call the PrivilegeCheck function to determine whether the + /// specified privileges are enabled in the access token, call the AccessCheck function to check the client's access to the object, + /// and then call ObjectPrivilegeAuditAlarm to log the results. + /// + /// + /// The ObjectPrivilegeAuditAlarm function requires the calling process to have SE_AUDIT_NAME privilege enabled. The test for + /// this privilege is always performed against the primary token of the calling process, not the impersonation token of the thread. + /// This allows the calling process to impersonate a client during the call. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-objectprivilegeauditalarma BOOL + // ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken, DWORD DesiredAccess, PPRIVILEGE_SET + // Privileges, BOOL AccessGranted ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "76714ffe-be7c-4928-b7c9-e72441ada4c7")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ObjectPrivilegeAuditAlarm(string SubsystemName, IntPtr HandleId, HTOKEN ClientToken, ACCESS_MASK DesiredAccess, + in PRIVILEGE_SET Privileges, [MarshalAs(UnmanagedType.Bool)] bool AccessGranted); + + /// + /// Opens an encrypted file in order to backup (export) or restore (import) the file. This is one of a group of Encrypted File System + /// (EFS) functions that is intended to implement backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// The name of the file to be opened. The string must consist of characters from the Windows character set. + /// + /// The operation to be performed. This parameter may be one of the following values. + /// + /// The address of a context block that must be presented in subsequent calls to ReadEncryptedFileRaw, WriteEncryptedFileRaw, or + /// CloseEncryptedFileRaw. Do not modify it. + /// + /// + /// If the function succeeds, it returns ERROR_SUCCESS. + /// + /// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the + /// FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic text description of the error. + /// + /// + /// + /// + /// The caller must either have read or write access to the file, or it must have backup privilege SeBackupPrivilege on the machine + /// on which the files reside in order for the call to succeed. + /// + /// + /// To back up an encrypted file, call OpenEncryptedFileRaw to open the file and then call ReadEncryptedFileRaw. When the + /// backup is complete, call CloseEncryptedFileRaw. + /// + /// + /// To restore an encrypted file, call OpenEncryptedFileRaw, specifying CREATE_FOR_IMPORT in the ulFlags parameter, and + /// then call WriteEncryptedFileRaw once. When the operation is completed, call CloseEncryptedFileRaw. + /// + /// + /// OpenEncryptedFileRaw fails if lpFileName exceeds MAX_PATH characters when opening an encrypted file on a remote machine. + /// + /// + /// If the caller does not have access to the key for the file, the caller needs SeBackupPrivilege to export encrypted files or + /// SeRestorePrivilege to import encrypted files. + /// + /// The BackupRead and BackupWrite functions handle backup and restore of unencrypted files. + /// In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies. + /// + /// + /// Technology + /// Supported + /// + /// + /// Server Message Block (SMB) 3.0 protocol + /// Yes + /// + /// + /// SMB 3.0 Transparent Failover (TFO) + /// No + /// + /// + /// SMB 3.0 with Scale-out File Shares (SO) + /// No + /// + /// + /// Cluster Shared Volume File System (CsvFS) + /// No + /// + /// + /// Resilient File System (ReFS) + /// No + /// + /// + /// SMB 3.0 does not support EFS on shares with continuous availability capability. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-openencryptedfilerawa DWORD OpenEncryptedFileRawA( LPCSTR + // lpFileName, ULONG ulFlags, PVOID *pvContext ); + [DllImport(Lib.AdvApi32, SetLastError = false, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "f792f38d-783e-4f39-a9d8-0c378d508d97")] + public static extern Win32Error OpenEncryptedFileRaw(string lpFileName, OpenRawFlags ulFlags, out IntPtr pvContext); + + /// + /// Notifies the system that the application is about to end an operation + /// + /// Every call to OperationStart must be followed by a call to OperationEnd, otherwise the operation's record of file access + /// patterns is discarded after 10 seconds. + /// + /// + /// + /// An _OPERATION_END_PARAMETERS structure that specifies VERSION, OPERATION_ID and FLAGS. + /// + /// TRUE for all valid parameters and FALSE otherwise. To get extended error information, call GetLastError. + /// + /// The version of the _OPERATION_END_PARAMETERS structure is defined as OPERATION_API_VERSION in the Windows SDK. + /// The OperationEnd function is safe to call on any thread. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-operationend BOOL OperationEnd( OPERATION_END_PARAMETERS + // *OperationEndParams ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winbase.h", MSDNShortId = "73C6FBDD-BB4A-46A5-8E39-7862A1938F47")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool OperationEnd(in OPERATION_END_PARAMETERS OperationEndParams); + + /// + /// Notifies the system that the application is about to start an operation. + /// + /// If an application calls OperationStart with a valid OPERATION_ID value, the system records the specified operation’s file + /// access patterns until OperationEnd is called for the same operation ID. This record is stored in a filename.pf prefetch file. + /// Every call to OperationStart must be followed by a call to OperationEnd, otherwise the operation's record is + /// discarded after 10 seconds. + /// + /// + /// If an application calls OperationStart for an operation ID for which a prefetch file exists, the system loads the + /// operation's files into memory prior to running the operation. The recording process remains the same and the system updates the + /// appropriate filename.pf prefetch file. + /// + /// + /// + /// An _OPERATION_START_PARAMETERS structure that specifies VERSION, OPERATION_ID and FLAGS. + /// + /// TRUE for all valid parameters and FALSE otherwise. To get extended error information, call GetLastError. + /// + /// The version of the _OPERATION_START_PARAMETERS structure is defined as OPERATION_API_VERSION in the Windows SDK. + /// + /// Because the OperationStart function is synchronous, it can take several seconds to return. This should be avoided in UI + /// threads for the best responsiveness. + /// + /// + /// There is a single instance of the operation recorder in a process. Although the operation recorder APIs can be called from + /// multiple threads within the process, all calls act on the single instance. + /// + /// + /// Application launch tracing lasts for the first 10 second of the process lifetime. OperationStart should be called after + /// the end of application launch tracing by the system. + /// + /// + /// Every call to OperationStart must be followed by a call to OperationEnd. Otherwise, the operation trace will be discarded + /// after about 10s. + /// + /// + /// The maximum number of operations that can be recorded on a given system is configurable. If this maximum is exceeded, the least + /// recently used prefetch files are replaced. + /// + /// + /// On Windows 8, this functionality requires the Superfetch service to be enabled. Windows 8 will have the service enabled by + /// default. For Windows Server 2012, this prefetching functionality needs to be enabled and disabled as required. This can be done + /// using CIM based PowerShell cmdlets. The prefetcher functionality can be exposed using the CIM class of the CIM_PrefetcherService. + /// + /// Examples + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-operationstart BOOL OperationStart( + // OPERATION_START_PARAMETERS *OperationStartParams ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winbase.h", MSDNShortId = "3E67057E-D09F-48BA-A95A-5D00F4783D9C")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool OperationStart(in OPERATION_START_PARAMETERS OperationStartParams); + + /// + /// + /// The PrivilegedServiceAuditAlarm function generates an audit message in the security event log. A protected server can use + /// this function to log attempts by a client to use a specified set of privileges. + /// + /// Alarms are not currently supported. + /// + /// + /// A pointer to a null-terminated string specifying the name of the subsystem calling the function. This information appears in the + /// security event log record. + /// + /// + /// A pointer to a null-terminated string specifying the name of the privileged subsystem service. This information appears in the + /// security event log record. + /// + /// + /// Identifies an access token representing the client that requested the operation. This handle must have been obtained by opening + /// the token of a thread impersonating the client. The token must be open for TOKEN_QUERY access. The function uses this token to + /// get the identity of the client for the security event log record. + /// + /// + /// A pointer to a PRIVILEGE_SET structure containing the privileges that the client attempted to use. The names of the privileges + /// appear in the security event log record. + /// + /// + /// Indicates whether the client's attempt to use the privileges was successful. If this value is TRUE, the security event log + /// record indicates success. If this value is FALSE, the security event log record indicates failure. + /// + /// + /// If the function succeeds, the return value is nonzero. + /// If the function fails, the return value is zero. To get extended error information, call GetLastError. + /// + /// + /// + /// The PrivilegedServiceAuditAlarm function does not check the client's access token to determine whether the privileges are + /// held or enabled. Typically, you first call the PrivilegeCheck function to determine whether the specified privileges are enabled + /// in the access token, and then call PrivilegedServiceAuditAlarm to log the results. + /// + /// + /// The PrivilegedServiceAuditAlarm function requires the calling process to have SE_AUDIT_NAME privilege enabled. The test + /// for this privilege is always performed against the primary token of the calling process. This allows the calling process to + /// impersonate a client during the call. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-privilegedserviceauditalarma BOOL + // PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken, PPRIVILEGE_SET Privileges, BOOL + // AccessGranted ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "a424c583-bb71-4bda-a27f-2389b89104d8")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool PrivilegedServiceAuditAlarm(string SubsystemName, string ServiceName, HTOKEN ClientToken, PRIVILEGE_SET Privileges, [MarshalAs(UnmanagedType.Bool)] bool AccessGranted); + + /// + /// Backs up (export) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is intended to implement + /// backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// A pointer to the export callback function. The system calls the callback function multiple times, each time passing a block of + /// the file's data to the callback function until the entire file has been read. For more information, see ExportCallback. + /// + /// + /// A pointer to an application-defined and allocated context block. The system passes this pointer to the callback function as a + /// parameter so that the callback function can have access to application-specific data. This can be a structure and can contain any + /// data the application needs, such as the handle to the file that will contain the backup copy of the encrypted file. + /// + /// + /// A pointer to a system-defined context block. The context block is returned by the OpenEncryptedFileRaw function. Do not modify it. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the + /// FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic text description of the error. + /// + /// + /// + /// The file being backed up is not decrypted; it is backed up in its encrypted state. + /// + /// To back up an encrypted file, call OpenEncryptedFileRaw to open the file. Then call ReadEncryptedFileRaw, passing it the + /// address of an application-defined export callback function. The system calls this callback function multiple times until the + /// entire file's contents have been read and backed up. When the backup is complete, call CloseEncryptedFileRaw to free resources + /// and close the file. See ExportCallback for details about how to declare the export callback function. + /// + /// + /// To restore an encrypted file, call OpenEncryptedFileRaw, specifying CREATE_FOR_IMPORT in the ulFlags parameter. Then call + /// WriteEncryptedFileRaw, passing it the address of an application-defined import callback function. The system calls this callback + /// function multiple times until the entire file's contents have been read and restored. When the restore is complete, call + /// CloseEncryptedFileRaw to free resources and close the file. See ImportCallback for details about how to declare the import + /// callback function. + /// + /// This function is intended for the backup of only encrypted files; see BackupRead for backup of unencrypted files. + /// In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies. + /// + /// + /// Technology + /// Supported + /// + /// + /// Server Message Block (SMB) 3.0 protocol + /// Yes + /// + /// + /// SMB 3.0 Transparent Failover (TFO) + /// No + /// + /// + /// SMB 3.0 with Scale-out File Shares (SO) + /// No + /// + /// + /// Cluster Shared Volume File System (CsvFS) + /// No + /// + /// + /// Resilient File System (ReFS) + /// No + /// + /// + /// SMB 3.0 does not support EFS on shares with continuous availability capability. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readencryptedfileraw DWORD ReadEncryptedFileRaw( + // PFE_EXPORT_FUNC pfExportCallback, PVOID pvCallbackContext, PVOID pvContext ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winbase.h", MSDNShortId = "15f6f617-969d-4a40-9038-b902a3c2518b")] + public static extern Win32Error ReadEncryptedFileRaw(ExportCallback pfExportCallback, IntPtr pvCallbackContext, IntPtr pvContext); + + /// + /// The SetFileSecurity function sets the security of a file or directory object. + /// This function is obsolete. Use the SetNamedSecurityInfo function instead. + /// + /// + /// A pointer to a null-terminated string that specifies the file or directory for which security is set. Note that security applied + /// to a directory is not inherited by its children. + /// + /// + /// Specifies a SECURITY_INFORMATION structure that identifies the contents of the security descriptor pointed to by the + /// pSecurityDescriptor parameter. + /// + /// A pointer to a SECURITY_DESCRIPTOR structure. + /// + /// If the function succeeds, the function returns nonzero. + /// If the function fails, it returns zero. To get extended error information, call GetLastError. + /// + /// The SetFileSecurity function is successful only if the following conditions are met: + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-setfilesecuritya BOOL SetFileSecurityA( LPCSTR lpFileName, + // SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor ); + [DllImport(Lib.AdvApi32, SetLastError = true, CharSet = CharSet.Auto)] + [PInvokeData("winbase.h", MSDNShortId = "27766c97-7ac5-40fc-b798-7cd07e496c0d")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetFileSecurity(string lpFileName, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor); + + /// + /// Restores (import) encrypted files. This is one of a group of Encrypted File System (EFS) functions that is intended to implement + /// backup and restore functionality, while maintaining files in their encrypted state. + /// + /// + /// A pointer to the import callback function. The system calls the callback function multiple times, each time passing a buffer that + /// will be filled by the callback function with a portion of backed-up file's data. When the callback function signals that the + /// entire file has been processed, it tells the system that the restore operation is finished. For more information, see ImportCallback. + /// + /// + /// A pointer to an application-defined and allocated context block. The system passes this pointer to the callback function as a + /// parameter so that the callback function can have access to application-specific data. This can be a structure and can contain any + /// data the application needs, such as the handle to the file that will contain the backup copy of the encrypted file. + /// + /// + /// A pointer to a system-defined context block. The context block is returned by the OpenEncryptedFileRaw function. Do not modify it. + /// + /// + /// If the function succeeds, the return value is ERROR_SUCCESS. + /// + /// If the function fails, it returns a nonzero error code defined in WinError.h. You can use FormatMessage with the + /// FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic text description of the error. + /// + /// + /// + /// The file being restored is not decrypted; it is restored in its encrypted state. + /// + /// To back up an encrypted file, call OpenEncryptedFileRaw to open the file. Then call ReadEncryptedFileRaw, passing it the address + /// of an application-defined export callback function. The system calls this callback function multiple times until the entire + /// file's contents have been read and backed up. When the backup is complete, call CloseEncryptedFileRaw to free resources and close + /// the file. See ExportCallback for details about how to declare the export callback function. + /// + /// + /// To restore an encrypted file, call OpenEncryptedFileRaw, specifying CREATE_FOR_IMPORT in the ulFlags parameter. Then call + /// WriteEncryptedFileRaw, passing it the address of an application-defined import callback function. The system calls this + /// callback function multiple times until the entire file's contents have been read and restored. When the restore is complete, call + /// CloseEncryptedFileRaw to free resources and close the file. See ImportCallback for details about how to declare the export + /// callback function. + /// + /// + /// If the file is a sparse file that was backed up from a volume with a smaller sparse allocation unit size than the volume it is + /// being restored to, the sparse blocks in the middle of the file may not properly align with the larger blocks and the function + /// call would fail and set an ERROR_INVALID_PARAMETER last error code. The sparse allocation unit size is either 16 clusters + /// or 64 KB, whichever is smaller. + /// + /// This function is intended for restoring only encrypted files; see BackupWrite for restoring unencrypted files. + /// In Windows 8, Windows Server 2012, and later, this function is supported by the following technologies. + /// + /// + /// Technology + /// Supported + /// + /// + /// Server Message Block (SMB) 3.0 protocol + /// Yes + /// + /// + /// SMB 3.0 Transparent Failover (TFO) + /// No + /// + /// + /// SMB 3.0 with Scale-out File Shares (SO) + /// No + /// + /// + /// Cluster Shared Volume File System (CsvFS) + /// No + /// + /// + /// Resilient File System (ReFS) + /// No + /// + /// + /// SMB 3.0 does not support EFS on shares with continuous availability capability. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-writeencryptedfileraw DWORD WriteEncryptedFileRaw( + // PFE_IMPORT_FUNC pfImportCallback, PVOID pvCallbackContext, PVOID pvContext ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winbase.h", MSDNShortId = "f44e291e-dbc6-4a44-92ba-92a81e043764")] + public static extern Win32Error WriteEncryptedFileRaw(ImportCallback pfImportCallback, IntPtr pvCallbackContext, IntPtr pvContext); + + /// + /// Contains information about a hardware profile. The GetCurrentHwProfile function uses this structure to retrieve the current + /// hardware profile for the local computer. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-hw_profile_infow typedef struct tagHW_PROFILE_INFOW { + // DWORD dwDockInfo; WCHAR szHwProfileGuid[HW_PROFILE_GUIDLEN]; WCHAR szHwProfileName[MAX_PROFILE_LEN]; } HW_PROFILE_INFOW, *LPHW_PROFILE_INFOW; + [PInvokeData("winbase.h", MSDNShortId = "b1c8eb4c-8c62-4e3e-a7d2-0888512b3d4c")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct HW_PROFILE_INFO + { + /// The reported docking state of the computer. This member can be a combination of the following bit values. + public DOCKINFO dwDockInfo; + + /// + /// + /// The globally unique identifier (GUID) string for the current hardware profile. The string returned by GetCurrentHwProfile + /// encloses the GUID in curly braces, {}; for example: + /// + /// {12340001-4980-1920-6788-123456789012} + /// + /// You can use this string as a registry subkey under your application's configuration settings key in HKEY_CURRENT_USER. + /// This enables you to store settings for each hardware profile. + /// + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 39)] + public string szHwProfileGuid; + + /// The display name for the current hardware profile. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] + public string szHwProfileName; + } + + /// This structure is used by the OperationEnd function. + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_operation_end_parameters typedef struct + // _OPERATION_END_PARAMETERS { ULONG Version; OPERATION_ID OperationId; ULONG Flags; } OPERATION_END_PARAMETERS, *POPERATION_END_PARAMETERS; + [PInvokeData("winbase.h", MSDNShortId = "45ABFE6A-7B70-418F-8C3C-6388079D1306")] + [StructLayout(LayoutKind.Sequential)] + public struct OPERATION_END_PARAMETERS + { + /// This parameter should be initialized to the OPERATION_API_VERSION defined in the Windows SDK. + public uint Version; + + /// + /// Each operation has an OPERATION_ID namespace that is unique for each process. If two applications both use the same + /// OPERATION_ID value to identify two operations, the system maintains separate contexts for each operation. + /// + public uint OperationId; + + /// The value of this parameter can include any combination of the following values. + public uint Flags; + } + + /// This structure is used by the OperationStart function. + // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_operation_start_parameters typedef struct + // _OPERATION_START_PARAMETERS { ULONG Version; OPERATION_ID OperationId; ULONG Flags; } OPERATION_START_PARAMETERS, *POPERATION_START_PARAMETERS; + [PInvokeData("winbase.h", MSDNShortId = "51AE0017-2CDE-4BCD-AE03-B366343DE558")] + [StructLayout(LayoutKind.Sequential)] + public struct OPERATION_START_PARAMETERS + { + /// This parameter should be initialized to the OPERATION_API_VERSION value defined in the Windows SDK. + public uint Version; + + /// + /// Each operation has an OPERATION_ID namespace that is unique for each process. If two applications both use the same + /// OPERATION_ID value to identify two operations, the system maintains separate contexts for each operation. + /// + public uint OperationId; + + /// The value of this parameter can include any combination of the following values. + public uint Flags; + } } } \ No newline at end of file diff --git a/PInvoke/Security/AdvApi32/WinCrypt.cs b/PInvoke/Security/AdvApi32/WinCrypt.cs index b1c5cda3..1a4029fc 100644 --- a/PInvoke/Security/AdvApi32/WinCrypt.cs +++ b/PInvoke/Security/AdvApi32/WinCrypt.cs @@ -1,11 +1,9 @@ using System; -using System.ComponentModel; using System.Runtime.InteropServices; -using Vanara.InteropServices; namespace Vanara.PInvoke { public static partial class AdvApi32 { } -} +} \ No newline at end of file diff --git a/PInvoke/Security/AdvApi32/WinSafer.cs b/PInvoke/Security/AdvApi32/WinSafer.cs new file mode 100644 index 00000000..722de71e --- /dev/null +++ b/PInvoke/Security/AdvApi32/WinSafer.cs @@ -0,0 +1,1267 @@ +using System; +using System.Runtime.InteropServices; +using Vanara.InteropServices; +using static Vanara.PInvoke.Crypt32; + +namespace Vanara.PInvoke +{ + public static partial class AdvApi32 + { + private const int SAFER_MAX_HASH_SIZE = 64; + + /// The types of criteria considered when evaluating this structure. + [PInvokeData("winsafer.h", MSDNShortId = "039a37a9-1744-4cff-919e-e0da50d7b291")] + [Flags] + public enum SAFER_CRITERIA + { + /// Check the code image path. + SAFER_CRITERIA_IMAGEPATH = 0x00001, + + /// Check the code hash. + SAFER_CRITERIA_IMAGEHASH = 0x00004, + + /// + /// Check the Authenticode signature. If this value is used, either the hImageFileHandle member or the ImagePath member must be set. + /// + SAFER_CRITERIA_AUTHENTICODE = 0x00008, + + /// Check the URL of origin. + SAFER_CRITERIA_URLZONE = 0x00010, + + /// Check the Windows NT image path. + SAFER_CRITERIA_IMAGEPATH_NT = 0x01000, + + /// Check for a Windows Store app package. For use by Windows Store apps. + SAFER_CRITERIA_APPX_PACKAGE = 0x00020, + } + + public enum SAFER_LEVEL_CREATE_FLAGS + { + SAFER_LEVEL_OPEN = 1, + } + + [Flags] + public enum SAFER_LEVELID + { + /// + /// Software cannot access certain resources, such as cryptographic keys and credentials, regardless of the user rights of the user. + /// + SAFER_LEVELID_CONSTRAINED = 0x10000, + + /// Software will not run, regardless of the user rights of the user. + SAFER_LEVELID_DISALLOWED = 0x00000, + + /// Software user rights are determined by the user rights of the user. + SAFER_LEVELID_FULLYTRUSTED = 0x40000, + + /// + /// Allows programs to execute as a user that does not have Administrator or Power User user rights. Software can access + /// resources accessible by normal users. + /// + SAFER_LEVELID_NORMALUSER = 0x20000, + + /// + /// Allows programs to execute with access only to resources granted to open well-known groups, blocking access to Administrator + /// and Power User privileges and personally granted rights. + /// + SAFER_LEVELID_UNTRUSTED = 0x01000, + } + + /// The SAFER_OBJECT_INFO_CLASS enumeration type defines the type of information requested about a Safer object. + /// The SAFER_OBJECT_INFO_CLASS enumeration type is used by the SaferGetLevelInformation function. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/ne-winsafer-_safer_object_info_class typedef enum + // _SAFER_OBJECT_INFO_CLASS { SaferObjectLevelId, SaferObjectScopeId, SaferObjectFriendlyName, SaferObjectDescription, + // SaferObjectBuiltin, SaferObjectDisallowed, SaferObjectDisableMaxPrivilege, SaferObjectInvertDeletedPrivileges, + // SaferObjectDeletedPrivileges, SaferObjectDefaultOwner, SaferObjectSidsToDisable, SaferObjectRestrictedSidsInverted, + // SaferObjectRestrictedSidsAdded, SaferObjectAllIdentificationGuids, SaferObjectSingleIdentification, SaferObjectExtendedError } SAFER_OBJECT_INFO_CLASS; + [PInvokeData("winsafer.h", MSDNShortId = "31de9e42-6795-433a-937f-c4243e4961df")] + public enum SAFER_OBJECT_INFO_CLASS + { + /// Queries for the LEVELID constant. + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferObjectLevelId = 1, + + /// Queries for the user or machine scope. + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferObjectScopeId, + + /// Queries for the display name. + [CorrespondingType(typeof(string), CorrepsondingAction.GetSet)] + SaferObjectFriendlyName, + + /// Queries for the description. + [CorrespondingType(typeof(string), CorrepsondingAction.GetSet)] + SaferObjectDescription, + + /// + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferObjectBuiltin, + + /// + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferObjectDisallowed, + + /// + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferObjectDisableMaxPrivilege, + + /// + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferObjectInvertDeletedPrivileges, + + /// + [CorrespondingType(typeof(PTOKEN_PRIVILEGES), CorrepsondingAction.Get)] + SaferObjectDeletedPrivileges, + + /// + [CorrespondingType(typeof(TOKEN_OWNER), CorrepsondingAction.Get)] + SaferObjectDefaultOwner, + + /// + [CorrespondingType(typeof(TOKEN_GROUPS), CorrepsondingAction.Get)] + SaferObjectSidsToDisable, + + /// + [CorrespondingType(typeof(TOKEN_GROUPS), CorrepsondingAction.Get)] + SaferObjectRestrictedSidsInverted, + + /// + [CorrespondingType(typeof(TOKEN_GROUPS), CorrepsondingAction.Get)] + SaferObjectRestrictedSidsAdded, + + /// Queries for all levels. + [CorrespondingType(typeof(IntPtr), CorrepsondingAction.Get)] + SaferObjectAllIdentificationGuids, + + /// Queries for a single additional rule. + [CorrespondingType(typeof(IntPtr), CorrepsondingAction.GetSet)] + SaferObjectSingleIdentification, + + /// Queries for additional error codes set during rule processing. + [CorrespondingType(typeof(Win32Error), CorrepsondingAction.Get)] + SaferObjectExtendedError, + } + + /// The SAFER_POLICY_INFO_CLASS enumeration type defines the ways in which a policy may be queried. + /// The SAFER_POLICY_INFO_CLASS enumeration type is used by the SaferGetPolicyInformation function. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/ne-winsafer-_safer_policy_info_class typedef enum + // _SAFER_POLICY_INFO_CLASS { SaferPolicyLevelList, SaferPolicyEnableTransparentEnforcement, SaferPolicyDefaultLevel, + // SaferPolicyEvaluateUserScope, SaferPolicyScopeFlags, SaferPolicyDefaultLevelFlags, SaferPolicyAuthenticodeEnabled } SAFER_POLICY_INFO_CLASS; + [PInvokeData("winsafer.h", MSDNShortId = "e1438a9f-abca-463d-8a3a-3a820cba16e8")] + public enum SAFER_POLICY_INFO_CLASS + { + /// Queries for the list of all levels defined in a policy. + [CorrespondingType(typeof(IntPtr), CorrepsondingAction.Get)] + SaferPolicyLevelList = 1, + + /// Queries for the policy value to determine whether DLL checking is enabled. + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferPolicyEnableTransparentEnforcement, + + /// Queries for the default policy level. + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferPolicyDefaultLevel, + + /// Queries to determine whether user scope rules should be consulted during policy evaluation. + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferPolicyEvaluateUserScope, + + /// Queries to determine whether the policy is to skip members of the local administrators group. + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferPolicyScopeFlags, + + /// + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferPolicyDefaultLevelFlags, + + /// + [CorrespondingType(typeof(uint), CorrepsondingAction.Get)] + SaferPolicyAuthenticodeEnabled, + } + + public enum SAFER_SCOPEID + { + /// The scope of the created level is by computer. + SAFER_SCOPEID_MACHINE = 1, + + /// The scope of the created level is by user. + SAFER_SCOPEID_USER = 2, + } + + /// Specifies the behavior of . + [PInvokeData("winsafer.h", MSDNShortId = "39406331-3101-48f2-8b92-e049849b2b38")] + [Flags] + public enum SAFER_TOKEN_FLAGS + { + /// + /// If the OutAccessToken parameter is not more restrictive than the InAccessToken parameter, the OutAccessToken parameter + /// returns NULL. + /// + SAFER_TOKEN_NULL_IF_EQUAL = 1, + + /// + /// The token specified by the InAccessToken parameter is compared with the token that would be created if the restrictions + /// specified by the LevelHandle parameter were applied. The restricted token is not actually created. + /// On output, the value of the lpReserved parameter specifies the result of the comparison. + /// + SAFER_TOKEN_COMPARE_ONLY = 2, + + /// + /// If this flag is set, the system does not check AppLocker rules or apply Software Restriction Policies. For AppLocker, this + /// flag disables checks for all four rule collections: Executable, Windows Installer, Script, and DLL. + /// Set this flag when creating a setup program that must run extracted DLLs during installation. + /// A token can be queried for existence of this flag by using GetTokenInformation. + /// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: AppLocker is not supported. + /// + SAFER_TOKEN_MAKE_INERT = 4, + + /// On output, the value of the lpReserved parameter specifies the set of flags used to create the restricted token. + SAFER_TOKEN_WANT_FLAGS = 8, + } + + /// Contains all the predefined zones used by Windows Internet Explorer. + [PInvokeData("urlmon.h")] + public enum URLZONE + { + /// Internet Explorer 7. Invalid zone. Used only if no appropriate zone is available. + URLZONE_INVALID = -1, + + /// Minimum value for a predefined zone. + URLZONE_PREDEFINED_MIN = 0, + + /// Zone used for content already on the user's local computer. This zone is not exposed by the user interface. + URLZONE_LOCAL_MACHINE = 0, + + /// Zone used for content found on an intranet. + URLZONE_INTRANET = (URLZONE_LOCAL_MACHINE + 1), + + /// Zone used for trusted Web sites on the Internet. + URLZONE_TRUSTED = (URLZONE_INTRANET + 1), + + /// Zone used for most of the content on the Internet. + URLZONE_INTERNET = (URLZONE_TRUSTED + 1), + + /// Zone used for Web sites that are not trusted. + URLZONE_UNTRUSTED = (URLZONE_INTERNET + 1), + + /// Maximum value for a predefined zone. + URLZONE_PREDEFINED_MAX = 999, + + /// Minimum value allowed for a user-defined zone. + URLZONE_USER_MIN = 1000, + + /// Maximum value allowed for a user-defined zone. + URLZONE_USER_MAX = 10000 + } + + /// + /// The SaferCloseLevel function closes a SAFER_LEVEL_HANDLE that was opened by using the SaferIdentifyLevel function or the + /// SaferCreateLevel function. + /// + /// The SAFER_LEVEL_HANDLE to be closed. + /// TRUE if the function succeeds; otherwise, FALSE. For extended error information, call GetLastError. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-safercloselevel BOOL SaferCloseLevel( SAFER_LEVEL_HANDLE + // hLevelHandle ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "8daffb35-5bb0-45b3-aff1-a8ea6a142ba5")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferCloseLevel(SAFER_LEVEL_HANDLE hLevelHandle); + + /// The SaferComputeTokenFromLevel function restricts a token using restrictions specified by a SAFER_LEVEL_HANDLE. + /// + /// SAFER_LEVEL_HANDLE that contains the restrictions to place on the input token. Do not pass handles with a LevelId of + /// SAFER_LEVELID_FULLYTRUSTED or SAFER_LEVELID_DISALLOWED to this function. This is because + /// SAFER_LEVELID_FULLYTRUSTED is unrestricted and SAFER_LEVELID_DISALLOWED does not contain a token. + /// + /// + /// Token to be restricted. If this parameter is NULL, the token of the current thread will be used. If the current thread + /// does not contain a token, the token of the current process is used. + /// + /// The resulting restricted token. + /// + /// + /// Specifies the behavior of the method. The value can be NULL or one or more of the following values combined by using a + /// bitwise- OR operation. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SAFER_TOKEN_NULL_IF_EQUAL 1 (0x1) + /// + /// If the OutAccessToken parameter is not more restrictive than the InAccessToken parameter, the OutAccessToken parameter returns NULL. + /// + /// + /// + /// SAFER_TOKEN_COMPARE_ONLY 2 (0x2) + /// + /// The token specified by the InAccessToken parameter is compared with the token that would be created if the restrictions specified + /// by the LevelHandle parameter were applied. The restricted token is not actually created. On output, the value of the lpReserved + /// parameter specifies the result of the comparison. + /// + /// + /// + /// SAFER_TOKEN_MAKE_INERT 4 (0x4) + /// + /// If this flag is set, the system does not check AppLocker rules or apply Software Restriction Policies. For AppLocker, this flag + /// disables checks for all four rule collections: Executable, Windows Installer, Script, and DLL. Set this flag when creating a + /// setup program that must run extracted DLLs during installation. A token can be queried for existence of this flag by using + /// GetTokenInformation. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: AppLocker is not supported. + /// + /// + /// + /// SAFER_TOKEN_WANT_FLAGS 8 (0x8) + /// On output, the value of the lpReserved parameter specifies the set of flags used to create the restricted token. + /// + /// + /// + /// + /// + /// If the SAFER_TOKEN_COMPARE_ONLY flag is set, this parameter, on output, specifies the result of the token comparison. The + /// output value is an LPDWORD. A value of –1 indicates that the resulting token would be less privileged than the token + /// specified by the InAccessToken parameter. + /// + /// + /// If the SAFER_TOKEN_WANT_FLAGS flag is set, and the SAFER_TOKEN_COMPARE_ONLY flag is not set, this parameter is an + /// LPDWORD value that specifies the flags used to create the restricted token. + /// + /// + /// TRUE if the function succeeds; otherwise, FALSE. For extended information, call GetLastError. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-safercomputetokenfromlevel BOOL + // SaferComputeTokenFromLevel( SAFER_LEVEL_HANDLE LevelHandle, HANDLE InAccessToken, PHANDLE OutAccessToken, DWORD dwFlags, LPVOID + // lpReserved ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "39406331-3101-48f2-8b92-e049849b2b38")] + // [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE LevelHandle, + // HANDLE InAccessToken, ref IntPtr OutAccessToken, uint dwFlags, IntPtr lpReserved); + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE LevelHandle, HTOKEN InAccessToken, out SafeHTOKEN OutAccessToken, SAFER_TOKEN_FLAGS dwFlags, out uint lpReserved); + + /// The SaferCreateLevel function opens a SAFER_LEVEL_HANDLE. + /// + /// The scope of the level to be created. The following table shows the possible values. + /// + /// + /// Value + /// Meaning + /// + /// + /// SAFER_SCOPEID_MACHINE 1 + /// The scope of the created level is by computer. + /// + /// + /// SAFER_SCOPEID_USER 2 + /// The scope of the created level is by user. + /// + /// + /// + /// + /// The level of the handle to be opened. The following table shows the possible values. + /// + /// + /// Value + /// Meaning + /// + /// + /// SAFER_LEVELID_CONSTRAINED 0x10000 + /// + /// Software cannot access certain resources, such as cryptographic keys and credentials, regardless of the user rights of the user. + /// + /// + /// + /// SAFER_LEVELID_DISALLOWED 0x00000 + /// Software will not run, regardless of the user rights of the user. + /// + /// + /// SAFER_LEVELID_FULLYTRUSTED 0x40000 + /// Software user rights are determined by the user rights of the user. + /// + /// + /// SAFER_LEVELID_NORMALUSER 0x20000 + /// + /// Allows programs to execute as a user that does not have Administrator or Power User user rights. Software can access resources + /// accessible by normal users. + /// + /// + /// + /// SAFER_LEVELID_UNTRUSTED 0x01000 + /// + /// Allows programs to execute with access only to resources granted to open well-known groups, blocking access to Administrator and + /// Power User privileges and personally granted rights. + /// + /// + /// + /// + /// + /// This can be the following value. + /// + /// + /// Value + /// Meaning + /// + /// + /// SAFER_LEVEL_OPEN 1 + /// + /// + /// + /// + /// + /// The returned SAFER_LEVEL_HANDLE. When you have finished using the handle, close it by calling the SaferCloseLevel function. + /// + /// This parameter is reserved for future use. Set it to NULL. + /// + /// Returns nonzero if successful or zero otherwise. + /// For extended error information, call GetLastError. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-safercreatelevel BOOL SaferCreateLevel( DWORD dwScopeId, + // DWORD dwLevelId, DWORD OpenFlags, SAFER_LEVEL_HANDLE *pLevelHandle, LPVOID lpReserved ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "7deb1365-5355-4983-900b-8e4fed009403")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferCreateLevel(SAFER_SCOPEID dwScopeId, SAFER_LEVELID dwLevelId, SAFER_LEVEL_CREATE_FLAGS OpenFlags, out SafeSAFER_LEVEL_HANDLE pLevelHandle, IntPtr lpReserved = default); + + /// The SaferGetLevelInformation function retrieves information about a policy level. + /// The handle of the level to be queried. + /// + /// + /// A SAFER_OBJECT_INFO_CLASS enumeration value that specifies the type of object information that should be returned. The specified + /// value determines the size and type of the lpQueryBuffer parameter. The following table shows the possible values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SaferObjectLevelId 1 + /// Queries for the LEVELID constant. lpQueryBuffer return type: DWORD. + /// + /// + /// SaferObjectScopeId 2 + /// Queries for the user or machine scope. lpQueryBuffer return type: DWORD. + /// + /// + /// SaferObjectFriendlyName 3 + /// Queries for the display name. lpQueryBuffer return type: LPCWSTR. + /// + /// + /// SaferObjectDescription 4 + /// Queries for the description. lpQueryBuffer return type: LPCWSTR. + /// + /// + /// + /// + /// A buffer to contain the results of the query. For the type of the returned information for each possible value of the dwInfoType + /// parameter, see the dwInfoType parameter. + /// + /// The size of the lpQueryBuffer parameter in bytes. + /// A pointer to return the output size of the lpQueryBuffer parameter. + /// TRUE if the function succeeds; otherwise, FALSE. For extended error information, call GetLastError. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-safergetlevelinformation BOOL SaferGetLevelInformation( + // SAFER_LEVEL_HANDLE LevelHandle, SAFER_OBJECT_INFO_CLASS dwInfoType, LPVOID lpQueryBuffer, DWORD dwInBufferSize, LPDWORD + // lpdwOutBufferSize ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "cbe73ebc-bf2c-4d39-a203-78ff1a407481")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferGetLevelInformation(SAFER_LEVEL_HANDLE LevelHandle, SAFER_OBJECT_INFO_CLASS dwInfoType, IntPtr lpQueryBuffer, uint dwInBufferSize, out uint lpdwOutBufferSize); + + /// + /// The SaferGetPolicyInformation function gets information about a policy. You can query to find out more information about + /// the policy. + /// + /// + /// The scope of the query. The following table shows the possible values. + /// + /// + /// Value + /// Meaning + /// + /// + /// SAFER_SCOPEID_MACHINE 1 + /// The scope of the query is by computer. + /// + /// + /// SAFER_SCOPEID_USER 2 + /// The scope of the query is by user. + /// + /// + /// + /// + /// + /// A SAFER_POLICY_INFO_CLASS enumeration value that specifies the type of policy information that should be returned. The specified + /// value determines the size and type of the InfoBuffer parameter. The following table shows the possible values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SaferPolicyLevelList 1 + /// Queries for the list of all levels defined in a policy. InfoBuffer return type: DWORD array of LevelIds. + /// + /// + /// SaferPolicyEnableTransparentEnforcement 2 + /// Queries for the policy value to determine whether DLL checking is enabled. InfoBuffer return type: DWORD Boolean. + /// + /// + /// SaferPolicyDefaultLevel 3 + /// Queries for the default policy level. InfoBuffer return type: DWORD LevelId. + /// + /// + /// SaferPolicyEvaluateUserScope 4 + /// Queries to determine whether user scope rules should be consulted during policy evaluation. InfoBuffer return type: DWORD. + /// + /// + /// SaferPolicyScopeFlags 5 + /// + /// Queries to determine whether the policy is to skip members of the local administrators group. InfoBuffer return type: DWORD. + /// + /// + /// + /// + /// The size, in bytes, of the InfoBuffer parameter. + /// + /// A buffer to contain the results of the query. The size and type of the returned information is determined by the + /// SaferPolicyInfoClass parameter. For the type of the returned information for each possible value of the SaferPolicyInfoClass + /// parameter, see the SaferPolicyInfoClass parameter. + /// + /// The number of bytes in the InfoBuffer parameter that were filled with policy information. + /// Reserved for future use. This parameter should be set to NULL. + /// TRUE if the function succeeds; otherwise, FALSE. For extended error information, call GetLastError. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-safergetpolicyinformation BOOL + // SaferGetPolicyInformation( DWORD dwScopeId, SAFER_POLICY_INFO_CLASS SaferPolicyInfoClass, DWORD InfoBufferSize, PVOID InfoBuffer, + // PDWORD InfoBufferRetSize, LPVOID lpReserved ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "1c69d3c1-87e6-42cd-9acb-4c3d06801401")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferGetPolicyInformation(SAFER_SCOPEID dwScopeId, SAFER_POLICY_INFO_CLASS SaferPolicyInfoClass, uint InfoBufferSize, IntPtr InfoBuffer, out uint InfoBufferRetSize, IntPtr lpReserved = default); + + /// The SaferIdentifyLevel function retrieves information about a level. + /// Number of SAFER_CODE_PROPERTIES structures in the pCodeproperties parameter. + /// + /// Array of SAFER_CODE_PROPERTIES structures. Each structure contains a code file to be checked and the criteria used to check the file. + /// + /// + /// The returned SAFER_LEVEL_HANDLE. When you have finished using the handle, close it by calling the SaferCloseLevel function. + /// + /// + /// Reserved for future use. Should be set to NULL. + /// Beginning with Windows 8 and Windows Server 2012 SRP_POLICY_APPX is defined as Windows Store app. + /// + /// TRUE if a SAFER_LEVEL_HANDLE was opened; otherwise, FALSE. For extended error information, call GetLastError. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-saferidentifylevel BOOL SaferIdentifyLevel( DWORD + // dwNumProperties, PSAFER_CODE_PROPERTIES pCodeProperties, SAFER_LEVEL_HANDLE *pLevelHandle, LPVOID lpReserved ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "f82c4f40-5c37-4f97-95a2-4b2cc26bf41e")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferIdentifyLevel(uint dwNumProperties, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] SAFER_CODE_PROPERTIES_V2[] pCodeProperties, out SafeSAFER_LEVEL_HANDLE pLevelHandle, IntPtr lpReserved = default); + + /// + /// The SaferiIsExecutableFileType function determines whether a specified file is an executable file. Applications use this + /// function to determine whether a file is an executable file, and if it is, then the application can take security precautions to + /// prevent invoking untrustworthy code. + /// + /// + /// Pointer to a null-terminated Unicode character string for the name of the file. The path is optional because only the file + /// name extension is evaluated. The evaluation of the file name extension is not case-sensitive. This parameter cannot be + /// NULL or an empty string, and the specified file must include a file name extension. + /// + /// + /// Boolean value that determines whether .exe files are treated as executable files for the file type evaluation. Set this value to + /// TRUE to omit .exe files from the evaluation or to FALSE to include them. + /// + /// + /// If the function successfully recognizes the file name's extension as an executable file type, the return value is TRUE. + /// If the function fails, or if szFullPath identifies a file name with a nonexecutable extension, the function returns FALSE. + /// + /// + /// The following file name extensions are examples of executable file types. This is not a complete list. + /// + /// + /// .bat + /// + /// + /// .cmd + /// + /// + /// .com + /// + /// + /// .exe + /// + /// + /// .js + /// + /// + /// .lnk + /// + /// + /// .pif + /// + /// + /// .pl + /// + /// + /// .shs + /// + /// + /// .url + /// + /// + /// .vbs + /// + /// + /// + /// The security policy Microsoft Management Console (MMC) snap-in (Secpol.msc) controls which extensions are considered executable + /// file types. + /// + /// To view or modify the extensions that are considered executable file types + /// + /// + /// Run Secpol.msc. + /// + /// + /// Expand Software Restriction Policies, and then double-click Designated File Types. + /// + /// + /// + /// Note To view the Designated File Types property page, you may need to create the Software Restriction + /// Policies node. To create the Software Restriction Policies node, follow the instructions that appear when you expand + /// Software Restriction Policies. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-saferiisexecutablefiletype BOOL + // SaferiIsExecutableFileType( LPCWSTR szFullPathname, BOOLEAN bFromShellExecute ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "f122ceaa-65bb-4cfe-a760-adf4f910c487")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferiIsExecutableFileType([MarshalAs(UnmanagedType.LPWStr)] string szFullPathname, [MarshalAs(UnmanagedType.U1)] bool bFromShellExecute); + + /// + /// Gets the level of a hash identification rule that matches the specified hash. + /// + /// This function has no associated import library and is not declared in a public header. You must define a function pointer with + /// the signature of this function, and you must use the LoadLibrary and GetProcAddress functions to dynamically link + /// to Advapi32.dll. + /// + /// We recommend using the SaferIdentifyLevel function to evaluate software restriction policies. + /// + /// The identifier of the algorithm used to create the hash. + /// A pointer to an array of bytes that contains the hash. + /// The size, in bytes, of the pHashBytes array. + /// The size, in bytes, of the original image from which the hash was computed. + /// A pointer to the level identifier for the matching hash identification rule. + /// Reserved. Set this value to zero. + /// TRUE if the function is successful; otherwise, FALSE. + // https://docs.microsoft.com/en-us/windows/desktop/DevNotes/saferisearchmatchinghashrules BOOL WINAPI SaferiSearchMatchingHashRules( + // _In_opt_ ALG_ID HashAlgorithm, _In_ PBYTE pHashBytes, _In_ DWORD dwHashSize, _In_opt_ DWORD dwOriginalImageSize, _Out_ PDWORD + // pdwFoundLevel, PDWORD pdwSaferFlags ); + [DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("", MSDNShortId = "1592c8da-31c0-45fb-b832-d439dd53c277")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferiSearchMatchingHashRules(ALG_ID HashAlgorithm, IntPtr pHashBytes, uint dwHashSize, uint dwOriginalImageSize, out uint pdwFoundLevel, IntPtr pdwSaferFlags = default); + + /// The SaferRecordEventLogEntry function saves messages to an event log. + /// SAFER_LEVEL_HANDLE that contains the details of the rule to send to the event log. + /// Path of the file that attempted to run. + /// Reserved for future use. This parameter should be set to NULL. + /// TRUE if the function succeeds; otherwise, FALSE. For extended error information, call GetLastError. + /// + /// If SaferIdentifyLevel returns a SAFER_LEVEL_HANDLE with a LevelId that is anything other than SAFER_LEVELID_FULLYTRUSTED + /// (0x40000), SaferRecordEventLogEntry can be called to facilitate troubleshooting. For example, clicking a button in + /// excel.exe might attempt to launch another process that is not fully trusted. This might display an obscure error message because + /// the program remapped the error returned from CreateProcess. To ease troubleshooting, some Safer functions call + /// SaferRecordEventLogEntry to send an event to the event log. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-saferrecordeventlogentry BOOL SaferRecordEventLogEntry( + // SAFER_LEVEL_HANDLE hLevel, LPCWSTR szTargetPath, LPVOID lpReserved ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "7eb48f80-3a57-46ec-aca1-6ff8c1c514c6")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferRecordEventLogEntry(SAFER_LEVEL_HANDLE hLevel, [MarshalAs(UnmanagedType.LPWStr)] string szTargetPath, IntPtr lpReserved = default); + + /// The SaferSetLevelInformation function sets the information about a policy level. + /// The handle of the level to be set. + /// + /// + /// A SAFER_OBJECT_INFO_CLASS enumeration value that specifies the type of object information that should be set. The specified value + /// determines the size and type of the lpQueryBuffer parameter. The following table shows the possible values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SaferObjectLevelId 1 + /// Sets the LEVELID constant. lpQueryBuffer return type: DWORD. + /// + /// + /// SaferObjectScopeId 2 + /// Sets the user or machine scope. lpQueryBuffer return type: DWORD. + /// + /// + /// SaferObjectFriendlyName 3 + /// Sets the display name. lpQueryBuffer return type: LPCWSTR. + /// + /// + /// SaferObjectDescription 4 + /// Sets the description. lpQueryBuffer return type: LPCWSTR. + /// + /// + /// + /// + /// A buffer to contain the results of the query. For the type of the returned information for each possible value of the dwInfoType + /// parameter, see the dwInfoType parameter. + /// + /// The size, in bytes, of the lpQueryBuffer parameter. + /// TRUE if the function succeeds; otherwise, FALSE. For extended error information, call GetLastError. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-safersetlevelinformation BOOL SaferSetLevelInformation( + // SAFER_LEVEL_HANDLE LevelHandle, SAFER_OBJECT_INFO_CLASS dwInfoType, LPVOID lpQueryBuffer, DWORD dwInBufferSize ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "8DB13F94-1736-4C05-B072-BFBFC076A726")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferSetLevelInformation(SAFER_LEVEL_HANDLE LevelHandle, SAFER_OBJECT_INFO_CLASS dwInfoType, IntPtr lpQueryBuffer, uint dwInBufferSize); + + /// The SaferSetPolicyInformation function sets the global policy controls. + /// + /// The scope of the query. The following table shows the possible values. + /// + /// + /// Value + /// Meaning + /// + /// + /// SAFER_SCOPEID_MACHINE 1 + /// The scope of the query is by computer. + /// + /// + /// SAFER_SCOPEID_USER 2 + /// The scope of the query is by user. + /// + /// + /// + /// + /// + /// A SAFER_POLICY_INFO_CLASS enumeration value that specifies the type of policy information that should be set. The specified value + /// determines the size and type of the InfoBuffer parameter. The following table shows the possible values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SaferPolicyLevelList 1 + /// Sets the list of all levels defined in a policy. InfoBuffer return type: DWORD array of LevelIds. + /// + /// + /// SaferPolicyEnableTransparentEnforcement 2 + /// Sets the policy value to determine whether DLL checking is enabled. InfoBuffer return type: DWORD Boolean. + /// + /// + /// SaferPolicyDefaultLevel 3 + /// Sets the default policy level. InfoBuffer return type: DWORD LevelId. + /// + /// + /// SaferPolicyEvaluateUserScope 4 + /// Sets whether user scope rules should be consulted during policy evaluation. InfoBuffer return type: DWORD. + /// + /// + /// SaferPolicyScopeFlags 5 + /// Sets whether the policy is to skip members of the local administrators group. InfoBuffer return type: DWORD. + /// + /// + /// + /// The size, in bytes, of the InfoBuffer parameter. + /// + /// A buffer to contain the results of the query. The size and type of the returned information is determined by the + /// SaferPolicyInfoClass parameter. For the type of the returned information for each possible value of the SaferPolicyInfoClass + /// parameter, see the SaferPolicyInfoClass parameter. + /// + /// Reserved for future use. This parameter should be set to NULL. + /// TRUE if the function succeeds; otherwise, FALSE. For extended error information, call GetLastError. + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/nf-winsafer-safersetpolicyinformation BOOL + // SaferSetPolicyInformation( DWORD dwScopeId, SAFER_POLICY_INFO_CLASS SaferPolicyInfoClass, DWORD InfoBufferSize, PVOID InfoBuffer, + // LPVOID lpReserved ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsafer.h", MSDNShortId = "B8F3AFC4-8CAD-4AD2-AF17-CCE05A315AD8")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SaferSetPolicyInformation(SAFER_SCOPEID dwScopeId, SAFER_POLICY_INFO_CLASS SaferPolicyInfoClass, uint InfoBufferSize, IntPtr InfoBuffer, IntPtr lpReserved = default); + + /// + /// + /// The SAFER_CODE_PROPERTIES_V1 structure contains code image information and criteria to be checked on the code image. An + /// array of SAFER_CODE_PROPERTIES_V1 structures is passed to the SaferIdentifyLevel function. + /// + /// + /// SAFER_CODE_PROPERTIES_V1 does not include the new members for Windows Store app packages. Existing binary callers can distinguish + /// which version by checking the cbSize member. + /// + /// + /// + /// SAFER_CODE_PROPERTIES was redefined to include additional members that allow Windows Store app to use the structure. Check the + /// cbSize member for the appropriate size of the structure and for whether you should use the SAFER_CODE_PROPERTIES + /// structure or the SAFER_CODE_PROPERTIES_V1 structure. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/ns-winsafer-safer_code_properties_v1 typedef struct + // _SAFER_CODE_PROPERTIES_V1 { DWORD cbSize; DWORD dwCheckFlags; LPCWSTR ImagePath; HANDLE hImageFileHandle; DWORD UrlZoneId; BYTE + // ImageHash[SAFER_MAX_HASH_SIZE]; DWORD dwImageHashSize; LARGE_INTEGER ImageSize; ALG_ID HashAlgorithm; LPBYTE pByteBlock; HWND + // hWndParent; DWORD dwWVTUIChoice; } SAFER_CODE_PROPERTIES_V1, *PSAFER_CODE_PROPERTIES_V1; + [PInvokeData("winsafer.h", MSDNShortId = "E09D287B-7223-4CAF-B404-61FB6871B622")] + [StructLayout(LayoutKind.Sequential)] + public struct SAFER_CODE_PROPERTIES_V1 + { + /// The size, in bytes, of this structure. This is used for future and backward compatibility. + public uint cbSize; + + /// + /// + /// The types of criteria considered when evaluating this structure. Some flags might be silently ignored if some or all of their + /// associated structure elements are not supplied. Specifying zero for this parameter causes the entire structure's contents to + /// be ignored. + /// + /// The following table shows the possible values. These values can be combined by using a bitwise- OR operation. + /// + /// + /// Value + /// Meaning + /// + /// + /// SAFER_CRITERIA_IMAGEPATH 0x00001 + /// Check the code image path. + /// + /// + /// SAFER_CRITERIA_IMAGEHASH 0x00004 + /// Check the code hash. + /// + /// + /// SAFER_CRITERIA_AUTHENTICODE 0x00008 + /// + /// Check the Authenticode signature. If this value is used, either the hImageFileHandle member or the ImagePath member must be set. + /// + /// + /// + /// SAFER_CRITERIA_URLZONE 0x00010 + /// Check the URL of origin. + /// + /// + /// SAFER_CRITERIA_IMAGEPATH_NT 0x01000 + /// Check the Windows NT image path. + /// + /// + /// + public SAFER_CRITERIA dwCheckFlags; + + /// + /// A string that specifies the fully qualified path and file name to be used for discrimination checks based on the path. The + /// image path is also used to open and read the file to identify any other discrimination criteria not supplied in this + /// structure. This member can be NULL; however, if the dwCheckFlags member includes + /// SAFER_CRITERIA_AUTHENTICODE, either this member or the hImageFileHandle member must be set. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string ImagePath; + + /// + /// A file handle to a code image with at least GENERIC_READ access. The handle is used instead of explicitly reopening the file + /// to compute discrimination criteria not supplied in this structure. This member can be NULL; however, if + /// dwCheckFlags includes SAFER_CRITERIA_AUTHENTICODE, either this member or the ImagePath member must be set. + /// + public HFILE hImageFileHandle; + + /// + /// The predetermined Internet Explorer security zones. The following zones are defined: + /// + /// + /// URLZONE_LOCAL_MACHINE + /// + /// + /// URLZONE_INTRANET + /// + /// + /// URLZONE_TRUSTED + /// + /// + /// URLZONE_INTERNET + /// + /// + /// URLZONE_UNTRUSTED + /// + /// + /// This member can be set to 0. + /// + public URLZONE UrlZoneId; + + /// + /// + /// The precomputed hash of the image. The supplied hash is interpreted as valid if both the ImageSize member and the + /// dwImageHashSize member are nonzero and the HashAlgorithm member contains a valid hashing algorithm from Wincrypt.h. + /// + /// If the supplied hash fails to meet these conditions, the hash is automatically recomputed by: + /// + /// + /// Using the ImageSize member and the pByteBlock member, if both are nonzero. + /// + /// + /// Using the hImageFileHandle member, if it is not NULL. + /// + /// + /// Opening and using the ImagePath member, if it is not NULL. + /// + /// + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = SAFER_MAX_HASH_SIZE)] + public byte[] ImageHash; + + /// The size, in bytes, of the ImageHash member. + public uint dwImageHashSize; + + /// + /// The size, in bytes, of the pByteBlock member. This member is not used if the pByteBlock member is NULL. + /// + public int ImageSize; + + /// The hash algorithm used to create the ImageHash member. + public ALG_ID HashAlgorithm; + + /// + /// The memory block that contains the image of the code being checked. This member is optional. If this member is specified, the + /// ImageSize member must also be supplied. + /// + public IntPtr pByteBlock; + + /// + /// The arguments used for Authenticode signer certificate verification. These arguments are passed to the WinVerifyTrust + /// function and control the UI that prompts the user to accept or reject entrusted certificates. + /// + public HWND hWndParent; + + /// + /// Indicates the type of UI used. The following table shows the possible values. + /// + /// + /// Value + /// Meaning + /// + /// + /// WTD_UI_ALL + /// Display all UI. + /// + /// + /// WTD_UI_NONE + /// Display no UI. + /// + /// + /// WTD_UI_NOBAD + /// Display UI only if there were no errors. + /// + /// + /// WTD_UI_NOGOOD + /// Display UI only if an error occurs. + /// + /// + /// + // TODO: Replace with WTD_UI once WinTrust.dll is supported + public uint dwWVTUIChoice; + } + + /// + /// + /// The SAFER_CODE_PROPERTIES structure contains code image information and criteria to be checked on the code image. An array + /// of SAFER_CODE_PROPERTIES structures is passed to the SaferIdentifyLevel function. + /// + /// + /// SAFER_CODE_PROPERTIES_V2 is a redefinition of SAFER_CODE_PROPERTIES and is an extended version of SAFER_CODE_PROPERTIES_V1 + /// because it includes new members for Windows Store app packages. Existing binary callers can distinguish which version by checking + /// the cbSize member. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsafer/ns-winsafer-safer_code_properties_v2 typedef struct + // _SAFER_CODE_PROPERTIES_V2 { DWORD cbSize; DWORD dwCheckFlags; LPCWSTR ImagePath; HANDLE hImageFileHandle; DWORD UrlZoneId; BYTE + // ImageHash[SAFER_MAX_HASH_SIZE]; DWORD dwImageHashSize; LARGE_INTEGER ImageSize; ALG_ID HashAlgorithm; LPBYTE pByteBlock; HWND + // hWndParent; DWORD dwWVTUIChoice; LPCWSTR PackageMoniker; LPCWSTR PackagePublisher; LPCWSTR PackageName; ULONG64 PackageVersion; + // BOOL PackageIsFramework; } SAFER_CODE_PROPERTIES_V2, *PSAFER_CODE_PROPERTIES_V2; + [PInvokeData("winsafer.h", MSDNShortId = "039a37a9-1744-4cff-919e-e0da50d7b291")] + [StructLayout(LayoutKind.Sequential)] + public struct SAFER_CODE_PROPERTIES_V2 + { + /// The size of this structure in bytes. This is used for future and backward compatibility. + public uint cbSize; + + /// + /// + /// The types of criteria considered when evaluating this structure. Some flags might be silently ignored if some or all of their + /// associated structure elements are not supplied. Specifying zero for this parameter causes the entire structure's contents to + /// be ignored. + /// + /// The following table shows the possible values. These values may be combined using a bitwise- OR operation. + /// + /// + /// Value + /// Meaning + /// + /// + /// SAFER_CRITERIA_IMAGEPATH 0x00001 + /// Check the code image path. + /// + /// + /// SAFER_CRITERIA_IMAGEHASH 0x00004 + /// Check the code hash. + /// + /// + /// SAFER_CRITERIA_AUTHENTICODE 0x00008 + /// + /// Check the Authenticode signature. If this value is used, either the hImageFileHandle member or the ImagePath member must be set. + /// + /// + /// + /// SAFER_CRITERIA_URLZONE 0x00010 + /// Check the URL of origin. + /// + /// + /// SAFER_CRITERIA_IMAGEPATH_NT 0x01000 + /// Check the Windows NT image path. + /// + /// + /// SAFER_CRITERIA_APPX_PACKAGE 0x00020 + /// Check for a Windows Store app package. For use by Windows Store apps. + /// + /// + /// + public SAFER_CRITERIA dwCheckFlags; + + /// + /// A string specifying the fully qualified path and file name to be used for discrimination checks based on the path. The image + /// path is also used to open and read the file to identify any other discrimination criteria not supplied in this structure. + /// This member can be NULL; however, if the dwCheckFlags member includes SAFER_CRITERIA_AUTHENTICODE, + /// either this member or the hImageFileHandle member must be set. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string ImagePath; + + /// + /// A file handle to a code image with at least GENERIC_READ access. The handle is used instead of explicitly reopening the file + /// to compute discrimination criteria not supplied in this structure. This member can be NULL; however, if + /// dwCheckFlags includes SAFER_CRITERIA_AUTHENTICODE, either this member or the ImagePath member must be set. + /// + public HFILE hImageFileHandle; + + /// + /// The predetermined Internet Explorer security zones. The following zones are defined: + /// + /// + /// URLZONE_LOCAL_MACHINE + /// + /// + /// URLZONE_INTRANET + /// + /// + /// URLZONE_TRUSTED + /// + /// + /// URLZONE_INTERNET + /// + /// + /// URLZONE_UNTRUSTED + /// + /// + /// This member can be set to 0. + /// + public URLZONE UrlZoneId; + + /// + /// + /// The pre-computed hash of the image. The supplied hash is interpreted as valid if both the ImageSize member and the + /// dwImageHashSize member are nonzero and the HashAlgorithm member contains a valid hashing algorithm from Wincrypt.h. + /// + /// If the supplied hash fails to meet these conditions, the hash will be automatically recomputed by: + /// + /// + /// Using the ImageSize member and the pByteBlock member if both are nonzero. + /// + /// + /// Using the hImageFileHandle member if it is not NULL. + /// + /// + /// Opening and using the ImagePath member if it is not NULL. + /// + /// + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = SAFER_MAX_HASH_SIZE)] + public byte[] ImageHash; + + /// The size in bytes of the ImageHash member. + public uint dwImageHashSize; + + /// + /// The size in bytes of the pByteBlock member. This member is not used if the pByteBlock member is NULL. + /// + public int ImageSize; + + /// The hash algorithm used to create the ImageHash member. + public ALG_ID HashAlgorithm; + + /// + /// The memory block containing the image of the code being checked. This member is optional. If this member is specified, the + /// ImageSize member must also be supplied. + /// + public IntPtr pByteBlock; + + /// + /// The arguments used for Authenticode signer certificate verification. These arguments are passed to the WinVerifyTrust + /// function and control the user interface (UI) that prompts the user to accept or reject entrusted certificates. + /// + public HWND hWndParent; + + /// + /// Indicates the type of UI used. The following table shows the possible values. + /// + /// + /// Value + /// Meaning + /// + /// + /// WTD_UI_ALL + /// Display all UI. + /// + /// + /// WTD_UI_NONE + /// Display no UI. + /// + /// + /// WTD_UI_NOBAD + /// Display UI only if there were no errors. + /// + /// + /// WTD_UI_NOGOOD + /// Display UI only if an error occurs. + /// + /// + /// + // TODO: Replace with WTD_UI once WinTrust.dll is supported + public uint dwWVTUIChoice; + + /// + /// The package moniker property. For use by Windows Store apps. + /// + /// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This member + /// is not available. + /// + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string PackageMoniker; + + /// + /// The package publisher property. For use by Windows Store apps. + /// + /// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This member + /// is not available. + /// + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string PackagePublisher; + + /// + /// The package name property. For use by Windows Store apps. + /// + /// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This member + /// is not available. + /// + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string PackageName; + + /// + /// The package version property. For use by Windows Store apps. + /// + /// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This member + /// is not available. + /// + /// + public ulong PackageVersion; + + /// + /// The package is a framework package. For use by Windows Store apps. + /// + /// Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: This member + /// is not available. + /// + /// + [MarshalAs(UnmanagedType.Bool)] + public bool PackageIsFramework; + } + + /// Provides a handle to a safer level. + [StructLayout(LayoutKind.Sequential)] + public struct SAFER_LEVEL_HANDLE : IHandle + { + private IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public SAFER_LEVEL_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static SAFER_LEVEL_HANDLE NULL => new SAFER_LEVEL_HANDLE(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(SAFER_LEVEL_HANDLE h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator SAFER_LEVEL_HANDLE(IntPtr h) => new SAFER_LEVEL_HANDLE(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(SAFER_LEVEL_HANDLE h1, SAFER_LEVEL_HANDLE h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(SAFER_LEVEL_HANDLE h1, SAFER_LEVEL_HANDLE h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is SAFER_LEVEL_HANDLE h ? handle == h.handle : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// Provides a for that is disposed using . + public class SafeSAFER_LEVEL_HANDLE : SafeHANDLE + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeSAFER_LEVEL_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeSAFER_LEVEL_HANDLE() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator SAFER_LEVEL_HANDLE(SafeSAFER_LEVEL_HANDLE h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => SaferCloseLevel(handle); + } + } +} \ No newline at end of file diff --git a/PInvoke/Security/AdvApi32/WinSvc.cs b/PInvoke/Security/AdvApi32/WinSvc.cs index 13934e22..cfad242a 100644 --- a/PInvoke/Security/AdvApi32/WinSvc.cs +++ b/PInvoke/Security/AdvApi32/WinSvc.cs @@ -2564,6 +2564,53 @@ namespace Vanara.PInvoke [PInvokeData("winsvc.h", MSDNShortId = "87861465-c966-479a-b906-27ae36cc83c8")] public static extern SC_LOCK LockServiceDatabase(SC_HANDLE hSCManager); + /// + /// Reports the boot status to the service control manager. It is used by boot verification programs. This function can be called + /// only by a process running in the LocalSystem or Administrator's account. + /// + /// + /// If the value is TRUE, the system saves the configuration as the last-known good configuration. If the value is FALSE, the system + /// immediately reboots, using the previously saved last-known good configuration. + /// + /// + /// If the BootAcceptable parameter is FALSE, the function does not return. + /// If the last-known good configuration was successfully saved, the return value is nonzero. + /// If an error occurs, the return value is zero. To get extended error information, call GetLastError. + /// + /// The following error codes may be set by the service control manager. Other error codes may be set by the registry functions that + /// are called by the service control manager to set parameters in the configuration registry. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_ACCESS_DENIED + /// + /// The user does not have permission to perform this operation. Only the system and members of the Administrator's group can do so. + /// + /// + /// + /// + /// + /// + /// Saving the configuration of a running system with this function is an acceptable method for saving the last-known good + /// configuration. If the boot configuration is unacceptable, use this function to reboot the system using the existing last-known + /// good configuration. + /// + /// + /// This function call requires the caller's token to have permission to acquire the SC_MANAGER_MODIFY_BOOT_CONFIG access right. For + /// more information, see Service Security and Access Rights. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsvc/nf-winsvc-notifybootconfigstatus + // BOOL NotifyBootConfigStatus( BOOL BootAcceptable ); + [DllImport(Lib.AdvApi32, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winsvc.h", MSDNShortId = "0b2b9cd0-f897-4681-9e99-5d0bed986112")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool NotifyBootConfigStatus([MarshalAs(UnmanagedType.Bool)] bool BootAcceptable); + /// /// Enables an application to receive notification when the specified service is created or deleted or when its status changes. /// diff --git a/UnitTests/PInvoke/Security/AdvApi32/AppMgmtTests.cs b/UnitTests/PInvoke/Security/AdvApi32/AppMgmtTests.cs new file mode 100644 index 00000000..f9b779a3 --- /dev/null +++ b/UnitTests/PInvoke/Security/AdvApi32/AppMgmtTests.cs @@ -0,0 +1,38 @@ +using NUnit.Framework; +using System; +using System.Linq; +using System.Security.Principal; +using Vanara.InteropServices; +using static Vanara.PInvoke.AdvApi32; + +namespace Vanara.PInvoke.Tests +{ + [TestFixture()] + public class AppMgmtTests + { + [Test] + public void GetLocalManagedApplicationsTest() + { + var l = GetLocalManagedApplications(true).ToArray(); + TestContext.WriteLine("; ", l.Select(i => i.pszDeploymentName)); + l = GetLocalManagedApplications(false).ToArray(); + TestContext.WriteLine("; ", l.Select(i => i.pszDeploymentName)); + } + + [Test] + public void GetManagedApplicationCategoriesTest() + { + var l = GetManagedApplicationCategories().ToArray(); + TestContext.WriteLine("; ", l.Select(i => i.pszDescription)); + Assert.That(l, Is.Not.Empty); + } + + [Test] + public void GetManagedApplicationsTest() + { + var l = GetManagedApplications(null).ToArray(); + TestContext.WriteLine("; ", l.Select(i => i.pszPackageName)); + Assert.That(l, Is.Not.Empty); + } + } +} \ No newline at end of file