diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d58eab9 --- /dev/null +++ b/.clang-format @@ -0,0 +1,16 @@ +BasedOnStyle: Chromium +IndentWidth: 4 + +# Reference: https://github.com/chromium/chromium/blob/3d90e395a5e87e305e567c097c434549f0d0874e/.clang-format +# Make sure code like: +# BEGIN_MESSAGE_MAP() +# MESSAGE_HANDLER(WidgetHostViewHost_Update, OnUpdate) +# END_MESSAGE_MAP() +# gets correctly indented. +MacroBlockBegin: "^\ +BEGIN_MSG_MAP|\ +BEGIN_MSG_MAP_EX|\ +BEGIN_DLGRESIZE_MAP$" +MacroBlockEnd: "^\ +END_MSG_MAP|\ +END_DLGRESIZE_MAP$" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48a07ae --- /dev/null +++ b/.gitignore @@ -0,0 +1,261 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..217cdbc --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + Windhawk Symbol Helper. + Copyright (C) 2023 Michael Maltsev + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Windhawk Symbol Helper Copyright (C) 2023 Michael Maltsev + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/MainDlg.cpp b/MainDlg.cpp new file mode 100644 index 0000000..a4bed70 --- /dev/null +++ b/MainDlg.cpp @@ -0,0 +1,257 @@ +#include "stdafx.h" + +#include "MainDlg.h" + +#include "symbol_enum.h" + +namespace { + +void OpenUrl(HWND hWnd, PCWSTR url) { + if ((INT_PTR)ShellExecute(hWnd, L"open", url, nullptr, nullptr, + SW_SHOWNORMAL) <= 32) { + CString errorMsg; + errorMsg.Format( + L"Failed to open link, you can copy it with Ctrl+C and open it in " + L"a browser manually:\n\n%s", + url); + MessageBox(hWnd, errorMsg, nullptr, MB_ICONHAND); + } +} + +} // namespace + +BOOL CMainDlg::PreTranslateMessage(MSG* pMsg) { + if (m_resultsEdit.PreTranslateMessage(pMsg)) { + return TRUE; + } + + if (m_accelerator && ::TranslateAccelerator(m_hWnd, m_accelerator, pMsg)) { + return TRUE; + } + + return CWindow::IsDialogMessage(pMsg); +} + +BOOL CMainDlg::OnInitDialog(CWindow wndFocus, LPARAM lInitParam) { + // Center the dialog on the screen. + CenterWindow(); + + // Set icons. + HICON hIcon = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, + ::GetSystemMetrics(SM_CXICON), + ::GetSystemMetrics(SM_CYICON)); + SetIcon(hIcon, TRUE); + HICON hIconSmall = AtlLoadIconImage(IDR_MAINFRAME, LR_DEFAULTCOLOR, + ::GetSystemMetrics(SM_CXSMICON), + ::GetSystemMetrics(SM_CYSMICON)); + SetIcon(hIconSmall, FALSE); + + // Bind keys... + m_accelerator = AtlLoadAccelerators(IDR_MAINFRAME); + + // Register object for message filtering and idle updates. + CMessageLoop* pLoop = _Module.GetMessageLoop(); + ATLASSERT(pLoop != NULL); + pLoop->AddMessageFilter(this); + + // Populate values. + CEdit(GetDlgItem(IDC_ENGINE_DIR)) + .SetWindowText(LR"(C:\Program Files\Windhawk\Engine\1.3.1)"); + CEdit(GetDlgItem(IDC_SYMBOLS_DIR)) + .SetWindowText(LR"(C:\ProgramData\Windhawk\Engine\Symbols)"); + CEdit(GetDlgItem(IDC_SYMBOL_SERVER)) + .SetWindowText(LR"(https://msdl.microsoft.com/download/symbols)"); + CEdit(GetDlgItem(IDC_TARGET_EXECUTABLE)) + .SetWindowText(LR"(C:\Windows\Explorer.exe)"); + CButton(GetDlgItem(IDC_UNDECORATED)).SetCheck(BST_CHECKED); + + // Init edit control. + auto resultsPlaceholderControl = GetDlgItem(IDC_RESULTS_PLACEHOLDER); + + CRect rc; + resultsPlaceholderControl.GetClientRect(&rc); + resultsPlaceholderControl.MapWindowPoints(m_hWnd, rc); + m_resultsEdit.Create(m_hWnd, rc, nullptr, + WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | + WS_VSCROLL | WS_HSCROLL, + WS_EX_CLIENTEDGE, IDC_RESULTS); + + CLogFont fontAttributes(AtlGetDefaultGuiFont()); + wcscpy_s(fontAttributes.lfFaceName, L"Consolas"); + m_resultsEditFont = fontAttributes.CreateFontIndirect(); + m_resultsEdit.SetFont(m_resultsEditFont); + + // Init resizing. + DlgResize_Init(); + + return TRUE; +} + +void CMainDlg::OnDestroy() { + m_enumSymbolsThread.reset(); + + PostQuitMessage(0); +} + +void CMainDlg::OnAppAbout(UINT uNotifyCode, int nID, CWindow wndCtl) { + PCWSTR content = + L"A tool to get symbols from executables the same way Windhawk mods do " + L"with the symbols API.\n\n" + L"The tool was created to help with Windhawk mod development.\n\n" + L"Windhawk can be downloaded at windhawk.net.\n\n" + L"Compiled at " __DATE__ " " __TIME__ "\n\n"; + + TASKDIALOGCONFIG taskDialogConfig{ + .cbSize = sizeof(taskDialogConfig), + .hwndParent = m_hWnd, + .hInstance = _Module.GetModuleInstance(), + .dwFlags = TDF_ENABLE_HYPERLINKS | TDF_ALLOW_DIALOG_CANCELLATION | + TDF_POSITION_RELATIVE_TO_WINDOW, + .pszWindowTitle = L"About", + .pszMainIcon = MAKEINTRESOURCE(IDR_MAINFRAME), + .pszMainInstruction = L"Windhawk Symbol Helper", + .pszContent = content, + .pfCallback = [](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, + LONG_PTR lpRefData) -> HRESULT { + switch (msg) { + case TDN_HYPERLINK_CLICKED: + OpenUrl(hwnd, (PCWSTR)lParam); + break; + } + + return S_OK; + }, + }; + + ::TaskDialogIndirect(&taskDialogConfig, nullptr, nullptr, nullptr); +} + +void CMainDlg::OnOK(UINT uNotifyCode, int nID, CWindow wndCtl) { + if (m_enumSymbolsThread) { + m_enumSymbolsThread->request_stop(); + GetDlgItem(IDOK).EnableWindow(FALSE); + return; + } + + struct { + CString engineDir; + CString symbolsDir; + CString symbolServer; + CString targetExecutable; + bool undecorated; + bool decorated; + bool log; + } threadParams; + + GetDlgItemText(IDC_ENGINE_DIR, threadParams.engineDir); + GetDlgItemText(IDC_SYMBOLS_DIR, threadParams.symbolsDir); + GetDlgItemText(IDC_SYMBOL_SERVER, threadParams.symbolServer); + GetDlgItemText(IDC_TARGET_EXECUTABLE, threadParams.targetExecutable); + threadParams.undecorated = + CButton(GetDlgItem(IDC_UNDECORATED)).GetCheck() != BST_UNCHECKED; + threadParams.decorated = + CButton(GetDlgItem(IDC_DECORATED)).GetCheck() != BST_UNCHECKED; + threadParams.log = CButton(GetDlgItem(IDC_LOG)).GetCheck() != BST_UNCHECKED; + + SetDlgItemText(IDOK, L"Cancel"); + + m_enumSymbolsThread = std::jthread([threadParams = std::move(threadParams), + &enumSymbolsResult = + m_enumSymbolsResult, + hWnd = + m_hWnd](std::stop_token stopToken) { + try { + CStringA logOutput; + CString result; + int count = 0; + + { + SymbolEnum::Callbacks callbacks{ + .queryCancel = + [&stopToken]() { return stopToken.stop_requested(); }, + .notifyProgress = + [hWnd](int progress) { + CWindow(hWnd).PostMessage(UWM_PROGRESS, + (WPARAM)progress); + }, + }; + + if (threadParams.log) { + callbacks.notifyLog = [&logOutput](PCSTR message) { + logOutput += message; + logOutput += "\r\n"; + }; + } + + SymbolEnum symbolEnum(threadParams.targetExecutable.GetString(), + 0, threadParams.engineDir.GetString(), + threadParams.symbolsDir.GetString(), + threadParams.symbolServer.GetString(), + callbacks); + + while (auto iter = symbolEnum.GetNextSymbol(false)) { + if (stopToken.stop_requested()) { + throw std::runtime_error("Cancelled"); + } + + CString addressStr; + addressStr.Format(L"%p", iter->address); + + if (threadParams.undecorated) { + result += L"["; + result += addressStr; + result += L"] "; + result += iter->name; + result += L"\r\n"; + } + + if (threadParams.decorated) { + result += L"["; + result += addressStr; + result += L"] "; + result += iter->nameDecorated; + result += L"\r\n"; + } + + count++; + } + } + + enumSymbolsResult.Format(L"Found %d symbols\r\n%S%s", count, + logOutput.GetString(), result.GetString()); + } catch (const std::exception& e) { + enumSymbolsResult.Format(L"Error: %S\r\n", e.what()); + } + + CWindow(hWnd).PostMessage(UWM_ENUM_SYMBOLS_DONE); + }); +} + +void CMainDlg::OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl) { + DestroyWindow(); +} + +LRESULT CMainDlg::OnProgress(UINT uMsg, WPARAM wParam, LPARAM lParam) { + int progress = (int)wParam; + + CString text; + text.Format(L"[%d%%] Cancel", progress); + + SetDlgItemText(IDOK, text); + + return 0; +} + +LRESULT CMainDlg::OnEnumSymbolsDone(UINT uMsg, WPARAM wParam, LPARAM lParam) { + m_enumSymbolsThread.reset(); + + SetDlgItemText(IDC_RESULTS, m_enumSymbolsResult); + m_enumSymbolsResult.Empty(); + + SetDlgItemText(IDOK, L"Get &symbols"); + GetDlgItem(IDOK).EnableWindow(TRUE); + + return 0; +} diff --git a/MainDlg.h b/MainDlg.h new file mode 100644 index 0000000..d697616 --- /dev/null +++ b/MainDlg.h @@ -0,0 +1,62 @@ +#pragma once + +#include "resource.h" +#include "view.h" + +class CMainDlg : public CDialogImpl, + public CMessageFilter, + public CDialogResize { + public: + enum { IDD = IDD_MAINDLG }; + + enum { + UWM_PROGRESS = WM_APP, + UWM_ENUM_SYMBOLS_DONE, + }; + + BEGIN_DLGRESIZE_MAP(CMainDlg) + DLGRESIZE_CONTROL(IDC_STATIC_ENGINE_DIR, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_ENGINE_DIR, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_STATIC_SYMBOLS_DIR, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_SYMBOLS_DIR, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_STATIC_SYMBOL_SERVER, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_SYMBOL_SERVER, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_STATIC_TARGET_EXECUTABLE, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_TARGET_EXECUTABLE, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_STATIC_RESULTS, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_RESULTS, DLSZ_SIZE_X | DLSZ_SIZE_Y) + DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_Y) + DLGRESIZE_CONTROL(ID_APP_ABOUT, DLSZ_CENTER_X | DLSZ_MOVE_Y) + DLGRESIZE_CONTROL(IDCANCEL, DLSZ_MOVE_X | DLSZ_MOVE_Y) + END_DLGRESIZE_MAP() + + private: + BEGIN_MSG_MAP(CMainDlg) + CHAIN_MSG_MAP(CDialogResize) + MSG_WM_INITDIALOG(OnInitDialog) + MSG_WM_DESTROY(OnDestroy) + COMMAND_ID_HANDLER_EX(ID_APP_ABOUT, OnAppAbout) + COMMAND_ID_HANDLER_EX(IDOK, OnOK) + COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel) + MESSAGE_HANDLER_EX(UWM_PROGRESS, OnProgress) + MESSAGE_HANDLER_EX(UWM_ENUM_SYMBOLS_DONE, OnEnumSymbolsDone) + CHAIN_COMMANDS_MEMBER(m_resultsEdit) + END_MSG_MAP() + + BOOL PreTranslateMessage(MSG* pMsg) override; + + BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam); + void OnDestroy(); + void OnAppAbout(UINT uNotifyCode, int nID, CWindow wndCtl); + void OnOK(UINT uNotifyCode, int nID, CWindow wndCtl); + void OnCancel(UINT uNotifyCode, int nID, CWindow wndCtl); + LRESULT OnProgress(UINT uMsg, WPARAM wParam, LPARAM lParam); + LRESULT OnEnumSymbolsDone(UINT uMsg, WPARAM wParam, LPARAM lParam); + + HACCEL m_accelerator = nullptr; + CEditView m_resultsEdit; + CFont m_resultsEditFont; + + std::optional m_enumSymbolsThread; + CString m_enumSymbolsResult; +}; diff --git a/README.md b/README.md new file mode 100644 index 0000000..3d70b68 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Windhawk Symbol Helper + +A tool to get symbols from executables the same way Windhawk mods do with the +symbols API. + +The tool was created to help with Windhawk mod development. + +For more information about Windhawk, visit +[windhawk.net](https://windhawk.net/). + +![Screenshot](screenshot.png) diff --git a/finddlg.h b/finddlg.h new file mode 100644 index 0000000..811babb --- /dev/null +++ b/finddlg.h @@ -0,0 +1,71 @@ + +#ifndef __FindReplaceDialogWithMessageFilter_h__ +#define __FindReplaceDialogWithMessageFilter_h__ + +#pragma once + +#ifndef __cplusplus + #error ATL requires C++ compilation (use a .cpp suffix) +#endif + +#ifndef __ATLAPP_H__ + #error FindReplaceDialogWithMessageFilter.h requires atlapp.h to be included first +#endif + +#ifndef __ATLWIN_H__ + #error FindReplaceDialogWithMessageFilter.h requires atlwin.h to be included first +#endif + +class CFindReplaceDialogWithMessageFilter : + public CFindReplaceDialogImpl, + public CMessageFilter +{ +protected: + CMessageLoop* m_messageLoop; + +public: + CFindReplaceDialogWithMessageFilter(CMessageLoop* messageLoop) : + m_messageLoop(messageLoop) + { + } + +public: + BOOL PreTranslateMessage(MSG* pMsg) + { + HWND hWndFocus = ::GetFocus(); + if((m_hWnd == hWndFocus) || this->IsChild(hWndFocus)) + return this->IsDialogMessage(pMsg); + + return FALSE; + } + + virtual void OnFinalMessage(HWND /*hWnd*/) + { + delete this; + } + + BEGIN_MSG_MAP(CFindReplaceDialogWithMessageFilter) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + END_MSG_MAP() + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_messageLoop) + m_messageLoop->AddMessageFilter(this); + + bHandled = FALSE; + return 0; + } + + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) + { + if(m_messageLoop) + m_messageLoop->RemoveMessageFilter(this); + + bHandled = FALSE; + return 0; + } +}; + +#endif //__FindReplaceDialogWithMessageFilter_h__ diff --git a/libraries/dia/cvconst.h b/libraries/dia/cvconst.h new file mode 100644 index 0000000..a3445d1 --- /dev/null +++ b/libraries/dia/cvconst.h @@ -0,0 +1,4109 @@ +// cvconst.h - codeview constant definitions +//----------------------------------------------------------------- +// +// Copyright Microsoft Corporation. All Rights Reserved. +// +//--------------------------------------------------------------- +#ifndef _CVCONST_H_ +#define _CVCONST_H_ + + + +// Enumeration for function call type + + +typedef enum CV_call_e +{ + CV_CALL_NEAR_C = 0x00, // near right to left push, caller pops stack + CV_CALL_FAR_C = 0x01, // far right to left push, caller pops stack + CV_CALL_NEAR_PASCAL = 0x02, // near left to right push, callee pops stack + CV_CALL_FAR_PASCAL = 0x03, // far left to right push, callee pops stack + CV_CALL_NEAR_FAST = 0x04, // near left to right push with regs, callee pops stack + CV_CALL_FAR_FAST = 0x05, // far left to right push with regs, callee pops stack + CV_CALL_SKIPPED = 0x06, // skipped (unused) call index + CV_CALL_NEAR_STD = 0x07, // near standard call + CV_CALL_FAR_STD = 0x08, // far standard call + CV_CALL_NEAR_SYS = 0x09, // near sys call + CV_CALL_FAR_SYS = 0x0a, // far sys call + CV_CALL_THISCALL = 0x0b, // this call (this passed in register) + CV_CALL_MIPSCALL = 0x0c, // Mips call + CV_CALL_GENERIC = 0x0d, // Generic call sequence + CV_CALL_ALPHACALL = 0x0e, // Alpha call + CV_CALL_PPCCALL = 0x0f, // PPC call + CV_CALL_SHCALL = 0x10, // Hitachi SuperH call + CV_CALL_ARMCALL = 0x11, // ARM call + CV_CALL_AM33CALL = 0x12, // AM33 call + CV_CALL_TRICALL = 0x13, // TriCore Call + CV_CALL_SH5CALL = 0x14, // Hitachi SuperH-5 call + CV_CALL_M32RCALL = 0x15, // M32R Call + CV_CALL_CLRCALL = 0x16, // clr call + CV_CALL_INLINE = 0x17, // Marker for routines always inlined and thus lacking a convention + CV_CALL_NEAR_VECTOR = 0x18, // near left to right push with regs, callee pops stack + CV_CALL_SWIFT = 0x19, // Swift calling convention + CV_CALL_RESERVED = 0x20 // first unused call enumeration + + // Do NOT add any more machine specific conventions. This is to be used for + // calling conventions in the source only (e.g. __cdecl, __stdcall). +} CV_call_e; + + +// Values for the access protection of class attributes + + +typedef enum CV_access_e +{ + CV_private = 1, + CV_protected = 2, + CV_public = 3 +} CV_access_e; + + +typedef enum THUNK_ORDINAL +{ + THUNK_ORDINAL_NOTYPE, // standard thunk + THUNK_ORDINAL_ADJUSTOR, // "this" adjustor thunk + THUNK_ORDINAL_VCALL, // virtual call thunk + THUNK_ORDINAL_PCODE, // pcode thunk + THUNK_ORDINAL_LOAD, // thunk which loads the address to jump to + // via unknown means... + + // trampoline thunk ordinals - only for use in Trampoline thunk symbols + + THUNK_ORDINAL_TRAMP_INCREMENTAL, + THUNK_ORDINAL_TRAMP_BRANCHISLAND, + THUNK_ORDINAL_TRAMP_STRICTICF, +} THUNK_ORDINAL; + + +enum CV_SourceChksum_t +{ + CHKSUM_TYPE_NONE = 0, // indicates no checksum is available + CHKSUM_TYPE_MD5, + CHKSUM_TYPE_SHA1, + CHKSUM_TYPE_SHA_256, +}; + +// +// DIA enums +// + +enum SymTagEnum +{ + SymTagNull, + SymTagExe, + SymTagCompiland, + SymTagCompilandDetails, + SymTagCompilandEnv, + SymTagFunction, + SymTagBlock, + SymTagData, + SymTagAnnotation, + SymTagLabel, + SymTagPublicSymbol, + SymTagUDT, + SymTagEnum, + SymTagFunctionType, + SymTagPointerType, + SymTagArrayType, + SymTagBaseType, + SymTagTypedef, + SymTagBaseClass, + SymTagFriend, + SymTagFunctionArgType, + SymTagFuncDebugStart, + SymTagFuncDebugEnd, + SymTagUsingNamespace, + SymTagVTableShape, + SymTagVTable, + SymTagCustom, + SymTagThunk, + SymTagCustomType, + SymTagManagedType, + SymTagDimension, + SymTagCallSite, + SymTagInlineSite, + SymTagBaseInterface, + SymTagVectorType, + SymTagMatrixType, + SymTagHLSLType, + SymTagCaller, + SymTagCallee, + SymTagExport, + SymTagHeapAllocationSite, + SymTagCoffGroup, + SymTagInlinee, + SymTagMax +}; + +enum LocationType +{ + LocIsNull, + LocIsStatic, + LocIsTLS, + LocIsRegRel, + LocIsThisRel, + LocIsEnregistered, + LocIsBitField, + LocIsSlot, + LocIsIlRel, + LocInMetaData, + LocIsConstant, + LocIsRegRelAliasIndir, + LocTypeMax +}; + +enum DataKind +{ + DataIsUnknown, + DataIsLocal, + DataIsStaticLocal, + DataIsParam, + DataIsObjectPtr, + DataIsFileStatic, + DataIsGlobal, + DataIsMember, + DataIsStaticMember, + DataIsConstant +}; + +enum UdtKind +{ + UdtStruct, + UdtClass, + UdtUnion, + UdtInterface +}; + +enum BasicType +{ + btNoType = 0, + btVoid = 1, + btChar = 2, + btWChar = 3, + btInt = 6, + btUInt = 7, + btFloat = 8, + btBCD = 9, + btBool = 10, + btLong = 13, + btULong = 14, + btCurrency = 25, + btDate = 26, + btVariant = 27, + btComplex = 28, + btBit = 29, + btBSTR = 30, + btHresult = 31, + btChar16 = 32, // char16_t + btChar32 = 33, // char32_t + btChar8 = 34, // char8_t +}; + + +// enumeration for type modifier values + +typedef enum CV_modifier_e +{ + // 0x0000 - 0x01ff - Reserved. + + CV_MOD_INVALID = 0x0000, + + // Standard modifiers. + + CV_MOD_CONST = 0x0001, + CV_MOD_VOLATILE = 0x0002, + CV_MOD_UNALIGNED = 0x0003, + + // 0x0200 - 0x03ff - HLSL modifiers. + + CV_MOD_HLSL_UNIFORM = 0x0200, + CV_MOD_HLSL_LINE = 0x0201, + CV_MOD_HLSL_TRIANGLE = 0x0202, + CV_MOD_HLSL_LINEADJ = 0x0203, + CV_MOD_HLSL_TRIANGLEADJ = 0x0204, + CV_MOD_HLSL_LINEAR = 0x0205, + CV_MOD_HLSL_CENTROID = 0x0206, + CV_MOD_HLSL_CONSTINTERP = 0x0207, + CV_MOD_HLSL_NOPERSPECTIVE = 0x0208, + CV_MOD_HLSL_SAMPLE = 0x0209, + CV_MOD_HLSL_CENTER = 0x020a, + CV_MOD_HLSL_SNORM = 0x020b, + CV_MOD_HLSL_UNORM = 0x020c, + CV_MOD_HLSL_PRECISE = 0x020d, + CV_MOD_HLSL_UAV_GLOBALLY_COHERENT = 0x020e, + + // 0x0400 - 0xffff - Unused. + +} CV_modifier_e; + + +// built-in type kinds + + +typedef enum CV_builtin_e +{ + // 0x0000 - 0x01ff - Reserved. + CV_BI_INVALID = 0x0000, + + // 0x0200 - 0x03ff - HLSL types. + + CV_BI_HLSL_INTERFACE_POINTER = 0x0200, + CV_BI_HLSL_TEXTURE1D = 0x0201, + CV_BI_HLSL_TEXTURE1D_ARRAY = 0x0202, + CV_BI_HLSL_TEXTURE2D = 0x0203, + CV_BI_HLSL_TEXTURE2D_ARRAY = 0x0204, + CV_BI_HLSL_TEXTURE3D = 0x0205, + CV_BI_HLSL_TEXTURECUBE = 0x0206, + CV_BI_HLSL_TEXTURECUBE_ARRAY = 0x0207, + CV_BI_HLSL_TEXTURE2DMS = 0x0208, + CV_BI_HLSL_TEXTURE2DMS_ARRAY = 0x0209, + CV_BI_HLSL_SAMPLER = 0x020a, + CV_BI_HLSL_SAMPLERCOMPARISON = 0x020b, + CV_BI_HLSL_BUFFER = 0x020c, + CV_BI_HLSL_POINTSTREAM = 0x020d, + CV_BI_HLSL_LINESTREAM = 0x020e, + CV_BI_HLSL_TRIANGLESTREAM = 0x020f, + CV_BI_HLSL_INPUTPATCH = 0x0210, + CV_BI_HLSL_OUTPUTPATCH = 0x0211, + CV_BI_HLSL_RWTEXTURE1D = 0x0212, + CV_BI_HLSL_RWTEXTURE1D_ARRAY = 0x0213, + CV_BI_HLSL_RWTEXTURE2D = 0x0214, + CV_BI_HLSL_RWTEXTURE2D_ARRAY = 0x0215, + CV_BI_HLSL_RWTEXTURE3D = 0x0216, + CV_BI_HLSL_RWBUFFER = 0x0217, + CV_BI_HLSL_BYTEADDRESS_BUFFER = 0x0218, + CV_BI_HLSL_RWBYTEADDRESS_BUFFER = 0x0219, + CV_BI_HLSL_STRUCTURED_BUFFER = 0x021a, + CV_BI_HLSL_RWSTRUCTURED_BUFFER = 0x021b, + CV_BI_HLSL_APPEND_STRUCTURED_BUFFER = 0x021c, + CV_BI_HLSL_CONSUME_STRUCTURED_BUFFER= 0x021d, + CV_BI_HLSL_MIN8FLOAT = 0x021e, + CV_BI_HLSL_MIN10FLOAT = 0x021f, + CV_BI_HLSL_MIN16FLOAT = 0x0220, + CV_BI_HLSL_MIN12INT = 0x0221, + CV_BI_HLSL_MIN16INT = 0x0222, + CV_BI_HLSL_MIN16UINT = 0x0223, + CV_BI_HLSL_CONSTANT_BUFFER = 0x0224, + + // 0x0400 - 0xffff - Unused. + +} CV_builtin_e; + + +// enum describing the compile flag source language + + +typedef enum CV_CFL_LANG +{ + CV_CFL_C = 0x00, + CV_CFL_CXX = 0x01, + CV_CFL_FORTRAN = 0x02, + CV_CFL_MASM = 0x03, + CV_CFL_PASCAL = 0x04, + CV_CFL_BASIC = 0x05, + CV_CFL_COBOL = 0x06, + CV_CFL_LINK = 0x07, + CV_CFL_CVTRES = 0x08, + CV_CFL_CVTPGD = 0x09, + CV_CFL_CSHARP = 0x0A, // C# + CV_CFL_VB = 0x0B, // Visual Basic + CV_CFL_ILASM = 0x0C, // IL (as in CLR) ASM + CV_CFL_JAVA = 0x0D, + CV_CFL_JSCRIPT = 0x0E, + CV_CFL_MSIL = 0x0F, // Unknown MSIL (LTCG of .NETMODULE) + CV_CFL_HLSL = 0x10, // High Level Shader Language + CV_CFL_OBJC = 0x11, // Objective-C + CV_CFL_OBJCXX = 0x12, // Objective-C++ + CV_CFL_SWIFT = 0x13, // Swift +} CV_CFL_LANG; + + +// enum describing target processor + + +typedef enum CV_CPU_TYPE_e +{ + CV_CFL_8080 = 0x00, + CV_CFL_8086 = 0x01, + CV_CFL_80286 = 0x02, + CV_CFL_80386 = 0x03, + CV_CFL_80486 = 0x04, + CV_CFL_PENTIUM = 0x05, + CV_CFL_PENTIUMII = 0x06, + CV_CFL_PENTIUMPRO = CV_CFL_PENTIUMII, + CV_CFL_PENTIUMIII = 0x07, + CV_CFL_MIPS = 0x10, + CV_CFL_MIPSR4000 = CV_CFL_MIPS, // don't break current code + CV_CFL_MIPS16 = 0x11, + CV_CFL_MIPS32 = 0x12, + CV_CFL_MIPS64 = 0x13, + CV_CFL_MIPSI = 0x14, + CV_CFL_MIPSII = 0x15, + CV_CFL_MIPSIII = 0x16, + CV_CFL_MIPSIV = 0x17, + CV_CFL_MIPSV = 0x18, + CV_CFL_M68000 = 0x20, + CV_CFL_M68010 = 0x21, + CV_CFL_M68020 = 0x22, + CV_CFL_M68030 = 0x23, + CV_CFL_M68040 = 0x24, + CV_CFL_ALPHA = 0x30, + CV_CFL_ALPHA_21064 = 0x30, + CV_CFL_ALPHA_21164 = 0x31, + CV_CFL_ALPHA_21164A = 0x32, + CV_CFL_ALPHA_21264 = 0x33, + CV_CFL_ALPHA_21364 = 0x34, + CV_CFL_PPC601 = 0x40, + CV_CFL_PPC603 = 0x41, + CV_CFL_PPC604 = 0x42, + CV_CFL_PPC620 = 0x43, + CV_CFL_PPCFP = 0x44, + CV_CFL_PPCBE = 0x45, + CV_CFL_SH3 = 0x50, + CV_CFL_SH3E = 0x51, + CV_CFL_SH3DSP = 0x52, + CV_CFL_SH4 = 0x53, + CV_CFL_SHMEDIA = 0x54, + CV_CFL_ARM3 = 0x60, + CV_CFL_ARM4 = 0x61, + CV_CFL_ARM4T = 0x62, + CV_CFL_ARM5 = 0x63, + CV_CFL_ARM5T = 0x64, + CV_CFL_ARM6 = 0x65, + CV_CFL_ARM_XMAC = 0x66, + CV_CFL_ARM_WMMX = 0x67, + CV_CFL_ARM7 = 0x68, + CV_CFL_OMNI = 0x70, + CV_CFL_IA64 = 0x80, + CV_CFL_IA64_1 = 0x80, + CV_CFL_IA64_2 = 0x81, + CV_CFL_CEE = 0x90, + CV_CFL_AM33 = 0xA0, + CV_CFL_M32R = 0xB0, + CV_CFL_TRICORE = 0xC0, + CV_CFL_X64 = 0xD0, + CV_CFL_AMD64 = CV_CFL_X64, + CV_CFL_EBC = 0xE0, + CV_CFL_THUMB = 0xF0, + CV_CFL_ARMNT = 0xF4, + CV_CFL_ARM64 = 0xF6, + CV_CFL_HYBRID_X86_ARM64 = 0xF7, + CV_CFL_ARM64EC = 0xF8, + CV_CFL_ARM64X = 0xF9, + CV_CFL_D3D11_SHADER = 0x100, +} CV_CPU_TYPE_e; + +typedef enum CV_HREG_e +{ + // Register subset shared by all processor types, + // must not overlap with any of the ranges below, hence the high values + + CV_ALLREG_ERR = 30000, + CV_ALLREG_TEB = 30001, + CV_ALLREG_TIMER = 30002, + CV_ALLREG_EFAD1 = 30003, + CV_ALLREG_EFAD2 = 30004, + CV_ALLREG_EFAD3 = 30005, + CV_ALLREG_VFRAME= 30006, + CV_ALLREG_HANDLE= 30007, + CV_ALLREG_PARAMS= 30008, + CV_ALLREG_LOCALS= 30009, + CV_ALLREG_TID = 30010, + CV_ALLREG_ENV = 30011, + CV_ALLREG_CMDLN = 30012, + + + // Register set for the Intel 80x86 and ix86 processor series + // (plus PCODE registers) + + CV_REG_NONE = 0, + CV_REG_AL = 1, + CV_REG_CL = 2, + CV_REG_DL = 3, + CV_REG_BL = 4, + CV_REG_AH = 5, + CV_REG_CH = 6, + CV_REG_DH = 7, + CV_REG_BH = 8, + CV_REG_AX = 9, + CV_REG_CX = 10, + CV_REG_DX = 11, + CV_REG_BX = 12, + CV_REG_SP = 13, + CV_REG_BP = 14, + CV_REG_SI = 15, + CV_REG_DI = 16, + CV_REG_EAX = 17, + CV_REG_ECX = 18, + CV_REG_EDX = 19, + CV_REG_EBX = 20, + CV_REG_ESP = 21, + CV_REG_EBP = 22, + CV_REG_ESI = 23, + CV_REG_EDI = 24, + CV_REG_ES = 25, + CV_REG_CS = 26, + CV_REG_SS = 27, + CV_REG_DS = 28, + CV_REG_FS = 29, + CV_REG_GS = 30, + CV_REG_IP = 31, + CV_REG_FLAGS = 32, + CV_REG_EIP = 33, + CV_REG_EFLAGS = 34, + CV_REG_TEMP = 40, // PCODE Temp + CV_REG_TEMPH = 41, // PCODE TempH + CV_REG_QUOTE = 42, // PCODE Quote + CV_REG_PCDR3 = 43, // PCODE reserved + CV_REG_PCDR4 = 44, // PCODE reserved + CV_REG_PCDR5 = 45, // PCODE reserved + CV_REG_PCDR6 = 46, // PCODE reserved + CV_REG_PCDR7 = 47, // PCODE reserved + CV_REG_CR0 = 80, // CR0 -- control registers + CV_REG_CR1 = 81, + CV_REG_CR2 = 82, + CV_REG_CR3 = 83, + CV_REG_CR4 = 84, // Pentium + CV_REG_DR0 = 90, // Debug register + CV_REG_DR1 = 91, + CV_REG_DR2 = 92, + CV_REG_DR3 = 93, + CV_REG_DR4 = 94, + CV_REG_DR5 = 95, + CV_REG_DR6 = 96, + CV_REG_DR7 = 97, + CV_REG_GDTR = 110, + CV_REG_GDTL = 111, + CV_REG_IDTR = 112, + CV_REG_IDTL = 113, + CV_REG_LDTR = 114, + CV_REG_TR = 115, + + CV_REG_PSEUDO1 = 116, + CV_REG_PSEUDO2 = 117, + CV_REG_PSEUDO3 = 118, + CV_REG_PSEUDO4 = 119, + CV_REG_PSEUDO5 = 120, + CV_REG_PSEUDO6 = 121, + CV_REG_PSEUDO7 = 122, + CV_REG_PSEUDO8 = 123, + CV_REG_PSEUDO9 = 124, + + CV_REG_ST0 = 128, + CV_REG_ST1 = 129, + CV_REG_ST2 = 130, + CV_REG_ST3 = 131, + CV_REG_ST4 = 132, + CV_REG_ST5 = 133, + CV_REG_ST6 = 134, + CV_REG_ST7 = 135, + CV_REG_CTRL = 136, + CV_REG_STAT = 137, + CV_REG_TAG = 138, + CV_REG_FPIP = 139, + CV_REG_FPCS = 140, + CV_REG_FPDO = 141, + CV_REG_FPDS = 142, + CV_REG_ISEM = 143, + CV_REG_FPEIP = 144, + CV_REG_FPEDO = 145, + + CV_REG_MM0 = 146, + CV_REG_MM1 = 147, + CV_REG_MM2 = 148, + CV_REG_MM3 = 149, + CV_REG_MM4 = 150, + CV_REG_MM5 = 151, + CV_REG_MM6 = 152, + CV_REG_MM7 = 153, + + CV_REG_XMM0 = 154, // KATMAI registers + CV_REG_XMM1 = 155, + CV_REG_XMM2 = 156, + CV_REG_XMM3 = 157, + CV_REG_XMM4 = 158, + CV_REG_XMM5 = 159, + CV_REG_XMM6 = 160, + CV_REG_XMM7 = 161, + + CV_REG_XMM00 = 162, // KATMAI sub-registers + CV_REG_XMM01 = 163, + CV_REG_XMM02 = 164, + CV_REG_XMM03 = 165, + CV_REG_XMM10 = 166, + CV_REG_XMM11 = 167, + CV_REG_XMM12 = 168, + CV_REG_XMM13 = 169, + CV_REG_XMM20 = 170, + CV_REG_XMM21 = 171, + CV_REG_XMM22 = 172, + CV_REG_XMM23 = 173, + CV_REG_XMM30 = 174, + CV_REG_XMM31 = 175, + CV_REG_XMM32 = 176, + CV_REG_XMM33 = 177, + CV_REG_XMM40 = 178, + CV_REG_XMM41 = 179, + CV_REG_XMM42 = 180, + CV_REG_XMM43 = 181, + CV_REG_XMM50 = 182, + CV_REG_XMM51 = 183, + CV_REG_XMM52 = 184, + CV_REG_XMM53 = 185, + CV_REG_XMM60 = 186, + CV_REG_XMM61 = 187, + CV_REG_XMM62 = 188, + CV_REG_XMM63 = 189, + CV_REG_XMM70 = 190, + CV_REG_XMM71 = 191, + CV_REG_XMM72 = 192, + CV_REG_XMM73 = 193, + + CV_REG_XMM0L = 194, + CV_REG_XMM1L = 195, + CV_REG_XMM2L = 196, + CV_REG_XMM3L = 197, + CV_REG_XMM4L = 198, + CV_REG_XMM5L = 199, + CV_REG_XMM6L = 200, + CV_REG_XMM7L = 201, + + CV_REG_XMM0H = 202, + CV_REG_XMM1H = 203, + CV_REG_XMM2H = 204, + CV_REG_XMM3H = 205, + CV_REG_XMM4H = 206, + CV_REG_XMM5H = 207, + CV_REG_XMM6H = 208, + CV_REG_XMM7H = 209, + + CV_REG_MXCSR = 211, // XMM status register + + CV_REG_EDXEAX = 212, // EDX:EAX pair + + CV_REG_EMM0L = 220, // XMM sub-registers (WNI integer) + CV_REG_EMM1L = 221, + CV_REG_EMM2L = 222, + CV_REG_EMM3L = 223, + CV_REG_EMM4L = 224, + CV_REG_EMM5L = 225, + CV_REG_EMM6L = 226, + CV_REG_EMM7L = 227, + + CV_REG_EMM0H = 228, + CV_REG_EMM1H = 229, + CV_REG_EMM2H = 230, + CV_REG_EMM3H = 231, + CV_REG_EMM4H = 232, + CV_REG_EMM5H = 233, + CV_REG_EMM6H = 234, + CV_REG_EMM7H = 235, + + // do not change the order of these regs, first one must be even too + CV_REG_MM00 = 236, + CV_REG_MM01 = 237, + CV_REG_MM10 = 238, + CV_REG_MM11 = 239, + CV_REG_MM20 = 240, + CV_REG_MM21 = 241, + CV_REG_MM30 = 242, + CV_REG_MM31 = 243, + CV_REG_MM40 = 244, + CV_REG_MM41 = 245, + CV_REG_MM50 = 246, + CV_REG_MM51 = 247, + CV_REG_MM60 = 248, + CV_REG_MM61 = 249, + CV_REG_MM70 = 250, + CV_REG_MM71 = 251, + + CV_REG_YMM0 = 252, // AVX registers + CV_REG_YMM1 = 253, + CV_REG_YMM2 = 254, + CV_REG_YMM3 = 255, + CV_REG_YMM4 = 256, + CV_REG_YMM5 = 257, + CV_REG_YMM6 = 258, + CV_REG_YMM7 = 259, + + CV_REG_YMM0H = 260, + CV_REG_YMM1H = 261, + CV_REG_YMM2H = 262, + CV_REG_YMM3H = 263, + CV_REG_YMM4H = 264, + CV_REG_YMM5H = 265, + CV_REG_YMM6H = 266, + CV_REG_YMM7H = 267, + + CV_REG_YMM0I0 = 268, // AVX integer registers + CV_REG_YMM0I1 = 269, + CV_REG_YMM0I2 = 270, + CV_REG_YMM0I3 = 271, + CV_REG_YMM1I0 = 272, + CV_REG_YMM1I1 = 273, + CV_REG_YMM1I2 = 274, + CV_REG_YMM1I3 = 275, + CV_REG_YMM2I0 = 276, + CV_REG_YMM2I1 = 277, + CV_REG_YMM2I2 = 278, + CV_REG_YMM2I3 = 279, + CV_REG_YMM3I0 = 280, + CV_REG_YMM3I1 = 281, + CV_REG_YMM3I2 = 282, + CV_REG_YMM3I3 = 283, + CV_REG_YMM4I0 = 284, + CV_REG_YMM4I1 = 285, + CV_REG_YMM4I2 = 286, + CV_REG_YMM4I3 = 287, + CV_REG_YMM5I0 = 288, + CV_REG_YMM5I1 = 289, + CV_REG_YMM5I2 = 290, + CV_REG_YMM5I3 = 291, + CV_REG_YMM6I0 = 292, + CV_REG_YMM6I1 = 293, + CV_REG_YMM6I2 = 294, + CV_REG_YMM6I3 = 295, + CV_REG_YMM7I0 = 296, + CV_REG_YMM7I1 = 297, + CV_REG_YMM7I2 = 298, + CV_REG_YMM7I3 = 299, + + CV_REG_YMM0F0 = 300, // AVX floating-point single precise registers + CV_REG_YMM0F1 = 301, + CV_REG_YMM0F2 = 302, + CV_REG_YMM0F3 = 303, + CV_REG_YMM0F4 = 304, + CV_REG_YMM0F5 = 305, + CV_REG_YMM0F6 = 306, + CV_REG_YMM0F7 = 307, + CV_REG_YMM1F0 = 308, + CV_REG_YMM1F1 = 309, + CV_REG_YMM1F2 = 310, + CV_REG_YMM1F3 = 311, + CV_REG_YMM1F4 = 312, + CV_REG_YMM1F5 = 313, + CV_REG_YMM1F6 = 314, + CV_REG_YMM1F7 = 315, + CV_REG_YMM2F0 = 316, + CV_REG_YMM2F1 = 317, + CV_REG_YMM2F2 = 318, + CV_REG_YMM2F3 = 319, + CV_REG_YMM2F4 = 320, + CV_REG_YMM2F5 = 321, + CV_REG_YMM2F6 = 322, + CV_REG_YMM2F7 = 323, + CV_REG_YMM3F0 = 324, + CV_REG_YMM3F1 = 325, + CV_REG_YMM3F2 = 326, + CV_REG_YMM3F3 = 327, + CV_REG_YMM3F4 = 328, + CV_REG_YMM3F5 = 329, + CV_REG_YMM3F6 = 330, + CV_REG_YMM3F7 = 331, + CV_REG_YMM4F0 = 332, + CV_REG_YMM4F1 = 333, + CV_REG_YMM4F2 = 334, + CV_REG_YMM4F3 = 335, + CV_REG_YMM4F4 = 336, + CV_REG_YMM4F5 = 337, + CV_REG_YMM4F6 = 338, + CV_REG_YMM4F7 = 339, + CV_REG_YMM5F0 = 340, + CV_REG_YMM5F1 = 341, + CV_REG_YMM5F2 = 342, + CV_REG_YMM5F3 = 343, + CV_REG_YMM5F4 = 344, + CV_REG_YMM5F5 = 345, + CV_REG_YMM5F6 = 346, + CV_REG_YMM5F7 = 347, + CV_REG_YMM6F0 = 348, + CV_REG_YMM6F1 = 349, + CV_REG_YMM6F2 = 350, + CV_REG_YMM6F3 = 351, + CV_REG_YMM6F4 = 352, + CV_REG_YMM6F5 = 353, + CV_REG_YMM6F6 = 354, + CV_REG_YMM6F7 = 355, + CV_REG_YMM7F0 = 356, + CV_REG_YMM7F1 = 357, + CV_REG_YMM7F2 = 358, + CV_REG_YMM7F3 = 359, + CV_REG_YMM7F4 = 360, + CV_REG_YMM7F5 = 361, + CV_REG_YMM7F6 = 362, + CV_REG_YMM7F7 = 363, + + CV_REG_YMM0D0 = 364, // AVX floating-point double precise registers + CV_REG_YMM0D1 = 365, + CV_REG_YMM0D2 = 366, + CV_REG_YMM0D3 = 367, + CV_REG_YMM1D0 = 368, + CV_REG_YMM1D1 = 369, + CV_REG_YMM1D2 = 370, + CV_REG_YMM1D3 = 371, + CV_REG_YMM2D0 = 372, + CV_REG_YMM2D1 = 373, + CV_REG_YMM2D2 = 374, + CV_REG_YMM2D3 = 375, + CV_REG_YMM3D0 = 376, + CV_REG_YMM3D1 = 377, + CV_REG_YMM3D2 = 378, + CV_REG_YMM3D3 = 379, + CV_REG_YMM4D0 = 380, + CV_REG_YMM4D1 = 381, + CV_REG_YMM4D2 = 382, + CV_REG_YMM4D3 = 383, + CV_REG_YMM5D0 = 384, + CV_REG_YMM5D1 = 385, + CV_REG_YMM5D2 = 386, + CV_REG_YMM5D3 = 387, + CV_REG_YMM6D0 = 388, + CV_REG_YMM6D1 = 389, + CV_REG_YMM6D2 = 390, + CV_REG_YMM6D3 = 391, + CV_REG_YMM7D0 = 392, + CV_REG_YMM7D1 = 393, + CV_REG_YMM7D2 = 394, + CV_REG_YMM7D3 = 395, + + CV_REG_BND0 = 396, // x86 MPX bounds registers + CV_REG_BND1 = 397, + CV_REG_BND2 = 398, + CV_REG_BND3 = 399, + CV_REG_BNDCFGU = 400, + CV_REG_BNDSTATUS = 401, + + CV_REG_ZMM0 = 402, // AVX-512 registers + CV_REG_ZMM1 = 403, + CV_REG_ZMM2 = 404, + CV_REG_ZMM3 = 405, + CV_REG_ZMM4 = 406, + CV_REG_ZMM5 = 407, + CV_REG_ZMM6 = 408, + CV_REG_ZMM7 = 409, + + CV_REG_ZMM0H = 410, + CV_REG_ZMM1H = 411, + CV_REG_ZMM2H = 412, + CV_REG_ZMM3H = 413, + CV_REG_ZMM4H = 414, + CV_REG_ZMM5H = 415, + CV_REG_ZMM6H = 416, + CV_REG_ZMM7H = 417, + + CV_REG_K0 = 418, + CV_REG_K1 = 419, + CV_REG_K2 = 420, + CV_REG_K3 = 421, + CV_REG_K4 = 422, + CV_REG_K5 = 423, + CV_REG_K6 = 424, + CV_REG_K7 = 425, + + CV_REG_SSP = 426, // CET- Shadow Stack Pointer + + // registers for the 68K processors + + CV_R68_D0 = 0, + CV_R68_D1 = 1, + CV_R68_D2 = 2, + CV_R68_D3 = 3, + CV_R68_D4 = 4, + CV_R68_D5 = 5, + CV_R68_D6 = 6, + CV_R68_D7 = 7, + CV_R68_A0 = 8, + CV_R68_A1 = 9, + CV_R68_A2 = 10, + CV_R68_A3 = 11, + CV_R68_A4 = 12, + CV_R68_A5 = 13, + CV_R68_A6 = 14, + CV_R68_A7 = 15, + CV_R68_CCR = 16, + CV_R68_SR = 17, + CV_R68_USP = 18, + CV_R68_MSP = 19, + CV_R68_SFC = 20, + CV_R68_DFC = 21, + CV_R68_CACR = 22, + CV_R68_VBR = 23, + CV_R68_CAAR = 24, + CV_R68_ISP = 25, + CV_R68_PC = 26, + //reserved 27 + CV_R68_FPCR = 28, + CV_R68_FPSR = 29, + CV_R68_FPIAR = 30, + //reserved 31 + CV_R68_FP0 = 32, + CV_R68_FP1 = 33, + CV_R68_FP2 = 34, + CV_R68_FP3 = 35, + CV_R68_FP4 = 36, + CV_R68_FP5 = 37, + CV_R68_FP6 = 38, + CV_R68_FP7 = 39, + //reserved 40 + CV_R68_MMUSR030 = 41, + CV_R68_MMUSR = 42, + CV_R68_URP = 43, + CV_R68_DTT0 = 44, + CV_R68_DTT1 = 45, + CV_R68_ITT0 = 46, + CV_R68_ITT1 = 47, + //reserved 50 + CV_R68_PSR = 51, + CV_R68_PCSR = 52, + CV_R68_VAL = 53, + CV_R68_CRP = 54, + CV_R68_SRP = 55, + CV_R68_DRP = 56, + CV_R68_TC = 57, + CV_R68_AC = 58, + CV_R68_SCC = 59, + CV_R68_CAL = 60, + CV_R68_TT0 = 61, + CV_R68_TT1 = 62, + //reserved 63 + CV_R68_BAD0 = 64, + CV_R68_BAD1 = 65, + CV_R68_BAD2 = 66, + CV_R68_BAD3 = 67, + CV_R68_BAD4 = 68, + CV_R68_BAD5 = 69, + CV_R68_BAD6 = 70, + CV_R68_BAD7 = 71, + CV_R68_BAC0 = 72, + CV_R68_BAC1 = 73, + CV_R68_BAC2 = 74, + CV_R68_BAC3 = 75, + CV_R68_BAC4 = 76, + CV_R68_BAC5 = 77, + CV_R68_BAC6 = 78, + CV_R68_BAC7 = 79, + + // Register set for the MIPS 4000 + + CV_M4_NOREG = CV_REG_NONE, + + CV_M4_IntZERO = 10, /* CPU REGISTER */ + CV_M4_IntAT = 11, + CV_M4_IntV0 = 12, + CV_M4_IntV1 = 13, + CV_M4_IntA0 = 14, + CV_M4_IntA1 = 15, + CV_M4_IntA2 = 16, + CV_M4_IntA3 = 17, + CV_M4_IntT0 = 18, + CV_M4_IntT1 = 19, + CV_M4_IntT2 = 20, + CV_M4_IntT3 = 21, + CV_M4_IntT4 = 22, + CV_M4_IntT5 = 23, + CV_M4_IntT6 = 24, + CV_M4_IntT7 = 25, + CV_M4_IntS0 = 26, + CV_M4_IntS1 = 27, + CV_M4_IntS2 = 28, + CV_M4_IntS3 = 29, + CV_M4_IntS4 = 30, + CV_M4_IntS5 = 31, + CV_M4_IntS6 = 32, + CV_M4_IntS7 = 33, + CV_M4_IntT8 = 34, + CV_M4_IntT9 = 35, + CV_M4_IntKT0 = 36, + CV_M4_IntKT1 = 37, + CV_M4_IntGP = 38, + CV_M4_IntSP = 39, + CV_M4_IntS8 = 40, + CV_M4_IntRA = 41, + CV_M4_IntLO = 42, + CV_M4_IntHI = 43, + + CV_M4_Fir = 50, + CV_M4_Psr = 51, + + CV_M4_FltF0 = 60, /* Floating point registers */ + CV_M4_FltF1 = 61, + CV_M4_FltF2 = 62, + CV_M4_FltF3 = 63, + CV_M4_FltF4 = 64, + CV_M4_FltF5 = 65, + CV_M4_FltF6 = 66, + CV_M4_FltF7 = 67, + CV_M4_FltF8 = 68, + CV_M4_FltF9 = 69, + CV_M4_FltF10 = 70, + CV_M4_FltF11 = 71, + CV_M4_FltF12 = 72, + CV_M4_FltF13 = 73, + CV_M4_FltF14 = 74, + CV_M4_FltF15 = 75, + CV_M4_FltF16 = 76, + CV_M4_FltF17 = 77, + CV_M4_FltF18 = 78, + CV_M4_FltF19 = 79, + CV_M4_FltF20 = 80, + CV_M4_FltF21 = 81, + CV_M4_FltF22 = 82, + CV_M4_FltF23 = 83, + CV_M4_FltF24 = 84, + CV_M4_FltF25 = 85, + CV_M4_FltF26 = 86, + CV_M4_FltF27 = 87, + CV_M4_FltF28 = 88, + CV_M4_FltF29 = 89, + CV_M4_FltF30 = 90, + CV_M4_FltF31 = 91, + CV_M4_FltFsr = 92, + + + // Register set for the ALPHA AXP + + CV_ALPHA_NOREG = CV_REG_NONE, + + CV_ALPHA_FltF0 = 10, // Floating point registers + CV_ALPHA_FltF1 = 11, + CV_ALPHA_FltF2 = 12, + CV_ALPHA_FltF3 = 13, + CV_ALPHA_FltF4 = 14, + CV_ALPHA_FltF5 = 15, + CV_ALPHA_FltF6 = 16, + CV_ALPHA_FltF7 = 17, + CV_ALPHA_FltF8 = 18, + CV_ALPHA_FltF9 = 19, + CV_ALPHA_FltF10 = 20, + CV_ALPHA_FltF11 = 21, + CV_ALPHA_FltF12 = 22, + CV_ALPHA_FltF13 = 23, + CV_ALPHA_FltF14 = 24, + CV_ALPHA_FltF15 = 25, + CV_ALPHA_FltF16 = 26, + CV_ALPHA_FltF17 = 27, + CV_ALPHA_FltF18 = 28, + CV_ALPHA_FltF19 = 29, + CV_ALPHA_FltF20 = 30, + CV_ALPHA_FltF21 = 31, + CV_ALPHA_FltF22 = 32, + CV_ALPHA_FltF23 = 33, + CV_ALPHA_FltF24 = 34, + CV_ALPHA_FltF25 = 35, + CV_ALPHA_FltF26 = 36, + CV_ALPHA_FltF27 = 37, + CV_ALPHA_FltF28 = 38, + CV_ALPHA_FltF29 = 39, + CV_ALPHA_FltF30 = 40, + CV_ALPHA_FltF31 = 41, + + CV_ALPHA_IntV0 = 42, // Integer registers + CV_ALPHA_IntT0 = 43, + CV_ALPHA_IntT1 = 44, + CV_ALPHA_IntT2 = 45, + CV_ALPHA_IntT3 = 46, + CV_ALPHA_IntT4 = 47, + CV_ALPHA_IntT5 = 48, + CV_ALPHA_IntT6 = 49, + CV_ALPHA_IntT7 = 50, + CV_ALPHA_IntS0 = 51, + CV_ALPHA_IntS1 = 52, + CV_ALPHA_IntS2 = 53, + CV_ALPHA_IntS3 = 54, + CV_ALPHA_IntS4 = 55, + CV_ALPHA_IntS5 = 56, + CV_ALPHA_IntFP = 57, + CV_ALPHA_IntA0 = 58, + CV_ALPHA_IntA1 = 59, + CV_ALPHA_IntA2 = 60, + CV_ALPHA_IntA3 = 61, + CV_ALPHA_IntA4 = 62, + CV_ALPHA_IntA5 = 63, + CV_ALPHA_IntT8 = 64, + CV_ALPHA_IntT9 = 65, + CV_ALPHA_IntT10 = 66, + CV_ALPHA_IntT11 = 67, + CV_ALPHA_IntRA = 68, + CV_ALPHA_IntT12 = 69, + CV_ALPHA_IntAT = 70, + CV_ALPHA_IntGP = 71, + CV_ALPHA_IntSP = 72, + CV_ALPHA_IntZERO = 73, + + + CV_ALPHA_Fpcr = 74, // Control registers + CV_ALPHA_Fir = 75, + CV_ALPHA_Psr = 76, + CV_ALPHA_FltFsr = 77, + CV_ALPHA_SoftFpcr = 78, + + // Register Set for Motorola/IBM PowerPC + + /* + ** PowerPC General Registers ( User Level ) + */ + CV_PPC_GPR0 = 1, + CV_PPC_GPR1 = 2, + CV_PPC_GPR2 = 3, + CV_PPC_GPR3 = 4, + CV_PPC_GPR4 = 5, + CV_PPC_GPR5 = 6, + CV_PPC_GPR6 = 7, + CV_PPC_GPR7 = 8, + CV_PPC_GPR8 = 9, + CV_PPC_GPR9 = 10, + CV_PPC_GPR10 = 11, + CV_PPC_GPR11 = 12, + CV_PPC_GPR12 = 13, + CV_PPC_GPR13 = 14, + CV_PPC_GPR14 = 15, + CV_PPC_GPR15 = 16, + CV_PPC_GPR16 = 17, + CV_PPC_GPR17 = 18, + CV_PPC_GPR18 = 19, + CV_PPC_GPR19 = 20, + CV_PPC_GPR20 = 21, + CV_PPC_GPR21 = 22, + CV_PPC_GPR22 = 23, + CV_PPC_GPR23 = 24, + CV_PPC_GPR24 = 25, + CV_PPC_GPR25 = 26, + CV_PPC_GPR26 = 27, + CV_PPC_GPR27 = 28, + CV_PPC_GPR28 = 29, + CV_PPC_GPR29 = 30, + CV_PPC_GPR30 = 31, + CV_PPC_GPR31 = 32, + + /* + ** PowerPC Condition Register ( User Level ) + */ + CV_PPC_CR = 33, + CV_PPC_CR0 = 34, + CV_PPC_CR1 = 35, + CV_PPC_CR2 = 36, + CV_PPC_CR3 = 37, + CV_PPC_CR4 = 38, + CV_PPC_CR5 = 39, + CV_PPC_CR6 = 40, + CV_PPC_CR7 = 41, + + /* + ** PowerPC Floating Point Registers ( User Level ) + */ + CV_PPC_FPR0 = 42, + CV_PPC_FPR1 = 43, + CV_PPC_FPR2 = 44, + CV_PPC_FPR3 = 45, + CV_PPC_FPR4 = 46, + CV_PPC_FPR5 = 47, + CV_PPC_FPR6 = 48, + CV_PPC_FPR7 = 49, + CV_PPC_FPR8 = 50, + CV_PPC_FPR9 = 51, + CV_PPC_FPR10 = 52, + CV_PPC_FPR11 = 53, + CV_PPC_FPR12 = 54, + CV_PPC_FPR13 = 55, + CV_PPC_FPR14 = 56, + CV_PPC_FPR15 = 57, + CV_PPC_FPR16 = 58, + CV_PPC_FPR17 = 59, + CV_PPC_FPR18 = 60, + CV_PPC_FPR19 = 61, + CV_PPC_FPR20 = 62, + CV_PPC_FPR21 = 63, + CV_PPC_FPR22 = 64, + CV_PPC_FPR23 = 65, + CV_PPC_FPR24 = 66, + CV_PPC_FPR25 = 67, + CV_PPC_FPR26 = 68, + CV_PPC_FPR27 = 69, + CV_PPC_FPR28 = 70, + CV_PPC_FPR29 = 71, + CV_PPC_FPR30 = 72, + CV_PPC_FPR31 = 73, + + /* + ** PowerPC Floating Point Status and Control Register ( User Level ) + */ + CV_PPC_FPSCR = 74, + + /* + ** PowerPC Machine State Register ( Supervisor Level ) + */ + CV_PPC_MSR = 75, + + /* + ** PowerPC Segment Registers ( Supervisor Level ) + */ + CV_PPC_SR0 = 76, + CV_PPC_SR1 = 77, + CV_PPC_SR2 = 78, + CV_PPC_SR3 = 79, + CV_PPC_SR4 = 80, + CV_PPC_SR5 = 81, + CV_PPC_SR6 = 82, + CV_PPC_SR7 = 83, + CV_PPC_SR8 = 84, + CV_PPC_SR9 = 85, + CV_PPC_SR10 = 86, + CV_PPC_SR11 = 87, + CV_PPC_SR12 = 88, + CV_PPC_SR13 = 89, + CV_PPC_SR14 = 90, + CV_PPC_SR15 = 91, + + /* + ** For all of the special purpose registers add 100 to the SPR# that the + ** Motorola/IBM documentation gives with the exception of any imaginary + ** registers. + */ + + /* + ** PowerPC Special Purpose Registers ( User Level ) + */ + CV_PPC_PC = 99, // PC (imaginary register) + + CV_PPC_MQ = 100, // MPC601 + CV_PPC_XER = 101, + CV_PPC_RTCU = 104, // MPC601 + CV_PPC_RTCL = 105, // MPC601 + CV_PPC_LR = 108, + CV_PPC_CTR = 109, + + CV_PPC_COMPARE = 110, // part of XER (internal to the debugger only) + CV_PPC_COUNT = 111, // part of XER (internal to the debugger only) + + /* + ** PowerPC Special Purpose Registers ( Supervisor Level ) + */ + CV_PPC_DSISR = 118, + CV_PPC_DAR = 119, + CV_PPC_DEC = 122, + CV_PPC_SDR1 = 125, + CV_PPC_SRR0 = 126, + CV_PPC_SRR1 = 127, + CV_PPC_SPRG0 = 372, + CV_PPC_SPRG1 = 373, + CV_PPC_SPRG2 = 374, + CV_PPC_SPRG3 = 375, + CV_PPC_ASR = 280, // 64-bit implementations only + CV_PPC_EAR = 382, + CV_PPC_PVR = 287, + CV_PPC_BAT0U = 628, + CV_PPC_BAT0L = 629, + CV_PPC_BAT1U = 630, + CV_PPC_BAT1L = 631, + CV_PPC_BAT2U = 632, + CV_PPC_BAT2L = 633, + CV_PPC_BAT3U = 634, + CV_PPC_BAT3L = 635, + CV_PPC_DBAT0U = 636, + CV_PPC_DBAT0L = 637, + CV_PPC_DBAT1U = 638, + CV_PPC_DBAT1L = 639, + CV_PPC_DBAT2U = 640, + CV_PPC_DBAT2L = 641, + CV_PPC_DBAT3U = 642, + CV_PPC_DBAT3L = 643, + + /* + ** PowerPC Special Purpose Registers Implementation Dependent ( Supervisor Level ) + */ + + /* + ** Doesn't appear that IBM/Motorola has finished defining these. + */ + + CV_PPC_PMR0 = 1044, // MPC620, + CV_PPC_PMR1 = 1045, // MPC620, + CV_PPC_PMR2 = 1046, // MPC620, + CV_PPC_PMR3 = 1047, // MPC620, + CV_PPC_PMR4 = 1048, // MPC620, + CV_PPC_PMR5 = 1049, // MPC620, + CV_PPC_PMR6 = 1050, // MPC620, + CV_PPC_PMR7 = 1051, // MPC620, + CV_PPC_PMR8 = 1052, // MPC620, + CV_PPC_PMR9 = 1053, // MPC620, + CV_PPC_PMR10 = 1054, // MPC620, + CV_PPC_PMR11 = 1055, // MPC620, + CV_PPC_PMR12 = 1056, // MPC620, + CV_PPC_PMR13 = 1057, // MPC620, + CV_PPC_PMR14 = 1058, // MPC620, + CV_PPC_PMR15 = 1059, // MPC620, + + CV_PPC_DMISS = 1076, // MPC603 + CV_PPC_DCMP = 1077, // MPC603 + CV_PPC_HASH1 = 1078, // MPC603 + CV_PPC_HASH2 = 1079, // MPC603 + CV_PPC_IMISS = 1080, // MPC603 + CV_PPC_ICMP = 1081, // MPC603 + CV_PPC_RPA = 1082, // MPC603 + + CV_PPC_HID0 = 1108, // MPC601, MPC603, MPC620 + CV_PPC_HID1 = 1109, // MPC601 + CV_PPC_HID2 = 1110, // MPC601, MPC603, MPC620 ( IABR ) + CV_PPC_HID3 = 1111, // Not Defined + CV_PPC_HID4 = 1112, // Not Defined + CV_PPC_HID5 = 1113, // MPC601, MPC604, MPC620 ( DABR ) + CV_PPC_HID6 = 1114, // Not Defined + CV_PPC_HID7 = 1115, // Not Defined + CV_PPC_HID8 = 1116, // MPC620 ( BUSCSR ) + CV_PPC_HID9 = 1117, // MPC620 ( L2CSR ) + CV_PPC_HID10 = 1118, // Not Defined + CV_PPC_HID11 = 1119, // Not Defined + CV_PPC_HID12 = 1120, // Not Defined + CV_PPC_HID13 = 1121, // MPC604 ( HCR ) + CV_PPC_HID14 = 1122, // Not Defined + CV_PPC_HID15 = 1123, // MPC601, MPC604, MPC620 ( PIR ) + + // + // JAVA VM registers + // + + CV_JAVA_PC = 1, + + // + // Register set for the Hitachi SH3 + // + + CV_SH3_NOREG = CV_REG_NONE, + + CV_SH3_IntR0 = 10, // CPU REGISTER + CV_SH3_IntR1 = 11, + CV_SH3_IntR2 = 12, + CV_SH3_IntR3 = 13, + CV_SH3_IntR4 = 14, + CV_SH3_IntR5 = 15, + CV_SH3_IntR6 = 16, + CV_SH3_IntR7 = 17, + CV_SH3_IntR8 = 18, + CV_SH3_IntR9 = 19, + CV_SH3_IntR10 = 20, + CV_SH3_IntR11 = 21, + CV_SH3_IntR12 = 22, + CV_SH3_IntR13 = 23, + CV_SH3_IntFp = 24, + CV_SH3_IntSp = 25, + CV_SH3_Gbr = 38, + CV_SH3_Pr = 39, + CV_SH3_Mach = 40, + CV_SH3_Macl = 41, + + CV_SH3_Pc = 50, + CV_SH3_Sr = 51, + + CV_SH3_BarA = 60, + CV_SH3_BasrA = 61, + CV_SH3_BamrA = 62, + CV_SH3_BbrA = 63, + CV_SH3_BarB = 64, + CV_SH3_BasrB = 65, + CV_SH3_BamrB = 66, + CV_SH3_BbrB = 67, + CV_SH3_BdrB = 68, + CV_SH3_BdmrB = 69, + CV_SH3_Brcr = 70, + + // + // Additional registers for Hitachi SH processors + // + + CV_SH_Fpscr = 75, // floating point status/control register + CV_SH_Fpul = 76, // floating point communication register + + CV_SH_FpR0 = 80, // Floating point registers + CV_SH_FpR1 = 81, + CV_SH_FpR2 = 82, + CV_SH_FpR3 = 83, + CV_SH_FpR4 = 84, + CV_SH_FpR5 = 85, + CV_SH_FpR6 = 86, + CV_SH_FpR7 = 87, + CV_SH_FpR8 = 88, + CV_SH_FpR9 = 89, + CV_SH_FpR10 = 90, + CV_SH_FpR11 = 91, + CV_SH_FpR12 = 92, + CV_SH_FpR13 = 93, + CV_SH_FpR14 = 94, + CV_SH_FpR15 = 95, + + CV_SH_XFpR0 = 96, + CV_SH_XFpR1 = 97, + CV_SH_XFpR2 = 98, + CV_SH_XFpR3 = 99, + CV_SH_XFpR4 = 100, + CV_SH_XFpR5 = 101, + CV_SH_XFpR6 = 102, + CV_SH_XFpR7 = 103, + CV_SH_XFpR8 = 104, + CV_SH_XFpR9 = 105, + CV_SH_XFpR10 = 106, + CV_SH_XFpR11 = 107, + CV_SH_XFpR12 = 108, + CV_SH_XFpR13 = 109, + CV_SH_XFpR14 = 110, + CV_SH_XFpR15 = 111, + + // + // Register set for the ARM processor. + // + + CV_ARM_NOREG = CV_REG_NONE, + + CV_ARM_R0 = 10, + CV_ARM_R1 = 11, + CV_ARM_R2 = 12, + CV_ARM_R3 = 13, + CV_ARM_R4 = 14, + CV_ARM_R5 = 15, + CV_ARM_R6 = 16, + CV_ARM_R7 = 17, + CV_ARM_R8 = 18, + CV_ARM_R9 = 19, + CV_ARM_R10 = 20, + CV_ARM_R11 = 21, // Frame pointer, if allocated + CV_ARM_R12 = 22, + CV_ARM_SP = 23, // Stack pointer + CV_ARM_LR = 24, // Link Register + CV_ARM_PC = 25, // Program counter + CV_ARM_CPSR = 26, // Current program status register + + CV_ARM_ACC0 = 27, // DSP co-processor 0 40 bit accumulator + + // + // Registers for ARM VFP10 support + // + + CV_ARM_FPSCR = 40, + CV_ARM_FPEXC = 41, + + CV_ARM_FS0 = 50, + CV_ARM_FS1 = 51, + CV_ARM_FS2 = 52, + CV_ARM_FS3 = 53, + CV_ARM_FS4 = 54, + CV_ARM_FS5 = 55, + CV_ARM_FS6 = 56, + CV_ARM_FS7 = 57, + CV_ARM_FS8 = 58, + CV_ARM_FS9 = 59, + CV_ARM_FS10 = 60, + CV_ARM_FS11 = 61, + CV_ARM_FS12 = 62, + CV_ARM_FS13 = 63, + CV_ARM_FS14 = 64, + CV_ARM_FS15 = 65, + CV_ARM_FS16 = 66, + CV_ARM_FS17 = 67, + CV_ARM_FS18 = 68, + CV_ARM_FS19 = 69, + CV_ARM_FS20 = 70, + CV_ARM_FS21 = 71, + CV_ARM_FS22 = 72, + CV_ARM_FS23 = 73, + CV_ARM_FS24 = 74, + CV_ARM_FS25 = 75, + CV_ARM_FS26 = 76, + CV_ARM_FS27 = 77, + CV_ARM_FS28 = 78, + CV_ARM_FS29 = 79, + CV_ARM_FS30 = 80, + CV_ARM_FS31 = 81, + + // + // ARM VFP Floating Point Extra control registers + // + + CV_ARM_FPEXTRA0 = 90, + CV_ARM_FPEXTRA1 = 91, + CV_ARM_FPEXTRA2 = 92, + CV_ARM_FPEXTRA3 = 93, + CV_ARM_FPEXTRA4 = 94, + CV_ARM_FPEXTRA5 = 95, + CV_ARM_FPEXTRA6 = 96, + CV_ARM_FPEXTRA7 = 97, + + // XSCALE Concan co-processor registers + CV_ARM_WR0 = 128, + CV_ARM_WR1 = 129, + CV_ARM_WR2 = 130, + CV_ARM_WR3 = 131, + CV_ARM_WR4 = 132, + CV_ARM_WR5 = 133, + CV_ARM_WR6 = 134, + CV_ARM_WR7 = 135, + CV_ARM_WR8 = 136, + CV_ARM_WR9 = 137, + CV_ARM_WR10 = 138, + CV_ARM_WR11 = 139, + CV_ARM_WR12 = 140, + CV_ARM_WR13 = 141, + CV_ARM_WR14 = 142, + CV_ARM_WR15 = 143, + + // XSCALE Concan co-processor control registers + CV_ARM_WCID = 144, + CV_ARM_WCON = 145, + CV_ARM_WCSSF = 146, + CV_ARM_WCASF = 147, + CV_ARM_WC4 = 148, + CV_ARM_WC5 = 149, + CV_ARM_WC6 = 150, + CV_ARM_WC7 = 151, + CV_ARM_WCGR0 = 152, + CV_ARM_WCGR1 = 153, + CV_ARM_WCGR2 = 154, + CV_ARM_WCGR3 = 155, + CV_ARM_WC12 = 156, + CV_ARM_WC13 = 157, + CV_ARM_WC14 = 158, + CV_ARM_WC15 = 159, + + // + // ARM VFPv3/Neon extended floating Point + // + + CV_ARM_FS32 = 200, + CV_ARM_FS33 = 201, + CV_ARM_FS34 = 202, + CV_ARM_FS35 = 203, + CV_ARM_FS36 = 204, + CV_ARM_FS37 = 205, + CV_ARM_FS38 = 206, + CV_ARM_FS39 = 207, + CV_ARM_FS40 = 208, + CV_ARM_FS41 = 209, + CV_ARM_FS42 = 210, + CV_ARM_FS43 = 211, + CV_ARM_FS44 = 212, + CV_ARM_FS45 = 213, + CV_ARM_FS46 = 214, + CV_ARM_FS47 = 215, + CV_ARM_FS48 = 216, + CV_ARM_FS49 = 217, + CV_ARM_FS50 = 218, + CV_ARM_FS51 = 219, + CV_ARM_FS52 = 220, + CV_ARM_FS53 = 221, + CV_ARM_FS54 = 222, + CV_ARM_FS55 = 223, + CV_ARM_FS56 = 224, + CV_ARM_FS57 = 225, + CV_ARM_FS58 = 226, + CV_ARM_FS59 = 227, + CV_ARM_FS60 = 228, + CV_ARM_FS61 = 229, + CV_ARM_FS62 = 230, + CV_ARM_FS63 = 231, + + // ARM double-precision floating point + + CV_ARM_ND0 = 300, + CV_ARM_ND1 = 301, + CV_ARM_ND2 = 302, + CV_ARM_ND3 = 303, + CV_ARM_ND4 = 304, + CV_ARM_ND5 = 305, + CV_ARM_ND6 = 306, + CV_ARM_ND7 = 307, + CV_ARM_ND8 = 308, + CV_ARM_ND9 = 309, + CV_ARM_ND10 = 310, + CV_ARM_ND11 = 311, + CV_ARM_ND12 = 312, + CV_ARM_ND13 = 313, + CV_ARM_ND14 = 314, + CV_ARM_ND15 = 315, + CV_ARM_ND16 = 316, + CV_ARM_ND17 = 317, + CV_ARM_ND18 = 318, + CV_ARM_ND19 = 319, + CV_ARM_ND20 = 320, + CV_ARM_ND21 = 321, + CV_ARM_ND22 = 322, + CV_ARM_ND23 = 323, + CV_ARM_ND24 = 324, + CV_ARM_ND25 = 325, + CV_ARM_ND26 = 326, + CV_ARM_ND27 = 327, + CV_ARM_ND28 = 328, + CV_ARM_ND29 = 329, + CV_ARM_ND30 = 330, + CV_ARM_ND31 = 331, + + // ARM extended precision floating point + + CV_ARM_NQ0 = 400, + CV_ARM_NQ1 = 401, + CV_ARM_NQ2 = 402, + CV_ARM_NQ3 = 403, + CV_ARM_NQ4 = 404, + CV_ARM_NQ5 = 405, + CV_ARM_NQ6 = 406, + CV_ARM_NQ7 = 407, + CV_ARM_NQ8 = 408, + CV_ARM_NQ9 = 409, + CV_ARM_NQ10 = 410, + CV_ARM_NQ11 = 411, + CV_ARM_NQ12 = 412, + CV_ARM_NQ13 = 413, + CV_ARM_NQ14 = 414, + CV_ARM_NQ15 = 415, + + // + // Register set for ARM64 + // + + CV_ARM64_NOREG = CV_REG_NONE, + + // General purpose 32-bit integer registers + + CV_ARM64_W0 = 10, + CV_ARM64_W1 = 11, + CV_ARM64_W2 = 12, + CV_ARM64_W3 = 13, + CV_ARM64_W4 = 14, + CV_ARM64_W5 = 15, + CV_ARM64_W6 = 16, + CV_ARM64_W7 = 17, + CV_ARM64_W8 = 18, + CV_ARM64_W9 = 19, + CV_ARM64_W10 = 20, + CV_ARM64_W11 = 21, + CV_ARM64_W12 = 22, + CV_ARM64_W13 = 23, + CV_ARM64_W14 = 24, + CV_ARM64_W15 = 25, + CV_ARM64_W16 = 26, + CV_ARM64_W17 = 27, + CV_ARM64_W18 = 28, + CV_ARM64_W19 = 29, + CV_ARM64_W20 = 30, + CV_ARM64_W21 = 31, + CV_ARM64_W22 = 32, + CV_ARM64_W23 = 33, + CV_ARM64_W24 = 34, + CV_ARM64_W25 = 35, + CV_ARM64_W26 = 36, + CV_ARM64_W27 = 37, + CV_ARM64_W28 = 38, + CV_ARM64_W29 = 39, + CV_ARM64_W30 = 40, + CV_ARM64_WZR = 41, + + // General purpose 64-bit integer registers + + CV_ARM64_X0 = 50, + CV_ARM64_X1 = 51, + CV_ARM64_X2 = 52, + CV_ARM64_X3 = 53, + CV_ARM64_X4 = 54, + CV_ARM64_X5 = 55, + CV_ARM64_X6 = 56, + CV_ARM64_X7 = 57, + CV_ARM64_X8 = 58, + CV_ARM64_X9 = 59, + CV_ARM64_X10 = 60, + CV_ARM64_X11 = 61, + CV_ARM64_X12 = 62, + CV_ARM64_X13 = 63, + CV_ARM64_X14 = 64, + CV_ARM64_X15 = 65, + CV_ARM64_IP0 = 66, + CV_ARM64_IP1 = 67, + CV_ARM64_X18 = 68, + CV_ARM64_X19 = 69, + CV_ARM64_X20 = 70, + CV_ARM64_X21 = 71, + CV_ARM64_X22 = 72, + CV_ARM64_X23 = 73, + CV_ARM64_X24 = 74, + CV_ARM64_X25 = 75, + CV_ARM64_X26 = 76, + CV_ARM64_X27 = 77, + CV_ARM64_X28 = 78, + CV_ARM64_FP = 79, + CV_ARM64_LR = 80, + CV_ARM64_SP = 81, + CV_ARM64_ZR = 82, + CV_ARM64_PC = 83, + + // status registers + + CV_ARM64_NZCV = 90, + CV_ARM64_CPSR = 91, + + // 32-bit floating point registers + + CV_ARM64_S0 = 100, + CV_ARM64_S1 = 101, + CV_ARM64_S2 = 102, + CV_ARM64_S3 = 103, + CV_ARM64_S4 = 104, + CV_ARM64_S5 = 105, + CV_ARM64_S6 = 106, + CV_ARM64_S7 = 107, + CV_ARM64_S8 = 108, + CV_ARM64_S9 = 109, + CV_ARM64_S10 = 110, + CV_ARM64_S11 = 111, + CV_ARM64_S12 = 112, + CV_ARM64_S13 = 113, + CV_ARM64_S14 = 114, + CV_ARM64_S15 = 115, + CV_ARM64_S16 = 116, + CV_ARM64_S17 = 117, + CV_ARM64_S18 = 118, + CV_ARM64_S19 = 119, + CV_ARM64_S20 = 120, + CV_ARM64_S21 = 121, + CV_ARM64_S22 = 122, + CV_ARM64_S23 = 123, + CV_ARM64_S24 = 124, + CV_ARM64_S25 = 125, + CV_ARM64_S26 = 126, + CV_ARM64_S27 = 127, + CV_ARM64_S28 = 128, + CV_ARM64_S29 = 129, + CV_ARM64_S30 = 130, + CV_ARM64_S31 = 131, + + // 64-bit floating point registers + + CV_ARM64_D0 = 140, + CV_ARM64_D1 = 141, + CV_ARM64_D2 = 142, + CV_ARM64_D3 = 143, + CV_ARM64_D4 = 144, + CV_ARM64_D5 = 145, + CV_ARM64_D6 = 146, + CV_ARM64_D7 = 147, + CV_ARM64_D8 = 148, + CV_ARM64_D9 = 149, + CV_ARM64_D10 = 150, + CV_ARM64_D11 = 151, + CV_ARM64_D12 = 152, + CV_ARM64_D13 = 153, + CV_ARM64_D14 = 154, + CV_ARM64_D15 = 155, + CV_ARM64_D16 = 156, + CV_ARM64_D17 = 157, + CV_ARM64_D18 = 158, + CV_ARM64_D19 = 159, + CV_ARM64_D20 = 160, + CV_ARM64_D21 = 161, + CV_ARM64_D22 = 162, + CV_ARM64_D23 = 163, + CV_ARM64_D24 = 164, + CV_ARM64_D25 = 165, + CV_ARM64_D26 = 166, + CV_ARM64_D27 = 167, + CV_ARM64_D28 = 168, + CV_ARM64_D29 = 169, + CV_ARM64_D30 = 170, + CV_ARM64_D31 = 171, + + // 128-bit SIMD registers + + CV_ARM64_Q0 = 180, + CV_ARM64_Q1 = 181, + CV_ARM64_Q2 = 182, + CV_ARM64_Q3 = 183, + CV_ARM64_Q4 = 184, + CV_ARM64_Q5 = 185, + CV_ARM64_Q6 = 186, + CV_ARM64_Q7 = 187, + CV_ARM64_Q8 = 188, + CV_ARM64_Q9 = 189, + CV_ARM64_Q10 = 190, + CV_ARM64_Q11 = 191, + CV_ARM64_Q12 = 192, + CV_ARM64_Q13 = 193, + CV_ARM64_Q14 = 194, + CV_ARM64_Q15 = 195, + CV_ARM64_Q16 = 196, + CV_ARM64_Q17 = 197, + CV_ARM64_Q18 = 198, + CV_ARM64_Q19 = 199, + CV_ARM64_Q20 = 200, + CV_ARM64_Q21 = 201, + CV_ARM64_Q22 = 202, + CV_ARM64_Q23 = 203, + CV_ARM64_Q24 = 204, + CV_ARM64_Q25 = 205, + CV_ARM64_Q26 = 206, + CV_ARM64_Q27 = 207, + CV_ARM64_Q28 = 208, + CV_ARM64_Q29 = 209, + CV_ARM64_Q30 = 210, + CV_ARM64_Q31 = 211, + + // Floating point status register + + CV_ARM64_FPSR = 220, + CV_ARM64_FPCR = 221, + + // 8-bit floating point registers + + CV_ARM64_B0 = 230, + CV_ARM64_B1 = 231, + CV_ARM64_B2 = 232, + CV_ARM64_B3 = 233, + CV_ARM64_B4 = 234, + CV_ARM64_B5 = 235, + CV_ARM64_B6 = 236, + CV_ARM64_B7 = 237, + CV_ARM64_B8 = 238, + CV_ARM64_B9 = 239, + CV_ARM64_B10 = 240, + CV_ARM64_B11 = 241, + CV_ARM64_B12 = 242, + CV_ARM64_B13 = 243, + CV_ARM64_B14 = 244, + CV_ARM64_B15 = 245, + CV_ARM64_B16 = 246, + CV_ARM64_B17 = 247, + CV_ARM64_B18 = 248, + CV_ARM64_B19 = 249, + CV_ARM64_B20 = 250, + CV_ARM64_B21 = 251, + CV_ARM64_B22 = 252, + CV_ARM64_B23 = 253, + CV_ARM64_B24 = 254, + CV_ARM64_B25 = 255, + CV_ARM64_B26 = 256, + CV_ARM64_B27 = 257, + CV_ARM64_B28 = 258, + CV_ARM64_B29 = 259, + CV_ARM64_B30 = 260, + CV_ARM64_B31 = 261, + + // 16-bit floating point registers + + CV_ARM64_H0 = 270, + CV_ARM64_H1 = 271, + CV_ARM64_H2 = 272, + CV_ARM64_H3 = 273, + CV_ARM64_H4 = 274, + CV_ARM64_H5 = 275, + CV_ARM64_H6 = 276, + CV_ARM64_H7 = 277, + CV_ARM64_H8 = 278, + CV_ARM64_H9 = 279, + CV_ARM64_H10 = 280, + CV_ARM64_H11 = 281, + CV_ARM64_H12 = 282, + CV_ARM64_H13 = 283, + CV_ARM64_H14 = 284, + CV_ARM64_H15 = 285, + CV_ARM64_H16 = 286, + CV_ARM64_H17 = 287, + CV_ARM64_H18 = 288, + CV_ARM64_H19 = 289, + CV_ARM64_H20 = 290, + CV_ARM64_H21 = 291, + CV_ARM64_H22 = 292, + CV_ARM64_H23 = 293, + CV_ARM64_H24 = 294, + CV_ARM64_H25 = 295, + CV_ARM64_H26 = 296, + CV_ARM64_H27 = 297, + CV_ARM64_H28 = 298, + CV_ARM64_H29 = 299, + CV_ARM64_H30 = 300, + CV_ARM64_H31 = 301, + + // 128-bit vector registers + + CV_ARM64_V0 = 310, + CV_ARM64_V1 = 311, + CV_ARM64_V2 = 312, + CV_ARM64_V3 = 313, + CV_ARM64_V4 = 314, + CV_ARM64_V5 = 315, + CV_ARM64_V6 = 316, + CV_ARM64_V7 = 317, + CV_ARM64_V8 = 318, + CV_ARM64_V9 = 319, + CV_ARM64_V10 = 320, + CV_ARM64_V11 = 321, + CV_ARM64_V12 = 322, + CV_ARM64_V13 = 323, + CV_ARM64_V14 = 324, + CV_ARM64_V15 = 325, + CV_ARM64_V16 = 326, + CV_ARM64_V17 = 327, + CV_ARM64_V18 = 328, + CV_ARM64_V19 = 329, + CV_ARM64_V20 = 330, + CV_ARM64_V21 = 331, + CV_ARM64_V22 = 332, + CV_ARM64_V23 = 333, + CV_ARM64_V24 = 334, + CV_ARM64_V25 = 335, + CV_ARM64_V26 = 336, + CV_ARM64_V27 = 337, + CV_ARM64_V28 = 338, + CV_ARM64_V29 = 339, + CV_ARM64_V30 = 340, + CV_ARM64_V31 = 341, + + // 128-bit SIMD registers upper 64 bits + + CV_ARM64_Q0H = 350, + CV_ARM64_Q1H = 351, + CV_ARM64_Q2H = 352, + CV_ARM64_Q3H = 353, + CV_ARM64_Q4H = 354, + CV_ARM64_Q5H = 355, + CV_ARM64_Q6H = 356, + CV_ARM64_Q7H = 357, + CV_ARM64_Q8H = 358, + CV_ARM64_Q9H = 359, + CV_ARM64_Q10H = 360, + CV_ARM64_Q11H = 361, + CV_ARM64_Q12H = 362, + CV_ARM64_Q13H = 363, + CV_ARM64_Q14H = 364, + CV_ARM64_Q15H = 365, + CV_ARM64_Q16H = 366, + CV_ARM64_Q17H = 367, + CV_ARM64_Q18H = 368, + CV_ARM64_Q19H = 369, + CV_ARM64_Q20H = 370, + CV_ARM64_Q21H = 371, + CV_ARM64_Q22H = 372, + CV_ARM64_Q23H = 373, + CV_ARM64_Q24H = 374, + CV_ARM64_Q25H = 375, + CV_ARM64_Q26H = 376, + CV_ARM64_Q27H = 377, + CV_ARM64_Q28H = 378, + CV_ARM64_Q29H = 379, + CV_ARM64_Q30H = 380, + CV_ARM64_Q31H = 381, + + // + // Register set for Intel IA64 + // + + CV_IA64_NOREG = CV_REG_NONE, + + // Branch Registers + + CV_IA64_Br0 = 512, + CV_IA64_Br1 = 513, + CV_IA64_Br2 = 514, + CV_IA64_Br3 = 515, + CV_IA64_Br4 = 516, + CV_IA64_Br5 = 517, + CV_IA64_Br6 = 518, + CV_IA64_Br7 = 519, + + // Predicate Registers + + CV_IA64_P0 = 704, + CV_IA64_P1 = 705, + CV_IA64_P2 = 706, + CV_IA64_P3 = 707, + CV_IA64_P4 = 708, + CV_IA64_P5 = 709, + CV_IA64_P6 = 710, + CV_IA64_P7 = 711, + CV_IA64_P8 = 712, + CV_IA64_P9 = 713, + CV_IA64_P10 = 714, + CV_IA64_P11 = 715, + CV_IA64_P12 = 716, + CV_IA64_P13 = 717, + CV_IA64_P14 = 718, + CV_IA64_P15 = 719, + CV_IA64_P16 = 720, + CV_IA64_P17 = 721, + CV_IA64_P18 = 722, + CV_IA64_P19 = 723, + CV_IA64_P20 = 724, + CV_IA64_P21 = 725, + CV_IA64_P22 = 726, + CV_IA64_P23 = 727, + CV_IA64_P24 = 728, + CV_IA64_P25 = 729, + CV_IA64_P26 = 730, + CV_IA64_P27 = 731, + CV_IA64_P28 = 732, + CV_IA64_P29 = 733, + CV_IA64_P30 = 734, + CV_IA64_P31 = 735, + CV_IA64_P32 = 736, + CV_IA64_P33 = 737, + CV_IA64_P34 = 738, + CV_IA64_P35 = 739, + CV_IA64_P36 = 740, + CV_IA64_P37 = 741, + CV_IA64_P38 = 742, + CV_IA64_P39 = 743, + CV_IA64_P40 = 744, + CV_IA64_P41 = 745, + CV_IA64_P42 = 746, + CV_IA64_P43 = 747, + CV_IA64_P44 = 748, + CV_IA64_P45 = 749, + CV_IA64_P46 = 750, + CV_IA64_P47 = 751, + CV_IA64_P48 = 752, + CV_IA64_P49 = 753, + CV_IA64_P50 = 754, + CV_IA64_P51 = 755, + CV_IA64_P52 = 756, + CV_IA64_P53 = 757, + CV_IA64_P54 = 758, + CV_IA64_P55 = 759, + CV_IA64_P56 = 760, + CV_IA64_P57 = 761, + CV_IA64_P58 = 762, + CV_IA64_P59 = 763, + CV_IA64_P60 = 764, + CV_IA64_P61 = 765, + CV_IA64_P62 = 766, + CV_IA64_P63 = 767, + + CV_IA64_Preds = 768, + + // Banked General Registers + + CV_IA64_IntH0 = 832, + CV_IA64_IntH1 = 833, + CV_IA64_IntH2 = 834, + CV_IA64_IntH3 = 835, + CV_IA64_IntH4 = 836, + CV_IA64_IntH5 = 837, + CV_IA64_IntH6 = 838, + CV_IA64_IntH7 = 839, + CV_IA64_IntH8 = 840, + CV_IA64_IntH9 = 841, + CV_IA64_IntH10 = 842, + CV_IA64_IntH11 = 843, + CV_IA64_IntH12 = 844, + CV_IA64_IntH13 = 845, + CV_IA64_IntH14 = 846, + CV_IA64_IntH15 = 847, + + // Special Registers + + CV_IA64_Ip = 1016, + CV_IA64_Umask = 1017, + CV_IA64_Cfm = 1018, + CV_IA64_Psr = 1019, + + // Banked General Registers + + CV_IA64_Nats = 1020, + CV_IA64_Nats2 = 1021, + CV_IA64_Nats3 = 1022, + + // General-Purpose Registers + + // Integer registers + CV_IA64_IntR0 = 1024, + CV_IA64_IntR1 = 1025, + CV_IA64_IntR2 = 1026, + CV_IA64_IntR3 = 1027, + CV_IA64_IntR4 = 1028, + CV_IA64_IntR5 = 1029, + CV_IA64_IntR6 = 1030, + CV_IA64_IntR7 = 1031, + CV_IA64_IntR8 = 1032, + CV_IA64_IntR9 = 1033, + CV_IA64_IntR10 = 1034, + CV_IA64_IntR11 = 1035, + CV_IA64_IntR12 = 1036, + CV_IA64_IntR13 = 1037, + CV_IA64_IntR14 = 1038, + CV_IA64_IntR15 = 1039, + CV_IA64_IntR16 = 1040, + CV_IA64_IntR17 = 1041, + CV_IA64_IntR18 = 1042, + CV_IA64_IntR19 = 1043, + CV_IA64_IntR20 = 1044, + CV_IA64_IntR21 = 1045, + CV_IA64_IntR22 = 1046, + CV_IA64_IntR23 = 1047, + CV_IA64_IntR24 = 1048, + CV_IA64_IntR25 = 1049, + CV_IA64_IntR26 = 1050, + CV_IA64_IntR27 = 1051, + CV_IA64_IntR28 = 1052, + CV_IA64_IntR29 = 1053, + CV_IA64_IntR30 = 1054, + CV_IA64_IntR31 = 1055, + + // Register Stack + CV_IA64_IntR32 = 1056, + CV_IA64_IntR33 = 1057, + CV_IA64_IntR34 = 1058, + CV_IA64_IntR35 = 1059, + CV_IA64_IntR36 = 1060, + CV_IA64_IntR37 = 1061, + CV_IA64_IntR38 = 1062, + CV_IA64_IntR39 = 1063, + CV_IA64_IntR40 = 1064, + CV_IA64_IntR41 = 1065, + CV_IA64_IntR42 = 1066, + CV_IA64_IntR43 = 1067, + CV_IA64_IntR44 = 1068, + CV_IA64_IntR45 = 1069, + CV_IA64_IntR46 = 1070, + CV_IA64_IntR47 = 1071, + CV_IA64_IntR48 = 1072, + CV_IA64_IntR49 = 1073, + CV_IA64_IntR50 = 1074, + CV_IA64_IntR51 = 1075, + CV_IA64_IntR52 = 1076, + CV_IA64_IntR53 = 1077, + CV_IA64_IntR54 = 1078, + CV_IA64_IntR55 = 1079, + CV_IA64_IntR56 = 1080, + CV_IA64_IntR57 = 1081, + CV_IA64_IntR58 = 1082, + CV_IA64_IntR59 = 1083, + CV_IA64_IntR60 = 1084, + CV_IA64_IntR61 = 1085, + CV_IA64_IntR62 = 1086, + CV_IA64_IntR63 = 1087, + CV_IA64_IntR64 = 1088, + CV_IA64_IntR65 = 1089, + CV_IA64_IntR66 = 1090, + CV_IA64_IntR67 = 1091, + CV_IA64_IntR68 = 1092, + CV_IA64_IntR69 = 1093, + CV_IA64_IntR70 = 1094, + CV_IA64_IntR71 = 1095, + CV_IA64_IntR72 = 1096, + CV_IA64_IntR73 = 1097, + CV_IA64_IntR74 = 1098, + CV_IA64_IntR75 = 1099, + CV_IA64_IntR76 = 1100, + CV_IA64_IntR77 = 1101, + CV_IA64_IntR78 = 1102, + CV_IA64_IntR79 = 1103, + CV_IA64_IntR80 = 1104, + CV_IA64_IntR81 = 1105, + CV_IA64_IntR82 = 1106, + CV_IA64_IntR83 = 1107, + CV_IA64_IntR84 = 1108, + CV_IA64_IntR85 = 1109, + CV_IA64_IntR86 = 1110, + CV_IA64_IntR87 = 1111, + CV_IA64_IntR88 = 1112, + CV_IA64_IntR89 = 1113, + CV_IA64_IntR90 = 1114, + CV_IA64_IntR91 = 1115, + CV_IA64_IntR92 = 1116, + CV_IA64_IntR93 = 1117, + CV_IA64_IntR94 = 1118, + CV_IA64_IntR95 = 1119, + CV_IA64_IntR96 = 1120, + CV_IA64_IntR97 = 1121, + CV_IA64_IntR98 = 1122, + CV_IA64_IntR99 = 1123, + CV_IA64_IntR100 = 1124, + CV_IA64_IntR101 = 1125, + CV_IA64_IntR102 = 1126, + CV_IA64_IntR103 = 1127, + CV_IA64_IntR104 = 1128, + CV_IA64_IntR105 = 1129, + CV_IA64_IntR106 = 1130, + CV_IA64_IntR107 = 1131, + CV_IA64_IntR108 = 1132, + CV_IA64_IntR109 = 1133, + CV_IA64_IntR110 = 1134, + CV_IA64_IntR111 = 1135, + CV_IA64_IntR112 = 1136, + CV_IA64_IntR113 = 1137, + CV_IA64_IntR114 = 1138, + CV_IA64_IntR115 = 1139, + CV_IA64_IntR116 = 1140, + CV_IA64_IntR117 = 1141, + CV_IA64_IntR118 = 1142, + CV_IA64_IntR119 = 1143, + CV_IA64_IntR120 = 1144, + CV_IA64_IntR121 = 1145, + CV_IA64_IntR122 = 1146, + CV_IA64_IntR123 = 1147, + CV_IA64_IntR124 = 1148, + CV_IA64_IntR125 = 1149, + CV_IA64_IntR126 = 1150, + CV_IA64_IntR127 = 1151, + + // Floating-Point Registers + + // Low Floating Point Registers + CV_IA64_FltF0 = 2048, + CV_IA64_FltF1 = 2049, + CV_IA64_FltF2 = 2050, + CV_IA64_FltF3 = 2051, + CV_IA64_FltF4 = 2052, + CV_IA64_FltF5 = 2053, + CV_IA64_FltF6 = 2054, + CV_IA64_FltF7 = 2055, + CV_IA64_FltF8 = 2056, + CV_IA64_FltF9 = 2057, + CV_IA64_FltF10 = 2058, + CV_IA64_FltF11 = 2059, + CV_IA64_FltF12 = 2060, + CV_IA64_FltF13 = 2061, + CV_IA64_FltF14 = 2062, + CV_IA64_FltF15 = 2063, + CV_IA64_FltF16 = 2064, + CV_IA64_FltF17 = 2065, + CV_IA64_FltF18 = 2066, + CV_IA64_FltF19 = 2067, + CV_IA64_FltF20 = 2068, + CV_IA64_FltF21 = 2069, + CV_IA64_FltF22 = 2070, + CV_IA64_FltF23 = 2071, + CV_IA64_FltF24 = 2072, + CV_IA64_FltF25 = 2073, + CV_IA64_FltF26 = 2074, + CV_IA64_FltF27 = 2075, + CV_IA64_FltF28 = 2076, + CV_IA64_FltF29 = 2077, + CV_IA64_FltF30 = 2078, + CV_IA64_FltF31 = 2079, + + // High Floating Point Registers + CV_IA64_FltF32 = 2080, + CV_IA64_FltF33 = 2081, + CV_IA64_FltF34 = 2082, + CV_IA64_FltF35 = 2083, + CV_IA64_FltF36 = 2084, + CV_IA64_FltF37 = 2085, + CV_IA64_FltF38 = 2086, + CV_IA64_FltF39 = 2087, + CV_IA64_FltF40 = 2088, + CV_IA64_FltF41 = 2089, + CV_IA64_FltF42 = 2090, + CV_IA64_FltF43 = 2091, + CV_IA64_FltF44 = 2092, + CV_IA64_FltF45 = 2093, + CV_IA64_FltF46 = 2094, + CV_IA64_FltF47 = 2095, + CV_IA64_FltF48 = 2096, + CV_IA64_FltF49 = 2097, + CV_IA64_FltF50 = 2098, + CV_IA64_FltF51 = 2099, + CV_IA64_FltF52 = 2100, + CV_IA64_FltF53 = 2101, + CV_IA64_FltF54 = 2102, + CV_IA64_FltF55 = 2103, + CV_IA64_FltF56 = 2104, + CV_IA64_FltF57 = 2105, + CV_IA64_FltF58 = 2106, + CV_IA64_FltF59 = 2107, + CV_IA64_FltF60 = 2108, + CV_IA64_FltF61 = 2109, + CV_IA64_FltF62 = 2110, + CV_IA64_FltF63 = 2111, + CV_IA64_FltF64 = 2112, + CV_IA64_FltF65 = 2113, + CV_IA64_FltF66 = 2114, + CV_IA64_FltF67 = 2115, + CV_IA64_FltF68 = 2116, + CV_IA64_FltF69 = 2117, + CV_IA64_FltF70 = 2118, + CV_IA64_FltF71 = 2119, + CV_IA64_FltF72 = 2120, + CV_IA64_FltF73 = 2121, + CV_IA64_FltF74 = 2122, + CV_IA64_FltF75 = 2123, + CV_IA64_FltF76 = 2124, + CV_IA64_FltF77 = 2125, + CV_IA64_FltF78 = 2126, + CV_IA64_FltF79 = 2127, + CV_IA64_FltF80 = 2128, + CV_IA64_FltF81 = 2129, + CV_IA64_FltF82 = 2130, + CV_IA64_FltF83 = 2131, + CV_IA64_FltF84 = 2132, + CV_IA64_FltF85 = 2133, + CV_IA64_FltF86 = 2134, + CV_IA64_FltF87 = 2135, + CV_IA64_FltF88 = 2136, + CV_IA64_FltF89 = 2137, + CV_IA64_FltF90 = 2138, + CV_IA64_FltF91 = 2139, + CV_IA64_FltF92 = 2140, + CV_IA64_FltF93 = 2141, + CV_IA64_FltF94 = 2142, + CV_IA64_FltF95 = 2143, + CV_IA64_FltF96 = 2144, + CV_IA64_FltF97 = 2145, + CV_IA64_FltF98 = 2146, + CV_IA64_FltF99 = 2147, + CV_IA64_FltF100 = 2148, + CV_IA64_FltF101 = 2149, + CV_IA64_FltF102 = 2150, + CV_IA64_FltF103 = 2151, + CV_IA64_FltF104 = 2152, + CV_IA64_FltF105 = 2153, + CV_IA64_FltF106 = 2154, + CV_IA64_FltF107 = 2155, + CV_IA64_FltF108 = 2156, + CV_IA64_FltF109 = 2157, + CV_IA64_FltF110 = 2158, + CV_IA64_FltF111 = 2159, + CV_IA64_FltF112 = 2160, + CV_IA64_FltF113 = 2161, + CV_IA64_FltF114 = 2162, + CV_IA64_FltF115 = 2163, + CV_IA64_FltF116 = 2164, + CV_IA64_FltF117 = 2165, + CV_IA64_FltF118 = 2166, + CV_IA64_FltF119 = 2167, + CV_IA64_FltF120 = 2168, + CV_IA64_FltF121 = 2169, + CV_IA64_FltF122 = 2170, + CV_IA64_FltF123 = 2171, + CV_IA64_FltF124 = 2172, + CV_IA64_FltF125 = 2173, + CV_IA64_FltF126 = 2174, + CV_IA64_FltF127 = 2175, + + // Application Registers + + CV_IA64_ApKR0 = 3072, + CV_IA64_ApKR1 = 3073, + CV_IA64_ApKR2 = 3074, + CV_IA64_ApKR3 = 3075, + CV_IA64_ApKR4 = 3076, + CV_IA64_ApKR5 = 3077, + CV_IA64_ApKR6 = 3078, + CV_IA64_ApKR7 = 3079, + CV_IA64_AR8 = 3080, + CV_IA64_AR9 = 3081, + CV_IA64_AR10 = 3082, + CV_IA64_AR11 = 3083, + CV_IA64_AR12 = 3084, + CV_IA64_AR13 = 3085, + CV_IA64_AR14 = 3086, + CV_IA64_AR15 = 3087, + CV_IA64_RsRSC = 3088, + CV_IA64_RsBSP = 3089, + CV_IA64_RsBSPSTORE = 3090, + CV_IA64_RsRNAT = 3091, + CV_IA64_AR20 = 3092, + CV_IA64_StFCR = 3093, + CV_IA64_AR22 = 3094, + CV_IA64_AR23 = 3095, + CV_IA64_EFLAG = 3096, + CV_IA64_CSD = 3097, + CV_IA64_SSD = 3098, + CV_IA64_CFLG = 3099, + CV_IA64_StFSR = 3100, + CV_IA64_StFIR = 3101, + CV_IA64_StFDR = 3102, + CV_IA64_AR31 = 3103, + CV_IA64_ApCCV = 3104, + CV_IA64_AR33 = 3105, + CV_IA64_AR34 = 3106, + CV_IA64_AR35 = 3107, + CV_IA64_ApUNAT = 3108, + CV_IA64_AR37 = 3109, + CV_IA64_AR38 = 3110, + CV_IA64_AR39 = 3111, + CV_IA64_StFPSR = 3112, + CV_IA64_AR41 = 3113, + CV_IA64_AR42 = 3114, + CV_IA64_AR43 = 3115, + CV_IA64_ApITC = 3116, + CV_IA64_AR45 = 3117, + CV_IA64_AR46 = 3118, + CV_IA64_AR47 = 3119, + CV_IA64_AR48 = 3120, + CV_IA64_AR49 = 3121, + CV_IA64_AR50 = 3122, + CV_IA64_AR51 = 3123, + CV_IA64_AR52 = 3124, + CV_IA64_AR53 = 3125, + CV_IA64_AR54 = 3126, + CV_IA64_AR55 = 3127, + CV_IA64_AR56 = 3128, + CV_IA64_AR57 = 3129, + CV_IA64_AR58 = 3130, + CV_IA64_AR59 = 3131, + CV_IA64_AR60 = 3132, + CV_IA64_AR61 = 3133, + CV_IA64_AR62 = 3134, + CV_IA64_AR63 = 3135, + CV_IA64_RsPFS = 3136, + CV_IA64_ApLC = 3137, + CV_IA64_ApEC = 3138, + CV_IA64_AR67 = 3139, + CV_IA64_AR68 = 3140, + CV_IA64_AR69 = 3141, + CV_IA64_AR70 = 3142, + CV_IA64_AR71 = 3143, + CV_IA64_AR72 = 3144, + CV_IA64_AR73 = 3145, + CV_IA64_AR74 = 3146, + CV_IA64_AR75 = 3147, + CV_IA64_AR76 = 3148, + CV_IA64_AR77 = 3149, + CV_IA64_AR78 = 3150, + CV_IA64_AR79 = 3151, + CV_IA64_AR80 = 3152, + CV_IA64_AR81 = 3153, + CV_IA64_AR82 = 3154, + CV_IA64_AR83 = 3155, + CV_IA64_AR84 = 3156, + CV_IA64_AR85 = 3157, + CV_IA64_AR86 = 3158, + CV_IA64_AR87 = 3159, + CV_IA64_AR88 = 3160, + CV_IA64_AR89 = 3161, + CV_IA64_AR90 = 3162, + CV_IA64_AR91 = 3163, + CV_IA64_AR92 = 3164, + CV_IA64_AR93 = 3165, + CV_IA64_AR94 = 3166, + CV_IA64_AR95 = 3167, + CV_IA64_AR96 = 3168, + CV_IA64_AR97 = 3169, + CV_IA64_AR98 = 3170, + CV_IA64_AR99 = 3171, + CV_IA64_AR100 = 3172, + CV_IA64_AR101 = 3173, + CV_IA64_AR102 = 3174, + CV_IA64_AR103 = 3175, + CV_IA64_AR104 = 3176, + CV_IA64_AR105 = 3177, + CV_IA64_AR106 = 3178, + CV_IA64_AR107 = 3179, + CV_IA64_AR108 = 3180, + CV_IA64_AR109 = 3181, + CV_IA64_AR110 = 3182, + CV_IA64_AR111 = 3183, + CV_IA64_AR112 = 3184, + CV_IA64_AR113 = 3185, + CV_IA64_AR114 = 3186, + CV_IA64_AR115 = 3187, + CV_IA64_AR116 = 3188, + CV_IA64_AR117 = 3189, + CV_IA64_AR118 = 3190, + CV_IA64_AR119 = 3191, + CV_IA64_AR120 = 3192, + CV_IA64_AR121 = 3193, + CV_IA64_AR122 = 3194, + CV_IA64_AR123 = 3195, + CV_IA64_AR124 = 3196, + CV_IA64_AR125 = 3197, + CV_IA64_AR126 = 3198, + CV_IA64_AR127 = 3199, + + // CPUID Registers + + CV_IA64_CPUID0 = 3328, + CV_IA64_CPUID1 = 3329, + CV_IA64_CPUID2 = 3330, + CV_IA64_CPUID3 = 3331, + CV_IA64_CPUID4 = 3332, + + // Control Registers + + CV_IA64_ApDCR = 4096, + CV_IA64_ApITM = 4097, + CV_IA64_ApIVA = 4098, + CV_IA64_CR3 = 4099, + CV_IA64_CR4 = 4100, + CV_IA64_CR5 = 4101, + CV_IA64_CR6 = 4102, + CV_IA64_CR7 = 4103, + CV_IA64_ApPTA = 4104, + CV_IA64_ApGPTA = 4105, + CV_IA64_CR10 = 4106, + CV_IA64_CR11 = 4107, + CV_IA64_CR12 = 4108, + CV_IA64_CR13 = 4109, + CV_IA64_CR14 = 4110, + CV_IA64_CR15 = 4111, + CV_IA64_StIPSR = 4112, + CV_IA64_StISR = 4113, + CV_IA64_CR18 = 4114, + CV_IA64_StIIP = 4115, + CV_IA64_StIFA = 4116, + CV_IA64_StITIR = 4117, + CV_IA64_StIIPA = 4118, + CV_IA64_StIFS = 4119, + CV_IA64_StIIM = 4120, + CV_IA64_StIHA = 4121, + CV_IA64_CR26 = 4122, + CV_IA64_CR27 = 4123, + CV_IA64_CR28 = 4124, + CV_IA64_CR29 = 4125, + CV_IA64_CR30 = 4126, + CV_IA64_CR31 = 4127, + CV_IA64_CR32 = 4128, + CV_IA64_CR33 = 4129, + CV_IA64_CR34 = 4130, + CV_IA64_CR35 = 4131, + CV_IA64_CR36 = 4132, + CV_IA64_CR37 = 4133, + CV_IA64_CR38 = 4134, + CV_IA64_CR39 = 4135, + CV_IA64_CR40 = 4136, + CV_IA64_CR41 = 4137, + CV_IA64_CR42 = 4138, + CV_IA64_CR43 = 4139, + CV_IA64_CR44 = 4140, + CV_IA64_CR45 = 4141, + CV_IA64_CR46 = 4142, + CV_IA64_CR47 = 4143, + CV_IA64_CR48 = 4144, + CV_IA64_CR49 = 4145, + CV_IA64_CR50 = 4146, + CV_IA64_CR51 = 4147, + CV_IA64_CR52 = 4148, + CV_IA64_CR53 = 4149, + CV_IA64_CR54 = 4150, + CV_IA64_CR55 = 4151, + CV_IA64_CR56 = 4152, + CV_IA64_CR57 = 4153, + CV_IA64_CR58 = 4154, + CV_IA64_CR59 = 4155, + CV_IA64_CR60 = 4156, + CV_IA64_CR61 = 4157, + CV_IA64_CR62 = 4158, + CV_IA64_CR63 = 4159, + CV_IA64_SaLID = 4160, + CV_IA64_SaIVR = 4161, + CV_IA64_SaTPR = 4162, + CV_IA64_SaEOI = 4163, + CV_IA64_SaIRR0 = 4164, + CV_IA64_SaIRR1 = 4165, + CV_IA64_SaIRR2 = 4166, + CV_IA64_SaIRR3 = 4167, + CV_IA64_SaITV = 4168, + CV_IA64_SaPMV = 4169, + CV_IA64_SaCMCV = 4170, + CV_IA64_CR75 = 4171, + CV_IA64_CR76 = 4172, + CV_IA64_CR77 = 4173, + CV_IA64_CR78 = 4174, + CV_IA64_CR79 = 4175, + CV_IA64_SaLRR0 = 4176, + CV_IA64_SaLRR1 = 4177, + CV_IA64_CR82 = 4178, + CV_IA64_CR83 = 4179, + CV_IA64_CR84 = 4180, + CV_IA64_CR85 = 4181, + CV_IA64_CR86 = 4182, + CV_IA64_CR87 = 4183, + CV_IA64_CR88 = 4184, + CV_IA64_CR89 = 4185, + CV_IA64_CR90 = 4186, + CV_IA64_CR91 = 4187, + CV_IA64_CR92 = 4188, + CV_IA64_CR93 = 4189, + CV_IA64_CR94 = 4190, + CV_IA64_CR95 = 4191, + CV_IA64_CR96 = 4192, + CV_IA64_CR97 = 4193, + CV_IA64_CR98 = 4194, + CV_IA64_CR99 = 4195, + CV_IA64_CR100 = 4196, + CV_IA64_CR101 = 4197, + CV_IA64_CR102 = 4198, + CV_IA64_CR103 = 4199, + CV_IA64_CR104 = 4200, + CV_IA64_CR105 = 4201, + CV_IA64_CR106 = 4202, + CV_IA64_CR107 = 4203, + CV_IA64_CR108 = 4204, + CV_IA64_CR109 = 4205, + CV_IA64_CR110 = 4206, + CV_IA64_CR111 = 4207, + CV_IA64_CR112 = 4208, + CV_IA64_CR113 = 4209, + CV_IA64_CR114 = 4210, + CV_IA64_CR115 = 4211, + CV_IA64_CR116 = 4212, + CV_IA64_CR117 = 4213, + CV_IA64_CR118 = 4214, + CV_IA64_CR119 = 4215, + CV_IA64_CR120 = 4216, + CV_IA64_CR121 = 4217, + CV_IA64_CR122 = 4218, + CV_IA64_CR123 = 4219, + CV_IA64_CR124 = 4220, + CV_IA64_CR125 = 4221, + CV_IA64_CR126 = 4222, + CV_IA64_CR127 = 4223, + + // Protection Key Registers + + CV_IA64_Pkr0 = 5120, + CV_IA64_Pkr1 = 5121, + CV_IA64_Pkr2 = 5122, + CV_IA64_Pkr3 = 5123, + CV_IA64_Pkr4 = 5124, + CV_IA64_Pkr5 = 5125, + CV_IA64_Pkr6 = 5126, + CV_IA64_Pkr7 = 5127, + CV_IA64_Pkr8 = 5128, + CV_IA64_Pkr9 = 5129, + CV_IA64_Pkr10 = 5130, + CV_IA64_Pkr11 = 5131, + CV_IA64_Pkr12 = 5132, + CV_IA64_Pkr13 = 5133, + CV_IA64_Pkr14 = 5134, + CV_IA64_Pkr15 = 5135, + + // Region Registers + + CV_IA64_Rr0 = 6144, + CV_IA64_Rr1 = 6145, + CV_IA64_Rr2 = 6146, + CV_IA64_Rr3 = 6147, + CV_IA64_Rr4 = 6148, + CV_IA64_Rr5 = 6149, + CV_IA64_Rr6 = 6150, + CV_IA64_Rr7 = 6151, + + // Performance Monitor Data Registers + + CV_IA64_PFD0 = 7168, + CV_IA64_PFD1 = 7169, + CV_IA64_PFD2 = 7170, + CV_IA64_PFD3 = 7171, + CV_IA64_PFD4 = 7172, + CV_IA64_PFD5 = 7173, + CV_IA64_PFD6 = 7174, + CV_IA64_PFD7 = 7175, + CV_IA64_PFD8 = 7176, + CV_IA64_PFD9 = 7177, + CV_IA64_PFD10 = 7178, + CV_IA64_PFD11 = 7179, + CV_IA64_PFD12 = 7180, + CV_IA64_PFD13 = 7181, + CV_IA64_PFD14 = 7182, + CV_IA64_PFD15 = 7183, + CV_IA64_PFD16 = 7184, + CV_IA64_PFD17 = 7185, + + // Performance Monitor Config Registers + + CV_IA64_PFC0 = 7424, + CV_IA64_PFC1 = 7425, + CV_IA64_PFC2 = 7426, + CV_IA64_PFC3 = 7427, + CV_IA64_PFC4 = 7428, + CV_IA64_PFC5 = 7429, + CV_IA64_PFC6 = 7430, + CV_IA64_PFC7 = 7431, + CV_IA64_PFC8 = 7432, + CV_IA64_PFC9 = 7433, + CV_IA64_PFC10 = 7434, + CV_IA64_PFC11 = 7435, + CV_IA64_PFC12 = 7436, + CV_IA64_PFC13 = 7437, + CV_IA64_PFC14 = 7438, + CV_IA64_PFC15 = 7439, + + // Instruction Translation Registers + + CV_IA64_TrI0 = 8192, + CV_IA64_TrI1 = 8193, + CV_IA64_TrI2 = 8194, + CV_IA64_TrI3 = 8195, + CV_IA64_TrI4 = 8196, + CV_IA64_TrI5 = 8197, + CV_IA64_TrI6 = 8198, + CV_IA64_TrI7 = 8199, + + // Data Translation Registers + + CV_IA64_TrD0 = 8320, + CV_IA64_TrD1 = 8321, + CV_IA64_TrD2 = 8322, + CV_IA64_TrD3 = 8323, + CV_IA64_TrD4 = 8324, + CV_IA64_TrD5 = 8325, + CV_IA64_TrD6 = 8326, + CV_IA64_TrD7 = 8327, + + // Instruction Breakpoint Registers + + CV_IA64_DbI0 = 8448, + CV_IA64_DbI1 = 8449, + CV_IA64_DbI2 = 8450, + CV_IA64_DbI3 = 8451, + CV_IA64_DbI4 = 8452, + CV_IA64_DbI5 = 8453, + CV_IA64_DbI6 = 8454, + CV_IA64_DbI7 = 8455, + + // Data Breakpoint Registers + + CV_IA64_DbD0 = 8576, + CV_IA64_DbD1 = 8577, + CV_IA64_DbD2 = 8578, + CV_IA64_DbD3 = 8579, + CV_IA64_DbD4 = 8580, + CV_IA64_DbD5 = 8581, + CV_IA64_DbD6 = 8582, + CV_IA64_DbD7 = 8583, + + // + // Register set for the TriCore processor. + // + + CV_TRI_NOREG = CV_REG_NONE, + + // General Purpose Data Registers + + CV_TRI_D0 = 10, + CV_TRI_D1 = 11, + CV_TRI_D2 = 12, + CV_TRI_D3 = 13, + CV_TRI_D4 = 14, + CV_TRI_D5 = 15, + CV_TRI_D6 = 16, + CV_TRI_D7 = 17, + CV_TRI_D8 = 18, + CV_TRI_D9 = 19, + CV_TRI_D10 = 20, + CV_TRI_D11 = 21, + CV_TRI_D12 = 22, + CV_TRI_D13 = 23, + CV_TRI_D14 = 24, + CV_TRI_D15 = 25, + + // General Purpose Address Registers + + CV_TRI_A0 = 26, + CV_TRI_A1 = 27, + CV_TRI_A2 = 28, + CV_TRI_A3 = 29, + CV_TRI_A4 = 30, + CV_TRI_A5 = 31, + CV_TRI_A6 = 32, + CV_TRI_A7 = 33, + CV_TRI_A8 = 34, + CV_TRI_A9 = 35, + CV_TRI_A10 = 36, + CV_TRI_A11 = 37, + CV_TRI_A12 = 38, + CV_TRI_A13 = 39, + CV_TRI_A14 = 40, + CV_TRI_A15 = 41, + + // Extended (64-bit) data registers + + CV_TRI_E0 = 42, + CV_TRI_E2 = 43, + CV_TRI_E4 = 44, + CV_TRI_E6 = 45, + CV_TRI_E8 = 46, + CV_TRI_E10 = 47, + CV_TRI_E12 = 48, + CV_TRI_E14 = 49, + + // Extended (64-bit) address registers + + CV_TRI_EA0 = 50, + CV_TRI_EA2 = 51, + CV_TRI_EA4 = 52, + CV_TRI_EA6 = 53, + CV_TRI_EA8 = 54, + CV_TRI_EA10 = 55, + CV_TRI_EA12 = 56, + CV_TRI_EA14 = 57, + + CV_TRI_PSW = 58, + CV_TRI_PCXI = 59, + CV_TRI_PC = 60, + CV_TRI_FCX = 61, + CV_TRI_LCX = 62, + CV_TRI_ISP = 63, + CV_TRI_ICR = 64, + CV_TRI_BIV = 65, + CV_TRI_BTV = 66, + CV_TRI_SYSCON = 67, + CV_TRI_DPRx_0 = 68, + CV_TRI_DPRx_1 = 69, + CV_TRI_DPRx_2 = 70, + CV_TRI_DPRx_3 = 71, + CV_TRI_CPRx_0 = 68, + CV_TRI_CPRx_1 = 69, + CV_TRI_CPRx_2 = 70, + CV_TRI_CPRx_3 = 71, + CV_TRI_DPMx_0 = 68, + CV_TRI_DPMx_1 = 69, + CV_TRI_DPMx_2 = 70, + CV_TRI_DPMx_3 = 71, + CV_TRI_CPMx_0 = 68, + CV_TRI_CPMx_1 = 69, + CV_TRI_CPMx_2 = 70, + CV_TRI_CPMx_3 = 71, + CV_TRI_DBGSSR = 72, + CV_TRI_EXEVT = 73, + CV_TRI_SWEVT = 74, + CV_TRI_CREVT = 75, + CV_TRI_TRnEVT = 76, + CV_TRI_MMUCON = 77, + CV_TRI_ASI = 78, + CV_TRI_TVA = 79, + CV_TRI_TPA = 80, + CV_TRI_TPX = 81, + CV_TRI_TFA = 82, + + // + // Register set for the AM33 and related processors. + // + + CV_AM33_NOREG = CV_REG_NONE, + + // "Extended" (general purpose integer) registers + CV_AM33_E0 = 10, + CV_AM33_E1 = 11, + CV_AM33_E2 = 12, + CV_AM33_E3 = 13, + CV_AM33_E4 = 14, + CV_AM33_E5 = 15, + CV_AM33_E6 = 16, + CV_AM33_E7 = 17, + + // Address registers + CV_AM33_A0 = 20, + CV_AM33_A1 = 21, + CV_AM33_A2 = 22, + CV_AM33_A3 = 23, + + // Integer data registers + CV_AM33_D0 = 30, + CV_AM33_D1 = 31, + CV_AM33_D2 = 32, + CV_AM33_D3 = 33, + + // (Single-precision) floating-point registers + CV_AM33_FS0 = 40, + CV_AM33_FS1 = 41, + CV_AM33_FS2 = 42, + CV_AM33_FS3 = 43, + CV_AM33_FS4 = 44, + CV_AM33_FS5 = 45, + CV_AM33_FS6 = 46, + CV_AM33_FS7 = 47, + CV_AM33_FS8 = 48, + CV_AM33_FS9 = 49, + CV_AM33_FS10 = 50, + CV_AM33_FS11 = 51, + CV_AM33_FS12 = 52, + CV_AM33_FS13 = 53, + CV_AM33_FS14 = 54, + CV_AM33_FS15 = 55, + CV_AM33_FS16 = 56, + CV_AM33_FS17 = 57, + CV_AM33_FS18 = 58, + CV_AM33_FS19 = 59, + CV_AM33_FS20 = 60, + CV_AM33_FS21 = 61, + CV_AM33_FS22 = 62, + CV_AM33_FS23 = 63, + CV_AM33_FS24 = 64, + CV_AM33_FS25 = 65, + CV_AM33_FS26 = 66, + CV_AM33_FS27 = 67, + CV_AM33_FS28 = 68, + CV_AM33_FS29 = 69, + CV_AM33_FS30 = 70, + CV_AM33_FS31 = 71, + + // Special purpose registers + + // Stack pointer + CV_AM33_SP = 80, + + // Program counter + CV_AM33_PC = 81, + + // Multiply-divide/accumulate registers + CV_AM33_MDR = 82, + CV_AM33_MDRQ = 83, + CV_AM33_MCRH = 84, + CV_AM33_MCRL = 85, + CV_AM33_MCVF = 86, + + // CPU status words + CV_AM33_EPSW = 87, + CV_AM33_FPCR = 88, + + // Loop buffer registers + CV_AM33_LIR = 89, + CV_AM33_LAR = 90, + + // + // Register set for the Mitsubishi M32R + // + + CV_M32R_NOREG = CV_REG_NONE, + + CV_M32R_R0 = 10, + CV_M32R_R1 = 11, + CV_M32R_R2 = 12, + CV_M32R_R3 = 13, + CV_M32R_R4 = 14, + CV_M32R_R5 = 15, + CV_M32R_R6 = 16, + CV_M32R_R7 = 17, + CV_M32R_R8 = 18, + CV_M32R_R9 = 19, + CV_M32R_R10 = 20, + CV_M32R_R11 = 21, + CV_M32R_R12 = 22, // Gloabal Pointer, if used + CV_M32R_R13 = 23, // Frame Pointer, if allocated + CV_M32R_R14 = 24, // Link Register + CV_M32R_R15 = 25, // Stack Pointer + CV_M32R_PSW = 26, // Preocessor Status Register + CV_M32R_CBR = 27, // Condition Bit Register + CV_M32R_SPI = 28, // Interrupt Stack Pointer + CV_M32R_SPU = 29, // User Stack Pointer + CV_M32R_SPO = 30, // OS Stack Pointer + CV_M32R_BPC = 31, // Backup Program Counter + CV_M32R_ACHI = 32, // Accumulator High + CV_M32R_ACLO = 33, // Accumulator Low + CV_M32R_PC = 34, // Program Counter + + // + // Register set for the SuperH SHMedia processor including compact + // mode + // + + // Integer - 64 bit general registers + CV_SHMEDIA_NOREG = CV_REG_NONE, + CV_SHMEDIA_R0 = 10, + CV_SHMEDIA_R1 = 11, + CV_SHMEDIA_R2 = 12, + CV_SHMEDIA_R3 = 13, + CV_SHMEDIA_R4 = 14, + CV_SHMEDIA_R5 = 15, + CV_SHMEDIA_R6 = 16, + CV_SHMEDIA_R7 = 17, + CV_SHMEDIA_R8 = 18, + CV_SHMEDIA_R9 = 19, + CV_SHMEDIA_R10 = 20, + CV_SHMEDIA_R11 = 21, + CV_SHMEDIA_R12 = 22, + CV_SHMEDIA_R13 = 23, + CV_SHMEDIA_R14 = 24, + CV_SHMEDIA_R15 = 25, + CV_SHMEDIA_R16 = 26, + CV_SHMEDIA_R17 = 27, + CV_SHMEDIA_R18 = 28, + CV_SHMEDIA_R19 = 29, + CV_SHMEDIA_R20 = 30, + CV_SHMEDIA_R21 = 31, + CV_SHMEDIA_R22 = 32, + CV_SHMEDIA_R23 = 33, + CV_SHMEDIA_R24 = 34, + CV_SHMEDIA_R25 = 35, + CV_SHMEDIA_R26 = 36, + CV_SHMEDIA_R27 = 37, + CV_SHMEDIA_R28 = 38, + CV_SHMEDIA_R29 = 39, + CV_SHMEDIA_R30 = 40, + CV_SHMEDIA_R31 = 41, + CV_SHMEDIA_R32 = 42, + CV_SHMEDIA_R33 = 43, + CV_SHMEDIA_R34 = 44, + CV_SHMEDIA_R35 = 45, + CV_SHMEDIA_R36 = 46, + CV_SHMEDIA_R37 = 47, + CV_SHMEDIA_R38 = 48, + CV_SHMEDIA_R39 = 49, + CV_SHMEDIA_R40 = 50, + CV_SHMEDIA_R41 = 51, + CV_SHMEDIA_R42 = 52, + CV_SHMEDIA_R43 = 53, + CV_SHMEDIA_R44 = 54, + CV_SHMEDIA_R45 = 55, + CV_SHMEDIA_R46 = 56, + CV_SHMEDIA_R47 = 57, + CV_SHMEDIA_R48 = 58, + CV_SHMEDIA_R49 = 59, + CV_SHMEDIA_R50 = 60, + CV_SHMEDIA_R51 = 61, + CV_SHMEDIA_R52 = 62, + CV_SHMEDIA_R53 = 63, + CV_SHMEDIA_R54 = 64, + CV_SHMEDIA_R55 = 65, + CV_SHMEDIA_R56 = 66, + CV_SHMEDIA_R57 = 67, + CV_SHMEDIA_R58 = 68, + CV_SHMEDIA_R59 = 69, + CV_SHMEDIA_R60 = 70, + CV_SHMEDIA_R61 = 71, + CV_SHMEDIA_R62 = 72, + CV_SHMEDIA_R63 = 73, + + // Target Registers - 32 bit + CV_SHMEDIA_TR0 = 74, + CV_SHMEDIA_TR1 = 75, + CV_SHMEDIA_TR2 = 76, + CV_SHMEDIA_TR3 = 77, + CV_SHMEDIA_TR4 = 78, + CV_SHMEDIA_TR5 = 79, + CV_SHMEDIA_TR6 = 80, + CV_SHMEDIA_TR7 = 81, + CV_SHMEDIA_TR8 = 82, // future-proof + CV_SHMEDIA_TR9 = 83, // future-proof + CV_SHMEDIA_TR10 = 84, // future-proof + CV_SHMEDIA_TR11 = 85, // future-proof + CV_SHMEDIA_TR12 = 86, // future-proof + CV_SHMEDIA_TR13 = 87, // future-proof + CV_SHMEDIA_TR14 = 88, // future-proof + CV_SHMEDIA_TR15 = 89, // future-proof + + // Single - 32 bit fp registers + CV_SHMEDIA_FR0 = 128, + CV_SHMEDIA_FR1 = 129, + CV_SHMEDIA_FR2 = 130, + CV_SHMEDIA_FR3 = 131, + CV_SHMEDIA_FR4 = 132, + CV_SHMEDIA_FR5 = 133, + CV_SHMEDIA_FR6 = 134, + CV_SHMEDIA_FR7 = 135, + CV_SHMEDIA_FR8 = 136, + CV_SHMEDIA_FR9 = 137, + CV_SHMEDIA_FR10 = 138, + CV_SHMEDIA_FR11 = 139, + CV_SHMEDIA_FR12 = 140, + CV_SHMEDIA_FR13 = 141, + CV_SHMEDIA_FR14 = 142, + CV_SHMEDIA_FR15 = 143, + CV_SHMEDIA_FR16 = 144, + CV_SHMEDIA_FR17 = 145, + CV_SHMEDIA_FR18 = 146, + CV_SHMEDIA_FR19 = 147, + CV_SHMEDIA_FR20 = 148, + CV_SHMEDIA_FR21 = 149, + CV_SHMEDIA_FR22 = 150, + CV_SHMEDIA_FR23 = 151, + CV_SHMEDIA_FR24 = 152, + CV_SHMEDIA_FR25 = 153, + CV_SHMEDIA_FR26 = 154, + CV_SHMEDIA_FR27 = 155, + CV_SHMEDIA_FR28 = 156, + CV_SHMEDIA_FR29 = 157, + CV_SHMEDIA_FR30 = 158, + CV_SHMEDIA_FR31 = 159, + CV_SHMEDIA_FR32 = 160, + CV_SHMEDIA_FR33 = 161, + CV_SHMEDIA_FR34 = 162, + CV_SHMEDIA_FR35 = 163, + CV_SHMEDIA_FR36 = 164, + CV_SHMEDIA_FR37 = 165, + CV_SHMEDIA_FR38 = 166, + CV_SHMEDIA_FR39 = 167, + CV_SHMEDIA_FR40 = 168, + CV_SHMEDIA_FR41 = 169, + CV_SHMEDIA_FR42 = 170, + CV_SHMEDIA_FR43 = 171, + CV_SHMEDIA_FR44 = 172, + CV_SHMEDIA_FR45 = 173, + CV_SHMEDIA_FR46 = 174, + CV_SHMEDIA_FR47 = 175, + CV_SHMEDIA_FR48 = 176, + CV_SHMEDIA_FR49 = 177, + CV_SHMEDIA_FR50 = 178, + CV_SHMEDIA_FR51 = 179, + CV_SHMEDIA_FR52 = 180, + CV_SHMEDIA_FR53 = 181, + CV_SHMEDIA_FR54 = 182, + CV_SHMEDIA_FR55 = 183, + CV_SHMEDIA_FR56 = 184, + CV_SHMEDIA_FR57 = 185, + CV_SHMEDIA_FR58 = 186, + CV_SHMEDIA_FR59 = 187, + CV_SHMEDIA_FR60 = 188, + CV_SHMEDIA_FR61 = 189, + CV_SHMEDIA_FR62 = 190, + CV_SHMEDIA_FR63 = 191, + + // Double - 64 bit synonyms for 32bit fp register pairs + // subtract 128 to find first base single register + CV_SHMEDIA_DR0 = 256, + CV_SHMEDIA_DR2 = 258, + CV_SHMEDIA_DR4 = 260, + CV_SHMEDIA_DR6 = 262, + CV_SHMEDIA_DR8 = 264, + CV_SHMEDIA_DR10 = 266, + CV_SHMEDIA_DR12 = 268, + CV_SHMEDIA_DR14 = 270, + CV_SHMEDIA_DR16 = 272, + CV_SHMEDIA_DR18 = 274, + CV_SHMEDIA_DR20 = 276, + CV_SHMEDIA_DR22 = 278, + CV_SHMEDIA_DR24 = 280, + CV_SHMEDIA_DR26 = 282, + CV_SHMEDIA_DR28 = 284, + CV_SHMEDIA_DR30 = 286, + CV_SHMEDIA_DR32 = 288, + CV_SHMEDIA_DR34 = 290, + CV_SHMEDIA_DR36 = 292, + CV_SHMEDIA_DR38 = 294, + CV_SHMEDIA_DR40 = 296, + CV_SHMEDIA_DR42 = 298, + CV_SHMEDIA_DR44 = 300, + CV_SHMEDIA_DR46 = 302, + CV_SHMEDIA_DR48 = 304, + CV_SHMEDIA_DR50 = 306, + CV_SHMEDIA_DR52 = 308, + CV_SHMEDIA_DR54 = 310, + CV_SHMEDIA_DR56 = 312, + CV_SHMEDIA_DR58 = 314, + CV_SHMEDIA_DR60 = 316, + CV_SHMEDIA_DR62 = 318, + + // Vector - 128 bit synonyms for 32bit fp register quads + // subtract 384 to find first base single register + CV_SHMEDIA_FV0 = 512, + CV_SHMEDIA_FV4 = 516, + CV_SHMEDIA_FV8 = 520, + CV_SHMEDIA_FV12 = 524, + CV_SHMEDIA_FV16 = 528, + CV_SHMEDIA_FV20 = 532, + CV_SHMEDIA_FV24 = 536, + CV_SHMEDIA_FV28 = 540, + CV_SHMEDIA_FV32 = 544, + CV_SHMEDIA_FV36 = 548, + CV_SHMEDIA_FV40 = 552, + CV_SHMEDIA_FV44 = 556, + CV_SHMEDIA_FV48 = 560, + CV_SHMEDIA_FV52 = 564, + CV_SHMEDIA_FV56 = 568, + CV_SHMEDIA_FV60 = 572, + + // Matrix - 512 bit synonyms for 16 adjacent 32bit fp registers + // subtract 896 to find first base single register + CV_SHMEDIA_MTRX0 = 1024, + CV_SHMEDIA_MTRX16 = 1040, + CV_SHMEDIA_MTRX32 = 1056, + CV_SHMEDIA_MTRX48 = 1072, + + // Control - Implementation defined 64bit control registers + CV_SHMEDIA_CR0 = 2000, + CV_SHMEDIA_CR1 = 2001, + CV_SHMEDIA_CR2 = 2002, + CV_SHMEDIA_CR3 = 2003, + CV_SHMEDIA_CR4 = 2004, + CV_SHMEDIA_CR5 = 2005, + CV_SHMEDIA_CR6 = 2006, + CV_SHMEDIA_CR7 = 2007, + CV_SHMEDIA_CR8 = 2008, + CV_SHMEDIA_CR9 = 2009, + CV_SHMEDIA_CR10 = 2010, + CV_SHMEDIA_CR11 = 2011, + CV_SHMEDIA_CR12 = 2012, + CV_SHMEDIA_CR13 = 2013, + CV_SHMEDIA_CR14 = 2014, + CV_SHMEDIA_CR15 = 2015, + CV_SHMEDIA_CR16 = 2016, + CV_SHMEDIA_CR17 = 2017, + CV_SHMEDIA_CR18 = 2018, + CV_SHMEDIA_CR19 = 2019, + CV_SHMEDIA_CR20 = 2020, + CV_SHMEDIA_CR21 = 2021, + CV_SHMEDIA_CR22 = 2022, + CV_SHMEDIA_CR23 = 2023, + CV_SHMEDIA_CR24 = 2024, + CV_SHMEDIA_CR25 = 2025, + CV_SHMEDIA_CR26 = 2026, + CV_SHMEDIA_CR27 = 2027, + CV_SHMEDIA_CR28 = 2028, + CV_SHMEDIA_CR29 = 2029, + CV_SHMEDIA_CR30 = 2030, + CV_SHMEDIA_CR31 = 2031, + CV_SHMEDIA_CR32 = 2032, + CV_SHMEDIA_CR33 = 2033, + CV_SHMEDIA_CR34 = 2034, + CV_SHMEDIA_CR35 = 2035, + CV_SHMEDIA_CR36 = 2036, + CV_SHMEDIA_CR37 = 2037, + CV_SHMEDIA_CR38 = 2038, + CV_SHMEDIA_CR39 = 2039, + CV_SHMEDIA_CR40 = 2040, + CV_SHMEDIA_CR41 = 2041, + CV_SHMEDIA_CR42 = 2042, + CV_SHMEDIA_CR43 = 2043, + CV_SHMEDIA_CR44 = 2044, + CV_SHMEDIA_CR45 = 2045, + CV_SHMEDIA_CR46 = 2046, + CV_SHMEDIA_CR47 = 2047, + CV_SHMEDIA_CR48 = 2048, + CV_SHMEDIA_CR49 = 2049, + CV_SHMEDIA_CR50 = 2050, + CV_SHMEDIA_CR51 = 2051, + CV_SHMEDIA_CR52 = 2052, + CV_SHMEDIA_CR53 = 2053, + CV_SHMEDIA_CR54 = 2054, + CV_SHMEDIA_CR55 = 2055, + CV_SHMEDIA_CR56 = 2056, + CV_SHMEDIA_CR57 = 2057, + CV_SHMEDIA_CR58 = 2058, + CV_SHMEDIA_CR59 = 2059, + CV_SHMEDIA_CR60 = 2060, + CV_SHMEDIA_CR61 = 2061, + CV_SHMEDIA_CR62 = 2062, + CV_SHMEDIA_CR63 = 2063, + + CV_SHMEDIA_FPSCR = 2064, + + // Compact mode synonyms + CV_SHMEDIA_GBR = CV_SHMEDIA_R16, + CV_SHMEDIA_MACL = 90, // synonym for lower 32bits of media R17 + CV_SHMEDIA_MACH = 91, // synonym for upper 32bits of media R17 + CV_SHMEDIA_PR = CV_SHMEDIA_R18, + CV_SHMEDIA_T = 92, // synonym for lowest bit of media R19 + CV_SHMEDIA_FPUL = CV_SHMEDIA_FR32, + CV_SHMEDIA_PC = 93, + CV_SHMEDIA_SR = CV_SHMEDIA_CR0, + + // + // AMD64 registers + // + + CV_AMD64_AL = 1, + CV_AMD64_CL = 2, + CV_AMD64_DL = 3, + CV_AMD64_BL = 4, + CV_AMD64_AH = 5, + CV_AMD64_CH = 6, + CV_AMD64_DH = 7, + CV_AMD64_BH = 8, + CV_AMD64_AX = 9, + CV_AMD64_CX = 10, + CV_AMD64_DX = 11, + CV_AMD64_BX = 12, + CV_AMD64_SP = 13, + CV_AMD64_BP = 14, + CV_AMD64_SI = 15, + CV_AMD64_DI = 16, + CV_AMD64_EAX = 17, + CV_AMD64_ECX = 18, + CV_AMD64_EDX = 19, + CV_AMD64_EBX = 20, + CV_AMD64_ESP = 21, + CV_AMD64_EBP = 22, + CV_AMD64_ESI = 23, + CV_AMD64_EDI = 24, + CV_AMD64_ES = 25, + CV_AMD64_CS = 26, + CV_AMD64_SS = 27, + CV_AMD64_DS = 28, + CV_AMD64_FS = 29, + CV_AMD64_GS = 30, + CV_AMD64_FLAGS = 32, + CV_AMD64_RIP = 33, + CV_AMD64_EFLAGS = 34, + + // Control registers + CV_AMD64_CR0 = 80, + CV_AMD64_CR1 = 81, + CV_AMD64_CR2 = 82, + CV_AMD64_CR3 = 83, + CV_AMD64_CR4 = 84, + CV_AMD64_CR8 = 88, + + // Debug registers + CV_AMD64_DR0 = 90, + CV_AMD64_DR1 = 91, + CV_AMD64_DR2 = 92, + CV_AMD64_DR3 = 93, + CV_AMD64_DR4 = 94, + CV_AMD64_DR5 = 95, + CV_AMD64_DR6 = 96, + CV_AMD64_DR7 = 97, + CV_AMD64_DR8 = 98, + CV_AMD64_DR9 = 99, + CV_AMD64_DR10 = 100, + CV_AMD64_DR11 = 101, + CV_AMD64_DR12 = 102, + CV_AMD64_DR13 = 103, + CV_AMD64_DR14 = 104, + CV_AMD64_DR15 = 105, + + CV_AMD64_GDTR = 110, + CV_AMD64_GDTL = 111, + CV_AMD64_IDTR = 112, + CV_AMD64_IDTL = 113, + CV_AMD64_LDTR = 114, + CV_AMD64_TR = 115, + + CV_AMD64_ST0 = 128, + CV_AMD64_ST1 = 129, + CV_AMD64_ST2 = 130, + CV_AMD64_ST3 = 131, + CV_AMD64_ST4 = 132, + CV_AMD64_ST5 = 133, + CV_AMD64_ST6 = 134, + CV_AMD64_ST7 = 135, + CV_AMD64_CTRL = 136, + CV_AMD64_STAT = 137, + CV_AMD64_TAG = 138, + CV_AMD64_FPIP = 139, + CV_AMD64_FPCS = 140, + CV_AMD64_FPDO = 141, + CV_AMD64_FPDS = 142, + CV_AMD64_ISEM = 143, + CV_AMD64_FPEIP = 144, + CV_AMD64_FPEDO = 145, + + CV_AMD64_MM0 = 146, + CV_AMD64_MM1 = 147, + CV_AMD64_MM2 = 148, + CV_AMD64_MM3 = 149, + CV_AMD64_MM4 = 150, + CV_AMD64_MM5 = 151, + CV_AMD64_MM6 = 152, + CV_AMD64_MM7 = 153, + + CV_AMD64_XMM0 = 154, // KATMAI registers + CV_AMD64_XMM1 = 155, + CV_AMD64_XMM2 = 156, + CV_AMD64_XMM3 = 157, + CV_AMD64_XMM4 = 158, + CV_AMD64_XMM5 = 159, + CV_AMD64_XMM6 = 160, + CV_AMD64_XMM7 = 161, + + CV_AMD64_XMM0_0 = 162, // KATMAI sub-registers + CV_AMD64_XMM0_1 = 163, + CV_AMD64_XMM0_2 = 164, + CV_AMD64_XMM0_3 = 165, + CV_AMD64_XMM1_0 = 166, + CV_AMD64_XMM1_1 = 167, + CV_AMD64_XMM1_2 = 168, + CV_AMD64_XMM1_3 = 169, + CV_AMD64_XMM2_0 = 170, + CV_AMD64_XMM2_1 = 171, + CV_AMD64_XMM2_2 = 172, + CV_AMD64_XMM2_3 = 173, + CV_AMD64_XMM3_0 = 174, + CV_AMD64_XMM3_1 = 175, + CV_AMD64_XMM3_2 = 176, + CV_AMD64_XMM3_3 = 177, + CV_AMD64_XMM4_0 = 178, + CV_AMD64_XMM4_1 = 179, + CV_AMD64_XMM4_2 = 180, + CV_AMD64_XMM4_3 = 181, + CV_AMD64_XMM5_0 = 182, + CV_AMD64_XMM5_1 = 183, + CV_AMD64_XMM5_2 = 184, + CV_AMD64_XMM5_3 = 185, + CV_AMD64_XMM6_0 = 186, + CV_AMD64_XMM6_1 = 187, + CV_AMD64_XMM6_2 = 188, + CV_AMD64_XMM6_3 = 189, + CV_AMD64_XMM7_0 = 190, + CV_AMD64_XMM7_1 = 191, + CV_AMD64_XMM7_2 = 192, + CV_AMD64_XMM7_3 = 193, + + CV_AMD64_XMM0L = 194, + CV_AMD64_XMM1L = 195, + CV_AMD64_XMM2L = 196, + CV_AMD64_XMM3L = 197, + CV_AMD64_XMM4L = 198, + CV_AMD64_XMM5L = 199, + CV_AMD64_XMM6L = 200, + CV_AMD64_XMM7L = 201, + + CV_AMD64_XMM0H = 202, + CV_AMD64_XMM1H = 203, + CV_AMD64_XMM2H = 204, + CV_AMD64_XMM3H = 205, + CV_AMD64_XMM4H = 206, + CV_AMD64_XMM5H = 207, + CV_AMD64_XMM6H = 208, + CV_AMD64_XMM7H = 209, + + CV_AMD64_MXCSR = 211, // XMM status register + + CV_AMD64_EMM0L = 220, // XMM sub-registers (WNI integer) + CV_AMD64_EMM1L = 221, + CV_AMD64_EMM2L = 222, + CV_AMD64_EMM3L = 223, + CV_AMD64_EMM4L = 224, + CV_AMD64_EMM5L = 225, + CV_AMD64_EMM6L = 226, + CV_AMD64_EMM7L = 227, + + CV_AMD64_EMM0H = 228, + CV_AMD64_EMM1H = 229, + CV_AMD64_EMM2H = 230, + CV_AMD64_EMM3H = 231, + CV_AMD64_EMM4H = 232, + CV_AMD64_EMM5H = 233, + CV_AMD64_EMM6H = 234, + CV_AMD64_EMM7H = 235, + + // do not change the order of these regs, first one must be even too + CV_AMD64_MM00 = 236, + CV_AMD64_MM01 = 237, + CV_AMD64_MM10 = 238, + CV_AMD64_MM11 = 239, + CV_AMD64_MM20 = 240, + CV_AMD64_MM21 = 241, + CV_AMD64_MM30 = 242, + CV_AMD64_MM31 = 243, + CV_AMD64_MM40 = 244, + CV_AMD64_MM41 = 245, + CV_AMD64_MM50 = 246, + CV_AMD64_MM51 = 247, + CV_AMD64_MM60 = 248, + CV_AMD64_MM61 = 249, + CV_AMD64_MM70 = 250, + CV_AMD64_MM71 = 251, + + // Extended KATMAI registers + CV_AMD64_XMM8 = 252, // KATMAI registers + CV_AMD64_XMM9 = 253, + CV_AMD64_XMM10 = 254, + CV_AMD64_XMM11 = 255, + CV_AMD64_XMM12 = 256, + CV_AMD64_XMM13 = 257, + CV_AMD64_XMM14 = 258, + CV_AMD64_XMM15 = 259, + + CV_AMD64_XMM8_0 = 260, // KATMAI sub-registers + CV_AMD64_XMM8_1 = 261, + CV_AMD64_XMM8_2 = 262, + CV_AMD64_XMM8_3 = 263, + CV_AMD64_XMM9_0 = 264, + CV_AMD64_XMM9_1 = 265, + CV_AMD64_XMM9_2 = 266, + CV_AMD64_XMM9_3 = 267, + CV_AMD64_XMM10_0 = 268, + CV_AMD64_XMM10_1 = 269, + CV_AMD64_XMM10_2 = 270, + CV_AMD64_XMM10_3 = 271, + CV_AMD64_XMM11_0 = 272, + CV_AMD64_XMM11_1 = 273, + CV_AMD64_XMM11_2 = 274, + CV_AMD64_XMM11_3 = 275, + CV_AMD64_XMM12_0 = 276, + CV_AMD64_XMM12_1 = 277, + CV_AMD64_XMM12_2 = 278, + CV_AMD64_XMM12_3 = 279, + CV_AMD64_XMM13_0 = 280, + CV_AMD64_XMM13_1 = 281, + CV_AMD64_XMM13_2 = 282, + CV_AMD64_XMM13_3 = 283, + CV_AMD64_XMM14_0 = 284, + CV_AMD64_XMM14_1 = 285, + CV_AMD64_XMM14_2 = 286, + CV_AMD64_XMM14_3 = 287, + CV_AMD64_XMM15_0 = 288, + CV_AMD64_XMM15_1 = 289, + CV_AMD64_XMM15_2 = 290, + CV_AMD64_XMM15_3 = 291, + + CV_AMD64_XMM8L = 292, + CV_AMD64_XMM9L = 293, + CV_AMD64_XMM10L = 294, + CV_AMD64_XMM11L = 295, + CV_AMD64_XMM12L = 296, + CV_AMD64_XMM13L = 297, + CV_AMD64_XMM14L = 298, + CV_AMD64_XMM15L = 299, + + CV_AMD64_XMM8H = 300, + CV_AMD64_XMM9H = 301, + CV_AMD64_XMM10H = 302, + CV_AMD64_XMM11H = 303, + CV_AMD64_XMM12H = 304, + CV_AMD64_XMM13H = 305, + CV_AMD64_XMM14H = 306, + CV_AMD64_XMM15H = 307, + + CV_AMD64_EMM8L = 308, // XMM sub-registers (WNI integer) + CV_AMD64_EMM9L = 309, + CV_AMD64_EMM10L = 310, + CV_AMD64_EMM11L = 311, + CV_AMD64_EMM12L = 312, + CV_AMD64_EMM13L = 313, + CV_AMD64_EMM14L = 314, + CV_AMD64_EMM15L = 315, + + CV_AMD64_EMM8H = 316, + CV_AMD64_EMM9H = 317, + CV_AMD64_EMM10H = 318, + CV_AMD64_EMM11H = 319, + CV_AMD64_EMM12H = 320, + CV_AMD64_EMM13H = 321, + CV_AMD64_EMM14H = 322, + CV_AMD64_EMM15H = 323, + + // Low byte forms of some standard registers + CV_AMD64_SIL = 324, + CV_AMD64_DIL = 325, + CV_AMD64_BPL = 326, + CV_AMD64_SPL = 327, + + // 64-bit regular registers + CV_AMD64_RAX = 328, + CV_AMD64_RBX = 329, + CV_AMD64_RCX = 330, + CV_AMD64_RDX = 331, + CV_AMD64_RSI = 332, + CV_AMD64_RDI = 333, + CV_AMD64_RBP = 334, + CV_AMD64_RSP = 335, + + // 64-bit integer registers with 8-, 16-, and 32-bit forms (B, W, and D) + CV_AMD64_R8 = 336, + CV_AMD64_R9 = 337, + CV_AMD64_R10 = 338, + CV_AMD64_R11 = 339, + CV_AMD64_R12 = 340, + CV_AMD64_R13 = 341, + CV_AMD64_R14 = 342, + CV_AMD64_R15 = 343, + + CV_AMD64_R8B = 344, + CV_AMD64_R9B = 345, + CV_AMD64_R10B = 346, + CV_AMD64_R11B = 347, + CV_AMD64_R12B = 348, + CV_AMD64_R13B = 349, + CV_AMD64_R14B = 350, + CV_AMD64_R15B = 351, + + CV_AMD64_R8W = 352, + CV_AMD64_R9W = 353, + CV_AMD64_R10W = 354, + CV_AMD64_R11W = 355, + CV_AMD64_R12W = 356, + CV_AMD64_R13W = 357, + CV_AMD64_R14W = 358, + CV_AMD64_R15W = 359, + + CV_AMD64_R8D = 360, + CV_AMD64_R9D = 361, + CV_AMD64_R10D = 362, + CV_AMD64_R11D = 363, + CV_AMD64_R12D = 364, + CV_AMD64_R13D = 365, + CV_AMD64_R14D = 366, + CV_AMD64_R15D = 367, + + // AVX registers 256 bits + CV_AMD64_YMM0 = 368, + CV_AMD64_YMM1 = 369, + CV_AMD64_YMM2 = 370, + CV_AMD64_YMM3 = 371, + CV_AMD64_YMM4 = 372, + CV_AMD64_YMM5 = 373, + CV_AMD64_YMM6 = 374, + CV_AMD64_YMM7 = 375, + CV_AMD64_YMM8 = 376, + CV_AMD64_YMM9 = 377, + CV_AMD64_YMM10 = 378, + CV_AMD64_YMM11 = 379, + CV_AMD64_YMM12 = 380, + CV_AMD64_YMM13 = 381, + CV_AMD64_YMM14 = 382, + CV_AMD64_YMM15 = 383, + + // AVX registers upper 128 bits + CV_AMD64_YMM0H = 384, + CV_AMD64_YMM1H = 385, + CV_AMD64_YMM2H = 386, + CV_AMD64_YMM3H = 387, + CV_AMD64_YMM4H = 388, + CV_AMD64_YMM5H = 389, + CV_AMD64_YMM6H = 390, + CV_AMD64_YMM7H = 391, + CV_AMD64_YMM8H = 392, + CV_AMD64_YMM9H = 393, + CV_AMD64_YMM10H = 394, + CV_AMD64_YMM11H = 395, + CV_AMD64_YMM12H = 396, + CV_AMD64_YMM13H = 397, + CV_AMD64_YMM14H = 398, + CV_AMD64_YMM15H = 399, + + //Lower/upper 8 bytes of XMM registers. Unlike CV_AMD64_XMM, these + //values reprsesent the bit patterns of the registers as 64-bit integers, not + //the representation of these registers as a double. + CV_AMD64_XMM0IL = 400, + CV_AMD64_XMM1IL = 401, + CV_AMD64_XMM2IL = 402, + CV_AMD64_XMM3IL = 403, + CV_AMD64_XMM4IL = 404, + CV_AMD64_XMM5IL = 405, + CV_AMD64_XMM6IL = 406, + CV_AMD64_XMM7IL = 407, + CV_AMD64_XMM8IL = 408, + CV_AMD64_XMM9IL = 409, + CV_AMD64_XMM10IL = 410, + CV_AMD64_XMM11IL = 411, + CV_AMD64_XMM12IL = 412, + CV_AMD64_XMM13IL = 413, + CV_AMD64_XMM14IL = 414, + CV_AMD64_XMM15IL = 415, + + CV_AMD64_XMM0IH = 416, + CV_AMD64_XMM1IH = 417, + CV_AMD64_XMM2IH = 418, + CV_AMD64_XMM3IH = 419, + CV_AMD64_XMM4IH = 420, + CV_AMD64_XMM5IH = 421, + CV_AMD64_XMM6IH = 422, + CV_AMD64_XMM7IH = 423, + CV_AMD64_XMM8IH = 424, + CV_AMD64_XMM9IH = 425, + CV_AMD64_XMM10IH = 426, + CV_AMD64_XMM11IH = 427, + CV_AMD64_XMM12IH = 428, + CV_AMD64_XMM13IH = 429, + CV_AMD64_XMM14IH = 430, + CV_AMD64_XMM15IH = 431, + + CV_AMD64_YMM0I0 = 432, // AVX integer registers + CV_AMD64_YMM0I1 = 433, + CV_AMD64_YMM0I2 = 434, + CV_AMD64_YMM0I3 = 435, + CV_AMD64_YMM1I0 = 436, + CV_AMD64_YMM1I1 = 437, + CV_AMD64_YMM1I2 = 438, + CV_AMD64_YMM1I3 = 439, + CV_AMD64_YMM2I0 = 440, + CV_AMD64_YMM2I1 = 441, + CV_AMD64_YMM2I2 = 442, + CV_AMD64_YMM2I3 = 443, + CV_AMD64_YMM3I0 = 444, + CV_AMD64_YMM3I1 = 445, + CV_AMD64_YMM3I2 = 446, + CV_AMD64_YMM3I3 = 447, + CV_AMD64_YMM4I0 = 448, + CV_AMD64_YMM4I1 = 449, + CV_AMD64_YMM4I2 = 450, + CV_AMD64_YMM4I3 = 451, + CV_AMD64_YMM5I0 = 452, + CV_AMD64_YMM5I1 = 453, + CV_AMD64_YMM5I2 = 454, + CV_AMD64_YMM5I3 = 455, + CV_AMD64_YMM6I0 = 456, + CV_AMD64_YMM6I1 = 457, + CV_AMD64_YMM6I2 = 458, + CV_AMD64_YMM6I3 = 459, + CV_AMD64_YMM7I0 = 460, + CV_AMD64_YMM7I1 = 461, + CV_AMD64_YMM7I2 = 462, + CV_AMD64_YMM7I3 = 463, + CV_AMD64_YMM8I0 = 464, + CV_AMD64_YMM8I1 = 465, + CV_AMD64_YMM8I2 = 466, + CV_AMD64_YMM8I3 = 467, + CV_AMD64_YMM9I0 = 468, + CV_AMD64_YMM9I1 = 469, + CV_AMD64_YMM9I2 = 470, + CV_AMD64_YMM9I3 = 471, + CV_AMD64_YMM10I0 = 472, + CV_AMD64_YMM10I1 = 473, + CV_AMD64_YMM10I2 = 474, + CV_AMD64_YMM10I3 = 475, + CV_AMD64_YMM11I0 = 476, + CV_AMD64_YMM11I1 = 477, + CV_AMD64_YMM11I2 = 478, + CV_AMD64_YMM11I3 = 479, + CV_AMD64_YMM12I0 = 480, + CV_AMD64_YMM12I1 = 481, + CV_AMD64_YMM12I2 = 482, + CV_AMD64_YMM12I3 = 483, + CV_AMD64_YMM13I0 = 484, + CV_AMD64_YMM13I1 = 485, + CV_AMD64_YMM13I2 = 486, + CV_AMD64_YMM13I3 = 487, + CV_AMD64_YMM14I0 = 488, + CV_AMD64_YMM14I1 = 489, + CV_AMD64_YMM14I2 = 490, + CV_AMD64_YMM14I3 = 491, + CV_AMD64_YMM15I0 = 492, + CV_AMD64_YMM15I1 = 493, + CV_AMD64_YMM15I2 = 494, + CV_AMD64_YMM15I3 = 495, + + CV_AMD64_YMM0F0 = 496, // AVX floating-point single precise registers + CV_AMD64_YMM0F1 = 497, + CV_AMD64_YMM0F2 = 498, + CV_AMD64_YMM0F3 = 499, + CV_AMD64_YMM0F4 = 500, + CV_AMD64_YMM0F5 = 501, + CV_AMD64_YMM0F6 = 502, + CV_AMD64_YMM0F7 = 503, + CV_AMD64_YMM1F0 = 504, + CV_AMD64_YMM1F1 = 505, + CV_AMD64_YMM1F2 = 506, + CV_AMD64_YMM1F3 = 507, + CV_AMD64_YMM1F4 = 508, + CV_AMD64_YMM1F5 = 509, + CV_AMD64_YMM1F6 = 510, + CV_AMD64_YMM1F7 = 511, + CV_AMD64_YMM2F0 = 512, + CV_AMD64_YMM2F1 = 513, + CV_AMD64_YMM2F2 = 514, + CV_AMD64_YMM2F3 = 515, + CV_AMD64_YMM2F4 = 516, + CV_AMD64_YMM2F5 = 517, + CV_AMD64_YMM2F6 = 518, + CV_AMD64_YMM2F7 = 519, + CV_AMD64_YMM3F0 = 520, + CV_AMD64_YMM3F1 = 521, + CV_AMD64_YMM3F2 = 522, + CV_AMD64_YMM3F3 = 523, + CV_AMD64_YMM3F4 = 524, + CV_AMD64_YMM3F5 = 525, + CV_AMD64_YMM3F6 = 526, + CV_AMD64_YMM3F7 = 527, + CV_AMD64_YMM4F0 = 528, + CV_AMD64_YMM4F1 = 529, + CV_AMD64_YMM4F2 = 530, + CV_AMD64_YMM4F3 = 531, + CV_AMD64_YMM4F4 = 532, + CV_AMD64_YMM4F5 = 533, + CV_AMD64_YMM4F6 = 534, + CV_AMD64_YMM4F7 = 535, + CV_AMD64_YMM5F0 = 536, + CV_AMD64_YMM5F1 = 537, + CV_AMD64_YMM5F2 = 538, + CV_AMD64_YMM5F3 = 539, + CV_AMD64_YMM5F4 = 540, + CV_AMD64_YMM5F5 = 541, + CV_AMD64_YMM5F6 = 542, + CV_AMD64_YMM5F7 = 543, + CV_AMD64_YMM6F0 = 544, + CV_AMD64_YMM6F1 = 545, + CV_AMD64_YMM6F2 = 546, + CV_AMD64_YMM6F3 = 547, + CV_AMD64_YMM6F4 = 548, + CV_AMD64_YMM6F5 = 549, + CV_AMD64_YMM6F6 = 550, + CV_AMD64_YMM6F7 = 551, + CV_AMD64_YMM7F0 = 552, + CV_AMD64_YMM7F1 = 553, + CV_AMD64_YMM7F2 = 554, + CV_AMD64_YMM7F3 = 555, + CV_AMD64_YMM7F4 = 556, + CV_AMD64_YMM7F5 = 557, + CV_AMD64_YMM7F6 = 558, + CV_AMD64_YMM7F7 = 559, + CV_AMD64_YMM8F0 = 560, + CV_AMD64_YMM8F1 = 561, + CV_AMD64_YMM8F2 = 562, + CV_AMD64_YMM8F3 = 563, + CV_AMD64_YMM8F4 = 564, + CV_AMD64_YMM8F5 = 565, + CV_AMD64_YMM8F6 = 566, + CV_AMD64_YMM8F7 = 567, + CV_AMD64_YMM9F0 = 568, + CV_AMD64_YMM9F1 = 569, + CV_AMD64_YMM9F2 = 570, + CV_AMD64_YMM9F3 = 571, + CV_AMD64_YMM9F4 = 572, + CV_AMD64_YMM9F5 = 573, + CV_AMD64_YMM9F6 = 574, + CV_AMD64_YMM9F7 = 575, + CV_AMD64_YMM10F0 = 576, + CV_AMD64_YMM10F1 = 577, + CV_AMD64_YMM10F2 = 578, + CV_AMD64_YMM10F3 = 579, + CV_AMD64_YMM10F4 = 580, + CV_AMD64_YMM10F5 = 581, + CV_AMD64_YMM10F6 = 582, + CV_AMD64_YMM10F7 = 583, + CV_AMD64_YMM11F0 = 584, + CV_AMD64_YMM11F1 = 585, + CV_AMD64_YMM11F2 = 586, + CV_AMD64_YMM11F3 = 587, + CV_AMD64_YMM11F4 = 588, + CV_AMD64_YMM11F5 = 589, + CV_AMD64_YMM11F6 = 590, + CV_AMD64_YMM11F7 = 591, + CV_AMD64_YMM12F0 = 592, + CV_AMD64_YMM12F1 = 593, + CV_AMD64_YMM12F2 = 594, + CV_AMD64_YMM12F3 = 595, + CV_AMD64_YMM12F4 = 596, + CV_AMD64_YMM12F5 = 597, + CV_AMD64_YMM12F6 = 598, + CV_AMD64_YMM12F7 = 599, + CV_AMD64_YMM13F0 = 600, + CV_AMD64_YMM13F1 = 601, + CV_AMD64_YMM13F2 = 602, + CV_AMD64_YMM13F3 = 603, + CV_AMD64_YMM13F4 = 604, + CV_AMD64_YMM13F5 = 605, + CV_AMD64_YMM13F6 = 606, + CV_AMD64_YMM13F7 = 607, + CV_AMD64_YMM14F0 = 608, + CV_AMD64_YMM14F1 = 609, + CV_AMD64_YMM14F2 = 610, + CV_AMD64_YMM14F3 = 611, + CV_AMD64_YMM14F4 = 612, + CV_AMD64_YMM14F5 = 613, + CV_AMD64_YMM14F6 = 614, + CV_AMD64_YMM14F7 = 615, + CV_AMD64_YMM15F0 = 616, + CV_AMD64_YMM15F1 = 617, + CV_AMD64_YMM15F2 = 618, + CV_AMD64_YMM15F3 = 619, + CV_AMD64_YMM15F4 = 620, + CV_AMD64_YMM15F5 = 621, + CV_AMD64_YMM15F6 = 622, + CV_AMD64_YMM15F7 = 623, + + CV_AMD64_YMM0D0 = 624, // AVX floating-point double precise registers + CV_AMD64_YMM0D1 = 625, + CV_AMD64_YMM0D2 = 626, + CV_AMD64_YMM0D3 = 627, + CV_AMD64_YMM1D0 = 628, + CV_AMD64_YMM1D1 = 629, + CV_AMD64_YMM1D2 = 630, + CV_AMD64_YMM1D3 = 631, + CV_AMD64_YMM2D0 = 632, + CV_AMD64_YMM2D1 = 633, + CV_AMD64_YMM2D2 = 634, + CV_AMD64_YMM2D3 = 635, + CV_AMD64_YMM3D0 = 636, + CV_AMD64_YMM3D1 = 637, + CV_AMD64_YMM3D2 = 638, + CV_AMD64_YMM3D3 = 639, + CV_AMD64_YMM4D0 = 640, + CV_AMD64_YMM4D1 = 641, + CV_AMD64_YMM4D2 = 642, + CV_AMD64_YMM4D3 = 643, + CV_AMD64_YMM5D0 = 644, + CV_AMD64_YMM5D1 = 645, + CV_AMD64_YMM5D2 = 646, + CV_AMD64_YMM5D3 = 647, + CV_AMD64_YMM6D0 = 648, + CV_AMD64_YMM6D1 = 649, + CV_AMD64_YMM6D2 = 650, + CV_AMD64_YMM6D3 = 651, + CV_AMD64_YMM7D0 = 652, + CV_AMD64_YMM7D1 = 653, + CV_AMD64_YMM7D2 = 654, + CV_AMD64_YMM7D3 = 655, + CV_AMD64_YMM8D0 = 656, + CV_AMD64_YMM8D1 = 657, + CV_AMD64_YMM8D2 = 658, + CV_AMD64_YMM8D3 = 659, + CV_AMD64_YMM9D0 = 660, + CV_AMD64_YMM9D1 = 661, + CV_AMD64_YMM9D2 = 662, + CV_AMD64_YMM9D3 = 663, + CV_AMD64_YMM10D0 = 664, + CV_AMD64_YMM10D1 = 665, + CV_AMD64_YMM10D2 = 666, + CV_AMD64_YMM10D3 = 667, + CV_AMD64_YMM11D0 = 668, + CV_AMD64_YMM11D1 = 669, + CV_AMD64_YMM11D2 = 670, + CV_AMD64_YMM11D3 = 671, + CV_AMD64_YMM12D0 = 672, + CV_AMD64_YMM12D1 = 673, + CV_AMD64_YMM12D2 = 674, + CV_AMD64_YMM12D3 = 675, + CV_AMD64_YMM13D0 = 676, + CV_AMD64_YMM13D1 = 677, + CV_AMD64_YMM13D2 = 678, + CV_AMD64_YMM13D3 = 679, + CV_AMD64_YMM14D0 = 680, + CV_AMD64_YMM14D1 = 681, + CV_AMD64_YMM14D2 = 682, + CV_AMD64_YMM14D3 = 683, + CV_AMD64_YMM15D0 = 684, + CV_AMD64_YMM15D1 = 685, + CV_AMD64_YMM15D2 = 686, + CV_AMD64_YMM15D3 = 687, + + CV_AMD64_BND0 = 688, // AMD64 MPX bounds registers + CV_AMD64_BND1 = 689, + CV_AMD64_BND2 = 690, + CV_AMD64_BND3 = 691, + CV_AMD64_BNDCFGU = 692, + CV_AMD64_BNDSTATUS = 693, + + CV_AMD64_XMM16 = 694, // AVX-512 registers + CV_AMD64_XMM17 = 695, + CV_AMD64_XMM18 = 696, + CV_AMD64_XMM19 = 697, + CV_AMD64_XMM20 = 698, + CV_AMD64_XMM21 = 699, + CV_AMD64_XMM22 = 700, + CV_AMD64_XMM23 = 701, + CV_AMD64_XMM24 = 702, + CV_AMD64_XMM25 = 703, + CV_AMD64_XMM26 = 704, + CV_AMD64_XMM27 = 705, + CV_AMD64_XMM28 = 706, + CV_AMD64_XMM29 = 707, + CV_AMD64_XMM30 = 708, + CV_AMD64_XMM31 = 709, + + CV_AMD64_YMM16 = 710, + CV_AMD64_YMM17 = 711, + CV_AMD64_YMM18 = 712, + CV_AMD64_YMM19 = 713, + CV_AMD64_YMM20 = 714, + CV_AMD64_YMM21 = 715, + CV_AMD64_YMM22 = 716, + CV_AMD64_YMM23 = 717, + CV_AMD64_YMM24 = 718, + CV_AMD64_YMM25 = 719, + CV_AMD64_YMM26 = 720, + CV_AMD64_YMM27 = 721, + CV_AMD64_YMM28 = 722, + CV_AMD64_YMM29 = 723, + CV_AMD64_YMM30 = 724, + CV_AMD64_YMM31 = 725, + + CV_AMD64_ZMM0 = 726, + CV_AMD64_ZMM1 = 727, + CV_AMD64_ZMM2 = 728, + CV_AMD64_ZMM3 = 729, + CV_AMD64_ZMM4 = 730, + CV_AMD64_ZMM5 = 731, + CV_AMD64_ZMM6 = 732, + CV_AMD64_ZMM7 = 733, + CV_AMD64_ZMM8 = 734, + CV_AMD64_ZMM9 = 735, + CV_AMD64_ZMM10 = 736, + CV_AMD64_ZMM11 = 737, + CV_AMD64_ZMM12 = 738, + CV_AMD64_ZMM13 = 739, + CV_AMD64_ZMM14 = 740, + CV_AMD64_ZMM15 = 741, + CV_AMD64_ZMM16 = 742, + CV_AMD64_ZMM17 = 743, + CV_AMD64_ZMM18 = 744, + CV_AMD64_ZMM19 = 745, + CV_AMD64_ZMM20 = 746, + CV_AMD64_ZMM21 = 747, + CV_AMD64_ZMM22 = 748, + CV_AMD64_ZMM23 = 749, + CV_AMD64_ZMM24 = 750, + CV_AMD64_ZMM25 = 751, + CV_AMD64_ZMM26 = 752, + CV_AMD64_ZMM27 = 753, + CV_AMD64_ZMM28 = 754, + CV_AMD64_ZMM29 = 755, + CV_AMD64_ZMM30 = 756, + CV_AMD64_ZMM31 = 757, + + CV_AMD64_K0 = 758, + CV_AMD64_K1 = 759, + CV_AMD64_K2 = 760, + CV_AMD64_K3 = 761, + CV_AMD64_K4 = 762, + CV_AMD64_K5 = 763, + CV_AMD64_K6 = 764, + CV_AMD64_K7 = 765, + + CV_AMD64_ZMM0H = 766, // upper 256 bits of the first 16 AMD64 AVX-512 registers + CV_AMD64_ZMM1H = 767, + CV_AMD64_ZMM2H = 768, + CV_AMD64_ZMM3H = 769, + CV_AMD64_ZMM4H = 770, + CV_AMD64_ZMM5H = 771, + CV_AMD64_ZMM6H = 772, + CV_AMD64_ZMM7H = 773, + CV_AMD64_ZMM8H = 774, + CV_AMD64_ZMM9H = 775, + CV_AMD64_ZMM10H = 776, + CV_AMD64_ZMM11H = 777, + CV_AMD64_ZMM12H = 778, + CV_AMD64_ZMM13H = 779, + CV_AMD64_ZMM14H = 780, + CV_AMD64_ZMM15H = 781, + + CV_AMD64_XMM16L = 782, // extended KATMAI registers + CV_AMD64_XMM17L = 783, + CV_AMD64_XMM18L = 784, + CV_AMD64_XMM19L = 785, + CV_AMD64_XMM20L = 786, + CV_AMD64_XMM21L = 787, + CV_AMD64_XMM22L = 788, + CV_AMD64_XMM23L = 789, + CV_AMD64_XMM24L = 790, + CV_AMD64_XMM25L = 791, + CV_AMD64_XMM26L = 792, + CV_AMD64_XMM27L = 793, + CV_AMD64_XMM28L = 794, + CV_AMD64_XMM29L = 795, + CV_AMD64_XMM30L = 796, + CV_AMD64_XMM31L = 797, + + CV_AMD64_XMM16_0 = 798, + CV_AMD64_XMM17_0 = 799, + CV_AMD64_XMM18_0 = 800, + CV_AMD64_XMM19_0 = 801, + CV_AMD64_XMM20_0 = 802, + CV_AMD64_XMM21_0 = 803, + CV_AMD64_XMM22_0 = 804, + CV_AMD64_XMM23_0 = 805, + CV_AMD64_XMM24_0 = 806, + CV_AMD64_XMM25_0 = 807, + CV_AMD64_XMM26_0 = 808, + CV_AMD64_XMM27_0 = 809, + CV_AMD64_XMM28_0 = 810, + CV_AMD64_XMM29_0 = 811, + CV_AMD64_XMM30_0 = 812, + CV_AMD64_XMM31_0 = 813, + + CV_AMD64_XMM16H = 814, + CV_AMD64_XMM17H = 815, + CV_AMD64_XMM18H = 816, + CV_AMD64_XMM19H = 817, + CV_AMD64_XMM20H = 818, + CV_AMD64_XMM21H = 819, + CV_AMD64_XMM22H = 820, + CV_AMD64_XMM23H = 821, + CV_AMD64_XMM24H = 822, + CV_AMD64_XMM25H = 823, + CV_AMD64_XMM26H = 824, + CV_AMD64_XMM27H = 825, + CV_AMD64_XMM28H = 826, + CV_AMD64_XMM29H = 827, + CV_AMD64_XMM30H = 828, + CV_AMD64_XMM31H = 829, + + CV_AMD64_EMM16H = 830, + CV_AMD64_EMM17H = 831, + CV_AMD64_EMM18H = 832, + CV_AMD64_EMM19H = 833, + CV_AMD64_EMM20H = 834, + CV_AMD64_EMM21H = 835, + CV_AMD64_EMM22H = 836, + CV_AMD64_EMM23H = 837, + CV_AMD64_EMM24H = 838, + CV_AMD64_EMM25H = 839, + CV_AMD64_EMM26H = 840, + CV_AMD64_EMM27H = 841, + CV_AMD64_EMM28H = 842, + CV_AMD64_EMM29H = 843, + CV_AMD64_EMM30H = 844, + CV_AMD64_EMM31H = 845, + + CV_AMD64_SSP = 846, // CET- Shadow Stack Pointer + + CV_AMD64_TMM0 = 847, // AMX tile registers + CV_AMD64_TMM1 = 848, + CV_AMD64_TMM2 = 849, + CV_AMD64_TMM3 = 850, + CV_AMD64_TMM4 = 851, + CV_AMD64_TMM5 = 852, + CV_AMD64_TMM6 = 853, + CV_AMD64_TMM7 = 854, + + // Note: Next set of platform registers need to go into a new enum... + // this one is above 44K now. + +} CV_HREG_e; + +typedef enum CV_HLSLREG_e +{ + CV_HLSLREG_TEMP = 0, + CV_HLSLREG_INPUT = 1, + CV_HLSLREG_OUTPUT = 2, + CV_HLSLREG_INDEXABLE_TEMP = 3, + CV_HLSLREG_IMMEDIATE32 = 4, + CV_HLSLREG_IMMEDIATE64 = 5, + CV_HLSLREG_SAMPLER = 6, + CV_HLSLREG_RESOURCE = 7, + CV_HLSLREG_CONSTANT_BUFFER = 8, + CV_HLSLREG_IMMEDIATE_CONSTANT_BUFFER = 9, + CV_HLSLREG_LABEL = 10, + CV_HLSLREG_INPUT_PRIMITIVEID = 11, + CV_HLSLREG_OUTPUT_DEPTH = 12, + CV_HLSLREG_NULL = 13, + CV_HLSLREG_RASTERIZER = 14, + CV_HLSLREG_OUTPUT_COVERAGE_MASK = 15, + CV_HLSLREG_STREAM = 16, + CV_HLSLREG_FUNCTION_BODY = 17, + CV_HLSLREG_FUNCTION_TABLE = 18, + CV_HLSLREG_INTERFACE = 19, + CV_HLSLREG_FUNCTION_INPUT = 20, + CV_HLSLREG_FUNCTION_OUTPUT = 21, + CV_HLSLREG_OUTPUT_CONTROL_POINT_ID = 22, + CV_HLSLREG_INPUT_FORK_INSTANCE_ID = 23, + CV_HLSLREG_INPUT_JOIN_INSTANCE_ID = 24, + CV_HLSLREG_INPUT_CONTROL_POINT = 25, + CV_HLSLREG_OUTPUT_CONTROL_POINT = 26, + CV_HLSLREG_INPUT_PATCH_CONSTANT = 27, + CV_HLSLREG_INPUT_DOMAIN_POINT = 28, + CV_HLSLREG_THIS_POINTER = 29, + CV_HLSLREG_UNORDERED_ACCESS_VIEW = 30, + CV_HLSLREG_THREAD_GROUP_SHARED_MEMORY = 31, + CV_HLSLREG_INPUT_THREAD_ID = 32, + CV_HLSLREG_INPUT_THREAD_GROUP_ID = 33, + CV_HLSLREG_INPUT_THREAD_ID_IN_GROUP = 34, + CV_HLSLREG_INPUT_COVERAGE_MASK = 35, + CV_HLSLREG_INPUT_THREAD_ID_IN_GROUP_FLATTENED = 36, + CV_HLSLREG_INPUT_GS_INSTANCE_ID = 37, + CV_HLSLREG_OUTPUT_DEPTH_GREATER_EQUAL = 38, + CV_HLSLREG_OUTPUT_DEPTH_LESS_EQUAL = 39, + CV_HLSLREG_CYCLE_COUNTER = 40, +} CV_HLSLREG_e; + +enum StackFrameTypeEnum +{ + FrameTypeFPO, // Frame pointer omitted, FPO info available + FrameTypeTrap, // Kernel Trap frame + FrameTypeTSS, // Kernel Trap frame + FrameTypeStandard, // Standard EBP stackframe + FrameTypeFrameData, // Frame pointer omitted, FrameData info available + + FrameTypeUnknown = -1, // Frame which does not have any debug info +}; + +enum MemoryTypeEnum +{ + MemTypeCode, // Read only code memory + MemTypeData, // Read only data/stack memory + MemTypeStack, // Read only stack memory + MemTypeCodeOnHeap, // Read only memory for code generated on heap by runtime + + MemTypeAny = -1, +}; + +typedef enum CV_HLSLMemorySpace_e +{ + // HLSL specific memory spaces + + CV_HLSL_MEMSPACE_DATA = 0x00, + CV_HLSL_MEMSPACE_SAMPLER = 0x01, + CV_HLSL_MEMSPACE_RESOURCE = 0x02, + CV_HLSL_MEMSPACE_RWRESOURCE = 0x03, + + CV_HLSL_MEMSPACE_MAX = 0x0F, +} CV_HLSLMemorySpace_e; + +enum +{ + NAMEHASH_BUILD_START, + NAMEHASH_BUILD_PAUSE, + NAMEHASH_BUILD_RESUME, + NAMEHASH_BUILD_COMPLETE, + NAMEHASH_BUILD_ERROR, + NAMEHASH_BUILD_OOM = NAMEHASH_BUILD_ERROR, + NAMEHASH_BUILD_FAIL_TO_OPEN_MOD, +}; + +#endif diff --git a/libraries/dia/dia2.h b/libraries/dia/dia2.h new file mode 100644 index 0000000..299bf25 --- /dev/null +++ b/libraries/dia/dia2.h @@ -0,0 +1,21777 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 8.01.0622 */ +/* @@MIDL_FILE_HEADING( ) */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __dia2_h__ +#define __dia2_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IDiaLoadCallback_FWD_DEFINED__ +#define __IDiaLoadCallback_FWD_DEFINED__ +typedef interface IDiaLoadCallback IDiaLoadCallback; + +#endif /* __IDiaLoadCallback_FWD_DEFINED__ */ + + +#ifndef __IDiaLoadCallback2_FWD_DEFINED__ +#define __IDiaLoadCallback2_FWD_DEFINED__ +typedef interface IDiaLoadCallback2 IDiaLoadCallback2; + +#endif /* __IDiaLoadCallback2_FWD_DEFINED__ */ + + +#ifndef __IDiaReadExeAtOffsetCallback_FWD_DEFINED__ +#define __IDiaReadExeAtOffsetCallback_FWD_DEFINED__ +typedef interface IDiaReadExeAtOffsetCallback IDiaReadExeAtOffsetCallback; + +#endif /* __IDiaReadExeAtOffsetCallback_FWD_DEFINED__ */ + + +#ifndef __IDiaReadExeAtRVACallback_FWD_DEFINED__ +#define __IDiaReadExeAtRVACallback_FWD_DEFINED__ +typedef interface IDiaReadExeAtRVACallback IDiaReadExeAtRVACallback; + +#endif /* __IDiaReadExeAtRVACallback_FWD_DEFINED__ */ + + +#ifndef __IDiaDataSource_FWD_DEFINED__ +#define __IDiaDataSource_FWD_DEFINED__ +typedef interface IDiaDataSource IDiaDataSource; + +#endif /* __IDiaDataSource_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumSymbols_FWD_DEFINED__ +#define __IDiaEnumSymbols_FWD_DEFINED__ +typedef interface IDiaEnumSymbols IDiaEnumSymbols; + +#endif /* __IDiaEnumSymbols_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumSymbolsByAddr_FWD_DEFINED__ +#define __IDiaEnumSymbolsByAddr_FWD_DEFINED__ +typedef interface IDiaEnumSymbolsByAddr IDiaEnumSymbolsByAddr; + +#endif /* __IDiaEnumSymbolsByAddr_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumSourceFiles_FWD_DEFINED__ +#define __IDiaEnumSourceFiles_FWD_DEFINED__ +typedef interface IDiaEnumSourceFiles IDiaEnumSourceFiles; + +#endif /* __IDiaEnumSourceFiles_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumInputAssemblyFiles_FWD_DEFINED__ +#define __IDiaEnumInputAssemblyFiles_FWD_DEFINED__ +typedef interface IDiaEnumInputAssemblyFiles IDiaEnumInputAssemblyFiles; + +#endif /* __IDiaEnumInputAssemblyFiles_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumLineNumbers_FWD_DEFINED__ +#define __IDiaEnumLineNumbers_FWD_DEFINED__ +typedef interface IDiaEnumLineNumbers IDiaEnumLineNumbers; + +#endif /* __IDiaEnumLineNumbers_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumInjectedSources_FWD_DEFINED__ +#define __IDiaEnumInjectedSources_FWD_DEFINED__ +typedef interface IDiaEnumInjectedSources IDiaEnumInjectedSources; + +#endif /* __IDiaEnumInjectedSources_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumSegments_FWD_DEFINED__ +#define __IDiaEnumSegments_FWD_DEFINED__ +typedef interface IDiaEnumSegments IDiaEnumSegments; + +#endif /* __IDiaEnumSegments_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumSectionContribs_FWD_DEFINED__ +#define __IDiaEnumSectionContribs_FWD_DEFINED__ +typedef interface IDiaEnumSectionContribs IDiaEnumSectionContribs; + +#endif /* __IDiaEnumSectionContribs_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumFrameData_FWD_DEFINED__ +#define __IDiaEnumFrameData_FWD_DEFINED__ +typedef interface IDiaEnumFrameData IDiaEnumFrameData; + +#endif /* __IDiaEnumFrameData_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumDebugStreamData_FWD_DEFINED__ +#define __IDiaEnumDebugStreamData_FWD_DEFINED__ +typedef interface IDiaEnumDebugStreamData IDiaEnumDebugStreamData; + +#endif /* __IDiaEnumDebugStreamData_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumDebugStreams_FWD_DEFINED__ +#define __IDiaEnumDebugStreams_FWD_DEFINED__ +typedef interface IDiaEnumDebugStreams IDiaEnumDebugStreams; + +#endif /* __IDiaEnumDebugStreams_FWD_DEFINED__ */ + + +#ifndef __IDiaAddressMap_FWD_DEFINED__ +#define __IDiaAddressMap_FWD_DEFINED__ +typedef interface IDiaAddressMap IDiaAddressMap; + +#endif /* __IDiaAddressMap_FWD_DEFINED__ */ + + +#ifndef __IDiaSession_FWD_DEFINED__ +#define __IDiaSession_FWD_DEFINED__ +typedef interface IDiaSession IDiaSession; + +#endif /* __IDiaSession_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol_FWD_DEFINED__ +#define __IDiaSymbol_FWD_DEFINED__ +typedef interface IDiaSymbol IDiaSymbol; + +#endif /* __IDiaSymbol_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol2_FWD_DEFINED__ +#define __IDiaSymbol2_FWD_DEFINED__ +typedef interface IDiaSymbol2 IDiaSymbol2; + +#endif /* __IDiaSymbol2_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol3_FWD_DEFINED__ +#define __IDiaSymbol3_FWD_DEFINED__ +typedef interface IDiaSymbol3 IDiaSymbol3; + +#endif /* __IDiaSymbol3_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol4_FWD_DEFINED__ +#define __IDiaSymbol4_FWD_DEFINED__ +typedef interface IDiaSymbol4 IDiaSymbol4; + +#endif /* __IDiaSymbol4_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol5_FWD_DEFINED__ +#define __IDiaSymbol5_FWD_DEFINED__ +typedef interface IDiaSymbol5 IDiaSymbol5; + +#endif /* __IDiaSymbol5_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol6_FWD_DEFINED__ +#define __IDiaSymbol6_FWD_DEFINED__ +typedef interface IDiaSymbol6 IDiaSymbol6; + +#endif /* __IDiaSymbol6_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol7_FWD_DEFINED__ +#define __IDiaSymbol7_FWD_DEFINED__ +typedef interface IDiaSymbol7 IDiaSymbol7; + +#endif /* __IDiaSymbol7_FWD_DEFINED__ */ + + +#ifndef __IDiaSourceFile_FWD_DEFINED__ +#define __IDiaSourceFile_FWD_DEFINED__ +typedef interface IDiaSourceFile IDiaSourceFile; + +#endif /* __IDiaSourceFile_FWD_DEFINED__ */ + + +#ifndef __IDiaInputAssemblyFile_FWD_DEFINED__ +#define __IDiaInputAssemblyFile_FWD_DEFINED__ +typedef interface IDiaInputAssemblyFile IDiaInputAssemblyFile; + +#endif /* __IDiaInputAssemblyFile_FWD_DEFINED__ */ + + +#ifndef __IDiaLineNumber_FWD_DEFINED__ +#define __IDiaLineNumber_FWD_DEFINED__ +typedef interface IDiaLineNumber IDiaLineNumber; + +#endif /* __IDiaLineNumber_FWD_DEFINED__ */ + + +#ifndef __IDiaSectionContrib_FWD_DEFINED__ +#define __IDiaSectionContrib_FWD_DEFINED__ +typedef interface IDiaSectionContrib IDiaSectionContrib; + +#endif /* __IDiaSectionContrib_FWD_DEFINED__ */ + + +#ifndef __IDiaSegment_FWD_DEFINED__ +#define __IDiaSegment_FWD_DEFINED__ +typedef interface IDiaSegment IDiaSegment; + +#endif /* __IDiaSegment_FWD_DEFINED__ */ + + +#ifndef __IDiaInjectedSource_FWD_DEFINED__ +#define __IDiaInjectedSource_FWD_DEFINED__ +typedef interface IDiaInjectedSource IDiaInjectedSource; + +#endif /* __IDiaInjectedSource_FWD_DEFINED__ */ + + +#ifndef __IDiaStackWalkFrame_FWD_DEFINED__ +#define __IDiaStackWalkFrame_FWD_DEFINED__ +typedef interface IDiaStackWalkFrame IDiaStackWalkFrame; + +#endif /* __IDiaStackWalkFrame_FWD_DEFINED__ */ + + +#ifndef __IDiaFrameData_FWD_DEFINED__ +#define __IDiaFrameData_FWD_DEFINED__ +typedef interface IDiaFrameData IDiaFrameData; + +#endif /* __IDiaFrameData_FWD_DEFINED__ */ + + +#ifndef __IDiaImageData_FWD_DEFINED__ +#define __IDiaImageData_FWD_DEFINED__ +typedef interface IDiaImageData IDiaImageData; + +#endif /* __IDiaImageData_FWD_DEFINED__ */ + + +#ifndef __IDiaTable_FWD_DEFINED__ +#define __IDiaTable_FWD_DEFINED__ +typedef interface IDiaTable IDiaTable; + +#endif /* __IDiaTable_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumTables_FWD_DEFINED__ +#define __IDiaEnumTables_FWD_DEFINED__ +typedef interface IDiaEnumTables IDiaEnumTables; + +#endif /* __IDiaEnumTables_FWD_DEFINED__ */ + + +#ifndef __DiaSource_FWD_DEFINED__ +#define __DiaSource_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class DiaSource DiaSource; +#else +typedef struct DiaSource DiaSource; +#endif /* __cplusplus */ + +#endif /* __DiaSource_FWD_DEFINED__ */ + + +#ifndef __DiaSourceAlt_FWD_DEFINED__ +#define __DiaSourceAlt_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class DiaSourceAlt DiaSourceAlt; +#else +typedef struct DiaSourceAlt DiaSourceAlt; +#endif /* __cplusplus */ + +#endif /* __DiaSourceAlt_FWD_DEFINED__ */ + + +#ifndef __DiaStackWalker_FWD_DEFINED__ +#define __DiaStackWalker_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class DiaStackWalker DiaStackWalker; +#else +typedef struct DiaStackWalker DiaStackWalker; +#endif /* __cplusplus */ + +#endif /* __DiaStackWalker_FWD_DEFINED__ */ + + +#ifndef __IDiaSectionContrib_FWD_DEFINED__ +#define __IDiaSectionContrib_FWD_DEFINED__ +typedef interface IDiaSectionContrib IDiaSectionContrib; + +#endif /* __IDiaSectionContrib_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumSectionContribs_FWD_DEFINED__ +#define __IDiaEnumSectionContribs_FWD_DEFINED__ +typedef interface IDiaEnumSectionContribs IDiaEnumSectionContribs; + +#endif /* __IDiaEnumSectionContribs_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol_FWD_DEFINED__ +#define __IDiaSymbol_FWD_DEFINED__ +typedef interface IDiaSymbol IDiaSymbol; + +#endif /* __IDiaSymbol_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol2_FWD_DEFINED__ +#define __IDiaSymbol2_FWD_DEFINED__ +typedef interface IDiaSymbol2 IDiaSymbol2; + +#endif /* __IDiaSymbol2_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol3_FWD_DEFINED__ +#define __IDiaSymbol3_FWD_DEFINED__ +typedef interface IDiaSymbol3 IDiaSymbol3; + +#endif /* __IDiaSymbol3_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol4_FWD_DEFINED__ +#define __IDiaSymbol4_FWD_DEFINED__ +typedef interface IDiaSymbol4 IDiaSymbol4; + +#endif /* __IDiaSymbol4_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol5_FWD_DEFINED__ +#define __IDiaSymbol5_FWD_DEFINED__ +typedef interface IDiaSymbol5 IDiaSymbol5; + +#endif /* __IDiaSymbol5_FWD_DEFINED__ */ + + +#ifndef __IDiaSymbol6_FWD_DEFINED__ +#define __IDiaSymbol6_FWD_DEFINED__ +typedef interface IDiaSymbol6 IDiaSymbol6; + +#endif /* __IDiaSymbol6_FWD_DEFINED__ */ + + +#ifndef __IDiaPropertyStorage_FWD_DEFINED__ +#define __IDiaPropertyStorage_FWD_DEFINED__ +typedef interface IDiaPropertyStorage IDiaPropertyStorage; + +#endif /* __IDiaPropertyStorage_FWD_DEFINED__ */ + + +#ifndef __IDiaStackFrame_FWD_DEFINED__ +#define __IDiaStackFrame_FWD_DEFINED__ +typedef interface IDiaStackFrame IDiaStackFrame; + +#endif /* __IDiaStackFrame_FWD_DEFINED__ */ + + +#ifndef __IDiaEnumStackFrames_FWD_DEFINED__ +#define __IDiaEnumStackFrames_FWD_DEFINED__ +typedef interface IDiaEnumStackFrames IDiaEnumStackFrames; + +#endif /* __IDiaEnumStackFrames_FWD_DEFINED__ */ + + +#ifndef __IDiaStackWalkHelper_FWD_DEFINED__ +#define __IDiaStackWalkHelper_FWD_DEFINED__ +typedef interface IDiaStackWalkHelper IDiaStackWalkHelper; + +#endif /* __IDiaStackWalkHelper_FWD_DEFINED__ */ + + +#ifndef __IDiaStackWalker_FWD_DEFINED__ +#define __IDiaStackWalker_FWD_DEFINED__ +typedef interface IDiaStackWalker IDiaStackWalker; + +#endif /* __IDiaStackWalker_FWD_DEFINED__ */ + + +#ifndef __IDiaStackWalkHelper2_FWD_DEFINED__ +#define __IDiaStackWalkHelper2_FWD_DEFINED__ +typedef interface IDiaStackWalkHelper2 IDiaStackWalkHelper2; + +#endif /* __IDiaStackWalkHelper2_FWD_DEFINED__ */ + + +#ifndef __IDiaStackWalker2_FWD_DEFINED__ +#define __IDiaStackWalker2_FWD_DEFINED__ +typedef interface IDiaStackWalker2 IDiaStackWalker2; + +#endif /* __IDiaStackWalker2_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "objidl.h" +#include "oaidl.h" +#include "propidl.h" +#include "cvconst.h" + +#ifdef __cplusplus +extern "C"{ +#endif + + +/* interface __MIDL_itf_dia2_0000_0000 */ +/* [local] */ + + +enum NameSearchOptions + { + nsNone = 0, + nsfCaseSensitive = 0x1, + nsfCaseInsensitive = 0x2, + nsfFNameExt = 0x4, + nsfRegularExpression = 0x8, + nsfUndecoratedName = 0x10, + nsCaseSensitive = nsfCaseSensitive, + nsCaseInsensitive = nsfCaseInsensitive, + nsFNameExt = ( nsfCaseInsensitive | nsfFNameExt ) , + nsRegularExpression = ( nsfRegularExpression | nsfCaseSensitive ) , + nsCaseInRegularExpression = ( nsfRegularExpression | nsfCaseInsensitive ) + } ; + +enum __MIDL___MIDL_itf_dia2_0000_0000_0001 + { + E_PDB_OK = ( HRESULT )(( ( ( ( unsigned long )1 << 31 ) | ( ( unsigned long )( LONG )0x6d << 16 ) ) | ( unsigned long )1 ) ), + E_PDB_USAGE = ( E_PDB_OK + 1 ) , + E_PDB_OUT_OF_MEMORY = ( E_PDB_USAGE + 1 ) , + E_PDB_FILE_SYSTEM = ( E_PDB_OUT_OF_MEMORY + 1 ) , + E_PDB_NOT_FOUND = ( E_PDB_FILE_SYSTEM + 1 ) , + E_PDB_INVALID_SIG = ( E_PDB_NOT_FOUND + 1 ) , + E_PDB_INVALID_AGE = ( E_PDB_INVALID_SIG + 1 ) , + E_PDB_PRECOMP_REQUIRED = ( E_PDB_INVALID_AGE + 1 ) , + E_PDB_OUT_OF_TI = ( E_PDB_PRECOMP_REQUIRED + 1 ) , + E_PDB_NOT_IMPLEMENTED = ( E_PDB_OUT_OF_TI + 1 ) , + E_PDB_V1_PDB = ( E_PDB_NOT_IMPLEMENTED + 1 ) , + E_PDB_FORMAT = ( E_PDB_V1_PDB + 1 ) , + E_PDB_LIMIT = ( E_PDB_FORMAT + 1 ) , + E_PDB_CORRUPT = ( E_PDB_LIMIT + 1 ) , + E_PDB_TI16 = ( E_PDB_CORRUPT + 1 ) , + E_PDB_ACCESS_DENIED = ( E_PDB_TI16 + 1 ) , + E_PDB_ILLEGAL_TYPE_EDIT = ( E_PDB_ACCESS_DENIED + 1 ) , + E_PDB_INVALID_EXECUTABLE = ( E_PDB_ILLEGAL_TYPE_EDIT + 1 ) , + E_PDB_DBG_NOT_FOUND = ( E_PDB_INVALID_EXECUTABLE + 1 ) , + E_PDB_NO_DEBUG_INFO = ( E_PDB_DBG_NOT_FOUND + 1 ) , + E_PDB_INVALID_EXE_TIMESTAMP = ( E_PDB_NO_DEBUG_INFO + 1 ) , + E_PDB_RESERVED = ( E_PDB_INVALID_EXE_TIMESTAMP + 1 ) , + E_PDB_DEBUG_INFO_NOT_IN_PDB = ( E_PDB_RESERVED + 1 ) , + E_PDB_SYMSRV_BAD_CACHE_PATH = ( E_PDB_DEBUG_INFO_NOT_IN_PDB + 1 ) , + E_PDB_SYMSRV_CACHE_FULL = ( E_PDB_SYMSRV_BAD_CACHE_PATH + 1 ) , + E_PDB_OBJECT_DISPOSED = ( E_PDB_SYMSRV_CACHE_FULL + 1 ) , + E_PDB_MAX = ( E_PDB_OBJECT_DISPOSED + 1 ) + } ; +typedef void ( __cdecl *PfnPDBDebugDirV )( + BOOL __MIDL____MIDL_itf_dia2_0000_00000000, + void *__MIDL____MIDL_itf_dia2_0000_00000001); + + + + + + + + + + + + + + + + + + + + +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0000_v0_0_s_ifspec; + +#ifndef __IDiaLoadCallback_INTERFACE_DEFINED__ +#define __IDiaLoadCallback_INTERFACE_DEFINED__ + +/* interface IDiaLoadCallback */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaLoadCallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C32ADB82-73F4-421b-95D5-A4706EDF5DBE") + IDiaLoadCallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE NotifyDebugDir( + /* [in] */ BOOL fExecutable, + /* [in] */ DWORD cbData, + /* [size_is][in] */ BYTE *pbData) = 0; + + virtual HRESULT STDMETHODCALLTYPE NotifyOpenDBG( + /* [in] */ LPCOLESTR dbgPath, + /* [in] */ HRESULT resultCode) = 0; + + virtual HRESULT STDMETHODCALLTYPE NotifyOpenPDB( + /* [in] */ LPCOLESTR pdbPath, + /* [in] */ HRESULT resultCode) = 0; + + virtual HRESULT STDMETHODCALLTYPE RestrictRegistryAccess( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE RestrictSymbolServerAccess( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaLoadCallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaLoadCallback * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaLoadCallback * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaLoadCallback * This); + + HRESULT ( STDMETHODCALLTYPE *NotifyDebugDir )( + IDiaLoadCallback * This, + /* [in] */ BOOL fExecutable, + /* [in] */ DWORD cbData, + /* [size_is][in] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *NotifyOpenDBG )( + IDiaLoadCallback * This, + /* [in] */ LPCOLESTR dbgPath, + /* [in] */ HRESULT resultCode); + + HRESULT ( STDMETHODCALLTYPE *NotifyOpenPDB )( + IDiaLoadCallback * This, + /* [in] */ LPCOLESTR pdbPath, + /* [in] */ HRESULT resultCode); + + HRESULT ( STDMETHODCALLTYPE *RestrictRegistryAccess )( + IDiaLoadCallback * This); + + HRESULT ( STDMETHODCALLTYPE *RestrictSymbolServerAccess )( + IDiaLoadCallback * This); + + END_INTERFACE + } IDiaLoadCallbackVtbl; + + interface IDiaLoadCallback + { + CONST_VTBL struct IDiaLoadCallbackVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaLoadCallback_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaLoadCallback_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaLoadCallback_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaLoadCallback_NotifyDebugDir(This,fExecutable,cbData,pbData) \ + ( (This)->lpVtbl -> NotifyDebugDir(This,fExecutable,cbData,pbData) ) + +#define IDiaLoadCallback_NotifyOpenDBG(This,dbgPath,resultCode) \ + ( (This)->lpVtbl -> NotifyOpenDBG(This,dbgPath,resultCode) ) + +#define IDiaLoadCallback_NotifyOpenPDB(This,pdbPath,resultCode) \ + ( (This)->lpVtbl -> NotifyOpenPDB(This,pdbPath,resultCode) ) + +#define IDiaLoadCallback_RestrictRegistryAccess(This) \ + ( (This)->lpVtbl -> RestrictRegistryAccess(This) ) + +#define IDiaLoadCallback_RestrictSymbolServerAccess(This) \ + ( (This)->lpVtbl -> RestrictSymbolServerAccess(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaLoadCallback_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaLoadCallback2_INTERFACE_DEFINED__ +#define __IDiaLoadCallback2_INTERFACE_DEFINED__ + +/* interface IDiaLoadCallback2 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaLoadCallback2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4688a074-5a4d-4486-aea8-7b90711d9f7c") + IDiaLoadCallback2 : public IDiaLoadCallback + { + public: + virtual HRESULT STDMETHODCALLTYPE RestrictOriginalPathAccess( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE RestrictReferencePathAccess( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE RestrictDBGAccess( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE RestrictSystemRootAccess( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaLoadCallback2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaLoadCallback2 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaLoadCallback2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaLoadCallback2 * This); + + HRESULT ( STDMETHODCALLTYPE *NotifyDebugDir )( + IDiaLoadCallback2 * This, + /* [in] */ BOOL fExecutable, + /* [in] */ DWORD cbData, + /* [size_is][in] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *NotifyOpenDBG )( + IDiaLoadCallback2 * This, + /* [in] */ LPCOLESTR dbgPath, + /* [in] */ HRESULT resultCode); + + HRESULT ( STDMETHODCALLTYPE *NotifyOpenPDB )( + IDiaLoadCallback2 * This, + /* [in] */ LPCOLESTR pdbPath, + /* [in] */ HRESULT resultCode); + + HRESULT ( STDMETHODCALLTYPE *RestrictRegistryAccess )( + IDiaLoadCallback2 * This); + + HRESULT ( STDMETHODCALLTYPE *RestrictSymbolServerAccess )( + IDiaLoadCallback2 * This); + + HRESULT ( STDMETHODCALLTYPE *RestrictOriginalPathAccess )( + IDiaLoadCallback2 * This); + + HRESULT ( STDMETHODCALLTYPE *RestrictReferencePathAccess )( + IDiaLoadCallback2 * This); + + HRESULT ( STDMETHODCALLTYPE *RestrictDBGAccess )( + IDiaLoadCallback2 * This); + + HRESULT ( STDMETHODCALLTYPE *RestrictSystemRootAccess )( + IDiaLoadCallback2 * This); + + END_INTERFACE + } IDiaLoadCallback2Vtbl; + + interface IDiaLoadCallback2 + { + CONST_VTBL struct IDiaLoadCallback2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaLoadCallback2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaLoadCallback2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaLoadCallback2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaLoadCallback2_NotifyDebugDir(This,fExecutable,cbData,pbData) \ + ( (This)->lpVtbl -> NotifyDebugDir(This,fExecutable,cbData,pbData) ) + +#define IDiaLoadCallback2_NotifyOpenDBG(This,dbgPath,resultCode) \ + ( (This)->lpVtbl -> NotifyOpenDBG(This,dbgPath,resultCode) ) + +#define IDiaLoadCallback2_NotifyOpenPDB(This,pdbPath,resultCode) \ + ( (This)->lpVtbl -> NotifyOpenPDB(This,pdbPath,resultCode) ) + +#define IDiaLoadCallback2_RestrictRegistryAccess(This) \ + ( (This)->lpVtbl -> RestrictRegistryAccess(This) ) + +#define IDiaLoadCallback2_RestrictSymbolServerAccess(This) \ + ( (This)->lpVtbl -> RestrictSymbolServerAccess(This) ) + + +#define IDiaLoadCallback2_RestrictOriginalPathAccess(This) \ + ( (This)->lpVtbl -> RestrictOriginalPathAccess(This) ) + +#define IDiaLoadCallback2_RestrictReferencePathAccess(This) \ + ( (This)->lpVtbl -> RestrictReferencePathAccess(This) ) + +#define IDiaLoadCallback2_RestrictDBGAccess(This) \ + ( (This)->lpVtbl -> RestrictDBGAccess(This) ) + +#define IDiaLoadCallback2_RestrictSystemRootAccess(This) \ + ( (This)->lpVtbl -> RestrictSystemRootAccess(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaLoadCallback2_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaReadExeAtOffsetCallback_INTERFACE_DEFINED__ +#define __IDiaReadExeAtOffsetCallback_INTERFACE_DEFINED__ + +/* interface IDiaReadExeAtOffsetCallback */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaReadExeAtOffsetCallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("587A461C-B80B-4f54-9194-5032589A6319") + IDiaReadExeAtOffsetCallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ReadExecutableAt( + /* [in] */ DWORDLONG fileOffset, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaReadExeAtOffsetCallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaReadExeAtOffsetCallback * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaReadExeAtOffsetCallback * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaReadExeAtOffsetCallback * This); + + HRESULT ( STDMETHODCALLTYPE *ReadExecutableAt )( + IDiaReadExeAtOffsetCallback * This, + /* [in] */ DWORDLONG fileOffset, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + END_INTERFACE + } IDiaReadExeAtOffsetCallbackVtbl; + + interface IDiaReadExeAtOffsetCallback + { + CONST_VTBL struct IDiaReadExeAtOffsetCallbackVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaReadExeAtOffsetCallback_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaReadExeAtOffsetCallback_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaReadExeAtOffsetCallback_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaReadExeAtOffsetCallback_ReadExecutableAt(This,fileOffset,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> ReadExecutableAt(This,fileOffset,cbData,pcbData,pbData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaReadExeAtOffsetCallback_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaReadExeAtRVACallback_INTERFACE_DEFINED__ +#define __IDiaReadExeAtRVACallback_INTERFACE_DEFINED__ + +/* interface IDiaReadExeAtRVACallback */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaReadExeAtRVACallback; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8E3F80CA-7517-432a-BA07-285134AAEA8E") + IDiaReadExeAtRVACallback : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ReadExecutableAtRVA( + /* [in] */ DWORD relativeVirtualAddress, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaReadExeAtRVACallbackVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaReadExeAtRVACallback * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaReadExeAtRVACallback * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaReadExeAtRVACallback * This); + + HRESULT ( STDMETHODCALLTYPE *ReadExecutableAtRVA )( + IDiaReadExeAtRVACallback * This, + /* [in] */ DWORD relativeVirtualAddress, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + END_INTERFACE + } IDiaReadExeAtRVACallbackVtbl; + + interface IDiaReadExeAtRVACallback + { + CONST_VTBL struct IDiaReadExeAtRVACallbackVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaReadExeAtRVACallback_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaReadExeAtRVACallback_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaReadExeAtRVACallback_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaReadExeAtRVACallback_ReadExecutableAtRVA(This,relativeVirtualAddress,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> ReadExecutableAtRVA(This,relativeVirtualAddress,cbData,pcbData,pbData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaReadExeAtRVACallback_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaDataSource_INTERFACE_DEFINED__ +#define __IDiaDataSource_INTERFACE_DEFINED__ + +/* interface IDiaDataSource */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaDataSource; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("79F1BB5F-B66E-48e5-B6A9-1545C323CA3D") + IDiaDataSource : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lastError( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE loadDataFromPdb( + /* [in] */ LPCOLESTR pdbPath) = 0; + + virtual HRESULT STDMETHODCALLTYPE loadAndValidateDataFromPdb( + /* [in] */ LPCOLESTR pdbPath, + /* [in] */ GUID *pcsig70, + /* [in] */ DWORD sig, + /* [in] */ DWORD age) = 0; + + virtual HRESULT STDMETHODCALLTYPE loadDataForExe( + /* [in] */ LPCOLESTR executable, + /* [in] */ LPCOLESTR searchPath, + /* [in] */ IUnknown *pCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE loadDataFromIStream( + /* [in] */ IStream *pIStream) = 0; + + virtual HRESULT STDMETHODCALLTYPE openSession( + /* [out] */ IDiaSession **ppSession) = 0; + + virtual HRESULT STDMETHODCALLTYPE loadDataFromCodeViewInfo( + /* [in] */ LPCOLESTR executable, + /* [in] */ LPCOLESTR searchPath, + /* [in] */ DWORD cbCvInfo, + /* [size_is][in] */ BYTE *pbCvInfo, + /* [in] */ IUnknown *pCallback) = 0; + + virtual HRESULT STDMETHODCALLTYPE loadDataFromMiscInfo( + /* [in] */ LPCOLESTR executable, + /* [in] */ LPCOLESTR searchPath, + /* [in] */ DWORD timeStampExe, + /* [in] */ DWORD timeStampDbg, + /* [in] */ DWORD sizeOfExe, + /* [in] */ DWORD cbMiscInfo, + /* [size_is][in] */ BYTE *pbMiscInfo, + /* [in] */ IUnknown *pCallback) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaDataSourceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaDataSource * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaDataSource * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaDataSource * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lastError )( + IDiaDataSource * This, + /* [retval][out] */ BSTR *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *loadDataFromPdb )( + IDiaDataSource * This, + /* [in] */ LPCOLESTR pdbPath); + + HRESULT ( STDMETHODCALLTYPE *loadAndValidateDataFromPdb )( + IDiaDataSource * This, + /* [in] */ LPCOLESTR pdbPath, + /* [in] */ GUID *pcsig70, + /* [in] */ DWORD sig, + /* [in] */ DWORD age); + + HRESULT ( STDMETHODCALLTYPE *loadDataForExe )( + IDiaDataSource * This, + /* [in] */ LPCOLESTR executable, + /* [in] */ LPCOLESTR searchPath, + /* [in] */ IUnknown *pCallback); + + HRESULT ( STDMETHODCALLTYPE *loadDataFromIStream )( + IDiaDataSource * This, + /* [in] */ IStream *pIStream); + + HRESULT ( STDMETHODCALLTYPE *openSession )( + IDiaDataSource * This, + /* [out] */ IDiaSession **ppSession); + + HRESULT ( STDMETHODCALLTYPE *loadDataFromCodeViewInfo )( + IDiaDataSource * This, + /* [in] */ LPCOLESTR executable, + /* [in] */ LPCOLESTR searchPath, + /* [in] */ DWORD cbCvInfo, + /* [size_is][in] */ BYTE *pbCvInfo, + /* [in] */ IUnknown *pCallback); + + HRESULT ( STDMETHODCALLTYPE *loadDataFromMiscInfo )( + IDiaDataSource * This, + /* [in] */ LPCOLESTR executable, + /* [in] */ LPCOLESTR searchPath, + /* [in] */ DWORD timeStampExe, + /* [in] */ DWORD timeStampDbg, + /* [in] */ DWORD sizeOfExe, + /* [in] */ DWORD cbMiscInfo, + /* [size_is][in] */ BYTE *pbMiscInfo, + /* [in] */ IUnknown *pCallback); + + END_INTERFACE + } IDiaDataSourceVtbl; + + interface IDiaDataSource + { + CONST_VTBL struct IDiaDataSourceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaDataSource_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaDataSource_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaDataSource_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaDataSource_get_lastError(This,pRetVal) \ + ( (This)->lpVtbl -> get_lastError(This,pRetVal) ) + +#define IDiaDataSource_loadDataFromPdb(This,pdbPath) \ + ( (This)->lpVtbl -> loadDataFromPdb(This,pdbPath) ) + +#define IDiaDataSource_loadAndValidateDataFromPdb(This,pdbPath,pcsig70,sig,age) \ + ( (This)->lpVtbl -> loadAndValidateDataFromPdb(This,pdbPath,pcsig70,sig,age) ) + +#define IDiaDataSource_loadDataForExe(This,executable,searchPath,pCallback) \ + ( (This)->lpVtbl -> loadDataForExe(This,executable,searchPath,pCallback) ) + +#define IDiaDataSource_loadDataFromIStream(This,pIStream) \ + ( (This)->lpVtbl -> loadDataFromIStream(This,pIStream) ) + +#define IDiaDataSource_openSession(This,ppSession) \ + ( (This)->lpVtbl -> openSession(This,ppSession) ) + +#define IDiaDataSource_loadDataFromCodeViewInfo(This,executable,searchPath,cbCvInfo,pbCvInfo,pCallback) \ + ( (This)->lpVtbl -> loadDataFromCodeViewInfo(This,executable,searchPath,cbCvInfo,pbCvInfo,pCallback) ) + +#define IDiaDataSource_loadDataFromMiscInfo(This,executable,searchPath,timeStampExe,timeStampDbg,sizeOfExe,cbMiscInfo,pbMiscInfo,pCallback) \ + ( (This)->lpVtbl -> loadDataFromMiscInfo(This,executable,searchPath,timeStampExe,timeStampDbg,sizeOfExe,cbMiscInfo,pbMiscInfo,pCallback) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaDataSource_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumSymbols_INTERFACE_DEFINED__ +#define __IDiaEnumSymbols_INTERFACE_DEFINED__ + +/* interface IDiaEnumSymbols */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumSymbols; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("CAB72C48-443B-48f5-9B0B-42F0820AB29A") + IDiaEnumSymbols : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IDiaSymbol **symbol) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaSymbol **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumSymbols **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumSymbolsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumSymbols * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumSymbols * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumSymbols * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumSymbols * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumSymbols * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumSymbols * This, + /* [in] */ DWORD index, + /* [retval][out] */ IDiaSymbol **symbol); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumSymbols * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaSymbol **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumSymbols * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumSymbols * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumSymbols * This, + /* [out] */ IDiaEnumSymbols **ppenum); + + END_INTERFACE + } IDiaEnumSymbolsVtbl; + + interface IDiaEnumSymbols + { + CONST_VTBL struct IDiaEnumSymbolsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumSymbols_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumSymbols_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumSymbols_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumSymbols_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumSymbols_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumSymbols_Item(This,index,symbol) \ + ( (This)->lpVtbl -> Item(This,index,symbol) ) + +#define IDiaEnumSymbols_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumSymbols_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumSymbols_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumSymbols_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumSymbols_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumSymbolsByAddr_INTERFACE_DEFINED__ +#define __IDiaEnumSymbolsByAddr_INTERFACE_DEFINED__ + +/* interface IDiaEnumSymbolsByAddr */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumSymbolsByAddr; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("624B7D9C-24EA-4421-9D06-3B577471C1FA") + IDiaEnumSymbolsByAddr : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE symbolByAddr( + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [retval][out] */ IDiaSymbol **ppSymbol) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE symbolByRVA( + /* [in] */ DWORD relativeVirtualAddress, + /* [retval][out] */ IDiaSymbol **ppSymbol) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE symbolByVA( + /* [in] */ ULONGLONG virtualAddress, + /* [retval][out] */ IDiaSymbol **ppSymbol) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaSymbol **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Prev( + /* [in] */ ULONG celt, + /* [out] */ IDiaSymbol **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumSymbolsByAddr **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumSymbolsByAddrVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumSymbolsByAddr * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumSymbolsByAddr * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumSymbolsByAddr * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *symbolByAddr )( + IDiaEnumSymbolsByAddr * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [retval][out] */ IDiaSymbol **ppSymbol); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *symbolByRVA )( + IDiaEnumSymbolsByAddr * This, + /* [in] */ DWORD relativeVirtualAddress, + /* [retval][out] */ IDiaSymbol **ppSymbol); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *symbolByVA )( + IDiaEnumSymbolsByAddr * This, + /* [in] */ ULONGLONG virtualAddress, + /* [retval][out] */ IDiaSymbol **ppSymbol); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumSymbolsByAddr * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaSymbol **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Prev )( + IDiaEnumSymbolsByAddr * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaSymbol **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumSymbolsByAddr * This, + /* [out] */ IDiaEnumSymbolsByAddr **ppenum); + + END_INTERFACE + } IDiaEnumSymbolsByAddrVtbl; + + interface IDiaEnumSymbolsByAddr + { + CONST_VTBL struct IDiaEnumSymbolsByAddrVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumSymbolsByAddr_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumSymbolsByAddr_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumSymbolsByAddr_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumSymbolsByAddr_symbolByAddr(This,isect,offset,ppSymbol) \ + ( (This)->lpVtbl -> symbolByAddr(This,isect,offset,ppSymbol) ) + +#define IDiaEnumSymbolsByAddr_symbolByRVA(This,relativeVirtualAddress,ppSymbol) \ + ( (This)->lpVtbl -> symbolByRVA(This,relativeVirtualAddress,ppSymbol) ) + +#define IDiaEnumSymbolsByAddr_symbolByVA(This,virtualAddress,ppSymbol) \ + ( (This)->lpVtbl -> symbolByVA(This,virtualAddress,ppSymbol) ) + +#define IDiaEnumSymbolsByAddr_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumSymbolsByAddr_Prev(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Prev(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumSymbolsByAddr_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumSymbolsByAddr_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumSourceFiles_INTERFACE_DEFINED__ +#define __IDiaEnumSourceFiles_INTERFACE_DEFINED__ + +/* interface IDiaEnumSourceFiles */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumSourceFiles; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("10F3DBD9-664F-4469-B808-9471C7A50538") + IDiaEnumSourceFiles : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IDiaSourceFile **sourceFile) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaSourceFile **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumSourceFiles **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumSourceFilesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumSourceFiles * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumSourceFiles * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumSourceFiles * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumSourceFiles * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumSourceFiles * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumSourceFiles * This, + /* [in] */ DWORD index, + /* [retval][out] */ IDiaSourceFile **sourceFile); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumSourceFiles * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaSourceFile **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumSourceFiles * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumSourceFiles * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumSourceFiles * This, + /* [out] */ IDiaEnumSourceFiles **ppenum); + + END_INTERFACE + } IDiaEnumSourceFilesVtbl; + + interface IDiaEnumSourceFiles + { + CONST_VTBL struct IDiaEnumSourceFilesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumSourceFiles_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumSourceFiles_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumSourceFiles_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumSourceFiles_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumSourceFiles_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumSourceFiles_Item(This,index,sourceFile) \ + ( (This)->lpVtbl -> Item(This,index,sourceFile) ) + +#define IDiaEnumSourceFiles_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumSourceFiles_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumSourceFiles_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumSourceFiles_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumSourceFiles_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumInputAssemblyFiles_INTERFACE_DEFINED__ +#define __IDiaEnumInputAssemblyFiles_INTERFACE_DEFINED__ + +/* interface IDiaEnumInputAssemblyFiles */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumInputAssemblyFiles; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1C7FF653-51F7-457E-8419-B20F57EF7E4D") + IDiaEnumInputAssemblyFiles : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IDiaInputAssemblyFile **file) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaInputAssemblyFile **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumInputAssemblyFiles **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumInputAssemblyFilesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumInputAssemblyFiles * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumInputAssemblyFiles * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumInputAssemblyFiles * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumInputAssemblyFiles * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumInputAssemblyFiles * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumInputAssemblyFiles * This, + /* [in] */ DWORD index, + /* [retval][out] */ IDiaInputAssemblyFile **file); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumInputAssemblyFiles * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaInputAssemblyFile **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumInputAssemblyFiles * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumInputAssemblyFiles * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumInputAssemblyFiles * This, + /* [out] */ IDiaEnumInputAssemblyFiles **ppenum); + + END_INTERFACE + } IDiaEnumInputAssemblyFilesVtbl; + + interface IDiaEnumInputAssemblyFiles + { + CONST_VTBL struct IDiaEnumInputAssemblyFilesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumInputAssemblyFiles_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumInputAssemblyFiles_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumInputAssemblyFiles_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumInputAssemblyFiles_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumInputAssemblyFiles_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumInputAssemblyFiles_Item(This,index,file) \ + ( (This)->lpVtbl -> Item(This,index,file) ) + +#define IDiaEnumInputAssemblyFiles_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumInputAssemblyFiles_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumInputAssemblyFiles_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumInputAssemblyFiles_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumInputAssemblyFiles_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumLineNumbers_INTERFACE_DEFINED__ +#define __IDiaEnumLineNumbers_INTERFACE_DEFINED__ + +/* interface IDiaEnumLineNumbers */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumLineNumbers; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("FE30E878-54AC-44f1-81BA-39DE940F6052") + IDiaEnumLineNumbers : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IDiaLineNumber **lineNumber) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaLineNumber **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumLineNumbers **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumLineNumbersVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumLineNumbers * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumLineNumbers * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumLineNumbers * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumLineNumbers * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumLineNumbers * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumLineNumbers * This, + /* [in] */ DWORD index, + /* [retval][out] */ IDiaLineNumber **lineNumber); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumLineNumbers * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaLineNumber **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumLineNumbers * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumLineNumbers * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumLineNumbers * This, + /* [out] */ IDiaEnumLineNumbers **ppenum); + + END_INTERFACE + } IDiaEnumLineNumbersVtbl; + + interface IDiaEnumLineNumbers + { + CONST_VTBL struct IDiaEnumLineNumbersVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumLineNumbers_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumLineNumbers_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumLineNumbers_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumLineNumbers_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumLineNumbers_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumLineNumbers_Item(This,index,lineNumber) \ + ( (This)->lpVtbl -> Item(This,index,lineNumber) ) + +#define IDiaEnumLineNumbers_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumLineNumbers_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumLineNumbers_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumLineNumbers_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumLineNumbers_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumInjectedSources_INTERFACE_DEFINED__ +#define __IDiaEnumInjectedSources_INTERFACE_DEFINED__ + +/* interface IDiaEnumInjectedSources */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumInjectedSources; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("D5612573-6925-4468-8883-98CDEC8C384A") + IDiaEnumInjectedSources : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IDiaInjectedSource **injectedSource) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaInjectedSource **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumInjectedSources **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumInjectedSourcesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumInjectedSources * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumInjectedSources * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumInjectedSources * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumInjectedSources * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumInjectedSources * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumInjectedSources * This, + /* [in] */ DWORD index, + /* [retval][out] */ IDiaInjectedSource **injectedSource); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumInjectedSources * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaInjectedSource **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumInjectedSources * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumInjectedSources * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumInjectedSources * This, + /* [out] */ IDiaEnumInjectedSources **ppenum); + + END_INTERFACE + } IDiaEnumInjectedSourcesVtbl; + + interface IDiaEnumInjectedSources + { + CONST_VTBL struct IDiaEnumInjectedSourcesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumInjectedSources_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumInjectedSources_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumInjectedSources_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumInjectedSources_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumInjectedSources_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumInjectedSources_Item(This,index,injectedSource) \ + ( (This)->lpVtbl -> Item(This,index,injectedSource) ) + +#define IDiaEnumInjectedSources_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumInjectedSources_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumInjectedSources_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumInjectedSources_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumInjectedSources_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumSegments_INTERFACE_DEFINED__ +#define __IDiaEnumSegments_INTERFACE_DEFINED__ + +/* interface IDiaEnumSegments */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumSegments; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("E8368CA9-01D1-419d-AC0C-E31235DBDA9F") + IDiaEnumSegments : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IDiaSegment **segment) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaSegment **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumSegments **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumSegmentsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumSegments * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumSegments * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumSegments * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumSegments * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumSegments * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumSegments * This, + /* [in] */ DWORD index, + /* [retval][out] */ IDiaSegment **segment); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumSegments * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaSegment **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumSegments * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumSegments * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumSegments * This, + /* [out] */ IDiaEnumSegments **ppenum); + + END_INTERFACE + } IDiaEnumSegmentsVtbl; + + interface IDiaEnumSegments + { + CONST_VTBL struct IDiaEnumSegmentsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumSegments_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumSegments_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumSegments_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumSegments_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumSegments_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumSegments_Item(This,index,segment) \ + ( (This)->lpVtbl -> Item(This,index,segment) ) + +#define IDiaEnumSegments_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumSegments_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumSegments_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumSegments_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumSegments_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumSectionContribs_INTERFACE_DEFINED__ +#define __IDiaEnumSectionContribs_INTERFACE_DEFINED__ + +/* interface IDiaEnumSectionContribs */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumSectionContribs; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("1994DEB2-2C82-4b1d-A57F-AFF424D54A68") + IDiaEnumSectionContribs : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IDiaSectionContrib **section) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaSectionContrib **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumSectionContribs **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumSectionContribsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumSectionContribs * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumSectionContribs * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumSectionContribs * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumSectionContribs * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumSectionContribs * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumSectionContribs * This, + /* [in] */ DWORD index, + /* [retval][out] */ IDiaSectionContrib **section); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumSectionContribs * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaSectionContrib **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumSectionContribs * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumSectionContribs * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumSectionContribs * This, + /* [out] */ IDiaEnumSectionContribs **ppenum); + + END_INTERFACE + } IDiaEnumSectionContribsVtbl; + + interface IDiaEnumSectionContribs + { + CONST_VTBL struct IDiaEnumSectionContribsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumSectionContribs_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumSectionContribs_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumSectionContribs_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumSectionContribs_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumSectionContribs_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumSectionContribs_Item(This,index,section) \ + ( (This)->lpVtbl -> Item(This,index,section) ) + +#define IDiaEnumSectionContribs_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumSectionContribs_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumSectionContribs_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumSectionContribs_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumSectionContribs_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumFrameData_INTERFACE_DEFINED__ +#define __IDiaEnumFrameData_INTERFACE_DEFINED__ + +/* interface IDiaEnumFrameData */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumFrameData; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9FC77A4B-3C1C-44ed-A798-6C1DEEA53E1F") + IDiaEnumFrameData : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IDiaFrameData **frame) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaFrameData **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumFrameData **ppenum) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE frameByRVA( + /* [in] */ DWORD relativeVirtualAddress, + /* [retval][out] */ IDiaFrameData **frame) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE frameByVA( + /* [in] */ ULONGLONG virtualAddress, + /* [retval][out] */ IDiaFrameData **frame) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumFrameDataVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumFrameData * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumFrameData * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumFrameData * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumFrameData * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumFrameData * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumFrameData * This, + /* [in] */ DWORD index, + /* [retval][out] */ IDiaFrameData **frame); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumFrameData * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaFrameData **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumFrameData * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumFrameData * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumFrameData * This, + /* [out] */ IDiaEnumFrameData **ppenum); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *frameByRVA )( + IDiaEnumFrameData * This, + /* [in] */ DWORD relativeVirtualAddress, + /* [retval][out] */ IDiaFrameData **frame); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *frameByVA )( + IDiaEnumFrameData * This, + /* [in] */ ULONGLONG virtualAddress, + /* [retval][out] */ IDiaFrameData **frame); + + END_INTERFACE + } IDiaEnumFrameDataVtbl; + + interface IDiaEnumFrameData + { + CONST_VTBL struct IDiaEnumFrameDataVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumFrameData_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumFrameData_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumFrameData_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumFrameData_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumFrameData_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumFrameData_Item(This,index,frame) \ + ( (This)->lpVtbl -> Item(This,index,frame) ) + +#define IDiaEnumFrameData_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumFrameData_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumFrameData_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumFrameData_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#define IDiaEnumFrameData_frameByRVA(This,relativeVirtualAddress,frame) \ + ( (This)->lpVtbl -> frameByRVA(This,relativeVirtualAddress,frame) ) + +#define IDiaEnumFrameData_frameByVA(This,virtualAddress,frame) \ + ( (This)->lpVtbl -> frameByVA(This,virtualAddress,frame) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumFrameData_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumDebugStreamData_INTERFACE_DEFINED__ +#define __IDiaEnumDebugStreamData_INTERFACE_DEFINED__ + +/* interface IDiaEnumDebugStreamData */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumDebugStreamData; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("486943E8-D187-4a6b-A3C4-291259FFF60D") + IDiaEnumDebugStreamData : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_name( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumDebugStreamData **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumDebugStreamDataVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumDebugStreamData * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumDebugStreamData * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumDebugStreamData * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumDebugStreamData * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumDebugStreamData * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaEnumDebugStreamData * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumDebugStreamData * This, + /* [in] */ DWORD index, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumDebugStreamData * This, + /* [in] */ ULONG celt, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumDebugStreamData * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumDebugStreamData * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumDebugStreamData * This, + /* [out] */ IDiaEnumDebugStreamData **ppenum); + + END_INTERFACE + } IDiaEnumDebugStreamDataVtbl; + + interface IDiaEnumDebugStreamData + { + CONST_VTBL struct IDiaEnumDebugStreamDataVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumDebugStreamData_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumDebugStreamData_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumDebugStreamData_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumDebugStreamData_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumDebugStreamData_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumDebugStreamData_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaEnumDebugStreamData_Item(This,index,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> Item(This,index,cbData,pcbData,pbData) ) + +#define IDiaEnumDebugStreamData_Next(This,celt,cbData,pcbData,pbData,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,cbData,pcbData,pbData,pceltFetched) ) + +#define IDiaEnumDebugStreamData_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumDebugStreamData_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumDebugStreamData_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumDebugStreamData_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumDebugStreams_INTERFACE_DEFINED__ +#define __IDiaEnumDebugStreams_INTERFACE_DEFINED__ + +/* interface IDiaEnumDebugStreams */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumDebugStreams; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("08CBB41E-47A6-4f87-92F1-1C9C87CED044") + IDiaEnumDebugStreams : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ VARIANT index, + /* [retval][out] */ IDiaEnumDebugStreamData **stream) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaEnumDebugStreamData **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumDebugStreams **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumDebugStreamsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumDebugStreams * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumDebugStreams * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumDebugStreams * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumDebugStreams * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumDebugStreams * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumDebugStreams * This, + /* [in] */ VARIANT index, + /* [retval][out] */ IDiaEnumDebugStreamData **stream); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumDebugStreams * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaEnumDebugStreamData **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumDebugStreams * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumDebugStreams * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumDebugStreams * This, + /* [out] */ IDiaEnumDebugStreams **ppenum); + + END_INTERFACE + } IDiaEnumDebugStreamsVtbl; + + interface IDiaEnumDebugStreams + { + CONST_VTBL struct IDiaEnumDebugStreamsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumDebugStreams_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumDebugStreams_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumDebugStreams_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumDebugStreams_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumDebugStreams_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumDebugStreams_Item(This,index,stream) \ + ( (This)->lpVtbl -> Item(This,index,stream) ) + +#define IDiaEnumDebugStreams_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumDebugStreams_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumDebugStreams_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumDebugStreams_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumDebugStreams_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dia2_0000_0016 */ +/* [local] */ + +struct DiaAddressMapEntry + { + DWORD rva; + DWORD rvaTo; + } ; + + +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0016_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0016_v0_0_s_ifspec; + +#ifndef __IDiaAddressMap_INTERFACE_DEFINED__ +#define __IDiaAddressMap_INTERFACE_DEFINED__ + +/* interface IDiaAddressMap */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaAddressMap; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("B62A2E7A-067A-4ea3-B598-04C09717502C") + IDiaAddressMap : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressMapEnabled( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_addressMapEnabled( + /* [in] */ BOOL NewVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddressEnabled( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_relativeVirtualAddressEnabled( + /* [in] */ BOOL NewVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_imageAlign( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_imageAlign( + /* [in] */ DWORD NewVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE set_imageHeaders( + /* [in] */ DWORD cbData, + /* [size_is][in] */ BYTE *pbData, + /* [in] */ BOOL originalHeaders) = 0; + + virtual HRESULT STDMETHODCALLTYPE set_addressMap( + /* [in] */ DWORD cData, + /* [size_is][in] */ struct DiaAddressMapEntry *pData, + /* [in] */ BOOL imageToSymbols) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaAddressMapVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaAddressMap * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaAddressMap * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaAddressMap * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressMapEnabled )( + IDiaAddressMap * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_addressMapEnabled )( + IDiaAddressMap * This, + /* [in] */ BOOL NewVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddressEnabled )( + IDiaAddressMap * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_relativeVirtualAddressEnabled )( + IDiaAddressMap * This, + /* [in] */ BOOL NewVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_imageAlign )( + IDiaAddressMap * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_imageAlign )( + IDiaAddressMap * This, + /* [in] */ DWORD NewVal); + + HRESULT ( STDMETHODCALLTYPE *set_imageHeaders )( + IDiaAddressMap * This, + /* [in] */ DWORD cbData, + /* [size_is][in] */ BYTE *pbData, + /* [in] */ BOOL originalHeaders); + + HRESULT ( STDMETHODCALLTYPE *set_addressMap )( + IDiaAddressMap * This, + /* [in] */ DWORD cData, + /* [size_is][in] */ struct DiaAddressMapEntry *pData, + /* [in] */ BOOL imageToSymbols); + + END_INTERFACE + } IDiaAddressMapVtbl; + + interface IDiaAddressMap + { + CONST_VTBL struct IDiaAddressMapVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaAddressMap_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaAddressMap_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaAddressMap_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaAddressMap_get_addressMapEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressMapEnabled(This,pRetVal) ) + +#define IDiaAddressMap_put_addressMapEnabled(This,NewVal) \ + ( (This)->lpVtbl -> put_addressMapEnabled(This,NewVal) ) + +#define IDiaAddressMap_get_relativeVirtualAddressEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddressEnabled(This,pRetVal) ) + +#define IDiaAddressMap_put_relativeVirtualAddressEnabled(This,NewVal) \ + ( (This)->lpVtbl -> put_relativeVirtualAddressEnabled(This,NewVal) ) + +#define IDiaAddressMap_get_imageAlign(This,pRetVal) \ + ( (This)->lpVtbl -> get_imageAlign(This,pRetVal) ) + +#define IDiaAddressMap_put_imageAlign(This,NewVal) \ + ( (This)->lpVtbl -> put_imageAlign(This,NewVal) ) + +#define IDiaAddressMap_set_imageHeaders(This,cbData,pbData,originalHeaders) \ + ( (This)->lpVtbl -> set_imageHeaders(This,cbData,pbData,originalHeaders) ) + +#define IDiaAddressMap_set_addressMap(This,cData,pData,imageToSymbols) \ + ( (This)->lpVtbl -> set_addressMap(This,cData,pData,imageToSymbols) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaAddressMap_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSession_INTERFACE_DEFINED__ +#define __IDiaSession_INTERFACE_DEFINED__ + +/* interface IDiaSession */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSession; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2F609EE1-D1C8-4E24-8288-3326BADCD211") + IDiaSession : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_loadAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_loadAddress( + /* [in] */ ULONGLONG NewVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_globalScope( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE getEnumTables( + /* [out] */ IDiaEnumTables **ppEnumTables) = 0; + + virtual HRESULT STDMETHODCALLTYPE getSymbolsByAddr( + /* [out] */ IDiaEnumSymbolsByAddr **ppEnumbyAddr) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildren( + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildrenEx( + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildrenExByAddr( + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildrenExByVA( + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildrenExByRVA( + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolByAddr( + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolByRVA( + /* [in] */ DWORD rva, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolByVA( + /* [in] */ ULONGLONG va, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolByToken( + /* [in] */ ULONG token, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol) = 0; + + virtual HRESULT STDMETHODCALLTYPE symsAreEquiv( + /* [in] */ IDiaSymbol *symbolA, + /* [in] */ IDiaSymbol *symbolB) = 0; + + virtual HRESULT STDMETHODCALLTYPE symbolById( + /* [in] */ DWORD id, + /* [out] */ IDiaSymbol **ppSymbol) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolByRVAEx( + /* [in] */ DWORD rva, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol, + /* [out] */ long *displacement) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolByVAEx( + /* [in] */ ULONGLONG va, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol, + /* [out] */ long *displacement) = 0; + + virtual HRESULT STDMETHODCALLTYPE findFile( + /* [in] */ IDiaSymbol *pCompiland, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSourceFiles **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findFileById( + /* [in] */ DWORD uniqueId, + /* [out] */ IDiaSourceFile **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findLines( + /* [in] */ IDiaSymbol *compiland, + /* [in] */ IDiaSourceFile *file, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findLinesByAddr( + /* [in] */ DWORD seg, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findLinesByRVA( + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findLinesByVA( + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findLinesByLinenum( + /* [in] */ IDiaSymbol *compiland, + /* [in] */ IDiaSourceFile *file, + /* [in] */ DWORD linenum, + /* [in] */ DWORD column, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInjectedSource( + /* [in] */ LPCOLESTR srcFile, + /* [out] */ IDiaEnumInjectedSources **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE getEnumDebugStreams( + /* [out] */ IDiaEnumDebugStreams **ppEnumDebugStreams) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineFramesByAddr( + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineFramesByRVA( + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineFramesByVA( + /* [in] */ IDiaSymbol *parent, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLines( + /* [in] */ IDiaSymbol *parent, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLinesByAddr( + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLinesByRVA( + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLinesByVA( + /* [in] */ IDiaSymbol *parent, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLinesByLinenum( + /* [in] */ IDiaSymbol *compiland, + /* [in] */ IDiaSourceFile *file, + /* [in] */ DWORD linenum, + /* [in] */ DWORD column, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineesByName( + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD option, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findAcceleratorInlineeLinesByLinenum( + /* [in] */ IDiaSymbol *parent, + /* [in] */ IDiaSourceFile *file, + /* [in] */ DWORD linenum, + /* [in] */ DWORD column, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolsForAcceleratorPointerTag( + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolsByRVAForAcceleratorPointerTag( + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findAcceleratorInlineesByName( + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD option, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE addressForVA( + /* [in] */ ULONGLONG va, + /* [out] */ DWORD *pISect, + /* [out] */ DWORD *pOffset) = 0; + + virtual HRESULT STDMETHODCALLTYPE addressForRVA( + /* [in] */ DWORD rva, + /* [out] */ DWORD *pISect, + /* [out] */ DWORD *pOffset) = 0; + + virtual HRESULT STDMETHODCALLTYPE findILOffsetsByAddr( + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findILOffsetsByRVA( + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findILOffsetsByVA( + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInputAssemblyFiles( + /* [out] */ IDiaEnumInputAssemblyFiles **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInputAssembly( + /* [in] */ DWORD index, + /* [out] */ IDiaInputAssemblyFile **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInputAssemblyById( + /* [in] */ DWORD uniqueId, + /* [out] */ IDiaInputAssemblyFile **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE getFuncMDTokenMapSize( + /* [out] */ DWORD *pcb) = 0; + + virtual HRESULT STDMETHODCALLTYPE getFuncMDTokenMap( + /* [in] */ DWORD cb, + /* [out] */ DWORD *pcb, + /* [size_is][out] */ BYTE *pb) = 0; + + virtual HRESULT STDMETHODCALLTYPE getTypeMDTokenMapSize( + /* [out] */ DWORD *pcb) = 0; + + virtual HRESULT STDMETHODCALLTYPE getTypeMDTokenMap( + /* [in] */ DWORD cb, + /* [out] */ DWORD *pcb, + /* [size_is][out] */ BYTE *pb) = 0; + + virtual HRESULT STDMETHODCALLTYPE getNumberOfFunctionFragments_VA( + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [out] */ DWORD *pNumFragments) = 0; + + virtual HRESULT STDMETHODCALLTYPE getNumberOfFunctionFragments_RVA( + /* [in] */ DWORD rvaFunc, + /* [in] */ DWORD cbFunc, + /* [out] */ DWORD *pNumFragments) = 0; + + virtual HRESULT STDMETHODCALLTYPE getFunctionFragments_VA( + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [in] */ DWORD cFragments, + /* [size_is][out] */ ULONGLONG *pVaFragment, + /* [size_is][out] */ DWORD *pLenFragment) = 0; + + virtual HRESULT STDMETHODCALLTYPE getFunctionFragments_RVA( + /* [in] */ DWORD rvaFunc, + /* [in] */ DWORD cbFunc, + /* [in] */ DWORD cFragments, + /* [size_is][out] */ DWORD *pRvaFragment, + /* [size_is][out] */ DWORD *pLenFragment) = 0; + + virtual HRESULT STDMETHODCALLTYPE getExports( + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE getHeapAllocationSites( + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInputAssemblyFile( + /* [in] */ IDiaSymbol *pSymbol, + /* [out] */ IDiaInputAssemblyFile **ppResult) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSessionVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSession * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSession * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSession * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_loadAddress )( + IDiaSession * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_loadAddress )( + IDiaSession * This, + /* [in] */ ULONGLONG NewVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_globalScope )( + IDiaSession * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + HRESULT ( STDMETHODCALLTYPE *getEnumTables )( + IDiaSession * This, + /* [out] */ IDiaEnumTables **ppEnumTables); + + HRESULT ( STDMETHODCALLTYPE *getSymbolsByAddr )( + IDiaSession * This, + /* [out] */ IDiaEnumSymbolsByAddr **ppEnumbyAddr); + + HRESULT ( STDMETHODCALLTYPE *findChildren )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenEx )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolByAddr )( + IDiaSession * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol); + + HRESULT ( STDMETHODCALLTYPE *findSymbolByRVA )( + IDiaSession * This, + /* [in] */ DWORD rva, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol); + + HRESULT ( STDMETHODCALLTYPE *findSymbolByVA )( + IDiaSession * This, + /* [in] */ ULONGLONG va, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol); + + HRESULT ( STDMETHODCALLTYPE *findSymbolByToken )( + IDiaSession * This, + /* [in] */ ULONG token, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol); + + HRESULT ( STDMETHODCALLTYPE *symsAreEquiv )( + IDiaSession * This, + /* [in] */ IDiaSymbol *symbolA, + /* [in] */ IDiaSymbol *symbolB); + + HRESULT ( STDMETHODCALLTYPE *symbolById )( + IDiaSession * This, + /* [in] */ DWORD id, + /* [out] */ IDiaSymbol **ppSymbol); + + HRESULT ( STDMETHODCALLTYPE *findSymbolByRVAEx )( + IDiaSession * This, + /* [in] */ DWORD rva, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol, + /* [out] */ long *displacement); + + HRESULT ( STDMETHODCALLTYPE *findSymbolByVAEx )( + IDiaSession * This, + /* [in] */ ULONGLONG va, + /* [in] */ enum SymTagEnum symtag, + /* [out] */ IDiaSymbol **ppSymbol, + /* [out] */ long *displacement); + + HRESULT ( STDMETHODCALLTYPE *findFile )( + IDiaSession * This, + /* [in] */ IDiaSymbol *pCompiland, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSourceFiles **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findFileById )( + IDiaSession * This, + /* [in] */ DWORD uniqueId, + /* [out] */ IDiaSourceFile **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findLines )( + IDiaSession * This, + /* [in] */ IDiaSymbol *compiland, + /* [in] */ IDiaSourceFile *file, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findLinesByAddr )( + IDiaSession * This, + /* [in] */ DWORD seg, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findLinesByRVA )( + IDiaSession * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findLinesByVA )( + IDiaSession * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findLinesByLinenum )( + IDiaSession * This, + /* [in] */ IDiaSymbol *compiland, + /* [in] */ IDiaSourceFile *file, + /* [in] */ DWORD linenum, + /* [in] */ DWORD column, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInjectedSource )( + IDiaSession * This, + /* [in] */ LPCOLESTR srcFile, + /* [out] */ IDiaEnumInjectedSources **ppResult); + + HRESULT ( STDMETHODCALLTYPE *getEnumDebugStreams )( + IDiaSession * This, + /* [out] */ IDiaEnumDebugStreams **ppEnumDebugStreams); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByAddr )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByRVA )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByVA )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLines )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByAddr )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByRVA )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByVA )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByLinenum )( + IDiaSession * This, + /* [in] */ IDiaSymbol *compiland, + /* [in] */ IDiaSourceFile *file, + /* [in] */ DWORD linenum, + /* [in] */ DWORD column, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineesByName )( + IDiaSession * This, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD option, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findAcceleratorInlineeLinesByLinenum )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ IDiaSourceFile *file, + /* [in] */ DWORD linenum, + /* [in] */ DWORD column, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsForAcceleratorPointerTag )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsByRVAForAcceleratorPointerTag )( + IDiaSession * This, + /* [in] */ IDiaSymbol *parent, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findAcceleratorInlineesByName )( + IDiaSession * This, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD option, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *addressForVA )( + IDiaSession * This, + /* [in] */ ULONGLONG va, + /* [out] */ DWORD *pISect, + /* [out] */ DWORD *pOffset); + + HRESULT ( STDMETHODCALLTYPE *addressForRVA )( + IDiaSession * This, + /* [in] */ DWORD rva, + /* [out] */ DWORD *pISect, + /* [out] */ DWORD *pOffset); + + HRESULT ( STDMETHODCALLTYPE *findILOffsetsByAddr )( + IDiaSession * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findILOffsetsByRVA )( + IDiaSession * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findILOffsetsByVA )( + IDiaSession * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFiles )( + IDiaSession * This, + /* [out] */ IDiaEnumInputAssemblyFiles **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInputAssembly )( + IDiaSession * This, + /* [in] */ DWORD index, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyById )( + IDiaSession * This, + /* [in] */ DWORD uniqueId, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + HRESULT ( STDMETHODCALLTYPE *getFuncMDTokenMapSize )( + IDiaSession * This, + /* [out] */ DWORD *pcb); + + HRESULT ( STDMETHODCALLTYPE *getFuncMDTokenMap )( + IDiaSession * This, + /* [in] */ DWORD cb, + /* [out] */ DWORD *pcb, + /* [size_is][out] */ BYTE *pb); + + HRESULT ( STDMETHODCALLTYPE *getTypeMDTokenMapSize )( + IDiaSession * This, + /* [out] */ DWORD *pcb); + + HRESULT ( STDMETHODCALLTYPE *getTypeMDTokenMap )( + IDiaSession * This, + /* [in] */ DWORD cb, + /* [out] */ DWORD *pcb, + /* [size_is][out] */ BYTE *pb); + + HRESULT ( STDMETHODCALLTYPE *getNumberOfFunctionFragments_VA )( + IDiaSession * This, + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [out] */ DWORD *pNumFragments); + + HRESULT ( STDMETHODCALLTYPE *getNumberOfFunctionFragments_RVA )( + IDiaSession * This, + /* [in] */ DWORD rvaFunc, + /* [in] */ DWORD cbFunc, + /* [out] */ DWORD *pNumFragments); + + HRESULT ( STDMETHODCALLTYPE *getFunctionFragments_VA )( + IDiaSession * This, + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [in] */ DWORD cFragments, + /* [size_is][out] */ ULONGLONG *pVaFragment, + /* [size_is][out] */ DWORD *pLenFragment); + + HRESULT ( STDMETHODCALLTYPE *getFunctionFragments_RVA )( + IDiaSession * This, + /* [in] */ DWORD rvaFunc, + /* [in] */ DWORD cbFunc, + /* [in] */ DWORD cFragments, + /* [size_is][out] */ DWORD *pRvaFragment, + /* [size_is][out] */ DWORD *pLenFragment); + + HRESULT ( STDMETHODCALLTYPE *getExports )( + IDiaSession * This, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *getHeapAllocationSites )( + IDiaSession * This, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFile )( + IDiaSession * This, + /* [in] */ IDiaSymbol *pSymbol, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + END_INTERFACE + } IDiaSessionVtbl; + + interface IDiaSession + { + CONST_VTBL struct IDiaSessionVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSession_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSession_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSession_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSession_get_loadAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_loadAddress(This,pRetVal) ) + +#define IDiaSession_put_loadAddress(This,NewVal) \ + ( (This)->lpVtbl -> put_loadAddress(This,NewVal) ) + +#define IDiaSession_get_globalScope(This,pRetVal) \ + ( (This)->lpVtbl -> get_globalScope(This,pRetVal) ) + +#define IDiaSession_getEnumTables(This,ppEnumTables) \ + ( (This)->lpVtbl -> getEnumTables(This,ppEnumTables) ) + +#define IDiaSession_getSymbolsByAddr(This,ppEnumbyAddr) \ + ( (This)->lpVtbl -> getSymbolsByAddr(This,ppEnumbyAddr) ) + +#define IDiaSession_findChildren(This,parent,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildren(This,parent,symtag,name,compareFlags,ppResult) ) + +#define IDiaSession_findChildrenEx(This,parent,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildrenEx(This,parent,symtag,name,compareFlags,ppResult) ) + +#define IDiaSession_findChildrenExByAddr(This,parent,symtag,name,compareFlags,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByAddr(This,parent,symtag,name,compareFlags,isect,offset,ppResult) ) + +#define IDiaSession_findChildrenExByVA(This,parent,symtag,name,compareFlags,va,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByVA(This,parent,symtag,name,compareFlags,va,ppResult) ) + +#define IDiaSession_findChildrenExByRVA(This,parent,symtag,name,compareFlags,rva,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByRVA(This,parent,symtag,name,compareFlags,rva,ppResult) ) + +#define IDiaSession_findSymbolByAddr(This,isect,offset,symtag,ppSymbol) \ + ( (This)->lpVtbl -> findSymbolByAddr(This,isect,offset,symtag,ppSymbol) ) + +#define IDiaSession_findSymbolByRVA(This,rva,symtag,ppSymbol) \ + ( (This)->lpVtbl -> findSymbolByRVA(This,rva,symtag,ppSymbol) ) + +#define IDiaSession_findSymbolByVA(This,va,symtag,ppSymbol) \ + ( (This)->lpVtbl -> findSymbolByVA(This,va,symtag,ppSymbol) ) + +#define IDiaSession_findSymbolByToken(This,token,symtag,ppSymbol) \ + ( (This)->lpVtbl -> findSymbolByToken(This,token,symtag,ppSymbol) ) + +#define IDiaSession_symsAreEquiv(This,symbolA,symbolB) \ + ( (This)->lpVtbl -> symsAreEquiv(This,symbolA,symbolB) ) + +#define IDiaSession_symbolById(This,id,ppSymbol) \ + ( (This)->lpVtbl -> symbolById(This,id,ppSymbol) ) + +#define IDiaSession_findSymbolByRVAEx(This,rva,symtag,ppSymbol,displacement) \ + ( (This)->lpVtbl -> findSymbolByRVAEx(This,rva,symtag,ppSymbol,displacement) ) + +#define IDiaSession_findSymbolByVAEx(This,va,symtag,ppSymbol,displacement) \ + ( (This)->lpVtbl -> findSymbolByVAEx(This,va,symtag,ppSymbol,displacement) ) + +#define IDiaSession_findFile(This,pCompiland,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findFile(This,pCompiland,name,compareFlags,ppResult) ) + +#define IDiaSession_findFileById(This,uniqueId,ppResult) \ + ( (This)->lpVtbl -> findFileById(This,uniqueId,ppResult) ) + +#define IDiaSession_findLines(This,compiland,file,ppResult) \ + ( (This)->lpVtbl -> findLines(This,compiland,file,ppResult) ) + +#define IDiaSession_findLinesByAddr(This,seg,offset,length,ppResult) \ + ( (This)->lpVtbl -> findLinesByAddr(This,seg,offset,length,ppResult) ) + +#define IDiaSession_findLinesByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findLinesByRVA(This,rva,length,ppResult) ) + +#define IDiaSession_findLinesByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findLinesByVA(This,va,length,ppResult) ) + +#define IDiaSession_findLinesByLinenum(This,compiland,file,linenum,column,ppResult) \ + ( (This)->lpVtbl -> findLinesByLinenum(This,compiland,file,linenum,column,ppResult) ) + +#define IDiaSession_findInjectedSource(This,srcFile,ppResult) \ + ( (This)->lpVtbl -> findInjectedSource(This,srcFile,ppResult) ) + +#define IDiaSession_getEnumDebugStreams(This,ppEnumDebugStreams) \ + ( (This)->lpVtbl -> getEnumDebugStreams(This,ppEnumDebugStreams) ) + +#define IDiaSession_findInlineFramesByAddr(This,parent,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByAddr(This,parent,isect,offset,ppResult) ) + +#define IDiaSession_findInlineFramesByRVA(This,parent,rva,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByRVA(This,parent,rva,ppResult) ) + +#define IDiaSession_findInlineFramesByVA(This,parent,va,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByVA(This,parent,va,ppResult) ) + +#define IDiaSession_findInlineeLines(This,parent,ppResult) \ + ( (This)->lpVtbl -> findInlineeLines(This,parent,ppResult) ) + +#define IDiaSession_findInlineeLinesByAddr(This,parent,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByAddr(This,parent,isect,offset,length,ppResult) ) + +#define IDiaSession_findInlineeLinesByRVA(This,parent,rva,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByRVA(This,parent,rva,length,ppResult) ) + +#define IDiaSession_findInlineeLinesByVA(This,parent,va,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByVA(This,parent,va,length,ppResult) ) + +#define IDiaSession_findInlineeLinesByLinenum(This,compiland,file,linenum,column,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByLinenum(This,compiland,file,linenum,column,ppResult) ) + +#define IDiaSession_findInlineesByName(This,name,option,ppResult) \ + ( (This)->lpVtbl -> findInlineesByName(This,name,option,ppResult) ) + +#define IDiaSession_findAcceleratorInlineeLinesByLinenum(This,parent,file,linenum,column,ppResult) \ + ( (This)->lpVtbl -> findAcceleratorInlineeLinesByLinenum(This,parent,file,linenum,column,ppResult) ) + +#define IDiaSession_findSymbolsForAcceleratorPointerTag(This,parent,tagValue,ppResult) \ + ( (This)->lpVtbl -> findSymbolsForAcceleratorPointerTag(This,parent,tagValue,ppResult) ) + +#define IDiaSession_findSymbolsByRVAForAcceleratorPointerTag(This,parent,tagValue,rva,ppResult) \ + ( (This)->lpVtbl -> findSymbolsByRVAForAcceleratorPointerTag(This,parent,tagValue,rva,ppResult) ) + +#define IDiaSession_findAcceleratorInlineesByName(This,name,option,ppResult) \ + ( (This)->lpVtbl -> findAcceleratorInlineesByName(This,name,option,ppResult) ) + +#define IDiaSession_addressForVA(This,va,pISect,pOffset) \ + ( (This)->lpVtbl -> addressForVA(This,va,pISect,pOffset) ) + +#define IDiaSession_addressForRVA(This,rva,pISect,pOffset) \ + ( (This)->lpVtbl -> addressForRVA(This,rva,pISect,pOffset) ) + +#define IDiaSession_findILOffsetsByAddr(This,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findILOffsetsByAddr(This,isect,offset,length,ppResult) ) + +#define IDiaSession_findILOffsetsByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findILOffsetsByRVA(This,rva,length,ppResult) ) + +#define IDiaSession_findILOffsetsByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findILOffsetsByVA(This,va,length,ppResult) ) + +#define IDiaSession_findInputAssemblyFiles(This,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFiles(This,ppResult) ) + +#define IDiaSession_findInputAssembly(This,index,ppResult) \ + ( (This)->lpVtbl -> findInputAssembly(This,index,ppResult) ) + +#define IDiaSession_findInputAssemblyById(This,uniqueId,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyById(This,uniqueId,ppResult) ) + +#define IDiaSession_getFuncMDTokenMapSize(This,pcb) \ + ( (This)->lpVtbl -> getFuncMDTokenMapSize(This,pcb) ) + +#define IDiaSession_getFuncMDTokenMap(This,cb,pcb,pb) \ + ( (This)->lpVtbl -> getFuncMDTokenMap(This,cb,pcb,pb) ) + +#define IDiaSession_getTypeMDTokenMapSize(This,pcb) \ + ( (This)->lpVtbl -> getTypeMDTokenMapSize(This,pcb) ) + +#define IDiaSession_getTypeMDTokenMap(This,cb,pcb,pb) \ + ( (This)->lpVtbl -> getTypeMDTokenMap(This,cb,pcb,pb) ) + +#define IDiaSession_getNumberOfFunctionFragments_VA(This,vaFunc,cbFunc,pNumFragments) \ + ( (This)->lpVtbl -> getNumberOfFunctionFragments_VA(This,vaFunc,cbFunc,pNumFragments) ) + +#define IDiaSession_getNumberOfFunctionFragments_RVA(This,rvaFunc,cbFunc,pNumFragments) \ + ( (This)->lpVtbl -> getNumberOfFunctionFragments_RVA(This,rvaFunc,cbFunc,pNumFragments) ) + +#define IDiaSession_getFunctionFragments_VA(This,vaFunc,cbFunc,cFragments,pVaFragment,pLenFragment) \ + ( (This)->lpVtbl -> getFunctionFragments_VA(This,vaFunc,cbFunc,cFragments,pVaFragment,pLenFragment) ) + +#define IDiaSession_getFunctionFragments_RVA(This,rvaFunc,cbFunc,cFragments,pRvaFragment,pLenFragment) \ + ( (This)->lpVtbl -> getFunctionFragments_RVA(This,rvaFunc,cbFunc,cFragments,pRvaFragment,pLenFragment) ) + +#define IDiaSession_getExports(This,ppResult) \ + ( (This)->lpVtbl -> getExports(This,ppResult) ) + +#define IDiaSession_getHeapAllocationSites(This,ppResult) \ + ( (This)->lpVtbl -> getHeapAllocationSites(This,ppResult) ) + +#define IDiaSession_findInputAssemblyFile(This,pSymbol,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFile(This,pSymbol,ppResult) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaSession_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSymbol_INTERFACE_DEFINED__ +#define __IDiaSymbol_INTERFACE_DEFINED__ + +/* interface IDiaSymbol */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSymbol; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("cb787b2f-bd6c-4635-ba52-933126bd2dcd") + IDiaSymbol : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_symIndexId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_symTag( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_name( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lexicalParent( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_classParent( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_type( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_dataKind( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_locationType( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_offset( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_slot( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_volatileType( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_constType( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_unalignedType( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_access( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_libraryName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_platform( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_language( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_editAndContinueEnabled( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frontEndMajor( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frontEndMinor( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frontEndBuild( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_backEndMajor( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_backEndMinor( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_backEndBuild( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sourceFileName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_unused( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_thunkOrdinal( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_thisAdjust( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBaseOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtual( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_intro( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_pure( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_callingConvention( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_value( + /* [retval][out] */ VARIANT *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_baseType( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_token( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_timeStamp( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_guid( + /* [retval][out] */ GUID *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_symbolsFileName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_reference( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_count( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_bitPosition( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_arrayIndexType( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_packed( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_constructor( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_overloadedOperator( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_nested( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasNestedTypes( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasAssignmentOperator( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasCastOperator( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_scoped( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBaseClass( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_indirectVirtualBaseClass( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBasePointerOffset( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualTableShape( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lexicalParentId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_classParentId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_typeId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_arrayIndexTypeId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualTableShapeId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_code( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_function( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_managed( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_msil( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBaseDispIndex( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_undecoratedName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_age( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_signature( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilerGenerated( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressTaken( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_rank( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lowerBound( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_upperBound( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lowerBoundId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_upperBoundId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_dataBytes( + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildren( + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildrenEx( + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildrenExByAddr( + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildrenExByVA( + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findChildrenExByRVA( + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_targetSection( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_targetOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_targetRelativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_targetVirtualAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_machineType( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_oemId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_oemSymbolId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_types( + /* [in] */ DWORD cTypes, + /* [out] */ DWORD *pcTypes, + /* [size_is][size_is][out] */ IDiaSymbol **pTypes) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_typeIds( + /* [in] */ DWORD cTypeIds, + /* [out] */ DWORD *pcTypeIds, + /* [size_is][out] */ DWORD *pdwTypeIds) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_objectPointerType( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_udtKind( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_undecoratedNameEx( + /* [in] */ DWORD undecorateOptions, + /* [out] */ BSTR *name) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_noReturn( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_customCallingConvention( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_noInline( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_optimizedCodeDebugInfo( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_notReached( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_interruptReturn( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_farReturn( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isStatic( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasDebugInfo( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isLTCG( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isDataAligned( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasSecurityChecks( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilerName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasAlloca( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasSetJump( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasLongJump( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasInlAsm( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasEH( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasSEH( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasEHa( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isNaked( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isAggregated( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isSplitted( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_container( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_inlSpec( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_noStackOrdering( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBaseTableType( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasManagedCode( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isHotpatchable( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isCVTCIL( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isMSILNetmodule( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isCTypes( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isStripped( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frontEndQFE( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_backEndQFE( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_wasInlined( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_strictGSCheck( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isCxxReturnUdt( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isConstructorVirtualBase( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_RValueReference( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_unmodifiedType( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_framePointerPresent( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isSafeBuffers( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_intrinsic( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sealed( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hfaFloat( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hfaDouble( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_liveRangeStartAddressSection( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_liveRangeStartAddressOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_liveRangeStartRelativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_countLiveRanges( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_liveRangeLength( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_offsetInUdt( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_paramBasePointerRegisterId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_localBasePointerRegisterId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isLocationControlFlowDependent( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_stride( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_numberOfRows( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_numberOfColumns( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isMatrixRowMajor( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_numericProperties( + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_modifierValues( + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isReturnValue( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isOptimizedAway( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_builtInKind( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerType( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_baseDataSlot( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_baseDataOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_textureSlot( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_samplerSlot( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_uavSlot( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sizeInUdt( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_memorySpaceKind( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_unmodifiedTypeId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_subTypeId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_subType( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_numberOfModifiers( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_numberOfRegisterIndices( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isHLSLData( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isPointerToDataMember( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isPointerToMemberFunction( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isSingleInheritance( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isMultipleInheritance( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isVirtualInheritance( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_restrictedType( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isPointerBasedOnSymbolValue( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_baseSymbol( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_baseSymbolId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_objectFileName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isAcceleratorGroupSharedLocal( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isAcceleratorPointerTagLiveRange( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isAcceleratorStubFunction( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_numberOfAcceleratorPointerTags( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isSdl( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isWinRTPointer( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isRefUdt( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isValueUdt( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isInterfaceUdt( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineFramesByAddr( + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineFramesByRVA( + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineFramesByVA( + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLines( + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLinesByAddr( + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLinesByRVA( + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInlineeLinesByVA( + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolsForAcceleratorPointerTag( + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE findSymbolsByRVAForAcceleratorPointerTag( + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_acceleratorPointerTags( + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags) = 0; + + virtual HRESULT STDMETHODCALLTYPE getSrcLineOnTypeDefn( + /* [out] */ IDiaLineNumber **ppResult) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isPGO( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasValidPGOCounts( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isOptimizedForSpeed( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PGOEntryCount( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PGOEdgeCount( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_PGODynamicInstructionCount( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_staticSize( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_finalLiveStaticSize( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_phaseName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasControlFlowCheck( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_constantExport( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_dataExport( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_privateExport( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_noNameExport( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_exportHasExplicitlyAssignedOrdinal( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_exportIsForwarder( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_ordinal( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frameSize( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_exceptionHandlerAddressSection( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_exceptionHandlerAddressOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_exceptionHandlerRelativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_exceptionHandlerVirtualAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE findInputAssemblyFile( + /* [out] */ IDiaInputAssemblyFile **ppResult) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_characteristics( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_coffGroup( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_bindID( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_bindSpace( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_bindSlot( + /* [retval][out] */ DWORD *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSymbolVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSymbol * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSymbol * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSymbol * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symIndexId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symTag )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParent )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParent )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataKind )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_locationType )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )( + IDiaSymbol * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_slot )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_volatileType )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constType )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unalignedType )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_access )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_libraryName )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_platform )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_language )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_editAndContinueEnabled )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMajor )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMinor )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndBuild )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMajor )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMinor )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndBuild )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileName )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unused )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thunkOrdinal )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thisAdjust )( + IDiaSymbol * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseOffset )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtual )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intro )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pure )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_callingConvention )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_value )( + IDiaSymbol * This, + /* [retval][out] */ VARIANT *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseType )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_token )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timeStamp )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_guid )( + IDiaSymbol * This, + /* [retval][out] */ GUID *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symbolsFileName )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_reference )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_count )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bitPosition )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexType )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_packed )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constructor )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_overloadedOperator )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_nested )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasNestedTypes )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAssignmentOperator )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasCastOperator )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_scoped )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseClass )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_indirectVirtualBaseClass )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBasePointerOffset )( + IDiaSymbol * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShape )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParentId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParentId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_typeId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexTypeId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShapeId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_function )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_managed )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_msil )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseDispIndex )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_undecoratedName )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_age )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_signature )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerGenerated )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressTaken )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_rank )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBound )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBound )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBoundId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBoundId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_dataBytes )( + IDiaSymbol * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *findChildren )( + IDiaSymbol * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenEx )( + IDiaSymbol * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )( + IDiaSymbol * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )( + IDiaSymbol * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )( + IDiaSymbol * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetSection )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetOffset )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetRelativeVirtualAddress )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetVirtualAddress )( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_machineType )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemSymbolId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_types )( + IDiaSymbol * This, + /* [in] */ DWORD cTypes, + /* [out] */ DWORD *pcTypes, + /* [size_is][size_is][out] */ IDiaSymbol **pTypes); + + HRESULT ( STDMETHODCALLTYPE *get_typeIds )( + IDiaSymbol * This, + /* [in] */ DWORD cTypeIds, + /* [out] */ DWORD *pcTypeIds, + /* [size_is][out] */ DWORD *pdwTypeIds); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectPointerType )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_udtKind )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_undecoratedNameEx )( + IDiaSymbol * This, + /* [in] */ DWORD undecorateOptions, + /* [out] */ BSTR *name); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noReturn )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_customCallingConvention )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noInline )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_optimizedCodeDebugInfo )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notReached )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_interruptReturn )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_farReturn )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStatic )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasDebugInfo )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLTCG )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isDataAligned )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSecurityChecks )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerName )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAlloca )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSetJump )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasLongJump )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasInlAsm )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEH )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSEH )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEHa )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isNaked )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAggregated )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSplitted )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_container )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlSpec )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noStackOrdering )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseTableType )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasManagedCode )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHotpatchable )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCVTCIL )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMSILNetmodule )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCTypes )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStripped )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndQFE )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndQFE )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_wasInlined )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_strictGSCheck )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCxxReturnUdt )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isConstructorVirtualBase )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RValueReference )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedType )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_framePointerPresent )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSafeBuffers )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intrinsic )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sealed )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaFloat )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaDouble )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressSection )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressOffset )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartRelativeVirtualAddress )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_countLiveRanges )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeLength )( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offsetInUdt )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_paramBasePointerRegisterId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localBasePointerRegisterId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLocationControlFlowDependent )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_stride )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRows )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfColumns )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMatrixRowMajor )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_numericProperties )( + IDiaSymbol * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties); + + HRESULT ( STDMETHODCALLTYPE *get_modifierValues )( + IDiaSymbol * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isReturnValue )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedAway )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_builtInKind )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerType )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataSlot )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataOffset )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_textureSlot )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_samplerSlot )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uavSlot )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sizeInUdt )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_memorySpaceKind )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedTypeId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subTypeId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subType )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfModifiers )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRegisterIndices )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHLSLData )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToDataMember )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToMemberFunction )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSingleInheritance )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMultipleInheritance )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isVirtualInheritance )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_restrictedType )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerBasedOnSymbolValue )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbol )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbolId )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFileName )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorGroupSharedLocal )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorPointerTagLiveRange )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorStubFunction )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfAcceleratorPointerTags )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSdl )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isWinRTPointer )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isRefUdt )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isValueUdt )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isInterfaceUdt )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByAddr )( + IDiaSymbol * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByRVA )( + IDiaSymbol * This, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByVA )( + IDiaSymbol * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLines )( + IDiaSymbol * This, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByAddr )( + IDiaSymbol * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByRVA )( + IDiaSymbol * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByVA )( + IDiaSymbol * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsForAcceleratorPointerTag )( + IDiaSymbol * This, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsByRVAForAcceleratorPointerTag )( + IDiaSymbol * This, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *get_acceleratorPointerTags )( + IDiaSymbol * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags); + + HRESULT ( STDMETHODCALLTYPE *getSrcLineOnTypeDefn )( + IDiaSymbol * This, + /* [out] */ IDiaLineNumber **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPGO )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasValidPGOCounts )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedForSpeed )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEntryCount )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEdgeCount )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGODynamicInstructionCount )( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_staticSize )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_finalLiveStaticSize )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_phaseName )( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasControlFlowCheck )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constantExport )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataExport )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_privateExport )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noNameExport )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportHasExplicitlyAssignedOrdinal )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportIsForwarder )( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ordinal )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frameSize )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressSection )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressOffset )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerRelativeVirtualAddress )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerVirtualAddress )( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFile )( + IDiaSymbol * This, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_characteristics )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_coffGroup )( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindID )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSpace )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSlot )( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + END_INTERFACE + } IDiaSymbolVtbl; + + interface IDiaSymbol + { + CONST_VTBL struct IDiaSymbolVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSymbol_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSymbol_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSymbol_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSymbol_get_symIndexId(This,pRetVal) \ + ( (This)->lpVtbl -> get_symIndexId(This,pRetVal) ) + +#define IDiaSymbol_get_symTag(This,pRetVal) \ + ( (This)->lpVtbl -> get_symTag(This,pRetVal) ) + +#define IDiaSymbol_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaSymbol_get_lexicalParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParent(This,pRetVal) ) + +#define IDiaSymbol_get_classParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParent(This,pRetVal) ) + +#define IDiaSymbol_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaSymbol_get_dataKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataKind(This,pRetVal) ) + +#define IDiaSymbol_get_locationType(This,pRetVal) \ + ( (This)->lpVtbl -> get_locationType(This,pRetVal) ) + +#define IDiaSymbol_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSymbol_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaSymbol_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaSymbol_get_registerId(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerId(This,pRetVal) ) + +#define IDiaSymbol_get_offset(This,pRetVal) \ + ( (This)->lpVtbl -> get_offset(This,pRetVal) ) + +#define IDiaSymbol_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSymbol_get_slot(This,pRetVal) \ + ( (This)->lpVtbl -> get_slot(This,pRetVal) ) + +#define IDiaSymbol_get_volatileType(This,pRetVal) \ + ( (This)->lpVtbl -> get_volatileType(This,pRetVal) ) + +#define IDiaSymbol_get_constType(This,pRetVal) \ + ( (This)->lpVtbl -> get_constType(This,pRetVal) ) + +#define IDiaSymbol_get_unalignedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unalignedType(This,pRetVal) ) + +#define IDiaSymbol_get_access(This,pRetVal) \ + ( (This)->lpVtbl -> get_access(This,pRetVal) ) + +#define IDiaSymbol_get_libraryName(This,pRetVal) \ + ( (This)->lpVtbl -> get_libraryName(This,pRetVal) ) + +#define IDiaSymbol_get_platform(This,pRetVal) \ + ( (This)->lpVtbl -> get_platform(This,pRetVal) ) + +#define IDiaSymbol_get_language(This,pRetVal) \ + ( (This)->lpVtbl -> get_language(This,pRetVal) ) + +#define IDiaSymbol_get_editAndContinueEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_editAndContinueEnabled(This,pRetVal) ) + +#define IDiaSymbol_get_frontEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMajor(This,pRetVal) ) + +#define IDiaSymbol_get_frontEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMinor(This,pRetVal) ) + +#define IDiaSymbol_get_frontEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndBuild(This,pRetVal) ) + +#define IDiaSymbol_get_backEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMajor(This,pRetVal) ) + +#define IDiaSymbol_get_backEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMinor(This,pRetVal) ) + +#define IDiaSymbol_get_backEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndBuild(This,pRetVal) ) + +#define IDiaSymbol_get_sourceFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFileName(This,pRetVal) ) + +#define IDiaSymbol_get_unused(This,pRetVal) \ + ( (This)->lpVtbl -> get_unused(This,pRetVal) ) + +#define IDiaSymbol_get_thunkOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_thunkOrdinal(This,pRetVal) ) + +#define IDiaSymbol_get_thisAdjust(This,pRetVal) \ + ( (This)->lpVtbl -> get_thisAdjust(This,pRetVal) ) + +#define IDiaSymbol_get_virtualBaseOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseOffset(This,pRetVal) ) + +#define IDiaSymbol_get_virtual(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtual(This,pRetVal) ) + +#define IDiaSymbol_get_intro(This,pRetVal) \ + ( (This)->lpVtbl -> get_intro(This,pRetVal) ) + +#define IDiaSymbol_get_pure(This,pRetVal) \ + ( (This)->lpVtbl -> get_pure(This,pRetVal) ) + +#define IDiaSymbol_get_callingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_callingConvention(This,pRetVal) ) + +#define IDiaSymbol_get_value(This,pRetVal) \ + ( (This)->lpVtbl -> get_value(This,pRetVal) ) + +#define IDiaSymbol_get_baseType(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseType(This,pRetVal) ) + +#define IDiaSymbol_get_token(This,pRetVal) \ + ( (This)->lpVtbl -> get_token(This,pRetVal) ) + +#define IDiaSymbol_get_timeStamp(This,pRetVal) \ + ( (This)->lpVtbl -> get_timeStamp(This,pRetVal) ) + +#define IDiaSymbol_get_guid(This,pRetVal) \ + ( (This)->lpVtbl -> get_guid(This,pRetVal) ) + +#define IDiaSymbol_get_symbolsFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_symbolsFileName(This,pRetVal) ) + +#define IDiaSymbol_get_reference(This,pRetVal) \ + ( (This)->lpVtbl -> get_reference(This,pRetVal) ) + +#define IDiaSymbol_get_count(This,pRetVal) \ + ( (This)->lpVtbl -> get_count(This,pRetVal) ) + +#define IDiaSymbol_get_bitPosition(This,pRetVal) \ + ( (This)->lpVtbl -> get_bitPosition(This,pRetVal) ) + +#define IDiaSymbol_get_arrayIndexType(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexType(This,pRetVal) ) + +#define IDiaSymbol_get_packed(This,pRetVal) \ + ( (This)->lpVtbl -> get_packed(This,pRetVal) ) + +#define IDiaSymbol_get_constructor(This,pRetVal) \ + ( (This)->lpVtbl -> get_constructor(This,pRetVal) ) + +#define IDiaSymbol_get_overloadedOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_overloadedOperator(This,pRetVal) ) + +#define IDiaSymbol_get_nested(This,pRetVal) \ + ( (This)->lpVtbl -> get_nested(This,pRetVal) ) + +#define IDiaSymbol_get_hasNestedTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasNestedTypes(This,pRetVal) ) + +#define IDiaSymbol_get_hasAssignmentOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAssignmentOperator(This,pRetVal) ) + +#define IDiaSymbol_get_hasCastOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasCastOperator(This,pRetVal) ) + +#define IDiaSymbol_get_scoped(This,pRetVal) \ + ( (This)->lpVtbl -> get_scoped(This,pRetVal) ) + +#define IDiaSymbol_get_virtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol_get_indirectVirtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_indirectVirtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol_get_virtualBasePointerOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBasePointerOffset(This,pRetVal) ) + +#define IDiaSymbol_get_virtualTableShape(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShape(This,pRetVal) ) + +#define IDiaSymbol_get_lexicalParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParentId(This,pRetVal) ) + +#define IDiaSymbol_get_classParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParentId(This,pRetVal) ) + +#define IDiaSymbol_get_typeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_typeId(This,pRetVal) ) + +#define IDiaSymbol_get_arrayIndexTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexTypeId(This,pRetVal) ) + +#define IDiaSymbol_get_virtualTableShapeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShapeId(This,pRetVal) ) + +#define IDiaSymbol_get_code(This,pRetVal) \ + ( (This)->lpVtbl -> get_code(This,pRetVal) ) + +#define IDiaSymbol_get_function(This,pRetVal) \ + ( (This)->lpVtbl -> get_function(This,pRetVal) ) + +#define IDiaSymbol_get_managed(This,pRetVal) \ + ( (This)->lpVtbl -> get_managed(This,pRetVal) ) + +#define IDiaSymbol_get_msil(This,pRetVal) \ + ( (This)->lpVtbl -> get_msil(This,pRetVal) ) + +#define IDiaSymbol_get_virtualBaseDispIndex(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseDispIndex(This,pRetVal) ) + +#define IDiaSymbol_get_undecoratedName(This,pRetVal) \ + ( (This)->lpVtbl -> get_undecoratedName(This,pRetVal) ) + +#define IDiaSymbol_get_age(This,pRetVal) \ + ( (This)->lpVtbl -> get_age(This,pRetVal) ) + +#define IDiaSymbol_get_signature(This,pRetVal) \ + ( (This)->lpVtbl -> get_signature(This,pRetVal) ) + +#define IDiaSymbol_get_compilerGenerated(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerGenerated(This,pRetVal) ) + +#define IDiaSymbol_get_addressTaken(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressTaken(This,pRetVal) ) + +#define IDiaSymbol_get_rank(This,pRetVal) \ + ( (This)->lpVtbl -> get_rank(This,pRetVal) ) + +#define IDiaSymbol_get_lowerBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBound(This,pRetVal) ) + +#define IDiaSymbol_get_upperBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBound(This,pRetVal) ) + +#define IDiaSymbol_get_lowerBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBoundId(This,pRetVal) ) + +#define IDiaSymbol_get_upperBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBoundId(This,pRetVal) ) + +#define IDiaSymbol_get_dataBytes(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_dataBytes(This,cbData,pcbData,pbData) ) + +#define IDiaSymbol_findChildren(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildren(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol_findChildrenEx(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildrenEx(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol_findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) ) + +#define IDiaSymbol_findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) ) + +#define IDiaSymbol_findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) ) + +#define IDiaSymbol_get_targetSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetSection(This,pRetVal) ) + +#define IDiaSymbol_get_targetOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetOffset(This,pRetVal) ) + +#define IDiaSymbol_get_targetRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol_get_targetVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol_get_machineType(This,pRetVal) \ + ( (This)->lpVtbl -> get_machineType(This,pRetVal) ) + +#define IDiaSymbol_get_oemId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemId(This,pRetVal) ) + +#define IDiaSymbol_get_oemSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemSymbolId(This,pRetVal) ) + +#define IDiaSymbol_get_types(This,cTypes,pcTypes,pTypes) \ + ( (This)->lpVtbl -> get_types(This,cTypes,pcTypes,pTypes) ) + +#define IDiaSymbol_get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) \ + ( (This)->lpVtbl -> get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) ) + +#define IDiaSymbol_get_objectPointerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectPointerType(This,pRetVal) ) + +#define IDiaSymbol_get_udtKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_udtKind(This,pRetVal) ) + +#define IDiaSymbol_get_undecoratedNameEx(This,undecorateOptions,name) \ + ( (This)->lpVtbl -> get_undecoratedNameEx(This,undecorateOptions,name) ) + +#define IDiaSymbol_get_noReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_noReturn(This,pRetVal) ) + +#define IDiaSymbol_get_customCallingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_customCallingConvention(This,pRetVal) ) + +#define IDiaSymbol_get_noInline(This,pRetVal) \ + ( (This)->lpVtbl -> get_noInline(This,pRetVal) ) + +#define IDiaSymbol_get_optimizedCodeDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_optimizedCodeDebugInfo(This,pRetVal) ) + +#define IDiaSymbol_get_notReached(This,pRetVal) \ + ( (This)->lpVtbl -> get_notReached(This,pRetVal) ) + +#define IDiaSymbol_get_interruptReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_interruptReturn(This,pRetVal) ) + +#define IDiaSymbol_get_farReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_farReturn(This,pRetVal) ) + +#define IDiaSymbol_get_isStatic(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStatic(This,pRetVal) ) + +#define IDiaSymbol_get_hasDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasDebugInfo(This,pRetVal) ) + +#define IDiaSymbol_get_isLTCG(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLTCG(This,pRetVal) ) + +#define IDiaSymbol_get_isDataAligned(This,pRetVal) \ + ( (This)->lpVtbl -> get_isDataAligned(This,pRetVal) ) + +#define IDiaSymbol_get_hasSecurityChecks(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSecurityChecks(This,pRetVal) ) + +#define IDiaSymbol_get_compilerName(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerName(This,pRetVal) ) + +#define IDiaSymbol_get_hasAlloca(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAlloca(This,pRetVal) ) + +#define IDiaSymbol_get_hasSetJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSetJump(This,pRetVal) ) + +#define IDiaSymbol_get_hasLongJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasLongJump(This,pRetVal) ) + +#define IDiaSymbol_get_hasInlAsm(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasInlAsm(This,pRetVal) ) + +#define IDiaSymbol_get_hasEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEH(This,pRetVal) ) + +#define IDiaSymbol_get_hasSEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSEH(This,pRetVal) ) + +#define IDiaSymbol_get_hasEHa(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEHa(This,pRetVal) ) + +#define IDiaSymbol_get_isNaked(This,pRetVal) \ + ( (This)->lpVtbl -> get_isNaked(This,pRetVal) ) + +#define IDiaSymbol_get_isAggregated(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAggregated(This,pRetVal) ) + +#define IDiaSymbol_get_isSplitted(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSplitted(This,pRetVal) ) + +#define IDiaSymbol_get_container(This,pRetVal) \ + ( (This)->lpVtbl -> get_container(This,pRetVal) ) + +#define IDiaSymbol_get_inlSpec(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlSpec(This,pRetVal) ) + +#define IDiaSymbol_get_noStackOrdering(This,pRetVal) \ + ( (This)->lpVtbl -> get_noStackOrdering(This,pRetVal) ) + +#define IDiaSymbol_get_virtualBaseTableType(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseTableType(This,pRetVal) ) + +#define IDiaSymbol_get_hasManagedCode(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasManagedCode(This,pRetVal) ) + +#define IDiaSymbol_get_isHotpatchable(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHotpatchable(This,pRetVal) ) + +#define IDiaSymbol_get_isCVTCIL(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCVTCIL(This,pRetVal) ) + +#define IDiaSymbol_get_isMSILNetmodule(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMSILNetmodule(This,pRetVal) ) + +#define IDiaSymbol_get_isCTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCTypes(This,pRetVal) ) + +#define IDiaSymbol_get_isStripped(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStripped(This,pRetVal) ) + +#define IDiaSymbol_get_frontEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndQFE(This,pRetVal) ) + +#define IDiaSymbol_get_backEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndQFE(This,pRetVal) ) + +#define IDiaSymbol_get_wasInlined(This,pRetVal) \ + ( (This)->lpVtbl -> get_wasInlined(This,pRetVal) ) + +#define IDiaSymbol_get_strictGSCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_strictGSCheck(This,pRetVal) ) + +#define IDiaSymbol_get_isCxxReturnUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCxxReturnUdt(This,pRetVal) ) + +#define IDiaSymbol_get_isConstructorVirtualBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_isConstructorVirtualBase(This,pRetVal) ) + +#define IDiaSymbol_get_RValueReference(This,pRetVal) \ + ( (This)->lpVtbl -> get_RValueReference(This,pRetVal) ) + +#define IDiaSymbol_get_unmodifiedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedType(This,pRetVal) ) + +#define IDiaSymbol_get_framePointerPresent(This,pRetVal) \ + ( (This)->lpVtbl -> get_framePointerPresent(This,pRetVal) ) + +#define IDiaSymbol_get_isSafeBuffers(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSafeBuffers(This,pRetVal) ) + +#define IDiaSymbol_get_intrinsic(This,pRetVal) \ + ( (This)->lpVtbl -> get_intrinsic(This,pRetVal) ) + +#define IDiaSymbol_get_sealed(This,pRetVal) \ + ( (This)->lpVtbl -> get_sealed(This,pRetVal) ) + +#define IDiaSymbol_get_hfaFloat(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaFloat(This,pRetVal) ) + +#define IDiaSymbol_get_hfaDouble(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaDouble(This,pRetVal) ) + +#define IDiaSymbol_get_liveRangeStartAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressSection(This,pRetVal) ) + +#define IDiaSymbol_get_liveRangeStartAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressOffset(This,pRetVal) ) + +#define IDiaSymbol_get_liveRangeStartRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol_get_countLiveRanges(This,pRetVal) \ + ( (This)->lpVtbl -> get_countLiveRanges(This,pRetVal) ) + +#define IDiaSymbol_get_liveRangeLength(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeLength(This,pRetVal) ) + +#define IDiaSymbol_get_offsetInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_offsetInUdt(This,pRetVal) ) + +#define IDiaSymbol_get_paramBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_paramBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol_get_localBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_localBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol_get_isLocationControlFlowDependent(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLocationControlFlowDependent(This,pRetVal) ) + +#define IDiaSymbol_get_stride(This,pRetVal) \ + ( (This)->lpVtbl -> get_stride(This,pRetVal) ) + +#define IDiaSymbol_get_numberOfRows(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRows(This,pRetVal) ) + +#define IDiaSymbol_get_numberOfColumns(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfColumns(This,pRetVal) ) + +#define IDiaSymbol_get_isMatrixRowMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMatrixRowMajor(This,pRetVal) ) + +#define IDiaSymbol_get_numericProperties(This,cnt,pcnt,pProperties) \ + ( (This)->lpVtbl -> get_numericProperties(This,cnt,pcnt,pProperties) ) + +#define IDiaSymbol_get_modifierValues(This,cnt,pcnt,pModifiers) \ + ( (This)->lpVtbl -> get_modifierValues(This,cnt,pcnt,pModifiers) ) + +#define IDiaSymbol_get_isReturnValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isReturnValue(This,pRetVal) ) + +#define IDiaSymbol_get_isOptimizedAway(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedAway(This,pRetVal) ) + +#define IDiaSymbol_get_builtInKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_builtInKind(This,pRetVal) ) + +#define IDiaSymbol_get_registerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerType(This,pRetVal) ) + +#define IDiaSymbol_get_baseDataSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataSlot(This,pRetVal) ) + +#define IDiaSymbol_get_baseDataOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataOffset(This,pRetVal) ) + +#define IDiaSymbol_get_textureSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_textureSlot(This,pRetVal) ) + +#define IDiaSymbol_get_samplerSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_samplerSlot(This,pRetVal) ) + +#define IDiaSymbol_get_uavSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_uavSlot(This,pRetVal) ) + +#define IDiaSymbol_get_sizeInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_sizeInUdt(This,pRetVal) ) + +#define IDiaSymbol_get_memorySpaceKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_memorySpaceKind(This,pRetVal) ) + +#define IDiaSymbol_get_unmodifiedTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedTypeId(This,pRetVal) ) + +#define IDiaSymbol_get_subTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_subTypeId(This,pRetVal) ) + +#define IDiaSymbol_get_subType(This,pRetVal) \ + ( (This)->lpVtbl -> get_subType(This,pRetVal) ) + +#define IDiaSymbol_get_numberOfModifiers(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfModifiers(This,pRetVal) ) + +#define IDiaSymbol_get_numberOfRegisterIndices(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRegisterIndices(This,pRetVal) ) + +#define IDiaSymbol_get_isHLSLData(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHLSLData(This,pRetVal) ) + +#define IDiaSymbol_get_isPointerToDataMember(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToDataMember(This,pRetVal) ) + +#define IDiaSymbol_get_isPointerToMemberFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToMemberFunction(This,pRetVal) ) + +#define IDiaSymbol_get_isSingleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSingleInheritance(This,pRetVal) ) + +#define IDiaSymbol_get_isMultipleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMultipleInheritance(This,pRetVal) ) + +#define IDiaSymbol_get_isVirtualInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isVirtualInheritance(This,pRetVal) ) + +#define IDiaSymbol_get_restrictedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_restrictedType(This,pRetVal) ) + +#define IDiaSymbol_get_isPointerBasedOnSymbolValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerBasedOnSymbolValue(This,pRetVal) ) + +#define IDiaSymbol_get_baseSymbol(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbol(This,pRetVal) ) + +#define IDiaSymbol_get_baseSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbolId(This,pRetVal) ) + +#define IDiaSymbol_get_objectFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectFileName(This,pRetVal) ) + +#define IDiaSymbol_get_isAcceleratorGroupSharedLocal(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorGroupSharedLocal(This,pRetVal) ) + +#define IDiaSymbol_get_isAcceleratorPointerTagLiveRange(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorPointerTagLiveRange(This,pRetVal) ) + +#define IDiaSymbol_get_isAcceleratorStubFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorStubFunction(This,pRetVal) ) + +#define IDiaSymbol_get_numberOfAcceleratorPointerTags(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfAcceleratorPointerTags(This,pRetVal) ) + +#define IDiaSymbol_get_isSdl(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSdl(This,pRetVal) ) + +#define IDiaSymbol_get_isWinRTPointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_isWinRTPointer(This,pRetVal) ) + +#define IDiaSymbol_get_isRefUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isRefUdt(This,pRetVal) ) + +#define IDiaSymbol_get_isValueUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isValueUdt(This,pRetVal) ) + +#define IDiaSymbol_get_isInterfaceUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isInterfaceUdt(This,pRetVal) ) + +#define IDiaSymbol_findInlineFramesByAddr(This,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByAddr(This,isect,offset,ppResult) ) + +#define IDiaSymbol_findInlineFramesByRVA(This,rva,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByRVA(This,rva,ppResult) ) + +#define IDiaSymbol_findInlineFramesByVA(This,va,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByVA(This,va,ppResult) ) + +#define IDiaSymbol_findInlineeLines(This,ppResult) \ + ( (This)->lpVtbl -> findInlineeLines(This,ppResult) ) + +#define IDiaSymbol_findInlineeLinesByAddr(This,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByAddr(This,isect,offset,length,ppResult) ) + +#define IDiaSymbol_findInlineeLinesByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByRVA(This,rva,length,ppResult) ) + +#define IDiaSymbol_findInlineeLinesByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByVA(This,va,length,ppResult) ) + +#define IDiaSymbol_findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) \ + ( (This)->lpVtbl -> findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) ) + +#define IDiaSymbol_findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) \ + ( (This)->lpVtbl -> findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) ) + +#define IDiaSymbol_get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) \ + ( (This)->lpVtbl -> get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) ) + +#define IDiaSymbol_getSrcLineOnTypeDefn(This,ppResult) \ + ( (This)->lpVtbl -> getSrcLineOnTypeDefn(This,ppResult) ) + +#define IDiaSymbol_get_isPGO(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPGO(This,pRetVal) ) + +#define IDiaSymbol_get_hasValidPGOCounts(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasValidPGOCounts(This,pRetVal) ) + +#define IDiaSymbol_get_isOptimizedForSpeed(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedForSpeed(This,pRetVal) ) + +#define IDiaSymbol_get_PGOEntryCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEntryCount(This,pRetVal) ) + +#define IDiaSymbol_get_PGOEdgeCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEdgeCount(This,pRetVal) ) + +#define IDiaSymbol_get_PGODynamicInstructionCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGODynamicInstructionCount(This,pRetVal) ) + +#define IDiaSymbol_get_staticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_staticSize(This,pRetVal) ) + +#define IDiaSymbol_get_finalLiveStaticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_finalLiveStaticSize(This,pRetVal) ) + +#define IDiaSymbol_get_phaseName(This,pRetVal) \ + ( (This)->lpVtbl -> get_phaseName(This,pRetVal) ) + +#define IDiaSymbol_get_hasControlFlowCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasControlFlowCheck(This,pRetVal) ) + +#define IDiaSymbol_get_constantExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_constantExport(This,pRetVal) ) + +#define IDiaSymbol_get_dataExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataExport(This,pRetVal) ) + +#define IDiaSymbol_get_privateExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_privateExport(This,pRetVal) ) + +#define IDiaSymbol_get_noNameExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_noNameExport(This,pRetVal) ) + +#define IDiaSymbol_get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) ) + +#define IDiaSymbol_get_exportIsForwarder(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportIsForwarder(This,pRetVal) ) + +#define IDiaSymbol_get_ordinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_ordinal(This,pRetVal) ) + +#define IDiaSymbol_get_frameSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_frameSize(This,pRetVal) ) + +#define IDiaSymbol_get_exceptionHandlerAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressSection(This,pRetVal) ) + +#define IDiaSymbol_get_exceptionHandlerAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressOffset(This,pRetVal) ) + +#define IDiaSymbol_get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol_get_exceptionHandlerVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol_findInputAssemblyFile(This,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFile(This,ppResult) ) + +#define IDiaSymbol_get_characteristics(This,pRetVal) \ + ( (This)->lpVtbl -> get_characteristics(This,pRetVal) ) + +#define IDiaSymbol_get_coffGroup(This,pRetVal) \ + ( (This)->lpVtbl -> get_coffGroup(This,pRetVal) ) + +#define IDiaSymbol_get_bindID(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindID(This,pRetVal) ) + +#define IDiaSymbol_get_bindSpace(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSpace(This,pRetVal) ) + +#define IDiaSymbol_get_bindSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSlot(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_virtualBaseTableType_Proxy( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + +void __RPC_STUB IDiaSymbol_get_virtualBaseTableType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_hasManagedCode_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_hasManagedCode_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isHotpatchable_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isHotpatchable_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isCVTCIL_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isCVTCIL_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isMSILNetmodule_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isMSILNetmodule_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isCTypes_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isCTypes_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isStripped_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isStripped_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_frontEndQFE_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_frontEndQFE_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_backEndQFE_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_backEndQFE_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_wasInlined_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_wasInlined_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_strictGSCheck_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_strictGSCheck_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isCxxReturnUdt_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isCxxReturnUdt_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isConstructorVirtualBase_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isConstructorVirtualBase_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_RValueReference_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_RValueReference_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_unmodifiedType_Proxy( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + +void __RPC_STUB IDiaSymbol_get_unmodifiedType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_framePointerPresent_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_framePointerPresent_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isSafeBuffers_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isSafeBuffers_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_intrinsic_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_intrinsic_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_sealed_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_sealed_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_hfaFloat_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_hfaFloat_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_hfaDouble_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_hfaDouble_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_liveRangeStartAddressSection_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_liveRangeStartAddressSection_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_liveRangeStartAddressOffset_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_liveRangeStartAddressOffset_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_liveRangeStartRelativeVirtualAddress_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_liveRangeStartRelativeVirtualAddress_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_countLiveRanges_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_countLiveRanges_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_liveRangeLength_Proxy( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_liveRangeLength_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_offsetInUdt_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_offsetInUdt_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_paramBasePointerRegisterId_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_paramBasePointerRegisterId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_localBasePointerRegisterId_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_localBasePointerRegisterId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isLocationControlFlowDependent_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isLocationControlFlowDependent_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_stride_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_stride_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_numberOfRows_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_numberOfRows_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_numberOfColumns_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_numberOfColumns_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isMatrixRowMajor_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isMatrixRowMajor_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_get_numericProperties_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties); + + +void __RPC_STUB IDiaSymbol_get_numericProperties_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_get_modifierValues_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers); + + +void __RPC_STUB IDiaSymbol_get_modifierValues_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isReturnValue_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isReturnValue_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isOptimizedAway_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isOptimizedAway_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_builtInKind_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_builtInKind_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_registerType_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_registerType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_baseDataSlot_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_baseDataSlot_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_baseDataOffset_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_baseDataOffset_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_textureSlot_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_textureSlot_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_samplerSlot_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_samplerSlot_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_uavSlot_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_uavSlot_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_sizeInUdt_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_sizeInUdt_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_memorySpaceKind_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_memorySpaceKind_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_unmodifiedTypeId_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_unmodifiedTypeId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_subTypeId_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_subTypeId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_subType_Proxy( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + +void __RPC_STUB IDiaSymbol_get_subType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_numberOfModifiers_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_numberOfModifiers_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_numberOfRegisterIndices_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_numberOfRegisterIndices_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isHLSLData_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isHLSLData_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isPointerToDataMember_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isPointerToDataMember_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isPointerToMemberFunction_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isPointerToMemberFunction_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isSingleInheritance_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isSingleInheritance_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isMultipleInheritance_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isMultipleInheritance_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isVirtualInheritance_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isVirtualInheritance_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_restrictedType_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_restrictedType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isPointerBasedOnSymbolValue_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isPointerBasedOnSymbolValue_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_baseSymbol_Proxy( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + +void __RPC_STUB IDiaSymbol_get_baseSymbol_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_baseSymbolId_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_baseSymbolId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_objectFileName_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_objectFileName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isAcceleratorGroupSharedLocal_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isAcceleratorGroupSharedLocal_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isAcceleratorPointerTagLiveRange_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isAcceleratorPointerTagLiveRange_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isAcceleratorStubFunction_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isAcceleratorStubFunction_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_numberOfAcceleratorPointerTags_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_numberOfAcceleratorPointerTags_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isSdl_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isSdl_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isWinRTPointer_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isWinRTPointer_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isRefUdt_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isRefUdt_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isValueUdt_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isValueUdt_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isInterfaceUdt_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isInterfaceUdt_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findInlineFramesByAddr_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + +void __RPC_STUB IDiaSymbol_findInlineFramesByAddr_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findInlineFramesByRVA_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + +void __RPC_STUB IDiaSymbol_findInlineFramesByRVA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findInlineFramesByVA_Proxy( + IDiaSymbol * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + +void __RPC_STUB IDiaSymbol_findInlineFramesByVA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findInlineeLines_Proxy( + IDiaSymbol * This, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + +void __RPC_STUB IDiaSymbol_findInlineeLines_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findInlineeLinesByAddr_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + +void __RPC_STUB IDiaSymbol_findInlineeLinesByAddr_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findInlineeLinesByRVA_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + +void __RPC_STUB IDiaSymbol_findInlineeLinesByRVA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findInlineeLinesByVA_Proxy( + IDiaSymbol * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + +void __RPC_STUB IDiaSymbol_findInlineeLinesByVA_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findSymbolsForAcceleratorPointerTag_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + +void __RPC_STUB IDiaSymbol_findSymbolsForAcceleratorPointerTag_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findSymbolsByRVAForAcceleratorPointerTag_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + +void __RPC_STUB IDiaSymbol_findSymbolsByRVAForAcceleratorPointerTag_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_get_acceleratorPointerTags_Proxy( + IDiaSymbol * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags); + + +void __RPC_STUB IDiaSymbol_get_acceleratorPointerTags_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_getSrcLineOnTypeDefn_Proxy( + IDiaSymbol * This, + /* [out] */ IDiaLineNumber **ppResult); + + +void __RPC_STUB IDiaSymbol_getSrcLineOnTypeDefn_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isPGO_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isPGO_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_hasValidPGOCounts_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_hasValidPGOCounts_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isOptimizedForSpeed_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_isOptimizedForSpeed_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_PGOEntryCount_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_PGOEntryCount_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_PGOEdgeCount_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_PGOEdgeCount_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_PGODynamicInstructionCount_Proxy( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_PGODynamicInstructionCount_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_staticSize_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_staticSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_finalLiveStaticSize_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_finalLiveStaticSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_phaseName_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BSTR *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_phaseName_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_hasControlFlowCheck_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_hasControlFlowCheck_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_constantExport_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_constantExport_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_dataExport_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_dataExport_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_privateExport_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_privateExport_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_noNameExport_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_noNameExport_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_exportHasExplicitlyAssignedOrdinal_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_exportHasExplicitlyAssignedOrdinal_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_exportIsForwarder_Proxy( + IDiaSymbol * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_exportIsForwarder_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_ordinal_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_ordinal_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_frameSize_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_frameSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_exceptionHandlerAddressSection_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_exceptionHandlerAddressSection_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_exceptionHandlerAddressOffset_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_exceptionHandlerAddressOffset_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_exceptionHandlerRelativeVirtualAddress_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_exceptionHandlerRelativeVirtualAddress_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_exceptionHandlerVirtualAddress_Proxy( + IDiaSymbol * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_exceptionHandlerVirtualAddress_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +HRESULT STDMETHODCALLTYPE IDiaSymbol_findInputAssemblyFile_Proxy( + IDiaSymbol * This, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + +void __RPC_STUB IDiaSymbol_findInputAssemblyFile_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_characteristics_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_characteristics_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_coffGroup_Proxy( + IDiaSymbol * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + +void __RPC_STUB IDiaSymbol_get_coffGroup_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_bindID_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_bindID_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_bindSpace_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_bindSpace_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_bindSlot_Proxy( + IDiaSymbol * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol_get_bindSlot_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDiaSymbol_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSymbol2_INTERFACE_DEFINED__ +#define __IDiaSymbol2_INTERFACE_DEFINED__ + +/* interface IDiaSymbol2 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSymbol2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("611e86cd-b7d1-4546-8a15-070e2b07a427") + IDiaSymbol2 : public IDiaSymbol + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isObjCClass( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isObjCCategory( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isObjCProtocol( + /* [retval][out] */ BOOL *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSymbol2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSymbol2 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSymbol2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSymbol2 * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symIndexId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symTag )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParent )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParent )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataKind )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_locationType )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSymbol2 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )( + IDiaSymbol2 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSymbol2 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_slot )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_volatileType )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constType )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unalignedType )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_access )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_libraryName )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_platform )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_language )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_editAndContinueEnabled )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMajor )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMinor )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndBuild )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMajor )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMinor )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndBuild )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileName )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unused )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thunkOrdinal )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thisAdjust )( + IDiaSymbol2 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseOffset )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtual )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intro )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pure )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_callingConvention )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_value )( + IDiaSymbol2 * This, + /* [retval][out] */ VARIANT *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseType )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_token )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timeStamp )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_guid )( + IDiaSymbol2 * This, + /* [retval][out] */ GUID *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symbolsFileName )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_reference )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_count )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bitPosition )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexType )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_packed )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constructor )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_overloadedOperator )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_nested )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasNestedTypes )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAssignmentOperator )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasCastOperator )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_scoped )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseClass )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_indirectVirtualBaseClass )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBasePointerOffset )( + IDiaSymbol2 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShape )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParentId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParentId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_typeId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexTypeId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShapeId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_function )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_managed )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_msil )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseDispIndex )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_undecoratedName )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_age )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_signature )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerGenerated )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressTaken )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_rank )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBound )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBound )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBoundId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBoundId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_dataBytes )( + IDiaSymbol2 * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *findChildren )( + IDiaSymbol2 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenEx )( + IDiaSymbol2 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )( + IDiaSymbol2 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )( + IDiaSymbol2 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )( + IDiaSymbol2 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetSection )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetOffset )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetRelativeVirtualAddress )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetVirtualAddress )( + IDiaSymbol2 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_machineType )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemSymbolId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_types )( + IDiaSymbol2 * This, + /* [in] */ DWORD cTypes, + /* [out] */ DWORD *pcTypes, + /* [size_is][size_is][out] */ IDiaSymbol **pTypes); + + HRESULT ( STDMETHODCALLTYPE *get_typeIds )( + IDiaSymbol2 * This, + /* [in] */ DWORD cTypeIds, + /* [out] */ DWORD *pcTypeIds, + /* [size_is][out] */ DWORD *pdwTypeIds); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectPointerType )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_udtKind )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_undecoratedNameEx )( + IDiaSymbol2 * This, + /* [in] */ DWORD undecorateOptions, + /* [out] */ BSTR *name); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noReturn )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_customCallingConvention )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noInline )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_optimizedCodeDebugInfo )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notReached )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_interruptReturn )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_farReturn )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStatic )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasDebugInfo )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLTCG )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isDataAligned )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSecurityChecks )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerName )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAlloca )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSetJump )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasLongJump )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasInlAsm )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEH )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSEH )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEHa )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isNaked )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAggregated )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSplitted )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_container )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlSpec )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noStackOrdering )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseTableType )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasManagedCode )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHotpatchable )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCVTCIL )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMSILNetmodule )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCTypes )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStripped )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndQFE )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndQFE )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_wasInlined )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_strictGSCheck )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCxxReturnUdt )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isConstructorVirtualBase )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RValueReference )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedType )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_framePointerPresent )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSafeBuffers )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intrinsic )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sealed )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaFloat )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaDouble )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressSection )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressOffset )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartRelativeVirtualAddress )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_countLiveRanges )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeLength )( + IDiaSymbol2 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offsetInUdt )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_paramBasePointerRegisterId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localBasePointerRegisterId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLocationControlFlowDependent )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_stride )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRows )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfColumns )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMatrixRowMajor )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_numericProperties )( + IDiaSymbol2 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties); + + HRESULT ( STDMETHODCALLTYPE *get_modifierValues )( + IDiaSymbol2 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isReturnValue )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedAway )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_builtInKind )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerType )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataSlot )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataOffset )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_textureSlot )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_samplerSlot )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uavSlot )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sizeInUdt )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_memorySpaceKind )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedTypeId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subTypeId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subType )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfModifiers )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRegisterIndices )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHLSLData )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToDataMember )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToMemberFunction )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSingleInheritance )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMultipleInheritance )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isVirtualInheritance )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_restrictedType )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerBasedOnSymbolValue )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbol )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbolId )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFileName )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorGroupSharedLocal )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorPointerTagLiveRange )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorStubFunction )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfAcceleratorPointerTags )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSdl )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isWinRTPointer )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isRefUdt )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isValueUdt )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isInterfaceUdt )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByAddr )( + IDiaSymbol2 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByRVA )( + IDiaSymbol2 * This, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByVA )( + IDiaSymbol2 * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLines )( + IDiaSymbol2 * This, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByAddr )( + IDiaSymbol2 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByRVA )( + IDiaSymbol2 * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByVA )( + IDiaSymbol2 * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsForAcceleratorPointerTag )( + IDiaSymbol2 * This, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsByRVAForAcceleratorPointerTag )( + IDiaSymbol2 * This, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *get_acceleratorPointerTags )( + IDiaSymbol2 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags); + + HRESULT ( STDMETHODCALLTYPE *getSrcLineOnTypeDefn )( + IDiaSymbol2 * This, + /* [out] */ IDiaLineNumber **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPGO )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasValidPGOCounts )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedForSpeed )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEntryCount )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEdgeCount )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGODynamicInstructionCount )( + IDiaSymbol2 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_staticSize )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_finalLiveStaticSize )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_phaseName )( + IDiaSymbol2 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasControlFlowCheck )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constantExport )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataExport )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_privateExport )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noNameExport )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportHasExplicitlyAssignedOrdinal )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportIsForwarder )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ordinal )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frameSize )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressSection )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressOffset )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerRelativeVirtualAddress )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerVirtualAddress )( + IDiaSymbol2 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFile )( + IDiaSymbol2 * This, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_characteristics )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_coffGroup )( + IDiaSymbol2 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindID )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSpace )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSlot )( + IDiaSymbol2 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCClass )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCCategory )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCProtocol )( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + END_INTERFACE + } IDiaSymbol2Vtbl; + + interface IDiaSymbol2 + { + CONST_VTBL struct IDiaSymbol2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSymbol2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSymbol2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSymbol2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSymbol2_get_symIndexId(This,pRetVal) \ + ( (This)->lpVtbl -> get_symIndexId(This,pRetVal) ) + +#define IDiaSymbol2_get_symTag(This,pRetVal) \ + ( (This)->lpVtbl -> get_symTag(This,pRetVal) ) + +#define IDiaSymbol2_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaSymbol2_get_lexicalParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParent(This,pRetVal) ) + +#define IDiaSymbol2_get_classParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParent(This,pRetVal) ) + +#define IDiaSymbol2_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaSymbol2_get_dataKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataKind(This,pRetVal) ) + +#define IDiaSymbol2_get_locationType(This,pRetVal) \ + ( (This)->lpVtbl -> get_locationType(This,pRetVal) ) + +#define IDiaSymbol2_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSymbol2_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaSymbol2_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol2_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaSymbol2_get_registerId(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerId(This,pRetVal) ) + +#define IDiaSymbol2_get_offset(This,pRetVal) \ + ( (This)->lpVtbl -> get_offset(This,pRetVal) ) + +#define IDiaSymbol2_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSymbol2_get_slot(This,pRetVal) \ + ( (This)->lpVtbl -> get_slot(This,pRetVal) ) + +#define IDiaSymbol2_get_volatileType(This,pRetVal) \ + ( (This)->lpVtbl -> get_volatileType(This,pRetVal) ) + +#define IDiaSymbol2_get_constType(This,pRetVal) \ + ( (This)->lpVtbl -> get_constType(This,pRetVal) ) + +#define IDiaSymbol2_get_unalignedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unalignedType(This,pRetVal) ) + +#define IDiaSymbol2_get_access(This,pRetVal) \ + ( (This)->lpVtbl -> get_access(This,pRetVal) ) + +#define IDiaSymbol2_get_libraryName(This,pRetVal) \ + ( (This)->lpVtbl -> get_libraryName(This,pRetVal) ) + +#define IDiaSymbol2_get_platform(This,pRetVal) \ + ( (This)->lpVtbl -> get_platform(This,pRetVal) ) + +#define IDiaSymbol2_get_language(This,pRetVal) \ + ( (This)->lpVtbl -> get_language(This,pRetVal) ) + +#define IDiaSymbol2_get_editAndContinueEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_editAndContinueEnabled(This,pRetVal) ) + +#define IDiaSymbol2_get_frontEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMajor(This,pRetVal) ) + +#define IDiaSymbol2_get_frontEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMinor(This,pRetVal) ) + +#define IDiaSymbol2_get_frontEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndBuild(This,pRetVal) ) + +#define IDiaSymbol2_get_backEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMajor(This,pRetVal) ) + +#define IDiaSymbol2_get_backEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMinor(This,pRetVal) ) + +#define IDiaSymbol2_get_backEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndBuild(This,pRetVal) ) + +#define IDiaSymbol2_get_sourceFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFileName(This,pRetVal) ) + +#define IDiaSymbol2_get_unused(This,pRetVal) \ + ( (This)->lpVtbl -> get_unused(This,pRetVal) ) + +#define IDiaSymbol2_get_thunkOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_thunkOrdinal(This,pRetVal) ) + +#define IDiaSymbol2_get_thisAdjust(This,pRetVal) \ + ( (This)->lpVtbl -> get_thisAdjust(This,pRetVal) ) + +#define IDiaSymbol2_get_virtualBaseOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseOffset(This,pRetVal) ) + +#define IDiaSymbol2_get_virtual(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtual(This,pRetVal) ) + +#define IDiaSymbol2_get_intro(This,pRetVal) \ + ( (This)->lpVtbl -> get_intro(This,pRetVal) ) + +#define IDiaSymbol2_get_pure(This,pRetVal) \ + ( (This)->lpVtbl -> get_pure(This,pRetVal) ) + +#define IDiaSymbol2_get_callingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_callingConvention(This,pRetVal) ) + +#define IDiaSymbol2_get_value(This,pRetVal) \ + ( (This)->lpVtbl -> get_value(This,pRetVal) ) + +#define IDiaSymbol2_get_baseType(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseType(This,pRetVal) ) + +#define IDiaSymbol2_get_token(This,pRetVal) \ + ( (This)->lpVtbl -> get_token(This,pRetVal) ) + +#define IDiaSymbol2_get_timeStamp(This,pRetVal) \ + ( (This)->lpVtbl -> get_timeStamp(This,pRetVal) ) + +#define IDiaSymbol2_get_guid(This,pRetVal) \ + ( (This)->lpVtbl -> get_guid(This,pRetVal) ) + +#define IDiaSymbol2_get_symbolsFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_symbolsFileName(This,pRetVal) ) + +#define IDiaSymbol2_get_reference(This,pRetVal) \ + ( (This)->lpVtbl -> get_reference(This,pRetVal) ) + +#define IDiaSymbol2_get_count(This,pRetVal) \ + ( (This)->lpVtbl -> get_count(This,pRetVal) ) + +#define IDiaSymbol2_get_bitPosition(This,pRetVal) \ + ( (This)->lpVtbl -> get_bitPosition(This,pRetVal) ) + +#define IDiaSymbol2_get_arrayIndexType(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexType(This,pRetVal) ) + +#define IDiaSymbol2_get_packed(This,pRetVal) \ + ( (This)->lpVtbl -> get_packed(This,pRetVal) ) + +#define IDiaSymbol2_get_constructor(This,pRetVal) \ + ( (This)->lpVtbl -> get_constructor(This,pRetVal) ) + +#define IDiaSymbol2_get_overloadedOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_overloadedOperator(This,pRetVal) ) + +#define IDiaSymbol2_get_nested(This,pRetVal) \ + ( (This)->lpVtbl -> get_nested(This,pRetVal) ) + +#define IDiaSymbol2_get_hasNestedTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasNestedTypes(This,pRetVal) ) + +#define IDiaSymbol2_get_hasAssignmentOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAssignmentOperator(This,pRetVal) ) + +#define IDiaSymbol2_get_hasCastOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasCastOperator(This,pRetVal) ) + +#define IDiaSymbol2_get_scoped(This,pRetVal) \ + ( (This)->lpVtbl -> get_scoped(This,pRetVal) ) + +#define IDiaSymbol2_get_virtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol2_get_indirectVirtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_indirectVirtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol2_get_virtualBasePointerOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBasePointerOffset(This,pRetVal) ) + +#define IDiaSymbol2_get_virtualTableShape(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShape(This,pRetVal) ) + +#define IDiaSymbol2_get_lexicalParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParentId(This,pRetVal) ) + +#define IDiaSymbol2_get_classParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParentId(This,pRetVal) ) + +#define IDiaSymbol2_get_typeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_typeId(This,pRetVal) ) + +#define IDiaSymbol2_get_arrayIndexTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexTypeId(This,pRetVal) ) + +#define IDiaSymbol2_get_virtualTableShapeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShapeId(This,pRetVal) ) + +#define IDiaSymbol2_get_code(This,pRetVal) \ + ( (This)->lpVtbl -> get_code(This,pRetVal) ) + +#define IDiaSymbol2_get_function(This,pRetVal) \ + ( (This)->lpVtbl -> get_function(This,pRetVal) ) + +#define IDiaSymbol2_get_managed(This,pRetVal) \ + ( (This)->lpVtbl -> get_managed(This,pRetVal) ) + +#define IDiaSymbol2_get_msil(This,pRetVal) \ + ( (This)->lpVtbl -> get_msil(This,pRetVal) ) + +#define IDiaSymbol2_get_virtualBaseDispIndex(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseDispIndex(This,pRetVal) ) + +#define IDiaSymbol2_get_undecoratedName(This,pRetVal) \ + ( (This)->lpVtbl -> get_undecoratedName(This,pRetVal) ) + +#define IDiaSymbol2_get_age(This,pRetVal) \ + ( (This)->lpVtbl -> get_age(This,pRetVal) ) + +#define IDiaSymbol2_get_signature(This,pRetVal) \ + ( (This)->lpVtbl -> get_signature(This,pRetVal) ) + +#define IDiaSymbol2_get_compilerGenerated(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerGenerated(This,pRetVal) ) + +#define IDiaSymbol2_get_addressTaken(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressTaken(This,pRetVal) ) + +#define IDiaSymbol2_get_rank(This,pRetVal) \ + ( (This)->lpVtbl -> get_rank(This,pRetVal) ) + +#define IDiaSymbol2_get_lowerBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBound(This,pRetVal) ) + +#define IDiaSymbol2_get_upperBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBound(This,pRetVal) ) + +#define IDiaSymbol2_get_lowerBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBoundId(This,pRetVal) ) + +#define IDiaSymbol2_get_upperBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBoundId(This,pRetVal) ) + +#define IDiaSymbol2_get_dataBytes(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_dataBytes(This,cbData,pcbData,pbData) ) + +#define IDiaSymbol2_findChildren(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildren(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol2_findChildrenEx(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildrenEx(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol2_findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) ) + +#define IDiaSymbol2_findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) ) + +#define IDiaSymbol2_findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) ) + +#define IDiaSymbol2_get_targetSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetSection(This,pRetVal) ) + +#define IDiaSymbol2_get_targetOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetOffset(This,pRetVal) ) + +#define IDiaSymbol2_get_targetRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol2_get_targetVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol2_get_machineType(This,pRetVal) \ + ( (This)->lpVtbl -> get_machineType(This,pRetVal) ) + +#define IDiaSymbol2_get_oemId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemId(This,pRetVal) ) + +#define IDiaSymbol2_get_oemSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemSymbolId(This,pRetVal) ) + +#define IDiaSymbol2_get_types(This,cTypes,pcTypes,pTypes) \ + ( (This)->lpVtbl -> get_types(This,cTypes,pcTypes,pTypes) ) + +#define IDiaSymbol2_get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) \ + ( (This)->lpVtbl -> get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) ) + +#define IDiaSymbol2_get_objectPointerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectPointerType(This,pRetVal) ) + +#define IDiaSymbol2_get_udtKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_udtKind(This,pRetVal) ) + +#define IDiaSymbol2_get_undecoratedNameEx(This,undecorateOptions,name) \ + ( (This)->lpVtbl -> get_undecoratedNameEx(This,undecorateOptions,name) ) + +#define IDiaSymbol2_get_noReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_noReturn(This,pRetVal) ) + +#define IDiaSymbol2_get_customCallingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_customCallingConvention(This,pRetVal) ) + +#define IDiaSymbol2_get_noInline(This,pRetVal) \ + ( (This)->lpVtbl -> get_noInline(This,pRetVal) ) + +#define IDiaSymbol2_get_optimizedCodeDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_optimizedCodeDebugInfo(This,pRetVal) ) + +#define IDiaSymbol2_get_notReached(This,pRetVal) \ + ( (This)->lpVtbl -> get_notReached(This,pRetVal) ) + +#define IDiaSymbol2_get_interruptReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_interruptReturn(This,pRetVal) ) + +#define IDiaSymbol2_get_farReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_farReturn(This,pRetVal) ) + +#define IDiaSymbol2_get_isStatic(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStatic(This,pRetVal) ) + +#define IDiaSymbol2_get_hasDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasDebugInfo(This,pRetVal) ) + +#define IDiaSymbol2_get_isLTCG(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLTCG(This,pRetVal) ) + +#define IDiaSymbol2_get_isDataAligned(This,pRetVal) \ + ( (This)->lpVtbl -> get_isDataAligned(This,pRetVal) ) + +#define IDiaSymbol2_get_hasSecurityChecks(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSecurityChecks(This,pRetVal) ) + +#define IDiaSymbol2_get_compilerName(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerName(This,pRetVal) ) + +#define IDiaSymbol2_get_hasAlloca(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAlloca(This,pRetVal) ) + +#define IDiaSymbol2_get_hasSetJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSetJump(This,pRetVal) ) + +#define IDiaSymbol2_get_hasLongJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasLongJump(This,pRetVal) ) + +#define IDiaSymbol2_get_hasInlAsm(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasInlAsm(This,pRetVal) ) + +#define IDiaSymbol2_get_hasEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEH(This,pRetVal) ) + +#define IDiaSymbol2_get_hasSEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSEH(This,pRetVal) ) + +#define IDiaSymbol2_get_hasEHa(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEHa(This,pRetVal) ) + +#define IDiaSymbol2_get_isNaked(This,pRetVal) \ + ( (This)->lpVtbl -> get_isNaked(This,pRetVal) ) + +#define IDiaSymbol2_get_isAggregated(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAggregated(This,pRetVal) ) + +#define IDiaSymbol2_get_isSplitted(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSplitted(This,pRetVal) ) + +#define IDiaSymbol2_get_container(This,pRetVal) \ + ( (This)->lpVtbl -> get_container(This,pRetVal) ) + +#define IDiaSymbol2_get_inlSpec(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlSpec(This,pRetVal) ) + +#define IDiaSymbol2_get_noStackOrdering(This,pRetVal) \ + ( (This)->lpVtbl -> get_noStackOrdering(This,pRetVal) ) + +#define IDiaSymbol2_get_virtualBaseTableType(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseTableType(This,pRetVal) ) + +#define IDiaSymbol2_get_hasManagedCode(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasManagedCode(This,pRetVal) ) + +#define IDiaSymbol2_get_isHotpatchable(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHotpatchable(This,pRetVal) ) + +#define IDiaSymbol2_get_isCVTCIL(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCVTCIL(This,pRetVal) ) + +#define IDiaSymbol2_get_isMSILNetmodule(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMSILNetmodule(This,pRetVal) ) + +#define IDiaSymbol2_get_isCTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCTypes(This,pRetVal) ) + +#define IDiaSymbol2_get_isStripped(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStripped(This,pRetVal) ) + +#define IDiaSymbol2_get_frontEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndQFE(This,pRetVal) ) + +#define IDiaSymbol2_get_backEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndQFE(This,pRetVal) ) + +#define IDiaSymbol2_get_wasInlined(This,pRetVal) \ + ( (This)->lpVtbl -> get_wasInlined(This,pRetVal) ) + +#define IDiaSymbol2_get_strictGSCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_strictGSCheck(This,pRetVal) ) + +#define IDiaSymbol2_get_isCxxReturnUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCxxReturnUdt(This,pRetVal) ) + +#define IDiaSymbol2_get_isConstructorVirtualBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_isConstructorVirtualBase(This,pRetVal) ) + +#define IDiaSymbol2_get_RValueReference(This,pRetVal) \ + ( (This)->lpVtbl -> get_RValueReference(This,pRetVal) ) + +#define IDiaSymbol2_get_unmodifiedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedType(This,pRetVal) ) + +#define IDiaSymbol2_get_framePointerPresent(This,pRetVal) \ + ( (This)->lpVtbl -> get_framePointerPresent(This,pRetVal) ) + +#define IDiaSymbol2_get_isSafeBuffers(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSafeBuffers(This,pRetVal) ) + +#define IDiaSymbol2_get_intrinsic(This,pRetVal) \ + ( (This)->lpVtbl -> get_intrinsic(This,pRetVal) ) + +#define IDiaSymbol2_get_sealed(This,pRetVal) \ + ( (This)->lpVtbl -> get_sealed(This,pRetVal) ) + +#define IDiaSymbol2_get_hfaFloat(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaFloat(This,pRetVal) ) + +#define IDiaSymbol2_get_hfaDouble(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaDouble(This,pRetVal) ) + +#define IDiaSymbol2_get_liveRangeStartAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressSection(This,pRetVal) ) + +#define IDiaSymbol2_get_liveRangeStartAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressOffset(This,pRetVal) ) + +#define IDiaSymbol2_get_liveRangeStartRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol2_get_countLiveRanges(This,pRetVal) \ + ( (This)->lpVtbl -> get_countLiveRanges(This,pRetVal) ) + +#define IDiaSymbol2_get_liveRangeLength(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeLength(This,pRetVal) ) + +#define IDiaSymbol2_get_offsetInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_offsetInUdt(This,pRetVal) ) + +#define IDiaSymbol2_get_paramBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_paramBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol2_get_localBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_localBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol2_get_isLocationControlFlowDependent(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLocationControlFlowDependent(This,pRetVal) ) + +#define IDiaSymbol2_get_stride(This,pRetVal) \ + ( (This)->lpVtbl -> get_stride(This,pRetVal) ) + +#define IDiaSymbol2_get_numberOfRows(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRows(This,pRetVal) ) + +#define IDiaSymbol2_get_numberOfColumns(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfColumns(This,pRetVal) ) + +#define IDiaSymbol2_get_isMatrixRowMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMatrixRowMajor(This,pRetVal) ) + +#define IDiaSymbol2_get_numericProperties(This,cnt,pcnt,pProperties) \ + ( (This)->lpVtbl -> get_numericProperties(This,cnt,pcnt,pProperties) ) + +#define IDiaSymbol2_get_modifierValues(This,cnt,pcnt,pModifiers) \ + ( (This)->lpVtbl -> get_modifierValues(This,cnt,pcnt,pModifiers) ) + +#define IDiaSymbol2_get_isReturnValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isReturnValue(This,pRetVal) ) + +#define IDiaSymbol2_get_isOptimizedAway(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedAway(This,pRetVal) ) + +#define IDiaSymbol2_get_builtInKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_builtInKind(This,pRetVal) ) + +#define IDiaSymbol2_get_registerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerType(This,pRetVal) ) + +#define IDiaSymbol2_get_baseDataSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataSlot(This,pRetVal) ) + +#define IDiaSymbol2_get_baseDataOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataOffset(This,pRetVal) ) + +#define IDiaSymbol2_get_textureSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_textureSlot(This,pRetVal) ) + +#define IDiaSymbol2_get_samplerSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_samplerSlot(This,pRetVal) ) + +#define IDiaSymbol2_get_uavSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_uavSlot(This,pRetVal) ) + +#define IDiaSymbol2_get_sizeInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_sizeInUdt(This,pRetVal) ) + +#define IDiaSymbol2_get_memorySpaceKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_memorySpaceKind(This,pRetVal) ) + +#define IDiaSymbol2_get_unmodifiedTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedTypeId(This,pRetVal) ) + +#define IDiaSymbol2_get_subTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_subTypeId(This,pRetVal) ) + +#define IDiaSymbol2_get_subType(This,pRetVal) \ + ( (This)->lpVtbl -> get_subType(This,pRetVal) ) + +#define IDiaSymbol2_get_numberOfModifiers(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfModifiers(This,pRetVal) ) + +#define IDiaSymbol2_get_numberOfRegisterIndices(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRegisterIndices(This,pRetVal) ) + +#define IDiaSymbol2_get_isHLSLData(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHLSLData(This,pRetVal) ) + +#define IDiaSymbol2_get_isPointerToDataMember(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToDataMember(This,pRetVal) ) + +#define IDiaSymbol2_get_isPointerToMemberFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToMemberFunction(This,pRetVal) ) + +#define IDiaSymbol2_get_isSingleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSingleInheritance(This,pRetVal) ) + +#define IDiaSymbol2_get_isMultipleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMultipleInheritance(This,pRetVal) ) + +#define IDiaSymbol2_get_isVirtualInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isVirtualInheritance(This,pRetVal) ) + +#define IDiaSymbol2_get_restrictedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_restrictedType(This,pRetVal) ) + +#define IDiaSymbol2_get_isPointerBasedOnSymbolValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerBasedOnSymbolValue(This,pRetVal) ) + +#define IDiaSymbol2_get_baseSymbol(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbol(This,pRetVal) ) + +#define IDiaSymbol2_get_baseSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbolId(This,pRetVal) ) + +#define IDiaSymbol2_get_objectFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectFileName(This,pRetVal) ) + +#define IDiaSymbol2_get_isAcceleratorGroupSharedLocal(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorGroupSharedLocal(This,pRetVal) ) + +#define IDiaSymbol2_get_isAcceleratorPointerTagLiveRange(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorPointerTagLiveRange(This,pRetVal) ) + +#define IDiaSymbol2_get_isAcceleratorStubFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorStubFunction(This,pRetVal) ) + +#define IDiaSymbol2_get_numberOfAcceleratorPointerTags(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfAcceleratorPointerTags(This,pRetVal) ) + +#define IDiaSymbol2_get_isSdl(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSdl(This,pRetVal) ) + +#define IDiaSymbol2_get_isWinRTPointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_isWinRTPointer(This,pRetVal) ) + +#define IDiaSymbol2_get_isRefUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isRefUdt(This,pRetVal) ) + +#define IDiaSymbol2_get_isValueUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isValueUdt(This,pRetVal) ) + +#define IDiaSymbol2_get_isInterfaceUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isInterfaceUdt(This,pRetVal) ) + +#define IDiaSymbol2_findInlineFramesByAddr(This,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByAddr(This,isect,offset,ppResult) ) + +#define IDiaSymbol2_findInlineFramesByRVA(This,rva,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByRVA(This,rva,ppResult) ) + +#define IDiaSymbol2_findInlineFramesByVA(This,va,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByVA(This,va,ppResult) ) + +#define IDiaSymbol2_findInlineeLines(This,ppResult) \ + ( (This)->lpVtbl -> findInlineeLines(This,ppResult) ) + +#define IDiaSymbol2_findInlineeLinesByAddr(This,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByAddr(This,isect,offset,length,ppResult) ) + +#define IDiaSymbol2_findInlineeLinesByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByRVA(This,rva,length,ppResult) ) + +#define IDiaSymbol2_findInlineeLinesByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByVA(This,va,length,ppResult) ) + +#define IDiaSymbol2_findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) \ + ( (This)->lpVtbl -> findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) ) + +#define IDiaSymbol2_findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) \ + ( (This)->lpVtbl -> findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) ) + +#define IDiaSymbol2_get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) \ + ( (This)->lpVtbl -> get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) ) + +#define IDiaSymbol2_getSrcLineOnTypeDefn(This,ppResult) \ + ( (This)->lpVtbl -> getSrcLineOnTypeDefn(This,ppResult) ) + +#define IDiaSymbol2_get_isPGO(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPGO(This,pRetVal) ) + +#define IDiaSymbol2_get_hasValidPGOCounts(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasValidPGOCounts(This,pRetVal) ) + +#define IDiaSymbol2_get_isOptimizedForSpeed(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedForSpeed(This,pRetVal) ) + +#define IDiaSymbol2_get_PGOEntryCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEntryCount(This,pRetVal) ) + +#define IDiaSymbol2_get_PGOEdgeCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEdgeCount(This,pRetVal) ) + +#define IDiaSymbol2_get_PGODynamicInstructionCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGODynamicInstructionCount(This,pRetVal) ) + +#define IDiaSymbol2_get_staticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_staticSize(This,pRetVal) ) + +#define IDiaSymbol2_get_finalLiveStaticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_finalLiveStaticSize(This,pRetVal) ) + +#define IDiaSymbol2_get_phaseName(This,pRetVal) \ + ( (This)->lpVtbl -> get_phaseName(This,pRetVal) ) + +#define IDiaSymbol2_get_hasControlFlowCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasControlFlowCheck(This,pRetVal) ) + +#define IDiaSymbol2_get_constantExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_constantExport(This,pRetVal) ) + +#define IDiaSymbol2_get_dataExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataExport(This,pRetVal) ) + +#define IDiaSymbol2_get_privateExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_privateExport(This,pRetVal) ) + +#define IDiaSymbol2_get_noNameExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_noNameExport(This,pRetVal) ) + +#define IDiaSymbol2_get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) ) + +#define IDiaSymbol2_get_exportIsForwarder(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportIsForwarder(This,pRetVal) ) + +#define IDiaSymbol2_get_ordinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_ordinal(This,pRetVal) ) + +#define IDiaSymbol2_get_frameSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_frameSize(This,pRetVal) ) + +#define IDiaSymbol2_get_exceptionHandlerAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressSection(This,pRetVal) ) + +#define IDiaSymbol2_get_exceptionHandlerAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressOffset(This,pRetVal) ) + +#define IDiaSymbol2_get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol2_get_exceptionHandlerVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol2_findInputAssemblyFile(This,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFile(This,ppResult) ) + +#define IDiaSymbol2_get_characteristics(This,pRetVal) \ + ( (This)->lpVtbl -> get_characteristics(This,pRetVal) ) + +#define IDiaSymbol2_get_coffGroup(This,pRetVal) \ + ( (This)->lpVtbl -> get_coffGroup(This,pRetVal) ) + +#define IDiaSymbol2_get_bindID(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindID(This,pRetVal) ) + +#define IDiaSymbol2_get_bindSpace(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSpace(This,pRetVal) ) + +#define IDiaSymbol2_get_bindSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSlot(This,pRetVal) ) + + +#define IDiaSymbol2_get_isObjCClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCClass(This,pRetVal) ) + +#define IDiaSymbol2_get_isObjCCategory(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCCategory(This,pRetVal) ) + +#define IDiaSymbol2_get_isObjCProtocol(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCProtocol(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol2_get_isObjCClass_Proxy( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol2_get_isObjCClass_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol2_get_isObjCCategory_Proxy( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol2_get_isObjCCategory_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol2_get_isObjCProtocol_Proxy( + IDiaSymbol2 * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol2_get_isObjCProtocol_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDiaSymbol2_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSymbol3_INTERFACE_DEFINED__ +#define __IDiaSymbol3_INTERFACE_DEFINED__ + +/* interface IDiaSymbol3 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSymbol3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("99b665f7-c1b2-49d3-89b2-a384361acab5") + IDiaSymbol3 : public IDiaSymbol2 + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_inlinee( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_inlineeId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSymbol3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSymbol3 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSymbol3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSymbol3 * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symIndexId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symTag )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParent )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParent )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataKind )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_locationType )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSymbol3 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )( + IDiaSymbol3 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSymbol3 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_slot )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_volatileType )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constType )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unalignedType )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_access )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_libraryName )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_platform )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_language )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_editAndContinueEnabled )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMajor )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMinor )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndBuild )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMajor )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMinor )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndBuild )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileName )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unused )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thunkOrdinal )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thisAdjust )( + IDiaSymbol3 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseOffset )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtual )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intro )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pure )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_callingConvention )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_value )( + IDiaSymbol3 * This, + /* [retval][out] */ VARIANT *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseType )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_token )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timeStamp )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_guid )( + IDiaSymbol3 * This, + /* [retval][out] */ GUID *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symbolsFileName )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_reference )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_count )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bitPosition )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexType )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_packed )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constructor )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_overloadedOperator )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_nested )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasNestedTypes )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAssignmentOperator )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasCastOperator )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_scoped )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseClass )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_indirectVirtualBaseClass )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBasePointerOffset )( + IDiaSymbol3 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShape )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParentId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParentId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_typeId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexTypeId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShapeId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_function )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_managed )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_msil )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseDispIndex )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_undecoratedName )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_age )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_signature )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerGenerated )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressTaken )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_rank )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBound )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBound )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBoundId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBoundId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_dataBytes )( + IDiaSymbol3 * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *findChildren )( + IDiaSymbol3 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenEx )( + IDiaSymbol3 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )( + IDiaSymbol3 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )( + IDiaSymbol3 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )( + IDiaSymbol3 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetSection )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetOffset )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetRelativeVirtualAddress )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetVirtualAddress )( + IDiaSymbol3 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_machineType )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemSymbolId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_types )( + IDiaSymbol3 * This, + /* [in] */ DWORD cTypes, + /* [out] */ DWORD *pcTypes, + /* [size_is][size_is][out] */ IDiaSymbol **pTypes); + + HRESULT ( STDMETHODCALLTYPE *get_typeIds )( + IDiaSymbol3 * This, + /* [in] */ DWORD cTypeIds, + /* [out] */ DWORD *pcTypeIds, + /* [size_is][out] */ DWORD *pdwTypeIds); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectPointerType )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_udtKind )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_undecoratedNameEx )( + IDiaSymbol3 * This, + /* [in] */ DWORD undecorateOptions, + /* [out] */ BSTR *name); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noReturn )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_customCallingConvention )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noInline )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_optimizedCodeDebugInfo )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notReached )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_interruptReturn )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_farReturn )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStatic )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasDebugInfo )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLTCG )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isDataAligned )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSecurityChecks )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerName )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAlloca )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSetJump )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasLongJump )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasInlAsm )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEH )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSEH )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEHa )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isNaked )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAggregated )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSplitted )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_container )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlSpec )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noStackOrdering )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseTableType )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasManagedCode )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHotpatchable )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCVTCIL )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMSILNetmodule )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCTypes )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStripped )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndQFE )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndQFE )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_wasInlined )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_strictGSCheck )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCxxReturnUdt )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isConstructorVirtualBase )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RValueReference )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedType )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_framePointerPresent )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSafeBuffers )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intrinsic )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sealed )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaFloat )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaDouble )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressSection )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressOffset )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartRelativeVirtualAddress )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_countLiveRanges )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeLength )( + IDiaSymbol3 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offsetInUdt )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_paramBasePointerRegisterId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localBasePointerRegisterId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLocationControlFlowDependent )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_stride )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRows )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfColumns )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMatrixRowMajor )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_numericProperties )( + IDiaSymbol3 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties); + + HRESULT ( STDMETHODCALLTYPE *get_modifierValues )( + IDiaSymbol3 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isReturnValue )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedAway )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_builtInKind )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerType )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataSlot )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataOffset )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_textureSlot )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_samplerSlot )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uavSlot )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sizeInUdt )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_memorySpaceKind )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedTypeId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subTypeId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subType )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfModifiers )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRegisterIndices )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHLSLData )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToDataMember )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToMemberFunction )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSingleInheritance )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMultipleInheritance )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isVirtualInheritance )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_restrictedType )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerBasedOnSymbolValue )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbol )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbolId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFileName )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorGroupSharedLocal )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorPointerTagLiveRange )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorStubFunction )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfAcceleratorPointerTags )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSdl )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isWinRTPointer )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isRefUdt )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isValueUdt )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isInterfaceUdt )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByAddr )( + IDiaSymbol3 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByRVA )( + IDiaSymbol3 * This, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByVA )( + IDiaSymbol3 * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLines )( + IDiaSymbol3 * This, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByAddr )( + IDiaSymbol3 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByRVA )( + IDiaSymbol3 * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByVA )( + IDiaSymbol3 * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsForAcceleratorPointerTag )( + IDiaSymbol3 * This, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsByRVAForAcceleratorPointerTag )( + IDiaSymbol3 * This, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *get_acceleratorPointerTags )( + IDiaSymbol3 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags); + + HRESULT ( STDMETHODCALLTYPE *getSrcLineOnTypeDefn )( + IDiaSymbol3 * This, + /* [out] */ IDiaLineNumber **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPGO )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasValidPGOCounts )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedForSpeed )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEntryCount )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEdgeCount )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGODynamicInstructionCount )( + IDiaSymbol3 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_staticSize )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_finalLiveStaticSize )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_phaseName )( + IDiaSymbol3 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasControlFlowCheck )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constantExport )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataExport )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_privateExport )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noNameExport )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportHasExplicitlyAssignedOrdinal )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportIsForwarder )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ordinal )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frameSize )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressSection )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressOffset )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerRelativeVirtualAddress )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerVirtualAddress )( + IDiaSymbol3 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFile )( + IDiaSymbol3 * This, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_characteristics )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_coffGroup )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindID )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSpace )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSlot )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCClass )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCCategory )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCProtocol )( + IDiaSymbol3 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlinee )( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlineeId )( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + END_INTERFACE + } IDiaSymbol3Vtbl; + + interface IDiaSymbol3 + { + CONST_VTBL struct IDiaSymbol3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSymbol3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSymbol3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSymbol3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSymbol3_get_symIndexId(This,pRetVal) \ + ( (This)->lpVtbl -> get_symIndexId(This,pRetVal) ) + +#define IDiaSymbol3_get_symTag(This,pRetVal) \ + ( (This)->lpVtbl -> get_symTag(This,pRetVal) ) + +#define IDiaSymbol3_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaSymbol3_get_lexicalParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParent(This,pRetVal) ) + +#define IDiaSymbol3_get_classParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParent(This,pRetVal) ) + +#define IDiaSymbol3_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaSymbol3_get_dataKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataKind(This,pRetVal) ) + +#define IDiaSymbol3_get_locationType(This,pRetVal) \ + ( (This)->lpVtbl -> get_locationType(This,pRetVal) ) + +#define IDiaSymbol3_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSymbol3_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaSymbol3_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol3_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaSymbol3_get_registerId(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerId(This,pRetVal) ) + +#define IDiaSymbol3_get_offset(This,pRetVal) \ + ( (This)->lpVtbl -> get_offset(This,pRetVal) ) + +#define IDiaSymbol3_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSymbol3_get_slot(This,pRetVal) \ + ( (This)->lpVtbl -> get_slot(This,pRetVal) ) + +#define IDiaSymbol3_get_volatileType(This,pRetVal) \ + ( (This)->lpVtbl -> get_volatileType(This,pRetVal) ) + +#define IDiaSymbol3_get_constType(This,pRetVal) \ + ( (This)->lpVtbl -> get_constType(This,pRetVal) ) + +#define IDiaSymbol3_get_unalignedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unalignedType(This,pRetVal) ) + +#define IDiaSymbol3_get_access(This,pRetVal) \ + ( (This)->lpVtbl -> get_access(This,pRetVal) ) + +#define IDiaSymbol3_get_libraryName(This,pRetVal) \ + ( (This)->lpVtbl -> get_libraryName(This,pRetVal) ) + +#define IDiaSymbol3_get_platform(This,pRetVal) \ + ( (This)->lpVtbl -> get_platform(This,pRetVal) ) + +#define IDiaSymbol3_get_language(This,pRetVal) \ + ( (This)->lpVtbl -> get_language(This,pRetVal) ) + +#define IDiaSymbol3_get_editAndContinueEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_editAndContinueEnabled(This,pRetVal) ) + +#define IDiaSymbol3_get_frontEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMajor(This,pRetVal) ) + +#define IDiaSymbol3_get_frontEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMinor(This,pRetVal) ) + +#define IDiaSymbol3_get_frontEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndBuild(This,pRetVal) ) + +#define IDiaSymbol3_get_backEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMajor(This,pRetVal) ) + +#define IDiaSymbol3_get_backEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMinor(This,pRetVal) ) + +#define IDiaSymbol3_get_backEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndBuild(This,pRetVal) ) + +#define IDiaSymbol3_get_sourceFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFileName(This,pRetVal) ) + +#define IDiaSymbol3_get_unused(This,pRetVal) \ + ( (This)->lpVtbl -> get_unused(This,pRetVal) ) + +#define IDiaSymbol3_get_thunkOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_thunkOrdinal(This,pRetVal) ) + +#define IDiaSymbol3_get_thisAdjust(This,pRetVal) \ + ( (This)->lpVtbl -> get_thisAdjust(This,pRetVal) ) + +#define IDiaSymbol3_get_virtualBaseOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseOffset(This,pRetVal) ) + +#define IDiaSymbol3_get_virtual(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtual(This,pRetVal) ) + +#define IDiaSymbol3_get_intro(This,pRetVal) \ + ( (This)->lpVtbl -> get_intro(This,pRetVal) ) + +#define IDiaSymbol3_get_pure(This,pRetVal) \ + ( (This)->lpVtbl -> get_pure(This,pRetVal) ) + +#define IDiaSymbol3_get_callingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_callingConvention(This,pRetVal) ) + +#define IDiaSymbol3_get_value(This,pRetVal) \ + ( (This)->lpVtbl -> get_value(This,pRetVal) ) + +#define IDiaSymbol3_get_baseType(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseType(This,pRetVal) ) + +#define IDiaSymbol3_get_token(This,pRetVal) \ + ( (This)->lpVtbl -> get_token(This,pRetVal) ) + +#define IDiaSymbol3_get_timeStamp(This,pRetVal) \ + ( (This)->lpVtbl -> get_timeStamp(This,pRetVal) ) + +#define IDiaSymbol3_get_guid(This,pRetVal) \ + ( (This)->lpVtbl -> get_guid(This,pRetVal) ) + +#define IDiaSymbol3_get_symbolsFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_symbolsFileName(This,pRetVal) ) + +#define IDiaSymbol3_get_reference(This,pRetVal) \ + ( (This)->lpVtbl -> get_reference(This,pRetVal) ) + +#define IDiaSymbol3_get_count(This,pRetVal) \ + ( (This)->lpVtbl -> get_count(This,pRetVal) ) + +#define IDiaSymbol3_get_bitPosition(This,pRetVal) \ + ( (This)->lpVtbl -> get_bitPosition(This,pRetVal) ) + +#define IDiaSymbol3_get_arrayIndexType(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexType(This,pRetVal) ) + +#define IDiaSymbol3_get_packed(This,pRetVal) \ + ( (This)->lpVtbl -> get_packed(This,pRetVal) ) + +#define IDiaSymbol3_get_constructor(This,pRetVal) \ + ( (This)->lpVtbl -> get_constructor(This,pRetVal) ) + +#define IDiaSymbol3_get_overloadedOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_overloadedOperator(This,pRetVal) ) + +#define IDiaSymbol3_get_nested(This,pRetVal) \ + ( (This)->lpVtbl -> get_nested(This,pRetVal) ) + +#define IDiaSymbol3_get_hasNestedTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasNestedTypes(This,pRetVal) ) + +#define IDiaSymbol3_get_hasAssignmentOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAssignmentOperator(This,pRetVal) ) + +#define IDiaSymbol3_get_hasCastOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasCastOperator(This,pRetVal) ) + +#define IDiaSymbol3_get_scoped(This,pRetVal) \ + ( (This)->lpVtbl -> get_scoped(This,pRetVal) ) + +#define IDiaSymbol3_get_virtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol3_get_indirectVirtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_indirectVirtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol3_get_virtualBasePointerOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBasePointerOffset(This,pRetVal) ) + +#define IDiaSymbol3_get_virtualTableShape(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShape(This,pRetVal) ) + +#define IDiaSymbol3_get_lexicalParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParentId(This,pRetVal) ) + +#define IDiaSymbol3_get_classParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParentId(This,pRetVal) ) + +#define IDiaSymbol3_get_typeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_typeId(This,pRetVal) ) + +#define IDiaSymbol3_get_arrayIndexTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexTypeId(This,pRetVal) ) + +#define IDiaSymbol3_get_virtualTableShapeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShapeId(This,pRetVal) ) + +#define IDiaSymbol3_get_code(This,pRetVal) \ + ( (This)->lpVtbl -> get_code(This,pRetVal) ) + +#define IDiaSymbol3_get_function(This,pRetVal) \ + ( (This)->lpVtbl -> get_function(This,pRetVal) ) + +#define IDiaSymbol3_get_managed(This,pRetVal) \ + ( (This)->lpVtbl -> get_managed(This,pRetVal) ) + +#define IDiaSymbol3_get_msil(This,pRetVal) \ + ( (This)->lpVtbl -> get_msil(This,pRetVal) ) + +#define IDiaSymbol3_get_virtualBaseDispIndex(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseDispIndex(This,pRetVal) ) + +#define IDiaSymbol3_get_undecoratedName(This,pRetVal) \ + ( (This)->lpVtbl -> get_undecoratedName(This,pRetVal) ) + +#define IDiaSymbol3_get_age(This,pRetVal) \ + ( (This)->lpVtbl -> get_age(This,pRetVal) ) + +#define IDiaSymbol3_get_signature(This,pRetVal) \ + ( (This)->lpVtbl -> get_signature(This,pRetVal) ) + +#define IDiaSymbol3_get_compilerGenerated(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerGenerated(This,pRetVal) ) + +#define IDiaSymbol3_get_addressTaken(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressTaken(This,pRetVal) ) + +#define IDiaSymbol3_get_rank(This,pRetVal) \ + ( (This)->lpVtbl -> get_rank(This,pRetVal) ) + +#define IDiaSymbol3_get_lowerBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBound(This,pRetVal) ) + +#define IDiaSymbol3_get_upperBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBound(This,pRetVal) ) + +#define IDiaSymbol3_get_lowerBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBoundId(This,pRetVal) ) + +#define IDiaSymbol3_get_upperBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBoundId(This,pRetVal) ) + +#define IDiaSymbol3_get_dataBytes(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_dataBytes(This,cbData,pcbData,pbData) ) + +#define IDiaSymbol3_findChildren(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildren(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol3_findChildrenEx(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildrenEx(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol3_findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) ) + +#define IDiaSymbol3_findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) ) + +#define IDiaSymbol3_findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) ) + +#define IDiaSymbol3_get_targetSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetSection(This,pRetVal) ) + +#define IDiaSymbol3_get_targetOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetOffset(This,pRetVal) ) + +#define IDiaSymbol3_get_targetRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol3_get_targetVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol3_get_machineType(This,pRetVal) \ + ( (This)->lpVtbl -> get_machineType(This,pRetVal) ) + +#define IDiaSymbol3_get_oemId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemId(This,pRetVal) ) + +#define IDiaSymbol3_get_oemSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemSymbolId(This,pRetVal) ) + +#define IDiaSymbol3_get_types(This,cTypes,pcTypes,pTypes) \ + ( (This)->lpVtbl -> get_types(This,cTypes,pcTypes,pTypes) ) + +#define IDiaSymbol3_get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) \ + ( (This)->lpVtbl -> get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) ) + +#define IDiaSymbol3_get_objectPointerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectPointerType(This,pRetVal) ) + +#define IDiaSymbol3_get_udtKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_udtKind(This,pRetVal) ) + +#define IDiaSymbol3_get_undecoratedNameEx(This,undecorateOptions,name) \ + ( (This)->lpVtbl -> get_undecoratedNameEx(This,undecorateOptions,name) ) + +#define IDiaSymbol3_get_noReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_noReturn(This,pRetVal) ) + +#define IDiaSymbol3_get_customCallingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_customCallingConvention(This,pRetVal) ) + +#define IDiaSymbol3_get_noInline(This,pRetVal) \ + ( (This)->lpVtbl -> get_noInline(This,pRetVal) ) + +#define IDiaSymbol3_get_optimizedCodeDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_optimizedCodeDebugInfo(This,pRetVal) ) + +#define IDiaSymbol3_get_notReached(This,pRetVal) \ + ( (This)->lpVtbl -> get_notReached(This,pRetVal) ) + +#define IDiaSymbol3_get_interruptReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_interruptReturn(This,pRetVal) ) + +#define IDiaSymbol3_get_farReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_farReturn(This,pRetVal) ) + +#define IDiaSymbol3_get_isStatic(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStatic(This,pRetVal) ) + +#define IDiaSymbol3_get_hasDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasDebugInfo(This,pRetVal) ) + +#define IDiaSymbol3_get_isLTCG(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLTCG(This,pRetVal) ) + +#define IDiaSymbol3_get_isDataAligned(This,pRetVal) \ + ( (This)->lpVtbl -> get_isDataAligned(This,pRetVal) ) + +#define IDiaSymbol3_get_hasSecurityChecks(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSecurityChecks(This,pRetVal) ) + +#define IDiaSymbol3_get_compilerName(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerName(This,pRetVal) ) + +#define IDiaSymbol3_get_hasAlloca(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAlloca(This,pRetVal) ) + +#define IDiaSymbol3_get_hasSetJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSetJump(This,pRetVal) ) + +#define IDiaSymbol3_get_hasLongJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasLongJump(This,pRetVal) ) + +#define IDiaSymbol3_get_hasInlAsm(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasInlAsm(This,pRetVal) ) + +#define IDiaSymbol3_get_hasEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEH(This,pRetVal) ) + +#define IDiaSymbol3_get_hasSEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSEH(This,pRetVal) ) + +#define IDiaSymbol3_get_hasEHa(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEHa(This,pRetVal) ) + +#define IDiaSymbol3_get_isNaked(This,pRetVal) \ + ( (This)->lpVtbl -> get_isNaked(This,pRetVal) ) + +#define IDiaSymbol3_get_isAggregated(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAggregated(This,pRetVal) ) + +#define IDiaSymbol3_get_isSplitted(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSplitted(This,pRetVal) ) + +#define IDiaSymbol3_get_container(This,pRetVal) \ + ( (This)->lpVtbl -> get_container(This,pRetVal) ) + +#define IDiaSymbol3_get_inlSpec(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlSpec(This,pRetVal) ) + +#define IDiaSymbol3_get_noStackOrdering(This,pRetVal) \ + ( (This)->lpVtbl -> get_noStackOrdering(This,pRetVal) ) + +#define IDiaSymbol3_get_virtualBaseTableType(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseTableType(This,pRetVal) ) + +#define IDiaSymbol3_get_hasManagedCode(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasManagedCode(This,pRetVal) ) + +#define IDiaSymbol3_get_isHotpatchable(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHotpatchable(This,pRetVal) ) + +#define IDiaSymbol3_get_isCVTCIL(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCVTCIL(This,pRetVal) ) + +#define IDiaSymbol3_get_isMSILNetmodule(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMSILNetmodule(This,pRetVal) ) + +#define IDiaSymbol3_get_isCTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCTypes(This,pRetVal) ) + +#define IDiaSymbol3_get_isStripped(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStripped(This,pRetVal) ) + +#define IDiaSymbol3_get_frontEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndQFE(This,pRetVal) ) + +#define IDiaSymbol3_get_backEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndQFE(This,pRetVal) ) + +#define IDiaSymbol3_get_wasInlined(This,pRetVal) \ + ( (This)->lpVtbl -> get_wasInlined(This,pRetVal) ) + +#define IDiaSymbol3_get_strictGSCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_strictGSCheck(This,pRetVal) ) + +#define IDiaSymbol3_get_isCxxReturnUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCxxReturnUdt(This,pRetVal) ) + +#define IDiaSymbol3_get_isConstructorVirtualBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_isConstructorVirtualBase(This,pRetVal) ) + +#define IDiaSymbol3_get_RValueReference(This,pRetVal) \ + ( (This)->lpVtbl -> get_RValueReference(This,pRetVal) ) + +#define IDiaSymbol3_get_unmodifiedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedType(This,pRetVal) ) + +#define IDiaSymbol3_get_framePointerPresent(This,pRetVal) \ + ( (This)->lpVtbl -> get_framePointerPresent(This,pRetVal) ) + +#define IDiaSymbol3_get_isSafeBuffers(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSafeBuffers(This,pRetVal) ) + +#define IDiaSymbol3_get_intrinsic(This,pRetVal) \ + ( (This)->lpVtbl -> get_intrinsic(This,pRetVal) ) + +#define IDiaSymbol3_get_sealed(This,pRetVal) \ + ( (This)->lpVtbl -> get_sealed(This,pRetVal) ) + +#define IDiaSymbol3_get_hfaFloat(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaFloat(This,pRetVal) ) + +#define IDiaSymbol3_get_hfaDouble(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaDouble(This,pRetVal) ) + +#define IDiaSymbol3_get_liveRangeStartAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressSection(This,pRetVal) ) + +#define IDiaSymbol3_get_liveRangeStartAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressOffset(This,pRetVal) ) + +#define IDiaSymbol3_get_liveRangeStartRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol3_get_countLiveRanges(This,pRetVal) \ + ( (This)->lpVtbl -> get_countLiveRanges(This,pRetVal) ) + +#define IDiaSymbol3_get_liveRangeLength(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeLength(This,pRetVal) ) + +#define IDiaSymbol3_get_offsetInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_offsetInUdt(This,pRetVal) ) + +#define IDiaSymbol3_get_paramBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_paramBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol3_get_localBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_localBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol3_get_isLocationControlFlowDependent(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLocationControlFlowDependent(This,pRetVal) ) + +#define IDiaSymbol3_get_stride(This,pRetVal) \ + ( (This)->lpVtbl -> get_stride(This,pRetVal) ) + +#define IDiaSymbol3_get_numberOfRows(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRows(This,pRetVal) ) + +#define IDiaSymbol3_get_numberOfColumns(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfColumns(This,pRetVal) ) + +#define IDiaSymbol3_get_isMatrixRowMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMatrixRowMajor(This,pRetVal) ) + +#define IDiaSymbol3_get_numericProperties(This,cnt,pcnt,pProperties) \ + ( (This)->lpVtbl -> get_numericProperties(This,cnt,pcnt,pProperties) ) + +#define IDiaSymbol3_get_modifierValues(This,cnt,pcnt,pModifiers) \ + ( (This)->lpVtbl -> get_modifierValues(This,cnt,pcnt,pModifiers) ) + +#define IDiaSymbol3_get_isReturnValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isReturnValue(This,pRetVal) ) + +#define IDiaSymbol3_get_isOptimizedAway(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedAway(This,pRetVal) ) + +#define IDiaSymbol3_get_builtInKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_builtInKind(This,pRetVal) ) + +#define IDiaSymbol3_get_registerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerType(This,pRetVal) ) + +#define IDiaSymbol3_get_baseDataSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataSlot(This,pRetVal) ) + +#define IDiaSymbol3_get_baseDataOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataOffset(This,pRetVal) ) + +#define IDiaSymbol3_get_textureSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_textureSlot(This,pRetVal) ) + +#define IDiaSymbol3_get_samplerSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_samplerSlot(This,pRetVal) ) + +#define IDiaSymbol3_get_uavSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_uavSlot(This,pRetVal) ) + +#define IDiaSymbol3_get_sizeInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_sizeInUdt(This,pRetVal) ) + +#define IDiaSymbol3_get_memorySpaceKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_memorySpaceKind(This,pRetVal) ) + +#define IDiaSymbol3_get_unmodifiedTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedTypeId(This,pRetVal) ) + +#define IDiaSymbol3_get_subTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_subTypeId(This,pRetVal) ) + +#define IDiaSymbol3_get_subType(This,pRetVal) \ + ( (This)->lpVtbl -> get_subType(This,pRetVal) ) + +#define IDiaSymbol3_get_numberOfModifiers(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfModifiers(This,pRetVal) ) + +#define IDiaSymbol3_get_numberOfRegisterIndices(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRegisterIndices(This,pRetVal) ) + +#define IDiaSymbol3_get_isHLSLData(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHLSLData(This,pRetVal) ) + +#define IDiaSymbol3_get_isPointerToDataMember(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToDataMember(This,pRetVal) ) + +#define IDiaSymbol3_get_isPointerToMemberFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToMemberFunction(This,pRetVal) ) + +#define IDiaSymbol3_get_isSingleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSingleInheritance(This,pRetVal) ) + +#define IDiaSymbol3_get_isMultipleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMultipleInheritance(This,pRetVal) ) + +#define IDiaSymbol3_get_isVirtualInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isVirtualInheritance(This,pRetVal) ) + +#define IDiaSymbol3_get_restrictedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_restrictedType(This,pRetVal) ) + +#define IDiaSymbol3_get_isPointerBasedOnSymbolValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerBasedOnSymbolValue(This,pRetVal) ) + +#define IDiaSymbol3_get_baseSymbol(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbol(This,pRetVal) ) + +#define IDiaSymbol3_get_baseSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbolId(This,pRetVal) ) + +#define IDiaSymbol3_get_objectFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectFileName(This,pRetVal) ) + +#define IDiaSymbol3_get_isAcceleratorGroupSharedLocal(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorGroupSharedLocal(This,pRetVal) ) + +#define IDiaSymbol3_get_isAcceleratorPointerTagLiveRange(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorPointerTagLiveRange(This,pRetVal) ) + +#define IDiaSymbol3_get_isAcceleratorStubFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorStubFunction(This,pRetVal) ) + +#define IDiaSymbol3_get_numberOfAcceleratorPointerTags(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfAcceleratorPointerTags(This,pRetVal) ) + +#define IDiaSymbol3_get_isSdl(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSdl(This,pRetVal) ) + +#define IDiaSymbol3_get_isWinRTPointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_isWinRTPointer(This,pRetVal) ) + +#define IDiaSymbol3_get_isRefUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isRefUdt(This,pRetVal) ) + +#define IDiaSymbol3_get_isValueUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isValueUdt(This,pRetVal) ) + +#define IDiaSymbol3_get_isInterfaceUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isInterfaceUdt(This,pRetVal) ) + +#define IDiaSymbol3_findInlineFramesByAddr(This,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByAddr(This,isect,offset,ppResult) ) + +#define IDiaSymbol3_findInlineFramesByRVA(This,rva,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByRVA(This,rva,ppResult) ) + +#define IDiaSymbol3_findInlineFramesByVA(This,va,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByVA(This,va,ppResult) ) + +#define IDiaSymbol3_findInlineeLines(This,ppResult) \ + ( (This)->lpVtbl -> findInlineeLines(This,ppResult) ) + +#define IDiaSymbol3_findInlineeLinesByAddr(This,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByAddr(This,isect,offset,length,ppResult) ) + +#define IDiaSymbol3_findInlineeLinesByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByRVA(This,rva,length,ppResult) ) + +#define IDiaSymbol3_findInlineeLinesByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByVA(This,va,length,ppResult) ) + +#define IDiaSymbol3_findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) \ + ( (This)->lpVtbl -> findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) ) + +#define IDiaSymbol3_findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) \ + ( (This)->lpVtbl -> findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) ) + +#define IDiaSymbol3_get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) \ + ( (This)->lpVtbl -> get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) ) + +#define IDiaSymbol3_getSrcLineOnTypeDefn(This,ppResult) \ + ( (This)->lpVtbl -> getSrcLineOnTypeDefn(This,ppResult) ) + +#define IDiaSymbol3_get_isPGO(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPGO(This,pRetVal) ) + +#define IDiaSymbol3_get_hasValidPGOCounts(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasValidPGOCounts(This,pRetVal) ) + +#define IDiaSymbol3_get_isOptimizedForSpeed(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedForSpeed(This,pRetVal) ) + +#define IDiaSymbol3_get_PGOEntryCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEntryCount(This,pRetVal) ) + +#define IDiaSymbol3_get_PGOEdgeCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEdgeCount(This,pRetVal) ) + +#define IDiaSymbol3_get_PGODynamicInstructionCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGODynamicInstructionCount(This,pRetVal) ) + +#define IDiaSymbol3_get_staticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_staticSize(This,pRetVal) ) + +#define IDiaSymbol3_get_finalLiveStaticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_finalLiveStaticSize(This,pRetVal) ) + +#define IDiaSymbol3_get_phaseName(This,pRetVal) \ + ( (This)->lpVtbl -> get_phaseName(This,pRetVal) ) + +#define IDiaSymbol3_get_hasControlFlowCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasControlFlowCheck(This,pRetVal) ) + +#define IDiaSymbol3_get_constantExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_constantExport(This,pRetVal) ) + +#define IDiaSymbol3_get_dataExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataExport(This,pRetVal) ) + +#define IDiaSymbol3_get_privateExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_privateExport(This,pRetVal) ) + +#define IDiaSymbol3_get_noNameExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_noNameExport(This,pRetVal) ) + +#define IDiaSymbol3_get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) ) + +#define IDiaSymbol3_get_exportIsForwarder(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportIsForwarder(This,pRetVal) ) + +#define IDiaSymbol3_get_ordinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_ordinal(This,pRetVal) ) + +#define IDiaSymbol3_get_frameSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_frameSize(This,pRetVal) ) + +#define IDiaSymbol3_get_exceptionHandlerAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressSection(This,pRetVal) ) + +#define IDiaSymbol3_get_exceptionHandlerAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressOffset(This,pRetVal) ) + +#define IDiaSymbol3_get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol3_get_exceptionHandlerVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol3_findInputAssemblyFile(This,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFile(This,ppResult) ) + +#define IDiaSymbol3_get_characteristics(This,pRetVal) \ + ( (This)->lpVtbl -> get_characteristics(This,pRetVal) ) + +#define IDiaSymbol3_get_coffGroup(This,pRetVal) \ + ( (This)->lpVtbl -> get_coffGroup(This,pRetVal) ) + +#define IDiaSymbol3_get_bindID(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindID(This,pRetVal) ) + +#define IDiaSymbol3_get_bindSpace(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSpace(This,pRetVal) ) + +#define IDiaSymbol3_get_bindSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSlot(This,pRetVal) ) + + +#define IDiaSymbol3_get_isObjCClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCClass(This,pRetVal) ) + +#define IDiaSymbol3_get_isObjCCategory(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCCategory(This,pRetVal) ) + +#define IDiaSymbol3_get_isObjCProtocol(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCProtocol(This,pRetVal) ) + + +#define IDiaSymbol3_get_inlinee(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlinee(This,pRetVal) ) + +#define IDiaSymbol3_get_inlineeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlineeId(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol3_get_inlinee_Proxy( + IDiaSymbol3 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + +void __RPC_STUB IDiaSymbol3_get_inlinee_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol3_get_inlineeId_Proxy( + IDiaSymbol3 * This, + /* [retval][out] */ DWORD *pRetVal); + + +void __RPC_STUB IDiaSymbol3_get_inlineeId_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDiaSymbol3_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSymbol4_INTERFACE_DEFINED__ +#define __IDiaSymbol4_INTERFACE_DEFINED__ + +/* interface IDiaSymbol4 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSymbol4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("bf6c88a7-e9d6-4346-99a1-d053de5a7808") + IDiaSymbol4 : public IDiaSymbol3 + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_noexcept( + /* [retval][out] */ BOOL *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSymbol4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSymbol4 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSymbol4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSymbol4 * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symIndexId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symTag )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParent )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParent )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataKind )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_locationType )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSymbol4 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )( + IDiaSymbol4 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSymbol4 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_slot )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_volatileType )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constType )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unalignedType )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_access )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_libraryName )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_platform )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_language )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_editAndContinueEnabled )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMajor )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMinor )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndBuild )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMajor )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMinor )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndBuild )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileName )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unused )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thunkOrdinal )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thisAdjust )( + IDiaSymbol4 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseOffset )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtual )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intro )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pure )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_callingConvention )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_value )( + IDiaSymbol4 * This, + /* [retval][out] */ VARIANT *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseType )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_token )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timeStamp )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_guid )( + IDiaSymbol4 * This, + /* [retval][out] */ GUID *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symbolsFileName )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_reference )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_count )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bitPosition )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexType )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_packed )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constructor )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_overloadedOperator )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_nested )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasNestedTypes )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAssignmentOperator )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasCastOperator )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_scoped )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseClass )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_indirectVirtualBaseClass )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBasePointerOffset )( + IDiaSymbol4 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShape )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParentId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParentId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_typeId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexTypeId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShapeId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_function )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_managed )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_msil )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseDispIndex )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_undecoratedName )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_age )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_signature )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerGenerated )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressTaken )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_rank )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBound )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBound )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBoundId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBoundId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_dataBytes )( + IDiaSymbol4 * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *findChildren )( + IDiaSymbol4 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenEx )( + IDiaSymbol4 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )( + IDiaSymbol4 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )( + IDiaSymbol4 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )( + IDiaSymbol4 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetSection )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetOffset )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetRelativeVirtualAddress )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetVirtualAddress )( + IDiaSymbol4 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_machineType )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemSymbolId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_types )( + IDiaSymbol4 * This, + /* [in] */ DWORD cTypes, + /* [out] */ DWORD *pcTypes, + /* [size_is][size_is][out] */ IDiaSymbol **pTypes); + + HRESULT ( STDMETHODCALLTYPE *get_typeIds )( + IDiaSymbol4 * This, + /* [in] */ DWORD cTypeIds, + /* [out] */ DWORD *pcTypeIds, + /* [size_is][out] */ DWORD *pdwTypeIds); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectPointerType )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_udtKind )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_undecoratedNameEx )( + IDiaSymbol4 * This, + /* [in] */ DWORD undecorateOptions, + /* [out] */ BSTR *name); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noReturn )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_customCallingConvention )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noInline )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_optimizedCodeDebugInfo )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notReached )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_interruptReturn )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_farReturn )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStatic )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasDebugInfo )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLTCG )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isDataAligned )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSecurityChecks )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerName )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAlloca )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSetJump )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasLongJump )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasInlAsm )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEH )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSEH )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEHa )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isNaked )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAggregated )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSplitted )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_container )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlSpec )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noStackOrdering )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseTableType )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasManagedCode )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHotpatchable )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCVTCIL )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMSILNetmodule )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCTypes )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStripped )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndQFE )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndQFE )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_wasInlined )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_strictGSCheck )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCxxReturnUdt )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isConstructorVirtualBase )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RValueReference )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedType )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_framePointerPresent )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSafeBuffers )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intrinsic )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sealed )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaFloat )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaDouble )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressSection )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressOffset )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartRelativeVirtualAddress )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_countLiveRanges )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeLength )( + IDiaSymbol4 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offsetInUdt )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_paramBasePointerRegisterId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localBasePointerRegisterId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLocationControlFlowDependent )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_stride )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRows )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfColumns )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMatrixRowMajor )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_numericProperties )( + IDiaSymbol4 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties); + + HRESULT ( STDMETHODCALLTYPE *get_modifierValues )( + IDiaSymbol4 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isReturnValue )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedAway )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_builtInKind )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerType )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataSlot )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataOffset )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_textureSlot )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_samplerSlot )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uavSlot )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sizeInUdt )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_memorySpaceKind )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedTypeId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subTypeId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subType )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfModifiers )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRegisterIndices )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHLSLData )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToDataMember )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToMemberFunction )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSingleInheritance )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMultipleInheritance )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isVirtualInheritance )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_restrictedType )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerBasedOnSymbolValue )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbol )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbolId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFileName )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorGroupSharedLocal )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorPointerTagLiveRange )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorStubFunction )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfAcceleratorPointerTags )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSdl )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isWinRTPointer )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isRefUdt )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isValueUdt )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isInterfaceUdt )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByAddr )( + IDiaSymbol4 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByRVA )( + IDiaSymbol4 * This, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByVA )( + IDiaSymbol4 * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLines )( + IDiaSymbol4 * This, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByAddr )( + IDiaSymbol4 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByRVA )( + IDiaSymbol4 * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByVA )( + IDiaSymbol4 * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsForAcceleratorPointerTag )( + IDiaSymbol4 * This, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsByRVAForAcceleratorPointerTag )( + IDiaSymbol4 * This, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *get_acceleratorPointerTags )( + IDiaSymbol4 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags); + + HRESULT ( STDMETHODCALLTYPE *getSrcLineOnTypeDefn )( + IDiaSymbol4 * This, + /* [out] */ IDiaLineNumber **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPGO )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasValidPGOCounts )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedForSpeed )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEntryCount )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEdgeCount )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGODynamicInstructionCount )( + IDiaSymbol4 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_staticSize )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_finalLiveStaticSize )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_phaseName )( + IDiaSymbol4 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasControlFlowCheck )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constantExport )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataExport )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_privateExport )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noNameExport )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportHasExplicitlyAssignedOrdinal )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportIsForwarder )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ordinal )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frameSize )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressSection )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressOffset )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerRelativeVirtualAddress )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerVirtualAddress )( + IDiaSymbol4 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFile )( + IDiaSymbol4 * This, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_characteristics )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_coffGroup )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindID )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSpace )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSlot )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCClass )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCCategory )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCProtocol )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlinee )( + IDiaSymbol4 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlineeId )( + IDiaSymbol4 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noexcept )( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + END_INTERFACE + } IDiaSymbol4Vtbl; + + interface IDiaSymbol4 + { + CONST_VTBL struct IDiaSymbol4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSymbol4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSymbol4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSymbol4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSymbol4_get_symIndexId(This,pRetVal) \ + ( (This)->lpVtbl -> get_symIndexId(This,pRetVal) ) + +#define IDiaSymbol4_get_symTag(This,pRetVal) \ + ( (This)->lpVtbl -> get_symTag(This,pRetVal) ) + +#define IDiaSymbol4_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaSymbol4_get_lexicalParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParent(This,pRetVal) ) + +#define IDiaSymbol4_get_classParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParent(This,pRetVal) ) + +#define IDiaSymbol4_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaSymbol4_get_dataKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataKind(This,pRetVal) ) + +#define IDiaSymbol4_get_locationType(This,pRetVal) \ + ( (This)->lpVtbl -> get_locationType(This,pRetVal) ) + +#define IDiaSymbol4_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSymbol4_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaSymbol4_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol4_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaSymbol4_get_registerId(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerId(This,pRetVal) ) + +#define IDiaSymbol4_get_offset(This,pRetVal) \ + ( (This)->lpVtbl -> get_offset(This,pRetVal) ) + +#define IDiaSymbol4_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSymbol4_get_slot(This,pRetVal) \ + ( (This)->lpVtbl -> get_slot(This,pRetVal) ) + +#define IDiaSymbol4_get_volatileType(This,pRetVal) \ + ( (This)->lpVtbl -> get_volatileType(This,pRetVal) ) + +#define IDiaSymbol4_get_constType(This,pRetVal) \ + ( (This)->lpVtbl -> get_constType(This,pRetVal) ) + +#define IDiaSymbol4_get_unalignedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unalignedType(This,pRetVal) ) + +#define IDiaSymbol4_get_access(This,pRetVal) \ + ( (This)->lpVtbl -> get_access(This,pRetVal) ) + +#define IDiaSymbol4_get_libraryName(This,pRetVal) \ + ( (This)->lpVtbl -> get_libraryName(This,pRetVal) ) + +#define IDiaSymbol4_get_platform(This,pRetVal) \ + ( (This)->lpVtbl -> get_platform(This,pRetVal) ) + +#define IDiaSymbol4_get_language(This,pRetVal) \ + ( (This)->lpVtbl -> get_language(This,pRetVal) ) + +#define IDiaSymbol4_get_editAndContinueEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_editAndContinueEnabled(This,pRetVal) ) + +#define IDiaSymbol4_get_frontEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMajor(This,pRetVal) ) + +#define IDiaSymbol4_get_frontEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMinor(This,pRetVal) ) + +#define IDiaSymbol4_get_frontEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndBuild(This,pRetVal) ) + +#define IDiaSymbol4_get_backEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMajor(This,pRetVal) ) + +#define IDiaSymbol4_get_backEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMinor(This,pRetVal) ) + +#define IDiaSymbol4_get_backEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndBuild(This,pRetVal) ) + +#define IDiaSymbol4_get_sourceFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFileName(This,pRetVal) ) + +#define IDiaSymbol4_get_unused(This,pRetVal) \ + ( (This)->lpVtbl -> get_unused(This,pRetVal) ) + +#define IDiaSymbol4_get_thunkOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_thunkOrdinal(This,pRetVal) ) + +#define IDiaSymbol4_get_thisAdjust(This,pRetVal) \ + ( (This)->lpVtbl -> get_thisAdjust(This,pRetVal) ) + +#define IDiaSymbol4_get_virtualBaseOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseOffset(This,pRetVal) ) + +#define IDiaSymbol4_get_virtual(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtual(This,pRetVal) ) + +#define IDiaSymbol4_get_intro(This,pRetVal) \ + ( (This)->lpVtbl -> get_intro(This,pRetVal) ) + +#define IDiaSymbol4_get_pure(This,pRetVal) \ + ( (This)->lpVtbl -> get_pure(This,pRetVal) ) + +#define IDiaSymbol4_get_callingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_callingConvention(This,pRetVal) ) + +#define IDiaSymbol4_get_value(This,pRetVal) \ + ( (This)->lpVtbl -> get_value(This,pRetVal) ) + +#define IDiaSymbol4_get_baseType(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseType(This,pRetVal) ) + +#define IDiaSymbol4_get_token(This,pRetVal) \ + ( (This)->lpVtbl -> get_token(This,pRetVal) ) + +#define IDiaSymbol4_get_timeStamp(This,pRetVal) \ + ( (This)->lpVtbl -> get_timeStamp(This,pRetVal) ) + +#define IDiaSymbol4_get_guid(This,pRetVal) \ + ( (This)->lpVtbl -> get_guid(This,pRetVal) ) + +#define IDiaSymbol4_get_symbolsFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_symbolsFileName(This,pRetVal) ) + +#define IDiaSymbol4_get_reference(This,pRetVal) \ + ( (This)->lpVtbl -> get_reference(This,pRetVal) ) + +#define IDiaSymbol4_get_count(This,pRetVal) \ + ( (This)->lpVtbl -> get_count(This,pRetVal) ) + +#define IDiaSymbol4_get_bitPosition(This,pRetVal) \ + ( (This)->lpVtbl -> get_bitPosition(This,pRetVal) ) + +#define IDiaSymbol4_get_arrayIndexType(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexType(This,pRetVal) ) + +#define IDiaSymbol4_get_packed(This,pRetVal) \ + ( (This)->lpVtbl -> get_packed(This,pRetVal) ) + +#define IDiaSymbol4_get_constructor(This,pRetVal) \ + ( (This)->lpVtbl -> get_constructor(This,pRetVal) ) + +#define IDiaSymbol4_get_overloadedOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_overloadedOperator(This,pRetVal) ) + +#define IDiaSymbol4_get_nested(This,pRetVal) \ + ( (This)->lpVtbl -> get_nested(This,pRetVal) ) + +#define IDiaSymbol4_get_hasNestedTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasNestedTypes(This,pRetVal) ) + +#define IDiaSymbol4_get_hasAssignmentOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAssignmentOperator(This,pRetVal) ) + +#define IDiaSymbol4_get_hasCastOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasCastOperator(This,pRetVal) ) + +#define IDiaSymbol4_get_scoped(This,pRetVal) \ + ( (This)->lpVtbl -> get_scoped(This,pRetVal) ) + +#define IDiaSymbol4_get_virtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol4_get_indirectVirtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_indirectVirtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol4_get_virtualBasePointerOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBasePointerOffset(This,pRetVal) ) + +#define IDiaSymbol4_get_virtualTableShape(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShape(This,pRetVal) ) + +#define IDiaSymbol4_get_lexicalParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParentId(This,pRetVal) ) + +#define IDiaSymbol4_get_classParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParentId(This,pRetVal) ) + +#define IDiaSymbol4_get_typeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_typeId(This,pRetVal) ) + +#define IDiaSymbol4_get_arrayIndexTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexTypeId(This,pRetVal) ) + +#define IDiaSymbol4_get_virtualTableShapeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShapeId(This,pRetVal) ) + +#define IDiaSymbol4_get_code(This,pRetVal) \ + ( (This)->lpVtbl -> get_code(This,pRetVal) ) + +#define IDiaSymbol4_get_function(This,pRetVal) \ + ( (This)->lpVtbl -> get_function(This,pRetVal) ) + +#define IDiaSymbol4_get_managed(This,pRetVal) \ + ( (This)->lpVtbl -> get_managed(This,pRetVal) ) + +#define IDiaSymbol4_get_msil(This,pRetVal) \ + ( (This)->lpVtbl -> get_msil(This,pRetVal) ) + +#define IDiaSymbol4_get_virtualBaseDispIndex(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseDispIndex(This,pRetVal) ) + +#define IDiaSymbol4_get_undecoratedName(This,pRetVal) \ + ( (This)->lpVtbl -> get_undecoratedName(This,pRetVal) ) + +#define IDiaSymbol4_get_age(This,pRetVal) \ + ( (This)->lpVtbl -> get_age(This,pRetVal) ) + +#define IDiaSymbol4_get_signature(This,pRetVal) \ + ( (This)->lpVtbl -> get_signature(This,pRetVal) ) + +#define IDiaSymbol4_get_compilerGenerated(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerGenerated(This,pRetVal) ) + +#define IDiaSymbol4_get_addressTaken(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressTaken(This,pRetVal) ) + +#define IDiaSymbol4_get_rank(This,pRetVal) \ + ( (This)->lpVtbl -> get_rank(This,pRetVal) ) + +#define IDiaSymbol4_get_lowerBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBound(This,pRetVal) ) + +#define IDiaSymbol4_get_upperBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBound(This,pRetVal) ) + +#define IDiaSymbol4_get_lowerBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBoundId(This,pRetVal) ) + +#define IDiaSymbol4_get_upperBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBoundId(This,pRetVal) ) + +#define IDiaSymbol4_get_dataBytes(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_dataBytes(This,cbData,pcbData,pbData) ) + +#define IDiaSymbol4_findChildren(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildren(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol4_findChildrenEx(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildrenEx(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol4_findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) ) + +#define IDiaSymbol4_findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) ) + +#define IDiaSymbol4_findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) ) + +#define IDiaSymbol4_get_targetSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetSection(This,pRetVal) ) + +#define IDiaSymbol4_get_targetOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetOffset(This,pRetVal) ) + +#define IDiaSymbol4_get_targetRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol4_get_targetVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol4_get_machineType(This,pRetVal) \ + ( (This)->lpVtbl -> get_machineType(This,pRetVal) ) + +#define IDiaSymbol4_get_oemId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemId(This,pRetVal) ) + +#define IDiaSymbol4_get_oemSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemSymbolId(This,pRetVal) ) + +#define IDiaSymbol4_get_types(This,cTypes,pcTypes,pTypes) \ + ( (This)->lpVtbl -> get_types(This,cTypes,pcTypes,pTypes) ) + +#define IDiaSymbol4_get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) \ + ( (This)->lpVtbl -> get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) ) + +#define IDiaSymbol4_get_objectPointerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectPointerType(This,pRetVal) ) + +#define IDiaSymbol4_get_udtKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_udtKind(This,pRetVal) ) + +#define IDiaSymbol4_get_undecoratedNameEx(This,undecorateOptions,name) \ + ( (This)->lpVtbl -> get_undecoratedNameEx(This,undecorateOptions,name) ) + +#define IDiaSymbol4_get_noReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_noReturn(This,pRetVal) ) + +#define IDiaSymbol4_get_customCallingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_customCallingConvention(This,pRetVal) ) + +#define IDiaSymbol4_get_noInline(This,pRetVal) \ + ( (This)->lpVtbl -> get_noInline(This,pRetVal) ) + +#define IDiaSymbol4_get_optimizedCodeDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_optimizedCodeDebugInfo(This,pRetVal) ) + +#define IDiaSymbol4_get_notReached(This,pRetVal) \ + ( (This)->lpVtbl -> get_notReached(This,pRetVal) ) + +#define IDiaSymbol4_get_interruptReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_interruptReturn(This,pRetVal) ) + +#define IDiaSymbol4_get_farReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_farReturn(This,pRetVal) ) + +#define IDiaSymbol4_get_isStatic(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStatic(This,pRetVal) ) + +#define IDiaSymbol4_get_hasDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasDebugInfo(This,pRetVal) ) + +#define IDiaSymbol4_get_isLTCG(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLTCG(This,pRetVal) ) + +#define IDiaSymbol4_get_isDataAligned(This,pRetVal) \ + ( (This)->lpVtbl -> get_isDataAligned(This,pRetVal) ) + +#define IDiaSymbol4_get_hasSecurityChecks(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSecurityChecks(This,pRetVal) ) + +#define IDiaSymbol4_get_compilerName(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerName(This,pRetVal) ) + +#define IDiaSymbol4_get_hasAlloca(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAlloca(This,pRetVal) ) + +#define IDiaSymbol4_get_hasSetJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSetJump(This,pRetVal) ) + +#define IDiaSymbol4_get_hasLongJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasLongJump(This,pRetVal) ) + +#define IDiaSymbol4_get_hasInlAsm(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasInlAsm(This,pRetVal) ) + +#define IDiaSymbol4_get_hasEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEH(This,pRetVal) ) + +#define IDiaSymbol4_get_hasSEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSEH(This,pRetVal) ) + +#define IDiaSymbol4_get_hasEHa(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEHa(This,pRetVal) ) + +#define IDiaSymbol4_get_isNaked(This,pRetVal) \ + ( (This)->lpVtbl -> get_isNaked(This,pRetVal) ) + +#define IDiaSymbol4_get_isAggregated(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAggregated(This,pRetVal) ) + +#define IDiaSymbol4_get_isSplitted(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSplitted(This,pRetVal) ) + +#define IDiaSymbol4_get_container(This,pRetVal) \ + ( (This)->lpVtbl -> get_container(This,pRetVal) ) + +#define IDiaSymbol4_get_inlSpec(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlSpec(This,pRetVal) ) + +#define IDiaSymbol4_get_noStackOrdering(This,pRetVal) \ + ( (This)->lpVtbl -> get_noStackOrdering(This,pRetVal) ) + +#define IDiaSymbol4_get_virtualBaseTableType(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseTableType(This,pRetVal) ) + +#define IDiaSymbol4_get_hasManagedCode(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasManagedCode(This,pRetVal) ) + +#define IDiaSymbol4_get_isHotpatchable(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHotpatchable(This,pRetVal) ) + +#define IDiaSymbol4_get_isCVTCIL(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCVTCIL(This,pRetVal) ) + +#define IDiaSymbol4_get_isMSILNetmodule(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMSILNetmodule(This,pRetVal) ) + +#define IDiaSymbol4_get_isCTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCTypes(This,pRetVal) ) + +#define IDiaSymbol4_get_isStripped(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStripped(This,pRetVal) ) + +#define IDiaSymbol4_get_frontEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndQFE(This,pRetVal) ) + +#define IDiaSymbol4_get_backEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndQFE(This,pRetVal) ) + +#define IDiaSymbol4_get_wasInlined(This,pRetVal) \ + ( (This)->lpVtbl -> get_wasInlined(This,pRetVal) ) + +#define IDiaSymbol4_get_strictGSCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_strictGSCheck(This,pRetVal) ) + +#define IDiaSymbol4_get_isCxxReturnUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCxxReturnUdt(This,pRetVal) ) + +#define IDiaSymbol4_get_isConstructorVirtualBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_isConstructorVirtualBase(This,pRetVal) ) + +#define IDiaSymbol4_get_RValueReference(This,pRetVal) \ + ( (This)->lpVtbl -> get_RValueReference(This,pRetVal) ) + +#define IDiaSymbol4_get_unmodifiedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedType(This,pRetVal) ) + +#define IDiaSymbol4_get_framePointerPresent(This,pRetVal) \ + ( (This)->lpVtbl -> get_framePointerPresent(This,pRetVal) ) + +#define IDiaSymbol4_get_isSafeBuffers(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSafeBuffers(This,pRetVal) ) + +#define IDiaSymbol4_get_intrinsic(This,pRetVal) \ + ( (This)->lpVtbl -> get_intrinsic(This,pRetVal) ) + +#define IDiaSymbol4_get_sealed(This,pRetVal) \ + ( (This)->lpVtbl -> get_sealed(This,pRetVal) ) + +#define IDiaSymbol4_get_hfaFloat(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaFloat(This,pRetVal) ) + +#define IDiaSymbol4_get_hfaDouble(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaDouble(This,pRetVal) ) + +#define IDiaSymbol4_get_liveRangeStartAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressSection(This,pRetVal) ) + +#define IDiaSymbol4_get_liveRangeStartAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressOffset(This,pRetVal) ) + +#define IDiaSymbol4_get_liveRangeStartRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol4_get_countLiveRanges(This,pRetVal) \ + ( (This)->lpVtbl -> get_countLiveRanges(This,pRetVal) ) + +#define IDiaSymbol4_get_liveRangeLength(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeLength(This,pRetVal) ) + +#define IDiaSymbol4_get_offsetInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_offsetInUdt(This,pRetVal) ) + +#define IDiaSymbol4_get_paramBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_paramBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol4_get_localBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_localBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol4_get_isLocationControlFlowDependent(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLocationControlFlowDependent(This,pRetVal) ) + +#define IDiaSymbol4_get_stride(This,pRetVal) \ + ( (This)->lpVtbl -> get_stride(This,pRetVal) ) + +#define IDiaSymbol4_get_numberOfRows(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRows(This,pRetVal) ) + +#define IDiaSymbol4_get_numberOfColumns(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfColumns(This,pRetVal) ) + +#define IDiaSymbol4_get_isMatrixRowMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMatrixRowMajor(This,pRetVal) ) + +#define IDiaSymbol4_get_numericProperties(This,cnt,pcnt,pProperties) \ + ( (This)->lpVtbl -> get_numericProperties(This,cnt,pcnt,pProperties) ) + +#define IDiaSymbol4_get_modifierValues(This,cnt,pcnt,pModifiers) \ + ( (This)->lpVtbl -> get_modifierValues(This,cnt,pcnt,pModifiers) ) + +#define IDiaSymbol4_get_isReturnValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isReturnValue(This,pRetVal) ) + +#define IDiaSymbol4_get_isOptimizedAway(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedAway(This,pRetVal) ) + +#define IDiaSymbol4_get_builtInKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_builtInKind(This,pRetVal) ) + +#define IDiaSymbol4_get_registerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerType(This,pRetVal) ) + +#define IDiaSymbol4_get_baseDataSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataSlot(This,pRetVal) ) + +#define IDiaSymbol4_get_baseDataOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataOffset(This,pRetVal) ) + +#define IDiaSymbol4_get_textureSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_textureSlot(This,pRetVal) ) + +#define IDiaSymbol4_get_samplerSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_samplerSlot(This,pRetVal) ) + +#define IDiaSymbol4_get_uavSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_uavSlot(This,pRetVal) ) + +#define IDiaSymbol4_get_sizeInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_sizeInUdt(This,pRetVal) ) + +#define IDiaSymbol4_get_memorySpaceKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_memorySpaceKind(This,pRetVal) ) + +#define IDiaSymbol4_get_unmodifiedTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedTypeId(This,pRetVal) ) + +#define IDiaSymbol4_get_subTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_subTypeId(This,pRetVal) ) + +#define IDiaSymbol4_get_subType(This,pRetVal) \ + ( (This)->lpVtbl -> get_subType(This,pRetVal) ) + +#define IDiaSymbol4_get_numberOfModifiers(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfModifiers(This,pRetVal) ) + +#define IDiaSymbol4_get_numberOfRegisterIndices(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRegisterIndices(This,pRetVal) ) + +#define IDiaSymbol4_get_isHLSLData(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHLSLData(This,pRetVal) ) + +#define IDiaSymbol4_get_isPointerToDataMember(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToDataMember(This,pRetVal) ) + +#define IDiaSymbol4_get_isPointerToMemberFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToMemberFunction(This,pRetVal) ) + +#define IDiaSymbol4_get_isSingleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSingleInheritance(This,pRetVal) ) + +#define IDiaSymbol4_get_isMultipleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMultipleInheritance(This,pRetVal) ) + +#define IDiaSymbol4_get_isVirtualInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isVirtualInheritance(This,pRetVal) ) + +#define IDiaSymbol4_get_restrictedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_restrictedType(This,pRetVal) ) + +#define IDiaSymbol4_get_isPointerBasedOnSymbolValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerBasedOnSymbolValue(This,pRetVal) ) + +#define IDiaSymbol4_get_baseSymbol(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbol(This,pRetVal) ) + +#define IDiaSymbol4_get_baseSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbolId(This,pRetVal) ) + +#define IDiaSymbol4_get_objectFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectFileName(This,pRetVal) ) + +#define IDiaSymbol4_get_isAcceleratorGroupSharedLocal(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorGroupSharedLocal(This,pRetVal) ) + +#define IDiaSymbol4_get_isAcceleratorPointerTagLiveRange(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorPointerTagLiveRange(This,pRetVal) ) + +#define IDiaSymbol4_get_isAcceleratorStubFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorStubFunction(This,pRetVal) ) + +#define IDiaSymbol4_get_numberOfAcceleratorPointerTags(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfAcceleratorPointerTags(This,pRetVal) ) + +#define IDiaSymbol4_get_isSdl(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSdl(This,pRetVal) ) + +#define IDiaSymbol4_get_isWinRTPointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_isWinRTPointer(This,pRetVal) ) + +#define IDiaSymbol4_get_isRefUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isRefUdt(This,pRetVal) ) + +#define IDiaSymbol4_get_isValueUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isValueUdt(This,pRetVal) ) + +#define IDiaSymbol4_get_isInterfaceUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isInterfaceUdt(This,pRetVal) ) + +#define IDiaSymbol4_findInlineFramesByAddr(This,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByAddr(This,isect,offset,ppResult) ) + +#define IDiaSymbol4_findInlineFramesByRVA(This,rva,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByRVA(This,rva,ppResult) ) + +#define IDiaSymbol4_findInlineFramesByVA(This,va,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByVA(This,va,ppResult) ) + +#define IDiaSymbol4_findInlineeLines(This,ppResult) \ + ( (This)->lpVtbl -> findInlineeLines(This,ppResult) ) + +#define IDiaSymbol4_findInlineeLinesByAddr(This,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByAddr(This,isect,offset,length,ppResult) ) + +#define IDiaSymbol4_findInlineeLinesByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByRVA(This,rva,length,ppResult) ) + +#define IDiaSymbol4_findInlineeLinesByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByVA(This,va,length,ppResult) ) + +#define IDiaSymbol4_findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) \ + ( (This)->lpVtbl -> findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) ) + +#define IDiaSymbol4_findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) \ + ( (This)->lpVtbl -> findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) ) + +#define IDiaSymbol4_get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) \ + ( (This)->lpVtbl -> get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) ) + +#define IDiaSymbol4_getSrcLineOnTypeDefn(This,ppResult) \ + ( (This)->lpVtbl -> getSrcLineOnTypeDefn(This,ppResult) ) + +#define IDiaSymbol4_get_isPGO(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPGO(This,pRetVal) ) + +#define IDiaSymbol4_get_hasValidPGOCounts(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasValidPGOCounts(This,pRetVal) ) + +#define IDiaSymbol4_get_isOptimizedForSpeed(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedForSpeed(This,pRetVal) ) + +#define IDiaSymbol4_get_PGOEntryCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEntryCount(This,pRetVal) ) + +#define IDiaSymbol4_get_PGOEdgeCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEdgeCount(This,pRetVal) ) + +#define IDiaSymbol4_get_PGODynamicInstructionCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGODynamicInstructionCount(This,pRetVal) ) + +#define IDiaSymbol4_get_staticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_staticSize(This,pRetVal) ) + +#define IDiaSymbol4_get_finalLiveStaticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_finalLiveStaticSize(This,pRetVal) ) + +#define IDiaSymbol4_get_phaseName(This,pRetVal) \ + ( (This)->lpVtbl -> get_phaseName(This,pRetVal) ) + +#define IDiaSymbol4_get_hasControlFlowCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasControlFlowCheck(This,pRetVal) ) + +#define IDiaSymbol4_get_constantExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_constantExport(This,pRetVal) ) + +#define IDiaSymbol4_get_dataExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataExport(This,pRetVal) ) + +#define IDiaSymbol4_get_privateExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_privateExport(This,pRetVal) ) + +#define IDiaSymbol4_get_noNameExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_noNameExport(This,pRetVal) ) + +#define IDiaSymbol4_get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) ) + +#define IDiaSymbol4_get_exportIsForwarder(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportIsForwarder(This,pRetVal) ) + +#define IDiaSymbol4_get_ordinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_ordinal(This,pRetVal) ) + +#define IDiaSymbol4_get_frameSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_frameSize(This,pRetVal) ) + +#define IDiaSymbol4_get_exceptionHandlerAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressSection(This,pRetVal) ) + +#define IDiaSymbol4_get_exceptionHandlerAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressOffset(This,pRetVal) ) + +#define IDiaSymbol4_get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol4_get_exceptionHandlerVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol4_findInputAssemblyFile(This,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFile(This,ppResult) ) + +#define IDiaSymbol4_get_characteristics(This,pRetVal) \ + ( (This)->lpVtbl -> get_characteristics(This,pRetVal) ) + +#define IDiaSymbol4_get_coffGroup(This,pRetVal) \ + ( (This)->lpVtbl -> get_coffGroup(This,pRetVal) ) + +#define IDiaSymbol4_get_bindID(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindID(This,pRetVal) ) + +#define IDiaSymbol4_get_bindSpace(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSpace(This,pRetVal) ) + +#define IDiaSymbol4_get_bindSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSlot(This,pRetVal) ) + + +#define IDiaSymbol4_get_isObjCClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCClass(This,pRetVal) ) + +#define IDiaSymbol4_get_isObjCCategory(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCCategory(This,pRetVal) ) + +#define IDiaSymbol4_get_isObjCProtocol(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCProtocol(This,pRetVal) ) + + +#define IDiaSymbol4_get_inlinee(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlinee(This,pRetVal) ) + +#define IDiaSymbol4_get_inlineeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlineeId(This,pRetVal) ) + + +#define IDiaSymbol4_get_noexcept(This,pRetVal) \ + ( (This)->lpVtbl -> get_noexcept(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol4_get_noexcept_Proxy( + IDiaSymbol4 * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol4_get_noexcept_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDiaSymbol4_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSymbol5_INTERFACE_DEFINED__ +#define __IDiaSymbol5_INTERFACE_DEFINED__ + +/* interface IDiaSymbol5 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSymbol5; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("abe2de00-dc2d-4793-af9a-ef1d90832644") + IDiaSymbol5 : public IDiaSymbol4 + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasAbsoluteAddress( + /* [retval][out] */ BOOL *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSymbol5Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSymbol5 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSymbol5 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSymbol5 * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symIndexId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symTag )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParent )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParent )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataKind )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_locationType )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSymbol5 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )( + IDiaSymbol5 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSymbol5 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_slot )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_volatileType )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constType )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unalignedType )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_access )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_libraryName )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_platform )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_language )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_editAndContinueEnabled )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMajor )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMinor )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndBuild )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMajor )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMinor )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndBuild )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileName )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unused )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thunkOrdinal )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thisAdjust )( + IDiaSymbol5 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseOffset )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtual )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intro )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pure )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_callingConvention )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_value )( + IDiaSymbol5 * This, + /* [retval][out] */ VARIANT *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseType )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_token )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timeStamp )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_guid )( + IDiaSymbol5 * This, + /* [retval][out] */ GUID *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symbolsFileName )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_reference )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_count )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bitPosition )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexType )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_packed )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constructor )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_overloadedOperator )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_nested )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasNestedTypes )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAssignmentOperator )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasCastOperator )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_scoped )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseClass )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_indirectVirtualBaseClass )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBasePointerOffset )( + IDiaSymbol5 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShape )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParentId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParentId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_typeId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexTypeId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShapeId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_function )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_managed )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_msil )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseDispIndex )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_undecoratedName )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_age )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_signature )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerGenerated )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressTaken )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_rank )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBound )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBound )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBoundId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBoundId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_dataBytes )( + IDiaSymbol5 * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *findChildren )( + IDiaSymbol5 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenEx )( + IDiaSymbol5 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )( + IDiaSymbol5 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )( + IDiaSymbol5 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )( + IDiaSymbol5 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetSection )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetOffset )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetRelativeVirtualAddress )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetVirtualAddress )( + IDiaSymbol5 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_machineType )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemSymbolId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_types )( + IDiaSymbol5 * This, + /* [in] */ DWORD cTypes, + /* [out] */ DWORD *pcTypes, + /* [size_is][size_is][out] */ IDiaSymbol **pTypes); + + HRESULT ( STDMETHODCALLTYPE *get_typeIds )( + IDiaSymbol5 * This, + /* [in] */ DWORD cTypeIds, + /* [out] */ DWORD *pcTypeIds, + /* [size_is][out] */ DWORD *pdwTypeIds); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectPointerType )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_udtKind )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_undecoratedNameEx )( + IDiaSymbol5 * This, + /* [in] */ DWORD undecorateOptions, + /* [out] */ BSTR *name); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noReturn )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_customCallingConvention )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noInline )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_optimizedCodeDebugInfo )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notReached )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_interruptReturn )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_farReturn )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStatic )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasDebugInfo )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLTCG )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isDataAligned )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSecurityChecks )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerName )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAlloca )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSetJump )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasLongJump )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasInlAsm )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEH )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSEH )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEHa )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isNaked )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAggregated )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSplitted )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_container )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlSpec )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noStackOrdering )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseTableType )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasManagedCode )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHotpatchable )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCVTCIL )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMSILNetmodule )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCTypes )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStripped )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndQFE )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndQFE )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_wasInlined )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_strictGSCheck )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCxxReturnUdt )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isConstructorVirtualBase )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RValueReference )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedType )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_framePointerPresent )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSafeBuffers )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intrinsic )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sealed )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaFloat )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaDouble )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressSection )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressOffset )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartRelativeVirtualAddress )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_countLiveRanges )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeLength )( + IDiaSymbol5 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offsetInUdt )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_paramBasePointerRegisterId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localBasePointerRegisterId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLocationControlFlowDependent )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_stride )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRows )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfColumns )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMatrixRowMajor )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_numericProperties )( + IDiaSymbol5 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties); + + HRESULT ( STDMETHODCALLTYPE *get_modifierValues )( + IDiaSymbol5 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isReturnValue )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedAway )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_builtInKind )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerType )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataSlot )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataOffset )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_textureSlot )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_samplerSlot )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uavSlot )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sizeInUdt )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_memorySpaceKind )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedTypeId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subTypeId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subType )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfModifiers )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRegisterIndices )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHLSLData )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToDataMember )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToMemberFunction )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSingleInheritance )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMultipleInheritance )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isVirtualInheritance )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_restrictedType )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerBasedOnSymbolValue )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbol )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbolId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFileName )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorGroupSharedLocal )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorPointerTagLiveRange )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorStubFunction )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfAcceleratorPointerTags )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSdl )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isWinRTPointer )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isRefUdt )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isValueUdt )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isInterfaceUdt )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByAddr )( + IDiaSymbol5 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByRVA )( + IDiaSymbol5 * This, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByVA )( + IDiaSymbol5 * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLines )( + IDiaSymbol5 * This, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByAddr )( + IDiaSymbol5 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByRVA )( + IDiaSymbol5 * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByVA )( + IDiaSymbol5 * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsForAcceleratorPointerTag )( + IDiaSymbol5 * This, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsByRVAForAcceleratorPointerTag )( + IDiaSymbol5 * This, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *get_acceleratorPointerTags )( + IDiaSymbol5 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags); + + HRESULT ( STDMETHODCALLTYPE *getSrcLineOnTypeDefn )( + IDiaSymbol5 * This, + /* [out] */ IDiaLineNumber **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPGO )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasValidPGOCounts )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedForSpeed )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEntryCount )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEdgeCount )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGODynamicInstructionCount )( + IDiaSymbol5 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_staticSize )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_finalLiveStaticSize )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_phaseName )( + IDiaSymbol5 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasControlFlowCheck )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constantExport )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataExport )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_privateExport )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noNameExport )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportHasExplicitlyAssignedOrdinal )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportIsForwarder )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ordinal )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frameSize )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressSection )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressOffset )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerRelativeVirtualAddress )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerVirtualAddress )( + IDiaSymbol5 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFile )( + IDiaSymbol5 * This, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_characteristics )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_coffGroup )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindID )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSpace )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSlot )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCClass )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCCategory )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCProtocol )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlinee )( + IDiaSymbol5 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlineeId )( + IDiaSymbol5 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noexcept )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAbsoluteAddress )( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + END_INTERFACE + } IDiaSymbol5Vtbl; + + interface IDiaSymbol5 + { + CONST_VTBL struct IDiaSymbol5Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSymbol5_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSymbol5_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSymbol5_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSymbol5_get_symIndexId(This,pRetVal) \ + ( (This)->lpVtbl -> get_symIndexId(This,pRetVal) ) + +#define IDiaSymbol5_get_symTag(This,pRetVal) \ + ( (This)->lpVtbl -> get_symTag(This,pRetVal) ) + +#define IDiaSymbol5_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaSymbol5_get_lexicalParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParent(This,pRetVal) ) + +#define IDiaSymbol5_get_classParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParent(This,pRetVal) ) + +#define IDiaSymbol5_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaSymbol5_get_dataKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataKind(This,pRetVal) ) + +#define IDiaSymbol5_get_locationType(This,pRetVal) \ + ( (This)->lpVtbl -> get_locationType(This,pRetVal) ) + +#define IDiaSymbol5_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSymbol5_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaSymbol5_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol5_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaSymbol5_get_registerId(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerId(This,pRetVal) ) + +#define IDiaSymbol5_get_offset(This,pRetVal) \ + ( (This)->lpVtbl -> get_offset(This,pRetVal) ) + +#define IDiaSymbol5_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSymbol5_get_slot(This,pRetVal) \ + ( (This)->lpVtbl -> get_slot(This,pRetVal) ) + +#define IDiaSymbol5_get_volatileType(This,pRetVal) \ + ( (This)->lpVtbl -> get_volatileType(This,pRetVal) ) + +#define IDiaSymbol5_get_constType(This,pRetVal) \ + ( (This)->lpVtbl -> get_constType(This,pRetVal) ) + +#define IDiaSymbol5_get_unalignedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unalignedType(This,pRetVal) ) + +#define IDiaSymbol5_get_access(This,pRetVal) \ + ( (This)->lpVtbl -> get_access(This,pRetVal) ) + +#define IDiaSymbol5_get_libraryName(This,pRetVal) \ + ( (This)->lpVtbl -> get_libraryName(This,pRetVal) ) + +#define IDiaSymbol5_get_platform(This,pRetVal) \ + ( (This)->lpVtbl -> get_platform(This,pRetVal) ) + +#define IDiaSymbol5_get_language(This,pRetVal) \ + ( (This)->lpVtbl -> get_language(This,pRetVal) ) + +#define IDiaSymbol5_get_editAndContinueEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_editAndContinueEnabled(This,pRetVal) ) + +#define IDiaSymbol5_get_frontEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMajor(This,pRetVal) ) + +#define IDiaSymbol5_get_frontEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMinor(This,pRetVal) ) + +#define IDiaSymbol5_get_frontEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndBuild(This,pRetVal) ) + +#define IDiaSymbol5_get_backEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMajor(This,pRetVal) ) + +#define IDiaSymbol5_get_backEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMinor(This,pRetVal) ) + +#define IDiaSymbol5_get_backEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndBuild(This,pRetVal) ) + +#define IDiaSymbol5_get_sourceFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFileName(This,pRetVal) ) + +#define IDiaSymbol5_get_unused(This,pRetVal) \ + ( (This)->lpVtbl -> get_unused(This,pRetVal) ) + +#define IDiaSymbol5_get_thunkOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_thunkOrdinal(This,pRetVal) ) + +#define IDiaSymbol5_get_thisAdjust(This,pRetVal) \ + ( (This)->lpVtbl -> get_thisAdjust(This,pRetVal) ) + +#define IDiaSymbol5_get_virtualBaseOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseOffset(This,pRetVal) ) + +#define IDiaSymbol5_get_virtual(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtual(This,pRetVal) ) + +#define IDiaSymbol5_get_intro(This,pRetVal) \ + ( (This)->lpVtbl -> get_intro(This,pRetVal) ) + +#define IDiaSymbol5_get_pure(This,pRetVal) \ + ( (This)->lpVtbl -> get_pure(This,pRetVal) ) + +#define IDiaSymbol5_get_callingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_callingConvention(This,pRetVal) ) + +#define IDiaSymbol5_get_value(This,pRetVal) \ + ( (This)->lpVtbl -> get_value(This,pRetVal) ) + +#define IDiaSymbol5_get_baseType(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseType(This,pRetVal) ) + +#define IDiaSymbol5_get_token(This,pRetVal) \ + ( (This)->lpVtbl -> get_token(This,pRetVal) ) + +#define IDiaSymbol5_get_timeStamp(This,pRetVal) \ + ( (This)->lpVtbl -> get_timeStamp(This,pRetVal) ) + +#define IDiaSymbol5_get_guid(This,pRetVal) \ + ( (This)->lpVtbl -> get_guid(This,pRetVal) ) + +#define IDiaSymbol5_get_symbolsFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_symbolsFileName(This,pRetVal) ) + +#define IDiaSymbol5_get_reference(This,pRetVal) \ + ( (This)->lpVtbl -> get_reference(This,pRetVal) ) + +#define IDiaSymbol5_get_count(This,pRetVal) \ + ( (This)->lpVtbl -> get_count(This,pRetVal) ) + +#define IDiaSymbol5_get_bitPosition(This,pRetVal) \ + ( (This)->lpVtbl -> get_bitPosition(This,pRetVal) ) + +#define IDiaSymbol5_get_arrayIndexType(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexType(This,pRetVal) ) + +#define IDiaSymbol5_get_packed(This,pRetVal) \ + ( (This)->lpVtbl -> get_packed(This,pRetVal) ) + +#define IDiaSymbol5_get_constructor(This,pRetVal) \ + ( (This)->lpVtbl -> get_constructor(This,pRetVal) ) + +#define IDiaSymbol5_get_overloadedOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_overloadedOperator(This,pRetVal) ) + +#define IDiaSymbol5_get_nested(This,pRetVal) \ + ( (This)->lpVtbl -> get_nested(This,pRetVal) ) + +#define IDiaSymbol5_get_hasNestedTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasNestedTypes(This,pRetVal) ) + +#define IDiaSymbol5_get_hasAssignmentOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAssignmentOperator(This,pRetVal) ) + +#define IDiaSymbol5_get_hasCastOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasCastOperator(This,pRetVal) ) + +#define IDiaSymbol5_get_scoped(This,pRetVal) \ + ( (This)->lpVtbl -> get_scoped(This,pRetVal) ) + +#define IDiaSymbol5_get_virtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol5_get_indirectVirtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_indirectVirtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol5_get_virtualBasePointerOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBasePointerOffset(This,pRetVal) ) + +#define IDiaSymbol5_get_virtualTableShape(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShape(This,pRetVal) ) + +#define IDiaSymbol5_get_lexicalParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParentId(This,pRetVal) ) + +#define IDiaSymbol5_get_classParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParentId(This,pRetVal) ) + +#define IDiaSymbol5_get_typeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_typeId(This,pRetVal) ) + +#define IDiaSymbol5_get_arrayIndexTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexTypeId(This,pRetVal) ) + +#define IDiaSymbol5_get_virtualTableShapeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShapeId(This,pRetVal) ) + +#define IDiaSymbol5_get_code(This,pRetVal) \ + ( (This)->lpVtbl -> get_code(This,pRetVal) ) + +#define IDiaSymbol5_get_function(This,pRetVal) \ + ( (This)->lpVtbl -> get_function(This,pRetVal) ) + +#define IDiaSymbol5_get_managed(This,pRetVal) \ + ( (This)->lpVtbl -> get_managed(This,pRetVal) ) + +#define IDiaSymbol5_get_msil(This,pRetVal) \ + ( (This)->lpVtbl -> get_msil(This,pRetVal) ) + +#define IDiaSymbol5_get_virtualBaseDispIndex(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseDispIndex(This,pRetVal) ) + +#define IDiaSymbol5_get_undecoratedName(This,pRetVal) \ + ( (This)->lpVtbl -> get_undecoratedName(This,pRetVal) ) + +#define IDiaSymbol5_get_age(This,pRetVal) \ + ( (This)->lpVtbl -> get_age(This,pRetVal) ) + +#define IDiaSymbol5_get_signature(This,pRetVal) \ + ( (This)->lpVtbl -> get_signature(This,pRetVal) ) + +#define IDiaSymbol5_get_compilerGenerated(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerGenerated(This,pRetVal) ) + +#define IDiaSymbol5_get_addressTaken(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressTaken(This,pRetVal) ) + +#define IDiaSymbol5_get_rank(This,pRetVal) \ + ( (This)->lpVtbl -> get_rank(This,pRetVal) ) + +#define IDiaSymbol5_get_lowerBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBound(This,pRetVal) ) + +#define IDiaSymbol5_get_upperBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBound(This,pRetVal) ) + +#define IDiaSymbol5_get_lowerBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBoundId(This,pRetVal) ) + +#define IDiaSymbol5_get_upperBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBoundId(This,pRetVal) ) + +#define IDiaSymbol5_get_dataBytes(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_dataBytes(This,cbData,pcbData,pbData) ) + +#define IDiaSymbol5_findChildren(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildren(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol5_findChildrenEx(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildrenEx(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol5_findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) ) + +#define IDiaSymbol5_findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) ) + +#define IDiaSymbol5_findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) ) + +#define IDiaSymbol5_get_targetSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetSection(This,pRetVal) ) + +#define IDiaSymbol5_get_targetOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetOffset(This,pRetVal) ) + +#define IDiaSymbol5_get_targetRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol5_get_targetVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol5_get_machineType(This,pRetVal) \ + ( (This)->lpVtbl -> get_machineType(This,pRetVal) ) + +#define IDiaSymbol5_get_oemId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemId(This,pRetVal) ) + +#define IDiaSymbol5_get_oemSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemSymbolId(This,pRetVal) ) + +#define IDiaSymbol5_get_types(This,cTypes,pcTypes,pTypes) \ + ( (This)->lpVtbl -> get_types(This,cTypes,pcTypes,pTypes) ) + +#define IDiaSymbol5_get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) \ + ( (This)->lpVtbl -> get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) ) + +#define IDiaSymbol5_get_objectPointerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectPointerType(This,pRetVal) ) + +#define IDiaSymbol5_get_udtKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_udtKind(This,pRetVal) ) + +#define IDiaSymbol5_get_undecoratedNameEx(This,undecorateOptions,name) \ + ( (This)->lpVtbl -> get_undecoratedNameEx(This,undecorateOptions,name) ) + +#define IDiaSymbol5_get_noReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_noReturn(This,pRetVal) ) + +#define IDiaSymbol5_get_customCallingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_customCallingConvention(This,pRetVal) ) + +#define IDiaSymbol5_get_noInline(This,pRetVal) \ + ( (This)->lpVtbl -> get_noInline(This,pRetVal) ) + +#define IDiaSymbol5_get_optimizedCodeDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_optimizedCodeDebugInfo(This,pRetVal) ) + +#define IDiaSymbol5_get_notReached(This,pRetVal) \ + ( (This)->lpVtbl -> get_notReached(This,pRetVal) ) + +#define IDiaSymbol5_get_interruptReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_interruptReturn(This,pRetVal) ) + +#define IDiaSymbol5_get_farReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_farReturn(This,pRetVal) ) + +#define IDiaSymbol5_get_isStatic(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStatic(This,pRetVal) ) + +#define IDiaSymbol5_get_hasDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasDebugInfo(This,pRetVal) ) + +#define IDiaSymbol5_get_isLTCG(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLTCG(This,pRetVal) ) + +#define IDiaSymbol5_get_isDataAligned(This,pRetVal) \ + ( (This)->lpVtbl -> get_isDataAligned(This,pRetVal) ) + +#define IDiaSymbol5_get_hasSecurityChecks(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSecurityChecks(This,pRetVal) ) + +#define IDiaSymbol5_get_compilerName(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerName(This,pRetVal) ) + +#define IDiaSymbol5_get_hasAlloca(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAlloca(This,pRetVal) ) + +#define IDiaSymbol5_get_hasSetJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSetJump(This,pRetVal) ) + +#define IDiaSymbol5_get_hasLongJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasLongJump(This,pRetVal) ) + +#define IDiaSymbol5_get_hasInlAsm(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasInlAsm(This,pRetVal) ) + +#define IDiaSymbol5_get_hasEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEH(This,pRetVal) ) + +#define IDiaSymbol5_get_hasSEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSEH(This,pRetVal) ) + +#define IDiaSymbol5_get_hasEHa(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEHa(This,pRetVal) ) + +#define IDiaSymbol5_get_isNaked(This,pRetVal) \ + ( (This)->lpVtbl -> get_isNaked(This,pRetVal) ) + +#define IDiaSymbol5_get_isAggregated(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAggregated(This,pRetVal) ) + +#define IDiaSymbol5_get_isSplitted(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSplitted(This,pRetVal) ) + +#define IDiaSymbol5_get_container(This,pRetVal) \ + ( (This)->lpVtbl -> get_container(This,pRetVal) ) + +#define IDiaSymbol5_get_inlSpec(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlSpec(This,pRetVal) ) + +#define IDiaSymbol5_get_noStackOrdering(This,pRetVal) \ + ( (This)->lpVtbl -> get_noStackOrdering(This,pRetVal) ) + +#define IDiaSymbol5_get_virtualBaseTableType(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseTableType(This,pRetVal) ) + +#define IDiaSymbol5_get_hasManagedCode(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasManagedCode(This,pRetVal) ) + +#define IDiaSymbol5_get_isHotpatchable(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHotpatchable(This,pRetVal) ) + +#define IDiaSymbol5_get_isCVTCIL(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCVTCIL(This,pRetVal) ) + +#define IDiaSymbol5_get_isMSILNetmodule(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMSILNetmodule(This,pRetVal) ) + +#define IDiaSymbol5_get_isCTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCTypes(This,pRetVal) ) + +#define IDiaSymbol5_get_isStripped(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStripped(This,pRetVal) ) + +#define IDiaSymbol5_get_frontEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndQFE(This,pRetVal) ) + +#define IDiaSymbol5_get_backEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndQFE(This,pRetVal) ) + +#define IDiaSymbol5_get_wasInlined(This,pRetVal) \ + ( (This)->lpVtbl -> get_wasInlined(This,pRetVal) ) + +#define IDiaSymbol5_get_strictGSCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_strictGSCheck(This,pRetVal) ) + +#define IDiaSymbol5_get_isCxxReturnUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCxxReturnUdt(This,pRetVal) ) + +#define IDiaSymbol5_get_isConstructorVirtualBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_isConstructorVirtualBase(This,pRetVal) ) + +#define IDiaSymbol5_get_RValueReference(This,pRetVal) \ + ( (This)->lpVtbl -> get_RValueReference(This,pRetVal) ) + +#define IDiaSymbol5_get_unmodifiedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedType(This,pRetVal) ) + +#define IDiaSymbol5_get_framePointerPresent(This,pRetVal) \ + ( (This)->lpVtbl -> get_framePointerPresent(This,pRetVal) ) + +#define IDiaSymbol5_get_isSafeBuffers(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSafeBuffers(This,pRetVal) ) + +#define IDiaSymbol5_get_intrinsic(This,pRetVal) \ + ( (This)->lpVtbl -> get_intrinsic(This,pRetVal) ) + +#define IDiaSymbol5_get_sealed(This,pRetVal) \ + ( (This)->lpVtbl -> get_sealed(This,pRetVal) ) + +#define IDiaSymbol5_get_hfaFloat(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaFloat(This,pRetVal) ) + +#define IDiaSymbol5_get_hfaDouble(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaDouble(This,pRetVal) ) + +#define IDiaSymbol5_get_liveRangeStartAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressSection(This,pRetVal) ) + +#define IDiaSymbol5_get_liveRangeStartAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressOffset(This,pRetVal) ) + +#define IDiaSymbol5_get_liveRangeStartRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol5_get_countLiveRanges(This,pRetVal) \ + ( (This)->lpVtbl -> get_countLiveRanges(This,pRetVal) ) + +#define IDiaSymbol5_get_liveRangeLength(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeLength(This,pRetVal) ) + +#define IDiaSymbol5_get_offsetInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_offsetInUdt(This,pRetVal) ) + +#define IDiaSymbol5_get_paramBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_paramBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol5_get_localBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_localBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol5_get_isLocationControlFlowDependent(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLocationControlFlowDependent(This,pRetVal) ) + +#define IDiaSymbol5_get_stride(This,pRetVal) \ + ( (This)->lpVtbl -> get_stride(This,pRetVal) ) + +#define IDiaSymbol5_get_numberOfRows(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRows(This,pRetVal) ) + +#define IDiaSymbol5_get_numberOfColumns(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfColumns(This,pRetVal) ) + +#define IDiaSymbol5_get_isMatrixRowMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMatrixRowMajor(This,pRetVal) ) + +#define IDiaSymbol5_get_numericProperties(This,cnt,pcnt,pProperties) \ + ( (This)->lpVtbl -> get_numericProperties(This,cnt,pcnt,pProperties) ) + +#define IDiaSymbol5_get_modifierValues(This,cnt,pcnt,pModifiers) \ + ( (This)->lpVtbl -> get_modifierValues(This,cnt,pcnt,pModifiers) ) + +#define IDiaSymbol5_get_isReturnValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isReturnValue(This,pRetVal) ) + +#define IDiaSymbol5_get_isOptimizedAway(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedAway(This,pRetVal) ) + +#define IDiaSymbol5_get_builtInKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_builtInKind(This,pRetVal) ) + +#define IDiaSymbol5_get_registerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerType(This,pRetVal) ) + +#define IDiaSymbol5_get_baseDataSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataSlot(This,pRetVal) ) + +#define IDiaSymbol5_get_baseDataOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataOffset(This,pRetVal) ) + +#define IDiaSymbol5_get_textureSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_textureSlot(This,pRetVal) ) + +#define IDiaSymbol5_get_samplerSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_samplerSlot(This,pRetVal) ) + +#define IDiaSymbol5_get_uavSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_uavSlot(This,pRetVal) ) + +#define IDiaSymbol5_get_sizeInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_sizeInUdt(This,pRetVal) ) + +#define IDiaSymbol5_get_memorySpaceKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_memorySpaceKind(This,pRetVal) ) + +#define IDiaSymbol5_get_unmodifiedTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedTypeId(This,pRetVal) ) + +#define IDiaSymbol5_get_subTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_subTypeId(This,pRetVal) ) + +#define IDiaSymbol5_get_subType(This,pRetVal) \ + ( (This)->lpVtbl -> get_subType(This,pRetVal) ) + +#define IDiaSymbol5_get_numberOfModifiers(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfModifiers(This,pRetVal) ) + +#define IDiaSymbol5_get_numberOfRegisterIndices(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRegisterIndices(This,pRetVal) ) + +#define IDiaSymbol5_get_isHLSLData(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHLSLData(This,pRetVal) ) + +#define IDiaSymbol5_get_isPointerToDataMember(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToDataMember(This,pRetVal) ) + +#define IDiaSymbol5_get_isPointerToMemberFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToMemberFunction(This,pRetVal) ) + +#define IDiaSymbol5_get_isSingleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSingleInheritance(This,pRetVal) ) + +#define IDiaSymbol5_get_isMultipleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMultipleInheritance(This,pRetVal) ) + +#define IDiaSymbol5_get_isVirtualInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isVirtualInheritance(This,pRetVal) ) + +#define IDiaSymbol5_get_restrictedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_restrictedType(This,pRetVal) ) + +#define IDiaSymbol5_get_isPointerBasedOnSymbolValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerBasedOnSymbolValue(This,pRetVal) ) + +#define IDiaSymbol5_get_baseSymbol(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbol(This,pRetVal) ) + +#define IDiaSymbol5_get_baseSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbolId(This,pRetVal) ) + +#define IDiaSymbol5_get_objectFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectFileName(This,pRetVal) ) + +#define IDiaSymbol5_get_isAcceleratorGroupSharedLocal(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorGroupSharedLocal(This,pRetVal) ) + +#define IDiaSymbol5_get_isAcceleratorPointerTagLiveRange(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorPointerTagLiveRange(This,pRetVal) ) + +#define IDiaSymbol5_get_isAcceleratorStubFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorStubFunction(This,pRetVal) ) + +#define IDiaSymbol5_get_numberOfAcceleratorPointerTags(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfAcceleratorPointerTags(This,pRetVal) ) + +#define IDiaSymbol5_get_isSdl(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSdl(This,pRetVal) ) + +#define IDiaSymbol5_get_isWinRTPointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_isWinRTPointer(This,pRetVal) ) + +#define IDiaSymbol5_get_isRefUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isRefUdt(This,pRetVal) ) + +#define IDiaSymbol5_get_isValueUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isValueUdt(This,pRetVal) ) + +#define IDiaSymbol5_get_isInterfaceUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isInterfaceUdt(This,pRetVal) ) + +#define IDiaSymbol5_findInlineFramesByAddr(This,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByAddr(This,isect,offset,ppResult) ) + +#define IDiaSymbol5_findInlineFramesByRVA(This,rva,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByRVA(This,rva,ppResult) ) + +#define IDiaSymbol5_findInlineFramesByVA(This,va,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByVA(This,va,ppResult) ) + +#define IDiaSymbol5_findInlineeLines(This,ppResult) \ + ( (This)->lpVtbl -> findInlineeLines(This,ppResult) ) + +#define IDiaSymbol5_findInlineeLinesByAddr(This,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByAddr(This,isect,offset,length,ppResult) ) + +#define IDiaSymbol5_findInlineeLinesByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByRVA(This,rva,length,ppResult) ) + +#define IDiaSymbol5_findInlineeLinesByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByVA(This,va,length,ppResult) ) + +#define IDiaSymbol5_findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) \ + ( (This)->lpVtbl -> findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) ) + +#define IDiaSymbol5_findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) \ + ( (This)->lpVtbl -> findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) ) + +#define IDiaSymbol5_get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) \ + ( (This)->lpVtbl -> get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) ) + +#define IDiaSymbol5_getSrcLineOnTypeDefn(This,ppResult) \ + ( (This)->lpVtbl -> getSrcLineOnTypeDefn(This,ppResult) ) + +#define IDiaSymbol5_get_isPGO(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPGO(This,pRetVal) ) + +#define IDiaSymbol5_get_hasValidPGOCounts(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasValidPGOCounts(This,pRetVal) ) + +#define IDiaSymbol5_get_isOptimizedForSpeed(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedForSpeed(This,pRetVal) ) + +#define IDiaSymbol5_get_PGOEntryCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEntryCount(This,pRetVal) ) + +#define IDiaSymbol5_get_PGOEdgeCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEdgeCount(This,pRetVal) ) + +#define IDiaSymbol5_get_PGODynamicInstructionCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGODynamicInstructionCount(This,pRetVal) ) + +#define IDiaSymbol5_get_staticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_staticSize(This,pRetVal) ) + +#define IDiaSymbol5_get_finalLiveStaticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_finalLiveStaticSize(This,pRetVal) ) + +#define IDiaSymbol5_get_phaseName(This,pRetVal) \ + ( (This)->lpVtbl -> get_phaseName(This,pRetVal) ) + +#define IDiaSymbol5_get_hasControlFlowCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasControlFlowCheck(This,pRetVal) ) + +#define IDiaSymbol5_get_constantExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_constantExport(This,pRetVal) ) + +#define IDiaSymbol5_get_dataExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataExport(This,pRetVal) ) + +#define IDiaSymbol5_get_privateExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_privateExport(This,pRetVal) ) + +#define IDiaSymbol5_get_noNameExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_noNameExport(This,pRetVal) ) + +#define IDiaSymbol5_get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) ) + +#define IDiaSymbol5_get_exportIsForwarder(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportIsForwarder(This,pRetVal) ) + +#define IDiaSymbol5_get_ordinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_ordinal(This,pRetVal) ) + +#define IDiaSymbol5_get_frameSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_frameSize(This,pRetVal) ) + +#define IDiaSymbol5_get_exceptionHandlerAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressSection(This,pRetVal) ) + +#define IDiaSymbol5_get_exceptionHandlerAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressOffset(This,pRetVal) ) + +#define IDiaSymbol5_get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol5_get_exceptionHandlerVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol5_findInputAssemblyFile(This,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFile(This,ppResult) ) + +#define IDiaSymbol5_get_characteristics(This,pRetVal) \ + ( (This)->lpVtbl -> get_characteristics(This,pRetVal) ) + +#define IDiaSymbol5_get_coffGroup(This,pRetVal) \ + ( (This)->lpVtbl -> get_coffGroup(This,pRetVal) ) + +#define IDiaSymbol5_get_bindID(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindID(This,pRetVal) ) + +#define IDiaSymbol5_get_bindSpace(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSpace(This,pRetVal) ) + +#define IDiaSymbol5_get_bindSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSlot(This,pRetVal) ) + + +#define IDiaSymbol5_get_isObjCClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCClass(This,pRetVal) ) + +#define IDiaSymbol5_get_isObjCCategory(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCCategory(This,pRetVal) ) + +#define IDiaSymbol5_get_isObjCProtocol(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCProtocol(This,pRetVal) ) + + +#define IDiaSymbol5_get_inlinee(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlinee(This,pRetVal) ) + +#define IDiaSymbol5_get_inlineeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlineeId(This,pRetVal) ) + + +#define IDiaSymbol5_get_noexcept(This,pRetVal) \ + ( (This)->lpVtbl -> get_noexcept(This,pRetVal) ) + + +#define IDiaSymbol5_get_hasAbsoluteAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAbsoluteAddress(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol5_get_hasAbsoluteAddress_Proxy( + IDiaSymbol5 * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol5_get_hasAbsoluteAddress_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDiaSymbol5_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSymbol6_INTERFACE_DEFINED__ +#define __IDiaSymbol6_INTERFACE_DEFINED__ + +/* interface IDiaSymbol6 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSymbol6; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8133dad3-75fe-4234-ac7e-f8e7a1d3cbb3") + IDiaSymbol6 : public IDiaSymbol5 + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isStaticMemberFunc( + /* [retval][out] */ BOOL *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSymbol6Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSymbol6 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSymbol6 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSymbol6 * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symIndexId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symTag )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParent )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParent )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataKind )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_locationType )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSymbol6 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )( + IDiaSymbol6 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSymbol6 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_slot )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_volatileType )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constType )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unalignedType )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_access )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_libraryName )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_platform )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_language )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_editAndContinueEnabled )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMajor )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMinor )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndBuild )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMajor )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMinor )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndBuild )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileName )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unused )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thunkOrdinal )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thisAdjust )( + IDiaSymbol6 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseOffset )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtual )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intro )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pure )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_callingConvention )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_value )( + IDiaSymbol6 * This, + /* [retval][out] */ VARIANT *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseType )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_token )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timeStamp )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_guid )( + IDiaSymbol6 * This, + /* [retval][out] */ GUID *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symbolsFileName )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_reference )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_count )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bitPosition )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexType )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_packed )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constructor )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_overloadedOperator )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_nested )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasNestedTypes )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAssignmentOperator )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasCastOperator )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_scoped )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseClass )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_indirectVirtualBaseClass )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBasePointerOffset )( + IDiaSymbol6 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShape )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParentId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParentId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_typeId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexTypeId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShapeId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_function )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_managed )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_msil )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseDispIndex )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_undecoratedName )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_age )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_signature )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerGenerated )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressTaken )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_rank )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBound )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBound )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBoundId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBoundId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_dataBytes )( + IDiaSymbol6 * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *findChildren )( + IDiaSymbol6 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenEx )( + IDiaSymbol6 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )( + IDiaSymbol6 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )( + IDiaSymbol6 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )( + IDiaSymbol6 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetSection )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetOffset )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetRelativeVirtualAddress )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetVirtualAddress )( + IDiaSymbol6 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_machineType )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemSymbolId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_types )( + IDiaSymbol6 * This, + /* [in] */ DWORD cTypes, + /* [out] */ DWORD *pcTypes, + /* [size_is][size_is][out] */ IDiaSymbol **pTypes); + + HRESULT ( STDMETHODCALLTYPE *get_typeIds )( + IDiaSymbol6 * This, + /* [in] */ DWORD cTypeIds, + /* [out] */ DWORD *pcTypeIds, + /* [size_is][out] */ DWORD *pdwTypeIds); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectPointerType )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_udtKind )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_undecoratedNameEx )( + IDiaSymbol6 * This, + /* [in] */ DWORD undecorateOptions, + /* [out] */ BSTR *name); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noReturn )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_customCallingConvention )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noInline )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_optimizedCodeDebugInfo )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notReached )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_interruptReturn )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_farReturn )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStatic )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasDebugInfo )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLTCG )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isDataAligned )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSecurityChecks )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerName )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAlloca )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSetJump )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasLongJump )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasInlAsm )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEH )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSEH )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEHa )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isNaked )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAggregated )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSplitted )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_container )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlSpec )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noStackOrdering )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseTableType )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasManagedCode )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHotpatchable )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCVTCIL )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMSILNetmodule )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCTypes )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStripped )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndQFE )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndQFE )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_wasInlined )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_strictGSCheck )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCxxReturnUdt )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isConstructorVirtualBase )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RValueReference )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedType )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_framePointerPresent )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSafeBuffers )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intrinsic )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sealed )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaFloat )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaDouble )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressSection )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressOffset )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartRelativeVirtualAddress )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_countLiveRanges )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeLength )( + IDiaSymbol6 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offsetInUdt )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_paramBasePointerRegisterId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localBasePointerRegisterId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLocationControlFlowDependent )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_stride )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRows )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfColumns )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMatrixRowMajor )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_numericProperties )( + IDiaSymbol6 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties); + + HRESULT ( STDMETHODCALLTYPE *get_modifierValues )( + IDiaSymbol6 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isReturnValue )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedAway )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_builtInKind )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerType )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataSlot )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataOffset )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_textureSlot )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_samplerSlot )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uavSlot )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sizeInUdt )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_memorySpaceKind )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedTypeId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subTypeId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subType )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfModifiers )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRegisterIndices )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHLSLData )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToDataMember )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToMemberFunction )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSingleInheritance )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMultipleInheritance )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isVirtualInheritance )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_restrictedType )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerBasedOnSymbolValue )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbol )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbolId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFileName )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorGroupSharedLocal )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorPointerTagLiveRange )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorStubFunction )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfAcceleratorPointerTags )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSdl )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isWinRTPointer )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isRefUdt )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isValueUdt )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isInterfaceUdt )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByAddr )( + IDiaSymbol6 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByRVA )( + IDiaSymbol6 * This, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByVA )( + IDiaSymbol6 * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLines )( + IDiaSymbol6 * This, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByAddr )( + IDiaSymbol6 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByRVA )( + IDiaSymbol6 * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByVA )( + IDiaSymbol6 * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsForAcceleratorPointerTag )( + IDiaSymbol6 * This, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsByRVAForAcceleratorPointerTag )( + IDiaSymbol6 * This, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *get_acceleratorPointerTags )( + IDiaSymbol6 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags); + + HRESULT ( STDMETHODCALLTYPE *getSrcLineOnTypeDefn )( + IDiaSymbol6 * This, + /* [out] */ IDiaLineNumber **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPGO )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasValidPGOCounts )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedForSpeed )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEntryCount )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEdgeCount )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGODynamicInstructionCount )( + IDiaSymbol6 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_staticSize )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_finalLiveStaticSize )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_phaseName )( + IDiaSymbol6 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasControlFlowCheck )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constantExport )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataExport )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_privateExport )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noNameExport )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportHasExplicitlyAssignedOrdinal )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportIsForwarder )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ordinal )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frameSize )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressSection )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressOffset )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerRelativeVirtualAddress )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerVirtualAddress )( + IDiaSymbol6 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFile )( + IDiaSymbol6 * This, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_characteristics )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_coffGroup )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindID )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSpace )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSlot )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCClass )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCCategory )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCProtocol )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlinee )( + IDiaSymbol6 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlineeId )( + IDiaSymbol6 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noexcept )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAbsoluteAddress )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStaticMemberFunc )( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + END_INTERFACE + } IDiaSymbol6Vtbl; + + interface IDiaSymbol6 + { + CONST_VTBL struct IDiaSymbol6Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSymbol6_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSymbol6_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSymbol6_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSymbol6_get_symIndexId(This,pRetVal) \ + ( (This)->lpVtbl -> get_symIndexId(This,pRetVal) ) + +#define IDiaSymbol6_get_symTag(This,pRetVal) \ + ( (This)->lpVtbl -> get_symTag(This,pRetVal) ) + +#define IDiaSymbol6_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaSymbol6_get_lexicalParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParent(This,pRetVal) ) + +#define IDiaSymbol6_get_classParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParent(This,pRetVal) ) + +#define IDiaSymbol6_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaSymbol6_get_dataKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataKind(This,pRetVal) ) + +#define IDiaSymbol6_get_locationType(This,pRetVal) \ + ( (This)->lpVtbl -> get_locationType(This,pRetVal) ) + +#define IDiaSymbol6_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSymbol6_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaSymbol6_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol6_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaSymbol6_get_registerId(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerId(This,pRetVal) ) + +#define IDiaSymbol6_get_offset(This,pRetVal) \ + ( (This)->lpVtbl -> get_offset(This,pRetVal) ) + +#define IDiaSymbol6_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSymbol6_get_slot(This,pRetVal) \ + ( (This)->lpVtbl -> get_slot(This,pRetVal) ) + +#define IDiaSymbol6_get_volatileType(This,pRetVal) \ + ( (This)->lpVtbl -> get_volatileType(This,pRetVal) ) + +#define IDiaSymbol6_get_constType(This,pRetVal) \ + ( (This)->lpVtbl -> get_constType(This,pRetVal) ) + +#define IDiaSymbol6_get_unalignedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unalignedType(This,pRetVal) ) + +#define IDiaSymbol6_get_access(This,pRetVal) \ + ( (This)->lpVtbl -> get_access(This,pRetVal) ) + +#define IDiaSymbol6_get_libraryName(This,pRetVal) \ + ( (This)->lpVtbl -> get_libraryName(This,pRetVal) ) + +#define IDiaSymbol6_get_platform(This,pRetVal) \ + ( (This)->lpVtbl -> get_platform(This,pRetVal) ) + +#define IDiaSymbol6_get_language(This,pRetVal) \ + ( (This)->lpVtbl -> get_language(This,pRetVal) ) + +#define IDiaSymbol6_get_editAndContinueEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_editAndContinueEnabled(This,pRetVal) ) + +#define IDiaSymbol6_get_frontEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMajor(This,pRetVal) ) + +#define IDiaSymbol6_get_frontEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMinor(This,pRetVal) ) + +#define IDiaSymbol6_get_frontEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndBuild(This,pRetVal) ) + +#define IDiaSymbol6_get_backEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMajor(This,pRetVal) ) + +#define IDiaSymbol6_get_backEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMinor(This,pRetVal) ) + +#define IDiaSymbol6_get_backEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndBuild(This,pRetVal) ) + +#define IDiaSymbol6_get_sourceFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFileName(This,pRetVal) ) + +#define IDiaSymbol6_get_unused(This,pRetVal) \ + ( (This)->lpVtbl -> get_unused(This,pRetVal) ) + +#define IDiaSymbol6_get_thunkOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_thunkOrdinal(This,pRetVal) ) + +#define IDiaSymbol6_get_thisAdjust(This,pRetVal) \ + ( (This)->lpVtbl -> get_thisAdjust(This,pRetVal) ) + +#define IDiaSymbol6_get_virtualBaseOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseOffset(This,pRetVal) ) + +#define IDiaSymbol6_get_virtual(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtual(This,pRetVal) ) + +#define IDiaSymbol6_get_intro(This,pRetVal) \ + ( (This)->lpVtbl -> get_intro(This,pRetVal) ) + +#define IDiaSymbol6_get_pure(This,pRetVal) \ + ( (This)->lpVtbl -> get_pure(This,pRetVal) ) + +#define IDiaSymbol6_get_callingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_callingConvention(This,pRetVal) ) + +#define IDiaSymbol6_get_value(This,pRetVal) \ + ( (This)->lpVtbl -> get_value(This,pRetVal) ) + +#define IDiaSymbol6_get_baseType(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseType(This,pRetVal) ) + +#define IDiaSymbol6_get_token(This,pRetVal) \ + ( (This)->lpVtbl -> get_token(This,pRetVal) ) + +#define IDiaSymbol6_get_timeStamp(This,pRetVal) \ + ( (This)->lpVtbl -> get_timeStamp(This,pRetVal) ) + +#define IDiaSymbol6_get_guid(This,pRetVal) \ + ( (This)->lpVtbl -> get_guid(This,pRetVal) ) + +#define IDiaSymbol6_get_symbolsFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_symbolsFileName(This,pRetVal) ) + +#define IDiaSymbol6_get_reference(This,pRetVal) \ + ( (This)->lpVtbl -> get_reference(This,pRetVal) ) + +#define IDiaSymbol6_get_count(This,pRetVal) \ + ( (This)->lpVtbl -> get_count(This,pRetVal) ) + +#define IDiaSymbol6_get_bitPosition(This,pRetVal) \ + ( (This)->lpVtbl -> get_bitPosition(This,pRetVal) ) + +#define IDiaSymbol6_get_arrayIndexType(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexType(This,pRetVal) ) + +#define IDiaSymbol6_get_packed(This,pRetVal) \ + ( (This)->lpVtbl -> get_packed(This,pRetVal) ) + +#define IDiaSymbol6_get_constructor(This,pRetVal) \ + ( (This)->lpVtbl -> get_constructor(This,pRetVal) ) + +#define IDiaSymbol6_get_overloadedOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_overloadedOperator(This,pRetVal) ) + +#define IDiaSymbol6_get_nested(This,pRetVal) \ + ( (This)->lpVtbl -> get_nested(This,pRetVal) ) + +#define IDiaSymbol6_get_hasNestedTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasNestedTypes(This,pRetVal) ) + +#define IDiaSymbol6_get_hasAssignmentOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAssignmentOperator(This,pRetVal) ) + +#define IDiaSymbol6_get_hasCastOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasCastOperator(This,pRetVal) ) + +#define IDiaSymbol6_get_scoped(This,pRetVal) \ + ( (This)->lpVtbl -> get_scoped(This,pRetVal) ) + +#define IDiaSymbol6_get_virtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol6_get_indirectVirtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_indirectVirtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol6_get_virtualBasePointerOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBasePointerOffset(This,pRetVal) ) + +#define IDiaSymbol6_get_virtualTableShape(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShape(This,pRetVal) ) + +#define IDiaSymbol6_get_lexicalParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParentId(This,pRetVal) ) + +#define IDiaSymbol6_get_classParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParentId(This,pRetVal) ) + +#define IDiaSymbol6_get_typeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_typeId(This,pRetVal) ) + +#define IDiaSymbol6_get_arrayIndexTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexTypeId(This,pRetVal) ) + +#define IDiaSymbol6_get_virtualTableShapeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShapeId(This,pRetVal) ) + +#define IDiaSymbol6_get_code(This,pRetVal) \ + ( (This)->lpVtbl -> get_code(This,pRetVal) ) + +#define IDiaSymbol6_get_function(This,pRetVal) \ + ( (This)->lpVtbl -> get_function(This,pRetVal) ) + +#define IDiaSymbol6_get_managed(This,pRetVal) \ + ( (This)->lpVtbl -> get_managed(This,pRetVal) ) + +#define IDiaSymbol6_get_msil(This,pRetVal) \ + ( (This)->lpVtbl -> get_msil(This,pRetVal) ) + +#define IDiaSymbol6_get_virtualBaseDispIndex(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseDispIndex(This,pRetVal) ) + +#define IDiaSymbol6_get_undecoratedName(This,pRetVal) \ + ( (This)->lpVtbl -> get_undecoratedName(This,pRetVal) ) + +#define IDiaSymbol6_get_age(This,pRetVal) \ + ( (This)->lpVtbl -> get_age(This,pRetVal) ) + +#define IDiaSymbol6_get_signature(This,pRetVal) \ + ( (This)->lpVtbl -> get_signature(This,pRetVal) ) + +#define IDiaSymbol6_get_compilerGenerated(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerGenerated(This,pRetVal) ) + +#define IDiaSymbol6_get_addressTaken(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressTaken(This,pRetVal) ) + +#define IDiaSymbol6_get_rank(This,pRetVal) \ + ( (This)->lpVtbl -> get_rank(This,pRetVal) ) + +#define IDiaSymbol6_get_lowerBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBound(This,pRetVal) ) + +#define IDiaSymbol6_get_upperBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBound(This,pRetVal) ) + +#define IDiaSymbol6_get_lowerBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBoundId(This,pRetVal) ) + +#define IDiaSymbol6_get_upperBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBoundId(This,pRetVal) ) + +#define IDiaSymbol6_get_dataBytes(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_dataBytes(This,cbData,pcbData,pbData) ) + +#define IDiaSymbol6_findChildren(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildren(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol6_findChildrenEx(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildrenEx(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol6_findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) ) + +#define IDiaSymbol6_findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) ) + +#define IDiaSymbol6_findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) ) + +#define IDiaSymbol6_get_targetSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetSection(This,pRetVal) ) + +#define IDiaSymbol6_get_targetOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetOffset(This,pRetVal) ) + +#define IDiaSymbol6_get_targetRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol6_get_targetVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol6_get_machineType(This,pRetVal) \ + ( (This)->lpVtbl -> get_machineType(This,pRetVal) ) + +#define IDiaSymbol6_get_oemId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemId(This,pRetVal) ) + +#define IDiaSymbol6_get_oemSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemSymbolId(This,pRetVal) ) + +#define IDiaSymbol6_get_types(This,cTypes,pcTypes,pTypes) \ + ( (This)->lpVtbl -> get_types(This,cTypes,pcTypes,pTypes) ) + +#define IDiaSymbol6_get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) \ + ( (This)->lpVtbl -> get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) ) + +#define IDiaSymbol6_get_objectPointerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectPointerType(This,pRetVal) ) + +#define IDiaSymbol6_get_udtKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_udtKind(This,pRetVal) ) + +#define IDiaSymbol6_get_undecoratedNameEx(This,undecorateOptions,name) \ + ( (This)->lpVtbl -> get_undecoratedNameEx(This,undecorateOptions,name) ) + +#define IDiaSymbol6_get_noReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_noReturn(This,pRetVal) ) + +#define IDiaSymbol6_get_customCallingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_customCallingConvention(This,pRetVal) ) + +#define IDiaSymbol6_get_noInline(This,pRetVal) \ + ( (This)->lpVtbl -> get_noInline(This,pRetVal) ) + +#define IDiaSymbol6_get_optimizedCodeDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_optimizedCodeDebugInfo(This,pRetVal) ) + +#define IDiaSymbol6_get_notReached(This,pRetVal) \ + ( (This)->lpVtbl -> get_notReached(This,pRetVal) ) + +#define IDiaSymbol6_get_interruptReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_interruptReturn(This,pRetVal) ) + +#define IDiaSymbol6_get_farReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_farReturn(This,pRetVal) ) + +#define IDiaSymbol6_get_isStatic(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStatic(This,pRetVal) ) + +#define IDiaSymbol6_get_hasDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasDebugInfo(This,pRetVal) ) + +#define IDiaSymbol6_get_isLTCG(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLTCG(This,pRetVal) ) + +#define IDiaSymbol6_get_isDataAligned(This,pRetVal) \ + ( (This)->lpVtbl -> get_isDataAligned(This,pRetVal) ) + +#define IDiaSymbol6_get_hasSecurityChecks(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSecurityChecks(This,pRetVal) ) + +#define IDiaSymbol6_get_compilerName(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerName(This,pRetVal) ) + +#define IDiaSymbol6_get_hasAlloca(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAlloca(This,pRetVal) ) + +#define IDiaSymbol6_get_hasSetJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSetJump(This,pRetVal) ) + +#define IDiaSymbol6_get_hasLongJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasLongJump(This,pRetVal) ) + +#define IDiaSymbol6_get_hasInlAsm(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasInlAsm(This,pRetVal) ) + +#define IDiaSymbol6_get_hasEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEH(This,pRetVal) ) + +#define IDiaSymbol6_get_hasSEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSEH(This,pRetVal) ) + +#define IDiaSymbol6_get_hasEHa(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEHa(This,pRetVal) ) + +#define IDiaSymbol6_get_isNaked(This,pRetVal) \ + ( (This)->lpVtbl -> get_isNaked(This,pRetVal) ) + +#define IDiaSymbol6_get_isAggregated(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAggregated(This,pRetVal) ) + +#define IDiaSymbol6_get_isSplitted(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSplitted(This,pRetVal) ) + +#define IDiaSymbol6_get_container(This,pRetVal) \ + ( (This)->lpVtbl -> get_container(This,pRetVal) ) + +#define IDiaSymbol6_get_inlSpec(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlSpec(This,pRetVal) ) + +#define IDiaSymbol6_get_noStackOrdering(This,pRetVal) \ + ( (This)->lpVtbl -> get_noStackOrdering(This,pRetVal) ) + +#define IDiaSymbol6_get_virtualBaseTableType(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseTableType(This,pRetVal) ) + +#define IDiaSymbol6_get_hasManagedCode(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasManagedCode(This,pRetVal) ) + +#define IDiaSymbol6_get_isHotpatchable(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHotpatchable(This,pRetVal) ) + +#define IDiaSymbol6_get_isCVTCIL(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCVTCIL(This,pRetVal) ) + +#define IDiaSymbol6_get_isMSILNetmodule(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMSILNetmodule(This,pRetVal) ) + +#define IDiaSymbol6_get_isCTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCTypes(This,pRetVal) ) + +#define IDiaSymbol6_get_isStripped(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStripped(This,pRetVal) ) + +#define IDiaSymbol6_get_frontEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndQFE(This,pRetVal) ) + +#define IDiaSymbol6_get_backEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndQFE(This,pRetVal) ) + +#define IDiaSymbol6_get_wasInlined(This,pRetVal) \ + ( (This)->lpVtbl -> get_wasInlined(This,pRetVal) ) + +#define IDiaSymbol6_get_strictGSCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_strictGSCheck(This,pRetVal) ) + +#define IDiaSymbol6_get_isCxxReturnUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCxxReturnUdt(This,pRetVal) ) + +#define IDiaSymbol6_get_isConstructorVirtualBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_isConstructorVirtualBase(This,pRetVal) ) + +#define IDiaSymbol6_get_RValueReference(This,pRetVal) \ + ( (This)->lpVtbl -> get_RValueReference(This,pRetVal) ) + +#define IDiaSymbol6_get_unmodifiedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedType(This,pRetVal) ) + +#define IDiaSymbol6_get_framePointerPresent(This,pRetVal) \ + ( (This)->lpVtbl -> get_framePointerPresent(This,pRetVal) ) + +#define IDiaSymbol6_get_isSafeBuffers(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSafeBuffers(This,pRetVal) ) + +#define IDiaSymbol6_get_intrinsic(This,pRetVal) \ + ( (This)->lpVtbl -> get_intrinsic(This,pRetVal) ) + +#define IDiaSymbol6_get_sealed(This,pRetVal) \ + ( (This)->lpVtbl -> get_sealed(This,pRetVal) ) + +#define IDiaSymbol6_get_hfaFloat(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaFloat(This,pRetVal) ) + +#define IDiaSymbol6_get_hfaDouble(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaDouble(This,pRetVal) ) + +#define IDiaSymbol6_get_liveRangeStartAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressSection(This,pRetVal) ) + +#define IDiaSymbol6_get_liveRangeStartAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressOffset(This,pRetVal) ) + +#define IDiaSymbol6_get_liveRangeStartRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol6_get_countLiveRanges(This,pRetVal) \ + ( (This)->lpVtbl -> get_countLiveRanges(This,pRetVal) ) + +#define IDiaSymbol6_get_liveRangeLength(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeLength(This,pRetVal) ) + +#define IDiaSymbol6_get_offsetInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_offsetInUdt(This,pRetVal) ) + +#define IDiaSymbol6_get_paramBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_paramBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol6_get_localBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_localBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol6_get_isLocationControlFlowDependent(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLocationControlFlowDependent(This,pRetVal) ) + +#define IDiaSymbol6_get_stride(This,pRetVal) \ + ( (This)->lpVtbl -> get_stride(This,pRetVal) ) + +#define IDiaSymbol6_get_numberOfRows(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRows(This,pRetVal) ) + +#define IDiaSymbol6_get_numberOfColumns(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfColumns(This,pRetVal) ) + +#define IDiaSymbol6_get_isMatrixRowMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMatrixRowMajor(This,pRetVal) ) + +#define IDiaSymbol6_get_numericProperties(This,cnt,pcnt,pProperties) \ + ( (This)->lpVtbl -> get_numericProperties(This,cnt,pcnt,pProperties) ) + +#define IDiaSymbol6_get_modifierValues(This,cnt,pcnt,pModifiers) \ + ( (This)->lpVtbl -> get_modifierValues(This,cnt,pcnt,pModifiers) ) + +#define IDiaSymbol6_get_isReturnValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isReturnValue(This,pRetVal) ) + +#define IDiaSymbol6_get_isOptimizedAway(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedAway(This,pRetVal) ) + +#define IDiaSymbol6_get_builtInKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_builtInKind(This,pRetVal) ) + +#define IDiaSymbol6_get_registerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerType(This,pRetVal) ) + +#define IDiaSymbol6_get_baseDataSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataSlot(This,pRetVal) ) + +#define IDiaSymbol6_get_baseDataOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataOffset(This,pRetVal) ) + +#define IDiaSymbol6_get_textureSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_textureSlot(This,pRetVal) ) + +#define IDiaSymbol6_get_samplerSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_samplerSlot(This,pRetVal) ) + +#define IDiaSymbol6_get_uavSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_uavSlot(This,pRetVal) ) + +#define IDiaSymbol6_get_sizeInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_sizeInUdt(This,pRetVal) ) + +#define IDiaSymbol6_get_memorySpaceKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_memorySpaceKind(This,pRetVal) ) + +#define IDiaSymbol6_get_unmodifiedTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedTypeId(This,pRetVal) ) + +#define IDiaSymbol6_get_subTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_subTypeId(This,pRetVal) ) + +#define IDiaSymbol6_get_subType(This,pRetVal) \ + ( (This)->lpVtbl -> get_subType(This,pRetVal) ) + +#define IDiaSymbol6_get_numberOfModifiers(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfModifiers(This,pRetVal) ) + +#define IDiaSymbol6_get_numberOfRegisterIndices(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRegisterIndices(This,pRetVal) ) + +#define IDiaSymbol6_get_isHLSLData(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHLSLData(This,pRetVal) ) + +#define IDiaSymbol6_get_isPointerToDataMember(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToDataMember(This,pRetVal) ) + +#define IDiaSymbol6_get_isPointerToMemberFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToMemberFunction(This,pRetVal) ) + +#define IDiaSymbol6_get_isSingleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSingleInheritance(This,pRetVal) ) + +#define IDiaSymbol6_get_isMultipleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMultipleInheritance(This,pRetVal) ) + +#define IDiaSymbol6_get_isVirtualInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isVirtualInheritance(This,pRetVal) ) + +#define IDiaSymbol6_get_restrictedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_restrictedType(This,pRetVal) ) + +#define IDiaSymbol6_get_isPointerBasedOnSymbolValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerBasedOnSymbolValue(This,pRetVal) ) + +#define IDiaSymbol6_get_baseSymbol(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbol(This,pRetVal) ) + +#define IDiaSymbol6_get_baseSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbolId(This,pRetVal) ) + +#define IDiaSymbol6_get_objectFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectFileName(This,pRetVal) ) + +#define IDiaSymbol6_get_isAcceleratorGroupSharedLocal(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorGroupSharedLocal(This,pRetVal) ) + +#define IDiaSymbol6_get_isAcceleratorPointerTagLiveRange(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorPointerTagLiveRange(This,pRetVal) ) + +#define IDiaSymbol6_get_isAcceleratorStubFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorStubFunction(This,pRetVal) ) + +#define IDiaSymbol6_get_numberOfAcceleratorPointerTags(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfAcceleratorPointerTags(This,pRetVal) ) + +#define IDiaSymbol6_get_isSdl(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSdl(This,pRetVal) ) + +#define IDiaSymbol6_get_isWinRTPointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_isWinRTPointer(This,pRetVal) ) + +#define IDiaSymbol6_get_isRefUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isRefUdt(This,pRetVal) ) + +#define IDiaSymbol6_get_isValueUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isValueUdt(This,pRetVal) ) + +#define IDiaSymbol6_get_isInterfaceUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isInterfaceUdt(This,pRetVal) ) + +#define IDiaSymbol6_findInlineFramesByAddr(This,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByAddr(This,isect,offset,ppResult) ) + +#define IDiaSymbol6_findInlineFramesByRVA(This,rva,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByRVA(This,rva,ppResult) ) + +#define IDiaSymbol6_findInlineFramesByVA(This,va,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByVA(This,va,ppResult) ) + +#define IDiaSymbol6_findInlineeLines(This,ppResult) \ + ( (This)->lpVtbl -> findInlineeLines(This,ppResult) ) + +#define IDiaSymbol6_findInlineeLinesByAddr(This,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByAddr(This,isect,offset,length,ppResult) ) + +#define IDiaSymbol6_findInlineeLinesByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByRVA(This,rva,length,ppResult) ) + +#define IDiaSymbol6_findInlineeLinesByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByVA(This,va,length,ppResult) ) + +#define IDiaSymbol6_findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) \ + ( (This)->lpVtbl -> findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) ) + +#define IDiaSymbol6_findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) \ + ( (This)->lpVtbl -> findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) ) + +#define IDiaSymbol6_get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) \ + ( (This)->lpVtbl -> get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) ) + +#define IDiaSymbol6_getSrcLineOnTypeDefn(This,ppResult) \ + ( (This)->lpVtbl -> getSrcLineOnTypeDefn(This,ppResult) ) + +#define IDiaSymbol6_get_isPGO(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPGO(This,pRetVal) ) + +#define IDiaSymbol6_get_hasValidPGOCounts(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasValidPGOCounts(This,pRetVal) ) + +#define IDiaSymbol6_get_isOptimizedForSpeed(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedForSpeed(This,pRetVal) ) + +#define IDiaSymbol6_get_PGOEntryCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEntryCount(This,pRetVal) ) + +#define IDiaSymbol6_get_PGOEdgeCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEdgeCount(This,pRetVal) ) + +#define IDiaSymbol6_get_PGODynamicInstructionCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGODynamicInstructionCount(This,pRetVal) ) + +#define IDiaSymbol6_get_staticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_staticSize(This,pRetVal) ) + +#define IDiaSymbol6_get_finalLiveStaticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_finalLiveStaticSize(This,pRetVal) ) + +#define IDiaSymbol6_get_phaseName(This,pRetVal) \ + ( (This)->lpVtbl -> get_phaseName(This,pRetVal) ) + +#define IDiaSymbol6_get_hasControlFlowCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasControlFlowCheck(This,pRetVal) ) + +#define IDiaSymbol6_get_constantExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_constantExport(This,pRetVal) ) + +#define IDiaSymbol6_get_dataExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataExport(This,pRetVal) ) + +#define IDiaSymbol6_get_privateExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_privateExport(This,pRetVal) ) + +#define IDiaSymbol6_get_noNameExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_noNameExport(This,pRetVal) ) + +#define IDiaSymbol6_get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) ) + +#define IDiaSymbol6_get_exportIsForwarder(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportIsForwarder(This,pRetVal) ) + +#define IDiaSymbol6_get_ordinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_ordinal(This,pRetVal) ) + +#define IDiaSymbol6_get_frameSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_frameSize(This,pRetVal) ) + +#define IDiaSymbol6_get_exceptionHandlerAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressSection(This,pRetVal) ) + +#define IDiaSymbol6_get_exceptionHandlerAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressOffset(This,pRetVal) ) + +#define IDiaSymbol6_get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol6_get_exceptionHandlerVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol6_findInputAssemblyFile(This,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFile(This,ppResult) ) + +#define IDiaSymbol6_get_characteristics(This,pRetVal) \ + ( (This)->lpVtbl -> get_characteristics(This,pRetVal) ) + +#define IDiaSymbol6_get_coffGroup(This,pRetVal) \ + ( (This)->lpVtbl -> get_coffGroup(This,pRetVal) ) + +#define IDiaSymbol6_get_bindID(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindID(This,pRetVal) ) + +#define IDiaSymbol6_get_bindSpace(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSpace(This,pRetVal) ) + +#define IDiaSymbol6_get_bindSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSlot(This,pRetVal) ) + + +#define IDiaSymbol6_get_isObjCClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCClass(This,pRetVal) ) + +#define IDiaSymbol6_get_isObjCCategory(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCCategory(This,pRetVal) ) + +#define IDiaSymbol6_get_isObjCProtocol(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCProtocol(This,pRetVal) ) + + +#define IDiaSymbol6_get_inlinee(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlinee(This,pRetVal) ) + +#define IDiaSymbol6_get_inlineeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlineeId(This,pRetVal) ) + + +#define IDiaSymbol6_get_noexcept(This,pRetVal) \ + ( (This)->lpVtbl -> get_noexcept(This,pRetVal) ) + + +#define IDiaSymbol6_get_hasAbsoluteAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAbsoluteAddress(This,pRetVal) ) + + +#define IDiaSymbol6_get_isStaticMemberFunc(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStaticMemberFunc(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol6_get_isStaticMemberFunc_Proxy( + IDiaSymbol6 * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol6_get_isStaticMemberFunc_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDiaSymbol6_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSymbol7_INTERFACE_DEFINED__ +#define __IDiaSymbol7_INTERFACE_DEFINED__ + +/* interface IDiaSymbol7 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSymbol7; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("64ce6cd5-7315-4328-86d6-10e303e010b4") + IDiaSymbol7 : public IDiaSymbol6 + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isSignRet( + /* [retval][out] */ BOOL *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSymbol7Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSymbol7 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSymbol7 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSymbol7 * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symIndexId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symTag )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParent )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParent )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataKind )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_locationType )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSymbol7 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )( + IDiaSymbol7 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSymbol7 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_slot )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_volatileType )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constType )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unalignedType )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_access )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_libraryName )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_platform )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_language )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_editAndContinueEnabled )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMajor )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMinor )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndBuild )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMajor )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMinor )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndBuild )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileName )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unused )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thunkOrdinal )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thisAdjust )( + IDiaSymbol7 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseOffset )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtual )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intro )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pure )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_callingConvention )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_value )( + IDiaSymbol7 * This, + /* [retval][out] */ VARIANT *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseType )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_token )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timeStamp )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_guid )( + IDiaSymbol7 * This, + /* [retval][out] */ GUID *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symbolsFileName )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_reference )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_count )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bitPosition )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexType )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_packed )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constructor )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_overloadedOperator )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_nested )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasNestedTypes )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAssignmentOperator )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasCastOperator )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_scoped )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseClass )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_indirectVirtualBaseClass )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBasePointerOffset )( + IDiaSymbol7 * This, + /* [retval][out] */ LONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShape )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParentId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParentId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_typeId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexTypeId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShapeId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_function )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_managed )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_msil )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseDispIndex )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_undecoratedName )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_age )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_signature )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerGenerated )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressTaken )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_rank )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBound )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBound )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBoundId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBoundId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_dataBytes )( + IDiaSymbol7 * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *findChildren )( + IDiaSymbol7 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenEx )( + IDiaSymbol7 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )( + IDiaSymbol7 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )( + IDiaSymbol7 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )( + IDiaSymbol7 * This, + /* [in] */ enum SymTagEnum symtag, + /* [in] */ LPCOLESTR name, + /* [in] */ DWORD compareFlags, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetSection )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetOffset )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetRelativeVirtualAddress )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetVirtualAddress )( + IDiaSymbol7 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_machineType )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemSymbolId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_types )( + IDiaSymbol7 * This, + /* [in] */ DWORD cTypes, + /* [out] */ DWORD *pcTypes, + /* [size_is][size_is][out] */ IDiaSymbol **pTypes); + + HRESULT ( STDMETHODCALLTYPE *get_typeIds )( + IDiaSymbol7 * This, + /* [in] */ DWORD cTypeIds, + /* [out] */ DWORD *pcTypeIds, + /* [size_is][out] */ DWORD *pdwTypeIds); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectPointerType )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_udtKind )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_undecoratedNameEx )( + IDiaSymbol7 * This, + /* [in] */ DWORD undecorateOptions, + /* [out] */ BSTR *name); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noReturn )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_customCallingConvention )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noInline )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_optimizedCodeDebugInfo )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notReached )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_interruptReturn )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_farReturn )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStatic )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasDebugInfo )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLTCG )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isDataAligned )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSecurityChecks )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerName )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAlloca )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSetJump )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasLongJump )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasInlAsm )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEH )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSEH )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEHa )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isNaked )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAggregated )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSplitted )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_container )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlSpec )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noStackOrdering )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseTableType )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasManagedCode )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHotpatchable )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCVTCIL )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMSILNetmodule )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCTypes )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStripped )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndQFE )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndQFE )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_wasInlined )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_strictGSCheck )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCxxReturnUdt )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isConstructorVirtualBase )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RValueReference )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedType )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_framePointerPresent )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSafeBuffers )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intrinsic )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sealed )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaFloat )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaDouble )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressSection )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressOffset )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartRelativeVirtualAddress )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_countLiveRanges )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeLength )( + IDiaSymbol7 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offsetInUdt )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_paramBasePointerRegisterId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localBasePointerRegisterId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLocationControlFlowDependent )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_stride )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRows )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfColumns )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMatrixRowMajor )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_numericProperties )( + IDiaSymbol7 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pProperties); + + HRESULT ( STDMETHODCALLTYPE *get_modifierValues )( + IDiaSymbol7 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ WORD *pModifiers); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isReturnValue )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedAway )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_builtInKind )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerType )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataSlot )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseDataOffset )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_textureSlot )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_samplerSlot )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uavSlot )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sizeInUdt )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_memorySpaceKind )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedTypeId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subTypeId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_subType )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfModifiers )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfRegisterIndices )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHLSLData )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToDataMember )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerToMemberFunction )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSingleInheritance )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMultipleInheritance )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isVirtualInheritance )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_restrictedType )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPointerBasedOnSymbolValue )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbol )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseSymbolId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFileName )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorGroupSharedLocal )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorPointerTagLiveRange )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAcceleratorStubFunction )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_numberOfAcceleratorPointerTags )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSdl )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isWinRTPointer )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isRefUdt )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isValueUdt )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isInterfaceUdt )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByAddr )( + IDiaSymbol7 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByRVA )( + IDiaSymbol7 * This, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineFramesByVA )( + IDiaSymbol7 * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLines )( + IDiaSymbol7 * This, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByAddr )( + IDiaSymbol7 * This, + /* [in] */ DWORD isect, + /* [in] */ DWORD offset, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByRVA )( + IDiaSymbol7 * This, + /* [in] */ DWORD rva, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findInlineeLinesByVA )( + IDiaSymbol7 * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD length, + /* [out] */ IDiaEnumLineNumbers **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsForAcceleratorPointerTag )( + IDiaSymbol7 * This, + /* [in] */ DWORD tagValue, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *findSymbolsByRVAForAcceleratorPointerTag )( + IDiaSymbol7 * This, + /* [in] */ DWORD tagValue, + /* [in] */ DWORD rva, + /* [out] */ IDiaEnumSymbols **ppResult); + + HRESULT ( STDMETHODCALLTYPE *get_acceleratorPointerTags )( + IDiaSymbol7 * This, + /* [in] */ DWORD cnt, + /* [out] */ DWORD *pcnt, + /* [size_is][out] */ DWORD *pPointerTags); + + HRESULT ( STDMETHODCALLTYPE *getSrcLineOnTypeDefn )( + IDiaSymbol7 * This, + /* [out] */ IDiaLineNumber **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isPGO )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasValidPGOCounts )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isOptimizedForSpeed )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEntryCount )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGOEdgeCount )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_PGODynamicInstructionCount )( + IDiaSymbol7 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_staticSize )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_finalLiveStaticSize )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_phaseName )( + IDiaSymbol7 * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasControlFlowCheck )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constantExport )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataExport )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_privateExport )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noNameExport )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportHasExplicitlyAssignedOrdinal )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exportIsForwarder )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_ordinal )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frameSize )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressSection )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerAddressOffset )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerRelativeVirtualAddress )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_exceptionHandlerVirtualAddress )( + IDiaSymbol7 * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *findInputAssemblyFile )( + IDiaSymbol7 * This, + /* [out] */ IDiaInputAssemblyFile **ppResult); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_characteristics )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_coffGroup )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindID )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSpace )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bindSlot )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCClass )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCCategory )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isObjCProtocol )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlinee )( + IDiaSymbol7 * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlineeId )( + IDiaSymbol7 * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noexcept )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAbsoluteAddress )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStaticMemberFunc )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSignRet )( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + END_INTERFACE + } IDiaSymbol7Vtbl; + + interface IDiaSymbol7 + { + CONST_VTBL struct IDiaSymbol7Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSymbol7_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSymbol7_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSymbol7_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSymbol7_get_symIndexId(This,pRetVal) \ + ( (This)->lpVtbl -> get_symIndexId(This,pRetVal) ) + +#define IDiaSymbol7_get_symTag(This,pRetVal) \ + ( (This)->lpVtbl -> get_symTag(This,pRetVal) ) + +#define IDiaSymbol7_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaSymbol7_get_lexicalParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParent(This,pRetVal) ) + +#define IDiaSymbol7_get_classParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParent(This,pRetVal) ) + +#define IDiaSymbol7_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaSymbol7_get_dataKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataKind(This,pRetVal) ) + +#define IDiaSymbol7_get_locationType(This,pRetVal) \ + ( (This)->lpVtbl -> get_locationType(This,pRetVal) ) + +#define IDiaSymbol7_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSymbol7_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaSymbol7_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol7_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaSymbol7_get_registerId(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerId(This,pRetVal) ) + +#define IDiaSymbol7_get_offset(This,pRetVal) \ + ( (This)->lpVtbl -> get_offset(This,pRetVal) ) + +#define IDiaSymbol7_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSymbol7_get_slot(This,pRetVal) \ + ( (This)->lpVtbl -> get_slot(This,pRetVal) ) + +#define IDiaSymbol7_get_volatileType(This,pRetVal) \ + ( (This)->lpVtbl -> get_volatileType(This,pRetVal) ) + +#define IDiaSymbol7_get_constType(This,pRetVal) \ + ( (This)->lpVtbl -> get_constType(This,pRetVal) ) + +#define IDiaSymbol7_get_unalignedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unalignedType(This,pRetVal) ) + +#define IDiaSymbol7_get_access(This,pRetVal) \ + ( (This)->lpVtbl -> get_access(This,pRetVal) ) + +#define IDiaSymbol7_get_libraryName(This,pRetVal) \ + ( (This)->lpVtbl -> get_libraryName(This,pRetVal) ) + +#define IDiaSymbol7_get_platform(This,pRetVal) \ + ( (This)->lpVtbl -> get_platform(This,pRetVal) ) + +#define IDiaSymbol7_get_language(This,pRetVal) \ + ( (This)->lpVtbl -> get_language(This,pRetVal) ) + +#define IDiaSymbol7_get_editAndContinueEnabled(This,pRetVal) \ + ( (This)->lpVtbl -> get_editAndContinueEnabled(This,pRetVal) ) + +#define IDiaSymbol7_get_frontEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMajor(This,pRetVal) ) + +#define IDiaSymbol7_get_frontEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndMinor(This,pRetVal) ) + +#define IDiaSymbol7_get_frontEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndBuild(This,pRetVal) ) + +#define IDiaSymbol7_get_backEndMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMajor(This,pRetVal) ) + +#define IDiaSymbol7_get_backEndMinor(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndMinor(This,pRetVal) ) + +#define IDiaSymbol7_get_backEndBuild(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndBuild(This,pRetVal) ) + +#define IDiaSymbol7_get_sourceFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFileName(This,pRetVal) ) + +#define IDiaSymbol7_get_unused(This,pRetVal) \ + ( (This)->lpVtbl -> get_unused(This,pRetVal) ) + +#define IDiaSymbol7_get_thunkOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_thunkOrdinal(This,pRetVal) ) + +#define IDiaSymbol7_get_thisAdjust(This,pRetVal) \ + ( (This)->lpVtbl -> get_thisAdjust(This,pRetVal) ) + +#define IDiaSymbol7_get_virtualBaseOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseOffset(This,pRetVal) ) + +#define IDiaSymbol7_get_virtual(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtual(This,pRetVal) ) + +#define IDiaSymbol7_get_intro(This,pRetVal) \ + ( (This)->lpVtbl -> get_intro(This,pRetVal) ) + +#define IDiaSymbol7_get_pure(This,pRetVal) \ + ( (This)->lpVtbl -> get_pure(This,pRetVal) ) + +#define IDiaSymbol7_get_callingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_callingConvention(This,pRetVal) ) + +#define IDiaSymbol7_get_value(This,pRetVal) \ + ( (This)->lpVtbl -> get_value(This,pRetVal) ) + +#define IDiaSymbol7_get_baseType(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseType(This,pRetVal) ) + +#define IDiaSymbol7_get_token(This,pRetVal) \ + ( (This)->lpVtbl -> get_token(This,pRetVal) ) + +#define IDiaSymbol7_get_timeStamp(This,pRetVal) \ + ( (This)->lpVtbl -> get_timeStamp(This,pRetVal) ) + +#define IDiaSymbol7_get_guid(This,pRetVal) \ + ( (This)->lpVtbl -> get_guid(This,pRetVal) ) + +#define IDiaSymbol7_get_symbolsFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_symbolsFileName(This,pRetVal) ) + +#define IDiaSymbol7_get_reference(This,pRetVal) \ + ( (This)->lpVtbl -> get_reference(This,pRetVal) ) + +#define IDiaSymbol7_get_count(This,pRetVal) \ + ( (This)->lpVtbl -> get_count(This,pRetVal) ) + +#define IDiaSymbol7_get_bitPosition(This,pRetVal) \ + ( (This)->lpVtbl -> get_bitPosition(This,pRetVal) ) + +#define IDiaSymbol7_get_arrayIndexType(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexType(This,pRetVal) ) + +#define IDiaSymbol7_get_packed(This,pRetVal) \ + ( (This)->lpVtbl -> get_packed(This,pRetVal) ) + +#define IDiaSymbol7_get_constructor(This,pRetVal) \ + ( (This)->lpVtbl -> get_constructor(This,pRetVal) ) + +#define IDiaSymbol7_get_overloadedOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_overloadedOperator(This,pRetVal) ) + +#define IDiaSymbol7_get_nested(This,pRetVal) \ + ( (This)->lpVtbl -> get_nested(This,pRetVal) ) + +#define IDiaSymbol7_get_hasNestedTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasNestedTypes(This,pRetVal) ) + +#define IDiaSymbol7_get_hasAssignmentOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAssignmentOperator(This,pRetVal) ) + +#define IDiaSymbol7_get_hasCastOperator(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasCastOperator(This,pRetVal) ) + +#define IDiaSymbol7_get_scoped(This,pRetVal) \ + ( (This)->lpVtbl -> get_scoped(This,pRetVal) ) + +#define IDiaSymbol7_get_virtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol7_get_indirectVirtualBaseClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_indirectVirtualBaseClass(This,pRetVal) ) + +#define IDiaSymbol7_get_virtualBasePointerOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBasePointerOffset(This,pRetVal) ) + +#define IDiaSymbol7_get_virtualTableShape(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShape(This,pRetVal) ) + +#define IDiaSymbol7_get_lexicalParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lexicalParentId(This,pRetVal) ) + +#define IDiaSymbol7_get_classParentId(This,pRetVal) \ + ( (This)->lpVtbl -> get_classParentId(This,pRetVal) ) + +#define IDiaSymbol7_get_typeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_typeId(This,pRetVal) ) + +#define IDiaSymbol7_get_arrayIndexTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_arrayIndexTypeId(This,pRetVal) ) + +#define IDiaSymbol7_get_virtualTableShapeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualTableShapeId(This,pRetVal) ) + +#define IDiaSymbol7_get_code(This,pRetVal) \ + ( (This)->lpVtbl -> get_code(This,pRetVal) ) + +#define IDiaSymbol7_get_function(This,pRetVal) \ + ( (This)->lpVtbl -> get_function(This,pRetVal) ) + +#define IDiaSymbol7_get_managed(This,pRetVal) \ + ( (This)->lpVtbl -> get_managed(This,pRetVal) ) + +#define IDiaSymbol7_get_msil(This,pRetVal) \ + ( (This)->lpVtbl -> get_msil(This,pRetVal) ) + +#define IDiaSymbol7_get_virtualBaseDispIndex(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseDispIndex(This,pRetVal) ) + +#define IDiaSymbol7_get_undecoratedName(This,pRetVal) \ + ( (This)->lpVtbl -> get_undecoratedName(This,pRetVal) ) + +#define IDiaSymbol7_get_age(This,pRetVal) \ + ( (This)->lpVtbl -> get_age(This,pRetVal) ) + +#define IDiaSymbol7_get_signature(This,pRetVal) \ + ( (This)->lpVtbl -> get_signature(This,pRetVal) ) + +#define IDiaSymbol7_get_compilerGenerated(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerGenerated(This,pRetVal) ) + +#define IDiaSymbol7_get_addressTaken(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressTaken(This,pRetVal) ) + +#define IDiaSymbol7_get_rank(This,pRetVal) \ + ( (This)->lpVtbl -> get_rank(This,pRetVal) ) + +#define IDiaSymbol7_get_lowerBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBound(This,pRetVal) ) + +#define IDiaSymbol7_get_upperBound(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBound(This,pRetVal) ) + +#define IDiaSymbol7_get_lowerBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_lowerBoundId(This,pRetVal) ) + +#define IDiaSymbol7_get_upperBoundId(This,pRetVal) \ + ( (This)->lpVtbl -> get_upperBoundId(This,pRetVal) ) + +#define IDiaSymbol7_get_dataBytes(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_dataBytes(This,cbData,pcbData,pbData) ) + +#define IDiaSymbol7_findChildren(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildren(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol7_findChildrenEx(This,symtag,name,compareFlags,ppResult) \ + ( (This)->lpVtbl -> findChildrenEx(This,symtag,name,compareFlags,ppResult) ) + +#define IDiaSymbol7_findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) ) + +#define IDiaSymbol7_findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) ) + +#define IDiaSymbol7_findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) \ + ( (This)->lpVtbl -> findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) ) + +#define IDiaSymbol7_get_targetSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetSection(This,pRetVal) ) + +#define IDiaSymbol7_get_targetOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetOffset(This,pRetVal) ) + +#define IDiaSymbol7_get_targetRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol7_get_targetVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_targetVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol7_get_machineType(This,pRetVal) \ + ( (This)->lpVtbl -> get_machineType(This,pRetVal) ) + +#define IDiaSymbol7_get_oemId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemId(This,pRetVal) ) + +#define IDiaSymbol7_get_oemSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_oemSymbolId(This,pRetVal) ) + +#define IDiaSymbol7_get_types(This,cTypes,pcTypes,pTypes) \ + ( (This)->lpVtbl -> get_types(This,cTypes,pcTypes,pTypes) ) + +#define IDiaSymbol7_get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) \ + ( (This)->lpVtbl -> get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) ) + +#define IDiaSymbol7_get_objectPointerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectPointerType(This,pRetVal) ) + +#define IDiaSymbol7_get_udtKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_udtKind(This,pRetVal) ) + +#define IDiaSymbol7_get_undecoratedNameEx(This,undecorateOptions,name) \ + ( (This)->lpVtbl -> get_undecoratedNameEx(This,undecorateOptions,name) ) + +#define IDiaSymbol7_get_noReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_noReturn(This,pRetVal) ) + +#define IDiaSymbol7_get_customCallingConvention(This,pRetVal) \ + ( (This)->lpVtbl -> get_customCallingConvention(This,pRetVal) ) + +#define IDiaSymbol7_get_noInline(This,pRetVal) \ + ( (This)->lpVtbl -> get_noInline(This,pRetVal) ) + +#define IDiaSymbol7_get_optimizedCodeDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_optimizedCodeDebugInfo(This,pRetVal) ) + +#define IDiaSymbol7_get_notReached(This,pRetVal) \ + ( (This)->lpVtbl -> get_notReached(This,pRetVal) ) + +#define IDiaSymbol7_get_interruptReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_interruptReturn(This,pRetVal) ) + +#define IDiaSymbol7_get_farReturn(This,pRetVal) \ + ( (This)->lpVtbl -> get_farReturn(This,pRetVal) ) + +#define IDiaSymbol7_get_isStatic(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStatic(This,pRetVal) ) + +#define IDiaSymbol7_get_hasDebugInfo(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasDebugInfo(This,pRetVal) ) + +#define IDiaSymbol7_get_isLTCG(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLTCG(This,pRetVal) ) + +#define IDiaSymbol7_get_isDataAligned(This,pRetVal) \ + ( (This)->lpVtbl -> get_isDataAligned(This,pRetVal) ) + +#define IDiaSymbol7_get_hasSecurityChecks(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSecurityChecks(This,pRetVal) ) + +#define IDiaSymbol7_get_compilerName(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilerName(This,pRetVal) ) + +#define IDiaSymbol7_get_hasAlloca(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAlloca(This,pRetVal) ) + +#define IDiaSymbol7_get_hasSetJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSetJump(This,pRetVal) ) + +#define IDiaSymbol7_get_hasLongJump(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasLongJump(This,pRetVal) ) + +#define IDiaSymbol7_get_hasInlAsm(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasInlAsm(This,pRetVal) ) + +#define IDiaSymbol7_get_hasEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEH(This,pRetVal) ) + +#define IDiaSymbol7_get_hasSEH(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasSEH(This,pRetVal) ) + +#define IDiaSymbol7_get_hasEHa(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasEHa(This,pRetVal) ) + +#define IDiaSymbol7_get_isNaked(This,pRetVal) \ + ( (This)->lpVtbl -> get_isNaked(This,pRetVal) ) + +#define IDiaSymbol7_get_isAggregated(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAggregated(This,pRetVal) ) + +#define IDiaSymbol7_get_isSplitted(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSplitted(This,pRetVal) ) + +#define IDiaSymbol7_get_container(This,pRetVal) \ + ( (This)->lpVtbl -> get_container(This,pRetVal) ) + +#define IDiaSymbol7_get_inlSpec(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlSpec(This,pRetVal) ) + +#define IDiaSymbol7_get_noStackOrdering(This,pRetVal) \ + ( (This)->lpVtbl -> get_noStackOrdering(This,pRetVal) ) + +#define IDiaSymbol7_get_virtualBaseTableType(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualBaseTableType(This,pRetVal) ) + +#define IDiaSymbol7_get_hasManagedCode(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasManagedCode(This,pRetVal) ) + +#define IDiaSymbol7_get_isHotpatchable(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHotpatchable(This,pRetVal) ) + +#define IDiaSymbol7_get_isCVTCIL(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCVTCIL(This,pRetVal) ) + +#define IDiaSymbol7_get_isMSILNetmodule(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMSILNetmodule(This,pRetVal) ) + +#define IDiaSymbol7_get_isCTypes(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCTypes(This,pRetVal) ) + +#define IDiaSymbol7_get_isStripped(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStripped(This,pRetVal) ) + +#define IDiaSymbol7_get_frontEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_frontEndQFE(This,pRetVal) ) + +#define IDiaSymbol7_get_backEndQFE(This,pRetVal) \ + ( (This)->lpVtbl -> get_backEndQFE(This,pRetVal) ) + +#define IDiaSymbol7_get_wasInlined(This,pRetVal) \ + ( (This)->lpVtbl -> get_wasInlined(This,pRetVal) ) + +#define IDiaSymbol7_get_strictGSCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_strictGSCheck(This,pRetVal) ) + +#define IDiaSymbol7_get_isCxxReturnUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isCxxReturnUdt(This,pRetVal) ) + +#define IDiaSymbol7_get_isConstructorVirtualBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_isConstructorVirtualBase(This,pRetVal) ) + +#define IDiaSymbol7_get_RValueReference(This,pRetVal) \ + ( (This)->lpVtbl -> get_RValueReference(This,pRetVal) ) + +#define IDiaSymbol7_get_unmodifiedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedType(This,pRetVal) ) + +#define IDiaSymbol7_get_framePointerPresent(This,pRetVal) \ + ( (This)->lpVtbl -> get_framePointerPresent(This,pRetVal) ) + +#define IDiaSymbol7_get_isSafeBuffers(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSafeBuffers(This,pRetVal) ) + +#define IDiaSymbol7_get_intrinsic(This,pRetVal) \ + ( (This)->lpVtbl -> get_intrinsic(This,pRetVal) ) + +#define IDiaSymbol7_get_sealed(This,pRetVal) \ + ( (This)->lpVtbl -> get_sealed(This,pRetVal) ) + +#define IDiaSymbol7_get_hfaFloat(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaFloat(This,pRetVal) ) + +#define IDiaSymbol7_get_hfaDouble(This,pRetVal) \ + ( (This)->lpVtbl -> get_hfaDouble(This,pRetVal) ) + +#define IDiaSymbol7_get_liveRangeStartAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressSection(This,pRetVal) ) + +#define IDiaSymbol7_get_liveRangeStartAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartAddressOffset(This,pRetVal) ) + +#define IDiaSymbol7_get_liveRangeStartRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeStartRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol7_get_countLiveRanges(This,pRetVal) \ + ( (This)->lpVtbl -> get_countLiveRanges(This,pRetVal) ) + +#define IDiaSymbol7_get_liveRangeLength(This,pRetVal) \ + ( (This)->lpVtbl -> get_liveRangeLength(This,pRetVal) ) + +#define IDiaSymbol7_get_offsetInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_offsetInUdt(This,pRetVal) ) + +#define IDiaSymbol7_get_paramBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_paramBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol7_get_localBasePointerRegisterId(This,pRetVal) \ + ( (This)->lpVtbl -> get_localBasePointerRegisterId(This,pRetVal) ) + +#define IDiaSymbol7_get_isLocationControlFlowDependent(This,pRetVal) \ + ( (This)->lpVtbl -> get_isLocationControlFlowDependent(This,pRetVal) ) + +#define IDiaSymbol7_get_stride(This,pRetVal) \ + ( (This)->lpVtbl -> get_stride(This,pRetVal) ) + +#define IDiaSymbol7_get_numberOfRows(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRows(This,pRetVal) ) + +#define IDiaSymbol7_get_numberOfColumns(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfColumns(This,pRetVal) ) + +#define IDiaSymbol7_get_isMatrixRowMajor(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMatrixRowMajor(This,pRetVal) ) + +#define IDiaSymbol7_get_numericProperties(This,cnt,pcnt,pProperties) \ + ( (This)->lpVtbl -> get_numericProperties(This,cnt,pcnt,pProperties) ) + +#define IDiaSymbol7_get_modifierValues(This,cnt,pcnt,pModifiers) \ + ( (This)->lpVtbl -> get_modifierValues(This,cnt,pcnt,pModifiers) ) + +#define IDiaSymbol7_get_isReturnValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isReturnValue(This,pRetVal) ) + +#define IDiaSymbol7_get_isOptimizedAway(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedAway(This,pRetVal) ) + +#define IDiaSymbol7_get_builtInKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_builtInKind(This,pRetVal) ) + +#define IDiaSymbol7_get_registerType(This,pRetVal) \ + ( (This)->lpVtbl -> get_registerType(This,pRetVal) ) + +#define IDiaSymbol7_get_baseDataSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataSlot(This,pRetVal) ) + +#define IDiaSymbol7_get_baseDataOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseDataOffset(This,pRetVal) ) + +#define IDiaSymbol7_get_textureSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_textureSlot(This,pRetVal) ) + +#define IDiaSymbol7_get_samplerSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_samplerSlot(This,pRetVal) ) + +#define IDiaSymbol7_get_uavSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_uavSlot(This,pRetVal) ) + +#define IDiaSymbol7_get_sizeInUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_sizeInUdt(This,pRetVal) ) + +#define IDiaSymbol7_get_memorySpaceKind(This,pRetVal) \ + ( (This)->lpVtbl -> get_memorySpaceKind(This,pRetVal) ) + +#define IDiaSymbol7_get_unmodifiedTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_unmodifiedTypeId(This,pRetVal) ) + +#define IDiaSymbol7_get_subTypeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_subTypeId(This,pRetVal) ) + +#define IDiaSymbol7_get_subType(This,pRetVal) \ + ( (This)->lpVtbl -> get_subType(This,pRetVal) ) + +#define IDiaSymbol7_get_numberOfModifiers(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfModifiers(This,pRetVal) ) + +#define IDiaSymbol7_get_numberOfRegisterIndices(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfRegisterIndices(This,pRetVal) ) + +#define IDiaSymbol7_get_isHLSLData(This,pRetVal) \ + ( (This)->lpVtbl -> get_isHLSLData(This,pRetVal) ) + +#define IDiaSymbol7_get_isPointerToDataMember(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToDataMember(This,pRetVal) ) + +#define IDiaSymbol7_get_isPointerToMemberFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerToMemberFunction(This,pRetVal) ) + +#define IDiaSymbol7_get_isSingleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSingleInheritance(This,pRetVal) ) + +#define IDiaSymbol7_get_isMultipleInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isMultipleInheritance(This,pRetVal) ) + +#define IDiaSymbol7_get_isVirtualInheritance(This,pRetVal) \ + ( (This)->lpVtbl -> get_isVirtualInheritance(This,pRetVal) ) + +#define IDiaSymbol7_get_restrictedType(This,pRetVal) \ + ( (This)->lpVtbl -> get_restrictedType(This,pRetVal) ) + +#define IDiaSymbol7_get_isPointerBasedOnSymbolValue(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPointerBasedOnSymbolValue(This,pRetVal) ) + +#define IDiaSymbol7_get_baseSymbol(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbol(This,pRetVal) ) + +#define IDiaSymbol7_get_baseSymbolId(This,pRetVal) \ + ( (This)->lpVtbl -> get_baseSymbolId(This,pRetVal) ) + +#define IDiaSymbol7_get_objectFileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectFileName(This,pRetVal) ) + +#define IDiaSymbol7_get_isAcceleratorGroupSharedLocal(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorGroupSharedLocal(This,pRetVal) ) + +#define IDiaSymbol7_get_isAcceleratorPointerTagLiveRange(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorPointerTagLiveRange(This,pRetVal) ) + +#define IDiaSymbol7_get_isAcceleratorStubFunction(This,pRetVal) \ + ( (This)->lpVtbl -> get_isAcceleratorStubFunction(This,pRetVal) ) + +#define IDiaSymbol7_get_numberOfAcceleratorPointerTags(This,pRetVal) \ + ( (This)->lpVtbl -> get_numberOfAcceleratorPointerTags(This,pRetVal) ) + +#define IDiaSymbol7_get_isSdl(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSdl(This,pRetVal) ) + +#define IDiaSymbol7_get_isWinRTPointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_isWinRTPointer(This,pRetVal) ) + +#define IDiaSymbol7_get_isRefUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isRefUdt(This,pRetVal) ) + +#define IDiaSymbol7_get_isValueUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isValueUdt(This,pRetVal) ) + +#define IDiaSymbol7_get_isInterfaceUdt(This,pRetVal) \ + ( (This)->lpVtbl -> get_isInterfaceUdt(This,pRetVal) ) + +#define IDiaSymbol7_findInlineFramesByAddr(This,isect,offset,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByAddr(This,isect,offset,ppResult) ) + +#define IDiaSymbol7_findInlineFramesByRVA(This,rva,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByRVA(This,rva,ppResult) ) + +#define IDiaSymbol7_findInlineFramesByVA(This,va,ppResult) \ + ( (This)->lpVtbl -> findInlineFramesByVA(This,va,ppResult) ) + +#define IDiaSymbol7_findInlineeLines(This,ppResult) \ + ( (This)->lpVtbl -> findInlineeLines(This,ppResult) ) + +#define IDiaSymbol7_findInlineeLinesByAddr(This,isect,offset,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByAddr(This,isect,offset,length,ppResult) ) + +#define IDiaSymbol7_findInlineeLinesByRVA(This,rva,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByRVA(This,rva,length,ppResult) ) + +#define IDiaSymbol7_findInlineeLinesByVA(This,va,length,ppResult) \ + ( (This)->lpVtbl -> findInlineeLinesByVA(This,va,length,ppResult) ) + +#define IDiaSymbol7_findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) \ + ( (This)->lpVtbl -> findSymbolsForAcceleratorPointerTag(This,tagValue,ppResult) ) + +#define IDiaSymbol7_findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) \ + ( (This)->lpVtbl -> findSymbolsByRVAForAcceleratorPointerTag(This,tagValue,rva,ppResult) ) + +#define IDiaSymbol7_get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) \ + ( (This)->lpVtbl -> get_acceleratorPointerTags(This,cnt,pcnt,pPointerTags) ) + +#define IDiaSymbol7_getSrcLineOnTypeDefn(This,ppResult) \ + ( (This)->lpVtbl -> getSrcLineOnTypeDefn(This,ppResult) ) + +#define IDiaSymbol7_get_isPGO(This,pRetVal) \ + ( (This)->lpVtbl -> get_isPGO(This,pRetVal) ) + +#define IDiaSymbol7_get_hasValidPGOCounts(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasValidPGOCounts(This,pRetVal) ) + +#define IDiaSymbol7_get_isOptimizedForSpeed(This,pRetVal) \ + ( (This)->lpVtbl -> get_isOptimizedForSpeed(This,pRetVal) ) + +#define IDiaSymbol7_get_PGOEntryCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEntryCount(This,pRetVal) ) + +#define IDiaSymbol7_get_PGOEdgeCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGOEdgeCount(This,pRetVal) ) + +#define IDiaSymbol7_get_PGODynamicInstructionCount(This,pRetVal) \ + ( (This)->lpVtbl -> get_PGODynamicInstructionCount(This,pRetVal) ) + +#define IDiaSymbol7_get_staticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_staticSize(This,pRetVal) ) + +#define IDiaSymbol7_get_finalLiveStaticSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_finalLiveStaticSize(This,pRetVal) ) + +#define IDiaSymbol7_get_phaseName(This,pRetVal) \ + ( (This)->lpVtbl -> get_phaseName(This,pRetVal) ) + +#define IDiaSymbol7_get_hasControlFlowCheck(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasControlFlowCheck(This,pRetVal) ) + +#define IDiaSymbol7_get_constantExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_constantExport(This,pRetVal) ) + +#define IDiaSymbol7_get_dataExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataExport(This,pRetVal) ) + +#define IDiaSymbol7_get_privateExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_privateExport(This,pRetVal) ) + +#define IDiaSymbol7_get_noNameExport(This,pRetVal) \ + ( (This)->lpVtbl -> get_noNameExport(This,pRetVal) ) + +#define IDiaSymbol7_get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportHasExplicitlyAssignedOrdinal(This,pRetVal) ) + +#define IDiaSymbol7_get_exportIsForwarder(This,pRetVal) \ + ( (This)->lpVtbl -> get_exportIsForwarder(This,pRetVal) ) + +#define IDiaSymbol7_get_ordinal(This,pRetVal) \ + ( (This)->lpVtbl -> get_ordinal(This,pRetVal) ) + +#define IDiaSymbol7_get_frameSize(This,pRetVal) \ + ( (This)->lpVtbl -> get_frameSize(This,pRetVal) ) + +#define IDiaSymbol7_get_exceptionHandlerAddressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressSection(This,pRetVal) ) + +#define IDiaSymbol7_get_exceptionHandlerAddressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerAddressOffset(This,pRetVal) ) + +#define IDiaSymbol7_get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerRelativeVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol7_get_exceptionHandlerVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_exceptionHandlerVirtualAddress(This,pRetVal) ) + +#define IDiaSymbol7_findInputAssemblyFile(This,ppResult) \ + ( (This)->lpVtbl -> findInputAssemblyFile(This,ppResult) ) + +#define IDiaSymbol7_get_characteristics(This,pRetVal) \ + ( (This)->lpVtbl -> get_characteristics(This,pRetVal) ) + +#define IDiaSymbol7_get_coffGroup(This,pRetVal) \ + ( (This)->lpVtbl -> get_coffGroup(This,pRetVal) ) + +#define IDiaSymbol7_get_bindID(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindID(This,pRetVal) ) + +#define IDiaSymbol7_get_bindSpace(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSpace(This,pRetVal) ) + +#define IDiaSymbol7_get_bindSlot(This,pRetVal) \ + ( (This)->lpVtbl -> get_bindSlot(This,pRetVal) ) + + +#define IDiaSymbol7_get_isObjCClass(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCClass(This,pRetVal) ) + +#define IDiaSymbol7_get_isObjCCategory(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCCategory(This,pRetVal) ) + +#define IDiaSymbol7_get_isObjCProtocol(This,pRetVal) \ + ( (This)->lpVtbl -> get_isObjCProtocol(This,pRetVal) ) + + +#define IDiaSymbol7_get_inlinee(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlinee(This,pRetVal) ) + +#define IDiaSymbol7_get_inlineeId(This,pRetVal) \ + ( (This)->lpVtbl -> get_inlineeId(This,pRetVal) ) + + +#define IDiaSymbol7_get_noexcept(This,pRetVal) \ + ( (This)->lpVtbl -> get_noexcept(This,pRetVal) ) + + +#define IDiaSymbol7_get_hasAbsoluteAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_hasAbsoluteAddress(This,pRetVal) ) + + +#define IDiaSymbol7_get_isStaticMemberFunc(This,pRetVal) \ + ( (This)->lpVtbl -> get_isStaticMemberFunc(This,pRetVal) ) + + +#define IDiaSymbol7_get_isSignRet(This,pRetVal) \ + ( (This)->lpVtbl -> get_isSignRet(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol7_get_isSignRet_Proxy( + IDiaSymbol7 * This, + /* [retval][out] */ BOOL *pRetVal); + + +void __RPC_STUB IDiaSymbol7_get_isSignRet_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IDiaSymbol7_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSourceFile_INTERFACE_DEFINED__ +#define __IDiaSourceFile_INTERFACE_DEFINED__ + +/* interface IDiaSourceFile */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSourceFile; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A2EF5353-F5A8-4eb3-90D2-CB526ACB3CDD") + IDiaSourceFile : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_uniqueId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_fileName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_checksumType( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilands( + /* [retval][out] */ IDiaEnumSymbols **pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_checksum( + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSourceFileVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSourceFile * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSourceFile * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSourceFile * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uniqueId )( + IDiaSourceFile * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_fileName )( + IDiaSourceFile * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_checksumType )( + IDiaSourceFile * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilands )( + IDiaSourceFile * This, + /* [retval][out] */ IDiaEnumSymbols **pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_checksum )( + IDiaSourceFile * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + END_INTERFACE + } IDiaSourceFileVtbl; + + interface IDiaSourceFile + { + CONST_VTBL struct IDiaSourceFileVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSourceFile_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSourceFile_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSourceFile_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSourceFile_get_uniqueId(This,pRetVal) \ + ( (This)->lpVtbl -> get_uniqueId(This,pRetVal) ) + +#define IDiaSourceFile_get_fileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_fileName(This,pRetVal) ) + +#define IDiaSourceFile_get_checksumType(This,pRetVal) \ + ( (This)->lpVtbl -> get_checksumType(This,pRetVal) ) + +#define IDiaSourceFile_get_compilands(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilands(This,pRetVal) ) + +#define IDiaSourceFile_get_checksum(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_checksum(This,cbData,pcbData,pbData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaSourceFile_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaInputAssemblyFile_INTERFACE_DEFINED__ +#define __IDiaInputAssemblyFile_INTERFACE_DEFINED__ + +/* interface IDiaInputAssemblyFile */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaInputAssemblyFile; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3BFE56B0-390C-4863-9430-1F3D083B7684") + IDiaInputAssemblyFile : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_uniqueId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_index( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_timestamp( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_pdbAvailableAtILMerge( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_fileName( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_version( + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaInputAssemblyFileVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaInputAssemblyFile * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaInputAssemblyFile * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaInputAssemblyFile * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uniqueId )( + IDiaInputAssemblyFile * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_index )( + IDiaInputAssemblyFile * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timestamp )( + IDiaInputAssemblyFile * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pdbAvailableAtILMerge )( + IDiaInputAssemblyFile * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_fileName )( + IDiaInputAssemblyFile * This, + /* [retval][out] */ BSTR *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_version )( + IDiaInputAssemblyFile * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + END_INTERFACE + } IDiaInputAssemblyFileVtbl; + + interface IDiaInputAssemblyFile + { + CONST_VTBL struct IDiaInputAssemblyFileVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaInputAssemblyFile_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaInputAssemblyFile_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaInputAssemblyFile_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaInputAssemblyFile_get_uniqueId(This,pRetVal) \ + ( (This)->lpVtbl -> get_uniqueId(This,pRetVal) ) + +#define IDiaInputAssemblyFile_get_index(This,pRetVal) \ + ( (This)->lpVtbl -> get_index(This,pRetVal) ) + +#define IDiaInputAssemblyFile_get_timestamp(This,pRetVal) \ + ( (This)->lpVtbl -> get_timestamp(This,pRetVal) ) + +#define IDiaInputAssemblyFile_get_pdbAvailableAtILMerge(This,pRetVal) \ + ( (This)->lpVtbl -> get_pdbAvailableAtILMerge(This,pRetVal) ) + +#define IDiaInputAssemblyFile_get_fileName(This,pRetVal) \ + ( (This)->lpVtbl -> get_fileName(This,pRetVal) ) + +#define IDiaInputAssemblyFile_get_version(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_version(This,cbData,pcbData,pbData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaInputAssemblyFile_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaLineNumber_INTERFACE_DEFINED__ +#define __IDiaLineNumber_INTERFACE_DEFINED__ + +/* interface IDiaLineNumber */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaLineNumber; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("B388EB14-BE4D-421d-A8A1-6CF7AB057086") + IDiaLineNumber : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compiland( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sourceFile( + /* [retval][out] */ IDiaSourceFile **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lineNumber( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lineNumberEnd( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_columnNumber( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_columnNumberEnd( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sourceFileId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_statement( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilandId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaLineNumberVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaLineNumber * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaLineNumber * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaLineNumber * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compiland )( + IDiaLineNumber * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFile )( + IDiaLineNumber * This, + /* [retval][out] */ IDiaSourceFile **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lineNumber )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lineNumberEnd )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_columnNumber )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_columnNumberEnd )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaLineNumber * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileId )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_statement )( + IDiaLineNumber * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilandId )( + IDiaLineNumber * This, + /* [retval][out] */ DWORD *pRetVal); + + END_INTERFACE + } IDiaLineNumberVtbl; + + interface IDiaLineNumber + { + CONST_VTBL struct IDiaLineNumberVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaLineNumber_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaLineNumber_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaLineNumber_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaLineNumber_get_compiland(This,pRetVal) \ + ( (This)->lpVtbl -> get_compiland(This,pRetVal) ) + +#define IDiaLineNumber_get_sourceFile(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFile(This,pRetVal) ) + +#define IDiaLineNumber_get_lineNumber(This,pRetVal) \ + ( (This)->lpVtbl -> get_lineNumber(This,pRetVal) ) + +#define IDiaLineNumber_get_lineNumberEnd(This,pRetVal) \ + ( (This)->lpVtbl -> get_lineNumberEnd(This,pRetVal) ) + +#define IDiaLineNumber_get_columnNumber(This,pRetVal) \ + ( (This)->lpVtbl -> get_columnNumber(This,pRetVal) ) + +#define IDiaLineNumber_get_columnNumberEnd(This,pRetVal) \ + ( (This)->lpVtbl -> get_columnNumberEnd(This,pRetVal) ) + +#define IDiaLineNumber_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaLineNumber_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaLineNumber_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaLineNumber_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaLineNumber_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaLineNumber_get_sourceFileId(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceFileId(This,pRetVal) ) + +#define IDiaLineNumber_get_statement(This,pRetVal) \ + ( (This)->lpVtbl -> get_statement(This,pRetVal) ) + +#define IDiaLineNumber_get_compilandId(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilandId(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaLineNumber_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSectionContrib_INTERFACE_DEFINED__ +#define __IDiaSectionContrib_INTERFACE_DEFINED__ + +/* interface IDiaSectionContrib */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSectionContrib; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0CF4B60E-35B1-4c6c-BDD8-854B9C8E3857") + IDiaSectionContrib : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compiland( + /* [retval][out] */ IDiaSymbol **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_notPaged( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_code( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_initializedData( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_uninitializedData( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_remove( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_comdat( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_discardable( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_notCached( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_share( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_execute( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_read( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_write( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_dataCrc( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relocationsCrc( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilandId( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_code16bit( + /* [retval][out] */ BOOL *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSectionContribVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSectionContrib * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSectionContrib * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSectionContrib * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compiland )( + IDiaSectionContrib * This, + /* [retval][out] */ IDiaSymbol **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSectionContrib * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaSectionContrib * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSectionContrib * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSectionContrib * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSectionContrib * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notPaged )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_initializedData )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uninitializedData )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_remove )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_comdat )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_discardable )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notCached )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_share )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_execute )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_read )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_write )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataCrc )( + IDiaSectionContrib * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relocationsCrc )( + IDiaSectionContrib * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilandId )( + IDiaSectionContrib * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code16bit )( + IDiaSectionContrib * This, + /* [retval][out] */ BOOL *pRetVal); + + END_INTERFACE + } IDiaSectionContribVtbl; + + interface IDiaSectionContrib + { + CONST_VTBL struct IDiaSectionContribVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSectionContrib_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSectionContrib_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSectionContrib_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSectionContrib_get_compiland(This,pRetVal) \ + ( (This)->lpVtbl -> get_compiland(This,pRetVal) ) + +#define IDiaSectionContrib_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSectionContrib_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaSectionContrib_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSectionContrib_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaSectionContrib_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSectionContrib_get_notPaged(This,pRetVal) \ + ( (This)->lpVtbl -> get_notPaged(This,pRetVal) ) + +#define IDiaSectionContrib_get_code(This,pRetVal) \ + ( (This)->lpVtbl -> get_code(This,pRetVal) ) + +#define IDiaSectionContrib_get_initializedData(This,pRetVal) \ + ( (This)->lpVtbl -> get_initializedData(This,pRetVal) ) + +#define IDiaSectionContrib_get_uninitializedData(This,pRetVal) \ + ( (This)->lpVtbl -> get_uninitializedData(This,pRetVal) ) + +#define IDiaSectionContrib_get_remove(This,pRetVal) \ + ( (This)->lpVtbl -> get_remove(This,pRetVal) ) + +#define IDiaSectionContrib_get_comdat(This,pRetVal) \ + ( (This)->lpVtbl -> get_comdat(This,pRetVal) ) + +#define IDiaSectionContrib_get_discardable(This,pRetVal) \ + ( (This)->lpVtbl -> get_discardable(This,pRetVal) ) + +#define IDiaSectionContrib_get_notCached(This,pRetVal) \ + ( (This)->lpVtbl -> get_notCached(This,pRetVal) ) + +#define IDiaSectionContrib_get_share(This,pRetVal) \ + ( (This)->lpVtbl -> get_share(This,pRetVal) ) + +#define IDiaSectionContrib_get_execute(This,pRetVal) \ + ( (This)->lpVtbl -> get_execute(This,pRetVal) ) + +#define IDiaSectionContrib_get_read(This,pRetVal) \ + ( (This)->lpVtbl -> get_read(This,pRetVal) ) + +#define IDiaSectionContrib_get_write(This,pRetVal) \ + ( (This)->lpVtbl -> get_write(This,pRetVal) ) + +#define IDiaSectionContrib_get_dataCrc(This,pRetVal) \ + ( (This)->lpVtbl -> get_dataCrc(This,pRetVal) ) + +#define IDiaSectionContrib_get_relocationsCrc(This,pRetVal) \ + ( (This)->lpVtbl -> get_relocationsCrc(This,pRetVal) ) + +#define IDiaSectionContrib_get_compilandId(This,pRetVal) \ + ( (This)->lpVtbl -> get_compilandId(This,pRetVal) ) + +#define IDiaSectionContrib_get_code16bit(This,pRetVal) \ + ( (This)->lpVtbl -> get_code16bit(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaSectionContrib_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaSegment_INTERFACE_DEFINED__ +#define __IDiaSegment_INTERFACE_DEFINED__ + +/* interface IDiaSegment */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaSegment; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("0775B784-C75B-4449-848B-B7BD3159545B") + IDiaSegment : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frame( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_offset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_read( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_write( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_execute( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaSegmentVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaSegment * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaSegment * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaSegment * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frame )( + IDiaSegment * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )( + IDiaSegment * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaSegment * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_read )( + IDiaSegment * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_write )( + IDiaSegment * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_execute )( + IDiaSegment * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaSegment * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaSegment * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaSegment * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + END_INTERFACE + } IDiaSegmentVtbl; + + interface IDiaSegment + { + CONST_VTBL struct IDiaSegmentVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaSegment_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaSegment_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaSegment_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaSegment_get_frame(This,pRetVal) \ + ( (This)->lpVtbl -> get_frame(This,pRetVal) ) + +#define IDiaSegment_get_offset(This,pRetVal) \ + ( (This)->lpVtbl -> get_offset(This,pRetVal) ) + +#define IDiaSegment_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaSegment_get_read(This,pRetVal) \ + ( (This)->lpVtbl -> get_read(This,pRetVal) ) + +#define IDiaSegment_get_write(This,pRetVal) \ + ( (This)->lpVtbl -> get_write(This,pRetVal) ) + +#define IDiaSegment_get_execute(This,pRetVal) \ + ( (This)->lpVtbl -> get_execute(This,pRetVal) ) + +#define IDiaSegment_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaSegment_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaSegment_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaSegment_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaInjectedSource_INTERFACE_DEFINED__ +#define __IDiaInjectedSource_INTERFACE_DEFINED__ + +/* interface IDiaInjectedSource */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaInjectedSource; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("AE605CDC-8105-4a23-B710-3259F1E26112") + IDiaInjectedSource : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_crc( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_filename( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_objectFilename( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualFilename( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sourceCompression( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_source( + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaInjectedSourceVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaInjectedSource * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaInjectedSource * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaInjectedSource * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_crc )( + IDiaInjectedSource * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )( + IDiaInjectedSource * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_filename )( + IDiaInjectedSource * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFilename )( + IDiaInjectedSource * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualFilename )( + IDiaInjectedSource * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceCompression )( + IDiaInjectedSource * This, + /* [retval][out] */ DWORD *pRetVal); + + HRESULT ( STDMETHODCALLTYPE *get_source )( + IDiaInjectedSource * This, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + END_INTERFACE + } IDiaInjectedSourceVtbl; + + interface IDiaInjectedSource + { + CONST_VTBL struct IDiaInjectedSourceVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaInjectedSource_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaInjectedSource_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaInjectedSource_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaInjectedSource_get_crc(This,pRetVal) \ + ( (This)->lpVtbl -> get_crc(This,pRetVal) ) + +#define IDiaInjectedSource_get_length(This,pRetVal) \ + ( (This)->lpVtbl -> get_length(This,pRetVal) ) + +#define IDiaInjectedSource_get_filename(This,pRetVal) \ + ( (This)->lpVtbl -> get_filename(This,pRetVal) ) + +#define IDiaInjectedSource_get_objectFilename(This,pRetVal) \ + ( (This)->lpVtbl -> get_objectFilename(This,pRetVal) ) + +#define IDiaInjectedSource_get_virtualFilename(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualFilename(This,pRetVal) ) + +#define IDiaInjectedSource_get_sourceCompression(This,pRetVal) \ + ( (This)->lpVtbl -> get_sourceCompression(This,pRetVal) ) + +#define IDiaInjectedSource_get_source(This,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> get_source(This,cbData,pcbData,pbData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaInjectedSource_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dia2_0000_0031 */ +/* [local] */ + + +enum __MIDL___MIDL_itf_dia2_0000_0031_0001 + { + E_DIA_INPROLOG = ( HRESULT )(( ( ( ( unsigned long )1 << 31 ) | ( ( unsigned long )( LONG )0x6d << 16 ) ) | ( unsigned long )100 ) ), + E_DIA_SYNTAX = ( E_DIA_INPROLOG + 1 ) , + E_DIA_FRAME_ACCESS = ( E_DIA_SYNTAX + 1 ) , + E_DIA_VALUE = ( E_DIA_FRAME_ACCESS + 1 ) + } ; + + +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0031_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0031_v0_0_s_ifspec; + +#ifndef __IDiaStackWalkFrame_INTERFACE_DEFINED__ +#define __IDiaStackWalkFrame_INTERFACE_DEFINED__ + +/* interface IDiaStackWalkFrame */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaStackWalkFrame; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("07C590C1-438D-4F47-BDCD-4397BC81AD75") + IDiaStackWalkFrame : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerValue( + /* [in] */ DWORD index, + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_registerValue( + /* [in] */ DWORD index, + /* [in] */ ULONGLONG NewVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE readMemory( + /* [in] */ enum MemoryTypeEnum type, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + virtual HRESULT STDMETHODCALLTYPE searchForReturnAddress( + /* [in] */ IDiaFrameData *frame, + /* [out] */ ULONGLONG *returnAddress) = 0; + + virtual HRESULT STDMETHODCALLTYPE searchForReturnAddressStart( + /* [in] */ IDiaFrameData *frame, + /* [in] */ ULONGLONG startAddress, + /* [out] */ ULONGLONG *returnAddress) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaStackWalkFrameVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaStackWalkFrame * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaStackWalkFrame * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaStackWalkFrame * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerValue )( + IDiaStackWalkFrame * This, + /* [in] */ DWORD index, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_registerValue )( + IDiaStackWalkFrame * This, + /* [in] */ DWORD index, + /* [in] */ ULONGLONG NewVal); + + HRESULT ( STDMETHODCALLTYPE *readMemory )( + IDiaStackWalkFrame * This, + /* [in] */ enum MemoryTypeEnum type, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *searchForReturnAddress )( + IDiaStackWalkFrame * This, + /* [in] */ IDiaFrameData *frame, + /* [out] */ ULONGLONG *returnAddress); + + HRESULT ( STDMETHODCALLTYPE *searchForReturnAddressStart )( + IDiaStackWalkFrame * This, + /* [in] */ IDiaFrameData *frame, + /* [in] */ ULONGLONG startAddress, + /* [out] */ ULONGLONG *returnAddress); + + END_INTERFACE + } IDiaStackWalkFrameVtbl; + + interface IDiaStackWalkFrame + { + CONST_VTBL struct IDiaStackWalkFrameVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaStackWalkFrame_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaStackWalkFrame_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaStackWalkFrame_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaStackWalkFrame_get_registerValue(This,index,pRetVal) \ + ( (This)->lpVtbl -> get_registerValue(This,index,pRetVal) ) + +#define IDiaStackWalkFrame_put_registerValue(This,index,NewVal) \ + ( (This)->lpVtbl -> put_registerValue(This,index,NewVal) ) + +#define IDiaStackWalkFrame_readMemory(This,type,va,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> readMemory(This,type,va,cbData,pcbData,pbData) ) + +#define IDiaStackWalkFrame_searchForReturnAddress(This,frame,returnAddress) \ + ( (This)->lpVtbl -> searchForReturnAddress(This,frame,returnAddress) ) + +#define IDiaStackWalkFrame_searchForReturnAddressStart(This,frame,startAddress,returnAddress) \ + ( (This)->lpVtbl -> searchForReturnAddressStart(This,frame,startAddress,returnAddress) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaStackWalkFrame_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaFrameData_INTERFACE_DEFINED__ +#define __IDiaFrameData_INTERFACE_DEFINED__ + +/* interface IDiaFrameData */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaFrameData; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A39184B7-6A36-42de-8EEC-7DF9F3F59F33") + IDiaFrameData : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressOffset( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthBlock( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthLocals( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthParams( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_maxStack( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthProlog( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthSavedRegisters( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_program( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_systemExceptionHandling( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_cplusplusExceptionHandling( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_functionStart( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_allocatesBasePointer( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_type( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_functionParent( + /* [retval][out] */ IDiaFrameData **pRetVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE execute( + IDiaStackWalkFrame *frame) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaFrameDataVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaFrameData * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaFrameData * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaFrameData * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaFrameData * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthBlock )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthLocals )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthParams )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_maxStack )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthProlog )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthSavedRegisters )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_program )( + IDiaFrameData * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_systemExceptionHandling )( + IDiaFrameData * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_cplusplusExceptionHandling )( + IDiaFrameData * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_functionStart )( + IDiaFrameData * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_allocatesBasePointer )( + IDiaFrameData * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaFrameData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_functionParent )( + IDiaFrameData * This, + /* [retval][out] */ IDiaFrameData **pRetVal); + + HRESULT ( STDMETHODCALLTYPE *execute )( + IDiaFrameData * This, + IDiaStackWalkFrame *frame); + + END_INTERFACE + } IDiaFrameDataVtbl; + + interface IDiaFrameData + { + CONST_VTBL struct IDiaFrameDataVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaFrameData_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaFrameData_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaFrameData_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaFrameData_get_addressSection(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressSection(This,pRetVal) ) + +#define IDiaFrameData_get_addressOffset(This,pRetVal) \ + ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) ) + +#define IDiaFrameData_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaFrameData_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaFrameData_get_lengthBlock(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthBlock(This,pRetVal) ) + +#define IDiaFrameData_get_lengthLocals(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthLocals(This,pRetVal) ) + +#define IDiaFrameData_get_lengthParams(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthParams(This,pRetVal) ) + +#define IDiaFrameData_get_maxStack(This,pRetVal) \ + ( (This)->lpVtbl -> get_maxStack(This,pRetVal) ) + +#define IDiaFrameData_get_lengthProlog(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthProlog(This,pRetVal) ) + +#define IDiaFrameData_get_lengthSavedRegisters(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthSavedRegisters(This,pRetVal) ) + +#define IDiaFrameData_get_program(This,pRetVal) \ + ( (This)->lpVtbl -> get_program(This,pRetVal) ) + +#define IDiaFrameData_get_systemExceptionHandling(This,pRetVal) \ + ( (This)->lpVtbl -> get_systemExceptionHandling(This,pRetVal) ) + +#define IDiaFrameData_get_cplusplusExceptionHandling(This,pRetVal) \ + ( (This)->lpVtbl -> get_cplusplusExceptionHandling(This,pRetVal) ) + +#define IDiaFrameData_get_functionStart(This,pRetVal) \ + ( (This)->lpVtbl -> get_functionStart(This,pRetVal) ) + +#define IDiaFrameData_get_allocatesBasePointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_allocatesBasePointer(This,pRetVal) ) + +#define IDiaFrameData_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaFrameData_get_functionParent(This,pRetVal) \ + ( (This)->lpVtbl -> get_functionParent(This,pRetVal) ) + +#define IDiaFrameData_execute(This,frame) \ + ( (This)->lpVtbl -> execute(This,frame) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaFrameData_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaImageData_INTERFACE_DEFINED__ +#define __IDiaImageData_INTERFACE_DEFINED__ + +/* interface IDiaImageData */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaImageData; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C8E40ED2-A1D9-4221-8692-3CE661184B44") + IDiaImageData : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_imageBase( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaImageDataVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaImageData * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaImageData * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaImageData * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )( + IDiaImageData * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )( + IDiaImageData * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_imageBase )( + IDiaImageData * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + END_INTERFACE + } IDiaImageDataVtbl; + + interface IDiaImageData + { + CONST_VTBL struct IDiaImageDataVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaImageData_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaImageData_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaImageData_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaImageData_get_relativeVirtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) ) + +#define IDiaImageData_get_virtualAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) ) + +#define IDiaImageData_get_imageBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_imageBase(This,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaImageData_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaTable_INTERFACE_DEFINED__ +#define __IDiaTable_INTERFACE_DEFINED__ + +/* interface IDiaTable */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaTable; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4A59FB77-ABAC-469b-A30B-9ECC85BFEF14") + IDiaTable : public IEnumUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_name( + /* [retval][out] */ BSTR *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ DWORD index, + /* [retval][out] */ IUnknown **element) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaTableVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaTable * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaTable * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaTable * This); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaTable * This, + /* [annotation][in] */ + _In_ ULONG celt, + /* [annotation][out] */ + _Out_writes_to_(celt,*pceltFetched) IUnknown **rgelt, + /* [annotation][out] */ + _Out_opt_ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaTable * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaTable * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaTable * This, + /* [out] */ IEnumUnknown **ppenum); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaTable * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )( + IDiaTable * This, + /* [retval][out] */ BSTR *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaTable * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaTable * This, + /* [in] */ DWORD index, + /* [retval][out] */ IUnknown **element); + + END_INTERFACE + } IDiaTableVtbl; + + interface IDiaTable + { + CONST_VTBL struct IDiaTableVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaTable_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaTable_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaTable_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaTable_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaTable_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaTable_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaTable_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + + +#define IDiaTable_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaTable_get_name(This,pRetVal) \ + ( (This)->lpVtbl -> get_name(This,pRetVal) ) + +#define IDiaTable_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaTable_Item(This,index,element) \ + ( (This)->lpVtbl -> Item(This,index,element) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaTable_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumTables_INTERFACE_DEFINED__ +#define __IDiaEnumTables_INTERFACE_DEFINED__ + +/* interface IDiaEnumTables */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumTables; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C65C2B0A-1150-4d7a-AFCC-E05BF3DEE81E") + IDiaEnumTables : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum( + /* [retval][out] */ IUnknown **pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count( + /* [retval][out] */ LONG *pRetVal) = 0; + + virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item( + /* [in] */ VARIANT index, + /* [retval][out] */ IDiaTable **table) = 0; + + virtual HRESULT STDMETHODCALLTYPE Next( + ULONG celt, + IDiaTable **rgelt, + ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Skip( + /* [in] */ ULONG celt) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ IDiaEnumTables **ppenum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumTablesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumTables * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumTables * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumTables * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )( + IDiaEnumTables * This, + /* [retval][out] */ IUnknown **pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )( + IDiaEnumTables * This, + /* [retval][out] */ LONG *pRetVal); + + /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )( + IDiaEnumTables * This, + /* [in] */ VARIANT index, + /* [retval][out] */ IDiaTable **table); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumTables * This, + ULONG celt, + IDiaTable **rgelt, + ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Skip )( + IDiaEnumTables * This, + /* [in] */ ULONG celt); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumTables * This); + + HRESULT ( STDMETHODCALLTYPE *Clone )( + IDiaEnumTables * This, + /* [out] */ IDiaEnumTables **ppenum); + + END_INTERFACE + } IDiaEnumTablesVtbl; + + interface IDiaEnumTables + { + CONST_VTBL struct IDiaEnumTablesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumTables_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumTables_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumTables_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumTables_get__NewEnum(This,pRetVal) \ + ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) ) + +#define IDiaEnumTables_get_Count(This,pRetVal) \ + ( (This)->lpVtbl -> get_Count(This,pRetVal) ) + +#define IDiaEnumTables_Item(This,index,table) \ + ( (This)->lpVtbl -> Item(This,index,table) ) + +#define IDiaEnumTables_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumTables_Skip(This,celt) \ + ( (This)->lpVtbl -> Skip(This,celt) ) + +#define IDiaEnumTables_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#define IDiaEnumTables_Clone(This,ppenum) \ + ( (This)->lpVtbl -> Clone(This,ppenum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumTables_INTERFACE_DEFINED__ */ + + + +#ifndef __Dia2Lib_LIBRARY_DEFINED__ +#define __Dia2Lib_LIBRARY_DEFINED__ + +/* library Dia2Lib */ +/* [helpstring][version][uuid] */ + + + + + +EXTERN_C const IID LIBID_Dia2Lib; + +EXTERN_C const CLSID CLSID_DiaSource; + +#ifdef __cplusplus + +class DECLSPEC_UUID("e6756135-1e65-4d17-8576-610761398c3c") +DiaSource; +#endif + +EXTERN_C const CLSID CLSID_DiaSourceAlt; + +#ifdef __cplusplus + +class DECLSPEC_UUID("91904831-49ca-4766-b95c-25397e2dd6dc") +DiaSourceAlt; +#endif + +EXTERN_C const CLSID CLSID_DiaStackWalker; + +#ifdef __cplusplus + +class DECLSPEC_UUID("ce4a85db-5768-475b-a4e1-c0bca2112a6b") +DiaStackWalker; +#endif +#endif /* __Dia2Lib_LIBRARY_DEFINED__ */ + +/* interface __MIDL_itf_dia2_0000_0037 */ +/* [local] */ + +#define DiaTable_Symbols ( L"Symbols" ) + +#define DiaTable_Sections ( L"Sections" ) + +#define DiaTable_SrcFiles ( L"SourceFiles" ) + +#define DiaTable_LineNums ( L"LineNumbers" ) + +#define DiaTable_SegMap ( L"SegmentMap" ) + +#define DiaTable_Dbg ( L"Dbg" ) + +#define DiaTable_InjSrc ( L"InjectedSource" ) + +#define DiaTable_FrameData ( L"FrameData" ) + +#define DiaTable_InputAssemblyFiles ( L"InputAssemblyFiles" ) + + + +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0037_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0037_v0_0_s_ifspec; + +#ifndef __IDiaPropertyStorage_INTERFACE_DEFINED__ +#define __IDiaPropertyStorage_INTERFACE_DEFINED__ + +/* interface IDiaPropertyStorage */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaPropertyStorage; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9d416f9c-e184-45b2-a4f0-ce517f719e9b") + IDiaPropertyStorage : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE ReadMultiple( + /* [in] */ ULONG cpspec, + /* [size_is][in] */ const PROPSPEC *rgpspec, + /* [size_is][out] */ PROPVARIANT *rgvar) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReadPropertyNames( + /* [in] */ ULONG cpropid, + /* [size_is][in] */ const PROPID *rgpropid, + /* [size_is][out][in] */ BSTR *rglpwstrName) = 0; + + virtual HRESULT STDMETHODCALLTYPE Enum( + /* [out] */ IEnumSTATPROPSTG **ppenum) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReadDWORD( + /* [in] */ PROPID id, + /* [out] */ DWORD *pValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReadLONG( + /* [in] */ PROPID id, + /* [out] */ LONG *pValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReadBOOL( + /* [in] */ PROPID id, + /* [out] */ BOOL *pValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReadULONGLONG( + /* [in] */ PROPID id, + /* [out] */ ULONGLONG *pValue) = 0; + + virtual HRESULT STDMETHODCALLTYPE ReadBSTR( + /* [in] */ PROPID id, + /* [out] */ BSTR *pValue) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaPropertyStorageVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaPropertyStorage * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaPropertyStorage * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaPropertyStorage * This); + + HRESULT ( STDMETHODCALLTYPE *ReadMultiple )( + IDiaPropertyStorage * This, + /* [in] */ ULONG cpspec, + /* [size_is][in] */ const PROPSPEC *rgpspec, + /* [size_is][out] */ PROPVARIANT *rgvar); + + HRESULT ( STDMETHODCALLTYPE *ReadPropertyNames )( + IDiaPropertyStorage * This, + /* [in] */ ULONG cpropid, + /* [size_is][in] */ const PROPID *rgpropid, + /* [size_is][out][in] */ BSTR *rglpwstrName); + + HRESULT ( STDMETHODCALLTYPE *Enum )( + IDiaPropertyStorage * This, + /* [out] */ IEnumSTATPROPSTG **ppenum); + + HRESULT ( STDMETHODCALLTYPE *ReadDWORD )( + IDiaPropertyStorage * This, + /* [in] */ PROPID id, + /* [out] */ DWORD *pValue); + + HRESULT ( STDMETHODCALLTYPE *ReadLONG )( + IDiaPropertyStorage * This, + /* [in] */ PROPID id, + /* [out] */ LONG *pValue); + + HRESULT ( STDMETHODCALLTYPE *ReadBOOL )( + IDiaPropertyStorage * This, + /* [in] */ PROPID id, + /* [out] */ BOOL *pValue); + + HRESULT ( STDMETHODCALLTYPE *ReadULONGLONG )( + IDiaPropertyStorage * This, + /* [in] */ PROPID id, + /* [out] */ ULONGLONG *pValue); + + HRESULT ( STDMETHODCALLTYPE *ReadBSTR )( + IDiaPropertyStorage * This, + /* [in] */ PROPID id, + /* [out] */ BSTR *pValue); + + END_INTERFACE + } IDiaPropertyStorageVtbl; + + interface IDiaPropertyStorage + { + CONST_VTBL struct IDiaPropertyStorageVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaPropertyStorage_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaPropertyStorage_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaPropertyStorage_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaPropertyStorage_ReadMultiple(This,cpspec,rgpspec,rgvar) \ + ( (This)->lpVtbl -> ReadMultiple(This,cpspec,rgpspec,rgvar) ) + +#define IDiaPropertyStorage_ReadPropertyNames(This,cpropid,rgpropid,rglpwstrName) \ + ( (This)->lpVtbl -> ReadPropertyNames(This,cpropid,rgpropid,rglpwstrName) ) + +#define IDiaPropertyStorage_Enum(This,ppenum) \ + ( (This)->lpVtbl -> Enum(This,ppenum) ) + +#define IDiaPropertyStorage_ReadDWORD(This,id,pValue) \ + ( (This)->lpVtbl -> ReadDWORD(This,id,pValue) ) + +#define IDiaPropertyStorage_ReadLONG(This,id,pValue) \ + ( (This)->lpVtbl -> ReadLONG(This,id,pValue) ) + +#define IDiaPropertyStorage_ReadBOOL(This,id,pValue) \ + ( (This)->lpVtbl -> ReadBOOL(This,id,pValue) ) + +#define IDiaPropertyStorage_ReadULONGLONG(This,id,pValue) \ + ( (This)->lpVtbl -> ReadULONGLONG(This,id,pValue) ) + +#define IDiaPropertyStorage_ReadBSTR(This,id,pValue) \ + ( (This)->lpVtbl -> ReadBSTR(This,id,pValue) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaPropertyStorage_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaStackFrame_INTERFACE_DEFINED__ +#define __IDiaStackFrame_INTERFACE_DEFINED__ + +/* interface IDiaStackFrame */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaStackFrame; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5edbc96d-cdd6-4792-afbe-cc89007d9610") + IDiaStackFrame : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_type( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_base( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_size( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_returnAddress( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_localsBase( + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthLocals( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthParams( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthProlog( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthSavedRegisters( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_systemExceptionHandling( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_cplusplusExceptionHandling( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_functionStart( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_allocatesBasePointer( + /* [retval][out] */ BOOL *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_maxStack( + /* [retval][out] */ DWORD *pRetVal) = 0; + + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerValue( + /* [in] */ DWORD index, + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaStackFrameVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaStackFrame * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaStackFrame * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaStackFrame * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )( + IDiaStackFrame * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_base )( + IDiaStackFrame * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_size )( + IDiaStackFrame * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_returnAddress )( + IDiaStackFrame * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localsBase )( + IDiaStackFrame * This, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthLocals )( + IDiaStackFrame * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthParams )( + IDiaStackFrame * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthProlog )( + IDiaStackFrame * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthSavedRegisters )( + IDiaStackFrame * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_systemExceptionHandling )( + IDiaStackFrame * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_cplusplusExceptionHandling )( + IDiaStackFrame * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_functionStart )( + IDiaStackFrame * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_allocatesBasePointer )( + IDiaStackFrame * This, + /* [retval][out] */ BOOL *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_maxStack )( + IDiaStackFrame * This, + /* [retval][out] */ DWORD *pRetVal); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerValue )( + IDiaStackFrame * This, + /* [in] */ DWORD index, + /* [retval][out] */ ULONGLONG *pRetVal); + + END_INTERFACE + } IDiaStackFrameVtbl; + + interface IDiaStackFrame + { + CONST_VTBL struct IDiaStackFrameVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaStackFrame_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaStackFrame_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaStackFrame_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaStackFrame_get_type(This,pRetVal) \ + ( (This)->lpVtbl -> get_type(This,pRetVal) ) + +#define IDiaStackFrame_get_base(This,pRetVal) \ + ( (This)->lpVtbl -> get_base(This,pRetVal) ) + +#define IDiaStackFrame_get_size(This,pRetVal) \ + ( (This)->lpVtbl -> get_size(This,pRetVal) ) + +#define IDiaStackFrame_get_returnAddress(This,pRetVal) \ + ( (This)->lpVtbl -> get_returnAddress(This,pRetVal) ) + +#define IDiaStackFrame_get_localsBase(This,pRetVal) \ + ( (This)->lpVtbl -> get_localsBase(This,pRetVal) ) + +#define IDiaStackFrame_get_lengthLocals(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthLocals(This,pRetVal) ) + +#define IDiaStackFrame_get_lengthParams(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthParams(This,pRetVal) ) + +#define IDiaStackFrame_get_lengthProlog(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthProlog(This,pRetVal) ) + +#define IDiaStackFrame_get_lengthSavedRegisters(This,pRetVal) \ + ( (This)->lpVtbl -> get_lengthSavedRegisters(This,pRetVal) ) + +#define IDiaStackFrame_get_systemExceptionHandling(This,pRetVal) \ + ( (This)->lpVtbl -> get_systemExceptionHandling(This,pRetVal) ) + +#define IDiaStackFrame_get_cplusplusExceptionHandling(This,pRetVal) \ + ( (This)->lpVtbl -> get_cplusplusExceptionHandling(This,pRetVal) ) + +#define IDiaStackFrame_get_functionStart(This,pRetVal) \ + ( (This)->lpVtbl -> get_functionStart(This,pRetVal) ) + +#define IDiaStackFrame_get_allocatesBasePointer(This,pRetVal) \ + ( (This)->lpVtbl -> get_allocatesBasePointer(This,pRetVal) ) + +#define IDiaStackFrame_get_maxStack(This,pRetVal) \ + ( (This)->lpVtbl -> get_maxStack(This,pRetVal) ) + +#define IDiaStackFrame_get_registerValue(This,index,pRetVal) \ + ( (This)->lpVtbl -> get_registerValue(This,index,pRetVal) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaStackFrame_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaEnumStackFrames_INTERFACE_DEFINED__ +#define __IDiaEnumStackFrames_INTERFACE_DEFINED__ + +/* interface IDiaEnumStackFrames */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaEnumStackFrames; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("ec9d461d-ce74-4711-a020-7d8f9a1dd255") + IDiaEnumStackFrames : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE Next( + /* [in] */ ULONG celt, + /* [out] */ IDiaStackFrame **rgelt, + /* [out] */ ULONG *pceltFetched) = 0; + + virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaEnumStackFramesVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaEnumStackFrames * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaEnumStackFrames * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaEnumStackFrames * This); + + HRESULT ( STDMETHODCALLTYPE *Next )( + IDiaEnumStackFrames * This, + /* [in] */ ULONG celt, + /* [out] */ IDiaStackFrame **rgelt, + /* [out] */ ULONG *pceltFetched); + + HRESULT ( STDMETHODCALLTYPE *Reset )( + IDiaEnumStackFrames * This); + + END_INTERFACE + } IDiaEnumStackFramesVtbl; + + interface IDiaEnumStackFrames + { + CONST_VTBL struct IDiaEnumStackFramesVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaEnumStackFrames_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaEnumStackFrames_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaEnumStackFrames_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaEnumStackFrames_Next(This,celt,rgelt,pceltFetched) \ + ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) ) + +#define IDiaEnumStackFrames_Reset(This) \ + ( (This)->lpVtbl -> Reset(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaEnumStackFrames_INTERFACE_DEFINED__ */ + + +/* interface __MIDL_itf_dia2_0000_0040 */ +/* [local] */ + +typedef /* [public] */ struct __MIDL___MIDL_itf_dia2_0000_0040_0001 + { + DWORD ulOffStart; + DWORD cbProcSize; + DWORD cdwLocals; + WORD cdwParams; + WORD cdwFlags; + } FPODATA; + + + +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0040_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0040_v0_0_s_ifspec; + +#ifndef __IDiaStackWalkHelper_INTERFACE_DEFINED__ +#define __IDiaStackWalkHelper_INTERFACE_DEFINED__ + +/* interface IDiaStackWalkHelper */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaStackWalkHelper; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("21F81B1B-C5BB-42A3-BC4F-CCBAA75B9F19") + IDiaStackWalkHelper : public IUnknown + { + public: + virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerValue( + /* [in] */ DWORD index, + /* [retval][out] */ ULONGLONG *pRetVal) = 0; + + virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_registerValue( + /* [in] */ DWORD index, + /* [in] */ ULONGLONG NewVal) = 0; + + virtual HRESULT STDMETHODCALLTYPE readMemory( + /* [in] */ enum MemoryTypeEnum type, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + virtual HRESULT STDMETHODCALLTYPE searchForReturnAddress( + /* [in] */ IDiaFrameData *frame, + /* [out] */ ULONGLONG *returnAddress) = 0; + + virtual HRESULT STDMETHODCALLTYPE searchForReturnAddressStart( + /* [in] */ IDiaFrameData *frame, + /* [in] */ ULONGLONG startAddress, + /* [out] */ ULONGLONG *returnAddress) = 0; + + virtual HRESULT STDMETHODCALLTYPE frameForVA( + /* [in] */ ULONGLONG va, + /* [out] */ IDiaFrameData **ppFrame) = 0; + + virtual HRESULT STDMETHODCALLTYPE symbolForVA( + /* [in] */ ULONGLONG va, + /* [out] */ IDiaSymbol **ppSymbol) = 0; + + virtual HRESULT STDMETHODCALLTYPE pdataForVA( + /* [in] */ ULONGLONG va, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData) = 0; + + virtual HRESULT STDMETHODCALLTYPE imageForVA( + /* [in] */ ULONGLONG vaContext, + /* [out] */ ULONGLONG *pvaImageStart) = 0; + + virtual HRESULT STDMETHODCALLTYPE addressForVA( + /* [in] */ ULONGLONG va, + /* [out] */ DWORD *pISect, + /* [out] */ DWORD *pOffset) = 0; + + virtual HRESULT STDMETHODCALLTYPE numberOfFunctionFragmentsForVA( + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [out] */ DWORD *pNumFragments) = 0; + + virtual HRESULT STDMETHODCALLTYPE functionFragmentsForVA( + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [in] */ DWORD cFragments, + /* [out] */ ULONGLONG *pVaFragment, + /* [out] */ DWORD *pLenFragment) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaStackWalkHelperVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaStackWalkHelper * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaStackWalkHelper * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaStackWalkHelper * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerValue )( + IDiaStackWalkHelper * This, + /* [in] */ DWORD index, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_registerValue )( + IDiaStackWalkHelper * This, + /* [in] */ DWORD index, + /* [in] */ ULONGLONG NewVal); + + HRESULT ( STDMETHODCALLTYPE *readMemory )( + IDiaStackWalkHelper * This, + /* [in] */ enum MemoryTypeEnum type, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *searchForReturnAddress )( + IDiaStackWalkHelper * This, + /* [in] */ IDiaFrameData *frame, + /* [out] */ ULONGLONG *returnAddress); + + HRESULT ( STDMETHODCALLTYPE *searchForReturnAddressStart )( + IDiaStackWalkHelper * This, + /* [in] */ IDiaFrameData *frame, + /* [in] */ ULONGLONG startAddress, + /* [out] */ ULONGLONG *returnAddress); + + HRESULT ( STDMETHODCALLTYPE *frameForVA )( + IDiaStackWalkHelper * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaFrameData **ppFrame); + + HRESULT ( STDMETHODCALLTYPE *symbolForVA )( + IDiaStackWalkHelper * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaSymbol **ppSymbol); + + HRESULT ( STDMETHODCALLTYPE *pdataForVA )( + IDiaStackWalkHelper * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *imageForVA )( + IDiaStackWalkHelper * This, + /* [in] */ ULONGLONG vaContext, + /* [out] */ ULONGLONG *pvaImageStart); + + HRESULT ( STDMETHODCALLTYPE *addressForVA )( + IDiaStackWalkHelper * This, + /* [in] */ ULONGLONG va, + /* [out] */ DWORD *pISect, + /* [out] */ DWORD *pOffset); + + HRESULT ( STDMETHODCALLTYPE *numberOfFunctionFragmentsForVA )( + IDiaStackWalkHelper * This, + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [out] */ DWORD *pNumFragments); + + HRESULT ( STDMETHODCALLTYPE *functionFragmentsForVA )( + IDiaStackWalkHelper * This, + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [in] */ DWORD cFragments, + /* [out] */ ULONGLONG *pVaFragment, + /* [out] */ DWORD *pLenFragment); + + END_INTERFACE + } IDiaStackWalkHelperVtbl; + + interface IDiaStackWalkHelper + { + CONST_VTBL struct IDiaStackWalkHelperVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaStackWalkHelper_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaStackWalkHelper_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaStackWalkHelper_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaStackWalkHelper_get_registerValue(This,index,pRetVal) \ + ( (This)->lpVtbl -> get_registerValue(This,index,pRetVal) ) + +#define IDiaStackWalkHelper_put_registerValue(This,index,NewVal) \ + ( (This)->lpVtbl -> put_registerValue(This,index,NewVal) ) + +#define IDiaStackWalkHelper_readMemory(This,type,va,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> readMemory(This,type,va,cbData,pcbData,pbData) ) + +#define IDiaStackWalkHelper_searchForReturnAddress(This,frame,returnAddress) \ + ( (This)->lpVtbl -> searchForReturnAddress(This,frame,returnAddress) ) + +#define IDiaStackWalkHelper_searchForReturnAddressStart(This,frame,startAddress,returnAddress) \ + ( (This)->lpVtbl -> searchForReturnAddressStart(This,frame,startAddress,returnAddress) ) + +#define IDiaStackWalkHelper_frameForVA(This,va,ppFrame) \ + ( (This)->lpVtbl -> frameForVA(This,va,ppFrame) ) + +#define IDiaStackWalkHelper_symbolForVA(This,va,ppSymbol) \ + ( (This)->lpVtbl -> symbolForVA(This,va,ppSymbol) ) + +#define IDiaStackWalkHelper_pdataForVA(This,va,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> pdataForVA(This,va,cbData,pcbData,pbData) ) + +#define IDiaStackWalkHelper_imageForVA(This,vaContext,pvaImageStart) \ + ( (This)->lpVtbl -> imageForVA(This,vaContext,pvaImageStart) ) + +#define IDiaStackWalkHelper_addressForVA(This,va,pISect,pOffset) \ + ( (This)->lpVtbl -> addressForVA(This,va,pISect,pOffset) ) + +#define IDiaStackWalkHelper_numberOfFunctionFragmentsForVA(This,vaFunc,cbFunc,pNumFragments) \ + ( (This)->lpVtbl -> numberOfFunctionFragmentsForVA(This,vaFunc,cbFunc,pNumFragments) ) + +#define IDiaStackWalkHelper_functionFragmentsForVA(This,vaFunc,cbFunc,cFragments,pVaFragment,pLenFragment) \ + ( (This)->lpVtbl -> functionFragmentsForVA(This,vaFunc,cbFunc,cFragments,pVaFragment,pLenFragment) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaStackWalkHelper_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaStackWalker_INTERFACE_DEFINED__ +#define __IDiaStackWalker_INTERFACE_DEFINED__ + +/* interface IDiaStackWalker */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaStackWalker; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("5485216b-a54c-469f-9670-52b24d5229bb") + IDiaStackWalker : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE getEnumFrames( + /* [in] */ IDiaStackWalkHelper *pHelper, + /* [out] */ IDiaEnumStackFrames **ppEnum) = 0; + + virtual HRESULT STDMETHODCALLTYPE getEnumFrames2( + /* [in] */ enum CV_CPU_TYPE_e cpuid, + /* [in] */ IDiaStackWalkHelper *pHelper, + /* [out] */ IDiaEnumStackFrames **ppEnum) = 0; + + }; + + +#else /* C style interface */ + + typedef struct IDiaStackWalkerVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaStackWalker * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaStackWalker * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaStackWalker * This); + + HRESULT ( STDMETHODCALLTYPE *getEnumFrames )( + IDiaStackWalker * This, + /* [in] */ IDiaStackWalkHelper *pHelper, + /* [out] */ IDiaEnumStackFrames **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *getEnumFrames2 )( + IDiaStackWalker * This, + /* [in] */ enum CV_CPU_TYPE_e cpuid, + /* [in] */ IDiaStackWalkHelper *pHelper, + /* [out] */ IDiaEnumStackFrames **ppEnum); + + END_INTERFACE + } IDiaStackWalkerVtbl; + + interface IDiaStackWalker + { + CONST_VTBL struct IDiaStackWalkerVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaStackWalker_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaStackWalker_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaStackWalker_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaStackWalker_getEnumFrames(This,pHelper,ppEnum) \ + ( (This)->lpVtbl -> getEnumFrames(This,pHelper,ppEnum) ) + +#define IDiaStackWalker_getEnumFrames2(This,cpuid,pHelper,ppEnum) \ + ( (This)->lpVtbl -> getEnumFrames2(This,cpuid,pHelper,ppEnum) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaStackWalker_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaStackWalkHelper2_INTERFACE_DEFINED__ +#define __IDiaStackWalkHelper2_INTERFACE_DEFINED__ + +/* interface IDiaStackWalkHelper2 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaStackWalkHelper2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8222c490-507b-4bef-b3bd-41dca7b5934c") + IDiaStackWalkHelper2 : public IDiaStackWalkHelper + { + public: + }; + + +#else /* C style interface */ + + typedef struct IDiaStackWalkHelper2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaStackWalkHelper2 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaStackWalkHelper2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaStackWalkHelper2 * This); + + /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerValue )( + IDiaStackWalkHelper2 * This, + /* [in] */ DWORD index, + /* [retval][out] */ ULONGLONG *pRetVal); + + /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_registerValue )( + IDiaStackWalkHelper2 * This, + /* [in] */ DWORD index, + /* [in] */ ULONGLONG NewVal); + + HRESULT ( STDMETHODCALLTYPE *readMemory )( + IDiaStackWalkHelper2 * This, + /* [in] */ enum MemoryTypeEnum type, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *searchForReturnAddress )( + IDiaStackWalkHelper2 * This, + /* [in] */ IDiaFrameData *frame, + /* [out] */ ULONGLONG *returnAddress); + + HRESULT ( STDMETHODCALLTYPE *searchForReturnAddressStart )( + IDiaStackWalkHelper2 * This, + /* [in] */ IDiaFrameData *frame, + /* [in] */ ULONGLONG startAddress, + /* [out] */ ULONGLONG *returnAddress); + + HRESULT ( STDMETHODCALLTYPE *frameForVA )( + IDiaStackWalkHelper2 * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaFrameData **ppFrame); + + HRESULT ( STDMETHODCALLTYPE *symbolForVA )( + IDiaStackWalkHelper2 * This, + /* [in] */ ULONGLONG va, + /* [out] */ IDiaSymbol **ppSymbol); + + HRESULT ( STDMETHODCALLTYPE *pdataForVA )( + IDiaStackWalkHelper2 * This, + /* [in] */ ULONGLONG va, + /* [in] */ DWORD cbData, + /* [out] */ DWORD *pcbData, + /* [size_is][out] */ BYTE *pbData); + + HRESULT ( STDMETHODCALLTYPE *imageForVA )( + IDiaStackWalkHelper2 * This, + /* [in] */ ULONGLONG vaContext, + /* [out] */ ULONGLONG *pvaImageStart); + + HRESULT ( STDMETHODCALLTYPE *addressForVA )( + IDiaStackWalkHelper2 * This, + /* [in] */ ULONGLONG va, + /* [out] */ DWORD *pISect, + /* [out] */ DWORD *pOffset); + + HRESULT ( STDMETHODCALLTYPE *numberOfFunctionFragmentsForVA )( + IDiaStackWalkHelper2 * This, + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [out] */ DWORD *pNumFragments); + + HRESULT ( STDMETHODCALLTYPE *functionFragmentsForVA )( + IDiaStackWalkHelper2 * This, + /* [in] */ ULONGLONG vaFunc, + /* [in] */ DWORD cbFunc, + /* [in] */ DWORD cFragments, + /* [out] */ ULONGLONG *pVaFragment, + /* [out] */ DWORD *pLenFragment); + + END_INTERFACE + } IDiaStackWalkHelper2Vtbl; + + interface IDiaStackWalkHelper2 + { + CONST_VTBL struct IDiaStackWalkHelper2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaStackWalkHelper2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaStackWalkHelper2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaStackWalkHelper2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaStackWalkHelper2_get_registerValue(This,index,pRetVal) \ + ( (This)->lpVtbl -> get_registerValue(This,index,pRetVal) ) + +#define IDiaStackWalkHelper2_put_registerValue(This,index,NewVal) \ + ( (This)->lpVtbl -> put_registerValue(This,index,NewVal) ) + +#define IDiaStackWalkHelper2_readMemory(This,type,va,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> readMemory(This,type,va,cbData,pcbData,pbData) ) + +#define IDiaStackWalkHelper2_searchForReturnAddress(This,frame,returnAddress) \ + ( (This)->lpVtbl -> searchForReturnAddress(This,frame,returnAddress) ) + +#define IDiaStackWalkHelper2_searchForReturnAddressStart(This,frame,startAddress,returnAddress) \ + ( (This)->lpVtbl -> searchForReturnAddressStart(This,frame,startAddress,returnAddress) ) + +#define IDiaStackWalkHelper2_frameForVA(This,va,ppFrame) \ + ( (This)->lpVtbl -> frameForVA(This,va,ppFrame) ) + +#define IDiaStackWalkHelper2_symbolForVA(This,va,ppSymbol) \ + ( (This)->lpVtbl -> symbolForVA(This,va,ppSymbol) ) + +#define IDiaStackWalkHelper2_pdataForVA(This,va,cbData,pcbData,pbData) \ + ( (This)->lpVtbl -> pdataForVA(This,va,cbData,pcbData,pbData) ) + +#define IDiaStackWalkHelper2_imageForVA(This,vaContext,pvaImageStart) \ + ( (This)->lpVtbl -> imageForVA(This,vaContext,pvaImageStart) ) + +#define IDiaStackWalkHelper2_addressForVA(This,va,pISect,pOffset) \ + ( (This)->lpVtbl -> addressForVA(This,va,pISect,pOffset) ) + +#define IDiaStackWalkHelper2_numberOfFunctionFragmentsForVA(This,vaFunc,cbFunc,pNumFragments) \ + ( (This)->lpVtbl -> numberOfFunctionFragmentsForVA(This,vaFunc,cbFunc,pNumFragments) ) + +#define IDiaStackWalkHelper2_functionFragmentsForVA(This,vaFunc,cbFunc,cFragments,pVaFragment,pLenFragment) \ + ( (This)->lpVtbl -> functionFragmentsForVA(This,vaFunc,cbFunc,cFragments,pVaFragment,pLenFragment) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaStackWalkHelper2_INTERFACE_DEFINED__ */ + + +#ifndef __IDiaStackWalker2_INTERFACE_DEFINED__ +#define __IDiaStackWalker2_INTERFACE_DEFINED__ + +/* interface IDiaStackWalker2 */ +/* [unique][helpstring][local][uuid][object] */ + + +EXTERN_C const IID IID_IDiaStackWalker2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7c185885-a015-4cac-9411-0f4fb39b1f3a") + IDiaStackWalker2 : public IDiaStackWalker + { + public: + }; + + +#else /* C style interface */ + + typedef struct IDiaStackWalker2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDiaStackWalker2 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDiaStackWalker2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDiaStackWalker2 * This); + + HRESULT ( STDMETHODCALLTYPE *getEnumFrames )( + IDiaStackWalker2 * This, + /* [in] */ IDiaStackWalkHelper *pHelper, + /* [out] */ IDiaEnumStackFrames **ppEnum); + + HRESULT ( STDMETHODCALLTYPE *getEnumFrames2 )( + IDiaStackWalker2 * This, + /* [in] */ enum CV_CPU_TYPE_e cpuid, + /* [in] */ IDiaStackWalkHelper *pHelper, + /* [out] */ IDiaEnumStackFrames **ppEnum); + + END_INTERFACE + } IDiaStackWalker2Vtbl; + + interface IDiaStackWalker2 + { + CONST_VTBL struct IDiaStackWalker2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IDiaStackWalker2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDiaStackWalker2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDiaStackWalker2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDiaStackWalker2_getEnumFrames(This,pHelper,ppEnum) \ + ( (This)->lpVtbl -> getEnumFrames(This,pHelper,ppEnum) ) + +#define IDiaStackWalker2_getEnumFrames2(This,cpuid,pHelper,ppEnum) \ + ( (This)->lpVtbl -> getEnumFrames2(This,cpuid,pHelper,ppEnum) ) + + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IDiaStackWalker2_INTERFACE_DEFINED__ */ + + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/libraries/dia/diacreate.h b/libraries/dia/diacreate.h new file mode 100644 index 0000000..fac6668 --- /dev/null +++ b/libraries/dia/diacreate.h @@ -0,0 +1,42 @@ +// diacreate.h - creation helper functions for DIA initialization +//----------------------------------------------------------------- +// +// Copyright Microsoft Corporation. All Rights Reserved. +// +//--------------------------------------------------------------- +#ifndef _DIACREATE_H_ +#define _DIACREATE_H_ + +// +// Create a dia data source object from the dia dll (by dll name - does not access the registry). +// + +HRESULT STDMETHODCALLTYPE NoRegCoCreate( const __wchar_t *dllName, + REFCLSID rclsid, + REFIID riid, + void **ppv); + +#ifndef _NATIVE_WCHAR_T_DEFINED +#ifdef __cplusplus + +HRESULT STDMETHODCALLTYPE NoRegCoCreate( const wchar_t *dllName, + REFCLSID rclsid, + REFIID riid, + void **ppv) +{ + return NoRegCoCreate( (const __wchar_t *)dllName, rclsid, riid, ppv ); +} + +#endif +#endif + + + +// +// Create a dia data source object from the dia dll (looks up the class id in the registry). +// +HRESULT STDMETHODCALLTYPE NoOleCoCreate( REFCLSID rclsid, + REFIID riid, + void **ppv); + +#endif diff --git a/libraries/dia/lib/amd64/diaguids.lib b/libraries/dia/lib/amd64/diaguids.lib new file mode 100644 index 0000000..077b0c6 Binary files /dev/null and b/libraries/dia/lib/amd64/diaguids.lib differ diff --git a/libraries/dia/lib/arm/diaguids.lib b/libraries/dia/lib/arm/diaguids.lib new file mode 100644 index 0000000..70747c1 Binary files /dev/null and b/libraries/dia/lib/arm/diaguids.lib differ diff --git a/libraries/dia/lib/arm64/diaguids.lib b/libraries/dia/lib/arm64/diaguids.lib new file mode 100644 index 0000000..c862dc2 Binary files /dev/null and b/libraries/dia/lib/arm64/diaguids.lib differ diff --git a/libraries/dia/lib/diaguids.lib b/libraries/dia/lib/diaguids.lib new file mode 100644 index 0000000..13c567d Binary files /dev/null and b/libraries/dia/lib/diaguids.lib differ diff --git a/libraries/wil/Tracelogging.h b/libraries/wil/Tracelogging.h new file mode 100644 index 0000000..a1bde69 --- /dev/null +++ b/libraries/wil/Tracelogging.h @@ -0,0 +1,3925 @@ +#pragma once +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* + +#ifndef __WIL_TRACELOGGING_H_INCLUDED +#define __WIL_TRACELOGGING_H_INCLUDED + +#ifdef _KERNEL_MODE +#error This header is not supported in kernel-mode. +#endif + +// Note that we avoid pulling in STL's memory header from TraceLogging.h through Resource.h as we have +// TraceLogging customers who are still on older versions of STL (without std::shared_ptr<>). +#define RESOURCE_SUPPRESS_STL +#ifndef __WIL_RESULT_INCLUDED +#include +#endif +#undef RESOURCE_SUPPRESS_STL +#include +#include +#include +#ifndef __WIL_TRACELOGGING_CONFIG_H +#include +#endif +#ifndef TRACELOGGING_SUPPRESS_NEW +#include +#endif + +#pragma warning(push) +#pragma warning(disable: 26135) // Missing locking annotation, Caller failing to hold lock + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmicrosoft-template-shadow" +#endif + +#ifndef __TRACELOGGING_TEST_HOOK_ERROR +#define __TRACELOGGING_TEST_HOOK_ERROR(failure) +#define __TRACELOGGING_TEST_HOOK_ACTIVITY_ERROR(failure) +#define __TRACELOGGING_TEST_HOOK_CALLCONTEXT_ERROR(pFailure, hr) +#define __TRACELOGGING_TEST_HOOK_ACTIVITY_START() +#define __TRACELOGGING_TEST_HOOK_ACTIVITY_STOP(pFailure, hr) +#define __TRACELOGGING_TEST_HOOK_SET_ENABLED false +#define __TRACELOGGING_TEST_HOOK_VERIFY_API_TELEMETRY(nameSpace, apiList, specializationList, countArray, numCounters) +#define __TRACELOGGING_TEST_HOOK_API_TELEMETRY_EVENT_DELAY_MS 5000 +#endif + +// For use only within wil\TraceLogging.h: +#define _wiltlg_STRINGIZE(x) _wiltlg_STRINGIZE_imp(x) +#define _wiltlg_STRINGIZE_imp(x) #x +#define _wiltlg_LSTRINGIZE(x) _wiltlg_LSTRINGIZE_imp1(x) +#define _wiltlg_LSTRINGIZE_imp1(x) _wiltlg_LSTRINGIZE_imp2(#x) +#define _wiltlg_LSTRINGIZE_imp2(s) L##s + +/* +Macro __TRACELOGGING_DEFINE_PROVIDER_STORAGE_LINK(name1, name2): +This macro defines a storage link association between two names for use by the +TlgReflector static analysis tool. +*/ +#define __TRACELOGGING_DEFINE_PROVIDER_STORAGE_LINK(name1, name2) \ + __annotation(L"_TlgProviderLink:|" _wiltlg_LSTRINGIZE(__LINE__) L"|Key|" _wiltlg_LSTRINGIZE(name1) L"=" _wiltlg_LSTRINGIZE(name2)) + +// Utility macro for writing relevant fields from a wil::FailureInfo structure into a TraceLoggingWrite +// statement. Most fields are relevant for telemetry or for simple ETW, but there are a few additional +// fields reported via ETW. + +#define __RESULT_TELEMETRY_COMMON_FAILURE_PARAMS(failure) \ + TraceLoggingUInt32((failure).hr, "hresult", "Failure error code"), \ + TraceLoggingString((failure).pszFile, "fileName", "Source code file name where the error occurred"), \ + TraceLoggingUInt32((failure).uLineNumber, "lineNumber", "Line number within the source code file where the error occurred"), \ + TraceLoggingString((failure).pszModule, "module", "Name of the binary where the error occurred"), \ + TraceLoggingUInt32(static_cast((failure).type), "failureType", "Indicates what type of failure was observed (exception, returned error, logged error or fail fast"), \ + TraceLoggingWideString((failure).pszMessage, "message", "Custom message associated with the failure (if any)"), \ + TraceLoggingUInt32((failure).threadId, "threadId", "Identifier of the thread the error occurred on"), \ + TraceLoggingString((failure).pszCallContext, "callContext", "List of telemetry activities containing this error"), \ + TraceLoggingUInt32((failure).callContextOriginating.contextId, "originatingContextId", "Identifier for the oldest telemetry activity containing this error"), \ + TraceLoggingString((failure).callContextOriginating.contextName, "originatingContextName", "Name of the oldest telemetry activity containing this error"), \ + TraceLoggingWideString((failure).callContextOriginating.contextMessage, "originatingContextMessage", "Custom message associated with the oldest telemetry activity containing this error (if any)"), \ + TraceLoggingUInt32((failure).callContextCurrent.contextId, "currentContextId", "Identifier for the newest telemetry activity containing this error"), \ + TraceLoggingString((failure).callContextCurrent.contextName, "currentContextName", "Name of the newest telemetry activity containing this error"), \ + TraceLoggingWideString((failure).callContextCurrent.contextMessage, "currentContextMessage", "Custom message associated with the newest telemetry activity containing this error (if any)") + +#define __RESULT_TRACELOGGING_COMMON_FAILURE_PARAMS(failure) \ + __RESULT_TELEMETRY_COMMON_FAILURE_PARAMS(failure), \ + TraceLoggingUInt32(static_cast((failure).failureId), "failureId", "Identifier assigned to this failure"), \ + TraceLoggingUInt32(static_cast((failure).cFailureCount), "failureCount", "Number of failures seen within the binary where the error occurred"), \ + TraceLoggingString((failure).pszFunction, "function", "Name of the function where the error occurred") + +// Activity Start Event (ALL) +#define __ACTIVITY_START_PARAMS() \ + TraceLoggingStruct(1, "wilActivity"), \ + TraceLoggingUInt32(::GetCurrentThreadId(), "threadId", "Identifier of the thread the activity was run on") + +// Activity Stop Event (SUCCESSFUL or those WITHOUT full failure info -- just hr) +// Also utilized for intermediate stop events (a successful call to 'Stop()' from a Split activity +#define __ACTIVITY_STOP_PARAMS(hr) \ + TraceLoggingStruct(2, "wilActivity"), \ + TraceLoggingUInt32(hr, "hresult", "Failure error code"), \ + TraceLoggingUInt32(::GetCurrentThreadId(), "threadId", "Identifier of the thread the activity was run on") + +// Activity Stop Event (FAILED with full failure info) +#define __ACTIVITY_STOP_TELEMETRY_FAILURE_PARAMS(failure) \ + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), \ + TraceLoggingStruct(14, "wilActivity"), \ + __RESULT_TELEMETRY_COMMON_FAILURE_PARAMS(failure) +#define __ACTIVITY_STOP_TRACELOGGING_FAILURE_PARAMS(failure) \ + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), \ + TraceLoggingStruct(17, "wilActivity"), \ + __RESULT_TRACELOGGING_COMMON_FAILURE_PARAMS(failure) + +// "ActivityError" tagged event (all distinct FAILURES occurring within the outer activity scope) +#define __ACTIVITY_ERROR_TELEMETRY_FAILURE_PARAMS(failure) \ + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), \ + TraceLoggingStruct(14, "wilActivity"), \ + __RESULT_TELEMETRY_COMMON_FAILURE_PARAMS(failure) +#define __ACTIVITY_ERROR_TRACELOGGING_FAILURE_PARAMS(failure) \ + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), \ + TraceLoggingStruct(17, "wilActivity"), \ + __RESULT_TRACELOGGING_COMMON_FAILURE_PARAMS(failure) + +// "ActivityFailure" tagged event (only comes through on TELEMETRY for CallContext activities that have FAILED) +#define __ACTIVITY_FAILURE_TELEMETRY_FAILURE_PARAMS(failure) \ + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), \ + TraceLoggingStruct(14, "wilActivity"), \ + __RESULT_TELEMETRY_COMMON_FAILURE_PARAMS(failure) +#define __ACTIVITY_FAILURE_TELEMETRY_PARAMS(hr, contextName, contextMessage) \ + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), \ + TraceLoggingStruct(4, "wilActivity"), \ + TraceLoggingUInt32(hr, "hresult", "Failure error code"), \ + TraceLoggingUInt32(::GetCurrentThreadId(), "threadId", "Identifier of the thread the activity was run on"), \ + TraceLoggingString(contextName, "currentContextName", "Name of the activity containing this error"), \ + TraceLoggingWideString(contextMessage, "currentContextMessage", "Custom message for the activity containing this error (if any)") + +// "FallbackError" events (all FAILURE events happening outside of ANY activity context) +#define __RESULT_TELEMETRY_FAILURE_PARAMS(failure) \ + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), \ + TraceLoggingStruct(14, "wilResult"), \ + __RESULT_TELEMETRY_COMMON_FAILURE_PARAMS(failure) +#define __RESULT_TRACELOGGING_FAILURE_PARAMS(failure) \ + TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), \ + TraceLoggingStruct(17, "wilResult"), \ + __RESULT_TRACELOGGING_COMMON_FAILURE_PARAMS(failure) + +namespace wil +{ + enum class ActivityOptions + { + None = 0, + TelemetryOnFailure = 0x1, + TraceLoggingOnFailure = 0x2 + }; + DEFINE_ENUM_FLAG_OPERATORS(ActivityOptions) + + template + class ActivityBase; + + /// @cond + namespace details + { + // Lazy static initialization helper for holding a singleton telemetry class to maintain + // the provider handle. + + template + class static_lazy + { + public: + void __cdecl cleanup() WI_NOEXCEPT + { + void* pVoid; + BOOL pending; + + // If object is being constructed on another thread, wait until construction completes. + // Need a memory barrier here (see get() and ~Completer below) so use the result that we + // get from InitOnceBeginInitialize(..., &pVoid, ...) + if (::InitOnceBeginInitialize(&m_initOnce, INIT_ONCE_CHECK_ONLY, &pending, &pVoid) && !pending) + { + static_cast(pVoid)->~T(); + } + } + + T* get(void(__cdecl *cleanupFunc)(void)) WI_NOEXCEPT + { + void* pVoid{}; + BOOL pending; + if (::InitOnceBeginInitialize(&m_initOnce, 0, &pending, &pVoid) && pending) + { + // Don't do anything non-trivial from DllMain, fail fast. + // Some 3rd party code in IE calls shell functions this way, so we can only enforce + // this in DEBUG. +#ifdef DEBUG + FAIL_FAST_IMMEDIATE_IF_IN_LOADER_CALLOUT(); +#endif + + Completer completer(this); + pVoid = &m_storage; + ::new(pVoid)T(); + atexit(cleanupFunc); // ignore failure (that's what the C runtime does, too) + completer.Succeed(); + } + return static_cast(pVoid); + } + + private: + INIT_ONCE m_initOnce; + alignas(T) BYTE m_storage[sizeof(T)]; + struct Completer + { + static_lazy *m_pSelf; + DWORD m_flags; + + explicit Completer(static_lazy *pSelf) WI_NOEXCEPT : m_pSelf(pSelf), m_flags(INIT_ONCE_INIT_FAILED) { } + void Succeed() WI_NOEXCEPT { m_flags = 0; } + + ~Completer() WI_NOEXCEPT + { + if (m_flags == 0) + { + reinterpret_cast(&m_pSelf->m_storage)->Create(); + } + ::InitOnceComplete(&m_pSelf->m_initOnce, m_flags, &m_pSelf->m_storage); + } + }; + }; + + // This class serves as a simple RAII wrapper around CallContextInfo. It presumes that + // the contextName parameter is always a static string, but copies or allocates the + // contextMessage as needed. + + class StoredCallContextInfo : public wil::CallContextInfo + { + public: + StoredCallContextInfo() WI_NOEXCEPT + { + ::ZeroMemory(this, sizeof(*this)); + } + + StoredCallContextInfo(StoredCallContextInfo &&other) WI_NOEXCEPT : + StoredCallContextInfo() + { + operator=(wistd::move(other)); + } + + StoredCallContextInfo& operator=(StoredCallContextInfo &&other) WI_NOEXCEPT + { + contextId = other.contextId; + contextName = other.contextName; + ClearMessage(); + contextMessage = other.contextMessage; + other.contextMessage = nullptr; + m_ownsMessage = other.m_ownsMessage; + other.m_ownsMessage = false; + return *this; + } + + StoredCallContextInfo(StoredCallContextInfo const &other) WI_NOEXCEPT : + m_ownsMessage(false) + { + contextId = other.contextId; + contextName = other.contextName; + if (other.m_ownsMessage) + { + AssignMessage(other.contextMessage); + } + else + { + contextMessage = other.contextMessage; + } + } + + StoredCallContextInfo(_In_opt_ PCSTR staticContextName) WI_NOEXCEPT : + m_ownsMessage(false) + { + contextId = 0; + contextName = staticContextName; + contextMessage = nullptr; + } + + StoredCallContextInfo(PCSTR staticContextName, _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT : + StoredCallContextInfo(staticContextName) + { + SetMessage(formatString, argList); + } + + void SetMessage(_Printf_format_string_ PCSTR formatString, va_list argList) + { + wchar_t loggingMessage[2048]; + PrintLoggingMessage(loggingMessage, ARRAYSIZE(loggingMessage), formatString, argList); + ClearMessage(); + AssignMessage(loggingMessage); + } + + void SetMessage(_In_opt_ PCWSTR message) + { + ClearMessage(); + contextMessage = message; + } + + void SetMessageCopy(_In_opt_ PCWSTR message) + { + ClearMessage(); + if (message != nullptr) + { + AssignMessage(message); + } + } + + void ClearMessage() + { + if (m_ownsMessage) + { + WIL_FreeMemory(const_cast(contextMessage)); + m_ownsMessage = false; + } + contextMessage = nullptr; + } + + ~StoredCallContextInfo() + { + ClearMessage(); + } + + StoredCallContextInfo& operator=(StoredCallContextInfo const &) = delete; + + private: + void AssignMessage(PCWSTR message) + { + auto length = wcslen(message); + if (length > 0) + { + auto sizeBytes = (length + 1) * sizeof(wchar_t); + contextMessage = static_cast(WIL_AllocateMemory(sizeBytes)); + if (contextMessage != nullptr) + { + m_ownsMessage = true; + memcpy_s(const_cast(contextMessage), sizeBytes, message, sizeBytes); + } + } + } + + bool m_ownsMessage; + }; + + template + void SetRelatedActivityId(TActivity&) + { + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + template + void SetRelatedActivityId(wil::ActivityBase& activity) + { + GUID capturedRelatedId; + EventActivityIdControl(EVENT_ACTIVITY_CTRL_GET_ID, &capturedRelatedId); + activity.SetRelatedActivityId(capturedRelatedId); + } +#endif + + typedef wistd::integral_constant tag_start; + typedef wistd::integral_constant tag_start_cv; + } // namespace details + /// @endcond + + + // This class acts as a simple RAII class returned by a call to ContinueOnCurrentThread() for an activity + // or by a call to WatchCurrentThread() on a provider. The result is meant to be a stack local variable + // whose scope controls the lifetime of an error watcher on the given thread. That error watcher re-directs + // errors occurrent within the object's lifetime to the associated provider or activity. + + class ActivityThreadWatcher + { + public: + ActivityThreadWatcher() WI_NOEXCEPT + : m_callbackHolder(nullptr, nullptr, false) + {} + + ActivityThreadWatcher(_In_ details::IFailureCallback *pCallback, PCSTR staticContextName) WI_NOEXCEPT : + m_callContext(staticContextName), + m_callbackHolder(pCallback, &m_callContext) + { + } + + ActivityThreadWatcher(_In_ details::IFailureCallback *pCallback, PCSTR staticContextName, _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT : + ActivityThreadWatcher(pCallback, staticContextName) + { + m_callContext.SetMessage(formatString, argList); + } + + // Uses the supplied StoredCallContextInfo rather than producing one itself + ActivityThreadWatcher(_In_ details::IFailureCallback *pCallback, _In_ details::StoredCallContextInfo const &callContext) WI_NOEXCEPT : + m_callContext(callContext), + m_callbackHolder(pCallback, &m_callContext) + { + } + + ActivityThreadWatcher(ActivityThreadWatcher &&other) WI_NOEXCEPT : + m_callContext(wistd::move(other.m_callContext)), + m_callbackHolder(wistd::move(other.m_callbackHolder)) + { + m_callbackHolder.SetCallContext(&m_callContext); + } + + ActivityThreadWatcher(ActivityThreadWatcher const &) = delete; + ActivityThreadWatcher& operator=(ActivityThreadWatcher const &) = delete; + + void SetMessage(_Printf_format_string_ PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + m_callContext.SetMessage(formatString, argList); + va_end(argList); + } + + void SetMessage(_In_opt_ PCWSTR message) + { + m_callContext.SetMessage(message); + } + + void SetMessageCopy(_In_opt_ PCWSTR message) + { + m_callContext.SetMessageCopy(message); + } + + private: + details::StoredCallContextInfo m_callContext; + details::ThreadFailureCallbackHolder m_callbackHolder; + }; + + + // This is the base-class implementation of a TraceLogging class. TraceLogging classes are defined with + // BEGIN_TRACELOGGING_CLASS and automatically derive from this class + + enum class ErrorReportingType + { + None = 0, + Telemetry, + TraceLogging + }; + + class TraceLoggingProvider : public details::IFailureCallback + { + public: + // Only one instance of each of these derived classes should be created + TraceLoggingProvider(_In_ TraceLoggingProvider const&) = delete; + TraceLoggingProvider& operator=(TraceLoggingProvider const&) = delete; + void* operator new(size_t) = delete; + void* operator new[](size_t) = delete; + + protected: + + // This can be overridden to provide specific initialization code for any individual provider. + // It will be ran once when the single static singleton instance of this class is created. + virtual void Initialize() WI_NOEXCEPT {} + + // This method can be overridden by a provider to more tightly control what happens in the event + // of a failure in a CallContext activity, WatchCurrentThread() object, or attributed to a specific failure. + virtual void OnErrorReported(bool alreadyReported, FailureInfo const &failure) WI_NOEXCEPT + { + if (!alreadyReported && WI_IsFlagClear(failure.flags, FailureFlags::RequestSuppressTelemetry)) + { + if (m_errorReportingType == ErrorReportingType::Telemetry) + { + ReportTelemetryFailure(failure); + } + else if (m_errorReportingType == ErrorReportingType::TraceLogging) + { + ReportTraceLoggingFailure(failure); + } + } + } + + public: + WI_NODISCARD TraceLoggingHProvider Provider_() const WI_NOEXCEPT + { + return m_providerHandle; + } + + protected: + TraceLoggingProvider() WI_NOEXCEPT {} + + virtual ~TraceLoggingProvider() WI_NOEXCEPT + { + if (m_ownsProviderHandle) + { + TraceLoggingUnregister(m_providerHandle); + } + } + + WI_NODISCARD bool IsEnabled_(UCHAR eventLevel /* WINEVENT_LEVEL_XXX, e.g. WINEVENT_LEVEL_VERBOSE */, ULONGLONG eventKeywords /* MICROSOFT_KEYWORD_XXX */) const WI_NOEXCEPT + { + return ((m_providerHandle != nullptr) && TraceLoggingProviderEnabled(m_providerHandle, eventLevel, eventKeywords)) || __TRACELOGGING_TEST_HOOK_SET_ENABLED; + } + + void SetErrorReportingType_(ErrorReportingType type) + { + m_errorReportingType = type; + } + + static bool WasAlreadyReportedToTelemetry(long failureId) WI_NOEXCEPT + { + static long volatile s_lastFailureSeen = -1; + auto wasSeen = (s_lastFailureSeen == failureId); + s_lastFailureSeen = failureId; + return wasSeen; + } + + void ReportTelemetryFailure(FailureInfo const &failure) WI_NOEXCEPT + { + __TRACELOGGING_TEST_HOOK_ERROR(failure); + TraceLoggingWrite(m_providerHandle, "FallbackError", TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), __RESULT_TELEMETRY_FAILURE_PARAMS(failure)); + } + + void ReportTraceLoggingFailure(FailureInfo const &failure) WI_NOEXCEPT + { + TraceLoggingWrite(m_providerHandle, "FallbackError", TraceLoggingLevel(WINEVENT_LEVEL_ERROR), __RESULT_TRACELOGGING_FAILURE_PARAMS(failure)); + } + + // Helper function for TraceLoggingError. + // It prints out a trace message for debug purposes. The message does not go into the telemetry. + void ReportTraceLoggingError(_In_ _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + if (IsEnabled_(WINEVENT_LEVEL_ERROR, 0)) + { + wchar_t loggingMessage[2048]; + details::PrintLoggingMessage(loggingMessage, ARRAYSIZE(loggingMessage), formatString, argList); + TraceLoggingWrite(m_providerHandle, "TraceLoggingError", TraceLoggingLevel(WINEVENT_LEVEL_ERROR), TraceLoggingWideString(loggingMessage, "traceLoggingMessage")); + } + } + + // Helper function for TraceLoggingInfo. + // It prints out a trace message for debug purposes. The message does not go into the telemetry. + void ReportTraceLoggingMessage(_In_ _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + if (IsEnabled_(WINEVENT_LEVEL_VERBOSE, 0)) + { + wchar_t loggingMessage[2048]; + details::PrintLoggingMessage(loggingMessage, ARRAYSIZE(loggingMessage), formatString, argList); + TraceLoggingWrite(m_providerHandle, "TraceLoggingInfo", TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE), TraceLoggingWideString(loggingMessage, "traceLoggingMessage")); + } + } + + void Register(TraceLoggingHProvider const providerHandle, TLG_PENABLECALLBACK callback = nullptr) WI_NOEXCEPT + { + // taking over the lifetime and management of providerHandle + m_providerHandle = providerHandle; + m_ownsProviderHandle = true; + TraceLoggingRegisterEx(providerHandle, callback, nullptr); + InternalInitialize(); + } + + void AttachProvider(TraceLoggingHProvider const providerHandle) WI_NOEXCEPT + { + m_providerHandle = providerHandle; + m_ownsProviderHandle = false; + InternalInitialize(); + } + + private: + // IFailureCallback + bool NotifyFailure(FailureInfo const &failure) WI_NOEXCEPT override + { + if (!WasAlreadyReportedToTelemetry(failure.failureId)) + { + OnErrorReported(false, failure); + } + return true; + } + + void InternalInitialize() + { + m_errorReportingType = ErrorReportingType::Telemetry; + Initialize(); + } + + TraceLoggingHProvider m_providerHandle{}; + bool m_ownsProviderHandle{}; + ErrorReportingType m_errorReportingType{}; + }; + + template< + typename TraceLoggingType, + UINT64 keyword = 0, + UINT8 level = WINEVENT_LEVEL_VERBOSE, + typename TlgReflectorTag = _TlgReflectorTag_Param0IsProviderType> // helps TlgReflector understand that this is a wrapper type + class BasicActivity + : public _TlgActivityBase, keyword, level> + { + using BaseTy = _TlgActivityBase, keyword, level>; + friend BaseTy; + + void OnStarted() + { + } + + void OnStopped() + { + } + + public: + + BasicActivity() + { + } + + BasicActivity(BasicActivity&& rhs) : + BaseTy(wistd::move(rhs)) + { + } + + BasicActivity& operator=(BasicActivity&& rhs) + { + BaseTy::operator=(wistd::move(rhs)); + return *this; + } + + /* + Returns a handle to the TraceLogging provider associated with this activity. + */ + WI_NODISCARD TraceLoggingHProvider Provider() const + { + return TraceLoggingType::Provider(); + } + + /* + Sets the related (parent) activity. + May only be called once. If used, must be called before starting the activity. + */ + template + void SetRelatedActivity(_In_ const ActivityTy& relatedActivity) + { + this->SetRelatedId(*relatedActivity.Id()); + } + + /* + Sets the related (parent) activity. + May only be called once. If used, must be called before starting the activity. + */ + void SetRelatedActivityId(_In_ const GUID& relatedActivityId) + { + this->SetRelatedId(relatedActivityId); + } + + /* + Sets the related (parent) activity. + May only be called once. If used, must be called before starting the activity. + */ + void SetRelatedActivityId(_In_ const GUID* relatedActivityId) + { + __FAIL_FAST_IMMEDIATE_ASSERT__(relatedActivityId != NULL); + this->SetRelatedId(*relatedActivityId); + } + }; + + template< + typename TraceLoggingType, + UINT64 keyword = 0, + UINT8 level = WINEVENT_LEVEL_VERBOSE, + typename TlgReflectorTag = _TlgReflectorTag_Param0IsProviderType> // helps TlgReflector understand that this is a wrapper type + class BasicThreadActivity + : public _TlgActivityBase, keyword, level> + { + using BaseTy = _TlgActivityBase, keyword, level>; + friend BaseTy; + + void OnStarted() + { + this->PushThreadActivityId(); + } + + void OnStopped() + { + this->PopThreadActivityId(); + } + + public: + + BasicThreadActivity() + { + } + + BasicThreadActivity(BasicThreadActivity&& rhs) + : BaseTy(wistd::move(rhs)) + { + } + + BasicThreadActivity& operator=(BasicThreadActivity&& rhs) + { + BaseTy::operator=(wistd::move(rhs)); + return *this; + } + + /* + Returns a handle to the TraceLogging provider associated with this activity. + */ + WI_NODISCARD TraceLoggingHProvider Provider() const + { + return TraceLoggingType::Provider(); + } + }; + +#define __WI_TraceLoggingWriteTagged(activity, name, ...) \ + __pragma(warning(push)) __pragma(warning(disable:4127)) \ + do { \ + _tlgActivityDecl(activity) \ + TraceLoggingWriteActivity( \ + TraceLoggingType::Provider(), \ + (name), \ + _tlgActivityRef(activity).Id(), \ + NULL, \ + __VA_ARGS__); \ + } while(0) \ + __pragma(warning(pop)) \ + + + // This is the ultimate base class implementation for all activities. Activity classes are defined with + // DEFINE_TRACELOGGING_ACTIVITY, DEFINE_CALLCONTEXT_ACTIVITY, DEFINE_TELEMETRY_ACTIVITY and others + + + template + class ActivityBase : public details::IFailureCallback + { + public: + typedef ActivityTraceLoggingType TraceLoggingType; + + static UINT64 const Keyword = keyword; + static UINT8 const Level = level; + static UINT64 const PrivacyTag = privacyTag; + + ActivityBase(PCSTR contextName, bool shouldWatchErrors = false) WI_NOEXCEPT : + m_activityData(contextName), + m_pActivityData(&m_activityData), + m_callbackHolder(this, m_activityData.GetCallContext(), shouldWatchErrors) + { + } + + ActivityBase(ActivityBase &&other, bool shouldWatchErrors) WI_NOEXCEPT : + m_activityData(wistd::move(other.m_activityData)), + m_sharedActivityData(wistd::move(other.m_sharedActivityData)), + m_callbackHolder(this, nullptr, shouldWatchErrors) + { + m_pActivityData = m_sharedActivityData ? m_sharedActivityData.get() : &m_activityData; + m_callbackHolder.SetCallContext(m_pActivityData->GetCallContext()); + other.m_pActivityData = &other.m_activityData; + if (other.m_callbackHolder.IsWatching()) + { + other.m_callbackHolder.StopWatching(); + } + } + + ActivityBase(ActivityBase &&other) WI_NOEXCEPT : + ActivityBase(wistd::move(other), other.m_callbackHolder.IsWatching()) + { + } + + ActivityBase(ActivityBase const &other) WI_NOEXCEPT : + m_activityData(), + m_pActivityData(&m_activityData), + m_callbackHolder(this, nullptr, false) // false = do not automatically watch for failures + { + operator=(other); + } + + ActivityBase& operator=(ActivityBase &&other) WI_NOEXCEPT + { + m_activityData = wistd::move(other.m_activityData); + m_sharedActivityData = wistd::move(other.m_sharedActivityData); + m_pActivityData = m_sharedActivityData ? m_sharedActivityData.get() : &m_activityData; + m_callbackHolder.SetCallContext(m_pActivityData->GetCallContext()); + m_callbackHolder.SetWatching(other.m_callbackHolder.IsWatching()); + other.m_pActivityData = &other.m_activityData; + if (other.m_callbackHolder.IsWatching()) + { + other.m_callbackHolder.StopWatching(); + } + return *this; + } + + ActivityBase& operator=(ActivityBase const &other) WI_NOEXCEPT + { + if (m_callbackHolder.IsWatching()) + { + m_callbackHolder.StopWatching(); + } + + if (other.m_sharedActivityData) + { + m_pActivityData = other.m_pActivityData; + m_sharedActivityData = other.m_sharedActivityData; + } + else if (m_sharedActivityData.create(wistd::move(other.m_activityData))) + { + // Locking should not be required as the first copy should always take place on the owning + // thread... + m_pActivityData = m_sharedActivityData.get(); + other.m_sharedActivityData = m_sharedActivityData; + other.m_pActivityData = m_pActivityData; + other.m_callbackHolder.SetCallContext(m_pActivityData->GetCallContext()); + } + m_callbackHolder.SetCallContext(m_pActivityData->GetCallContext()); + return *this; + } + + // These calls all result in setting a message to associate with any failures that might occur while + // running the activity. For example, you could associate a filename with a call context activity + // so that the file name is only reported if the activity fails with the failure. + + void SetMessage(_In_ _Printf_format_string_ PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + auto lock = LockExclusive(); + GetCallContext()->SetMessage(formatString, argList); + va_end(argList); + } + + void SetMessage(_In_opt_ PCWSTR message) + { + auto lock = LockExclusive(); + GetCallContext()->SetMessage(message); + } + + void SetMessageCopy(_In_opt_ PCWSTR message) + { + auto lock = LockExclusive(); + GetCallContext()->SetMessageCopy(message); + } + + // This call stops watching for errors on the thread that the activity was originally + // created on. Use it when moving the activity into a thread-agnostic class or moving + // an activity across threads. + + void IgnoreCurrentThread() WI_NOEXCEPT + { + if (m_callbackHolder.IsWatching()) + { + m_callbackHolder.StopWatching(); + } + } + + // Call this API to retrieve an RAII object to watch events on the current thread. The returned + // object should only be used on the stack. + + WI_NODISCARD ActivityThreadWatcher ContinueOnCurrentThread() WI_NOEXCEPT + { + if (IsRunning()) + { + return ActivityThreadWatcher(this, *m_pActivityData->GetCallContext()); + } + return ActivityThreadWatcher(); + } + + // This is the 'default' Stop routine that accepts an HRESULT and completes the activity... + + void Stop(HRESULT hr = S_OK) WI_NOEXCEPT + { + bool stopActivity; + HRESULT hrLocal; + { + auto lock = LockExclusive(); + stopActivity = m_pActivityData->SetStopResult(hr, &hrLocal); + } + if (stopActivity) + { + ReportStopActivity(hrLocal); + } + else + { + __WI_TraceLoggingWriteTagged(*this, "ActivityIntermediateStop", TraceLoggingKeyword(Keyword), TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), __ACTIVITY_STOP_PARAMS(hr)); + } + IgnoreCurrentThread(); + } + + // IFailureCallback + + bool NotifyFailure(FailureInfo const &failure) WI_NOEXCEPT override + { + // We always report errors to the ETW stream, but we hold-back the telemetry keyword if we've already reported this error to this + // particular telemetry provider. + + __TRACELOGGING_TEST_HOOK_ACTIVITY_ERROR(failure); + + if (WI_IsFlagClear(failure.flags, FailureFlags::RequestSuppressTelemetry)) + { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-value" +#endif +#pragma warning(push) +#pragma warning(disable: 6319) + if (false, WI_IsFlagSet(options, ActivityOptions::TelemetryOnFailure) && !WasAlreadyReportedToTelemetry(failure.failureId)) + { + __WI_TraceLoggingWriteTagged(*this, "ActivityError", TraceLoggingKeyword(Keyword | MICROSOFT_KEYWORD_TELEMETRY), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), __ACTIVITY_ERROR_TELEMETRY_FAILURE_PARAMS(failure)); + } + else if (false, WI_IsFlagSet(options, ActivityOptions::TraceLoggingOnFailure)) + { + __WI_TraceLoggingWriteTagged(*this, "ActivityError", TraceLoggingKeyword(0), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), __ACTIVITY_ERROR_TRACELOGGING_FAILURE_PARAMS(failure)); + } + else + { + __WI_TraceLoggingWriteTagged(*this, "ActivityError", TraceLoggingKeyword(Keyword), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), __ACTIVITY_ERROR_TRACELOGGING_FAILURE_PARAMS(failure)); + } +#pragma warning(pop) +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + } + + auto lock = LockExclusive(); + m_pActivityData->NotifyFailure(failure); + return true; + } + + // This is the base TraceLoggingActivity<> contract... we implement it so that this class + // can be used by all of the activity macros and we re-route the request as needed. + // + // The contract required by the TraceLogging Activity macros is: + // - activity.Keyword // compile-time constant + // - activity.Level // compile-time constant + // - activity.PrivacyTag // compile-time constant + // - activity.Provider() + // - activity.Id() + // - activity.zInternalRelatedId() + // - activity.zInternalStart() + // - activity.zInternalStop() + // In addition, for TlgReflector to work correctly, it must be possible for + // TlgReflector to statically map from typeof(activity) to hProvider. + + WI_NODISCARD GUID const* zInternalRelatedId() const WI_NOEXCEPT + { + return m_pActivityData->zInternalRelatedId(); + } + + void zInternalStart() WI_NOEXCEPT + { + auto lock = LockExclusive(); m_pActivityData->zInternalStart(); + } + + void zInternalStop() WI_NOEXCEPT + { + auto lock = LockExclusive(); m_pActivityData->zInternalStop(); + } + + static TraceLoggingHProvider Provider() WI_NOEXCEPT + { + return ActivityTraceLoggingType::Provider(); + } + + WI_NODISCARD GUID const* Id() const WI_NOEXCEPT + { + return m_pActivityData->Id(); + } + + WI_NODISCARD GUID const* providerGuid() const WI_NOEXCEPT + { + return m_pActivityData->providerGuid(); + } + + template + void SetRelatedActivity(OtherTy const &relatedActivity) WI_NOEXCEPT + { + auto lock = LockExclusive(); + m_pActivityData->SetRelatedActivityId(relatedActivity.Id()); + } + + void SetRelatedActivityId(_In_ const GUID& relatedActivityId) WI_NOEXCEPT + { + auto lock = LockExclusive(); + m_pActivityData->SetRelatedActivityId(&relatedActivityId); + } + + void SetRelatedActivityId(_In_ const GUID* relatedActivityId) WI_NOEXCEPT + { + auto lock = LockExclusive(); + m_pActivityData->SetRelatedActivityId(relatedActivityId); + } + + WI_NODISCARD inline bool IsRunning() const WI_NOEXCEPT + { + return m_pActivityData->NeedsStopped(); + } + protected: + virtual void StopActivity() WI_NOEXCEPT = 0; + virtual bool WasAlreadyReportedToTelemetry(long failureId) WI_NOEXCEPT = 0; + + void EnsureWatchingCurrentThread() + { + if (!m_callbackHolder.IsWatching()) + { + m_callbackHolder.StartWatching(); + } + } + + void SetStopResult(HRESULT hr, _Out_opt_ HRESULT *phr = nullptr) WI_NOEXCEPT + { + auto lock = LockExclusive(); + m_pActivityData->SetStopResult(hr, phr); + } + + void IncrementExpectedStopCount() WI_NOEXCEPT + { + auto lock = LockExclusive(); + m_pActivityData->IncrementExpectedStopCount(); + } + + // Locking should not be required on these accessors as we only use this at reporting (which will only happen from + // the final stop) + + FailureInfo const* GetFailureInfo() WI_NOEXCEPT + { + return m_pActivityData->GetFailureInfo(); + } + + WI_NODISCARD inline HRESULT GetResult() const WI_NOEXCEPT + { + return m_pActivityData->GetResult(); + } + + WI_NODISCARD details::StoredCallContextInfo* GetCallContext() const WI_NOEXCEPT + { + return m_pActivityData->GetCallContext(); + } + + // Think of this routine as the destructor -- since we need to call virtual derived methods, we can't use it as + // a destructor without a pure virtual method call, so we have the derived class call it in its destructor... + + void Destroy() WI_NOEXCEPT + { + bool fStop = true; + if (m_sharedActivityData) + { + // The lock unifies the 'unique()' check and the 'reset()' of any non-unique activity so that we + // can positively identify the final release of the internal data + + auto lock = LockExclusive(); + if (!m_sharedActivityData.unique()) + { + fStop = false; + m_sharedActivityData.reset(); + } + } + + if (fStop && m_pActivityData->NeedsStopped()) + { + ReportStopActivity(m_pActivityData->SetUnhandledException()); + } + } + + private: + void ReportStopActivity(HRESULT hr) WI_NOEXCEPT + { + if (FAILED(hr) && WI_AreAllFlagsClear(Keyword, (MICROSOFT_KEYWORD_TELEMETRY | MICROSOFT_KEYWORD_MEASURES | MICROSOFT_KEYWORD_CRITICAL_DATA)) && WI_IsFlagSet(options, ActivityOptions::TelemetryOnFailure)) + { + wil::FailureInfo const* pFailure = GetFailureInfo(); + if (pFailure != nullptr) + { + __TRACELOGGING_TEST_HOOK_CALLCONTEXT_ERROR(pFailure, pFailure->hr); + auto & failure = *pFailure; + __WI_TraceLoggingWriteTagged(*this, "ActivityFailure", TraceLoggingKeyword(Keyword | MICROSOFT_KEYWORD_TELEMETRY), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), __ACTIVITY_FAILURE_TELEMETRY_FAILURE_PARAMS(failure)); + } + else + { + __TRACELOGGING_TEST_HOOK_CALLCONTEXT_ERROR(nullptr, hr); + __WI_TraceLoggingWriteTagged(*this, "ActivityFailure", TraceLoggingKeyword(Keyword | MICROSOFT_KEYWORD_TELEMETRY), TraceLoggingLevel(WINEVENT_LEVEL_ERROR), + __ACTIVITY_FAILURE_TELEMETRY_PARAMS(hr, m_pActivityData->GetCallContext()->contextName, m_pActivityData->GetCallContext()->contextMessage)); + } + } + + StopActivity(); + } + + rwlock_release_exclusive_scope_exit LockExclusive() WI_NOEXCEPT + { + // We only need to lock when we're sharing.... + return (m_sharedActivityData ? m_sharedActivityData->LockExclusive() : rwlock_release_exclusive_scope_exit()); + } + + template + class ActivityData : + public _TlgActivityBase, keyword, level> + { + using BaseTy = _TlgActivityBase, keyword, level>; + friend BaseTy; + void OnStarted() {} + void OnStopped() {} + + // SFINAE dispatching on presence of ActivityTraceLoggingType::CreateActivityId(_Out_ GUID& childActivityId, _In_opt_ const GUID* relatedActivityId) + template + auto CreateActivityIdByProviderType(int, _Out_ GUID& childActivityId) -> + decltype(ProviderType::CreateActivityId(childActivityId, this->GetRelatedId()), (void)0) + { + ProviderType::CreateActivityId(childActivityId, this->GetRelatedId()); + } + + template + auto CreateActivityIdByProviderType(long, _Out_ GUID& childActivityId) -> + void + { + EventActivityIdControl(EVENT_ACTIVITY_CTRL_CREATE_ID, &childActivityId); + } + + void CreateActivityId(_Out_ GUID& childActivityId) + { + CreateActivityIdByProviderType(0, childActivityId); + } + + public: + ActivityData(_In_opt_ PCSTR contextName = nullptr) WI_NOEXCEPT : + BaseTy(), + m_callContext(contextName), + m_result(S_OK), + m_stopCountExpected(1) + { + } + + ActivityData(ActivityData &&other) WI_NOEXCEPT : + BaseTy(wistd::move(other)), + m_callContext(wistd::move(other.m_callContext)), + m_result(other.m_result), + m_failure(wistd::move(other.m_failure)), + m_stopCountExpected(other.m_stopCountExpected) + { + } + + ActivityData & operator=(ActivityData &&other) WI_NOEXCEPT + { + BaseTy::operator=(wistd::move(other)); + m_callContext = wistd::move(other.m_callContext); + m_result = other.m_result; + m_failure = wistd::move(other.m_failure); + m_stopCountExpected = other.m_stopCountExpected; + return *this; + } + + ActivityData(ActivityData const &other) = delete; + ActivityData & operator=(ActivityData const &other) = delete; + + // returns true if the event was reported to telemetry + void NotifyFailure(FailureInfo const &failure) WI_NOEXCEPT + { + if ((failure.hr != m_failure.GetFailureInfo().hr) && // don't replace with the same error (likely propagation up the stack) + ((failure.hr != m_result) || SUCCEEDED(m_result))) // don't replace if we've already got the current explicitly supplied failure code + { + m_failure.SetFailureInfo(failure); + } + } + + rwlock_release_exclusive_scope_exit LockExclusive() WI_NOEXCEPT + { + return m_lock.lock_exclusive(); + } + + static TraceLoggingHProvider Provider() + { + return ActivityTraceLoggingType::Provider(); + } + + WI_NODISCARD bool NeedsStopped() const WI_NOEXCEPT + { + return BaseTy::IsStarted(); + } + + void SetRelatedActivityId(const GUID* relatedId) + { + this->SetRelatedId(*relatedId); + } + + bool SetStopResult(HRESULT hr, _Out_opt_ HRESULT *phr) WI_NOEXCEPT + { + // We must be expecting at least one Stop -- otherwise the caller is calling Stop() more times + // than it can (normally once, or +1 for each call to Split()) + __FAIL_FAST_IMMEDIATE_ASSERT__(m_stopCountExpected >= 1); + if (SUCCEEDED(m_result)) + { + m_result = hr; + } + if (phr != nullptr) + { + *phr = m_result; + } + return ((--m_stopCountExpected) == 0); + } + + HRESULT SetUnhandledException() WI_NOEXCEPT + { + HRESULT hr = m_failure.GetFailureInfo().hr; + SetStopResult(FAILED(hr) ? hr : HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION), &hr); + return hr; + } + + void IncrementExpectedStopCount() WI_NOEXCEPT + { + m_stopCountExpected++; + } + + WI_NODISCARD FailureInfo const* GetFailureInfo() const WI_NOEXCEPT + { + return (FAILED(m_result) && (m_result == m_failure.GetFailureInfo().hr)) ? &m_failure.GetFailureInfo() : nullptr; + } + + WI_NODISCARD inline HRESULT GetResult() const WI_NOEXCEPT + { + return m_result; + } + + details::StoredCallContextInfo *GetCallContext() WI_NOEXCEPT + { + return &m_callContext; + } + + private: + details::StoredCallContextInfo m_callContext; + HRESULT m_result; + StoredFailureInfo m_failure; + int m_stopCountExpected; + wil::srwlock m_lock; + }; + + mutable ActivityData m_activityData; + mutable ActivityData *m_pActivityData; + mutable details::shared_object> m_sharedActivityData; + mutable details::ThreadFailureCallbackHolder m_callbackHolder; + }; + +} // namespace wil + + +// Internal MACRO implementation of Activities. +// Do NOT use these macros directly. + +#define __WI_TraceLoggingWriteStart(activity, name, ...) \ + __pragma(warning(push)) __pragma(warning(disable:4127)) \ + do { \ + _tlgActivityDecl(activity) \ + static const UINT64 _tlgActivity_Keyword = _tlgActivityRef(activity).Keyword;\ + static const UINT8 _tlgActivity_Level = _tlgActivityRef(activity).Level;\ + static const UINT64 _tlgActivityPrivacyTag = _tlgActivityRef(activity).PrivacyTag;\ + static_assert( \ + _tlgActivity_Keyword == (_tlgActivity_Keyword _tlg_FOREACH(_tlgKeywordVal, __VA_ARGS__)), \ + "Do not use TraceLoggingKeyword in TraceLoggingWriteStart. Keywords for START events are " \ + "specified in the activity type, e.g. TraceLoggingActivity."); \ + static_assert( \ + _tlgActivity_Level == (_tlgActivity_Level _tlg_FOREACH(_tlgLevelVal, __VA_ARGS__)), \ + "Do not use TraceLoggingLevel in TraceLoggingWriteStart. The Level for START events is " \ + "specified in the activity type, e.g. TraceLoggingActivity."); \ + _tlgActivityRef(activity).zInternalStart(); \ + TraceLoggingWriteActivity( \ + TraceLoggingType::Provider(), \ + (name), \ + _tlgActivityRef(activity).Id(), \ + _tlgActivityRef(activity).zInternalRelatedId(), \ + TraceLoggingOpcode(1 /* WINEVENT_OPCODE_START */), \ + TraceLoggingKeyword(_tlgActivity_Keyword), \ + TraceLoggingLevel(_tlgActivity_Level), \ + TelemetryPrivacyDataTag(_tlgActivityPrivacyTag), \ + TraceLoggingDescription("~^" _wiltlg_LSTRINGIZE(activity) L"^~"), \ + __VA_ARGS__); \ + } while(0) \ + __pragma(warning(pop)) \ + +#define __WRITE_ACTIVITY_START(EventId, ...) \ + __TRACELOGGING_TEST_HOOK_ACTIVITY_START(); \ + __WI_TraceLoggingWriteStart(*this, #EventId, __ACTIVITY_START_PARAMS(), __VA_ARGS__); \ + EnsureWatchingCurrentThread() + +#define __WI_TraceLoggingWriteStop(activity, name, ...) \ + __pragma(warning(push)) __pragma(warning(disable:4127)) \ + do { \ + _tlgActivityDecl(activity) \ + static const UINT64 _tlgActivity_Keyword = _tlgActivityRef(activity).Keyword;\ + static const UINT8 _tlgActivity_Level = _tlgActivityRef(activity).Level;\ + static const UINT64 _tlgActivityPrivacyTag = _tlgActivityRef(activity).PrivacyTag;\ + static_assert( \ + _tlgActivity_Keyword == (_tlgActivity_Keyword _tlg_FOREACH(_tlgKeywordVal, __VA_ARGS__)), \ + "Do not use TraceLoggingKeyword in TraceLoggingWriteStop. Keywords for STOP events are " \ + "specified in the activity type, e.g. TraceLoggingActivity."); \ + static_assert( \ + _tlgActivity_Level == (_tlgActivity_Level _tlg_FOREACH(_tlgLevelVal, __VA_ARGS__)), \ + "Do not use TraceLoggingLevel in TraceLoggingWriteStop. The Level for STOP events is " \ + "specified in the activity type, e.g. TraceLoggingActivity."); \ + _tlgActivityRef(activity).zInternalStop(); \ + TraceLoggingWriteActivity( \ + TraceLoggingType::Provider(), \ + (name), \ + _tlgActivityRef(activity).Id(), \ + NULL, \ + TraceLoggingOpcode(2 /* WINEVENT_OPCODE_STOP */),\ + TraceLoggingKeyword(_tlgActivity_Keyword),\ + TraceLoggingLevel(_tlgActivity_Level),\ + TelemetryPrivacyDataTag(_tlgActivityPrivacyTag), \ + TraceLoggingDescription("~^" _wiltlg_LSTRINGIZE(activity) L"^~"),\ + __VA_ARGS__); \ + } while(0) \ + __pragma(warning(pop)) \ + +#define __WRITE_ACTIVITY_STOP(EventId, ...) \ + wil::FailureInfo const* pFailure = GetFailureInfo(); \ + if (pFailure != nullptr) \ + { \ + __TRACELOGGING_TEST_HOOK_ACTIVITY_STOP(pFailure, pFailure->hr); \ + auto &failure = *pFailure; \ + if (false, WI_IsAnyFlagSet(Keyword, (MICROSOFT_KEYWORD_TELEMETRY | MICROSOFT_KEYWORD_MEASURES | MICROSOFT_KEYWORD_CRITICAL_DATA))) \ + { \ + __WI_TraceLoggingWriteStop(*this, #EventId, __ACTIVITY_STOP_TELEMETRY_FAILURE_PARAMS(failure), __VA_ARGS__); \ + } \ + else \ + { \ + __WI_TraceLoggingWriteStop(*this, #EventId, __ACTIVITY_STOP_TRACELOGGING_FAILURE_PARAMS(failure), __VA_ARGS__); \ + } \ + } \ + else \ + { \ + __TRACELOGGING_TEST_HOOK_ACTIVITY_STOP(nullptr, GetResult()); \ + __WI_TraceLoggingWriteStop(*this, #EventId, __ACTIVITY_STOP_PARAMS(GetResult()), __VA_ARGS__); \ + } \ + IgnoreCurrentThread(); + +// optional params are: KeyWord, Level, PrivacyTags, Options +#define __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, ...) \ + class ActivityClassName final : public wil::ActivityBase \ + { \ + protected: \ + void StopActivity() WI_NOEXCEPT override \ + { __WRITE_ACTIVITY_STOP(ActivityClassName); } \ + bool WasAlreadyReportedToTelemetry(long failureId) WI_NOEXCEPT override \ + { return TraceLoggingType::WasAlreadyReportedToTelemetry(failureId); } \ + public: \ + static bool IsEnabled() WI_NOEXCEPT \ + { return TraceLoggingType::IsEnabled(); } \ + ~ActivityClassName() WI_NOEXCEPT { ActivityBase::Destroy(); } \ + ActivityClassName(ActivityClassName const &other) WI_NOEXCEPT : ActivityBase(other) {} \ + ActivityClassName(ActivityClassName &&other) WI_NOEXCEPT : ActivityBase(wistd::move(other)) {} \ + ActivityClassName(ActivityClassName &&other, bool shouldWatchErrors) WI_NOEXCEPT : ActivityBase(wistd::move(other), shouldWatchErrors) {} \ + ActivityClassName& operator=(ActivityClassName const &other) WI_NOEXCEPT \ + { ActivityBase::operator=(other); return *this; } \ + ActivityClassName& operator=(ActivityClassName &&other) WI_NOEXCEPT \ + { auto localActivity(wistd::move(*this)); ActivityBase::operator=(wistd::move(other)); return *this; } \ + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT \ + { return IsRunning(); } \ + void StopWithResult(HRESULT hr) \ + { ActivityBase::Stop(hr); } \ + template \ + void StopWithResult(HRESULT hr, TArgs&&... args) \ + { SetStopResult(hr); Stop(wistd::forward(args)...); } \ + void Stop(HRESULT hr = S_OK) WI_NOEXCEPT \ + { ActivityBase::Stop(hr); } \ + void StartActivity() WI_NOEXCEPT \ + { __WRITE_ACTIVITY_START(ActivityClassName); } \ + void StartRelatedActivity() WI_NOEXCEPT \ + { wil::details::SetRelatedActivityId(*this); StartActivity(); } \ + void StartActivityWithCorrelationVector(PCSTR correlationVector) WI_NOEXCEPT \ + { __WRITE_ACTIVITY_START(ActivityClassName, TraceLoggingString(correlationVector, "__TlgCV__")); } \ + WI_NODISCARD ActivityClassName Split() WI_NOEXCEPT \ + { __FAIL_FAST_IMMEDIATE_ASSERT__(IsRunning()); IncrementExpectedStopCount(); return ActivityClassName(*this); } \ + WI_NODISCARD ActivityClassName TransferToCurrentThread() WI_NOEXCEPT \ + { return ActivityClassName(wistd::move(*this), IsRunning()); } \ + WI_NODISCARD ActivityClassName TransferToMember() WI_NOEXCEPT \ + { return ActivityClassName(wistd::move(*this), false); } + +#define __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) \ + private: \ + template \ + ActivityClassName(wil::details::tag_start, TArgs&&... args) WI_NOEXCEPT : ActivityBase(#ActivityClassName) \ + { StartActivity(wistd::forward(args)...); \ + __TRACELOGGING_DEFINE_PROVIDER_STORAGE_LINK("this", ActivityClassName); } \ + template \ + ActivityClassName(wil::details::tag_start_cv, _In_opt_ PCSTR correlationVector, TArgs&&... args) WI_NOEXCEPT : ActivityBase(#ActivityClassName) \ + { StartActivityWithCorrelationVector(correlationVector, wistd::forward(args)...); \ + __TRACELOGGING_DEFINE_PROVIDER_STORAGE_LINK("this", ActivityClassName); } \ + public: \ + ActivityClassName() WI_NOEXCEPT : ActivityBase(#ActivityClassName, false) {} \ + template \ + WI_NODISCARD static ActivityClassName Start(TArgs&&... args) \ + { return ActivityClassName(wil::details::tag_start(), wistd::forward(args)...); } \ + template \ + WI_NODISCARD static ActivityClassName StartWithCorrelationVector(_In_ PCSTR correlationVector, TArgs&&... args) \ + { return ActivityClassName(wil::details::tag_start_cv(), correlationVector, wistd::forward(args)...); } + +#define __IMPLEMENT_CALLCONTEXT_CLASS(ActivityClassName) \ + protected: \ + ActivityClassName(_In_opt_ void **, PCSTR contextName, _In_opt_ _Printf_format_string_ PCSTR formatString, _In_opt_ va_list argList) : \ + ActivityBase(contextName) \ + { GetCallContext()->SetMessage(formatString, argList); StartActivity(); } \ + ActivityClassName(_In_opt_ void **, PCSTR contextName) : \ + ActivityBase(contextName) \ + { StartActivity(); } \ + public: \ + ActivityClassName(PCSTR contextName) : ActivityBase(contextName, false) {} \ + ActivityClassName(PCSTR contextName, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT : ActivityClassName(contextName) \ + { va_list argList; va_start(argList, formatString); GetCallContext()->SetMessage(formatString, argList); } \ + WI_NODISCARD static ActivityClassName Start(PCSTR contextName) WI_NOEXCEPT \ + { return ActivityClassName(static_cast(__nullptr), contextName); } \ + WI_NODISCARD static ActivityClassName Start(PCSTR contextName, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT \ + { va_list argList; va_start(argList, formatString); return ActivityClassName(static_cast(__nullptr), contextName, formatString, argList); } + +#define __END_TRACELOGGING_ACTIVITY_CLASS() \ + }; + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT(EventId, ...) \ + void EventId() \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, _GENERIC_PARTB_FIELDS_ENABLED, __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT(EventId, ...) \ + void EventId() \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_CV(EventId, ...) \ + void EventId(PCSTR correlationVector) \ + { __WI_TraceLoggingWriteTagged(*this, #EventId, _GENERIC_PARTB_FIELDS_ENABLED, TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_CV(EventId, ...) \ + void EventId(PCSTR correlationVector) \ + { __WI_TraceLoggingWriteTagged(*this, #EventId, TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, ...) \ + template void EventId(T1 &&varName1) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, ...) \ + template void EventId(T1 &&varName1) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, ...) \ + template void EventId(T1 &&varName1, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, ...) \ + template void EventId(T1 &&varName1, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, PCSTR correlationVector) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM9(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, T9 &&varName9) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingValue(static_cast(wistd::forward(varName9)), _wiltlg_STRINGIZE(varName9)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM9(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, ...) \ + template void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, T9 &&varName9) \ + { \ + __WI_TraceLoggingWriteTagged(*this, #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingValue(static_cast(wistd::forward(varName9)), _wiltlg_STRINGIZE(varName9)), \ + __VA_ARGS__); \ + } +#endif + +#define DEFINE_TAGGED_TRACELOGGING_EVENT_UINT32(EventId, varName, ...) DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, UINT32, varName, __VA_ARGS__) +#define DEFINE_TAGGED_TRACELOGGING_EVENT_BOOL(EventId, varName, ...) DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, bool, varName, __VA_ARGS__) +#define DEFINE_TAGGED_TRACELOGGING_EVENT_STRING(EventId, varName, ...) DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, PCWSTR, varName, __VA_ARGS__) + + +// Internal MACRO implementation of TraceLogging classes. +// Do NOT use these macros directly. + +#define __IMPLEMENT_TRACELOGGING_CLASS_BASE(TraceLoggingClassName, TraceLoggingProviderOwnerClassName) \ + public: \ + typedef TraceLoggingProviderOwnerClassName TraceLoggingType; \ + static bool IsEnabled(UCHAR eventLevel = 0 /* WINEVENT_LEVEL_XXX, e.g. WINEVENT_LEVEL_VERBOSE */, ULONGLONG eventKeywords = 0 /* MICROSOFT_KEYWORD_XXX */) WI_NOEXCEPT \ + { return Instance()->IsEnabled_(eventLevel, eventKeywords); } \ + static TraceLoggingHProvider Provider() WI_NOEXCEPT \ + { return static_cast(Instance())->Provider_(); } \ + static void SetTelemetryEnabled(bool) WI_NOEXCEPT {} \ + static void SetErrorReportingType(wil::ErrorReportingType type) WI_NOEXCEPT \ + { return Instance()->SetErrorReportingType_(type); } \ + static void __stdcall FallbackTelemetryCallback(bool alreadyReported, wil::FailureInfo const &failure) WI_NOEXCEPT \ + { return Instance()->OnErrorReported(alreadyReported, failure); } \ + WI_NODISCARD static wil::ActivityThreadWatcher WatchCurrentThread(PCSTR contextName) WI_NOEXCEPT \ + { return wil::ActivityThreadWatcher(Instance(), contextName); } \ + WI_NODISCARD static wil::ActivityThreadWatcher WatchCurrentThread(PCSTR contextName, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT \ + { va_list argList; va_start(argList, formatString); return wil::ActivityThreadWatcher(Instance(), contextName, formatString, argList); } \ + __BEGIN_TRACELOGGING_ACTIVITY_CLASS(CallContext, wil::ActivityOptions::TelemetryOnFailure) \ + __IMPLEMENT_CALLCONTEXT_CLASS(CallContext); \ + __END_TRACELOGGING_ACTIVITY_CLASS(); \ + static CallContext Start(PCSTR contextName) WI_NOEXCEPT \ + { return CallContext(contextName, __nullptr, __nullptr); } \ + static CallContext Start(PCSTR contextName, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT \ + { va_list argList; va_start(argList, formatString); return CallContext(contextName, formatString, argList); } \ + static void TraceLoggingInfo(_Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT \ + { va_list argList; va_start(argList, formatString); return Instance()->ReportTraceLoggingMessage(formatString, argList); } \ + static void TraceLoggingError(_Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT \ + { va_list argList; va_start(argList, formatString); return Instance()->ReportTraceLoggingError(formatString, argList); } \ + private: \ + TraceLoggingHProvider Provider_() const WI_NOEXCEPT = delete; \ + TraceLoggingClassName() WI_NOEXCEPT {}; \ + protected: \ + static TraceLoggingClassName* Instance() WI_NOEXCEPT \ + { static wil::details::static_lazy wrapper; return wrapper.get([](){wrapper.cleanup();}); } \ + friend class wil::details::static_lazy; \ + + +#define __IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP(TraceLoggingClassName, ProviderName, ProviderId, TraceLoggingOption) \ + __IMPLEMENT_TRACELOGGING_CLASS_BASE(TraceLoggingClassName, TraceLoggingClassName) \ + private: \ + struct StaticHandle \ + { \ + TraceLoggingHProvider handle; \ + StaticHandle() WI_NOEXCEPT \ + { \ + TRACELOGGING_DEFINE_PROVIDER_STORAGE(__hInner, ProviderName, ProviderId, TraceLoggingOption); \ + _tlg_DefineProvider_annotation(TraceLoggingClassName, _Tlg##TraceLoggingClassName##Prov, 0, ProviderName); \ + handle = &__hInner; \ + } \ + } m_staticHandle; \ + protected: \ + void Create() WI_NOEXCEPT \ + { Register(m_staticHandle.handle); } \ + public: + +#define __IMPLEMENT_TRACELOGGING_CLASS(TraceLoggingClassName, ProviderName, ProviderId) \ + __IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP(TraceLoggingClassName, ProviderName, ProviderId, TraceLoggingOptionMicrosoftTelemetry()) + +#define __IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP_CB(TraceLoggingClassName, ProviderName, ProviderId, TraceLoggingOption) \ + __IMPLEMENT_TRACELOGGING_CLASS_BASE(TraceLoggingClassName, TraceLoggingClassName) \ + private: \ + struct StaticHandle \ + { \ + TraceLoggingHProvider handle; \ + StaticHandle() WI_NOEXCEPT \ + { \ + TRACELOGGING_DEFINE_PROVIDER_STORAGE(__hInner, ProviderName, ProviderId, TraceLoggingOption); \ + _tlg_DefineProvider_annotation(TraceLoggingClassName, _Tlg##TraceLoggingClassName##Prov, 0, ProviderName); \ + handle = &__hInner; \ + } \ + } m_staticHandle; \ + static VOID NTAPI Callback( _In_ const GUID* SourceId, \ + ULONG ControlCode, \ + UCHAR Level, \ + ULONGLONG MatchAnyKeyword, \ + ULONGLONG MatchAllKeyword, \ + _In_opt_ EVENT_FILTER_DESCRIPTOR* FilterData, \ + void* CallbackContext ); \ + protected: \ + void Create() WI_NOEXCEPT \ + { Register(m_staticHandle.handle, &TraceLoggingClassName::Callback); } \ + public: + + +#define __IMPLEMENT_TRACELOGGING_CLASS_WITHOUT_TELEMETRY(TraceLoggingClassName, ProviderName, ProviderId) \ + __IMPLEMENT_TRACELOGGING_CLASS_BASE(TraceLoggingClassName, TraceLoggingClassName) \ + private: \ + struct StaticHandle \ + { \ + TraceLoggingHProvider handle; \ + StaticHandle() WI_NOEXCEPT \ + { \ + TRACELOGGING_DEFINE_PROVIDER_STORAGE(__hInner, ProviderName, ProviderId); \ + _tlg_DefineProvider_annotation(TraceLoggingClassName, _Tlg##TraceLoggingClassName##Prov, 0, ProviderName); \ + handle = &__hInner; \ + } \ + } m_staticHandle; \ + protected: \ + void Create() WI_NOEXCEPT \ + { Register(m_staticHandle.handle); } \ + public: + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT(EventId, ...) \ + static void EventId() { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT(EventId, ...) \ + static void EventId() { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_CV(EventId, ...) \ + static void EventId(PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_CV(EventId, ...) \ + static void EventId(PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, ...) \ + template static void EventId(T1 &&varName1) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, ...) \ + template static void EventId(T1 &&varName1) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, ...) \ + template static void EventId(T1 &&varName1, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, ...) \ + template static void EventId(T1 &&varName1, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM9(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, T9 &&varName9) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingValue(static_cast(wistd::forward(varName9)), _wiltlg_STRINGIZE(varName9)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM9(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, T9 &&varName9) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingValue(static_cast(wistd::forward(varName9)), _wiltlg_STRINGIZE(varName9)), \ + __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM9_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, T9 &&varName9, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingValue(static_cast(wistd::forward(varName9)), _wiltlg_STRINGIZE(varName9)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM9_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, T9 &&varName9, PCSTR correlationVector) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingValue(static_cast(wistd::forward(varName9)), _wiltlg_STRINGIZE(varName9)), \ + TraceLoggingString(correlationVector, "__TlgCV__"), __VA_ARGS__); \ + } +#endif + +#ifdef _GENERIC_PARTB_FIELDS_ENABLED + #define DEFINE_TRACELOGGING_EVENT_PARAM10(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, VarType10, varName10, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, T9 &&varName9, T10 &&varName10) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingValue(static_cast(wistd::forward(varName9)), _wiltlg_STRINGIZE(varName9)), \ + TraceLoggingValue(static_cast(wistd::forward(varName10)), _wiltlg_STRINGIZE(varName10)), \ + _GENERIC_PARTB_FIELDS_ENABLED, \ + __VA_ARGS__); \ + } +#else + #define DEFINE_TRACELOGGING_EVENT_PARAM10(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, VarType10, varName10, ...) \ + template static void EventId(T1 &&varName1, T2 &&varName2, T3 &&varName3, T4 &&varName4, T5 &&varName5, T6 &&varName6, T7 &&varName7, T8 &&varName8, T9 &&varName9, T10 &&varName10) \ + { \ + TraceLoggingWrite(TraceLoggingType::Provider(), #EventId, \ + TraceLoggingValue(static_cast(wistd::forward(varName1)), _wiltlg_STRINGIZE(varName1)), \ + TraceLoggingValue(static_cast(wistd::forward(varName2)), _wiltlg_STRINGIZE(varName2)), \ + TraceLoggingValue(static_cast(wistd::forward(varName3)), _wiltlg_STRINGIZE(varName3)), \ + TraceLoggingValue(static_cast(wistd::forward(varName4)), _wiltlg_STRINGIZE(varName4)), \ + TraceLoggingValue(static_cast(wistd::forward(varName5)), _wiltlg_STRINGIZE(varName5)), \ + TraceLoggingValue(static_cast(wistd::forward(varName6)), _wiltlg_STRINGIZE(varName6)), \ + TraceLoggingValue(static_cast(wistd::forward(varName7)), _wiltlg_STRINGIZE(varName7)), \ + TraceLoggingValue(static_cast(wistd::forward(varName8)), _wiltlg_STRINGIZE(varName8)), \ + TraceLoggingValue(static_cast(wistd::forward(varName9)), _wiltlg_STRINGIZE(varName9)), \ + TraceLoggingValue(static_cast(wistd::forward(varName10)), _wiltlg_STRINGIZE(varName10)), \ + __VA_ARGS__); \ + } +#endif + +#define DEFINE_TRACELOGGING_EVENT_UINT32(EventId, varName, ...) DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, UINT32, varName, __VA_ARGS__) +#define DEFINE_TRACELOGGING_EVENT_BOOL(EventId, varName, ...) DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, bool, varName, __VA_ARGS__) +#define DEFINE_TRACELOGGING_EVENT_STRING(EventId, varName, ...) DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, PCWSTR, varName, __VA_ARGS__) + + +// Declaring a pure TraceLogging class +// To declare a tracelogging class, declare your class derived from wil::TraceLoggingProvider, populate the uuid +// attribute of the class with the GUID of your provider, and then include the IMPLEMENT_TRACELOGGING_CLASS_WITH_MICROSOFT_TELEMETRY +// macro within your class. +// +// If you want to register a provider using a callback to log events, you can instead use the IMPLEMENT_TRACELOGGING_CLASS_WITH_MICROSOFT_TELEMETRY_AND_CALLBACK +// Additionally your tracelogging class will have to implement a static Callback method. See the declaration within __IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP_CB. +// +// If you don't need or use telemetry, you can instead use the IMPLEMENT_TRACELOGGING_CLASS_WITHOUT_TELEMETRY. +// This prevents telemetry from enabling your provider even if you're not using telemetry. + +#define IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP(TraceLoggingClassName, ProviderName, ProviderId, GroupName) \ + __IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP(TraceLoggingClassName, ProviderName, ProviderId, GroupName) + +#define IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP_CB(TraceLoggingClassName, ProviderName, ProviderId, GroupName) \ + __IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP_CB(TraceLoggingClassName, ProviderName, ProviderId, GroupName) + +#define IMPLEMENT_TRACELOGGING_CLASS_WITH_MICROSOFT_TELEMETRY(TraceLoggingClassName, ProviderName, ProviderId) \ + IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP(TraceLoggingClassName, ProviderName, ProviderId, TraceLoggingOptionMicrosoftTelemetry()) +#define IMPLEMENT_TRACELOGGING_CLASS_WITH_MICROSOFT_TELEMETRY_AND_CALLBACK(TraceLoggingClassName, ProviderName, ProviderId) \ + IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP_CB(TraceLoggingClassName, ProviderName, ProviderId, TraceLoggingOptionMicrosoftTelemetry()) +#define IMPLEMENT_TRACELOGGING_CLASS_WITH_WINDOWS_CORE_TELEMETRY(TraceLoggingClassName, ProviderName, ProviderId) \ + IMPLEMENT_TRACELOGGING_CLASS_WITH_GROUP(TraceLoggingClassName, ProviderName, ProviderId, TraceLoggingOptionWindowsCoreTelemetry()) +#define IMPLEMENT_TRACELOGGING_CLASS_WITHOUT_TELEMETRY(TraceLoggingClassName, ProviderName, ProviderId) \ + __IMPLEMENT_TRACELOGGING_CLASS_WITHOUT_TELEMETRY(TraceLoggingClassName, ProviderName, ProviderId) + +#ifndef WIL_HIDE_DEPRECATED_1612 +WIL_WARN_DEPRECATED_1612_PRAGMA("IMPLEMENT_TRACELOGGING_CLASS") +// DEPRECATED: Use IMPLEMENT_TRACELOGGING_CLASS_WITH_MICROSOFT_TELEMETRY +#define IMPLEMENT_TRACELOGGING_CLASS IMPLEMENT_TRACELOGGING_CLASS_WITH_MICROSOFT_TELEMETRY +#endif + +// [Optional] Externally using a Tracelogging class +// Use TraceLoggingProviderWrite to directly use the trace logging provider externally from the class in code. +// This is recommended only for simple TraceLogging events. Telemetry events and activities are better defined +// within your Tracelogging class using one of the macros below. + +#define TraceLoggingProviderWrite(TraceLoggingClassName, EventId, ...) \ + TraceLoggingWrite(TraceLoggingClassName::TraceLoggingType::Provider(), EventId, __VA_ARGS__) + +#define TraceLoggingProviderWriteTelemetry(TraceLoggingClassName, EventId, ...) \ + TraceLoggingWrite(TraceLoggingClassName::TraceLoggingType::Provider(), EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), __VA_ARGS__) + +#define TraceLoggingProviderWriteMeasure(TraceLoggingClassName, EventId, ...) \ + TraceLoggingWrite(TraceLoggingClassName::TraceLoggingType::Provider(), EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), __VA_ARGS__) + +#define TraceLoggingProviderWriteCriticalData(TraceLoggingClassName, EventId, ...) \ + TraceLoggingWrite(TraceLoggingClassName::TraceLoggingType::Provider(), EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), __VA_ARGS__) + + +// [Optional] Custom Events +// Use these macros to define a Custom Event for a Provider. Use the TraceLoggingClassWrite or TraceLoggingClassWriteTelemetry +// from within a custom event to issue the event. Methods will be a no-op (and not be called) if the provider is not +// enabled. + +#define TraceLoggingClassWrite(EventId, ...) \ + TraceLoggingWrite(TraceLoggingType::Provider(), EventId, __VA_ARGS__) + +#define TraceLoggingClassWriteTelemetry(EventId, ...) \ + TraceLoggingWrite(TraceLoggingType::Provider(), EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), __VA_ARGS__) + +#define TraceLoggingClassWriteMeasure(EventId, ...) \ + TraceLoggingWrite(TraceLoggingType::Provider(), EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), __VA_ARGS__) + +#define TraceLoggingClassWriteCriticalData(EventId, ...) \ + TraceLoggingWrite(TraceLoggingType::Provider(), EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), __VA_ARGS__) + +#define DEFINE_EVENT_METHOD(MethodName) \ + template \ + static void MethodName(TArgs&&... args) WI_NOEXCEPT \ + { \ + if (IsEnabled()) \ + { Instance()->MethodName##_(wistd::forward(args)...); } \ + } \ + void MethodName##_ + + +// [Optional] Simple Events +// Use these macros to define very simple telemetry events for a Provider. The events can +// be TELEMETRY events or TRACELOGGING events. + +#define DEFINE_TELEMETRY_EVENT(EventId) \ + DEFINE_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) + +#define DEFINE_TELEMETRY_EVENT_PARAM1(EventId, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) + +#define DEFINE_TELEMETRY_EVENT_CV(EventId) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM1_CV(EventId, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TELEMETRY_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) + +#define DEFINE_TELEMETRY_EVENT_UINT32(EventId, varName) DEFINE_TELEMETRY_EVENT_PARAM1(EventId, UINT32, varName) +#define DEFINE_TELEMETRY_EVENT_BOOL(EventId, varName) DEFINE_TELEMETRY_EVENT_PARAM1(EventId, bool, varName) +#define DEFINE_TELEMETRY_EVENT_STRING(EventId, varName) DEFINE_TELEMETRY_EVENT_PARAM1(EventId, PCWSTR, varName) + +#define DEFINE_COMPLIANT_TELEMETRY_EVENT(EventId, PrivacyTag) \ + DEFINE_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM1(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM2(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM3(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM4(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM5(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM6(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM7(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM8(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_CV(EventId, PrivacyTag) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM1_CV(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM2_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM3_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM4_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM5_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM6_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM7_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM8_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_CV(EventId, PrivacyTag, EventTag) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_PARAM1_CV(EventId, PrivacyTag, EventTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_PARAM2_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_PARAM3_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_PARAM4_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_PARAM5_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_PARAM6_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_PARAM7_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_TELEMETRY_EVENT_PARAM8_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) + +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_UINT32(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM1(EventId, PrivacyTag, UINT32, varName) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_BOOL(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM1(EventId, PrivacyTag, bool, varName) +#define DEFINE_COMPLIANT_TELEMETRY_EVENT_STRING(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_TELEMETRY_EVENT_PARAM1(EventId, PrivacyTag, PCWSTR, varName) + +// [Optional] Simple Events +// Use these macros to define very simple measure events for a Provider. + +#define DEFINE_MEASURES_EVENT(EventId) \ + DEFINE_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM1(EventId, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) + +#define DEFINE_MEASURES_EVENT_CV(EventId) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM1_CV(EventId, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_MEASURES_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) + +#define DEFINE_MEASURES_EVENT_UINT32(EventId, varName) DEFINE_MEASURES_EVENT_PARAM1(EventId, UINT32, varName) +#define DEFINE_MEASURES_EVENT_BOOL(EventId, varName) DEFINE_MEASURES_EVENT_PARAM1(EventId, bool, varName) +#define DEFINE_MEASURES_EVENT_STRING(EventId, varName) DEFINE_MEASURES_EVENT_PARAM1(EventId, PCWSTR, varName) + +#define DEFINE_COMPLIANT_MEASURES_EVENT(EventId, PrivacyTag) \ + DEFINE_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM1(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM2(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM3(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM4(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM5(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM6(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM7(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM8(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM9(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9) \ + DEFINE_TRACELOGGING_EVENT_PARAM9(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM10(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, VarType10, varName10) \ + DEFINE_TRACELOGGING_EVENT_PARAM10(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, VarType10, varName10, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_COMPLIANT_MEASURES_EVENT_CV(EventId, PrivacyTag) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM1_CV(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM2_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM3_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM4_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM5_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM6_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM7_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_MEASURES_EVENT_PARAM8_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_CV(EventId, PrivacyTag, EventTag) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM1_CV(EventId, PrivacyTag, EventTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM2_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM3_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM4_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM5_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM6_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM7_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM8_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_MEASURES_EVENT_PARAM9_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9) \ + DEFINE_TRACELOGGING_EVENT_PARAM9_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) + +#define DEFINE_COMPLIANT_MEASURES_EVENT_UINT32(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_MEASURES_EVENT_PARAM1(EventId, PrivacyTag, UINT32, varName) +#define DEFINE_COMPLIANT_MEASURES_EVENT_BOOL(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_MEASURES_EVENT_PARAM1(EventId, PrivacyTag, bool, varName) +#define DEFINE_COMPLIANT_MEASURES_EVENT_STRING(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_MEASURES_EVENT_PARAM1(EventId, PrivacyTag, PCWSTR, varName) + +// [Optional] Simple Events +// Use these macros to define very simple critical data events for a Provider. + +#define DEFINE_CRITICAL_DATA_EVENT(EventId) \ + DEFINE_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM1(EventId, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) + +#define DEFINE_CRITICAL_DATA_EVENT_CV(EventId) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM1_CV(EventId, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_CRITICAL_DATA_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) + +#define DEFINE_CRITICAL_DATA_EVENT_UINT32(EventId, varName) DEFINE_CRITICAL_DATA_EVENT_PARAM1(EventId, UINT32, varName) +#define DEFINE_CRITICAL_DATA_EVENT_BOOL(EventId, varName) DEFINE_CRITICAL_DATA_EVENT_PARAM1(EventId, bool, varName) +#define DEFINE_CRITICAL_DATA_EVENT_STRING(EventId, varName) DEFINE_CRITICAL_DATA_EVENT_PARAM1(EventId, PCWSTR, varName) + +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT(EventId, PrivacyTag) \ + DEFINE_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM2(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM3(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM4(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM5(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM6(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM7(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM8(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_CV(EventId, PrivacyTag) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1_CV(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM2_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM3_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM4_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM5_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM6_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM7_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM8_CV(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_CV(EventId, PrivacyTag, EventTag) \ + DEFINE_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM1_CV(EventId, PrivacyTag, EventTag, VarType1, varName1) \ + DEFINE_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM2_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM3_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM4_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM5_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM6_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM7_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM8_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) +#define DEFINE_COMPLIANT_EVENTTAGGED_CRITICAL_DATA_EVENT_PARAM9_CV(EventId, PrivacyTag, EventTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9) \ + DEFINE_TRACELOGGING_EVENT_PARAM9_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag), TraceLoggingEventTag(EventTag)) + +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_UINT32(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1(EventId, PrivacyTag, UINT32, varName) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_BOOL(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1(EventId, PrivacyTag, bool, varName) +#define DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_STRING(EventId, PrivacyTag, varName) DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1(EventId, PrivacyTag, PCWSTR, varName) + +// Custom Activities +// For these you pair the appropriate BEGIN and END macros to define your activity. Within the pair +// you can use the (TODO: LIST MACRO NAMES) macros to add behavior. + +// [optional] params are: Options, Keyword, Level, PrivacyTag +#define BEGIN_CUSTOM_ACTIVITY_CLASS(ActivityClassName, ...) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, __VA_ARGS__) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) + +// [optional] param is: Level, PrivacyTag +#define BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_TRACELOGGING_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::None, 0, Level) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, PrivacyTag) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::None, 0, WINEVENT_LEVEL_VERBOSE, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_TRACELOGGING_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::None, 0, Level, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) + +// [optional] param is: Level +#define BEGIN_CALLCONTEXT_ACTIVITY_CLASS(ActivityClassName) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_CALLCONTEXT_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, 0, Level) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_CALLCONTEXT_ACTIVITY_CLASS(ActivityClassName, PrivacyTag) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, 0, WINEVENT_LEVEL_VERBOSE, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_CALLCONTEXT_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, 0, Level, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) + +// [optional] param is: Level +#define BEGIN_TELEMETRY_ACTIVITY_CLASS(ActivityClassName) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_TELEMETRY) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_TELEMETRY_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_TELEMETRY, Level) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_TELEMETRY_ACTIVITY_CLASS(ActivityClassName, PrivacyTag) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_TELEMETRY, WINEVENT_LEVEL_VERBOSE, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_TELEMETRY_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_TELEMETRY, Level, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) + +// [optional] param is: Level +#define BEGIN_MEASURES_ACTIVITY_CLASS(ActivityClassName) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_MEASURES) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_MEASURES_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_MEASURES, Level) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(ActivityClassName, PrivacyTag) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_MEASURES, WINEVENT_LEVEL_VERBOSE, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_MEASURES, Level, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) + +// [optional] param is: Level +#define BEGIN_CRITICAL_DATA_ACTIVITY_CLASS(ActivityClassName) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_CRITICAL_DATA) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_CRITICAL_DATA_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_CRITICAL_DATA, Level) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_CRITICAL_DATA_ACTIVITY_CLASS(ActivityClassName, PrivacyTag) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_CRITICAL_DATA, WINEVENT_LEVEL_VERBOSE, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) +#define BEGIN_COMPLIANT_CRITICAL_DATA_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) __BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName, wil::ActivityOptions::TelemetryOnFailure, MICROSOFT_KEYWORD_CRITICAL_DATA, Level, PrivacyTag) \ + __IMPLEMENT_ACTIVITY_CLASS(ActivityClassName) + +// Use to end ALL activity class definitions +#define END_ACTIVITY_CLASS() __END_TRACELOGGING_ACTIVITY_CLASS() + + +// Simple Activities +// For these you just use the appropriate macro to define the KIND of activity you want and specify +// the name (for tracelogging you can give other options) + +// [optional] params are: Options, Keyword, Level +#define DEFINE_CUSTOM_ACTIVITY(ActivityClassName, ...) \ + BEGIN_CUSTOM_ACTIVITY_CLASS(ActivityClassName, __VA_ARGS__) \ + END_ACTIVITY_CLASS() + +#define DEFINE_TRACELOGGING_ACTIVITY(ActivityClassName) \ + BEGIN_TRACELOGGING_ACTIVITY_CLASS(ActivityClassName) \ + END_ACTIVITY_CLASS() +#define DEFINE_TRACELOGGING_ACTIVITY_WITH_LEVEL(ActivityClassName, Level) \ + BEGIN_TRACELOGGING_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) \ + END_ACTIVITY_CLASS() + +#define DEFINE_CALLCONTEXT_ACTIVITY(ActivityClassName) \ + BEGIN_CALLCONTEXT_ACTIVITY_CLASS(ActivityClassName) \ + END_ACTIVITY_CLASS() +#define DEFINE_CALLCONTEXT_ACTIVITY_WITH_LEVEL(ActivityClassName, Level) \ + BEGIN_CALLCONTEXT_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) \ + END_ACTIVITY_CLASS() + +#define DEFINE_TELEMETRY_ACTIVITY(ActivityClassName) \ + BEGIN_TELEMETRY_ACTIVITY_CLASS(ActivityClassName) \ + END_ACTIVITY_CLASS() +#define DEFINE_TELEMETRY_ACTIVITY_WITH_LEVEL(ActivityClassName, Level) \ + BEGIN_TELEMETRY_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) \ + END_ACTIVITY_CLASS() +#define DEFINE_COMPLIANT_TELEMETRY_ACTIVITY(ActivityClassName, PrivacyTag) \ + BEGIN_COMPLIANT_TELEMETRY_ACTIVITY_CLASS(ActivityClassName, PrivacyTag) \ + END_ACTIVITY_CLASS() +#define DEFINE_COMPLIANT_TELEMETRY_ACTIVITY_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) \ + BEGIN_COMPLIANT_TELEMETRY_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) \ + END_ACTIVITY_CLASS() + +#define DEFINE_MEASURES_ACTIVITY(ActivityClassName) \ + BEGIN_MEASURES_ACTIVITY_CLASS(ActivityClassName) \ + END_ACTIVITY_CLASS() +#define DEFINE_MEASURES_ACTIVITY_WITH_LEVEL(ActivityClassName, Level) \ + BEGIN_MEASURES_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) \ + END_ACTIVITY_CLASS() +#define DEFINE_COMPLIANT_MEASURES_ACTIVITY(ActivityClassName, PrivacyTag) \ + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(ActivityClassName, PrivacyTag) \ + END_ACTIVITY_CLASS() +#define DEFINE_COMPLIANT_MEASURES_ACTIVITY_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) \ + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) \ + END_ACTIVITY_CLASS() + +#define DEFINE_CRITICAL_DATA_ACTIVITY(ActivityClassName) \ + BEGIN_CRITICAL_DATA_ACTIVITY_CLASS(ActivityClassName) \ + END_ACTIVITY_CLASS() +#define DEFINE_CRITICAL_DATA_ACTIVITY_WITH_LEVEL(ActivityClassName, Level) \ + BEGIN_CRITICAL_DATA_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, Level) \ + END_ACTIVITY_CLASS() +#define DEFINE_COMPLIANT_CRITICAL_DATA_ACTIVITY(ActivityClassName, PrivacyTag) \ + BEGIN_COMPLIANT_CRITICAL_DATA_ACTIVITY_CLASS(ActivityClassName, PrivacyTag) \ + END_ACTIVITY_CLASS() +#define DEFINE_COMPLIANT_CRITICAL_DATA_ACTIVITY_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) \ + BEGIN_COMPLIANT_CRITICAL_DATA_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, PrivacyTag, Level) \ + END_ACTIVITY_CLASS() + + +// [Optional] Custom Start or Stop Events for Activities +// Use these macros to define custom start or custom stop methods for an activity. Any activity can +// have multiple start or stop methods. To add custom start or stop events, define a StartActivity instance +// method or a Stop instance method within the BEGIN/END pair of a custom activity. Within that function, use +// TraceLoggingClassWriteStart or TraceLoggingClassWriteStop. + +// Params: (EventId, ...) +#define TraceLoggingClassWriteStart __WRITE_ACTIVITY_START +#define TraceLoggingClassWriteStop __WRITE_ACTIVITY_STOP + + +// [Optional] Custom Tagged Events for Activities +// Use these macros to define a Custom Tagged Event for a Custom Activity. Use the +// TraceLoggingClassWriteTagged or TraceLoggingClassWriteTaggedTelemetry macros from within a custom event +// to write the event. + +#define TraceLoggingClassWriteTagged(EventId, ...) \ + __WI_TraceLoggingWriteTagged(*this, #EventId, __VA_ARGS__) + +#define TraceLoggingClassWriteTaggedTelemetry(EventId, ...) \ + __WI_TraceLoggingWriteTagged(*this, #EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), __VA_ARGS__) + +#define TraceLoggingClassWriteTaggedMeasure(EventId, ...) \ + __WI_TraceLoggingWriteTagged(*this, #EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), __VA_ARGS__) + +#define TraceLoggingClassWriteTaggedCriticalData(EventId, ...) \ + __WI_TraceLoggingWriteTagged(*this, #EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), __VA_ARGS__) + +// [Optional] Simple Tagged Events for Activities +// Use these methods to define very simple tagged events for a Custom Activity. + +#define DEFINE_TAGGED_TELEMETRY_EVENT(EventId) \ + DEFINE_TAGGED_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM1(EventId, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) + +#define DEFINE_TAGGED_TELEMETRY_EVENT_CV(EventId) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM1_CV(EventId, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) +#define DEFINE_TAGGED_TELEMETRY_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY)) + +#define DEFINE_TAGGED_TELEMETRY_EVENT_UINT32(EventId, varName) DEFINE_TAGGED_TELEMETRY_EVENT_PARAM1(EventId, UINT32, varName) +#define DEFINE_TAGGED_TELEMETRY_EVENT_BOOL(EventId, varName) DEFINE_TAGGED_TELEMETRY_EVENT_PARAM1(EventId, bool, varName) +#define DEFINE_TAGGED_TELEMETRY_EVENT_STRING(EventId, varName) DEFINE_TAGGED_TELEMETRY_EVENT_PARAM1(EventId, PCWSTR, varName) + +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT(EventId, PrivacyTag) \ + DEFINE_TAGGED_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM1(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM2(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM3(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM4(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM5(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM6(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM7(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM8(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_UINT32(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM1(EventId, PrivacyTag, UINT32, varName) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_BOOL(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM1(EventId, PrivacyTag, bool, varName) +#define DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_STRING(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_TELEMETRY_EVENT_PARAM1(EventId, PrivacyTag, PCWSTR, varName) + +// [Optional] Simple Tagged Events for Activities +// Use these methods to define very simple tagged measures events for a Custom Activity. + +#define DEFINE_TAGGED_MEASURES_EVENT(EventId) \ + DEFINE_TAGGED_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM1(EventId, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) + +#define DEFINE_TAGGED_MEASURES_EVENT_CV(EventId) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM1_CV(EventId, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) +#define DEFINE_TAGGED_MEASURES_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)) + +#define DEFINE_TAGGED_MEASURES_EVENT_UINT32(EventId, varName) DEFINE_TAGGED_MEASURES_EVENT_PARAM1(EventId, UINT32, varName) +#define DEFINE_TAGGED_MEASURES_EVENT_BOOL(EventId, varName) DEFINE_TAGGED_MEASURES_EVENT_PARAM1(EventId, bool, varName) +#define DEFINE_TAGGED_MEASURES_EVENT_STRING(EventId, varName) DEFINE_TAGGED_MEASURES_EVENT_PARAM1(EventId, PCWSTR, varName) + +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT(EventId, PrivacyTag) \ + DEFINE_TAGGED_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM1(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM2(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM3(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM4(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM5(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM6(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM7(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM8(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_UINT32(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM1(EventId, PrivacyTag, UINT32, varName) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_BOOL(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM1(EventId, PrivacyTag, bool, varName) +#define DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_STRING(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_MEASURES_EVENT_PARAM1(EventId, PrivacyTag, PCWSTR, varName) + +// [Optional] Simple Tagged Events for Activities +// Use these methods to define very simple tagged CRITICAL_DATA events for a Custom Activity. + +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT(EventId) \ + DEFINE_TAGGED_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM1(EventId, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM9(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM9(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, VarType9, varName9, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) + +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_CV(EventId) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_CV(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM1_CV(EventId, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1_CV(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2_CV(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8_CV(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)) + +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_UINT32(EventId, varName) DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM1(EventId, UINT32, varName) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_BOOL(EventId, varName) DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM1(EventId, bool, varName) +#define DEFINE_TAGGED_CRITICAL_DATA_EVENT_STRING(EventId, varName) DEFINE_TAGGED_CRITICAL_DATA_EVENT_PARAM1(EventId, PCWSTR, varName) + +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT(EventId, PrivacyTag) \ + DEFINE_TAGGED_TRACELOGGING_EVENT(EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1(EventId, PrivacyTag, VarType1, varName1) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1(EventId, VarType1, varName1, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM2(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2(EventId, VarType1, varName1, VarType2, varName2, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM3(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM4(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM5(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM6(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM7(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM8(EventId, PrivacyTag, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8) \ + DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM8(EventId, VarType1, varName1, VarType2, varName2, VarType3, varName3, VarType4, varName4, VarType5, varName5, VarType6, varName6, VarType7, varName7, VarType8, varName8, TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA), TelemetryPrivacyDataTag(PrivacyTag)) + +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_UINT32(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1(EventId, PrivacyTag, UINT32, varName) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_BOOL(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1(EventId, PrivacyTag, bool, varName) +#define DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_STRING(EventId, PrivacyTag, varName) DEFINE_TAGGED_COMPLIANT_CRITICAL_DATA_EVENT_PARAM1(EventId, PrivacyTag, PCWSTR, varName) + +// Thread Activities [deprecated] +// These are desktop only and are not recommended by the fundamentals team. These activities lag behind regular activities in +// their ability to use CallContext or to be cross-thread portable, so their usage should be limited. + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_KEYWORD_LEVEL(ActivityClassName, keyword, level) \ + class ActivityClassName final : public _TlgActivityBase \ + { \ + static const UINT64 PrivacyTag = 0; \ + friend class _TlgActivityBase; \ + void OnStarted() { PushThreadActivityId(); } \ + void OnStopped() { PopThreadActivityId(); } \ + public: \ + ActivityClassName() : m_result(S_OK) \ + { \ + } \ + private: \ + template \ + ActivityClassName(_In_ void **, TArgs&&... args) : m_result(S_OK) \ + { \ + StartActivity(wistd::forward(args)...); \ + } \ + protected: \ + void EnsureWatchingCurrentThread() {} \ + void IgnoreCurrentThread() {} \ + wil::FailureInfo const *GetFailureInfo() \ + { \ + return (FAILED(m_result) && (m_cache.GetFailure() != nullptr) && (m_result == m_cache.GetFailure()->hr)) ? m_cache.GetFailure() : nullptr; \ + } \ + HRESULT GetResult() \ + { \ + return m_result; \ + } \ + public: \ + ~ActivityClassName() \ + { \ + Stop(HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)); \ + } \ + ActivityClassName(ActivityClassName &&) = default; \ + WI_NODISCARD TraceLoggingHProvider Provider() const \ + { \ + return TraceLoggingType::Provider(); \ + } \ + void Stop(HRESULT hr = S_OK) \ + { \ + if (IsStarted()) \ + { \ + m_result = hr; \ + TRACELOGGING_WRITE_ACTIVITY_STOP(ActivityClassName); \ + } \ + } \ + template \ + void StopWithResult(HRESULT hr, TArgs&&... args) \ + { \ + m_result = hr; \ + Stop(wistd::forward(args)...); \ + } \ + template \ + static ActivityClassName Start(TArgs&&... args) \ + { \ + return ActivityClassName(static_cast(__nullptr), wistd::forward(args)...); \ + } \ + void StartActivity() \ + { \ + TRACELOGGING_WRITE_ACTIVITY_START(ActivityClassName); \ + } \ + +#define BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_KEYWORD(ActivityClassName, keyword) \ + BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_KEYWORD_LEVEL(ActivityClassName, keyword, WINEVENT_LEVEL_VERBOSE) + +#define BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, level) \ + BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_KEYWORD_LEVEL(ActivityClassName, 0, level) + +#define BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS(ActivityClassName) \ + BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_KEYWORD_LEVEL(ActivityClassName, 0, WINEVENT_LEVEL_VERBOSE) + +#define END_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS() \ + private: \ + HRESULT m_result; \ + wil::ThreadFailureCache m_cache; \ + }; + +#define BEGIN_DEFINE_TELEMETRY_THREAD_ACTIVITY_CLASS(ActivityClassName) \ + BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_KEYWORD(ActivityClassName, MICROSOFT_KEYWORD_TELEMETRY) + +#define END_DEFINE_TELEMETRY_THREAD_ACTIVITY_CLASS() \ + END_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS() + +#define DEFINE_TRACELOGGING_THREAD_ACTIVITY_WITH_KEYWORD_LEVEL(ActivityClassName, keyword, level) \ + BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_KEYWORD_LEVEL(ActivityClassName, keyword, level) \ + END_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS() + +#define DEFINE_TRACELOGGING_THREAD_ACTIVITY_WITH_KEYWORD(ActivityClassName, keyword) \ + BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_KEYWORD(ActivityClassName, keyword) \ + END_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS() + +#define DEFINE_TRACELOGGING_THREAD_ACTIVITY_WITH_LEVEL(ActivityClassName, level) \ + BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS_WITH_LEVEL(ActivityClassName, level) \ + END_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS() + +#define DEFINE_TRACELOGGING_THREAD_ACTIVITY(ActivityClassName) \ + BEGIN_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS(ActivityClassName) \ + END_DEFINE_TRACELOGGING_THREAD_ACTIVITY_CLASS() + +#define DEFINE_TELEMETRY_THREAD_ACTIVITY(ActivityClassName) \ + BEGIN_DEFINE_TELEMETRY_THREAD_ACTIVITY_CLASS(ActivityClassName) \ + END_DEFINE_TELEMETRY_THREAD_ACTIVITY_CLASS() + +#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */ + + +// [deprecated] +// DO NOT USE these concepts +// These should be removed post RI/FI cycle... + +#define DEFINE_TRACELOGGING_METHOD DEFINE_EVENT_METHOD +#define BEGIN_DEFINE_TELEMETRY_ACTIVITY_CLASS BEGIN_TELEMETRY_ACTIVITY_CLASS +#define END_DEFINE_TELEMETRY_ACTIVITY_CLASS END_ACTIVITY_CLASS +#define BEGIN_DEFINE_TRACELOGGING_ACTIVITY_CLASS BEGIN_TRACELOGGING_ACTIVITY_CLASS +#define END_DEFINE_TRACELOGGING_ACTIVITY_CLASS END_ACTIVITY_CLASS +#define TELEMETRY_WRITE_ACTIVITY_START TraceLoggingClassWriteStart +#define TRACELOGGING_WRITE_ACTIVITY_START TraceLoggingClassWriteStart +#define TELEMETRY_WRITE_ACTIVITY_STOP TraceLoggingClassWriteStop +#define TRACELOGGING_WRITE_ACTIVITY_STOP TraceLoggingClassWriteStop +#define WRITE_TRACELOGGING_EVENT TraceLoggingClassWrite +#define WRITE_TELEMETRY_EVENT TraceLoggingClassWriteTelemetry +#define TRACELOGGING_WRITE_TAGGED_EVENT TraceLoggingClassWriteTagged +#define TELEMETRY_WRITE_TAGGED_EVENT TraceLoggingClassWriteTaggedTelemetry + +// [deprecated] +// DO NOT USE these concepts +// These should be removed post RI/FI cycle... +#define __DEFINE_EVENT DEFINE_TRACELOGGING_EVENT +#define __DEFINE_EVENT_PARAM1 DEFINE_TRACELOGGING_EVENT_PARAM1 +#define __DEFINE_EVENT_PARAM2 DEFINE_TRACELOGGING_EVENT_PARAM2 +#define __DEFINE_EVENT_PARAM3 DEFINE_TRACELOGGING_EVENT_PARAM3 +#define __DEFINE_EVENT_PARAM4 DEFINE_TRACELOGGING_EVENT_PARAM4 +#define __DEFINE_EVENT_PARAM5 DEFINE_TRACELOGGING_EVENT_PARAM5 +#define __DEFINE_EVENT_PARAM6 DEFINE_TRACELOGGING_EVENT_PARAM6 +#define __DEFINE_EVENT_PARAM7 DEFINE_TRACELOGGING_EVENT_PARAM7 +#define __DEFINE_EVENT_UINT32 DEFINE_TRACELOGGING_EVENT_UINT32 +#define __DEFINE_EVENT_BOOL DEFINE_TRACELOGGING_EVENT_BOOL +#define __DEFINE_EVENT_STRING DEFINE_TRACELOGGING_EVENT_STRING + +// [deprecated] +// DO NOT USE these concepts +// These should be removed post RI/FI cycle... +#define __DEFINE_TAGGED_EVENT DEFINE_TAGGED_TRACELOGGING_EVENT +#define __DEFINE_TAGGED_EVENT_PARAM1 DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM1 +#define __DEFINE_TAGGED_EVENT_PARAM2 DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM2 +#define __DEFINE_TAGGED_EVENT_PARAM3 DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM3 +#define __DEFINE_TAGGED_EVENT_PARAM4 DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM4 +#define __DEFINE_TAGGED_EVENT_PARAM5 DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM5 +#define __DEFINE_TAGGED_EVENT_PARAM6 DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM6 +#define __DEFINE_TAGGED_EVENT_PARAM7 DEFINE_TAGGED_TRACELOGGING_EVENT_PARAM7 +#define __DEFINE_TAGGED_EVENT_UINT32 DEFINE_TAGGED_TRACELOGGING_EVENT_UINT32 +#define __DEFINE_TAGGED_EVENT_BOOL DEFINE_TAGGED_TRACELOGGING_EVENT_BOOL +#define __DEFINE_TAGGED_EVENT_STRING DEFINE_TAGGED_TRACELOGGING_EVENT_STRING + +template +class ActivityErrorTracer +{ +public: + ActivityErrorTracer(T const &) {} +}; + +using TelemetryBase = wil::TraceLoggingProvider; + +#define TRACELOGGING_WRITE_EVENT(TraceLoggingClassName, EventId, ...) \ + TraceLoggingWrite(TraceLoggingClassName::TraceLoggingType::Provider(), EventId, __VA_ARGS__) + +#define TELEMETRY_WRITE_EVENT(EventId, ...) \ + TraceLoggingWrite(TraceLoggingType::Provider(), EventId, TraceLoggingKeyword(MICROSOFT_KEYWORD_TELEMETRY), __VA_ARGS__) + +#define DEFINE_TAGGED_EVENT_METHOD(MethodName) \ + public: void MethodName + +#define DEFINE_ACTIVITY_START(...) \ + void StartActivity(__VA_ARGS__) + +#define DEFINE_ACTIVITY_STOP(...) \ + void Stop(__VA_ARGS__) + +#define DECLARE_TRACELOGGING_CLASS(TraceLoggingClassName, ProviderName, ProviderId) \ + class TraceLoggingClassName : public wil::TraceLoggingProvider \ + { \ + IMPLEMENT_TRACELOGGING_CLASS_WITH_MICROSOFT_TELEMETRY(TraceLoggingClassName, ProviderName, ProviderId); \ + }; + +#define IMPLEMENT_TELEMETRY_CLASS(TelemetryClassName, TraceLoggingClassName) \ + __IMPLEMENT_TRACELOGGING_CLASS_BASE(TelemetryClassName, TraceLoggingClassName) \ + protected: \ + void Create() \ + { AttachProvider(TraceLoggingClassName::Provider()); \ + __TRACELOGGING_DEFINE_PROVIDER_STORAGE_LINK(TelemetryClassName, TraceLoggingClassName); } \ + public: + +namespace wil +{ + /// @cond + namespace details + { +#ifdef WIL_API_TELEMETRY_SUSPEND_HANDLER +#pragma detect_mismatch("ODR_violation_WIL_API_TELEMETRY_SUSPEND_HANDLER_mismatch", "1") +#else +#pragma detect_mismatch("ODR_violation_WIL_API_TELEMETRY_SUSPEND_HANDLER_mismatch", "0") +#endif + + class ApiTelemetryLogger : public wil::TraceLoggingProvider + { + // {fb7fcbc6-7156-5a5b-eabd-0be47b14f453} + IMPLEMENT_TRACELOGGING_CLASS_WITH_MICROSOFT_TELEMETRY(ApiTelemetryLogger, "Microsoft.Windows.ApiTelemetry", (0xfb7fcbc6, 0x7156, 0x5a5b, 0xea, 0xbd, 0x0b, 0xe4, 0x7b, 0x14, 0xf4, 0x53)); + public: + // Used to store of list of APIs (with namespace, class, custom and call count data per API). + // This is public so that it can be unit tested. + class ApiDataList + { + public: + struct ApiData + { + PCWSTR className = nullptr; + PCWSTR apiName = nullptr; + PCSTR specialization = nullptr; + volatile long* counterReference = nullptr; + wistd::unique_ptr next; + + ApiData(PCWSTR className_, PCWSTR apiName_, PCSTR specialization_, volatile long* counterReference_) : + className(className_), apiName(apiName_), specialization(specialization_), counterReference(counterReference_) + { + } + }; + + // Inserts a new Api call counter into the list, keeping the list sorted by className + void Insert(PCWSTR className, PCWSTR apiName, _In_opt_ PCSTR specialization, volatile long* counterReference) + { + wistd::unique_ptr newApiData(new(std::nothrow) ApiData(className, apiName, specialization, counterReference)); + if (newApiData) + { + auto lock = m_lock.lock_exclusive(); + + // Insert the new ApiData, keeping the list sorted by className. + wistd::unique_ptr* currentNode = &m_root; + while (*currentNode) + { + wistd::unique_ptr& node = *currentNode; + if (wcscmp(className, node->className) <= 0) + { + break; + } + currentNode = &(node->next); + } + newApiData->next.reset(currentNode->release()); + currentNode->reset(newApiData.release()); + } + } + + // For each distinct namespace, calls the provided flushCallback function. + // After returning, it will have deleted all ApiData elements, and zeroed the *counterReference stored in each ApiData. + void Flush(wistd::function flushCallback) + { + wistd::unique_ptr root; + if (m_root) + { + auto lock = m_lock.lock_exclusive(); + root.swap(m_root); + } + + while (root) + { + // First find the number of characters we need to allocate for each string, and the number of items in the counter array to allocate + size_t totalApiListLength = 1; // Init to 1 to account for null terminator + size_t totalSpecializationsLength = 1; // Init to 1 to account for null terminator + UINT16 numCounts = 0; + + ProcessSingleNamespace(&root, + [&](wistd::unique_ptr& node) + { + // Get the length needed for the class string + const wchar_t* strAfterNamespace = GetClassStringPointer(node->className); + size_t classStrLen = wcslen(strAfterNamespace ? strAfterNamespace : node->className); + + totalApiListLength += (classStrLen + wcslen(node->apiName) + 1); // We add 1 to account for the comma delimeter + if (node->specialization) + { + totalSpecializationsLength += strlen(node->specialization) + 1; // We add 1 to account for the comma delimeter + } + else + { + totalSpecializationsLength += 2; // '-' plus comma delimeter + } + numCounts++; + }); + + // Fill arrays with the API data, and then pass it to the callback function + wistd::unique_ptr apiList(new(std::nothrow) wchar_t[totalApiListLength]); + wistd::unique_ptr specializationList(new(std::nothrow) char[totalSpecializationsLength]); + wistd::unique_ptr countArray(new(std::nothrow) UINT32[numCounts]); + size_t nameSpaceLength = GetNameSpaceLength(root->className) + 1; + wistd::unique_ptr nameSpace(new(std::nothrow) wchar_t[nameSpaceLength]); + if (!apiList || !specializationList || !countArray || !nameSpace) + { + return; + } + + ZeroMemory(apiList.get(), totalApiListLength * sizeof(wchar_t)); + ZeroMemory(specializationList.get(), totalSpecializationsLength * sizeof(char)); + ZeroMemory(countArray.get(), numCounts * sizeof(UINT32)); + ZeroMemory(nameSpace.get(), nameSpaceLength * sizeof(wchar_t)); + + StringCchCopyNW(nameSpace.get(), STRSAFE_MAX_CCH, root->className, nameSpaceLength - 1); + + int countArrayIndex = 0; + + wistd::unique_ptr* lastNamespaceNode = ProcessSingleNamespace(&root, + [&](wistd::unique_ptr& node) + { + countArray[countArrayIndex] = static_cast(::InterlockedExchangeNoFence(node->counterReference, 0)); + + // Prepend the portion of the apiName group string that's after the '.'. So for example, if the + // className is "Windows.System.Launcher", then we prepend "Launcher." to the apiName string. + const wchar_t* strAfterNamespace = GetClassStringPointer(node->className); + if (strAfterNamespace) + { + FAIL_FAST_IF_FAILED(StringCchCatW(apiList.get(), totalApiListLength, strAfterNamespace + 1)); + FAIL_FAST_IF_FAILED(StringCchCatW(apiList.get(), totalApiListLength, L".")); + } + + FAIL_FAST_IF_FAILED(StringCchCatW(apiList.get(), totalApiListLength, node->apiName)); + if (node->specialization) + { + FAIL_FAST_IF(strncat_s(specializationList.get(), totalSpecializationsLength, node->specialization, strlen(node->specialization)) != 0); + } + else + { + FAIL_FAST_IF(strncat_s(specializationList.get(), totalSpecializationsLength, "-", 1) != 0); + } + + if (countArrayIndex != (numCounts - 1)) + { + FAIL_FAST_IF_FAILED(StringCchCatW(apiList.get(), totalApiListLength, L",")); + FAIL_FAST_IF(strncat_s(specializationList.get(), totalSpecializationsLength, ",", 1) != 0); + } + + countArrayIndex++; + }); + + // Call the callback function with the data we've collected for this namespace + flushCallback(nameSpace.get(), apiList.get(), specializationList.get(), countArray.get(), numCounts); + + if (*lastNamespaceNode) + { + root.swap((*lastNamespaceNode)->next); + } + else + { + root.reset(); + } + } + } + + private: + static wistd::unique_ptr* ProcessSingleNamespace(wistd::unique_ptr* root, wistd::function&)> workerCallback) + { + wistd::unique_ptr* currentNode = root; + while (*currentNode) + { + wistd::unique_ptr& node = *currentNode; + + workerCallback(node); + + // Check if our next node would be a new namespace; if so, then break out + if (node->next && !IsSameNameSpace(node->className, node->next->className)) + { + break; + } + + currentNode = &(node->next); + } + + return currentNode; + } + + static bool IsSameNameSpace(PCWSTR namespaceClass1, PCWSTR namespaceClass2) + { + return (wcsncmp(namespaceClass1, namespaceClass2, GetNameSpaceLength(namespaceClass2) + 1) == 0); + } + + static size_t GetNameSpaceLength(PCWSTR nameSpaceClass) + { + const wchar_t* strAfterNamespace = GetClassStringPointer(nameSpaceClass); + return (strAfterNamespace ? (strAfterNamespace - nameSpaceClass) : wcslen(nameSpaceClass)); + } + + static const wchar_t* GetClassStringPointer(PCWSTR nameSpaceClass) + { + // Note: Usage of wcsrchr can cause build errors in some components, so we implement a way of getting the pointer to the 'class' portion + // of the string ourselves. + int retIndex = 0; + while (nameSpaceClass[retIndex] != '\0') + { + retIndex++; + } + while (retIndex > 0 && nameSpaceClass[retIndex] != '.') + { + retIndex--; + } + return (retIndex != 0 ? &(nameSpaceClass[retIndex]) : nullptr); + } + + wistd::unique_ptr m_root; + wil::srwlock m_lock; + }; + + public: + // Initializes an entry that holds the className.apiName, along with a counter for that className.apiName. + // The counterReference passed to this should later be passed to LogApiInfo. + // + // A separate entry will be created for each apiName that has a distinct specialization value. + // + // This function only needs to be called once for each API, although it doesn't hurt if it gets called more than once. + // + // The apiName, className, and specialization parameters should be compile time constants. specialization can be null. + DEFINE_EVENT_METHOD(InitApiData)(PCWSTR className, PCWSTR apiName, _In_opt_ PCSTR specialization, volatile long* counterReference) + { + // TODO: Validate that apiName and className are a compile-time constants; validate that specialization is + // either compile-time constant or nullptr; validate that counterReference points to static variable. + // Can do this by making sure address is <= (GetModuleHandle() + DLL size). + m_apiDataList.Insert(className, apiName, specialization, counterReference); + } + + // Fires a telemetry event that contains the method call apiName that has been logged by the component, + // since the last FireEvent() call, or since the component was loaded. + DEFINE_EVENT_METHOD(FireEvent)() + { + m_apiDataList.Flush( + [](PCWSTR nameSpace, PCWSTR apiList, PCSTR specializationList, UINT32* countArray, UINT16 numCounters) + { + if (::wil::details::IsDebuggerPresent()) + { + TraceLoggingWrite(Provider(), "ApiCallCountsWithDebuggerPresent", TraceLoggingValue(nameSpace, "Namespace"), TraceLoggingValue(apiList, "ApiDataList"), + TraceLoggingValue(specializationList, "CustomList"), TraceLoggingUInt32Array(countArray, numCounters, "HitCounts"), TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA)); + } + else + { + TraceLoggingWrite(Provider(), "ApiCallCounts", TraceLoggingValue(nameSpace, "Namespace"), TraceLoggingValue(apiList, "ApiDataList"), + TraceLoggingValue(specializationList, "CustomList"), TraceLoggingUInt32Array(countArray, numCounters, "HitCounts"), TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"), + TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES)); + } + + __TRACELOGGING_TEST_HOOK_VERIFY_API_TELEMETRY(nameSpace, apiList, specializationList, countArray, numCounters); + }); + + if (m_fireEventDelay < c_fireEventDelayLimit) + { + // Double the exponential backoff timer, until it reaches the maximum + m_fireEventDelay *= 2; + if (m_fireEventDelay > c_fireEventDelayLimit) + { + m_fireEventDelay = c_fireEventDelayLimit; + } + } + + ScheduleFireEventCallback(); + } + + // Used to declare that the component will handle calling FireEvent() in its own suspend handler. + // This optimizes the frequency at which the event will be fired. + DEFINE_EVENT_METHOD(UsingOwnSuspendHandler)() + { + m_fireEventDelay = c_fireEventDelayLimit; + ScheduleFireEventCallback(); + } + + private: + void Initialize() WI_NOEXCEPT override + { +#ifdef WIL_API_TELEMETRY_SUSPEND_HANDLER + m_fireEventDelay = c_fireEventDelayLimit; + + PPSM_APPSTATE_REGISTRATION psmReg; + BOOLEAN quiesced; + PsmRegisterAppStateChangeNotification( + [](BOOLEAN quiesced, PVOID, HANDLE) + { + if (quiesced) + { + FireEvent(); + } + }, + StateChangeCategoryApplication, 0, nullptr, &quiesced, &psmReg); +#else + m_fireEventDelay = __TRACELOGGING_TEST_HOOK_API_TELEMETRY_EVENT_DELAY_MS; +#endif + m_fireEventThreadPoolTimer.reset(::CreateThreadpoolTimer( + [](PTP_CALLBACK_INSTANCE, PVOID, PTP_TIMER) + { + FireEvent(); + }, + nullptr, + nullptr)); + ScheduleFireEventCallback(); + } + + ~ApiTelemetryLogger() WI_NOEXCEPT override + { + FireEvent(); + + // release handle to thread pool timer instead of its destructor being call, if process is being terminated and dll is not being unloaded dynamically + // destruction of threadpool timer is considered invalid during process termination + if (ProcessShutdownInProgress()) + { + m_fireEventThreadPoolTimer.release(); + } + } + + void ScheduleFireEventCallback() + { + // do not schedule thread pool timer callback, if process is being terminated and dll is not being unloaded dynamically + if (m_fireEventThreadPoolTimer && !ProcessShutdownInProgress()) + { + // Note this will override any pending scheduled callback + FILETIME dueTime{}; + *reinterpret_cast(&dueTime) = -static_cast(m_fireEventDelay) * 10000; + SetThreadpoolTimer(m_fireEventThreadPoolTimer.get(), &dueTime, 0, 0); + } + } + + ApiDataList m_apiDataList; + wil::unique_threadpool_timer m_fireEventThreadPoolTimer; + + // The timer used to determine when to fire the next telemetry event (when it's fired based on a timer). + UINT m_fireEventDelay{}; + DWORD const c_fireEventDelayLimit = 20 * 60 * 1000; // 20 minutes + }; + } // namespace details + /// @endcond +} // namespace wil + +// Insert WI_LOG_API_USE near the top of a WinRT method to log that a method was called. +// The parameter should be the method name, for example: +// - WI_LOG_API_USE(L"LaunchUriAsync"); +// +// To log that the WinRT method reached a certain line of code, pass an override string: +// - WI_LOG_API_USE(L"LaunchUriAsync", "PointA"); +// +// If the class name can't be obtained at runtime, or if instrumenting a non-WinRT API, use the below macro, +// and pass the fully qualified class name (in the case of WinRT), or a string identifying the group of the non-WinRT API: +// - WI_LOG_CLASS_API_USE(RuntimeClass_Windows_System_Launcher, L"LaunchUriAsync"); +// +// Note: If the component can have a suspend handler, the following line should be added before including TraceLogging.h: +// - #define WIL_API_TELEMETRY_SUSPEND_HANDLER +// This will optimize the component's ability to upload telemetry, as it will upload on suspend. It will also disable +// frequent telemetry upload early in process execution. +// +// Alternatively, a component can call wil::details:ApiTelemetryLogger::FireEvent() from it's own suspend handler. +// If this is done, then in DLLMain it should also call wil::details::ApiTelemetryLogger::UsingOwnSuspendHandler(). +// +// Note: In your DLLMain method, please also add following code snippet +// +// wil::details::g_processShutdownInProgress = (lpReserved == nullptr); +// +// Adding this code snippet ensures that during process termination, thread pool timer +// destructor or SetThreadPoolTimer methods are not called, because they are invalid to call +// when dll is not getting dynamically unloaded. Skipping this code block will result in a continuable +// exception being thrown if process is getting terminated and dll in which ApiTelemetryLogger is not getting dynamically +// unloaded. For more details about lpReserved parameter, please refer to MSDN. + +#define __WI_LOG_CLASS_API_USE3(className, apiName, specialization) \ + do \ + { \ + static volatile long __wil_apiCallCounter = 0; \ + if (1 == ::InterlockedIncrementNoFence(&__wil_apiCallCounter)) \ + { \ + ::wil::details::ApiTelemetryLogger::InitApiData(className, apiName, specialization, &__wil_apiCallCounter); \ + } \ + } \ + while (0,0) +#define __WI_LOG_CLASS_API_USE2(className, apiName) \ + __WI_LOG_CLASS_API_USE3(className, apiName, nullptr) +#define __WI_LOG_API_USE2(apiName, specialization) \ + __WI_LOG_CLASS_API_USE3(InternalGetRuntimeClassName(), apiName, specialization) +#define __WI_LOG_API_USE1(apiName) \ + __WI_LOG_CLASS_API_USE3(InternalGetRuntimeClassName(), apiName, nullptr) + +#define WI_LOG_CLASS_API_USE(...) \ + WI_MACRO_DISPATCH(__WI_LOG_CLASS_API_USE, __VA_ARGS__) + +#define WI_LOG_API_USE(...) \ + WI_MACRO_DISPATCH(__WI_LOG_API_USE, __VA_ARGS__) + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#pragma warning(pop) +#endif // __WIL_TRACELOGGING_H_INCLUDED diff --git a/libraries/wil/_version.txt b/libraries/wil/_version.txt new file mode 100644 index 0000000..216576c --- /dev/null +++ b/libraries/wil/_version.txt @@ -0,0 +1,3 @@ +https://github.com/microsoft/wil/tree/a6c9f2d8520e830b04c47c3c395bac428696cc0d ++ +https://github.com/microsoft/wil/pull/357 diff --git a/libraries/wil/com.h b/libraries/wil/com.h new file mode 100644 index 0000000..3ee0ea0 --- /dev/null +++ b/libraries/wil/com.h @@ -0,0 +1,3007 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_COM_INCLUDED +#define __WIL_COM_INCLUDED + +#include +#include +#include "result.h" +#include "resource.h" // last to ensure _COMBASEAPI_H_ protected definitions are available + +#if __has_include() +#include +#endif +#if __has_include() +#include +#endif + +// Forward declaration within WIL (see https://msdn.microsoft.com/en-us/library/br244983.aspx) +/// @cond +namespace Microsoft +{ + namespace WRL + { + template + class ComPtr; + } +} +/// @endcond + +namespace wil +{ + /// @cond + namespace details + { + // We can't directly use wistd::is_convertible as it returns TRUE for an ambiguous conversion. + // Adding is_abstract to the mix, enables us to allow conversion for interfaces, but deny it for + // classes (where the multiple inheritance causes ambiguity). + // NOTE: I've reached out to vcsig on this topic and it turns out that __is_convertible_to should NEVER + // return true for ambiguous conversions. This was a bug in our compiler that has since been fixed. + // Eventually, once that fix propagates we can move to a more efficient __is_convertible_to without + // the added complexity. + template + struct is_com_convertible : + wistd::bool_constant<__is_convertible_to(TFrom, TTo) && (__is_abstract(TFrom) || wistd::is_same::value)> + { + }; + + using tag_com_query = wistd::integral_constant; + using tag_try_com_query = wistd::integral_constant; + using tag_com_copy = wistd::integral_constant; + using tag_try_com_copy = wistd::integral_constant; + + class default_query_policy + { + public: + template + inline static HRESULT query(_In_ T* ptr, REFIID riid, _COM_Outptr_ void** result) + { + return ptr->QueryInterface(riid, result); + } + + template + inline static HRESULT query(_In_ T* ptr, _COM_Outptr_ TResult** result) + { + return query_dispatch(ptr, typename details::is_com_convertible::type(), result); + } + + private: + template + inline static HRESULT query_dispatch(_In_ T* ptr, wistd::true_type, _COM_Outptr_ TResult** result) // convertible + { + *result = ptr; + (*result)->AddRef(); + return S_OK; + } + + template + inline static HRESULT query_dispatch(_In_ T* ptr, wistd::false_type, _COM_Outptr_ TResult** result) // not convertible + { + auto hr = ptr->QueryInterface(IID_PPV_ARGS(result)); + __analysis_assume(SUCCEEDED(hr) || (*result == nullptr)); + return hr; + } + }; + + template + struct query_policy_helper + { + using type = default_query_policy; + }; + + class weak_query_policy + { + public: + inline static HRESULT query(_In_ IWeakReference* ptr, REFIID riid, _COM_Outptr_ void** result) + { + WI_ASSERT_MSG(riid != __uuidof(IWeakReference), "Cannot resolve a weak reference to IWeakReference"); + *result = nullptr; + + IInspectable* temp; + HRESULT hr = ptr->Resolve(__uuidof(IInspectable), &temp); + if (SUCCEEDED(hr)) + { + if (temp == nullptr) + { + return E_NOT_SET; + } + hr = temp->QueryInterface(riid, result); + __analysis_assume(SUCCEEDED(hr) || (*result == nullptr)); + temp->Release(); + } + + return hr; + } + + template + inline static HRESULT query(_In_ IWeakReference* ptr, _COM_Outptr_ TResult** result) + { + static_assert(!wistd::is_same::value, "Cannot resolve a weak reference to IWeakReference"); + return query_dispatch(ptr, wistd::is_base_of(), result); + } + + private: + template + static HRESULT query_dispatch(_In_ IWeakReference* ptr, wistd::true_type, _COM_Outptr_ TResult** result) + { + auto hr = ptr->Resolve(__uuidof(TResult), reinterpret_cast(result)); + if (SUCCEEDED(hr) && (*result == nullptr)) + { + hr = E_NOT_SET; + } + __analysis_assume(SUCCEEDED(hr) || (*result == nullptr)); + return hr; + } + + template + static HRESULT query_dispatch(_In_ IWeakReference* ptr, wistd::false_type, _COM_Outptr_ TResult** result) + { + return query(ptr, IID_PPV_ARGS(result)); + } + }; + + template <> + struct query_policy_helper + { + using type = weak_query_policy; + }; + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) + class agile_query_policy + { + public: + inline static HRESULT query(_In_ IAgileReference* ptr, REFIID riid, _COM_Outptr_ void** result) + { + WI_ASSERT_MSG(riid != __uuidof(IAgileReference), "Cannot resolve a agile reference to IAgileReference"); + auto hr = ptr->Resolve(riid, result); + __analysis_assume(SUCCEEDED(hr) || (*result == nullptr)); // IAgileReference::Resolve not annotated correctly + return hr; + } + + template + static HRESULT query(_In_ IAgileReference* ptr, _COM_Outptr_ TResult** result) + { + static_assert(!wistd::is_same::value, "Cannot resolve a agile reference to IAgileReference"); + return query(ptr, __uuidof(TResult), reinterpret_cast(result)); + } + }; + + template <> + struct query_policy_helper + { + using type = agile_query_policy; + }; +#endif + + template + using query_policy_t = typename query_policy_helper::type>::type; + + } // details + /// @endcond + + //! Represents the base template type that implements com_ptr, com_weak_ref, and com_agile_ref. + //! See @ref page_comptr for more background. See @ref page_query for more information on querying with WIL. + //! @tparam T Represents the type being held by the com_ptr_t. + //! For com_ptr, this will always be the interface being represented. For com_weak_ref, this will always be + //! IWeakReference. For com_agile_ref, this will always be IAgileReference. + //! @tparam err_policy Represents the error policy for the class (error codes, exceptions, or fail fast; see @ref page_errors) + template + class com_ptr_t + { + private: + using element_type_reference = typename wistd::add_lvalue_reference::type; + using query_policy = details::query_policy_t; + public: + //! The function return result (HRESULT or void) for the given err_policy (see @ref page_errors). + using result = typename err_policy::result; + //! The template type `T` being held by the com_ptr_t. + using element_type = T; + //! A pointer to the template type `T` being held by the com_ptr_t (what `get()` returns). + using pointer = T*; + + //! @name Constructors + //! @{ + + //! Default constructor (holds nullptr). + com_ptr_t() WI_NOEXCEPT : + m_ptr(nullptr) + { + } + + //! Implicit construction from nullptr_t (holds nullptr). + com_ptr_t(wistd::nullptr_t) WI_NOEXCEPT : + com_ptr_t() + { + } + + //! Implicit construction from a compatible raw interface pointer (AddRef's the parameter). + com_ptr_t(pointer ptr) WI_NOEXCEPT : + m_ptr(ptr) + { + if (m_ptr) + { + m_ptr->AddRef(); + } + } + + //! Copy-construction from a like `com_ptr_t` (copies and AddRef's the parameter). + com_ptr_t(const com_ptr_t& other) WI_NOEXCEPT : + com_ptr_t(other.get()) + { + } + + //! Copy-construction from a convertible `com_ptr_t` (copies and AddRef's the parameter). + template > + com_ptr_t(const com_ptr_t& other) WI_NOEXCEPT : + com_ptr_t(static_cast(other.get())) + { + } + + //! Move construction from a like `com_ptr_t` (avoids AddRef/Release by moving from the parameter). + com_ptr_t(com_ptr_t&& other) WI_NOEXCEPT : + m_ptr(other.detach()) + { + } + + //! Move construction from a compatible `com_ptr_t` (avoids AddRef/Release by moving from the parameter). + template > + com_ptr_t(com_ptr_t&& other) WI_NOEXCEPT : + m_ptr(other.detach()) + { + } + //! @} + + //! Destructor (releases the pointer). + ~com_ptr_t() WI_NOEXCEPT + { + if (m_ptr) + { + m_ptr->Release(); + } + } + + //! @name Assignment operators + //! @{ + + //! Assign to nullptr (releases the current pointer, holds nullptr). + com_ptr_t& operator=(wistd::nullptr_t) WI_NOEXCEPT + { + reset(); + return *this; + } + + //! Assign a compatible raw interface pointer (releases current pointer, copies and AddRef's the parameter). + com_ptr_t& operator=(pointer other) WI_NOEXCEPT + { + auto ptr = m_ptr; + m_ptr = other; + if (m_ptr) + { + m_ptr->AddRef(); + } + if (ptr) + { + ptr->Release(); + } + return *this; + } + + //! Assign a like `com_ptr_t` (releases current pointer, copies and AddRef's the parameter). + com_ptr_t& operator=(const com_ptr_t& other) WI_NOEXCEPT + { + return operator=(other.get()); + } + + //! Assign a convertible `com_ptr_t` (releases current pointer, copies and AddRef's the parameter). + template > + com_ptr_t& operator=(const com_ptr_t& other) WI_NOEXCEPT + { + return operator=(static_cast(other.get())); + } + + //! Move assign from a like `com_ptr_t` (releases current pointer, avoids AddRef/Release by moving the parameter). + com_ptr_t& operator=(com_ptr_t&& other) WI_NOEXCEPT + { + attach(other.detach()); + return *this; + } + + //! Move assignment from a compatible `com_ptr_t` (releases current pointer, avoids AddRef/Release by moving from the parameter). + template > + com_ptr_t& operator=(com_ptr_t&& other) WI_NOEXCEPT + { + attach(other.detach()); + return *this; + } + //! @} + + //! @name Modifiers + //! @{ + + //! Swap pointers with an another named com_ptr_t object. + template + void swap(com_ptr_t& other) WI_NOEXCEPT + { + auto ptr = m_ptr; + m_ptr = other.m_ptr; + other.m_ptr = ptr; + } + + //! Swap pointers with a rvalue reference to another com_ptr_t object. + template + void swap(com_ptr_t&& other) WI_NOEXCEPT + { + swap(other); + } + + //! Releases the pointer and sets it to nullptr. + void reset() WI_NOEXCEPT + { + auto ptr = m_ptr; + m_ptr = nullptr; + if (ptr) + { + ptr->Release(); + } + } + + //! Releases the pointer and sets it to nullptr. + void reset(wistd::nullptr_t) WI_NOEXCEPT + { + reset(); + } + + //! Takes ownership of a compatible raw interface pointer (releases pointer, copies but DOES NOT AddRef the parameter). + void attach(pointer other) WI_NOEXCEPT + { + auto ptr = m_ptr; + m_ptr = other; + if (ptr) + { + ULONG ref = ptr->Release(); + WI_ASSERT_MSG(((other != ptr) || (ref > 0)), "Bug: Attaching the same already assigned, destructed pointer"); + } + } + + //! Relinquishes ownership and returns the internal interface pointer (DOES NOT release the detached pointer, sets class pointer to null). + WI_NODISCARD pointer detach() WI_NOEXCEPT + { + auto temp = m_ptr; + m_ptr = nullptr; + return temp; + } + + //! Returns the address of the internal pointer (releases ownership of the pointer BEFORE returning the address). + //! The pointer is explicitly released to prevent accidental leaks of the pointer. Coding standards generally indicate that + //! there is little valid `_Inout_` use of `IInterface**`, making this safe to do under typical use. + //! @see addressof + //! ~~~~ + //! STDAPI GetMuffin(IMuffin **muffin); + //! wil::com_ptr myMuffin; + //! THROW_IF_FAILED(GetMuffin(myMuffin.put())); + //! ~~~~ + pointer* put() WI_NOEXCEPT + { + reset(); + return &m_ptr; + } + + //! Returns the address of the internal pointer casted to void** (releases ownership of the pointer BEFORE returning the address). + //! @see put + void** put_void() WI_NOEXCEPT + { + return reinterpret_cast(put()); + } + + //! Returns the address of the internal pointer casted to IUnknown** (releases ownership of the pointer BEFORE returning the address). + //! @see put + ::IUnknown** put_unknown() WI_NOEXCEPT + { + return reinterpret_cast<::IUnknown**>(put()); + } + + //! Returns the address of the internal pointer (releases ownership of the pointer BEFORE returning the address). + //! The pointer is explicitly released to prevent accidental leaks of the pointer. Coding standards generally indicate that + //! there is little valid `_Inout_` use of `IInterface**`, making this safe to do under typical use. Since this behavior is not always immediately + //! apparent, prefer to scope variables as close to use as possible (generally avoiding use of the same com_ptr variable in successive calls to + //! receive an output interface). + //! @see addressof + pointer* operator&() WI_NOEXCEPT + { + return put(); + } + + //! Returns the address of the internal pointer (does not release the pointer; should not be used for `_Out_` parameters) + pointer* addressof() WI_NOEXCEPT + { + return &m_ptr; + } + //! @} + + //! @name Inspection + //! @{ + + //! Returns the address of the const internal pointer (does not release the pointer) + WI_NODISCARD const pointer* addressof() const WI_NOEXCEPT + { + return &m_ptr; + } + + //! Returns 'true' if the pointer is assigned (NOT nullptr) + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return (m_ptr != nullptr); + } + + //! Returns the pointer + WI_NODISCARD pointer get() const WI_NOEXCEPT + { + return m_ptr; + } + + //! Allows direct calls against the pointer (AV on internal nullptr) + WI_NODISCARD pointer operator->() const WI_NOEXCEPT + { + return m_ptr; + } + + //! Dereferences the pointer (AV on internal nullptr) + WI_NODISCARD element_type_reference operator*() const WI_NOEXCEPT + { + return *m_ptr; + } + //! @} + + //! @name Query helpers + //! * Retrieves the requested interface + //! * AV if the pointer is null + //! * Produce an error if the requested interface is unsupported + //! + //! See @ref page_query for more information + //! @{ + + //! Query and return a smart pointer matching the interface specified by 'U': `auto foo = m_ptr.query();`. + //! See @ref page_query for more information. + //! + //! This method is the primary method that should be used to query a com_ptr in exception-based or fail-fast based code. + //! Error-code returning code should use @ref query_to so that the returned HRESULT can be examined. In the following + //! examples, `m_ptr` is an exception-based or fail-fast based com_ptr, com_weak_ref, or com_agile_ref: + //! ~~~~ + //! auto foo = ptr.query(); + //! foo->Method1(); + //! foo->Method2(); + //! ~~~~ + //! For simple single-method calls, this method allows removing the temporary that holds the com_ptr: + //! ~~~~ + //! ptr.query()->Method1(); + //! ~~~~ + //! @tparam U Represents the interface being queried + //! @return A `com_ptr_t` pointer to the given interface `U`. The pointer is guaranteed not null. The returned + //! `com_ptr_t` type will be @ref com_ptr or @ref com_ptr_failfast (matching the error handling form of the + //! pointer being queried (exception based or fail-fast). + template + WI_NODISCARD inline com_ptr_t query() const + { + static_assert(wistd::is_same::value, "query requires exceptions or fail fast; use try_query or query_to"); + return com_ptr_t(m_ptr, details::tag_com_query()); + } + + //! Query for the interface of the given out parameter `U`: `ptr.query_to(&foo);`. + //! See @ref page_query for more information. + //! + //! For fail-fast and exception-based behavior this routine should primarily be used to write to out parameters and @ref query should + //! be used to perform most queries. For error-code based code, this routine is the primary method that should be used to query a com_ptr. + //! + //! Error-code based samples: + //! ~~~~ + //! // class member being queried: + //! wil::com_ptr_nothrow m_ptr; + //! + //! // simple query example: + //! wil::com_ptr_nothrow foo; + //! RETURN_IF_FAILED(m_ptr.query_to(&foo)); + //! foo->FooMethod1(); + //! + //! // output parameter example: + //! HRESULT GetFoo(_COM_Outptr_ IFoo** fooPtr) + //! { + //! RETURN_IF_FAILED(m_ptr.query_to(fooPtr)); + //! return S_OK; + //! } + //! ~~~~ + //! Exception or fail-fast samples: + //! ~~~~ + //! // class member being queried + //! wil::com_ptr m_ptr; + //! + //! void GetFoo(_COM_Outptr_ IFoo** fooPtr) + //! { + //! m_ptr.query_to(fooPtr); + //! } + //! ~~~~ + //! @tparam U Represents the interface being queried (type of the output parameter). This interface does not need to + //! be specified directly. Rely upon template type deduction to pick up the type from the output parameter. + //! @param ptrResult The output pointer that will receive the newly queried interface. This pointer will be assigned null on failure. + //! @return For the nothrow (error code-based) classes (@ref com_ptr_nothrow, @ref com_weak_ref_nothrow, @ref com_agile_ref_nothrow) this + //! method returns an `HRESULT` indicating whether the query was successful. Exception-based and fail-fast based classes + //! do not return a value (void). + template + result query_to(_COM_Outptr_ U** ptrResult) const + { + // Prefast cannot see through the error policy + query_policy mapping and as a result fires 6388 and 28196 for this function. + // Suppression is also not working. Wrapping this entire function in #pragma warning(disable: 6388 28196) does not stop all of the prefast errors + // from being emitted. +#if defined(_PREFAST_) + *ptrResult = nullptr; + return err_policy::HResult(E_NOINTERFACE); +#else + return err_policy::HResult(query_policy::query(m_ptr, ptrResult)); +#endif + } + + //! Query for the requested interface using the iid, ppv pattern: `ptr.query_to(riid, ptr);`. + //! See @ref page_query for more information. + //! + //! This method is built to implement an API boundary that exposes a returned pointer to a caller through the REFIID and void** pointer + //! pattern (like QueryInterface). This pattern should not be used outside of that pattern (through IID_PPV_ARGS) as it is less efficient + //! than the typed version of @ref query_to which can elide the QueryInterface in favor of AddRef when the types are convertible. + //! ~~~~ + //! // class member being queried: + //! wil::com_ptr_nothrow m_ptr; + //! + //! // output parameter example: + //! HRESULT GetFoo(REFIID riid, _COM_Outptr_ void** ptrResult) + //! { + //! RETURN_IF_FAILED(m_ptr.query_to(riid, ptrResult)); + //! return S_OK; + //! } + //! ~~~~ + //! @param riid The interface to query for. + //! @param ptrResult The output pointer that will receive the newly queried interface. This pointer will be assigned null on failure. + //! @return For the nothrow (error code-based) classes (@ref com_ptr_nothrow, @ref com_weak_ref_nothrow, @ref com_agile_ref_nothrow) this + //! method returns an `HRESULT` indicating whether the query was successful. Exception-based and fail-fast based classes + //! do not return a value (void). + result query_to(REFIID riid, _COM_Outptr_ void** ptrResult) const + { + // Prefast cannot see through the error policy + query_policy mapping and as a result and as a result fires 6388 and 28196 for this function. + // Suppression is also not working. Wrapping this entire function in #pragma warning(disable: 6388 28196) does not stop the prefast errors + // from being emitted. +#if defined(_PREFAST_) + *ptrResult = nullptr; + return err_policy::HResult(E_NOINTERFACE); +#else + return err_policy::HResult(query_policy::query(m_ptr, riid, ptrResult)); +#endif + } + //! @} + + //! @name Try query helpers + //! * Attempts to retrieves the requested interface + //! * AV if the pointer is null + //! * Produce null if the requested interface is unsupported + //! * bool returns 'true' when query was successful + //! + //! See @ref page_query for more information. + //! @{ + + //! Attempt a query and return a smart pointer matching the interface specified by 'U': `auto foo = m_ptr.try_query();` (null result when interface is unsupported). + //! See @ref page_query for more information. + //! + //! This method can be used to query a com_ptr for an interface when it's known that support for that interface is + //! optional (failing the query should not produce an error). The caller must examine the returned pointer to see + //! if it's null before using it: + //! ~~~~ + //! auto foo = ptr.try_query(); + //! if (foo) + //! { + //! foo->Method1(); + //! foo->Method2(); + //! } + //! ~~~~ + //! @tparam U Represents the interface being queried + //! @return A `com_ptr_t` pointer to the given interface `U`. The returned pointer will be null if the interface is + //! not supported. The returned `com_ptr_t` will have the same error handling policy (exceptions, failfast or error codes) as + //! the pointer being queried. + template + WI_NODISCARD inline com_ptr_t try_query() const + { + return com_ptr_t(m_ptr, details::tag_try_com_query()); + } + + //! Attempts to query for the interface matching the given output parameter; returns a bool indicating if the query was successful (non-null). + //! See @ref page_query for more information. + //! + //! This method can be used to perform a query against a non-null interface when it's known that support for that interface is + //! optional (failing the query should not produce an error). The caller must examine the returned bool before using the returned pointer. + //! ~~~~ + //! wil::com_ptr_nothrow foo; + //! if (ptr.try_query_to(&foo)) + //! { + //! foo->Method1(); + //! foo->Method2(); + //! } + //! ~~~~ + //! @param ptrResult The pointer to query for. The interface to query is deduced from the type of this out parameter; do not specify + //! the type directly to the template. + //! @return A `bool` indicating `true` of the query was successful (the returned parameter is non-null). + template + _Success_return_ bool try_query_to(_COM_Outptr_ U** ptrResult) const + { + return SUCCEEDED(query_policy::query(m_ptr, ptrResult)); + } + + //! Attempts a query for the requested interface using the iid, ppv pattern: `ptr.try_query_to(riid, ptr);`. + //! See @ref page_query for more information. + //! + //! This method is built to implement an API boundary that exposes a returned pointer to a caller through the REFIID and void** pointer + //! pattern (like QueryInterface). The key distinction is that this routine does not produce an error if the request isn't fulfilled, so + //! it's appropriate for `_COM_Outptr_result_maybenull_` cases. This pattern should not be used outside of that pattern (through IID_PPV_ARGS) as + //! it is less efficient than the typed version of @ref try_query_to which can elide the QueryInterface in favor of AddRef when the types are convertible. + //! The caller must examine the returned bool before using the returned pointer. + //! ~~~~ + //! // class member being queried: + //! wil::com_ptr_nothrow m_ptr; + //! + //! // output parameter example (result may be null): + //! HRESULT GetFoo(REFIID riid, _COM_Outptr_result_maybenull_ void** ptrResult) + //! { + //! m_ptr.try_query_to(riid, ptrResult); + //! return S_OK; + //! } + //! ~~~~ + //! @param riid The interface to query for. + //! @param ptrResult The output pointer that will receive the newly queried interface. This pointer will be assigned null on failure. + //! @return A `bool` indicating `true` of the query was successful (the returned parameter is non-null). + _Success_return_ bool try_query_to(REFIID riid, _COM_Outptr_ void** ptrResult) const + { + return SUCCEEDED(query_policy::query(m_ptr, riid, ptrResult)); + } + //! @} + + //! @name Copy helpers + //! * Retrieves the requested interface + //! * Succeeds with null if the pointer is null + //! * Produce an error if the requested interface is unsupported + //! + //! See @ref page_query for more information. + //! @{ + + //! Query and return a smart pointer matching the interface specified by 'U': `auto foo = m_ptr.copy();` (succeeds and returns a null ptr if the queried pointer is null). + //! See @ref page_query for more information. + //! + //! This method is identical to @ref query with the exception that it can be used when the pointer is null. When used + //! against a null pointer, the returned pointer will always be null and an error will not be produced. Like query it will + //! produce an error for a non-null pointer that does not support the requested interface. + //! @tparam U Represents the interface being queried + //! @return A `com_ptr_t` pointer to the given interface `U`. The pointer will be null ONLY if the pointer being queried is null. The returned + //! `com_ptr_t` type will be @ref com_ptr or @ref com_ptr_failfast (matching the error handling form of the + //! pointer being queried (exception based or fail-fast). + template + WI_NODISCARD inline com_ptr_t copy() const + { + static_assert(wistd::is_same::value, "copy requires exceptions or fail fast; use the try_copy or copy_to method"); + return com_ptr_t(m_ptr, details::tag_com_copy()); + } + + //! Query for the interface of the given out parameter `U`: `ptr.copy_to(&foo);` (succeeds and returns null ptr if the queried pointer is null). + //! See @ref page_query for more information. + //! + //! This method is identical to @ref query_to with the exception that it can be used when the pointer is null. When used + //! against a null pointer, the returned pointer will always be null and an error will not be produced. Like query_to it will + //! produce an error for a non-null pointer that does not support the requested interface. + //! @tparam U Represents the interface being queried (type of the output parameter). This interface does not need to + //! be specified directly. Rely upon template type deduction to pick up the type from the output parameter. + //! @param ptrResult The output pointer that will receive the newly queried interface. This pointer will be assigned null on failure OR assigned null + //! when the source pointer is null. + //! @return For the nothrow (error code-based) classes (@ref com_ptr_nothrow, @ref com_weak_ref_nothrow, @ref com_agile_ref_nothrow) this + //! method returns an `HRESULT` indicating whether the query was successful. Copying a null value is considered success. Exception-based + //! and fail-fast based classes do not return a value (void). + template + result copy_to(_COM_Outptr_result_maybenull_ U** ptrResult) const + { + if (m_ptr) + { + // Prefast cannot see through the error policy + query_policy mapping and as a result and as a result fires 6388 and 28196 for this function. + // Suppression is also not working. Wrapping this entire function in #pragma warning(disable: 6388 28196) does not stop the prefast errors + // from being emitted. +#if defined(_PREFAST_) + *ptrResult = nullptr; + return err_policy::HResult(E_NOINTERFACE); +#else + return err_policy::HResult(query_policy::query(m_ptr, ptrResult)); +#endif + } + *ptrResult = nullptr; + return err_policy::OK(); + } + + //! Query for the requested interface using the iid, ppv pattern: `ptr.copy_to(riid, ptr);`. (succeeds and returns null ptr if the queried pointer is null). + //! See @ref page_query for more information. + //! + //! Identical to the corresponding @ref query_to method with the exception that it can be used when the pointer is null. When used + //! against a null pointer, the returned pointer will always be null and an error will not be produced. Like query_to it will + //! produce an error for a non-null pointer that does not support the requested interface. + //! @param riid The interface to query for. + //! @param ptrResult The output pointer that will receive the newly queried interface. This pointer will be assigned null on failure OR assigned null + //! when the source pointer is null. + //! @return For the nothrow (error code-based) classes (@ref com_ptr_nothrow, @ref com_weak_ref_nothrow, @ref com_agile_ref_nothrow) this + //! method returns an `HRESULT` indicating whether the query was successful. Copying a null value is considered success. Exception-based + //! and fail-fast based classes do not return a value (void). + result copy_to(REFIID riid, _COM_Outptr_result_maybenull_ void** ptrResult) const + { + if (m_ptr) + { + // Prefast cannot see through the error policy + query_policy mapping and as a result and as a result fires 6388 and 28196 for this function. + // Suppression is also not working. Wrapping this entire function in #pragma warning(disable: 6388 28196) does not stop the prefast errors + // from being emitted. +#if defined(_PREFAST_) + *ptrResult = nullptr; + return err_policy::HResult(E_NOINTERFACE); +#else + return err_policy::HResult(query_policy::query(m_ptr, riid, ptrResult)); +#endif + } + *ptrResult = nullptr; + return err_policy::OK(); + } + //! @} + + //! @name Try copy helpers + //! * Attempts to retrieves the requested interface + //! * Successfully produces null if the queried pointer is already null + //! * Produce null if the requested interface is unsupported + //! * bool returns 'false' ONLY when the queried pointer is not null and the requested interface is unsupported + //! + //! See @ref page_query for more information. + //! @{ + + //! Attempt a query and return a smart pointer matching the interface specified by 'U': `auto foo = m_ptr.try_query();` (null result when interface is unsupported or queried pointer is null). + //! See @ref page_query for more information. + //! + //! Identical to the corresponding @ref try_query method with the exception that it can be used when the pointer is null. When used + //! against a null pointer, the returned pointer will always be null and an error will not be produced. + //! @tparam U Represents the interface being queried + //! @return A `com_ptr_t` pointer to the given interface `U`. The returned pointer will be null if the interface was + //! not supported or the pointer being queried is null. The returned `com_ptr_t` will have the same error handling + //! policy (exceptions, failfast or error codes) as the pointer being queried. + template + WI_NODISCARD inline com_ptr_t try_copy() const + { + return com_ptr_t(m_ptr, details::tag_try_com_copy()); + } + + //! Attempts to query for the interface matching the given output parameter; returns a bool indicating if the query was successful (returns `false` if the pointer is null). + //! See @ref page_query for more information. + //! + //! Identical to the corresponding @ref try_query_to method with the exception that it can be used when the pointer is null. When used + //! against a null pointer, the returned pointer will be null and the return value will be `false`. + //! @param ptrResult The pointer to query for. The interface to query is deduced from the type of this out parameter; do not specify + //! the type directly to the template. + //! @return A `bool` indicating `true` of the query was successful (the returned parameter is non-null). + template + _Success_return_ bool try_copy_to(_COM_Outptr_result_maybenull_ U** ptrResult) const + { + if (m_ptr) + { + return SUCCEEDED(query_policy::query(m_ptr, ptrResult)); + } + *ptrResult = nullptr; + return false; + } + + //! Attempts a query for the requested interface using the iid, ppv pattern: `ptr.try_query_to(riid, ptr);` (returns `false` if the pointer is null) + //! See @ref page_query for more information. + //! + //! Identical to the corresponding @ref try_query_to method with the exception that it can be used when the pointer is null. When used + //! against a null pointer, the returned pointer will be null and the return value will be `false`. + //! @param riid The interface to query for. + //! @param ptrResult The output pointer that will receive the newly queried interface. This pointer will be assigned null on failure or + //! if the source pointer being queried is null. + //! @return A `bool` indicating `true` of the query was successful (the returned parameter is non-null). Querying a null + //! pointer will return `false` with a null result. + _Success_return_ bool try_copy_to(REFIID riid, _COM_Outptr_result_maybenull_ void** ptrResult) const + { + if (m_ptr) + { + return SUCCEEDED(query_policy::query(m_ptr, riid, ptrResult)); + } + *ptrResult = nullptr; + return false; + } + //! @} + + //! @name WRL compatibility + //! @{ + + //! Copy construct from a compatible WRL ComPtr. + template > + com_ptr_t(const Microsoft::WRL::ComPtr& other) WI_NOEXCEPT : + com_ptr_t(static_cast(other.Get())) + { + } + + //! Move construct from a compatible WRL ComPtr. + template > + com_ptr_t(Microsoft::WRL::ComPtr&& other) WI_NOEXCEPT : + m_ptr(other.Detach()) + { + } + + //! Assign from a compatible WRL ComPtr. + template > + com_ptr_t& operator=(const Microsoft::WRL::ComPtr& other) WI_NOEXCEPT + { + return operator=(static_cast(other.Get())); + } + + //! Move assign from a compatible WRL ComPtr. + template > + com_ptr_t& operator=(Microsoft::WRL::ComPtr&& other) WI_NOEXCEPT + { + attach(other.Detach()); + return *this; + } + + //! Swap pointers with a WRL ComPtr to the same interface. + void swap(Microsoft::WRL::ComPtr& other) WI_NOEXCEPT + { + auto ptr = m_ptr; + m_ptr = other.Detach(); + other.Attach(ptr); + } + + //! Swap pointers with a rvalue reference to a WRL ComPtr to the same interface. + void swap(Microsoft::WRL::ComPtr&& other) WI_NOEXCEPT + { + swap(other); + } + //! @} // WRL compatibility + + public: + // Internal Helpers + /// @cond + template + inline com_ptr_t(_In_ U* ptr, details::tag_com_query) : m_ptr(nullptr) + { + err_policy::HResult(details::query_policy_t::query(ptr, &m_ptr)); + } + + template + inline com_ptr_t(_In_ U* ptr, details::tag_try_com_query) WI_NOEXCEPT : m_ptr(nullptr) + { + details::query_policy_t::query(ptr, &m_ptr); + } + + template + inline com_ptr_t(_In_opt_ U* ptr, details::tag_com_copy) : m_ptr(nullptr) + { + if (ptr) + { + err_policy::HResult(details::query_policy_t::query(ptr, &m_ptr)); + } + } + + template + inline com_ptr_t(_In_opt_ U* ptr, details::tag_try_com_copy) WI_NOEXCEPT : m_ptr(nullptr) + { + if (ptr) + { + details::query_policy_t::query(ptr, &m_ptr); + } + } + /// @endcond + + private: + pointer m_ptr; + }; + + // Error-policy driven forms of com_ptr + +#ifdef WIL_ENABLE_EXCEPTIONS + //! COM pointer, errors throw exceptions (see @ref com_ptr_t for details) + template + using com_ptr = com_ptr_t; +#endif + + //! COM pointer, errors return error codes (see @ref com_ptr_t for details) + template + using com_ptr_nothrow = com_ptr_t; + + //! COM pointer, errors fail-fast (see @ref com_ptr_t for details) + template + using com_ptr_failfast = com_ptr_t; + + + // Global operators / swap + + //! Swaps the given com pointers that have different error handling. + //! Note that there are also corresponding versions to allow you to swap any wil com_ptr with a WRL ComPtr. + template + inline void swap(com_ptr_t& left, com_ptr_t& right) WI_NOEXCEPT + { + left.swap(right); + } + + //! Swaps the given com pointers that have the same error handling. + template + inline void swap(com_ptr_t& left, com_ptr_t& right) WI_NOEXCEPT + { + left.swap(right); + } + + //! Compare two com pointers. + //! Compares the two raw com pointers for equivalence. Does NOT compare object identity with a QI for IUnknown. + //! + //! Note that documentation for all of the various comparators has not been generated to reduce global function + //! clutter, but ALL standard comparison operators are supported between wil com_ptr objects, nullptr_t, and + //! WRL ComPtr. + template + inline bool operator==(const com_ptr_t& left, const com_ptr_t& right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left.get() == right.get()); + } + + // We don't document all of the global comparison operators (reduce clutter) + /// @cond + template + inline bool operator<(const com_ptr_t& left, const com_ptr_t& right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left.get() < right.get()); + } + + template + inline bool operator==(const com_ptr_t& left, wistd::nullptr_t) WI_NOEXCEPT + { + return (left.get() == nullptr); + } + + template + inline bool operator!=(const com_ptr_t& left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(left == right)); } + + template + inline bool operator>=(const com_ptr_t& left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(left < right)); } + + template + inline bool operator>(const com_ptr_t& left, const com_ptr_t& right) WI_NOEXCEPT + { return (right < left); } + + template + inline bool operator<=(const com_ptr_t& left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(right < left)); } + + template + inline bool operator==(wistd::nullptr_t, const com_ptr_t& right) WI_NOEXCEPT + { + return (right.get() == nullptr); + } + + template + inline bool operator!=(const com_ptr_t& left, wistd::nullptr_t) WI_NOEXCEPT + { return (!(left == nullptr)); } + + template + inline bool operator!=(wistd::nullptr_t, const com_ptr_t& right) WI_NOEXCEPT + { return (!(right == nullptr)); } + + // WRL ComPtr support + + template + inline void swap(com_ptr_t& left, Microsoft::WRL::ComPtr& right) WI_NOEXCEPT + { + left.swap(right); + } + + template + inline bool operator==(const com_ptr_t& left, const Microsoft::WRL::ComPtr& right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left.get() == right.Get()); + } + + template + inline bool operator<(const com_ptr_t& left, const Microsoft::WRL::ComPtr& right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left.get() < right.Get()); + } + + template + inline bool operator!=(const com_ptr_t& left, const Microsoft::WRL::ComPtr& right) WI_NOEXCEPT + { return (!(left == right)); } + + template + inline bool operator>=(const com_ptr_t& left, const Microsoft::WRL::ComPtr& right) WI_NOEXCEPT + { return (!(left < right)); } + + template + inline bool operator>(const com_ptr_t& left, const Microsoft::WRL::ComPtr& right) WI_NOEXCEPT + { return (right < left); } + + template + inline bool operator<=(const com_ptr_t& left, const Microsoft::WRL::ComPtr& right) WI_NOEXCEPT + { return (!(right < left)); } + + template + inline void swap(Microsoft::WRL::ComPtr& left, com_ptr_t& right) WI_NOEXCEPT + { + right.swap(left); + } + + template + inline bool operator==(const Microsoft::WRL::ComPtr& left, const com_ptr_t& right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left.Get() == right.get()); + } + + template + inline bool operator<(const Microsoft::WRL::ComPtr& left, const com_ptr_t& right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left.Get() < right.get()); + } + + template + inline bool operator!=(const Microsoft::WRL::ComPtr& left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(left == right)); } + + template + inline bool operator>=(const Microsoft::WRL::ComPtr& left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(left < right)); } + + template + inline bool operator>(const Microsoft::WRL::ComPtr& left, const com_ptr_t& right) WI_NOEXCEPT + { return (right < left); } + + template + inline bool operator<=(const Microsoft::WRL::ComPtr& left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(right < left)); } + + // raw COM pointer support + // + // Use these for convenience and to avoid unnecessary AddRef/Release cyles when using raw + // pointers to access STL containers. Specify std::less<> to benefit from operator<. + // + // Example: std::set, std::less<>> set; + + template + inline bool operator==(const com_ptr_t& left, TRight* right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left.get() == right); + } + + template + inline bool operator<(const com_ptr_t& left, TRight* right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left.get() < right); + } + + template + inline bool operator!=(const com_ptr_t& left, TRight* right) WI_NOEXCEPT + { return (!(left == right)); } + + template + inline bool operator>=(const com_ptr_t& left, TRight* right) WI_NOEXCEPT + { return (!(left < right)); } + + template + inline bool operator>(const com_ptr_t& left, TRight* right) WI_NOEXCEPT + { return (right < left); } + + template + inline bool operator<=(const com_ptr_t& left, TRight* right) WI_NOEXCEPT + { return (!(right < left)); } + + template + inline bool operator==(TLeft* left, const com_ptr_t& right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left == right.get()); + } + + template + inline bool operator<(TLeft* left, const com_ptr_t& right) WI_NOEXCEPT + { + static_assert(__is_convertible_to(TLeft*, TRight*) || __is_convertible_to(TRight*, TLeft*), "comparison operator requires left and right pointers to be compatible"); + return (left < right.get()); + } + + template + inline bool operator!=(TLeft* left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(left == right)); } + + template + inline bool operator>=(TLeft* left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(left < right)); } + + template + inline bool operator>(TLeft* left, const com_ptr_t& right) WI_NOEXCEPT + { return (right < left); } + + template + inline bool operator<=(TLeft* left, const com_ptr_t& right) WI_NOEXCEPT + { return (!(right < left)); } + + // suppress documentation of every single comparison operator + /// @endcond + + + //! An overloaded function that retrieves the raw com pointer from a raw pointer, wil::com_ptr_t, WRL ComPtr, or Platform::Object^. + //! This function is primarily useful by library or helper code. It allows code to be written to accept a forwarding reference + //! template that can be used as an input com pointer. That input com pointer is allowed to be any of: + //! * Raw Pointer: `T* com_raw_ptr(T* ptr)` + //! * Wil com_ptr: `T* com_raw_ptr(const wil::com_ptr_t& ptr)` + //! * WRL ComPtr: `T* com_raw_ptr(const Microsoft::WRL::ComPtr& ptr)` + //! * C++/CX hat: `IInspectable* com_raw_ptr(Platform::Object^ ptr)` + //! + //! Which in turn allows code like the following to be written: + //! ~~~~ + //! template + //! void com_query_to(T&& ptrSource, _COM_Outptr_ U** ptrResult) + //! { + //! auto raw = com_raw_ptr(wistd::forward(ptrSource)); + //! // decltype(raw) has the type of the inner pointer and raw is guaranteed to be a raw com pointer + //! ~~~~ + template + T* com_raw_ptr(T* ptr) + { + return ptr; + } + + /// @cond + template + T* com_raw_ptr(const wil::com_ptr_t& ptr) + { + return ptr.get(); + } + + template + T* com_raw_ptr(const Microsoft::WRL::ComPtr& ptr) + { + return ptr.Get(); + } + +#ifdef __cplusplus_winrt + + template + inline IInspectable* com_raw_ptr(T^ ptr) + { + return reinterpret_cast(static_cast<::Platform::Object^>(ptr)); + } + +#endif + /// @endcond + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Constructs a `com_ptr` from a raw pointer. + //! This avoids having to restate the interface in pre-C++20. + //! Starting in C++20, you can write `wil::com_ptr(p)` directly. + //! ~~~ + //! void example(ILongNamedThing* thing) + //! { + //! callback([thing = wil::make_com_ptr(thing)] { /* do something */ }); + //! } + //! ~~~ + template + com_ptr make_com_ptr(T* p) { return p; } +#endif + + //! Constructs a `com_ptr_nothrow` from a raw pointer. + //! This avoids having to restate the interface in pre-C++20. + //! Starting in C++20, you can write `wil::com_ptr_nothrow(p)` directly. + //! ~~~ + //! void example(ILongNamedThing* thing) + //! { + //! callback([thing = wil::make_com_ptr_nothrow(thing)] { /* do something */ }); + //! } + //! ~~~ + template + com_ptr_nothrow make_com_ptr_nothrow(T* p) { return p; } + + //! Constructs a `com_ptr_failfast` from a raw pointer. + //! This avoids having to restate the interface in pre-C++20. + //! Starting in C++20, you can write `wil::com_ptr_failfast(p)` directly. + //! ~~~ + //! void example(ILongNamedThing* thing) + //! { + //! callback([thing = wil::make_com_ptr_failfast(thing)] { /* do something */ }); + //! } + //! ~~~ + template + com_ptr_failfast make_com_ptr_failfast(T* p) { return p; } + + //! @name Stand-alone query helpers + //! * Source pointer can be raw interface pointer, any wil com_ptr, or WRL ComPtr + //! * Retrieves the requested interface + //! * AV if the source pointer is null + //! * Produce an error if the requested interface is unsupported + //! + //! See @ref page_query for more information + //! @{ + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Queries for the specified interface and returns an exception-based wil::com_ptr to that interface (exception if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr` pointer to the given interface `U`. The returned pointer is guaranteed not null. + template + inline com_ptr com_query(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr(raw, details::tag_com_query()); + } +#endif + + //! Queries for the specified interface and returns a fail-fast-based wil::com_ptr_failfast to that interface (fail-fast if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr` pointer to the given interface `U`. The returned pointer is guaranteed not null. + template + inline com_ptr_failfast com_query_failfast(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr_failfast(raw, details::tag_com_query()); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Queries for the interface specified by the type of the output parameter (throws an exception if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @param ptrResult Represents the output pointer to populate. The returned pointer is guaranteed not null. + template + _Success_true_ void com_query_to(T&& ptrSource, _COM_Outptr_ U** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + THROW_IF_FAILED(details::query_policy_t::query(raw, ptrResult)); + __analysis_assume(*ptrResult != nullptr); + } +#endif + + //! Queries for the interface specified by the type of the output parameter (fail-fast if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @param ptrResult Represents the output pointer to populate. The returned pointer is guaranteed not null. + template + _Success_true_ void com_query_to_failfast(T&& ptrSource, _COM_Outptr_ U** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + FAIL_FAST_IF_FAILED(details::query_policy_t::query(raw, ptrResult)); + __analysis_assume(*ptrResult != nullptr); + } + + //! Queries for the interface specified by the type of the output parameter (returns an error if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @param ptrResult Represents the output pointer to populate. The returned pointer will be null upon failure. + //! @return Returns an HRESULT representing whether the query succeeded. + template + HRESULT com_query_to_nothrow(T&& ptrSource, _COM_Outptr_ U** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + auto hr = details::query_policy_t::query(raw, ptrResult); + __analysis_assume(SUCCEEDED(hr) || (*ptrResult == nullptr)); + return hr; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Queries for the interface specified by the given REFIID parameter (throws an exception if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @param riid The interface to query for + //! @param ptrResult Represents the output pointer to populate. The returned pointer is guaranteed not null. + template + _Success_true_ void com_query_to(T&& ptrSource, REFIID riid, _COM_Outptr_ void** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + THROW_IF_FAILED(details::query_policy_t::query(raw, riid, ptrResult)); + __analysis_assume(*ptrResult != nullptr); + } +#endif + + //! Queries for the interface specified by the given REFIID parameter (fail-fast if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @param riid The interface to query for + //! @param ptrResult Represents the output pointer to populate. The returned pointer is guaranteed not null. + template + _Success_true_ void com_query_to_failfast(T&& ptrSource, REFIID riid, _COM_Outptr_ void** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + FAIL_FAST_IF_FAILED(details::query_policy_t::query(raw, riid, ptrResult)); + __analysis_assume(*ptrResult != nullptr); + } + + //! Queries for the interface specified by the given REFIID parameter (returns an error if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @param riid The interface to query for + //! @param ptrResult Represents the output pointer to populate. The returned pointer will be null upon failure. + template + HRESULT com_query_to_nothrow(T&& ptrSource, REFIID riid, _COM_Outptr_ void** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + auto hr = details::query_policy_t::query(raw, riid, ptrResult); + __analysis_assume(SUCCEEDED(hr) || (*ptrResult == nullptr)); + return hr; + } + //! @} + + //! @name Stand-alone try query helpers + //! * Source pointer can be raw interface pointer, any wil com_ptr, or WRL ComPtr + //! * Attempts to retrieves the requested interface + //! * AV if the source pointer is null + //! * Produce null if the requested interface is unsupported + //! * bool returns 'true' when query was successful (non-null return result) + //! + //! See @ref page_query for more information. + //! @{ + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Attempts a query for the specified interface and returns an exception-based wil::com_ptr to that interface (returns null if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr` pointer to the given interface `U`. The returned pointer is null if the requested interface was not supported. + template + inline com_ptr try_com_query(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr(raw, details::tag_try_com_query()); + } +#endif + + //! Attempts a query for the specified interface and returns an fail-fast wil::com_ptr_failfast to that interface (returns null if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr_failfast` pointer to the given interface `U`. The returned pointer is null if the requested interface was not supported. + template + inline com_ptr_failfast try_com_query_failfast(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr_failfast(raw, details::tag_try_com_query()); + } + + //! Attempts a query for the specified interface and returns an error-code-based wil::com_ptr_nothrow to that interface (returns null if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr_nothrow` pointer to the given interface `U`. The returned pointer is null if the requested interface was not supported. + template + inline com_ptr_nothrow try_com_query_nothrow(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr_nothrow(raw, details::tag_try_com_query()); + } + + //! Attempts a query for the interface specified by the type of the output parameter (returns `false` if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null. + //! @param ptrResult Represents the output pointer to populate. If the interface is unsupported, the returned pointer will be null. + //! @return A bool value representing whether the query was successful (non-null return result). + template + _Success_return_ bool try_com_query_to(T&& ptrSource, _COM_Outptr_ U** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return (SUCCEEDED(details::query_policy_t::query(raw, ptrResult))); + } + + //! Attempts a query for the interface specified by the type of the output parameter (returns `false` if unsupported). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), should not be null. + //! @param riid The interface to query for + //! @param ptrResult Represents the output pointer to populate. If the interface is unsupported, the returned pointer will be null. + //! @return A bool value representing whether the query was successful (non-null return result). + template + _Success_return_ bool try_com_query_to(T&& ptrSource, REFIID riid, _COM_Outptr_ void** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return (SUCCEEDED(details::query_policy_t::query(raw, riid, ptrResult))); + } + //! @} + + + //! @name Stand-alone copy helpers + //! * Source pointer can be raw interface pointer, any wil com_ptr, or WRL ComPtr + //! * Retrieves the requested interface + //! * Succeeds with null if the source pointer is null + //! * Produce an error if the requested interface is unsupported + //! + //! See @ref page_query for more information + //! @{ + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Queries for the specified interface and returns an exception-based wil::com_ptr to that interface (exception if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr` pointer to the given interface `U`. The returned pointer will be null only if the source is null. + template + inline com_ptr com_copy(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr(raw, details::tag_com_copy()); + } +#endif + + //! Queries for the specified interface and returns a fail-fast-based wil::com_ptr_failfast to that interface (fail-fast if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr` pointer to the given interface `U`. The returned pointer will be null only if the source is null. + template + inline com_ptr_failfast com_copy_failfast(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr_failfast(raw, details::tag_com_copy()); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Queries for the interface specified by the type of the output parameter (throws an exception if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @param ptrResult Represents the output pointer to populate. The returned pointer will be null only if the source is null. + template + _Success_true_ void com_copy_to(T&& ptrSource, _COM_Outptr_result_maybenull_ U** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + THROW_IF_FAILED(details::query_policy_t::query(raw, ptrResult)); + return; + } + *ptrResult = nullptr; + } +#endif + + //! Queries for the interface specified by the type of the output parameter (fail-fast if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @param ptrResult Represents the output pointer to populate. The returned pointer will be null only if the source is null. + template + _Success_true_ void com_copy_to_failfast(T&& ptrSource, _COM_Outptr_result_maybenull_ U** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + FAIL_FAST_IF_FAILED(details::query_policy_t::query(raw, ptrResult)); + return; + } + *ptrResult = nullptr; + } + + //! Queries for the interface specified by the type of the output parameter (returns an error if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @param ptrResult Represents the output pointer to populate. The returned pointer will be null upon failure or if the source is null. + //! @return Returns an HRESULT representing whether the query succeeded (returns S_OK if the source is null). + template + HRESULT com_copy_to_nothrow(T&& ptrSource, _COM_Outptr_result_maybenull_ U** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + RETURN_HR(details::query_policy_t::query(raw, ptrResult)); + } + *ptrResult = nullptr; + return S_OK; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Queries for the interface specified by the given REFIID parameter (throws an exception if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @param riid The interface to query for + //! @param ptrResult Represents the output pointer to populate. The returned pointer will be null only if the source is null. + template + _Success_true_ void com_copy_to(T&& ptrSource, REFIID riid, _COM_Outptr_result_maybenull_ void** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + THROW_IF_FAILED(details::query_policy_t::query(raw, riid, ptrResult)); + return; + } + *ptrResult = nullptr; + } +#endif + + //! Queries for the interface specified by the given REFIID parameter (fail-fast if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @param riid The interface to query for + //! @param ptrResult Represents the output pointer to populate. The returned pointer will be null only if the source is null. + template + _Success_true_ void com_copy_to_failfast(T&& ptrSource, REFIID riid, _COM_Outptr_result_maybenull_ void** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + FAIL_FAST_IF_FAILED(details::query_policy_t::query(raw, riid, ptrResult)); + return; + } + *ptrResult = nullptr; + } + + //! Queries for the interface specified by the given REFIID parameter (returns an error if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @param riid The interface to query for + //! @param ptrResult Represents the output pointer to populate. The returned pointer will be null upon failure or if the source is null. + //! @return Returns an HRESULT representing whether the query succeeded (returns S_OK if the source is null). + template + HRESULT com_copy_to_nothrow(T&& ptrSource, REFIID riid, _COM_Outptr_result_maybenull_ void** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + RETURN_HR(details::query_policy_t::query(raw, riid, ptrResult)); + } + *ptrResult = nullptr; + return S_OK; + } + //! @} + + + //! @name Stand-alone try copy helpers + //! * Source pointer can be raw interface pointer, any wil com_ptr, or WRL ComPtr + //! * Attempts to retrieves the requested interface + //! * Succeeds with null if the source pointer is null + //! * Produce null if the requested interface is unsupported + //! * bool returns 'true' when query was successful (non-null return result) + //! + //! See @ref page_query for more information. + //! @{ + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Attempts a query for the specified interface and returns an exception-based wil::com_ptr to that interface (returns null if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr` pointer to the given interface `U`. The returned pointer is null if the requested interface was not supported. + template + inline com_ptr try_com_copy(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr(raw, details::tag_try_com_copy()); + } +#endif + + //! Attempts a query for the specified interface and returns an fail-fast wil::com_ptr_failfast to that interface (returns null if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr_failfast` pointer to the given interface `U`. The returned pointer is null if the requested interface was not supported. + template + inline com_ptr_failfast try_com_copy_failfast(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr_failfast(raw, details::tag_try_com_copy()); + } + + //! Attempts a query for the specified interface and returns an error-code-based wil::com_ptr_nothrow to that interface (returns null if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null + //! @tparam U Represents the interface being queried + //! @return A `wil::com_ptr_nothrow` pointer to the given interface `U`. The returned pointer is null if the requested interface was not supported. + template + inline com_ptr_nothrow try_com_copy_nothrow(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + return com_ptr_nothrow(raw, details::tag_try_com_copy()); + } + + //! Attempts a query for the interface specified by the type of the output parameter (returns `false` if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null. + //! @param ptrResult Represents the output pointer to populate. If the interface is unsupported, the returned pointer will be null. + //! @return A bool value representing whether the query was successful (non-null return result). + template + _Success_return_ bool try_com_copy_to(T&& ptrSource, _COM_Outptr_result_maybenull_ U** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + return SUCCEEDED(details::query_policy_t::query(raw, ptrResult)); + } + *ptrResult = nullptr; + return false; + } + + //! Attempts a query for the interface specified by the type of the output parameter (returns `false` if unsupported, preserves null). + //! See @ref page_query for more information. + //! @param ptrSource The pointer to query (may be a raw interface pointer, wil com_ptr, or WRL ComPtr), may be null. + //! @param riid The interface to query for + //! @param ptrResult Represents the output pointer to populate. If the interface is unsupported, the returned pointer will be null. + //! @return A bool value representing whether the query was successful (non-null return result). + template + _Success_return_ bool try_com_copy_to(T&& ptrSource, REFIID riid, _COM_Outptr_result_maybenull_ void** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + return SUCCEEDED(details::query_policy_t::query(raw, riid, ptrResult)); + } + *ptrResult = nullptr; + return false; + } + //! @} + +#ifdef __cplusplus_winrt + //! @name Stand-alone helpers to query for CX ref ("hat") types from ABI COM types. + //! * Source pointer can be raw interface pointer, any wil com_ptr, or WRL ComPtr + //! * Retrieves the requested C++/CX interface or ref class. + //! * Preserves null if the source pointer is null + //! * Produce an error if the requested interface is unsupported + //! + //! See @ref page_query for more information + //! @{ + + template + ::Platform::Object^ cx_object_from_abi(T&& ptr) WI_NOEXCEPT + { + IInspectable* const inspectable = com_raw_ptr(wistd::forward(ptr)); + return reinterpret_cast<::Platform::Object^>(inspectable); + } + + template + inline U^ cx_safe_cast(T&& ptrSource) + { + return safe_cast(cx_object_from_abi(wistd::forward(ptrSource))); + } + + template + inline U^ cx_dynamic_cast(T&& ptrSource) WI_NOEXCEPT + { + return dynamic_cast(cx_object_from_abi(wistd::forward(ptrSource))); + } + //! @} +#endif + + + //***************************************************************************** + // Agile References + //***************************************************************************** + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +#ifdef WIL_ENABLE_EXCEPTIONS + //! Agile reference to a COM interface, errors throw exceptions (see @ref com_ptr_t and @ref com_agile_query for details) + using com_agile_ref = com_ptr; +#endif + //! Agile reference to a COM interface, errors return error codes (see @ref com_ptr_t and @ref com_agile_query_nothrow for details) + using com_agile_ref_nothrow = com_ptr_nothrow; + //! Agile reference to a COM interface, errors fail fast (see @ref com_ptr_t and @ref com_agile_query_failfast for details) + using com_agile_ref_failfast = com_ptr_failfast; + + //! @name Create agile reference helpers + //! * Attempts to retrieve an agile reference to the requested interface (see [RoGetAgileReference](https://msdn.microsoft.com/en-us/library/dn269839.aspx)) + //! * Source pointer can be raw interface pointer, any wil com_ptr, or WRL ComPtr + //! * `query` methods AV if the source pointer is null + //! * `copy` methods succeed with null if the source pointer is null + //! * Accept optional [AgileReferenceOptions](https://msdn.microsoft.com/en-us/library/dn269836.aspx) + //! + //! See @ref page_query for more information on resolving an agile ref + //! @{ + +#ifdef WIL_ENABLE_EXCEPTIONS + //! return a com_agile_ref representing the given source pointer (throws an exception on failure) + template + com_agile_ref com_agile_query(T&& ptrSource, AgileReferenceOptions options = AGILEREFERENCE_DEFAULT) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + com_agile_ref agileRef; + THROW_IF_FAILED(::RoGetAgileReference(options, __uuidof(raw), raw, &agileRef)); + return agileRef; + } +#endif + + //! return a com_agile_ref_failfast representing the given source pointer (fail-fast on failure) + template + com_agile_ref_failfast com_agile_query_failfast(T&& ptrSource, AgileReferenceOptions options = AGILEREFERENCE_DEFAULT) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + com_agile_ref_failfast agileRef; + FAIL_FAST_IF_FAILED(::RoGetAgileReference(options, __uuidof(raw), raw, &agileRef)); + return agileRef; + } + + //! return a com_agile_ref_nothrow representing the given source pointer (returns an HRESULT on failure) + template + HRESULT com_agile_query_nothrow(T&& ptrSource, _COM_Outptr_ IAgileReference** ptrResult, AgileReferenceOptions options = AGILEREFERENCE_DEFAULT) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + auto hr = ::RoGetAgileReference(options, __uuidof(raw), raw, ptrResult); + __analysis_assume(SUCCEEDED(hr) || (*ptrResult == nullptr)); + return hr; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! return a com_agile_ref representing the given source pointer (throws an exception on failure, source maybe null) + template + com_agile_ref com_agile_copy(T&& ptrSource, AgileReferenceOptions options = AGILEREFERENCE_DEFAULT) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + com_agile_ref agileRef; + if (raw) + { + THROW_IF_FAILED(::RoGetAgileReference(options, __uuidof(raw), raw, &agileRef)); + } + return agileRef; + } +#endif + + //! return a com_agile_ref_failfast representing the given source pointer (fail-fast on failure, source maybe null) + template + com_agile_ref_failfast com_agile_copy_failfast(T&& ptrSource, AgileReferenceOptions options = AGILEREFERENCE_DEFAULT) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + com_agile_ref_failfast agileRef; + if (raw) + { + FAIL_FAST_IF_FAILED(::RoGetAgileReference(options, __uuidof(raw), raw, &agileRef)); + } + return agileRef; + } + + //! return an agile ref (com_agile_ref_XXX or other representation) representing the given source pointer (return error on failure, source maybe null) + template + HRESULT com_agile_copy_nothrow(T&& ptrSource, _COM_Outptr_result_maybenull_ IAgileReference** ptrResult, AgileReferenceOptions options = AGILEREFERENCE_DEFAULT) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + RETURN_HR(::RoGetAgileReference(options, __uuidof(raw), raw, ptrResult)); + } + *ptrResult = nullptr; + return S_OK; + } + //! @} +#endif + + //***************************************************************************** + // Weak References + //***************************************************************************** + + namespace details + { + template + HRESULT GetWeakReference(T* ptr, _COM_Outptr_ IWeakReference** weakReference) + { + static_assert(!wistd::is_same::value, "Cannot get an IWeakReference to an IWeakReference"); + + *weakReference = nullptr; + com_ptr_nothrow source; + HRESULT hr = ptr->QueryInterface(IID_PPV_ARGS(&source)); + if (SUCCEEDED(hr)) + { + hr = source->GetWeakReference(weakReference); + } + return hr; + } + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! Weak reference to a COM interface, errors throw exceptions (see @ref com_ptr_t and @ref com_weak_query for details) + using com_weak_ref = com_ptr; +#endif + //! Weak reference to a COM interface, errors return error codes (see @ref com_ptr_t and @ref com_weak_query_nothrow for details) + using com_weak_ref_nothrow = com_ptr_nothrow; + //! Weak reference to a COM interface, errors fail fast (see @ref com_ptr_t and @ref com_weak_query_failfast for details) + using com_weak_ref_failfast = com_ptr_failfast; + + //! @name Create weak reference helpers + //! * Attempts to retrieve a weak reference to the requested interface (see WRL's similar [WeakRef](https://msdn.microsoft.com/en-us/library/br244853.aspx)) + //! * Source pointer can be raw interface pointer, any wil com_ptr, or WRL ComPtr + //! * `query` methods AV if the source pointer is null + //! * `copy` methods succeed with null if the source pointer is null + //! + //! See @ref page_query for more information on resolving a weak ref + //! @{ + +#ifdef WIL_ENABLE_EXCEPTIONS + //! return a com_weak_ref representing the given source pointer (throws an exception on failure) + template + com_weak_ref com_weak_query(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + com_weak_ref weakRef; + THROW_IF_FAILED(details::GetWeakReference(raw, &weakRef)); + return weakRef; + } +#endif + + //! return a com_weak_ref_failfast representing the given source pointer (fail-fast on failure) + template + com_weak_ref_failfast com_weak_query_failfast(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + com_weak_ref_failfast weakRef; + FAIL_FAST_IF_FAILED(details::GetWeakReference(raw, &weakRef)); + return weakRef; + } + + //! return a com_weak_ref_nothrow representing the given source pointer (returns an HRESULT on failure) + template + HRESULT com_weak_query_nothrow(T&& ptrSource, _COM_Outptr_ IWeakReference** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + auto hr = details::GetWeakReference(raw, ptrResult); + __analysis_assume(SUCCEEDED(hr) || (*ptrResult == nullptr)); + return hr; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! return a com_weak_ref representing the given source pointer (throws an exception on failure, source maybe null) + template + com_weak_ref com_weak_copy(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + com_weak_ref weakRef; + if (raw) + { + THROW_IF_FAILED(details::GetWeakReference(raw, &weakRef)); + } + return weakRef; + } +#endif + + //! return a com_weak_ref_failfast representing the given source pointer (fail-fast on failure, source maybe null) + template + com_weak_ref_failfast com_weak_copy_failfast(T&& ptrSource) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + com_weak_ref_failfast weakRef; + if (raw) + { + FAIL_FAST_IF_FAILED(details::GetWeakReference(raw, &weakRef)); + } + return weakRef; + } + + //! return a com_weak_ref_failfast representing the given source pointer (fail-fast on failure, source maybe null) + template + HRESULT com_weak_copy_nothrow(T&& ptrSource, _COM_Outptr_result_maybenull_ IWeakReference** ptrResult) + { + auto raw = com_raw_ptr(wistd::forward(ptrSource)); + if (raw) + { + RETURN_HR(details::GetWeakReference(raw, ptrResult)); + } + *ptrResult = nullptr; + return S_OK; + } + +#pragma region COM Object Helpers + + template + inline bool is_agile(T&& ptrSource) + { + wil::com_ptr_nothrow agileObject; + return SUCCEEDED(com_raw_ptr(wistd::forward(ptrSource))->QueryInterface(IID_PPV_ARGS(&agileObject))); + } + + /** constructs a COM object using an CLSID on a specific interface or IUnknown.*/ + template + wil::com_ptr_t CoCreateInstance(REFCLSID rclsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER) + { + wil::com_ptr_t result; + error_policy::HResult(::CoCreateInstance(rclsid, nullptr, dwClsContext, IID_PPV_ARGS(&result))); + return result; + } + + /** constructs a COM object using the class as the identifier (that has an associated CLSID) on a specific interface or IUnknown. */ + template + wil::com_ptr_t CoCreateInstance(DWORD dwClsContext = CLSCTX_INPROC_SERVER) + { + return CoCreateInstance(__uuidof(Class), dwClsContext); + } + + /** constructs a COM object using an CLSID on a specific interface or IUnknown. */ + template + wil::com_ptr_failfast CoCreateInstanceFailFast(REFCLSID rclsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER) WI_NOEXCEPT + { + return CoCreateInstance(rclsid, dwClsContext); + } + + /** constructs a COM object using the class as the identifier (that has an associated CLSID) on a specific interface or IUnknown. */ + template + wil::com_ptr_failfast CoCreateInstanceFailFast(DWORD dwClsContext = CLSCTX_INPROC_SERVER) WI_NOEXCEPT + { + return CoCreateInstanceFailFast(__uuidof(Class), dwClsContext); + } + + /** constructs a COM object using an CLSID on a specific interface or IUnknown. + Note, failures are reported as a null result, the HRESULT is lost. */ + template + wil::com_ptr_nothrow CoCreateInstanceNoThrow(REFCLSID rclsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER) WI_NOEXCEPT + { + return CoCreateInstance(rclsid, dwClsContext); + } + + /** constructs a COM object using the class as the identifier (that has an associated CLSID) on a specific interface or IUnknown. + Note, failures are reported as a null result, the HRESULT is lost. */ + template + wil::com_ptr_nothrow CoCreateInstanceNoThrow(DWORD dwClsContext = CLSCTX_INPROC_SERVER) WI_NOEXCEPT + { + return CoCreateInstanceNoThrow(__uuidof(Class), dwClsContext); + } + + /** constructs a COM object class factory using an CLSID on IClassFactory or a specific interface. */ + template + wil::com_ptr_t CoGetClassObject(REFCLSID rclsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER) + { + wil::com_ptr_t result; + error_policy::HResult(CoGetClassObject(rclsid, dwClsContext, nullptr, IID_PPV_ARGS(&result))); + return result; + } + + /** constructs a COM object class factory using the class as the identifier (that has an associated CLSID) + on IClassFactory or a specific interface. */ + template + wil::com_ptr_t CoGetClassObject(DWORD dwClsContext = CLSCTX_INPROC_SERVER) + { + return CoGetClassObject(__uuidof(Class), dwClsContext); + } + + /** constructs a COM object class factory using an CLSID on IClassFactory or a specific interface. */ + template + wil::com_ptr_failfast CoGetClassObjectFailFast(REFCLSID rclsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER) + { + return CoGetClassObject(rclsid, dwClsContext); + } + + /** constructs a COM object class factory using the class as the identifier (that has an associated CLSID) + on IClassFactory or a specific interface. */ + template + wil::com_ptr_failfast CoGetClassObjectFailFast(DWORD dwClsContext = CLSCTX_INPROC_SERVER) + { + return CoGetClassObjectFailFast(__uuidof(Class), dwClsContext); + } + + /** constructs a COM object class factory using an CLSID on IClassFactory or a specific interface. + Note, failures are reported as a null result, the HRESULT is lost. */ + template + wil::com_ptr_nothrow CoGetClassObjectNoThrow(REFCLSID rclsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER) + { + return CoGetClassObject(rclsid, dwClsContext); + } + + /** constructs a COM object class factory using the class as the identifier (that has an associated CLSID) + on IClassFactory or a specific interface. + Note, failures are reported as a null result, the HRESULT is lost. */ + template + wil::com_ptr_nothrow CoGetClassObjectNoThrow(DWORD dwClsContext = CLSCTX_INPROC_SERVER) + { + return CoGetClassObjectNoThrow(__uuidof(Class), dwClsContext); + } + +#if __cpp_lib_apply && __has_include() + namespace details + { + template + auto CoCreateInstanceEx(REFCLSID clsid, CLSCTX clsCtx) noexcept + { + MULTI_QI multiQis[sizeof...(Results)]{}; + const IID* iids[sizeof...(Results)]{ &__uuidof(Results)... }; + + static_assert(sizeof...(Results) > 0); + + for (auto i = 0U; i < sizeof...(Results); ++i) + { + multiQis[i].pIID = iids[i]; + } + + const auto hr = CoCreateInstanceEx(clsid, nullptr, clsCtx, nullptr, + ARRAYSIZE(multiQis), multiQis); + + std::tuple...> resultTuple; + + std::apply([i = 0, &multiQis](auto&... a) mutable + { + (a.attach(reinterpret_cast::type::pointer>(multiQis[i++].pItf)), ...); + }, resultTuple); + return std::tuple(hr, std::move(resultTuple)); + } + + template + auto com_multi_query(IUnknown* obj) + { + MULTI_QI multiQis[sizeof...(Results)]{}; + const IID* iids[sizeof...(Results)]{ &__uuidof(Results)... }; + + static_assert(sizeof...(Results) > 0); + + for (auto i = 0U; i < sizeof...(Results); ++i) + { + multiQis[i].pIID = iids[i]; + } + + std::tuple...> resultTuple{}; + + wil::com_ptr_nothrow multiQi; + auto hr = obj->QueryInterface(IID_PPV_ARGS(&multiQi)); + if (SUCCEEDED(hr)) + { + hr = multiQi->QueryMultipleInterfaces(ARRAYSIZE(multiQis), multiQis); + std::apply([i = 0, &multiQis](auto&... a) mutable + { + (a.attach(reinterpret_cast::type::pointer>(multiQis[i++].pItf)), ...); + }, resultTuple); + } + return std::tuple{hr, std::move(resultTuple)}; + } + } + +#ifdef WIL_ENABLE_EXCEPTIONS + // CoCreateInstanceEx can be used to improve performance by requesting multiple interfaces + // from an object at create time. This is most useful for out of process (OOP) servers, saving + // and RPC per extra interface requested. + template + auto CoCreateInstanceEx(REFCLSID clsid, CLSCTX clsCtx = CLSCTX_LOCAL_SERVER) + { + auto [error, result] = details::CoCreateInstanceEx(clsid, clsCtx); + THROW_IF_FAILED(error); + THROW_HR_IF(E_NOINTERFACE, error == CO_S_NOTALLINTERFACES); + return result; + } + + template + auto TryCoCreateInstanceEx(REFCLSID clsid, CLSCTX clsCtx = CLSCTX_LOCAL_SERVER) + { + auto [error, result] = details::CoCreateInstanceEx(clsid, clsCtx); + return result; + } +#endif + + // Returns [error, result] where result is a tuple with each of the requested interfaces. + template + auto CoCreateInstanceExNoThrow(REFCLSID clsid, CLSCTX clsCtx = CLSCTX_LOCAL_SERVER) noexcept + { + auto [error, result] = details::CoCreateInstanceEx(clsid, clsCtx); + if (SUCCEEDED(error) && (error == CO_S_NOTALLINTERFACES)) + { + return std::tuple{E_NOINTERFACE, {}}; + } + return std::tuple{error, result}; + } + + template + auto TryCoCreateInstanceExNoThrow(REFCLSID clsid, CLSCTX clsCtx = CLSCTX_LOCAL_SERVER) noexcept + { + auto [error, result] = details::CoCreateInstanceEx(clsid, clsCtx); + return result; + } + + template + auto CoCreateInstanceExFailFast(REFCLSID clsid, CLSCTX clsCtx = CLSCTX_LOCAL_SERVER) noexcept + { + auto [error, result] = details::CoCreateInstanceEx(clsid, clsCtx); + FAIL_FAST_IF_FAILED(error); + FAIL_FAST_HR_IF(E_NOINTERFACE, error == CO_S_NOTALLINTERFACES); + return result; + } + + template + auto TryCoCreateInstanceExFailFast(REFCLSID clsid, CLSCTX clsCtx = CLSCTX_LOCAL_SERVER) noexcept + { + auto [error, result] = details::CoCreateInstanceEx(clsid, clsCtx); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + template + auto com_multi_query(IUnknown* obj) + { + auto [error, result] = details::com_multi_query(obj); + THROW_IF_FAILED(error); + THROW_HR_IF(E_NOINTERFACE, error == S_FALSE); + return result; + } + + template + auto try_com_multi_query(IUnknown* obj) + { + auto [error, result] = details::com_multi_query(obj); + return result; + } +#endif + +#endif // __cpp_lib_apply && __has_include() + +#pragma endregion + +#pragma region Stream helpers + + /** Read data from a stream into a buffer. + Reads up to a certain number of bytes into a buffer. Returns the amount of data written, which + may be less than the amount requested if the stream ran out. + ~~~~ + IStream* source = // ... + ULONG dataBlob = 0; + size_t read = 0; + RETURN_IF_FAILED(wil::stream_read_partial_nothrow(source, &dataBlob, sizeof(dataBlob), &read)); + if (read != sizeof(dataBlob)) + { + // end of stream, probably + } + else if (dataBlob == 0x8675309) + { + DoThing(dataBlob); + } + ~~~~ + @param stream The stream from which to read at most `size` bytes. + @param data A buffer into which up to `size` bytes will be read + @param size The size, in bytes, of the buffer pointed to by `data` + @param wrote The amount, in bytes, of data read from `stream` into `data` + */ + inline HRESULT stream_read_partial_nothrow(_In_ ISequentialStream* stream, _Out_writes_bytes_to_(size, *wrote) void* data, unsigned long size, unsigned long *wrote) + { + RETURN_HR(stream->Read(data, size, wrote)); + } + + /** Read an exact number of bytes from a stream into a buffer. + Fails if the stream didn't read all the bytes requested. + ~~~~ + IStream* source = // ... + ULONG dataBlob = 0; + RETURN_IF_FAILED(wil::stream_read_nothrow(source, &dataBlob, sizeof(dataBlob))); + if (dataBlob == 0x8675309) + { + DoThing(dataBlob); + } + ~~~~ + @param stream The stream from which to read at most `size` bytes. + @param data A buffer into which up to `size` bytes will be read + @param size The size, in bytes, of the buffer pointed to by `data` + @return The underlying stream read result, or HRESULT_FROM_WIN32(ERROR_INVALID_DATA) if the stream + did not read the complete buffer. + */ + inline HRESULT stream_read_nothrow(_In_ ISequentialStream* stream, _Out_writes_bytes_all_(size) void* data, unsigned long size) + { + unsigned long didRead; + RETURN_IF_FAILED(stream_read_partial_nothrow(stream, data, size, &didRead)); + RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), didRead != size); + + return S_OK; + } + + /** Read from a stream into a POD type. + Fails if the stream didn't have enough bytes. + ~~~~ + IStream* source = // ... + MY_HEADER header{}; + RETURN_IF_FAILED(wil::stream_read_nothrow(source, &header)); + if (header.Version == 0x8675309) + { + ConsumeOldHeader(stream, header); + } + ~~~~ + @param stream The stream from which to read at most `size` bytes. + @param pThing The POD data type to read from the stream. + @return The underlying stream read result, or HRESULT_FROM_WIN32(ERROR_INVALID_DATA) if the stream + did not read the complete buffer. + */ + template HRESULT stream_read_nothrow(_In_ ISequentialStream* stream, _Out_ T* pThing) + { + static_assert(__is_pod(T), "Type must be POD."); + return stream_read_nothrow(stream, pThing, sizeof(T)); + } + + /** Write an exact number of bytes to a stream from a buffer. + Fails if the stream didn't read write the bytes requested. + ~~~~ + IStream* source = // ... + ULONG dataBlob = 0x8675309; + RETURN_IF_FAILED(wil::stream_write_nothrow(source, &dataBlob, sizeof(dataBlob))); + ~~~~ + @param stream The stream to which to write at most `size` bytes. + @param data A buffer from which up to `size` bytes will be read + @param size The size, in bytes, of the buffer pointed to by `data` + */ + inline HRESULT stream_write_nothrow(_In_ ISequentialStream* stream, _In_reads_bytes_(size) const void* data, unsigned long size) + { + unsigned long wrote; + RETURN_IF_FAILED(stream->Write(data, size, &wrote)); + RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), wrote != size); + + return S_OK; + } + + /** Write a POD type to a stream. + Fails if not all the bytes were written. + ~~~~ + IStream* source = // ... + MY_HEADER header { 0x8675309, HEADER_FLAG_1 | HEADER_FLAG_2 }; + RETURN_IF_FAILED(wil::stream_write_nothrow(source, header)); + + ULONGLONG value = 16; + RETURN_IF_FAILED(wil::stream_write_nothrow(source, value)); + ~~~~ + @param stream The stream to which to write `thing` + @param thing The POD data type to write to the stream. + */ + template inline HRESULT stream_write_nothrow(_In_ ISequentialStream* stream, const T& thing) + { + return stream_write_nothrow(stream, wistd::addressof(thing), sizeof(thing)); + } + + /** Retrieve the size of this stream, in bytes + ~~~~ + IStream* source = // ... + ULONGLONG size; + RETURN_IF_FAILED(wil::stream_size_nothrow(source, &size)); + RETURN_HR_IF(E_INVALIDARG, size > ULONG_MAX); + ~~~~ + @param stream The stream whose size is to be returned in `value` + @param value The size, in bytes, reported by `stream` + */ + inline HRESULT stream_size_nothrow(_In_ IStream* stream, _Out_ unsigned long long* value) + { + STATSTG st{}; + RETURN_IF_FAILED(stream->Stat(&st, STATFLAG_NONAME)); + *value = st.cbSize.QuadPart; + + return S_OK; + } + + /** Seek a stream to a relative offset or absolute position + ~~~~ + IStream* source = // ... + unsigned long long landed; + RETURN_IF_FAILED(wil::stream_seek_nothrow(source, 16, STREAM_SEEK_CUR, &landed)); + RETURN_IF_FAILED(wil::stream_seek_nothrow(source, -5, STREAM_SEEK_END)); + RETURN_IF_FAILED(wil::stream_seek_nothrow(source, LLONG_MAX, STREAM_SEEK_CUR)); + ~~~~ + @param stream The stream to seek + @param offset The position, in bytes from the current position, to seek + @param from The starting point from which to seek, from the STREAM_SEEK_* set of values + @param value Optionally recieves the new absolute position from the stream + */ + inline HRESULT stream_seek_nothrow(_In_ IStream* stream, long long offset, unsigned long from, _Out_opt_ unsigned long long* value = nullptr) + { + LARGE_INTEGER amount{}; + ULARGE_INTEGER landed{}; + amount.QuadPart = offset; + RETURN_IF_FAILED(stream->Seek(amount, from, value ? &landed : nullptr)); + assign_to_opt_param(value, landed.QuadPart); + + return S_OK; + } + + /** Seek a stream to an absolute offset + ~~~~ + IStream* source = // ... + RETURN_HR(wil::stream_set_position_nothrow(source, 16)); + ~~~~ + @param stream The stream whose size is to be returned in `value` + @param offset The position, in bytes from the start of the stream, to seek to + @param value Optionally recieves the new absolute position from the stream + */ + inline HRESULT stream_set_position_nothrow(_In_ IStream* stream, unsigned long long offset, _Out_opt_ unsigned long long* value = nullptr) + { + // IStream::Seek(..., _SET) interprets the first parameter as an unsigned value. + return stream_seek_nothrow(stream, static_cast(offset), STREAM_SEEK_SET, value); + } + + /** Seek a relative amount in a stream + ~~~~ + IStream* source = // ... + RETURN_IF_FAILED(wil::stream_seek_from_current_position_nothrow(source, -16)); + + ULONGLONG newPosition; + RETURN_IF_FAILED(wil::stream_seek_from_current_position_nothrow(source, 16, &newPosition)); + ~~~~ + @param stream The stream whose location is to be moved + @param amount The offset, in bytes, to seek the stream. + @param value Set to the new absolute steam position, in bytes + */ + inline HRESULT stream_seek_from_current_position_nothrow(_In_ IStream* stream, long long amount, _Out_opt_ unsigned long long* value = nullptr) + { + return stream_seek_nothrow(stream, amount, STREAM_SEEK_CUR, value); + } + + /** Determine the current byte position in the stream + ~~~~ + IStream* source = // ... + ULONGLONG currentPos; + RETURN_IF_FAILED(wil::stream_get_position_nothrow(source, ¤tPos)); + ~~~~ + @param stream The stream whose location is to be moved + @param position Set to the current absolute steam position, in bytes + */ + inline HRESULT stream_get_position_nothrow(_In_ IStream* stream, _Out_ unsigned long long* position) + { + return stream_seek_from_current_position_nothrow(stream, 0, position); + } + + /** Moves the stream to absolute position 0 + ~~~~ + IStream* source = // ... + RETURN_IF_FAILED(wil::stream_reset_nothrow(source)); + ~~~~ + @param stream The stream whose location is to be moved + */ + inline HRESULT stream_reset_nothrow(_In_ IStream* stream) + { + return stream_set_position_nothrow(stream, 0); + } + + /** Copy data from one stream to another, returning the final amount copied. + ~~~~ + IStream* source = // ... + IStream* target = // ... + ULONGLONG copied; + RETURN_IF_FAILED(wil::stream_copy_bytes_nothrow(source, target, sizeof(MyType), &copied)); + if (copied < sizeof(MyType)) + { + DoSomethingAboutPartialCopy(); + } + ~~~~ + @param source The stream from which to copy at most `amount` bytes + @param target The steam to which to copy at most `amount` bytes + @param amount The maximum number of bytes to copy from `source` to `target` + @param pCopied If non-null, set to the number of bytes copied between the two. + */ + inline HRESULT stream_copy_bytes_nothrow(_In_ IStream* source, _In_ IStream* target, unsigned long long amount, _Out_opt_ unsigned long long* pCopied = nullptr) + { + ULARGE_INTEGER toCopy{}; + ULARGE_INTEGER copied{}; + toCopy.QuadPart = amount; + RETURN_IF_FAILED(source->CopyTo(target, toCopy, nullptr, &copied)); + assign_to_opt_param(pCopied, copied.QuadPart); + + return S_OK; + } + + /** Copy all data from one stream to another, returning the final amount copied. + ~~~~ + IStream* source = // ... + IStream* target = // ... + ULONGLONG copied; + RETURN_IF_FAILED(wil::stream_copy_all_nothrow(source, target, &copied)); + if (copied < 8) + { + DoSomethingAboutPartialCopy(); + } + ~~~~ + @param source The stream from which to copy all content + @param target The steam to which to copy all content + @param pCopied If non-null, set to the number of bytes copied between the two. + */ + inline HRESULT stream_copy_all_nothrow(_In_ IStream* source, _In_ IStream* target, _Out_opt_ unsigned long long* pCopied = nullptr) + { + return stream_copy_bytes_nothrow(source, target, ULLONG_MAX, pCopied); + } + + /** Copies an exact amount of data from one stream to another, failing otherwise + ~~~~ + IStream* source = // ... + IStream* target = // ... + RETURN_IF_FAILED(wil::stream_copy_all_nothrow(source, target, 16)); + ~~~~ + @param source The stream from which to copy at most `amount` bytes + @param target The steam to which to copy at most `amount` bytes + @param amount The number of bytes to copy from `source` to `target` + */ + inline HRESULT stream_copy_exact_nothrow(_In_ IStream* source, _In_ IStream* target, unsigned long long amount) + { + unsigned long long copied; + RETURN_IF_FAILED(stream_copy_bytes_nothrow(source, target, ULLONG_MAX, &copied)); + RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), copied != amount); + + return S_OK; + } + + //! Controls behavior when reading a zero-length string from a stream + enum class empty_string_options + { + //! Zero-length strings are returned as nullptr + returns_null, + + //! Zero-length strings are allocated and returned with zero characters + returns_empty, + }; + +#ifdef __WIL_OBJBASE_H_ + + /** Read a string from a stream and returns an allocated copy + Deserializes strings in streams written by both IStream_WriteStr and wil::stream_write_string[_nothrow]. The format + is a single 16-bit quantity, followed by that many wchar_ts. The returned string is allocated with CoTaskMemAlloc. + Returns a zero-length (but non-null) string if the stream contained a zero-length string. + ~~~~ + IStream* source = // ... + wil::unique_cotaskmem_string content; + RETURN_IF_FAILED(wil::stream_read_string_nothrow(source, &content)); + if (wcscmp(content.get(), L"waffles") == 0) + { + // Waffles! + } + ~~~~ + @param source The stream from which to read a string + @param value Set to point to the allocated result of reading a string from `source` + */ + inline HRESULT stream_read_string_nothrow( + _In_ ISequentialStream* source, + _When_(options == empty_string_options::returns_empty, _Outptr_result_z_) _When_(options == empty_string_options::returns_null, _Outptr_result_maybenull_z_) wchar_t** value, + empty_string_options options = empty_string_options::returns_empty) + { + unsigned short cch; + RETURN_IF_FAILED(stream_read_nothrow(source, &cch)); + + if ((cch == 0) && (options == empty_string_options::returns_null)) + { + *value = nullptr; + } + else + { + auto allocated = make_unique_cotaskmem_nothrow(static_cast(cch) + 1); + RETURN_IF_NULL_ALLOC(allocated); + RETURN_IF_FAILED(stream_read_nothrow(source, allocated.get(), static_cast(cch) * sizeof(wchar_t))); + allocated[cch] = 0; + + *value = allocated.release(); + } + + return S_OK; + } + +#endif // __WIL_OBJBASE_H + + /** Write a string to a stream + Serializes a string into a stream by putting its length and then the wchar_ts in the string + into the stream. Zero-length strings have their length but no data written. This is the + form expected by IStream_ReadStr and wil::string_read_stream. + ~~~~ + IStream* target = // ... + RETURN_IF_FAILED(wil::stream_write_string_nothrow(target, L"Waffles", 3)); + // Produces wchar_t[] { 0x3, L'W', L'a', L'f' }; + ~~~~ + @param target The stream to which to write a string + @param source The string to write. Can be null if `writeLength` is zero + @param writeLength The number of characters to write from source into `target` + */ + inline HRESULT stream_write_string_nothrow(_In_ ISequentialStream* target, _In_reads_opt_(writeLength) const wchar_t* source, _In_ size_t writeLength) + { + FAIL_FAST_IF(writeLength > USHRT_MAX); + + RETURN_IF_FAILED(stream_write_nothrow(target, static_cast(writeLength))); + + if (writeLength > 0) + { + RETURN_IF_FAILED(stream_write_nothrow(target, source, static_cast(writeLength) * sizeof(wchar_t))); + } + + return S_OK; + } + + /** Write a string to a stream + Serializes a string into a stream by putting its length and then the wchar_ts in the string + into the stream. Zero-length strings have their length but no data written. This is the + form expected by IStream_ReadStr and wil::string_read_stream. + ~~~~ + IStream* target = // ... + RETURN_IF_FAILED(wil::stream_write_string_nothrow(target, L"Waffles")); + // Produces wchar_t[] { 0x3, L'W', L'a', L'f', L'f', L'l', L'e', L's' }; + ~~~~ + @param target The stream to which to write a string + @param source The string to write. When nullptr, a zero-length string is written. + */ + inline HRESULT stream_write_string_nothrow(_In_ ISequentialStream* target, _In_opt_z_ const wchar_t* source) + { + return stream_write_string_nothrow(target, source, source ? wcslen(source) : 0); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + + /** Read data from a stream into a buffer. + ~~~~ + IStream* source = // ... + ULONG dataBlob = 0; + auto read = wil::stream_read_partial(source, &dataBlob, sizeof(dataBlob)); + if (read != sizeof(dataBlob)) + { + // end of stream, probably + } + else if (dataBlob == 0x8675309) + { + DoThing(dataBlob); + } + ~~~~ + @param stream The stream from which to read at most `size` bytes. + @param data A buffer into which up to `size` bytes will be read + @param size The size, in bytes, of the buffer pointed to by `data` + @return The amount, in bytes, of data read from `stream` into `data` + */ + inline unsigned long stream_read_partial(_In_ ISequentialStream* stream, _Out_writes_bytes_to_(size, return) void* data, unsigned long size) + { + unsigned long didRead; + THROW_IF_FAILED(stream_read_partial_nothrow(stream, data, size, &didRead)); + + return didRead; + } + + /** Read an exact number of bytes from a stream into a buffer. + Fails if the stream didn't read all the bytes requested by throwing HRESULT_FROM_WIN32(ERROR_INVALID_DATA). + ~~~~ + IStream* source = // ... + ULONG dataBlob = 0; + wil::stream_read(source, &dataBlob, sizeof(dataBlob)); + if (dataBlob == 0x8675309) + { + DoThing(dataBlob); + } + ~~~~ + @param stream The stream from which to read at most `size` bytes. + @param data A buffer into which up to `size` bytes will be read + @param size The size, in bytes, of the buffer pointed to by `data` + */ + inline void stream_read(_In_ ISequentialStream* stream, _Out_writes_bytes_all_(size) void* data, unsigned long size) + { + THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), stream_read_partial(stream, data, size) != size); + } + + /** Read from a stream into a POD type. + Fails if the stream didn't have enough bytes by throwing HRESULT_FROM_WIN32(ERROR_INVALID_DATA). + ~~~~ + IStream* source = // ... + MY_HEADER header = wil::stream_read(source); + if (header.Version == 0x8675309) + { + ConsumeOldHeader(stream, header); + } + ~~~~ + @param stream The stream from which to read at most `sizeof(T)` bytes. + @return An instance of `T` read from the stream + */ + template T stream_read(_In_ ISequentialStream* stream) + { + static_assert(__is_pod(T), "Read type must be POD"); + T temp{}; + stream_read(stream, &temp, sizeof(temp)); + + return temp; + } + + /** Write an exact number of bytes to a stream from a buffer. + Fails if the stream didn't read write the bytes requested. + ~~~~ + IStream* source = // ... + ULONG dataBlob = 0; + wil::stream_write(source, dataBlob, sizeof(dataBlob)); + ~~~~ + @param stream The stream to which to write at most `size` bytes. + @param data A buffer from which up to `size` bytes will be read + @param size The size, in bytes, of the buffer pointed to by `data` + */ + inline void stream_write(_In_ ISequentialStream* stream, _In_reads_bytes_(size) const void* data, unsigned long size) + { + THROW_IF_FAILED(stream_write_nothrow(stream, data, size)); + } + + /** Write a POD type to a stream. + Fails if the stream didn't accept the entire size. + ~~~~ + IStream* target = // ... + + MY_HEADER header { 0x8675309, HEADER_FLAG_1 | HEADER_FLAG_2 }; + wil::stream_write(target, header) + + wil::stream_write(target, 16); + ~~~~ + @param stream The stream to which to write `thing` + @param thing The POD data type to write to the stream. + */ + template inline void stream_write(_In_ ISequentialStream* stream, const T& thing) + { + stream_write(stream, wistd::addressof(thing), sizeof(thing)); + } + + /** Retrieve the size of this stream, in bytes + ~~~~ + IStream* source = // ... + ULONGLONG size = wil::stream_size(source); + ~~~~ + @param stream The stream whose size is to be returned in `value` + @return The size, in bytes, reported by `stream` + */ + inline unsigned long long stream_size(_In_ IStream* stream) + { + unsigned long long size; + THROW_IF_FAILED(stream_size_nothrow(stream, &size)); + + return size; + } + + /** Seek a stream to an absolute offset + ~~~~ + IStream* source = // ... + wil::stream_set_position(source, sizeof(HEADER)); + ~~~~ + @param stream The stream whose size is to be returned in `value` + @param offset The offset, in bytes, to seek the stream. + @return The new absolute stream position, in bytes + */ + inline unsigned long long stream_set_position(_In_ IStream* stream, unsigned long long offset) + { + unsigned long long landed; + THROW_IF_FAILED(stream_set_position_nothrow(stream, offset, &landed)); + return landed; + } + + /** Seek a relative amount in a stream + ~~~~ + IStream* source = // ... + ULONGLONG newPosition = wil::stream_seek_from_current_position(source, 16); + ~~~~ + @param stream The stream whose location is to be moved + @param amount The offset, in bytes, to seek the stream. + @return The new absolute stream position, in bytes + */ + inline unsigned long long stream_seek_from_current_position(_In_ IStream* stream, long long amount) + { + unsigned long long landed; + THROW_IF_FAILED(stream_seek_from_current_position_nothrow(stream, amount, &landed)); + + return landed; + } + + /** Determine the current byte position in the stream + ~~~~ + IStream* source = // ... + ULONGLONG currentPos = wil::stream_get_position(source); + ~~~~ + @param stream The stream whose location is to be moved + @return The current position reported by `stream` + */ + inline unsigned long long stream_get_position(_In_ IStream* stream) + { + return stream_seek_from_current_position(stream, 0); + } + + /** Moves the stream to absolute position 0 + ~~~~ + IStream* source = // ... + wil::stream_reset(source); + ASSERT(wil::stream_get_position(source) == 0); + ~~~~ + @param stream The stream whose location is to be moved + */ + inline void stream_reset(_In_ IStream* stream) + { + stream_set_position(stream, 0); + } + + /** Copy data from one stream to another + ~~~~ + IStream* source = // ... + IStream* target = // ... + ULONGLONG copied = ; + if (wil::stream_copy_bytes(source, target, sizeof(Header)) < sizeof(Header)) + { + DoSomethingAboutPartialCopy(); + } + ~~~~ + @param source The stream from which to copy at most `amount` bytes + @param target The steam to which to copy at most `amount` bytes + @param amount The maximum number of bytes to copy from `source` to `target` + @return The number of bytes copied between the two streams + */ + inline unsigned long long stream_copy_bytes(_In_ IStream* source, _In_ IStream* target, unsigned long long amount) + { + unsigned long long copied; + THROW_IF_FAILED(stream_copy_bytes_nothrow(source, target, amount, &copied)); + + return copied; + } + + /** Copy all data from one stream to another + ~~~~ + IStream* source = // ... + IStream* target = // ... + ULONGLONG copied = wil::stream_copy_all(source, target); + ~~~~ + @param source The stream from which to copy all content + @param target The steam to which to copy all content + @return The number of bytes copied between the two. + */ + inline unsigned long long stream_copy_all(_In_ IStream* source, _In_ IStream* target) + { + return stream_copy_bytes(source, target, ULLONG_MAX); + } + + /** Copies an exact amount of data from one stream to another, failing otherwise + ~~~~ + IStream* source = // ... + IStream* target = // ... + wil::stream_copy_all_nothrow(source, target, sizeof(SOMETHING)); + ~~~~ + @param source The stream from which to copy at most `amount` bytes + @param target The steam to which to copy at most `amount` bytes + @param amount The number of bytes to copy from `source` to `target` + */ + inline void stream_copy_exact(_In_ IStream* source, _In_ IStream* target, unsigned long long amount) + { + THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), stream_copy_bytes(source, target, amount) != amount); + } + +#ifdef __WIL_OBJBASE_H_ + + /** Read a string from a stream and returns an allocated copy + Deserializes strings in streams written by both IStream_WriteStr and wil::stream_write_string[_nothrow]. The format + is a single 16-bit quantity, followed by that many wchar_ts. The returned string is allocated with CoTaskMemAlloc. + Returns a zero-length (but non-null) string if the stream contained a zero-length string. + ~~~~ + IStream* source = // ... + wil::unique_cotaskmem_string content = wil::stream_read_string(source); + if (wcscmp(content.get(), L"waffles") == 0) + { + // Waffles! + } + ~~~~ + @param source The stream from which to read a string + @return An non-null string (but possibly zero lengh) string read from `source` + */ + inline wil::unique_cotaskmem_string stream_read_string(_In_ ISequentialStream* source, empty_string_options options = empty_string_options::returns_empty) + { + wil::unique_cotaskmem_string result; + THROW_IF_FAILED(stream_read_string_nothrow(source, &result, options)); + + return result; + } + +#endif // __WIL_OBJBASE_H + + /** Write a string to a stream + Serializes a string into a stream by putting its length and then the wchar_ts in the string + into the stream. Zero-length strings have their length but no data written. This is the + form expected by IStream_ReadStr and wil::string_read_stream. + ~~~~ + IStream* target = // ... + wil::stream_write_string(target, L"Waffles", 3); + ~~~~ + @param target The stream to which to write a string + @param source The string to write. Can be null if `toWriteCch` is zero + @param toWriteCch The number of characters to write from source into `target` + */ + inline void stream_write_string(_In_ ISequentialStream* target, _In_reads_opt_(toWriteCch) const wchar_t* source, _In_ size_t toWriteCch) + { + THROW_IF_FAILED(stream_write_string_nothrow(target, source, toWriteCch)); + } + + /** Write a string to a stream + Serializes a string into a stream by putting its length and then the wchar_ts in the string + into the stream. Zero-length strings have their length but no data written.This is the + form expected by IStream_ReadStr and wil::string_read_stream. + ~~~~ + IStream* target = // ... + wil::stream_write_string(target, L"Waffles"); + ~~~~ + @param target The stream to which to write a string + @param source The string to write. When nullptr, a zero-length string is written. + */ + inline void stream_write_string(_In_ ISequentialStream* target, _In_opt_z_ const wchar_t* source) + { + THROW_IF_FAILED(stream_write_string_nothrow(target, source, source ? wcslen(source) : 0)); + } + + /** Saves and restores the position of a stream + Useful for potentially reading data from a stream, or being able to read ahead, then reset + back to where one left off, such as conditionally reading content from a stream. + ~~~~ + void MaybeConsumeStream(IStream* stream) + { + // On error, reset the read position in the stream to where we left off + auto saver = wil::stream_position_saver(stream); + auto header = wil::stream_read(stream); + for (ULONG i = 0; i < header.Count; ++i) + { + ProcessElement(wil::stream_read(stream)); + } + } + ~~~~ + */ + class stream_position_saver + { + public: + //! Constructs a saver from the current position of this stream + //! @param stream The stream instance whose position is to be saved. + explicit stream_position_saver(_In_opt_ IStream* stream) : + m_stream(stream), + m_position(stream ? stream_get_position(stream) : 0) + { + } + + ~stream_position_saver() + { + if (m_stream) + { + LOG_IF_FAILED(stream_set_position_nothrow(m_stream.get(), m_position)); + } + } + + /** Updates the current position in the stream + ~~~~ + // Read a size marker from the stream, then advance that much. + IStream* stream1 = // ... + auto saver = wil::stream_position_saver(stream1); + auto size = wil::stream_read(stream1); + wil::stream_seek_from_current_position(stream, size); + saver.update(); + ~~~~ + */ + void update() + { + m_position = stream_get_position(m_stream.get()); + } + + //! Returns the current position being saved for the stream + //! @returns The position, in bytes, being saved for the stream + WI_NODISCARD unsigned long long position() const + { + return m_position; + } + + /** Resets the position saver to manage a new stream + Reverts the position of any stream this saver is currently holding a place for. + ~~~~ + IStream* stream1 = // ... + IStream* stream2 = // ... + auto saver = wil::stream_position_saver(stream1); + if (wil::stream_read(stream1).Flags != 0) + { + saver.reset(stream2); // position in stream1 is reverted, now holding stream2 + } + ~~~~ + @param stream The stream whose position is to be saved + */ + void reset(_In_ IStream* stream) + { + reset(); + + m_stream = stream; + m_position = wil::stream_get_position(m_stream.get()); + } + + /** Resets the position of the stream + ~~~~ + IStream* stream1 = // ... + auto saver = wil::stream_position_saver(stream1); + MyType mt = wil::stream_read(stream1); + if (mt.Flags & MyTypeFlags::Extended) + { + saver.reset(); + ProcessExtended(stream1, wil::stream_read(stream1)); + } + else + { + ProcessStandard(stream1, mt); + } + ~~~~ + */ + void reset() + { + if (m_stream) + { + wil::stream_set_position(m_stream.get(), m_position); + } + } + + /** Stops saving the position of the stream + ~~~~ + // The stream has either a standard or extended header, followed by interesting content. + // Read either one, leaving the stream after the headers have been read off. On failure, + // the stream's position is restored. + std::pair get_headers(_In_ IStream* source) + { + auto saver = wil::stream_position_saver(stream1); + MyType mt = wil::stream_read(stream1); + MyTypeExtended mte{}; + if (mt.Flags & MyTypeFlags::Extended) + { + mte = wil::stream_read(stream1); + } + saver.dismiss(); + return { mt, mte }; + } + ~~~~ + */ + void dismiss() + { + m_stream.reset(); + } + + stream_position_saver(stream_position_saver&&) = default; + stream_position_saver& operator=(stream_position_saver&&) = default; + + stream_position_saver(const stream_position_saver&) = delete; + void operator=(const stream_position_saver&) = delete; + + private: + com_ptr m_stream; + unsigned long long m_position; + }; +#endif // WIL_ENABLE_EXCEPTIONS +#pragma endregion // stream helpers + +#if defined(__IObjectWithSite_INTERFACE_DEFINED__) + /// @cond + namespace details + { + inline void __stdcall SetSiteNull(IObjectWithSite* objWithSite) + { + objWithSite->SetSite(nullptr); // break the cycle + } + } // details + /// @endcond + + using unique_set_site_null_call = wil::unique_com_call; + + /** RAII support for managing the site chain. This function sets the site pointer on an object and return an object + that resets it on destruction to break the cycle. + Note, this does not preserve the existing site if there is one (an uncommon case) so only use this when that is not required. + ~~~ + auto cleanup = wil::com_set_site(execCommand.get(), serviceProvider->GetAsSite()); + ~~~ + Include ocidl.h before wil\com.h to use this. + */ + WI_NODISCARD inline unique_set_site_null_call com_set_site(_In_opt_ IUnknown* obj, _In_opt_ IUnknown* site) + { + wil::com_ptr_nothrow objWithSite; + if (site && wil::try_com_copy_to(obj, &objWithSite)) + { + objWithSite->SetSite(site); + } + return unique_set_site_null_call(objWithSite.get()); + } + + /** Iterate over each object in a site chain. Useful for debugging site issues, here is sample use. + ~~~ + void OutputDebugSiteChainWatchWindowText(IUnknown* site) + { + OutputDebugStringW(L"Copy and paste these entries into the Visual Studio Watch Window\n"); + wil::for_each_site(site, [](IUnknown* site) + { + wchar_t msg[64]; + StringCchPrintfW(msg, ARRAYSIZE(msg), L"((IUnknown*)0x%p)->__vfptr[0]\n", site); + OutputDebugStringW(msg); + }); + } + */ + + template + void for_each_site(_In_opt_ IUnknown* siteInput, TLambda&& callback) + { + wil::com_ptr_nothrow site(siteInput); + while (site) + { + callback(site.get()); + auto objWithSite = site.try_query(); + site.reset(); + if (objWithSite) + { + objWithSite->GetSite(IID_PPV_ARGS(&site)); + } + } + } + +#endif // __IObjectWithSite_INTERFACE_DEFINED__ + +} // wil + +#endif diff --git a/libraries/wil/com_apartment_variable.h b/libraries/wil/com_apartment_variable.h new file mode 100644 index 0000000..1ff631d --- /dev/null +++ b/libraries/wil/com_apartment_variable.h @@ -0,0 +1,467 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_COM_APARTMENT_VARIABLE_INCLUDED +#define __WIL_COM_APARTMENT_VARIABLE_INCLUDED + +#include +#include +#include +#include +#include +#include + +#include "com.h" +#include "cppwinrt.h" +#include "result_macros.h" +#include "win32_helpers.h" + +#ifndef WIL_ENABLE_EXCEPTIONS +#error This header requires exceptions +#endif + +namespace wil +{ + // Determine if apartment variables are supported in the current process context. + // Prior to build 22365, the APIs needed to create apartment variables (e.g. RoGetApartmentIdentifier) + // failed for unpackaged processes. For MS people, see http://task.ms/31861017 for details. + // APIs needed to implement apartment variables did not work in non-packaged processes. + inline bool are_apartment_variables_supported() + { + unsigned long long apartmentId{}; + return RoGetApartmentIdentifier(&apartmentId) != HRESULT_FROM_WIN32(ERROR_API_UNAVAILABLE); + } + + // COM will implicitly rundown the apartment registration when it invokes a handler + // and blocks calling unregister when executing the callback. So be careful to release() + // this when callback is invoked to avoid a double free of the cookie. + using unique_apartment_shutdown_registration = unique_any; + + struct apartment_variable_platform + { + static unsigned long long GetApartmentId() + { + unsigned long long apartmentId{}; + FAIL_FAST_IF_FAILED(RoGetApartmentIdentifier(&apartmentId)); + return apartmentId; + } + + static auto RegisterForApartmentShutdown(IApartmentShutdown* observer) + { + unsigned long long id{}; + shutdown_type cookie; + THROW_IF_FAILED(RoRegisterForApartmentShutdown(observer, &id, cookie.put())); + return cookie; + } + + static void UnRegisterForApartmentShutdown(APARTMENT_SHUTDOWN_REGISTRATION_COOKIE cookie) + { + FAIL_FAST_IF_FAILED(RoUnregisterForApartmentShutdown(cookie)); + } + + static auto CoInitializeEx(DWORD coinitFlags = 0 /*COINIT_MULTITHREADED*/) + { + return wil::CoInitializeEx(coinitFlags); + } + + // disable the test hook + inline static constexpr unsigned long AsyncRundownDelayForTestingRaces = INFINITE; + + using shutdown_type = wil::unique_apartment_shutdown_registration; + }; + + enum class apartment_variable_leak_action { fail_fast, ignore }; + + // "pins" the current module in memory by incrementing the module reference count and leaking that. + inline void ensure_module_stays_loaded() + { + static INIT_ONCE s_initLeakModule{}; // avoiding magic statics + wil::init_once_failfast(s_initLeakModule, []() + { + HMODULE result{}; + FAIL_FAST_IF(!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, L"", &result)); + return S_OK; + }); + } + + namespace details + { + // For the address of data, you can detect global variables by the ability to resolve the module from the address. + inline bool IsGlobalVariable(const void* moduleAddress) noexcept + { + wil::unique_hmodule moduleHandle; + return GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, static_cast(moduleAddress), &moduleHandle) != FALSE; + } + + struct any_maker_base + { + std::any(*adapter)(void*); + void* inner; + + WI_NODISCARD std::any operator()() const + { + return adapter(inner); + } + }; + + template + struct any_maker : any_maker_base + { + any_maker() + { + adapter = [](auto) -> std::any { return T{}; }; + } + + any_maker(T(*maker)()) + { + adapter = [](auto maker) -> std::any { return reinterpret_cast(maker)(); }; + inner = reinterpret_cast(maker); + } + + template + any_maker(F&& f) + { + adapter = [](auto maker) -> std::any { return reinterpret_cast(maker)[0](); }; + inner = std::addressof(f); + } + }; + + template + struct apartment_variable_base + { + inline static winrt::slim_mutex s_lock; + + struct apartment_variable_storage + { + apartment_variable_storage(apartment_variable_storage&& other) noexcept = default; + apartment_variable_storage(const apartment_variable_storage& other) = delete; + + apartment_variable_storage(typename test_hook::shutdown_type&& cookie_) : cookie(std::move(cookie_)) + { + } + + winrt::apartment_context context; + typename test_hook::shutdown_type cookie; + // Variables are stored using the address of the apartment_variable_base<> as the key. + std::unordered_map*, std::any> variables; + }; + + // Apartment id -> variables storage. + inline static wil::object_without_destructor_on_shutdown< + std::unordered_map> + s_apartmentStorage; + + constexpr apartment_variable_base() = default; + ~apartment_variable_base() + { + // Global variables (object with static storage duration) + // are run down when the process is shutting down or when the + // dll is unloaded. At these points it is not possible to start + // an async operation and the work performed is not needed, + // the apartments with variable have been run down already. + const auto isGlobal = details::IsGlobalVariable(this); + if (!isGlobal) + { + clear_all_apartments_async(); + } + + if constexpr (leak_action == apartment_variable_leak_action::fail_fast) + { + if (isGlobal && !ProcessShutdownInProgress()) + { + // If you hit this fail fast it means the storage in s_apartmentStorage will be leaked. + // For apartment variables used in .exes, this is expected and + // this fail fast should be disabled using + // wil::apartment_variable + // + // For DLLs, if this is expected, disable this fail fast using + // wil::apartment_variable + // + // Use of apartment variables in DLLs only loaded by COM will never hit this case + // as COM will unload DLLs before apartments are rundown, + // providing the opportunity to empty s_apartmentStorage. + // + // But DLLs loaded and unloaded to call DLL entry points (outside of COM) may + // create variable storage that can't be cleaned up as the DLL lifetime is + // shorter that the COM lifetime. In these cases either + // 1) accept the leaks and disable the fail fast as describe above + // 2) disable module unloading by calling wil::ensure_module_stays_loaded + // 3) CoCreate an object from this DLL to make COM aware of the DLL + FAIL_FAST_IF(!s_apartmentStorage.get().empty()); + } + } + } + + // non-copyable, non-assignable + apartment_variable_base(apartment_variable_base const&) = delete; + void operator=(apartment_variable_base const&) = delete; + + // get current value or throw if no value has been set + std::any& get_existing() + { + if (auto any = get_if()) + { + return *any; + } + THROW_HR(E_NOT_SET); + } + + static apartment_variable_storage* get_current_apartment_variable_storage() + { + auto storage = s_apartmentStorage.get().find(test_hook::GetApartmentId()); + if (storage != s_apartmentStorage.get().end()) + { + return &storage->second; + } + return nullptr; + } + + apartment_variable_storage* ensure_current_apartment_variables() + { + auto variables = get_current_apartment_variable_storage(); + if (variables) + { + return variables; + } + + struct ApartmentObserver : public winrt::implements + { + void STDMETHODCALLTYPE OnUninitialize(unsigned long long apartmentId) noexcept override + { + // This code runs at apartment rundown so be careful to avoid deadlocks by + // extracting the variables under the lock then release them outside. + auto variables = [apartmentId]() + { + auto lock = winrt::slim_lock_guard(s_lock); + return s_apartmentStorage.get().extract(apartmentId); + }(); + WI_ASSERT(variables.key() == apartmentId); + // The system implicitly releases the shutdown observer + // after invoking the callback and does not allow calling unregister + // in the callback. So release the reference to the registration. + variables.mapped().cookie.release(); + } + }; + auto shutdownRegistration = test_hook::RegisterForApartmentShutdown(winrt::make().get()); + return &s_apartmentStorage.get().insert({ test_hook::GetApartmentId(), apartment_variable_storage(std::move(shutdownRegistration)) }).first->second; + } + + // get current value or custom-construct one on demand + template + std::any& get_or_create(any_maker && creator) + { + apartment_variable_storage* variable_storage = nullptr; + + { // scope for lock + auto lock = winrt::slim_lock_guard(s_lock); + variable_storage = ensure_current_apartment_variables(); + + auto variable = variable_storage->variables.find(this); + if (variable != variable_storage->variables.end()) + { + return variable->second; + } + } // drop the lock + + // create the object outside the lock to avoid reentrant deadlock + auto value = creator(); + + auto insert_lock = winrt::slim_lock_guard(s_lock); + // The insertion may fail if creator() recursively caused itself to be created, + // in which case we return the existing object and the falsely-created one is discarded. + return variable_storage->variables.insert({ this, std::move(value) }).first->second; + } + + // get pointer to current value or nullptr if no value has been set + std::any* get_if() + { + auto lock = winrt::slim_lock_guard(s_lock); + + if (auto variable_storage = get_current_apartment_variable_storage()) + { + auto variable = variable_storage->variables.find(this); + if (variable != variable_storage->variables.end()) + { + return &(variable->second); + } + } + return nullptr; + } + + // replace or create the current value, fail fasts if the value is not already stored + void set(std::any value) + { + // release value, with the swapped value, outside of the lock + { + auto lock = winrt::slim_lock_guard(s_lock); + auto storage = s_apartmentStorage.get().find(test_hook::GetApartmentId()); + FAIL_FAST_IF(storage == s_apartmentStorage.get().end()); + auto& variable_storage = storage->second; + auto variable = variable_storage.variables.find(this); + FAIL_FAST_IF(variable == variable_storage.variables.end()); + variable->second.swap(value); + } + } + + // remove any current value + void clear() + { + auto lock = winrt::slim_lock_guard(s_lock); + if (auto variable_storage = get_current_apartment_variable_storage()) + { + variable_storage->variables.erase(this); + if (variable_storage->variables.size() == 0) + { + s_apartmentStorage.get().erase(test_hook::GetApartmentId()); + } + } + } + + winrt::Windows::Foundation::IAsyncAction clear_all_apartments_async() + { + // gather all the apartments that hold objects we need to destruct + // (do not gather the objects themselves, because the apartment might + // destruct before we get around to it, and we should let the apartment + // destruct the object while it still can). + + std::vector contexts; + { // scope for lock + auto lock = winrt::slim_lock_guard(s_lock); + for (auto& [id, storage] : s_apartmentStorage.get()) + { + auto variable = storage.variables.find(this); + if (variable != storage.variables.end()) + { + contexts.push_back(storage.context); + } + } + } + + if (contexts.empty()) + { + co_return; + } + + wil::unique_mta_usage_cookie mta_reference; // need to extend the MTA due to async cleanup + FAIL_FAST_IF_FAILED(CoIncrementMTAUsage(mta_reference.put())); + + // From a background thread hop into each apartment to run down the object + // if it's still there. + co_await winrt::resume_background(); + + // This hook enables testing the case where execution of this method loses the race with + // apartment rundown by other means. + if constexpr (test_hook::AsyncRundownDelayForTestingRaces != INFINITE) + { + Sleep(test_hook::AsyncRundownDelayForTestingRaces); + } + + for (auto&& context : contexts) + { + try + { + co_await context; + clear(); + } + catch (winrt::hresult_error const& e) + { + // Ignore failure if apartment ran down before we could clean it up. + // The object already ran down as part of apartment cleanup. + if ((e.code() != RPC_E_SERVER_DIED_DNE) && + (e.code() != RPC_E_DISCONNECTED)) + { + throw; + } + } + catch (...) + { + FAIL_FAST(); + } + } + } + + static const auto& storage() + { + return s_apartmentStorage.get(); + } + + static size_t current_apartment_variable_count() + { + auto lock = winrt::slim_lock_guard(s_lock); + if (auto variable_storage = get_current_apartment_variable_storage()) + { + return variable_storage->variables.size(); + } + return 0; + } + }; + } + + // Apartment variables enable storing COM objects safely in globals + // (objects with static storage duration) by creating a unique copy + // in each apartment and managing their lifetime based on apartment rundown + // notifications. + // They can also be used for automatic or dynamic storage duration but those + // cases are less common. + // This type is also useful for storing references to apartment affine objects. + // + // Note, that apartment variables hosted in a COM DLL need to integrate with + // the DllCanUnloadNow() function to include the ref counts contributed by + // C++ WinRT objects. This is automatic for DLLs that host C++ WinRT objects + // but WRL projects will need to be updated to call winrt::get_module_lock(). + + template + struct apartment_variable : details::apartment_variable_base + { + using base = details::apartment_variable_base; + + constexpr apartment_variable() = default; + + // Get current value or throw if no value has been set. + T& get_existing() { return std::any_cast(base::get_existing()); } + + // Get current value or default-construct one on demand. + T& get_or_create() + { + return std::any_cast(base::get_or_create(details::any_maker())); + } + + // Get current value or custom-construct one on demand. + template + T& get_or_create(F&& f) + { + return std::any_cast(base::get_or_create(details::any_maker(std::forward(f)))); + } + + // get pointer to current value or nullptr if no value has been set + T* get_if() { return std::any_cast(base::get_if()); } + + // replace or create the current value, fail fasts if the value is not already stored + template void set(V&& value) { return base::set(std::forward(value)); } + + // Clear the value in the current apartment. + using base::clear; + + // Asynchronously clear the value in all apartments it is present in. + using base::clear_all_apartments_async; + + // For testing only. + // 1) To observe the state of the storage in the debugger assign this to + // a temporary variable (const&) and watch its contents. + // 2) Use this to test the implementation. + using base::storage; + // For testing only. The number of variables in the current apartment. + using base::current_apartment_variable_count; + }; +} + +#endif // __WIL_COM_APARTMENT_VARIABLE_INCLUDED diff --git a/libraries/wil/common.h b/libraries/wil/common.h new file mode 100644 index 0000000..9edfdc0 --- /dev/null +++ b/libraries/wil/common.h @@ -0,0 +1,798 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_COMMON_INCLUDED +#define __WIL_COMMON_INCLUDED + +#if defined(_KERNEL_MODE ) && !defined(__WIL_MIN_KERNEL) +// This define indicates that the WIL usage is in a kernel mode context where +// a high degree of WIL functionality is desired. +// +// Use (sparingly) to change behavior based on whether WIL is being used in kernel +// mode or user mode. +#define WIL_KERNEL_MODE +#endif + +// Defining WIL_HIDE_DEPRECATED will hide everything deprecated. +// Each wave of deprecation will add a new WIL_HIDE_DEPRECATED_YYMM number that can be used to lock deprecation at +// a particular point, allowing components to avoid backslide and catch up to the current independently. +#ifdef WIL_HIDE_DEPRECATED +#define WIL_HIDE_DEPRECATED_1809 +#endif +#ifdef WIL_HIDE_DEPRECATED_1809 +#define WIL_HIDE_DEPRECATED_1612 +#endif +#ifdef WIL_HIDE_DEPRECATED_1612 +#define WIL_HIDE_DEPRECATED_1611 +#endif + +// Implementation side note: ideally the deprecation would be done with the function-level declspec +// as it allows you to utter the error text when used. The declspec works, but doing it selectively with +// a macro makes intellisense deprecation comments not work. So we just use the #pragma deprecation. +#ifdef WIL_WARN_DEPRECATED +#define WIL_WARN_DEPRECATED_1809 +#endif +#ifdef WIL_WARN_DEPRECATED_1809 +#define WIL_WARN_DEPRECATED_1612 +#endif +#ifdef WIL_WARN_DEPRECATED_1612 +#define WIL_WARN_DEPRECATED_1611 +#endif +#ifdef WIL_WARN_DEPRECATED_1809 +#define WIL_WARN_DEPRECATED_1809_PRAGMA(...) __pragma(deprecated(__VA_ARGS__)) +#else +#define WIL_WARN_DEPRECATED_1809_PRAGMA(...) +#endif +#ifdef WIL_WARN_DEPRECATED_1611 +#define WIL_WARN_DEPRECATED_1611_PRAGMA(...) __pragma(deprecated(__VA_ARGS__)) +#else +#define WIL_WARN_DEPRECATED_1611_PRAGMA(...) +#endif +#ifdef WIL_WARN_DEPRECATED_1612 +#define WIL_WARN_DEPRECATED_1612_PRAGMA(...) __pragma(deprecated(__VA_ARGS__)) +#else +#define WIL_WARN_DEPRECATED_1612_PRAGMA(...) +#endif + +#if defined(_MSVC_LANG) +#define __WI_SUPPRESS_4127_S __pragma(warning(push)) __pragma(warning(disable:4127)) __pragma(warning(disable:26498)) __pragma(warning(disable:4245)) +#define __WI_SUPPRESS_4127_E __pragma(warning(pop)) +#define __WI_SUPPRESS_NULLPTR_ANALYSIS __pragma(warning(suppress:28285)) __pragma(warning(suppress:6504)) +#define __WI_SUPPRESS_NONINIT_ANALYSIS __pragma(warning(suppress:26495)) +#define __WI_SUPPRESS_NOEXCEPT_ANALYSIS __pragma(warning(suppress:26439)) +#else +#define __WI_SUPPRESS_4127_S +#define __WI_SUPPRESS_4127_E +#define __WI_SUPPRESS_NULLPTR_ANALYSIS +#define __WI_SUPPRESS_NONINIT_ANALYSIS +#define __WI_SUPPRESS_NOEXCEPT_ANALYSIS +#endif + +#include + +// Some SAL remapping / decoration to better support Doxygen. Macros that look like function calls can +// confuse Doxygen when they are used to decorate a function or variable. We simplify some of these to +// basic macros without the function for common use cases. +/// @cond +#define _Success_return_ _Success_(return) +#define _Success_true_ _Success_(true) +#define __declspec_noinline_ __declspec(noinline) +#define __declspec_selectany_ __declspec(selectany) +/// @endcond + +//! @defgroup macrobuilding Macro Composition +//! The following macros are building blocks primarily intended for authoring other macros. +//! @{ + +//! Re-state a macro value (indirection for composition) +#define WI_FLATTEN(...) __VA_ARGS__ + +/// @cond +#define __WI_PASTE_imp(a, b) a##b +/// @endcond + +//! This macro is for use in other macros to paste two tokens together, such as a constant and the __LINE__ macro. +#define WI_PASTE(a, b) __WI_PASTE_imp(a, b) + +/// @cond +#define __WI_HAS_VA_OPT_IMPL(F, T, ...) T +#define __WI_HAS_VA_OPT_(...) __WI_HAS_VA_OPT_IMPL(__VA_OPT__(0,) 1, 0) +/// @endcond + +//! Evaluates to '1' when support for '__VA_OPT__' is available, else '0' +#define WI_HAS_VA_OPT __WI_HAS_VA_OPT_(unused) + +/// @cond +#define __WI_ARGS_COUNT1(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, \ + A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40, A41, A42, A43, A44, A45, A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, \ + A60, A61, A62, A63, A64, A65, A66, A67, A68, A69, A70, A71, A72, A73, A74, A75, A76, A77, A78, A79, A80, A81, A82, A83, A84, A85, A86, A87, A88, A89, \ + A90, A91, A92, A93, A94, A95, A96, A97, A98, A99, count, ...) count +#define __WI_ARGS_COUNT0(...) WI_FLATTEN(__WI_ARGS_COUNT1(__VA_ARGS__, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \ + 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \ + 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) +#define __WI_ARGS_COUNT_PREFIX(...) 0, __VA_ARGS__ +/// @endcond + +//! This variadic macro returns the number of arguments passed to it (up to 99). +#if WI_HAS_VA_OPT +#define WI_ARGS_COUNT(...) __WI_ARGS_COUNT0(0 __VA_OPT__(, __VA_ARGS__)) +#else +#define WI_ARGS_COUNT(...) __WI_ARGS_COUNT0(__WI_ARGS_COUNT_PREFIX(__VA_ARGS__)) +#endif + +/// @cond +#define __WI_FOR_imp0( fn) +#define __WI_FOR_imp1( fn, arg) fn(arg) +#define __WI_FOR_imp2( fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp1(fn, __VA_ARGS__)) +#define __WI_FOR_imp3( fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp2(fn, __VA_ARGS__)) +#define __WI_FOR_imp4( fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp3(fn, __VA_ARGS__)) +#define __WI_FOR_imp5( fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp4(fn, __VA_ARGS__)) +#define __WI_FOR_imp6( fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp5(fn, __VA_ARGS__)) +#define __WI_FOR_imp7( fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp6(fn, __VA_ARGS__)) +#define __WI_FOR_imp8( fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp7(fn, __VA_ARGS__)) +#define __WI_FOR_imp9( fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp8(fn, __VA_ARGS__)) +#define __WI_FOR_imp10(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp9(fn, __VA_ARGS__)) +#define __WI_FOR_imp11(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp10(fn, __VA_ARGS__)) +#define __WI_FOR_imp12(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp11(fn, __VA_ARGS__)) +#define __WI_FOR_imp13(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp12(fn, __VA_ARGS__)) +#define __WI_FOR_imp14(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp13(fn, __VA_ARGS__)) +#define __WI_FOR_imp15(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp14(fn, __VA_ARGS__)) +#define __WI_FOR_imp16(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp15(fn, __VA_ARGS__)) +#define __WI_FOR_imp17(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp16(fn, __VA_ARGS__)) +#define __WI_FOR_imp18(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp17(fn, __VA_ARGS__)) +#define __WI_FOR_imp19(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp18(fn, __VA_ARGS__)) +#define __WI_FOR_imp20(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp19(fn, __VA_ARGS__)) +#define __WI_FOR_imp21(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp20(fn, __VA_ARGS__)) +#define __WI_FOR_imp22(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp21(fn, __VA_ARGS__)) +#define __WI_FOR_imp23(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp22(fn, __VA_ARGS__)) +#define __WI_FOR_imp24(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp23(fn, __VA_ARGS__)) +#define __WI_FOR_imp25(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp24(fn, __VA_ARGS__)) +#define __WI_FOR_imp26(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp25(fn, __VA_ARGS__)) +#define __WI_FOR_imp27(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp26(fn, __VA_ARGS__)) +#define __WI_FOR_imp28(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp27(fn, __VA_ARGS__)) +#define __WI_FOR_imp29(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp28(fn, __VA_ARGS__)) +#define __WI_FOR_imp30(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp29(fn, __VA_ARGS__)) +#define __WI_FOR_imp31(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp30(fn, __VA_ARGS__)) +#define __WI_FOR_imp32(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp31(fn, __VA_ARGS__)) +#define __WI_FOR_imp33(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp32(fn, __VA_ARGS__)) +#define __WI_FOR_imp34(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp33(fn, __VA_ARGS__)) +#define __WI_FOR_imp35(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp34(fn, __VA_ARGS__)) +#define __WI_FOR_imp36(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp35(fn, __VA_ARGS__)) +#define __WI_FOR_imp37(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp36(fn, __VA_ARGS__)) +#define __WI_FOR_imp38(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp37(fn, __VA_ARGS__)) +#define __WI_FOR_imp39(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp38(fn, __VA_ARGS__)) +#define __WI_FOR_imp40(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp39(fn, __VA_ARGS__)) +#define __WI_FOR_imp41(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp40(fn, __VA_ARGS__)) +#define __WI_FOR_imp42(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp41(fn, __VA_ARGS__)) +#define __WI_FOR_imp43(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp42(fn, __VA_ARGS__)) +#define __WI_FOR_imp44(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp43(fn, __VA_ARGS__)) +#define __WI_FOR_imp45(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp44(fn, __VA_ARGS__)) +#define __WI_FOR_imp46(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp45(fn, __VA_ARGS__)) +#define __WI_FOR_imp47(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp46(fn, __VA_ARGS__)) +#define __WI_FOR_imp48(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp47(fn, __VA_ARGS__)) +#define __WI_FOR_imp49(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp48(fn, __VA_ARGS__)) +#define __WI_FOR_imp50(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp49(fn, __VA_ARGS__)) +#define __WI_FOR_imp51(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp50(fn, __VA_ARGS__)) +#define __WI_FOR_imp52(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp51(fn, __VA_ARGS__)) +#define __WI_FOR_imp53(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp52(fn, __VA_ARGS__)) +#define __WI_FOR_imp54(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp53(fn, __VA_ARGS__)) +#define __WI_FOR_imp55(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp54(fn, __VA_ARGS__)) +#define __WI_FOR_imp56(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp55(fn, __VA_ARGS__)) +#define __WI_FOR_imp57(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp56(fn, __VA_ARGS__)) +#define __WI_FOR_imp58(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp57(fn, __VA_ARGS__)) +#define __WI_FOR_imp59(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp58(fn, __VA_ARGS__)) +#define __WI_FOR_imp60(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp59(fn, __VA_ARGS__)) +#define __WI_FOR_imp61(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp60(fn, __VA_ARGS__)) +#define __WI_FOR_imp62(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp61(fn, __VA_ARGS__)) +#define __WI_FOR_imp63(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp62(fn, __VA_ARGS__)) +#define __WI_FOR_imp64(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp63(fn, __VA_ARGS__)) +#define __WI_FOR_imp65(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp64(fn, __VA_ARGS__)) +#define __WI_FOR_imp66(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp65(fn, __VA_ARGS__)) +#define __WI_FOR_imp67(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp66(fn, __VA_ARGS__)) +#define __WI_FOR_imp68(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp67(fn, __VA_ARGS__)) +#define __WI_FOR_imp69(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp68(fn, __VA_ARGS__)) +#define __WI_FOR_imp70(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp69(fn, __VA_ARGS__)) +#define __WI_FOR_imp71(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp70(fn, __VA_ARGS__)) +#define __WI_FOR_imp72(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp71(fn, __VA_ARGS__)) +#define __WI_FOR_imp73(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp72(fn, __VA_ARGS__)) +#define __WI_FOR_imp74(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp73(fn, __VA_ARGS__)) +#define __WI_FOR_imp75(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp74(fn, __VA_ARGS__)) +#define __WI_FOR_imp76(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp75(fn, __VA_ARGS__)) +#define __WI_FOR_imp77(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp76(fn, __VA_ARGS__)) +#define __WI_FOR_imp78(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp77(fn, __VA_ARGS__)) +#define __WI_FOR_imp79(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp78(fn, __VA_ARGS__)) +#define __WI_FOR_imp80(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp79(fn, __VA_ARGS__)) +#define __WI_FOR_imp81(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp80(fn, __VA_ARGS__)) +#define __WI_FOR_imp82(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp81(fn, __VA_ARGS__)) +#define __WI_FOR_imp83(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp82(fn, __VA_ARGS__)) +#define __WI_FOR_imp84(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp83(fn, __VA_ARGS__)) +#define __WI_FOR_imp85(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp84(fn, __VA_ARGS__)) +#define __WI_FOR_imp86(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp85(fn, __VA_ARGS__)) +#define __WI_FOR_imp87(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp86(fn, __VA_ARGS__)) +#define __WI_FOR_imp88(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp87(fn, __VA_ARGS__)) +#define __WI_FOR_imp89(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp88(fn, __VA_ARGS__)) +#define __WI_FOR_imp90(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp89(fn, __VA_ARGS__)) +#define __WI_FOR_imp91(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp90(fn, __VA_ARGS__)) +#define __WI_FOR_imp92(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp91(fn, __VA_ARGS__)) +#define __WI_FOR_imp93(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp92(fn, __VA_ARGS__)) +#define __WI_FOR_imp94(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp93(fn, __VA_ARGS__)) +#define __WI_FOR_imp95(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp94(fn, __VA_ARGS__)) +#define __WI_FOR_imp96(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp95(fn, __VA_ARGS__)) +#define __WI_FOR_imp97(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp96(fn, __VA_ARGS__)) +#define __WI_FOR_imp98(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp97(fn, __VA_ARGS__)) +#define __WI_FOR_imp99(fn, arg, ...) fn(arg) WI_FLATTEN(__WI_FOR_imp98(fn, __VA_ARGS__)) + +#define __WI_FOR_imp(n, fnAndArgs) WI_PASTE(__WI_FOR_imp, n) fnAndArgs +/// @endcond + +//! Iterates through each of the given arguments invoking the specified macro against each one. +#define WI_FOREACH(fn, ...) __WI_FOR_imp(WI_ARGS_COUNT(__VA_ARGS__), (fn, ##__VA_ARGS__)) + +//! Dispatches a single macro name to separate macros based on the number of arguments passed to it. +#define WI_MACRO_DISPATCH(name, ...) WI_PASTE(WI_PASTE(name, WI_ARGS_COUNT(__VA_ARGS__)), (__VA_ARGS__)) + +//! @} // Macro composition helpers + +#if !defined(__cplusplus) || defined(__WIL_MIN_KERNEL) + +#define WI_ODR_PRAGMA(NAME, TOKEN) +#define WI_NOEXCEPT + +#else +#pragma warning(push) +#pragma warning(disable:4714) // __forceinline not honored + +// DO NOT add *any* further includes to this file -- there should be no dependencies from its usage +#include "wistd_type_traits.h" + +//! This macro inserts ODR violation protection; the macro allows it to be compatible with straight "C" code +#define WI_ODR_PRAGMA(NAME, TOKEN) __pragma(detect_mismatch("ODR_violation_" NAME "_mismatch", TOKEN)) + +#ifdef WIL_KERNEL_MODE +WI_ODR_PRAGMA("WIL_KERNEL_MODE", "1") +#else +WI_ODR_PRAGMA("WIL_KERNEL_MODE", "0") +#endif + +#if (defined(_CPPUNWIND) || defined(__EXCEPTIONS)) && !defined(WIL_SUPPRESS_EXCEPTIONS) +/** This define is automatically set when exceptions are enabled within wil. +It is automatically defined when your code is compiled with exceptions enabled (via checking for the built-in +_CPPUNWIND or __EXCEPTIONS flag) unless you explicitly define WIL_SUPPRESS_EXCEPTIONS ahead of including your first wil +header. All exception-based WIL methods and classes are included behind: +~~~~ +#ifdef WIL_ENABLE_EXCEPTIONS +// code +#endif +~~~~ +This enables exception-free code to directly include WIL headers without worrying about exception-based +routines suddenly becoming available. */ +#define WIL_ENABLE_EXCEPTIONS +#endif +/// @endcond + +/// @cond +#if defined(WIL_EXCEPTION_MODE) +static_assert(WIL_EXCEPTION_MODE <= 2, "Invalid exception mode"); +#elif !defined(WIL_LOCK_EXCEPTION_MODE) +#define WIL_EXCEPTION_MODE 0 // default, can link exception-based and non-exception based libraries together +#pragma detect_mismatch("ODR_violation_WIL_EXCEPTION_MODE_mismatch", "0") +#elif defined(WIL_ENABLE_EXCEPTIONS) +#define WIL_EXCEPTION_MODE 1 // new code optimization: ONLY support linking libraries together that have exceptions enabled +#pragma detect_mismatch("ODR_violation_WIL_EXCEPTION_MODE_mismatch", "1") +#else +#define WIL_EXCEPTION_MODE 2 // old code optimization: ONLY support linking libraries that are NOT using exceptions +#pragma detect_mismatch("ODR_violation_WIL_EXCEPTION_MODE_mismatch", "2") +#endif + +#if WIL_EXCEPTION_MODE == 1 && !defined(WIL_ENABLE_EXCEPTIONS) +#error Must enable exceptions when WIL_EXCEPTION_MODE == 1 +#endif + +// block for documentation only +#if defined(WIL_DOXYGEN) +/** This define can be explicitly set to disable exception usage within wil. +Normally this define is never needed as the WIL_ENABLE_EXCEPTIONS macro is enabled automatically by looking +at _CPPUNWIND. If your code compiles with exceptions enabled, but does not want to enable the exception-based +classes and methods from WIL, define this macro ahead of including the first WIL header. */ +#define WIL_SUPPRESS_EXCEPTIONS + +/** This define can be explicitly set to lock the process exception mode to WIL_ENABLE_EXCEPTIONS. +Locking the exception mode provides optimizations to exception barriers, staging hooks and DLL load costs as it eliminates the need to +do copy-on-write initialization of various function pointers and the necessary indirection that's done within WIL to avoid ODR violations +when linking libraries together with different exception handling semantics. */ +#define WIL_LOCK_EXCEPTION_MODE + +/** This define explicit sets the exception mode for the process to control optimizations. +Three exception modes are available: +0) This is the default. This enables a binary to link both exception-based and non-exception based libraries together that + use WIL. This adds overhead to exception barriers, DLL copy on write pages and indirection through function pointers to avoid ODR + violations when linking libraries together with different exception handling semantics. +1) Prefer this setting when it can be used. This locks the binary to only supporting libraries which were built with exceptions enabled. +2) This locks the binary to libraries built without exceptions. */ +#define WIL_EXCEPTION_MODE +#endif + +#if (__cplusplus >= 201703) || (_MSVC_LANG >= 201703) +#define WIL_HAS_CXX_17 1 +#else +#define WIL_HAS_CXX_17 0 +#endif + +// Until we'll have C++17 enabled in our code base, we're falling back to SAL +#define WI_NODISCARD __WI_LIBCPP_NODISCARD_ATTRIBUTE + +#define __R_ENABLE_IF_IS_CLASS(ptrType) wistd::enable_if_t::value, void*> = nullptr +#define __R_ENABLE_IF_IS_NOT_CLASS(ptrType) wistd::enable_if_t::value, void*> = nullptr + +//! @defgroup bitwise Bitwise Inspection and Manipulation +//! Bitwise helpers to improve readability and reduce the error rate of bitwise operations. +//! Several macros have been constructed to assist with bitwise inspection and manipulation. These macros exist +//! for two primary purposes: +//! +//! 1. To improve the readability of bitwise comparisons and manipulation. +//! +//! The macro names are the more concise, readable form of what's being done and do not require that any flags +//! or variables be specified multiple times for the comparisons. +//! +//! 2. To reduce the error rate associated with bitwise operations. +//! +//! The readability improvements naturally lend themselves to this by cutting down the number of concepts. +//! Using `WI_IsFlagSet(var, MyEnum::Flag)` rather than `((var & MyEnum::Flag) == MyEnum::Flag)` removes the comparison +//! operator and repetition in the flag value. +//! +//! Additionally, these macros separate single flag operations (which tend to be the most common) from multi-flag +//! operations so that compile-time errors are generated for bitwise operations which are likely incorrect, +//! such as: `WI_IsFlagSet(var, MyEnum::None)` or `WI_IsFlagSet(var, MyEnum::ValidMask)`. +//! +//! Note that the single flag helpers should be used when a compile-time constant single flag is being manipulated. These +//! helpers provide compile-time errors on misuse and should be preferred over the multi-flag helpers. The multi-flag helpers +//! should be used when multiple flags are being used simultaneously or when the flag values are not compile-time constants. +//! +//! Common example usage (manipulation of flag variables): +//! ~~~~ +//! WI_SetFlag(m_flags, MyFlags::Foo); // Set a single flag in the given variable +//! WI_SetAllFlags(m_flags, MyFlags::Foo | MyFlags::Bar); // Set one or more flags +//! WI_ClearFlagIf(m_flags, MyFlags::Bar, isBarClosed); // Conditionally clear a single flag based upon a bool +//! WI_ClearAllFlags(m_flags, MyFlags::Foo | MyFlags::Bar); // Clear one or more flags from the given variable +//! WI_ToggleFlag(m_flags, MyFlags::Foo); // Toggle (change to the opposite value) a single flag +//! WI_UpdateFlag(m_flags, MyFlags::Bar, isBarClosed); // Sets or Clears a single flag from the given variable based upon a bool value +//! WI_UpdateFlagsInMask(m_flags, flagsMask, newFlagValues); // Sets or Clears the flags in flagsMask to the masked values from newFlagValues +//! ~~~~ +//! Common example usage (inspection of flag variables): +//! ~~~~ +//! if (WI_IsFlagSet(m_flags, MyFlags::Foo)) // Is a single flag set in the given variable? +//! if (WI_IsAnyFlagSet(m_flags, MyFlags::Foo | MyFlags::Bar)) // Is at least one flag from the given mask set? +//! if (WI_AreAllFlagsClear(m_flags, MyFlags::Foo | MyFlags::Bar)) // Are all flags in the given list clear? +//! if (WI_IsSingleFlagSet(m_flags)) // Is *exactly* one flag set in the given variable? +//! ~~~~ +//! @{ + +//! Returns the unsigned type of the same width and numeric value as the given enum +#define WI_EnumValue(val) static_cast<::wil::integral_from_enum>(val) +//! Validates that exactly ONE bit is set in compile-time constant `flag` +#define WI_StaticAssertSingleBitSet(flag) static_cast(::wil::details::verify_single_flag_helper(WI_EnumValue(flag))>::value) + +//! @name Bitwise manipulation macros +//! @{ + +//! Set zero or more bitflags specified by `flags` in the variable `var`. +#define WI_SetAllFlags(var, flags) ((var) |= (flags)) +//! Set a single compile-time constant `flag` in the variable `var`. +#define WI_SetFlag(var, flag) WI_SetAllFlags(var, WI_StaticAssertSingleBitSet(flag)) +//! Conditionally sets a single compile-time constant `flag` in the variable `var` only if `condition` is true. +#define WI_SetFlagIf(var, flag, condition) do { if (wil::verify_bool(condition)) { WI_SetFlag(var, flag); } } while ((void)0, 0) + +//! Clear zero or more bitflags specified by `flags` from the variable `var`. +#define WI_ClearAllFlags(var, flags) ((var) &= ~(flags)) +//! Clear a single compile-time constant `flag` from the variable `var`. +#define WI_ClearFlag(var, flag) WI_ClearAllFlags(var, WI_StaticAssertSingleBitSet(flag)) +//! Conditionally clear a single compile-time constant `flag` in the variable `var` only if `condition` is true. +#define WI_ClearFlagIf(var, flag, condition) do { if (wil::verify_bool(condition)) { WI_ClearFlag(var, flag); } } while ((void)0, 0) + +//! Changes a single compile-time constant `flag` in the variable `var` to be set if `isFlagSet` is true or cleared if `isFlagSet` is false. +#define WI_UpdateFlag(var, flag, isFlagSet) (wil::verify_bool(isFlagSet) ? WI_SetFlag(var, flag) : WI_ClearFlag(var, flag)) +//! Changes only the flags specified by `flagsMask` in the variable `var` to match the corresponding flags in `newFlags`. +#define WI_UpdateFlagsInMask(var, flagsMask, newFlags) wil::details::UpdateFlagsInMaskHelper(var, flagsMask, newFlags) + +//! Toggles (XOR the value) of multiple bitflags specified by `flags` in the variable `var`. +#define WI_ToggleAllFlags(var, flags) ((var) ^= (flags)) +//! Toggles (XOR the value) of a single compile-time constant `flag` in the variable `var`. +#define WI_ToggleFlag(var, flag) WI_ToggleAllFlags(var, WI_StaticAssertSingleBitSet(flag)) +//! @} // bitwise manipulation macros + +//! @name Bitwise inspection macros +//! @{ + +//! Evaluates as true if every bitflag specified in `flags` is set within `val`. +#define WI_AreAllFlagsSet(val, flags) wil::details::AreAllFlagsSetHelper(val, flags) +//! Evaluates as true if one or more bitflags specified in `flags` are set within `val`. +#define WI_IsAnyFlagSet(val, flags) (static_cast(WI_EnumValue(val) & WI_EnumValue(flags)) != static_cast(0)) +//! Evaluates as true if a single compile-time constant `flag` is set within `val`. +#define WI_IsFlagSet(val, flag) WI_IsAnyFlagSet(val, WI_StaticAssertSingleBitSet(flag)) + +//! Evaluates as true if every bitflag specified in `flags` is clear within `val`. +#define WI_AreAllFlagsClear(val, flags) (static_cast(WI_EnumValue(val) & WI_EnumValue(flags)) == static_cast(0)) +//! Evaluates as true if one or more bitflags specified in `flags` are clear within `val`. +#define WI_IsAnyFlagClear(val, flags) (!wil::details::AreAllFlagsSetHelper(val, flags)) +//! Evaluates as true if a single compile-time constant `flag` is clear within `val`. +#define WI_IsFlagClear(val, flag) WI_AreAllFlagsClear(val, WI_StaticAssertSingleBitSet(flag)) + +//! Evaluates as true if exactly one bit (any bit) is set within `val`. +#define WI_IsSingleFlagSet(val) wil::details::IsSingleFlagSetHelper(val) +//! Evaluates as true if exactly one bit from within the specified `mask` is set within `val`. +#define WI_IsSingleFlagSetInMask(val, mask) wil::details::IsSingleFlagSetHelper((val) & (mask)) +//! Evaluates as true if exactly one bit (any bit) is set within `val` or if there are no bits set within `val`. +#define WI_IsClearOrSingleFlagSet(val) wil::details::IsClearOrSingleFlagSetHelper(val) +//! Evaluates as true if exactly one bit from within the specified `mask` is set within `val` or if there are no bits from `mask` set within `val`. +#define WI_IsClearOrSingleFlagSetInMask(val, mask) wil::details::IsClearOrSingleFlagSetHelper((val) & (mask)) +//! @} + +#if defined(WIL_DOXYGEN) +/** This macro provides a C++ header with a guaranteed initialization function. +Normally, were a global object's constructor used for this purpose, the optimizer/linker might throw +the object away if it's unreferenced (which throws away the side-effects that the initialization function +was trying to achieve). Using this macro forces linker inclusion of a variable that's initialized by the +provided function to elide that optimization. +//! +This functionality is primarily provided as a building block for header-based libraries (such as WIL) +to be able to layer additional functionality into other libraries by their mere inclusion. Alternative models +of initialization should be used whenever they are available. +~~~~ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +WI_HEADER_INITITALIZATION_FUNCTION(InitializeDesktopFamilyApis, [] +{ + g_pfnGetModuleName = GetCurrentModuleName; + g_pfnFailFastInLoaderCallout = FailFastInLoaderCallout; + return 1; +}); +#endif +~~~~ +The above example is used within WIL to decide whether or not the library containing WIL is allowed to use +desktop APIs. Building this functionality as #IFDEFs within functions would create ODR violations, whereas +doing it with global function pointers and header initialization allows a runtime determination. */ +#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) +#elif defined(_M_IX86) +#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) \ + extern "C" { __declspec(selectany) unsigned char g_header_init_ ## name = static_cast(fn()); } \ + __pragma(comment(linker, "/INCLUDE:_g_header_init_" #name)) +#elif defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM) || defined(_M_ARM64) +#define WI_HEADER_INITITALIZATION_FUNCTION(name, fn) \ + extern "C" { __declspec(selectany) unsigned char g_header_init_ ## name = static_cast(fn()); } \ + __pragma(comment(linker, "/INCLUDE:g_header_init_" #name)) +#else + #error linker pragma must include g_header_init variation +#endif + + +/** All Windows Implementation Library classes and functions are located within the "wil" namespace. +The 'wil' namespace is an intentionally short name as the intent is for code to be able to reference +the namespace directly (example: `wil::srwlock lock;`) without a using statement. Resist adding a using +statement for wil to avoid introducing potential name collisions between wil and other namespaces. */ +namespace wil +{ + /// @cond + namespace details + { + template + class pointer_range + { + public: + pointer_range(T begin_, T end_) : m_begin(begin_), m_end(end_) {} + WI_NODISCARD T begin() const { return m_begin; } + WI_NODISCARD T end() const { return m_end; } + private: + T m_begin; + T m_end; + }; + } + /// @endcond + + /** Enables using range-based for between a begin and end object pointer. + ~~~~ + for (auto& obj : make_range(objPointerBegin, objPointerEnd)) { } + ~~~~ */ + template + details::pointer_range make_range(T begin, T end) + { + return details::pointer_range(begin, end); + } + + /** Enables using range-based for on a range when given the base pointer and the number of objects in the range. + ~~~~ + for (auto& obj : make_range(objPointer, objCount)) { } + ~~~~ */ + template + details::pointer_range make_range(T begin, size_t count) + { + return details::pointer_range(begin, begin + count); + } + + + //! @defgroup outparam Output Parameters + //! Improve the conciseness of assigning values to optional output parameters. + //! @{ + + /** Assign the given value to an optional output parameter. + Makes code more concise by removing trivial `if (outParam)` blocks. */ + template + inline void assign_to_opt_param(_Out_opt_ T *outParam, T val) + { + if (outParam != nullptr) + { + *outParam = val; + } + } + + /** Assign NULL to an optional output pointer parameter. + Makes code more concise by removing trivial `if (outParam)` blocks. */ + template + inline void assign_null_to_opt_param(_Out_opt_ T *outParam) + { + if (outParam != nullptr) + { + *outParam = nullptr; + } + } + //! @} // end output parameter helpers + + /** Performs a logical or of the given variadic template parameters allowing indirect compile-time boolean evaluation. + Example usage: + ~~~~ + template + struct FeatureRequiredBy + { + static const bool enabled = wil::variadic_logical_or::enabled...>::value; + }; + ~~~~ */ + template struct variadic_logical_or; + /// @cond + template <> struct variadic_logical_or<> : wistd::false_type { }; + template struct variadic_logical_or : wistd::true_type { }; + template struct variadic_logical_or : variadic_logical_or::type { }; + /// @endcond + + /// @cond + namespace details + { + template + struct verify_single_flag_helper + { + static_assert((flag != 0) && ((flag & (flag - 1)) == 0), "Single flag expected, zero or multiple flags found"); + static const unsigned long long value = flag; + }; + } + /// @endcond + + + //! @defgroup typesafety Type Validation + //! Helpers to validate variable types to prevent accidental, but allowed type conversions. + //! These helpers are most useful when building macros that accept a particular type. Putting these functions around the types accepted + //! prior to pushing that type through to a function (or using it within the macro) allows the macro to add an additional layer of type + //! safety that would ordinarily be stripped away by C++ implicit conversions. This system is extensively used in the error handling helper + //! macros to validate the types given to various macro parameters. + //! @{ + + /** Verify that `val` can be evaluated as a logical bool. + Other types will generate an intentional compilation error. Allowed types for a logical bool are bool, BOOL, + boolean, BOOLEAN, and classes with an explicit bool cast. + @param val The logical bool expression + @return A C++ bool representing the evaluation of `val`. */ + template + _Post_satisfies_(return == static_cast(val)) + __forceinline constexpr bool verify_bool(const T& val) + { + return static_cast(val); + } + + template + __forceinline constexpr bool verify_bool(T /*val*/) + { + static_assert(!wistd::is_same::value, "Wrong Type: bool/BOOL/BOOLEAN/boolean expected"); + return false; + } + + template <> + _Post_satisfies_(return == val) + __forceinline constexpr bool verify_bool(bool val) + { + return val; + } + + template <> + _Post_satisfies_(return == (val != 0)) + __forceinline constexpr bool verify_bool(int val) + { + return (val != 0); + } + + template <> + _Post_satisfies_(return == (val != 0)) + __forceinline constexpr bool verify_bool(unsigned char val) + { + return (val != 0); + } + + /** Verify that `val` is a Win32 BOOL value. + Other types (including other logical bool expressions) will generate an intentional compilation error. Note that this will + accept any `int` value as long as that is the underlying typedef behind `BOOL`. + @param val The Win32 BOOL returning expression + @return A Win32 BOOL representing the evaluation of `val`. */ + template + _Post_satisfies_(return == val) + __forceinline constexpr int verify_BOOL(T val) + { + // Note: Written in terms of 'int' as BOOL is actually: typedef int BOOL; + static_assert((wistd::is_same::value), "Wrong Type: BOOL expected"); + return val; + } + + /** Verify that `hr` is an HRESULT value. + Other types will generate an intentional compilation error. Note that this will accept any `long` value as that is the + underlying typedef behind HRESULT. + //! + Note that occasionally you might run into an HRESULT which is directly defined with a #define, such as: + ~~~~ + #define UIA_E_NOTSUPPORTED 0x80040204 + ~~~~ + Though this looks like an `HRESULT`, this is actually an `unsigned long` (the hex specification forces this). When + these are encountered and they are NOT in the public SDK (have not yet shipped to the public), then you should change + their definition to match the manner in which `HRESULT` constants are defined in winerror.h: + ~~~~ + #define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001L) + ~~~~ + When these are encountered in the public SDK, their type should not be changed and you should use a static_cast + to use this value in a macro that utilizes `verify_hresult`, for example: + ~~~~ + RETURN_HR_IF(static_cast(UIA_E_NOTSUPPORTED), (patternId != UIA_DragPatternId)); + ~~~~ + @param hr The HRESULT returning expression + @return An HRESULT representing the evaluation of `val`. */ + template + _Post_satisfies_(return == hr) + inline constexpr long verify_hresult(T hr) + { + // Note: Written in terms of 'long' as HRESULT is actually: typedef _Return_type_success_(return >= 0) long HRESULT + static_assert(wistd::is_same::value, "Wrong Type: HRESULT expected"); + return hr; + } + + /** Verify that `status` is an NTSTATUS value. + Other types will generate an intentional compilation error. Note that this will accept any `long` value as that is the + underlying typedef behind NTSTATUS. + //! + Note that occasionally you might run into an NTSTATUS which is directly defined with a #define, such as: + ~~~~ + #define STATUS_NOT_SUPPORTED 0x1 + ~~~~ + Though this looks like an `NTSTATUS`, this is actually an `unsigned long` (the hex specification forces this). When + these are encountered and they are NOT in the public SDK (have not yet shipped to the public), then you should change + their definition to match the manner in which `NTSTATUS` constants are defined in ntstatus.h: + ~~~~ + #define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BBL) + ~~~~ + When these are encountered in the public SDK, their type should not be changed and you should use a static_cast + to use this value in a macro that utilizes `verify_ntstatus`, for example: + ~~~~ + NT_RETURN_IF_FALSE(static_cast(STATUS_NOT_SUPPORTED), (dispatch->Version == HKE_V1_0)); + ~~~~ + @param status The NTSTATUS returning expression + @return An NTSTATUS representing the evaluation of `val`. */ + template + _Post_satisfies_(return == status) + inline long verify_ntstatus(T status) + { + // Note: Written in terms of 'long' as NTSTATUS is actually: typedef _Return_type_success_(return >= 0) long NTSTATUS + static_assert(wistd::is_same::value, "Wrong Type: NTSTATUS expected"); + return status; + } + + /** Verify that `error` is a Win32 error code. + Other types will generate an intentional compilation error. Note that this will accept any `long` value as that is + the underlying type used for WIN32 error codes, as well as any `DWORD` (`unsigned long`) value since this is the type + commonly used when manipulating Win32 error codes. + @param error The Win32 error code returning expression + @return An Win32 error code representing the evaluation of `error`. */ + template + _Post_satisfies_(return == error) + inline T verify_win32(T error) + { + // Note: Win32 error code are defined as 'long' (#define ERROR_SUCCESS 0L), but are more frequently used as DWORD (unsigned long). + // This accept both types. + static_assert(wistd::is_same::value || wistd::is_same::value, "Wrong Type: Win32 error code (long / unsigned long) expected"); + return error; + } + /// @} // end type validation routines + + /// @cond + // Implementation details for macros and helper functions... do not use directly. + namespace details + { + // Use size-specific casts to avoid sign extending numbers -- avoid warning C4310: cast truncates constant value + #define __WI_MAKE_UNSIGNED(val) \ + (__pragma(warning(push)) __pragma(warning(disable: 4310 4309)) (sizeof(val) == 1 ? static_cast(val) : \ + sizeof(val) == 2 ? static_cast(val) : \ + sizeof(val) == 4 ? static_cast(val) : \ + static_cast(val)) __pragma(warning(pop))) + #define __WI_IS_UNSIGNED_SINGLE_FLAG_SET(val) ((val) && !((val) & ((val) - 1))) + #define __WI_IS_SINGLE_FLAG_SET(val) __WI_IS_UNSIGNED_SINGLE_FLAG_SET(__WI_MAKE_UNSIGNED(val)) + + template + __forceinline constexpr bool AreAllFlagsSetHelper(TVal val, TFlags flags) + { + return ((val & flags) == static_cast(flags)); + } + + template + __forceinline constexpr bool IsSingleFlagSetHelper(TVal val) + { + return __WI_IS_SINGLE_FLAG_SET(val); + } + + template + __forceinline constexpr bool IsClearOrSingleFlagSetHelper(TVal val) + { + return ((val == static_cast>(0)) || IsSingleFlagSetHelper(val)); + } + + template + __forceinline constexpr void UpdateFlagsInMaskHelper(_Inout_ TVal& val, TMask mask, TFlags flags) + { + val = static_cast>((val & ~mask) | (flags & mask)); + } + + template + struct variable_size; + + template <> + struct variable_size<1> + { + using type = unsigned char; + }; + + template <> + struct variable_size<2> + { + using type = unsigned short; + }; + + template <> + struct variable_size<4> + { + using type = unsigned long; + }; + + template <> + struct variable_size<8> + { + using type = unsigned long long; + }; + + template + struct variable_size_mapping + { + using type = typename variable_size::type; + }; + } // details + /// @endcond + + /** Defines the unsigned type of the same width (1, 2, 4, or 8 bytes) as the given type. + This allows code to generically convert any enum class to it's corresponding underlying type. */ + template + using integral_from_enum = typename details::variable_size_mapping::type; + + //! Declares a name that intentionally hides a name from an outer scope. + //! Use this to prevent accidental use of a parameter or lambda captured variable. + using hide_name = void(struct hidden_name); +} // wil + +#pragma warning(pop) + +#endif // __cplusplus +#endif // __WIL_COMMON_INCLUDED diff --git a/libraries/wil/coroutine.h b/libraries/wil/coroutine.h new file mode 100644 index 0000000..c115983 --- /dev/null +++ b/libraries/wil/coroutine.h @@ -0,0 +1,810 @@ +#ifndef __WIL_COROUTINE_INCLUDED +#define __WIL_COROUTINE_INCLUDED + + /* + * A wil::task / com_task is a coroutine with the following characteristics: + * + * - T must be a copyable object, movable object, reference, or void. + * - The coroutine may be awaited at most once. The second await will crash. + * - The coroutine may be abandoned (allowed to destruct without co_await), + * in which case unobserved exceptions are fatal. + * - By default, wil::task resumes on an arbitrary thread. + * - By default, wil::com_task resumes in the same COM apartment. + * - task.resume_any_thread() allows resumption on any thread. + * - task.resume_same_apartment() forces resumption in the same COM apartment. + * + * The wil::task and wil::com_task are intended to supplement PPL and C++/WinRT, + * not to replace them. It provides coroutine implementations for scenarios that PPL + * and C++/WinRT do not support, but it does not support everything that PPL and + * C++/WinRT do. + * + * The implementation is optimized on the assumption that the coroutine is + * awaited only once, and that the coroutine is discarded after completion. + * To ensure proper usage, the task object is move-only, and + * co_await takes ownership of the task. See further discussion below. + * + * Comparison with PPL and C++/WinRT: + * + * | | PPL | C++/WinRT | wil::*task | + * |-----------------------------------------------------|-----------|-----------|---------------| + * | T can be non-constructible | No | Yes | Yes | + * | T can be void | Yes | Yes | Yes | + * | T can be reference | No | No | Yes | + * | T can be WinRT object | Yes | Yes | Yes | + * | T can be non-WinRT object | Yes | No | Yes | + * | T can be move-only | No | No | Yes | + * | Coroutine can be cancelled | Yes | Yes | No | + * | Coroutine can throw arbitrary exceptions | Yes | No | Yes | + * | Can co_await more than once | Yes | No | No | + * | Can have multiple clients waiting for completion | Yes | No | No | + * | co_await resumes in same COM context | Sometimes | Yes | You choose [1]| + * | Can force co_await to resume in same context | Yes | N/A | Yes [1] | + * | Can force co_await to resume in any thread | Yes | No | Yes | + * | Can change coroutine's resumption model | No | No | Yes | + * | Can wait synchronously | Yes | Yes | Yes [2] | + * | Can be consumed by non-C++ languages | No | Yes | No | + * | Implementation is small and efficient | No | Yes | Yes | + * | Can abandon coroutine (fail to co_await) | Yes | Yes | Yes | + * | Exception in abandoned coroutine | Crash | Ignored | Crash | + * | Coroutine starts automatically | Yes | Yes | Yes | + * | Coroutine starts synchronously | No | Yes | Yes | + * | Integrates with C++/WinRT coroutine callouts | No | Yes | No | + * + * [1] Resumption in the same COM apartment requires that you include COM headers. + * [2] Synchronous waiting requires that you include (usually via ). + * + * You can include the COM headers and/or synchapi.h headers, and then + * re-include this header file to activate the features dependent upon + * those headers. + * + * Examples: + * + * Implement a coroutine that returns a move-only non-WinRT type + * and which resumes on an arbitrary thread. + * + * wil::task GetNameAsync() + * { + * co_await resume_background(); // do work on BG thread + * wil::unique_cotaskmem_string name; + * THROW_IF_FAILED(GetNameSlow(&name)); + * co_return name; // awaiter will resume on arbitrary thread + * } + * + * Consumers: + * + * winrt::IAsyncAction UpdateNameAsync() + * { + * // wil::task resumes on an arbitrary thread. + * auto name = co_await GetNameAsync(); + * // could be on any thread now + * co_await SendNameAsync(name.get()); + * } + * + * winrt::IAsyncAction UpdateNameAsync() + * { + * // override default behavior of wil::task and + * // force it to resume in the same COM apartment. + * auto name = co_await GetNameAsync().resume_same_apartment(); + * // so we are still on the UI thread + * NameElement().Text(winrt::hstring(name.get())); + * } + * + * Conversely, a coroutine that returns a + * wil::com_task defaults to resuming in the same + * COM apartment, but you can allow it to resume on any thread + * by doing co_await GetNameAsync().resume_any_thread(). + * + * There is no harm in doing resume_same_apartment() / resume_any_thread() for a + * task that already defaults to resuming in that manner. In fact, awaiting the + * task directly is just a shorthand for awaiting the corresponding + * resume_whatever() method. + * + * Alternatively, you can just convert between wil::task and wil::com_task + * to change the default resumption context. + * + * co_await wil::com_task(GetNameAsync()); // now defaults to resume_same_apartment(); + * + * You can store the task in a variable, but since it is a move-only + * object, you will have to use std::move in order to transfer ownership out of + * an lvalue. + * + * winrt::IAsyncAction SomethingAsync() + * { + * wil::com_task task; + * switch (source) + * { + * // Some of these might return wil::task, + * // but assigning to a wil::com_task will make + * // the task resume in the same COM apartment. + * case widget: task = GetValueFromWidgetAsync(); break; + * case gadget: task = GetValueFromGadgetAsync(); break; + * case doodad: task = GetValueFromDoodadAsync(); break; + * default: FAIL_FAST(); // unknown source + * } + * auto value = co_await std::move(task); // **** need std::move + * DoSomethingWith(value); + * } + * + * You can wait synchronously by calling get(). The usual caveats + * about synchronous waits on STA threads apply. + * + * auto value = GetValueFromWidgetAsync().get(); + * + * auto task = GetValueFromWidgetAsync(); + * auto value = std::move(task).get(); // **** need std::move + */ + +// Detect which version of the coroutine standard we have. +#if defined(_RESUMABLE_FUNCTIONS_SUPPORTED) +#include +#define __WI_COROUTINE_NAMESPACE ::std::experimental +#elif defined(__cpp_lib_coroutine) +#include +#define __WI_COROUTINE_NAMESPACE ::std +#else +#error You must compile with C++20 coroutine support to use coroutine.h. +#endif +#include +#include +#include +#include +#include + +namespace wil +{ + // There are three general categories of T that you can + // use with a task. We give them these names: + // + // T = void ("void category") + // T = some kind of reference ("reference category") + // T = non-void non-reference ("object category") + // + // Take care that the implementation supports all three categories. + // + // There is a sub-category of object category for move-only types. + // We designed our task to be co_awaitable only once, so that + // it can contain a move-only type. Any transfer of T as an + // object category must be done as an rvalue reference. + template + struct task; + + template + struct com_task; +} + +namespace wil::details::coro +{ + template + struct task_promise; + + // Unions may not contain references, C++/CX types, or void. + // To work around that, we put everything inside a result_wrapper + // struct, and put the struct in the union. For void, + // we create a special empty structure. + // + // get_value returns rvalue reference to T for object + // category, or just T itself for void and reference + // category. + // + // We take advantage of the reference collapsing rules + // so that T&& = T if T is reference category. + + template + struct result_wrapper + { + T value; + T get_value() { return wistd::forward(value); } + }; + + template<> + struct result_wrapper + { + void get_value() { } + }; + + + // The result_holder is basically a + // std::variant + // but with these extra quirks: + // * The only valid transition is monotype -> something-else. + // Consequently, it does not have valueless_by_exception. + + template + struct result_holder + { + // The content of the result_holder + // depends on the result_status: + // + // empty: No active member. + // value: Active member is wrap. + // error: Active member is error. + enum class result_status { empty, value, error }; + + result_status status{ result_status::empty }; + union variant + { + variant() {} + ~variant() {} + result_wrapper wrap; + std::exception_ptr error; + } result; + + // emplace_value will be called with + // + // * no parameters (void category) + // * The reference type T (reference category) + // * Some kind of reference to T (object category) + // + // Set the status after constructing the object. + // That way, if object construction throws an exception, + // the holder remains empty. + template + void emplace_value(Args&&... args) + { + WI_ASSERT(status == result_status::empty); + new (wistd::addressof(result.wrap)) result_wrapper{ wistd::forward(args)... }; + status = result_status::value; + } + + void unhandled_exception() noexcept + { + WI_ASSERT(status == result_status::empty); + new (wistd::addressof(result.error)) std::exception_ptr(std::current_exception()); + status = result_status::error; + } + + T get_value() + { + if (status == result_status::value) + { + return result.wrap.get_value(); + } + WI_ASSERT(status == result_status::error); + std::rethrow_exception(wistd::exchange(result.error, {})); + } + + result_holder() = default; + result_holder(result_holder const&) = delete; + void operator=(result_holder const&) = delete; + + ~result_holder() noexcept(false) + { + switch (status) + { + case result_status::value: + result.wrap.~result_wrapper(); + break; + case result_status::error: + // Rethrow unobserved exception. Delete this line to + // discard unobserved exceptions. + if (result.error) std::rethrow_exception(result.error); + result.error.~exception_ptr(); + } + } + }; + + // Most of the work is done in the promise_base, + // It is a CRTP-like base class for task_promise and + // task_promise because the language forbids + // a single promise from containing both return_value and + // return_void methods (even if one of them is deleted by SFINAE). + template + struct promise_base + { + // The coroutine state remains alive as long as the coroutine is + // still running (hasn't reached final_suspend) or the associated + // task has not yet abandoned the coroutine (either finished awaiting + // or destructed without awaiting). + // + // This saves an allocation, but does mean that the local + // frame of the coroutine will remain allocated (with the + // coroutine's imbound parameters still live) until all + // references are destroyed. To force the promise_base to be + // destroyed after co_await, we make the promise_base a + // move-only object and require co_await to be given an rvalue reference. + + // Special values for m_waiting. + static void* running_ptr() { return nullptr; } + static void* completed_ptr() { return reinterpret_cast(1); } + static void* abandoned_ptr() { return reinterpret_cast(2); } + + // The awaiting coroutine is resumed by calling the + // m_resumer with the m_waiting. If the resumer is null, + // then the m_waiting is assumed to be the address of a + // coroutine_handle<>, which is resumed synchronously. + // Externalizing the resumer allows unused awaiters to be + // removed by the linker and removes a hard dependency on COM. + // Using nullptr to represent the default resumer avoids a + // CFG check. + + void(__stdcall* m_resumer)(void*); + std::atomic m_waiting{ running_ptr() }; + result_holder m_holder; + + // Make it easier to access our CRTP derived class. + using Promise = task_promise; + auto as_promise() noexcept + { + return static_cast(this); + } + + // Make it easier to access the coroutine handle. + auto as_handle() noexcept + { + return __WI_COROUTINE_NAMESPACE::coroutine_handle::from_promise(*as_promise()); + } + + auto get_return_object() noexcept + { + // let the compiler construct the task / com_task from the promise. + return as_promise(); + } + + void destroy() + { + as_handle().destroy(); + } + + // The client lost interest in the coroutine, either because they are discarding + // the result without awaiting (risky!), or because they have finished awaiting. + // Discarding the result without awaiting is risky because any exception in the coroutine + // will be unobserved and result in a crash. If you want to disallow it, then + // raise an exception if waiting == running_ptr. + void abandon() + { + auto waiting = m_waiting.exchange(abandoned_ptr(), std::memory_order_acq_rel); + if (waiting != running_ptr()) destroy(); + } + + __WI_COROUTINE_NAMESPACE::suspend_never initial_suspend() noexcept + { + return {}; + } + + template + void emplace_value(Args&&... args) + { + m_holder.emplace_value(wistd::forward(args)...); + } + + void unhandled_exception() noexcept + { + m_holder.unhandled_exception(); + } + + void resume_waiting_coroutine(void* waiting) const + { + if (m_resumer) + { + m_resumer(waiting); + } + else + { + __WI_COROUTINE_NAMESPACE::coroutine_handle<>::from_address(waiting).resume(); + } + } + + auto final_suspend() noexcept + { + struct awaiter : __WI_COROUTINE_NAMESPACE::suspend_always + { + promise_base& self; + void await_suspend(__WI_COROUTINE_NAMESPACE::coroutine_handle<>) const noexcept + { + // Need acquire so we can read from m_resumer. + // Need release so that the results are published in the case that nobody + // is awaiting right now, so that the eventual awaiter (possibly on another thread) + // can read the results. + auto waiting = self.m_waiting.exchange(completed_ptr(), std::memory_order_acq_rel); + if (waiting == abandoned_ptr()) + { + self.destroy(); + } + else if (waiting != running_ptr()) + { + WI_ASSERT(waiting != completed_ptr()); + self.resume_waiting_coroutine(waiting); + } + }; + }; + return awaiter{ {}, *this }; + } + + // The remaining methods are used by the awaiters. + bool client_await_ready() + { + // Need acquire in case the coroutine has already completed, + // so we can read the results. This matches the release in + // the final_suspend's await_suspend. + auto waiting = m_waiting.load(std::memory_order_acquire); + WI_ASSERT((waiting == running_ptr()) || (waiting == completed_ptr())); + return waiting != running_ptr(); + } + + auto client_await_suspend(void* waiting, void(__stdcall* resumer)(void*)) + { + // "waiting" needs to be a pointer to an object. We reserve the first 16 + // pseudo-pointers as sentinels. + WI_ASSERT(reinterpret_cast(waiting) > 16); + + m_resumer = resumer; + + // Acquire to ensure that we can read the results of the return value, if the coroutine is completed. + // Release to ensure that our resumption state is published, if the coroutine is not completed. + auto previous = m_waiting.exchange(waiting, std::memory_order_acq_rel); + + // Suspend if the coroutine is still running. + // Otherwise, the coroutine is completed: Nobody will resume us, so we will have to resume ourselves. + WI_ASSERT((previous == running_ptr()) || (previous == completed_ptr())); + return previous == running_ptr(); + } + + T client_await_resume() + { + return m_holder.get_value(); + } + }; + + template + struct task_promise : promise_base + { + template + void return_value(U&& value) + { + this->emplace_value(wistd::forward(value)); + } + + template + wistd::enable_if_t, Dummy> + return_value(T const& value) + { + this->emplace_value(value); + } + }; + + template<> + struct task_promise : promise_base + { + void return_void() + { + this->emplace_value(); + } + }; + + template + struct promise_deleter + { + void operator()(promise_base* promise) const noexcept + { + promise->abandon(); + } + }; + + template + using promise_ptr = wistd::unique_ptr, promise_deleter>; + + template + struct agile_awaiter + { + agile_awaiter(promise_ptr&& initial) : promise(wistd::move(initial)) { } + + promise_ptr promise; + + bool await_ready() + { + return promise->client_await_ready(); + } + + auto await_suspend(__WI_COROUTINE_NAMESPACE::coroutine_handle<> handle) + { + // Use the default resumer. + return promise->client_await_suspend(handle.address(), nullptr); + } + + T await_resume() + { + return promise->client_await_resume(); + } + }; + + template + struct task_base + { + auto resume_any_thread() && noexcept + { + return agile_awaiter{ wistd::move(promise) }; + } + + // You must #include before to enable apartment-aware awaiting. + auto resume_same_apartment() && noexcept; + + // Compiler error message metaprogramming: Tell people that they + // need to use std::move() if they try to co_await an lvalue. + struct cannot_await_lvalue_use_std_move { void await_ready() {} }; + cannot_await_lvalue_use_std_move operator co_await() & = delete; + + // You must #include (usually via ) to enable synchronous waiting. + decltype(auto) get() &&; + + protected: + task_base(task_promise* initial = nullptr) noexcept : promise(initial) {} + + template + D& assign(D* self, task_base&& other) noexcept + { + static_cast(*this) = wistd::move(other); + return *self; + } + + private: + promise_ptr promise; + + static void __stdcall wake_by_address(void* completed); + }; +} + +namespace wil +{ + // Must write out both classes separately + // Cannot use deduction guides with alias template type prior to C++20. + template + struct task : details::coro::task_base + { + using base = details::coro::task_base; + // Constructing from task_promise* cannot be explicit because get_return_object relies on implicit conversion. + task(details::coro::task_promise* initial = nullptr) noexcept : base(initial) {} + explicit task(base&& other) noexcept : base(wistd::move(other)) {} + task& operator=(base&& other) noexcept + { + return base::assign(this, wistd::move(other)); + } + + using base::operator co_await; + + auto operator co_await() && noexcept + { + return wistd::move(*this).resume_any_thread(); + } + }; + + template + struct com_task : details::coro::task_base + { + using base = details::coro::task_base; + // Constructing from task_promise* cannot be explicit because get_return_object relies on implicit conversion. + com_task(details::coro::task_promise* initial = nullptr) noexcept : base(initial) {} + explicit com_task(base&& other) noexcept : base(wistd::move(other)) {} + com_task& operator=(base&& other) noexcept + { + return base::assign(this, wistd::move(other)); + } + + using base::operator co_await; + + auto operator co_await() && noexcept + { + // You must #include before to enable non-agile awaiting. + return wistd::move(*this).resume_same_apartment(); + } + }; + + template + task(com_task&&)->task; + template + com_task(task&&)->com_task; +} + +template +struct __WI_COROUTINE_NAMESPACE::coroutine_traits, Args...> +{ + using promise_type = wil::details::coro::task_promise; +}; + +template +struct __WI_COROUTINE_NAMESPACE::coroutine_traits, Args...> +{ + using promise_type = wil::details::coro::task_promise; +}; + +#endif // __WIL_COROUTINE_INCLUDED + +// Can re-include this header after including synchapi.h (usually via windows.h) to enable synchronous wait. +#if defined(_SYNCHAPI_H_) && !defined(__WIL_COROUTINE_SYNCHRONOUS_GET_INCLUDED) +#define __WIL_COROUTINE_SYNCHRONOUS_GET_INCLUDED + +namespace wil::details::coro +{ + template + decltype(auto) task_base::get() && + { + if (!promise->client_await_ready()) + { + bool completed = false; + if (promise->client_await_suspend(&completed, wake_by_address)) + { + bool pending = false; + while (!completed) + { + WaitOnAddress(&completed, &pending, sizeof(pending), INFINITE); + } + } + } + return std::exchange(promise, {})->client_await_resume(); + } + + template + void __stdcall task_base::wake_by_address(void* completed) + { + *reinterpret_cast(completed) = true; + WakeByAddressSingle(completed); + } +} +#endif // __WIL_COROUTINE_SYNCHRONOUS_GET_INCLUDED + +// Can re-include this header after including COM header files to enable non-agile tasks. +#if defined(_COMBASEAPI_H_) && defined(_THREADPOOLAPISET_H_) && !defined(__WIL_COROUTINE_NON_AGILE_INCLUDED) +#define __WIL_COROUTINE_NON_AGILE_INCLUDED +#include +#include + +namespace wil::details::coro +{ + struct apartment_info + { + APTTYPE aptType; + APTTYPEQUALIFIER aptTypeQualifier; + + void load() + { + if (FAILED(CoGetApartmentType(&aptType, &aptTypeQualifier))) + { + // If COM is not initialized, then act as if we are running + // on the implicit MTA. + aptType = APTTYPE_MTA; + aptTypeQualifier = APTTYPEQUALIFIER_IMPLICIT_MTA; + } + } + }; + + // apartment_resumer resumes a coroutine in a captured apartment. + struct apartment_resumer + { + static auto as_self(void* p) + { + return reinterpret_cast(p); + } + + static bool is_sta() + { + apartment_info info; + info.load(); + switch (info.aptType) + { + case APTTYPE_STA: + case APTTYPE_MAINSTA: + return true; + case APTTYPE_NA: + return info.aptTypeQualifier == APTTYPEQUALIFIER_NA_ON_STA || + info.aptTypeQualifier == APTTYPEQUALIFIER_NA_ON_MAINSTA; + default: + return false; + } + } + + static wil::com_ptr current_context() + { + wil::com_ptr context; + // This will fail if COM is not initialized. Treat as implicit MTA. + // Do not use IID_PPV_ARGS to avoid ambiguity between ::IUnknown and winrt::IUnknown. + CoGetObjectContext(__uuidof(IContextCallback), reinterpret_cast(&context)); + return context; + } + + __WI_COROUTINE_NAMESPACE::coroutine_handle<> waiter; + wil::com_ptr context{ nullptr }; + apartment_info info; + HRESULT resume_result = S_OK; + + void capture_context(__WI_COROUTINE_NAMESPACE::coroutine_handle<> handle) + { + waiter = handle; + info.load(); + context = current_context(); + if (context == nullptr) + { + __debugbreak(); + } + } + + static void __stdcall resume_in_context(void* parameter) + { + auto self = as_self(parameter); + if (self->context == nullptr || self->context == current_context()) + { + self->context = nullptr; // removes the context cleanup from the resume path + self->waiter(); + } + else if (is_sta()) + { + submit_threadpool_callback(resume_context, self); + } + else + { + self->resume_context_sync(); + } + } + + static void submit_threadpool_callback(PTP_SIMPLE_CALLBACK callback, void* context) + { + THROW_IF_WIN32_BOOL_FALSE(TrySubmitThreadpoolCallback(callback, context, nullptr)); + } + + static void CALLBACK resume_context(PTP_CALLBACK_INSTANCE /*instance*/, void* parameter) + { + as_self(parameter)->resume_context_sync(); + } + + void resume_context_sync() + { + ComCallData data{}; + data.pUserDefined = this; + // The call to resume_apartment_callback will destruct the context. + // Capture into a local so we don't destruct it while it's in use. + // This also removes the context cleanup from the resume path. + auto local_context = wistd::move(context); + auto result = local_context->ContextCallback(resume_apartment_callback, &data, IID_ICallbackWithNoReentrancyToApplicationSTA, 5, nullptr); + if (FAILED(result)) + { + // Unable to resume on the correct apartment. + // Resume on the wrong apartment, but tell the coroutine why. + resume_result = result; + waiter(); + } + } + + static HRESULT CALLBACK resume_apartment_callback(ComCallData* data) noexcept + { + as_self(data->pUserDefined)->waiter(); + return S_OK; + } + + void check() + { + THROW_IF_FAILED(resume_result); + } + }; + + // The COM awaiter captures the COM context when the co_await begins. + // When the co_await completes, it uses that COM context to resume execution. + // This follows the same algorithm employed by C++/WinRT, which has features like + // avoiding stack buildup and proper handling of the neutral apartment. + // It does, however, introduce fail-fast code paths if thread pool tasks cannot + // be submitted. (Those fail-fasts could be removed by preallocating the tasks, + // but that means paying an up-front cost for something that may never end up used, + // as well as introducing extra cleanup code in the fast-path.) + template + struct com_awaiter : agile_awaiter + { + com_awaiter(promise_ptr&& initial) : agile_awaiter(wistd::move(initial)) { } + apartment_resumer resumer; + + auto await_suspend(__WI_COROUTINE_NAMESPACE::coroutine_handle<> handle) + { + resumer.capture_context(handle); + return this->promise->client_await_suspend(wistd::addressof(resumer), apartment_resumer::resume_in_context); + } + + decltype(auto) await_resume() + { + resumer.check(); + return agile_awaiter::await_resume(); + } + }; + + template + auto task_base::resume_same_apartment() && noexcept + { + return com_awaiter{ wistd::move(promise) }; + } +} +#endif // __WIL_COROUTINE_NON_AGILE_INCLUDED diff --git a/libraries/wil/cppwinrt.h b/libraries/wil/cppwinrt.h new file mode 100644 index 0000000..c69a851 --- /dev/null +++ b/libraries/wil/cppwinrt.h @@ -0,0 +1,491 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_CPPWINRT_INCLUDED +#define __WIL_CPPWINRT_INCLUDED + +#include "common.h" +#include +#include +#include +#include + +// WIL and C++/WinRT use two different exception types for communicating HRESULT failures. Thus, both libraries need to +// understand how to translate these exception types into the correct HRESULT values at the ABI boundary. Prior to +// C++/WinRT "2.0" this was accomplished by injecting the WINRT_EXTERNAL_CATCH_CLAUSE macro - that WIL defines below - +// into its exception handler (winrt::to_hresult). Starting with C++/WinRT "2.0" this mechanism has shifted to a global +// function pointer - winrt_to_hresult_handler - that WIL sets automatically when this header is included and +// 'CPPWINRT_SUPPRESS_STATIC_INITIALIZERS' is not defined. + +/// @cond +namespace wil::details +{ + // Since the C++/WinRT version macro is a string... + // For example: "2.0.221104.6" + inline constexpr int version_from_string(const char* versionString) + { + int result = 0; + while ((*versionString >= '0') && (*versionString <= '9')) + { + result = result * 10 + (*versionString - '0'); + ++versionString; + } + + return result; + } + + inline constexpr int major_version_from_string(const char* versionString) + { + return version_from_string(versionString); + } + + inline constexpr int minor_version_from_string(const char* versionString) + { + int dotCount = 0; + while ((*versionString != '\0')) + { + if (*versionString == '.') + { + ++dotCount; + } + + ++versionString; + if (dotCount == 2) + { + return version_from_string(versionString); + } + } + + return 0; + } +} +/// @endcond + +#ifdef CPPWINRT_VERSION +// Prior to C++/WinRT "2.0" this header needed to be included before 'winrt/base.h' so that our definition of +// 'WINRT_EXTERNAL_CATCH_CLAUSE' would get picked up in the implementation of 'winrt::to_hresult'. This is no longer +// problematic, so only emit an error when using a version of C++/WinRT prior to 2.0 +static_assert(::wil::details::major_version_from_string(CPPWINRT_VERSION) >= 2, + "Please include wil/cppwinrt.h before including any C++/WinRT headers"); +#endif + +// NOTE: Will eventually be removed once C++/WinRT 2.0 use can be assumed +#ifdef WINRT_EXTERNAL_CATCH_CLAUSE +#define __WI_CONFLICTING_WINRT_EXTERNAL_CATCH_CLAUSE 1 +#else +#define WINRT_EXTERNAL_CATCH_CLAUSE \ + catch (const wil::ResultException& e) \ + { \ + return winrt::hresult_error(e.GetErrorCode(), winrt::to_hstring(e.what())).to_abi(); \ + } +#endif + +#include "result_macros.h" +#include + +#if __WI_CONFLICTING_WINRT_EXTERNAL_CATCH_CLAUSE +static_assert(::wil::details::major_version_from_string(CPPWINRT_VERSION) >= 2, + "C++/WinRT external catch clause already defined outside of WIL"); +#endif + +// In C++/WinRT 2.0 and beyond, this function pointer exists. In earlier versions it does not. It's much easier to avoid +// linker errors than it is to SFINAE on variable existence, so we declare the variable here, but are careful not to +// use it unless the version of C++/WinRT is high enough +extern std::int32_t(__stdcall* winrt_to_hresult_handler)(void*) noexcept; + +// The same is true with this function pointer as well, except that the version must be 2.X or higher. +extern void(__stdcall* winrt_throw_hresult_handler)(uint32_t, char const*, char const*, void*, winrt::hresult const) noexcept; + +/// @cond +namespace wil::details +{ + inline void MaybeGetExceptionString( + const winrt::hresult_error& exception, + _Out_writes_opt_(debugStringChars) PWSTR debugString, + _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars) + { + if (debugString) + { + StringCchPrintfW(debugString, debugStringChars, L"winrt::hresult_error: %ls", exception.message().c_str()); + } + } + + inline HRESULT __stdcall ResultFromCaughtException_CppWinRt( + _Inout_updates_opt_(debugStringChars) PWSTR debugString, + _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars, + _Inout_ bool* isNormalized) noexcept + { + if (g_pfnResultFromCaughtException) + { + try + { + throw; + } + catch (const ResultException& exception) + { + *isNormalized = true; + MaybeGetExceptionString(exception, debugString, debugStringChars); + return exception.GetErrorCode(); + } + catch (const winrt::hresult_error& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return exception.to_abi(); + } + catch (const std::bad_alloc& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return E_OUTOFMEMORY; + } + catch (const std::out_of_range& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return E_BOUNDS; + } + catch (const std::invalid_argument& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return E_INVALIDARG; + } + catch (...) + { + auto hr = RecognizeCaughtExceptionFromCallback(debugString, debugStringChars); + if (FAILED(hr)) + { + return hr; + } + } + } + else + { + try + { + throw; + } + catch (const ResultException& exception) + { + *isNormalized = true; + MaybeGetExceptionString(exception, debugString, debugStringChars); + return exception.GetErrorCode(); + } + catch (const winrt::hresult_error& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return exception.to_abi(); + } + catch (const std::bad_alloc& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return E_OUTOFMEMORY; + } + catch (const std::out_of_range& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return E_BOUNDS; + } + catch (const std::invalid_argument& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return E_INVALIDARG; + } + catch (const std::exception& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION); + } + catch (...) + { + // Fall through to returning 'S_OK' below + } + } + + // Tell the caller that we were unable to map the exception by succeeding... + return S_OK; + } +} +/// @endcond + +namespace wil +{ + inline std::int32_t __stdcall winrt_to_hresult(void* returnAddress) noexcept + { + // C++/WinRT only gives us the return address (caller), so pass along an empty 'DiagnosticsInfo' since we don't + // have accurate file/line/etc. information + return static_cast(details::ReportFailure_CaughtException(__R_DIAGNOSTICS_RA(DiagnosticsInfo{}, returnAddress))); + } + + inline void __stdcall winrt_throw_hresult(uint32_t lineNumber, char const* fileName, char const* functionName, void* returnAddress, winrt::hresult const result) noexcept + { + void* callerReturnAddress{nullptr}; PCSTR code{nullptr}; + wil::details::ReportFailure_Hr(__R_FN_CALL_FULL __R_COMMA result); + } + + inline void WilInitialize_CppWinRT() + { + details::g_pfnResultFromCaughtException_CppWinRt = details::ResultFromCaughtException_CppWinRt; + if constexpr (details::major_version_from_string(CPPWINRT_VERSION) >= 2) + { + WI_ASSERT(winrt_to_hresult_handler == nullptr); + winrt_to_hresult_handler = winrt_to_hresult; + + if constexpr (details::minor_version_from_string(CPPWINRT_VERSION) >= 210122) + { + WI_ASSERT(winrt_throw_hresult_handler == nullptr); + winrt_throw_hresult_handler = winrt_throw_hresult; + } + } + } + + /// @cond + namespace details + { +#ifndef CPPWINRT_SUPPRESS_STATIC_INITIALIZERS + WI_ODR_PRAGMA("CPPWINRT_SUPPRESS_STATIC_INITIALIZERS", "0") + WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_CppWinRT, [] + { + ::wil::WilInitialize_CppWinRT(); + return 1; + }); +#else + WI_ODR_PRAGMA("CPPWINRT_SUPPRESS_STATIC_INITIALIZERS", "1") +#endif + } + /// @endcond + + // Provides an overload of verify_hresult so that the WIL macros can recognize winrt::hresult as a valid "hresult" type. + inline long verify_hresult(winrt::hresult hr) noexcept + { + return hr; + } + + // Provides versions of get_abi and put_abi for genericity that directly use HSTRING for convenience. + template + auto get_abi(T const& object) noexcept + { + return winrt::get_abi(object); + } + + inline auto get_abi(winrt::hstring const& object) noexcept + { + return static_cast(winrt::get_abi(object)); + } + + inline auto str_raw_ptr(const winrt::hstring& str) noexcept + { + return str.c_str(); + } + + template + auto put_abi(T& object) noexcept + { + return winrt::put_abi(object); + } + + inline auto put_abi(winrt::hstring& object) noexcept + { + return reinterpret_cast(winrt::put_abi(object)); + } + + inline ::IUnknown* com_raw_ptr(const winrt::Windows::Foundation::IUnknown& ptr) noexcept + { + return static_cast<::IUnknown*>(winrt::get_abi(ptr)); + } + + // Needed to power wil::cx_object_from_abi that requires IInspectable + inline ::IInspectable* com_raw_ptr(const winrt::Windows::Foundation::IInspectable& ptr) noexcept + { + return static_cast<::IInspectable*>(winrt::get_abi(ptr)); + } + + // Taken from the docs.microsoft.com article + template + T convert_from_abi(::IUnknown* from) + { + T to{ nullptr }; // `T` is a projected type. + winrt::check_hresult(from->QueryInterface(winrt::guid_of(), winrt::put_abi(to))); + return to; + } + + // For obtaining an object from an interop method on the factory. Example: + // winrt::InputPane inputPane = wil::capture_interop(&IInputPaneInterop::GetForWindow, hwnd); + // If the method produces something different from the factory type: + // winrt::IAsyncAction action = wil::capture_interop(&IAccountsSettingsPaneInterop::ShowAddAccountForWindow, hwnd); + template + auto capture_interop(HRESULT(__stdcall Interface::* method)(InterfaceArgs...), Args&&... args) + { + auto interop = winrt::get_activation_factory(); + return winrt::capture(interop, method, std::forward(args)...); + } + + // For obtaining an object from an interop method on an instance. Example: + // winrt::UserActivitySession session = wil::capture_interop(activity, &IUserActivityInterop::CreateSessionForWindow, hwnd); + template + auto capture_interop(winrt::Windows::Foundation::IUnknown const& o, HRESULT(__stdcall Interface::* method)(InterfaceArgs...), Args&&... args) + { + return winrt::capture(o.as(), method, std::forward(args)...); + } + + /** Holds a reference to the host C++/WinRT module to prevent it from being unloaded. + Normally, this is done by being in an IAsyncOperation coroutine or by holding a strong + reference to a C++/WinRT object hosted in the same module, but if you have neither, + you will need to hold a reference explicitly. For the WRL equivalent, see wrl_module_reference. + + This can be used as a base, which permits EBO: + ~~~~ + struct NonWinrtObject : wil::winrt_module_reference + { + int value; + }; + + // DLL will not be unloaded as long as NonWinrtObject is still alive. + auto p = std::make_unique(); + ~~~~ + + Or it can be used as a member (with [[no_unique_address]] to avoid + occupying any memory): + ~~~~ + struct NonWinrtObject + { + int value; + + [[no_unique_address]] wil::winrt_module_reference module_ref; + }; + + // DLL will not be unloaded as long as NonWinrtObject is still alive. + auto p = std::make_unique(); + ~~~~ + + If using it to prevent the host DLL from unloading while a thread + or threadpool work item is still running, create the object before + starting the thread, and pass it to the thread. This avoids a race + condition where the host DLL could get unloaded before the thread starts. + ~~~~ + std::thread([module_ref = wil::winrt_module_reference()]() { do_background_work(); }); + + // Don't do this (race condition) + std::thread([]() { wil::winrt_module_reference module_ref; do_background_work(); }); // WRONG + ~~~~ + + Also useful in coroutines that neither capture DLL-hosted COM objects, nor are themselves + DLL-hosted COM objects. (If the coroutine returns IAsyncAction or captures a get_strong() + of its containing WinRT class, then the IAsyncAction or strong reference will itself keep + a strong reference to the host module.) + ~~~~ + winrt::fire_and_forget ContinueBackgroundWork() + { + // prevent DLL from unloading while we are running on a background thread. + // Do this before switching to the background thread. + wil::winrt_module_reference module_ref; + + co_await winrt::resume_background(); + do_background_work(); + }; + ~~~~ + */ + struct [[nodiscard]] winrt_module_reference + { + winrt_module_reference() + { + ++winrt::get_module_lock(); + } + + winrt_module_reference(winrt_module_reference const&) : winrt_module_reference() {} + + ~winrt_module_reference() + { + --winrt::get_module_lock(); + } + }; + + /** Implements a C++/WinRT class where some interfaces are conditionally supported. + ~~~~ + // Assume the existence of a class "Version2" which says whether + // the IMyThing2 interface should be supported. + struct Version2 { static bool IsEnabled(); }; + + // Declare implementation class which conditionally supports IMyThing2. + struct MyThing : wil::winrt_conditionally_implements, + Version2, IMyThing2> + { + // implementation goes here + }; + + ~~~~ + + If `Version2::IsEnabled()` returns `false`, then the `QueryInterface` + for `IMyThing2` will fail. + + Any interface not listed as conditional is assumed to be enabled unconditionally. + + You can add additional Version / Interface pairs to the template parameter list. + Interfaces may be conditionalized on at most one Version class. If you need a + complex conditional, create a new helper class. + + ~~~~ + // Helper class for testing two Versions. + struct Version2_or_greater { + static bool IsEnabled() { return Version2::IsEnabled() || Version3::IsEnabled(); } + }; + + // This implementation supports IMyThing2 if either Version2 or Version3 is enabled, + // and supports IMyThing3 only if Version3 is enabled. + struct MyThing : wil::winrt_conditionally_implements, + Version2_or_greater, IMyThing2, Version3, IMyThing3> + { + // implementation goes here + }; + ~~~~ + */ + template + struct winrt_conditionally_implements : Implements + { + using Implements::Implements; + + void* find_interface(winrt::guid const& iid) const noexcept override + { + static_assert(sizeof...(Rest) % 2 == 0, "Extra template parameters should come in groups of two"); + if (is_enabled<0, std::tuple>(iid)) + { + return Implements::find_interface(iid); + } + return nullptr; + } + + private: + template + static bool is_enabled(winrt::guid const& iid) + { + if constexpr (index >= std::tuple_size_v) + { + return true; + } + else + { + check_no_duplicates<1, index + 1, Tuple>(); + return (iid == winrt::guid_of>()) ? + std::tuple_element_t::IsEnabled() : + is_enabled(iid); + } + } + + template + static constexpr void check_no_duplicates() + { + if constexpr (index < upto) + { + static_assert(!std::is_same_v, std::tuple_element_t>, + "Duplicate interfaces found in winrt_conditionally_implements"); + check_no_duplicates(); + } + } + }; +} + +#endif // __WIL_CPPWINRT_INCLUDED diff --git a/libraries/wil/cppwinrt_authoring.h b/libraries/wil/cppwinrt_authoring.h new file mode 100644 index 0000000..bdb0b67 --- /dev/null +++ b/libraries/wil/cppwinrt_authoring.h @@ -0,0 +1,284 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* + +namespace wil +{ +#ifndef __WIL_CPPWINRT_AUTHORING_PROPERTIES_INCLUDED +#define __WIL_CPPWINRT_AUTHORING_PROPERTIES_INCLUDED + namespace details + { + template + struct single_threaded_property_storage + { + T m_value{}; + single_threaded_property_storage() = default; + single_threaded_property_storage(const T& value) : m_value(value) {} + operator T& () { return m_value; } + operator T const& () const { return m_value; } + template auto operator=(Q&& q) + { + m_value = wistd::forward(q); + return *this; + } + }; + } + + template + struct single_threaded_property : std::conditional_t || std::is_final_v, wil::details::single_threaded_property_storage, T> + { + single_threaded_property() = default; + template single_threaded_property(TArgs&&... value) : base_type(std::forward(value)...) {} + + using base_type = std::conditional_t || std::is_final_v, wil::details::single_threaded_property_storage, T>; + + T operator()() const + { + return *this; + } + + template auto& operator()(Q&& q) + { + *this = std::forward(q); + return *this; + } + + template auto& operator=(Q&& q) + { + static_cast(*this) = std::forward(q); + return *this; + } + }; + + template + struct single_threaded_rw_property : single_threaded_property + { + using base_type = single_threaded_property; + template single_threaded_rw_property(TArgs&&... value) : base_type(std::forward(value)...) {} + + using base_type::operator(); + + // needed in lieu of deducing-this + template auto& operator()(Q&& q) + { + return *this = std::forward(q); + } + + // needed in lieu of deducing-this + template auto& operator=(Q&& q) + { + base_type::operator=(std::forward(q)); + return *this; + } + }; + +#endif // __WIL_CPPWINRT_AUTHORING_PROPERTIES_INCLUDED + +#if !defined(__WIL_CPPWINRT_AUTHORING_INCLUDED_FOUNDATION) && defined(WINRT_Windows_Foundation_H) // WinRT / XAML helpers +#define __WIL_CPPWINRT_AUTHORING_INCLUDED_FOUNDATION + namespace details + { + template + struct event_base { + winrt::event_token operator()(const T& handler) + { + return m_handler.add(handler); + } + + auto operator()(const winrt::event_token& token) noexcept + { + return m_handler.remove(token); + } + + template + auto invoke(TArgs&&... args) + { + return m_handler(std::forward(args)...); + } + private: + winrt::event m_handler; + }; + } + + /** + * @brief A default event handler that maps to [Windows.Foundation.EventHandler](https://docs.microsoft.com/uwp/api/windows.foundation.eventhandler-1). + * @tparam T The event data type. + */ + template + struct untyped_event : wil::details::event_base> {}; + + /** + * @brief A default event handler that maps to [Windows.Foundation.TypedEventHandler](https://docs.microsoft.com/uwp/api/windows.foundation.typedeventhandler-2). + * @tparam T The event data type. + * @details Usage example: + * @code + * // In IDL, this corresponds to: + * // event Windows.Foundation.TypedEventHandler OkClicked; + * wil::typed_event OkClicked; + * @endcode + */ + template + struct typed_event : wil::details::event_base> {}; + +#endif // !defined(__WIL_CPPWINRT_AUTHORING_INCLUDED_FOUNDATION) && defined(WINRT_Windows_Foundation_H) + +#if !defined(__WIL_CPPWINRT_AUTHORING_INCLUDED_XAML_DATA) && (defined(WINRT_Microsoft_UI_Xaml_Data_H) || defined(WINRT_Windows_UI_Xaml_Data_H)) // INotifyPropertyChanged helpers +#define __WIL_CPPWINRT_AUTHORING_INCLUDED_XAML_DATA + namespace details + { +#ifdef WINRT_Microsoft_UI_Xaml_Data_H + using Xaml_Data_PropertyChangedEventHandler = winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventHandler; + using Xaml_Data_PropertyChangedEventArgs = winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventArgs; +#elif defined(WINRT_Windows_UI_Xaml_Data_H) + using Xaml_Data_PropertyChangedEventHandler = winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler; + using Xaml_Data_PropertyChangedEventArgs = winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs; +#endif + } + + /** + * @brief Helper base class to inherit from to have a simple implementation of [INotifyPropertyChanged](https://docs.microsoft.com/uwp/api/windows.ui.xaml.data.inotifypropertychanged). + * @tparam T CRTP type + * @details When you declare your class, make this class a base class and pass your class as a template parameter: + * @code + * struct MyPage : MyPageT, wil::notify_property_changed_base + * { + * wil::single_threaded_notifying_property MyInt; + * MyPage() : INIT_NOTIFYING_PROPERTY(MyInt, 42) { } + * // or + * WIL_NOTIFYING_PROPERTY(int, MyInt, 42); + * }; + * @endcode + */ + template + struct notify_property_changed_base + { + using Type = T; + auto PropertyChanged(Xaml_Data_PropertyChangedEventHandler const& value) + { + return m_propertyChanged.add(value); + } + + void PropertyChanged(winrt::event_token const& token) + { + m_propertyChanged.remove(token); + } + + Type& self() + { + return *static_cast(this); + } + + /** + * @brief Raises a property change notification event + * @param name The name of the property + * @return + * @details Usage example\n + * C++ + * @code + * void MyPage::DoSomething() + * { + * // modify MyInt + * // MyInt = ... + * + * // now send a notification to update the bound UI elements + * RaisePropertyChanged(L"MyInt"); + * } + * @endcode + */ + auto RaisePropertyChanged(std::wstring_view name) + { + return m_propertyChanged(self(), Xaml_Data_PropertyChangedEventArgs{ name }); + } + protected: + winrt::event m_propertyChanged; + }; + + /** + * @brief Implements a property type with notifications + * @tparam T the property type + * @details Use the #INIT_NOTIFY_PROPERTY macro to initialize this property in your class constructor. This will set up the right property name, and bind it to the `notify_property_changed_base` implementation. + */ + template + struct single_threaded_notifying_property : single_threaded_rw_property + { + using Type = T; + using base_type = single_threaded_rw_property; + using base_type::operator(); + + template auto& operator()(Q&& q) + { + return *this = std::forward(q); + } + + template auto& operator=(Q&& q) + { + if (q != this->operator()()) + { + static_cast(*this) = std::forward(q); + if (auto strong = m_sender.get(); (m_npc != nullptr) && (strong != nullptr)) + { + (*m_npc)(strong, Xaml_Data_PropertyChangedEventArgs{ m_name }); + } + } + return *this; + } + + template + single_threaded_notifying_property( + winrt::event* npc, + const winrt::Windows::Foundation::IInspectable& sender, + std::wstring_view name, + TArgs&&... args) : + single_threaded_rw_property(std::forward(args)...), + m_name(name), + m_npc(npc), + m_sender(sender) + {} + + single_threaded_notifying_property(const single_threaded_notifying_property&) = default; + single_threaded_notifying_property(single_threaded_notifying_property&&) = default; + std::wstring_view Name() const noexcept { return m_name; } + private: + std::wstring_view m_name; + winrt::event* m_npc; + winrt::weak_ref m_sender; + }; + + /** + * @def WIL_NOTIFYING_PROPERTY + * @brief use this to stamp out a property that calls RaisePropertyChanged upon changing its value. This is a zero-storage alternative to wil::single_threaded_notifying_property + * @details You can pass an initializer list for the initial property value in the variadic arguments to this macro. + */ +#define WIL_NOTIFYING_PROPERTY(type, name, ...) \ + type m_##name{__VA_ARGS__}; \ + auto name() const noexcept { return m_##name; } \ + auto& name(type value) \ + { \ + if (m_##name != value) \ + { \ + m_##name = std::move(value); \ + RaisePropertyChanged(L"" #name); \ + } \ + return *this; \ + } \ + + /** + * @def INIT_NOTIFYING_PROPERTY + * @brief use this to initialize a wil::single_threaded_notifying_property in your class constructor. + */ +#define INIT_NOTIFYING_PROPERTY(NAME, VALUE) \ + NAME(&m_propertyChanged, *this, L"" #NAME, VALUE) + +#endif // !defined(__WIL_CPPWINRT_AUTHORING_INCLUDED_XAML_DATA) && (defined(WINRT_Microsoft_UI_Xaml_Data_H) || defined(WINRT_Windows_UI_Xaml_Data_H)) +} // namespace wil diff --git a/libraries/wil/cppwinrt_helpers.h b/libraries/wil/cppwinrt_helpers.h new file mode 100644 index 0000000..0e2c960 --- /dev/null +++ b/libraries/wil/cppwinrt_helpers.h @@ -0,0 +1,352 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* + +#ifndef __WIL_CPPWINRT_HELPERS_DEFINED +#define __WIL_CPPWINRT_HELPERS_DEFINED + +/// @cond +namespace wil::details +{ + struct dispatcher_RunAsync + { + template + static void Schedule(Dispatcher const& dispatcher, Args&&... args) + { + dispatcher.RunAsync(std::forward(args)...); + } + }; + + struct dispatcher_TryEnqueue + { + template + static void Schedule(Dispatcher const& dispatcher, Args&&... args) + { + dispatcher.TryEnqueue(std::forward(args)...); + } + }; + + template struct dispatcher_traits; +} + +#if defined(_RESUMABLE_FUNCTIONS_SUPPORTED) +#include +namespace wil::details +{ + template using coroutine_handle = std::experimental::coroutine_handle; +} +#elif defined(__cpp_lib_coroutine) && (__cpp_lib_coroutine >= 201902L) +#include +namespace wil::details +{ + template using coroutine_handle = std::coroutine_handle; +} +#endif +/// @endcond + +#if defined(_RESUMABLE_FUNCTIONS_SUPPORTED) || (defined(__cpp_lib_coroutine) && (__cpp_lib_coroutine >= 201902L)) +/// @cond +namespace wil::details +{ + struct dispatched_handler_state + { + details::coroutine_handle<> handle{}; + bool orphaned = false; + }; + + struct dispatcher_handler + { + dispatcher_handler(dispatched_handler_state* state) : m_state(state) { } + dispatcher_handler(dispatcher_handler&& other) noexcept : m_state(std::exchange(other.m_state, {})) {} + + ~dispatcher_handler() + { + if (m_state && m_state->handle) + { + m_state->orphaned = true; + Complete(); + } + } + void operator()() + { + Complete(); + } + + void Complete() + { + auto state = std::exchange(m_state, nullptr); + std::exchange(state->handle, {}).resume(); + } + + dispatched_handler_state* m_state; + }; +} +/// @endcond + +namespace wil +{ + //! Resumes coroutine execution on the thread associated with the dispatcher, or throws + //! an exception (from an arbitrary thread) if unable. Supported dispatchers are + //! Windows.System.DispatcherQueue, Microsoft.System.DispatcherQueue, + //! Microsoft.UI.Dispatching.DispatcherQueue, and Windows.UI.Core.CoreDispatcher, + //! but you must include the corresponding header before including + //! wil\cppwinrt_helpers.h. It is okay to include wil\cppwinrt_helpers.h multiple times: + //! support will be enabled for any winrt/Namespace.h headers that were included since + //! the previous inclusion of wil\cppwinrt_headers.h. + template + [[nodiscard]] auto resume_foreground(Dispatcher const& dispatcher, + typename details::dispatcher_traits::Priority priority = details::dispatcher_traits::Priority::Normal) + { + using Traits = details::dispatcher_traits; + using Priority = typename Traits::Priority; + using Handler = typename Traits::Handler; + + struct awaitable + { + awaitable(Dispatcher const& dispatcher, Priority priority) noexcept : + m_dispatcher(dispatcher), + m_priority(priority) + { + } + bool await_ready() const noexcept { return false; } + + void await_suspend(details::coroutine_handle<> handle) + { + m_state.handle = handle; + Handler handler{ details::dispatcher_handler(&m_state) }; + try + { + // The return value of Schedule is not reliable. Use the dispatcher_handler destructor + // to detect whether the work item failed to run. + Traits::Scheduler::Schedule(m_dispatcher, m_priority, handler); + } + catch (...) + { + m_state.handle = nullptr; // the exception will resume the coroutine, so the handler shouldn't do it + throw; + } + } + + void await_resume() const + { + if (m_state.orphaned) + { + throw winrt::hresult_error(static_cast(0x800701ab)); // HRESULT_FROM_WIN32(ERROR_NO_TASK_QUEUE) + } + } + + private: + Dispatcher const& m_dispatcher; + Priority const m_priority; + details::dispatched_handler_state m_state; + }; + return awaitable{ dispatcher, priority }; + } +} +#endif // Coroutines are supported + +#endif // __WIL_CPPWINRT_HELPERS_DEFINED + +/// @cond +#if defined(WINRT_Windows_UI_Core_H) && !defined(__WIL_CPPWINRT_WINDOWS_UI_CORE_HELPERS) +#define __WIL_CPPWINRT_WINDOWS_UI_CORE_HELPERS +namespace wil::details +{ + template<> + struct dispatcher_traits + { + using Priority = winrt::Windows::UI::Core::CoreDispatcherPriority; + using Handler = winrt::Windows::UI::Core::DispatchedHandler; + using Scheduler = dispatcher_RunAsync; + }; +} +#endif // __WIL_CPPWINRT_WINDOWS_UI_CORE_HELPERS + +#if defined(WINRT_Windows_System_H) && !defined(__WIL_CPPWINRT_WINDOWS_SYSTEM_HELPERS) +#define __WIL_CPPWINRT_WINDOWS_SYSTEM_HELPERS +namespace wil::details +{ + template<> + struct dispatcher_traits + { + using Priority = winrt::Windows::System::DispatcherQueuePriority; + using Handler = winrt::Windows::System::DispatcherQueueHandler; + using Scheduler = dispatcher_TryEnqueue; + }; +} +#endif // __WIL_CPPWINRT_WINDOWS_SYSTEM_HELPERS + +#if defined(WINRT_Microsoft_System_H) && !defined(__WIL_CPPWINRT_MICROSOFT_SYSTEM_HELPERS) +#define __WIL_CPPWINRT_MICROSOFT_SYSTEM_HELPERS +namespace wil::details +{ + template<> + struct dispatcher_traits + { + using Priority = winrt::Microsoft::System::DispatcherQueuePriority; + using Handler = winrt::Microsoft::System::DispatcherQueueHandler; + using Scheduler = dispatcher_TryEnqueue; + }; +} +#endif // __WIL_CPPWINRT_MICROSOFT_SYSTEM_HELPERS + +#if defined(WINRT_Microsoft_UI_Dispatching_H) && !defined(__WIL_CPPWINRT_MICROSOFT_UI_DISPATCHING_HELPERS) +#define __WIL_CPPWINRT_MICROSOFT_UI_DISPATCHING_HELPERS +namespace wil::details +{ + template<> + struct dispatcher_traits + { + using Priority = winrt::Microsoft::UI::Dispatching::DispatcherQueuePriority; + using Handler = winrt::Microsoft::UI::Dispatching::DispatcherQueueHandler; + using Scheduler = dispatcher_TryEnqueue; + }; +} +#endif // __WIL_CPPWINRT_MICROSOFT_UI_DISPATCHING_HELPERS +/// @endcond + +#if defined(WINRT_Windows_Foundation_Collections_H) && !defined(__WIL_CPPWINRT_WINDOWS_FOUNDATION_COLLECTION_HELPERS) +#define __WIL_CPPWINRT_WINDOWS_FOUNDATION_COLLECTION_HELPERS +namespace wil +{ + /// @cond + namespace details + { + template struct is_winrt_vector_like { + private: + template ().GetMany(std::declval().Size(), + winrt::array_view().GetAt(0))>{}))> + static constexpr bool get_value(int) { return true; } + template static constexpr bool get_value(...) { return false; } + public: + static constexpr bool value = get_value(0); + }; + + template struct is_winrt_iterator_like { + private: + template ().GetMany(winrt::array_view().Current())>{}))> + static constexpr bool get_value(int) { return true; } + template static constexpr bool get_value(...) { return false; } + public: + static constexpr bool value = get_value(0); + }; + + template constexpr T empty() noexcept + { + if constexpr (std::is_base_of_v) + { + return nullptr; + } + else + { + return {}; + } + } + } + /// @endcond + + /** Converts C++ / WinRT vectors, iterators, and iterables to std::vector by requesting the + collection's data in bulk. This can be more efficient in terms of IPC cost than iteratively + processing the collection. + ~~~ + winrt::IVector collection = GetCollection(); + std::vector allData = wil::to_vector(collection); // read all data from collection + for (winrt::hstring const& item : allData) + { + // use item + } + ~~~ + Can be used for IVector, IVectorView, IIterable, IIterator, and any type or + interface that C++/WinRT projects those interfaces for (PropertySet, IMap, etc.) + Iterable-only types fetch content in units of 64. When used with an iterator, the returned + vector contains the iterator's current position and any others after it. + */ + template auto to_vector(TSrc const& src) + { + if constexpr (details::is_winrt_vector_like::value) + { + using T = decltype(src.GetAt(0)); + std::vector result; + if (auto expected = src.Size()) + { + result.resize(expected + 1, details::empty()); + auto actual = src.GetMany(0, result); + if (actual > expected) + { + throw winrt::hresult_changed_state(); + } + result.resize(actual, details::empty()); + } + return result; + } + else if constexpr (details::is_winrt_iterator_like::value) + { + using T = decltype(src.Current()); + std::vector result; + constexpr uint32_t chunkSize = 64; + while (true) + { + auto const lastSize = result.size(); + result.resize(lastSize + chunkSize, details::empty()); + auto fetched = src.GetMany({result.data() + lastSize, result.data() + lastSize + chunkSize }); + if (fetched < chunkSize) + { + result.resize(lastSize + fetched, details::empty()); + break; + } + } + return result; + } + else + { + return to_vector(src.First()); + } + } +} +#endif + +#if defined(WINRT_Windows_UI_H) && defined(_WINDOWS_UI_INTEROP_H_) && !defined(__WIL_CPPWINRT_WINDOWS_UI_INTEROP_HELPERS) +#define __WIL_CPPWINRT_WINDOWS_UI_INTEROP_HELPERS +#if !defined(____x_ABI_CWindows_CFoundation_CIClosable_FWD_DEFINED__) && !defined(MIDL_NS_PREFIX) +#pragma push_macro("ABI") +#undef ABI +#define ABI +#endif + +namespace wil +{ +#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_WIN10_CU) + //! The following methods require that you include both + //! before including wil/cppwinrt_helpers.h, and that NTDDI_VERSION + //! is at least NTDDI_WIN10_CU. It is okay to include wil\cppwinrt_helpers.h multiple times: + //! support will be enabled for any headers that were included since the previous inclusion + //! of wil\cppwinrt_headers.h. + inline winrt::Windows::UI::WindowId GetWindowIdFromWindow(HWND hwnd) + { + ABI::Windows::UI::WindowId abiWindowId; + winrt::check_hresult(::GetWindowIdFromWindow(hwnd, &abiWindowId)); + return winrt::Windows::UI::WindowId{ abiWindowId.Value }; + } + + inline HWND GetWindowFromWindowId(winrt::Windows::UI::WindowId windowId) + { + HWND hwnd; + winrt::check_hresult(::GetWindowFromWindowId({ windowId.Value }, &hwnd)); + return hwnd; + } +#endif /*defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_WIN10_CU)*/ +} + +#if !defined(____x_ABI_CWindows_CFoundation_CIClosable_FWD_DEFINED__) && !defined(MIDL_NS_PREFIX) +#pragma pop_macro("ABI") +#endif +#endif // __WIL_CPPWINRT_WINDOWS_UI_INTEROP_HELPERS diff --git a/libraries/wil/cppwinrt_wrl.h b/libraries/wil/cppwinrt_wrl.h new file mode 100644 index 0000000..afd6f8e --- /dev/null +++ b/libraries/wil/cppwinrt_wrl.h @@ -0,0 +1,74 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_CPPWINRT_WRL_INCLUDED +#define __WIL_CPPWINRT_WRL_INCLUDED + +#include "cppwinrt.h" +#include + +#include "result_macros.h" +#include + +// wil::wrl_factory_for_winrt_com_class provides interopability between a +// C++/WinRT class and the WRL Module system, allowing the winrt class to be +// CoCreatable. +// +// Usage: +// - In your cpp, add: +// CoCreatableCppWinRtClass(className) +// +// - In the dll.cpp (or equivalent) for the module containing your class, add: +// CoCreatableClassWrlCreatorMapInclude(className) +// +namespace wil +{ + namespace details + { + template + class module_count_wrapper : public TCppWinRTClass + { + public: + module_count_wrapper() + { + if (auto modulePtr = ::Microsoft::WRL::GetModuleBase()) + { + modulePtr->IncrementObjectCount(); + } + } + + virtual ~module_count_wrapper() + { + if (auto modulePtr = ::Microsoft::WRL::GetModuleBase()) + { + modulePtr->DecrementObjectCount(); + } + } + }; + } + + template + class wrl_factory_for_winrt_com_class : public ::Microsoft::WRL::ClassFactory<> + { + public: + IFACEMETHODIMP CreateInstance(_In_opt_ ::IUnknown* unknownOuter, REFIID riid, _COM_Outptr_ void **object) noexcept try + { + *object = nullptr; + RETURN_HR_IF(CLASS_E_NOAGGREGATION, unknownOuter != nullptr); + + return winrt::make>().as(riid, object); + } + CATCH_RETURN() + }; +} + +#define CoCreatableCppWinRtClass(className) CoCreatableClassWithFactory(className, ::wil::wrl_factory_for_winrt_com_class) + +#endif // __WIL_CPPWINRT_WRL_INCLUDED diff --git a/libraries/wil/filesystem.h b/libraries/wil/filesystem.h new file mode 100644 index 0000000..4434cbe --- /dev/null +++ b/libraries/wil/filesystem.h @@ -0,0 +1,1050 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_FILESYSTEM_INCLUDED +#define __WIL_FILESYSTEM_INCLUDED + +#ifdef _KERNEL_MODE +#error This header is not supported in kernel-mode. +#endif + +#include +#include // Needed for CoTaskMemFree() used in output of some helpers. +#include // LocalAlloc +#include +#include "result.h" +#include "win32_helpers.h" +#include "resource.h" + +namespace wil +{ + //! Determines if a path is an extended length path that can be used to access paths longer than MAX_PATH. + inline bool is_extended_length_path(_In_ PCWSTR path) + { + return wcsncmp(path, L"\\\\?\\", 4) == 0; + } + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN7) + //! Find the last segment of a path. Matches the behavior of shlwapi!PathFindFileNameW() + //! note, does not support streams being specified like PathFindFileNameW(), is that a bug or a feature? + inline PCWSTR find_last_path_segment(_In_ PCWSTR path) + { + auto const pathLength = wcslen(path); + // If there is a trailing slash ignore that in the search. + auto const limitedLength = ((pathLength > 0) && (path[pathLength - 1] == L'\\')) ? (pathLength - 1) : pathLength; + + PCWSTR result = nullptr; + auto const offset = FindStringOrdinal(FIND_FROMEND, path, static_cast(limitedLength), L"\\", 1, TRUE); + if (offset == -1) + { + result = path + pathLength; // null terminator + } + else + { + result = path + offset + 1; // just past the slash + } + return result; + } +#endif + + //! Determine if the file name is one of the special "." or ".." names. + inline bool path_is_dot_or_dotdot(_In_ PCWSTR fileName) + { + return ((fileName[0] == L'.') && + ((fileName[1] == L'\0') || ((fileName[1] == L'.') && (fileName[2] == L'\0')))); + } + + //! Returns the drive number, if it has one. Returns true if there is a drive number, false otherwise. Supports regular and extended length paths. + inline bool try_get_drive_letter_number(_In_ PCWSTR path, _Out_ int* driveNumber) + { + if (path[0] == L'\\' && path[1] == L'\\' && path[2] == L'?' && path[3] == L'\\') + { + path += 4; + } + if (path[0] && (path[1] == L':')) + { + if ((path[0] >= L'a') && (path[0] <= L'z')) + { + *driveNumber = path[0] - L'a'; + return true; + } + else if ((path[0] >= L'A') && (path[0] <= L'Z')) + { + *driveNumber = path[0] - L'A'; + return true; + } + } + *driveNumber = -1; + return false; + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN7) + + // PathCch.h APIs are only in desktop API for now. + + // Compute the substring in the input value that is the parent folder path. + // returns: + // true + parentPathLength - path has a parent starting at the beginning path and of parentPathLength length. + // false, no parent path, the input is a root path. + inline bool try_get_parent_path_range(_In_ PCWSTR path, _Out_ size_t* parentPathLength) + { + *parentPathLength = 0; + bool hasParent = false; + PCWSTR rootEnd = nullptr; + if (SUCCEEDED(PathCchSkipRoot(path, &rootEnd)) && (*rootEnd != L'\0')) + { + auto const lastSegment = find_last_path_segment(path); + *parentPathLength = lastSegment - path; + hasParent = (*parentPathLength != 0); + } + return hasParent; + } + + // Creates directories for the specified path, creating parent paths + // as needed. + inline HRESULT CreateDirectoryDeepNoThrow(PCWSTR path) WI_NOEXCEPT + { + if (::CreateDirectoryW(path, nullptr) == FALSE) + { + DWORD lastError = ::GetLastError(); + if (lastError == ERROR_PATH_NOT_FOUND) + { + size_t parentLength{}; + if (try_get_parent_path_range(path, &parentLength)) + { + wistd::unique_ptr parent(new (std::nothrow) wchar_t[parentLength + 1]); + RETURN_IF_NULL_ALLOC(parent.get()); + RETURN_IF_FAILED(StringCchCopyNW(parent.get(), parentLength + 1, path, parentLength)); + RETURN_IF_FAILED(CreateDirectoryDeepNoThrow(parent.get())); // recurs + } + if (::CreateDirectoryW(path, nullptr) == FALSE) + { + lastError = ::GetLastError(); + if (lastError != ERROR_ALREADY_EXISTS) + { + RETURN_WIN32(lastError); + } + } + } + else if (lastError != ERROR_ALREADY_EXISTS) + { + RETURN_WIN32(lastError); + } + } + return S_OK; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + inline void CreateDirectoryDeep(PCWSTR path) + { + THROW_IF_FAILED(CreateDirectoryDeepNoThrow(path)); + } +#endif // WIL_ENABLE_EXCEPTIONS + + //! A strongly typed version of the Win32 API GetFullPathNameW. + //! Return a path in an allocated buffer for handling long paths. + //! Optionally return the pointer to the file name part. + template + HRESULT GetFullPathNameW(PCWSTR file, string_type& path, _Outptr_opt_ PCWSTR* filePart = nullptr) + { + wil::assign_null_to_opt_param(filePart); + const auto hr = AdaptFixedSizeToAllocatedResult(path, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNull) -> HRESULT + { + // Note that GetFullPathNameW() is not limited to MAX_PATH + // but it does take a fixed size buffer. + *valueLengthNeededWithNull = ::GetFullPathNameW(file, static_cast(valueLength), value, nullptr); + RETURN_LAST_ERROR_IF(*valueLengthNeededWithNull == 0); + WI_ASSERT((*value != L'\0') == (*valueLengthNeededWithNull < valueLength)); + if (*valueLengthNeededWithNull < valueLength) + { + (*valueLengthNeededWithNull)++; // it fit, account for the null + } + return S_OK; + }); + if (SUCCEEDED(hr) && filePart) + { + *filePart = wil::find_last_path_segment(details::string_maker::get(path)); + } + return hr; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! A strongly typed version of the Win32 API of GetFullPathNameW. + //! Return a path in an allocated buffer for handling long paths. + //! Optionally return the pointer to the file name part. + template + string_type GetFullPathNameW(PCWSTR file, _Outptr_opt_ PCWSTR* filePart = nullptr) + { + string_type result{}; + THROW_IF_FAILED((GetFullPathNameW(file, result, filePart))); + return result; + } +#endif + + enum class RemoveDirectoryOptions + { + None = 0, + KeepRootDirectory = 0x1, + RemoveReadOnly = 0x2, + }; + DEFINE_ENUM_FLAG_OPERATORS(RemoveDirectoryOptions); + + namespace details + { + // Reparse points should not be traversed in most recursive walks of the file system, + // unless allowed through the appropriate reparse tag. + inline bool CanRecurseIntoDirectory(const FILE_ATTRIBUTE_TAG_INFO& info) + { + return (WI_IsFlagSet(info.FileAttributes, FILE_ATTRIBUTE_DIRECTORY) && + (WI_IsFlagClear(info.FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT) || + (IsReparseTagDirectory(info.ReparseTag) || (info.ReparseTag == IO_REPARSE_TAG_WCI)))); + } + } + + // Retrieve a handle to a directory only if it is safe to recurse into. + inline wil::unique_hfile TryCreateFileCanRecurseIntoDirectory(PCWSTR path, PWIN32_FIND_DATAW fileFindData, DWORD access = GENERIC_READ | /*DELETE*/ 0x00010000L, DWORD share = FILE_SHARE_READ) + { + wil::unique_hfile result(CreateFileW(path, access, share, + nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr)); + if (result) + { + FILE_ATTRIBUTE_TAG_INFO fati{}; + if (GetFileInformationByHandleEx(result.get(), FileAttributeTagInfo, &fati, sizeof(fati)) && + details::CanRecurseIntoDirectory(fati)) + { + if (fileFindData) + { + // Refresh the found file's data now that we have secured the directory from external manipulation. + fileFindData->dwFileAttributes = fati.FileAttributes; + fileFindData->dwReserved0 = fati.ReparseTag; + } + } + else + { + result.reset(); + } + } + + return result; + } + + // If inputPath is a non-normalized name be sure to pass an extended length form to ensure + // it can be addressed and deleted. + inline HRESULT RemoveDirectoryRecursiveNoThrow(PCWSTR inputPath, RemoveDirectoryOptions options = RemoveDirectoryOptions::None, HANDLE deleteHandle = INVALID_HANDLE_VALUE) WI_NOEXCEPT + { + wil::unique_hlocal_string path; + PATHCCH_OPTIONS combineOptions = PATHCCH_NONE; + + if (is_extended_length_path(inputPath)) + { + path = wil::make_hlocal_string_nothrow(inputPath); + RETURN_IF_NULL_ALLOC(path); + // PathAllocCombine will convert extended length paths to regular paths if shorter than + // MAX_PATH, avoid that behavior to provide access inputPath with non-normalized names. + combineOptions = PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH; + } + else + { + // For regular paths normalize here to get consistent results when searching and deleting. + RETURN_IF_FAILED(wil::GetFullPathNameW(inputPath, path)); + combineOptions = PATHCCH_ALLOW_LONG_PATHS; + } + + wil::unique_hlocal_string searchPath; + RETURN_IF_FAILED(::PathAllocCombine(path.get(), L"*", combineOptions, &searchPath)); + + WIN32_FIND_DATAW fd{}; + wil::unique_hfind findHandle(::FindFirstFileW(searchPath.get(), &fd)); + RETURN_LAST_ERROR_IF(!findHandle); + + for (;;) + { + // skip "." and ".." + if (!(WI_IsFlagSet(fd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) && path_is_dot_or_dotdot(fd.cFileName))) + { + // Need to form an extended length path to provide the ability to delete paths > MAX_PATH + // and files with non-normalized names (dots or spaces at the end). + wil::unique_hlocal_string pathToDelete; + RETURN_IF_FAILED(::PathAllocCombine(path.get(), fd.cFileName, + PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH | PATHCCH_DO_NOT_NORMALIZE_SEGMENTS, &pathToDelete)); + if (WI_IsFlagSet(fd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) + { + // Get a handle to the directory to delete, preventing it from being replaced to prevent writes which could be used + // to bypass permission checks, and verify that it is not a name surrogate (e.g. symlink, mount point, etc). + wil::unique_hfile recursivelyDeletableDirectoryHandle = TryCreateFileCanRecurseIntoDirectory(pathToDelete.get(), &fd); + if (recursivelyDeletableDirectoryHandle) + { + RemoveDirectoryOptions localOptions = options; + RETURN_IF_FAILED(RemoveDirectoryRecursiveNoThrow(pathToDelete.get(), WI_ClearFlag(localOptions, RemoveDirectoryOptions::KeepRootDirectory), recursivelyDeletableDirectoryHandle.get())); + } + else if (WI_IsFlagSet(fd.dwFileAttributes, FILE_ATTRIBUTE_REPARSE_POINT)) + { + // This is a directory reparse point that should not be recursed. Delete it without traversing into it. + RETURN_IF_WIN32_BOOL_FALSE(::RemoveDirectoryW(pathToDelete.get())); + } + else + { + // Failed to grab a handle to the file or to read its attributes. This is not safe to recurse. + RETURN_WIN32(::GetLastError()); + } + } + else + { + // Try a DeleteFile. Some errors may be recoverable. + if (!::DeleteFileW(pathToDelete.get())) + { + // Fail for anything other than ERROR_ACCESS_DENIED with option to RemoveReadOnly available + bool potentiallyFixableReadOnlyProblem = + WI_IsFlagSet(options, RemoveDirectoryOptions::RemoveReadOnly) && ::GetLastError() == ERROR_ACCESS_DENIED; + RETURN_LAST_ERROR_IF(!potentiallyFixableReadOnlyProblem); + + // Fail if the file does not have read-only set, likely just an ACL problem + DWORD fileAttr = ::GetFileAttributesW(pathToDelete.get()); + RETURN_LAST_ERROR_IF(!WI_IsFlagSet(fileAttr, FILE_ATTRIBUTE_READONLY)); + + // Remove read-only flag, setting to NORMAL if completely empty + WI_ClearFlag(fileAttr, FILE_ATTRIBUTE_READONLY); + if (fileAttr == 0) + { + fileAttr = FILE_ATTRIBUTE_NORMAL; + } + + // Set the new attributes and try to delete the file again, returning any failure + ::SetFileAttributesW(pathToDelete.get(), fileAttr); + RETURN_IF_WIN32_BOOL_FALSE(::DeleteFileW(pathToDelete.get())); + } + } + } + + if (!::FindNextFileW(findHandle.get(), &fd)) + { + auto const err = ::GetLastError(); + if (err == ERROR_NO_MORE_FILES) + { + break; + } + RETURN_WIN32(err); + } + } + + if (WI_IsFlagClear(options, RemoveDirectoryOptions::KeepRootDirectory)) + { + if (deleteHandle != INVALID_HANDLE_VALUE) + { +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) + // DeleteFile and RemoveDirectory use POSIX delete, falling back to non-POSIX on most errors. Do the same here. + FILE_DISPOSITION_INFO_EX fileInfoEx{}; + fileInfoEx.Flags = FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS; + if (!SetFileInformationByHandle(deleteHandle, FileDispositionInfoEx, &fileInfoEx, sizeof(fileInfoEx))) + { + auto const err = ::GetLastError(); + // The real error we're looking for is STATUS_CANNOT_DELETE, but that's mapped to ERROR_ACCESS_DENIED. + if (err != ERROR_ACCESS_DENIED) + { +#endif + FILE_DISPOSITION_INFO fileInfo{}; + fileInfo.DeleteFile = TRUE; + RETURN_IF_WIN32_BOOL_FALSE(SetFileInformationByHandle(deleteHandle, FileDispositionInfo, &fileInfo, sizeof(fileInfo))); +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) + } + else + { + RETURN_WIN32(err); + } + } +#endif + } + else + { + RETURN_IF_WIN32_BOOL_FALSE(::RemoveDirectoryW(path.get())); + } + } + return S_OK; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + inline void RemoveDirectoryRecursive(PCWSTR path, RemoveDirectoryOptions options = RemoveDirectoryOptions::None) + { + THROW_IF_FAILED(RemoveDirectoryRecursiveNoThrow(path, options)); + } +#endif // WIL_ENABLE_EXCEPTIONS + + // Range based for that supports Win32 structures that use NextEntryOffset as the basis of traversing + // a result buffer that contains data. This is used in the following FileIO calls: + // FileStreamInfo, FILE_STREAM_INFO + // FileIdBothDirectoryInfo, FILE_ID_BOTH_DIR_INFO + // FileFullDirectoryInfo, FILE_FULL_DIR_INFO + // FileIdExtdDirectoryInfo, FILE_ID_EXTD_DIR_INFO + // ReadDirectoryChangesW, FILE_NOTIFY_INFORMATION + + template + struct next_entry_offset_iterator + { + // Fulfill std::iterator_traits requirements + using difference_type = ptrdiff_t; + using value_type = T; + using pointer = const T*; + using reference = const T&; +#ifdef _XUTILITY_ + using iterator_category = ::std::forward_iterator_tag; +#endif + + next_entry_offset_iterator(T *iterable = __nullptr) : current_(iterable) {} + + // range based for requires operator!=, operator++ and operator* to do its work + // on the type returned from begin() and end(), provide those here. + WI_NODISCARD bool operator!=(const next_entry_offset_iterator& other) const { return current_ != other.current_; } + + next_entry_offset_iterator& operator++() + { + current_ = (current_->NextEntryOffset != 0) ? + reinterpret_cast(reinterpret_cast(current_) + current_->NextEntryOffset) : + __nullptr; + return *this; + } + + next_entry_offset_iterator operator++(int) + { + auto copy = *this; + ++(*this); + return copy; + } + + WI_NODISCARD reference operator*() const WI_NOEXCEPT { return *current_; } + WI_NODISCARD pointer operator->() const WI_NOEXCEPT { return current_; } + + next_entry_offset_iterator begin() { return *this; } + next_entry_offset_iterator end() { return next_entry_offset_iterator(); } + + T* current_; + }; + + template + next_entry_offset_iterator create_next_entry_offset_iterator(T* p) + { + return next_entry_offset_iterator(p); + } + +#pragma region Folder Watcher + // Example use in exception based code: + // auto watcher = wil::make_folder_watcher(folder.Path().c_str(), true, wil::allChangeEvents, []() + // { + // // respond + // }); + // + // Example use in result code based code: + // wil::unique_folder_watcher watcher; + // THROW_IF_FAILED(watcher.create(folder, true, wil::allChangeEvents, []() + // { + // // respond + // })); + + enum class FolderChangeEvent : DWORD + { + ChangesLost = 0, // requies special handling, reset state as events were lost + Added = FILE_ACTION_ADDED, + Removed = FILE_ACTION_REMOVED, + Modified = FILE_ACTION_MODIFIED, + RenameOldName = FILE_ACTION_RENAMED_OLD_NAME, + RenameNewName = FILE_ACTION_RENAMED_NEW_NAME, + }; + + enum class FolderChangeEvents : DWORD + { + None = 0, + FileName = FILE_NOTIFY_CHANGE_FILE_NAME, + DirectoryName = FILE_NOTIFY_CHANGE_DIR_NAME, + Attributes = FILE_NOTIFY_CHANGE_ATTRIBUTES, + FileSize = FILE_NOTIFY_CHANGE_SIZE, + LastWriteTime = FILE_NOTIFY_CHANGE_LAST_WRITE, + Security = FILE_NOTIFY_CHANGE_SECURITY, + All = FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_LAST_WRITE | + FILE_NOTIFY_CHANGE_SECURITY + }; + DEFINE_ENUM_FLAG_OPERATORS(FolderChangeEvents); + + /// @cond + namespace details + { + struct folder_watcher_state + { + folder_watcher_state(wistd::function &&callback) : m_callback(wistd::move(callback)) + { + } + wistd::function m_callback; + // Order is important, need to close the thread pool wait before the change handle. + unique_hfind_change m_findChangeHandle; + unique_threadpool_wait m_threadPoolWait; + }; + + inline void delete_folder_watcher_state(_In_opt_ folder_watcher_state *storage) { delete storage; } + + typedef resource_policy folder_watcher_state_resource_policy; + } + /// @endcond + + template + class folder_watcher_t : public storage_t + { + public: + // forward all base class constructors... + template + explicit folder_watcher_t(args_t&&... args) WI_NOEXCEPT : storage_t(wistd::forward(args)...) {} + + // HRESULT or void error handling... + typedef typename err_policy::result result; + + // Exception-based constructors + folder_watcher_t(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions; use the create method"); + create(folderToWatch, isRecursive, filter, wistd::move(callback)); + } + + result create(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) + { + return err_policy::HResult(create_common(folderToWatch, isRecursive, filter, wistd::move(callback))); + } + private: + // Factored into a standalone function to support Clang which does not support conversion of stateless lambdas + // to __stdcall + static void __stdcall callback(PTP_CALLBACK_INSTANCE /*Instance*/, void *context, TP_WAIT *pThreadPoolWait, TP_WAIT_RESULT /*result*/) + { + auto watcherState = static_cast(context); + watcherState->m_callback(); + + // Rearm the wait. Should not fail with valid parameters. + FindNextChangeNotification(watcherState->m_findChangeHandle.get()); + SetThreadpoolWait(pThreadPoolWait, watcherState->m_findChangeHandle.get(), __nullptr); + } + + // This function exists to avoid template expansion of this code based on err_policy. + HRESULT create_common(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) + { + wistd::unique_ptr watcherState(new(std::nothrow) details::folder_watcher_state(wistd::move(callback))); + RETURN_IF_NULL_ALLOC(watcherState); + + watcherState->m_findChangeHandle.reset(FindFirstChangeNotificationW(folderToWatch, isRecursive, static_cast(filter))); + RETURN_LAST_ERROR_IF(!watcherState->m_findChangeHandle); + + watcherState->m_threadPoolWait.reset(CreateThreadpoolWait(&folder_watcher_t::callback, watcherState.get(), __nullptr)); + RETURN_LAST_ERROR_IF(!watcherState->m_threadPoolWait); + this->reset(watcherState.release()); // no more failures after this, pass ownership + SetThreadpoolWait(this->get()->m_threadPoolWait.get(), this->get()->m_findChangeHandle.get(), __nullptr); + return S_OK; + } + }; + + typedef unique_any_t, err_returncode_policy>> unique_folder_watcher_nothrow; + + inline unique_folder_watcher_nothrow make_folder_watcher_nothrow(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) WI_NOEXCEPT + { + unique_folder_watcher_nothrow watcher; + watcher.create(folderToWatch, isRecursive, filter, wistd::move(callback)); + return watcher; // caller must test for success using if (watcher) + } + +#ifdef WIL_ENABLE_EXCEPTIONS + typedef unique_any_t, err_exception_policy>> unique_folder_watcher; + + inline unique_folder_watcher make_folder_watcher(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) + { + return unique_folder_watcher(folderToWatch, isRecursive, filter, wistd::move(callback)); + } +#endif // WIL_ENABLE_EXCEPTIONS + +#pragma endregion + +#pragma region Folder Reader + + // Example use for throwing: + // auto reader = wil::make_folder_change_reader(folder.Path().c_str(), true, wil::FolderChangeEvents::All, + // [](wil::FolderChangeEvent event, PCWSTR fileName) + // { + // switch (event) + // { + // case wil::FolderChangeEvent::ChangesLost: break; + // case wil::FolderChangeEvent::Added: break; + // case wil::FolderChangeEvent::Removed: break; + // case wil::FolderChangeEvent::Modified: break; + // case wil::FolderChangeEvent::RenamedOldName: break; + // case wil::FolderChangeEvent::RenamedNewName: break; + // }); + // + // Example use for non throwing: + // wil::unique_folder_change_reader_nothrow reader; + // THROW_IF_FAILED(reader.create(folder, true, wil::FolderChangeEvents::All, + // [](wil::FolderChangeEvent event, PCWSTR fileName) + // { + // // handle changes + // })); + // + + // @cond + namespace details + { + struct folder_change_reader_state + { + folder_change_reader_state(bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) + : m_callback(wistd::move(callback)), m_isRecursive(isRecursive), m_filter(filter) + { + } + + ~folder_change_reader_state() + { + if (m_tpIo != __nullptr) + { + TP_IO *tpIo = m_tpIo; + + // Indicate to the callback function that this object is being torn + // down. + + { + auto autoLock = m_cancelLock.lock_exclusive(); + m_tpIo = __nullptr; + } + + // Cancel IO to terminate the file system monitoring operation. + + if (m_folderHandle) + { + CancelIoEx(m_folderHandle.get(), &m_overlapped); + + DWORD bytesTransferredIgnored = 0; + GetOverlappedResult(m_folderHandle.get(), &m_overlapped, &bytesTransferredIgnored, TRUE); + } + + // Wait for callbacks to complete. + // + // N.B. This is a blocking call and must not be made within a + // callback or within a lock which is taken inside the + // callback. + + WaitForThreadpoolIoCallbacks(tpIo, TRUE); + CloseThreadpoolIo(tpIo); + } + } + + HRESULT StartIo() + { + // Unfortunately we have to handle ref-counting of IOs on behalf of the + // thread pool. + StartThreadpoolIo(m_tpIo); + HRESULT hr = ReadDirectoryChangesW(m_folderHandle.get(), m_readBuffer, sizeof(m_readBuffer), + m_isRecursive, static_cast(m_filter), __nullptr, &m_overlapped, __nullptr) ? + S_OK : HRESULT_FROM_WIN32(::GetLastError()); + if (FAILED(hr)) + { + // This operation does not have the usual semantic of returning + // ERROR_IO_PENDING. + // WI_ASSERT(hr != HRESULT_FROM_WIN32(ERROR_IO_PENDING)); + + // If the operation failed for whatever reason, ensure the TP + // ref counts are accurate. + + CancelThreadpoolIo(m_tpIo); + } + return hr; + } + + // void (wil::FolderChangeEvent event, PCWSTR fileName) + wistd::function m_callback; + unique_handle m_folderHandle; + BOOL m_isRecursive = FALSE; + FolderChangeEvents m_filter = FolderChangeEvents::None; + OVERLAPPED m_overlapped{}; + TP_IO *m_tpIo = __nullptr; + srwlock m_cancelLock; + unsigned char m_readBuffer[4096]{}; // Consider alternative buffer sizes. With 512 byte buffer i was not able to observe overflow. + }; + + inline void delete_folder_change_reader_state(_In_opt_ folder_change_reader_state *storage) { delete storage; } + + typedef resource_policy folder_change_reader_state_resource_policy; + } + /// @endcond + + template + class folder_change_reader_t : public storage_t + { + public: + // forward all base class constructors... + template + explicit folder_change_reader_t(args_t&&... args) WI_NOEXCEPT : storage_t(wistd::forward(args)...) {} + + // HRESULT or void error handling... + typedef typename err_policy::result result; + + // Exception-based constructors + folder_change_reader_t(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions; use the create method"); + create(folderToWatch, isRecursive, filter, wistd::move(callback)); + } + + result create(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) + { + return err_policy::HResult(create_common(folderToWatch, isRecursive, filter, wistd::move(callback))); + } + + wil::unique_hfile& folder_handle() { return this->get()->m_folderHandle; } + + private: + // Factored into a standalone function to support Clang which does not support conversion of stateless lambdas + // to __stdcall + static void __stdcall callback(PTP_CALLBACK_INSTANCE /* Instance */, void *context, void * /*overlapped*/, + ULONG result, ULONG_PTR /* BytesTransferred */, TP_IO * /* Io */) + { + auto readerState = static_cast(context); + // WI_ASSERT(overlapped == &readerState->m_overlapped); + + if (result == ERROR_SUCCESS) + { + for (auto const& info : create_next_entry_offset_iterator(reinterpret_cast(readerState->m_readBuffer))) + { + wchar_t realtiveFileName[MAX_PATH]; + StringCchCopyNW(realtiveFileName, ARRAYSIZE(realtiveFileName), info.FileName, info.FileNameLength / sizeof(info.FileName[0])); + + readerState->m_callback(static_cast(info.Action), realtiveFileName); + } + } + else if (result == ERROR_NOTIFY_ENUM_DIR) + { + readerState->m_callback(FolderChangeEvent::ChangesLost, __nullptr); + } + else + { + // No need to requeue + return; + } + + // If the lock is held non-shared or the TP IO is nullptr, this + // structure is being torn down. Otherwise, monitor for further + // changes. + auto autoLock = readerState->m_cancelLock.try_lock_shared(); + if (autoLock && readerState->m_tpIo) + { + readerState->StartIo(); // ignoring failure here + } + } + + // This function exists to avoid template expansion of this code based on err_policy. + HRESULT create_common(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, wistd::function &&callback) + { + wistd::unique_ptr readerState(new(std::nothrow) details::folder_change_reader_state( + isRecursive, filter, wistd::move(callback))); + RETURN_IF_NULL_ALLOC(readerState); + + readerState->m_folderHandle.reset(CreateFileW(folderToWatch, + FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, + __nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, __nullptr)); + RETURN_LAST_ERROR_IF(!readerState->m_folderHandle); + + readerState->m_tpIo = CreateThreadpoolIo(readerState->m_folderHandle.get(), &folder_change_reader_t::callback, readerState.get(), __nullptr); + RETURN_LAST_ERROR_IF_NULL(readerState->m_tpIo); + RETURN_IF_FAILED(readerState->StartIo()); + this->reset(readerState.release()); + return S_OK; + } + }; + + typedef unique_any_t, err_returncode_policy>> unique_folder_change_reader_nothrow; + + inline unique_folder_change_reader_nothrow make_folder_change_reader_nothrow(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, + wistd::function &&callback) WI_NOEXCEPT + { + unique_folder_change_reader_nothrow watcher; + watcher.create(folderToWatch, isRecursive, filter, wistd::move(callback)); + return watcher; // caller must test for success using if (watcher) + } + +#ifdef WIL_ENABLE_EXCEPTIONS + typedef unique_any_t, err_exception_policy>> unique_folder_change_reader; + + inline unique_folder_change_reader make_folder_change_reader(PCWSTR folderToWatch, bool isRecursive, FolderChangeEvents filter, + wistd::function &&callback) + { + return unique_folder_change_reader(folderToWatch, isRecursive, filter, wistd::move(callback)); + } +#endif // WIL_ENABLE_EXCEPTIONS +#pragma endregion + + //! Dos and VolumeGuid paths are always extended length paths with the \\?\ prefix. + enum class VolumePrefix + { + Dos = VOLUME_NAME_DOS, // Extended Dos Device path form, e.g. \\?\C:\Users\Chris\AppData\Local\Temp\wil8C31.tmp + VolumeGuid = VOLUME_NAME_GUID, // \\?\Volume{588fb606-b95b-4eae-b3cb-1e49861aaf18}\Users\Chris\AppData\Local\Temp\wil8C31.tmp + // The following are special paths which can't be used with Win32 APIs, but are useful in other scenarios. + None = VOLUME_NAME_NONE, // Path without the volume root, e.g. \Users\Chris\AppData\Local\Temp\wil8C31.tmp + NtObjectName = VOLUME_NAME_NT, // Unique name used by Object Manager, e.g. \Device\HarddiskVolume4\Users\Chris\AppData\Local\Temp\wil8C31.tmp + }; + enum class PathOptions + { + Normalized = FILE_NAME_NORMALIZED, + Opened = FILE_NAME_OPENED, + }; + DEFINE_ENUM_FLAG_OPERATORS(PathOptions); + + /** A strongly typed version of the Win32 API GetFinalPathNameByHandleW. + Get the full path name in different forms + Use this instead + VolumePrefix::None instead of GetFileInformationByHandleEx(FileNameInfo) to + get that path form. */ + template + HRESULT GetFinalPathNameByHandleW(HANDLE fileHandle, string_type& path, + wil::VolumePrefix volumePrefix = wil::VolumePrefix::Dos, wil::PathOptions options = wil::PathOptions::Normalized) + { + return AdaptFixedSizeToAllocatedResult(path, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNull) -> HRESULT + { + *valueLengthNeededWithNull = ::GetFinalPathNameByHandleW(fileHandle, value, static_cast(valueLength), + static_cast(volumePrefix) | static_cast(options)); + RETURN_LAST_ERROR_IF(*valueLengthNeededWithNull == 0); + WI_ASSERT((*value != L'\0') == (*valueLengthNeededWithNull < valueLength)); + if (*valueLengthNeededWithNull < valueLength) + { + (*valueLengthNeededWithNull)++; // it fit, account for the null + } + return S_OK; + }); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** A strongly typed version of the Win32 API GetFinalPathNameByHandleW. + Get the full path name in different forms. Use this + VolumePrefix::None + instead of GetFileInformationByHandleEx(FileNameInfo) to get that path form. */ + template + string_type GetFinalPathNameByHandleW(HANDLE fileHandle, + wil::VolumePrefix volumePrefix = wil::VolumePrefix::Dos, wil::PathOptions options = wil::PathOptions::Normalized) + { + string_type result{}; + THROW_IF_FAILED((GetFinalPathNameByHandleW(fileHandle, result, volumePrefix, options))); + return result; + } +#endif + + //! A strongly typed version of the Win32 API of GetCurrentDirectoryW. + //! Return a path in an allocated buffer for handling long paths. + template + HRESULT GetCurrentDirectoryW(string_type& path) + { + return AdaptFixedSizeToAllocatedResult(path, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNull) -> HRESULT + { + *valueLengthNeededWithNull = ::GetCurrentDirectoryW(static_cast(valueLength), value); + RETURN_LAST_ERROR_IF(*valueLengthNeededWithNull == 0); + WI_ASSERT((*value != L'\0') == (*valueLengthNeededWithNull < valueLength)); + if (*valueLengthNeededWithNull < valueLength) + { + (*valueLengthNeededWithNull)++; // it fit, account for the null + } + return S_OK; + }); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! A strongly typed version of the Win32 API of GetCurrentDirectoryW. + //! Return a path in an allocated buffer for handling long paths. + template + string_type GetCurrentDirectoryW() + { + string_type result{}; + THROW_IF_FAILED((GetCurrentDirectoryW(result))); + return result; + } +#endif + + // TODO: add support for these and other similar APIs. + // GetShortPathNameW() + // GetLongPathNameW() + // GetTempDirectory() + + /// @cond + namespace details + { + template struct MapInfoClassToInfoStruct; // failure to map is a usage error caught by the compiler +#define MAP_INFOCLASS_TO_STRUCT(InfoClass, InfoStruct, IsFixed, Extra) \ + template <> struct MapInfoClassToInfoStruct \ + { \ + typedef InfoStruct type; \ + static bool const isFixed = IsFixed; \ + static size_t const extraSize = Extra; \ + }; + + MAP_INFOCLASS_TO_STRUCT(FileBasicInfo, FILE_BASIC_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileStandardInfo, FILE_STANDARD_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileNameInfo, FILE_NAME_INFO, false, 32); + MAP_INFOCLASS_TO_STRUCT(FileRenameInfo, FILE_RENAME_INFO, false, 32); + MAP_INFOCLASS_TO_STRUCT(FileDispositionInfo, FILE_DISPOSITION_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileAllocationInfo, FILE_ALLOCATION_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileEndOfFileInfo, FILE_END_OF_FILE_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileStreamInfo, FILE_STREAM_INFO, false, 32); + MAP_INFOCLASS_TO_STRUCT(FileCompressionInfo, FILE_COMPRESSION_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileAttributeTagInfo, FILE_ATTRIBUTE_TAG_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileIdBothDirectoryInfo, FILE_ID_BOTH_DIR_INFO, false, 4096); + MAP_INFOCLASS_TO_STRUCT(FileIdBothDirectoryRestartInfo, FILE_ID_BOTH_DIR_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileIoPriorityHintInfo, FILE_IO_PRIORITY_HINT_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileRemoteProtocolInfo, FILE_REMOTE_PROTOCOL_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileFullDirectoryInfo, FILE_FULL_DIR_INFO, false, 4096); + MAP_INFOCLASS_TO_STRUCT(FileFullDirectoryRestartInfo, FILE_FULL_DIR_INFO, true, 0); +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + MAP_INFOCLASS_TO_STRUCT(FileStorageInfo, FILE_STORAGE_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileAlignmentInfo, FILE_ALIGNMENT_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileIdInfo, FILE_ID_INFO, true, 0); + MAP_INFOCLASS_TO_STRUCT(FileIdExtdDirectoryInfo, FILE_ID_EXTD_DIR_INFO, false, 4096); + MAP_INFOCLASS_TO_STRUCT(FileIdExtdDirectoryRestartInfo, FILE_ID_EXTD_DIR_INFO, true, 0); +#endif + + // Type unsafe version used in the implementation to avoid template bloat. + inline HRESULT GetFileInfo(HANDLE fileHandle, FILE_INFO_BY_HANDLE_CLASS infoClass, size_t allocationSize, + _Outptr_result_maybenull_ void **result) + { + *result = nullptr; + + wistd::unique_ptr resultHolder(new(std::nothrow) char[allocationSize]); + RETURN_IF_NULL_ALLOC(resultHolder); + + for (;;) + { + if (GetFileInformationByHandleEx(fileHandle, infoClass, resultHolder.get(), static_cast(allocationSize))) + { + *result = resultHolder.release(); + break; + } + else + { + DWORD const lastError = ::GetLastError(); + if (lastError == ERROR_MORE_DATA) + { + allocationSize *= 2; + resultHolder.reset(new(std::nothrow) char[allocationSize]); + RETURN_IF_NULL_ALLOC(resultHolder); + } + else if (lastError == ERROR_NO_MORE_FILES) // for folder enumeration cases + { + break; + } + else if (lastError == ERROR_INVALID_PARAMETER) // operation not supported by file system + { + return HRESULT_FROM_WIN32(lastError); + } + else + { + RETURN_WIN32(lastError); + } + } + } + return S_OK; + } + } + /// @endcond + + /** Get file information for a variable sized structure, returns an HRESULT. + ~~~ + wistd::unique_ptr fileNameInfo; + RETURN_IF_FAILED(GetFileInfoNoThrow(fileHandle, fileNameInfo)); + ~~~ + */ + template ::isFixed, int>::type = 0> + HRESULT GetFileInfoNoThrow(HANDLE fileHandle, wistd::unique_ptr::type> &result) WI_NOEXCEPT + { + void *rawResult; + HRESULT hr = details::GetFileInfo(fileHandle, infoClass, + sizeof(typename details::MapInfoClassToInfoStruct::type) + details::MapInfoClassToInfoStruct::extraSize, + &rawResult); + result.reset(static_cast::type*>(rawResult)); + RETURN_HR_IF_EXPECTED(hr, hr == E_INVALIDARG); // operation not supported by file system + RETURN_IF_FAILED(hr); + return S_OK; + } + + /** Get file information for a fixed sized structure, returns an HRESULT. + ~~~ + FILE_BASIC_INFO fileBasicInfo; + RETURN_IF_FAILED(GetFileInfoNoThrow(fileHandle, &fileBasicInfo)); + ~~~ + */ + template ::isFixed, int>::type = 0> + HRESULT GetFileInfoNoThrow(HANDLE fileHandle, _Out_ typename details::MapInfoClassToInfoStruct::type *result) WI_NOEXCEPT + { + const HRESULT hr = GetFileInformationByHandleEx(fileHandle, infoClass, result, sizeof(*result)) ? + S_OK : HRESULT_FROM_WIN32(::GetLastError()); + RETURN_HR_IF_EXPECTED(hr, hr == E_INVALIDARG); // operation not supported by file system + RETURN_IF_FAILED(hr); + return S_OK; + } + + // Verifies that the given file path is not a hard or a soft link. If the file is present at the path, returns + // a handle to it without delete permissions to block an attacker from swapping the file. + inline HRESULT CreateFileAndEnsureNotLinked(PCWSTR path, wil::unique_hfile& fileHandle) + { + // Open handles to the original path and to the final path and compare each file's information + // to verify they are the same file. If they are different, the file is a soft link. + fileHandle.reset(CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, nullptr)); + RETURN_LAST_ERROR_IF(!fileHandle); + BY_HANDLE_FILE_INFORMATION fileInfo; + RETURN_IF_WIN32_BOOL_FALSE(GetFileInformationByHandle(fileHandle.get(), &fileInfo)); + + // Open a handle without the reparse point flag to get the final path in case it is a soft link. + wil::unique_hfile finalPathHandle(CreateFileW(path, 0, 0, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr)); + RETURN_LAST_ERROR_IF(!finalPathHandle); + BY_HANDLE_FILE_INFORMATION finalFileInfo; + RETURN_IF_WIN32_BOOL_FALSE(GetFileInformationByHandle(finalPathHandle.get(), &finalFileInfo)); + finalPathHandle.reset(); + + // The low and high indices and volume serial number uniquely identify a file. These must match if they are the same file. + const bool isSoftLink = + ((fileInfo.nFileIndexLow != finalFileInfo.nFileIndexLow) || + (fileInfo.nFileIndexHigh != finalFileInfo.nFileIndexHigh) || + (fileInfo.dwVolumeSerialNumber != finalFileInfo.dwVolumeSerialNumber)); + + // Return failure if it is a soft link or a hard link (number of links greater than 1). + RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME), (isSoftLink || fileInfo.nNumberOfLinks > 1)); + + return S_OK; + } + +#ifdef _CPPUNWIND + /** Get file information for a fixed sized structure, throws on failure. + ~~~ + auto fileBasicInfo = GetFileInfo(fileHandle); + ~~~ + */ + template ::isFixed, int>::type = 0> + typename details::MapInfoClassToInfoStruct::type GetFileInfo(HANDLE fileHandle) + { + typename details::MapInfoClassToInfoStruct::type result{}; + THROW_IF_FAILED(GetFileInfoNoThrow(fileHandle, &result)); + return result; + } + + /** Get file information for a variable sized structure, throws on failure. + ~~~ + auto fileBasicInfo = GetFileInfo(fileHandle); + ~~~ + */ + template ::isFixed, int>::type = 0> + wistd::unique_ptr::type> GetFileInfo(HANDLE fileHandle) + { + wistd::unique_ptr::type> result; + THROW_IF_FAILED(GetFileInfoNoThrow(fileHandle, result)); + return result; + } +#endif // _CPPUNWIND +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN7) +} + +#endif // __WIL_FILESYSTEM_INCLUDED diff --git a/libraries/wil/nt_result_macros.h b/libraries/wil/nt_result_macros.h new file mode 100644 index 0000000..d563235 --- /dev/null +++ b/libraries/wil/nt_result_macros.h @@ -0,0 +1,168 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_NT_RESULTMACROS_INCLUDED +#define __WIL_NT_RESULTMACROS_INCLUDED + +#include "result_macros.h" + +// Helpers for return macros +#define __NT_RETURN_NTSTATUS(status, str) __WI_SUPPRESS_4127_S do { NTSTATUS __status = (status); if (FAILED_NTSTATUS(__status)) { __R_FN(Return_NtStatus)(__R_INFO(str) __status); } return __status; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __NT_RETURN_NTSTATUS_MSG(status, str, fmt, ...) __WI_SUPPRESS_4127_S do { NTSTATUS __status = (status); if (FAILED_NTSTATUS(__status)) { __R_FN(Return_NtStatusMsg)(__R_INFO(str) __status, fmt, ##__VA_ARGS__); } return __status; } __WI_SUPPRESS_4127_E while ((void)0, 0) + +//***************************************************************************** +// Macros for returning failures as NTSTATUS +//***************************************************************************** + +// Always returns a known result (NTSTATUS) - always logs failures +#define NT_RETURN_NTSTATUS(status) __NT_RETURN_NTSTATUS(wil::verify_ntstatus(status), #status) + +// Always returns a known failure (NTSTATUS) - always logs a var-arg message on failure +#define NT_RETURN_NTSTATUS_MSG(status, fmt, ...) __NT_RETURN_NTSTATUS_MSG(wil::verify_ntstatus(status), #status, fmt, ##__VA_ARGS__) + +// Conditionally returns failures (NTSTATUS) - always logs failures +#define NT_RETURN_IF_NTSTATUS_FAILED(status) __WI_SUPPRESS_4127_S do { const auto __statusRet = wil::verify_ntstatus(status); if (FAILED_NTSTATUS(__statusRet)) { __NT_RETURN_NTSTATUS(__statusRet, #status); }} __WI_SUPPRESS_4127_E while ((void)0, 0) + +// Conditionally returns failures (NTSTATUS) - always logs a var-arg message on failure +#define NT_RETURN_IF_NTSTATUS_FAILED_MSG(status, fmt, ...) __WI_SUPPRESS_4127_S do { const auto __statusRet = wil::verify_ntstatus(status); if (FAILED_NTSTATUS(__statusRet)) { __NT_RETURN_NTSTATUS_MSG(__statusRet, #status, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) + +//***************************************************************************** +// Macros to catch and convert exceptions on failure +//***************************************************************************** + +// Use these macros *within* a catch (...) block to handle exceptions +#define NT_RETURN_CAUGHT_EXCEPTION() return __R_FN(Nt_Return_CaughtException)(__R_INFO_ONLY(nullptr)) +#define NT_RETURN_CAUGHT_EXCEPTION_MSG(fmt, ...) return __R_FN(Nt_Return_CaughtExceptionMsg)(__R_INFO(nullptr) fmt, ##__VA_ARGS__) + +// Use these macros in place of a catch block to handle exceptions +#define NT_CATCH_RETURN() catch (...) { NT_RETURN_CAUGHT_EXCEPTION(); } +#define NT_CATCH_RETURN_MSG(fmt, ...) catch (...) { NT_RETURN_CAUGHT_EXCEPTION_MSG(fmt, ##__VA_ARGS__); } + + +namespace wil +{ + //***************************************************************************** + // Public Helpers that catch -- mostly only enabled when exceptions are enabled + //***************************************************************************** + + // StatusFromCaughtException is a function that is meant to be called from within a catch(...) block. Internally + // it re-throws and catches the exception to convert it to an NTSTATUS. If an exception is of an unrecognized type + // the function will fail fast. + // + // try + // { + // // Code + // } + // catch (...) + // { + // status = wil::StatusFromCaughtException(); + // } + _Always_(_Post_satisfies_(return < 0)) + __declspec(noinline) inline NTSTATUS StatusFromCaughtException() WI_NOEXCEPT + { + bool isNormalized = false; + NTSTATUS status = STATUS_SUCCESS; + if (details::g_pfnResultFromCaughtExceptionInternal) + { + status = details::g_pfnResultFromCaughtExceptionInternal(nullptr, 0, &isNormalized).status; + } + if (FAILED_NTSTATUS(status)) + { + return status; + } + + // Caller bug: an unknown exception was thrown + __WIL_PRIVATE_FAIL_FAST_HR_IF(__HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION), g_fResultFailFastUnknownExceptions); + return wil::details::HrToNtStatus(__HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)); + } + + namespace details + { + template + __declspec(noinline) inline NTSTATUS ReportStatus_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported = SupportedExceptions::Default); + template + __declspec(noinline) inline NTSTATUS ReportStatus_CaughtExceptionMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList); + + namespace __R_NS_NAME + { +#ifdef WIL_ENABLE_EXCEPTIONS + __R_DIRECT_METHOD(NTSTATUS, Nt_Return_CaughtException)(__R_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + return wil::details::ReportStatus_CaughtException(__R_DIRECT_FN_CALL_ONLY); + } + + __R_DIRECT_METHOD(NTSTATUS, Nt_Return_CaughtExceptionMsg)(__R_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + return wil::details::ReportStatus_CaughtExceptionMsg(__R_DIRECT_FN_CALL formatString, argList); + } +#endif + } + + template + __declspec(noinline) inline NTSTATUS ReportStatus_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported) + { + wchar_t message[2048]; + message[0] = L'\0'; + return ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), supported).status; + } + + template<> + __declspec(noinline) inline NTSTATUS ReportStatus_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported) + { + wchar_t message[2048]; + message[0] = L'\0'; + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), supported).status); + } + + template<> + __declspec(noinline) inline NTSTATUS ReportStatus_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported) + { + wchar_t message[2048]; + message[0] = L'\0'; + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), supported).status); + } + + template + __declspec(noinline) inline NTSTATUS ReportStatus_CaughtExceptionMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + // Pre-populate the buffer with our message, the exception message will be added to it... + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + StringCchCatW(message, ARRAYSIZE(message), L" -- "); + return ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), SupportedExceptions::Default).status; + } + + template<> + __declspec(noinline) inline NTSTATUS ReportStatus_CaughtExceptionMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + // Pre-populate the buffer with our message, the exception message will be added to it... + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + StringCchCatW(message, ARRAYSIZE(message), L" -- "); + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), SupportedExceptions::Default).status); + } + + template<> + __declspec(noinline) inline NTSTATUS ReportStatus_CaughtExceptionMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + // Pre-populate the buffer with our message, the exception message will be added to it... + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + StringCchCatW(message, ARRAYSIZE(message), L" -- "); + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), SupportedExceptions::Default).status); + } + } +} + +#endif // __WIL_NT_RESULTMACROS_INCLUDED diff --git a/libraries/wil/registry.h b/libraries/wil/registry.h new file mode 100644 index 0000000..aaff74f --- /dev/null +++ b/libraries/wil/registry.h @@ -0,0 +1,3270 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_REGISTRY_INCLUDED +#define __WIL_REGISTRY_INCLUDED + +#ifdef _KERNEL_MODE +#error This header is not supported in kernel-mode. +#endif + +#include +#include // new(std::nothrow) +#include "registry_helpers.h" +#include "resource.h" + +// wil registry does not require the use of the STL or C++ exceptions (see _nothrow functions) +// wil registry natively supports std::vector and std::wstring when preferring those types +// wil registry uses the __WIL_WINREG_STL define to enable support for wil::shared_* types (defined in resource.h) + +namespace wil +{ + namespace reg + { +#if defined(WIL_ENABLE_EXCEPTIONS) + /** + * \brief Opens a new HKEY to the specified path - see RegOpenKeyExW + * \param key An open or well-known registry key + * \param subKey The name of the registry subkey to be opened. + * If `nullptr`, then `key` is used without modification. + * \param access The requested access desired for the opened key + * \return A wil::unique_hkey containing the resulting opened HKEY + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline ::wil::unique_hkey open_unique_key(HKEY key, _In_opt_ PCWSTR subKey, ::wil::reg::key_access access = ::wil::reg::key_access::read) + { + const reg_view_details::reg_view regview{ key }; + ::wil::unique_hkey return_value; + regview.open_key(subKey, &return_value, access); + return return_value; + } + + /** + * \brief Creates a new HKEY to the specified path - see RegCreateKeyExW + * \param key An open or well-known registry key + * \param subKey The name of a subkey that this function opens or creates. + * Note: this cannot be null (see the above referenced API documentation) + * \param access The requested access desired for the opened key + * \return A wil::unique_hkey or wil::shared_hkey containing the resulting opened HKEY + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline ::wil::unique_hkey create_unique_key(HKEY key, PCWSTR subKey, ::wil::reg::key_access access = ::wil::reg::key_access::read) + { + const reg_view_details::reg_view regview{ key }; + ::wil::unique_hkey return_value; + regview.create_key(subKey, &return_value, access); + return return_value; + } + +#if defined(__WIL_WINREG_STL) + /** + * \brief Opens a new HKEY to the specified path - see RegOpenKeyExW + * \param key An open or well-known registry key + * \param subKey The name of the registry subkey to be opened. + * If `nullptr`, then `key` is used without modification. + * \param access The requested access desired for the opened key + * \return A wil::shared_hkey containing the resulting opened HKEY + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline ::wil::shared_hkey open_shared_key(HKEY key, _In_opt_ PCWSTR subKey, ::wil::reg::key_access access = ::wil::reg::key_access::read) + { + const reg_view_details::reg_view regview{ key }; + ::wil::shared_hkey return_value; + regview.open_key(subKey, &return_value, access); + return return_value; + } + + /** + * \brief Creates a new HKEY to the specified path - see RegCreateKeyExW + * \param key An open or well-known registry key + * \param subKey The name of a subkey that this function opens or creates. + * Note: this cannot be null (see the above referenced API documentation) + * \param access The requested access desired for the opened key + * \return A wil::shared_hkey or wil::shared_hkey containing the resulting opened HKEY + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline ::wil::shared_hkey create_shared_key(HKEY key, PCWSTR subKey, ::wil::reg::key_access access = ::wil::reg::key_access::read) + { + const reg_view_details::reg_view regview{ key }; + ::wil::shared_hkey return_value; + regview.create_key(subKey, &return_value, access); + return return_value; + } +#endif // #if defined(__WIL_WINREG_STL) +#endif // #if defined(WIL_ENABLE_EXCEPTIONS) + + /** + * \brief Opens a new HKEY to the specified path - see RegOpenKeyExW + * \param key An open or well-known registry key + * \param subKey The name of the registry subkey to be opened. + * If `nullptr`, then `key` is used without modification. + * \param[out] hkey A reference to a wil::unique_hkey to receive the opened HKEY + * \param access The requested access desired for the opened key + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT open_unique_key_nothrow(HKEY key, _In_opt_ PCWSTR subKey, ::wil::unique_hkey& hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.open_key(subKey, hkey.put(), access); + } + + /** + * \brief Creates a new HKEY to the specified path - see RegCreateKeyExW + * \param key An open or well-known registry key + * \param subKey The name of a subkey that this function opens or creates. + * Note: this cannot be null (see the above referenced API documentation) + * \param[out] hkey A reference to a wil::unique_hkey to receive the opened HKEY + * \param access The requested access desired for the opened key + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT create_unique_key_nothrow(HKEY key, PCWSTR subKey, ::wil::unique_hkey& hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.create_key(subKey, hkey.put(), access); + } + +#if defined(__WIL_WINREG_STL) + /** + * \brief Opens a new HKEY to the specified path - see RegOpenKeyExW + * \param key An open or well-known registry key + * \param subKey The name of the registry subkey to be opened. + * If `nullptr`, then `key` is used without modification. + * \param[out] hkey A reference to a wil::shared_hkey to receive the opened HKEY + * \param access The requested access desired for the opened key + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT open_shared_key_nothrow(HKEY key, _In_opt_ PCWSTR subKey, ::wil::shared_hkey& hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.open_key(subKey, hkey.put(), access); + } + + /** + * \brief Creates a new HKEY to the specified path - see RegCreateKeyExW + * \param key An open or well-known registry key + * \param subKey The name of a subkey that this function opens or creates. + * Note: this cannot be null (see the above referenced API documentation) + * \param[out] hkey A reference to a wil::shared_hkey to receive the opened HKEY + * \param access The requested access desired for the opened key + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT create_shared_key_nothrow(HKEY key, PCWSTR subKey, ::wil::shared_hkey& hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.create_key(subKey, hkey.put(), access); + } +#endif // #define __WIL_WINREG_STL + // + // wil::key_iterator and wil::value_iterator objects enable enumerating registry keys and values. + // + // Examples of usage when std::wstring is included: + // + // for (const auto& key_data : wil::make_range(wil::reg::key_iterator{hkey}, wil::reg::key_iterator{})) + // { + // key_data.name; // the std::wstring of the enumerated key + // } + // + // for (const auto& value_data : wil::make_range(wil::reg::value_iterator{hkey}, wil::reg::value_iterator{})) + // { + // value_data.name; // the std::wstring of the enumerated value + // value_data.type; // the REG_ type of the enumerated value + // } + // + // When std::wstring is not included, wil::unique_process_heap_string can be used instead: + // + // for (const auto& key_data : wil::make_range(wil::reg::key_heap_string_iterator{hkey}, wil::reg::key_heap_string_iterator{})) + // { + // key_data.name.get(); // the PCWSTR of the enumerated key + // } + // + // for (const auto& value_data : wil::make_range(wil::reg::value_heap_string_iterator{hkey}, wil::reg::value_heap_string_iterator{})) + // { + // value_data.name.get(); // the PCWSTR of the enumerated value + // value_data.type; // the REG_ type of the enumerated value + // } + // + // When not using exceptions, can manually walk the iterator using wil::unique_process_heap_string: + // + // auto iterate_keys = wil::reg::key_heap_string_nothrow_iterator{hkey}; + // for (const auto& key_data : wil::make_range(iterate_keys, wil::reg::key_heap_string_nothrow_iterator{})) + // { + // key_data.name.get(); // the PCWSTR of the enumerated key + // } + // if (FAILED(iterate_keys.last_error())) + // { + // // the HRESULT last_error() returns the registry error that prevented enumeration + // } + // + // auto iterate_values = wil::reg::value_heap_string_nothrow_iterator{hkey}; + // for (const auto& value_data : wil::make_range(iterate_values, wil::reg::value_heap_string_nothrow_iterator{})) + // { + // value_data.name.get(); // the PCWSTR of the enumerated value + // value_data.type; // the REG_ type of the enumerated value + // } + // if (FAILED(iterate_values.last_error())) + // { + // // the HRESULT last_error() returns the registry error that prevented enumeration + // } + // +#if defined(WIL_ENABLE_EXCEPTIONS) + +#if defined(_STRING_) + using key_iterator = ::wil::reg::iterator_t<::wil::reg::key_iterator_data<::std::wstring>>; + using value_iterator = ::wil::reg::iterator_t<::wil::reg::value_iterator_data<::std::wstring>>; +#endif + +#if defined(__WIL_OLEAUTO_H_) + using key_bstr_iterator = ::wil::reg::iterator_t<::wil::reg::key_iterator_data<::wil::unique_bstr>>; + using value_bstr_iterator = ::wil::reg::iterator_t<::wil::reg::value_iterator_data<::wil::unique_bstr>>; +#endif // #if defined(__WIL_OLEAUTO_H_) + + using key_heap_string_iterator = ::wil::reg::iterator_t<::wil::reg::key_iterator_data<::wil::unique_process_heap_string>>; + using value_heap_string_iterator = ::wil::reg::iterator_t<::wil::reg::value_iterator_data<::wil::unique_process_heap_string>>; +#endif // #if defined(WIL_ENABLE_EXCEPTIONS) + + // no-throw versions of applicable registry iterators +#if defined(__WIL_OLEAUTO_H_) + using key_bstr_nothrow_iterator = ::wil::reg::iterator_nothrow_t<::wil::reg::key_iterator_data<::wil::unique_bstr>>; + using value_bstr_nothrow_iterator = ::wil::reg::iterator_nothrow_t<::wil::reg::value_iterator_data<::wil::unique_bstr>>; +#endif // #if defined(__WIL_OLEAUTO_H_) + using key_heap_string_nothrow_iterator = ::wil::reg::iterator_nothrow_t<::wil::reg::key_iterator_data<::wil::unique_process_heap_string>>; + using value_heap_string_nothrow_iterator = ::wil::reg::iterator_nothrow_t<::wil::reg::value_iterator_data<::wil::unique_process_heap_string>>; + + /** + * \brief Queries for number of sub-keys + * \param key The HKEY to query for number of sub-keys + * \param[out] numSubKeys A pointer to a DWORD to receive the returned count + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_child_key_count_nothrow(HKEY key, _Out_ DWORD* numSubKeys) WI_NOEXCEPT + { + RETURN_IF_WIN32_ERROR( + RegQueryInfoKeyW( + key, + nullptr, // null class + nullptr, // null class character count, + nullptr, // null reserved + numSubKeys, + nullptr, // null max subkey length + nullptr, // null max class length + nullptr, // null value count + nullptr, // null max value name length + nullptr, // null max value length + nullptr, // null security descriptor + nullptr)); // null last write filetime + return S_OK; + } + + inline HRESULT get_child_key_count_nothrow(HKEY key, _Out_ uint32_t* numSubKeys) WI_NOEXCEPT + { + DWORD subKeys{}; + RETURN_IF_FAILED(::wil::reg::get_child_key_count_nothrow(key, &subKeys)); + *numSubKeys = subKeys; + return S_OK; + } + + /** + * \brief Queries for number of values + * \param key The HKEY to query for number of values + * \param[out] numSubValues A pointer to a DWORD to receive the returned count + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_child_value_count_nothrow(HKEY key, _Out_ DWORD* numSubValues) WI_NOEXCEPT + { + RETURN_IF_WIN32_ERROR( + RegQueryInfoKeyW( + key, + nullptr, // null class + nullptr, // null class char count, + nullptr, // null reserved + nullptr, // null subkey count + nullptr, // null max subkey length + nullptr, // null max class length + numSubValues, + nullptr, // null max value name length + nullptr, // null max value length + nullptr, // null security descriptor + nullptr)); // null last write filetime + return S_OK; + } + + inline HRESULT get_child_value_count_nothrow(HKEY key, _Out_ uint32_t* numSubValues) WI_NOEXCEPT + { + DWORD subValues{}; + RETURN_IF_FAILED(::wil::reg::get_child_value_count_nothrow(key, &subValues)); + *numSubValues = subValues; + return S_OK; + } + + /** + * \brief Queries for the filetime when the registry key was last written + * \param key The HKEY to query for number of values + * \param[out] lastModified A pointer to a FILETIME to receive the last write time + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline HRESULT get_last_write_filetime_nothrow(HKEY key, _Out_ FILETIME* lastModified) WI_NOEXCEPT + { + RETURN_IF_WIN32_ERROR( + RegQueryInfoKeyW( + key, + nullptr, // null class + nullptr, // null class char count, + nullptr, // null reserved + nullptr, // null subkey count + nullptr, // null max subkey length + nullptr, // null max class length + nullptr, // null value count + nullptr, // null max value name length + nullptr, // null max value length + nullptr, // null security descriptor + lastModified)); + return S_OK; + } + +#if defined(WIL_ENABLE_EXCEPTIONS) + /** + * \brief Queries for number of sub-keys + * \param key The HKEY to query for number of sub-keys + * \return The queried number of sub-keys if succeeded + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline uint32_t get_child_key_count(HKEY key) + { + uint32_t numSubKeys{}; + THROW_IF_FAILED(::wil::reg::get_child_key_count_nothrow(key, &numSubKeys)); + return numSubKeys; + } + + /** + * \brief Queries for number of values + * \param key The HKEY to query for number of values + * \return The queried number of value if succeeded + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline uint32_t get_child_value_count(HKEY key) + { + uint32_t numSubValues{}; + THROW_IF_FAILED(::wil::reg::get_child_value_count_nothrow(key, &numSubValues)); + return numSubValues; + } + + /** + * \brief Queries for the filetime when the registry key was last written + * \param key The HKEY to query for number of values + * \return The queried filetime if succeeded + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline FILETIME get_last_write_filetime(HKEY key) + { + FILETIME lastModified{}; + THROW_IF_FAILED(::wil::reg::get_last_write_filetime_nothrow(key, &lastModified)); + return lastModified; + } +#endif // #if defined(WIL_ENABLE_EXCEPTIONS) + +#if defined(WIL_ENABLE_EXCEPTIONS) + // + // template + // void set_value(...) + // + // - Writes a value to a specified key and subkey, deducing the type from the given data + // - Throws a std::exception on failure (including wil::ResultException) + // + // Examples of usage (the template type does not need to be explicitly specified) + // wil::reg::set_value(key, L"subkey", L"dword_value_name", 0); // writes a REG_DWORD + // wil::reg::set_value(key, L"subkey", L"qword_value_name", 0ull); // writes a REG_QWORD + // wil::reg::set_value(key, L"subkey", L"string_value_name", L"hello"); // writes a REG_SZ + // + // A subkey is not required if the key is opened where this should write the value: + // wil::reg::set_value(key, L"dword_value_name", 0); // writes a REG_DWORD + // wil::reg::set_value(key, L"qword_value_name", 0ull); // writes a REG_QWORD + // wil::reg::set_value(key, L"string_value_name", L"hello"); // writes a REG_SZ + // + // Example usage writing a vector of wstrings to a REG_MULTI_SZ + // std::vector data { L"string1", L"string2", L"string3" }; + // wil::reg::set_value(key, L"multi_string_value_name", data); + // wil::reg::set_value(key, L"multi_string_value_name", data); + // + // Example of usage writing directly to a registry value from a raw byte vector + // - notice the registry type is required, not implied + // std::vector data { 0x00, 0xff, 0xee, 0xdd, 0xcc }; + // wil::reg::set_value_binary(key, L"binary_value_name", REG_BINARY, data); + // wil::reg::set_value_binary(key, L"binary_value_name", REG_BINARY, data); + // + + /** + * \brief Writes a value to a specified key and subkey, deducing the type from the given data. + * \tparam T The type of the data being set (the registry value type is deduced from T). + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The data (of type T) to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + template + void set_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const T& data) + { + const reg_view_details::reg_view regview{ key }; + regview.set_value(subkey, value_name, data); + } + + /** + * \brief Writes a value under a specified key, the registry type based off the templated type passed as data + * \tparam T The type of the data being set (the registry value type is deduced from T). + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The data (of type T) to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + template + void set_value(HKEY key, _In_opt_ PCWSTR value_name, const T& data) + { + ::wil::reg::set_value(key, nullptr, value_name, data); + } + + /** + * \brief Writes a null-terminated string value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) + { + const reg_view_details::reg_view regview{ key }; + regview.set_value(subkey, value_name, data); + } + + /** + * \brief Writes a null-terminated string value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) + { + ::wil::reg::set_value(key, nullptr, value_name, data); + } + + + /** + * \brief Writes a REG_DWORD value from a uint32_t + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The 32-bit value to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_dword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t data) + { + ::wil::reg::set_value(key, subkey, value_name, data); + } + + /** + * \brief Writes a REG_DWORD value from a uint32_t + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The 32-bit value to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_dword(HKEY key, _In_opt_ PCWSTR value_name, uint32_t data) + { + ::wil::reg::set_value(key, nullptr, value_name, data); + } + + /** + * \brief Writes a REG_QWORD value from a uint64_t + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The 64-bit value to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_qword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint64_t data) + { + ::wil::reg::set_value(key, subkey, value_name, data); + } + + /** + * \brief Writes a REG_QWORD value from a uint64_t + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The 64-bit value to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_qword(HKEY key, _In_opt_ PCWSTR value_name, uint64_t data) + { + ::wil::reg::set_value(key, nullptr, value_name, data); + } + + /** + * \brief Writes a REG_SZ value from a null-terminated string + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string value to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) + { + ::wil::reg::set_value(key, subkey, value_name, data); + } + + /** + * \brief Writes a REG_SZ value from a null-terminated string + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string value to write to the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_string(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) + { + ::wil::reg::set_value(key, nullptr, value_name, data); + } + + /** + * \brief Writes a REG_EXPAND_SZ value from a null-terminated string + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated, unexpanded string value to write to the specified registry value. For example, `%PATH%`. + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_expanded_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) + { + const reg_view_details::reg_view regview{ key }; + regview.set_value(subkey, value_name, data, REG_EXPAND_SZ); + } + + /** + * \brief Writes a REG_EXPAND_SZ value from a null-terminated string + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated, unexpanded string value to write to the specified registry value. For example, `%PATH%`. + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_expanded_string(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) + { + ::wil::reg::set_value_expanded_string(key, nullptr, value_name, data); + } + +#if defined(_VECTOR_) && defined(_STRING_) + /** + * \brief The generic set_value template function to write a REG_MULTI_SZ value from a std::vector + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data A std::vector to write to the specified registry value. + * Each string will be marshaled to a contiguous null-terminator-delimited multi-sz string + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const ::std::vector<::std::wstring>& data) + { + const auto multiStringWcharVector(reg_view_details::get_multistring_from_wstrings(::std::begin(data), ::std::end(data))); + const reg_view_details::reg_view regview{ key }; + regview.set_value(subkey, value_name, multiStringWcharVector, REG_MULTI_SZ); + } + + /** + * \brief The generic set_value template function to write a REG_MULTI_SZ value from a std::vector + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data A std::vector to write to the specified registry value. + * Each string will be marshaled to a contiguous null-terminator-delimited multi-sz string. + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value(HKEY key, _In_opt_ PCWSTR value_name, const ::std::vector<::std::wstring>& data) + { + ::wil::reg::set_value(key, nullptr, value_name, data); + } + + /** + * \brief Writes a REG_MULTI_SZ value from a std::vector + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data A std::vector to write to the specified registry value. + * Each string will be marshaled to a contiguous null-terminator-delimited multi-sz string + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_multistring(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const ::std::vector<::std::wstring>& data) + { + ::wil::reg::set_value(key, subkey, value_name, data); + } + + /** + * \brief Writes a REG_MULTI_SZ value from a std::vector + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data A std::vector to write to the specified registry value. + * Each string will be marshaled to a contiguous null-terminator-delimited multi-sz string. + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_multistring(HKEY key, _In_opt_ PCWSTR value_name, const ::std::vector<::std::wstring>& data) + { + ::wil::reg::set_value(key, nullptr, value_name, data); + } +#endif // #if defined(_VECTOR_) && defined(_STRING_) + +#if defined(_VECTOR_) + /** + * \brief Writes a registry value of the specified type from a std::vector/std::vector + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param type The registry type for the specified registry value - see RegSetKeyValueW + * \param data A std::vector/std::vector to write to the specified registry value. + * The vector contents will be directly marshaled to the specified value. + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_binary(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type, const ::std::vector& data) + { + const reg_view_details::reg_view regview{ key }; + regview.set_value(subkey, value_name, data, type); + } + + /** + * \brief Writes a registry value of the specified type from a std::vector/std::vector + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param type The registry type for the specified registry value - see RegSetKeyValueW + * \param data A std::vector/std::vector to write to the specified registry value. + * The vector contents will be directly marshaled to the specified value. + * \exception std::exception (including wil::ResultException) will be thrown on all failures + */ + inline void set_value_binary(HKEY key, _In_opt_ PCWSTR value_name, uint32_t type, const ::std::vector& data) + { + ::wil::reg::set_value_binary(key, nullptr, value_name, type, data); + } +#endif // #if defined(_VECTOR_) +#endif // #if defined(WIL_ENABLE_EXCEPTIONS) + + // + // template + // HRESULT set_value_nothrow(...) + // + // - Writes a value under a specified key + // - The type of registry value is determined by the template type T of data given + // - Returns an HRESULT error code indicating success or failure (does not throw C++ exceptions) + // + // Examples of usage (the template type does not need to be explicitly specified) + // hr = wil::reg::set_value_nothrow(key, L"subkey", L"dword_value_name", 0); // writes a REG_DWORD + // hr = wil::reg::set_value_nothrow(key, L"subkey", L"qword_value_name", 0ull); // writes a REG_QWORD + // hr = wil::reg::set_value_nothrow(key, L"subkey", L"string_value_name", L"hello"); // writes a REG_SZ + // + // A subkey is not required if the key is opened where this should write the value: + // hr = wil::reg::set_value_nothrow(key, L"dword_value_name", 0); // writes a REG_DWORD + // hr = wil::reg::set_value_nothrow(key, L"qword_value_name", 0ull); // writes a REG_QWORD + // hr = wil::reg::set_value_nothrow(key, L"string_value_name", L"hello"); // writes a REG_SZ + // + // Example of usage writing a REG_MULTI_SZ + // std::vector multisz_data { L"string1", L"string2", L"string3" }; + // hr = wil::reg::set_value_nothrow(key, L"multi_string_value_name", multisz_data); + // + // Values can be written directly from a vector of bytes - the registry type must be specified; e.g.: + // std::vector data { 0x00, 0xff, 0xee, 0xdd, 0xcc }; + // hr = wil::reg::set_value_binary_nothrow(key, L"binary_value_name", REG_BINARY, data); + // + /** + * \brief Writes a value to a specified key and subkey, deducing the type from the given data. + * \tparam T The type of the data being set (the registry value type is deduced from T). + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The data (of type T) to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template + HRESULT set_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const T& data) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.set_value(subkey, value_name, data); + } + + /** + * \brief Writes a value under a specified key, the registry type based off the templated type passed as data + * \tparam T The type of the data being set (the registry value type is deduced from T). + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The data (of type T) to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template + HRESULT set_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, const T& data) WI_NOEXCEPT + { + return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data); + } + + /** + * \brief Writes a null-terminated string value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.set_value(subkey, value_name, data); + } + + /** + * \brief Writes a null-terminated string value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT + { + return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data); + } + + /** + * \brief Writes a REG_DWORD value from a uint32_t + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The 32-bit value to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_dword_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t data) WI_NOEXCEPT + { + return ::wil::reg::set_value_nothrow(key, subkey, value_name, data); + } + + /** + * \brief Writes a REG_DWORD value from a uint32_t + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The 32-bit value to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_dword_nothrow(HKEY key, _In_opt_ PCWSTR value_name, uint32_t data) WI_NOEXCEPT + { + return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data); + } + + /** + * \brief Writes a REG_QWORD value from a uint64_t + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The 64-bit value to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_qword_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint64_t data) WI_NOEXCEPT + { + return ::wil::reg::set_value_nothrow(key, subkey, value_name, data); + } + + /** + * \brief Writes a REG_QWORD value from a uint64_t + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The 64-bit value to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_qword_nothrow(HKEY key, _In_opt_ PCWSTR value_name, uint64_t data) WI_NOEXCEPT + { + return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data); + } + + /** + * \brief Writes a REG_SZ value from a null-terminated string + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string value to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT + { + return ::wil::reg::set_value_nothrow(key, subkey, value_name, data); + } + + /** + * \brief Writes a REG_SZ value from a null-terminated string + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string value to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT + { + return ::wil::reg::set_value_nothrow(key, nullptr, value_name, data); + } + + /** + * \brief Writes a REG_EXPAND_SZ value from a null-terminated string + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string value to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.set_value(subkey, value_name, data, REG_EXPAND_SZ); + } + + /** + * \brief Writes a REG_EXPAND_SZ value from a null-terminated string + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param data The null-terminated string value to write to the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, PCWSTR data) WI_NOEXCEPT + { + return ::wil::reg::set_value_expanded_string_nothrow(key, nullptr, value_name, data); + } + +#if defined(__WIL_OBJBASE_H_) + /** + * \brief Writes raw bytes into a registry value under a specified key of the specified type + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param type The registry type for the specified registry value to write to - see RegSetValue + * \param value A ::wil::unique_cotaskmem_array_ptr holding the bytes to write into the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_binary_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type, const ::wil::unique_cotaskmem_array_ptr& value) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + RETURN_IF_FAILED(regview.set_value<::wil::unique_cotaskmem_array_ptr>(subkey, value_name, value, type)); + return S_OK; + } + + /** + * \brief Writes raw bytes into a registry value under a specified key of the specified type + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to write to the unnamed default registry value. + * \param type The registry type for the specified registry value to write to - see RegSetValue + * \param value A ::wil::unique_cotaskmem_array_ptr holding the bytes to write into the specified registry value + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT set_value_binary_nothrow(HKEY key, _In_opt_ PCWSTR value_name, uint32_t type, const ::wil::unique_cotaskmem_array_ptr& value) WI_NOEXCEPT + { + return ::wil::reg::set_value_binary_nothrow(key, nullptr, value_name, type, value); + } +#endif + +#if defined(WIL_ENABLE_EXCEPTIONS) + // + // template + // T get_value(...) + // + // - Reads a value under a specified key. + // - Requires a type T to be specified. + // - Throws a std::exception on failure (including wil::ResultException), including registry value not found. + // If you don't want an exception when the value does not exist, use try_get_value(...) + // + // Examples of usage (ensure the code handles a possible std::exception that will be thrown on all errors) + // uint32_t dword_value = wil::reg::get_value(key, L"subkey", L"dword_value_name"); + // uint64_t qword_value = wil::reg::get_value(key, L"subkey", L"qword_value_name); + // std::wstring string_value = wil::reg::get_value(key, L"subkey", L"string_value_name"); + // + // A subkey is not required if the key is opened where this should write the value: + // uint32_t dword_value = wil::reg::get_value(key, L"dword_value_name"); + // uint64_t qword_value = wil::reg::get_value(key, L"qword_value_name); + // std::wstring string_value = wil::reg::get_value(key, L"string_value_name"); + // + // The template type does not need to be specified if using functions written for a targeted type + // uint32_t dword_value = wil::reg::get_value_dword(key, L"dword_value_name"); + // uint64_t qword_value = wil::reg::get_value_qword(key, L"qword_value_name"); + // std::wstring string_value = wil::reg::get_value_string(key, L"string_value_name"); + // + // Values with REG_EXPAND_SZ can be read into each of the string types; e.g.: + // std::wstring expanded_string_value = wil::reg::get_value_expanded_string(key, L"string_value_name_with_environment_variables"); + // + // Values can be read directly into a vector of bytes - the registry type must be specified; e.g.: + // std::vector data = wil::reg::get_value_binary(key, L"binary_value_name", REG_BINARY); + // + // Multi-string values can be read into a vector; e.g.: + // std::vector multi_string_value = wil::reg::get_value_multistring(key, L"multi_string_value_name"); + // for (const auto& sub_string_value : multi_string_value) + // { + // // can read each string parsed from the multi-string + // PCWSTR string_value = sub_string_value.c_str(); + // } + // + // Reading REG_SZ and REG_EXPAND_SZ types are done through the below templated get_value_string and get_value_expanded_string functions + // Where the template type is the type to receive the string value + // The default template type is std::wstring, available if the caller has included the STL header + // + // Reading a bstr can be stored in a wil::shared_bstr or wil::unique_bstr - wil::shared_bstr has a c'tor taking a wil::unique_bstr + // wil::unique_bstr unique_value { wil::reg::get_value_string<::wil::unique_bstr>(key, L"string_value_name") }; + // wil::shared_bstr shared_value { wil::reg::get_value_string<::wil::shared_bstr>(key, L"string_value_name") }; + // + // Reading a cotaskmem string can be stored in a wil::unique_cotaskmem_string or wil::shared_cotaskmem_string + // wil::unique_cotaskmem_string unique_value { wil::reg::get_value_string(key, L"string_value_name") }; + // wil::shared_cotaskmem_string shared_value { wil::reg::get_value_string(key, L"string_value_name") }; + // + // Blocking get_value_string template types that are not already specialized - this gives a much friendlier compiler error message + template + T get_value_string(HKEY /*key*/, _In_opt_ PCWSTR /*subkey*/, _In_opt_ PCWSTR /*value_name*/) + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_string"); + } + + template + T get_value_string(HKEY /*key*/, _In_opt_ PCWSTR /*value_name*/) + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_string"); + } + + template + T get_value_expanded_string(HKEY /*key*/, _In_opt_ PCWSTR /*subkey*/, _In_opt_ PCWSTR /*value_name*/) + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_expanded_string"); + } + + template + T get_value_expanded_string(HKEY /*key*/, _In_opt_ PCWSTR /*value_name*/) + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_expanded_string"); + } + + /** + * \brief Reads a value from a specified key and subkey, deducing registry type from the type parameter T. + * \tparam T The type to read (the registry value type is deduced from T) + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type T + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template + T get_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + T return_value{}; + const reg_view_details::reg_view regview{ key }; + regview.get_value(subkey, value_name, return_value); + return return_value; + } + + /** + * \brief Reads a value under a specified key, deducing registry type from the type parameter T. + * \tparam T The type to read (the registry value type is deduced from T) + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type T + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template + T get_value(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_DWORD value, returning a uint32_t + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The uint32_t value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline uint32_t get_value_dword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value(key, subkey, value_name); + } + + /** + * \brief Reads a REG_DWORD value, returning a uint32_t + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The uint32_t value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline uint32_t get_value_dword(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_QWORD value, returning a uint64_t + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The uint64_t value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline uint64_t get_value_qword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value(key, subkey, value_name); + } + + /** + * \brief Reads a REG_QWORD value, returning a uint64_t + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The uint64_t value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline uint64_t get_value_qword(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value(key, nullptr, value_name); + } + +#if defined(_STRING_) + /** + * \brief Reads a REG_SZ value, returning a std::wstring + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A std::wstring created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline ::std::wstring get_value_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::std::wstring>(key, subkey, value_name); + } + + /** + * \brief Reads a REG_SZ value, returning a std::wstring + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A std::wstring created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline ::std::wstring get_value_string(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::std::wstring>(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_SZ value, returning a std::wstring + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A std::wstring created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::std::wstring get_value_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::std::wstring>(key, subkey, value_name); + } + + /** + * \brief Reads a REG_SZ value, returning a std::wstring + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A std::wstring created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::std::wstring get_value_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::std::wstring>(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a std::wstring + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A std::wstring created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline ::std::wstring get_value_expanded_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + ::std::wstring value; + const reg_view_details::reg_view regview{ key }; + regview.get_value(subkey, value_name, value, REG_EXPAND_SZ); + return value; + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a std::wstring + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A std::wstring created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline ::std::wstring get_value_expanded_string(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value_expanded_string(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a std::wstring + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A std::wstring created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::std::wstring get_value_expanded_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value_expanded_string(key, subkey, value_name); + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a std::wstring + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A std::wstring created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::std::wstring get_value_expanded_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value_expanded_string(key, nullptr, value_name); + } +#endif // #if defined(_STRING_) + +#if defined(__WIL_OLEAUTO_H_) + /** + * \brief Reads a REG_SZ value, returning a wil::unique_bstr + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::unique_bstr created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::unique_bstr get_value_string<::wil::unique_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::wil::unique_bstr>(key, subkey, value_name); + } + + /** + * \brief Reads a REG_SZ value, returning a wil::unique_bstr + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::unique_bstr created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::unique_bstr get_value_string<::wil::unique_bstr>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::wil::unique_bstr>(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a wil::unique_bstr + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::unique_bstr created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::unique_bstr get_value_expanded_string<::wil::unique_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + ::wil::unique_bstr value; + const reg_view_details::reg_view regview{ key }; + regview.get_value(subkey, value_name, value, REG_EXPAND_SZ); + return value; + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a wil::unique_bstr + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::unique_bstr created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::unique_bstr get_value_expanded_string<::wil::unique_bstr>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value_expanded_string<::wil::unique_bstr>(key, nullptr, value_name); + } +#if defined(__WIL_OLEAUTO_H_STL) + /** + * \brief Reads a REG_SZ value, returning a wil::shared_bstr + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::shared_bstr created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::shared_bstr get_value_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::wil::shared_bstr>(key, subkey, value_name); + } + + /** + * \brief Reads a REG_SZ value, returning a wil::shared_bstr + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::shared_bstr created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::shared_bstr get_value_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::wil::shared_bstr>(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a wil::unique_bstr + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::shared_bstr created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::shared_bstr get_value_expanded_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + ::wil::shared_bstr value; + const reg_view_details::reg_view regview{ key }; + regview.get_value(subkey, value_name, value, REG_EXPAND_SZ); + return value; + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a wil::shared_bstr + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::shared_bstr created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::shared_bstr get_value_expanded_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value_expanded_string<::wil::shared_bstr>(key, nullptr, value_name); + } +#endif // #if defined(__WIL_OLEAUTO_H_STL) +#endif // #if defined(__WIL_OLEAUTO_H_) + +#if defined(__WIL_OBJBASE_H_) + /** + * \brief Reads a REG_SZ value, returning a wil::unique_cotaskmem_string + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::unique_cotaskmem_string created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::unique_cotaskmem_string get_value_string<::wil::unique_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::wil::unique_cotaskmem_string>(key, subkey, value_name); + } + + /** + * \brief Reads a REG_SZ value, returning a wil::unique_cotaskmem_string + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::unique_cotaskmem_string created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::unique_cotaskmem_string get_value_string<::wil::unique_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::wil::unique_cotaskmem_string>(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a wil::unique_cotaskmem_string + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::unique_cotaskmem_string created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::unique_cotaskmem_string get_value_expanded_string<::wil::unique_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + ::wil::unique_cotaskmem_string value; + const reg_view_details::reg_view regview{ key }; + regview.get_value(subkey, value_name, value, REG_EXPAND_SZ); + return value; + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a wil::unique_cotaskmem_string + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::unique_cotaskmem_string created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::unique_cotaskmem_string get_value_expanded_string<::wil::unique_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name) + { + return wil::reg::get_value_expanded_string<::wil::unique_cotaskmem_string>(key, nullptr, value_name); + } +#if defined(__WIL_OBJBASE_H_STL) + /** + * \brief Reads a REG_SZ value, returning a wil::shared_cotaskmem_string + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::shared_cotaskmem_string created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::shared_cotaskmem_string get_value_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::wil::shared_cotaskmem_string>(key, subkey, value_name); + } + + /** + * \brief Reads a REG_SZ value, returning a wil::shared_cotaskmem_string + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::shared_cotaskmem_string created from the string value read from the registry + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::shared_cotaskmem_string get_value_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::wil::shared_cotaskmem_string>(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a wil::shared_cotaskmem_string + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::shared_cotaskmem_string created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::shared_cotaskmem_string get_value_expanded_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + ::wil::shared_cotaskmem_string value; + const reg_view_details::reg_view regview{ key }; + regview.get_value(subkey, value_name, value, REG_EXPAND_SZ); + return value; + } + + /** + * \brief Reads a REG_EXPAND_SZ value, returning a wil::shared_cotaskmem_string + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A wil::shared_cotaskmem_string created from the string value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + template <> + inline ::wil::shared_cotaskmem_string get_value_expanded_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name) + { + return wil::reg::get_value_expanded_string<::wil::shared_cotaskmem_string>(key, nullptr, value_name); + } +#endif // #if defined(__WIL_OBJBASE_H_STL) +#endif // defined(__WIL_OBJBASE_H_) + +#if defined(_VECTOR_) + /** + * \brief Reads a registry value of the specified type, returning a std::vector + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \param type The registry type for the specified registry value to read from - see RegGetValueW + * \return A std::vector containing the bytes of the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline ::std::vector get_value_binary(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type) + { + ::std::vector return_value{}; + const reg_view_details::reg_view regview{ key }; + regview.get_value(subkey, value_name, return_value, type); + return return_value; + } + + /** + * \brief Reads a registry value of the specified type, returning a std::vector + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \param type The registry type for the specified registry value to read from - see RegGetValueW + * \return A std::vector containing the bytes of the specified registry value + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + */ + inline ::std::vector get_value_binary(HKEY key, _In_opt_ PCWSTR value_name, uint32_t type) + { + return ::wil::reg::get_value_binary(key, nullptr, value_name, type); + } +#endif // #if defined(_VECTOR_) + +#if defined(_VECTOR_) && defined(_STRING_) + /** + * \brief Reads a REG_MULTI_SZ value, returning a std::vector + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A vector of strings read from the REG_MULTI_SZ. Note: embedded nulls will be read as empty strings. See remarks. + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + * + * \remark Note that will return empty strings for embedded nulls - it won't stop at the first double-null character + * e.g. a REG_MULTI_SZ of L"string1\0\0string2\0\0string3\0\0" + * returns a vector of size 5: L"string1", empty-string, L"string2", empty-string, L"string3" + */ + template <> + inline ::std::vector<::std::wstring> get_value<::std::vector<::std::wstring>>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + ::std::vector<::std::wstring> return_value; + ::std::vector rawData{ ::wil::reg::get_value_binary(key, subkey, value_name, REG_MULTI_SZ) }; + if (!rawData.empty()) + { + auto* const begin = reinterpret_cast(rawData.data()); + auto* const end = begin + rawData.size() / sizeof(wchar_t); + return_value = ::wil::reg::reg_view_details::get_wstring_vector_from_multistring(begin, end); + } + + return return_value; + } + + /** + * \brief Reads a REG_MULTI_SZ value, returning a std::vector + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A vector of strings read from the REG_MULTI_SZ. Note: embedded nulls will be read as empty strings. See remarks. + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + * + * \remark Note that will return empty strings for embedded nulls - it won't stop at the first double-null character + * e.g. a REG_MULTI_SZ of L"string1\0\0string2\0\0string3\0\0" + * returns a vector of size 5: L"string1", empty-string, L"string2", empty-string, L"string3" + */ + template <> + inline ::std::vector<::std::wstring> get_value<::std::vector<::std::wstring>>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::std::vector<::std::wstring>>(key, nullptr, value_name); + } + + /** + * \brief Reads a REG_MULTI_SZ value, returning a std::vector + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A vector of strings read from the REG_MULTI_SZ. Note: embedded nulls will be read as empty strings. See remarks. + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + * + * \remark Note that will return empty strings for embedded nulls - it won't stop at the first double-null character + * e.g. a REG_MULTI_SZ of L"string1\0\0string2\0\0string3\0\0" + * returns a vector of size 5: L"string1", empty-string, L"string2", empty-string, L"string3" + */ + inline ::std::vector<::std::wstring> get_value_multistring(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::std::vector<::std::wstring>>(key, subkey, value_name); + } + + /** + * \brief Reads a REG_MULTI_SZ value, returning a std::vector + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return A vector of strings read from the REG_MULTI_SZ. Note: embedded nulls will be read as empty strings. See remarks. + * \exception std::exception (including wil::ResultException) will be thrown on all failures, including value not found + * + * \remark Note that will return empty strings for embedded nulls - it won't stop at the first double-null character + * e.g. a REG_MULTI_SZ of L"string1\0\0string2\0\0string3\0\0" + * returns a vector of size 5: L"string1", empty-string, L"string2", empty-string, L"string3" + */ + inline ::std::vector<::std::wstring> get_value_multistring(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::get_value<::std::vector<::std::wstring>>(key, nullptr, value_name); + } +#endif // #if defined(_VECTOR_) && defined(_STRING_) + +#if defined (_OPTIONAL_) && defined(__cpp_lib_optional) + // + // template + // void try_get_value(...) + // + // - Reads a value under a specified key and subkey, deducing registry type from the type parameter T. + // - throws a std::exception on failure (including wil::ResultException), except if the registry value was not found + // returns a std::nullopt if the registry value is not found + // + // Examples using the returned std::optional + // - Caller should ensure the code handles a possible std::exception that will be thrown on all errors except value not found + // + // std::optional opt_dword_value = wil::reg::try_get_value(key, L"dword_value_name"); + // if (opt_dword_value.has_value()) + // { + // // opt_dword_value.value() returns the uint32_t read from the registry + // } + // else + // { + // // the registry value did not exist + // } + // // if the caller wants to apply a default value of 0, they can call value_or() + // uint32_t opt_dword_value = wil::reg::try_get_value(key, L"dword_value_name").value_or(0); + // + // Examples using the returned std::optional + // std::optional opt_string_value = wil::reg::try_get_value_string(key, L"string_value_name"); + // if (opt_string_value.has_value()) + // { + // // opt_string_value.value() returns the std::wstring read from the registry + // // the below avoids copying the std::wstring as value() here returns a std::wstring& + // PCWSTR string_value = opt_string_value.value().c_str(); + // } + // else + // { + // // the registry value did not exist + // } + // + // // if the caller wants to apply a default value of L"default", they can call value_or() + // // note that std::optional only attempts to construct a std::wstring for L"default" if the std::optional is empty (std::nullopt) + // // thus only allocating a new std::wstring for the default value when it's needed + // std::optional opt_string_value = wil::reg::try_get_value_string(key, L"string_value_name").value_or(L"default"); + // + // Examples of usage: + // std::optional opt_dword_value = wil::reg::try_get_value(key, L"subkey", L"dword_value_name"); + // std::optional opt_qword_value = wil::reg::try_get_value(key, L"subkey", L"qword_value_name); + // std::optional opt_string_value = wil::reg::try_get_value(key, L"subkey", L"string_value_name"); + // + // A subkey is not required if the key is opened where this should write the value; e.g. + // std::optional opt_dword_value = wil::reg::try_get_value(key, L"dword_value_name"); + // std::optional opt_qword_value = wil::reg::try_get_value(key, L"qword_value_name); + // std::optional opt_string_value = wil::reg::try_get_value(key, L"string_value_name"); + // + // The template type does not need to be specified if using functions written for a targeted type; e.g. + // std::optional opt_dword_value = wil::reg::try_get_value_dword(key, L"dword_value_name"); + // std::optional opt_qword_value = wil::reg::try_get_value_qword(key, L"qword_value_name"); + // std::optional opt_string_value = wil::reg::try_get_value_string(key, L"string_value_name"); + // + // Values with REG_EXPAND_SZ can be read into each of the string types; e.g.: + // std::optional opt_expanded_string_value = wil::reg::try_get_value_expanded_string(key, L"string_value_name_with_environment_variables"); + // + // Values can be read directly into a vector of bytes - the registry type must be specified; e.g.: + // std::optional> opt_data = wil::reg::try_get_value_binary(key, L"binary_value_name", REG_BINARY); + // + // Multi-string values can be read into a std::vector; e.g.: + // std::optional<::std::vector<::std::wstring>> try_get_value_multistring(key, L"multi_string_value_name"); + // See the definition of try_get_value_multistring before for usage guidance + // + // Reading REG_SZ and REG_EXPAND_SZ types are done through the below templated try_get_value_string and try_get_value_expanded_string functions + // Where the template type is the type to receive the string value + // The default template type is std::wstring, available if the caller has included the STL header + // + // Reading a bstr is returned in a std::optional - because wil::unique_bstr cannot be copied and thus is difficult to work with a std::optional + // std::optional shared_value { wil::reg::try_get_value_string<::wil::shared_bstr>(key, L"string_value_name") }; + // + // Reading a cotaskmem string is returned in a std::optional - because wil::unique_cotaskmem_string cannot be copied and thus is difficult to work with a std::optional + // std::optional opt_shared_value { wil::reg::try_get_value_string(key, L"string_value_name") }; + // + // Blocking try_get_value_string template types that are not already specialized - this gives a much friendlier compiler error message + template + ::std::optional try_get_value_string(HKEY /*key*/, _In_opt_ PCWSTR /*subkey*/, _In_opt_ PCWSTR /*value_name*/) + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for try_get_value_string"); + } + + template + ::std::optional try_get_value_string(HKEY /*key*/, _In_opt_ PCWSTR /*value_name*/) + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for try_get_value_string"); + } + + template + ::std::optional try_get_value_expanded_string(HKEY /*key*/, _In_opt_ PCWSTR /*subkey*/, _In_opt_ PCWSTR /*value_name*/) + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for try_get_value_expanded_string"); + } + + template + ::std::optional try_get_value_expanded_string(HKEY /*key*/, _In_opt_ PCWSTR /*value_name*/) + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for try_get_value_expanded_string"); + } + + /** + * \brief Attempts to read a value under a specified key and subkey, returning in a std::optional, deducing registry type from the type parameter T. + * \tparam T The type to read, which will be placed into a std::optional (the registry value type is deduced from T) + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value (of type T) read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template + ::std::optional try_get_value(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { +#if defined(__WIL_OLEAUTO_H_) + // not allowing unique types with try_get_value: wil::unique_bstr cannot be copied and thus is difficult to work with a std::optional + static_assert(!wistd::is_same_v, "try_get with wil::unique_bstr is disabled"); +#endif // #if defined(__WIL_OLEAUTO_H_) +#if defined(__WIL_OBJBASE_H_) + // not allowing unique types with try_get_value: wil::unique_cotaskmem_string cannot be copied and thus is difficult to work with a std::optional + static_assert(!wistd::is_same_v, "try_get with wil::unique_cotaskmem_string is disabled"); +#endif // #if defined(__WIL_OBJBASE_H_) + + const reg_view_details::reg_view regview{ key }; + return regview.try_get_value(subkey, value_name); + } + + /** + * \brief Attempts to read a value under a specified key, returning the value in a std::optional, deducing registry type from the type parameter T. + * \tparam T The type to read, which will be placed into a std::optional (the registry value type is deduced from T) + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value (of type T) read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template + ::std::optional try_get_value(HKEY key, _In_opt_ PCWSTR value_name) + { +#if defined(__WIL_OLEAUTO_H_) + // not allowing unique types with try_get_value: wil::unique_bstr cannot be copied and thus is difficult to work with a std::optional + static_assert(!wistd::is_same_v, "try_get with wil::unique_bstr is disabled"); +#endif // #if defined(__WIL_OLEAUTO_H_) +#if defined(__WIL_OBJBASE_H_) + // not allowing unique types with try_get_value: wil::unique_cotaskmem_string cannot be copied and thus is difficult to work with a std::optional + static_assert(!wistd::is_same_v, "try_get with wil::unique_cotaskmem_string is disabled"); +#endif // #if defined(__WIL_OBJBASE_H_) + + return ::wil::reg::try_get_value(key, nullptr, value_name); + } + + /** + * \brief Attempts to read a REG_DWORD value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional try_get_value_dword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value(key, subkey, value_name); + } + + /** + * \brief Attempts to read a REG_DWORD value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional try_get_value_dword(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value(key, nullptr, value_name); + } + + /** + * \brief Attempts to read a REG_QWORD value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional try_get_value_qword(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value(key, subkey, value_name); + } + + /** + * \brief Attempts to read a REG_QWORD value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional try_get_value_qword(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value(key, nullptr, value_name); + } + +#if defined(_VECTOR_) + /** + * \brief Attempts to read a value under a specified key requiring the specified type, returning the raw bytes in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \param type The registry type for the specified registry value to read from - see RegGetValueW + * \return The raw bytes read from the registry value stored in a std::optional>. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional<::std::vector> try_get_value_binary(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type) + { + const reg_view_details::reg_view regview{ key }; + return regview.try_get_value<::std::vector>(subkey, value_name, type); + } + + /** + * \brief Attempts to read a value under a specified key requiring the specified type, returning the raw bytes in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \param type The registry type for the specified registry value to read from - see RegGetValueW + * \return The raw bytes read from the registry value stored in a std::optional>. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional<::std::vector> try_get_value_binary(HKEY key, _In_opt_ PCWSTR value_name, uint32_t type) + { + return ::wil::reg::try_get_value_binary(key, nullptr, value_name, type); + } +#endif // #if defined(_VECTOR_) + +#if defined(_STRING_) + /** + * \brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional<::std::wstring> try_get_value_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + const reg_view_details::reg_view regview{ key }; + return regview.try_get_value<::std::wstring>(subkey, value_name); + } + + /** + * \brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional<::std::wstring> try_get_value_string(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_string(key, nullptr, value_name); + } + + /** + * \brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::std::wstring> try_get_value_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_string(key, subkey, value_name); + } + + /** + * \brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value, in a std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::std::wstring> try_get_value_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_string(key, nullptr, value_name); + } + + /** + * \brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional<::std::wstring> try_get_value_expanded_string(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + const reg_view_details::reg_view regview{ key }; + return regview.try_get_value<::std::wstring>(subkey, value_name, REG_EXPAND_SZ); + } + + /** + * \brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional<::std::wstring> try_get_value_expanded_string(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_expanded_string(key, nullptr, value_name); + } + + /** + * \brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::std::wstring> try_get_value_expanded_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_expanded_string(key, subkey, value_name); + } + + /** + * \brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::std::wstring> try_get_value_expanded_string<::std::wstring>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_expanded_string(key, nullptr, value_name); + } +#endif // #if defined(_STRING_) + +#if defined(__WIL_OLEAUTO_H_STL) + /** + * \brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::wil::shared_bstr> try_get_value_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + const reg_view_details::reg_view regview{ key }; + return regview.try_get_value<::wil::shared_bstr>(subkey, value_name); + } + + /** + * \brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::wil::shared_bstr> try_get_value_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_string<::wil::shared_bstr>(key, nullptr, value_name); + } + + /** + * \brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::wil::shared_bstr> try_get_value_expanded_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + const reg_view_details::reg_view regview{ key }; + return regview.try_get_value<::wil::shared_bstr>(subkey, value_name, REG_EXPAND_SZ); + } + + /** + * \brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::wil::shared_bstr> try_get_value_expanded_string<::wil::shared_bstr>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_expanded_string<::wil::shared_bstr>(key, nullptr, value_name); + } +#endif // #if defined(__WIL_OLEAUTO_H_STL) + +#if defined(__WIL_OBJBASE_H_STL) + /** + * \brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::wil::shared_cotaskmem_string> try_get_value_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + const reg_view_details::reg_view regview{ key }; + return regview.try_get_value<::wil::shared_cotaskmem_string>(subkey, value_name); + } + + /** + * \brief Attempts to read a REG_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::wil::shared_cotaskmem_string> try_get_value_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_string<::wil::shared_cotaskmem_string>(key, nullptr, value_name); + } + + /** + * \brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional<:wil::shared_cotaskmem_string>, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::wil::shared_cotaskmem_string> try_get_value_expanded_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + const reg_view_details::reg_view regview{ key }; + return regview.try_get_value<::wil::shared_cotaskmem_string>(subkey, value_name, REG_EXPAND_SZ); + } + + /** + * \brief Attempts to read a REG_EXPAND_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value of the template type std::optional, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::wil::shared_cotaskmem_string> try_get_value_expanded_string<::wil::shared_cotaskmem_string>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value_expanded_string<::wil::shared_cotaskmem_string>(key, nullptr, value_name); + } +#endif // defined(__WIL_OBJBASE_H_STL) + +#if defined (_VECTOR_) && defined (_STRING_) + /** + * \brief Attempts to read a REG_MULTI_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value marshaled to a std::optional>. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::std::vector<::std::wstring>> try_get_value<::std::vector<::std::wstring>>(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + ::std::vector<::std::wstring> value; + const auto hr = ::wil::ResultFromException([&] { + value = ::wil::reg::get_value_multistring(key, subkey, value_name); + }); + if (SUCCEEDED(hr)) + { + return { value }; + } + + if (::wil::reg::is_registry_not_found(hr)) + { + return { ::std::nullopt }; + } + + THROW_HR(HRESULT_FROM_WIN32(hr)); + } + + /** + * \brief Attempts to read a REG_MULTI_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value marshaled to a std::optional>. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + template <> + inline ::std::optional<::std::vector<::std::wstring>> try_get_value<::std::vector<::std::wstring>>(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value<::std::vector<::std::wstring>>(key, nullptr, value_name); + } + + /** + * \brief Attempts to read a REG_MULTI_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value marshaled to a std::optional>. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional<::std::vector<::std::wstring>> try_get_value_multistring(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value<::std::vector<::std::wstring>>(key, subkey, value_name); + } + + /** + * \brief Attempts to read a REG_MULTI_SZ value under a specified key, returning the value in a std::optional + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be updated. + * Can be nullptr to read from the unnamed default registry value. + * \return The value read from the registry value marshaled to a std::optional>. + * Returns std::nullopt if the value does not exist. + * \exception std::exception (including wil::ResultException) will be thrown on failures except value not found + */ + inline ::std::optional<::std::vector<::std::wstring>> try_get_value_multistring(HKEY key, _In_opt_ PCWSTR value_name) + { + return ::wil::reg::try_get_value<::std::vector<::std::wstring>>(key, nullptr, value_name); + } +#endif // #if defined (_VECTOR_) && defined (_STRING_) +#endif // #if defined (_OPTIONAL_) && defined(__cpp_lib_optional) +#endif // #if defined(WIL_ENABLE_EXCEPTIONS) + + // + // template + // HRESULT get_value_nothrow(...) + // + // - Reads a value from under a specified key + // - The required type of registry value being read from is determined by the template type T + // - Returns an HRESULT error code indicating success or failure (does not throw C++ exceptions) + // + // Examples of usage (the template type does not need to be explicitly specified) + // uint32_t dword_value{}; + // hr = wil::reg::get_value_nothrow(key, L"subkey", L"dword_value_name", &dword_value); // reads a REG_DWORD + // uint64_t qword_value{}; + // hr = wil::reg::get_value_nothrow(key, L"subkey", L"qword_value_name", &qword_value); // reads a REG_QWORD + // wil::unique_bstr string_value{}; + // hr = wil::reg::get_value_nothrow(key, L"subkey", L"string_value_name", string_value); // reads a REG_SZ + // + // A subkey is not required if the key is opened where this should write the value: + // hr = wil::reg::get_value_nothrow(key, L"dword_value_name", &dword_value); // reads a REG_DWORD + // hr = wil::reg::get_value_nothrow(key, L"qword_value_name", &qword_value); // reads a REG_QWORD + // hr = wil::reg::get_value_nothrow(key, L"string_value_name", string_value); // reads a REG_SZ + // + // Can also specify the registry type in the function name: + // hr = wil::reg::get_value_dword_nothrow(key, L"dword_value_name", &dword_value); // reads a REG_DWORD + // hr = wil::reg::get_value_qword_nothrow(key, L"qword_value_name", &qword_value); // reads a REG_QWORD + // hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", string_value); // reads a REG_SZ + // + // Example storing directly into a WCHAR array - note will return the required number of bytes if the supplied array is too small + // WCHAR string_value[100]{}; + // uint32_t requiredBytes{}; + // hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", string_value, &requiredBytes); + // + // Example of usage writing a REG_MULTI_SZ + // wil::unique_cotaskmem_array_ptr string_values{}; + // hr = wil::reg::get_value_multistring_nothrow(key, L"multi_string_value_name", string_values); + // + // Values can be written directly from a vector of bytes - the registry type must be specified; e.g.: + // wil::unique_cotaskmem_array_ptr raw_value{}; + // hr = wil::reg::get_value_binary_nothrow(key, L"binary_value_name", REG_BINARY, raw_value); + // + // Reading REG_SZ and REG_EXPAND_SZ types are done through the below templated get_value_string_nothrow and get_value_expanded_string_nothrow functions + // Where the template type is the type to receive the string value + // The default template type is std::wstring, available if the caller has included the STL header + // + // Example storing a string in a wil::unique_bstr, wil::shared_bstr, wil::unique_cotaskmem_string, or wil::shared_cotaskmem_string + /// - These string types are passed by reference, not by pointer, because the wil types overload the & operator + // + // wil::unique_bstr bstr_value{}; + // hr = wil::reg::get_value_nothrow(key, L"string_value_name", bstr_value); + // // or can specify explicitly reading a string into a wil::unique_bstr type + // hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", bstr_value); + // + // wil::shared_bstr shared_bstr_value{}; + // hr = wil::reg::get_value_nothrow(key, L"string_value_name", shared_bstr_value); + // // or can specify explicitly reading a string into a wil::shared_bstr type + // hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", shared_bstr_value); + // + // wil::unique_cotaskmem_string string_value{}; + // hr = wil::reg::get_value_nothrow(key, L"string_value_name", string_value); + // // or can specify explicitly reading a string into a wil::unique_cotaskmem_string type + // hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", string_value); + // + // wil::shared_cotaskmem_string shared_string_value{}; + // hr = wil::reg::get_value_nothrow(key, L"string_value_name", shared_string_value); + // // or can specify explicitly reading a string into a wil::shared_cotaskmem_string type + // hr = wil::reg::get_value_string_nothrow(key, L"string_value_name", shared_string_value); + // + + /** + * \brief Reads a value under a specified key, the registry type based off the templated type passed as data + * \tparam T The type of the data being set (the registry value type is deduced from T). + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A pointer-to-T receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template >* = nullptr> + HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, _Out_ T* return_value) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value(subkey, value_name, *return_value); + } + + /** + * \brief Reads a value under a specified key, the registry type based off the templated type passed as data + * \tparam T The type of the data being set (the registry value type is deduced from T). + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A pointer-to-T receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template >* = nullptr> + HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, _Out_ T* return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \param[out] requiredBytes An optional pointer to a unsigned 32-bit value to receive the required bytes of the string in the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template || wistd::is_same_v>* = nullptr> + HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length], _Out_opt_ DwordType * requiredBytes) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value_char_array(subkey, value_name, return_value, REG_SZ, requiredBytes); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \param[out] requiredBytes An optional pointer to an unsigned 32-bit value to receive the required bytes of the string to be read + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template || wistd::is_same_v>* = nullptr> + HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length], _Out_opt_ DwordType * requiredBytes) WI_NOEXCEPT + { + return ::wil::reg::get_value_string_nothrow(key, nullptr, value_name, return_value, requiredBytes); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template + HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length]) WI_NOEXCEPT + { + constexpr uint32_t* null_out_param = nullptr; + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value_char_array(subkey, value_name, return_value, REG_SZ, null_out_param); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template + HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length]) WI_NOEXCEPT + { + return ::wil::reg::get_value_string_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template + HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length]) WI_NOEXCEPT + { + return ::wil::reg::get_value_string_nothrow(key, subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template + HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length]) WI_NOEXCEPT + { + return ::wil::reg::get_value_string_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_DWORD value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A pointer to an unsigned 32-bit value receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template || wistd::is_same_v>* = nullptr> + HRESULT get_value_dword_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, _Out_ DwordType * return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_DWORD value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A pointer to an unsigned 32-bit value receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template || wistd::is_same_v>* = nullptr> + HRESULT get_value_dword_nothrow(HKEY key, _In_opt_ PCWSTR value_name, _Out_ DwordType * return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_QWORD value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A uint64_t receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template || wistd::is_same_v>* = nullptr> + HRESULT get_value_qword_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, _Out_ QwordType * return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_QWORD value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A uint64_t receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template || wistd::is_same_v>* = nullptr> + HRESULT get_value_qword_nothrow(HKEY key, _In_opt_ PCWSTR value_name, _Out_ QwordType * return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + +#if defined(__WIL_OLEAUTO_H_) + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_bstr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value(subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_bstr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_bstr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value.addressof()); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_bstr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_string_nothrow(key, nullptr, value_name, return_value); + } + +#if defined(__WIL_OLEAUTO_H_STL) + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_bstr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value(subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_bstr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_bstr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value.addressof()); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_bstr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_string_nothrow(key, nullptr, value_name, return_value); + } +#endif // #if defined(__WIL_OLEAUTO_H_STL) +#endif // #if defined(__WIL_OLEAUTO_H_) + +#if defined(__WIL_OBJBASE_H_) + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT + { + return_value.reset(); + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value(subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + +#if defined(__WIL_OBJBASE_H_STL) + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT + { + return_value.reset(); + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value(subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } +#endif // #if defined(__WIL_OBJBASE_H_STL) +#endif // defined(__WIL_OBJBASE_H_) + +#if defined(__WIL_OBJBASE_H_) + /** + * \brief Reads the raw bytes from a registry value under a specified key of the specified type + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param type The registry type for the specified registry value to read from - see RegGetValueW + * \param[out] return_value A ::wil::unique_cotaskmem_array_ptr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_binary_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, uint32_t type, ::wil::unique_cotaskmem_array_ptr& return_value) WI_NOEXCEPT + { + // zero the vector if it already had a buffer + for (auto& byte_value : return_value) + { + byte_value = 0x00; + } + const reg_view_details::reg_view_nothrow regview{ key }; + RETURN_IF_FAILED(regview.get_value<::wil::unique_cotaskmem_array_ptr>(subkey, value_name, return_value, type)); + return S_OK; + } + + /** + * \brief Reads the raw bytes from a registry value under a specified key of the specified type + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param type The registry type for the specified registry value to read from - see RegGetValueW + * \param[out] return_value A ::wil::unique_cotaskmem_array_ptr receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_binary_nothrow(HKEY key, _In_opt_ PCWSTR value_name, uint32_t type, ::wil::unique_cotaskmem_array_ptr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_binary_nothrow(key, nullptr, value_name, type, return_value); + } +#endif// #if defined(__WIL_OBJBASE_H_) + + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \param[out] requiredBytes An optional pointer to a uint32_t to receive the required bytes of the string to be read + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template || wistd::is_same_v>* = nullptr> + HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length], _Out_opt_ DwordType * requiredBytes) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value_char_array(subkey, value_name, return_value, REG_EXPAND_SZ, requiredBytes); + } + + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \param[out] requiredBytes An optional pointer to a uint32_t to receive the required bytes of the string to be read + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template || wistd::is_same_v>* = nullptr> + HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length], _Out_opt_ DwordType * requiredBytes) WI_NOEXCEPT + { + return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value, requiredBytes); + } + + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template + HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length]) WI_NOEXCEPT + { + constexpr uint32_t* null_out_param = nullptr; + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value_char_array(subkey, value_name, return_value, REG_EXPAND_SZ, null_out_param); + } + + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \tparam Length The length of the WCHAR array passed as an OUT parameter + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A WCHAR array receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * Will write to the WCHAR array the string value read from the registry, guaranteeing null-termination + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + template + HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length]) WI_NOEXCEPT + { + return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value); + } + + +#if defined(__WIL_OLEAUTO_H_) + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_bstr receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value<::wil::unique_bstr>(subkey, value_name, return_value, REG_EXPAND_SZ); + } + + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_bstr receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_bstr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value); + } + +#if defined(__WIL_OLEAUTO_H_STL) + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_bstr receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value<::wil::shared_bstr>(subkey, value_name, return_value, REG_EXPAND_SZ); + } + + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_bstr receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_bstr& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value); + } +#endif // #if defined(__WIL_OLEAUTO_H_STL) +#endif // #if defined(__WIL_OLEAUTO_H_) + +#if defined(__WIL_OBJBASE_H_) + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value<::wil::unique_cotaskmem_string>(subkey, value_name, return_value, REG_EXPAND_SZ); + } + + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::unique_cotaskmem_string receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_string& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value); + } + +#if defined(__WIL_OBJBASE_H_STL) + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT + { + const reg_view_details::reg_view_nothrow regview{ key }; + return regview.get_value<::wil::shared_cotaskmem_string>(subkey, value_name, return_value, REG_EXPAND_SZ); + } + + /** + * \brief Reads a REG_EXPAND_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A wil::shared_cotaskmem_string receiving the value read from the registry, + * with environment variables expanded, as though passed through ExpandEnvironmentStringsW. + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_expanded_string_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::shared_cotaskmem_string& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_expanded_string_nothrow(key, nullptr, value_name, return_value); + } +#endif // #if defined(__WIL_OBJBASE_H_STL) +#endif // defined(__WIL_OBJBASE_H_) + +#if defined(__WIL_OBJBASE_H_) + /** + * \brief Reads a REG_MULTI_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string> receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& return_value) WI_NOEXCEPT + { + ::wil::unique_cotaskmem_array_ptr rawData; + RETURN_IF_FAILED(::wil::reg::get_value_binary_nothrow(key, subkey, value_name, REG_MULTI_SZ, rawData)); + if (!rawData.empty()) + { + auto* const begin = reinterpret_cast(rawData.data()); + auto* const end = begin + rawData.size() / sizeof(wchar_t); + ::wil::reg::reg_view_details::get_cotaskmemstring_array_from_multistring_nothrow(begin, end, return_value); + } + return S_OK; + } + + /** + * \brief Reads a REG_MULTI_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string> receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } + + /** + * \brief Reads a REG_MULTI_SZ value under a specified key + * \param key An open or well-known registry key + * \param subkey The name of the subkey to append to `key`. + * If `nullptr`, then `key` is used without modification. + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string> receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_multistring_nothrow(HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, subkey, value_name, return_value); + } + + /** + * \brief Reads a REG_MULTI_SZ value under a specified key + * \param key An open or well-known registry key + * \param value_name The name of the registry value whose data is to be read. + * Can be nullptr to read from the unnamed default registry value. + * \param[out] return_value A ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string> receiving the value read from the registry + * \return HRESULT error code indicating success or failure (does not throw C++ exceptions) + */ + inline HRESULT get_value_multistring_nothrow(HKEY key, _In_opt_ PCWSTR value_name, ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& return_value) WI_NOEXCEPT + { + return ::wil::reg::get_value_nothrow(key, nullptr, value_name, return_value); + } +#endif // #if defined(__WIL_OBJBASE_H_) + } + + // unique_registry_watcher/unique_registry_watcher_nothrow/unique_registry_watcher_failfast + // These classes make it easy to execute a provided function when a + // registry key changes (optionally recursively). Specify the key + // either as a root key + path, or an open registry handle as wil::unique_hkey + // or a raw HKEY value (that will be duplicated). + // + // Example use with exceptions base error handling: + // auto watcher = wil::make_registry_watcher(HKEY_CURRENT_USER, L"Software\\MyApp", true, wil::RegistryChangeKind changeKind[] + // { + // if (changeKind == RegistryChangeKind::Delete) + // { + // watcher.reset(); + // } + // // invalidate cached registry data here + // }); + // + // Example use with error code base error handling: + // auto watcher = wil::make_registry_watcher_nothrow(HKEY_CURRENT_USER, L"Software\\MyApp", true, wil::RegistryChangeKind[] + // { + // // invalidate cached registry data here + // }); + // RETURN_IF_NULL_ALLOC(watcher); + + enum class RegistryChangeKind + { + Modify = 0, + Delete = 1, + }; + + /// @cond + namespace details + { + struct registry_watcher_state + { + registry_watcher_state(unique_hkey&& keyToWatch, bool isRecursive, wistd::function&& callback) + : m_callback(wistd::move(callback)), m_keyToWatch(wistd::move(keyToWatch)), m_isRecursive(isRecursive) + { + } + wistd::function m_callback; + unique_hkey m_keyToWatch; + unique_event_nothrow m_eventHandle; + + // While not strictly needed since this is ref counted the thread pool wait + // should be last to ensure that the other members are valid + // when it is destructed as it will reference them. + unique_threadpool_wait m_threadPoolWait; + bool m_isRecursive; + + volatile long m_refCount = 1; + srwlock m_lock; + + // Returns true if the ref-count can be increased from a non zero value, + // false it was zero implying that the object is in or on the way to the destructor. + // In this case ReleaseFromCallback() should not be called. + bool TryAddRef() + { + return ::InterlockedIncrement(&m_refCount) > 1; + } + + void Release() + { + auto lock = m_lock.lock_exclusive(); + if (0 == ::InterlockedDecrement(&m_refCount)) + { + lock.reset(); // leave the lock before deleting it. + delete this; + } + } + + void ReleaseFromCallback(bool rearm) + { + auto lock = m_lock.lock_exclusive(); + if (0 == ::InterlockedDecrement(&m_refCount)) + { + // Destroy the thread pool wait now to avoid the wait that would occur in the + // destructor. That wait would cause a deadlock since we are doing this from the callback. + ::CloseThreadpoolWait(m_threadPoolWait.release()); + lock.reset(); // leave the lock before deleting it. + delete this; + // Sleep(1); // Enable for testing to find use after free bugs. + } + else if (rearm) + { + ::SetThreadpoolWait(m_threadPoolWait.get(), m_eventHandle.get(), nullptr); + } + } + }; + + inline void delete_registry_watcher_state(_In_opt_ registry_watcher_state* watcherStorage) { watcherStorage->Release(); } + + typedef resource_policy registry_watcher_state_resource_policy; + } + /// @endcond + + template + class registry_watcher_t : public storage_t + { + public: + // forward all base class constructors... + template + explicit registry_watcher_t(args_t&&... args) WI_NOEXCEPT : storage_t(wistd::forward(args)...) {} + + // HRESULT or void error handling... + typedef typename err_policy::result result; + + // Exception-based constructors + registry_watcher_t(HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function&& callback) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions; use the create method"); + create(rootKey, subKey, isRecursive, wistd::move(callback)); + } + + registry_watcher_t(unique_hkey&& keyToWatch, bool isRecursive, wistd::function&& callback) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions; use the create method"); + create(wistd::move(keyToWatch), isRecursive, wistd::move(callback)); + } + + // Pass a root key, sub key pair or use an empty string to use rootKey as the key to watch. + result create(HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function&& callback) + { + // Most use will want to create the key, consider adding an option for open as a future design change. + unique_hkey keyToWatch; + HRESULT hr = HRESULT_FROM_WIN32(RegCreateKeyExW(rootKey, subKey, 0, nullptr, 0, KEY_NOTIFY, nullptr, &keyToWatch, nullptr)); + if (FAILED(hr)) + { + return err_policy::HResult(hr); + } + return err_policy::HResult(create_common(wistd::move(keyToWatch), isRecursive, wistd::move(callback))); + } + + result create(unique_hkey&& keyToWatch, bool isRecursive, wistd::function&& callback) + { + return err_policy::HResult(create_common(wistd::move(keyToWatch), isRecursive, wistd::move(callback))); + } + + private: + // Factored into a standalone function to support Clang which does not support conversion of stateless lambdas + // to __stdcall + static void __stdcall callback(PTP_CALLBACK_INSTANCE, void* context, TP_WAIT*, TP_WAIT_RESULT) + { +#ifndef __WIL_REGISTRY_CHANGE_CALLBACK_TEST +#define __WIL_REGISTRY_CHANGE_CALLBACK_TEST +#endif + __WIL_REGISTRY_CHANGE_CALLBACK_TEST + const auto watcherState = static_cast(context); + if (watcherState->TryAddRef()) + { + // using auto reset event so don't need to manually reset. + + // failure here is a programming error. + const LSTATUS error = RegNotifyChangeKeyValue(watcherState->m_keyToWatch.get(), watcherState->m_isRecursive, + REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_THREAD_AGNOSTIC, + watcherState->m_eventHandle.get(), TRUE); + + // Call the client before re-arming to ensure that multiple callbacks don't + // run concurrently. + switch (error) + { + case ERROR_SUCCESS: + case ERROR_ACCESS_DENIED: + // Normal modification: send RegistryChangeKind::Modify and re-arm. + watcherState->m_callback(RegistryChangeKind::Modify); + watcherState->ReleaseFromCallback(true); + break; + + case ERROR_KEY_DELETED: + // Key deleted, send RegistryChangeKind::Delete, do not re-arm. + watcherState->m_callback(RegistryChangeKind::Delete); + watcherState->ReleaseFromCallback(false); + break; + + case ERROR_HANDLE_REVOKED: + // Handle revoked. This can occur if the user session ends before + // the watcher shuts-down. Disarm silently since there is generally no way to respond. + watcherState->ReleaseFromCallback(false); + break; + + default: + FAIL_FAST_HR(HRESULT_FROM_WIN32(error)); + } + } + } + + // This function exists to avoid template expansion of this code based on err_policy. + HRESULT create_common(unique_hkey&& keyToWatch, bool isRecursive, wistd::function&& callback) + { + wistd::unique_ptr watcherState(new(std::nothrow) details::registry_watcher_state( + wistd::move(keyToWatch), isRecursive, wistd::move(callback))); + RETURN_IF_NULL_ALLOC(watcherState); + RETURN_IF_FAILED(watcherState->m_eventHandle.create()); + RETURN_IF_WIN32_ERROR(RegNotifyChangeKeyValue(watcherState->m_keyToWatch.get(), + watcherState->m_isRecursive, REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_THREAD_AGNOSTIC, + watcherState->m_eventHandle.get(), TRUE)); + + watcherState->m_threadPoolWait.reset(CreateThreadpoolWait(®istry_watcher_t::callback, watcherState.get(), nullptr)); + RETURN_LAST_ERROR_IF(!watcherState->m_threadPoolWait); + storage_t::reset(watcherState.release()); // no more failures after this, pass ownership + SetThreadpoolWait(storage_t::get()->m_threadPoolWait.get(), storage_t::get()->m_eventHandle.get(), nullptr); + return S_OK; + } + }; + + typedef unique_any_t, err_returncode_policy>> unique_registry_watcher_nothrow; + typedef unique_any_t, err_failfast_policy>> unique_registry_watcher_failfast; + + inline unique_registry_watcher_nothrow make_registry_watcher_nothrow(HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function&& callback) WI_NOEXCEPT + { + unique_registry_watcher_nothrow watcher; + watcher.create(rootKey, subKey, isRecursive, wistd::move(callback)); + return watcher; // caller must test for success using if (watcher) + } + + inline unique_registry_watcher_nothrow make_registry_watcher_nothrow(unique_hkey&& keyToWatch, bool isRecursive, wistd::function&& callback) WI_NOEXCEPT + { + unique_registry_watcher_nothrow watcher; + watcher.create(wistd::move(keyToWatch), isRecursive, wistd::move(callback)); + return watcher; // caller must test for success using if (watcher) + } + + inline unique_registry_watcher_failfast make_registry_watcher_failfast(HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function&& callback) + { + return unique_registry_watcher_failfast(rootKey, subKey, isRecursive, wistd::move(callback)); + } + + inline unique_registry_watcher_failfast make_registry_watcher_failfast(unique_hkey&& keyToWatch, bool isRecursive, wistd::function&& callback) + { + return unique_registry_watcher_failfast(wistd::move(keyToWatch), isRecursive, wistd::move(callback)); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + typedef unique_any_t, err_exception_policy >> unique_registry_watcher; + + inline unique_registry_watcher make_registry_watcher(HKEY rootKey, _In_ PCWSTR subKey, bool isRecursive, wistd::function&& callback) + { + return unique_registry_watcher(rootKey, subKey, isRecursive, wistd::move(callback)); + } + + inline unique_registry_watcher make_registry_watcher(unique_hkey&& keyToWatch, bool isRecursive, wistd::function&& callback) + { + return unique_registry_watcher(wistd::move(keyToWatch), isRecursive, wistd::move(callback)); + } +#endif // WIL_ENABLE_EXCEPTIONS +} // namespace wil + +#endif diff --git a/libraries/wil/registry_helpers.h b/libraries/wil/registry_helpers.h new file mode 100644 index 0000000..3cb344c --- /dev/null +++ b/libraries/wil/registry_helpers.h @@ -0,0 +1,1860 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_REGISTRY_HELPERS_INCLUDED +#define __WIL_REGISTRY_HELPERS_INCLUDED + +#if defined(_STRING_) || defined (_VECTOR_) || (defined (__cpp_lib_optional) && defined (_OPTIONAL_)) +#include +#include +#endif + +#include +#include +#include "resource.h" + +#ifdef _KERNEL_MODE +#error This header is not supported in kernel-mode. +#endif + +namespace wil +{ + namespace reg + { + /** + * \brief Helper function to translate registry return values if the value was not found + * \param hr HRESULT to test from registry APIs + * \return boolean if the HRESULT indicates the registry value was not found + */ + constexpr bool is_registry_not_found(HRESULT hr) WI_NOEXCEPT + { + return (hr == __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) || + (hr == __HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)); + } + + /** + * \brief Helper function to translate registry return values if the buffer was too small + * \param hr HRESULT to test from registry APIs + * \return boolean if the HRESULT indicates the buffer was too small for the value being read + */ + constexpr bool is_registry_buffer_too_small(HRESULT hr) WI_NOEXCEPT + { + return hr == __HRESULT_FROM_WIN32(ERROR_MORE_DATA); + } + + // Access rights for opening registry keys. See https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-key-security-and-access-rights. + enum class key_access + { + // Open key for reading. + read, + + // Open key for reading and writing. Equivalent to KEY_ALL_ACCESS. + readwrite, + }; + + namespace reg_view_details + { + constexpr DWORD get_value_flags_from_value_type(DWORD type) WI_NOEXCEPT + { + switch (type) + { + case REG_DWORD: + return RRF_RT_REG_DWORD; + case REG_QWORD: + return RRF_RT_REG_QWORD; + case REG_SZ: + return RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND; + case REG_EXPAND_SZ: + return RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ; + case REG_MULTI_SZ: + return RRF_RT_REG_MULTI_SZ; + case REG_BINARY: + return RRF_RT_REG_BINARY; + // the caller can directly specify their own flags if they need to + default: + return type; + } + } + + constexpr DWORD get_access_flags(key_access access) WI_NOEXCEPT + { + switch (access) + { + case key_access::read: + return KEY_READ; + case key_access::readwrite: + return KEY_ALL_ACCESS; + } + FAIL_FAST(); + } + + /** + * \brief A utility function that walks a contiguous wchar_t container looking for strings within a multi-string + * \tparam InputIt An iterator type that reference a container that holds wchar_t characters to translate into individual strings + * \tparam Fn A callback function to be called each time a string is found - given the [begin, end] iterators referencing the found string + * \param first An iterator referencing to the beginning of the target container (like a std::begin iterator) + * \param last An iterator referencing one-past-the-end of the target container (like a std::end iterator) + * \param func A callback function to be called each time a string is found - given the [begin, end] iterators referencing the found string + */ + template + void walk_multistring(const InputIt& first, const InputIt& last, Fn func) + { + auto current = first; + const auto end_iterator = last; + const auto last_null = (end_iterator - 1); + while (current != end_iterator) + { + // hand rolling ::std::find(current, end_iterator, L'\0'); + // as this may be called when isn't available + auto next = current; + while (next != end_iterator && *next != L'\0') + { + ++next; + } + + if (next != end_iterator) + { + // don't add an empty string for the final 2nd-null-terminator + if (next != last_null) + { + // call the function provided with the [begin, end] pair referencing a string found + func(current, next); + } + current = next + 1; + } + else + { + current = next; + } + } + } + +#if defined(_VECTOR_) && defined(_STRING_) && defined(WIL_ENABLE_EXCEPTIONS) + /** + * \brief A translation function taking iterators referencing std::wstring objects and returns a corresponding std::vector to be written to a MULTI_SZ registry value + * The translation follows the rules for how MULTI_SZ registry values should be formatted, notably how null characters should be embedded within the returned vector + * \tparam InputIt An iterator type that references a container that holds std::wstring objects to translate into a wchar_t buffer + * \param first An iterator referencing to the beginning of the target container (like a std::begin iterator) + * \param last An iterator referencing one-past-the-end of the target container (like a std::end iterator) + * \return A std::vector with the raw wchar_t buffer of bytes prepared to write to a MULTI_SZ registry value + */ + template + ::std::vector get_multistring_from_wstrings(const InputIt& first, const InputIt& last) + { + ::std::vector multistring; + + if (first == last) + { + multistring.push_back(L'\0'); + multistring.push_back(L'\0'); + return multistring; + } + + for (const auto& wstr : ::wil::make_range(first, last)) + { + multistring.insert(multistring.end(), ::std::begin(wstr), ::std::end(wstr)); + multistring.push_back(L'\0'); + } + + // double-null-terminate the last string + multistring.push_back(L'\0'); + return multistring; + } + + /** + * \brief A translation function taking iterators referencing wchar_t characters and returns extracted individual std::wstring objects + * The translation follows the rules for how MULTI_SZ registry value can be formatted, notably with embedded null characters + * Note that this conversion avoids returning empty std::wstring objects even though the input may contain contiguous null wchar_t values + * \tparam InputIt An iterator type that reference a container that holds wchar_t characters to translate into individual strings + * \param first An iterator referencing to the beginning of the target container (like a std::begin iterator) + * \param last An iterator referencing one-past-the-end of the target container (like a std::end iterator) + * \return A std::vector of the extracted strings from the input container of wchar_t characters + */ + template + ::std::vector<::std::wstring> get_wstring_vector_from_multistring(const InputIt& first, const InputIt& last) + { + if (last - first < 3) + { + // it doesn't have the required 2 terminating null characters - return an empty string + return ::std::vector<::std::wstring>(1); + } + + ::std::vector<::std::wstring> strings; + walk_multistring(first, last, [&](const InputIt& string_first, const InputIt& string_last) + { + strings.emplace_back(string_first, string_last); + } + ); + return strings; + } +#endif // #if defined(_VECTOR_) && defined(_STRING_) && defined(WIL_ENABLE_EXCEPTIONS) + +#if defined(__WIL_OBJBASE_H_) + template + void get_multistring_bytearray_from_strings_nothrow(const PCWSTR data[C], ::wil::unique_cotaskmem_array_ptr& multistring) WI_NOEXCEPT + { + constexpr uint8_t nullTermination[2]{ 0x00, 0x00 }; + + size_t total_array_length_bytes = 0; + for (size_t i = 0; i < C; ++i) + { + total_array_length_bytes += wcslen(data[i]) * sizeof(wchar_t); + total_array_length_bytes += sizeof(wchar_t); // plus one for the null-terminator + } + total_array_length_bytes += sizeof(wchar_t); // plus one for the ending double-null-terminator + + *multistring.addressof() = static_cast(::CoTaskMemAlloc(total_array_length_bytes)); + if (!multistring.get()) + { + multistring.reset(); + return; + } + *multistring.size_address() = total_array_length_bytes; + + size_t array_offset = 0; + for (size_t i = 0; i < C; ++i) + { + const auto string_length_bytes = wcslen(data[i]) * sizeof(wchar_t); + memcpy(multistring.get() + array_offset, data[i], string_length_bytes); + array_offset += string_length_bytes; + + static_assert(sizeof(nullTermination) == sizeof(wchar_t), "null terminator must be a wchar"); + memcpy(multistring.get() + array_offset, nullTermination, sizeof(nullTermination)); + array_offset += sizeof(nullTermination); + } + + // double-null-terminate the last string + memcpy(multistring.get() + array_offset, nullTermination, sizeof(nullTermination)); + } + + /** + * \brief A translation function taking iterators referencing wchar_t characters and returns extracted individual wil::unique_cotaskmem_string objects + * The translation follows the rules for how MULTI_SZ registry value can be formatted, notably with embedded null characters + * Note that this conversion avoids returning empty wil::unique_cotaskmem_string objects even though the input may contain contiguous null wchar_t values + * \tparam InputIt An iterator type that reference a container that holds wchar_t characters to translate into individual strings + * \param first An iterator referencing to the beginning of the target container (like a std::begin iterator) + * \param last An iterator referencing one-past-the-end of the target container (like a std::end iterator) + * \param cotaskmem_array The [out] wil::unique_cotaskmem_array_ptr to contain the array of strings + * A wil::unique_cotaskmem_array_ptr of the extracted strings from the input container of wchar_t characters + * An empty wil::unique_cotaskmem_array_ptr should be translated as out-of-memory as there should always be at least one wil::unique_cotaskmem_string + */ + template + void get_cotaskmemstring_array_from_multistring_nothrow(const InputIt& first, const InputIt& last, ::wil::unique_cotaskmem_array_ptr<::wil::unique_cotaskmem_string>& cotaskmem_array) WI_NOEXCEPT + { + if (last - first < 3) + { + // it doesn't have the required 2 terminating null characters - return an empty string + *cotaskmem_array.addressof() = static_cast(::CoTaskMemAlloc(sizeof(PWSTR) * 1)); + if (cotaskmem_array) + { + auto new_string = ::wil::make_cotaskmem_string_nothrow(L""); + if (new_string) + { + *cotaskmem_array.size_address() = 1; + cotaskmem_array[0] = new_string.release(); + } + else + { + // oom will return an empty array + cotaskmem_array.reset(); + } + } + else + { + // oom will return an empty array + cotaskmem_array.reset(); + } + return; + } + + // we must first count the # of strings for the array + size_t arraySize = 0; + walk_multistring(first, last, [&](const InputIt&, const InputIt&) + { + ++arraySize; + } + ); + + // allocate the array size necessary to hold all the unique_cotaskmem_strings + *cotaskmem_array.addressof() = static_cast(::CoTaskMemAlloc(sizeof(PWSTR) * arraySize)); + if (!cotaskmem_array) + { + // oom will return an empty array + cotaskmem_array.reset(); + return; + } + + *cotaskmem_array.size_address() = arraySize; + ZeroMemory(cotaskmem_array.data(), sizeof(PWSTR) * arraySize); + + size_t arrayOffset = 0; + walk_multistring(first, last, [&](const InputIt& string_first, const InputIt& string_last) + { + FAIL_FAST_IF(arrayOffset >= arraySize); + const auto stringSize = string_last - string_first; + auto new_string = ::wil::make_cotaskmem_string_nothrow(&(*string_first), stringSize); + if (!new_string) + { + // oom will return an empty array + cotaskmem_array.reset(); + return; + } + cotaskmem_array[arrayOffset] = new_string.release(); + ++arrayOffset; + } + ); + } +#endif // #if defined(__WIL_OBJBASE_H_) + + namespace reg_value_type_info + { + // supports_prepare_buffer is used to determine if the input buffer to read a registry value should be prepared + // before the first call to the registry read API + template + constexpr bool supports_prepare_buffer() WI_NOEXCEPT + { + return false; + } + template + HRESULT prepare_buffer(T&) WI_NOEXCEPT + { + // no-op in the default case + return S_OK; + } + + // supports_resize_buffer is used to determine if the input buffer to read a registry value can be resized + // for those cases if the error from the registry read API indicates it needs a larger buffer + template + constexpr bool supports_resize_buffer() WI_NOEXCEPT + { + return false; + } + template + constexpr HRESULT resize_buffer(T&, DWORD) WI_NOEXCEPT + { + return E_NOTIMPL; + } + + // supports_trim_buffer is used to determine if the input buffer to read a registry value must be trimmed + // after the registry read API has successfully written into the supplied buffer + // note that currently only std::wstring requires this as it cannot have embedded nulls + template + constexpr bool supports_trim_buffer() WI_NOEXCEPT + { + return false; + } + template + constexpr void trim_buffer(T&) WI_NOEXCEPT + { + } + + constexpr void* get_buffer(const int32_t& value) WI_NOEXCEPT + { + return const_cast(&value); + } + + constexpr DWORD get_buffer_size_bytes(int32_t) WI_NOEXCEPT + { + return static_cast(sizeof(int32_t)); + } + + constexpr void* get_buffer(const uint32_t& value) WI_NOEXCEPT + { + return const_cast(&value); + } + + constexpr DWORD get_buffer_size_bytes(uint32_t) WI_NOEXCEPT + { + return static_cast(sizeof(uint32_t)); + } + + constexpr void* get_buffer(const long& value) WI_NOEXCEPT + { + return const_cast(&value); + } + + constexpr DWORD get_buffer_size_bytes(long) WI_NOEXCEPT + { + return static_cast(sizeof(long)); + } + + constexpr void* get_buffer(const unsigned long& value) WI_NOEXCEPT + { + return const_cast(&value); + } + + constexpr DWORD get_buffer_size_bytes(unsigned long) WI_NOEXCEPT + { + return static_cast(sizeof(unsigned long)); + } + + constexpr void* get_buffer(const int64_t& value) WI_NOEXCEPT + { + return const_cast(&value); + } + + constexpr DWORD get_buffer_size_bytes(int64_t) WI_NOEXCEPT + { + return static_cast(sizeof(int64_t)); + } + + constexpr void* get_buffer(const uint64_t& value) WI_NOEXCEPT + { + return const_cast(&value); + } + + constexpr DWORD get_buffer_size_bytes(uint64_t) WI_NOEXCEPT + { + return static_cast(sizeof(uint64_t)); + } + + constexpr void* get_buffer(PCWSTR value) WI_NOEXCEPT + { + return const_cast(value); + } + + inline DWORD get_buffer_size_bytes(PCWSTR value) WI_NOEXCEPT + { + if (!value) + { + return 0; + } + // including the last null buffer space in the returned buffer-size-bytes + // as the registry API we call guarantees null termination + return static_cast((::wcslen(value) + 1) * sizeof(wchar_t)); + } + +#if defined(_VECTOR_) && defined(WIL_ENABLE_EXCEPTIONS) + inline void* get_buffer(const ::std::vector& buffer) WI_NOEXCEPT + { + return const_cast(buffer.data()); + } + + inline DWORD get_buffer_size_bytes(const ::std::vector& value) WI_NOEXCEPT + { + return static_cast(value.size()); + } + + template <> + constexpr bool supports_prepare_buffer<::std::vector>() WI_NOEXCEPT + { + return true; + } + inline HRESULT prepare_buffer(::std::vector& value) WI_NOEXCEPT try + { + // resize the initial vector to at least 1 byte + // this is needed so we can detect when the registry value exists + // but the value has zero-bytes + if (value.empty()) + { + value.resize(1); + } + // zero out the buffer if pre-allocated + for (auto& string_char : value) + { + string_char = 0x00; + } + return S_OK; + } + CATCH_RETURN(); + + template <> + constexpr bool supports_resize_buffer<::std::vector>() WI_NOEXCEPT + { + return true; + } + inline HRESULT resize_buffer(::std::vector& buffer, DWORD byteSize) WI_NOEXCEPT try + { + buffer.resize(byteSize); + return S_OK; + } + CATCH_RETURN(); + + // std::vector does not implement resize_buffer + // because these support functions are only needed for set_value + // from the return of get_multistring_from_wstrings + inline void* get_buffer(const ::std::vector& value) WI_NOEXCEPT + { + return const_cast(value.data()); + } + + inline DWORD get_buffer_size_bytes(const ::std::vector& value) WI_NOEXCEPT + { + return static_cast(value.size()) * sizeof(wchar_t); + } + + template <> + constexpr bool supports_prepare_buffer<::std::vector>() WI_NOEXCEPT + { + return true; + } + inline HRESULT prepare_buffer(::std::vector& value) WI_NOEXCEPT + { + // zero out the buffer if pre-allocated + for (auto& string_char : value) + { + string_char = L'\0'; + } + return S_OK; + } +#endif // #if defined(_VECTOR_) && defined(WIL_ENABLE_EXCEPTIONS) + +#if defined(_STRING_) && defined(WIL_ENABLE_EXCEPTIONS) + inline void* get_buffer(const ::std::wstring& string) WI_NOEXCEPT + { + return const_cast(string.data()); + } + + inline DWORD get_buffer_size_bytes(const ::std::wstring& string) WI_NOEXCEPT + { + // including the last null buffer space in the returned buffer-size-bytes + // as the registry API we call guarantees null termination + return static_cast((string.size() + 1) * sizeof(wchar_t)); + } + + template <> + constexpr bool supports_prepare_buffer<::std::wstring>() WI_NOEXCEPT + { + return true; + } + inline HRESULT prepare_buffer(::std::wstring& string) WI_NOEXCEPT + { + // zero out the buffer if pre-allocated + for (auto& string_char : string) + { + string_char = L'\0'; + } + return S_OK; + } + + template <> + constexpr bool supports_resize_buffer<::std::wstring>() WI_NOEXCEPT + { + return true; + } + inline HRESULT resize_buffer(::std::wstring& string, DWORD byteSize) WI_NOEXCEPT try + { + string.resize(byteSize / sizeof(wchar_t)); + return S_OK; + } + CATCH_RETURN(); + + template <> + constexpr bool supports_trim_buffer<::std::wstring>() WI_NOEXCEPT + { + return true; + } + inline void trim_buffer(::std::wstring& buffer) WI_NOEXCEPT + { + // remove any embedded null characters + const auto offset = buffer.find_first_of(L'\0'); + if (offset != ::std::wstring::npos) + { + buffer.resize(offset); + } + } +#endif // #if defined(_STRING_) && defined(WIL_ENABLE_EXCEPTIONS) + +#if defined(__WIL_OLEAUTO_H_) + inline void* get_buffer(const BSTR& value) WI_NOEXCEPT + { + return value; + } + + inline DWORD get_buffer_size_bytes(const BSTR& value) WI_NOEXCEPT + { + auto length = ::SysStringLen(value); + if (length > 0) + { + // SysStringLen does not count the null-terminator + // including the last null buffer space in the returned buffer-size-bytes + // as the registry API we call guarantees null termination + length += 1; + } + return length * sizeof(wchar_t); + } + + template <> + constexpr bool supports_prepare_buffer() WI_NOEXCEPT + { + return true; + } + inline HRESULT prepare_buffer(const BSTR& value) WI_NOEXCEPT + { + if (value) + { + // zero out the buffer if pre-allocated + for (auto& string_char : ::wil::make_range(value, get_buffer_size_bytes(value) / sizeof(WCHAR))) + { + string_char = L'\0'; + } + } + return S_OK; + } + + template <> + constexpr bool supports_resize_buffer() WI_NOEXCEPT + { + return true; + } + // transferringOwnership is only set to false if this is a 'shallow' copy of the BSTR + // and the caller maintained ownership of the original BSTR. + inline HRESULT resize_buffer(BSTR& string, DWORD byteSize, bool transferringOwnership = true) WI_NOEXCEPT + { + // convert bytes to length (number of WCHAR's) + DWORD length = byteSize / sizeof(WCHAR); + // SysAllocStringLen adds a null, so subtract a wchar_t from the input length + length = length > 0 ? length - 1 : length; + const BSTR new_bstr{ ::SysAllocStringLen(string, length) }; + RETURN_IF_NULL_ALLOC(new_bstr); + + // if not transferring ownership, the caller will still own the original BSTR + if (transferringOwnership) + { + ::SysFreeString(string); + } + + string = new_bstr; + return S_OK; + } + + inline void* get_buffer(const ::wil::unique_bstr& value) WI_NOEXCEPT + { + return value.get(); + } + + inline DWORD get_buffer_size_bytes(const ::wil::unique_bstr& value) WI_NOEXCEPT + { + return get_buffer_size_bytes(value.get()); + } + + template <> + constexpr bool supports_prepare_buffer<::wil::unique_bstr>() WI_NOEXCEPT + { + return true; + } + inline HRESULT prepare_buffer(const ::wil::unique_bstr& value) WI_NOEXCEPT + { + if (value) + { + // zero out the buffer if pre-allocated + for (auto& string_char : ::wil::make_range(value.get(), get_buffer_size_bytes(value) / sizeof(WCHAR))) + { + string_char = L'\0'; + } + } + return S_OK; + } + + template<> + constexpr bool supports_resize_buffer<::wil::unique_bstr>() WI_NOEXCEPT + { + return true; + } + inline HRESULT resize_buffer(::wil::unique_bstr& string, DWORD byteSize) WI_NOEXCEPT + { + BSTR temp_bstr = string.get(); + + // not transferring ownership of the BSTR within 'string' to resize_buffer() + // resize_buffer() will overwrite temp_bstr with a newly-allocated BSTR + constexpr bool transferringOwnership = false; + RETURN_IF_FAILED(resize_buffer(temp_bstr, byteSize, transferringOwnership)); + + // if succeeded in creating a new BSTR, move ownership of the new BSTR into string + string.reset(temp_bstr); + return S_OK; + } +#endif // #if defined(__WIL_OLEAUTO_H_) + +#if defined(__WIL_OLEAUTO_H_STL) + inline void* get_buffer(const ::wil::shared_bstr& value) WI_NOEXCEPT + { + return value.get(); + } + + inline DWORD get_buffer_size_bytes(const ::wil::shared_bstr& value) WI_NOEXCEPT + { + return get_buffer_size_bytes(value.get()); + } + + template <> + constexpr bool supports_prepare_buffer<::wil::shared_bstr>() WI_NOEXCEPT + { + return true; + } + inline HRESULT prepare_buffer(const ::wil::shared_bstr& value) WI_NOEXCEPT + { + if (value) + { + // zero out the buffer if pre-allocated + for (auto& string_char : ::wil::make_range(value.get(), get_buffer_size_bytes(value) / sizeof(WCHAR))) + { + string_char = L'\0'; + } + } + return S_OK; + } + + template<> + constexpr bool supports_resize_buffer<::wil::shared_bstr>() WI_NOEXCEPT + { + return true; + } + inline HRESULT resize_buffer(::wil::shared_bstr& string, DWORD byteSize) WI_NOEXCEPT + { + BSTR temp_bstr = string.get(); + + // not transferring ownership of the BSTR within 'string' to resize_buffer() + // resize_buffer() will overwrite temp_bstr with a newly-allocated BSTR + constexpr bool transferringOwnership = false; + RETURN_IF_FAILED(resize_buffer(temp_bstr, byteSize, transferringOwnership)); + + // if succeeded in creating a new BSTR, move ownership of the new BSTR into string + string.reset(temp_bstr); + return S_OK; + } +#endif // #if defined(__WIL_OLEAUTO_H_STL) + +#if defined(__WIL_OBJBASE_H_) + inline void* get_buffer(const ::wil::unique_cotaskmem_string& value) WI_NOEXCEPT + { + return value.get(); + } + + constexpr DWORD get_buffer_size_bytes(const ::wil::unique_cotaskmem_string&) WI_NOEXCEPT + { + // wil::unique_cotaskmem_string does not intrinsically track its internal buffer size + // thus the caller must track the buffer size it requested to be allocated + return 0; + } + + template<> + constexpr bool supports_resize_buffer<::wil::unique_cotaskmem_string>() WI_NOEXCEPT + { + return true; + } + inline HRESULT resize_buffer(::wil::unique_cotaskmem_string& string, DWORD byteSize) WI_NOEXCEPT + { + // convert bytes to length (number of WCHAR's) + size_t length = byteSize / sizeof(wchar_t); + // ::wil::make_unique_string_nothrow adds one to the length when it allocates, so subtracting 1 from the input length + length = length > 0 ? length - 1 : length; + auto new_string = ::wil::make_unique_string_nothrow<::wil::unique_cotaskmem_string>(string.get(), length); + RETURN_IF_NULL_ALLOC(new_string.get()); + + string = ::wistd::move(new_string); + return S_OK; + } + + inline void* get_buffer(const ::wil::unique_cotaskmem_array_ptr& value) WI_NOEXCEPT + { + return value.get(); + } + + inline DWORD get_buffer_size_bytes(const ::wil::unique_cotaskmem_array_ptr& value) WI_NOEXCEPT + { + return static_cast(value.size()); + } + + template<> + constexpr bool supports_resize_buffer<::wil::unique_cotaskmem_array_ptr>() WI_NOEXCEPT + { + return true; + } + inline HRESULT resize_buffer(::wil::unique_cotaskmem_array_ptr& arrayValue, DWORD byteSize) WI_NOEXCEPT + { + ::wil::unique_cotaskmem_array_ptr tempValue; + *tempValue.addressof() = static_cast(::CoTaskMemAlloc(byteSize)); + RETURN_IF_NULL_ALLOC(tempValue.get()); + *tempValue.size_address() = byteSize; + + const auto bytesToCopy = arrayValue.size() < byteSize ? arrayValue.size() : byteSize; + CopyMemory(tempValue.get(), arrayValue.get(), bytesToCopy); + + arrayValue = ::wistd::move(tempValue); + return S_OK; + } +#endif // #if defined(__WIL_OBJBASE_H_) + +#if defined(__WIL_OBJBASE_H_STL) + inline void* get_buffer(const ::wil::shared_cotaskmem_string& value) WI_NOEXCEPT + { + return value.get(); + } + + constexpr DWORD get_buffer_size_bytes(const ::wil::shared_cotaskmem_string&) WI_NOEXCEPT + { + // wil::shared_cotaskmem_string does not intrinsically track its internal buffer size + // thus the caller must track the buffer size it requested to be allocated + return 0; + } + + template<> + constexpr bool supports_resize_buffer<::wil::shared_cotaskmem_string>() WI_NOEXCEPT + { + return true; + } + inline HRESULT resize_buffer(::wil::shared_cotaskmem_string& string, DWORD byteSize) WI_NOEXCEPT + { + // convert bytes to length (number of WCHAR's) + size_t length = byteSize / sizeof(wchar_t); + // ::wil::make_unique_string_nothrow adds one to the length when it allocates, so subtracting 1 from the input length + length = length > 0 ? length - 1 : length; + auto new_string = ::wil::make_unique_string_nothrow<::wil::unique_cotaskmem_string>(string.get(), length); + RETURN_IF_NULL_ALLOC(new_string.get()); + + string = ::wistd::move(new_string); + return S_OK; + } +#endif // #if defined(__WIL_OBJBASE_H_STL) + + inline void* get_buffer(const ::wil::unique_process_heap_string& value) WI_NOEXCEPT + { + return value.get(); + } + + constexpr DWORD get_buffer_size_bytes(const ::wil::unique_process_heap_string&) WI_NOEXCEPT + { + // wil::unique_process_heap_string does not intrinsically track its internal buffer size + // thus the caller must track the buffer size it requested to be allocated + return 0; + } + + template<> + constexpr bool supports_resize_buffer<::wil::unique_process_heap_string>() WI_NOEXCEPT + { + return true; + } + inline HRESULT resize_buffer(::wil::unique_process_heap_string& string, DWORD byteSize) WI_NOEXCEPT + { + // convert bytes to length (number of WCHAR's) + size_t length = byteSize / sizeof(wchar_t); + // ::wil::make_unique_string_nothrow adds one to the length when it allocates, so subtracting 1 from the input length + length = length > 0 ? length - 1 : length; + auto new_string = ::wil::make_unique_string_nothrow<::wil::unique_process_heap_string>(string.get(), length); + RETURN_IF_NULL_ALLOC(new_string.get()); + + string = ::wistd::move(new_string); + return S_OK; + } + + // constexpr expressions to determining the get* and set* registry value types + // for all supported types T to read/write values + template + DWORD get_value_type() WI_NOEXCEPT + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for get_value_type"); + } + + template + DWORD set_value_type() WI_NOEXCEPT + { + static_assert(sizeof(T) != sizeof(T), "Unsupported type for set_value_type"); + } + + template <> + constexpr DWORD get_value_type() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_DWORD); + } + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_DWORD; + } + + template <> + constexpr DWORD get_value_type() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_DWORD); + } + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_DWORD; + } + + template <> + constexpr DWORD get_value_type() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_DWORD); + } + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_DWORD; + } + + template <> + constexpr DWORD get_value_type() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_DWORD); + } + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_DWORD; + } + + template <> + constexpr DWORD get_value_type() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_QWORD); + } + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_QWORD; + } + + template <> + constexpr DWORD get_value_type() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_QWORD); + } + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_QWORD; + } + + template <> + constexpr DWORD get_value_type() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_SZ); + } + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_SZ; + } + +#if defined(_STRING_) && defined(WIL_ENABLE_EXCEPTIONS) + template <> + constexpr DWORD get_value_type<::std::wstring>() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_SZ); + } + + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_SZ; + } +#endif // #if defined(_STRING_) && defined(WIL_ENABLE_EXCEPTIONS) + +#if defined(__WIL_OLEAUTO_H_) + template <> + constexpr DWORD get_value_type() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_SZ); + } + template <> + constexpr DWORD get_value_type<::wil::unique_bstr>() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_SZ); + } + + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_SZ; + } + + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_SZ; + } +#endif // #if defined(__WIL_OLEAUTO_H_) + +#if defined(__WIL_OLEAUTO_H_STL) + + template <> + constexpr DWORD get_value_type<::wil::shared_bstr>() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_SZ); + } + + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_SZ; + } +#endif // #if defined(__WIL_OLEAUTO_H_STL) + +#if defined(__WIL_OBJBASE_H_) + template <> + constexpr DWORD get_value_type<::wil::unique_cotaskmem_string>() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_SZ); + } + + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_SZ; + } +#endif // defined(__WIL_OBJBASE_H_) + +#if defined(__WIL_OBJBASE_H_STL) + template <> + constexpr DWORD get_value_type<::wil::shared_cotaskmem_string>() WI_NOEXCEPT + { + return get_value_flags_from_value_type(REG_SZ); + } + + template <> + constexpr DWORD set_value_type() WI_NOEXCEPT + { + return REG_SZ; + } +#endif // #if defined(__WIL_OBJBASE_H_STL) + } + + template + class reg_view_t + { + public: + explicit reg_view_t(HKEY key) WI_NOEXCEPT : m_key(key) + { + } + ~reg_view_t() WI_NOEXCEPT = default; + reg_view_t(const reg_view_t&) = delete; + reg_view_t& operator=(const reg_view_t&) = delete; + reg_view_t(reg_view_t&&) = delete; + reg_view_t& operator=(reg_view_t&&) = delete; + + typename err_policy::result open_key(_In_opt_ _In_opt_ PCWSTR subKey, _Out_ HKEY* hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) const + { + constexpr DWORD zero_options{ 0 }; + return err_policy::HResult(HRESULT_FROM_WIN32(::RegOpenKeyExW(m_key, subKey, zero_options, get_access_flags(access), hkey))); + } + + typename err_policy::result create_key(PCWSTR subKey, _Out_ HKEY* hkey, ::wil::reg::key_access access = ::wil::reg::key_access::read) const + { + *hkey = nullptr; + + constexpr DWORD zero_reserved{ 0 }; + constexpr PWSTR null_class{ nullptr }; + constexpr DWORD zero_options{ 0 }; + constexpr SECURITY_ATTRIBUTES* null_security_attributes{ nullptr }; + DWORD disposition{ 0 }; + return err_policy::HResult(HRESULT_FROM_WIN32( + ::RegCreateKeyExW(m_key, subKey, zero_reserved, null_class, zero_options, get_access_flags(access), null_security_attributes, hkey, &disposition))); + } + + typename err_policy::result delete_tree(_In_opt_ PCWSTR sub_key) const + { + auto hr = HRESULT_FROM_WIN32(::RegDeleteTreeW(m_key, sub_key)); + if (::wil::reg::is_registry_not_found(hr)) + { + hr = S_OK; + } + return err_policy::HResult(hr); + } + + typename err_policy::result delete_value(_In_opt_ PCWSTR value_name) const + { + return err_policy::HResult(HRESULT_FROM_WIN32(::RegDeleteValueW(m_key, value_name))); + } + + template + typename err_policy::result get_value(_In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, R& return_value, DWORD type = reg_value_type_info::get_value_type()) const + { + return get_value_with_type(subkey, value_name, return_value, type); + } + + // typename D supports unsigned 32-bit values; i.e. allows the caller to pass a DWORD* as well as uint32_t* + template || wistd::is_same_v>* = nullptr> + typename err_policy::result get_value_char_array(_In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, WCHAR(&return_value)[Length], DWORD type, _Out_opt_ DwordType * requiredBytes) const + { + constexpr DwordType zero_value{ 0ul }; + ::wil::assign_to_opt_param(requiredBytes, zero_value); + DWORD data_size_bytes{ Length * sizeof(WCHAR) }; + const auto hr = HRESULT_FROM_WIN32( + ::RegGetValueW(m_key, subkey, value_name, ::wil::reg::reg_view_details::get_value_flags_from_value_type(type), nullptr, return_value, &data_size_bytes)); + if (SUCCEEDED(hr) || ::wil::reg::is_registry_buffer_too_small(hr)) + { + const DwordType updated_value{ data_size_bytes }; + ::wil::assign_to_opt_param(requiredBytes, updated_value); + } + return err_policy::HResult(hr); + } + +#if defined (_OPTIONAL_) && defined(__cpp_lib_optional) + // intended for err_exception_policy as err_returncode_policy will not get an error code + template + ::std::optional try_get_value(_In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, DWORD type = reg_value_type_info::get_value_type()) const + { + R value{}; + const auto hr = get_value_with_type(subkey, value_name, value, type); + if (SUCCEEDED(hr)) + { + return ::std::optional(::wistd::move(value)); + } + + if (::wil::reg::is_registry_not_found(hr)) + { + return ::std::nullopt; + } + + // throw if exception policy + err_policy::HResult(hr); + return ::std::nullopt; + } +#endif // #if defined (_OPTIONAL_) && defined(__cpp_lib_optional) + + template + typename err_policy::result set_value(_In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const R& value, DWORD type = reg_value_type_info::set_value_type()) const + { + return set_value_with_type(subkey, value_name, value, type); + } + + private: + const HKEY m_key{}; + + template + typename err_policy::result set_value_with_type(_In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, const R& value, DWORD type) const + { + return err_policy::HResult(HRESULT_FROM_WIN32( + ::RegSetKeyValueW( + m_key, + subkey, + value_name, + type, + static_cast(reg_value_type_info::get_buffer(value)), + reg_value_type_info::get_buffer_size_bytes(value)))); + } + + template + typename get_value_with_type_policy::result get_value_with_type(_In_opt_ PCWSTR subkey, _In_opt_ PCWSTR value_name, R& return_value, DWORD type = reg_value_type_info::get_value_type()) const + { + if +#if defined(__cpp_if_constexpr) + constexpr +#endif + (reg_value_type_info::supports_prepare_buffer()) + + { + const auto prepare_buffer_hr = reg_value_type_info::prepare_buffer(return_value); + if (FAILED(prepare_buffer_hr)) + { + return get_value_with_type_policy::HResult(prepare_buffer_hr); + } + } + + // get_buffer_size_bytes should include the null terminator when used for strings. + DWORD bytes_allocated{ reg_value_type_info::get_buffer_size_bytes(return_value) }; + HRESULT get_value_hresult = S_OK; + for (;;) + { + constexpr DWORD* null_type{ nullptr }; + DWORD data_size_bytes{ bytes_allocated }; + get_value_hresult = HRESULT_FROM_WIN32(::RegGetValueW( + m_key, + subkey, + value_name, + get_value_flags_from_value_type(type), + null_type, + reg_value_type_info::get_buffer(return_value), + &data_size_bytes)); + + // some return types we can grow as needed - e.g. when writing to a std::wstring + // only compile and resize_buffer for those types that support dynamically growing the buffer + if +#if defined(__cpp_if_constexpr) + constexpr +#endif + (reg_value_type_info::supports_resize_buffer()) + { + // Attempt to grow the buffer with the data_size_bytes returned from GetRegValueW + // GetRegValueW will indicate the caller allocate the returned number of bytes in one of two cases: + // 1. returns ERROR_MORE_DATA + // 2. returns ERROR_SUCCESS when we gave it a nullptr for the out buffer + const bool shouldReallocate = + (::wil::reg::is_registry_buffer_too_small(get_value_hresult)) || + (SUCCEEDED(get_value_hresult) && (reg_value_type_info::get_buffer(return_value) == nullptr) && (data_size_bytes > 0)); + if (shouldReallocate) + { + // verify if resize_buffer succeeded allocation + const auto resize_buffer_hr = reg_value_type_info::resize_buffer(return_value, data_size_bytes); + if (FAILED(resize_buffer_hr)) + { + // if resize fails, return this error back to the caller + return get_value_with_type_policy::HResult(resize_buffer_hr); + } + + // if it resize succeeds, continue the for loop to try again + bytes_allocated = data_size_bytes; + continue; + } + + // if the RegGetValueW call succeeded with a non-null [out] param, + // and the type supports resize_buffer + // and the bytes we allocated don't match data_size_bytes returned from RegGetValueW + // resize the buffer to match what RegGetValueW returned + if (SUCCEEDED(get_value_hresult)) + { + const auto current_byte_size = reg_value_type_info::get_buffer_size_bytes(return_value); + if (current_byte_size != data_size_bytes) + { + // verify if resize_buffer succeeded allocation + const auto resize_buffer_hr = reg_value_type_info::resize_buffer(return_value, data_size_bytes); + if (FAILED(resize_buffer_hr)) + { + // if resize fails, return this error back to the caller + return get_value_with_type_policy::HResult(resize_buffer_hr); + } + } + } + } + + // we don't need to reallocate and retry the call to RegGetValueW so breaking out of the loop + break; + } + + // some types (generally string types) require trimming its internal buffer after RegGetValueW successfully wrote into its buffer + if +#if defined(__cpp_if_constexpr) + constexpr +#endif + (reg_value_type_info::supports_trim_buffer()) + + { + if (SUCCEEDED(get_value_hresult)) + { + reg_value_type_info::trim_buffer(return_value); + } + } + + return get_value_with_type_policy::HResult(get_value_hresult); + } + }; + + using reg_view_nothrow = ::wil::reg::reg_view_details::reg_view_t<::wil::err_returncode_policy>; +#if defined(WIL_ENABLE_EXCEPTIONS) + using reg_view = ::wil::reg::reg_view_details::reg_view_t<::wil::err_exception_policy>; +#endif // #if defined(WIL_ENABLE_EXCEPTIONS) + } // namespace reg_view_details + + namespace reg_iterator_details + { + constexpr uint32_t iterator_end_offset = 0xffffffff; + constexpr size_t iterator_default_buffer_length = 16; + + // function overloads to allow *_enumerator objects to be constructed from all 3 types of HKEY representatives + inline HKEY get_hkey(HKEY h) WI_NOEXCEPT + { + return h; + } + inline HKEY get_hkey(const ::wil::unique_hkey& h) WI_NOEXCEPT + { + return h.get(); + } +#if defined(__WIL_WINREG_STL) + inline HKEY get_hkey(const ::wil::shared_hkey& h) WI_NOEXCEPT + { + return h.get(); + } +#endif // #if defined(__WIL_WINREG_STL) + +#if defined(WIL_ENABLE_EXCEPTIONS) && defined(_STRING_) + // overloads for some of the below string functions - specific for std::wstring + // these overloads must be declared before the template functions below, as some of those template functions + // reference these overload functions + inline void clear_name(::std::wstring& name, size_t) WI_NOEXCEPT + { + name.assign(name.size(), L'\0'); + } + inline ::std::wstring copy_name(const ::std::wstring& str, size_t length) WI_NOEXCEPT + { + try + { + // guarantee that the copied string has the specified internal length + // i.e., the same length assumptions hold when the string is copied + ::std::wstring tempString(length, L'0'); + tempString.assign(str); + return tempString; + } + catch (...) + { + return {}; + } + } + inline bool is_valid(const ::std::wstring& name) WI_NOEXCEPT + { + return !name.empty(); + } +#endif // #if defined(WIL_ENABLE_EXCEPTIONS) && defined(_STRING_) + + // string manipulation functions needed for iterator functions + template + PWSTR address_of_name(const T& name) WI_NOEXCEPT + { + return static_cast(::wil::reg::reg_view_details::reg_value_type_info::get_buffer(name)); + } + + template + bool is_valid(const T& name) WI_NOEXCEPT + { + return static_cast(address_of_name(name)); + } + + template + bool compare_name(const T& name, PCWSTR comparand) WI_NOEXCEPT + { + if (!is_valid(name) || !comparand) + { + return false; + } + return 0 == wcscmp(address_of_name(name), comparand); + } + + template + void clear_name(const T& name, size_t length) WI_NOEXCEPT + { + if (is_valid(name) && length > 0) + { + memset(address_of_name(name), 0, length * sizeof(wchar_t)); + } + } + + // failure returns zero + template + size_t resize_name(T& name, size_t current_length, size_t new_length) WI_NOEXCEPT + { + if (new_length > current_length) + { + // resize_buffer takes size in bytes + if (FAILED(::wil::reg::reg_view_details::reg_value_type_info::resize_buffer(name, static_cast(new_length * sizeof(wchar_t))))) + { + return 0; + } + return new_length; + } + + // continue to use the existing buffer since the requested length is less than or equals to the current length + clear_name(name, current_length); + return current_length; + } + + template + T copy_name(const T& name, size_t length) WI_NOEXCEPT + { + if (!is_valid(name)) + { + return {}; + + } + return ::wil::make_unique_string_nothrow(address_of_name(name), length); + } + +#if defined(__WIL_OLEAUTO_H_) + // overloads for some of the above string functions - specific for wil::unique_bstr + // these should come after the template functions - as they reference some of those functions + inline size_t resize_name(::wil::unique_bstr& name, size_t current_length, size_t new_length) WI_NOEXCEPT + { + if (new_length > current_length) + { + // SysAllocStringLen adds a null, so subtract a wchar_t from the input length + new_length = new_length > 0 ? new_length - 1 : new_length; + const BSTR new_bstr{ ::SysAllocStringLen(nullptr, static_cast(new_length)) }; + if (!new_bstr) + { + return 0; + } + name.reset(new_bstr); + return new_length; + } + + // continue to use the existing buffer since the requested length is less than or equals to the current length + clear_name(name, current_length); + return current_length; + } + inline ::wil::unique_bstr copy_name(const ::wil::unique_bstr& name, size_t length) WI_NOEXCEPT + { + if (!is_valid(name)) + { + return {}; + } + + // SysAllocStringLen adds a null, so subtract a wchar_t from the input length + length = length > 0 ? length - 1 : length; + return ::wil::unique_bstr{ ::SysAllocStringLen(name.get(), static_cast(length)) }; + } +#endif // #if defined(__WIL_OLEAUTO_H_) + }; + + // forward declaration to allow friend-ing the template iterator class +#if defined(WIL_ENABLE_EXCEPTIONS) + template class iterator_t; +#endif + template + class iterator_nothrow_t; + + // all methods must be noexcept - to be usable with any iterator type (throwing or non-throwing) + template + class key_iterator_data + { + public: + T name{}; + + key_iterator_data(HKEY key = nullptr) WI_NOEXCEPT : m_hkey{ key } + { + } + ~key_iterator_data() WI_NOEXCEPT = default; + + key_iterator_data(const key_iterator_data& rhs) WI_NOEXCEPT + { + // might return null/empty string on failure + name = ::wil::reg::reg_iterator_details::copy_name(rhs.name, rhs.m_name_length); + m_hkey = rhs.m_hkey; + m_index = rhs.m_index; + m_name_length = ::wil::reg::reg_iterator_details::is_valid(name) ? rhs.m_name_length : 0; + } + key_iterator_data& operator=(const key_iterator_data& rhs) WI_NOEXCEPT + { + if (&rhs != this) + { + key_iterator_data temp(rhs); + *this = ::wistd::move(temp); + } + return *this; + } + + key_iterator_data(key_iterator_data&&) WI_NOEXCEPT = default; + key_iterator_data& operator=(key_iterator_data&& rhs) WI_NOEXCEPT = default; + + // Case-sensitive comparison + bool operator==(PCWSTR comparand) const WI_NOEXCEPT + { + return ::wil::reg::reg_iterator_details::compare_name(name, comparand); + } + + private: +#if defined(WIL_ENABLE_EXCEPTIONS) + friend class ::wil::reg::iterator_t; +#endif + friend class ::wil::reg::iterator_nothrow_t; + + bool at_end() const WI_NOEXCEPT + { + return m_index == ::wil::reg::reg_iterator_details::iterator_end_offset; + } + + void make_end_iterator() WI_NOEXCEPT + { + ::wil::reg::reg_iterator_details::clear_name(name, m_name_length); + m_index = ::wil::reg::reg_iterator_details::iterator_end_offset; + } + + bool resize(size_t new_length) WI_NOEXCEPT + { + m_name_length = ::wil::reg::reg_iterator_details::resize_name(name, m_name_length, new_length); + // if failed to resize_name, will return 0 + return m_name_length > 0; + } + + HRESULT enumerate_current_index() WI_NOEXCEPT + { + FAIL_FAST_IF(at_end()); + + for (auto string_length = static_cast(m_name_length);;) + { + if (!resize(string_length)) + { + return E_OUTOFMEMORY; + } + + const auto error = ::RegEnumKeyExW( + m_hkey, // hKey + m_index, // dwIndex + string_length == 0 ? nullptr : ::wil::reg::reg_iterator_details::address_of_name(name), // lpName + &string_length, // lpcchName + nullptr, // lpReserved + nullptr, // lpClass + nullptr, // lpcchClass + nullptr); // lpftLastWriteTime + + if (error == ERROR_SUCCESS) + { + // some types, like std::wstring, cannot have embedded nulls + ::wil::reg::reg_view_details::reg_value_type_info::trim_buffer(name); + break; + } + if (error == ERROR_NO_MORE_ITEMS) + { + make_end_iterator(); + break; + } + if (error == ERROR_MORE_DATA) + { + // resize to iterator_default_buffer_length and try again + string_length += ::wil::reg::reg_iterator_details::iterator_default_buffer_length; + continue; + } + // any other error will fail + RETURN_WIN32(error); + } + return S_OK; + } + + HKEY m_hkey{}; + uint32_t m_index = ::wil::reg::reg_iterator_details::iterator_end_offset; + size_t m_name_length{}; + }; + + // all methods must be noexcept - to be usable with any iterator type (throwing or non-throwing) + template + class value_iterator_data + { + public: + T name{}; + DWORD type = REG_NONE; + + value_iterator_data(HKEY key = nullptr) WI_NOEXCEPT : m_hkey{ key } + { + } + ~value_iterator_data() WI_NOEXCEPT = default; + + value_iterator_data(const value_iterator_data& rhs) WI_NOEXCEPT + { + // might return null/empty string on failure + name = ::wil::reg::reg_iterator_details::copy_name(rhs.name, rhs.m_name_length); + type = rhs.type; + m_hkey = rhs.m_hkey; + m_index = rhs.m_index; + m_name_length = ::wil::reg::reg_iterator_details::is_valid(name) ? rhs.m_name_length : 0; + } + value_iterator_data& operator=(const value_iterator_data& rhs) WI_NOEXCEPT + { + if (&rhs != this) + { + value_iterator_data temp(rhs); + *this = ::wistd::move(temp); + } + return *this; + } + + value_iterator_data(value_iterator_data&&) WI_NOEXCEPT = default; + value_iterator_data& operator=(value_iterator_data&& rhs) WI_NOEXCEPT = default; + + bool at_end() const WI_NOEXCEPT + { + return m_index == ::wil::reg::reg_iterator_details::iterator_end_offset; + } + + private: +#if defined(WIL_ENABLE_EXCEPTIONS) + friend class ::wil::reg::iterator_t; +#endif + friend class ::wil::reg::iterator_nothrow_t; + + void make_end_iterator() WI_NOEXCEPT + { + ::wil::reg::reg_iterator_details::clear_name(name, m_name_length); + m_index = ::wil::reg::reg_iterator_details::iterator_end_offset; + } + + bool resize(size_t new_length) + { + m_name_length = ::wil::reg::reg_iterator_details::resize_name(name, m_name_length, new_length); + // if failed to resize_name, will return 0 + return m_name_length > 0; + } + + HRESULT enumerate_current_index() WI_NOEXCEPT + { + FAIL_FAST_IF(at_end()); + + for (auto string_length = static_cast(m_name_length);;) + { + if (!resize(string_length)) + { + return E_OUTOFMEMORY; + } + + const auto error = ::RegEnumValueW( + m_hkey, // hKey + m_index, // dwIndex + string_length == 0 ? nullptr : ::wil::reg::reg_iterator_details::address_of_name(name), // lpValueName + &string_length, // lpcchValueName + nullptr, // lpReserved + &type, // lpType + nullptr, // lpData + nullptr); // lpcbData + + if (error == ERROR_SUCCESS) + { + // some types, like std::wstring, cannot have embedded nulls + ::wil::reg::reg_view_details::reg_value_type_info::trim_buffer(name); + break; + } + if (error == ERROR_NO_MORE_ITEMS) + { + make_end_iterator(); + break; + } + if (error == ERROR_MORE_DATA) + { + // resize to iterator_default_buffer_length and try again + string_length += ::wil::reg::reg_iterator_details::iterator_default_buffer_length; + continue; + } + + // any other error will fail + RETURN_WIN32(error); + } + return S_OK; + } + + HKEY m_hkey{}; + uint32_t m_index = ::wil::reg::reg_iterator_details::iterator_end_offset; + size_t m_name_length{}; + }; + +#if defined(WIL_ENABLE_EXCEPTIONS) + template + class iterator_t + { + public: + // defining iterator_traits allows STL functions to be used with this iterator class. + // Notice this is a forward_iterator + // - does not support random-access (e.g. vector::iterator) + // - does not support bi-directional access (e.g. list::iterator) +#if defined(_ITERATOR_) + using iterator_category = ::std::forward_iterator_tag; +#endif + using value_type = T; + using difference_type = size_t; + using distance_type = size_t; + using pointer = T*; + using reference = T&; + + iterator_t() WI_NOEXCEPT = default; + ~iterator_t() WI_NOEXCEPT = default; + + iterator_t(HKEY hkey) : m_data(hkey) + { + if (hkey != nullptr) + { + m_data.resize(::wil::reg::reg_iterator_details::iterator_default_buffer_length); + m_data.m_index = 0; + m_data.enumerate_current_index(); + } + } + + iterator_t(const iterator_t&) = default; + iterator_t& operator=(const iterator_t&) = default; + iterator_t(iterator_t&&) WI_NOEXCEPT = default; + iterator_t& operator=(iterator_t&&) WI_NOEXCEPT = default; + + // operator support + const T& operator*() const + { + FAIL_FAST_IF(m_data.at_end()); + return m_data; + } + const T& operator*() + { + FAIL_FAST_IF(m_data.at_end()); + return m_data; + } + const T* operator->() const + { + FAIL_FAST_IF(m_data.at_end()); + return &m_data; + } + const T* operator->() + { + FAIL_FAST_IF(m_data.at_end()); + return &m_data; + } + + bool operator==(const iterator_t& rhs) const WI_NOEXCEPT + { + if (m_data.at_end() || rhs.m_data.at_end()) + { + // if either is not initialized (or end), both must not be initialized (or end) to be equal + return m_data.m_index == rhs.m_data.m_index; + } + return m_data.m_hkey == rhs.m_data.m_hkey && m_data.m_index == rhs.m_data.m_index; + } + + bool operator!=(const iterator_t& rhs) const WI_NOEXCEPT + { + return !(*this == rhs); + } + + // pre-increment + iterator_t& operator++() + { + this->operator +=(1); + return *this; + } + const iterator_t& operator++() const + { + this->operator +=(1); + return *this; + } + + // increment by integer + iterator_t& operator+=(size_t offset) + { + uint32_t newIndex = m_data.m_index + static_cast(offset); + if (newIndex < m_data.m_index) + { + // fail on integer overflow + THROW_HR(E_INVALIDARG); + } + if (newIndex == ::wil::reg::reg_iterator_details::iterator_end_offset) + { + // fail if this creates an end iterator + THROW_HR(E_INVALIDARG); + } + + // iterate by the integer offset + for (size_t count = 0; count < offset; ++count) + { + ++m_data.m_index; + m_data.enumerate_current_index(); + } + return *this; + } + + // not supporting post-increment - which would require copy-construction + iterator_t operator++(int) = delete; + + private: + // container based on the class template type + T m_data{}; + }; +#endif + + template + class iterator_nothrow_t + { + public: + iterator_nothrow_t() WI_NOEXCEPT = default; + ~iterator_nothrow_t() WI_NOEXCEPT = default; + + iterator_nothrow_t(HKEY hkey) WI_NOEXCEPT : m_data(hkey) + { + if (hkey != nullptr) + { + m_data.m_index = 0; + if (!m_data.resize(::wil::reg::reg_iterator_details::iterator_default_buffer_length)) + { + m_last_error = E_OUTOFMEMORY; + } + else + { + m_last_error = m_data.enumerate_current_index(); + } + } + } + + iterator_nothrow_t(const iterator_nothrow_t&) WI_NOEXCEPT = default; + iterator_nothrow_t& operator=(const iterator_nothrow_t&) WI_NOEXCEPT = default; + iterator_nothrow_t(iterator_nothrow_t&&) WI_NOEXCEPT = default; + iterator_nothrow_t& operator=(iterator_nothrow_t&&) WI_NOEXCEPT = default; + + bool at_end() const WI_NOEXCEPT + { + return m_data.at_end(); + } + + HRESULT last_error() const WI_NOEXCEPT + { + return m_last_error; + } + + HRESULT move_next() WI_NOEXCEPT + { + const auto newIndex = m_data.m_index + 1; + if (newIndex < m_data.m_index) + { + // fail on integer overflow + m_last_error = E_INVALIDARG; + } + else if (newIndex == ::wil::reg::reg_iterator_details::iterator_end_offset) + { + // fail if this creates an end iterator + m_last_error = E_INVALIDARG; + } + else + { + m_data.m_index = newIndex; + m_last_error = m_data.enumerate_current_index(); + } + + if (FAILED(m_last_error)) + { + // on failure, set the iterator to an end iterator + m_data.make_end_iterator(); + } + + return m_last_error; + } + + // operator support + const T& operator*() const WI_NOEXCEPT + { + return m_data; + } + const T& operator*() WI_NOEXCEPT + { + return m_data; + } + const T* operator->() const WI_NOEXCEPT + { + return &m_data; + } + const T* operator->() WI_NOEXCEPT + { + return &m_data; + } + bool operator==(const iterator_nothrow_t& rhs) const WI_NOEXCEPT + { + if (m_data.at_end() || rhs.m_data.at_end()) + { + // if either is not initialized (or end), both must not be initialized (or end) to be equal + return m_data.m_index == rhs.m_data.m_index; + } + return m_data.m_hkey == rhs.m_data.m_hkey && m_data.m_index == rhs.m_data.m_index; + } + + bool operator!=(const iterator_nothrow_t& rhs) const WI_NOEXCEPT + { + return !(*this == rhs); + } + + iterator_nothrow_t& operator++() WI_NOEXCEPT + { + move_next(); + return *this; + } + const iterator_nothrow_t& operator++() const WI_NOEXCEPT + { + move_next(); + return *this; + } + + private: + // container based on the class template type + T m_data{}; + HRESULT m_last_error{}; + }; + + } // namespace reg +} // namespace wil +#endif // __WIL_REGISTRY_HELPERS_INCLUDED \ No newline at end of file diff --git a/libraries/wil/resource.h b/libraries/wil/resource.h new file mode 100644 index 0000000..b45dde4 --- /dev/null +++ b/libraries/wil/resource.h @@ -0,0 +1,7095 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* + +#include "result_macros.h" +#include "wistd_functional.h" +#include "wistd_memory.h" + +#pragma warning(push) +#pragma warning(disable:26135 26110) // Missing locking annotation, Caller failing to hold lock +#pragma warning(disable:4714) // __forceinline not honored + +#ifndef __WIL_RESOURCE +#define __WIL_RESOURCE + +// stdint.h and intsafe.h have conflicting definitions, so it's not safe to include either to pick up our dependencies, +// so the definitions we need are copied below +#ifdef _WIN64 +#define __WI_SIZE_MAX 0xffffffffffffffffui64 // UINT64_MAX +#else /* _WIN64 */ +#define __WI_SIZE_MAX 0xffffffffui32 // UINT32_MAX +#endif /* _WIN64 */ + +// Forward declaration +/// @cond +namespace Microsoft +{ + namespace WRL + { + template + class ComPtr; + } +} +/// @endcond + +namespace wil +{ + //! This type copies the current value of GetLastError at construction and resets the last error + //! to that value when it is destroyed. + //! + //! This is useful in library code that runs during a value's destructor. If the library code could + //! inadvertently change the value of GetLastError (by calling a Win32 API or similar), it should + //! instantiate a value of this type before calling the library function in order to preserve the + //! GetLastError value the user would expect. + //! + //! This construct exists to hide kernel mode/user mode differences in wil library code. + //! + //! Example usage: + //! + //! if (!CreateFile(...)) + //! { + //! auto lastError = wil::last_error_context(); + //! WriteFile(g_hlog, logdata); + //! } + //! + class last_error_context + { +#ifndef WIL_KERNEL_MODE + bool m_dismissed = false; + DWORD m_error = 0; + public: + last_error_context() WI_NOEXCEPT : last_error_context(::GetLastError()) + { + } + + explicit last_error_context(DWORD error) WI_NOEXCEPT : + m_error(error) + { + } + + last_error_context(last_error_context&& other) WI_NOEXCEPT + { + operator=(wistd::move(other)); + } + + last_error_context& operator=(last_error_context&& other) WI_NOEXCEPT + { + m_dismissed = wistd::exchange(other.m_dismissed, true); + m_error = other.m_error; + + return *this; + } + + ~last_error_context() WI_NOEXCEPT + { + if (!m_dismissed) + { + ::SetLastError(m_error); + } + } + + //! last_error_context doesn't own a concrete resource, so therefore + //! it just disarms its destructor and returns void. + void release() WI_NOEXCEPT + { + WI_ASSERT(!m_dismissed); + m_dismissed = true; + } + + WI_NODISCARD auto value() const WI_NOEXCEPT + { + return m_error; + } +#else + public: + void release() WI_NOEXCEPT { } +#endif // WIL_KERNEL_MODE + }; + + /// @cond + namespace details + { + typedef wistd::integral_constant pointer_access_all; // get(), release(), addressof(), and '&' are available + typedef wistd::integral_constant pointer_access_noaddress; // get() and release() are available + typedef wistd::integral_constant pointer_access_none; // the raw pointer is not available + + template struct close_invoke_helper + { + __forceinline static void close(pointer_storage_t value) WI_NOEXCEPT { wistd::invoke(close_fn, value); } + inline static void close_reset(pointer_storage_t value) WI_NOEXCEPT + { + auto preserveError = last_error_context(); + wistd::invoke(close_fn, value); + } + }; + + template struct close_invoke_helper + { + __forceinline static void close(pointer_storage_t value) WI_NOEXCEPT { close_fn(value); } + inline static void close_reset(pointer_storage_t value) WI_NOEXCEPT + { + auto preserveError = last_error_context(); + close_fn(value); + } + }; + + template using close_invoker = + close_invoke_helper ? wistd::is_function_v> : false, close_fn_t, close_fn, pointer_storage_t>; + + template // nullptr_t if the invalid handle value is compatible with nullptr, otherwise pointer + struct resource_policy : close_invoker + { + typedef pointer_storage_t pointer_storage; + typedef pointer_t pointer; + typedef pointer_invalid_t pointer_invalid; + typedef pointer_access_t pointer_access; + __forceinline static pointer_storage invalid_value() { return (pointer)invalid; } + __forceinline static bool is_valid(pointer_storage value) WI_NOEXCEPT { return (static_cast(value) != (pointer)invalid); } + }; + + + // This class provides the pointer storage behind the implementation of unique_any_t utilizing the given + // resource_policy. It is separate from unique_any_t to allow a type-specific specialization class to plug + // into the inheritance chain between unique_any_t and unique_storage. This allows classes like unique_event + // to be a unique_any formed class, but also expose methods like SetEvent directly. + + template + class unique_storage + { + protected: + typedef Policy policy; + typedef typename policy::pointer_storage pointer_storage; + typedef typename policy::pointer pointer; + typedef unique_storage base_storage; + + public: + unique_storage() WI_NOEXCEPT : + m_ptr(policy::invalid_value()) + { + } + + explicit unique_storage(pointer_storage ptr) WI_NOEXCEPT : + m_ptr(ptr) + { + } + + unique_storage(unique_storage &&other) WI_NOEXCEPT : + m_ptr(wistd::move(other.m_ptr)) + { + other.m_ptr = policy::invalid_value(); + } + + ~unique_storage() WI_NOEXCEPT + { + if (policy::is_valid(m_ptr)) + { + policy::close(m_ptr); + } + } + + WI_NODISCARD bool is_valid() const WI_NOEXCEPT + { + return policy::is_valid(m_ptr); + } + + void reset(pointer_storage ptr = policy::invalid_value()) WI_NOEXCEPT + { + if (policy::is_valid(m_ptr)) + { + policy::close_reset(m_ptr); + } + m_ptr = ptr; + } + + void reset(wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::value, "reset(nullptr): valid only for handle types using nullptr as the invalid value"); + reset(); + } + + WI_NODISCARD pointer get() const WI_NOEXCEPT + { + return static_cast(m_ptr); + } + + pointer_storage release() WI_NOEXCEPT + { + static_assert(!wistd::is_same::value, "release(): the raw handle value is not available for this resource class"); + auto ptr = m_ptr; + m_ptr = policy::invalid_value(); + return ptr; + } + + pointer_storage *addressof() WI_NOEXCEPT + { + static_assert(wistd::is_same::value, "addressof(): the address of the raw handle is not available for this resource class"); + return &m_ptr; + } + + protected: + void replace(unique_storage &&other) WI_NOEXCEPT + { + reset(other.m_ptr); + other.m_ptr = policy::invalid_value(); + } + + private: + pointer_storage m_ptr; + }; + } // details + /// @endcond + + + // This class when paired with unique_storage and an optional type-specific specialization class implements + // the same interface as STL's unique_ptr<> for resource handle types. It is a non-copyable, yet movable class + // supporting attach (reset), detach (release), retrieval (get()). + + template + class unique_any_t : public storage_t + { + public: + typedef typename storage_t::policy policy; + typedef typename policy::pointer_storage pointer_storage; + typedef typename policy::pointer pointer; + + unique_any_t(unique_any_t const &) = delete; + unique_any_t& operator=(unique_any_t const &) = delete; + + // Note that the default constructor really shouldn't be needed (taken care of by the forwarding constructor below), but + // the forwarding constructor causes an internal compiler error when the class is used in a C++ array. Defining the default + // constructor independent of the forwarding constructor removes the compiler limitation. + unique_any_t() = default; + + // forwarding constructor: forwards all 'explicit' and multi-arg constructors to the base class + template + explicit unique_any_t(arg1 && first, args_t&&... args) + __WI_NOEXCEPT_((wistd::is_nothrow_constructible_v)) : + storage_t(wistd::forward(first), wistd::forward(args)...) + { + static_assert(wistd::is_same::value || + wistd::is_same::value || + wistd::is_same::value, "pointer_access policy must be a known pointer_access* integral type"); + } + + unique_any_t(wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::value, "nullptr constructor: valid only for handle types using nullptr as the invalid value"); + } + + unique_any_t(unique_any_t &&other) WI_NOEXCEPT : + storage_t(wistd::move(other)) + { + } + + unique_any_t& operator=(unique_any_t &&other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + // cast to base_storage to 'skip' calling the (optional) specialization class that provides handle-specific functionality + storage_t::replace(wistd::move(static_cast(other))); + } + return (*this); + } + + unique_any_t& operator=(wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::value, "nullptr assignment: valid only for handle types using nullptr as the invalid value"); + storage_t::reset(); + return (*this); + } + + void swap(unique_any_t &other) WI_NOEXCEPT + { + unique_any_t self(wistd::move(*this)); + operator=(wistd::move(other)); + other = wistd::move(self); + } + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return storage_t::is_valid(); + } + + //! ~~~~ + //! BOOL OpenOrCreateWaffle(PCWSTR name, HWAFFLE* handle); + //! wil::unique_any waffle; + //! RETURN_IF_WIN32_BOOL_FALSE(OpenOrCreateWaffle(L"tasty.yum", waffle.put())); + //! ~~~~ + pointer_storage *put() WI_NOEXCEPT + { + static_assert(wistd::is_same::value, "operator & is not available for this handle"); + storage_t::reset(); + return storage_t::addressof(); + } + + pointer_storage *operator&() WI_NOEXCEPT + { + return put(); + } + + WI_NODISCARD pointer get() const WI_NOEXCEPT + { + static_assert(!wistd::is_same::value, "get(): the raw handle value is not available for this resource class"); + return storage_t::get(); + } + + // The following functions are publicly exposed by their inclusion in the unique_storage base class + + // explicit unique_any_t(pointer_storage ptr) WI_NOEXCEPT + // void reset(pointer_storage ptr = policy::invalid_value()) WI_NOEXCEPT + // void reset(wistd::nullptr_t) WI_NOEXCEPT + // pointer_storage release() WI_NOEXCEPT // not exposed for some resource types + // pointer_storage *addressof() WI_NOEXCEPT // not exposed for some resource types + }; + + template + void swap(unique_any_t& left, unique_any_t& right) WI_NOEXCEPT + { + left.swap(right); + } + + template + bool operator==(const unique_any_t& left, const unique_any_t& right) WI_NOEXCEPT + { + return (left.get() == right.get()); + } + + template + bool operator==(const unique_any_t& left, wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::policy::pointer_invalid, wistd::nullptr_t>::value, "the resource class does not use nullptr as an invalid value"); + return !left; + } + + template + bool operator==(wistd::nullptr_t, const unique_any_t& right) WI_NOEXCEPT + { + static_assert(wistd::is_same::policy::pointer_invalid, wistd::nullptr_t>::value, "the resource class does not use nullptr as an invalid value"); + return !right; + } + + template + bool operator!=(const unique_any_t& left, const unique_any_t& right) WI_NOEXCEPT + { + return (!(left.get() == right.get())); + } + + template + bool operator!=(const unique_any_t& left, wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::policy::pointer_invalid, wistd::nullptr_t>::value, "the resource class does not use nullptr as an invalid value"); + return !!left; + } + + template + bool operator!=(wistd::nullptr_t, const unique_any_t& right) WI_NOEXCEPT + { + static_assert(wistd::is_same::policy::pointer_invalid, wistd::nullptr_t>::value, "the resource class does not use nullptr as an invalid value"); + return !!right; + } + + template + bool operator<(const unique_any_t& left, const unique_any_t& right) WI_NOEXCEPT + { + return (left.get() < right.get()); + } + + template + bool operator>=(const unique_any_t& left, const unique_any_t& right) WI_NOEXCEPT + { + return (!(left < right)); + } + + template + bool operator>(const unique_any_t& left, const unique_any_t& right) WI_NOEXCEPT + { + return (right < left); + } + + template + bool operator<=(const unique_any_t& left, const unique_any_t& right) WI_NOEXCEPT + { + return (!(right < left)); + } + + // unique_any provides a template alias for easily building a unique_any_t from a unique_storage class with the given + // template parameters for resource_policy. + + template // nullptr_t if the invalid handle value is compatible with nullptr, otherwise pointer + using unique_any = unique_any_t>>; + + /// @cond + namespace details + { + template + class lambda_call + { + public: + lambda_call(const lambda_call&) = delete; + lambda_call& operator=(const lambda_call&) = delete; + lambda_call& operator=(lambda_call&& other) = delete; + + explicit lambda_call(TLambda&& lambda) WI_NOEXCEPT : m_lambda(wistd::move(lambda)) + { + static_assert(wistd::is_same::value, "scope_exit lambdas must not have a return value"); + static_assert(!wistd::is_lvalue_reference::value && !wistd::is_rvalue_reference::value, + "scope_exit should only be directly used with a lambda"); + } + + lambda_call(lambda_call&& other) WI_NOEXCEPT : m_lambda(wistd::move(other.m_lambda)), m_call(other.m_call) + { + other.m_call = false; + } + + ~lambda_call() WI_NOEXCEPT + { + reset(); + } + + // Ensures the scope_exit lambda will not be called + void release() WI_NOEXCEPT + { + m_call = false; + } + + // Executes the scope_exit lambda immediately if not yet run; ensures it will not run again + void reset() WI_NOEXCEPT + { + if (m_call) + { + m_call = false; + m_lambda(); + } + } + + // Returns true if the scope_exit lambda is still going to be executed + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return m_call; + } + + protected: + TLambda m_lambda; + bool m_call = true; + }; + +#ifdef WIL_ENABLE_EXCEPTIONS + template + class lambda_call_log + { + public: + lambda_call_log(const lambda_call_log&) = delete; + lambda_call_log& operator=(const lambda_call_log&) = delete; + lambda_call_log& operator=(lambda_call_log&& other) = delete; + + explicit lambda_call_log(void* address, const DiagnosticsInfo& info, TLambda&& lambda) WI_NOEXCEPT : + m_address(address), m_info(info), m_lambda(wistd::move(lambda)) + { + static_assert(wistd::is_same::value, "scope_exit lambdas must return 'void'"); + static_assert(!wistd::is_lvalue_reference::value && !wistd::is_rvalue_reference::value, + "scope_exit should only be directly used with a lambda"); + } + + lambda_call_log(lambda_call_log&& other) WI_NOEXCEPT : + m_address(other.m_address), m_info(other.m_info), m_lambda(wistd::move(other.m_lambda)), m_call(other.m_call) + { + other.m_call = false; + } + + ~lambda_call_log() WI_NOEXCEPT + { + reset(); + } + + // Ensures the scope_exit lambda will not be called + void release() WI_NOEXCEPT + { + m_call = false; + } + + // Executes the scope_exit lambda immediately if not yet run; ensures it will not run again + void reset() WI_NOEXCEPT + { + if (m_call) + { + m_call = false; + try + { + m_lambda(); + } + catch (...) + { + ReportFailure_CaughtException(__R_DIAGNOSTICS(m_info), m_address); + } + } + } + + // Returns true if the scope_exit lambda is still going to be executed + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return m_call; + } + + private: + void* m_address; + DiagnosticsInfo m_info; + TLambda m_lambda; + bool m_call = true; + }; +#endif // WIL_ENABLE_EXCEPTIONS + } + /// @endcond + + /** Returns an object that executes the given lambda when destroyed. + Capture the object with 'auto'; use reset() to execute the lambda early or release() to avoid + execution. Exceptions thrown in the lambda will fail-fast; use scope_exit_log to avoid. */ + template + WI_NODISCARD inline auto scope_exit(TLambda&& lambda) WI_NOEXCEPT + { + return details::lambda_call(wistd::forward(lambda)); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Returns an object that executes the given lambda when destroyed; logs exceptions. + Capture the object with 'auto'; use reset() to execute the lambda early or release() to avoid + execution. Exceptions thrown in the lambda will be caught and logged without being propagated. */ + template + WI_NODISCARD inline __declspec(noinline) auto scope_exit_log(const DiagnosticsInfo& diagnostics, TLambda&& lambda) WI_NOEXCEPT + { + return details::lambda_call_log(_ReturnAddress(), diagnostics, wistd::forward(lambda)); + } +#endif + + // Forward declaration... + template + class com_ptr_t; + + //! Type traits class that identifies the inner type of any smart pointer. + template + struct smart_pointer_details + { + typedef typename Ptr::pointer pointer; + }; + + /// @cond + template + struct smart_pointer_details> + { + typedef T* pointer; + }; + /// @endcond + + /** Generically detaches a raw pointer from any smart pointer. + Caller takes ownership of the returned raw pointer; calls the correct release(), detach(), + or Detach() method based on the smart pointer type */ + template + WI_NODISCARD typename TSmartPointer::pointer detach_from_smart_pointer(TSmartPointer& smartPtr) + { + return smartPtr.release(); + } + + /// @cond + // Generically detaches a raw pointer from any smart pointer + template + WI_NODISCARD T* detach_from_smart_pointer(wil::com_ptr_t& smartPtr) + { + return smartPtr.detach(); + } + + // Generically detaches a raw pointer from any smart pointer + template + WI_NODISCARD T* detach_from_smart_pointer(Microsoft::WRL::ComPtr& smartPtr) + { + return smartPtr.Detach(); + } + + template class com_ptr_t; // forward + namespace details + { + // The first two attach_to_smart_pointer() overloads are ambiguous when passed a com_ptr_t. + // To solve that use this functions return type to elminate the reset form for com_ptr_t. + template wistd::false_type use_reset(wil::com_ptr_t*) { return wistd::false_type(); } + template wistd::true_type use_reset(T*) { return wistd::true_type(); } + } + /// @endcond + + /** Generically attach a raw pointer to a compatible smart pointer. + Calls the correct reset(), attach(), or Attach() method based on samrt pointer type. */ + template (nullptr)))::value>> + void attach_to_smart_pointer(TSmartPointer& smartPtr, typename TSmartPointer::pointer rawPtr) + { + smartPtr.reset(rawPtr); + } + + /// @cond + + // Generically attach a raw pointer to a compatible smart pointer. + template + void attach_to_smart_pointer(wil::com_ptr_t& smartPtr, T* rawPtr) + { + smartPtr.attach(rawPtr); + } + + // Generically attach a raw pointer to a compatible smart pointer. + template + void attach_to_smart_pointer(Microsoft::WRL::ComPtr& smartPtr, T* rawPtr) + { + smartPtr.Attach(rawPtr); + } + /// @endcond + + //! @ingroup outparam + /** Detach a smart pointer resource to an optional output pointer parameter. + Avoids cluttering code with nullptr tests; works generically for any smart pointer */ + template + inline void detach_to_opt_param(_Out_opt_ T* outParam, TSmartPointer&& smartPtr) + { + if (outParam) + { + *outParam = detach_from_smart_pointer(smartPtr); + } + } + + /// @cond + namespace details + { + template + struct out_param_t + { + typedef typename wil::smart_pointer_details::pointer pointer; + T &wrapper; + pointer pRaw; + bool replace = true; + + out_param_t(_Inout_ T &output) : + wrapper(output), + pRaw(nullptr) + { + } + + out_param_t(out_param_t&& other) WI_NOEXCEPT : + wrapper(other.wrapper), + pRaw(other.pRaw) + { + WI_ASSERT(other.replace); + other.replace = false; + } + + operator pointer*() + { + WI_ASSERT(replace); + return &pRaw; + } + + ~out_param_t() + { + if (replace) + { + attach_to_smart_pointer(wrapper, pRaw); + } + } + + out_param_t(out_param_t const &other) = delete; + out_param_t &operator=(out_param_t const &other) = delete; + }; + + template + struct out_param_ptr_t + { + typedef typename wil::smart_pointer_details::pointer pointer; + T &wrapper; + pointer pRaw; + bool replace = true; + + out_param_ptr_t(_Inout_ T &output) : + wrapper(output), + pRaw(nullptr) + { + } + + out_param_ptr_t(out_param_ptr_t&& other) WI_NOEXCEPT : + wrapper(other.wrapper), + pRaw(other.pRaw) + { + WI_ASSERT(other.replace); + other.replace = false; + } + + operator Tcast() + { + WI_ASSERT(replace); + return reinterpret_cast(&pRaw); + } + + ~out_param_ptr_t() + { + if (replace) + { + attach_to_smart_pointer(wrapper, pRaw); + } + } + + out_param_ptr_t(out_param_ptr_t const &other) = delete; + out_param_ptr_t &operator=(out_param_ptr_t const &other) = delete; + }; + } // details + /// @endcond + + /** Use to retrieve raw out parameter pointers into smart pointers that do not support the '&' operator. + This avoids multi-step handling of a raw resource to establish the smart pointer. + Example: `GetFoo(out_param(foo));` */ + template + details::out_param_t out_param(T& p) + { + return details::out_param_t(p); + } + + /** Use to retrieve raw out parameter pointers (with a required cast) into smart pointers that do not support the '&' operator. + Use only when the smart pointer's &handle is not equal to the output type a function requires, necessitating a cast. + Example: `wil::out_param_ptr(securityDescriptor)` */ + template + details::out_param_ptr_t out_param_ptr(T& p) + { + return details::out_param_ptr_t(p); + } + + /** Use unique_struct to define an RAII type for a trivial struct that references resources that must be cleaned up. + Unique_struct wraps a trivial struct using a custom clean up function and, optionally, custom initializer function. If no custom initialier function is defined in the template + then ZeroMemory is used. + Unique_struct is modeled off of std::unique_ptr. However, unique_struct inherits from the defined type instead of managing the struct through a private member variable. + + If the type you're wrapping is a system type, you can share the code by declaring it in this file (Resource.h). Send requests to wildisc. + Otherwise, if the type is local to your project, declare it locally. + @tparam struct_t The struct you want to manage + @tparam close_fn_t The type of the function to clean up the struct. Takes one parameter: a pointer of struct_t. Return values are ignored. + @tparam close_fn The function of type close_fn_t. This is called in the destructor and reset functions. + @tparam init_fn_t Optional:The type of the function to initialize the struct. Takes one parameter: a pointer of struct_t. Return values are ignored. + @tparam init_fn Optional:The function of type init_fn_t. This is called in the constructor, reset, and release functions. The default is ZeroMemory to initialize the struct. + + Defined using the default zero memory initializer + ~~~ + typedef wil::unique_struct unique_prop_variant_default_init; + + unique_prop_variant_default_init propvariant; + SomeFunction(&propvariant); + ~~~ + + Defined using a custom initializer + ~~~ + typedef wil::unique_struct unique_prop_variant; + + unique_prop_variant propvariant; + SomeFunction(&propvariant); + ~~~ + */ + template + class unique_struct : public struct_t + { + using closer = details::close_invoker; + public: + //! Initializes the managed struct using the user-provided initialization function, or ZeroMemory if no function is specified + unique_struct() + { + call_init(use_default_init_fn()); + } + + //! Takes ownership of the struct by doing a shallow copy. Must explicitly be type struct_t + explicit unique_struct(const struct_t& other) WI_NOEXCEPT : + struct_t(other) + {} + + //! Initializes the managed struct by taking the ownership of the other managed struct + //! Then resets the other managed struct by calling the custom close function + unique_struct(unique_struct&& other) WI_NOEXCEPT : + struct_t(other.release()) + {} + + //! Resets this managed struct by calling the custom close function and takes ownership of the other managed struct + //! Then resets the other managed struct by calling the custom close function + unique_struct & operator=(unique_struct&& other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(other.release()); + } + return *this; + } + + //! Calls the custom close function + ~unique_struct() WI_NOEXCEPT + { + closer::close(this); + } + + void reset(const unique_struct&) = delete; + + //! Resets this managed struct by calling the custom close function and begins management of the other struct + void reset(const struct_t& other) WI_NOEXCEPT + { + closer::close_reset(this); + struct_t::operator=(other); + } + + //! Resets this managed struct by calling the custom close function + //! Then initializes this managed struct using the user-provided initialization function, or ZeroMemory if no function is specified + void reset() WI_NOEXCEPT + { + closer::close(this); + call_init(use_default_init_fn()); + } + + void swap(struct_t&) = delete; + + //! Swaps the managed structs + void swap(unique_struct& other) WI_NOEXCEPT + { + struct_t self(*this); + struct_t::operator=(other); + *(other.addressof()) = self; + } + + //! Returns the managed struct + //! Then initializes this managed struct using the user-provided initialization function, or ZeroMemory if no function is specified + struct_t release() WI_NOEXCEPT + { + struct_t value(*this); + call_init(use_default_init_fn()); + return value; + } + + //! Returns address of the managed struct + struct_t * addressof() WI_NOEXCEPT + { + return this; + } + + //! Resets this managed struct by calling the custom close function + //! Then initializes this managed struct using the user-provided initialization function, or ZeroMemory if no function is specified + //! Returns address of the managed struct + struct_t * reset_and_addressof() WI_NOEXCEPT + { + reset(); + return this; + } + + unique_struct(const unique_struct&) = delete; + unique_struct& operator=(const unique_struct&) = delete; + unique_struct& operator=(const struct_t&) = delete; + + private: + typedef typename wistd::is_same::type use_default_init_fn; + + void call_init(wistd::true_type) + { + RtlZeroMemory(this, sizeof(*this)); + } + + void call_init(wistd::false_type) + { + init_fn(this); + } + }; + + struct empty_deleter + { + template + void operator()(_Pre_opt_valid_ _Frees_ptr_opt_ T) const + { + } + }; + + /** unique_any_array_ptr is a RAII type for managing conformant arrays that need to be freed and have elements that may need to be freed. + The intented use for this RAII type would be to capture out params from API like IPropertyValue::GetStringArray. + This class also maintains the size of the array, so it can iterate over the members and deallocate them before it deallocates the base array pointer. + + If the type you're wrapping is a system type, you can share the code by declaring it in this file (Resource.h). Send requests to wildisc. + Otherwise, if the type is local to your project, declare it locally. + + @tparam ValueType: The type of array you want to manage. + @tparam ArrayDeleter: The type of the function to clean up the array. Takes one parameter of type T[] or T*. Return values are ignored. This is called in the destructor and reset functions. + @tparam ElementDeleter: The type of the function to clean up the array elements. Takes one parameter of type T. Return values are ignored. This is called in the destructor and reset functions. + + ~~~ + void GetSomeArray(_Out_ size_t*, _Out_ NOTMYTYPE**); + + struct not_my_deleter + { + void operator()(NOTMYTYPE p) const + { + destroy(p); + } + }; + + wil::unique_any_array_ptr myArray; + GetSomeArray(myArray.size_address(), &myArray); + ~~~ */ + template + class unique_any_array_ptr + { + public: + typedef ValueType value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef ValueType *pointer; + typedef const ValueType *const_pointer; + typedef ValueType& reference; + typedef const ValueType& const_reference; + + typedef ValueType* iterator; + typedef const ValueType* const_iterator; + + unique_any_array_ptr() = default; + unique_any_array_ptr(const unique_any_array_ptr&) = delete; + unique_any_array_ptr& operator=(const unique_any_array_ptr&) = delete; + + unique_any_array_ptr(wistd::nullptr_t) WI_NOEXCEPT + { + } + + unique_any_array_ptr& operator=(wistd::nullptr_t) WI_NOEXCEPT + { + reset(); + return *this; + } + + unique_any_array_ptr(pointer ptr, size_t size) WI_NOEXCEPT : m_ptr(ptr), m_size(size) + { + } + + unique_any_array_ptr(unique_any_array_ptr&& other) WI_NOEXCEPT : m_ptr(other.m_ptr), m_size(other.m_size) + { + other.m_ptr = nullptr; + other.m_size = size_type{}; + } + + unique_any_array_ptr& operator=(unique_any_array_ptr&& other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + swap(other); + } + return *this; + } + + ~unique_any_array_ptr() WI_NOEXCEPT + { + reset(); + } + + void swap(unique_any_array_ptr& other) WI_NOEXCEPT + { + auto ptr = m_ptr; + auto size = m_size; + m_ptr = other.m_ptr; + m_size = other.m_size; + other.m_ptr = ptr; + other.m_size = size; + } + + WI_NODISCARD iterator begin() WI_NOEXCEPT + { + return (iterator(m_ptr)); + } + + WI_NODISCARD const_iterator begin() const WI_NOEXCEPT + { + return (const_iterator(m_ptr)); + } + + WI_NODISCARD iterator end() WI_NOEXCEPT + { + return (iterator(m_ptr + m_size)); + } + + WI_NODISCARD const_iterator end() const WI_NOEXCEPT + { + return (const_iterator(m_ptr + m_size)); + } + + WI_NODISCARD const_iterator cbegin() const WI_NOEXCEPT + { + return (begin()); + } + + WI_NODISCARD const_iterator cend() const WI_NOEXCEPT + { + return (end()); + } + + WI_NODISCARD size_type size() const WI_NOEXCEPT + { + return (m_size); + } + + WI_NODISCARD bool empty() const WI_NOEXCEPT + { + return (size() == size_type{}); + } + + WI_NODISCARD reference operator[](size_type position) + { + WI_ASSERT(position < m_size); + _Analysis_assume_(position < m_size); + return (m_ptr[position]); + } + + WI_NODISCARD const_reference operator[](size_type position) const + { + WI_ASSERT(position < m_size); + _Analysis_assume_(position < m_size); + return (m_ptr[position]); + } + + WI_NODISCARD reference front() + { + WI_ASSERT(!empty()); + return (m_ptr[0]); + } + + WI_NODISCARD const_reference front() const + { + WI_ASSERT(!empty()); + return (m_ptr[0]); + } + + WI_NODISCARD reference back() + { + WI_ASSERT(!empty()); + return (m_ptr[m_size - 1]); + } + + WI_NODISCARD const_reference back() const + { + WI_ASSERT(!empty()); + return (m_ptr[m_size - 1]); + } + + WI_NODISCARD ValueType* data() WI_NOEXCEPT + { + return (m_ptr); + } + + WI_NODISCARD const ValueType* data() const WI_NOEXCEPT + { + return (m_ptr); + } + + WI_NODISCARD pointer get() const WI_NOEXCEPT + { + return m_ptr; + } + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return (m_ptr != pointer()); + } + + pointer release() WI_NOEXCEPT + { + auto result = m_ptr; + m_ptr = nullptr; + m_size = size_type{}; + return result; + } + + void reset() WI_NOEXCEPT + { + if (m_ptr) + { + reset_array(ElementDeleter()); + ArrayDeleter()(m_ptr); + m_ptr = nullptr; + m_size = size_type{}; + } + } + + void reset(pointer ptr, size_t size) WI_NOEXCEPT + { + reset(); + m_ptr = ptr; + m_size = size; + } + + pointer* addressof() WI_NOEXCEPT + { + return &m_ptr; + } + + pointer* put() WI_NOEXCEPT + { + reset(); + return addressof(); + } + + pointer* operator&() WI_NOEXCEPT + { + return put(); + } + + size_type* size_address() WI_NOEXCEPT + { + return &m_size; + } + + template + struct size_address_ptr + { + unique_any_array_ptr& wrapper; + TSize size{}; + bool replace = true; + + size_address_ptr(_Inout_ unique_any_array_ptr& output) : + wrapper(output) + { + } + + size_address_ptr(size_address_ptr&& other) WI_NOEXCEPT : + wrapper(other.wrapper), + size(other.size) + { + WI_ASSERT(other.replace); + other.replace = false; + } + + operator TSize*() + { + WI_ASSERT(replace); + return &size; + } + + ~size_address_ptr() + { + if (replace) + { + *wrapper.size_address() = static_cast(size); + } + } + + size_address_ptr(size_address_ptr const &other) = delete; + size_address_ptr &operator=(size_address_ptr const &other) = delete; + }; + + template + size_address_ptr size_address() WI_NOEXCEPT + { + return size_address_ptr(*this); + } + + private: + pointer m_ptr = nullptr; + size_type m_size{}; + + void reset_array(const empty_deleter&) + { + } + + template + void reset_array(const T& deleter) + { + for (auto& element : make_range(m_ptr, m_size)) + { + deleter(element); + } + } + }; + + // forward declaration + template + class com_ptr_t; + + /// @cond + namespace details + { + template + struct unique_any_array_deleter + { + template + void operator()(_Pre_opt_valid_ _Frees_ptr_opt_ T* p) const + { + UniqueAnyType::policy::close_reset(p); + } + }; + + template + struct unique_struct_array_deleter + { + template + void operator()(_Pre_opt_valid_ _Frees_ptr_opt_ T& p) const + { + close_invoker::close(&p); + } + }; + + struct com_unknown_deleter + { + template + void operator()(_Pre_opt_valid_ _Frees_ptr_opt_ T* p) const + { + if (p) + { + p->Release(); + } + } + }; + + template + struct element_traits + { + typedef empty_deleter deleter; + typedef T type; + }; + + template + struct element_traits> + { + typedef unique_any_array_deleter> deleter; + typedef typename unique_any_t::pointer type; + }; + + template + struct element_traits> + { + typedef com_unknown_deleter deleter; + typedef T* type; + }; + + template + struct element_traits> + { + typedef unique_struct_array_deleter deleter; + typedef struct_t type; + }; + } + /// @endcond + + template + using unique_array_ptr = unique_any_array_ptr::type, ArrayDeleter, typename details::element_traits::deleter>; + + /** Adapter for single-parameter 'free memory' for `wistd::unique_ptr`. + This struct provides a standard wrapper for calling a platform function to deallocate memory held by a + `wistd::unique_ptr`, making declaring them as easy as declaring wil::unique_any<>. + + Consider this adapter in preference to `wil::unique_any<>` when the returned type is really a pointer or an + array of items; `wistd::unique_ptr<>` exposes `operator->()` and `operator[]` for array-typed things safely. + ~~~~ + EXTERN_C VOID WINAPI MyDllFreeMemory(void* p); + EXTERN_C HRESULT MyDllGetString(_Outptr_ PWSTR* pString); + EXTERN_C HRESULT MyDllGetThing(_In_ PCWSTR pString, _Outptr_ PMYSTRUCT* ppThing); + template + using unique_mydll_ptr = wistd::unique_ptr>; + HRESULT Test() + { + unique_mydll_ptr dllString; + unique_mydll_ptr thing; + RETURN_IF_FAILED(MyDllGetString(wil::out_param(dllString))); + RETURN_IF_FAILED(MyDllGetThing(dllString.get(), wil::out_param(thing))); + if (thing->Member) + { + // ... + } + return S_OK; + } + ~~~~ */ + template struct function_deleter + { + template void operator()(_Frees_ptr_opt_ T* toFree) const + { + TDeleter(toFree); + } + }; + + /** Use unique_com_token to define an RAII type for a token-based resource that is managed by a COM interface. + By comparison, unique_any_t has the requirement that the close function must be static. This works for functions + such as CloseHandle(), but for any resource cleanup function that relies on a more complex interface, + unique_com_token can be used. + + @tparam interface_t A COM interface pointer that will manage this resource type. + @tparam token_t The token type that relates to the COM interface management functions. + @tparam close_fn_t The type of the function that is called when the resource is destroyed. + @tparam close_fn The function used to destroy the associated resource. This function should have the signature void(interface_t* source, token_t token). + @tparam invalid_token Optional:An invalid token value. Defaults to default-constructed token_t(). + + Example + ~~~ + void __stdcall MyInterfaceCloseFunction(IMyInterface* source, DWORD token) + { + source->MyCloseFunction(token); + } + using unique_my_interface_token = wil::unique_com_token; + ~~~ */ + template + class unique_com_token + { + public: + unique_com_token() = default; + + unique_com_token(_In_opt_ interface_t* source, token_t token = invalid_token) WI_NOEXCEPT + { + reset(source, token); + } + + unique_com_token(unique_com_token&& other) WI_NOEXCEPT : m_source(other.m_source), m_token(other.m_token) + { + other.m_source = nullptr; + other.m_token = invalid_token; + } + + unique_com_token& operator=(unique_com_token&& other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + m_source = other.m_source; + m_token = other.m_token; + + other.m_source = nullptr; + other.m_token = invalid_token; + } + return *this; + } + + ~unique_com_token() WI_NOEXCEPT + { + reset(); + } + + //! Determine if the underlying source and token are valid + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return (m_token != invalid_token) && m_source; + } + + //! Associates a new source and releases the existing token if valid + void associate(_In_opt_ interface_t* source) WI_NOEXCEPT + { + reset(source, invalid_token); + } + + //! Assigns a new source and token + void reset(_In_opt_ interface_t* source, token_t token) WI_NOEXCEPT + { + WI_ASSERT(source || (token == invalid_token)); + + // Determine if we need to call the close function on our previous token. + if (m_token != invalid_token) + { + if ((m_source != source) || (m_token != token)) + { + wistd::invoke(close_fn, m_source, m_token); + } + } + + m_token = token; + + // Assign our new source and manage the reference counts + if (m_source != source) + { + auto oldSource = m_source; + m_source = source; + + if (m_source) + { + m_source->AddRef(); + } + + if (oldSource) + { + oldSource->Release(); + } + } + } + + //! Assigns a new token without modifying the source; associate must be called first + void reset(token_t token) WI_NOEXCEPT + { + reset(m_source, token); + } + + //! Closes the token and the releases the reference to the source + void reset() WI_NOEXCEPT + { + reset(nullptr, invalid_token); + } + + //! Exchanges values with another managed token + void swap(unique_com_token& other) WI_NOEXCEPT + { + wistd::swap_wil(m_source, other.m_source); + wistd::swap_wil(m_token, other.m_token); + } + + //! Releases the held token to the caller without closing it and releases the reference to the source. + //! Requires that the associated COM interface be kept alive externally or the released token may be invalidated + token_t release() WI_NOEXCEPT + { + auto token = m_token; + m_token = invalid_token; + reset(); + return token; + } + + //! Returns address of the managed token; associate must be called first + token_t* addressof() WI_NOEXCEPT + { + WI_ASSERT(m_source); + return &m_token; + } + + //! Releases the held token and allows attaching a new token; associate must be called first + token_t* put() WI_NOEXCEPT + { + reset(invalid_token); + return addressof(); + } + + //! Releases the held token and allows attaching a new token; associate must be called first + token_t* operator&() WI_NOEXCEPT + { + return put(); + } + + //! Retrieves the token + WI_NODISCARD token_t get() const WI_NOEXCEPT + { + return m_token; + } + + unique_com_token(const unique_com_token&) = delete; + unique_com_token& operator=(const unique_com_token&) = delete; + + private: + interface_t* m_source = nullptr; + token_t m_token = invalid_token; + }; + + /** Use unique_com_call to define an RAII type that demands a particular parameter-less method be called on a COM interface. + This allows implementing an RAII type that can call a Close() method (think IClosable) or a SetSite(nullptr) + method (think IObjectWithSite) or some other method when a basic interface call is required as part of the RAII contract. + see wil::com_set_site in wil\com.h for the IObjectWithSite support. + + @tparam interface_t A COM interface pointer that provides context to make the call. + @tparam close_fn_t The type of the function that is called to invoke the method. + @tparam close_fn The function used to invoke the interface method. This function should have the signature void(interface_t* source). + + Example + ~~~ + void __stdcall CloseIClosable(IClosable* source) + { + source->Close(); + } + using unique_closable_call = wil::unique_com_call; + ~~~ */ + template + class unique_com_call + { + public: + unique_com_call() = default; + + explicit unique_com_call(_In_opt_ interface_t* ptr) WI_NOEXCEPT + { + reset(ptr); + } + + unique_com_call(unique_com_call&& other) WI_NOEXCEPT + { + m_ptr = other.m_ptr; + other.m_ptr = nullptr; + } + + unique_com_call& operator=(unique_com_call&& other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + m_ptr = other.m_ptr; + other.m_ptr = nullptr; + } + return *this; + } + + ~unique_com_call() WI_NOEXCEPT + { + reset(); + } + + //! Assigns an interface to make a given call on + void reset(_In_opt_ interface_t* ptr = nullptr) WI_NOEXCEPT + { + if (ptr != m_ptr) + { + auto oldSource = m_ptr; + m_ptr = ptr; + if (m_ptr) + { + m_ptr->AddRef(); + } + if (oldSource) + { + details::close_invoker::close(oldSource); + oldSource->Release(); + } + } + } + + //! Exchanges values with another class + void swap(unique_com_call& other) WI_NOEXCEPT + { + wistd::swap_wil(m_ptr, other.m_ptr); + } + + //! Cancel the interface call that this class was expected to make + void release() WI_NOEXCEPT + { + auto ptr = m_ptr; + m_ptr = nullptr; + if (ptr) + { + ptr->Release(); + } + } + + //! Returns true if the call this class was expected to make is still outstanding + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return (m_ptr != nullptr); + } + + //! Returns address of the internal interface + interface_t** addressof() WI_NOEXCEPT + { + return &m_ptr; + } + + //! Releases the held interface (first performing the interface call if required) + //! and allows attaching a new interface + interface_t** put() WI_NOEXCEPT + { + reset(); + return addressof(); + } + + //! Releases the held interface (first performing the interface call if required) + //! and allows attaching a new interface + interface_t** operator&() WI_NOEXCEPT + { + return put(); + } + + unique_com_call(const unique_com_call&) = delete; + unique_com_call& operator=(const unique_com_call&) = delete; + + private: + interface_t* m_ptr = nullptr; + }; + + + /** Use unique_call to define an RAII type that demands a particular parameter-less global function be called. + This allows implementing a RAII types that can call methods like CoUninitialize. + + @tparam close_fn_t The type of the function that is called to invoke the call. + @tparam close_fn The function used to invoke the call. This function should have the signature void(). + @tparam default_value Determines whether the unique_call is active or inactive when default-constructed or reset. + + Example + ~~~ + void __stdcall CoUninitializeFunction() + { + ::CoUninitialize(); + } + using unique_couninitialize_call = wil::unique_call; + ~~~ */ + template + class unique_call + { + public: + unique_call() = default; + + explicit unique_call(bool call) WI_NOEXCEPT : m_call(call) + { + } + + unique_call(unique_call&& other) WI_NOEXCEPT + { + m_call = other.m_call; + other.m_call = false; + } + + unique_call& operator=(unique_call&& other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + m_call = other.m_call; + other.m_call = false; + } + return *this; + } + + ~unique_call() WI_NOEXCEPT + { + reset(); + } + + //! Assigns a new ptr and token + void reset() WI_NOEXCEPT + { + auto call = m_call; + m_call = false; + if (call) + { + close_fn(); + } + } + + //! Exchanges values with raii class + void swap(unique_call& other) WI_NOEXCEPT + { + wistd::swap_wil(m_call, other.m_call); + } + + //! Make the interface call that was expected of this class + void activate() WI_NOEXCEPT + { + m_call = true; + } + + //! Do not make the interface call that was expected of this class + void release() WI_NOEXCEPT + { + m_call = false; + } + + //! Returns true if the call that was expected is still outstanding + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return m_call; + } + + unique_call(const unique_call&) = delete; + unique_call& operator=(const unique_call&) = delete; + + private: + bool m_call = default_value; + }; + + // str_raw_ptr is an overloaded function that retrieves a const pointer to the first character in a string's buffer. + // Overloads in this file support any string that is implicitly convertible to a PCWSTR, HSTRING, and any unique_any_t + // that points to any other supported type (this covers unique_hstring, unique_cotaskmem_string, and similar). + // An overload for std::wstring is available in stl.h. + inline PCWSTR str_raw_ptr(PCWSTR str) + { + return str; + } + + template + PCWSTR str_raw_ptr(const unique_any_t& ua) + { + return str_raw_ptr(ua.get()); + } + +#if !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) + namespace details + { + // Forward declaration + template struct string_maker; + + // Concatenate any number of strings together and store it in an automatically allocated string. If a string is present + // in the input buffer, it is overwritten. + template + HRESULT str_build_nothrow(string_type& result, _In_reads_(strCount) PCWSTR* strList, size_t strCount) + { + size_t lengthRequiredWithoutNull{}; + for (auto& string : make_range(strList, strCount)) + { + lengthRequiredWithoutNull += string ? wcslen(string) : 0; + } + + details::string_maker maker; + RETURN_IF_FAILED(maker.make(nullptr, lengthRequiredWithoutNull)); + + auto buffer = maker.buffer(); + auto bufferEnd = buffer + lengthRequiredWithoutNull + 1; + for (auto& string : make_range(strList, strCount)) + { + if (string) + { + RETURN_IF_FAILED(StringCchCopyExW(buffer, (bufferEnd - buffer), string, &buffer, nullptr, STRSAFE_IGNORE_NULLS)); + } + } + + result = maker.release(); + return S_OK; + } + + // NOTE: 'Strings' must all be PCWSTR, or convertible to PCWSTR, but C++ doesn't allow us to express that cleanly + template + HRESULT str_build_nothrow(string_type& result, Strings... strings) + { + PCWSTR localStrings[] = { strings... }; + return str_build_nothrow(result, localStrings, sizeof...(Strings)); + } + } + + // Concatenate any number of strings together and store it in an automatically allocated string. If a string is present + // in the input buffer, the remaining strings are appended to it. + template + HRESULT str_concat_nothrow(string_type& buffer, const strings&... str) + { + static_assert(sizeof...(str) > 0, "attempting to concatenate no strings"); + return details::str_build_nothrow(buffer, details::string_maker::get(buffer), str_raw_ptr(str)...); + } +#endif // !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) + +#ifdef WIL_ENABLE_EXCEPTIONS + // Concatenate any number of strings together and store it in an automatically allocated string. + template + string_type str_concat(arguments&&... args) + { + string_type result{}; + THROW_IF_FAILED(str_concat_nothrow(result, wistd::forward(args)...)); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + + // Concatenate any number of strings together and store it in an automatically allocated string. + template + string_type str_concat_failfast(arguments&&... args) + { + string_type result{}; + FAIL_FAST_IF_FAILED(str_concat_nothrow(result, wistd::forward(args)...)); + return result; + } + +#if !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) + namespace details + { + // Wraps StringCchPrintFExW and stores it in an automatically allocated string. Takes a buffer followed by the same format arguments + // that StringCchPrintfExW takes. + template + HRESULT str_vprintf_nothrow(string_type& result, _Printf_format_string_ PCWSTR pszFormat, va_list& argsVL) + { + size_t lengthRequiredWithoutNull = _vscwprintf(pszFormat, argsVL); + + string_maker maker; + RETURN_IF_FAILED(maker.make(nullptr, lengthRequiredWithoutNull)); + + auto buffer = maker.buffer(); + RETURN_IF_FAILED(StringCchVPrintfExW(buffer, lengthRequiredWithoutNull + 1, nullptr, nullptr, STRSAFE_NULL_ON_FAILURE, pszFormat, argsVL)); + + result = maker.release(); + return S_OK; + } + } + + // Wraps StringCchPrintFExW and stores it in an automatically allocated string. Takes a buffer followed by the same format arguments + // that StringCchPrintfExW takes. + template + HRESULT str_printf_nothrow(string_type& result, _Printf_format_string_ PCWSTR pszFormat, ...) + { + va_list argsVL; + va_start(argsVL, pszFormat); + auto hr = details::str_vprintf_nothrow(result, pszFormat, argsVL); + va_end(argsVL); + return hr; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + // Wraps StringCchPrintFExW and stores it in an automatically allocated string. Takes a buffer followed by the same format arguments + // that StringCchPrintfExW takes. + template + string_type str_printf(_Printf_format_string_ PCWSTR pszFormat, ...) + { + string_type result{}; + va_list argsVL; + va_start(argsVL, pszFormat); + auto hr = details::str_vprintf_nothrow(result, pszFormat, argsVL); + va_end(argsVL); + THROW_IF_FAILED(hr); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + + // Wraps StringCchPrintFExW and stores it in an automatically allocated string. Takes a buffer followed by the same format arguments + // that StringCchPrintfExW takes. + template + string_type str_printf_failfast(_Printf_format_string_ PCWSTR pszFormat, ...) + { + string_type result{}; + va_list argsVL; + va_start(argsVL, pszFormat); + auto hr = details::str_vprintf_nothrow(result, pszFormat, argsVL); + va_end(argsVL); + FAIL_FAST_IF_FAILED(hr); + return result; + } +#endif // !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) + +} // namespace wil +#endif // __WIL_RESOURCE + + + // Hash deferral function for unique_any_t +#if (defined(_UNORDERED_SET_) || defined(_UNORDERED_MAP_)) && !defined(__WIL_RESOURCE_UNIQUE_HASH) +#define __WIL_RESOURCE_UNIQUE_HASH +namespace std +{ + template + struct hash> + { + WI_NODISCARD size_t operator()(wil::unique_any_t const &val) const + { + return (hash::pointer>()(val.get())); + } + }; +} +#endif + +// shared_any and weak_any implementation using STL header +#if defined(_MEMORY_) && defined(WIL_ENABLE_EXCEPTIONS) && !defined(WIL_RESOURCE_STL) && !defined(RESOURCE_SUPPRESS_STL) +#define WIL_RESOURCE_STL +namespace wil { + + template + class weak_any; + + /// @cond + namespace details + { + // This class provides the pointer storage behind the implementation of shared_any_t utilizing the given + // resource_policy. It is separate from shared_any_t to allow a type-specific specialization class to plug + // into the inheritance chain between shared_any_t and shared_storage. This allows classes like shared_event + // to be a shared_any formed class, but also expose methods like SetEvent directly. + + template + class shared_storage + { + protected: + typedef UniqueT unique_t; + typedef typename unique_t::policy policy; + typedef typename policy::pointer_storage pointer_storage; + typedef typename policy::pointer pointer; + typedef shared_storage base_storage; + + public: + shared_storage() = default; + + explicit shared_storage(pointer_storage ptr) + { + if (policy::is_valid(ptr)) + { + m_ptr = std::make_shared(unique_t(ptr)); // unique_t on the stack to prevent leak on throw + } + } + + shared_storage(unique_t &&other) + { + if (other) + { + m_ptr = std::make_shared(wistd::move(other)); + } + } + + shared_storage(const shared_storage &other) WI_NOEXCEPT : + m_ptr(other.m_ptr) + { + } + + shared_storage& operator=(const shared_storage &other) WI_NOEXCEPT + { + m_ptr = other.m_ptr; + return *this; + } + + shared_storage(shared_storage &&other) WI_NOEXCEPT : + m_ptr(wistd::move(other.m_ptr)) + { + } + + shared_storage(std::shared_ptr const &ptr) : + m_ptr(ptr) + { + } + + WI_NODISCARD bool is_valid() const WI_NOEXCEPT + { + return (m_ptr && m_ptr->is_valid()); + } + + void reset(pointer_storage ptr = policy::invalid_value()) + { + if (policy::is_valid(ptr)) + { + m_ptr = std::make_shared(unique_t(ptr)); // unique_t on the stack to prevent leak on throw + } + else + { + m_ptr = nullptr; + } + } + + void reset(unique_t &&other) + { + m_ptr = std::make_shared(wistd::move(other)); + } + + void reset(wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::value, "reset(nullptr): valid only for handle types using nullptr as the invalid value"); + reset(); + } + + template ::value, int>::type = 0> + WI_NODISCARD pointer get() const WI_NOEXCEPT + { + return (m_ptr ? m_ptr->get() : policy::invalid_value()); + } + + template ::value, int>::type = 0> + pointer_storage *addressof() + { + if (!m_ptr) + { + m_ptr = std::make_shared(); + } + return m_ptr->addressof(); + } + + WI_NODISCARD long int use_count() const WI_NOEXCEPT + { + return m_ptr.use_count(); + } + + protected: + void replace(shared_storage &&other) WI_NOEXCEPT + { + m_ptr = wistd::move(other.m_ptr); + } + + private: + template + friend class ::wil::weak_any; + + std::shared_ptr m_ptr; + }; + } + /// @endcond + + // This class when paired with shared_storage and an optional type-specific specialization class implements + // the same interface as STL's shared_ptr<> for resource handle types. It is both copyable and movable, supporting + // weak references and automatic closure of the handle upon release of the last shared_any. + + template + class shared_any_t : public storage_t + { + public: + typedef typename storage_t::policy policy; + typedef typename policy::pointer_storage pointer_storage; + typedef typename policy::pointer pointer; + typedef typename storage_t::unique_t unique_t; + + // default and forwarding constructor: forwards default, all 'explicit' and multi-arg constructors to the base class + template + explicit shared_any_t(args_t&&... args) + __WI_NOEXCEPT_((wistd::is_nothrow_constructible_v)) : + storage_t(wistd::forward(args)...) + { + } + + shared_any_t(wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::value, "nullptr constructor: valid only for handle types using nullptr as the invalid value"); + } + + shared_any_t(shared_any_t &&other) WI_NOEXCEPT : + storage_t(wistd::move(other)) + { + } + + shared_any_t(const shared_any_t &other) WI_NOEXCEPT : + storage_t(other) + { + } + + shared_any_t& operator=(shared_any_t &&other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + storage_t::replace(wistd::move(static_cast(other))); + } + return (*this); + } + + shared_any_t& operator=(const shared_any_t& other) WI_NOEXCEPT + { + storage_t::operator=(other); + return (*this); + } + + shared_any_t(unique_t &&other) : + storage_t(wistd::move(other)) + { + } + + shared_any_t& operator=(unique_t &&other) + { + storage_t::reset(wistd::move(other)); + return (*this); + } + + shared_any_t& operator=(wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::value, "nullptr assignment: valid only for handle types using nullptr as the invalid value"); + storage_t::reset(); + return (*this); + } + + void swap(shared_any_t &other) WI_NOEXCEPT + { + shared_any_t self(wistd::move(*this)); + operator=(wistd::move(other)); + other = wistd::move(self); + } + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return storage_t::is_valid(); + } + + pointer_storage *put() + { + static_assert(wistd::is_same::value, "operator & is not available for this handle"); + storage_t::reset(); + return storage_t::addressof(); + } + + pointer_storage *operator&() + { + return put(); + } + + WI_NODISCARD pointer get() const WI_NOEXCEPT + { + static_assert(!wistd::is_same::value, "get(): the raw handle value is not available for this resource class"); + return storage_t::get(); + } + + // The following functions are publicly exposed by their inclusion in the base class + + // void reset(pointer_storage ptr = policy::invalid_value()) WI_NOEXCEPT + // void reset(wistd::nullptr_t) WI_NOEXCEPT + // pointer_storage *addressof() WI_NOEXCEPT // (note: not exposed for opaque resource types) + }; + + template + void swap(shared_any_t& left, shared_any_t& right) WI_NOEXCEPT + { + left.swap(right); + } + + template + bool operator==(const shared_any_t& left, const shared_any_t& right) WI_NOEXCEPT + { + return (left.get() == right.get()); + } + + template + bool operator==(const shared_any_t& left, wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::policy::pointer_invalid, wistd::nullptr_t>::value, "the resource class does not use nullptr as an invalid value"); + return !left; + } + + template + bool operator==(wistd::nullptr_t, const shared_any_t& right) WI_NOEXCEPT + { + static_assert(wistd::is_same::policy::pointer_invalid, wistd::nullptr_t>::value, "the resource class does not use nullptr as an invalid value"); + return !right; + } + + template + bool operator!=(const shared_any_t& left, const shared_any_t& right) WI_NOEXCEPT + { + return (!(left.get() == right.get())); + } + + template + bool operator!=(const shared_any_t& left, wistd::nullptr_t) WI_NOEXCEPT + { + static_assert(wistd::is_same::policy::pointer_invalid, wistd::nullptr_t>::value, "the resource class does not use nullptr as an invalid value"); + return !!left; + } + + template + bool operator!=(wistd::nullptr_t, const shared_any_t& right) WI_NOEXCEPT + { + static_assert(wistd::is_same::policy::pointer_invalid, wistd::nullptr_t>::value, "the resource class does not use nullptr as an invalid value"); + return !!right; + } + + template + bool operator<(const shared_any_t& left, const shared_any_t& right) WI_NOEXCEPT + { + return (left.get() < right.get()); + } + + template + bool operator>=(const shared_any_t& left, const shared_any_t& right) WI_NOEXCEPT + { + return (!(left < right)); + } + + template + bool operator>(const shared_any_t& left, const shared_any_t& right) WI_NOEXCEPT + { + return (right < left); + } + + template + bool operator<=(const shared_any_t& left, const shared_any_t& right) WI_NOEXCEPT + { + return (!(right < left)); + } + + + // This class provides weak_ptr<> support for shared_any<>, bringing the same weak reference counting and lock() acquire semantics + // to shared_any. + + template + class weak_any + { + public: + typedef SharedT shared_t; + + weak_any() WI_NOEXCEPT + { + } + + weak_any(const shared_t &other) WI_NOEXCEPT : + m_weakPtr(other.m_ptr) + { + } + + weak_any(const weak_any &other) WI_NOEXCEPT : + m_weakPtr(other.m_weakPtr) + { + } + + weak_any& operator=(const weak_any &right) WI_NOEXCEPT + { + m_weakPtr = right.m_weakPtr; + return (*this); + } + + weak_any& operator=(const shared_t &right) WI_NOEXCEPT + { + m_weakPtr = right.m_ptr; + return (*this); + } + + void reset() WI_NOEXCEPT + { + m_weakPtr.reset(); + } + + void swap(weak_any &other) WI_NOEXCEPT + { + m_weakPtr.swap(other.m_weakPtr); + } + + WI_NODISCARD bool expired() const WI_NOEXCEPT + { + return m_weakPtr.expired(); + } + + WI_NODISCARD shared_t lock() const WI_NOEXCEPT + { + return shared_t(m_weakPtr.lock()); + } + + private: + std::weak_ptr m_weakPtr; + }; + + template + void swap(weak_any& left, weak_any& right) WI_NOEXCEPT + { + left.swap(right); + } + + template + using shared_any = shared_any_t>; + +} // namespace wil +#endif + + +#if defined(WIL_RESOURCE_STL) && (defined(_UNORDERED_SET_) || defined(_UNORDERED_MAP_)) && !defined(__WIL_RESOURCE_SHARED_HASH) +#define __WIL_RESOURCE_SHARED_HASH +namespace std +{ + template + struct hash> + { + WI_NODISCARD size_t operator()(wil::shared_any_t const &val) const + { + return (hash::pointer>()(val.get())); + } + }; +} +#endif + + +namespace wil +{ + +#if defined(__NOTHROW_T_DEFINED) && !defined(__WIL__NOTHROW_T_DEFINED) +#define __WIL__NOTHROW_T_DEFINED + /** Provides `std::make_unique()` semantics for resources allocated in a context that may not throw upon allocation failure. + `wil::make_unique_nothrow()` is identical to `std::make_unique()` except for the following: + * It returns `wistd::unique_ptr`, rather than `std::unique_ptr` + * It returns an empty (null) `wistd::unique_ptr` upon allocation failure, rather than throwing an exception + + Note that `wil::make_unique_nothrow()` is not marked WI_NOEXCEPT as it may be used to create an exception-based class that may throw in its constructor. + ~~~ + auto foo = wil::make_unique_nothrow(fooConstructorParam1, fooConstructorParam2); + if (foo) + { + foo->Bar(); + } + ~~~ + */ + template + inline typename wistd::enable_if::value, wistd::unique_ptr<_Ty> >::type make_unique_nothrow(_Types&&... _Args) + { + return (wistd::unique_ptr<_Ty>(new(std::nothrow) _Ty(wistd::forward<_Types>(_Args)...))); + } + + /** Provides `std::make_unique()` semantics for array resources allocated in a context that may not throw upon allocation failure. + See the overload of `wil::make_unique_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_nothrow(size); // the default constructor will be called on each Foo object + if (foos) + { + for (auto& elem : wil::make_range(foos.get(), size)) + { + elem.Bar(); + } + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent<_Ty>::value == 0, wistd::unique_ptr<_Ty> >::type make_unique_nothrow(size_t _Size) + { + typedef typename wistd::remove_extent<_Ty>::type _Elem; + return (wistd::unique_ptr<_Ty>(new(std::nothrow) _Elem[_Size]())); + } + + template + typename wistd::enable_if::value != 0, void>::type make_unique_nothrow(_Types&&...) = delete; + +#if !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) + /** Provides `std::make_unique()` semantics for resources allocated in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_failfast(fooConstructorParam1, fooConstructorParam2); + foo->Bar(); + ~~~ + */ + template + inline typename wistd::enable_if::value, wistd::unique_ptr<_Ty> >::type make_unique_failfast(_Types&&... _Args) + { +#pragma warning(suppress: 28193) // temporary must be inspected (it is within the called function) + return (wistd::unique_ptr<_Ty>(FAIL_FAST_IF_NULL_ALLOC(new(std::nothrow) _Ty(wistd::forward<_Types>(_Args)...)))); + } + + /** Provides `std::make_unique()` semantics for array resources allocated in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_nothrow(size); // the default constructor will be called on each Foo object + for (auto& elem : wil::make_range(foos.get(), size)) + { + elem.Bar(); + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent<_Ty>::value == 0, wistd::unique_ptr<_Ty> >::type make_unique_failfast(size_t _Size) + { + typedef typename wistd::remove_extent<_Ty>::type _Elem; +#pragma warning(suppress: 28193) // temporary must be inspected (it is within the called function) + return (wistd::unique_ptr<_Ty>(FAIL_FAST_IF_NULL_ALLOC(new(std::nothrow) _Elem[_Size]()))); + } + + template + typename wistd::enable_if::value != 0, void>::type make_unique_failfast(_Types&&...) = delete; +#endif // !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) +#endif // __WIL__NOTHROW_T_DEFINED + +#if defined(_WINBASE_) && !defined(__WIL_WINBASE_) && !defined(WIL_KERNEL_MODE) +#define __WIL_WINBASE_ + /// @cond + namespace details + { + inline void __stdcall SetEvent(HANDLE h) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT_WIN32_BOOL_FALSE__(::SetEvent(h)); + } + + inline void __stdcall ResetEvent(HANDLE h) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT_WIN32_BOOL_FALSE__(::ResetEvent(h)); + } + + inline void __stdcall CloseHandle(HANDLE h) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT_WIN32_BOOL_FALSE__(::CloseHandle(h)); + } + + inline void __stdcall ReleaseSemaphore(_In_ HANDLE h) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT_WIN32_BOOL_FALSE__(::ReleaseSemaphore(h, 1, nullptr)); + } + + inline void __stdcall ReleaseMutex(_In_ HANDLE h) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT_WIN32_BOOL_FALSE__(::ReleaseMutex(h)); + } + + inline void __stdcall CloseTokenLinkedToken(_In_ TOKEN_LINKED_TOKEN* linkedToken) WI_NOEXCEPT + { + if (linkedToken->LinkedToken && (linkedToken->LinkedToken != INVALID_HANDLE_VALUE)) + { + __FAIL_FAST_ASSERT_WIN32_BOOL_FALSE__(::CloseHandle(linkedToken->LinkedToken)); + } + } + + enum class PendingCallbackCancellationBehavior + { + Cancel, + Wait, + NoWait, + }; + + template + struct DestroyThreadPoolWait + { + static void Destroy(_In_ PTP_WAIT threadPoolWait) WI_NOEXCEPT + { + ::SetThreadpoolWait(threadPoolWait, nullptr, nullptr); + ::WaitForThreadpoolWaitCallbacks(threadPoolWait, (cancellationBehavior == PendingCallbackCancellationBehavior::Cancel)); + ::CloseThreadpoolWait(threadPoolWait); + } + }; + + template <> + struct DestroyThreadPoolWait + { + static void Destroy(_In_ PTP_WAIT threadPoolWait) WI_NOEXCEPT + { + ::CloseThreadpoolWait(threadPoolWait); + } + }; + + template + struct DestroyThreadPoolWork + { + static void Destroy(_In_ PTP_WORK threadpoolWork) WI_NOEXCEPT + { + ::WaitForThreadpoolWorkCallbacks(threadpoolWork, (cancellationBehavior == PendingCallbackCancellationBehavior::Cancel)); + ::CloseThreadpoolWork(threadpoolWork); + } + }; + + template <> + struct DestroyThreadPoolWork + { + static void Destroy(_In_ PTP_WORK threadpoolWork) WI_NOEXCEPT + { + ::CloseThreadpoolWork(threadpoolWork); + } + }; + + // Non-RTL implementation for threadpool_t parameter of DestroyThreadPoolTimer<> + struct SystemThreadPoolMethods + { + static void WINAPI SetThreadpoolTimer(_Inout_ PTP_TIMER Timer, _In_opt_ PFILETIME DueTime, _In_ DWORD Period, _In_ DWORD WindowLength) WI_NOEXCEPT + { + ::SetThreadpoolTimer(Timer, DueTime, Period, WindowLength); + } + static void WaitForThreadpoolTimerCallbacks(_Inout_ PTP_TIMER Timer, _In_ BOOL CancelPendingCallbacks) WI_NOEXCEPT + { + ::WaitForThreadpoolTimerCallbacks(Timer, CancelPendingCallbacks); + } + static void CloseThreadpoolTimer(_Inout_ PTP_TIMER Timer) WI_NOEXCEPT + { + ::CloseThreadpoolTimer(Timer); + } + }; + + // SetThreadpoolTimer(timer, nullptr, 0, 0) will cancel any pending callbacks, + // then CloseThreadpoolTimer will asynchronusly close the timer if a callback is running. + template + struct DestroyThreadPoolTimer + { + static void Destroy(_In_ PTP_TIMER threadpoolTimer) WI_NOEXCEPT + { + threadpool_t::SetThreadpoolTimer(threadpoolTimer, nullptr, 0, 0); +#pragma warning(suppress:4127) // conditional expression is constant + if (cancellationBehavior != PendingCallbackCancellationBehavior::NoWait) + { + threadpool_t::WaitForThreadpoolTimerCallbacks(threadpoolTimer, (cancellationBehavior == PendingCallbackCancellationBehavior::Cancel)); + } + threadpool_t::CloseThreadpoolTimer(threadpoolTimer); + } + }; + + // PendingCallbackCancellationBehavior::NoWait explicitly does not block waiting for + // callbacks when destructing. + template + struct DestroyThreadPoolTimer + { + static void Destroy(_In_ PTP_TIMER threadpoolTimer) WI_NOEXCEPT + { + threadpool_t::CloseThreadpoolTimer(threadpoolTimer); + } + }; + + template + struct DestroyThreadPoolIo + { + static void Destroy(_In_ PTP_IO threadpoolIo) WI_NOEXCEPT + { + ::WaitForThreadpoolIoCallbacks(threadpoolIo, (cancellationBehavior == PendingCallbackCancellationBehavior::Cancel)); + ::CloseThreadpoolIo(threadpoolIo); + } + }; + + template <> + struct DestroyThreadPoolIo + { + static void Destroy(_In_ PTP_IO threadpoolIo) WI_NOEXCEPT + { + ::CloseThreadpoolIo(threadpoolIo); + } + }; + + template + struct handle_invalid_resource_policy : resource_policy + { + __forceinline static bool is_valid(HANDLE ptr) WI_NOEXCEPT { return ((ptr != INVALID_HANDLE_VALUE) && (ptr != nullptr)); } + }; + + template + struct handle_null_resource_policy : resource_policy + { + __forceinline static bool is_valid(HANDLE ptr) WI_NOEXCEPT { return ((ptr != nullptr) && (ptr != INVALID_HANDLE_VALUE)); } + }; + + template + struct handle_null_only_resource_policy : resource_policy + { + __forceinline static bool is_valid(HANDLE ptr) WI_NOEXCEPT { return (ptr != nullptr); } + }; + + typedef resource_policy handle_resource_policy; + } + /// @endcond + + template + using unique_any_handle_invalid = unique_any_t>>; + + template + using unique_any_handle_null = unique_any_t>>; + + template + using unique_any_handle_null_only = unique_any_t>>; + + typedef unique_any_handle_invalid unique_hfile; + typedef unique_any_handle_null unique_handle; + typedef unique_any_handle_invalid unique_hfind; + typedef unique_any unique_hmodule; + typedef unique_any_handle_null_only unique_process_handle; + + typedef unique_struct unique_token_linked_token; + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) + typedef unique_any unique_sid; + typedef unique_any_handle_null_only unique_boundary_descriptor; + + namespace details + { + template + inline void __stdcall ClosePrivateNamespaceHelper(HANDLE h) WI_NOEXCEPT + { + ::ClosePrivateNamespace(h, flags); + } + } + + template + using unique_private_namespace = unique_any_handle_null_only>; + + using unique_private_namespace_close = unique_private_namespace<>; + using unique_private_namespace_destroy = unique_private_namespace; +#endif + + using unique_tool_help_snapshot = unique_hfile; + + typedef unique_any::Destroy> unique_threadpool_wait; + typedef unique_any::Destroy> unique_threadpool_wait_nocancel; + typedef unique_any::Destroy> unique_threadpool_wait_nowait; + typedef unique_any::Destroy> unique_threadpool_work; + typedef unique_any::Destroy> unique_threadpool_work_nocancel; + typedef unique_any::Destroy> unique_threadpool_work_nowait; + typedef unique_any::Destroy> unique_threadpool_timer; + typedef unique_any::Destroy> unique_threadpool_timer_nocancel; + typedef unique_any::Destroy> unique_threadpool_timer_nowait; + typedef unique_any::Destroy> unique_threadpool_io; + typedef unique_any::Destroy> unique_threadpool_io_nocancel; + typedef unique_any::Destroy> unique_threadpool_io_nowait; + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + typedef unique_any_handle_invalid unique_hfind_change; +#endif + + typedef unique_any event_set_scope_exit; + typedef unique_any event_reset_scope_exit; + + // Guarantees a SetEvent on the given event handle when the returned object goes out of scope + // Note: call SetEvent early with the reset() method on the returned object or abort the call with the release() method + WI_NODISCARD inline event_set_scope_exit SetEvent_scope_exit(HANDLE hEvent) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT__(hEvent != nullptr); + return event_set_scope_exit(hEvent); + } + + // Guarantees a ResetEvent on the given event handle when the returned object goes out of scope + // Note: call ResetEvent early with the reset() method on the returned object or abort the call with the release() method + WI_NODISCARD inline event_reset_scope_exit ResetEvent_scope_exit(HANDLE hEvent) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT__(hEvent != nullptr); + return event_reset_scope_exit(hEvent); + } + + // Checks to see if the given *manual reset* event is currently signaled. The event must not be an auto-reset event. + // Use when the event will only be set once (cancellation-style) or will only be reset by the polling thread + inline bool event_is_signaled(HANDLE hEvent) WI_NOEXCEPT + { + auto status = ::WaitForSingleObjectEx(hEvent, 0, FALSE); + // Fast fail will trip for wait failures, auto-reset events, or when the event is being both Set and Reset + // from a thread other than the polling thread (use event_wait directly for those cases). + __FAIL_FAST_ASSERT__((status == WAIT_TIMEOUT) || ((status == WAIT_OBJECT_0) && (WAIT_OBJECT_0 == ::WaitForSingleObjectEx(hEvent, 0, FALSE)))); + return (status == WAIT_OBJECT_0); + } + + // Waits on the given handle for the specified duration + inline bool handle_wait(HANDLE hEvent, DWORD dwMilliseconds = INFINITE, BOOL bAlertable = FALSE) WI_NOEXCEPT + { + DWORD status = ::WaitForSingleObjectEx(hEvent, dwMilliseconds, bAlertable); + __FAIL_FAST_ASSERT__((status == WAIT_TIMEOUT) || (status == WAIT_OBJECT_0) || (bAlertable && (status == WAIT_IO_COMPLETION))); + return (status == WAIT_OBJECT_0); + } + + enum class EventOptions + { + None = 0x0, + ManualReset = 0x1, + Signaled = 0x2 + }; + DEFINE_ENUM_FLAG_OPERATORS(EventOptions); + + template + class event_t : public storage_t + { + public: + // forward all base class constructors... + template + explicit event_t(args_t&&... args) WI_NOEXCEPT : storage_t(wistd::forward(args)...) {} + + // HRESULT or void error handling... + typedef typename err_policy::result result; + + // Exception-based constructor to create an unnamed event + event_t(EventOptions options) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions or fail fast; use the create method"); + create(options); + } + + void ResetEvent() const WI_NOEXCEPT + { + details::ResetEvent(storage_t::get()); + } + + void SetEvent() const WI_NOEXCEPT + { + details::SetEvent(storage_t::get()); + } + + // Guarantees a SetEvent on the given event handle when the returned object goes out of scope + // Note: call SetEvent early with the reset() method on the returned object or abort the call with the release() method + WI_NODISCARD event_set_scope_exit SetEvent_scope_exit() const WI_NOEXCEPT + { + return wil::SetEvent_scope_exit(storage_t::get()); + } + + // Guarantees a ResetEvent on the given event handle when the returned object goes out of scope + // Note: call ResetEvent early with the reset() method on the returned object or abort the call with the release() method + WI_NODISCARD event_reset_scope_exit ResetEvent_scope_exit() const WI_NOEXCEPT + { + return wil::ResetEvent_scope_exit(storage_t::get()); + } + + // Checks if a *manual reset* event is currently signaled. The event must not be an auto-reset event. + // Use when the event will only be set once (cancellation-style) or will only be reset by the polling thread + WI_NODISCARD bool is_signaled() const WI_NOEXCEPT + { + return wil::event_is_signaled(storage_t::get()); + } + + // Basic WaitForSingleObject on the event handle with the given timeout + bool wait(DWORD dwMilliseconds = INFINITE, BOOL bAlertable = FALSE) const WI_NOEXCEPT + { + return wil::handle_wait(storage_t::get(), dwMilliseconds, bAlertable); + } + + // Tries to create a named event -- returns false if unable to do so (gle may still be inspected with return=false) + bool try_create(EventOptions options, PCWSTR name, _In_opt_ LPSECURITY_ATTRIBUTES securityAttributes = nullptr, _Out_opt_ bool *alreadyExists = nullptr) + { + auto handle = ::CreateEventExW(securityAttributes, name, (WI_IsFlagSet(options, EventOptions::ManualReset) ? CREATE_EVENT_MANUAL_RESET : 0) | (WI_IsFlagSet(options, EventOptions::Signaled) ? CREATE_EVENT_INITIAL_SET : 0), EVENT_ALL_ACCESS); + if (!handle) + { + assign_to_opt_param(alreadyExists, false); + return false; + } + assign_to_opt_param(alreadyExists, (::GetLastError() == ERROR_ALREADY_EXISTS)); + storage_t::reset(handle); + return true; + } + + // Returns HRESULT for unique_event_nothrow, void with exceptions for shared_event and unique_event + result create(EventOptions options = EventOptions::None, PCWSTR name = nullptr, _In_opt_ LPSECURITY_ATTRIBUTES securityAttributes = nullptr, _Out_opt_ bool *alreadyExists = nullptr) + { + return err_policy::LastErrorIfFalse(try_create(options, name, securityAttributes, alreadyExists)); + } + + // Tries to open the named event -- returns false if unable to do so (gle may still be inspected with return=false) + bool try_open(_In_ PCWSTR name, DWORD desiredAccess = SYNCHRONIZE | EVENT_MODIFY_STATE, bool inheritHandle = false) + { + auto handle = ::OpenEventW(desiredAccess, inheritHandle, name); + if (handle == nullptr) + { + return false; + } + storage_t::reset(handle); + return true; + } + + // Returns HRESULT for unique_event_nothrow, void with exceptions for shared_event and unique_event + result open(_In_ PCWSTR name, DWORD desiredAccess = SYNCHRONIZE | EVENT_MODIFY_STATE, bool inheritHandle = false) + { + return err_policy::LastErrorIfFalse(try_open(name, desiredAccess, inheritHandle)); + } + }; + + typedef unique_any_t, err_returncode_policy>> unique_event_nothrow; + typedef unique_any_t, err_failfast_policy>> unique_event_failfast; +#ifdef WIL_ENABLE_EXCEPTIONS + typedef unique_any_t, err_exception_policy>> unique_event; +#endif + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && ((_WIN32_WINNT >= _WIN32_WINNT_WIN8) || (__WIL_RESOURCE_ENABLE_QUIRKS && (_WIN32_WINNT >= _WIN32_WINNT_WIN7))) + enum class SlimEventType + { + AutoReset, + ManualReset, + }; + + /** A lean and mean event class. + This class provides a very similar API to `wil::unique_event` but doesn't require a kernel object. + + The two variants of this class are: + - `wil::slim_event_auto_reset` + - `wil::slim_event_manual_reset` + + In addition, `wil::slim_event_auto_reset` has the alias `wil::slim_event`. + + Some key differences to `wil::unique_event` include: + - There is no 'create()' function, as initialization occurs in the constructor and can't fail. + - The move functions have been deleted. + - For auto-reset events, the `is_signaled()` function doesn't reset the event. (Use `ResetEvent()` instead.) + - The `ResetEvent()` function returns the previous state of the event. + - To create a manual reset event, use `wil::slim_event_manual_reset'. + ~~~~ + wil::slim_event finished; + std::thread doStuff([&finished] () { + Sleep(10); + finished.SetEvent(); + }); + finished.wait(); + + std::shared_ptr CreateSharedEvent(bool startSignaled) + { + return std::make_shared(startSignaled); + } + ~~~~ */ + template + class slim_event_t + { + public: + slim_event_t() WI_NOEXCEPT = default; + + slim_event_t(bool isSignaled) WI_NOEXCEPT : + m_isSignaled(isSignaled ? TRUE : FALSE) + { + } + + // Cannot change memory location. + slim_event_t(const slim_event_t&) = delete; + slim_event_t(slim_event_t&&) = delete; + slim_event_t& operator=(const slim_event_t&) = delete; + slim_event_t& operator=(slim_event_t&&) = delete; + + // Returns the previous state of the event. + bool ResetEvent() WI_NOEXCEPT + { + return !!InterlockedExchange(&m_isSignaled, FALSE); + } + + void SetEvent() WI_NOEXCEPT + { + // FYI: 'WakeByAddress*' invokes a full memory barrier. + WriteRelease(&m_isSignaled, TRUE); + + #pragma warning(suppress:4127) // conditional expression is constant + if (Type == SlimEventType::AutoReset) + { + WakeByAddressSingle(&m_isSignaled); + } + else + { + WakeByAddressAll(&m_isSignaled); + } + } + + // Checks if the event is currently signaled. + // Note: Unlike Win32 auto-reset event objects, this will not reset the event. + WI_NODISCARD bool is_signaled() const WI_NOEXCEPT + { + return !!ReadAcquire(&m_isSignaled); + } + + bool wait(DWORD timeoutMiliseconds) WI_NOEXCEPT + { + if (timeoutMiliseconds == 0) + { + return TryAcquireEvent(); + } + else if (timeoutMiliseconds == INFINITE) + { + return wait(); + } + + UINT64 startTime{}; + QueryUnbiasedInterruptTime(&startTime); + + UINT64 elapsedTimeMilliseconds = 0; + + while (!TryAcquireEvent()) + { + if (elapsedTimeMilliseconds >= timeoutMiliseconds) + { + return false; + } + + DWORD newTimeout = static_cast(timeoutMiliseconds - elapsedTimeMilliseconds); + + if (!WaitForSignal(newTimeout)) + { + return false; + } + + UINT64 currTime; + QueryUnbiasedInterruptTime(&currTime); + + elapsedTimeMilliseconds = (currTime - startTime) / static_cast(10 * 1000); + } + + return true; + } + + bool wait() WI_NOEXCEPT + { + while (!TryAcquireEvent()) + { + if (!WaitForSignal(INFINITE)) + { + return false; + } + } + + return true; + } + + private: + bool TryAcquireEvent() WI_NOEXCEPT + { + #pragma warning(suppress:4127) // conditional expression is constant + if (Type == SlimEventType::AutoReset) + { + return ResetEvent(); + } + else + { + return is_signaled(); + } + } + + bool WaitForSignal(DWORD timeoutMiliseconds) WI_NOEXCEPT + { + LONG falseValue = FALSE; + BOOL waitResult = WaitOnAddress(&m_isSignaled, &falseValue, sizeof(m_isSignaled), timeoutMiliseconds); + __FAIL_FAST_ASSERT__(waitResult || ::GetLastError() == ERROR_TIMEOUT); + return !!waitResult; + } + + LONG m_isSignaled = FALSE; + }; + + /** An event object that will atomically revert to an unsignaled state anytime a `wait()` call succeeds (i.e. returns true). */ + using slim_event_auto_reset = slim_event_t; + + /** An event object that once signaled remains that way forever, unless `ResetEvent()` is called. */ + using slim_event_manual_reset = slim_event_t; + + /** An alias for `wil::slim_event_auto_reset`. */ + using slim_event = slim_event_auto_reset; + +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + + typedef unique_any mutex_release_scope_exit; + + WI_NODISCARD inline mutex_release_scope_exit ReleaseMutex_scope_exit(_In_ HANDLE hMutex) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT__(hMutex != nullptr); + return mutex_release_scope_exit(hMutex); + } + + // For efficiency, avoid using mutexes when an srwlock or condition variable will do. + template + class mutex_t : public storage_t + { + public: + // forward all base class constructors... + template + explicit mutex_t(args_t&&... args) WI_NOEXCEPT : storage_t(wistd::forward(args)...) {} + + // HRESULT or void error handling... + typedef typename err_policy::result result; + + // Exception-based constructor to create a mutex (prefer unnamed (nullptr) for the name) + mutex_t(_In_opt_ PCWSTR name) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions or fail fast; use the create method"); + create(name); + } + + void ReleaseMutex() const WI_NOEXCEPT + { + details::ReleaseMutex(storage_t::get()); + } + + WI_NODISCARD mutex_release_scope_exit ReleaseMutex_scope_exit() const WI_NOEXCEPT + { + return wil::ReleaseMutex_scope_exit(storage_t::get()); + } + + WI_NODISCARD mutex_release_scope_exit acquire(_Out_opt_ DWORD *pStatus = nullptr, DWORD dwMilliseconds = INFINITE, BOOL bAlertable = FALSE) const WI_NOEXCEPT + { + auto handle = storage_t::get(); + DWORD status = ::WaitForSingleObjectEx(handle, dwMilliseconds, bAlertable); + assign_to_opt_param(pStatus, status); + __FAIL_FAST_ASSERT__((status == WAIT_TIMEOUT) || (status == WAIT_OBJECT_0) || (status == WAIT_ABANDONED) || (bAlertable && (status == WAIT_IO_COMPLETION))); + return mutex_release_scope_exit(((status == WAIT_OBJECT_0) || (status == WAIT_ABANDONED)) ? handle : nullptr); + } + + // Tries to create a named mutex -- returns false if unable to do so (gle may still be inspected with return=false) + bool try_create(_In_opt_ PCWSTR name, DWORD dwFlags = 0, DWORD desiredAccess = MUTEX_ALL_ACCESS, + _In_opt_ PSECURITY_ATTRIBUTES mutexAttributes = nullptr, _Out_opt_ bool* alreadyExists = nullptr) + { + auto handle = ::CreateMutexExW(mutexAttributes, name, dwFlags, desiredAccess); + if (handle == nullptr) + { + assign_to_opt_param(alreadyExists, false); + return false; + } + assign_to_opt_param(alreadyExists, (::GetLastError() == ERROR_ALREADY_EXISTS)); + storage_t::reset(handle); + return true; + } + + // Returns HRESULT for unique_mutex_nothrow, void with exceptions for shared_mutex and unique_mutex + result create(_In_opt_ PCWSTR name = nullptr, DWORD dwFlags = 0, DWORD desiredAccess = MUTEX_ALL_ACCESS, + _In_opt_ PSECURITY_ATTRIBUTES mutexAttributes = nullptr, _Out_opt_ bool* alreadyExists = nullptr) + { + return err_policy::LastErrorIfFalse(try_create(name, dwFlags, desiredAccess, mutexAttributes, alreadyExists)); + } + + // Tries to open a named mutex -- returns false if unable to do so (gle may still be inspected with return=false) + bool try_open(_In_ PCWSTR name, DWORD desiredAccess = SYNCHRONIZE | MUTEX_MODIFY_STATE, bool inheritHandle = false) + { + auto handle = ::OpenMutexW(desiredAccess, inheritHandle, name); + if (handle == nullptr) + { + return false; + } + storage_t::reset(handle); + return true; + } + + // Returns HRESULT for unique_mutex_nothrow, void with exceptions for shared_mutex and unique_mutex + result open(_In_ PCWSTR name, DWORD desiredAccess = SYNCHRONIZE | MUTEX_MODIFY_STATE, bool inheritHandle = false) + { + return err_policy::LastErrorIfFalse(try_open(name, desiredAccess, inheritHandle)); + } + }; + + typedef unique_any_t, err_returncode_policy>> unique_mutex_nothrow; + typedef unique_any_t, err_failfast_policy>> unique_mutex_failfast; +#ifdef WIL_ENABLE_EXCEPTIONS + typedef unique_any_t, err_exception_policy>> unique_mutex; +#endif + + typedef unique_any semaphore_release_scope_exit; + + WI_NODISCARD inline semaphore_release_scope_exit ReleaseSemaphore_scope_exit(_In_ HANDLE hSemaphore) WI_NOEXCEPT + { + __FAIL_FAST_ASSERT__(hSemaphore != nullptr); + return semaphore_release_scope_exit(hSemaphore); + } + + template + class semaphore_t : public storage_t + { + public: + // forward all base class constructors... + template + explicit semaphore_t(args_t&&... args) WI_NOEXCEPT : storage_t(wistd::forward(args)...) {} + + // HRESULT or void error handling... + typedef typename err_policy::result result; + + // Note that for custom-constructors the type given the constructor has to match exactly as not all implicit conversions will make it through the + // forwarding constructor. This constructor, for example, uses 'int' instead of 'LONG' as the count to ease that particular issue (const numbers are int by default). + explicit semaphore_t(int initialCount, int maximumCount, _In_opt_ PCWSTR name = nullptr, DWORD desiredAccess = SEMAPHORE_ALL_ACCESS, _In_opt_ PSECURITY_ATTRIBUTES pSemaphoreAttributes = nullptr) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions or fail fast; use the create method"); + create(initialCount, maximumCount, name, desiredAccess, pSemaphoreAttributes); + } + + void ReleaseSemaphore(long nReleaseCount = 1, _In_opt_ long *pnPreviousCount = nullptr) WI_NOEXCEPT + { + long nPreviousCount = 0; + __FAIL_FAST_ASSERT__(::ReleaseSemaphore(storage_t::get(), nReleaseCount, &nPreviousCount)); + assign_to_opt_param(pnPreviousCount, nPreviousCount); + } + + WI_NODISCARD semaphore_release_scope_exit ReleaseSemaphore_scope_exit() WI_NOEXCEPT + { + return wil::ReleaseSemaphore_scope_exit(storage_t::get()); + } + + WI_NODISCARD semaphore_release_scope_exit acquire(_Out_opt_ DWORD *pStatus = nullptr, DWORD dwMilliseconds = INFINITE, BOOL bAlertable = FALSE) WI_NOEXCEPT + { + auto handle = storage_t::get(); + DWORD status = ::WaitForSingleObjectEx(handle, dwMilliseconds, bAlertable); + assign_to_opt_param(pStatus, status); + __FAIL_FAST_ASSERT__((status == WAIT_TIMEOUT) || (status == WAIT_OBJECT_0) || (bAlertable && (status == WAIT_IO_COMPLETION))); + return semaphore_release_scope_exit((status == WAIT_OBJECT_0) ? handle : nullptr); + } + + // Tries to create a named event -- returns false if unable to do so (gle may still be inspected with return=false) + bool try_create(LONG lInitialCount, LONG lMaximumCount, _In_opt_ PCWSTR name, DWORD desiredAccess = SEMAPHORE_ALL_ACCESS, _In_opt_ PSECURITY_ATTRIBUTES pSemaphoreAttributes = nullptr, _Out_opt_ bool *alreadyExists = nullptr) + { + auto handle = ::CreateSemaphoreExW(pSemaphoreAttributes, lInitialCount, lMaximumCount, name, 0, desiredAccess); + if (handle == nullptr) + { + assign_to_opt_param(alreadyExists, false); + return false; + } + assign_to_opt_param(alreadyExists, (::GetLastError() == ERROR_ALREADY_EXISTS)); + storage_t::reset(handle); + return true; + } + + // Returns HRESULT for unique_semaphore_nothrow, void with exceptions for shared_event and unique_event + result create(LONG lInitialCount, LONG lMaximumCount, _In_opt_ PCWSTR name = nullptr, DWORD desiredAccess = SEMAPHORE_ALL_ACCESS, _In_opt_ PSECURITY_ATTRIBUTES pSemaphoreAttributes = nullptr, _Out_opt_ bool *alreadyExists = nullptr) + { + return err_policy::LastErrorIfFalse(try_create(lInitialCount, lMaximumCount, name, desiredAccess, pSemaphoreAttributes, alreadyExists)); + } + + // Tries to open the named semaphore -- returns false if unable to do so (gle may still be inspected with return=false) + bool try_open(_In_ PCWSTR name, DWORD desiredAccess = SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, bool inheritHandle = false) + { + auto handle = ::OpenSemaphoreW(desiredAccess, inheritHandle, name); + if (handle == nullptr) + { + return false; + } + storage_t::reset(handle); + return true; + } + + // Returns HRESULT for unique_semaphore_nothrow, void with exceptions for shared_semaphore and unique_semaphore + result open(_In_ PCWSTR name, DWORD desiredAccess = SYNCHRONIZE | SEMAPHORE_MODIFY_STATE, bool inheritHandle = false) + { + return err_policy::LastErrorIfFalse(try_open(name, desiredAccess, inheritHandle)); + } + }; + + typedef unique_any_t, err_returncode_policy>> unique_semaphore_nothrow; + typedef unique_any_t, err_failfast_policy>> unique_semaphore_failfast; +#ifdef WIL_ENABLE_EXCEPTIONS + typedef unique_any_t, err_exception_policy>> unique_semaphore; +#endif + + typedef unique_any rwlock_release_exclusive_scope_exit; + typedef unique_any rwlock_release_shared_scope_exit; + + WI_NODISCARD inline rwlock_release_exclusive_scope_exit AcquireSRWLockExclusive(_Inout_ SRWLOCK *plock) WI_NOEXCEPT + { + ::AcquireSRWLockExclusive(plock); + return rwlock_release_exclusive_scope_exit(plock); + } + + WI_NODISCARD inline rwlock_release_shared_scope_exit AcquireSRWLockShared(_Inout_ SRWLOCK *plock) WI_NOEXCEPT + { + ::AcquireSRWLockShared(plock); + return rwlock_release_shared_scope_exit(plock); + } + + WI_NODISCARD inline rwlock_release_exclusive_scope_exit TryAcquireSRWLockExclusive(_Inout_ SRWLOCK *plock) WI_NOEXCEPT + { + return rwlock_release_exclusive_scope_exit(::TryAcquireSRWLockExclusive(plock) ? plock : nullptr); + } + + WI_NODISCARD inline rwlock_release_shared_scope_exit TryAcquireSRWLockShared(_Inout_ SRWLOCK *plock) WI_NOEXCEPT + { + return rwlock_release_shared_scope_exit(::TryAcquireSRWLockShared(plock) ? plock : nullptr); + } + + class srwlock + { + public: + srwlock(const srwlock&) = delete; + srwlock(srwlock&&) = delete; + srwlock& operator=(const srwlock&) = delete; + srwlock& operator=(srwlock&&) = delete; + + srwlock() = default; + + WI_NODISCARD rwlock_release_exclusive_scope_exit lock_exclusive() WI_NOEXCEPT + { + return wil::AcquireSRWLockExclusive(&m_lock); + } + + WI_NODISCARD rwlock_release_exclusive_scope_exit try_lock_exclusive() WI_NOEXCEPT + { + return wil::TryAcquireSRWLockExclusive(&m_lock); + } + + WI_NODISCARD rwlock_release_shared_scope_exit lock_shared() WI_NOEXCEPT + { + return wil::AcquireSRWLockShared(&m_lock); + } + + WI_NODISCARD rwlock_release_shared_scope_exit try_lock_shared() WI_NOEXCEPT + { + return wil::TryAcquireSRWLockShared(&m_lock); + } + + private: + SRWLOCK m_lock = SRWLOCK_INIT; + }; + + typedef unique_any cs_leave_scope_exit; + + WI_NODISCARD inline cs_leave_scope_exit EnterCriticalSection(_Inout_ CRITICAL_SECTION *pcs) WI_NOEXCEPT + { + ::EnterCriticalSection(pcs); + return cs_leave_scope_exit(pcs); + } + + WI_NODISCARD inline cs_leave_scope_exit TryEnterCriticalSection(_Inout_ CRITICAL_SECTION *pcs) WI_NOEXCEPT + { + return cs_leave_scope_exit(::TryEnterCriticalSection(pcs) ? pcs : nullptr); + } + + // Critical sections are worse than srwlocks in performance and memory usage (their only unique attribute + // being recursive acquisition). Prefer srwlocks over critical sections when you don't need recursive acquisition. + class critical_section + { + public: + critical_section(const critical_section&) = delete; + critical_section(critical_section&&) = delete; + critical_section& operator=(const critical_section&) = delete; + critical_section& operator=(critical_section&&) = delete; + + critical_section(ULONG spincount = 0) WI_NOEXCEPT + { + // Initialization will not fail without invalid params... + ::InitializeCriticalSectionEx(&m_cs, spincount, 0); + } + + ~critical_section() WI_NOEXCEPT + { + ::DeleteCriticalSection(&m_cs); + } + + WI_NODISCARD cs_leave_scope_exit lock() WI_NOEXCEPT + { + return wil::EnterCriticalSection(&m_cs); + } + + WI_NODISCARD cs_leave_scope_exit try_lock() WI_NOEXCEPT + { + return wil::TryEnterCriticalSection(&m_cs); + } + + private: + CRITICAL_SECTION m_cs; + }; + + class condition_variable + { + public: + condition_variable(const condition_variable&) = delete; + condition_variable(condition_variable&&) = delete; + condition_variable& operator=(const condition_variable&) = delete; + condition_variable& operator=(condition_variable&&) = delete; + + condition_variable() = default; + + void notify_one() WI_NOEXCEPT + { + ::WakeConditionVariable(&m_cv); + } + + void notify_all() WI_NOEXCEPT + { + ::WakeAllConditionVariable(&m_cv); + } + + void wait(const cs_leave_scope_exit& lock) WI_NOEXCEPT + { + wait_for(lock, INFINITE); + } + + void wait(const rwlock_release_exclusive_scope_exit& lock) WI_NOEXCEPT + { + wait_for(lock, INFINITE); + } + + void wait(const rwlock_release_shared_scope_exit& lock) WI_NOEXCEPT + { + wait_for(lock, INFINITE); + } + + bool wait_for(const cs_leave_scope_exit& lock, DWORD timeoutMs) WI_NOEXCEPT + { + bool result = !!::SleepConditionVariableCS(&m_cv, lock.get(), timeoutMs); + __FAIL_FAST_ASSERT__(result || ::GetLastError() == ERROR_TIMEOUT); + return result; + } + + bool wait_for(const rwlock_release_exclusive_scope_exit& lock, DWORD timeoutMs) WI_NOEXCEPT + { + bool result = !!::SleepConditionVariableSRW(&m_cv, lock.get(), timeoutMs, 0); + __FAIL_FAST_ASSERT__(result || ::GetLastError() == ERROR_TIMEOUT); + return result; + } + + bool wait_for(const rwlock_release_shared_scope_exit& lock, DWORD timeoutMs) WI_NOEXCEPT + { + bool result = !!::SleepConditionVariableSRW(&m_cv, lock.get(), timeoutMs, CONDITION_VARIABLE_LOCKMODE_SHARED); + __FAIL_FAST_ASSERT__(result || ::GetLastError() == ERROR_TIMEOUT); + return result; + } + + private: + CONDITION_VARIABLE m_cv = CONDITION_VARIABLE_INIT; + }; + + /// @cond + namespace details + { + template struct string_allocator + { + static void* allocate(size_t /*size*/) WI_NOEXCEPT + { + static_assert(!wistd::is_same::value, "This type did not provide a string_allocator, add a specialization of string_allocator to support your type."); + return nullptr; + } + }; + } + /// @endcond + + // This string helper does not support the ansi wil string helpers + template + PCWSTR string_get_not_null(const string_type& string) + { + return string ? string.get() : L""; + } + +#ifndef MAKE_UNIQUE_STRING_MAX_CCH +#define MAKE_UNIQUE_STRING_MAX_CCH 2147483647 // max buffer size, in characters, that we support (same as INT_MAX) +#endif + + /** Copies a string (up to the given length) into memory allocated with a specified allocator returning null on failure. + Use `wil::make_unique_string_nothrow()` for string resources returned from APIs that must satisfy a memory allocation contract + that requires use of a specific allocator and free function (CoTaskMemAlloc/CoTaskMemFree, LocalAlloc/LocalFree, GlobalAlloc/GlobalFree, etc.). + ~~~ + auto str = wil::make_unique_string_nothrow(L"a string of words", 8); + RETURN_IF_NULL_ALLOC(str); + std::wcout << L"This is " << str.get() << std::endl; // prints "This is a string" + + auto str = wil::make_unique_string_nothrow(L"a string"); + RETURN_IF_NULL_ALLOC(str); + std::wcout << L"This is " << str.get() << std::endl; // prints "This is a string" + + NOTE: If source is not null terminated, then length MUST be equal to or less than the size + of the buffer pointed to by source. + ~~~ + */ + template string_type make_unique_string_nothrow( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + const wchar_t* source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + // guard against invalid parameters (null source with -1 length) + FAIL_FAST_IF(!source && (length == static_cast(-1))); + + // When the source string exists, calculate the number of characters to copy up to either + // 1) the length that is given + // 2) the length of the source string. When the source does not exist, use the given length + // for calculating both the size of allocated buffer and the number of characters to copy. + size_t lengthToCopy = length; + if (source) + { + size_t maxLength = length < MAKE_UNIQUE_STRING_MAX_CCH ? length : MAKE_UNIQUE_STRING_MAX_CCH; + PCWSTR endOfSource = source; + while (maxLength && (*endOfSource != L'\0')) + { + endOfSource++; + maxLength--; + } + lengthToCopy = endOfSource - source; + } + + if (length == static_cast(-1)) + { + length = lengthToCopy; + } + const size_t allocatedBytes = (length + 1) * sizeof(*source); + auto result = static_cast(details::string_allocator::allocate(allocatedBytes)); + + if (result) + { + if (source) + { + const size_t bytesToCopy = lengthToCopy * sizeof(*source); + memcpy_s(result, allocatedBytes, source, bytesToCopy); + result[lengthToCopy] = L'\0'; // ensure the copied string is zero terminated + } + else + { + *result = L'\0'; // ensure null terminated in the "reserve space" use case. + } + result[length] = L'\0'; // ensure the final char of the buffer is zero terminated + } + return string_type(result); + } +#ifndef WIL_NO_ANSI_STRINGS + template string_type make_unique_ansistring_nothrow( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + if (length == static_cast(-1)) + { + // guard against invalid parameters (null source with -1 length) + FAIL_FAST_IF(!source); + length = strlen(source); + } + const size_t cb = (length + 1) * sizeof(*source); + auto result = static_cast(details::string_allocator::allocate(cb)); + if (result) + { + if (source) + { + memcpy_s(result, cb, source, cb - sizeof(*source)); + } + else + { + *result = '\0'; // ensure null terminated in the "reserve space" use case. + } + result[length] = '\0'; // ensure zero terminated + } + return string_type(result); + } +#endif // WIL_NO_ANSI_STRINGS + + /** Copies a given string into memory allocated with a specified allocator that will fail fast on failure. + The use of variadic templates parameters supports the 2 forms of make_unique_string, see those for more details. + */ + template string_type make_unique_string_failfast( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + auto result(make_unique_string_nothrow(source, length)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + +#ifndef WIL_NO_ANSI_STRINGS + template string_type make_unique_ansistring_failfast( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + auto result(make_unique_ansistring_nothrow(source, length)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } +#endif // WIL_NO_ANSI_STRINGS + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Copies a given string into memory allocated with a specified allocator that will throw on failure. + The use of variadic templates parameters supports the 2 forms of make_unique_string, see those for more details. + */ + template string_type make_unique_string( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) + { + auto result(make_unique_string_nothrow(source, length)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#ifndef WIL_NO_ANSI_STRINGS + template string_type make_unique_ansistring( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCSTR source, size_t length = static_cast(-1)) + { + auto result(make_unique_ansistring_nothrow(source, length)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif // WIL_NO_ANSI_STRINGS +#endif // WIL_ENABLE_EXCEPTIONS + + /// @cond + namespace details + { + // string_maker abstracts creating a string for common string types. This form supports the + // wil::unique_xxx_string types. Specializations of other types like HSTRING and std::wstring + // are found in wil\winrt.h and wil\stl.h. + // This design supports creating the string in a single step or using two phase construction. + + template struct string_maker + { + HRESULT make( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + const wchar_t* source, + size_t length) + { + m_value = make_unique_string_nothrow(source, length); + return m_value ? S_OK : E_OUTOFMEMORY; + } + + wchar_t* buffer() { WI_ASSERT(m_value.get()); return m_value.get(); } + + // By default, assume string_type is a null-terminated string and therefore does not require trimming. + HRESULT trim_at_existing_null(size_t /* length */) { return S_OK; } + + string_type release() { return wistd::move(m_value); } + + // Utility to abstract access to the null terminated m_value of all string types. + static PCWSTR get(const string_type& value) { return value.get(); } + + private: + string_type m_value; // a wil::unique_xxx_string type. + }; + + struct SecureZeroData + { + void *pointer; + size_t sizeBytes; + SecureZeroData(void *pointer_, size_t sizeBytes_ = 0) WI_NOEXCEPT { pointer = pointer_; sizeBytes = sizeBytes_; } + WI_NODISCARD operator void*() const WI_NOEXCEPT { return pointer; } + static void Close(SecureZeroData data) WI_NOEXCEPT { ::SecureZeroMemory(data.pointer, data.sizeBytes); } + }; + } + /// @endcond + + typedef unique_any secure_zero_memory_scope_exit; + + WI_NODISCARD inline secure_zero_memory_scope_exit SecureZeroMemory_scope_exit(_In_reads_bytes_(sizeBytes) void* pSource, size_t sizeBytes) + { + return secure_zero_memory_scope_exit(details::SecureZeroData(pSource, sizeBytes)); + } + + WI_NODISCARD inline secure_zero_memory_scope_exit SecureZeroMemory_scope_exit(_In_ PWSTR initializedString) + { + return SecureZeroMemory_scope_exit(static_cast(initializedString), wcslen(initializedString) * sizeof(initializedString[0])); + } + + /// @cond + namespace details + { + inline void __stdcall FreeProcessHeap(_Pre_opt_valid_ _Frees_ptr_opt_ void* p) + { + ::HeapFree(::GetProcessHeap(), 0, p); + } + } + /// @endcond + + struct process_heap_deleter + { + template + void operator()(_Pre_valid_ _Frees_ptr_ T* p) const + { + details::FreeProcessHeap(p); + } + }; + + struct virtualalloc_deleter + { + template + void operator()(_Pre_valid_ _Frees_ptr_ T* p) const + { + ::VirtualFree(p, 0, MEM_RELEASE); + } + }; + + struct mapview_deleter + { + template + void operator()(_Pre_valid_ _Frees_ptr_ T* p) const + { + ::UnmapViewOfFile(p); + } + }; + + template + using unique_process_heap_ptr = wistd::unique_ptr; + + typedef unique_any unique_process_heap_string; + + /// @cond + namespace details + { + template<> struct string_allocator + { + static _Ret_opt_bytecap_(size) void* allocate(size_t size) WI_NOEXCEPT + { + return ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, size); + } + }; + } + /// @endcond + + /** Manages a typed pointer allocated with VirtualAlloc + A specialization of wistd::unique_ptr<> that frees via VirtualFree(p, 0, MEM_RELEASE). + */ + template + using unique_virtualalloc_ptr = wistd::unique_ptr; + + /** Manages a typed pointer allocated with MapViewOfFile + A specialization of wistd::unique_ptr<> that frees via UnmapViewOfFile(p). + */ + template + using unique_mapview_ptr = wistd::unique_ptr; + +#endif // __WIL_WINBASE_ + +#if defined(__WIL_WINBASE_) && defined(__NOTHROW_T_DEFINED) && !defined(__WIL_WINBASE_NOTHROW_T_DEFINED) +#define __WIL_WINBASE_NOTHROW_T_DEFINED + // unique_event_watcher, unique_event_watcher_nothrow, unique_event_watcher_failfast + // + // Clients must include or to enable use of this class as it uses new(std::nothrow). + // This is to avoid the dependency on those headers that some clients can't tolerate. + // + // These classes makes it easy to execute a provided function when an event + // is signaled. It will create the event handle for you, take ownership of one + // or duplicate a handle provided. It supports the ability to signal the + // event using SetEvent() and SetEvent_scope_exit(); + // + // This can be used to support producer-consumer pattern + // where a producer updates some state then signals the event when done. + // The consumer will consume that state in the callback provided to unique_event_watcher. + // + // Note, multiple signals may coalesce into a single callback. + // + // Example use of throwing version: + // auto globalStateWatcher = wil::make_event_watcher([] + // { + // currentState = GetGlobalState(); + // }); + // + // UpdateGlobalState(value); + // globalStateWatcher.SetEvent(); // signal observers so they can update + // + // Example use of non-throwing version: + // auto globalStateWatcher = wil::make_event_watcher_nothrow([] + // { + // currentState = GetGlobalState(); + // }); + // RETURN_IF_NULL_ALLOC(globalStateWatcher); + // + // UpdateGlobalState(value); + // globalStateWatcher.SetEvent(); // signal observers so they can update + + /// @cond + namespace details + { + struct event_watcher_state + { + event_watcher_state(unique_event_nothrow &&eventHandle, wistd::function &&callback) + : m_callback(wistd::move(callback)), m_event(wistd::move(eventHandle)) + { + } + wistd::function m_callback; + unique_event_nothrow m_event; + // The thread pool must be last to ensure that the other members are valid + // when it is destructed as it will reference them. + unique_threadpool_wait m_threadPoolWait; + }; + + inline void delete_event_watcher_state(_In_opt_ event_watcher_state *watcherStorage) { delete watcherStorage; } + + typedef resource_policy event_watcher_state_resource_policy; + } + /// @endcond + + template + class event_watcher_t : public storage_t + { + public: + // forward all base class constructors... + template + explicit event_watcher_t(args_t&&... args) WI_NOEXCEPT : storage_t(wistd::forward(args)...) {} + + // HRESULT or void error handling... + typedef typename err_policy::result result; + + // Exception-based constructors + template + event_watcher_t(unique_any_t, from_err_policy>> &&eventHandle, wistd::function &&callback) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions or fail fast; use the create method"); + create(wistd::move(eventHandle), wistd::move(callback)); + } + + event_watcher_t(_In_ HANDLE eventHandle, wistd::function &&callback) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions or fail fast; use the create method"); + create(eventHandle, wistd::move(callback)); + } + + event_watcher_t(wistd::function &&callback) + { + static_assert(wistd::is_same::value, "this constructor requires exceptions or fail fast; use the create method"); + create(wistd::move(callback)); + } + + template + result create(unique_any_t, event_err_policy>> &&eventHandle, + wistd::function &&callback) + { + return err_policy::HResult(create_take_hevent_ownership(eventHandle.release(), wistd::move(callback))); + } + + // Creates the event that you will be watching. + result create(wistd::function &&callback) + { + unique_event_nothrow eventHandle; + HRESULT hr = eventHandle.create(EventOptions::ManualReset); // auto-reset is supported too. + if (FAILED(hr)) + { + return err_policy::HResult(hr); + } + return err_policy::HResult(create_take_hevent_ownership(eventHandle.release(), wistd::move(callback))); + } + + // Input is an event handler that is duplicated into this class. + result create(_In_ HANDLE eventHandle, wistd::function &&callback) + { + unique_event_nothrow ownedHandle; + if (!DuplicateHandle(GetCurrentProcess(), eventHandle, GetCurrentProcess(), &ownedHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + return err_policy::LastError(); + } + return err_policy::HResult(create_take_hevent_ownership(ownedHandle.release(), wistd::move(callback))); + } + + // Provide access to the inner event and the very common SetEvent() method on it. + WI_NODISCARD unique_event_nothrow const& get_event() const WI_NOEXCEPT { return storage_t::get()->m_event; } + void SetEvent() const WI_NOEXCEPT { storage_t::get()->m_event.SetEvent(); } + + private: + + // Had to move this from a Lambda so it would compile in C++/CLI (which thought the Lambda should be a managed function for some reason). + static void CALLBACK wait_callback(PTP_CALLBACK_INSTANCE, void *context, TP_WAIT *pThreadPoolWait, TP_WAIT_RESULT) + { + auto pThis = static_cast(context); + // Manual events must be re-set to avoid missing the last notification. + pThis->m_event.ResetEvent(); + // Call the client before re-arming to ensure that multiple callbacks don't + // run concurrently. + pThis->m_callback(); + SetThreadpoolWait(pThreadPoolWait, pThis->m_event.get(), nullptr); // valid params ensure success + } + + // To avoid template expansion (if unique_event/unique_event_nothrow forms were used) this base + // create function takes a raw handle and assumes its ownership, even on failure. + HRESULT create_take_hevent_ownership(_In_ HANDLE rawHandleOwnershipTaken, wistd::function &&callback) + { + __FAIL_FAST_ASSERT__(rawHandleOwnershipTaken != nullptr); // invalid parameter + unique_event_nothrow eventHandle(rawHandleOwnershipTaken); + wistd::unique_ptr watcherState(new(std::nothrow) details::event_watcher_state(wistd::move(eventHandle), wistd::move(callback))); + RETURN_IF_NULL_ALLOC(watcherState); + + watcherState->m_threadPoolWait.reset(CreateThreadpoolWait(wait_callback, watcherState.get(), nullptr)); + RETURN_LAST_ERROR_IF(!watcherState->m_threadPoolWait); + storage_t::reset(watcherState.release()); // no more failures after this, pass ownership + SetThreadpoolWait(storage_t::get()->m_threadPoolWait.get(), storage_t::get()->m_event.get(), nullptr); + return S_OK; + } + }; + + typedef unique_any_t, err_returncode_policy>> unique_event_watcher_nothrow; + typedef unique_any_t, err_failfast_policy>> unique_event_watcher_failfast; + + template + unique_event_watcher_nothrow make_event_watcher_nothrow(unique_any_t, err_policy>> &&eventHandle, wistd::function &&callback) WI_NOEXCEPT + { + unique_event_watcher_nothrow watcher; + watcher.create(wistd::move(eventHandle), wistd::move(callback)); + return watcher; // caller must test for success using if (watcher) + } + + inline unique_event_watcher_nothrow make_event_watcher_nothrow(_In_ HANDLE eventHandle, wistd::function &&callback) WI_NOEXCEPT + { + unique_event_watcher_nothrow watcher; + watcher.create(eventHandle, wistd::move(callback)); + return watcher; // caller must test for success using if (watcher) + } + + inline unique_event_watcher_nothrow make_event_watcher_nothrow(wistd::function &&callback) WI_NOEXCEPT + { + unique_event_watcher_nothrow watcher; + watcher.create(wistd::move(callback)); + return watcher; // caller must test for success using if (watcher) + } + + template + unique_event_watcher_failfast make_event_watcher_failfast(unique_any_t, err_policy>> &&eventHandle, wistd::function &&callback) + { + return unique_event_watcher_failfast(wistd::move(eventHandle), wistd::move(callback)); + } + + inline unique_event_watcher_failfast make_event_watcher_failfast(_In_ HANDLE eventHandle, wistd::function &&callback) + { + return unique_event_watcher_failfast(eventHandle, wistd::move(callback)); + } + + inline unique_event_watcher_failfast make_event_watcher_failfast(wistd::function &&callback) + { + return unique_event_watcher_failfast(wistd::move(callback)); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + typedef unique_any_t, err_exception_policy>> unique_event_watcher; + + template + unique_event_watcher make_event_watcher(unique_any_t, err_policy>> &&eventHandle, wistd::function &&callback) + { + return unique_event_watcher(wistd::move(eventHandle), wistd::move(callback)); + } + + inline unique_event_watcher make_event_watcher(_In_ HANDLE eventHandle, wistd::function &&callback) + { + return unique_event_watcher(eventHandle, wistd::move(callback)); + } + + inline unique_event_watcher make_event_watcher(wistd::function &&callback) + { + return unique_event_watcher(wistd::move(callback)); + } +#endif // WIL_ENABLE_EXCEPTIONS + +#endif // __WIL_WINBASE_NOTHROW_T_DEFINED + +#if defined(__WIL_WINBASE_) && !defined(__WIL_WINBASE_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WINBASE_STL + typedef shared_any_t>> shared_event; + typedef shared_any_t>> shared_mutex; + typedef shared_any_t>> shared_semaphore; + typedef shared_any shared_hfile; + typedef shared_any shared_handle; + typedef shared_any shared_hfind; + typedef shared_any shared_hmodule; + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + typedef shared_any shared_threadpool_wait; + typedef shared_any shared_threadpool_wait_nocancel; + typedef shared_any shared_threadpool_work; + typedef shared_any shared_threadpool_work_nocancel; + + typedef shared_any shared_hfind_change; +#endif + + typedef weak_any weak_event; + typedef weak_any weak_mutex; + typedef weak_any weak_semaphore; + typedef weak_any weak_hfile; + typedef weak_any weak_handle; + typedef weak_any weak_hfind; + typedef weak_any weak_hmodule; + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + typedef weak_any weak_threadpool_wait; + typedef weak_any weak_threadpool_wait_nocancel; + typedef weak_any weak_threadpool_work; + typedef weak_any weak_threadpool_work_nocancel; + + typedef weak_any weak_hfind_change; +#endif + +#endif // __WIL_WINBASE_STL + +#if defined(__WIL_WINBASE_) && defined(__NOTHROW_T_DEFINED) && !defined(__WIL_WINBASE_NOTHROW_T_DEFINED_STL) && defined(WIL_RESOURCE_STL) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_WINBASE_NOTHROW_T_DEFINED_STL + typedef shared_any_t>> shared_event_watcher; + typedef weak_any weak_event_watcher; +#endif // __WIL_WINBASE_NOTHROW_T_DEFINED_STL + +#if defined(__WIL_WINBASE_) && !defined(__WIL_WINBASE_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_WINBASE_DESKTOP + /// @cond + namespace details + { + inline void __stdcall DestroyPrivateObjectSecurity(_Pre_opt_valid_ _Frees_ptr_opt_ PSECURITY_DESCRIPTOR pObjectDescriptor) WI_NOEXCEPT + { + ::DestroyPrivateObjectSecurity(&pObjectDescriptor); + } + } + /// @endcond + + using hlocal_deleter = function_deleter; + + template + using unique_hlocal_ptr = wistd::unique_ptr; + + /** Provides `std::make_unique()` semantics for resources allocated with `LocalAlloc()` in a context that may not throw upon allocation failure. + Use `wil::make_unique_hlocal_nothrow()` for resources returned from APIs that must satisfy a memory allocation contract that requires the use of `LocalAlloc()` / `LocalFree()`. + Use `wil::make_unique_nothrow()` when `LocalAlloc()` is not required. + + Allocations are initialized with placement new and will call constructors (if present), but this does not guarantee initialization. + + Note that `wil::make_unique_hlocal_nothrow()` is not marked WI_NOEXCEPT as it may be used to create an exception-based class that may throw in its constructor. + ~~~ + auto foo = wil::make_unique_hlocal_nothrow(); + if (foo) + { + // initialize allocated Foo object as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_hlocal_ptr>::type make_unique_hlocal_nothrow(Args&&... args) + { + static_assert(wistd::is_trivially_destructible::value, "T has a destructor that won't be run when used with this function; use make_unique instead"); + unique_hlocal_ptr sp(static_cast(::LocalAlloc(LMEM_FIXED, sizeof(T)))); + if (sp) + { + // use placement new to initialize memory from the previous allocation + new (sp.get()) T(wistd::forward(args)...); + } + return sp; + } + + /** Provides `std::make_unique()` semantics for array resources allocated with `LocalAlloc()` in a context that may not throw upon allocation failure. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_hlocal_nothrow(size); + if (foos) + { + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_hlocal_ptr>::type make_unique_hlocal_nothrow(size_t size) + { + typedef typename wistd::remove_extent::type E; + static_assert(wistd::is_trivially_destructible::value, "E has a destructor that won't be run when used with this function; use make_unique instead"); + FAIL_FAST_IF((__WI_SIZE_MAX / sizeof(E)) < size); + size_t allocSize = sizeof(E) * size; + unique_hlocal_ptr sp(static_cast(::LocalAlloc(LMEM_FIXED, allocSize))); + if (sp) + { + // use placement new to initialize memory from the previous allocation; + // note that array placement new cannot be used as the standard allows for operator new[] + // to consume overhead in the allocation for internal bookkeeping + for (auto& elem : make_range(static_cast(sp.get()), size)) + { + new (&elem) E(); + } + } + return sp; + } + + /** Provides `std::make_unique()` semantics for resources allocated with `LocalAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_hlocal_failfast(); + // initialize allocated Foo object as appropriate + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_hlocal_ptr>::type make_unique_hlocal_failfast(Args&&... args) + { + unique_hlocal_ptr result(make_unique_hlocal_nothrow(wistd::forward(args)...)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + + /** Provides `std::make_unique()` semantics for array resources allocated with `LocalAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_hlocal_failfast(size); + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_hlocal_ptr>::type make_unique_hlocal_failfast(size_t size) + { + unique_hlocal_ptr result(make_unique_hlocal_nothrow(size)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Provides `std::make_unique()` semantics for resources allocated with `LocalAlloc()`. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_hlocal(); + // initialize allocated Foo object as appropriate + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_hlocal_ptr>::type make_unique_hlocal(Args&&... args) + { + unique_hlocal_ptr result(make_unique_hlocal_nothrow(wistd::forward(args)...)); + THROW_IF_NULL_ALLOC(result); + return result; + } + + /** Provides `std::make_unique()` semantics for array resources allocated with `LocalAlloc()`. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_hlocal(size); + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_hlocal_ptr>::type make_unique_hlocal(size_t size) + { + unique_hlocal_ptr result(make_unique_hlocal_nothrow(size)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + + typedef unique_any unique_hlocal; + typedef unique_any unique_hlocal_string; +#ifndef WIL_NO_ANSI_STRINGS + typedef unique_any unique_hlocal_ansistring; +#endif // WIL_NO_ANSI_STRINGS + + /// @cond + namespace details + { + struct localalloc_allocator + { + static _Ret_opt_bytecap_(size) void* allocate(size_t size) WI_NOEXCEPT + { + return ::LocalAlloc(LMEM_FIXED, size); + } + }; + + template<> struct string_allocator : localalloc_allocator {}; +#ifndef WIL_NO_ANSI_STRINGS + template<> struct string_allocator : localalloc_allocator {}; +#endif // WIL_NO_ANSI_STRINGS + } + /// @endcond + + inline auto make_hlocal_string_nothrow( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + return make_unique_string_nothrow(source, length); + } + + inline auto make_hlocal_string_failfast( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + return make_unique_string_failfast(source, length); + } + +#ifndef WIL_NO_ANSI_STRINGS + inline auto make_hlocal_ansistring_nothrow( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + return make_unique_ansistring_nothrow(source, length); + } + + inline auto make_hlocal_ansistring_failfast( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + return make_unique_ansistring_failfast(source, length); + } +#endif + +#ifdef WIL_ENABLE_EXCEPTIONS + inline auto make_hlocal_string( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) + { + return make_unique_string(source, length); + } + +#ifndef WIL_NO_ANSI_STRINGS + inline auto make_hlocal_ansistring( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCSTR source, size_t length = static_cast(-1)) + { + return make_unique_ansistring(source, length); + } +#endif // WIL_NO_ANSI_STRINGS +#endif // WIL_ENABLE_EXCEPTIONS + + struct hlocal_secure_deleter + { + template + void operator()(_Pre_opt_valid_ _Frees_ptr_opt_ T* p) const + { + if (p) + { +#pragma warning(suppress: 26006 26007) // LocalSize() ensures proper buffer length + ::SecureZeroMemory(p, ::LocalSize(p)); // this is safe since LocalSize() returns 0 on failure + ::LocalFree(p); + } + } + }; + + template + using unique_hlocal_secure_ptr = wistd::unique_ptr; + + /** Provides `std::make_unique()` semantics for secure resources allocated with `LocalAlloc()` in a context that may not throw upon allocation failure. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_hlocal_secure_nothrow(); + if (foo) + { + // initialize allocated Foo object as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_hlocal_secure_ptr>::type make_unique_hlocal_secure_nothrow(Args&&... args) + { + return unique_hlocal_secure_ptr(make_unique_hlocal_nothrow(wistd::forward(args)...).release()); + } + + /** Provides `std::make_unique()` semantics for secure array resources allocated with `LocalAlloc()` in a context that may not throw upon allocation failure. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_hlocal_secure_nothrow(size); + if (foos) + { + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_hlocal_secure_ptr>::type make_unique_hlocal_secure_nothrow(size_t size) + { + return unique_hlocal_secure_ptr(make_unique_hlocal_nothrow(size).release()); + } + + /** Provides `std::make_unique()` semantics for secure resources allocated with `LocalAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_hlocal_secure_failfast(); + // initialize allocated Foo object as appropriate + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_hlocal_secure_ptr>::type make_unique_hlocal_secure_failfast(Args&&... args) + { + unique_hlocal_secure_ptr result(make_unique_hlocal_secure_nothrow(wistd::forward(args)...)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + + /** Provides `std::make_unique()` semantics for secure array resources allocated with `LocalAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_hlocal_secure_failfast(size); + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_hlocal_secure_ptr>::type make_unique_hlocal_secure_failfast(size_t size) + { + unique_hlocal_secure_ptr result(make_unique_hlocal_secure_nothrow(size)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Provides `std::make_unique()` semantics for secure resources allocated with `LocalAlloc()`. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_hlocal_secure(); + // initialize allocated Foo object as appropriate + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_hlocal_secure_ptr>::type make_unique_hlocal_secure(Args&&... args) + { + unique_hlocal_secure_ptr result(make_unique_hlocal_secure_nothrow(wistd::forward(args)...)); + THROW_IF_NULL_ALLOC(result); + return result; + } + + /** Provides `std::make_unique()` semantics for secure array resources allocated with `LocalAlloc()`. + See the overload of `wil::make_unique_hlocal_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_hlocal_secure(size); + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_hlocal_secure_ptr>::type make_unique_hlocal_secure(size_t size) + { + unique_hlocal_secure_ptr result(make_unique_hlocal_secure_nothrow(size)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + + typedef unique_hlocal_secure_ptr unique_hlocal_string_secure; + + /** Copies a given string into secure memory allocated with `LocalAlloc()` in a context that may not throw upon allocation failure. + See the overload of `wil::make_hlocal_string_nothrow()` with supplied length for more details. + ~~~ + auto str = wil::make_hlocal_string_secure_nothrow(L"a string"); + RETURN_IF_NULL_ALLOC(str); + std::wcout << L"This is " << str.get() << std::endl; // prints "This is a string" + ~~~ + */ + inline auto make_hlocal_string_secure_nothrow(_In_ PCWSTR source) WI_NOEXCEPT + { + return unique_hlocal_string_secure(make_hlocal_string_nothrow(source).release()); + } + + /** Copies a given string into secure memory allocated with `LocalAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_hlocal_string_nothrow()` with supplied length for more details. + ~~~ + auto str = wil::make_hlocal_string_secure_failfast(L"a string"); + std::wcout << L"This is " << str.get() << std::endl; // prints "This is a string" + ~~~ + */ + inline auto make_hlocal_string_secure_failfast(_In_ PCWSTR source) WI_NOEXCEPT + { + unique_hlocal_string_secure result(make_hlocal_string_secure_nothrow(source)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Copies a given string into secure memory allocated with `LocalAlloc()`. + See the overload of `wil::make_hlocal_string_nothrow()` with supplied length for more details. + ~~~ + auto str = wil::make_hlocal_string_secure(L"a string"); + std::wcout << L"This is " << str.get() << std::endl; // prints "This is a string" + ~~~ + */ + inline auto make_hlocal_string_secure(_In_ PCWSTR source) + { + unique_hlocal_string_secure result(make_hlocal_string_secure_nothrow(source)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif + + using hglobal_deleter = function_deleter; + + template + using unique_hglobal_ptr = wistd::unique_ptr; + + typedef unique_any unique_hglobal; + typedef unique_any unique_hglobal_string; +#ifndef WIL_NO_ANSI_STRINGS + typedef unique_any unique_hglobal_ansistring; +#endif // WIL_NO_ANSI_STRINGS + + /// @cond + namespace details + { + template<> struct string_allocator + { + static _Ret_opt_bytecap_(size) void* allocate(size_t size) WI_NOEXCEPT + { + return ::GlobalAlloc(GPTR, size); + } + }; + } + /// @endcond + + inline auto make_process_heap_string_nothrow( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + return make_unique_string_nothrow(source, length); + } + + inline auto make_process_heap_string_failfast( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + return make_unique_string_failfast(source, length); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + inline auto make_process_heap_string( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) + { + return make_unique_string(source, length); + } +#endif // WIL_ENABLE_EXCEPTIONS + + typedef unique_any_handle_null unique_hheap; + typedef unique_any unique_tls; + typedef unique_any unique_hlocal_security_descriptor; + typedef unique_any unique_private_security_descriptor; + +#if defined(_WINUSER_) && !defined(__WIL__WINUSER_) +#define __WIL__WINUSER_ + typedef unique_any unique_haccel; + typedef unique_any unique_hcursor; + typedef unique_any unique_hwnd; +#if !defined(NOUSER) && !defined(NOWH) + typedef unique_any unique_hhook; +#endif +#if !defined(NOWINABLE) + typedef unique_any unique_hwineventhook; +#endif +#if !defined(NOCLIPBOARD) + using unique_close_clipboard_call = unique_call; + + inline unique_close_clipboard_call open_clipboard(HWND hwnd) + { + return unique_close_clipboard_call { OpenClipboard(hwnd) != FALSE }; + } +#endif +#endif // __WIL__WINUSER_ + +#if !defined(NOGDI) && !defined(NODESKTOP) + typedef unique_any unique_hdesk; + typedef unique_any unique_hwinsta; +#endif // !defined(NOGDI) && !defined(NODESKTOP) + +#endif +#if defined(__WIL_WINBASE_DESKTOP) && !defined(__WIL_WINBASE_DESKTOP_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WINBASE_DESKTOP_STL + typedef shared_any shared_hheap; + typedef shared_any shared_hlocal; + typedef shared_any shared_tls; + typedef shared_any shared_hlocal_security_descriptor; + typedef shared_any shared_private_security_descriptor; + typedef shared_any shared_haccel; + typedef shared_any shared_hcursor; +#if !defined(NOGDI) && !defined(NODESKTOP) + typedef shared_any shared_hdesk; + typedef shared_any shared_hwinsta; +#endif // !defined(NOGDI) && !defined(NODESKTOP) + typedef shared_any shared_hwnd; +#if !defined(NOUSER) && !defined(NOWH) + typedef shared_any shared_hhook; +#endif +#if !defined(NOWINABLE) + typedef shared_any shared_hwineventhook; +#endif + + typedef weak_any weak_hheap; + typedef weak_any weak_hlocal; + typedef weak_any weak_tls; + typedef weak_any weak_hlocal_security_descriptor; + typedef weak_any weak_private_security_descriptor; + typedef weak_any weak_haccel; + typedef weak_any weak_hcursor; +#if !defined(NOGDI) && !defined(NODESKTOP) + typedef weak_any weak_hdesk; + typedef weak_any weak_hwinsta; +#endif // !defined(NOGDI) && !defined(NODESKTOP) + typedef weak_any weak_hwnd; +#if !defined(NOUSER) && !defined(NOWH) + typedef weak_any weak_hhook; +#endif +#if !defined(NOWINABLE) + typedef weak_any weak_hwineventhook; +#endif +#endif // __WIL_WINBASE_DESKTOP_STL + +#if defined(_COMBASEAPI_H_) && !defined(__WIL__COMBASEAPI_H_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) && !defined(WIL_KERNEL_MODE) +#define __WIL__COMBASEAPI_H_ +#if (NTDDI_VERSION >= NTDDI_WIN8) + typedef unique_any unique_mta_usage_cookie; +#endif + + typedef unique_any unique_com_class_object_cookie; + + /// @cond + namespace details + { + inline void __stdcall MultiQiCleanup(_In_ MULTI_QI* multiQi) + { + if (multiQi->pItf) + { + multiQi->pItf->Release(); + multiQi->pItf = nullptr; + } + } + } + /// @endcond + + //! A type that calls CoRevertToSelf on destruction (or reset()). + using unique_coreverttoself_call = unique_call; + + //! Calls CoImpersonateClient and fail-fasts if it fails; returns an RAII object that reverts + WI_NODISCARD inline unique_coreverttoself_call CoImpersonateClient_failfast() + { + FAIL_FAST_IF_FAILED(::CoImpersonateClient()); + return unique_coreverttoself_call(); + } + + typedef unique_struct unique_multi_qi; +#endif // __WIL__COMBASEAPI_H_ +#if defined(__WIL__COMBASEAPI_H_) && defined(WIL_ENABLE_EXCEPTIONS) && !defined(__WIL__COMBASEAPI_H_EXCEPTIONAL) +#define __WIL__COMBASEAPI_H_EXCEPTIONAL + WI_NODISCARD inline unique_coreverttoself_call CoImpersonateClient() + { + THROW_IF_FAILED(::CoImpersonateClient()); + return unique_coreverttoself_call(); + } +#endif +#if defined(__WIL__COMBASEAPI_H_) && !defined(__WIL__COMBASEAPI_H__STL) && defined(WIL_RESOURCE_STL) && (NTDDI_VERSION >= NTDDI_WIN8) +#define __WIL__COMBASEAPI_H__STL + typedef shared_any shared_mta_usage_cookie; + typedef weak_any weak_mta_usage_cookie; +#endif // __WIL__COMBASEAPI_H__STL + +#if defined(_COMBASEAPI_H_) && !defined(__WIL__COMBASEAPI_H_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) && !defined(WIL_KERNEL_MODE) +#define __WIL__COMBASEAPI_H_APP + //! A type that calls CoUninitialize on destruction (or reset()). + using unique_couninitialize_call = unique_call; + + //! Calls CoInitializeEx and fail-fasts if it fails; returns an RAII object that reverts + WI_NODISCARD inline unique_couninitialize_call CoInitializeEx_failfast(DWORD coinitFlags = 0 /*COINIT_MULTITHREADED*/) + { + FAIL_FAST_IF_FAILED(::CoInitializeEx(nullptr, coinitFlags)); + return {}; + } +#endif // __WIL__COMBASEAPI_H_APP +#if defined(__WIL__COMBASEAPI_H_APP) && defined(WIL_ENABLE_EXCEPTIONS) && !defined(__WIL__COMBASEAPI_H_APPEXCEPTIONAL) +#define __WIL__COMBASEAPI_H_APPEXCEPTIONAL + WI_NODISCARD inline unique_couninitialize_call CoInitializeEx(DWORD coinitFlags = 0 /*COINIT_MULTITHREADED*/) + { + THROW_IF_FAILED(::CoInitializeEx(nullptr, coinitFlags)); + return {}; + } +#endif + +#if defined(__ROAPI_H_) && !defined(__WIL__ROAPI_H_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) && (NTDDI_VERSION >= NTDDI_WIN8) +#define __WIL__ROAPI_H_APP + + typedef unique_any unique_ro_registration_cookie; + + //! A type that calls RoUninitialize on destruction (or reset()). + //! Use as a replacement for Windows::Foundation::Uninitialize. + using unique_rouninitialize_call = unique_call; + + //! Calls RoInitialize and fail-fasts if it fails; returns an RAII object that reverts + //! Use as a replacement for Windows::Foundation::Initialize + WI_NODISCARD inline unique_rouninitialize_call RoInitialize_failfast(RO_INIT_TYPE initType = RO_INIT_MULTITHREADED) + { + FAIL_FAST_IF_FAILED(::RoInitialize(initType)); + return unique_rouninitialize_call(); + } +#endif // __WIL__ROAPI_H_APP +#if defined(__WIL__ROAPI_H_APP) && defined(WIL_ENABLE_EXCEPTIONS) && !defined(__WIL__ROAPI_H_APPEXCEPTIONAL) +#define __WIL__ROAPI_H_APPEXCEPTIONAL + //! Calls RoInitialize and throws an exception if it fails; returns an RAII object that reverts + //! Use as a replacement for Windows::Foundation::Initialize + WI_NODISCARD inline unique_rouninitialize_call RoInitialize(RO_INIT_TYPE initType = RO_INIT_MULTITHREADED) + { + THROW_IF_FAILED(::RoInitialize(initType)); + return unique_rouninitialize_call(); + } +#endif + +#if defined(__WINSTRING_H_) && !defined(__WIL__WINSTRING_H_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) +#define __WIL__WINSTRING_H_ + typedef unique_any unique_hstring; + + template<> inline unique_hstring make_unique_string_nothrow( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length) WI_NOEXCEPT + { + WI_ASSERT(source != nullptr); // the HSTRING version of this function does not suport this case + if (length == static_cast(-1)) + { + length = wcslen(source); + } + + unique_hstring result; + ::WindowsCreateString(source, static_cast(length), &result); + return result; + } + + typedef unique_any unique_hstring_buffer; + + /** Promotes an hstring_buffer to an HSTRING. + When an HSTRING_BUFFER object is promoted to a real string it must not be passed to WindowsDeleteString. The caller owns the + HSTRING afterwards. + ~~~ + HRESULT Type::MakePath(_Out_ HSTRING* path) + { + wchar_t* bufferStorage = nullptr; + wil::unique_hstring_buffer theBuffer; + RETURN_IF_FAILED(::WindowsPreallocateStringBuffer(65, &bufferStorage, &theBuffer)); + RETURN_IF_FAILED(::PathCchCombine(bufferStorage, 65, m_foo, m_bar)); + RETURN_IF_FAILED(wil::make_hstring_from_buffer_nothrow(wistd::move(theBuffer), path))); + return S_OK; + } + ~~~ + */ + inline HRESULT make_hstring_from_buffer_nothrow(unique_hstring_buffer&& source, _Out_ HSTRING* promoted) + { + HRESULT hr = ::WindowsPromoteStringBuffer(source.get(), promoted); + if (SUCCEEDED(hr)) + { + source.release(); + } + return hr; + } + + //! A fail-fast variant of `make_hstring_from_buffer_nothrow` + inline unique_hstring make_hstring_from_buffer_failfast(unique_hstring_buffer&& source) + { + unique_hstring result; + FAIL_FAST_IF_FAILED(make_hstring_from_buffer_nothrow(wistd::move(source), &result)); + return result; + } + +#if defined WIL_ENABLE_EXCEPTIONS + /** Promotes an hstring_buffer to an HSTRING. + When an HSTRING_BUFFER object is promoted to a real string it must not be passed to WindowsDeleteString. The caller owns the + HSTRING afterwards. + ~~~ + wil::unique_hstring Type::Make() + { + wchar_t* bufferStorage = nullptr; + wil::unique_hstring_buffer theBuffer; + THROW_IF_FAILED(::WindowsPreallocateStringBuffer(65, &bufferStorage, &theBuffer)); + THROW_IF_FAILED(::PathCchCombine(bufferStorage, 65, m_foo, m_bar)); + return wil::make_hstring_from_buffer(wistd::move(theBuffer)); + } + ~~~ + */ + inline unique_hstring make_hstring_from_buffer(unique_hstring_buffer&& source) + { + unique_hstring result; + THROW_IF_FAILED(make_hstring_from_buffer_nothrow(wistd::move(source), &result)); + return result; + } +#endif + + /// @cond + namespace details + { + template<> struct string_maker + { + string_maker() = default; + string_maker(const string_maker&) = delete; + void operator=(const string_maker&) = delete; + string_maker& operator=(string_maker&& source) WI_NOEXCEPT + { + m_value = wistd::move(source.m_value); + m_bufferHandle = wistd::move(source.m_bufferHandle); + m_charBuffer = wistd::exchange(source.m_charBuffer, nullptr); + return *this; + } + + HRESULT make( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + const wchar_t* source, + size_t length) + { + if (source) + { + RETURN_IF_FAILED(WindowsCreateString(source, static_cast(length), &m_value)); + m_charBuffer = nullptr; + m_bufferHandle.reset(); // do this after WindowsCreateString so we can trim_at_existing_null() from our own buffer + } + else + { + // Need to set it to the empty string to support the empty string case. + m_value.reset(); + RETURN_IF_FAILED(WindowsPreallocateStringBuffer(static_cast(length), &m_charBuffer, &m_bufferHandle)); + } + return S_OK; + } + + WI_NODISCARD wchar_t* buffer() { WI_ASSERT(m_charBuffer != nullptr); return m_charBuffer; } + WI_NODISCARD const wchar_t* buffer() const { return m_charBuffer; } + + HRESULT trim_at_existing_null(size_t length) { return make(buffer(), length); } + + unique_hstring release() + { + m_charBuffer = nullptr; + if (m_bufferHandle) + { + return make_hstring_from_buffer_failfast(wistd::move(m_bufferHandle)); + } + return wistd::move(m_value); + } + + static PCWSTR get(const wil::unique_hstring& value) { return WindowsGetStringRawBuffer(value.get(), nullptr); } + + private: + unique_hstring m_value; + unique_hstring_buffer m_bufferHandle; + wchar_t* m_charBuffer = nullptr; + }; + } + /// @endcond + + // str_raw_ptr is an overloaded function that retrieves a const pointer to the first character in a string's buffer. + // This is the overload for HSTRING. Other overloads available above. + inline PCWSTR str_raw_ptr(HSTRING str) + { + return WindowsGetStringRawBuffer(str, nullptr); + } + + inline PCWSTR str_raw_ptr(const unique_hstring& str) + { + return str_raw_ptr(str.get()); + } + +#endif // __WIL__WINSTRING_H_ +#if defined(__WIL__WINSTRING_H_) && !defined(__WIL__WINSTRING_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL__WINSTRING_H_STL + typedef shared_any shared_hstring; + typedef shared_any shared_hstring_buffer; + typedef weak_any weak_hstring; + typedef weak_any weak_hstring_buffer; +#endif // __WIL__WINSTRING_H_STL + + +#if defined(_WINREG_) && !defined(__WIL_WINREG_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && !defined(WIL_KERNEL_MODE) +#define __WIL_WINREG_ + typedef unique_any unique_hkey; +#endif // __WIL_WINREG_ +#if defined(__WIL_WINREG_) && !defined(__WIL_WINREG_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WINREG_STL + typedef shared_any shared_hkey; + typedef weak_any weak_hkey; +#endif // __WIL_WINREG_STL + +#if defined(__propidl_h__) && !defined(_WIL__propidl_h__) && !defined(WIL_KERNEL_MODE) +#define _WIL__propidl_h__ + // if language extensions (/Za) disabled, PropVariantInit will not exist, PROPVARIANT has forward declaration only +#if defined(_MSC_EXTENSIONS) + using unique_prop_variant = wil::unique_struct; +#endif +#endif // _WIL__propidl_h__ + +#if defined(_OLEAUTO_H_) && !defined(__WIL_OLEAUTO_H_) && !defined(WIL_KERNEL_MODE) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) +#define __WIL_OLEAUTO_H_ + using unique_variant = wil::unique_struct; + typedef unique_any unique_bstr; + + inline wil::unique_bstr make_bstr_nothrow(PCWSTR source) WI_NOEXCEPT + { + return wil::unique_bstr(::SysAllocString(source)); + } + + inline wil::unique_bstr make_bstr_failfast(PCWSTR source) WI_NOEXCEPT + { + return wil::unique_bstr(FAIL_FAST_IF_NULL_ALLOC(::SysAllocString(source))); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + inline wil::unique_bstr make_bstr(PCWSTR source) + { + wil::unique_bstr result(make_bstr_nothrow(source)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + + inline wil::unique_variant make_variant_bstr_nothrow(PCWSTR source) WI_NOEXCEPT + { + wil::unique_variant result{}; + V_UNION(result.addressof(), bstrVal) = ::SysAllocString(source); + if (V_UNION(result.addressof(), bstrVal) != nullptr) + { + V_VT(result.addressof()) = VT_BSTR; + } + return result; + } + + inline wil::unique_variant make_variant_bstr_failfast(PCWSTR source) WI_NOEXCEPT + { + auto result{make_variant_bstr_nothrow(source)}; + FAIL_FAST_HR_IF(E_OUTOFMEMORY, V_VT(result.addressof()) == VT_EMPTY); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + inline wil::unique_variant make_variant_bstr(PCWSTR source) + { + auto result{make_variant_bstr_nothrow(source)}; + THROW_HR_IF(E_OUTOFMEMORY, V_VT(result.addressof()) == VT_EMPTY); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + +#endif // __WIL_OLEAUTO_H_ +#if defined(__WIL_OLEAUTO_H_) && !defined(__WIL_OLEAUTO_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_OLEAUTO_H_STL + typedef shared_any shared_bstr; + typedef weak_any weak_bstr; +#endif // __WIL_OLEAUTO_H_STL + + +#if (defined(_WININET_) || defined(_DUBINET_)) && !defined(__WIL_WININET_) +#define __WIL_WININET_ + typedef unique_any unique_hinternet; +#endif // __WIL_WININET_ +#if defined(__WIL_WININET_) && !defined(__WIL_WININET_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WININET_STL + typedef shared_any shared_hinternet; + typedef weak_any weak_hinternet; +#endif // __WIL_WININET_STL + + +#if defined(_WINHTTPX_) && !defined(__WIL_WINHTTP_) +#define __WIL_WINHTTP_ + typedef unique_any unique_winhttp_hinternet; +#endif // __WIL_WINHTTP_ +#if defined(__WIL_WINHTTP_) && !defined(__WIL_WINHTTP_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WINHTTP_STL + typedef shared_any shared_winhttp_hinternet; + typedef weak_any weak_winhttp_hinternet; +#endif // __WIL_WINHTTP_STL + + +#if defined(_WINSOCKAPI_) && !defined(__WIL_WINSOCKAPI_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_WINSOCKAPI_ + typedef unique_any unique_socket; +#endif // __WIL_WINSOCKAPI_ +#if defined(__WIL_WINSOCKAPI_) && !defined(__WIL_WINSOCKAPI_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WINSOCKAPI_STL + typedef shared_any shared_socket; + typedef weak_any weak_socket; +#endif // __WIL_WINSOCKAPI_STL + + +#if defined(_WINGDI_) && !defined(__WIL_WINGDI_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && !defined(NOGDI) && !defined(WIL_KERNEL_MODE) +#define __WIL_WINGDI_ + struct window_dc + { + HDC dc; + HWND hwnd; + window_dc(HDC dc_, HWND hwnd_ = nullptr) WI_NOEXCEPT { dc = dc_; hwnd = hwnd_; } + WI_NODISCARD operator HDC() const WI_NOEXCEPT { return dc; } + static void close(window_dc wdc) WI_NOEXCEPT { ::ReleaseDC(wdc.hwnd, wdc.dc); } + }; + typedef unique_any unique_hdc_window; + + struct paint_dc + { + HWND hwnd; + PAINTSTRUCT ps; + paint_dc(HDC hdc = nullptr) { ::ZeroMemory(this, sizeof(*this)); ps.hdc = hdc; } + WI_NODISCARD operator HDC() const WI_NOEXCEPT { return ps.hdc; } + static void close(paint_dc pdc) WI_NOEXCEPT { ::EndPaint(pdc.hwnd, &pdc.ps); } + }; + typedef unique_any unique_hdc_paint; + + struct select_result + { + HGDIOBJ hgdi; + HDC hdc; + select_result(HGDIOBJ hgdi_, HDC hdc_ = nullptr) WI_NOEXCEPT { hgdi = hgdi_; hdc = hdc_; } + WI_NODISCARD operator HGDIOBJ() const WI_NOEXCEPT { return hgdi; } + static void close(select_result sr) WI_NOEXCEPT { ::SelectObject(sr.hdc, sr.hgdi); } + }; + typedef unique_any unique_select_object; + + inline unique_hdc_window GetDC(HWND hwnd) WI_NOEXCEPT + { + return unique_hdc_window(window_dc(::GetDC(hwnd), hwnd)); + } + + inline unique_hdc_window GetWindowDC(HWND hwnd) WI_NOEXCEPT + { + return unique_hdc_window(window_dc(::GetWindowDC(hwnd), hwnd)); + } + + inline unique_hdc_paint BeginPaint(HWND hwnd, _Out_opt_ PPAINTSTRUCT pPaintStruct = nullptr) WI_NOEXCEPT + { + paint_dc pdc; + pdc.hwnd = hwnd; + HDC hdc = ::BeginPaint(hwnd, &pdc.ps); + assign_to_opt_param(pPaintStruct, pdc.ps); + return (hdc == nullptr) ? unique_hdc_paint() : unique_hdc_paint(pdc); + } + + inline unique_select_object SelectObject(HDC hdc, HGDIOBJ gdiobj) WI_NOEXCEPT + { + return unique_select_object(select_result(::SelectObject(hdc, gdiobj), hdc)); + } + + typedef unique_any unique_hgdiobj; + typedef unique_any unique_hpen; + typedef unique_any unique_hbrush; + typedef unique_any unique_hfont; + typedef unique_any unique_hbitmap; + typedef unique_any unique_hrgn; + typedef unique_any unique_hpalette; + typedef unique_any unique_hdc; + typedef unique_any unique_hicon; +#if !defined(NOMENUS) + typedef unique_any unique_hmenu; +#endif // !defined(NOMENUS) +#endif // __WIL_WINGDI_ +#if defined(__WIL_WINGDI_) && !defined(__WIL_WINGDI_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WINGDI_STL + typedef shared_any shared_hgdiobj; + typedef shared_any shared_hpen; + typedef shared_any shared_hbrush; + typedef shared_any shared_hfont; + typedef shared_any shared_hbitmap; + typedef shared_any shared_hrgn; + typedef shared_any shared_hpalette; + typedef shared_any shared_hdc; + typedef shared_any shared_hicon; +#if !defined(NOMENUS) + typedef shared_any shared_hmenu; +#endif // !defined(NOMENUS) + + typedef weak_any weak_hgdiobj; + typedef weak_any weak_hpen; + typedef weak_any weak_hbrush; + typedef weak_any weak_hfont; + typedef weak_any weak_hbitmap; + typedef weak_any weak_hrgn; + typedef weak_any weak_hpalette; + typedef weak_any weak_hdc; + typedef weak_any weak_hicon; +#if !defined(NOMENUS) + typedef weak_any weak_hmenu; +#endif // !defined(NOMENUS) +#endif // __WIL_WINGDI_STL + +#if defined(_INC_WTSAPI) && !defined(__WIL_WTSAPI) +#define __WIL_WTSAPI + template + using unique_wtsmem_ptr = wistd::unique_ptr>; +#endif // __WIL_WTSAPI + +#if defined(_WINSCARD_H_) && !defined(__WIL_WINSCARD_H_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_WINSCARD_H_ + typedef unique_any unique_scardctx; +#endif // __WIL_WINSCARD_H_ +#if defined(__WIL_WINSCARD_H_) && !defined(__WIL_WINSCARD_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WINSCARD_H_STL + typedef shared_any shared_scardctx; + typedef weak_any weak_scardctx; +#endif // __WIL_WINSCARD_H_STL + + +#if defined(__WINCRYPT_H__) && !defined(__WIL__WINCRYPT_H__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL__WINCRYPT_H__ + /// @cond + namespace details + { + inline void __stdcall CertCloseStoreNoParam(_Pre_opt_valid_ _Frees_ptr_opt_ HCERTSTORE hCertStore) WI_NOEXCEPT + { + ::CertCloseStore(hCertStore, 0); + } + + inline void __stdcall CryptReleaseContextNoParam(_Pre_opt_valid_ _Frees_ptr_opt_ HCRYPTPROV hCryptCtx) WI_NOEXCEPT + { + ::CryptReleaseContext(hCryptCtx, 0); + } + } + /// @endcond + + struct cert_context_t : details::unique_storage> + { + // forward all base class constructors... + template + explicit cert_context_t(args_t&&... args) WI_NOEXCEPT : unique_storage(wistd::forward(args)...) {} + + /** A wrapper around CertEnumCertificatesInStore. + CertEnumCertificatesInStore takes ownership of its second paramter in an unclear fashion, + making it error-prone to use in combination with unique_cert_context. This wrapper helps + manage the resource correctly while ensuring the GetLastError state set by CertEnumCertificatesInStore. + is not lost. See MSDN for more information on `CertEnumCertificatesInStore`. + ~~~~ + void MyMethod(HCERTSTORE certStore) + { + wil::unique_cert_context enumCert; + while (enumCert.CertEnumCertificatesInStore(certStore)) + { + UseTheCertToDoTheThing(enumCert); + } + } + ~~~~ + @param certStore A handle of a certificate store. + @param 'true' if a certificate was enumerated by this call, false otherwise. + */ + bool CertEnumCertificatesInStore(HCERTSTORE certStore) WI_NOEXCEPT + { + reset(::CertEnumCertificatesInStore(certStore, release())); + return is_valid(); + } + }; + + // Warning - ::CertEnumCertificatesInStore takes ownership of its parameter. Prefer the + // .CertEnumCertificatesInStore method of the unique_cert_context or else use .release + // when calling ::CertEnumCertificatesInStore directly. + typedef unique_any_t unique_cert_context; + typedef unique_any unique_cert_chain_context; + typedef unique_any unique_hcertstore; + typedef unique_any unique_hcryptprov; + typedef unique_any unique_hcryptkey; + typedef unique_any unique_hcrypthash; + typedef unique_any unique_hcryptmsg; +#endif // __WIL__WINCRYPT_H__ +#if defined(__WIL__WINCRYPT_H__) && !defined(__WIL__WINCRYPT_H__STL) && defined(WIL_RESOURCE_STL) +#define __WIL__WINCRYPT_H__STL + typedef shared_any shared_cert_context; + typedef shared_any shared_cert_chain_context; + typedef shared_any shared_hcertstore; + typedef shared_any shared_hcryptprov; + typedef shared_any shared_hcryptkey; + typedef shared_any shared_hcrypthash; + typedef shared_any shared_hcryptmsg; + + typedef weak_any weak_cert_context; + typedef weak_any weak_cert_chain_context; + typedef weak_any weak_hcertstore; + typedef weak_any weak_hcryptprov; + typedef weak_any weak_hcryptkey; + typedef weak_any weak_hcrypthash; + typedef weak_any weak_hcryptmsg; +#endif // __WIL__WINCRYPT_H__STL + + +#if defined(__NCRYPT_H__) && !defined(__WIL_NCRYPT_H__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_NCRYPT_H__ + using ncrypt_deleter = function_deleter; + + template + using unique_ncrypt_ptr = wistd::unique_ptr; + + typedef unique_any unique_ncrypt_prov; + typedef unique_any unique_ncrypt_key; + typedef unique_any unique_ncrypt_secret; +#endif // __WIL_NCRYPT_H__ +#if defined(__WIL_NCRYPT_H__) && !defined(__WIL_NCRYPT_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_NCRYPT_H_STL + typedef shared_any shared_ncrypt_prov; + typedef shared_any shared_ncrypt_key; + typedef shared_any shared_ncrypt_secret; + + typedef weak_any weak_ncrypt_prov; + typedef weak_any weak_ncrypt_key; + typedef weak_any weak_ncrypt_secret; +#endif // __WIL_NCRYPT_H_STL + +#if defined(__BCRYPT_H__) && !defined(__WIL_BCRYPT_H__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_BCRYPT_H__ + /// @cond + namespace details + { + inline void __stdcall BCryptCloseAlgorithmProviderNoFlags(_Pre_opt_valid_ _Frees_ptr_opt_ BCRYPT_ALG_HANDLE hAlgorithm) WI_NOEXCEPT + { + if (hAlgorithm) + { + ::BCryptCloseAlgorithmProvider(hAlgorithm, 0); + } + } + } + /// @endcond + + using bcrypt_deleter = function_deleter; + + template + using unique_bcrypt_ptr = wistd::unique_ptr; + + typedef unique_any unique_bcrypt_algorithm; + typedef unique_any unique_bcrypt_hash; + typedef unique_any unique_bcrypt_key; + typedef unique_any unique_bcrypt_secret; +#endif // __WIL_BCRYPT_H__ +#if defined(__WIL_BCRYPT_H__) && !defined(__WIL_BCRYPT_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_BCRYPT_H_STL + typedef shared_any shared_bcrypt_algorithm; + typedef shared_any shared_bcrypt_hash; + typedef shared_any shared_bcrypt_key; + typedef shared_any shared_bcrypt_secret; + + typedef weak_any weak_bcrypt_algorithm; + typedef weak_any weak_bcrypt_hash; + typedef weak_any weak_bcrypt_key; + typedef weak_any weak_bcrypt_secret; +#endif // __WIL_BCRYPT_H_STL + + +#if defined(__RPCNDR_H__) && !defined(__WIL__RPCNDR_H__) && !defined(WIL_KERNEL_MODE) +#define __WIL__RPCNDR_H__ + + //! Function deleter for use with pointers allocated by MIDL_user_allocate + using midl_deleter = function_deleter; + + //! Unique-ptr holding a type allocated by MIDL_user_alloc or returned from an RPC invocation + template using unique_midl_ptr = wistd::unique_ptr; + + //! Unique-ptr for strings allocated by MIDL_user_alloc + using unique_midl_string = unique_midl_ptr; +#ifndef WIL_NO_ANSI_STRINGS + using unique_midl_ansistring = unique_midl_ptr; +#endif + + namespace details + { + struct midl_allocator + { + static _Ret_opt_bytecap_(size) void* allocate(size_t size) WI_NOEXCEPT + { + return ::MIDL_user_allocate(size); + } + }; + + // Specialization to support construction of unique_midl_string instances + template<> struct string_allocator : midl_allocator {}; + +#ifndef WIL_NO_ANSI_STRINGS + template<> struct string_allocator : midl_allocator {}; +#endif + } +#endif // __WIL__RPCNDR_H__ + +#if defined(_OBJBASE_H_) && !defined(__WIL_OBJBASE_H_) && !defined(WIL_KERNEL_MODE) +#define __WIL_OBJBASE_H_ + using cotaskmem_deleter = function_deleter; + + template + using unique_cotaskmem_ptr = wistd::unique_ptr; + + template + using unique_cotaskmem_array_ptr = unique_array_ptr; + + /** Provides `std::make_unique()` semantics for resources allocated with `CoTaskMemAlloc()` in a context that may not throw upon allocation failure. + Use `wil::make_unique_cotaskmem_nothrow()` for resources returned from APIs that must satisfy a memory allocation contract that requires the use of `CoTaskMemAlloc()` / `CoTaskMemFree()`. + Use `wil::make_unique_nothrow()` when `CoTaskMemAlloc()` is not required. + + Allocations are initialized with placement new and will call constructors (if present), but this does not guarantee initialization. + + Note that `wil::make_unique_cotaskmem_nothrow()` is not marked WI_NOEXCEPT as it may be used to create an exception-based class that may throw in its constructor. + ~~~ + auto foo = wil::make_unique_cotaskmem_nothrow(); + if (foo) + { + // initialize allocated Foo object as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_cotaskmem_ptr>::type make_unique_cotaskmem_nothrow(Args&&... args) + { + static_assert(wistd::is_trivially_destructible::value, "T has a destructor that won't be run when used with this function; use make_unique instead"); + unique_cotaskmem_ptr sp(static_cast(::CoTaskMemAlloc(sizeof(T)))); + if (sp) + { + // use placement new to initialize memory from the previous allocation + new (sp.get()) T(wistd::forward(args)...); + } + return sp; + } + + /** Provides `std::make_unique()` semantics for array resources allocated with `CoTaskMemAlloc()` in a context that may not throw upon allocation failure. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_cotaskmem_nothrow(size); + if (foos) + { + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_cotaskmem_ptr>::type make_unique_cotaskmem_nothrow(size_t size) + { + typedef typename wistd::remove_extent::type E; + static_assert(wistd::is_trivially_destructible::value, "E has a destructor that won't be run when used with this function; use make_unique instead"); + FAIL_FAST_IF((__WI_SIZE_MAX / sizeof(E)) < size); + size_t allocSize = sizeof(E) * size; + unique_cotaskmem_ptr sp(static_cast(::CoTaskMemAlloc(allocSize))); + if (sp) + { + // use placement new to initialize memory from the previous allocation; + // note that array placement new cannot be used as the standard allows for operator new[] + // to consume overhead in the allocation for internal bookkeeping + for (auto& elem : make_range(static_cast(sp.get()), size)) + { + new (&elem) E(); + } + } + return sp; + } + + /** Provides `std::make_unique()` semantics for resources allocated with `CoTaskMemAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_cotaskmem_failfast(); + // initialize allocated Foo object as appropriate + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_cotaskmem_ptr>::type make_unique_cotaskmem_failfast(Args&&... args) + { + unique_cotaskmem_ptr result(make_unique_cotaskmem_nothrow(wistd::forward(args)...)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + + /** Provides `std::make_unique()` semantics for array resources allocated with `CoTaskMemAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_cotaskmem_failfast(size); + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_cotaskmem_ptr>::type make_unique_cotaskmem_failfast(size_t size) + { + unique_cotaskmem_ptr result(make_unique_cotaskmem_nothrow(size)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Provides `std::make_unique()` semantics for resources allocated with `CoTaskMemAlloc()`. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_cotaskmem(); + // initialize allocated Foo object as appropriate + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_cotaskmem_ptr>::type make_unique_cotaskmem(Args&&... args) + { + unique_cotaskmem_ptr result(make_unique_cotaskmem_nothrow(wistd::forward(args)...)); + THROW_IF_NULL_ALLOC(result); + return result; + } + + /** Provides `std::make_unique()` semantics for array resources allocated with `CoTaskMemAlloc()`. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_cotaskmem(size); + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_cotaskmem_ptr>::type make_unique_cotaskmem(size_t size) + { + unique_cotaskmem_ptr result(make_unique_cotaskmem_nothrow(size)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + + typedef unique_any unique_cotaskmem; + typedef unique_any unique_cotaskmem_string; +#ifndef WIL_NO_ANSI_STRINGS + typedef unique_any unique_cotaskmem_ansistring; +#endif // WIL_NO_ANSI_STRINGS + + /// @cond + namespace details + { + struct cotaskmem_allocator + { + static _Ret_opt_bytecap_(size) void* allocate(size_t size) WI_NOEXCEPT + { + return ::CoTaskMemAlloc(size); + } + }; + + template<> struct string_allocator : cotaskmem_allocator {}; + +#ifndef WIL_NO_ANSI_STRINGS + template<> struct string_allocator : cotaskmem_allocator {}; +#endif // WIL_NO_ANSI_STRINGS + } + /// @endcond + + inline auto make_cotaskmem_string_nothrow( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + return make_unique_string_nothrow(source, length); + } + + inline auto make_cotaskmem_string_failfast( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) WI_NOEXCEPT + { + return make_unique_string_failfast(source, length); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + inline auto make_cotaskmem_string( + _When_((source != nullptr) && length != static_cast(-1), _In_reads_(length)) + _When_((source != nullptr) && length == static_cast(-1), _In_z_) + PCWSTR source, size_t length = static_cast(-1)) + { + return make_unique_string(source, length); + } + +#endif // WIL_ENABLE_EXCEPTIONS +#endif // __WIL_OBJBASE_H_ +#if defined(__WIL_OBJBASE_H_) && !defined(__WIL_OBJBASE_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_OBJBASE_H_STL + typedef shared_any shared_cotaskmem; + typedef weak_any weak_cotaskmem; + typedef shared_any shared_cotaskmem_string; + typedef weak_any weak_cotaskmem_string; +#endif // __WIL_OBJBASE_H_STL + +#if defined(__WIL_OBJBASE_H_) && defined(__WIL_WINBASE_) && !defined(__WIL_OBJBASE_AND_WINBASE_H_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_OBJBASE_AND_WINBASE_H_ + + struct cotaskmem_secure_deleter + { + template + void operator()(_Pre_opt_valid_ _Frees_ptr_opt_ T* p) const + { + if (p) + { + IMalloc* malloc; + if (SUCCEEDED(::CoGetMalloc(1, &malloc))) + { + size_t const size = malloc->GetSize(p); + if (size != static_cast(-1)) + { + ::SecureZeroMemory(p, size); + } + malloc->Release(); + } + ::CoTaskMemFree(p); + } + } + }; + + template + using unique_cotaskmem_secure_ptr = wistd::unique_ptr; + + /** Provides `std::make_unique()` semantics for secure resources allocated with `CoTaskMemAlloc()` in a context that may not throw upon allocation failure. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_cotaskmem_secure_nothrow(); + if (foo) + { + // initialize allocated Foo object as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_cotaskmem_secure_ptr>::type make_unique_cotaskmem_secure_nothrow(Args&&... args) + { + return unique_cotaskmem_secure_ptr(make_unique_cotaskmem_nothrow(wistd::forward(args)...).release()); + } + + /** Provides `std::make_unique()` semantics for secure array resources allocated with `CoTaskMemAlloc()` in a context that may not throw upon allocation failure. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_cotaskmem_secure_nothrow(size); + if (foos) + { + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_cotaskmem_secure_ptr>::type make_unique_cotaskmem_secure_nothrow(size_t size) + { + return unique_cotaskmem_secure_ptr(make_unique_cotaskmem_nothrow(size).release()); + } + + /** Provides `std::make_unique()` semantics for secure resources allocated with `CoTaskMemAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_cotaskmem_secure_failfast(); + // initialize allocated Foo object as appropriate + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_cotaskmem_secure_ptr>::type make_unique_cotaskmem_secure_failfast(Args&&... args) + { + unique_cotaskmem_secure_ptr result(make_unique_cotaskmem_secure_nothrow(wistd::forward(args)...)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + + /** Provides `std::make_unique()` semantics for secure array resources allocated with `CoTaskMemAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_cotaskmem_secure_failfast(size); + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_cotaskmem_secure_ptr>::type make_unique_cotaskmem_secure_failfast(size_t size) + { + unique_cotaskmem_secure_ptr result(make_unique_cotaskmem_secure_nothrow(size)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Provides `std::make_unique()` semantics for secure resources allocated with `CoTaskMemAlloc()`. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + auto foo = wil::make_unique_cotaskmem_secure(); + // initialize allocated Foo object as appropriate + ~~~ + */ + template + inline typename wistd::enable_if::value, unique_cotaskmem_secure_ptr>::type make_unique_cotaskmem_secure(Args&&... args) + { + unique_cotaskmem_secure_ptr result(make_unique_cotaskmem_secure_nothrow(wistd::forward(args)...)); + THROW_IF_NULL_ALLOC(result); + return result; + } + + /** Provides `std::make_unique()` semantics for secure array resources allocated with `CoTaskMemAlloc()`. + See the overload of `wil::make_unique_cotaskmem_nothrow()` for non-array types for more details. + ~~~ + const size_t size = 42; + auto foos = wil::make_unique_cotaskmem_secure(size); + for (auto& elem : wil::make_range(foos.get(), size)) + { + // initialize allocated Foo objects as appropriate + } + ~~~ + */ + template + inline typename wistd::enable_if::value && wistd::extent::value == 0, unique_cotaskmem_secure_ptr>::type make_unique_cotaskmem_secure(size_t size) + { + unique_cotaskmem_secure_ptr result(make_unique_cotaskmem_secure_nothrow(size)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + + typedef unique_cotaskmem_secure_ptr unique_cotaskmem_string_secure; + + /** Copies a given string into secure memory allocated with `CoTaskMemAlloc()` in a context that may not throw upon allocation failure. + See the overload of `wil::make_cotaskmem_string_nothrow()` with supplied length for more details. + ~~~ + auto str = wil::make_cotaskmem_string_secure_nothrow(L"a string"); + if (str) + { + std::wcout << L"This is " << str.get() << std::endl; // prints "This is a string" + } + ~~~ + */ + inline unique_cotaskmem_string_secure make_cotaskmem_string_secure_nothrow(_In_ PCWSTR source) WI_NOEXCEPT + { + return unique_cotaskmem_string_secure(make_cotaskmem_string_nothrow(source).release()); + } + + /** Copies a given string into secure memory allocated with `CoTaskMemAlloc()` in a context that must fail fast upon allocation failure. + See the overload of `wil::make_cotaskmem_string_nothrow()` with supplied length for more details. + ~~~ + auto str = wil::make_cotaskmem_string_secure_failfast(L"a string"); + std::wcout << L"This is " << str.get() << std::endl; // prints "This is a string" + ~~~ + */ + inline unique_cotaskmem_string_secure make_cotaskmem_string_secure_failfast(_In_ PCWSTR source) WI_NOEXCEPT + { + unique_cotaskmem_string_secure result(make_cotaskmem_string_secure_nothrow(source)); + FAIL_FAST_IF_NULL_ALLOC(result); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Copies a given string into secure memory allocated with `CoTaskMemAlloc()`. + See the overload of `wil::make_cotaskmem_string_nothrow()` with supplied length for more details. + ~~~ + auto str = wil::make_cotaskmem_string_secure(L"a string"); + std::wcout << L"This is " << str.get() << std::endl; // prints "This is a string" + ~~~ + */ + inline unique_cotaskmem_string_secure make_cotaskmem_string_secure(_In_ PCWSTR source) + { + unique_cotaskmem_string_secure result(make_cotaskmem_string_secure_nothrow(source)); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif +#endif // __WIL_OBJBASE_AND_WINBASE_H_ + +#if defined(_OLE2_H_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && !defined(__WIL_OLE2_H_) && !defined(WIL_KERNEL_MODE) +#define __WIL_OLE2_H_ + typedef unique_struct unique_stg_medium; + struct unique_hglobal_locked : public unique_any + { + unique_hglobal_locked() = delete; + + explicit unique_hglobal_locked(HGLOBAL global) : unique_any(global) + { + // GlobalLock returns a pointer to the associated global memory block and that's what callers care about. + m_globalMemory = GlobalLock(global); + if (!m_globalMemory) + { + release(); + } + } + + explicit unique_hglobal_locked(STGMEDIUM& medium) : unique_hglobal_locked(medium.hGlobal) + { + } + + WI_NODISCARD pointer get() const + { + return m_globalMemory; + } + + private: + pointer m_globalMemory; + }; + + //! A type that calls OleUninitialize on destruction (or reset()). + //! Use as a replacement for Windows::Foundation::Uninitialize. + using unique_oleuninitialize_call = unique_call; + + //! Calls RoInitialize and fail-fasts if it fails; returns an RAII object that reverts + //! Use as a replacement for Windows::Foundation::Initialize + _Check_return_ inline unique_oleuninitialize_call OleInitialize_failfast() + { + FAIL_FAST_IF_FAILED(::OleInitialize(nullptr)); + return unique_oleuninitialize_call(); + } +#endif // __WIL_OLE2_H_ + +#if defined(__WIL_OLE2_H_) && defined(WIL_ENABLE_EXCEPTIONS) && !defined(__WIL_OLE2_H_EXCEPTIONAL) +#define __WIL_OLE2_H_EXCEPTIONAL + //! Calls RoInitialize and throws an exception if it fails; returns an RAII object that reverts + //! Use as a replacement for Windows::Foundation::Initialize + _Check_return_ inline unique_oleuninitialize_call OleInitialize() + { + THROW_IF_FAILED(::OleInitialize(nullptr)); + return unique_oleuninitialize_call(); + } +#endif + +#if defined(_INC_COMMCTRL) && !defined(__WIL_INC_COMMCTRL) && !defined(WIL_KERNEL_MODE) +#define __WIL_INC_COMMCTRL + typedef unique_any unique_himagelist; +#endif // __WIL_INC_COMMCTRL +#if defined(__WIL_INC_COMMCTRL) && !defined(__WIL_INC_COMMCTRL_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_INC_COMMCTRL_STL + typedef shared_any shared_himagelist; + typedef weak_any weak_himagelist; +#endif // __WIL_INC_COMMCTRL_STL + +#if defined(_UXTHEME_H_) && !defined(__WIL_INC_UXTHEME) && !defined(WIL_KERNEL_MODE) +#define __WIL_INC_UXTHEME + typedef unique_any unique_htheme; +#endif // __WIL_INC_UXTHEME + +#pragma warning(push) +#pragma warning(disable:4995) +#if defined(_INC_USERENV) && !defined(__WIL_INC_USERENV) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) && !defined(WIL_KERNEL_MODE) +#define __WIL_INC_USERENV + typedef unique_any unique_environment_block; +#endif // __WIL_INC_USERENV +#pragma warning(pop) + +#if defined(__WINEVT_H__) && !defined(__WIL_INC_EVT_HANDLE) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PKG_EVENTLOGSERVICE) && !defined(WIL_KERNEL_MODE) +#define __WIL_INC_EVT_HANDLE + typedef unique_any unique_evt_handle; +#endif // __WIL_INC_EVT_HANDLE + +#if defined(_WINSVC_) && !defined(__WIL_HANDLE_H_WINSVC) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && !defined(WIL_KERNEL_MODE) +#define __WIL_HANDLE_H_WINSVC + typedef unique_any unique_schandle; +#endif // __WIL_HANDLE_H_WINSVC +#if defined(__WIL_HANDLE_H_WINSVC) && !defined(__WIL_HANDLE_H_WINSVC_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_HANDLE_H_WINSVC_STL + typedef shared_any shared_schandle; + typedef weak_any weak_schandle; +#endif // __WIL_HANDLE_H_WINSVC_STL + +#if defined(_INC_STDIO) && !defined(__WIL_INC_STDIO) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && !defined(WIL_KERNEL_MODE) +#define __WIL_INC_STDIO + typedef unique_any unique_pipe; + typedef unique_any unique_file; +#endif // __WIL_INC_STDIO +#if defined(__WIL_INC_STDIO) && !defined(__WIL__INC_STDIO_STL) && defined(WIL_RESOURCE_STL) +#define __WIL__INC_STDIO_STL + typedef shared_any shared_pipe; + typedef weak_any weak_pipe; + typedef shared_any shared_file; + typedef weak_any weak_file; +#endif // __WIL__INC_STDIO_STL + +#if defined(_INC_LOCALE) && !defined(__WIL_INC_LOCALE) && !defined(WIL_KERNEL_MODE) +#define __WIL_INC_LOCALE + typedef unique_any<_locale_t, decltype(&::_free_locale), ::_free_locale> unique_locale; +#endif // __WIL_INC_LOCALE +#if defined(__WIL_INC_LOCALE) && !defined(__WIL__INC_LOCALE_STL) && defined(WIL_RESOURCE_STL) +#define __WIL__INC_LOCALE_STL + typedef shared_any shared_locale; + typedef weak_any weak_locale; +#endif // __WIL__INC_LOCALE_STL + +#if defined(_NTLSA_) && !defined(__WIL_NTLSA_) && !defined(WIL_KERNEL_MODE) +#define __WIL_NTLSA_ + typedef unique_any unique_hlsa; + + using lsa_freemem_deleter = function_deleter; + + template + using unique_lsamem_ptr = wistd::unique_ptr; +#endif // _NTLSA_ +#if defined(_NTLSA_) && !defined(__WIL_NTLSA_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_NTLSA_STL + typedef shared_any shared_hlsa; + typedef weak_any weak_hlsa; +#endif // _NTLSA_ + +#if defined(_LSALOOKUP_) && !defined(__WIL_LSALOOKUP_) +#define __WIL_LSALOOKUP_ + typedef unique_any unique_hlsalookup; + + using lsalookup_freemem_deleter = function_deleter; + + template + using unique_lsalookupmem_ptr = wistd::unique_ptr; +#endif // _LSALOOKUP_ +#if defined(_LSALOOKUP_) && !defined(__WIL_LSALOOKUP_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_LSALOOKUP_STL + typedef shared_any shared_hlsalookup; + typedef weak_any weak_hlsalookup; +#endif // _LSALOOKUP_ + +#if defined(_NTLSA_IFS_) && !defined(__WIL_HANDLE_H_NTLSA_IFS_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_HANDLE_H_NTLSA_IFS_ + using lsa_deleter = function_deleter; + + template + using unique_lsa_ptr = wistd::unique_ptr; +#endif // __WIL_HANDLE_H_NTLSA_IFS_ + +#if defined(__WERAPI_H__) && !defined(__WIL_WERAPI_H__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_WERAPI_H__ + typedef unique_any unique_wer_report; +#endif + +#if defined(__MIDLES_H__) && !defined(__WIL_MIDLES_H__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_MIDLES_H__ + typedef unique_any unique_rpc_pickle; +#endif +#if defined(__WIL_MIDLES_H__) && !defined(__WIL_MIDLES_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_MIDLES_H_STL + typedef shared_any shared_rpc_pickle; + typedef weak_any weak_rpc_pickle; +#endif + +#if defined(__RPCDCE_H__) && !defined(__WIL_RPCDCE_H__) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_RPCDCE_H__ + /// @cond + namespace details + { + inline void __stdcall WpRpcBindingFree(_Pre_opt_valid_ _Frees_ptr_opt_ RPC_BINDING_HANDLE binding) + { + ::RpcBindingFree(&binding); + } + + inline void __stdcall WpRpcBindingVectorFree(_Pre_opt_valid_ _Frees_ptr_opt_ RPC_BINDING_VECTOR* bindingVector) + { + ::RpcBindingVectorFree(&bindingVector); + } + + inline void __stdcall WpRpcStringFree(_Pre_opt_valid_ _Frees_ptr_opt_ RPC_WSTR wstr) + { + ::RpcStringFreeW(&wstr); + } + } + /// @endcond + + typedef unique_any unique_rpc_binding; + typedef unique_any unique_rpc_binding_vector; + typedef unique_any unique_rpc_wstr; +#endif +#if defined(__WIL_RPCDCE_H__) && !defined(__WIL_RPCDCE_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_RPCDCE_H_STL + typedef shared_any shared_rpc_binding; + typedef weak_any weak_rpc_binding; + typedef shared_any shared_rpc_binding_vector; + typedef weak_any weak_rpc_binding_vector; + typedef shared_any shared_rpc_wstr; + typedef weak_any weak_rpc_wstr; +#endif + +#if defined(_WCMAPI_H) && !defined(__WIL_WCMAPI_H_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_WCMAPI_H_ + using wcm_deleter = function_deleter; + + template + using unique_wcm_ptr = wistd::unique_ptr; +#endif + +#if defined(_NETIOAPI_H_) && defined(_WS2IPDEF_) && defined(MIB_INVALID_TEREDO_PORT_NUMBER) && !defined(__WIL_NETIOAPI_H_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_NETIOAPI_H_ + typedef unique_any unique_mib_iftable; +#endif +#if defined(__WIL_NETIOAPI_H_) && !defined(__WIL_NETIOAPI_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_NETIOAPI_H_STL + typedef shared_any shared_mib_iftable; + typedef weak_any weak_mib_iftable; +#endif + +#if defined(_WLAN_WLANAPI_H) && !defined(__WIL_WLAN_WLANAPI_H) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_WLAN_WLANAPI_H + using wlan_deleter = function_deleter; + + template + using unique_wlan_ptr = wistd::unique_ptr < T, wlan_deleter >; + + /// @cond + namespace details + { + inline void __stdcall CloseWlanHandle(_Frees_ptr_ HANDLE hClientHandle) + { + ::WlanCloseHandle(hClientHandle, nullptr); + } + } + /// @endcond + + typedef unique_any unique_wlan_handle; +#endif +#if defined(__WIL_WLAN_WLANAPI_H) && !defined(__WIL_WLAN_WLANAPI_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_WLAN_WLANAPI_H_STL + typedef shared_any shared_wlan_handle; + typedef weak_any weak_wlan_handle; +#endif + +#if defined(_HPOWERNOTIFY_DEF_) && !defined(__WIL_HPOWERNOTIFY_DEF_H_) && !defined(WIL_KERNEL_MODE) +#define __WIL_HPOWERNOTIFY_DEF_H_ + typedef unique_any unique_hpowernotify; +#endif + +#if defined(__WIL_WINBASE_DESKTOP) && defined(SID_DEFINED) && !defined(__WIL_PSID_DEF_H_) +#define __WIL_PSID_DEF_H_ + typedef unique_any unique_any_psid; +#if defined(_OBJBASE_H_) + typedef unique_any unique_cotaskmem_psid; +#endif +#endif + +#if defined(_PROCESSTHREADSAPI_H_) && !defined(__WIL_PROCESSTHREADSAPI_H_DESK_SYS) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) && !defined(WIL_KERNEL_MODE) +#define __WIL_PROCESSTHREADSAPI_H_DESK_SYS + /// @cond + namespace details + { + inline void __stdcall CloseProcessInformation(_In_ PROCESS_INFORMATION* p) + { + if (p->hProcess) + { + CloseHandle(p->hProcess); + } + + if (p->hThread) + { + CloseHandle(p->hThread); + } + } + } + /// @endcond + + /** Manages the outbound parameter containing handles returned by `CreateProcess()` and related methods. + ~~~ + unique_process_information process; + CreateProcessW(..., CREATE_SUSPENDED, ..., &process); + THROW_LAST_ERROR_IF(ResumeThread(process.hThread) == -1); + THROW_LAST_ERROR_IF(WaitForSingleObject(process.hProcess, INFINITE) != WAIT_OBJECT_0); + ~~~ + */ + using unique_process_information = unique_struct; +#endif + +#if defined(_PROCESSENV_) && !defined(__WIL__PROCESSENV_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM) +#define __WIL__PROCESSENV_ + /** Manages lifecycle of an environment-strings block + ~~~ + wil::unique_environstrings_ptr env { ::GetEnvironmentStringsW() }; + const wchar_t *nextVar = env.get(); + while (nextVar && *nextVar) + { + // consume 'nextVar' + nextVar += wcslen(nextVar) + 1; + } + ~~~ + */ + using unique_environstrings_ptr = wistd::unique_ptr>; + +#ifndef WIL_NO_ANSI_STRINGS + //! ANSI equivalent to unique_environstrings_ptr; + using unique_environansistrings_ptr = wistd::unique_ptr>; +#endif +#endif + +#if defined(_APPMODEL_H_) && !defined(__WIL_APPMODEL_H_) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define __WIL_APPMODEL_H_ + typedef unique_any unique_package_info_reference; +#endif // __WIL_APPMODEL_H_ +#if defined(__WIL_APPMODEL_H_) && !defined(__WIL_APPMODEL_H_STL) && defined(WIL_RESOURCE_STL) +#define __WIL_APPMODEL_H_STL + typedef shared_any shared_package_info_reference; + typedef weak_any weak_package_info_reference; +#endif // __WIL_APPMODEL_H_STL + +#if defined(WDFAPI) && !defined(__WIL_WDFAPI) +#define __WIL_WDFAPI + + namespace details + { + template + using wdf_object_resource_policy = resource_policy; + } + + template + using unique_wdf_any = unique_any_t>>; + + using unique_wdf_object = unique_wdf_any; + + using unique_wdf_timer = unique_wdf_any; + using unique_wdf_work_item = unique_wdf_any; + + using unique_wdf_memory = unique_wdf_any; + + using unique_wdf_dma_enabler = unique_wdf_any; + using unique_wdf_dma_transaction = unique_wdf_any; + using unique_wdf_common_buffer = unique_wdf_any; + + using unique_wdf_key = unique_wdf_any; + using unique_wdf_string = unique_wdf_any; + using unique_wdf_collection = unique_wdf_any; + + using wdf_wait_lock_release_scope_exit = + unique_any< + WDFWAITLOCK, + decltype(&::WdfWaitLockRelease), + ::WdfWaitLockRelease, + details::pointer_access_none>; + + inline + WI_NODISCARD + _IRQL_requires_max_(PASSIVE_LEVEL) + _Acquires_lock_(lock) + wdf_wait_lock_release_scope_exit + acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEXCEPT + { + ::WdfWaitLockAcquire(lock, nullptr); + return wdf_wait_lock_release_scope_exit(lock); + } + + inline + WI_NODISCARD + _IRQL_requires_max_(APC_LEVEL) + _When_(return, _Acquires_lock_(lock)) + wdf_wait_lock_release_scope_exit + try_acquire_wdf_wait_lock(WDFWAITLOCK lock) WI_NOEXCEPT + { + LONGLONG timeout = 0; + NTSTATUS status = ::WdfWaitLockAcquire(lock, &timeout); + if (status == STATUS_SUCCESS) + { + return wdf_wait_lock_release_scope_exit(lock); + } + else + { + return wdf_wait_lock_release_scope_exit(); + } + } + + using wdf_spin_lock_release_scope_exit = + unique_any< + WDFSPINLOCK, + decltype(&::WdfSpinLockRelease), + ::WdfSpinLockRelease, + details::pointer_access_none>; + + inline + WI_NODISCARD + _IRQL_requires_max_(DISPATCH_LEVEL) + _IRQL_raises_(DISPATCH_LEVEL) + _Acquires_lock_(lock) + wdf_spin_lock_release_scope_exit + acquire_wdf_spin_lock(WDFSPINLOCK lock) WI_NOEXCEPT + { + ::WdfSpinLockAcquire(lock); + return wdf_spin_lock_release_scope_exit(lock); + } + + namespace details + { + template + using unique_wdf_lock_storage = unique_storage>; + + class unique_wdf_spin_lock_storage : public unique_wdf_lock_storage + { + using wdf_lock_storage_t = unique_wdf_lock_storage; + + public: + using pointer = wdf_lock_storage_t::pointer; + + // Forward all base class constructors, but have it be explicit. + template + explicit unique_wdf_spin_lock_storage(args_t&& ... args) WI_NOEXCEPT : wdf_lock_storage_t(wistd::forward(args)...) {} + + NTSTATUS create(_In_opt_ WDF_OBJECT_ATTRIBUTES* attributes = WDF_NO_OBJECT_ATTRIBUTES) + { + return ::WdfSpinLockCreate(attributes, out_param(*this)); + } + + WI_NODISCARD + _IRQL_requires_max_(DISPATCH_LEVEL) + _IRQL_raises_(DISPATCH_LEVEL) + wdf_spin_lock_release_scope_exit acquire() WI_NOEXCEPT + { + return wil::acquire_wdf_spin_lock(wdf_lock_storage_t::get()); + } + }; + + class unique_wdf_wait_lock_storage : public unique_wdf_lock_storage + { + using wdf_lock_storage_t = unique_wdf_lock_storage; + + public: + using pointer = wdf_lock_storage_t::pointer; + + // Forward all base class constructors, but have it be explicit. + template + explicit unique_wdf_wait_lock_storage(args_t&& ... args) WI_NOEXCEPT : wdf_lock_storage_t(wistd::forward(args)...) {} + + NTSTATUS create(_In_opt_ WDF_OBJECT_ATTRIBUTES* attributes = WDF_NO_OBJECT_ATTRIBUTES) + { + return ::WdfWaitLockCreate(attributes, out_param(*this)); + } + + WI_NODISCARD + _IRQL_requires_max_(PASSIVE_LEVEL) + wdf_wait_lock_release_scope_exit acquire() WI_NOEXCEPT + { + return wil::acquire_wdf_wait_lock(wdf_lock_storage_t::get()); + } + + WI_NODISCARD + _IRQL_requires_max_(APC_LEVEL) + wdf_wait_lock_release_scope_exit try_acquire() WI_NOEXCEPT + { + return wil::try_acquire_wdf_wait_lock(wdf_lock_storage_t::get()); + } + }; + } + + using unique_wdf_wait_lock = unique_any_t; + using unique_wdf_spin_lock = unique_any_t; + + //! unique_wdf_object_reference is a RAII type for managing WDF object references acquired using + //! the WdfObjectReference* family of APIs. The behavior of this class is exactly identical to + //! wil::unique_any but a few methods have some WDF-object-reference-specific enhancements. + //! + //! * The constructor takes not only a WDFOBJECT-compatible type or a wil::unique_wdf_any, but + //! optionally also a tag with which the reference was acquired. + //! * A get_tag() method is provided to retrieve the tag. + //! * reset() is similar to the constructor in that it also optionally takes a tag. + //! * release() optionally takes an out-param that returns the tag. + //! + //! These subtle differences make it impossible to reuse the wil::unique_any_t template for its implementation. + template + class unique_wdf_object_reference + { + public: + unique_wdf_object_reference() WI_NOEXCEPT = default; + + //! Wrap a WDF object reference that has already been acquired into this RAII type. If you + //! want to acquire a new reference instead, use WI_WdfObjectReferenceIncrement. + explicit unique_wdf_object_reference(wdf_object_t wdfObject, void* tag = nullptr) WI_NOEXCEPT + : m_wdfObject(wdfObject), m_tag(tag) + { + } + + //! This is similar to the constructor that takes a raw WDF handle but is enlightened to + //! take a const-ref to a wil::unique_wdf_any<> instead, obviating the need to call .get() + //! on it. As with the other constructor, the expectation is that the raw reference has + //! already been acquired and ownership is being transferred into this RAII object. + explicit unique_wdf_object_reference(const wil::unique_wdf_any& wdfObject, void* tag = nullptr) WI_NOEXCEPT + : unique_wdf_object_reference(wdfObject.get(), tag) + { + } + + unique_wdf_object_reference(const unique_wdf_object_reference&) = delete; + unique_wdf_object_reference& operator=(const unique_wdf_object_reference&) = delete; + + unique_wdf_object_reference(unique_wdf_object_reference&& other) + : m_wdfObject(other.m_wdfObject), m_tag(other.m_tag) + { + other.m_wdfObject = WDF_NO_HANDLE; + other.m_tag = nullptr; + } + + unique_wdf_object_reference& operator=(unique_wdf_object_reference&& other) + { + if (this != wistd::addressof(other)) + { + reset(other.m_wdfObject, other.m_tag); + other.m_wdfObject = WDF_NO_HANDLE; + other.m_tag = nullptr; + } + + return *this; + } + + ~unique_wdf_object_reference() WI_NOEXCEPT + { + reset(); + } + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return m_wdfObject != WDF_NO_HANDLE; + } + + WI_NODISCARD wdf_object_t get() const WI_NOEXCEPT + { + return m_wdfObject; + } + + WI_NODISCARD void* get_tag() const WI_NOEXCEPT + { + return m_tag; + } + + //! Replaces the current instance (releasing it if it exists) with a new WDF object + //! reference that has already been acquired by the caller. + void reset(wdf_object_t wdfObject = WDF_NO_HANDLE, void* tag = nullptr) WI_NOEXCEPT + { + if (m_wdfObject != WDF_NO_HANDLE) + { + // We don't use WdfObjectDereferenceActual because there is no way to provide the + // correct __LINE__ and __FILE__, but if you use RAII all the way, you shouldn't have to + // worry about where it was released, only where it was acquired. + WdfObjectDereferenceWithTag(m_wdfObject, m_tag); + } + + m_wdfObject = wdfObject; + m_tag = tag; + } + + void reset(const wil::unique_wdf_any& wdfObject, void* tag = nullptr) WI_NOEXCEPT + { + reset(wdfObject.get(), tag); + } + + wdf_object_t release(_Outptr_opt_ void** tag = nullptr) WI_NOEXCEPT + { + const auto wdfObject = m_wdfObject; + wil::assign_to_opt_param(tag, m_tag); + m_wdfObject = WDF_NO_HANDLE; + m_tag = nullptr; + return wdfObject; + } + + void swap(unique_wdf_object_reference& other) WI_NOEXCEPT + { + wistd::swap_wil(m_wdfObject, other.m_wdfObject); + wistd::swap_wil(m_tag, other.m_tag); + } + + //! Drops the current reference if any, and returns a pointer to a WDF handle which can + //! receive a newly referenced WDF handle. The tag is assumed to be nullptr. If a different + //! tag needs to be used, a temporary variable will need to be used to receive the WDF + //! handle and a unique_wdf_object_reference will need to be constructed with it. + //! + //! The quintessential use-case for this method is WdfIoQueueFindRequest. + wdf_object_t* put() WI_NOEXCEPT + { + reset(); + return &m_wdfObject; + } + + wdf_object_t* operator&() WI_NOEXCEPT + { + return put(); + } + + private: + wdf_object_t m_wdfObject = WDF_NO_HANDLE; + void* m_tag = nullptr; + }; + + // Increment the ref-count on a WDF object and return a unique_wdf_object_reference for it. Use + // WI_WdfObjectReferenceIncrement to automatically use the call-site source location. Use this + // function only if the call-site source location is obtained from elsewhere (i.e., plumbed + // through other abstractions). + template + inline WI_NODISCARD unique_wdf_object_reference wdf_object_reference_increment( + wdf_object_t wdfObject, PVOID tag, LONG lineNumber, PCSTR fileName) WI_NOEXCEPT + { + // Parameter is incorrectly marked as non-const, so the const-cast is required. + ::WdfObjectReferenceActual(wdfObject, tag, lineNumber, const_cast(fileName)); + return unique_wdf_object_reference{ wdfObject, tag }; + } + + template + inline WI_NODISCARD unique_wdf_object_reference wdf_object_reference_increment( + const wil::unique_wdf_any& wdfObject, PVOID tag, LONG lineNumber, PCSTR fileName) WI_NOEXCEPT + { + return wdf_object_reference_increment(wdfObject.get(), tag, lineNumber, fileName); + } + +// A macro so that we can capture __LINE__ and __FILE__. +#define WI_WdfObjectReferenceIncrement(wdfObject, tag) \ + wil::wdf_object_reference_increment(wdfObject, tag, __LINE__, __FILE__) + + //! wdf_request_completer is a unique_any-like RAII class for managing completion of a + //! WDFREQUEST. On destruction or explicit reset() it completes the WDFREQUEST with parameters + //! (status, information, priority boost) previously set using methods on this class. + //! + //! This class does not use the unique_any_t template primarily because the release() and put() + //! methods need to return a WDFREQUEST/WDFREQUEST*, as opposed to the internal storage type. + class wdf_request_completer + { + public: + + explicit wdf_request_completer(WDFREQUEST wdfRequest = WDF_NO_HANDLE) WI_NOEXCEPT + : m_wdfRequest(wdfRequest) + { + } + + wdf_request_completer(const wdf_request_completer&) = delete; + wdf_request_completer& operator=(const wdf_request_completer&) = delete; + + wdf_request_completer(wdf_request_completer&& other) WI_NOEXCEPT + : m_wdfRequest(other.m_wdfRequest), m_status(other.m_status), m_information(other.m_information), +#if defined(WIL_KERNEL_MODE) + m_priorityBoost(other.m_priorityBoost), +#endif + m_completionFlags(other.m_completionFlags) + { + clear_state(other); + } + + wdf_request_completer& operator=(wdf_request_completer&& other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + m_wdfRequest = other.m_wdfRequest; + m_status = other.m_status; + m_information = other.m_information; +#if defined(WIL_KERNEL_MODE) + m_priorityBoost = other.m_priorityBoost; +#endif + m_completionFlags = other.m_completionFlags; + clear_state(other); + } + + return *this; + } + + ~wdf_request_completer() WI_NOEXCEPT + { + reset(); + } + + WI_NODISCARD WDFREQUEST get() const WI_NOEXCEPT + { + return m_wdfRequest; + } + + //! Set the NTSTATUS value with with the WDFREQUEST will be completed when the RAII object + //! goes out of scope or .reset() is called explicitly. Calling this method does *not* + //! complete the request right away. No effect if this object currently does not have + //! ownership of a WDFREQUEST. The expected usage pattern is that set_status() is called + //! only after ownership of a WDFREQUEST is transferred to this object. + void set_status(NTSTATUS status) WI_NOEXCEPT + { + // The contract is that this method has no effect if we currently do not have a + // m_wdfRequest. But that is enforced by discarding all state when a WDFREQUEST is + // attached, not by explicitly checking for that condition here. + + m_status = status; + } + + //! Set the IO_STATUS_BLOCK.Information value with which the WDFREQUEST will be completed. + //! Note that the Information value is not stored directly in the WDFREQUEST using + //! WdfRequestSetInformation. It is only used at the time of completion. No effect if this + //! object currently does not have ownership of a WDFREQUEST. The expected usage pattern is + //! that set_information() is called only after ownership of a WDFREQUEST is transferred to + //! this object. + void set_information(ULONG_PTR information) WI_NOEXCEPT + { + // The contract is that this method has no effect if we currently do not have a + // m_wdfRequest. But that is enforced by discarding all state when a WDFREQUEST is + // attached, not by explicitly checking for that condition here. + + m_completionFlags.informationSet = 1; + m_information = information; + } + +#if defined(WIL_KERNEL_MODE) + //! Set the priority boost with which the WDFREQUEST will be completed. If this method is + //! called, the WDFREQUEST will eventually be completed with + //! WdfRequestCompleteWithPriorityBoost. No effect if this object currently does not have + //! ownership of a WDFREQUEST. The expected usage pattern is that set_priority_boost() is + //! called only after ownership of a WDFREQUEST is transferred to this object. + void set_priority_boost(CCHAR priorityBoost) WI_NOEXCEPT + { + // The contract is that this method has no effect if we currently do not have a + // m_wdfRequest. But that is enforced by discarding all state when a WDFREQUEST is + // attached, not by explicitly checking for that condition here. + + m_completionFlags.priorityBoostSet = 1; + m_priorityBoost = priorityBoost; + } +#endif + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return m_wdfRequest != WDF_NO_HANDLE; + } + + WDFREQUEST* put() WI_NOEXCEPT + { + reset(); + return &m_wdfRequest; + } + + WDFREQUEST* operator&() WI_NOEXCEPT + { + return put(); + } + + //! Relinquishes completion responsibility for the WDFREQUEST. Note that any state + //! (information, priority boost, status) set on this object is lost. This design choice was + //! made because it is atypical to set an information or priority boost value upfront; they + //! are typically set at the point where the request is going to be completed. Hence a + //! use-case wherein release() is called will typically not have set an information or + //! priority boost. + WDFREQUEST release() WI_NOEXCEPT + { + const auto wdfRequest = m_wdfRequest; + clear_state(*this); + return wdfRequest; + } + + void swap(wdf_request_completer& other) WI_NOEXCEPT + { + wistd::swap_wil(m_wdfRequest, other.m_wdfRequest); + wistd::swap_wil(m_information, other.m_information); + wistd::swap_wil(m_status, other.m_status); +#if defined(WIL_KERNEL_MODE) + wistd::swap_wil(m_priorityBoost, other.m_priorityBoost); +#endif + wistd::swap_wil(m_completionFlags, other.m_completionFlags); + } + + void reset(WDFREQUEST newWdfRequest = WDF_NO_HANDLE) + { + if (m_wdfRequest != WDF_NO_HANDLE) + { + // We try to match the usage patterns that the driver would have typically used in the + // various scenarios. For instance, if the driver has set the information field, we'll + // call WdfRequestCompleteWithInformation instead of calling WdfRequestSetInformation + // followed by WdfRequestComplete. + +#if defined(WIL_KERNEL_MODE) + if (m_completionFlags.priorityBoostSet) + { + if (m_completionFlags.informationSet) + { + WdfRequestSetInformation(m_wdfRequest, m_information); + } + + WdfRequestCompleteWithPriorityBoost(m_wdfRequest, m_status, m_priorityBoost); + } + else +#endif + if (m_completionFlags.informationSet) + { + WdfRequestCompleteWithInformation(m_wdfRequest, m_status, m_information); + } + else + { + WdfRequestComplete(m_wdfRequest, m_status); + } + } + + // We call clear_state unconditionally just in case some parameters (status, + // information, etc.) were set prior to attaching a WDFREQUEST to this object. Those + // parameters are not considered relevant to the WDFREQUEST being attached to this + // object now. + clear_state(*this, newWdfRequest); + } + + private: + + static void clear_state(wdf_request_completer& completer, WDFREQUEST newWdfRequest = WDF_NO_HANDLE) WI_NOEXCEPT + { + completer.m_wdfRequest = newWdfRequest; + completer.m_status = STATUS_UNSUCCESSFUL; + completer.m_information = 0; +#if defined(WIL_KERNEL_MODE) + completer.m_priorityBoost = 0; +#endif + completer.m_completionFlags = {}; + } + + // Members are ordered in decreasing size to minimize padding. + + WDFREQUEST m_wdfRequest = WDF_NO_HANDLE; + + // This will not be used unless m_completionFlags.informationSet is set. + ULONG_PTR m_information = 0; + + // There is no reasonably default NTSTATUS value. Callers are expected to explicitly set a + // status value at the point where it is decided that the request needs to be completed. + NTSTATUS m_status = STATUS_UNSUCCESSFUL; + +// UMDF does not support WdfRequestCompleteWithPriorityBoost. +#if defined(WIL_KERNEL_MODE) + // This will not be used unless m_completionFlags.priorityBoostSet is set. + CCHAR m_priorityBoost = 0; +#endif + + struct + { + UINT8 informationSet : 1; +#if defined(WIL_KERNEL_MODE) + UINT8 priorityBoostSet : 1; +#endif + } m_completionFlags = {}; + }; +#endif + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) && \ + defined(_CFGMGR32_H_) && \ + (WINVER >= _WIN32_WINNT_WIN8) && \ + !defined(__WIL_CFGMGR32_H_) +#define __WIL_CFGMGR32_H_ + typedef unique_any unique_hcmnotification; +#endif + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) && \ + defined(_SWDEVICE_H_) && \ + (WINVER >= _WIN32_WINNT_WIN8) && \ + !defined(__WIL_SWDEVICE_H_) +#define __WIL_SWDEVICE_H_ + typedef unique_any unique_hswdevice; +#endif + +#if defined(WIL_KERNEL_MODE) && (defined(_WDMDDK_) || defined(_NTDDK_)) && !defined(__WIL_RESOURCE_WDM) +#define __WIL_RESOURCE_WDM + + namespace details + { + struct kspin_lock_saved_irql + { + PKSPIN_LOCK spinLock = nullptr; + KIRQL savedIrql = PASSIVE_LEVEL; + + kspin_lock_saved_irql() = default; + + kspin_lock_saved_irql(PKSPIN_LOCK /* spinLock */) + { + // This constructor exists simply to allow conversion of the pointer type to + // pointer_storage type when constructing an invalid instance. The spinLock pointer + // is expected to be nullptr. + } + + // Exists to satisfy the interconvertibility requirement for pointer_storage and + // pointer. + WI_NODISCARD explicit operator PKSPIN_LOCK() const + { + return spinLock; + } + + _IRQL_requires_(DISPATCH_LEVEL) + static + void Release(_In_ _IRQL_restores_ const kspin_lock_saved_irql& spinLockSavedIrql) + { + KeReleaseSpinLock(spinLockSavedIrql.spinLock, spinLockSavedIrql.savedIrql); + } + }; + + // On some architectures KeReleaseSpinLockFromDpcLevel is a macro, and we need a thunk + // function we can take the address of. + inline + _IRQL_requires_min_(DISPATCH_LEVEL) + void __stdcall ReleaseSpinLockFromDpcLevel(_Inout_ PKSPIN_LOCK spinLock) WI_NOEXCEPT + { + KeReleaseSpinLockFromDpcLevel(spinLock); + } + } + + using kspin_lock_guard = unique_any; + + using kspin_lock_at_dpc_guard = unique_any; + + WI_NODISCARD + inline + _IRQL_requires_max_(DISPATCH_LEVEL) + _IRQL_saves_ + _IRQL_raises_(DISPATCH_LEVEL) + kspin_lock_guard + acquire_kspin_lock(_In_ PKSPIN_LOCK spinLock) + { + details::kspin_lock_saved_irql spinLockSavedIrql; + KeAcquireSpinLock(spinLock, &spinLockSavedIrql.savedIrql); + spinLockSavedIrql.spinLock = spinLock; + return kspin_lock_guard(spinLockSavedIrql); + } + + WI_NODISCARD + inline + _IRQL_requires_min_(DISPATCH_LEVEL) + kspin_lock_at_dpc_guard + acquire_kspin_lock_at_dpc(_In_ PKSPIN_LOCK spinLock) + { + KeAcquireSpinLockAtDpcLevel(spinLock); + return kspin_lock_at_dpc_guard(spinLock); + } + + class kernel_spin_lock + { + public: + kernel_spin_lock() WI_NOEXCEPT + { + ::KeInitializeSpinLock(&m_kSpinLock); + } + + ~kernel_spin_lock() = default; + + // Cannot change memory location. + kernel_spin_lock(const kernel_spin_lock&) = delete; + kernel_spin_lock& operator=(const kernel_spin_lock&) = delete; + kernel_spin_lock(kernel_spin_lock&&) = delete; + kernel_spin_lock& operator=(kernel_spin_lock&&) = delete; + + WI_NODISCARD + _IRQL_requires_max_(DISPATCH_LEVEL) + _IRQL_saves_ + _IRQL_raises_(DISPATCH_LEVEL) + kspin_lock_guard acquire() WI_NOEXCEPT + { + return acquire_kspin_lock(&m_kSpinLock); + } + + WI_NODISCARD + _IRQL_requires_min_(DISPATCH_LEVEL) + kspin_lock_at_dpc_guard acquire_at_dpc() WI_NOEXCEPT + { + return acquire_kspin_lock_at_dpc(&m_kSpinLock); + } + + private: + KSPIN_LOCK m_kSpinLock; + }; + + namespace details + { + template + class kernel_event_t + { + public: + explicit kernel_event_t(bool isSignaled = false) WI_NOEXCEPT + { + ::KeInitializeEvent(&m_kernelEvent, static_cast(eventType), isSignaled ? TRUE : FALSE); + } + + // Cannot change memory location. + kernel_event_t(const kernel_event_t&) = delete; + kernel_event_t(kernel_event_t&&) = delete; + kernel_event_t& operator=(const kernel_event_t&) = delete; + kernel_event_t& operator=(kernel_event_t&&) = delete; + + // Get the underlying KEVENT structure for more advanced usages like + // KeWaitForMultipleObjects or KeWaitForSingleObject with non-default parameters. + PRKEVENT get() WI_NOEXCEPT + { + return &m_kernelEvent; + } + + void clear() WI_NOEXCEPT + { + // The most common use-case is to clear the event with no interest in its previous + // value. Hence, that is the functionality we provide by default. If the previous + // value is required, one may .get() the underlying event object and call + // ::KeResetEvent(). + ::KeClearEvent(&m_kernelEvent); + } + + // Returns the previous state of the event. + bool set(KPRIORITY increment = IO_NO_INCREMENT) WI_NOEXCEPT + { + return ::KeSetEvent(&m_kernelEvent, increment, FALSE) ? true : false; + } + + // Checks if the event is currently signaled. Does not change the state of the event. + WI_NODISCARD bool is_signaled() const WI_NOEXCEPT + { + return ::KeReadStateEvent(const_cast(&m_kernelEvent)) ? true : false; + } + + // Return true if the wait was satisfied. Time is specified in 100ns units, relative + // (negative) or absolute (positive). For more details, see the documentation of + // KeWaitForSingleObject. + bool wait(LONGLONG waitTime) WI_NOEXCEPT + { + LARGE_INTEGER duration; + duration.QuadPart = waitTime; + return wait_for_single_object(&duration); + } + + // Waits indefinitely for the event to be signaled. + void wait() WI_NOEXCEPT + { + wait_for_single_object(nullptr); + } + + private: + bool wait_for_single_object(_In_opt_ LARGE_INTEGER* waitDuration) WI_NOEXCEPT + { + auto status = ::KeWaitForSingleObject(&m_kernelEvent, Executive, KernelMode, FALSE, waitDuration); + + // We specified Executive and non-alertable, which means some of the return values are + // not possible. + WI_ASSERT((status == STATUS_SUCCESS) || (status == STATUS_TIMEOUT)); + return (status == STATUS_SUCCESS); + } + + KEVENT m_kernelEvent; + }; + } + + using kernel_event_auto_reset = details::kernel_event_t; + using kernel_event_manual_reset = details::kernel_event_t; + using kernel_event = kernel_event_auto_reset; // For parity with the default for other WIL event types. + + /** + RAII class and lock-guards for a kernel FAST_MUTEX. + */ + + using fast_mutex_guard = unique_any; + + WI_NODISCARD + inline + _IRQL_requires_max_(APC_LEVEL) + fast_mutex_guard acquire_fast_mutex(FAST_MUTEX* fastMutex) WI_NOEXCEPT + { + ::ExAcquireFastMutex(fastMutex); + return fast_mutex_guard(fastMutex); + } + + WI_NODISCARD + inline + _IRQL_requires_max_(APC_LEVEL) + fast_mutex_guard try_acquire_fast_mutex(FAST_MUTEX* fastMutex) WI_NOEXCEPT + { + if (::ExTryToAcquireFastMutex(fastMutex)) + { + return fast_mutex_guard(fastMutex); + } + else + { + return fast_mutex_guard(); + } + } + + class fast_mutex + { + public: + fast_mutex() WI_NOEXCEPT + { + ::ExInitializeFastMutex(&m_fastMutex); + } + + ~fast_mutex() WI_NOEXCEPT = default; + + // Cannot change memory location. + fast_mutex(const fast_mutex&) = delete; + fast_mutex& operator=(const fast_mutex&) = delete; + fast_mutex(fast_mutex&&) = delete; + fast_mutex& operator=(fast_mutex&&) = delete; + + // Calls ExAcquireFastMutex. Returned wil::unique_any object calls ExReleaseFastMutex on + // destruction. + WI_NODISCARD + _IRQL_requires_max_(APC_LEVEL) + fast_mutex_guard acquire() WI_NOEXCEPT + { + return acquire_fast_mutex(&m_fastMutex); + } + + // Calls ExTryToAcquireFastMutex. Returned wil::unique_any may be empty. If non-empty, it + // calls ExReleaseFastMutex on destruction. + WI_NODISCARD + _IRQL_requires_max_(APC_LEVEL) + fast_mutex_guard try_acquire() WI_NOEXCEPT + { + return try_acquire_fast_mutex(&m_fastMutex); + } + + private: + FAST_MUTEX m_fastMutex; + }; + + namespace details + { + _IRQL_requires_max_(APC_LEVEL) + inline void release_fast_mutex_with_critical_region(FAST_MUTEX* fastMutex) WI_NOEXCEPT + { + ::ExReleaseFastMutexUnsafe(fastMutex); + ::KeLeaveCriticalRegion(); + } + } + + using fast_mutex_with_critical_region_guard = + unique_any; + + WI_NODISCARD + inline + _IRQL_requires_max_(APC_LEVEL) + fast_mutex_with_critical_region_guard acquire_fast_mutex_with_critical_region(FAST_MUTEX* fastMutex) WI_NOEXCEPT + { + ::KeEnterCriticalRegion(); + ::ExAcquireFastMutexUnsafe(fastMutex); + return fast_mutex_with_critical_region_guard(fastMutex); + } + + // A FAST_MUTEX lock class that calls KeEnterCriticalRegion and then ExAcquireFastMutexUnsafe. + // Returned wil::unique_any lock-guard calls ExReleaseFastMutexUnsafe and KeLeaveCriticalRegion + // on destruction. This is useful if calling code wants to stay at PASSIVE_LEVEL. + class fast_mutex_with_critical_region + { + public: + fast_mutex_with_critical_region() WI_NOEXCEPT + { + ::ExInitializeFastMutex(&m_fastMutex); + } + + ~fast_mutex_with_critical_region() WI_NOEXCEPT = default; + + // Cannot change memory location. + fast_mutex_with_critical_region(const fast_mutex_with_critical_region&) = delete; + fast_mutex_with_critical_region& operator=(const fast_mutex_with_critical_region&) = delete; + fast_mutex_with_critical_region(fast_mutex_with_critical_region&&) = delete; + fast_mutex_with_critical_region& operator=(fast_mutex_with_critical_region&&) = delete; + + WI_NODISCARD + _IRQL_requires_max_(APC_LEVEL) + fast_mutex_with_critical_region_guard acquire() WI_NOEXCEPT + { + return acquire_fast_mutex_with_critical_region(&m_fastMutex); + } + + private: + FAST_MUTEX m_fastMutex; + }; + + //! A type that calls KeLeaveCriticalRegion on destruction (or reset()). + using unique_leave_critical_region_call = unique_call; + + //! Disables user APCs and normal kernel APCs; returns an RAII object that reverts + WI_NODISCARD inline unique_leave_critical_region_call enter_critical_region() + { + KeEnterCriticalRegion(); + return{}; + } + + //! A type that calls KeLeaveGuardedRegion on destruction (or reset()). + using unique_leave_guarded_region_call = unique_call; + + //! Disables all APCs; returns an RAII object that reverts + WI_NODISCARD inline unique_leave_guarded_region_call enter_guarded_region() + { + KeEnterGuardedRegion(); + return{}; + } + +//! WDM version of EX_PUSH_LOCK is available starting with Windows 10 1809 +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) + namespace details + { + _IRQL_requires_max_(APC_LEVEL) + inline void release_push_lock_exclusive(EX_PUSH_LOCK* pushLock) WI_NOEXCEPT + { + ::ExReleasePushLockExclusive(pushLock); + ::KeLeaveCriticalRegion(); + } + + _IRQL_requires_max_(APC_LEVEL) + inline void release_push_lock_shared(EX_PUSH_LOCK* pushLock) WI_NOEXCEPT + { + ::ExReleasePushLockShared(pushLock); + ::KeLeaveCriticalRegion(); + } + } + + using push_lock_exclusive_guard = + unique_any; + + using push_lock_shared_guard = + unique_any; + + WI_NODISCARD + inline + _IRQL_requires_max_(APC_LEVEL) + push_lock_exclusive_guard acquire_push_lock_exclusive(EX_PUSH_LOCK* pushLock) WI_NOEXCEPT + { + ::KeEnterCriticalRegion(); + ::ExAcquirePushLockExclusive(pushLock); + return push_lock_exclusive_guard(pushLock); + } + + WI_NODISCARD + inline + _IRQL_requires_max_(APC_LEVEL) + push_lock_shared_guard acquire_push_lock_shared(EX_PUSH_LOCK* pushLock) WI_NOEXCEPT + { + ::KeEnterCriticalRegion(); + ::ExAcquirePushLockShared(pushLock); + return push_lock_shared_guard(pushLock); + } + + class push_lock + { + public: + push_lock() WI_NOEXCEPT + { + ::ExInitializePushLock(&m_pushLock); + } + + ~push_lock() WI_NOEXCEPT = default; + + // Cannot change memory location. + push_lock(const push_lock&) = delete; + push_lock& operator=(const push_lock&) = delete; + push_lock(push_lock&&) = delete; + push_lock& operator=(push_lock&&) = delete; + + WI_NODISCARD + _IRQL_requires_max_(APC_LEVEL) + push_lock_exclusive_guard acquire_exclusive() WI_NOEXCEPT + { + return acquire_push_lock_exclusive(&m_pushLock); + } + + WI_NODISCARD + _IRQL_requires_max_(APC_LEVEL) + push_lock_shared_guard acquire_shared() WI_NOEXCEPT + { + return acquire_push_lock_shared(&m_pushLock); + } + + private: + EX_PUSH_LOCK m_pushLock; + }; +#endif + + namespace details + { + // Define a templated type for pool functions in order to satisfy overload resolution below + template + struct pool_helpers + { + static inline + _IRQL_requires_max_(DISPATCH_LEVEL) + void __stdcall FreePoolWithTag(pointer value) WI_NOEXCEPT + { + if (value) + { + ExFreePoolWithTag(value, tag); + } + } + }; + } + + template + using unique_tagged_pool_ptr = unique_any::FreePoolWithTag), &details::pool_helpers::FreePoolWithTag>; + + // For use with IRPs that need to be IoFreeIrp'ed when done, typically allocated using IoAllocateIrp. + using unique_allocated_irp = wil::unique_any; + using unique_io_workitem = wil::unique_any; + +#endif // __WIL_RESOURCE_WDM + +#if defined(WIL_KERNEL_MODE) && (defined(_WDMDDK_) || defined(_ZWAPI_)) && !defined(__WIL_RESOURCE_ZWAPI) +#define __WIL_RESOURCE_ZWAPI + + using unique_kernel_handle = wil::unique_any; + +#endif // __WIL_RESOURCE_ZWAPI + +#if defined(WINTRUST_H) && defined(SOFTPUB_H) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && !defined(__WIL_WINTRUST) +#define __WIL_WINTRUST + namespace details + { + inline void __stdcall CloseWintrustData(_Inout_ WINTRUST_DATA* wtData) WI_NOEXCEPT + { + GUID guidV2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; + wtData->dwStateAction = WTD_STATEACTION_CLOSE; + WinVerifyTrust(static_cast(INVALID_HANDLE_VALUE), &guidV2, wtData); + } + } + typedef wil::unique_struct unique_wintrust_data; +#endif // __WIL_WINTRUST + +#if defined(MSCAT_H) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && !defined(__WIL_MSCAT) +#define __WIL_MSCAT + namespace details + { + inline void __stdcall CryptCATAdminReleaseContextNoFlags(_Pre_opt_valid_ _Frees_ptr_opt_ HCATADMIN handle) WI_NOEXCEPT + { + CryptCATAdminReleaseContext(handle, 0); + } + } + typedef wil::unique_any unique_hcatadmin; + +#if defined(WIL_RESOURCE_STL) + typedef shared_any shared_hcatadmin; + struct hcatinfo_deleter + { + hcatinfo_deleter(wil::shared_hcatadmin handle) WI_NOEXCEPT : m_hCatAdmin(wistd::move(handle)) {} + void operator()(_Pre_opt_valid_ _Frees_ptr_opt_ HCATINFO handle) const WI_NOEXCEPT + { + CryptCATAdminReleaseCatalogContext(m_hCatAdmin.get(), handle, 0); + } + wil::shared_hcatadmin m_hCatAdmin; + }; + // This stores HCATINFO, i.e. HANDLE (void *) + typedef wistd::unique_ptr unique_hcatinfo; + + namespace details + { + class crypt_catalog_enumerator + { + wil::unique_hcatinfo m_hCatInfo; + const BYTE* m_hash; + DWORD m_hashLen; + bool m_initialized = false; + + struct ref + { + explicit ref(crypt_catalog_enumerator &r) WI_NOEXCEPT : + m_r(r) + {} + + WI_NODISCARD operator HCATINFO() const WI_NOEXCEPT + { + return m_r.current(); + } + + wil::unique_hcatinfo move_from_unique_hcatinfo() WI_NOEXCEPT + { + wil::unique_hcatinfo info(wistd::move(m_r.m_hCatInfo)); + return info; + } + + WI_NODISCARD bool operator==(wistd::nullptr_t) const WI_NOEXCEPT + { + return m_r.m_hCatInfo == nullptr; + } + + WI_NODISCARD bool operator!=(wistd::nullptr_t) const WI_NOEXCEPT + { + return !(*this == nullptr); + } + + private: + crypt_catalog_enumerator &m_r; + }; + + struct iterator + { +#ifdef _XUTILITY_ + // muse be input_iterator_tag as use of one instance invalidates the other. + typedef ::std::input_iterator_tag iterator_category; +#endif + + explicit iterator(crypt_catalog_enumerator *r) WI_NOEXCEPT : + m_r(r) + {} + + iterator(const iterator &) = default; + iterator(iterator &&) = default; + iterator &operator=(const iterator &) = default; + iterator &operator=(iterator &&) = default; + + WI_NODISCARD bool operator==(const iterator &rhs) const WI_NOEXCEPT + { + if (rhs.m_r == m_r) + { + return true; + } + + return (*this == nullptr) && (rhs == nullptr); + } + + WI_NODISCARD bool operator!=(const iterator &rhs) const WI_NOEXCEPT + { + return !(rhs == *this); + } + + WI_NODISCARD bool operator==(wistd::nullptr_t) const WI_NOEXCEPT + { + return nullptr == m_r || nullptr == m_r->current(); + } + + WI_NODISCARD bool operator!=(wistd::nullptr_t) const WI_NOEXCEPT + { + return !(*this == nullptr); + } + + iterator &operator++() WI_NOEXCEPT + { + if (m_r != nullptr) + { + m_r->next(); + } + + return *this; + } + + WI_NODISCARD ref operator*() const WI_NOEXCEPT + { + return ref(*m_r); + } + + private: + crypt_catalog_enumerator *m_r; + }; + + shared_hcatadmin &hcatadmin() WI_NOEXCEPT + { + return m_hCatInfo.get_deleter().m_hCatAdmin; + } + + bool move_next() WI_NOEXCEPT + { + HCATINFO prevCatInfo = m_hCatInfo.release(); + m_hCatInfo.reset( + ::CryptCATAdminEnumCatalogFromHash( + hcatadmin().get(), + const_cast(m_hash), + m_hashLen, + 0, + &prevCatInfo)); + return !!m_hCatInfo; + } + + HCATINFO next() WI_NOEXCEPT + { + if (m_initialized && m_hCatInfo) + { + move_next(); + } + + return current(); + } + + HCATINFO init() WI_NOEXCEPT + { + if (!m_initialized) + { + m_initialized = true; + move_next(); + } + + return current(); + } + + HCATINFO current() WI_NOEXCEPT + { + return m_hCatInfo.get(); + } + + public: + crypt_catalog_enumerator(wil::shared_hcatadmin &hCatAdmin, + const BYTE *hash, + DWORD hashLen) WI_NOEXCEPT : + m_hCatInfo(nullptr, hCatAdmin), + m_hash(hash), + m_hashLen(hashLen) + // , m_initialized(false) // redundant + {} + + WI_NODISCARD iterator begin() WI_NOEXCEPT + { + init(); + return iterator(this); + } + + WI_NODISCARD iterator end() const WI_NOEXCEPT + { + return iterator(nullptr); + } + + crypt_catalog_enumerator(crypt_catalog_enumerator &&) = default; + crypt_catalog_enumerator &operator=(crypt_catalog_enumerator &&) = default; + + crypt_catalog_enumerator(const crypt_catalog_enumerator &) = delete; + crypt_catalog_enumerator &operator=(const crypt_catalog_enumerator &) = delete; + }; + } + + /** Use to enumerate catalogs containing a hash with a range-based for. + This avoids handling a raw resource to call CryptCATAdminEnumCatalogFromHash correctly. + Example: + `for (auto&& cat : wil::make_catalog_enumerator(hCatAdmin, hash, hashLen)) + { CryptCATCatalogInfoFromContext(cat, &catInfo, 0); }` */ + inline details::crypt_catalog_enumerator make_crypt_catalog_enumerator(wil::shared_hcatadmin &hCatAdmin, + _In_count_(hashLen) const BYTE *hash, DWORD hashLen) WI_NOEXCEPT + { + return details::crypt_catalog_enumerator(hCatAdmin, hash, hashLen); + } + + template + details::crypt_catalog_enumerator make_crypt_catalog_enumerator(wil::shared_hcatadmin &hCatAdmin, + const BYTE (&hash)[Size]) WI_NOEXCEPT + { + static_assert(Size <= static_cast(0xffffffffUL), "Array size truncated"); + return details::crypt_catalog_enumerator(hCatAdmin, hash, static_cast(Size)); + } + +#endif // WI_RESOURCE_STL + +#endif // __WIL_MSCAT + + +#if !defined(__WIL_RESOURCE_LOCK_ENFORCEMENT) +#define __WIL_RESOURCE_LOCK_ENFORCEMENT + + /** + Functions that need an exclusive lock use can use write_lock_required as a parameter to enforce lock + safety at compile time. Similarly, read_lock_required may stand as a parameter where shared ownership + of a lock is required. These are empty structs that will never be used, other than passing them on to + another function that requires them. + + These types are implicitly convertible from various lock holding types, enabling callers to provide them as + proof of the lock that they hold. + + The following example is intentially contrived to demonstrate multiple use cases: + - Methods that require only shared/read access + - Methods that require only exclusive write access + - Methods that pass their proof-of-lock to a helper + ~~~ + class RemoteControl + { + public: + void VolumeUp(); + int GetVolume(); + private: + int GetCurrentVolume(wil::read_lock_required); + void AdjustVolume(int delta, wil::write_lock_required); + void SetNewVolume(int newVolume, wil::write_lock_required); + + int m_currentVolume = 0; + wil::srwlock m_lock; + }; + + void RemoteControl::VolumeUp() + { + auto writeLock = m_lock.lock_exclusive(); + AdjustVolume(1, writeLock); + } + + int RemoteControl::GetVolume() + { + auto readLock = m_lock.lock_shared(); + return GetCurrentVolume(readLock); + } + + int RemoteControl::GetCurrentVolume(wil::read_lock_required) + { + return m_currentVolume; + } + + void AdjustVolume(int delta, wil::write_lock_required lockProof) + { + const auto currentVolume = GetCurrentVolume(lockProof); + SetNewVolume(currentVolume + delta, lockProof); + } + + void RemoteControl::SetNewVolume(int newVolume, wil::write_lock_required) + { + m_currentVolume = newVolume; + } + ~~~ + + In this design it is impossible to not meet the "lock must be held" precondition and the function parameter types + help you understand which one. + + Cases not handled: + - Functions that need the lock held, but fail to specify this fact by requiring a lock required parameter need + to be found via code inspection. + - Recursively taking a lock, when it is already held, is not avoided in this pattern + - Readers will learn to be suspicious of acquiring a lock in functions with lock required parameters. + - Designs with multiple locks, that must be careful to take them in the same order every time, are not helped + by this pattern. + - Locking the wrong object + - Use of a std::lock type that has not actually be secured yet (such as by std::try_to_lock or std::defer_lock) + - or use of a lock type that had been acquired but has since been released, reset, or otherwise unlocked + + These utility types are not fool-proof against all lock misuse, anti-patterns, or other complex yet valid + scenarios. However on the net, their usage in typical cases can assist in creating clearer, self-documenting + code that catches the common issues of forgetting to hold a lock or forgetting whether a lock is required to + call another method safely. + */ + struct write_lock_required; + + /** + Stands as proof that a shared lock has been acquired. See write_lock_required for more information. + */ + struct read_lock_required; + + namespace details + { + // Only those lock types specialized by lock_proof_traits will allow either a write_lock_required or + // read_lock_required to be constructed. The allows_exclusive value indicates if the type represents an exclusive, + // write-safe lock aquisition, or a shared, read-only lock acquisition. + template + struct lock_proof_traits { }; + + // Base for specializing lock_proof_traits where the lock type is shared + struct shared_lock_proof + { + static constexpr bool allows_shared = true; + }; + + // Base for specializing lock_proof_traits where the lock type is exclusive (super-set of shared_lock_proof) + struct exclusive_lock_proof : shared_lock_proof + { + static constexpr bool allows_exclusive = true; + }; + } + + struct write_lock_required + { + /** + Construct a new write_lock_required object for use as proof that an exclusive lock has been acquired. + */ + template + write_lock_required(const TLockProof&, wistd::enable_if_t::allows_exclusive, int> = 0) {} + + write_lock_required() = delete; // No default construction + }; + + struct read_lock_required + { + /** + Construct a new read_lock_required object for use as proof that a shared lock has been acquired. + */ + template + read_lock_required(const TLockProof&, wistd::enable_if_t::allows_shared, int> = 0) {} + + /** + Uses a prior write_lock_required object to construct a read_lock_required object as proof that at shared lock + has been acquired. (Exclusive locks held are presumed to suffice for proof of a read lock) + */ + read_lock_required(const write_lock_required&) {} + + read_lock_required() = delete; // No default construction + }; +#endif // __WIL_RESOURCE_LOCK_ENFORCEMENT + +#if defined(__WIL_WINBASE_) && !defined(__WIL__RESOURCE_LOCKPROOF_WINBASE) && defined(__WIL_RESOURCE_LOCK_ENFORCEMENT) +#define __WIL__RESOURCE_LOCKPROOF_WINBASE + + namespace details + { + // Specializations for srwlock + template<> + struct lock_proof_traits : shared_lock_proof {}; + + template<> + struct lock_proof_traits : exclusive_lock_proof {}; + + // Specialization for critical_section + template<> + struct lock_proof_traits : exclusive_lock_proof {}; + } + +#endif //__WIL__RESOURCE_LOCKPROOF_WINBASE + +#if defined(_MUTEX_) && !defined(__WIL__RESOURCE_LOCKPROOF_MUTEX) && defined(__WIL_RESOURCE_LOCK_ENFORCEMENT) +#define __WIL__RESOURCE_LOCKPROOF_MUTEX + + namespace details + { + template + struct lock_proof_traits> : exclusive_lock_proof {}; + + template + struct lock_proof_traits> : exclusive_lock_proof {}; + } + +#endif //__WIL__RESOURCE_LOCKPROOF_MUTEX + +#if defined(_SHARED_MUTEX_) && !defined(__WIL__RESOURCE_LOCKPROOF_SHAREDMUTEX) && defined(__WIL_RESOURCE_LOCK_ENFORCEMENT) +#define __WIL__RESOURCE_LOCKPROOF_SHAREDMUTEX + + namespace details + { + template + struct lock_proof_traits> : shared_lock_proof {}; + } + +#endif //__WIL__RESOURCE_LOCKPROOF_SHAREDMUTEX + +} // namespace wil + +#pragma warning(pop) diff --git a/libraries/wil/result.h b/libraries/wil/result.h new file mode 100644 index 0000000..d8b5f38 --- /dev/null +++ b/libraries/wil/result.h @@ -0,0 +1,1281 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_RESULT_INCLUDED +#define __WIL_RESULT_INCLUDED + +// Most functionality is picked up from result_macros.h. This file specifically provides higher level processing of errors when +// they are encountered by the underlying macros. +#include "result_macros.h" + +// Note that we avoid pulling in STL's memory header from Result.h through Resource.h as we have +// Result.h customers who are still on older versions of STL (without std::shared_ptr<>). +#ifndef RESOURCE_SUPPRESS_STL +#define RESOURCE_SUPPRESS_STL +#include "resource.h" +#undef RESOURCE_SUPPRESS_STL +#else +#include "resource.h" +#endif + +#ifdef WIL_KERNEL_MODE +#error This header is not supported in kernel-mode. +#endif + +// The updated behavior of running init-list ctors during placement new is proper & correct, disable the warning that requests developers verify they want it +#pragma warning(push) +#pragma warning(disable : 4351) + +namespace wil +{ + // WARNING: EVERYTHING in this namespace must be handled WITH CARE as the entities defined within + // are used as an in-proc ABI contract between binaries that utilize WIL. Making changes + // that add v-tables or change the storage semantics of anything herein needs to be done + // with care and respect to versioning. + ///@cond + namespace details_abi + { + #define __WI_SEMAHPORE_VERSION L"_p0" + + // This class uses named semaphores to be able to stash a numeric value (including a pointer + // for retrieval from within any module in a process). This is a very specific need of a + // header-based library that should not be generally used. + // + // Notes for use: + // * Data members must be stable unless __WI_SEMAHPORE_VERSION is changed + // * The class must not reference module code (v-table, function pointers, etc) + // * Use of this class REQUIRES that there be a MUTEX held around the semaphore manipulation + // and tests as it doesn't attempt to handle thread contention on the semaphore while manipulating + // the count. + // * This class supports storing a 31-bit number of a single semaphore or a 62-bit number across + // two semaphores and directly supports pointers. + + class SemaphoreValue + { + public: + SemaphoreValue() = default; + SemaphoreValue(const SemaphoreValue&) = delete; + SemaphoreValue& operator=(const SemaphoreValue&) = delete; + + SemaphoreValue(SemaphoreValue&& other) WI_NOEXCEPT : + m_semaphore(wistd::move(other.m_semaphore)), + m_semaphoreHigh(wistd::move(other.m_semaphoreHigh)) + { + static_assert(sizeof(m_semaphore) == sizeof(HANDLE), "unique_any must be a direct representation of the HANDLE to be used across module"); + } + + void Destroy() + { + m_semaphore.reset(); + m_semaphoreHigh.reset(); + } + + template + HRESULT CreateFromValue(PCWSTR name, T value) + { + return CreateFromValueInternal(name, (sizeof(value) > sizeof(unsigned long)), static_cast(value)); + } + + HRESULT CreateFromPointer(PCWSTR name, void* pointer) + { + ULONG_PTR value = reinterpret_cast(pointer); + FAIL_FAST_IMMEDIATE_IF(WI_IsAnyFlagSet(value, 0x3)); + return CreateFromValue(name, value >> 2); + } + + template + static HRESULT TryGetValue(PCWSTR name, _Out_ T* value, _Out_opt_ bool *retrieved = nullptr) + { + *value = static_cast(0); + unsigned __int64 value64 = 0; + __WIL_PRIVATE_RETURN_IF_FAILED(TryGetValueInternal(name, (sizeof(T) > sizeof(unsigned long)), &value64, retrieved)); + *value = static_cast(value64); + return S_OK; + } + + static HRESULT TryGetPointer(PCWSTR name, _Outptr_result_maybenull_ void** pointer) + { + *pointer = nullptr; + ULONG_PTR value = 0; + __WIL_PRIVATE_RETURN_IF_FAILED(TryGetValue(name, &value)); + *pointer = reinterpret_cast(value << 2); + return S_OK; + } + + private: + HRESULT CreateFromValueInternal(PCWSTR name, bool is64Bit, unsigned __int64 value) + { + WI_ASSERT(!m_semaphore && !m_semaphoreHigh); // call Destroy first + + // This routine only supports 31 bits when semahporeHigh is not supplied or 62 bits when the value + // is supplied. It's a programming error to use it when either of these conditions are not true. + + FAIL_FAST_IMMEDIATE_IF((!is64Bit && WI_IsAnyFlagSet(value, 0xFFFFFFFF80000000)) || + (is64Bit && WI_IsAnyFlagSet(value, 0xC000000000000000))); + + wchar_t localName[MAX_PATH]; + WI_VERIFY_SUCCEEDED(StringCchCopyW(localName, ARRAYSIZE(localName), name)); + WI_VERIFY_SUCCEEDED(StringCchCatW(localName, ARRAYSIZE(localName), __WI_SEMAHPORE_VERSION)); + + const unsigned long highPart = static_cast(value >> 31); + const unsigned long lowPart = static_cast(value & 0x000000007FFFFFFF); + + // We set the count of the semaphore equal to the max (the value we're storing). The only exception to that + // is ZERO, where you can't create a semaphore of value ZERO, where we push the max to one and use a count of ZERO. + + __WIL_PRIVATE_RETURN_IF_FAILED(m_semaphore.create(static_cast(lowPart), static_cast((lowPart > 0) ? lowPart : 1), localName)); + if (is64Bit) + { + WI_VERIFY_SUCCEEDED(StringCchCatW(localName, ARRAYSIZE(localName), L"h")); + __WIL_PRIVATE_RETURN_IF_FAILED(m_semaphoreHigh.create(static_cast(highPart), static_cast((highPart > 0) ? highPart : 1), localName)); + } + + return S_OK; + } + + static HRESULT GetValueFromSemaphore(HANDLE semaphore, _Out_ LONG* count) + { + // First we consume a single count from the semaphore. This will work in all cases other + // than the case where the count we've recorded is ZERO which will TIMEOUT. + + DWORD result = ::WaitForSingleObject(semaphore, 0); + __WIL_PRIVATE_RETURN_LAST_ERROR_IF(result == WAIT_FAILED); + __WIL_PRIVATE_RETURN_HR_IF(E_UNEXPECTED, !((result == WAIT_OBJECT_0) || (result == WAIT_TIMEOUT))); + + LONG value = 0; + if (result == WAIT_OBJECT_0) + { + // We were able to wait. To establish our count, all we have to do is release that count + // back to the semaphore and observe the value that we released. + + __WIL_PRIVATE_RETURN_IF_WIN32_BOOL_FALSE(::ReleaseSemaphore(semaphore, 1, &value)); + value++; // we waited first, so our actual value is one more than the old value + + // Make sure the value is correct by validating that we have no more posts. + BOOL expectedFailure = ::ReleaseSemaphore(semaphore, 1, nullptr); + __WIL_PRIVATE_RETURN_HR_IF(E_UNEXPECTED, expectedFailure || (::GetLastError() != ERROR_TOO_MANY_POSTS)); + } + else + { + WI_ASSERT(result == WAIT_TIMEOUT); + + // We know at this point that the value is ZERO. We'll do some verification to ensure that + // this address is right by validating that we have one and only one more post that we could use. + + LONG expected = 0; + __WIL_PRIVATE_RETURN_IF_WIN32_BOOL_FALSE(::ReleaseSemaphore(semaphore, 1, &expected)); + __WIL_PRIVATE_RETURN_HR_IF(E_UNEXPECTED, expected != 0); + + const BOOL expectedFailure = ::ReleaseSemaphore(semaphore, 1, nullptr); + __WIL_PRIVATE_RETURN_HR_IF(E_UNEXPECTED, expectedFailure || (::GetLastError() != ERROR_TOO_MANY_POSTS)); + + result = ::WaitForSingleObject(semaphore, 0); + __WIL_PRIVATE_RETURN_LAST_ERROR_IF(result == WAIT_FAILED); + __WIL_PRIVATE_RETURN_HR_IF(E_UNEXPECTED, result != WAIT_OBJECT_0); + } + + *count = value; + return S_OK; + } + + static HRESULT TryGetValueInternal(PCWSTR name, bool is64Bit, _Out_ unsigned __int64* value, _Out_opt_ bool* retrieved) + { + assign_to_opt_param(retrieved, false); + *value = 0; + + wchar_t localName[MAX_PATH]; + WI_VERIFY_SUCCEEDED(StringCchCopyW(localName, ARRAYSIZE(localName), name)); + WI_VERIFY_SUCCEEDED(StringCchCatW(localName, ARRAYSIZE(localName), __WI_SEMAHPORE_VERSION)); + + wil::unique_semaphore_nothrow semaphoreLow(::OpenSemaphoreW(SEMAPHORE_ALL_ACCESS, FALSE, localName)); + if (!semaphoreLow) + { + __WIL_PRIVATE_RETURN_HR_IF(S_OK, (::GetLastError() == ERROR_FILE_NOT_FOUND)); + __WIL_PRIVATE_RETURN_LAST_ERROR(); + } + + LONG countLow = 0; + LONG countHigh = 0; + + __WIL_PRIVATE_RETURN_IF_FAILED(GetValueFromSemaphore(semaphoreLow.get(), &countLow)); + + if (is64Bit) + { + WI_VERIFY_SUCCEEDED(StringCchCatW(localName, ARRAYSIZE(localName), L"h")); + wil::unique_semaphore_nothrow semaphoreHigh(::OpenSemaphoreW(SEMAPHORE_ALL_ACCESS, FALSE, localName)); + __WIL_PRIVATE_RETURN_LAST_ERROR_IF_NULL(semaphoreHigh); + + __WIL_PRIVATE_RETURN_IF_FAILED(GetValueFromSemaphore(semaphoreHigh.get(), &countHigh)); + } + + WI_ASSERT((countLow >= 0) && (countHigh >= 0)); + + const unsigned __int64 newValueHigh = (static_cast(countHigh) << 31); + const unsigned __int64 newValueLow = static_cast(countLow); + + assign_to_opt_param(retrieved, true); + *value = (newValueHigh | newValueLow); + return S_OK; + } + + wil::unique_semaphore_nothrow m_semaphore; + wil::unique_semaphore_nothrow m_semaphoreHigh; + }; + + template + class ProcessLocalStorageData + { + public: + ProcessLocalStorageData(unique_mutex_nothrow&& mutex, SemaphoreValue&& value) : + m_mutex(wistd::move(mutex)), + m_value(wistd::move(value)), + m_data() + { + static_assert(sizeof(m_mutex) == sizeof(HANDLE), "unique_any must be equivalent to the handle size to safely use across module"); + } + + T* GetData() + { + WI_ASSERT(m_mutex); + return &m_data; + } + + void Release() + { + if (ProcessShutdownInProgress()) + { + // There are no other threads to contend with. + m_refCount = m_refCount - 1; + if (m_refCount == 0) + { + m_data.ProcessShutdown(); + } + } + else + { + auto lock = m_mutex.acquire(); + m_refCount = m_refCount - 1; + if (m_refCount == 0) + { + // We must explicitly destroy our semaphores while holding the mutex + m_value.Destroy(); + lock.reset(); + + this->~ProcessLocalStorageData(); + ::HeapFree(::GetProcessHeap(), 0, this); + } + } + } + + static HRESULT Acquire(PCSTR staticNameWithVersion, _Outptr_result_nullonfailure_ ProcessLocalStorageData** data) + { + *data = nullptr; + + // NOTE: the '0' in SM0 below is intended as the VERSION number. Changes to this class require + // that this value be revised. + + const DWORD size = static_cast(sizeof(ProcessLocalStorageData)); + wchar_t name[MAX_PATH]; + WI_VERIFY(SUCCEEDED(StringCchPrintfW(name, ARRAYSIZE(name), L"Local\\SM0:%lu:%lu:%hs", ::GetCurrentProcessId(), size, staticNameWithVersion))); + + unique_mutex_nothrow mutex; + mutex.reset(::CreateMutexExW(nullptr, name, 0, MUTEX_ALL_ACCESS)); + + // This will fail in some environments and will be fixed with deliverable 12394134 + RETURN_LAST_ERROR_IF_EXPECTED(!mutex); + auto lock = mutex.acquire(); + + void* pointer = nullptr; + __WIL_PRIVATE_RETURN_IF_FAILED(SemaphoreValue::TryGetPointer(name, &pointer)); + if (pointer) + { + *data = reinterpret_cast*>(pointer); + (*data)->m_refCount = (*data)->m_refCount + 1; + } + else + { + __WIL_PRIVATE_RETURN_IF_FAILED(MakeAndInitialize(name, wistd::move(mutex), data)); // Assumes mutex handle ownership on success ('lock' will still be released) + } + + return S_OK; + } + + private: + + volatile long m_refCount = 1; + unique_mutex_nothrow m_mutex; + SemaphoreValue m_value; + T m_data; + + static HRESULT MakeAndInitialize(PCWSTR name, unique_mutex_nothrow&& mutex, _Outptr_result_nullonfailure_ ProcessLocalStorageData** data) + { + *data = nullptr; + + const DWORD size = static_cast(sizeof(ProcessLocalStorageData)); + + unique_process_heap_ptr> dataAlloc(static_cast*>(details::ProcessHeapAlloc(HEAP_ZERO_MEMORY, size))); + __WIL_PRIVATE_RETURN_IF_NULL_ALLOC(dataAlloc); + + SemaphoreValue semaphoreValue; + __WIL_PRIVATE_RETURN_IF_FAILED(semaphoreValue.CreateFromPointer(name, dataAlloc.get())); + + new(dataAlloc.get()) ProcessLocalStorageData(wistd::move(mutex), wistd::move(semaphoreValue)); + *data = dataAlloc.release(); + + return S_OK; + } + }; + + template + class ProcessLocalStorage + { + public: + ProcessLocalStorage(PCSTR staticNameWithVersion) WI_NOEXCEPT : + m_staticNameWithVersion(staticNameWithVersion) + { + } + + ~ProcessLocalStorage() WI_NOEXCEPT + { + if (m_data) + { + m_data->Release(); + } + } + + T* GetShared() WI_NOEXCEPT + { + if (!m_data) + { + ProcessLocalStorageData* localTemp = nullptr; + if (SUCCEEDED(ProcessLocalStorageData::Acquire(m_staticNameWithVersion, &localTemp)) && !m_data) + { + m_data = localTemp; + } + } + return m_data ? m_data->GetData() : nullptr; + } + + private: + PCSTR m_staticNameWithVersion = nullptr; + ProcessLocalStorageData* m_data = nullptr; + }; + + template + class ThreadLocalStorage + { + public: + ThreadLocalStorage(const ThreadLocalStorage&) = delete; + ThreadLocalStorage& operator=(const ThreadLocalStorage&) = delete; + + ThreadLocalStorage() = default; + + ~ThreadLocalStorage() WI_NOEXCEPT + { + for (auto &entry : m_hashArray) + { + Node *pNode = entry; + while (pNode != nullptr) + { + auto pCurrent = pNode; +#pragma warning(push) +#pragma warning(disable:6001) // https://github.com/microsoft/wil/issues/164 + pNode = pNode->pNext; +#pragma warning(pop) + pCurrent->~Node(); + ::HeapFree(::GetProcessHeap(), 0, pCurrent); + } + entry = nullptr; + } + } + + // Note: Can return nullptr even when (shouldAllocate == true) upon allocation failure + T* GetLocal(bool shouldAllocate = false) WI_NOEXCEPT + { + DWORD const threadId = ::GetCurrentThreadId(); + size_t const index = (threadId % ARRAYSIZE(m_hashArray)); + for (auto pNode = m_hashArray[index]; pNode != nullptr; pNode = pNode->pNext) + { + if (pNode->threadId == threadId) + { + return &pNode->value; + } + } + + if (shouldAllocate) + { + if (auto pNewRaw = details::ProcessHeapAlloc(0, sizeof(Node))) + { + auto pNew = new (pNewRaw) Node{ threadId }; + + Node *pFirst; + do + { + pFirst = m_hashArray[index]; + pNew->pNext = pFirst; + } while (::InterlockedCompareExchangePointer(reinterpret_cast(m_hashArray + index), pNew, pFirst) != pFirst); + + return &pNew->value; + } + } + return nullptr; + } + + private: + + struct Node + { + DWORD threadId = ULONG_MAX; + Node* pNext = nullptr; + T value{}; + }; + + Node * volatile m_hashArray[10]{}; + }; + + struct ThreadLocalFailureInfo + { + // ABI contract (carry size to facilitate additive change without re-versioning) + unsigned short size; + unsigned char reserved1[2]; // packing, reserved + // When this failure was seen + unsigned int sequenceId; + + // Information about the failure + HRESULT hr; + PCSTR fileName; + unsigned short lineNumber; + unsigned char failureType; // FailureType + unsigned char reserved2; // packing, reserved + PCSTR modulePath; + void* returnAddress; + void* callerReturnAddress; + PCWSTR message; + + // The allocation (LocalAlloc) where structure strings point + void* stringBuffer; + size_t stringBufferSize; + + // NOTE: Externally Managed: Must not have constructor or destructor + + void Clear() + { + ::HeapFree(::GetProcessHeap(), 0, stringBuffer); + stringBuffer = nullptr; + stringBufferSize = 0; + } + + void Set(const FailureInfo& info, unsigned int newSequenceId) + { + sequenceId = newSequenceId; + + hr = info.hr; + fileName = nullptr; + lineNumber = static_cast(info.uLineNumber); + failureType = static_cast(info.type); + modulePath = nullptr; + returnAddress = info.returnAddress; + callerReturnAddress = info.callerReturnAddress; + message = nullptr; + + size_t neededSize = details::ResultStringSize(info.pszFile) + + details::ResultStringSize(info.pszModule) + + details::ResultStringSize(info.pszMessage); + + if (!stringBuffer || (stringBufferSize < neededSize)) + { + auto newBuffer = details::ProcessHeapAlloc(HEAP_ZERO_MEMORY, neededSize); + if (newBuffer) + { + ::HeapFree(::GetProcessHeap(), 0, stringBuffer); + stringBuffer = newBuffer; + stringBufferSize = neededSize; + } + } + + if (stringBuffer) + { + unsigned char *pBuffer = static_cast(stringBuffer); + unsigned char *pBufferEnd = pBuffer + stringBufferSize; + + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, info.pszFile, &fileName); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, info.pszModule, &modulePath); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, info.pszMessage, &message); + ZeroMemory(pBuffer, pBufferEnd - pBuffer); + } + } + + void Get(FailureInfo& info) const + { + ::ZeroMemory(&info, sizeof(info)); + + info.failureId = sequenceId; + info.hr = hr; + info.pszFile = fileName; + info.uLineNumber = lineNumber; + info.type = static_cast(failureType); + info.pszModule = modulePath; + info.returnAddress = returnAddress; + info.callerReturnAddress = callerReturnAddress; + info.pszMessage = message; + } + }; + + struct ThreadLocalData + { + // ABI contract (carry size to facilitate additive change without re-versioning) + unsigned short size = sizeof(ThreadLocalData); + + // Subscription information + unsigned int threadId = 0; + volatile long* failureSequenceId = nullptr; // backpointer to the global ID + + // Information about thread errors + unsigned int latestSubscribedFailureSequenceId = 0; + + // The last (N) observed errors + ThreadLocalFailureInfo* errors = nullptr; + unsigned short errorAllocCount = 0; + unsigned short errorCurrentIndex = 0; + + // NOTE: Externally Managed: Must allow ZERO init construction + + ~ThreadLocalData() + { + Clear(); + } + + void Clear() + { + for (auto& error : make_range(errors, errorAllocCount)) + { + error.Clear(); + } + ::HeapFree(::GetProcessHeap(), 0, errors); + errorAllocCount = 0; + errorCurrentIndex = 0; + errors = nullptr; + } + + bool EnsureAllocated(bool create = true) + { + if (!errors && create) + { + const unsigned short errorCount = 5; + errors = reinterpret_cast(details::ProcessHeapAlloc(HEAP_ZERO_MEMORY, errorCount * sizeof(ThreadLocalFailureInfo))); + if (errors) + { + errorAllocCount = errorCount; + errorCurrentIndex = 0; + for (auto& error : make_range(errors, errorAllocCount)) + { + error.size = sizeof(ThreadLocalFailureInfo); + } + } + } + return (errors != nullptr); + } + + void SetLastError(const wil::FailureInfo& info) + { + const bool hasListener = (latestSubscribedFailureSequenceId > 0); + + if (!EnsureAllocated(hasListener)) + { + // We either couldn't allocate or we haven't yet allocated and nobody + // was listening, so we ignore. + return; + } + + if (hasListener) + { + // When we have listeners, we can throw away any updates to the last seen error + // code within the same listening context presuming it's an update of the existing + // error with the same code. + + for (auto& error : make_range(errors, errorAllocCount)) + { + if ((error.sequenceId > latestSubscribedFailureSequenceId) && (error.hr == info.hr)) + { + return; + } + } + } + + // Otherwise we create a new failure... + + errorCurrentIndex = (errorCurrentIndex + 1) % errorAllocCount; + errors[errorCurrentIndex].Set(info, ::InterlockedIncrementNoFence(failureSequenceId)); + } + + WI_NODISCARD bool GetLastError(_Inout_ wil::FailureInfo& info, unsigned int minSequenceId, HRESULT matchRequirement) const + { + if (!errors) + { + return false; + } + + // If the last error we saw doesn't meet the filter requirement or if the last error was never + // set, then we couldn't return a result at all... + auto& lastFailure = errors[errorCurrentIndex]; + if (minSequenceId >= lastFailure.sequenceId) + { + return false; + } + + // With no result filter, we just go to the last error and report it + if (matchRequirement == S_OK) + { + lastFailure.Get(info); + return true; + } + + // Find the oldest result matching matchRequirement and passing minSequenceId + ThreadLocalFailureInfo* find = nullptr; + for (auto& error : make_range(errors, errorAllocCount)) + { + if ((error.hr == matchRequirement) && (error.sequenceId > minSequenceId)) + { + if (!find || (error.sequenceId < find->sequenceId)) + { + find = &error; + } + } + } + if (find) + { + find->Get(info); + return true; + } + + return false; + } + + bool GetCaughtExceptionError(_Inout_ wil::FailureInfo& info, unsigned int minSequenceId, _In_opt_ const DiagnosticsInfo* diagnostics, HRESULT matchRequirement, void* returnAddress) + { + // First attempt to get the last error and then see if it matches the error returned from + // the last caught exception. If it does, then we're good to go and we return that last error. + + FailureInfo last = {}; + if (GetLastError(last, minSequenceId, matchRequirement) && (last.hr == ResultFromCaughtException())) + { + info = last; + return true; + } + + // The last error didn't match or we never had one... we need to create one -- we do so by logging + // our current request and then using the last error. + + DiagnosticsInfo source; + if (diagnostics) + { + source = *diagnostics; + } + + // NOTE: FailureType::Log as it's only informative (no action) and SupportedExceptions::All as it's not a barrier, only recognition. + wchar_t message[2048]{}; + message[0] = L'\0'; + const HRESULT hr = details::ReportFailure_CaughtExceptionCommon(__R_DIAGNOSTICS_RA(source, returnAddress), message, ARRAYSIZE(message), SupportedExceptions::All).hr; + + // Now that the exception was logged, we should be able to fetch it. + return GetLastError(info, minSequenceId, hr); + } + }; + + struct ProcessLocalData + { + // ABI contract (carry size to facilitate additive change without re-versioning) + unsigned short size = sizeof(ProcessLocalData); + + // Failure Information + volatile long failureSequenceId = 1; // process global variable + ThreadLocalStorage threads; // list of allocated threads + + void ProcessShutdown() {} + }; + + __declspec(selectany) ProcessLocalStorage* g_pProcessLocalData = nullptr; + + __declspec(noinline) inline ThreadLocalData* GetThreadLocalDataCache(bool allocate = true) + { + ThreadLocalData* result = nullptr; + if (g_pProcessLocalData) + { + auto processData = g_pProcessLocalData->GetShared(); + if (processData) + { + result = processData->threads.GetLocal(allocate); + if (result && !result->failureSequenceId) + { + result->failureSequenceId = &(processData->failureSequenceId); + } + } + } + return result; + } + + __forceinline ThreadLocalData* GetThreadLocalData(bool allocate = true) + { + return GetThreadLocalDataCache(allocate); + } + + } // details_abi + /// @endcond + + + /** Returns a sequence token that can be used with wil::GetLastError to limit errors to those that occur after this token was retrieved. + General usage pattern: use wil::GetCurrentErrorSequenceId to cache a token, execute your code, on failure use wil::GetLastError with the token + to provide information on the error that occurred while executing your code. Prefer to use wil::ThreadErrorContext over this approach when + possible. */ + inline long GetCurrentErrorSequenceId() + { + auto data = details_abi::GetThreadLocalData(); + if (data) + { + // someone is interested -- make sure we can store errors + data->EnsureAllocated(); + return *data->failureSequenceId; + } + + return 0; + } + + /** Caches failure information for later retrieval from GetLastError. + Most people will never need to do this explicitly as failure information is automatically made available per-thread across a process when + errors are encountered naturally through the WIL macros. */ + inline void SetLastError(const wil::FailureInfo& info) + { + static volatile unsigned int lastThread = 0; + auto threadId = ::GetCurrentThreadId(); + if (lastThread != threadId) + { + static volatile long depth = 0; + if (::InterlockedIncrementNoFence(&depth) < 4) + { + lastThread = threadId; + auto data = details_abi::GetThreadLocalData(false); // false = avoids allocation if not already present + if (data) + { + data->SetLastError(info); + } + lastThread = 0; + } + ::InterlockedDecrementNoFence(&depth); + } + } + + /** Retrieves failure information for the current thread with the given filters. + This API can be used to retrieve information about the last WIL failure that occurred on the current thread. + This error crosses DLL boundaries as long as the error occurred in the current process. Passing a minSequenceId + restricts the error returned to one that occurred after the given sequence ID. Passing matchRequirement also filters + the returned result to the given error code. */ + inline bool GetLastError(_Inout_ wil::FailureInfo& info, unsigned int minSequenceId = 0, HRESULT matchRequirement = S_OK) + { + auto data = details_abi::GetThreadLocalData(false); // false = avoids allocation if not already present + if (data) + { + return data->GetLastError(info, minSequenceId, matchRequirement); + } + return false; + } + + /** Retrieves failure information when within a catch block for the current thread with the given filters. + When unable to retrieve the exception information (when WIL hasn't yet seen it), this will attempt (best effort) to + discover information about the exception and will attribute that information to the given DiagnosticsInfo position. + See GetLastError for capabilities and filtering. */ + inline __declspec(noinline) bool GetCaughtExceptionError(_Inout_ wil::FailureInfo& info, unsigned int minSequenceId = 0, const DiagnosticsInfo* diagnostics = nullptr, HRESULT matchRequirement = S_OK) + { + auto data = details_abi::GetThreadLocalData(); + if (data) + { + return data->GetCaughtExceptionError(info, minSequenceId, diagnostics, matchRequirement, _ReturnAddress()); + } + return false; + } + + /** Use this class to manage retrieval of information about an error occurring in the requested code. + Construction of this class sets a point in time after which you can use the GetLastError class method to retrieve + the origination of the last error that occurred on this thread since the class was created. */ + class ThreadErrorContext + { + public: + ThreadErrorContext() : + m_data(details_abi::GetThreadLocalData()) + { + if (m_data) + { + m_sequenceIdLast = m_data->latestSubscribedFailureSequenceId; + m_sequenceIdStart = *m_data->failureSequenceId; + m_data->latestSubscribedFailureSequenceId = m_sequenceIdStart; + } + } + + ~ThreadErrorContext() + { + if (m_data) + { + m_data->latestSubscribedFailureSequenceId = m_sequenceIdLast; + } + } + + /** Retrieves the origination of the last error that occurred since this class was constructed. + The optional parameter allows the failure information returned to be filtered to a specific + result. */ + inline bool GetLastError(FailureInfo& info, HRESULT matchRequirement = S_OK) + { + if (m_data) + { + return m_data->GetLastError(info, m_sequenceIdStart, matchRequirement); + } + return false; + } + + /** Retrieves the origin of the current exception (within a catch block) since this class was constructed. + See @ref GetCaughtExceptionError for more information */ + inline __declspec(noinline) bool GetCaughtExceptionError(_Inout_ wil::FailureInfo& info, const DiagnosticsInfo* diagnostics = nullptr, HRESULT matchRequirement = S_OK) + { + if (m_data) + { + return m_data->GetCaughtExceptionError(info, m_sequenceIdStart, diagnostics, matchRequirement, _ReturnAddress()); + } + return false; + } + + private: + details_abi::ThreadLocalData* m_data; + unsigned long m_sequenceIdStart{}; + unsigned long m_sequenceIdLast{}; + }; + + + enum class WilInitializeCommand + { + Create, + Destroy, + }; + + + /// @cond + namespace details + { + struct IFailureCallback + { + virtual bool NotifyFailure(FailureInfo const &failure) WI_NOEXCEPT = 0; + }; + + class ThreadFailureCallbackHolder; + + __declspec(selectany) details_abi::ThreadLocalStorage* g_pThreadFailureCallbacks = nullptr; + + class ThreadFailureCallbackHolder + { + public: + ThreadFailureCallbackHolder(_In_opt_ IFailureCallback *pCallbackParam, _In_opt_ CallContextInfo *pCallContext = nullptr, bool watchNow = true) WI_NOEXCEPT : + m_ppThreadList(nullptr), + m_pCallback(pCallbackParam), + m_pNext(nullptr), + m_threadId(0), + m_pCallContext(pCallContext) + { + if (watchNow) + { + StartWatching(); + } + } + + ThreadFailureCallbackHolder(ThreadFailureCallbackHolder &&other) WI_NOEXCEPT : + m_ppThreadList(nullptr), + m_pCallback(other.m_pCallback), + m_pNext(nullptr), + m_threadId(0), + m_pCallContext(other.m_pCallContext) + { + if (other.m_threadId != 0) + { + other.StopWatching(); + StartWatching(); + } + } + + ~ThreadFailureCallbackHolder() WI_NOEXCEPT + { + if (m_threadId != 0) + { + StopWatching(); + } + } + + void SetCallContext(_In_opt_ CallContextInfo *pCallContext) + { + m_pCallContext = pCallContext; + } + + CallContextInfo *CallContextInfo() + { + return m_pCallContext; + } + + void StartWatching() + { + // out-of balance Start/Stop calls? + __FAIL_FAST_IMMEDIATE_ASSERT__(m_threadId == 0); + + m_ppThreadList = g_pThreadFailureCallbacks ? g_pThreadFailureCallbacks->GetLocal(true) : nullptr; // true = allocate thread list if missing + if (m_ppThreadList) + { + m_pNext = *m_ppThreadList; + *m_ppThreadList = this; + m_threadId = ::GetCurrentThreadId(); + } + } + + void StopWatching() + { + if (m_threadId != ::GetCurrentThreadId()) + { + // The thread-specific failure holder cannot be stopped on a different thread than it was started on or the + // internal book-keeping list will be corrupted. To fix this change the telemetry pattern in the calling code + // to match one of the patterns available here: + // https://microsoft.sharepoint.com/teams/osg_development/Shared%20Documents/Windows%20TraceLogging%20Helpers.docx + + WI_USAGE_ERROR("MEMORY CORRUPTION: Calling code is leaking an activity thread-watcher and releasing it on another thread"); + } + + m_threadId = 0; + + while (*m_ppThreadList != nullptr) + { + if (*m_ppThreadList == this) + { + *m_ppThreadList = m_pNext; + break; + } + m_ppThreadList = &((*m_ppThreadList)->m_pNext); + } + m_ppThreadList = nullptr; + } + + WI_NODISCARD bool IsWatching() const + { + return (m_threadId != 0); + } + + void SetWatching(bool shouldWatch) + { + if (shouldWatch && !IsWatching()) + { + StartWatching(); + } + else if (!shouldWatch && IsWatching()) + { + StopWatching(); + } + } + + static bool GetThreadContext(_Inout_ FailureInfo *pFailure, _In_opt_ ThreadFailureCallbackHolder *pCallback, _Out_writes_(callContextStringLength) _Post_z_ PSTR callContextString, _Pre_satisfies_(callContextStringLength > 0) size_t callContextStringLength) + { + *callContextString = '\0'; + bool foundContext = false; + if (pCallback != nullptr) + { + foundContext = GetThreadContext(pFailure, pCallback->m_pNext, callContextString, callContextStringLength); + + if (pCallback->m_pCallContext != nullptr) + { + auto &context = *pCallback->m_pCallContext; + + // We generate the next telemetry ID only when we've found an error (avoid always incrementing) + if (context.contextId == 0) + { + context.contextId = ::InterlockedIncrementNoFence(&s_telemetryId); + } + + if (pFailure->callContextOriginating.contextId == 0) + { + pFailure->callContextOriginating = context; + } + + pFailure->callContextCurrent = context; + + auto callContextStringEnd = callContextString + callContextStringLength; + callContextString += strlen(callContextString); + + if ((callContextStringEnd - callContextString) > 2) // room for at least the slash + null + { + *callContextString++ = '\\'; + auto nameSizeBytes = strlen(context.contextName) + 1; + size_t remainingBytes = static_cast(callContextStringEnd - callContextString); + auto copyBytes = (nameSizeBytes < remainingBytes) ? nameSizeBytes : remainingBytes; + memcpy_s(callContextString, remainingBytes, context.contextName, copyBytes); + *(callContextString + (copyBytes - 1)) = '\0'; + } + + return true; + } + } + return foundContext; + } + + static void GetContextAndNotifyFailure(_Inout_ FailureInfo *pFailure, _Out_writes_(callContextStringLength) _Post_z_ PSTR callContextString, _Pre_satisfies_(callContextStringLength > 0) size_t callContextStringLength) WI_NOEXCEPT + { + *callContextString = '\0'; + bool reportedTelemetry = false; + + ThreadFailureCallbackHolder **ppListeners = g_pThreadFailureCallbacks ? g_pThreadFailureCallbacks->GetLocal() : nullptr; + if ((ppListeners != nullptr) && (*ppListeners != nullptr)) + { + callContextString[0] = '\0'; + if (GetThreadContext(pFailure, *ppListeners, callContextString, callContextStringLength)) + { + pFailure->pszCallContext = callContextString; + } + + auto pNode = *ppListeners; + do + { + reportedTelemetry |= pNode->m_pCallback->NotifyFailure(*pFailure); + pNode = pNode->m_pNext; + } + while (pNode != nullptr); + } + + if (g_pfnTelemetryCallback != nullptr) + { + // If the telemetry was requested to be suppressed, + // pretend like it has already been reported to the fallback callback + g_pfnTelemetryCallback(reportedTelemetry || WI_IsFlagSet(pFailure->flags, FailureFlags::RequestSuppressTelemetry), *pFailure); + } + } + + ThreadFailureCallbackHolder(ThreadFailureCallbackHolder const &) = delete; + ThreadFailureCallbackHolder& operator=(ThreadFailureCallbackHolder const &) = delete; + + private: + static long volatile s_telemetryId; + + ThreadFailureCallbackHolder **m_ppThreadList; + IFailureCallback *m_pCallback; + ThreadFailureCallbackHolder *m_pNext; + DWORD m_threadId; + wil::CallContextInfo *m_pCallContext; + }; + + __declspec(selectany) long volatile ThreadFailureCallbackHolder::s_telemetryId = 1; + + template + class ThreadFailureCallbackFn final : public IFailureCallback + { + public: + explicit ThreadFailureCallbackFn(_In_opt_ CallContextInfo *pContext, _Inout_ TLambda &&errorFunction) WI_NOEXCEPT : + m_errorFunction(wistd::move(errorFunction)), + m_callbackHolder(this, pContext) + { + } + + ThreadFailureCallbackFn(_Inout_ ThreadFailureCallbackFn && other) WI_NOEXCEPT : + m_errorFunction(wistd::move(other.m_errorFunction)), + m_callbackHolder(this, other.m_callbackHolder.CallContextInfo()) + { + } + + bool NotifyFailure(FailureInfo const &failure) WI_NOEXCEPT override + { + return m_errorFunction(failure); + } + + private: + ThreadFailureCallbackFn(_In_ ThreadFailureCallbackFn const &); + ThreadFailureCallbackFn & operator=(_In_ ThreadFailureCallbackFn const &); + + TLambda m_errorFunction; + ThreadFailureCallbackHolder m_callbackHolder; + }; + + + // returns true if telemetry was reported for this error + inline void __stdcall GetContextAndNotifyFailure(_Inout_ FailureInfo *pFailure, _Out_writes_(callContextStringLength) _Post_z_ PSTR callContextString, _Pre_satisfies_(callContextStringLength > 0) size_t callContextStringLength) WI_NOEXCEPT + { + ThreadFailureCallbackHolder::GetContextAndNotifyFailure(pFailure, callContextString, callContextStringLength); + + // Update the process-wide failure cache + wil::SetLastError(*pFailure); + } + + template void InitGlobalWithStorage(WilInitializeCommand state, void* storage, T*& global, TCtorArgs&&... args) + { + if ((state == WilInitializeCommand::Create) && !global) + { + global = ::new (storage) T(wistd::forward(args)...); + } + else if ((state == WilInitializeCommand::Destroy) && global) + { + global->~T(); + global = nullptr; + } + } + } + /// @endcond + + /** Modules that cannot use CRT-based static initialization may call this method from their entrypoint + instead. Disable the use of CRT-based initializers by defining RESULT_SUPPRESS_STATIC_INITIALIZERS + while compiling this header. Linking together libraries that disagree on this setting and calling + this method will behave correctly. It may be necessary to recompile all statically linked libraries + with the RESULT_SUPPRESS_... setting to eliminate all "LNK4201 - CRT section exists, but..." errors. + */ + inline void WilInitialize_Result(WilInitializeCommand state) + { + static unsigned char s_processLocalData[sizeof(*details_abi::g_pProcessLocalData)]; + static unsigned char s_threadFailureCallbacks[sizeof(*details::g_pThreadFailureCallbacks)]; + + details::InitGlobalWithStorage(state, s_processLocalData, details_abi::g_pProcessLocalData, "WilError_03"); + details::InitGlobalWithStorage(state, s_threadFailureCallbacks, details::g_pThreadFailureCallbacks); + + if (state == WilInitializeCommand::Create) + { + details::g_pfnGetContextAndNotifyFailure = details::GetContextAndNotifyFailure; + } + } + + /// @cond + namespace details + { +#ifndef RESULT_SUPPRESS_STATIC_INITIALIZERS + __declspec(selectany) ::wil::details_abi::ProcessLocalStorage<::wil::details_abi::ProcessLocalData> g_processLocalData("WilError_03"); + __declspec(selectany) ::wil::details_abi::ThreadLocalStorage g_threadFailureCallbacks; + + WI_HEADER_INITITALIZATION_FUNCTION(InitializeResultHeader, [] + { + g_pfnGetContextAndNotifyFailure = GetContextAndNotifyFailure; + ::wil::details_abi::g_pProcessLocalData = &g_processLocalData; + g_pThreadFailureCallbacks = &g_threadFailureCallbacks; + return 1; + }); +#endif + } + /// @endcond + + + // This helper functions much like scope_exit -- give it a lambda and get back a local object that can be used to + // catch all errors happening in your module through all WIL error handling mechanisms. The lambda will be called + // once for each error throw, error return, or error catch that is handled while the returned object is still in + // scope. Usage: + // + // auto monitor = wil::ThreadFailureCallback([](wil::FailureInfo const &failure) + // { + // // Write your code that logs or cares about failure details here... + // // It has access to HRESULT, filename, line number, etc through the failure param. + // }); + // + // As long as the returned 'monitor' object remains in scope, the lambda will continue to receive callbacks for any + // failures that occur in this module on the calling thread. Note that this will guarantee that the lambda will run + // for any failure that is through any of the WIL macros (THROW_XXX, RETURN_XXX, LOG_XXX, etc). + + template + inline wil::details::ThreadFailureCallbackFn ThreadFailureCallback(_Inout_ TLambda &&fnAtExit) WI_NOEXCEPT + { + return wil::details::ThreadFailureCallbackFn(nullptr, wistd::forward(fnAtExit)); + } + + + // Much like ThreadFailureCallback, this class will receive WIL failure notifications from the time it's instantiated + // until the time that it's destroyed. At any point during that time you can ask for the last failure that was seen + // by any of the WIL macros (RETURN_XXX, THROW_XXX, LOG_XXX, etc) on the current thread. + // + // This class is most useful when utilized as a member of an RAII class that's dedicated to providing logging or + // telemetry. In the destructor of that class, if the operation had not been completed successfully (it goes out of + // scope due to early return or exception unwind before success is acknowledged) then details about the last failure + // can be retrieved and appropriately logged. + // + // Usage: + // + // class MyLogger + // { + // public: + // MyLogger() : m_fComplete(false) {} + // ~MyLogger() + // { + // if (!m_fComplete) + // { + // FailureInfo *pFailure = m_cache.GetFailure(); + // if (pFailure != nullptr) + // { + // // Log information about pFailure (pFileure->hr, pFailure->pszFile, pFailure->uLineNumber, etc) + // } + // else + // { + // // It's possible that you get stack unwind from an exception that did NOT come through WIL + // // like (std::bad_alloc from the STL). Use a reasonable default like: HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION). + // } + // } + // } + // void Complete() { m_fComplete = true; } + // private: + // bool m_fComplete; + // ThreadFailureCache m_cache; + // }; + + class ThreadFailureCache final : + public details::IFailureCallback + { + public: + ThreadFailureCache() : + m_callbackHolder(this) + { + } + + ThreadFailureCache(ThreadFailureCache && rhs) WI_NOEXCEPT : + m_failure(wistd::move(rhs.m_failure)), + m_callbackHolder(this) + { + } + + ThreadFailureCache& operator=(ThreadFailureCache && rhs) WI_NOEXCEPT + { + m_failure = wistd::move(rhs.m_failure); + return *this; + } + + void WatchCurrentThread() + { + m_callbackHolder.StartWatching(); + } + + void IgnoreCurrentThread() + { + m_callbackHolder.StopWatching(); + } + + FailureInfo const* GetFailure() + { + return (FAILED(m_failure.GetFailureInfo().hr) ? &(m_failure.GetFailureInfo()) : nullptr); + } + + bool NotifyFailure(FailureInfo const& failure) WI_NOEXCEPT override + { + // When we "cache" a failure, we bias towards trying to find the origin of the last HRESULT + // generated, so we ignore subsequent failures on the same error code (assuming propagation). + + if (failure.hr != m_failure.GetFailureInfo().hr) + { + m_failure.SetFailureInfo(failure); + } + return false; + } + + private: + StoredFailureInfo m_failure; + details::ThreadFailureCallbackHolder m_callbackHolder; + }; + +} // wil + +#pragma warning(pop) + +#endif diff --git a/libraries/wil/result_macros.h b/libraries/wil/result_macros.h new file mode 100644 index 0000000..3d48aa9 --- /dev/null +++ b/libraries/wil/result_macros.h @@ -0,0 +1,6156 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_RESULTMACROS_INCLUDED +#define __WIL_RESULTMACROS_INCLUDED + +// WARNING: +// Code within this scope must satisfy both C99 and C++ + +#include "common.h" + +#if !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) +#include +#endif + +// Setup the debug behavior. For kernel-mode, we ignore NDEBUG because that gets set automatically +// for driver projects. We mimic the behavior of NT_ASSERT which checks only for DBG. +// RESULT_NO_DEBUG is provided as an opt-out mechanism. +#ifndef RESULT_DEBUG +#if (DBG || defined(DEBUG) || defined(_DEBUG)) && !defined(RESULT_NO_DEBUG) && (defined(WIL_KERNEL_MODE) || !defined(NDEBUG)) +#define RESULT_DEBUG +#endif +#endif + +/// @cond +#if defined(_PREFAST_) +#define __WI_ANALYSIS_ASSUME(_exp) _Analysis_assume_(_exp) +#else +#ifdef RESULT_DEBUG +#define __WI_ANALYSIS_ASSUME(_exp) ((void) 0) +#else +// NOTE: Clang does not currently handle __noop correctly and will fail to compile if the argument is not copy +// constructible. Therefore, use 'sizeof' for syntax validation. We don't do this universally for all compilers +// since lambdas are not allowed in unevaluated contexts prior to C++20, which does not appear to affect __noop +#if !defined(_MSC_VER) || defined(__clang__) +#define __WI_ANALYSIS_ASSUME(_exp) ((void)sizeof(!(_exp))) // Validate syntax on non-debug builds +#else +#define __WI_ANALYSIS_ASSUME(_exp) __noop(_exp) +#endif +#endif +#endif // _PREFAST_ + +//***************************************************************************** +// Assert Macros +//***************************************************************************** + +#ifdef RESULT_DEBUG +#if defined(__clang__) && defined(_WIN32) +// Clang currently mis-handles '__annotation' for 32-bit - https://bugs.llvm.org/show_bug.cgi?id=41890 +#define __WI_ASSERT_FAIL_ANNOTATION(msg) (void)0 +#else +#define __WI_ASSERT_FAIL_ANNOTATION(msg) __annotation(L"Debug", L"AssertFail", msg) +#endif + +#define WI_ASSERT(condition) (__WI_ANALYSIS_ASSUME(condition), ((!(condition)) ? (__WI_ASSERT_FAIL_ANNOTATION(L"" #condition), DbgRaiseAssertionFailure(), FALSE) : TRUE)) +#define WI_ASSERT_MSG(condition, msg) (__WI_ANALYSIS_ASSUME(condition), ((!(condition)) ? (__WI_ASSERT_FAIL_ANNOTATION(L##msg), DbgRaiseAssertionFailure(), FALSE) : TRUE)) +#define WI_ASSERT_NOASSUME WI_ASSERT +#define WI_ASSERT_MSG_NOASSUME WI_ASSERT_MSG +#define WI_VERIFY WI_ASSERT +#define WI_VERIFY_MSG WI_ASSERT_MSG +#define WI_VERIFY_SUCCEEDED(condition) WI_ASSERT(SUCCEEDED(condition)) +#else +#define WI_ASSERT(condition) (__WI_ANALYSIS_ASSUME(condition), 0) +#define WI_ASSERT_MSG(condition, msg) (__WI_ANALYSIS_ASSUME(condition), 0) +#define WI_ASSERT_NOASSUME(condition) ((void) 0) +#define WI_ASSERT_MSG_NOASSUME(condition, msg) ((void) 0) +#define WI_VERIFY(condition) (__WI_ANALYSIS_ASSUME(condition), ((condition) ? TRUE : FALSE)) +#define WI_VERIFY_MSG(condition, msg) (__WI_ANALYSIS_ASSUME(condition), ((condition) ? TRUE : FALSE)) +#define WI_VERIFY_SUCCEEDED(condition) (__WI_ANALYSIS_ASSUME(SUCCEEDED(condition)), ((SUCCEEDED(condition)) ? TRUE : FALSE)) +#endif // RESULT_DEBUG + +#if !defined(_NTDEF_) +typedef _Return_type_success_(return >= 0) LONG NTSTATUS; +#endif +#ifndef STATUS_SUCCESS +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#endif +#ifndef STATUS_UNSUCCESSFUL +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) +#endif +#ifndef __NTSTATUS_FROM_WIN32 +#define __NTSTATUS_FROM_WIN32(x) ((NTSTATUS)(x) <= 0 ? ((NTSTATUS)(x)) : ((NTSTATUS) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | ERROR_SEVERITY_ERROR))) +#endif + +#ifndef WIL_AllocateMemory +#ifdef _KERNEL_MODE +#define WIL_AllocateMemory(SIZE) ExAllocatePoolWithTag(NonPagedPoolNx, SIZE, 'LIW') +WI_ODR_PRAGMA("WIL_AllocateMemory", "2") +#else +#define WIL_AllocateMemory(SIZE) HeapAlloc(GetProcessHeap(), 0, SIZE) +WI_ODR_PRAGMA("WIL_AllocateMemory", "1") +#endif +#else +WI_ODR_PRAGMA("WIL_AllocateMemory", "0") +#endif + +#ifndef WIL_FreeMemory +#ifdef _KERNEL_MODE +#define WIL_FreeMemory(MEM) ExFreePoolWithTag(MEM, 'LIW') +WI_ODR_PRAGMA("WIL_FreeMemory", "2") +#else +#define WIL_FreeMemory(MEM) HeapFree(GetProcessHeap(), 0, MEM) +WI_ODR_PRAGMA("WIL_FreeMemory", "1") +#endif +#else +WI_ODR_PRAGMA("WIL_FreeMemory", "0") +#endif + +// It would appear as though the C++17 "noexcept is part of the type system" update in MSVC has "infected" the behavior +// when compiling with C++14 (the default...), however the updated behavior for decltype understanding noexcept is _not_ +// present... So, work around it +#if __WI_LIBCPP_STD_VER >= 17 +#define WI_PFN_NOEXCEPT WI_NOEXCEPT +#else +#define WI_PFN_NOEXCEPT +#endif +/// @endcond + +#if defined(__cplusplus) && !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) + +#include +#include // provides the _ReturnAddress() intrinsic +#include // provides 'operator new', 'std::nothrow', etc. +#if defined(WIL_ENABLE_EXCEPTIONS) && !defined(WIL_SUPPRESS_NEW) +#include // provides std::bad_alloc in the windows and public CRT headers +#endif + +#pragma warning(push) +#pragma warning(disable:4714 6262) // __forceinline not honored, stack size + +//***************************************************************************** +// Behavioral setup (error handling macro configuration) +//***************************************************************************** +// Set any of the following macros to the values given below before including Result.h to +// control the error handling macro's trade-offs between diagnostics and performance + +// RESULT_DIAGNOSTICS_LEVEL +// This define controls the level of diagnostic instrumentation that is built into the binary as a +// byproduct of using the macros. The amount of diagnostic instrumentation that is supplied is +// a trade-off between diagnosibility of issues and code size and performance. The modes are: +// 0 - No diagnostics, smallest & fastest (subject to tail-merge) +// 1 - No diagnostics, unique call sites for each macro (defeat's tail-merge) +// 2 - Line number +// 3 - Line number + source filename +// 4 - Line number + source filename + function name +// 5 - Line number + source filename + function name + code within the macro +// By default, mode 3 is used in free builds and mode 5 is used in checked builds. Note that the +// _ReturnAddress() will always be available through all modes when possible. + +// RESULT_INCLUDE_CALLER_RETURNADDRESS +// This controls whether or not the _ReturnAddress() of the function that includes the macro will +// be reported to telemetry. Note that this is in addition to the _ReturnAddress() of the actual +// macro position (which is always reported). The values are: +// 0 - The address is not included +// 1 - The address is included +// The default value is '1'. + +// RESULT_INLINE_ERROR_TESTS +// For conditional macros (other than RETURN_XXX), this controls whether branches will be evaluated +// within the call containing the macro or will be forced into the function called by the macros. +// Pushing branching into the called function reduces code size and the number of unique branches +// evaluated, but increases the instruction count executed per macro. +// 0 - Branching will not happen inline to the macros +// 1 - Branching is pushed into the calling function via __forceinline +// The default value is '1'. Note that XXX_MSG functions are always effectively mode '0' due to the +// compiler's unwillingness to inline var-arg functions. + +// RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST +// RESULT_INCLUDE_CALLER_RETURNADDRESS_FAIL_FAST +// RESULT_INLINE_ERROR_TESTS_FAIL_FAST +// These defines are identical to those above in form/function, but only applicable to fail fast error +// handling allowing a process to have different diagnostic information and performance characteristics +// for fail fast than for other error handling given the different reporting infrastructure (Watson +// vs Telemetry). + +// Set the default diagnostic mode +// Note that RESULT_DEBUG_INFO and RESULT_SUPPRESS_DEBUG_INFO are older deprecated models of controlling mode +#ifndef RESULT_DIAGNOSTICS_LEVEL +#if (defined(RESULT_DEBUG) || defined(RESULT_DEBUG_INFO)) && !defined(RESULT_SUPPRESS_DEBUG_INFO) +#define RESULT_DIAGNOSTICS_LEVEL 5 +#else +#define RESULT_DIAGNOSTICS_LEVEL 3 +#endif +#endif +#ifndef RESULT_INCLUDE_CALLER_RETURNADDRESS +#define RESULT_INCLUDE_CALLER_RETURNADDRESS 1 +#endif +#ifndef RESULT_INLINE_ERROR_TESTS +#define RESULT_INLINE_ERROR_TESTS 1 +#endif +#ifndef RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST +#define RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST RESULT_DIAGNOSTICS_LEVEL +#endif +#ifndef RESULT_INCLUDE_CALLER_RETURNADDRESS_FAIL_FAST +#define RESULT_INCLUDE_CALLER_RETURNADDRESS_FAIL_FAST RESULT_INCLUDE_CALLER_RETURNADDRESS +#endif +#ifndef RESULT_INLINE_ERROR_TESTS_FAIL_FAST +#define RESULT_INLINE_ERROR_TESTS_FAIL_FAST RESULT_INLINE_ERROR_TESTS +#endif + + +//***************************************************************************** +// Win32 specific error macros +//***************************************************************************** + +#define FAILED_WIN32(win32err) ((win32err) != 0) +#define SUCCEEDED_WIN32(win32err) ((win32err) == 0) + + +//***************************************************************************** +// NT_STATUS specific error macros +//***************************************************************************** + +#define FAILED_NTSTATUS(status) (((NTSTATUS)(status)) < 0) +#define SUCCEEDED_NTSTATUS(status) (((NTSTATUS)(status)) >= 0) + + +//***************************************************************************** +// Testing helpers - redefine to run unit tests against fail fast +//***************************************************************************** + +#ifndef RESULT_NORETURN +#define RESULT_NORETURN __declspec(noreturn) +#endif +#ifndef RESULT_NORETURN_NULL +#define RESULT_NORETURN_NULL _Ret_notnull_ +#endif +#ifndef RESULT_NORETURN_RESULT +#define RESULT_NORETURN_RESULT(expr) (void)(expr); +#endif + +//***************************************************************************** +// Helpers to setup the macros and functions used below... do not directly use. +//***************************************************************************** + +/// @cond +#define __R_DIAGNOSTICS(diagnostics) diagnostics.returnAddress, diagnostics.line, diagnostics.file, nullptr, nullptr +#define __R_DIAGNOSTICS_RA(diagnostics, address) diagnostics.returnAddress, diagnostics.line, diagnostics.file, nullptr, nullptr, address +#define __R_FN_PARAMS_FULL _In_opt_ void* callerReturnAddress, unsigned int lineNumber, _In_opt_ PCSTR fileName, _In_opt_ PCSTR functionName, _In_opt_ PCSTR code, void* returnAddress +#define __R_FN_LOCALS_FULL_RA void* callerReturnAddress = nullptr; unsigned int lineNumber = 0; PCSTR fileName = nullptr; PCSTR functionName = nullptr; PCSTR code = nullptr; void* returnAddress = _ReturnAddress(); +// NOTE: This BEGINs the common macro handling (__R_ prefix) for non-fail fast handled cases +// This entire section will be repeated below for fail fast (__RFF_ prefix). +#define __R_COMMA , +#define __R_FN_CALL_FULL callerReturnAddress, lineNumber, fileName, functionName, code, returnAddress +#define __R_FN_CALL_FULL_RA callerReturnAddress, lineNumber, fileName, functionName, code, _ReturnAddress() +// The following macros assemble the varying amount of data we want to collect from the macros, treating it uniformly +#if (RESULT_DIAGNOSTICS_LEVEL >= 2) // line number +#define __R_IF_LINE(term) term +#define __R_IF_NOT_LINE(term) +#define __R_IF_COMMA , +#define __R_LINE_VALUE static_cast(__LINE__) +#else +#define __R_IF_LINE(term) +#define __R_IF_NOT_LINE(term) term +#define __R_IF_COMMA +#define __R_LINE_VALUE static_cast(0) +#endif +#if (RESULT_DIAGNOSTICS_LEVEL >= 3) // line number + file name +#define __R_IF_FILE(term) term +#define __R_IF_NOT_FILE(term) +#define __R_FILE_VALUE __FILE__ +#else +#define __R_IF_FILE(term) +#define __R_IF_NOT_FILE(term) term +#define __R_FILE_VALUE nullptr +#endif +#if (RESULT_DIAGNOSTICS_LEVEL >= 4) // line number + file name + function name +#define __R_IF_FUNCTION(term) term +#define __R_IF_NOT_FUNCTION(term) +#else +#define __R_IF_FUNCTION(term) +#define __R_IF_NOT_FUNCTION(term) term +#endif +#if (RESULT_DIAGNOSTICS_LEVEL >= 5) // line number + file name + function name + macro code +#define __R_IF_CODE(term) term +#define __R_IF_NOT_CODE(term) +#else +#define __R_IF_CODE(term) +#define __R_IF_NOT_CODE(term) term +#endif +#if (RESULT_INCLUDE_CALLER_RETURNADDRESS == 1) +#define __R_IF_CALLERADDRESS(term) term +#define __R_IF_NOT_CALLERADDRESS(term) +#define __R_CALLERADDRESS_VALUE _ReturnAddress() +#else +#define __R_IF_CALLERADDRESS(term) +#define __R_IF_NOT_CALLERADDRESS(term) term +#define __R_CALLERADDRESS_VALUE nullptr +#endif +#if (RESULT_INCLUDE_CALLER_RETURNADDRESS == 1) || (RESULT_DIAGNOSTICS_LEVEL >= 2) +#define __R_IF_TRAIL_COMMA , +#else +#define __R_IF_TRAIL_COMMA +#endif +// Assemble the varying amounts of data into a single macro +#define __R_INFO_ONLY(CODE) __R_IF_CALLERADDRESS(_ReturnAddress() __R_IF_COMMA) __R_IF_LINE(__R_LINE_VALUE) __R_IF_FILE(__R_COMMA __R_FILE_VALUE) __R_IF_FUNCTION(__R_COMMA __FUNCTION__) __R_IF_CODE(__R_COMMA CODE) +#define __R_INFO(CODE) __R_INFO_ONLY(CODE) __R_IF_TRAIL_COMMA +#define __R_INFO_NOFILE_ONLY(CODE) __R_IF_CALLERADDRESS(_ReturnAddress() __R_IF_COMMA) __R_IF_LINE(__R_LINE_VALUE) __R_IF_FILE(__R_COMMA "wil") __R_IF_FUNCTION(__R_COMMA __FUNCTION__) __R_IF_CODE(__R_COMMA CODE) +#define __R_INFO_NOFILE(CODE) __R_INFO_NOFILE_ONLY(CODE) __R_IF_TRAIL_COMMA +#define __R_FN_PARAMS_ONLY __R_IF_CALLERADDRESS(void* callerReturnAddress __R_IF_COMMA) __R_IF_LINE(unsigned int lineNumber) __R_IF_FILE(__R_COMMA _In_opt_ PCSTR fileName) __R_IF_FUNCTION(__R_COMMA _In_opt_ PCSTR functionName) __R_IF_CODE(__R_COMMA _In_opt_ PCSTR code) +#define __R_FN_PARAMS __R_FN_PARAMS_ONLY __R_IF_TRAIL_COMMA +#define __R_FN_CALL_ONLY __R_IF_CALLERADDRESS(callerReturnAddress __R_IF_COMMA) __R_IF_LINE(lineNumber) __R_IF_FILE(__R_COMMA fileName) __R_IF_FUNCTION(__R_COMMA functionName) __R_IF_CODE(__R_COMMA code) +#define __R_FN_CALL __R_FN_CALL_ONLY __R_IF_TRAIL_COMMA +#define __R_FN_LOCALS __R_IF_NOT_CALLERADDRESS(void* callerReturnAddress = nullptr;) __R_IF_NOT_LINE(unsigned int lineNumber = 0;) __R_IF_NOT_FILE(PCSTR fileName = nullptr;) __R_IF_NOT_FUNCTION(PCSTR functionName = nullptr;) __R_IF_NOT_CODE(PCSTR code = nullptr;) +#define __R_FN_LOCALS_RA __R_IF_NOT_CALLERADDRESS(void* callerReturnAddress = nullptr;) __R_IF_NOT_LINE(unsigned int lineNumber = 0;) __R_IF_NOT_FILE(PCSTR fileName = nullptr;) __R_IF_NOT_FUNCTION(PCSTR functionName = nullptr;) __R_IF_NOT_CODE(PCSTR code = nullptr;) void* returnAddress = _ReturnAddress(); +#define __R_FN_UNREFERENCED __R_IF_CALLERADDRESS((void)callerReturnAddress;) __R_IF_LINE((void)lineNumber;) __R_IF_FILE((void)fileName;) __R_IF_FUNCTION((void)functionName;) __R_IF_CODE((void)code;) +// 1) Direct Methods +// * Called Directly by Macros +// * Always noinline +// * May be template-driven to create unique call sites if (RESULT_DIAGNOSTICS_LEVEL == 1) +#if (RESULT_DIAGNOSTICS_LEVEL == 1) +#define __R_DIRECT_METHOD(RetType, MethodName) template inline __declspec(noinline) RetType MethodName +#define __R_DIRECT_NORET_METHOD(RetType, MethodName) template inline __declspec(noinline) RESULT_NORETURN RetType MethodName +#else +#define __R_DIRECT_METHOD(RetType, MethodName) inline __declspec(noinline) RetType MethodName +#define __R_DIRECT_NORET_METHOD(RetType, MethodName) inline __declspec(noinline) RESULT_NORETURN RetType MethodName +#endif +#define __R_DIRECT_FN_PARAMS __R_FN_PARAMS +#define __R_DIRECT_FN_PARAMS_ONLY __R_FN_PARAMS_ONLY +#define __R_DIRECT_FN_CALL __R_FN_CALL_FULL_RA __R_COMMA +#define __R_DIRECT_FN_CALL_ONLY __R_FN_CALL_FULL_RA +// 2) Internal Methods +// * Only called by Conditional routines +// * 'inline' when (RESULT_INLINE_ERROR_TESTS = 0 and RESULT_DIAGNOSTICS_LEVEL != 1), otherwise noinline (directly called by code when branching is forceinlined) +// * May be template-driven to create unique call sites if (RESULT_DIAGNOSTICS_LEVEL == 1 and RESULT_INLINE_ERROR_TESTS = 1) +#if (RESULT_DIAGNOSTICS_LEVEL == 1) +#define __R_INTERNAL_NOINLINE_METHOD(MethodName) inline __declspec(noinline) void MethodName +#define __R_INTERNAL_NOINLINE_NORET_METHOD(MethodName) inline __declspec(noinline) RESULT_NORETURN void MethodName +#define __R_INTERNAL_INLINE_METHOD(MethodName) template inline __declspec(noinline) void MethodName +#define __R_INTERNAL_INLINE_NORET_METHOD(MethodName) template inline __declspec(noinline) RESULT_NORETURN void MethodName +#define __R_CALL_INTERNAL_INLINE_METHOD(MethodName) MethodName +#else +#define __R_INTERNAL_NOINLINE_METHOD(MethodName) inline void MethodName +#define __R_INTERNAL_NOINLINE_NORET_METHOD(MethodName) inline RESULT_NORETURN void MethodName +#define __R_INTERNAL_INLINE_METHOD(MethodName) inline __declspec(noinline) void MethodName +#define __R_INTERNAL_INLINE_NORET_METHOD(MethodName) inline __declspec(noinline) RESULT_NORETURN void MethodName +#define __R_CALL_INTERNAL_INLINE_METHOD(MethodName) MethodName +#endif +#define __R_CALL_INTERNAL_NOINLINE_METHOD(MethodName) MethodName +#define __R_INTERNAL_NOINLINE_FN_PARAMS __R_FN_PARAMS void* returnAddress __R_COMMA +#define __R_INTERNAL_NOINLINE_FN_PARAMS_ONLY __R_FN_PARAMS void* returnAddress +#define __R_INTERNAL_NOINLINE_FN_CALL __R_FN_CALL_FULL __R_COMMA +#define __R_INTERNAL_NOINLINE_FN_CALL_ONLY __R_FN_CALL_FULL +#define __R_INTERNAL_INLINE_FN_PARAMS __R_FN_PARAMS +#define __R_INTERNAL_INLINE_FN_PARAMS_ONLY __R_FN_PARAMS_ONLY +#define __R_INTERNAL_INLINE_FN_CALL __R_FN_CALL_FULL_RA __R_COMMA +#define __R_INTERNAL_INLINE_FN_CALL_ONLY __R_FN_CALL_FULL_RA +#if (RESULT_INLINE_ERROR_TESTS == 0) +#define __R_INTERNAL_METHOD __R_INTERNAL_NOINLINE_METHOD +#define __R_INTERNAL_NORET_METHOD __R_INTERNAL_NOINLINE_NORET_METHOD +#define __R_CALL_INTERNAL_METHOD __R_CALL_INTERNAL_NOINLINE_METHOD +#define __R_INTERNAL_FN_PARAMS __R_INTERNAL_NOINLINE_FN_PARAMS +#define __R_INTERNAL_FN_PARAMS_ONLY __R_INTERNAL_NOINLINE_FN_PARAMS_ONLY +#define __R_INTERNAL_FN_CALL __R_INTERNAL_NOINLINE_FN_CALL +#define __R_INTERNAL_FN_CALL_ONLY __R_INTERNAL_NOINLINE_FN_CALL_ONLY +#else +#define __R_INTERNAL_METHOD __R_INTERNAL_INLINE_METHOD +#define __R_INTERNAL_NORET_METHOD __R_INTERNAL_INLINE_NORET_METHOD +#define __R_CALL_INTERNAL_METHOD __R_CALL_INTERNAL_INLINE_METHOD +#define __R_INTERNAL_FN_PARAMS __R_INTERNAL_INLINE_FN_PARAMS +#define __R_INTERNAL_FN_PARAMS_ONLY __R_INTERNAL_INLINE_FN_PARAMS_ONLY +#define __R_INTERNAL_FN_CALL __R_INTERNAL_INLINE_FN_CALL +#define __R_INTERNAL_FN_CALL_ONLY __R_INTERNAL_INLINE_FN_CALL_ONLY +#endif +// 3) Conditional Methods +// * Called Directly by Macros +// * May be noinline or __forceinline depending upon (RESULT_INLINE_ERROR_TESTS) +// * May be template-driven to create unique call sites if (RESULT_DIAGNOSTICS_LEVEL == 1) +#if (RESULT_DIAGNOSTICS_LEVEL == 1) +#define __R_CONDITIONAL_NOINLINE_METHOD(RetType, MethodName) template inline __declspec(noinline) RetType MethodName +#define __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RetType, MethodName) inline __declspec(noinline) RetType MethodName +#define __R_CONDITIONAL_INLINE_METHOD(RetType, MethodName) template __forceinline RetType MethodName +#define __R_CONDITIONAL_INLINE_TEMPLATE_METHOD(RetType, MethodName) __forceinline RetType MethodName +#define __R_CONDITIONAL_PARTIAL_TEMPLATE unsigned int optimizerCounter __R_COMMA +#else +#define __R_CONDITIONAL_NOINLINE_METHOD(RetType, MethodName) inline __declspec(noinline) RetType MethodName +#define __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RetType, MethodName) inline __declspec(noinline) RetType MethodName +#define __R_CONDITIONAL_INLINE_METHOD(RetType, MethodName) __forceinline RetType MethodName +#define __R_CONDITIONAL_INLINE_TEMPLATE_METHOD(RetType, MethodName) __forceinline RetType MethodName +#define __R_CONDITIONAL_PARTIAL_TEMPLATE +#endif +#define __R_CONDITIONAL_NOINLINE_FN_CALL __R_FN_CALL _ReturnAddress() __R_COMMA +#define __R_CONDITIONAL_NOINLINE_FN_CALL_ONLY __R_FN_CALL _ReturnAddress() +#define __R_CONDITIONAL_INLINE_FN_CALL __R_FN_CALL +#define __R_CONDITIONAL_INLINE_FN_CALL_ONLY __R_FN_CALL_ONLY +#if (RESULT_INLINE_ERROR_TESTS == 0) +#define __R_CONDITIONAL_METHOD __R_CONDITIONAL_NOINLINE_METHOD +#define __R_CONDITIONAL_TEMPLATE_METHOD __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD +#define __R_CONDITIONAL_FN_CALL __R_CONDITIONAL_NOINLINE_FN_CALL +#define __R_CONDITIONAL_FN_CALL_ONLY __R_CONDITIONAL_NOINLINE_FN_CALL_ONLY +#else +#define __R_CONDITIONAL_METHOD __R_CONDITIONAL_INLINE_METHOD +#define __R_CONDITIONAL_TEMPLATE_METHOD __R_CONDITIONAL_INLINE_TEMPLATE_METHOD +#define __R_CONDITIONAL_FN_CALL __R_CONDITIONAL_INLINE_FN_CALL +#define __R_CONDITIONAL_FN_CALL_ONLY __R_CONDITIONAL_INLINE_FN_CALL_ONLY +#endif +#define __R_CONDITIONAL_FN_PARAMS __R_FN_PARAMS +#define __R_CONDITIONAL_FN_PARAMS_ONLY __R_FN_PARAMS_ONLY +// Macro call-site helpers +#define __R_NS_ASSEMBLE2(ri, rd) in##ri##diag##rd // Differing internal namespaces eliminate ODR violations between modes +#define __R_NS_ASSEMBLE(ri, rd) __R_NS_ASSEMBLE2(ri, rd) +#define __R_NS_NAME __R_NS_ASSEMBLE(RESULT_INLINE_ERROR_TESTS, RESULT_DIAGNOSTICS_LEVEL) +#define __R_NS wil::details::__R_NS_NAME +#if (RESULT_DIAGNOSTICS_LEVEL == 1) +#define __R_FN(MethodName) __R_NS:: MethodName <__COUNTER__> +#else +#define __R_FN(MethodName) __R_NS:: MethodName +#endif +// NOTE: This ENDs the common macro handling (__R_ prefix) for non-fail fast handled cases +// This entire section is repeated below for fail fast (__RFF_ prefix). For ease of editing this section, the +// process is to copy/paste, and search and replace (__R_ -> __RFF_), (RESULT_DIAGNOSTICS_LEVEL -> RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST), +// (RESULT_INLINE_ERROR_TESTS -> RESULT_INLINE_ERROR_TESTS_FAIL_FAST) and (RESULT_INCLUDE_CALLER_RETURNADDRESS -> RESULT_INCLUDE_CALLER_RETURNADDRESS_FAIL_FAST) +#define __RFF_COMMA , +#define __RFF_FN_CALL_FULL callerReturnAddress, lineNumber, fileName, functionName, code, returnAddress +#define __RFF_FN_CALL_FULL_RA callerReturnAddress, lineNumber, fileName, functionName, code, _ReturnAddress() +// The following macros assemble the varying amount of data we want to collect from the macros, treating it uniformly +#if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST >= 2) // line number +#define __RFF_IF_LINE(term) term +#define __RFF_IF_NOT_LINE(term) +#define __RFF_IF_COMMA , +#else +#define __RFF_IF_LINE(term) +#define __RFF_IF_NOT_LINE(term) term +#define __RFF_IF_COMMA +#endif +#if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST >= 3) // line number + file name +#define __RFF_IF_FILE(term) term +#define __RFF_IF_NOT_FILE(term) +#else +#define __RFF_IF_FILE(term) +#define __RFF_IF_NOT_FILE(term) term +#endif +#if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST >= 4) // line number + file name + function name +#define __RFF_IF_FUNCTION(term) term +#define __RFF_IF_NOT_FUNCTION(term) +#else +#define __RFF_IF_FUNCTION(term) +#define __RFF_IF_NOT_FUNCTION(term) term +#endif +#if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST >= 5) // line number + file name + function name + macro code +#define __RFF_IF_CODE(term) term +#define __RFF_IF_NOT_CODE(term) +#else +#define __RFF_IF_CODE(term) +#define __RFF_IF_NOT_CODE(term) term +#endif +#if (RESULT_INCLUDE_CALLER_RETURNADDRESS_FAIL_FAST == 1) +#define __RFF_IF_CALLERADDRESS(term) term +#define __RFF_IF_NOT_CALLERADDRESS(term) +#else +#define __RFF_IF_CALLERADDRESS(term) +#define __RFF_IF_NOT_CALLERADDRESS(term) term +#endif +#if (RESULT_INCLUDE_CALLER_RETURNADDRESS_FAIL_FAST == 1) || (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST >= 2) +#define __RFF_IF_TRAIL_COMMA , +#else +#define __RFF_IF_TRAIL_COMMA +#endif +// Assemble the varying amounts of data into a single macro +#define __RFF_INFO_ONLY(CODE) __RFF_IF_CALLERADDRESS(_ReturnAddress() __RFF_IF_COMMA) __RFF_IF_LINE(__R_LINE_VALUE) __RFF_IF_FILE(__RFF_COMMA __R_FILE_VALUE) __RFF_IF_FUNCTION(__RFF_COMMA __FUNCTION__) __RFF_IF_CODE(__RFF_COMMA CODE) +#define __RFF_INFO(CODE) __RFF_INFO_ONLY(CODE) __RFF_IF_TRAIL_COMMA +#define __RFF_INFO_NOFILE_ONLY(CODE) __RFF_IF_CALLERADDRESS(_ReturnAddress() __RFF_IF_COMMA) __RFF_IF_LINE(__R_LINE_VALUE) __RFF_IF_FILE(__RFF_COMMA "wil") __RFF_IF_FUNCTION(__RFF_COMMA __FUNCTION__) __RFF_IF_CODE(__RFF_COMMA CODE) +#define __RFF_INFO_NOFILE(CODE) __RFF_INFO_NOFILE_ONLY(CODE) __RFF_IF_TRAIL_COMMA +#define __RFF_FN_PARAMS_ONLY __RFF_IF_CALLERADDRESS(void* callerReturnAddress __RFF_IF_COMMA) __RFF_IF_LINE(unsigned int lineNumber) __RFF_IF_FILE(__RFF_COMMA _In_opt_ PCSTR fileName) __RFF_IF_FUNCTION(__RFF_COMMA _In_opt_ PCSTR functionName) __RFF_IF_CODE(__RFF_COMMA _In_opt_ PCSTR code) +#define __RFF_FN_PARAMS __RFF_FN_PARAMS_ONLY __RFF_IF_TRAIL_COMMA +#define __RFF_FN_CALL_ONLY __RFF_IF_CALLERADDRESS(callerReturnAddress __RFF_IF_COMMA) __RFF_IF_LINE(lineNumber) __RFF_IF_FILE(__RFF_COMMA fileName) __RFF_IF_FUNCTION(__RFF_COMMA functionName) __RFF_IF_CODE(__RFF_COMMA code) +#define __RFF_FN_CALL __RFF_FN_CALL_ONLY __RFF_IF_TRAIL_COMMA +#define __RFF_FN_LOCALS __RFF_IF_NOT_CALLERADDRESS(void* callerReturnAddress = nullptr;) __RFF_IF_NOT_LINE(unsigned int lineNumber = 0;) __RFF_IF_NOT_FILE(PCSTR fileName = nullptr;) __RFF_IF_NOT_FUNCTION(PCSTR functionName = nullptr;) __RFF_IF_NOT_CODE(PCSTR code = nullptr;) +#define __RFF_FN_UNREFERENCED __RFF_IF_CALLERADDRESS(callerReturnAddress;) __RFF_IF_LINE(lineNumber;) __RFF_IF_FILE(fileName;) __RFF_IF_FUNCTION(functionName;) __RFF_IF_CODE(code;) +// 1) Direct Methods +// * Called Directly by Macros +// * Always noinline +// * May be template-driven to create unique call sites if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST == 1) +#if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST == 1) +#define __RFF_DIRECT_METHOD(RetType, MethodName) template inline __declspec(noinline) RetType MethodName +#define __RFF_DIRECT_NORET_METHOD(RetType, MethodName) template inline __declspec(noinline) RESULT_NORETURN RetType MethodName +#else +#define __RFF_DIRECT_METHOD(RetType, MethodName) inline __declspec(noinline) RetType MethodName +#define __RFF_DIRECT_NORET_METHOD(RetType, MethodName) inline __declspec(noinline) RESULT_NORETURN RetType MethodName +#endif +#define __RFF_DIRECT_FN_PARAMS __RFF_FN_PARAMS +#define __RFF_DIRECT_FN_PARAMS_ONLY __RFF_FN_PARAMS_ONLY +#define __RFF_DIRECT_FN_CALL __RFF_FN_CALL_FULL_RA __RFF_COMMA +#define __RFF_DIRECT_FN_CALL_ONLY __RFF_FN_CALL_FULL_RA +// 2) Internal Methods +// * Only called by Conditional routines +// * 'inline' when (RESULT_INLINE_ERROR_TESTS_FAIL_FAST = 0 and RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST != 1), otherwise noinline (directly called by code when branching is forceinlined) +// * May be template-driven to create unique call sites if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST == 1 and RESULT_INLINE_ERROR_TESTS_FAIL_FAST = 1) +#if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST == 1) +#define __RFF_INTERNAL_NOINLINE_METHOD(MethodName) inline __declspec(noinline) void MethodName +#define __RFF_INTERNAL_NOINLINE_NORET_METHOD(MethodName) inline __declspec(noinline) RESULT_NORETURN void MethodName +#define __RFF_INTERNAL_INLINE_METHOD(MethodName) template inline __declspec(noinline) void MethodName +#define __RFF_INTERNAL_INLINE_NORET_METHOD(MethodName) template inline __declspec(noinline) RESULT_NORETURN void MethodName +#define __RFF_CALL_INTERNAL_INLINE_METHOD(MethodName) MethodName +#else +#define __RFF_INTERNAL_NOINLINE_METHOD(MethodName) inline void MethodName +#define __RFF_INTERNAL_NOINLINE_NORET_METHOD(MethodName) inline RESULT_NORETURN void MethodName +#define __RFF_INTERNAL_INLINE_METHOD(MethodName) inline __declspec(noinline) void MethodName +#define __RFF_INTERNAL_INLINE_NORET_METHOD(MethodName) inline __declspec(noinline) RESULT_NORETURN void MethodName +#define __RFF_CALL_INTERNAL_INLINE_METHOD(MethodName) MethodName +#endif +#define __RFF_CALL_INTERNAL_NOINLINE_METHOD(MethodName) MethodName +#define __RFF_INTERNAL_NOINLINE_FN_PARAMS __RFF_FN_PARAMS void* returnAddress __RFF_COMMA +#define __RFF_INTERNAL_NOINLINE_FN_PARAMS_ONLY __RFF_FN_PARAMS void* returnAddress +#define __RFF_INTERNAL_NOINLINE_FN_CALL __RFF_FN_CALL_FULL __RFF_COMMA +#define __RFF_INTERNAL_NOINLINE_FN_CALL_ONLY __RFF_FN_CALL_FULL +#define __RFF_INTERNAL_INLINE_FN_PARAMS __RFF_FN_PARAMS +#define __RFF_INTERNAL_INLINE_FN_PARAMS_ONLY __RFF_FN_PARAMS_ONLY +#define __RFF_INTERNAL_INLINE_FN_CALL __RFF_FN_CALL_FULL_RA __RFF_COMMA +#define __RFF_INTERNAL_INLINE_FN_CALL_ONLY __RFF_FN_CALL_FULL_RA +#if (RESULT_INLINE_ERROR_TESTS_FAIL_FAST == 0) +#define __RFF_INTERNAL_METHOD __RFF_INTERNAL_NOINLINE_METHOD +#define __RFF_INTERNAL_NORET_METHOD __RFF_INTERNAL_NOINLINE_NORET_METHOD +#define __RFF_CALL_INTERNAL_METHOD __RFF_CALL_INTERNAL_NOINLINE_METHOD +#define __RFF_INTERNAL_FN_PARAMS __RFF_INTERNAL_NOINLINE_FN_PARAMS +#define __RFF_INTERNAL_FN_PARAMS_ONLY __RFF_INTERNAL_NOINLINE_FN_PARAMS_ONLY +#define __RFF_INTERNAL_FN_CALL __RFF_INTERNAL_NOINLINE_FN_CALL +#define __RFF_INTERNAL_FN_CALL_ONLY __RFF_INTERNAL_NOINLINE_FN_CALL_ONLY +#else +#define __RFF_INTERNAL_METHOD __RFF_INTERNAL_INLINE_METHOD +#define __RFF_INTERNAL_NORET_METHOD __RFF_INTERNAL_INLINE_NORET_METHOD +#define __RFF_CALL_INTERNAL_METHOD __RFF_CALL_INTERNAL_INLINE_METHOD +#define __RFF_INTERNAL_FN_PARAMS __RFF_INTERNAL_INLINE_FN_PARAMS +#define __RFF_INTERNAL_FN_PARAMS_ONLY __RFF_INTERNAL_INLINE_FN_PARAMS_ONLY +#define __RFF_INTERNAL_FN_CALL __RFF_INTERNAL_INLINE_FN_CALL +#define __RFF_INTERNAL_FN_CALL_ONLY __RFF_INTERNAL_INLINE_FN_CALL_ONLY +#endif +// 3) Conditional Methods +// * Called Directly by Macros +// * May be noinline or __forceinline depending upon (RESULT_INLINE_ERROR_TESTS_FAIL_FAST) +// * May be template-driven to create unique call sites if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST == 1) +#if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST == 1) +#define __RFF_CONDITIONAL_NOINLINE_METHOD(RetType, MethodName) template inline __declspec(noinline) RetType MethodName +#define __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RetType, MethodName) inline __declspec(noinline) RetType MethodName +#define __RFF_CONDITIONAL_INLINE_METHOD(RetType, MethodName) template __forceinline RetType MethodName +#define __RFF_CONDITIONAL_INLINE_TEMPLATE_METHOD(RetType, MethodName) __forceinline RetType MethodName +#define __RFF_CONDITIONAL_PARTIAL_TEMPLATE unsigned int optimizerCounter __RFF_COMMA +#else +#define __RFF_CONDITIONAL_NOINLINE_METHOD(RetType, MethodName) inline __declspec(noinline) RetType MethodName +#define __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RetType, MethodName) inline __declspec(noinline) RetType MethodName +#define __RFF_CONDITIONAL_INLINE_METHOD(RetType, MethodName) __forceinline RetType MethodName +#define __RFF_CONDITIONAL_INLINE_TEMPLATE_METHOD(RetType, MethodName) __forceinline RetType MethodName +#define __RFF_CONDITIONAL_PARTIAL_TEMPLATE +#endif +#define __RFF_CONDITIONAL_NOINLINE_FN_CALL __RFF_FN_CALL _ReturnAddress() __RFF_COMMA +#define __RFF_CONDITIONAL_NOINLINE_FN_CALL_ONLY __RFF_FN_CALL _ReturnAddress() +#define __RFF_CONDITIONAL_INLINE_FN_CALL __RFF_FN_CALL +#define __RFF_CONDITIONAL_INLINE_FN_CALL_ONLY __RFF_FN_CALL_ONLY +#if (RESULT_INLINE_ERROR_TESTS_FAIL_FAST == 0) +#define __RFF_CONDITIONAL_METHOD __RFF_CONDITIONAL_NOINLINE_METHOD +#define __RFF_CONDITIONAL_TEMPLATE_METHOD __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD +#define __RFF_CONDITIONAL_FN_CALL __RFF_CONDITIONAL_NOINLINE_FN_CALL +#define __RFF_CONDITIONAL_FN_CALL_ONLY __RFF_CONDITIONAL_NOINLINE_FN_CALL_ONLY +#else +#define __RFF_CONDITIONAL_METHOD __RFF_CONDITIONAL_INLINE_METHOD +#define __RFF_CONDITIONAL_TEMPLATE_METHOD __RFF_CONDITIONAL_INLINE_TEMPLATE_METHOD +#define __RFF_CONDITIONAL_FN_CALL __RFF_CONDITIONAL_INLINE_FN_CALL +#define __RFF_CONDITIONAL_FN_CALL_ONLY __RFF_CONDITIONAL_INLINE_FN_CALL_ONLY +#endif +#define __RFF_CONDITIONAL_FN_PARAMS __RFF_FN_PARAMS +#define __RFF_CONDITIONAL_FN_PARAMS_ONLY __RFF_FN_PARAMS_ONLY +// Macro call-site helpers +#define __RFF_NS_ASSEMBLE2(ri, rd) in##ri##diag##rd // Differing internal namespaces eliminate ODR violations between modes +#define __RFF_NS_ASSEMBLE(ri, rd) __RFF_NS_ASSEMBLE2(ri, rd) +#define __RFF_NS_NAME __RFF_NS_ASSEMBLE(RESULT_INLINE_ERROR_TESTS_FAIL_FAST, RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST) +#define __RFF_NS wil::details::__RFF_NS_NAME +#if (RESULT_DIAGNOSTICS_LEVEL_FAIL_FAST == 1) +#define __RFF_FN(MethodName) __RFF_NS:: MethodName <__COUNTER__> +#else +#define __RFF_FN(MethodName) __RFF_NS:: MethodName +#endif +// end-of-repeated fail-fast handling macros + +// Helpers for return macros +#define __RETURN_HR_MSG(hr, str, fmt, ...) __WI_SUPPRESS_4127_S do { const HRESULT __hr = (hr); if (FAILED(__hr)) { __R_FN(Return_HrMsg)(__R_INFO(str) __hr, fmt, ##__VA_ARGS__); } return __hr; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_HR_MSG_FAIL(hr, str, fmt, ...) __WI_SUPPRESS_4127_S do { const HRESULT __hr = (hr); __R_FN(Return_HrMsg)(__R_INFO(str) __hr, fmt, ##__VA_ARGS__); return __hr; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_WIN32_MSG(err, str, fmt, ...) __WI_SUPPRESS_4127_S do { const DWORD __err = (err); if (FAILED_WIN32(__err)) { return __R_FN(Return_Win32Msg)(__R_INFO(str) __err, fmt, ##__VA_ARGS__); } return S_OK; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_WIN32_MSG_FAIL(err, str, fmt, ...) __WI_SUPPRESS_4127_S do { const DWORD __err = (err); return __R_FN(Return_Win32Msg)(__R_INFO(str) __err, fmt, ##__VA_ARGS__); } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_GLE_MSG_FAIL(str, fmt, ...) return __R_FN(Return_GetLastErrorMsg)(__R_INFO(str) fmt, ##__VA_ARGS__) +#define __RETURN_NTSTATUS_MSG(status, str, fmt, ...) __WI_SUPPRESS_4127_S do { const NTSTATUS __status = (status); if (FAILED_NTSTATUS(__status)) { return __R_FN(Return_NtStatusMsg)(__R_INFO(str) __status, fmt, ##__VA_ARGS__); } return S_OK; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_NTSTATUS_MSG_FAIL(status, str, fmt, ...) __WI_SUPPRESS_4127_S do { const NTSTATUS __status = (status); return __R_FN(Return_NtStatusMsg)(__R_INFO(str) __status, fmt, ##__VA_ARGS__); } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_HR(hr, str) __WI_SUPPRESS_4127_S do { const HRESULT __hr = (hr); if (FAILED(__hr)) { __R_FN(Return_Hr)(__R_INFO(str) __hr); } return __hr; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_HR_NOFILE(hr, str) __WI_SUPPRESS_4127_S do { const HRESULT __hr = (hr); if (FAILED(__hr)) { __R_FN(Return_Hr)(__R_INFO_NOFILE(str) __hr); } return __hr; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_HR_FAIL(hr, str) __WI_SUPPRESS_4127_S do { const HRESULT __hr = (hr); __R_FN(Return_Hr)(__R_INFO(str) __hr); return __hr; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_HR_FAIL_NOFILE(hr, str) __WI_SUPPRESS_4127_S do { const HRESULT __hr = (hr); __R_FN(Return_Hr)(__R_INFO_NOFILE(str) __hr); return __hr; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_WIN32(err, str) __WI_SUPPRESS_4127_S do { const DWORD __err = (err); if (FAILED_WIN32(__err)) { return __R_FN(Return_Win32)(__R_INFO(str) __err); } return S_OK; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_WIN32_FAIL(err, str) __WI_SUPPRESS_4127_S do { const DWORD __err = (err); return __R_FN(Return_Win32)(__R_INFO(str) __err); } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_GLE_FAIL(str) return __R_FN(Return_GetLastError)(__R_INFO_ONLY(str)) +#define __RETURN_GLE_FAIL_NOFILE(str) return __R_FN(Return_GetLastError)(__R_INFO_NOFILE_ONLY(str)) +#define __RETURN_NTSTATUS(status, str) __WI_SUPPRESS_4127_S do { const NTSTATUS __status = (status); if (FAILED_NTSTATUS(__status)) { return __R_FN(Return_NtStatus)(__R_INFO(str) __status); } return S_OK; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __RETURN_NTSTATUS_FAIL(status, str) __WI_SUPPRESS_4127_S do { const NTSTATUS __status = (status); return __R_FN(Return_NtStatus)(__R_INFO(str) __status); } __WI_SUPPRESS_4127_E while ((void)0, 0) +/// @endcond + +//***************************************************************************** +// Macros for returning failures as HRESULTs +//***************************************************************************** + +// Always returns a known result (HRESULT) - always logs failures +#define RETURN_HR(hr) __RETURN_HR(wil::verify_hresult(hr), #hr) +#define RETURN_LAST_ERROR() __RETURN_GLE_FAIL(nullptr) +#define RETURN_WIN32(win32err) __RETURN_WIN32(win32err, #win32err) +#define RETURN_NTSTATUS(status) __RETURN_NTSTATUS(status, #status) + +// Conditionally returns failures (HRESULT) - always logs failures +#define RETURN_IF_FAILED(hr) __WI_SUPPRESS_4127_S do { const auto __hrRet = wil::verify_hresult(hr); if (FAILED(__hrRet)) { __RETURN_HR_FAIL(__hrRet, #hr); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_IF_WIN32_BOOL_FALSE(win32BOOL) __WI_SUPPRESS_4127_S do { const auto __boolRet = wil::verify_BOOL(win32BOOL); if (!__boolRet) { __RETURN_GLE_FAIL(#win32BOOL); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_IF_WIN32_ERROR(win32err) __WI_SUPPRESS_4127_S do { const DWORD __errRet = (win32err); if (FAILED_WIN32(__errRet)) { __RETURN_WIN32_FAIL(__errRet, #win32err); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_IF_NULL_ALLOC(ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { __RETURN_HR_FAIL(E_OUTOFMEMORY, #ptr); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_HR_IF(hr, condition) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { __RETURN_HR(wil::verify_hresult(hr), #condition); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_HR_IF_NULL(hr, ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { __RETURN_HR(wil::verify_hresult(hr), #ptr); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_LAST_ERROR_IF(condition) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { __RETURN_GLE_FAIL(#condition); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_LAST_ERROR_IF_NULL(ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { __RETURN_GLE_FAIL(#ptr); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_IF_NTSTATUS_FAILED(status) __WI_SUPPRESS_4127_S do { const NTSTATUS __statusRet = (status); if (FAILED_NTSTATUS(__statusRet)) { __RETURN_NTSTATUS_FAIL(__statusRet, #status); }} __WI_SUPPRESS_4127_E while ((void)0, 0) + +// Always returns a known failure (HRESULT) - always logs a var-arg message on failure +#define RETURN_HR_MSG(hr, fmt, ...) __RETURN_HR_MSG(wil::verify_hresult(hr), #hr, fmt, ##__VA_ARGS__) +#define RETURN_LAST_ERROR_MSG(fmt, ...) __RETURN_GLE_MSG_FAIL(nullptr, fmt, ##__VA_ARGS__) +#define RETURN_WIN32_MSG(win32err, fmt, ...) __RETURN_WIN32_MSG(win32err, #win32err, fmt, ##__VA_ARGS__) +#define RETURN_NTSTATUS_MSG(status, fmt, ...) __RETURN_NTSTATUS_MSG(status, #status, fmt, ##__VA_ARGS__) + +// Conditionally returns failures (HRESULT) - always logs a var-arg message on failure +#define RETURN_IF_FAILED_MSG(hr, fmt, ...) __WI_SUPPRESS_4127_S do { const auto __hrRet = wil::verify_hresult(hr); if (FAILED(__hrRet)) { __RETURN_HR_MSG_FAIL(__hrRet, #hr, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_IF_WIN32_BOOL_FALSE_MSG(win32BOOL, fmt, ...) __WI_SUPPRESS_4127_S do { if (!wil::verify_BOOL(win32BOOL)) { __RETURN_GLE_MSG_FAIL(#win32BOOL, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_IF_WIN32_ERROR_MSG(win32err, fmt, ...) __WI_SUPPRESS_4127_S do { const DWORD __errRet = (win32err); if (FAILED_WIN32(__errRet)) { __RETURN_WIN32_MSG_FAIL(__errRet, #win32err, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_IF_NULL_ALLOC_MSG(ptr, fmt, ...) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { __RETURN_HR_MSG_FAIL(E_OUTOFMEMORY, #ptr, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_HR_IF_MSG(hr, condition, fmt, ...) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { __RETURN_HR_MSG(wil::verify_hresult(hr), #condition, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_HR_IF_NULL_MSG(hr, ptr, fmt, ...) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { __RETURN_HR_MSG(wil::verify_hresult(hr), #ptr, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_LAST_ERROR_IF_MSG(condition, fmt, ...) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { __RETURN_GLE_MSG_FAIL(#condition, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_LAST_ERROR_IF_NULL_MSG(ptr, fmt, ...) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { __RETURN_GLE_MSG_FAIL(#ptr, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_IF_NTSTATUS_FAILED_MSG(status, fmt, ...) __WI_SUPPRESS_4127_S do { const NTSTATUS __statusRet = (status); if (FAILED_NTSTATUS(__statusRet)) { __RETURN_NTSTATUS_MSG_FAIL(__statusRet, #status, fmt, ##__VA_ARGS__); }} __WI_SUPPRESS_4127_E while((void)0, 0) + +// Conditionally returns failures (HRESULT) - use for failures that are expected in common use - failures are not logged - macros are only for control flow pattern +#define RETURN_IF_FAILED_EXPECTED(hr) __WI_SUPPRESS_4127_S do { const auto __hrRet = wil::verify_hresult(hr); if (FAILED(__hrRet)) { return __hrRet; }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define RETURN_IF_WIN32_BOOL_FALSE_EXPECTED(win32BOOL) __WI_SUPPRESS_4127_S do { if (!wil::verify_BOOL(win32BOOL)) { return wil::details::GetLastErrorFailHr(); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_IF_WIN32_ERROR_EXPECTED(win32err) __WI_SUPPRESS_4127_S do { const DWORD __errRet = (win32err); if (FAILED_WIN32(__errRet)) { return __HRESULT_FROM_WIN32(__errRet); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_IF_NULL_ALLOC_EXPECTED(ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { return E_OUTOFMEMORY; }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_HR_IF_EXPECTED(hr, condition) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { return wil::verify_hresult(hr); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_HR_IF_NULL_EXPECTED(hr, ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { return wil::verify_hresult(hr); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_LAST_ERROR_IF_EXPECTED(condition) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { return wil::details::GetLastErrorFailHr(); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_LAST_ERROR_IF_NULL_EXPECTED(ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { return wil::details::GetLastErrorFailHr(); }} __WI_SUPPRESS_4127_E while((void)0, 0) +#define RETURN_IF_NTSTATUS_FAILED_EXPECTED(status) __WI_SUPPRESS_4127_S do { const NTSTATUS __statusRet = (status); if (FAILED_NTSTATUS(__statusRet)) { return wil::details::NtStatusToHr(__statusRet); }} __WI_SUPPRESS_4127_E while((void)0, 0) + +#define __WI_OR_IS_EXPECTED_HRESULT(e) || (__hrRet == wil::verify_hresult(e)) +#define RETURN_IF_FAILED_WITH_EXPECTED(hr, hrExpected, ...) \ + do \ + { \ + const auto __hrRet = wil::verify_hresult(hr); \ + if (FAILED(__hrRet)) \ + { \ + if ((__hrRet == wil::verify_hresult(hrExpected)) WI_FOREACH(__WI_OR_IS_EXPECTED_HRESULT, ##__VA_ARGS__)) \ + { \ + return __hrRet; \ + } \ + __RETURN_HR_FAIL(__hrRet, #hr); \ + } \ + } \ + while ((void)0, 0) + +//***************************************************************************** +// Macros for logging failures (ignore or pass-through) +//***************************************************************************** + +// Always logs a known failure +#define LOG_HR(hr) __R_FN(Log_Hr)(__R_INFO(#hr) wil::verify_hresult(hr)) +#define LOG_LAST_ERROR() __R_FN(Log_GetLastError)(__R_INFO_ONLY(nullptr)) +#define LOG_WIN32(win32err) __R_FN(Log_Win32)(__R_INFO(#win32err) win32err) +#define LOG_NTSTATUS(status) __R_FN(Log_NtStatus)(__R_INFO(#status) status) + +// Conditionally logs failures - returns parameter value +#define LOG_IF_FAILED(hr) __R_FN(Log_IfFailed)(__R_INFO(#hr) wil::verify_hresult(hr)) +#define LOG_IF_WIN32_BOOL_FALSE(win32BOOL) __R_FN(Log_IfWin32BoolFalse)(__R_INFO(#win32BOOL) wil::verify_BOOL(win32BOOL)) +#define LOG_IF_WIN32_ERROR(win32err) __R_FN(Log_IfWin32Error)(__R_INFO(#win32err) win32err) +#define LOG_IF_NULL_ALLOC(ptr) __R_FN(Log_IfNullAlloc)(__R_INFO(#ptr) ptr) +#define LOG_HR_IF(hr, condition) __R_FN(Log_HrIf)(__R_INFO(#condition) wil::verify_hresult(hr), wil::verify_bool(condition)) +#define LOG_HR_IF_NULL(hr, ptr) __R_FN(Log_HrIfNull)(__R_INFO(#ptr) wil::verify_hresult(hr), ptr) +#define LOG_LAST_ERROR_IF(condition) __R_FN(Log_GetLastErrorIf)(__R_INFO(#condition) wil::verify_bool(condition)) +#define LOG_LAST_ERROR_IF_NULL(ptr) __R_FN(Log_GetLastErrorIfNull)(__R_INFO(#ptr) ptr) +#define LOG_IF_NTSTATUS_FAILED(status) __R_FN(Log_IfNtStatusFailed)(__R_INFO(#status) status) + +// Alternatives for SUCCEEDED(hr) and FAILED(hr) that conditionally log failures +#define SUCCEEDED_LOG(hr) SUCCEEDED(LOG_IF_FAILED(hr)) +#define FAILED_LOG(hr) FAILED(LOG_IF_FAILED(hr)) +#define SUCCEEDED_WIN32_LOG(win32err) SUCCEEDED_WIN32(LOG_IF_WIN32_ERROR(win32err)) +#define FAILED_WIN32_LOG(win32err) FAILED_WIN32(LOG_IF_WIN32_ERROR(win32err)) +#define SUCCEEDED_NTSTATUS_LOG(status) SUCCEEDED_NTSTATUS(LOG_IF_NTSTATUS_FAILED(status)) +#define FAILED_NTSTATUS_LOG(status) FAILED_NTSTATUS(LOG_IF_NTSTATUS_FAILED(status)) + +// Alternatives for NT_SUCCESS(x) that conditionally logs failures +#define NT_SUCCESS_LOG(status) NT_SUCCESS(LOG_IF_NTSTATUS_FAILED(status)) + +// Always logs a known failure - logs a var-arg message on failure +#define LOG_HR_MSG(hr, fmt, ...) __R_FN(Log_HrMsg)(__R_INFO(#hr) wil::verify_hresult(hr), fmt, ##__VA_ARGS__) +#define LOG_LAST_ERROR_MSG(fmt, ...) __R_FN(Log_GetLastErrorMsg)(__R_INFO(nullptr) fmt, ##__VA_ARGS__) +#define LOG_WIN32_MSG(win32err, fmt, ...) __R_FN(Log_Win32Msg)(__R_INFO(#win32err) win32err, fmt, ##__VA_ARGS__) +#define LOG_NTSTATUS_MSG(status, fmt, ...) __R_FN(Log_NtStatusMsg)(__R_INFO(#status) status, fmt, ##__VA_ARGS__) + +// Conditionally logs failures - returns parameter value - logs a var-arg message on failure +#define LOG_IF_FAILED_MSG(hr, fmt, ...) __R_FN(Log_IfFailedMsg)(__R_INFO(#hr) wil::verify_hresult(hr), fmt, ##__VA_ARGS__) +#define LOG_IF_WIN32_BOOL_FALSE_MSG(win32BOOL, fmt, ...) __R_FN(Log_IfWin32BoolFalseMsg)(__R_INFO(#win32BOOL) wil::verify_BOOL(win32BOOL), fmt, ##__VA_ARGS__) +#define LOG_IF_WIN32_ERROR_MSG(win32err, fmt, ...) __R_FN(Log_IfWin32ErrorMsg)(__R_INFO(#win32err) win32err, fmt, ##__VA_ARGS__) +#define LOG_IF_NULL_ALLOC_MSG(ptr, fmt, ...) __R_FN(Log_IfNullAllocMsg)(__R_INFO(#ptr) ptr, fmt, ##__VA_ARGS__) +#define LOG_HR_IF_MSG(hr, condition, fmt, ...) __R_FN(Log_HrIfMsg)(__R_INFO(#condition) wil::verify_hresult(hr), wil::verify_bool(condition), fmt, ##__VA_ARGS__) +#define LOG_HR_IF_NULL_MSG(hr, ptr, fmt, ...) __R_FN(Log_HrIfNullMsg)(__R_INFO(#ptr) wil::verify_hresult(hr), ptr, fmt, ##__VA_ARGS__) +#define LOG_LAST_ERROR_IF_MSG(condition, fmt, ...) __R_FN(Log_GetLastErrorIfMsg)(__R_INFO(#condition) wil::verify_bool(condition), fmt, ##__VA_ARGS__) +#define LOG_LAST_ERROR_IF_NULL_MSG(ptr, fmt, ...) __R_FN(Log_GetLastErrorIfNullMsg)(__R_INFO(#ptr) ptr, fmt, ##__VA_ARGS__) +#define LOG_IF_NTSTATUS_FAILED_MSG(status, fmt, ...) __R_FN(Log_IfNtStatusFailedMsg)(__R_INFO(#status) status, fmt, ##__VA_ARGS__) + +#define __WI_COMMA_EXPECTED_HRESULT(e) , wil::verify_hresult(e) +#define LOG_IF_FAILED_WITH_EXPECTED(hr, hrExpected, ...) __R_FN(Log_IfFailedWithExpected)(__R_INFO(#hr) wil::verify_hresult(hr), WI_ARGS_COUNT(__VA_ARGS__) + 1, wil::verify_hresult(hrExpected) WI_FOREACH(__WI_COMMA_EXPECTED_HRESULT, ##__VA_ARGS__)) + +//***************************************************************************** +// Macros to fail fast the process on failures +//***************************************************************************** + +// Always fail fast a known failure +#define FAIL_FAST_HR(hr) __RFF_FN(FailFast_Hr)(__RFF_INFO(#hr) wil::verify_hresult(hr)) +#define FAIL_FAST_LAST_ERROR() __RFF_FN(FailFast_GetLastError)(__RFF_INFO_ONLY(nullptr)) +#define FAIL_FAST_WIN32(win32err) __RFF_FN(FailFast_Win32)(__RFF_INFO(#win32err) win32err) +#define FAIL_FAST_NTSTATUS(status) __RFF_FN(FailFast_NtStatus)(__RFF_INFO(#status) status) + +// Conditionally fail fast failures - returns parameter value +#define FAIL_FAST_IF_FAILED(hr) __RFF_FN(FailFast_IfFailed)(__RFF_INFO(#hr) wil::verify_hresult(hr)) +#define FAIL_FAST_IF_WIN32_BOOL_FALSE(win32BOOL) __RFF_FN(FailFast_IfWin32BoolFalse)(__RFF_INFO(#win32BOOL) wil::verify_BOOL(win32BOOL)) +#define FAIL_FAST_IF_WIN32_ERROR(win32err) __RFF_FN(FailFast_IfWin32Error)(__RFF_INFO(#win32err) win32err) +#define FAIL_FAST_IF_NULL_ALLOC(ptr) __RFF_FN(FailFast_IfNullAlloc)(__RFF_INFO(#ptr) ptr) +#define FAIL_FAST_HR_IF(hr, condition) __RFF_FN(FailFast_HrIf)(__RFF_INFO(#condition) wil::verify_hresult(hr), wil::verify_bool(condition)) +#define FAIL_FAST_HR_IF_NULL(hr, ptr) __RFF_FN(FailFast_HrIfNull)(__RFF_INFO(#ptr) wil::verify_hresult(hr), ptr) +#define FAIL_FAST_LAST_ERROR_IF(condition) __RFF_FN(FailFast_GetLastErrorIf)(__RFF_INFO(#condition) wil::verify_bool(condition)) +#define FAIL_FAST_LAST_ERROR_IF_NULL(ptr) __RFF_FN(FailFast_GetLastErrorIfNull)(__RFF_INFO(#ptr) ptr) +#define FAIL_FAST_IF_NTSTATUS_FAILED(status) __RFF_FN(FailFast_IfNtStatusFailed)(__RFF_INFO(#status) status) + +// Always fail fast a known failure - fail fast a var-arg message on failure +#define FAIL_FAST_HR_MSG(hr, fmt, ...) __RFF_FN(FailFast_HrMsg)(__RFF_INFO(#hr) wil::verify_hresult(hr), fmt, ##__VA_ARGS__) +#define FAIL_FAST_LAST_ERROR_MSG(fmt, ...) __RFF_FN(FailFast_GetLastErrorMsg)(__RFF_INFO(nullptr) fmt, ##__VA_ARGS__) +#define FAIL_FAST_WIN32_MSG(win32err, fmt, ...) __RFF_FN(FailFast_Win32Msg)(__RFF_INFO(#win32err) win32err, fmt, ##__VA_ARGS__) +#define FAIL_FAST_NTSTATUS_MSG(status, fmt, ...) __RFF_FN(FailFast_NtStatusMsg)(__RFF_INFO(#status) status, fmt, ##__VA_ARGS__) + +// Conditionally fail fast failures - returns parameter value - fail fast a var-arg message on failure +#define FAIL_FAST_IF_FAILED_MSG(hr, fmt, ...) __RFF_FN(FailFast_IfFailedMsg)(__RFF_INFO(#hr) wil::verify_hresult(hr), fmt, ##__VA_ARGS__) +#define FAIL_FAST_IF_WIN32_BOOL_FALSE_MSG(win32BOOL, fmt, ...) __RFF_FN(FailFast_IfWin32BoolFalseMsg)(__RFF_INFO(#win32BOOL) wil::verify_BOOL(win32BOOL), fmt, ##__VA_ARGS__) +#define FAIL_FAST_IF_WIN32_ERROR_MSG(win32err, fmt, ...) __RFF_FN(FailFast_IfWin32ErrorMsg)(__RFF_INFO(#win32err) win32err, fmt, ##__VA_ARGS__) +#define FAIL_FAST_IF_NULL_ALLOC_MSG(ptr, fmt, ...) __RFF_FN(FailFast_IfNullAllocMsg)(__RFF_INFO(#ptr) ptr, fmt, ##__VA_ARGS__) +#define FAIL_FAST_HR_IF_MSG(hr, condition, fmt, ...) __RFF_FN(FailFast_HrIfMsg)(__RFF_INFO(#condition) wil::verify_hresult(hr), wil::verify_bool(condition), fmt, ##__VA_ARGS__) +#define FAIL_FAST_HR_IF_NULL_MSG(hr, ptr, fmt, ...) __RFF_FN(FailFast_HrIfNullMsg)(__RFF_INFO(#ptr) wil::verify_hresult(hr), ptr, fmt, ##__VA_ARGS__) +#define FAIL_FAST_LAST_ERROR_IF_MSG(condition, fmt, ...) __RFF_FN(FailFast_GetLastErrorIfMsg)(__RFF_INFO(#condition) wil::verify_bool(condition), fmt, ##__VA_ARGS__) +#define FAIL_FAST_LAST_ERROR_IF_NULL_MSG(ptr, fmt, ...) __RFF_FN(FailFast_GetLastErrorIfNullMsg)(__RFF_INFO(#ptr) ptr, fmt, ##__VA_ARGS__) +#define FAIL_FAST_IF_NTSTATUS_FAILED_MSG(status, fmt, ...) __RFF_FN(FailFast_IfNtStatusFailedMsg)(__RFF_INFO(#status) status, fmt, ##__VA_ARGS__) + +// Always fail fast a known failure +#ifndef FAIL_FAST +#define FAIL_FAST() __RFF_FN(FailFast_Unexpected)(__RFF_INFO_ONLY(nullptr)) +#endif + +// Conditionally fail fast failures - returns parameter value +#define FAIL_FAST_IF(condition) __RFF_FN(FailFast_If)(__RFF_INFO(#condition) wil::verify_bool(condition)) +#define FAIL_FAST_IF_NULL(ptr) __RFF_FN(FailFast_IfNull)(__RFF_INFO(#ptr) ptr) + +// Always fail fast a known failure - fail fast a var-arg message on failure +#define FAIL_FAST_MSG(fmt, ...) __RFF_FN(FailFast_UnexpectedMsg)(__RFF_INFO(nullptr) fmt, ##__VA_ARGS__) + +// Conditionally fail fast failures - returns parameter value - fail fast a var-arg message on failure +#define FAIL_FAST_IF_MSG(condition, fmt, ...) __RFF_FN(FailFast_IfMsg)(__RFF_INFO(#condition) wil::verify_bool(condition), fmt, ##__VA_ARGS__) +#define FAIL_FAST_IF_NULL_MSG(ptr, fmt, ...) __RFF_FN(FailFast_IfNullMsg)(__RFF_INFO(#ptr) ptr, fmt, ##__VA_ARGS__) + +// Immediate fail fast (no telemetry - use rarely / only when *already* in an undefined state) +#define FAIL_FAST_IMMEDIATE() __RFF_FN(FailFastImmediate_Unexpected)() + +// Conditional immediate fail fast (no telemetry - use rarely / only when *already* in an undefined state) +#define FAIL_FAST_IMMEDIATE_IF_FAILED(hr) __RFF_FN(FailFastImmediate_IfFailed)(wil::verify_hresult(hr)) +#define FAIL_FAST_IMMEDIATE_IF(condition) __RFF_FN(FailFastImmediate_If)(wil::verify_bool(condition)) +#define FAIL_FAST_IMMEDIATE_IF_NULL(ptr) __RFF_FN(FailFastImmediate_IfNull)(ptr) +#define FAIL_FAST_IMMEDIATE_IF_NTSTATUS_FAILED(status) __RFF_FN(FailFastImmediate_IfNtStatusFailed)(status) + +// Specializations +#define FAIL_FAST_IMMEDIATE_IF_IN_LOADER_CALLOUT() do { if (wil::details::g_pfnFailFastInLoaderCallout != nullptr) { wil::details::g_pfnFailFastInLoaderCallout(); } } while ((void)0, 0) + + +//***************************************************************************** +// Macros to throw exceptions on failure +//***************************************************************************** + +#ifdef WIL_ENABLE_EXCEPTIONS + +// Always throw a known failure +#define THROW_HR(hr) __R_FN(Throw_Hr)(__R_INFO(#hr) wil::verify_hresult(hr)) +#define THROW_LAST_ERROR() __R_FN(Throw_GetLastError)(__R_INFO_ONLY(nullptr)) +#define THROW_WIN32(win32err) __R_FN(Throw_Win32)(__R_INFO(#win32err) win32err) +#define THROW_EXCEPTION(exception) wil::details::ReportFailure_CustomException(__R_INFO(#exception) exception) +#define THROW_NTSTATUS(status) __R_FN(Throw_NtStatus)(__R_INFO(#status) status) + +// Conditionally throw failures - returns parameter value +#define THROW_IF_FAILED(hr) __R_FN(Throw_IfFailed)(__R_INFO(#hr) wil::verify_hresult(hr)) +#define THROW_IF_WIN32_BOOL_FALSE(win32BOOL) __R_FN(Throw_IfWin32BoolFalse)(__R_INFO(#win32BOOL) wil::verify_BOOL(win32BOOL)) +#define THROW_IF_WIN32_ERROR(win32err) __R_FN(Throw_IfWin32Error)(__R_INFO(#win32err) win32err) +#define THROW_IF_NULL_ALLOC(ptr) __R_FN(Throw_IfNullAlloc)(__R_INFO(#ptr) ptr) +#define THROW_HR_IF(hr, condition) __R_FN(Throw_HrIf)(__R_INFO(#condition) wil::verify_hresult(hr), wil::verify_bool(condition)) +#define THROW_HR_IF_NULL(hr, ptr) __R_FN(Throw_HrIfNull)(__R_INFO(#ptr) wil::verify_hresult(hr), ptr) +#define THROW_WIN32_IF(win32err, condition) __R_FN(Throw_Win32If)(__R_INFO(#condition) wil::verify_win32(win32err), wil::verify_bool(condition)) +#define THROW_LAST_ERROR_IF(condition) __R_FN(Throw_GetLastErrorIf)(__R_INFO(#condition) wil::verify_bool(condition)) +#define THROW_LAST_ERROR_IF_NULL(ptr) __R_FN(Throw_GetLastErrorIfNull)(__R_INFO(#ptr) ptr) +#define THROW_IF_NTSTATUS_FAILED(status) __R_FN(Throw_IfNtStatusFailed)(__R_INFO(#status) status) + +// Always throw a known failure - throw a var-arg message on failure +#define THROW_HR_MSG(hr, fmt, ...) __R_FN(Throw_HrMsg)(__R_INFO(#hr) wil::verify_hresult(hr), fmt, ##__VA_ARGS__) +#define THROW_LAST_ERROR_MSG(fmt, ...) __R_FN(Throw_GetLastErrorMsg)(__R_INFO(nullptr) fmt, ##__VA_ARGS__) +#define THROW_WIN32_MSG(win32err, fmt, ...) __R_FN(Throw_Win32Msg)(__R_INFO(#win32err) win32err, fmt, ##__VA_ARGS__) +#define THROW_EXCEPTION_MSG(exception, fmt, ...) wil::details::ReportFailure_CustomExceptionMsg(__R_INFO(#exception) exception, fmt, ##__VA_ARGS__) +#define THROW_NTSTATUS_MSG(status, fmt, ...) __R_FN(Throw_NtStatusMsg)(__R_INFO(#status) status, fmt, ##__VA_ARGS__) + +// Conditionally throw failures - returns parameter value - throw a var-arg message on failure +#define THROW_IF_FAILED_MSG(hr, fmt, ...) __R_FN(Throw_IfFailedMsg)(__R_INFO(#hr) wil::verify_hresult(hr), fmt, ##__VA_ARGS__) +#define THROW_IF_WIN32_BOOL_FALSE_MSG(win32BOOL, fmt, ...) __R_FN(Throw_IfWin32BoolFalseMsg)(__R_INFO(#win32BOOL) wil::verify_BOOL(win32BOOL), fmt, ##__VA_ARGS__) +#define THROW_IF_WIN32_ERROR_MSG(win32err, fmt, ...) __R_FN(Throw_IfWin32ErrorMsg)(__R_INFO(#win32err) win32err, fmt, ##__VA_ARGS__) +#define THROW_IF_NULL_ALLOC_MSG(ptr, fmt, ...) __R_FN(Throw_IfNullAllocMsg)(__R_INFO(#ptr) ptr, fmt, ##__VA_ARGS__) +#define THROW_HR_IF_MSG(hr, condition, fmt, ...) __R_FN(Throw_HrIfMsg)(__R_INFO(#condition) wil::verify_hresult(hr), wil::verify_bool(condition), fmt, ##__VA_ARGS__) +#define THROW_HR_IF_NULL_MSG(hr, ptr, fmt, ...) __R_FN(Throw_HrIfNullMsg)(__R_INFO(#ptr) wil::verify_hresult(hr), ptr, fmt, ##__VA_ARGS__) +#define THROW_WIN32_IF_MSG(win32err, condition, fmt, ...) __R_FN(Throw_Win32IfMsg)(__R_INFO(#condition) wil::verify_win32(win32err), wil::verify_bool(condition), fmt, ##__VA_ARGS__) +#define THROW_LAST_ERROR_IF_MSG(condition, fmt, ...) __R_FN(Throw_GetLastErrorIfMsg)(__R_INFO(#condition) wil::verify_bool(condition), fmt, ##__VA_ARGS__) +#define THROW_LAST_ERROR_IF_NULL_MSG(ptr, fmt, ...) __R_FN(Throw_GetLastErrorIfNullMsg)(__R_INFO(#ptr) ptr, fmt, ##__VA_ARGS__) +#define THROW_IF_NTSTATUS_FAILED_MSG(status, fmt, ...) __R_FN(Throw_IfNtStatusFailedMsg)(__R_INFO(#status) status, fmt, ##__VA_ARGS__) + + +//***************************************************************************** +// Macros to catch and convert exceptions on failure +//***************************************************************************** + +// Use these macros *within* a catch (...) block to handle exceptions +#define RETURN_CAUGHT_EXCEPTION() return __R_FN(Return_CaughtException)(__R_INFO_ONLY(nullptr)) +#define RETURN_CAUGHT_EXCEPTION_MSG(fmt, ...) return __R_FN(Return_CaughtExceptionMsg)(__R_INFO(nullptr) fmt, ##__VA_ARGS__) +#define RETURN_CAUGHT_EXCEPTION_EXPECTED() return wil::ResultFromCaughtException() +#define LOG_CAUGHT_EXCEPTION() __R_FN(Log_CaughtException)(__R_INFO_ONLY(nullptr)) +#define LOG_CAUGHT_EXCEPTION_MSG(fmt, ...) __R_FN(Log_CaughtExceptionMsg)(__R_INFO(nullptr) fmt, ##__VA_ARGS__) +#define FAIL_FAST_CAUGHT_EXCEPTION() __R_FN(FailFast_CaughtException)(__R_INFO_ONLY(nullptr)) +#define FAIL_FAST_CAUGHT_EXCEPTION_MSG(fmt, ...) __R_FN(FailFast_CaughtExceptionMsg)(__R_INFO(nullptr) fmt, ##__VA_ARGS__) +#define THROW_NORMALIZED_CAUGHT_EXCEPTION() __R_FN(Throw_CaughtException)(__R_INFO_ONLY(nullptr)) +#define THROW_NORMALIZED_CAUGHT_EXCEPTION_MSG(fmt, ...) __R_FN(Throw_CaughtExceptionMsg)(__R_INFO(nullptr) fmt, ##__VA_ARGS__) + +// Use these macros in place of a catch block to handle exceptions +#define CATCH_RETURN() catch (...) { RETURN_CAUGHT_EXCEPTION(); } +#define CATCH_RETURN_MSG(fmt, ...) catch (...) { RETURN_CAUGHT_EXCEPTION_MSG(fmt, ##__VA_ARGS__); } +#define CATCH_RETURN_EXPECTED() catch (...) { RETURN_CAUGHT_EXCEPTION_EXPECTED(); } +#define CATCH_LOG() catch (...) { LOG_CAUGHT_EXCEPTION(); } +// Use CATCH_LOG_RETURN instead of CATCH_LOG in a function-try block around a destructor. CATCH_LOG in this specific case has an implicit throw at the end of scope. +// Due to a bug (DevDiv 441931), Warning 4297 (function marked noexcept throws exception) is detected even when the throwing code is unreachable, such as the end of scope after a return, in function-level catch. +#define CATCH_LOG_RETURN() catch (...) { __pragma(warning(suppress : 4297)); LOG_CAUGHT_EXCEPTION(); return; } +#define CATCH_LOG_MSG(fmt, ...) catch (...) { LOG_CAUGHT_EXCEPTION_MSG(fmt, ##__VA_ARGS__); } +// Likewise use CATCH_LOG_RETURN_MSG instead of CATCH_LOG_MSG in function-try blocks around destructors. +#define CATCH_LOG_RETURN_MSG(fmt, ...) catch (...) { __pragma(warning(suppress : 4297)); LOG_CAUGHT_EXCEPTION_MSG(fmt, ##__VA_ARGS__); return; } +#define CATCH_FAIL_FAST() catch (...) { FAIL_FAST_CAUGHT_EXCEPTION(); } +#define CATCH_FAIL_FAST_MSG(fmt, ...) catch (...) { FAIL_FAST_CAUGHT_EXCEPTION_MSG(fmt, ##__VA_ARGS__); } +#define CATCH_THROW_NORMALIZED() catch (...) { THROW_NORMALIZED_CAUGHT_EXCEPTION(); } +#define CATCH_THROW_NORMALIZED_MSG(fmt, ...) catch (...) { THROW_NORMALIZED_CAUGHT_EXCEPTION_MSG(fmt, ##__VA_ARGS__); } +#define CATCH_LOG_RETURN_HR(hr) catch (...) { LOG_CAUGHT_EXCEPTION(); return hr; } + +#endif // WIL_ENABLE_EXCEPTIONS + +// Use this macro to supply diagnostics information to wil::ResultFromException +#define WI_DIAGNOSTICS_INFO wil::DiagnosticsInfo(__R_CALLERADDRESS_VALUE, __R_LINE_VALUE, __R_FILE_VALUE) +#define WI_DIAGNOSTICS_NAME(name) wil::DiagnosticsInfo(__R_CALLERADDRESS_VALUE, __R_LINE_VALUE, __R_FILE_VALUE, name) + + + +//***************************************************************************** +// Usage Error Macros +//***************************************************************************** + +#ifndef WI_USAGE_ASSERT_STOP +#define WI_USAGE_ASSERT_STOP(condition) WI_ASSERT(condition) +#endif +#ifdef RESULT_DEBUG +#define WI_USAGE_ERROR(msg, ...) do { LOG_HR_MSG(HRESULT_FROM_WIN32(ERROR_ASSERTION_FAILURE), msg, ##__VA_ARGS__); WI_USAGE_ASSERT_STOP(false); } while ((void)0, 0) +#define WI_USAGE_ERROR_FORWARD(msg, ...) do { ReportFailure_ReplaceMsg(__R_FN_CALL_FULL, HRESULT_FROM_WIN32(ERROR_ASSERTION_FAILURE), msg, ##__VA_ARGS__); WI_USAGE_ASSERT_STOP(false); } while ((void)0, 0) +#else +#define WI_USAGE_ERROR(msg, ...) do { LOG_HR(HRESULT_FROM_WIN32(ERROR_ASSERTION_FAILURE)); WI_USAGE_ASSERT_STOP(false); } while ((void)0, 0) +#define WI_USAGE_ERROR_FORWARD(msg, ...) do { ReportFailure_Hr(__R_FN_CALL_FULL, HRESULT_FROM_WIN32(ERROR_ASSERTION_FAILURE)); WI_USAGE_ASSERT_STOP(false); } while ((void)0, 0) +#endif +#define WI_USAGE_VERIFY(condition, msg, ...) do { const auto __passed = wil::verify_bool(condition); if (!__passed) { WI_USAGE_ERROR(msg, ##__VA_ARGS__); }} while ((void)0, 0) +#define WI_USAGE_VERIFY_FORWARD(condition, msg, ...) do { const auto __passed = wil::verify_bool(condition); if (!__passed) { WI_USAGE_ERROR_FORWARD(msg, ##__VA_ARGS__); }} while ((void)0, 0) +#ifdef RESULT_DEBUG +#define WI_USAGE_ASSERT(condition, msg, ...) WI_USAGE_VERIFY(condition, msg, ##__VA_ARGS__) +#else +#define WI_USAGE_ASSERT(condition, msg, ...) +#endif + +//***************************************************************************** +// Internal Error Macros - DO NOT USE - these are for internal WIL use only to reduce sizes of binaries that use WIL +//***************************************************************************** +#ifdef RESULT_DEBUG +#define __WIL_PRIVATE_RETURN_IF_FAILED(hr) RETURN_IF_FAILED(hr) +#define __WIL_PRIVATE_RETURN_HR_IF(hr, cond) RETURN_HR_IF(hr, cond) +#define __WIL_PRIVATE_RETURN_LAST_ERROR_IF(cond) RETURN_LAST_ERROR_IF(cond) +#define __WIL_PRIVATE_RETURN_IF_WIN32_BOOL_FALSE(win32BOOL) RETURN_IF_WIN32_BOOL_FALSE(win32BOOL) +#define __WIL_PRIVATE_RETURN_LAST_ERROR_IF_NULL(ptr) RETURN_LAST_ERROR_IF_NULL(ptr) +#define __WIL_PRIVATE_RETURN_IF_NULL_ALLOC(ptr) RETURN_IF_NULL_ALLOC(ptr) +#define __WIL_PRIVATE_RETURN_LAST_ERROR() RETURN_LAST_ERROR() +#define __WIL_PRIVATE_FAIL_FAST_HR_IF(hr, condition) FAIL_FAST_HR_IF(hr, condition) +#define __WIL_PRIVATE_FAIL_FAST_HR(hr) FAIL_FAST_HR(hr) +#define __WIL_PRIVATE_LOG_HR(hr) LOG_HR(hr) +#else +#define __WIL_PRIVATE_RETURN_IF_FAILED(hr) do { const auto __hrRet = wil::verify_hresult(hr); if (FAILED(__hrRet)) { __RETURN_HR_FAIL_NOFILE(__hrRet, #hr); }} while ((void)0, 0) +#define __WIL_PRIVATE_RETURN_HR_IF(hr, cond) do { if (wil::verify_bool(cond)) { __RETURN_HR_NOFILE(wil::verify_hresult(hr), #cond); }} while ((void)0, 0) +#define __WIL_PRIVATE_RETURN_LAST_ERROR_IF(cond) do { if (wil::verify_bool(cond)) { __RETURN_GLE_FAIL_NOFILE(#cond); }} while ((void)0, 0) +#define __WIL_PRIVATE_RETURN_IF_WIN32_BOOL_FALSE(win32BOOL) do { const BOOL __boolRet = wil::verify_BOOL(win32BOOL); if (!__boolRet) { __RETURN_GLE_FAIL_NOFILE(#win32BOOL); }} while ((void)0, 0) +#define __WIL_PRIVATE_RETURN_LAST_ERROR_IF_NULL(ptr) do { if ((ptr) == nullptr) { __RETURN_GLE_FAIL_NOFILE(#ptr); }} while ((void)0, 0) +#define __WIL_PRIVATE_RETURN_IF_NULL_ALLOC(ptr) do { if ((ptr) == nullptr) { __RETURN_HR_FAIL_NOFILE(E_OUTOFMEMORY, #ptr); }} while ((void)0, 0) +#define __WIL_PRIVATE_RETURN_LAST_ERROR() __RETURN_GLE_FAIL_NOFILE(nullptr) +#define __WIL_PRIVATE_FAIL_FAST_HR_IF(hr, condition) __RFF_FN(FailFast_HrIf)(__RFF_INFO_NOFILE(#condition) wil::verify_hresult(hr), wil::verify_bool(condition)) +#define __WIL_PRIVATE_FAIL_FAST_HR(hr) __RFF_FN(FailFast_Hr)(__RFF_INFO_NOFILE(#hr) wil::verify_hresult(hr)) +#define __WIL_PRIVATE_LOG_HR(hr) __R_FN(Log_Hr)(__R_INFO_NOFILE(#hr) wil::verify_hresult(hr)) +#endif + +namespace wil +{ + // Indicates the kind of message / failure type that was used to produce a given error + enum class FailureType + { + Exception, // THROW_... + Return, // RETURN_..._LOG or RETURN_..._MSG + Log, // LOG_... + FailFast // FAIL_FAST_... + }; + + enum class FailureFlags + { + None = 0x00, + RequestFailFast = 0x01, + RequestSuppressTelemetry = 0x02, + RequestDebugBreak = 0x04, + NtStatus = 0x08, + }; + DEFINE_ENUM_FLAG_OPERATORS(FailureFlags); + + /** Use with functions and macros that allow customizing which kinds of exceptions are handled. + This is used with methods like wil::ResultFromException and wil::ResultFromExceptionDebug. */ + enum class SupportedExceptions + { + Default, //!< [Default] all well known exceptions (honors g_fResultFailFastUnknownExceptions). + Known, //!< [Known] all well known exceptions (including std::exception). + All, //!< [All] all exceptions, known or otherwise. + None, //!< [None] no exceptions at all, an exception will fail-fast where thrown. + Thrown, //!< [Thrown] exceptions thrown by wil only (Platform::Exception^ or ResultException). + ThrownOrAlloc //!< [ThrownOrAlloc] exceptions thrown by wil (Platform::Exception^ or ResultException) or std::bad_alloc. + }; + + // Represents the call context information about a given failure + // No constructors, destructors or virtual members should be contained within + struct CallContextInfo + { + long contextId; // incrementing ID for this call context (unique across an individual module load within process) + PCSTR contextName; // the explicit name given to this context + PCWSTR contextMessage; // [optional] Message that can be associated with the call context + }; + + // Represents all context information about a given failure + // No constructors, destructors or virtual members should be contained within + struct FailureInfo + { + FailureType type; + FailureFlags flags; + HRESULT hr; + NTSTATUS status; + long failureId; // incrementing ID for this specific failure (unique across an individual module load within process) + PCWSTR pszMessage; // Message is only present for _MSG logging (it's the Sprintf message) + DWORD threadId; // the thread this failure was originally encountered on + PCSTR pszCode; // [debug only] Capture code from the macro + PCSTR pszFunction; // [debug only] The function name + PCSTR pszFile; + unsigned int uLineNumber; + int cFailureCount; // How many failures of 'type' have been reported in this module so far + PCSTR pszCallContext; // General breakdown of the call context stack that generated this failure + CallContextInfo callContextOriginating; // The outermost (first seen) call context + CallContextInfo callContextCurrent; // The most recently seen call context + PCSTR pszModule; // The module where the failure originated + void* returnAddress; // The return address to the point that called the macro + void* callerReturnAddress; // The return address of the function that includes the macro + }; + + //! Created automatically from using WI_DIAGNOSTICS_INFO to provide diagnostics to functions. + //! Note that typically wil hides diagnostics from users under the covers by passing them automatically to functions as + //! parameters hidden behind a macro. In some cases, the user needs to directly supply these, so this class provides + //! the mechanism for that. We only use this for user-passed content as it can't be directly controlled by RESULT_DIAGNOSTICS_LEVEL + //! to ensure there are no ODR violations (though that variable still controls what parameters within this structure would be available). + struct DiagnosticsInfo + { + void* returnAddress = nullptr; + PCSTR file = nullptr; + PCSTR name = nullptr; + unsigned short line = 0; + + DiagnosticsInfo() = default; + + __forceinline DiagnosticsInfo(void* returnAddress_, unsigned short line_, PCSTR file_) : + returnAddress(returnAddress_), + file(file_), + line(line_) + { + } + + __forceinline DiagnosticsInfo(void* returnAddress_, unsigned short line_, PCSTR file_, PCSTR name_) : + returnAddress(returnAddress_), + file(file_), + name(name_), + line(line_) + { + } + }; + + enum class ErrorReturn + { + Auto, + None + }; + + // [optionally] Plug in error logging + // Note: This callback is deprecated. Please use SetResultTelemetryFallback for telemetry or + // SetResultLoggingCallback for observation. + extern "C" __declspec(selectany) void(__stdcall *g_pfnResultLoggingCallback)(_Inout_ wil::FailureInfo *pFailure, _Inout_updates_opt_z_(cchDebugMessage) PWSTR pszDebugMessage, _Pre_satisfies_(cchDebugMessage > 0) size_t cchDebugMessage) WI_PFN_NOEXCEPT = nullptr; + + // [optional] + // This can be explicitly set to control whether or not error messages will be output to OutputDebugString. It can also + // be set directly from within the debugger to force console logging for debugging purposes. + __declspec(selectany) bool g_fResultOutputDebugString = true; + + // [optionally] Allows application to specify a debugger to detect whether a debugger is present. + // Useful for processes that can only be debugged under kernel debuggers where IsDebuggerPresent returns + // false. + __declspec(selectany) bool(__stdcall *g_pfnIsDebuggerPresent)() WI_PFN_NOEXCEPT = nullptr; + + // [optionally] Allows forcing WIL to believe a debugger is present. Useful for when a kernel debugger is attached and ::IsDebuggerPresent returns false + __declspec(selectany) bool g_fIsDebuggerPresent = false; + + // [optionally] Plug in additional exception-type support (return S_OK when *unable* to remap the exception) + __declspec(selectany) HRESULT(__stdcall *g_pfnResultFromCaughtException)() WI_PFN_NOEXCEPT = nullptr; + + // [optionally] Use to configure fast fail of unknown exceptions (turn them off). + __declspec(selectany) bool g_fResultFailFastUnknownExceptions = true; + + // [optionally] Set to false to a configure all THROW_XXX macros in C++/CX to throw ResultException rather than Platform::Exception^ + __declspec(selectany) bool g_fResultThrowPlatformException = true; + + // [optionally] Set to false to a configure all CATCH_ and CAUGHT_ macros to NOT support (fail-fast) std::exception based exceptions (other than std::bad_alloc and wil::ResultException) + __declspec(selectany) bool g_fResultSupportStdException = true; + + // [optionally] Set to true to cause a debug break to occur on a result failure + __declspec(selectany) bool g_fBreakOnFailure = false; + + // [optionally] customize failfast behavior + __declspec(selectany) bool(__stdcall *g_pfnWilFailFast)(const wil::FailureInfo& info) WI_PFN_NOEXCEPT = nullptr; + + /// @cond + namespace details + { + // True if g_pfnResultLoggingCallback is set (allows cutting off backwards compat calls to the function) + __declspec(selectany) bool g_resultMessageCallbackSet = false; + + // On Desktop/System WINAPI family: convert NTSTATUS error codes to friendly name strings. + __declspec(selectany) void(__stdcall *g_pfnFormatNtStatusMsg)(NTSTATUS, PWSTR, DWORD) = nullptr; + + _Success_(true) _Ret_range_(dest, destEnd) + inline PWSTR LogStringPrintf(_Out_writes_to_ptr_(destEnd) _Always_(_Post_z_) PWSTR dest, _Pre_satisfies_(destEnd >= dest) PCWSTR destEnd, _In_ _Printf_format_string_ PCWSTR format, ...) + { + va_list argList; + va_start(argList, format); + StringCchVPrintfW(dest, (destEnd - dest), format, argList); + return (destEnd == dest) ? dest : (dest + wcslen(dest)); + } + } + /// @endcond + + // This call generates the default logging string that makes its way to OutputDebugString for + // any particular failure. This string is also used to associate a failure with a PlatformException^ which + // only allows a single string to be associated with the exception. + inline HRESULT GetFailureLogString(_Out_writes_(cchDest) _Always_(_Post_z_) PWSTR pszDest, _Pre_satisfies_(cchDest > 0) _In_ size_t cchDest, _In_ FailureInfo const &failure) WI_NOEXCEPT + { + // This function was lenient to empty strings at one point and some callers became dependent on this beahvior + if ((cchDest == 0) || (pszDest == nullptr)) + { + return S_OK; + } + + pszDest[0] = L'\0'; + + // Call the logging callback (if present) to allow them to generate the debug string that will be pushed to the console + // or the platform exception object if the caller desires it. + if ((g_pfnResultLoggingCallback != nullptr) && details::g_resultMessageCallbackSet) + { + // older-form callback was a non-const FailureInfo*; conceptually this is const as callers should not be modifying + g_pfnResultLoggingCallback(const_cast(&failure), pszDest, cchDest); + } + + // The callback only optionally needs to supply the debug string -- if the callback didn't populate it, yet we still want + // it for OutputDebugString or exception message, then generate the default string. + if (pszDest[0] == L'\0') + { + PCSTR pszType = ""; + switch (failure.type) + { + case FailureType::Exception: + pszType = "Exception"; + break; + case FailureType::Return: + if (WI_IsFlagSet(failure.flags, FailureFlags::NtStatus)) + { + pszType = "ReturnNt"; + } + else + { + pszType = "ReturnHr"; + } + break; + case FailureType::Log: + if (WI_IsFlagSet(failure.flags, FailureFlags::NtStatus)) + { + pszType = "LogNt"; + } + else + { + pszType = "LogHr"; + } + break; + case FailureType::FailFast: + pszType = "FailFast"; + break; + } + + wchar_t szErrorText[256]{}; + szErrorText[0] = L'\0'; + LONG errorCode = 0; + + if (WI_IsFlagSet(failure.flags, FailureFlags::NtStatus)) + { + errorCode = failure.status; + if (wil::details::g_pfnFormatNtStatusMsg) + { + wil::details::g_pfnFormatNtStatusMsg(failure.status, szErrorText, ARRAYSIZE(szErrorText)); + } + } + else + { + errorCode = failure.hr; + FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, failure.hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), szErrorText, ARRAYSIZE(szErrorText), nullptr); + } + + // %FILENAME(%LINE): %TYPE(%count) tid(%threadid) %HRESULT %SystemMessage + // %Caller_MSG [%CODE(%FUNCTION)] + + PWSTR dest = pszDest; + PCWSTR destEnd = (pszDest + cchDest); + + if (failure.pszFile != nullptr) + { + dest = details::LogStringPrintf(dest, destEnd, L"%hs(%u)\\%hs!%p: ", failure.pszFile, failure.uLineNumber, failure.pszModule, failure.returnAddress); + } + else + { + dest = details::LogStringPrintf(dest, destEnd, L"%hs!%p: ", failure.pszModule, failure.returnAddress); + } + + if (failure.callerReturnAddress != nullptr) + { + dest = details::LogStringPrintf(dest, destEnd, L"(caller: %p) ", failure.callerReturnAddress); + } + + dest = details::LogStringPrintf(dest, destEnd, L"%hs(%d) tid(%x) %08X %ws", pszType, failure.cFailureCount, ::GetCurrentThreadId(), errorCode, szErrorText); + + if ((failure.pszMessage != nullptr) || (failure.pszCallContext != nullptr) || (failure.pszFunction != nullptr)) + { + dest = details::LogStringPrintf(dest, destEnd, L" "); + if (failure.pszMessage != nullptr) + { + dest = details::LogStringPrintf(dest, destEnd, L"Msg:[%ws] ", failure.pszMessage); + } + if (failure.pszCallContext != nullptr) + { + dest = details::LogStringPrintf(dest, destEnd, L"CallContext:[%hs] ", failure.pszCallContext); + } + + if (failure.pszCode != nullptr) + { + dest = details::LogStringPrintf(dest, destEnd, L"[%hs(%hs)]\n", failure.pszFunction, failure.pszCode); + } + else if (failure.pszFunction != nullptr) + { + dest = details::LogStringPrintf(dest, destEnd, L"[%hs]\n", failure.pszFunction); + } + else + { + dest = details::LogStringPrintf(dest, destEnd, L"\n"); + } + } + } + + // Explicitly choosing to return success in the event of truncation... Current callers + // depend upon it or it would be eliminated. + return S_OK; + } + + /// @cond + namespace details + { + //! Interface used to wrap up code (generally a lambda or other functor) to run in an exception-managed context where + //! exceptions or errors can be observed and logged. + struct IFunctor + { + virtual HRESULT Run() = 0; + }; + + //! Used to provide custom behavior when an exception is encountered while executing IFunctor + struct IFunctorHost + { + virtual HRESULT Run(IFunctor& functor) = 0; + virtual HRESULT ExceptionThrown(void* returnAddress) = 0; + }; + + __declspec(noinline) inline HRESULT NtStatusToHr(NTSTATUS status) WI_NOEXCEPT; + __declspec(noinline) inline NTSTATUS HrToNtStatus(HRESULT) WI_NOEXCEPT; + + struct ResultStatus + { + enum Kind : unsigned int { HResult, NtStatus }; + + static ResultStatus FromResult(const HRESULT _hr) + { + return { _hr, wil::details::HrToNtStatus(_hr), Kind::HResult }; + } + static ResultStatus FromStatus(const NTSTATUS _status) + { + return { wil::details::NtStatusToHr(_status), _status, Kind::NtStatus }; + } + static ResultStatus FromFailureInfo(const FailureInfo& _failure) + { + return { _failure.hr, _failure.status, WI_IsFlagSet(_failure.flags, FailureFlags::NtStatus) ? Kind::NtStatus : Kind::HResult }; + } + HRESULT hr = S_OK; + NTSTATUS status = STATUS_SUCCESS; + Kind kind = Kind::NtStatus; + }; + + // Fallback telemetry provider callback (set with wil::SetResultTelemetryFallback) + __declspec(selectany) void(__stdcall *g_pfnTelemetryCallback)(bool alreadyReported, wil::FailureInfo const &failure) WI_PFN_NOEXCEPT = nullptr; + + // Result.h plug-in (WIL use only) + __declspec(selectany) void(__stdcall* g_pfnNotifyFailure)(_Inout_ FailureInfo* pFailure) WI_PFN_NOEXCEPT = nullptr; + __declspec(selectany) void(__stdcall *g_pfnGetContextAndNotifyFailure)(_Inout_ FailureInfo *pFailure, _Out_writes_(callContextStringLength) _Post_z_ PSTR callContextString, _Pre_satisfies_(callContextStringLength > 0) size_t callContextStringLength) WI_PFN_NOEXCEPT = nullptr; + + // Observe all errors flowing through the system with this callback (set with wil::SetResultLoggingCallback); use with custom logging + __declspec(selectany) void(__stdcall *g_pfnLoggingCallback)(wil::FailureInfo const &failure) WI_PFN_NOEXCEPT = nullptr; + + // Desktop/System Only: Module fetch function (automatically setup) + __declspec(selectany) PCSTR(__stdcall *g_pfnGetModuleName)() WI_PFN_NOEXCEPT = nullptr; + + // Desktop/System Only: Retrieve address offset and modulename + __declspec(selectany) bool(__stdcall *g_pfnGetModuleInformation)(void* address, _Out_opt_ unsigned int* addressOffset, _Out_writes_bytes_opt_(size) char* name, size_t size) WI_PFN_NOEXCEPT = nullptr; + + // Called with the expectation that the program will terminate when called inside of a loader callout. + // Desktop/System Only: Automatically setup when building Windows (BUILD_WINDOWS defined) + __declspec(selectany) void(__stdcall *g_pfnFailFastInLoaderCallout)() WI_PFN_NOEXCEPT = nullptr; + + // Called to translate an NTSTATUS value to a Win32 error code + // Desktop/System Only: Automatically setup when building Windows (BUILD_WINDOWS defined) + __declspec(selectany) ULONG(__stdcall *g_pfnRtlNtStatusToDosErrorNoTeb)(NTSTATUS) WI_PFN_NOEXCEPT = nullptr; + + // Desktop/System Only: Call to DebugBreak + __declspec(selectany) void(__stdcall *g_pfnDebugBreak)() WI_PFN_NOEXCEPT = nullptr; + + // Called to determine whether or not termination is happening + // Desktop/System Only: Automatically setup when building Windows (BUILD_WINDOWS defined) + __declspec(selectany) BOOLEAN(__stdcall *g_pfnDllShutdownInProgress)() WI_PFN_NOEXCEPT = nullptr; + __declspec(selectany) bool g_processShutdownInProgress = false; + + // On Desktop/System WINAPI family: dynalink RaiseFailFastException because we may encounter modules + // that do not have RaiseFailFastException in kernelbase. UWP apps will directly link. + __declspec(selectany) void (__stdcall *g_pfnRaiseFailFastException)(PEXCEPTION_RECORD,PCONTEXT,DWORD) = nullptr; + + // Exception-based compiled additions + __declspec(selectany) HRESULT(__stdcall *g_pfnRunFunctorWithExceptionFilter)(IFunctor& functor, IFunctorHost& host, void* returnAddress) = nullptr; + __declspec(selectany) void(__stdcall *g_pfnRethrow)() = nullptr; + __declspec(selectany) void(__stdcall *g_pfnThrowResultException)(const FailureInfo& failure) = nullptr; + extern "C" __declspec(selectany) ResultStatus(__stdcall *g_pfnResultFromCaughtExceptionInternal)(_Out_writes_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars, _Out_ bool* isNormalized) WI_PFN_NOEXCEPT = nullptr; + + // C++/WinRT additions + extern "C" __declspec(selectany) HRESULT(__stdcall *g_pfnResultFromCaughtException_CppWinRt)(_Out_writes_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars, _Out_ bool* isNormalized) WI_PFN_NOEXCEPT = nullptr; + + // C++/cx compiled additions + extern "C" __declspec(selectany) void(__stdcall *g_pfnThrowPlatformException)(FailureInfo const &failure, PCWSTR debugString) = nullptr; + extern "C" __declspec(selectany) _Always_(_Post_satisfies_(return < 0)) HRESULT(__stdcall *g_pfnResultFromCaughtException_WinRt)(_Inout_updates_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars, _Out_ bool* isNormalized) WI_PFN_NOEXCEPT = nullptr; + __declspec(selectany) _Always_(_Post_satisfies_(return < 0)) HRESULT(__stdcall *g_pfnResultFromKnownExceptions_WinRt)(const DiagnosticsInfo& diagnostics, void* returnAddress, SupportedExceptions supported, IFunctor& functor) = nullptr; + + // Plugin to call RoOriginateError (WIL use only) + __declspec(selectany) void(__stdcall *g_pfnOriginateCallback)(wil::FailureInfo const& failure) WI_PFN_NOEXCEPT = nullptr; + + // Plugin to call RoFailFastWithErrorContext (WIL use only) + __declspec(selectany) void(__stdcall* g_pfnFailfastWithContextCallback)(wil::FailureInfo const& failure) WI_PFN_NOEXCEPT = nullptr; + + + // Allocate and disown the allocation so that Appverifier does not complain about a false leak + inline PVOID ProcessHeapAlloc(_In_ DWORD flags, _In_ size_t size) WI_NOEXCEPT + { + const HANDLE processHeap = ::GetProcessHeap(); + const PVOID allocation = ::HeapAlloc(processHeap, flags, size); + + static bool fetchedRtlDisownModuleHeapAllocation = false; + static NTSTATUS (__stdcall *pfnRtlDisownModuleHeapAllocation)(HANDLE, PVOID) WI_PFN_NOEXCEPT = nullptr; + + if (pfnRtlDisownModuleHeapAllocation) + { + (void)pfnRtlDisownModuleHeapAllocation(processHeap, allocation); + } + else if (!fetchedRtlDisownModuleHeapAllocation) + { + if (auto ntdllModule = ::GetModuleHandleW(L"ntdll.dll")) + { + pfnRtlDisownModuleHeapAllocation = reinterpret_cast(::GetProcAddress(ntdllModule, "RtlDisownModuleHeapAllocation")); + } + fetchedRtlDisownModuleHeapAllocation = true; + + if (pfnRtlDisownModuleHeapAllocation) + { + (void)pfnRtlDisownModuleHeapAllocation(processHeap, allocation); + } + } + + return allocation; + } + + enum class ReportFailureOptions + { + None = 0x00, + ForcePlatformException = 0x01, + MayRethrow = 0x02, + }; + DEFINE_ENUM_FLAG_OPERATORS(ReportFailureOptions); + + template + using functor_return_type = decltype((*static_cast(nullptr))()); + + template + struct functor_wrapper_void : public IFunctor + { + TFunctor&& functor; + functor_wrapper_void(TFunctor&& functor_) : functor(wistd::forward(functor_)) { } + #pragma warning(push) + #pragma warning(disable:4702) // https://github.com/Microsoft/wil/issues/2 + HRESULT Run() override + { + functor(); + return S_OK; + } + #pragma warning(pop) + }; + + template + struct functor_wrapper_HRESULT : public IFunctor + { + TFunctor&& functor; + functor_wrapper_HRESULT(TFunctor& functor_) : functor(wistd::forward(functor_)) { } + HRESULT Run() override + { + return functor(); + } + }; + + template + struct functor_wrapper_other : public IFunctor + { + TFunctor&& functor; + TReturn& retVal; + functor_wrapper_other(TFunctor& functor_, TReturn& retval_) : functor(wistd::forward(functor_)), retVal(retval_) { } + #pragma warning(push) + #pragma warning(disable:4702) // https://github.com/Microsoft/wil/issues/2 + HRESULT Run() override + { + retVal = functor(); + return S_OK; + } + #pragma warning(pop) + }; + + struct tag_return_void : public wistd::integral_constant + { + template + using functor_wrapper = functor_wrapper_void; + }; + + struct tag_return_HRESULT : public wistd::integral_constant + { + template + using functor_wrapper = functor_wrapper_HRESULT; + }; + + struct tag_return_other : public wistd::integral_constant + { + template + using functor_wrapper = functor_wrapper_other; + }; + + // type-trait to help discover the return type of a functor for tag/dispatch. + + template + struct return_type + { + using type = tag_return_other; + }; + + template <> + struct return_type + { + using type = tag_return_HRESULT; + }; + + template <> + struct return_type + { + using type = tag_return_void; + }; + + template <> + struct return_type + { + using type = tag_return_void; + }; + + template + using functor_tag = typename return_type>::type; + + // Forward declarations to enable use of fail fast and reporting internally... + namespace __R_NS_NAME + { + _Post_satisfies_(return == hr) __R_DIRECT_METHOD(HRESULT, Log_Hr)(__R_DIRECT_FN_PARAMS HRESULT hr) WI_NOEXCEPT; + _Post_satisfies_(return == hr) __R_DIRECT_METHOD(HRESULT, Log_HrMsg)(__R_DIRECT_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT; + _Post_satisfies_(return == err) __R_DIRECT_METHOD(DWORD, Log_Win32Msg)(__R_DIRECT_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT; + } + namespace __RFF_NS_NAME + { + __RFF_DIRECT_NORET_METHOD(void, FailFast_Unexpected)(__RFF_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT; + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) __RFF_CONDITIONAL_METHOD(bool, FailFast_If)(__RFF_CONDITIONAL_FN_PARAMS bool condition) WI_NOEXCEPT; + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) __RFF_CONDITIONAL_METHOD(bool, FailFast_HrIf)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition) WI_NOEXCEPT; + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) __RFF_CONDITIONAL_METHOD(bool, FailFast_IfFalse)(__RFF_CONDITIONAL_FN_PARAMS bool condition) WI_NOEXCEPT; + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) __RFF_CONDITIONAL_METHOD(bool, FailFastImmediate_If)(bool condition) WI_NOEXCEPT; + } + + RESULT_NORETURN inline void __stdcall WilFailFast(const FailureInfo& info); + inline void LogFailure(__R_FN_PARAMS_FULL, FailureType type, const ResultStatus& resultPair, _In_opt_ PCWSTR message, + bool fWantDebugString, _Out_writes_(debugStringSizeChars) _Post_z_ PWSTR debugString, _Pre_satisfies_(debugStringSizeChars > 0) size_t debugStringSizeChars, + _Out_writes_(callContextStringSizeChars) _Post_z_ PSTR callContextString, _Pre_satisfies_(callContextStringSizeChars > 0) size_t callContextStringSizeChars, + _Out_ FailureInfo *failure) WI_NOEXCEPT; + + __declspec(noinline) inline void ReportFailure(__R_FN_PARAMS_FULL, FailureType type, const ResultStatus& resultPair, _In_opt_ PCWSTR message = nullptr, ReportFailureOptions options = ReportFailureOptions::None); + template + __declspec(noinline) inline void ReportFailure_Base(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, _In_opt_ PCWSTR message = nullptr, ReportFailureOptions options = ReportFailureOptions::None); + template + inline void ReportFailure_ReplaceMsg(__R_FN_PARAMS_FULL, HRESULT hr, _Printf_format_string_ PCSTR formatString, ...); + __declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, FailureType type, HRESULT hr); + template + __declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr); + template + __declspec(noinline) inline HRESULT ReportFailure_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported = SupportedExceptions::Default); + + //***************************************************************************** + // Fail fast helpers (for use only internally to WIL) + //***************************************************************************** + + /// @cond + #define __FAIL_FAST_ASSERT__(condition) do { if (!(condition)) { __RFF_FN(FailFast_Unexpected)(__RFF_INFO_ONLY(#condition)); } } while ((void)0, 0) + #define __FAIL_FAST_IMMEDIATE_ASSERT__(condition) do { if (!(condition)) { wil::FailureInfo failure {}; wil::details::WilFailFast(failure); } } while ((void)0, 0) + #define __FAIL_FAST_ASSERT_WIN32_BOOL_FALSE__(condition) __RFF_FN(FailFast_IfWin32BoolFalse)(__RFF_INFO(#condition) wil::verify_BOOL(condition)) + + // A simple ref-counted buffer class. The interface is very similar to shared_ptr<>, only it manages + // an allocated buffer and maintains the size. + + class shared_buffer + { + public: + shared_buffer() WI_NOEXCEPT : m_pCopy(nullptr), m_size(0) + { + } + + shared_buffer(shared_buffer const &other) WI_NOEXCEPT : m_pCopy(nullptr), m_size(0) + { + assign(other.m_pCopy, other.m_size); + } + + shared_buffer(shared_buffer &&other) WI_NOEXCEPT : + m_pCopy(other.m_pCopy), + m_size(other.m_size) + { + other.m_pCopy = nullptr; + other.m_size = 0; + } + + ~shared_buffer() WI_NOEXCEPT + { + reset(); + } + + shared_buffer& operator=(shared_buffer const &other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + assign(other.m_pCopy, other.m_size); + } + return *this; + } + + shared_buffer& operator=(shared_buffer &&other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + m_pCopy = other.m_pCopy; + m_size = other.m_size; + other.m_pCopy = nullptr; + other.m_size = 0; + } + return *this; + } + + void reset() WI_NOEXCEPT + { + if (m_pCopy != nullptr) + { + if (0 == ::InterlockedDecrementRelease(m_pCopy)) + { + WIL_FreeMemory(m_pCopy); + } + m_pCopy = nullptr; + m_size = 0; + } + } + + bool create(_In_reads_bytes_opt_(cbData) void const *pData, size_t cbData) WI_NOEXCEPT + { + if (cbData == 0) + { + reset(); + return true; + } + + long *pCopyRefCount = reinterpret_cast(WIL_AllocateMemory(sizeof(long)+cbData)); + if (pCopyRefCount == nullptr) + { + return false; + } + + *pCopyRefCount = 0; + if (pData != nullptr) + { + memcpy_s(pCopyRefCount + 1, cbData, pData, cbData); // +1 to advance past sizeof(long) counter + } + assign(pCopyRefCount, cbData); + return true; + } + + bool create(size_t cbData) WI_NOEXCEPT + { + return create(nullptr, cbData); + } + + WI_NODISCARD void* get(_Out_opt_ size_t *pSize = nullptr) const WI_NOEXCEPT + { + if (pSize != nullptr) + { + *pSize = m_size; + } + return (m_pCopy == nullptr) ? nullptr : (m_pCopy + 1); + } + + WI_NODISCARD size_t size() const WI_NOEXCEPT + { + return m_size; + } + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return (m_pCopy != nullptr); + } + + WI_NODISCARD bool unique() const WI_NOEXCEPT + { + return ((m_pCopy != nullptr) && (*m_pCopy == 1)); + } + + private: + long *m_pCopy; // pointer to allocation: refcount + data + size_t m_size; // size of the data from m_pCopy + + void assign(_In_opt_ long *pCopy, size_t cbSize) WI_NOEXCEPT + { + reset(); + if (pCopy != nullptr) + { + m_pCopy = pCopy; + m_size = cbSize; + ::InterlockedIncrementNoFence(m_pCopy); + } + } + }; + + inline shared_buffer make_shared_buffer_nothrow(_In_reads_bytes_opt_(countBytes) void *pData, size_t countBytes) WI_NOEXCEPT + { + shared_buffer buffer; + buffer.create(pData, countBytes); + return buffer; + } + + inline shared_buffer make_shared_buffer_nothrow(size_t countBytes) WI_NOEXCEPT + { + shared_buffer buffer; + buffer.create(countBytes); + return buffer; + } + + // A small mimic of the STL shared_ptr class, but unlike shared_ptr, a pointer is not attached to the class, but is + // always simply contained within (it cannot be attached or detached). + + template + class shared_object + { + public: + shared_object() WI_NOEXCEPT : m_pCopy(nullptr) + { + } + + shared_object(shared_object const &other) WI_NOEXCEPT : + m_pCopy(other.m_pCopy) + { + if (m_pCopy != nullptr) + { + ::InterlockedIncrementNoFence(&m_pCopy->m_refCount); + } + } + + shared_object(shared_object &&other) WI_NOEXCEPT : + m_pCopy(other.m_pCopy) + { + other.m_pCopy = nullptr; + } + + ~shared_object() WI_NOEXCEPT + { + reset(); + } + + shared_object& operator=(shared_object const &other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + m_pCopy = other.m_pCopy; + if (m_pCopy != nullptr) + { + ::InterlockedIncrementNoFence(&m_pCopy->m_refCount); + } + } + return *this; + } + + shared_object& operator=(shared_object &&other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + m_pCopy = other.m_pCopy; + other.m_pCopy = nullptr; + } + return *this; + } + + void reset() WI_NOEXCEPT + { + if (m_pCopy != nullptr) + { + if (0 == ::InterlockedDecrementRelease(&m_pCopy->m_refCount)) + { + delete m_pCopy; + } + m_pCopy = nullptr; + } + } + + bool create() + { + RefAndObject *pObject = new(std::nothrow) RefAndObject(); + if (pObject == nullptr) + { + return false; + } + reset(); + m_pCopy = pObject; + return true; + } + + template + bool create(param_t &¶m1) + { + RefAndObject *pObject = new(std::nothrow) RefAndObject(wistd::forward(param1)); + if (pObject == nullptr) + { + return false; + } + reset(); + m_pCopy = pObject; + return true; + } + + WI_NODISCARD object_t* get() const WI_NOEXCEPT + { + return (m_pCopy == nullptr) ? nullptr : &m_pCopy->m_object; + } + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return (m_pCopy != nullptr); + } + + WI_NODISCARD bool unique() const WI_NOEXCEPT + { + return ((m_pCopy != nullptr) && (m_pCopy->m_refCount == 1)); + } + + WI_NODISCARD object_t* operator->() const WI_NOEXCEPT + { + return get(); + } + + private: + struct RefAndObject + { + long m_refCount; + object_t m_object; + + RefAndObject() : + m_refCount(1), + m_object() + { + } + + template + RefAndObject(param_t &¶m1) : + m_refCount(1), + m_object(wistd::forward(param1)) + { + } + }; + + RefAndObject *m_pCopy; + }; + + // The following functions are basically the same, but are kept separated to: + // 1) Provide a unique count and last error code per-type + // 2) Avoid merging the types to allow easy debugging (breakpoints, conditional breakpoints based + // upon count of errors from a particular type, etc) +__WI_PUSH_WARNINGS +#if __clang_major__ >= 13 +__WI_CLANG_DISABLE_WARNING(-Wunused-but-set-variable) // s_hrErrorLast used for debugging. We intentionally only assign to it +#endif + __declspec(noinline) inline int RecordException(HRESULT hr) WI_NOEXCEPT + { + static HRESULT volatile s_hrErrorLast = S_OK; + static long volatile s_cErrorCount = 0; + s_hrErrorLast = hr; + return ::InterlockedIncrementNoFence(&s_cErrorCount); + } + + __declspec(noinline) inline int RecordReturn(HRESULT hr) WI_NOEXCEPT + { + static HRESULT volatile s_hrErrorLast = S_OK; + static long volatile s_cErrorCount = 0; + s_hrErrorLast = hr; + return ::InterlockedIncrementNoFence(&s_cErrorCount); + } + + __declspec(noinline) inline int RecordLog(HRESULT hr) WI_NOEXCEPT + { + static HRESULT volatile s_hrErrorLast = S_OK; + static long volatile s_cErrorCount = 0; + s_hrErrorLast = hr; + return ::InterlockedIncrementNoFence(&s_cErrorCount); + } + + __declspec(noinline) inline int RecordFailFast(HRESULT hr) WI_NOEXCEPT + { + static HRESULT volatile s_hrErrorLast = S_OK; + s_hrErrorLast = hr; + return 1; + } +__WI_POP_WARNINGS + + inline RESULT_NORETURN void __stdcall WilRaiseFailFastException(_In_ PEXCEPTION_RECORD er, _In_opt_ PCONTEXT cr, _In_ DWORD flags) + { + // if we managed to load the pointer either through WilDynamicRaiseFailFastException (PARTITION_DESKTOP etc.) + // or via direct linkage (e.g. UWP apps), then use it. + if (g_pfnRaiseFailFastException) + { + g_pfnRaiseFailFastException(er, cr, flags); + } + // if not, as a best effort, we are just going to call the intrinsic. + __fastfail(FAST_FAIL_FATAL_APP_EXIT); + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + inline bool __stdcall GetModuleInformation(_In_opt_ void* address, _Out_opt_ unsigned int* addressOffset, _Out_writes_bytes_opt_(size) char* name, size_t size) WI_NOEXCEPT + { + HMODULE hModule = nullptr; + if (address && !GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(address), &hModule)) + { + assign_to_opt_param(addressOffset, 0U); + return false; + } + if (addressOffset) + { + *addressOffset = address ? static_cast(static_cast(address) - reinterpret_cast(hModule)) : 0; + } + if (name) + { + char modulePath[MAX_PATH]; + if (!GetModuleFileNameA(hModule, modulePath, ARRAYSIZE(modulePath))) + { + return false; + } + + PCSTR start = modulePath + strlen(modulePath); + while ((start > modulePath) && (*(start - 1) != '\\')) + { + start--; + } + StringCchCopyA(name, size, start); + } + return true; + } + + inline PCSTR __stdcall GetCurrentModuleName() WI_NOEXCEPT + { + static char s_szModule[64] = {}; + static volatile bool s_fModuleValid = false; + if (!s_fModuleValid) // Races are acceptable + { + GetModuleInformation(reinterpret_cast(&RecordFailFast), nullptr, s_szModule, ARRAYSIZE(s_szModule)); + s_fModuleValid = true; + } + return s_szModule; + } + + inline void __stdcall DebugBreak() WI_NOEXCEPT + { + ::DebugBreak(); + } + + inline void __stdcall WilDynamicLoadRaiseFailFastException(_In_ PEXCEPTION_RECORD er, _In_ PCONTEXT cr, _In_ DWORD flags) + { + auto k32handle = GetModuleHandleW(L"kernelbase.dll"); + _Analysis_assume_(k32handle != nullptr); + auto pfnRaiseFailFastException = reinterpret_cast(GetProcAddress(k32handle, "RaiseFailFastException")); + if (pfnRaiseFailFastException) + { + pfnRaiseFailFastException(er, cr, flags); + } + } +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + + inline bool __stdcall GetModuleInformationFromAddress(_In_opt_ void* address, _Out_opt_ unsigned int* addressOffset, _Out_writes_bytes_opt_(size) char* buffer, size_t size) WI_NOEXCEPT + { + if (size > 0) + { + assign_to_opt_param(buffer, '\0'); + } + if (addressOffset) + { + *addressOffset = 0; + } + if (g_pfnGetModuleInformation) + { + return g_pfnGetModuleInformation(address, addressOffset, buffer, size); + } + return false; + } + + __declspec(noinline) inline HRESULT NtStatusToHr(NTSTATUS status) WI_NOEXCEPT + { + // The following conversions are the only known incorrect mappings in RtlNtStatusToDosErrorNoTeb + if (SUCCEEDED_NTSTATUS(status)) + { + // All successful status codes have only one hresult equivalent, S_OK + return S_OK; + } + if (status == static_cast(STATUS_NO_MEMORY)) + { + // RtlNtStatusToDosErrorNoTeb maps STATUS_NO_MEMORY to the less popular of two Win32 no memory error codes resulting in an unexpected mapping + return E_OUTOFMEMORY; + } + + if (g_pfnRtlNtStatusToDosErrorNoTeb != nullptr) + { + DWORD err = g_pfnRtlNtStatusToDosErrorNoTeb(status); + + // ERROR_MR_MID_NOT_FOUND indicates a bug in the originator of the error (failure to add a mapping to the Win32 error codes). + // There are known instances of this bug which are unlikely to be fixed soon, and it's always possible that additional instances + // could be added in the future. In these cases, it's better to use HRESULT_FROM_NT rather than returning a meaningless error. + if ((err != 0) && (err != ERROR_MR_MID_NOT_FOUND)) + { + return __HRESULT_FROM_WIN32(err); + } + } + + return HRESULT_FROM_NT(status); + } + + __declspec(noinline) inline NTSTATUS HrToNtStatus(HRESULT hr) WI_NOEXCEPT + { + // Constants taken from ntstatus.h + static constexpr NTSTATUS WIL_STATUS_INVALID_PARAMETER = 0xC000000D; + static constexpr NTSTATUS WIL_STATUS_INTERNAL_ERROR = 0xC00000E5; + static constexpr NTSTATUS WIL_STATUS_INTEGER_OVERFLOW = 0xC0000095; + static constexpr NTSTATUS WIL_STATUS_OBJECT_PATH_NOT_FOUND = 0xC000003A; + static constexpr NTSTATUS WIL_STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034; + static constexpr NTSTATUS WIL_STATUS_NOT_IMPLEMENTED = 0xC0000002; + static constexpr NTSTATUS WIL_STATUS_BUFFER_OVERFLOW = 0x80000005; + static constexpr NTSTATUS WIL_STATUS_IMPLEMENTATION_LIMIT = 0xC000042B; + static constexpr NTSTATUS WIL_STATUS_NO_MORE_MATCHES = 0xC0000273; + static constexpr NTSTATUS WIL_STATUS_ILLEGAL_CHARACTER = 0xC0000161; + static constexpr NTSTATUS WIL_STATUS_UNDEFINED_CHARACTER = 0xC0000163; + static constexpr NTSTATUS WIL_STATUS_BUFFER_TOO_SMALL = 0xC0000023; + static constexpr NTSTATUS WIL_STATUS_DISK_FULL = 0xC000007F; + static constexpr NTSTATUS WIL_STATUS_OBJECT_NAME_INVALID = 0xC0000033; + static constexpr NTSTATUS WIL_STATUS_DLL_NOT_FOUND = 0xC0000135; + static constexpr NTSTATUS WIL_STATUS_REVISION_MISMATCH = 0xC0000059; + static constexpr NTSTATUS WIL_STATUS_XML_PARSE_ERROR = 0xC000A083; + static constexpr HRESULT WIL_E_FAIL = 0x80004005; + + NTSTATUS status = STATUS_SUCCESS; + + switch (hr) + { + case S_OK: + status = STATUS_SUCCESS; + break; + case E_INVALIDARG: + status = WIL_STATUS_INVALID_PARAMETER; + break; + case __HRESULT_FROM_WIN32(ERROR_INTERNAL_ERROR): + status = WIL_STATUS_INTERNAL_ERROR; + break; + case E_OUTOFMEMORY: + status = STATUS_NO_MEMORY; + break; + case __HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW): + status = WIL_STATUS_INTEGER_OVERFLOW; + break; + case __HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND): + status = WIL_STATUS_OBJECT_PATH_NOT_FOUND; + break; + case __HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND): + status = WIL_STATUS_OBJECT_NAME_NOT_FOUND; + break; + case __HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION): + status = WIL_STATUS_NOT_IMPLEMENTED; + break; + case __HRESULT_FROM_WIN32(ERROR_MORE_DATA): + status = WIL_STATUS_BUFFER_OVERFLOW; + break; + case __HRESULT_FROM_WIN32(ERROR_IMPLEMENTATION_LIMIT): + status = WIL_STATUS_IMPLEMENTATION_LIMIT; + break; + case __HRESULT_FROM_WIN32(ERROR_NO_MORE_MATCHES): + status = WIL_STATUS_NO_MORE_MATCHES; + break; + case __HRESULT_FROM_WIN32(ERROR_ILLEGAL_CHARACTER): + status = WIL_STATUS_ILLEGAL_CHARACTER; + break; + case __HRESULT_FROM_WIN32(ERROR_UNDEFINED_CHARACTER): + status = WIL_STATUS_UNDEFINED_CHARACTER; + break; + case __HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER): + status = WIL_STATUS_BUFFER_TOO_SMALL; + break; + case __HRESULT_FROM_WIN32(ERROR_DISK_FULL): + status = WIL_STATUS_DISK_FULL; + break; + case __HRESULT_FROM_WIN32(ERROR_INVALID_NAME): + status = WIL_STATUS_OBJECT_NAME_INVALID; + break; + case __HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND): + status = WIL_STATUS_DLL_NOT_FOUND; + break; + case __HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION): + status = WIL_STATUS_REVISION_MISMATCH; + break; + case WIL_E_FAIL: + status = STATUS_UNSUCCESSFUL; + break; + case __HRESULT_FROM_WIN32(ERROR_XML_PARSE_ERROR): + status = WIL_STATUS_XML_PARSE_ERROR; + break; + case __HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION): + status = STATUS_NONCONTINUABLE_EXCEPTION; + break; + default: + if ((hr & FACILITY_NT_BIT) != 0) + { + status = (hr & ~FACILITY_NT_BIT); + } + else if (HRESULT_FACILITY(hr) == FACILITY_WIN32) + { + status = __NTSTATUS_FROM_WIN32(HRESULT_CODE(hr)); + } + else if (HRESULT_FACILITY(hr) == FACILITY_SSPI) + { + status = ((NTSTATUS)(hr) <= 0 ? ((NTSTATUS)(hr)) : ((NTSTATUS)(((hr) & 0x0000FFFF) | (FACILITY_SSPI << 16) | ERROR_SEVERITY_ERROR))); + } + else + { + status = WIL_STATUS_INTERNAL_ERROR; + } + break; + } + return status; + } + + // The following set of functions all differ only based upon number of arguments. They are unified in their handling + // of data from each of the various error-handling types (fast fail, exceptions, etc.). + _Post_equals_last_error_ + inline DWORD GetLastErrorFail(__R_FN_PARAMS_FULL) WI_NOEXCEPT + { + __R_FN_UNREFERENCED; + auto err = ::GetLastError(); + if (SUCCEEDED_WIN32(err)) + { + // This function should only be called when GetLastError() is set to a FAILURE. + // If you hit this assert (or are reviewing this failure telemetry), then there are one of three issues: + // 1) Your code is using a macro (such as RETURN_IF_WIN32_BOOL_FALSE()) on a function that does not actually + // set the last error (consult MSDN). + // 2) Your macro check against the error is not immediately after the API call. Pushing it later can result + // in another API call between the previous one and the check resetting the last error. + // 3) The API you're calling has a bug in it and does not accurately set the last error (there are a few + // examples here, such as SendMessageTimeout() that don't accurately set the last error). For these, + // please send mail to 'wildisc' when found and work-around with win32errorhelpers. + + WI_USAGE_ERROR_FORWARD("CALLER BUG: Macro usage error detected. GetLastError() does not have an error."); + return ERROR_ASSERTION_FAILURE; + } + return err; + } + + inline __declspec(noinline) DWORD GetLastErrorFail() WI_NOEXCEPT + { + __R_FN_LOCALS_FULL_RA; + return GetLastErrorFail(__R_FN_CALL_FULL); + } + + _Translates_last_error_to_HRESULT_ + inline HRESULT GetLastErrorFailHr(__R_FN_PARAMS_FULL) WI_NOEXCEPT + { + return HRESULT_FROM_WIN32(GetLastErrorFail(__R_FN_CALL_FULL)); + } + + _Translates_last_error_to_HRESULT_ + inline __declspec(noinline) HRESULT GetLastErrorFailHr() WI_NOEXCEPT + { + __R_FN_LOCALS_FULL_RA; + return GetLastErrorFailHr(__R_FN_CALL_FULL); + } + + inline void PrintLoggingMessage(_Out_writes_(cchDest) _Post_z_ PWSTR pszDest, _Pre_satisfies_(cchDest > 0) size_t cchDest, _In_opt_ _Printf_format_string_ PCSTR formatString, _In_opt_ va_list argList) WI_NOEXCEPT + { + if (formatString == nullptr) + { + pszDest[0] = L'\0'; + } + else if (argList == nullptr) + { + StringCchPrintfW(pszDest, cchDest, L"%hs", formatString); + } + else + { + wchar_t szFormatWide[2048]; + StringCchPrintfW(szFormatWide, ARRAYSIZE(szFormatWide), L"%hs", formatString); + StringCchVPrintfW(pszDest, cchDest, szFormatWide, argList); + } + } + +#pragma warning(push) +#pragma warning(disable:__WARNING_RETURNING_BAD_RESULT) + // NOTE: The following two functions are unfortunate copies of strsafe.h functions that have been copied to reduce the friction associated with using + // Result.h and ResultException.h in a build that does not have WINAPI_PARTITION_DESKTOP defined (where these are conditionally enabled). + + static STRSAFEAPI WilStringLengthWorkerA(_In_reads_or_z_(cchMax) STRSAFE_PCNZCH psz, _In_ _In_range_(<= , STRSAFE_MAX_CCH) size_t cchMax, _Out_opt_ _Deref_out_range_(< , cchMax) _Deref_out_range_(<= , _String_length_(psz)) size_t* pcchLength) + { + HRESULT hr = S_OK; + size_t cchOriginalMax = cchMax; + while (cchMax && (*psz != '\0')) + { + psz++; + cchMax--; + } + if (cchMax == 0) + { + // the string is longer than cchMax + hr = STRSAFE_E_INVALID_PARAMETER; + } + if (pcchLength) + { + if (SUCCEEDED(hr)) + { + *pcchLength = cchOriginalMax - cchMax; + } + else + { + *pcchLength = 0; + } + } + return hr; + } + + _Must_inspect_result_ STRSAFEAPI StringCchLengthA(_In_reads_or_z_(cchMax) STRSAFE_PCNZCH psz, _In_ _In_range_(1, STRSAFE_MAX_CCH) size_t cchMax, _Out_opt_ _Deref_out_range_(<, cchMax) _Deref_out_range_(<= , _String_length_(psz)) size_t* pcchLength) + { + HRESULT hr = S_OK; + if ((psz == nullptr) || (cchMax > STRSAFE_MAX_CCH)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + else + { + hr = WilStringLengthWorkerA(psz, cchMax, pcchLength); + } + if (FAILED(hr) && pcchLength) + { + *pcchLength = 0; + } + return hr; + } +#pragma warning(pop) + + _Post_satisfies_(cchDest > 0 && cchDest <= cchMax) static STRSAFEAPI WilStringValidateDestA(_In_reads_opt_(cchDest) STRSAFE_PCNZCH /*pszDest*/, _In_ size_t cchDest, _In_ const size_t cchMax) + { + HRESULT hr = S_OK; + if ((cchDest == 0) || (cchDest > cchMax)) + { + hr = STRSAFE_E_INVALID_PARAMETER; + } + return hr; + } + + _Ret_range_(sizeof(char), (psz == nullptr) ? sizeof(char) : (_String_length_(psz) + sizeof(char))) + inline size_t ResultStringSize(_In_opt_ PCSTR psz) + { return (psz == nullptr) ? sizeof(char) : (strlen(psz) + sizeof(char)); } + + _Ret_range_(sizeof(wchar_t), (psz == nullptr) ? sizeof(wchar_t) : ((_String_length_(psz) + 1) * sizeof(wchar_t))) + inline size_t ResultStringSize(_In_opt_ PCWSTR psz) + { return (psz == nullptr) ? sizeof(wchar_t) : (wcslen(psz) + 1) * sizeof(wchar_t); } + + template + _Ret_range_(pStart, pEnd) inline unsigned char* WriteResultString( + _Pre_satisfies_(pStart <= pEnd) + _When_((pStart == pEnd) || (pszString == nullptr) || (pszString[0] == 0), _In_opt_) + _When_((pStart != pEnd) && (pszString != nullptr) && (pszString[0] != 0), _Out_writes_bytes_opt_(_String_length_(pszString) * sizeof(pszString[0]))) + unsigned char* pStart, _Pre_satisfies_(pEnd >= pStart) unsigned char* pEnd, _In_opt_z_ TString pszString, _Outptr_result_maybenull_z_ TString* ppszBufferString) + { + // No space? Null string? Do nothing. + if ((pStart == pEnd) || !pszString || !*pszString) + { + assign_null_to_opt_param(ppszBufferString); + return pStart; + } + + // Treats the range pStart--pEnd as a memory buffer into which pszString is copied. A pointer to + // the start of the copied string is placed into ppszStringBuffer. If the buffer isn't big enough, + // do nothing, and tell the caller nothing was written. + size_t const stringSize = ResultStringSize(pszString); + size_t const bufferSize = pEnd - pStart; + if (bufferSize < stringSize) + { + assign_null_to_opt_param(ppszBufferString); + return pStart; + } + + memcpy_s(pStart, bufferSize, pszString, stringSize); + assign_to_opt_param(ppszBufferString, reinterpret_cast(pStart));// lgtm[cpp/incorrect-string-type-conversion] False positive - The query is misinterpreting a buffer (char *) with a MBS string, the cast to TString is expected. + return pStart + stringSize; + } + + _Ret_range_(0, (cchMax > 0) ? cchMax - 1 : 0) inline size_t UntrustedStringLength(_In_ PCSTR psz, _In_ size_t cchMax) { size_t cbLength; return SUCCEEDED(wil::details::StringCchLengthA(psz, cchMax, &cbLength)) ? cbLength : 0; } + _Ret_range_(0, (cchMax > 0) ? cchMax - 1 : 0) inline size_t UntrustedStringLength(_In_ PCWSTR psz, _In_ size_t cchMax) { size_t cbLength; return SUCCEEDED(::StringCchLengthW(psz, cchMax, &cbLength)) ? cbLength : 0; } + + template + _Ret_range_(pStart, pEnd) inline unsigned char *GetResultString(_In_reads_to_ptr_opt_(pEnd) unsigned char *pStart, _Pre_satisfies_(pEnd >= pStart) unsigned char *pEnd, _Out_ TString *ppszBufferString) + { + size_t cchLen = UntrustedStringLength(reinterpret_cast(pStart), (pEnd - pStart) / sizeof((*ppszBufferString)[0])); + *ppszBufferString = (cchLen > 0) ? reinterpret_cast(pStart) : nullptr; + auto pReturn = (wistd::min)(pEnd, pStart + ((cchLen + 1) * sizeof((*ppszBufferString)[0]))); + __analysis_assume((pReturn >= pStart) && (pReturn <= pEnd)); + return pReturn; + } + } // details namespace + /// @endcond + + //***************************************************************************** + // WIL result handling initializers + // + // Generally, callers do not need to manually initialize WIL. This header creates + // the appropriate .CRT init section pieces through global objects to ensure that + // WilInitialize... is called before DllMain or main(). + // + // Certain binaries do not link with the CRT or do not support .CRT-section based + // initializers. Those binaries must link only with other static libraries that + // also set RESULT_SUPPRESS_STATIC_INITIALIZERS to ensure no .CRT inits are left, + // and they should call one of the WilInitialize_ResultMacros_??? methods during + // their initialization phase. Skipping this initialization path is OK as well, + // but results in a slightly degraded experience with result reporting. + // + // Calling WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse provides: + // - The name of the current module in wil::FailureInfo::pszModule + // - The name of the returning-to module during wil\staging.h failures + //***************************************************************************** + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + //! Call this method to initialize WIL manually in a module where RESULT_SUPPRESS_STATIC_INITIALIZERS is required. WIL will + //! only use publicly documented APIs. + inline void WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse() + { + details::g_pfnGetModuleName = details::GetCurrentModuleName; + details::g_pfnGetModuleInformation = details::GetModuleInformation; + details::g_pfnDebugBreak = details::DebugBreak; + details::g_pfnRaiseFailFastException = wil::details::WilDynamicLoadRaiseFailFastException; + } + + /// @cond + namespace details + { +#ifndef RESULT_SUPPRESS_STATIC_INITIALIZERS +#if !defined(BUILD_WINDOWS) || defined(WIL_SUPPRESS_PRIVATE_API_USE) + WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse, [] + { + ::wil::WilInitialize_ResultMacros_DesktopOrSystem_SuppressPrivateApiUse(); + return 1; + }); +#endif +#endif + } + /// @endcond +#else // !WINAPI_PARTITION_DESKTOP, !WINAPI_PARTITION_SYSTEM, explicitly assume these modules can direct link + namespace details + { + WI_HEADER_INITITALIZATION_FUNCTION(WilInitialize_ResultMacros_AppOnly, [] + { + g_pfnRaiseFailFastException = ::RaiseFailFastException; + return 1; + }); + } +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + + //***************************************************************************** + // Public Error Handling Helpers + //***************************************************************************** + + //! Call this method to determine if process shutdown is in progress (allows avoiding work during dll unload). + inline bool ProcessShutdownInProgress() + { + return (details::g_processShutdownInProgress || (details::g_pfnDllShutdownInProgress ? details::g_pfnDllShutdownInProgress() : false)); + } + + /** Use this object to wrap an object that wants to prevent its destructor from being run when the process is shutting down, + but the hosting DLL doesn't support CRT initializers (such as kernelbase.dll). The hosting DLL is responsible for calling + Construct() and Destroy() to manually run the constructor and destructor during DLL load & unload. + Upon process shutdown a method (ProcessShutdown()) is called that must be implemented on the object, otherwise the destructor is + called as is typical. */ + template + class manually_managed_shutdown_aware_object + { + public: + manually_managed_shutdown_aware_object() = default; + manually_managed_shutdown_aware_object(manually_managed_shutdown_aware_object const&) = delete; + void operator=(manually_managed_shutdown_aware_object const&) = delete; + + void construct() + { + void* var = &m_raw; + ::new(var) T(); + } + + void destroy() + { + if (ProcessShutdownInProgress()) + { + get().ProcessShutdown(); + } + else + { + (&get())->~T(); + } + } + + //! Retrieves a reference to the contained object + T& get() WI_NOEXCEPT + { + return *reinterpret_cast(&m_raw); + } + + private: + alignas(T) unsigned char m_raw[sizeof(T)]; + }; + + /** Use this object to wrap an object that wants to prevent its destructor from being run when the process is shutting down. + Upon process shutdown a method (ProcessShutdown()) is called that must be implemented on the object, otherwise the destructor is + called as is typical. */ + template + class shutdown_aware_object + { + public: + shutdown_aware_object() + { + m_object.construct(); + } + + ~shutdown_aware_object() + { + m_object.destroy(); + } + + shutdown_aware_object(shutdown_aware_object const&) = delete; + void operator=(shutdown_aware_object const&) = delete; + + //! Retrieves a reference to the contained object + T& get() WI_NOEXCEPT + { + return m_object.get(); + } + + private: + manually_managed_shutdown_aware_object m_object; + }; + + /** Use this object to wrap an object that wants to prevent its destructor from being run when the process is shutting down. */ + template + class object_without_destructor_on_shutdown + { + public: + object_without_destructor_on_shutdown() + { + void* var = &m_raw; + ::new(var) T(); + } + + ~object_without_destructor_on_shutdown() + { + if (!ProcessShutdownInProgress()) + { + get().~T(); + } + } + + object_without_destructor_on_shutdown(object_without_destructor_on_shutdown const&) = delete; + void operator=(object_without_destructor_on_shutdown const&) = delete; + + //! Retrieves a reference to the contained object + T& get() WI_NOEXCEPT + { + return *reinterpret_cast(&m_raw); + } + + private: + alignas(T) unsigned char m_raw[sizeof(T)]{}; + }; + + /** Forward your DLLMain to this function so that WIL can have visibility into whether a DLL unload is because + of termination or normal unload. Note that when g_pfnDllShutdownInProgress is set, WIL attempts to make this + determination on its own without this callback. Suppressing private APIs requires use of this. */ + inline void DLLMain(HINSTANCE, DWORD reason, _In_opt_ LPVOID reserved) + { + if (!details::g_processShutdownInProgress) + { + if ((reason == DLL_PROCESS_DETACH) && (reserved != nullptr)) + { + details::g_processShutdownInProgress = true; + } + } + } + + // [optionally] Plug in fallback telemetry reporting + // Normally, the callback is owned by including ResultLogging.h in the including module. Alternatively a module + // could re-route fallback telemetry to any ONE specific provider by calling this method. + inline void SetResultTelemetryFallback(_In_opt_ decltype(details::g_pfnTelemetryCallback) callbackFunction) + { + // Only ONE telemetry provider can own the fallback telemetry callback. + __FAIL_FAST_IMMEDIATE_ASSERT__((details::g_pfnTelemetryCallback == nullptr) || (callbackFunction == nullptr) || (details::g_pfnTelemetryCallback == callbackFunction)); + details::g_pfnTelemetryCallback = callbackFunction; + } + + // [optionally] Plug in result logging (do not use for telemetry) + // This provides the ability for a module to hook all failures flowing through the system for inspection + // and/or logging. + inline void SetResultLoggingCallback(_In_opt_ decltype(details::g_pfnLoggingCallback) callbackFunction) + { + // Only ONE function can own the result logging callback + __FAIL_FAST_IMMEDIATE_ASSERT__((details::g_pfnLoggingCallback == nullptr) || (callbackFunction == nullptr) || (details::g_pfnLoggingCallback == callbackFunction)); + details::g_pfnLoggingCallback = callbackFunction; + } + + // [optionally] Plug in custom result messages + // There are some purposes that require translating the full information that is known about a failure + // into a message to be logged (either through the console for debugging OR as the message attached + // to a Platform::Exception^). This callback allows a module to format the string itself away from the + // default. + inline void SetResultMessageCallback(_In_opt_ decltype(wil::g_pfnResultLoggingCallback) callbackFunction) + { + // Only ONE function can own the result message callback + __FAIL_FAST_IMMEDIATE_ASSERT__((g_pfnResultLoggingCallback == nullptr) || (callbackFunction == nullptr) || (g_pfnResultLoggingCallback == callbackFunction)); + details::g_resultMessageCallbackSet = true; + g_pfnResultLoggingCallback = callbackFunction; + } + + // [optionally] Plug in exception remapping + // A module can plug a callback in using this function to setup custom exception handling to allow any + // exception type to be converted into an HRESULT from exception barriers. + inline void SetResultFromCaughtExceptionCallback(_In_opt_ decltype(wil::g_pfnResultFromCaughtException) callbackFunction) + { + // Only ONE function can own the exception conversion + __FAIL_FAST_IMMEDIATE_ASSERT__((g_pfnResultFromCaughtException == nullptr) || (callbackFunction == nullptr) || (g_pfnResultFromCaughtException == callbackFunction)); + g_pfnResultFromCaughtException = callbackFunction; + } + + // [optionally] Plug in exception remapping + // This provides the ability for a module to call RoOriginateError in case of a failure. + // Normally, the callback is owned by including result_originate.h in the including module. Alternatively a module + // could re-route error origination callback to its own implementation. + inline void SetOriginateErrorCallback(_In_opt_ decltype(details::g_pfnOriginateCallback) callbackFunction) + { + // Only ONE function can own the error origination callback + __FAIL_FAST_IMMEDIATE_ASSERT__((details::g_pfnOriginateCallback == nullptr) || (callbackFunction == nullptr) || (details::g_pfnOriginateCallback == callbackFunction)); + details::g_pfnOriginateCallback = callbackFunction; + } + + // [optionally] Plug in failfast callback + // This provides the ability for a module to call RoFailFastWithErrorContext in the failfast handler -if- there is stowed + // exception data available. Normally, the callback is owned by including result_originate.h in the including module. + // Alternatively a module could re-route to its own implementation. + inline void SetFailfastWithContextCallback(_In_opt_ decltype(details::g_pfnFailfastWithContextCallback) callbackFunction) + { + // Only ONE function can own the failfast with context callback + __FAIL_FAST_IMMEDIATE_ASSERT__((details::g_pfnFailfastWithContextCallback == nullptr) || (callbackFunction == nullptr) || (details::g_pfnFailfastWithContextCallback == callbackFunction)); + details::g_pfnFailfastWithContextCallback = callbackFunction; + } + + // A RAII wrapper around the storage of a FailureInfo struct (which is normally meant to be consumed + // on the stack or from the caller). The storage of FailureInfo needs to copy some data internally + // for lifetime purposes. + + class StoredFailureInfo + { + public: + StoredFailureInfo() WI_NOEXCEPT + { + ::ZeroMemory(&m_failureInfo, sizeof(m_failureInfo)); + } + + StoredFailureInfo(FailureInfo const &other) WI_NOEXCEPT + { + SetFailureInfo(other); + } + + WI_NODISCARD FailureInfo const& GetFailureInfo() const WI_NOEXCEPT + { + return m_failureInfo; + } + + void SetFailureInfo(FailureInfo const &failure) WI_NOEXCEPT + { + m_failureInfo = failure; + + size_t const cbNeed = details::ResultStringSize(failure.pszMessage) + + details::ResultStringSize(failure.pszCode) + + details::ResultStringSize(failure.pszFunction) + + details::ResultStringSize(failure.pszFile) + + details::ResultStringSize(failure.pszCallContext) + + details::ResultStringSize(failure.pszModule) + + details::ResultStringSize(failure.callContextCurrent.contextName) + + details::ResultStringSize(failure.callContextCurrent.contextMessage) + + details::ResultStringSize(failure.callContextOriginating.contextName) + + details::ResultStringSize(failure.callContextOriginating.contextMessage); + + if (!m_spStrings.unique() || (m_spStrings.size() < cbNeed)) + { + m_spStrings.reset(); + m_spStrings.create(cbNeed); + } + + size_t cbAlloc; + unsigned char *pBuffer = static_cast(m_spStrings.get(&cbAlloc)); + unsigned char *pBufferEnd = (pBuffer != nullptr) ? pBuffer + cbAlloc : nullptr; + + if (pBuffer) + { + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.pszMessage, &m_failureInfo.pszMessage); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.pszCode, &m_failureInfo.pszCode); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.pszFunction, &m_failureInfo.pszFunction); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.pszFile, &m_failureInfo.pszFile); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.pszCallContext, &m_failureInfo.pszCallContext); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.pszModule, &m_failureInfo.pszModule); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.callContextCurrent.contextName, &m_failureInfo.callContextCurrent.contextName); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.callContextCurrent.contextMessage, &m_failureInfo.callContextCurrent.contextMessage); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.callContextOriginating.contextName, &m_failureInfo.callContextOriginating.contextName); + pBuffer = details::WriteResultString(pBuffer, pBufferEnd, failure.callContextOriginating.contextMessage, &m_failureInfo.callContextOriginating.contextMessage); + ZeroMemory(pBuffer, pBufferEnd - pBuffer); + } + } + + // Relies upon generated copy constructor and assignment operator + + protected: + FailureInfo m_failureInfo; + details::shared_buffer m_spStrings; + }; + +#if defined(WIL_ENABLE_EXCEPTIONS) || defined(WIL_FORCE_INCLUDE_RESULT_EXCEPTION) + + //! This is WIL's default exception class thrown from all THROW_XXX macros (outside of c++/cx). + //! This class stores all of the FailureInfo context that is available when the exception is thrown. It's also caught by + //! exception guards for automatic conversion to HRESULT. + //! + //! In c++/cx, Platform::Exception^ is used instead of this class (unless @ref wil::g_fResultThrowPlatformException has been changed). + class ResultException : public std::exception + { + public: + //! Constructs a new ResultException from an existing FailureInfo. + ResultException(const FailureInfo& failure) WI_NOEXCEPT : + m_failure(failure) + { + } + + //! Constructs a new exception type from a given HRESULT (use only for constructing custom exception types). + ResultException(_Pre_satisfies_(hr < 0) HRESULT hr) WI_NOEXCEPT : + m_failure(CustomExceptionFailureInfo(hr)) + { + } + + //! Returns the failed HRESULT that this exception represents. + _Always_(_Post_satisfies_(return < 0)) WI_NODISCARD HRESULT GetErrorCode() const WI_NOEXCEPT + { + HRESULT const hr = m_failure.GetFailureInfo().hr; + __analysis_assume(hr < 0); + return hr; + } + + //! Returns the failed NTSTATUS that this exception represents. + _Always_(_Post_satisfies_(return < 0)) WI_NODISCARD NTSTATUS GetStatusCode() const WI_NOEXCEPT + { + NTSTATUS const status = m_failure.GetFailureInfo().status; + __analysis_assume(status < 0); + return status; + } + + //! Get a reference to the stored FailureInfo. + WI_NODISCARD FailureInfo const& GetFailureInfo() const WI_NOEXCEPT + { + return m_failure.GetFailureInfo(); + } + + //! Sets the stored FailureInfo (use primarily only when constructing custom exception types). + void SetFailureInfo(FailureInfo const &failure) WI_NOEXCEPT + { + m_failure.SetFailureInfo(failure); + } + + //! Provides a string representing the FailureInfo from this exception. + WI_NODISCARD inline const char* __CLR_OR_THIS_CALL what() const WI_NOEXCEPT override + { + if (!m_what) + { + wchar_t message[2048]; + GetFailureLogString(message, ARRAYSIZE(message), m_failure.GetFailureInfo()); + + char messageA[1024]; + int len = WideCharToMultiByte(CP_ACP, 0, message, -1, messageA, ARRAYSIZE(messageA), nullptr, nullptr); + m_what.create(messageA, len); + } + return static_cast(m_what.get()); + } + + // Relies upon auto-generated copy constructor and assignment operator + protected: + StoredFailureInfo m_failure; //!< The failure information for this exception + mutable details::shared_buffer m_what; //!< The on-demand generated what() string + + //! Use to produce a custom FailureInfo from an HRESULT (use only when constructing custom exception types). + static FailureInfo CustomExceptionFailureInfo(HRESULT hr) WI_NOEXCEPT + { + FailureInfo fi = {}; + fi.type = FailureType::Exception; + fi.hr = hr; + return fi; + } + }; +#endif + + + //***************************************************************************** + // Public Helpers that catch -- mostly only enabled when exceptions are enabled + //***************************************************************************** + + // ResultFromCaughtException is a function that is meant to be called from within a catch(...) block. Internally + // it re-throws and catches the exception to convert it to an HRESULT. If an exception is of an unrecognized type + // the function will fail fast. + // + // try + // { + // // Code + // } + // catch (...) + // { + // hr = wil::ResultFromCaughtException(); + // } + _Always_(_Post_satisfies_(return < 0)) + __declspec(noinline) inline HRESULT ResultFromCaughtException() WI_NOEXCEPT + { + bool isNormalized = false; + HRESULT hr = S_OK; + if (details::g_pfnResultFromCaughtExceptionInternal) + { + hr = details::g_pfnResultFromCaughtExceptionInternal(nullptr, 0, &isNormalized).hr; + } + if (FAILED(hr)) + { + return hr; + } + + // Caller bug: an unknown exception was thrown + __WIL_PRIVATE_FAIL_FAST_HR_IF(__HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION), g_fResultFailFastUnknownExceptions); + return __HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION); + } + + //! Identical to 'throw;', but can be called from error-code neutral code to rethrow in code that *may* be running under an exception context + inline void RethrowCaughtException() + { + // We always want to rethrow the exception under normal circumstances. Ordinarily, we could actually guarantee + // this as we should be able to rethrow if we caught an exception, but if we got here in the middle of running + // dynamic initializers, then it's possible that we haven't yet setup the rethrow function pointer, thus the + // runtime check without the noreturn annotation. + + if (details::g_pfnRethrow) + { + details::g_pfnRethrow(); + } + } + + //! Identical to 'throw ResultException(failure);', but can be referenced from error-code neutral code + inline void ThrowResultException(const FailureInfo& failure) + { + if (details::g_pfnThrowResultException) + { + details::g_pfnThrowResultException(failure); + } + } + + //! @cond + namespace details + { +#ifdef WIL_ENABLE_EXCEPTIONS + //***************************************************************************** + // Private helpers to catch and propagate exceptions + //***************************************************************************** + + RESULT_NORETURN inline void TerminateAndReportError(_In_opt_ PEXCEPTION_POINTERS) + { + // This is an intentional fail-fast that was caught by an exception guard with WIL. Look back up the callstack to determine + // the source of the actual exception being thrown. The exception guard used by the calling code did not expect this + // exception type to be thrown or is specifically requesting fail-fast for this class of exception. + + FailureInfo failure{}; + WilFailFast(failure); + } + + inline void MaybeGetExceptionString(const ResultException& exception, _Out_writes_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars) + { + if (debugString) + { + GetFailureLogString(debugString, debugStringChars, exception.GetFailureInfo()); + } + } + + inline void MaybeGetExceptionString(const std::exception& exception, _Out_writes_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars) + { + if (debugString) + { + StringCchPrintfW(debugString, debugStringChars, L"std::exception: %hs", exception.what()); + } + } + + inline HRESULT ResultFromKnownException(const ResultException& exception, const DiagnosticsInfo& diagnostics, void* returnAddress) + { + wchar_t message[2048]{}; + message[0] = L'\0'; + MaybeGetExceptionString(exception, message, ARRAYSIZE(message)); + auto hr = exception.GetErrorCode(); + wil::details::ReportFailure_Base(__R_DIAGNOSTICS_RA(diagnostics, returnAddress), ResultStatus::FromResult(hr), message); + return hr; + } + + inline HRESULT ResultFromKnownException(const std::bad_alloc& exception, const DiagnosticsInfo& diagnostics, void* returnAddress) + { + wchar_t message[2048]{}; + message[0] = L'\0'; + MaybeGetExceptionString(exception, message, ARRAYSIZE(message)); + constexpr auto hr = E_OUTOFMEMORY; + wil::details::ReportFailure_Base(__R_DIAGNOSTICS_RA(diagnostics, returnAddress), ResultStatus::FromResult(hr), message); + return hr; + } + + inline HRESULT ResultFromKnownException(const std::exception& exception, const DiagnosticsInfo& diagnostics, void* returnAddress) + { + wchar_t message[2048]{}; + message[0] = L'\0'; + MaybeGetExceptionString(exception, message, ARRAYSIZE(message)); + constexpr auto hr = __HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION); + ReportFailure_Base(__R_DIAGNOSTICS_RA(diagnostics, returnAddress), ResultStatus::FromResult(hr), message); + return hr; + } + + inline HRESULT ResultFromKnownException_CppWinRT(const DiagnosticsInfo& diagnostics, void* returnAddress) + { + if (g_pfnResultFromCaughtException_CppWinRt) + { + wchar_t message[2048]{}; + message[0] = L'\0'; + bool ignored; + auto hr = g_pfnResultFromCaughtException_CppWinRt(message, ARRAYSIZE(message), &ignored); + if (FAILED(hr)) + { + ReportFailure_Base(__R_DIAGNOSTICS_RA(diagnostics, returnAddress), ResultStatus::FromResult(hr), message); + return hr; + } + } + + // Indicate that this either isn't a C++/WinRT exception or a handler isn't configured by returning success + return S_OK; + } + + inline HRESULT RecognizeCaughtExceptionFromCallback(_Inout_updates_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars) + { + HRESULT hr = g_pfnResultFromCaughtException(); + + // If we still don't know the error -- or we would like to get the debug string for the error (if possible) we + // rethrow and catch std::exception. + + if (SUCCEEDED(hr) || debugString) + { + try + { + throw; + } + catch (std::exception& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + if (SUCCEEDED(hr)) + { + hr = __HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION); + } + } + catch (...) + { + // Fall through to returning 'hr' below + } + } + + return hr; + } + +#ifdef __cplusplus_winrt + inline Platform::String^ GetPlatformExceptionMessage(Platform::Exception^ exception) + { + struct RawExceptionData_Partial + { + PCWSTR description; + PCWSTR restrictedErrorString; + }; + + auto exceptionPtr = reinterpret_cast(static_cast<::Platform::Object^>(exception)); + auto exceptionInfoPtr = reinterpret_cast(exceptionPtr) - 1; + auto partial = reinterpret_cast(*exceptionInfoPtr); + + Platform::String^ message = exception->Message; + + PCWSTR errorString = partial->restrictedErrorString; + PCWSTR messageString = reinterpret_cast(message ? message->Data() : nullptr); + + // An old Platform::Exception^ bug that did not actually expose the error string out of the exception + // message. We do it by hand here if the message associated with the strong does not contain the + // message that was originally attached to the string (in the fixed version it will). + + if ((errorString && *errorString && messageString) && + (wcsstr(messageString, errorString) == nullptr)) + { + return ref new Platform::String(reinterpret_cast<_Null_terminated_ const __wchar_t *>(errorString)); + } + return message; + } + + inline void MaybeGetExceptionString(_In_ Platform::Exception^ exception, _Out_writes_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars) + { + if (debugString) + { + auto message = GetPlatformExceptionMessage(exception); + auto messageString = !message ? L"(null Message)" : reinterpret_cast(message->Data()); + StringCchPrintfW(debugString, debugStringChars, L"Platform::Exception^: %ws", messageString); + } + } + + inline HRESULT ResultFromKnownException(Platform::Exception^ exception, const DiagnosticsInfo& diagnostics, void* returnAddress) + { + wchar_t message[2048]; + message[0] = L'\0'; + MaybeGetExceptionString(exception, message, ARRAYSIZE(message)); + auto hr = exception->HResult; + wil::details::ReportFailure_Base(__R_DIAGNOSTICS_RA(diagnostics, returnAddress), ResultStatus::FromResult(hr), message); + return hr; + } + + inline HRESULT __stdcall ResultFromCaughtException_WinRt(_Inout_updates_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars, _Inout_ bool* isNormalized) WI_NOEXCEPT + { + if (g_pfnResultFromCaughtException) + { + try + { + throw; + } + catch (const ResultException& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return exception.GetErrorCode(); + } + catch (Platform::Exception^ exception) + { + *isNormalized = true; + // We need to call __abi_translateCurrentException so that the CX runtime will pull the originated error information + // out of the exception object and place it back into thread-local storage. + __abi_translateCurrentException(false); + MaybeGetExceptionString(exception, debugString, debugStringChars); + return exception->HResult; + } + catch (const std::bad_alloc& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return E_OUTOFMEMORY; + } + catch (...) + { + auto hr = RecognizeCaughtExceptionFromCallback(debugString, debugStringChars); + if (FAILED(hr)) + { + return hr; + } + } + } + else + { + try + { + throw; + } + catch (const ResultException& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return exception.GetErrorCode(); + } + catch (Platform::Exception^ exception) + { + *isNormalized = true; + // We need to call __abi_translateCurrentException so that the CX runtime will pull the originated error information + // out of the exception object and place it back into thread-local storage. + __abi_translateCurrentException(false); + MaybeGetExceptionString(exception, debugString, debugStringChars); + return exception->HResult; + } + catch (const std::bad_alloc& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return E_OUTOFMEMORY; + } + catch (std::exception& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION); + } + catch (...) + { + // Fall through to returning 'S_OK' below + } + } + + // Tell the caller that we were unable to map the exception by succeeding... + return S_OK; + } + + // WinRT supporting version to execute a functor and catch known exceptions. + inline HRESULT __stdcall ResultFromKnownExceptions_WinRt(const DiagnosticsInfo& diagnostics, void* returnAddress, SupportedExceptions supported, IFunctor& functor) + { + WI_ASSERT(supported != SupportedExceptions::Default); + + switch (supported) + { + case SupportedExceptions::Known: + try + { + return functor.Run(); + } + catch (const ResultException& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (Platform::Exception^ exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (const std::bad_alloc& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (std::exception& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (...) + { + auto hr = ResultFromKnownException_CppWinRT(diagnostics, returnAddress); + if (FAILED(hr)) + { + return hr; + } + + // Unknown exception + throw; + } + break; + + case SupportedExceptions::ThrownOrAlloc: + try + { + return functor.Run(); + } + catch (const ResultException& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (Platform::Exception^ exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (const std::bad_alloc& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + break; + + case SupportedExceptions::Thrown: + try + { + return functor.Run(); + } + catch (const ResultException& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (Platform::Exception^ exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + break; + } + + WI_ASSERT(false); + return S_OK; + } + + inline void __stdcall ThrowPlatformException(FailureInfo const &failure, LPCWSTR debugString) + { + throw Platform::Exception::CreateException(failure.hr, ref new Platform::String(reinterpret_cast<_Null_terminated_ const __wchar_t *>(debugString))); + } + +#if !defined(RESULT_SUPPRESS_STATIC_INITIALIZERS) + WI_HEADER_INITITALIZATION_FUNCTION(InitializeWinRt, [] + { + g_pfnResultFromCaughtException_WinRt = ResultFromCaughtException_WinRt; + g_pfnResultFromKnownExceptions_WinRt = ResultFromKnownExceptions_WinRt; + g_pfnThrowPlatformException = ThrowPlatformException; + return 1; + }); +#endif +#endif + + inline void __stdcall Rethrow() + { + throw; + } + + inline void __stdcall ThrowResultExceptionInternal(const FailureInfo& failure) + { + throw ResultException(failure); + } + + __declspec(noinline) inline ResultStatus __stdcall ResultFromCaughtExceptionInternal(_Out_writes_opt_(debugStringChars) PWSTR debugString, _When_(debugString != nullptr, _Pre_satisfies_(debugStringChars > 0)) size_t debugStringChars, _Out_ bool* isNormalized) WI_NOEXCEPT + { + if (debugString) + { + *debugString = L'\0'; + } + *isNormalized = false; + + if (details::g_pfnResultFromCaughtException_CppWinRt != nullptr) + { + const auto hr = details::g_pfnResultFromCaughtException_CppWinRt(debugString, debugStringChars, isNormalized); + if (FAILED(hr)) + { + return ResultStatus::FromResult(hr); + } + } + + if (details::g_pfnResultFromCaughtException_WinRt != nullptr) + { + const auto hr = details::g_pfnResultFromCaughtException_WinRt(debugString, debugStringChars, isNormalized); + return ResultStatus::FromResult(hr); + } + + if (g_pfnResultFromCaughtException) + { + try + { + throw; + } + catch (const ResultException& exception) + { + *isNormalized = true; + MaybeGetExceptionString(exception, debugString, debugStringChars); + return ResultStatus::FromFailureInfo(exception.GetFailureInfo()); + } + catch (const std::bad_alloc& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return ResultStatus::FromResult(E_OUTOFMEMORY); + } + catch (...) + { + auto hr = RecognizeCaughtExceptionFromCallback(debugString, debugStringChars); + if (FAILED(hr)) + { + return ResultStatus::FromResult(hr); + } + } + } + else + { + try + { + throw; + } + catch (const ResultException& exception) + { + *isNormalized = true; + MaybeGetExceptionString(exception, debugString, debugStringChars); + return ResultStatus::FromFailureInfo(exception.GetFailureInfo()); + } + catch (const std::bad_alloc& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return ResultStatus::FromResult(E_OUTOFMEMORY); + } + catch (std::exception& exception) + { + MaybeGetExceptionString(exception, debugString, debugStringChars); + return ResultStatus::FromResult(__HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)); + } + catch (...) + { + // Fall through to returning 'S_OK' below + } + } + + // Tell the caller that we were unable to map the exception by succeeding... + return ResultStatus::FromResult(S_OK); + } + + // Runs the given functor, converting any exceptions of the supported types that are known to HRESULTs and returning + // that HRESULT. Does NOT attempt to catch unknown exceptions (which propagate). Primarily used by SEH exception + // handling techniques to stop at the point the exception is thrown. + inline HRESULT ResultFromKnownExceptions(const DiagnosticsInfo& diagnostics, void* returnAddress, SupportedExceptions supported, IFunctor& functor) + { + if (supported == SupportedExceptions::Default) + { + supported = g_fResultSupportStdException ? SupportedExceptions::Known : SupportedExceptions::ThrownOrAlloc; + } + + if ((details::g_pfnResultFromKnownExceptions_WinRt != nullptr) && + ((supported == SupportedExceptions::Known) || (supported == SupportedExceptions::Thrown) || (supported == SupportedExceptions::ThrownOrAlloc))) + { + return details::g_pfnResultFromKnownExceptions_WinRt(diagnostics, returnAddress, supported, functor); + } + + switch (supported) + { + case SupportedExceptions::Known: + try + { + return functor.Run(); + } + catch (const ResultException& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (const std::bad_alloc& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (std::exception& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (...) + { + auto hr = ResultFromKnownException_CppWinRT(diagnostics, returnAddress); + if (FAILED(hr)) + { + return hr; + } + + // Unknown exception + throw; + } + + case SupportedExceptions::ThrownOrAlloc: + try + { + return functor.Run(); + } + catch (const ResultException& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + catch (const std::bad_alloc& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + + case SupportedExceptions::Thrown: + try + { + return functor.Run(); + } + catch (const ResultException& exception) + { + return ResultFromKnownException(exception, diagnostics, returnAddress); + } + + case SupportedExceptions::All: + try + { + return functor.Run(); + } + catch (...) + { + return wil::details::ReportFailure_CaughtException(__R_DIAGNOSTICS_RA(diagnostics, returnAddress), supported); + } + + case SupportedExceptions::None: + return functor.Run(); + + case SupportedExceptions::Default: + WI_ASSERT(false); + } + + WI_ASSERT(false); + return S_OK; + } + + inline HRESULT ResultFromExceptionSeh(const DiagnosticsInfo& diagnostics, void* returnAddress, SupportedExceptions supported, IFunctor& functor) WI_NOEXCEPT + { + __try + { + return wil::details::ResultFromKnownExceptions(diagnostics, returnAddress, supported, functor); + } + __except (wil::details::TerminateAndReportError(GetExceptionInformation()), EXCEPTION_CONTINUE_SEARCH) + { + WI_ASSERT(false); + RESULT_NORETURN_RESULT(HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)); + } + } + + __declspec(noinline) inline HRESULT ResultFromException(const DiagnosticsInfo& diagnostics, SupportedExceptions supported, IFunctor& functor) WI_NOEXCEPT + { +#ifdef RESULT_DEBUG + // We can't do debug SEH handling if the caller also wants a shot at mapping the exceptions + // themselves or if the caller doesn't want to fail-fast unknown exceptions + if ((g_pfnResultFromCaughtException == nullptr) && g_fResultFailFastUnknownExceptions) + { + return wil::details::ResultFromExceptionSeh(diagnostics, _ReturnAddress(), supported, functor); + } +#endif + try + { + return functor.Run(); + } + catch (...) + { + return wil::details::ReportFailure_CaughtException(__R_DIAGNOSTICS(diagnostics), _ReturnAddress(), supported); + } + } + + __declspec(noinline) inline HRESULT ResultFromExceptionDebug(const DiagnosticsInfo& diagnostics, SupportedExceptions supported, IFunctor& functor) WI_NOEXCEPT + { + return wil::details::ResultFromExceptionSeh(diagnostics, _ReturnAddress(), supported, functor); + } + + // Exception guard -- catch exceptions and log them (or handle them with a custom callback) + // WARNING: may throw an exception... + inline HRESULT __stdcall RunFunctorWithExceptionFilter(IFunctor& functor, IFunctorHost& host, void* returnAddress) + { + try + { + return host.Run(functor); + } + catch (...) + { + // Note that the host may choose to re-throw, throw a normalized exception, return S_OK and eat the exception or + // return the remapped failure. + return host.ExceptionThrown(returnAddress); + } + } + + WI_HEADER_INITITALIZATION_FUNCTION(InitializeResultExceptions, [] + { + g_pfnRunFunctorWithExceptionFilter = RunFunctorWithExceptionFilter; + g_pfnRethrow = Rethrow; + g_pfnThrowResultException = ThrowResultExceptionInternal; + g_pfnResultFromCaughtExceptionInternal = ResultFromCaughtExceptionInternal; + return 1; + }); + + } + + //! A lambda-based exception guard that can vary the supported exception types. + //! This function accepts a lambda and diagnostics information as its parameters and executes that lambda + //! under a try/catch(...) block. All exceptions are caught and the function reports the exception information + //! and diagnostics to telemetry on failure. An HRESULT is returned that maps to the exception. + //! + //! Note that an overload exists that does not report failures to telemetry at all. This version should be preferred + //! to that version. Also note that neither of these versions are preferred over using try catch blocks to accomplish + //! the same thing as they will be more efficient. + //! + //! See @ref page_exception_guards for more information and examples on exception guards. + //! ~~~~ + //! return wil::ResultFromException(WI_DIAGNOSTICS_INFO, [&] + //! { + //! // exception-based code + //! // telemetry is reported with full exception information + //! }); + //! ~~~~ + //! @param diagnostics Always pass WI_DIAGNOSTICS_INFO as the first parameter + //! @param supported What kind of exceptions you want to support + //! @param functor A lambda that accepts no parameters; any return value is ignored + //! @return S_OK on success (no exception thrown) or an error based upon the exception thrown + template + __forceinline HRESULT ResultFromException(const DiagnosticsInfo& diagnostics, SupportedExceptions supported, Functor&& functor) WI_NOEXCEPT + { + static_assert(details::functor_tag::value != details::tag_return_other::value, "Functor must return void or HRESULT"); + typename details::functor_tag::template functor_wrapper functorObject(wistd::forward(functor)); + + return wil::details::ResultFromException(diagnostics, supported, functorObject); + } + + //! A lambda-based exception guard. + //! This overload uses SupportedExceptions::Known by default. See @ref ResultFromException for more detailed information. + template + __forceinline HRESULT ResultFromException(const DiagnosticsInfo& diagnostics, Functor&& functor) WI_NOEXCEPT + { + return ResultFromException(diagnostics, SupportedExceptions::Known, wistd::forward(functor)); + } + + //! A lambda-based exception guard that does not report failures to telemetry. + //! This function accepts a lambda as it's only parameter and executes that lambda under a try/catch(...) block. + //! All exceptions are caught and the function returns an HRESULT mapping to the exception. + //! + //! This version (taking only a lambda) does not report failures to telemetry. An overload with the same name + //! can be utilized by passing `WI_DIAGNOSTICS_INFO` as the first parameter and the lambda as the second parameter + //! to report failure information to telemetry. + //! + //! See @ref page_exception_guards for more information and examples on exception guards. + //! ~~~~ + //! hr = wil::ResultFromException([&] + //! { + //! // exception-based code + //! // the conversion of exception to HRESULT doesn't report telemetry + //! }); + //! + //! hr = wil::ResultFromException(WI_DIAGNOSTICS_INFO, [&] + //! { + //! // exception-based code + //! // telemetry is reported with full exception information + //! }); + //! ~~~~ + //! @param functor A lambda that accepts no parameters; any return value is ignored + //! @return S_OK on success (no exception thrown) or an error based upon the exception thrown + template + inline HRESULT ResultFromException(Functor&& functor) WI_NOEXCEPT try + { + static_assert(details::functor_tag::value == details::tag_return_void::value, "Functor must return void"); + typename details::functor_tag::template functor_wrapper functorObject(wistd::forward(functor)); + + functorObject.Run(); + return S_OK; + } + catch (...) + { + return ResultFromCaughtException(); + } + + + //! A lambda-based exception guard that can identify the origin of unknown exceptions and can vary the supported exception types. + //! Functionally this is nearly identical to the corresponding @ref ResultFromException function with the exception + //! that it utilizes structured exception handling internally to be able to terminate at the point where a unknown + //! exception is thrown, rather than after that unknown exception has been unwound. Though less efficient, this leads + //! to a better debugging experience when analyzing unknown exceptions. + //! + //! For example: + //! ~~~~ + //! hr = wil::ResultFromExceptionDebug(WI_DIAGNOSTICS_INFO, [&] + //! { + //! FunctionWhichMayThrow(); + //! }); + //! ~~~~ + //! Assume FunctionWhichMayThrow() has a bug in it where it accidentally does a `throw E_INVALIDARG;`. This ends up + //! throwing a `long` as an exception object which is not what the caller intended. The normal @ref ResultFromException + //! would fail-fast when this is encountered, but it would do so AFTER FunctionWhichMayThrow() is already off of the + //! stack and has been unwound. Because SEH is used for ResultFromExceptionDebug, the fail-fast occurs with everything + //! leading up to and including the `throw INVALIDARG;` still on the stack (and easily debuggable). + //! + //! The penalty paid for using this, however, is efficiency. It's far less efficient as a general pattern than either + //! using ResultFromException directly or especially using try with CATCH_ macros directly. Still it's helpful to deploy + //! selectively to isolate issues a component may be having with unknown/unhandled exceptions. + //! + //! The ability to vary the SupportedExceptions that this routine provides adds the ability to track down unexpected + //! exceptions not falling into the supported category easily through fail-fast. For example, by not supporting any + //! exception, you can use this function to quickly add an exception guard that will fail-fast any exception at the point + //! the exception occurs (the throw) in a codepath where the origination of unknown exceptions need to be tracked down. + //! + //! Also see @ref ResultFromExceptionDebugNoStdException. It functions almost identically, but also will fail-fast and stop + //! on std::exception based exceptions (but not Platform::Exception^ or wil::ResultException). Using this can help isolate + //! where an unexpected exception is being generated from. + //! @param diagnostics Always pass WI_DIAGNOSTICS_INFO as the first parameter + //! @param supported What kind of exceptions you want to support + //! @param functor A lambda that accepts no parameters; any return value is ignored + //! @return S_OK on success (no exception thrown) or an error based upon the exception thrown + template + __forceinline HRESULT ResultFromExceptionDebug(const DiagnosticsInfo& diagnostics, SupportedExceptions supported, Functor&& functor) WI_NOEXCEPT + { + static_assert(details::functor_tag::value == details::tag_return_void::value, "Functor must return void"); + typename details::functor_tag::template functor_wrapper functorObject(wistd::forward(functor)); + + return wil::details::ResultFromExceptionDebug(diagnostics, supported, functorObject); + } + + //! A lambda-based exception guard that can identify the origin of unknown exceptions. + //! This overload uses SupportedExceptions::Known by default. See @ref ResultFromExceptionDebug for more detailed information. + template + __forceinline HRESULT ResultFromExceptionDebug(const DiagnosticsInfo& diagnostics, Functor&& functor) WI_NOEXCEPT + { + static_assert(details::functor_tag::value == details::tag_return_void::value, "Functor must return void"); + typename details::functor_tag::template functor_wrapper functorObject(wistd::forward(functor)); + + return wil::details::ResultFromExceptionDebug(diagnostics, SupportedExceptions::Known, functorObject); + } + + //! A fail-fast based exception guard. + //! Technically this is an overload of @ref ResultFromExceptionDebug that uses SupportedExceptions::None by default. Any uncaught + //! exception that makes it back to this guard would result in a fail-fast at the point the exception is thrown. + template + __forceinline void FailFastException(const DiagnosticsInfo& diagnostics, Functor&& functor) WI_NOEXCEPT + { + static_assert(details::functor_tag::value == details::tag_return_void::value, "Functor must return void"); + typename details::functor_tag::template functor_wrapper functorObject(wistd::forward(functor)); + + wil::details::ResultFromExceptionDebug(diagnostics, SupportedExceptions::None, functorObject); + } + + namespace details { + +#endif // WIL_ENABLE_EXCEPTIONS + + // Exception guard -- catch exceptions and log them (or handle them with a custom callback) + // WARNING: may throw an exception... + inline __declspec(noinline) HRESULT RunFunctor(IFunctor& functor, IFunctorHost& host) + { + if (g_pfnRunFunctorWithExceptionFilter) + { + return g_pfnRunFunctorWithExceptionFilter(functor, host, _ReturnAddress()); + } + + return host.Run(functor); + } + + // Returns true if a debugger should be considered to be connected. + // Modules can force this on through setting g_fIsDebuggerPresent explicitly (useful for live debugging), + // they can provide a callback function by setting g_pfnIsDebuggerPresent (useful for kernel debbugging), + // and finally the user-mode check (IsDebuggerPrsent) is checked. IsDebuggerPresent is a fast call + inline bool IsDebuggerPresent() + { + return g_fIsDebuggerPresent || ((g_pfnIsDebuggerPresent != nullptr) ? g_pfnIsDebuggerPresent() : (::IsDebuggerPresent() != FALSE)); + } + + //***************************************************************************** + // Shared Reporting -- all reporting macros bubble up through this codepath + //***************************************************************************** + + inline void LogFailure(__R_FN_PARAMS_FULL, FailureType type, const ResultStatus& resultPair, _In_opt_ PCWSTR message, + bool fWantDebugString, _Out_writes_(debugStringSizeChars) _Post_z_ PWSTR debugString, _Pre_satisfies_(debugStringSizeChars > 0) size_t debugStringSizeChars, + _Out_writes_(callContextStringSizeChars) _Post_z_ PSTR callContextString, _Pre_satisfies_(callContextStringSizeChars > 0) size_t callContextStringSizeChars, + _Out_ FailureInfo *failure) WI_NOEXCEPT + { + debugString[0] = L'\0'; + callContextString[0] = L'\0'; + + static long volatile s_failureId = 0; + + failure->hr = resultPair.hr; + failure->status = resultPair.status; + + int failureCount = 0; + switch (type) + { + case FailureType::Exception: + failureCount = RecordException(failure->hr); + break; + case FailureType::Return: + failureCount = RecordReturn(failure->hr); + break; + case FailureType::Log: + if (SUCCEEDED(failure->hr)) + { + // If you hit this assert (or are reviewing this failure telemetry), then most likely you are trying to log success + // using one of the WIL macros. Example: + // LOG_HR(S_OK); + // Instead, use one of the forms that conditionally logs based upon the error condition: + // LOG_IF_FAILED(hr); + + WI_USAGE_ERROR_FORWARD("CALLER BUG: Macro usage error detected. Do not LOG_XXX success."); + failure->hr = __HRESULT_FROM_WIN32(ERROR_ASSERTION_FAILURE); + failure->status = wil::details::HrToNtStatus(failure->hr); + } + failureCount = RecordLog(failure->hr); + break; + case FailureType::FailFast: + failureCount = RecordFailFast(failure->hr); + break; + }; + + failure->type = type; + failure->flags = FailureFlags::None; + WI_SetFlagIf(failure->flags, FailureFlags::NtStatus, resultPair.kind == ResultStatus::Kind::NtStatus); + failure->failureId = ::InterlockedIncrementNoFence(&s_failureId); + failure->pszMessage = ((message != nullptr) && (message[0] != L'\0')) ? message : nullptr; + failure->threadId = ::GetCurrentThreadId(); + failure->pszFile = fileName; + failure->uLineNumber = lineNumber; + failure->cFailureCount = failureCount; + failure->pszCode = code; + failure->pszFunction = functionName; + failure->returnAddress = returnAddress; + failure->callerReturnAddress = callerReturnAddress; + failure->pszCallContext = nullptr; + ::ZeroMemory(&failure->callContextCurrent, sizeof(failure->callContextCurrent)); + ::ZeroMemory(&failure->callContextOriginating, sizeof(failure->callContextOriginating)); + failure->pszModule = (g_pfnGetModuleName != nullptr) ? g_pfnGetModuleName() : nullptr; + + // Process failure notification / adjustments + if (details::g_pfnNotifyFailure) + { + details::g_pfnNotifyFailure(failure); + } + + // Completes filling out failure, notifies thread-based callbacks and the telemetry callback + if (details::g_pfnGetContextAndNotifyFailure) + { + details::g_pfnGetContextAndNotifyFailure(failure, callContextString, callContextStringSizeChars); + } + + // Allow hooks to inspect the failure before acting upon it + if (details::g_pfnLoggingCallback) + { + details::g_pfnLoggingCallback(*failure); + } + + // If the hook is enabled then it will be given the opportunity to call RoOriginateError to greatly improve the diagnostic experience + // for uncaught exceptions. In cases where we will be throwing a C++/CX Platform::Exception we should avoid originating because the + // CX runtime will be doing that for us. fWantDebugString is only set to true when the caller will be throwing a Platform::Exception. + if (details::g_pfnOriginateCallback && !fWantDebugString && WI_IsFlagClear(failure->flags, FailureFlags::RequestSuppressTelemetry)) + { + details::g_pfnOriginateCallback(*failure); + } + + if (SUCCEEDED(failure->hr)) + { + // Caller bug: Leaking a success code into a failure-only function + FAIL_FAST_IMMEDIATE_IF(type != FailureType::FailFast); + failure->hr = E_UNEXPECTED; + failure->status = wil::details::HrToNtStatus(failure->hr); + } + + bool const fUseOutputDebugString = IsDebuggerPresent() && g_fResultOutputDebugString && WI_IsFlagClear(failure->flags, FailureFlags::RequestSuppressTelemetry); + + // We need to generate the logging message if: + // * We're logging to OutputDebugString + // * OR the caller asked us to (generally for attaching to a C++/CX exception) + if (fWantDebugString || fUseOutputDebugString) + { + // Call the logging callback (if present) to allow them to generate the debug string that will be pushed to the console + // or the platform exception object if the caller desires it. + if ((g_pfnResultLoggingCallback != nullptr) && !g_resultMessageCallbackSet) + { + g_pfnResultLoggingCallback(failure, debugString, debugStringSizeChars); + } + + // The callback only optionally needs to supply the debug string -- if the callback didn't populate it, yet we still want + // it for OutputDebugString or exception message, then generate the default string. + if (debugString[0] == L'\0') + { + GetFailureLogString(debugString, debugStringSizeChars, *failure); + } + + if (fUseOutputDebugString) + { + ::OutputDebugStringW(debugString); + } + } + else + { + // [deprecated behavior] + // This callback was at one point *always* called for all failures, so we continue to call it for failures even when we don't + // need to generate the debug string information (when the callback was supplied directly). We can avoid this if the caller + // used the explicit function (through g_resultMessageCallbackSet) + if ((g_pfnResultLoggingCallback != nullptr) && !g_resultMessageCallbackSet) + { + g_pfnResultLoggingCallback(failure, nullptr, 0); + } + } + + if ((WI_IsFlagSet(failure->flags, FailureFlags::RequestDebugBreak) || g_fBreakOnFailure) && (g_pfnDebugBreak != nullptr)) + { + g_pfnDebugBreak(); + } + } + + inline RESULT_NORETURN void __stdcall WilFailFast(const wil::FailureInfo& failure) + { + if (g_pfnWilFailFast) + { + g_pfnWilFailFast(failure); + } + +#ifdef RESULT_RAISE_FAST_FAIL_EXCEPTION + // Use of this macro is an ODR violation - use the callback instead. This will be removed soon. + RESULT_RAISE_FAST_FAIL_EXCEPTION; +#endif + + // Before we fail fast in this method, give the [optional] RoFailFastWithErrorContext a try. + if (g_pfnFailfastWithContextCallback) + { + g_pfnFailfastWithContextCallback(failure); + } + + // parameter 0 is the !analyze code (FAST_FAIL_FATAL_APP_EXIT) + EXCEPTION_RECORD er{}; + er.NumberParameters = 1; // default to be safe, see below + er.ExceptionCode = static_cast(STATUS_STACK_BUFFER_OVERRUN); // 0xC0000409 + er.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + er.ExceptionInformation[0] = FAST_FAIL_FATAL_APP_EXIT; // see winnt.h, generated from minkernel\published\base\ntrtl_x.w + if (failure.returnAddress == nullptr) // FailureInfo does not have _ReturnAddress, have RaiseFailFastException generate it + { + // passing ExceptionCode 0xC0000409 and one param with FAST_FAIL_APP_EXIT will use existing + // !analyze functionality to crawl the stack looking for the HRESULT + // don't pass a 0 HRESULT in param 1 because that will result in worse bucketing. + WilRaiseFailFastException(&er, nullptr, FAIL_FAST_GENERATE_EXCEPTION_ADDRESS); + } + else // use FailureInfo caller address + { + // parameter 1 is the failing HRESULT + // parameter 2 is the line number. This is never used for bucketing (due to code churn causing re-bucketing) but is available in the dump's + // exception record to aid in failure locality. Putting it here prevents it from being poisoned in triage dumps. + er.NumberParameters = 3; + er.ExceptionInformation[1] = failure.hr; + er.ExceptionInformation[2] = failure.uLineNumber; + er.ExceptionAddress = failure.returnAddress; + WilRaiseFailFastException(&er, nullptr, 0 /* do not generate exception address */); + } + } + + template + inline __declspec(noinline) void ReportFailure_Return(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) + { + bool needPlatformException = ((T == FailureType::Exception) && + WI_IsFlagClear(options, ReportFailureOptions::MayRethrow) && + (g_pfnThrowPlatformException != nullptr) && + (g_fResultThrowPlatformException || WI_IsFlagSet(options, ReportFailureOptions::ForcePlatformException))); + + FailureInfo failure; + wchar_t debugString[2048]; + char callContextString[1024]; + + LogFailure(__R_FN_CALL_FULL, T, resultPair, message, needPlatformException, + debugString, ARRAYSIZE(debugString), callContextString, ARRAYSIZE(callContextString), &failure); + + if (WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast)) + { + WilFailFast(failure); + } + } + + template + inline __declspec(noinline) void ReportFailure_Base(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) + { + ReportFailure_Return(__R_FN_CALL_FULL, resultPair, message, options); + } + + template + inline __declspec(noinline) RESULT_NORETURN void ReportFailure_NoReturn(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) + { + bool needPlatformException = ((T == FailureType::Exception) && + WI_IsFlagClear(options, ReportFailureOptions::MayRethrow) && + (g_pfnThrowPlatformException != nullptr) && + (g_fResultThrowPlatformException || WI_IsFlagSet(options, ReportFailureOptions::ForcePlatformException))); + + FailureInfo failure; + wchar_t debugString[2048]; + char callContextString[1024]; + + LogFailure(__R_FN_CALL_FULL, T, resultPair, message, needPlatformException, + debugString, ARRAYSIZE(debugString), callContextString, ARRAYSIZE(callContextString), &failure); +__WI_SUPPRESS_4127_S + if ((T == FailureType::FailFast) || WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast)) + { + WilFailFast(const_cast(failure)); + } + else + { + if (needPlatformException) + { + g_pfnThrowPlatformException(failure, debugString); + } + + if (WI_IsFlagSet(options, ReportFailureOptions::MayRethrow)) + { + RethrowCaughtException(); + } + + ThrowResultException(failure); + + // Wil was instructed to throw, but doesn't have any capability to do so (global function pointers are not setup) + WilFailFast(const_cast(failure)); + } +__WI_SUPPRESS_4127_E + } + + template<> + inline __declspec(noinline) RESULT_NORETURN void ReportFailure_Base(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) + { + ReportFailure_NoReturn(__R_FN_CALL_FULL, resultPair, message, options); + } + + template<> + inline __declspec(noinline) RESULT_NORETURN void ReportFailure_Base(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, PCWSTR message, ReportFailureOptions options) + { + ReportFailure_NoReturn(__R_FN_CALL_FULL, resultPair, message, options); + } + + __declspec(noinline) inline void ReportFailure(__R_FN_PARAMS_FULL, FailureType type, const ResultStatus& resultPair, _In_opt_ PCWSTR message, ReportFailureOptions options) + { + switch(type) + { + case FailureType::Exception: + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, message, options); + break; + case FailureType::FailFast: + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, message, options); + break; + case FailureType::Log: + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, message, options); + break; + case FailureType::Return: + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, message, options); + break; + } + } + + template + inline ResultStatus ReportFailure_CaughtExceptionCommon(__R_FN_PARAMS_FULL, _Inout_updates_(debugStringChars) PWSTR debugString, _Pre_satisfies_(debugStringChars > 0) size_t debugStringChars, SupportedExceptions supported) + { + bool isNormalized = false; + auto length = wcslen(debugString); + WI_ASSERT(length < debugStringChars); + ResultStatus resultPair; + if (details::g_pfnResultFromCaughtExceptionInternal) + { + resultPair = details::g_pfnResultFromCaughtExceptionInternal(debugString + length, debugStringChars - length, &isNormalized); + } + + const bool known = (FAILED(resultPair.hr)); + if (!known) + { + resultPair = ResultStatus::FromResult(__HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)); + } + + ReportFailureOptions options = ReportFailureOptions::ForcePlatformException; + WI_SetFlagIf(options, ReportFailureOptions::MayRethrow, isNormalized); + + if ((supported == SupportedExceptions::None) || + ((supported == SupportedExceptions::Known) && !known) || + ((supported == SupportedExceptions::Thrown) && !isNormalized) || + ((supported == SupportedExceptions::Default) && !known && g_fResultFailFastUnknownExceptions)) + { + // By default WIL will issue a fail fast for unrecognized exception types. Wil recognizes any std::exception or wil::ResultException based + // types and Platform::Exception^, so there aren't too many valid exception types which could cause this. Those that are valid, should be handled + // by remapping the exception callback. Those that are not valid should be found and fixed (meaningless accidents like 'throw hr;'). + // The caller may also be requesting non-default behavior to fail-fast more frequently (primarily for debugging unknown exceptions). + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, debugString, options); + } + else + { + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, debugString, options); + } + + return resultPair; + } + + template + inline ResultStatus RESULT_NORETURN ReportFailure_CaughtExceptionCommonNoReturnBase(__R_FN_PARAMS_FULL, _Inout_updates_(debugStringChars) PWSTR debugString, _Pre_satisfies_(debugStringChars > 0) size_t debugStringChars, SupportedExceptions supported) + { + bool isNormalized = false; + const auto length = wcslen(debugString); + WI_ASSERT(length < debugStringChars); + ResultStatus resultPair; + if (details::g_pfnResultFromCaughtExceptionInternal) + { + resultPair = details::g_pfnResultFromCaughtExceptionInternal(debugString + length, debugStringChars - length, &isNormalized); + } + + const bool known = (FAILED(resultPair.hr)); + if (!known) + { + resultPair = ResultStatus::FromResult(__HRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)); + } + + ReportFailureOptions options = ReportFailureOptions::ForcePlatformException; + WI_SetFlagIf(options, ReportFailureOptions::MayRethrow, isNormalized); + + if ((supported == SupportedExceptions::None) || + ((supported == SupportedExceptions::Known) && !known) || + ((supported == SupportedExceptions::Thrown) && !isNormalized) || + ((supported == SupportedExceptions::Default) && !known && g_fResultFailFastUnknownExceptions)) + { + // By default WIL will issue a fail fast for unrecognized exception types. Wil recognizes any std::exception or wil::ResultException based + // types and Platform::Exception^, so there aren't too many valid exception types which could cause this. Those that are valid, should be handled + // by remapping the exception callback. Those that are not valid should be found and fixed (meaningless accidents like 'throw hr;'). + // The caller may also be requesting non-default behavior to fail-fast more frequently (primarily for debugging unknown exceptions). + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, debugString, options); + } + else + { + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, debugString, options); + } + + RESULT_NORETURN_RESULT(resultPair); + } + + template<> + inline RESULT_NORETURN ResultStatus ReportFailure_CaughtExceptionCommon(__R_FN_PARAMS_FULL, _Inout_updates_(debugStringChars) PWSTR debugString, _Pre_satisfies_(debugStringChars > 0) size_t debugStringChars, SupportedExceptions supported) + { + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommonNoReturnBase(__R_FN_CALL_FULL, debugString, debugStringChars, supported)); + } + + template<> + inline RESULT_NORETURN ResultStatus ReportFailure_CaughtExceptionCommon(__R_FN_PARAMS_FULL, _Inout_updates_(debugStringChars) PWSTR debugString, _Pre_satisfies_(debugStringChars > 0) size_t debugStringChars, SupportedExceptions supported) + { + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommonNoReturnBase(__R_FN_CALL_FULL, debugString, debugStringChars, supported)); + } + + template + inline void ReportFailure_Msg(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, _Printf_format_string_ PCSTR formatString, va_list argList) + { + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, message); + } + + template<> + inline RESULT_NORETURN void ReportFailure_Msg(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, _Printf_format_string_ PCSTR formatString, va_list argList) + { + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, message); + } + + template<> + inline RESULT_NORETURN void ReportFailure_Msg(__R_FN_PARAMS_FULL, const ResultStatus& resultPair, _Printf_format_string_ PCSTR formatString, va_list argList) + { + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + ReportFailure_Base(__R_FN_CALL_FULL, resultPair, message); + } + + template + inline void ReportFailure_ReplaceMsg(__R_FN_PARAMS_FULL, HRESULT hr, PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + } + + template + __declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr) + { + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + } + + template<> + __declspec(noinline) inline RESULT_NORETURN void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr) + { + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + } + + template<> + __declspec(noinline) inline RESULT_NORETURN void ReportFailure_Hr(__R_FN_PARAMS_FULL, HRESULT hr) + { + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + } + + __declspec(noinline) inline void ReportFailure_Hr(__R_FN_PARAMS_FULL, FailureType type, HRESULT hr) + { + switch(type) + { + case FailureType::Exception: + ReportFailure_Hr(__R_FN_CALL_FULL, hr); + break; + case FailureType::FailFast: + ReportFailure_Hr(__R_FN_CALL_FULL, hr); + break; + case FailureType::Log: + ReportFailure_Hr(__R_FN_CALL_FULL, hr); + break; + case FailureType::Return: + ReportFailure_Hr(__R_FN_CALL_FULL, hr); + break; + } + } + + template + _Success_(true) + _Translates_Win32_to_HRESULT_(err) + __declspec(noinline) inline HRESULT ReportFailure_Win32(__R_FN_PARAMS_FULL, DWORD err) + { + const auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + return hr; + } + + template<> + _Success_(true) + _Translates_Win32_to_HRESULT_(err) + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_Win32(__R_FN_PARAMS_FULL, DWORD err) + { + const auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + RESULT_NORETURN_RESULT(hr); + } + + template<> + _Success_(true) + _Translates_Win32_to_HRESULT_(err) + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_Win32(__R_FN_PARAMS_FULL, DWORD err) + { + const auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + RESULT_NORETURN_RESULT(hr); + } + + template + __declspec(noinline) inline DWORD ReportFailure_GetLastError(__R_FN_PARAMS_FULL) + { + const auto err = GetLastErrorFail(__R_FN_CALL_FULL); + const auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + ::SetLastError(err); + return err; + } + + template<> + __declspec(noinline) inline RESULT_NORETURN DWORD ReportFailure_GetLastError(__R_FN_PARAMS_FULL) + { + const auto err = GetLastErrorFail(__R_FN_CALL_FULL); + const auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + RESULT_NORETURN_RESULT(err); + } + + template<> + __declspec(noinline) inline RESULT_NORETURN DWORD ReportFailure_GetLastError(__R_FN_PARAMS_FULL) + { + const auto err = GetLastErrorFail(__R_FN_CALL_FULL); + const auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + RESULT_NORETURN_RESULT(err); + } + + template + _Success_(true) + _Translates_last_error_to_HRESULT_ + __declspec(noinline) inline HRESULT ReportFailure_GetLastErrorHr(__R_FN_PARAMS_FULL) + { + const auto hr = GetLastErrorFailHr(__R_FN_CALL_FULL); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + return hr; + } + + template<> + _Success_(true) + _Translates_last_error_to_HRESULT_ + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_GetLastErrorHr(__R_FN_PARAMS_FULL) + { + const auto hr = GetLastErrorFailHr(__R_FN_CALL_FULL); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + RESULT_NORETURN_RESULT(hr); + } + + template<> + _Success_(true) + _Translates_last_error_to_HRESULT_ + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_GetLastErrorHr(__R_FN_PARAMS_FULL) + { + const auto hr = GetLastErrorFailHr(__R_FN_CALL_FULL); + ReportFailure_Base(__R_FN_CALL_FULL, ResultStatus::FromResult(hr)); + RESULT_NORETURN_RESULT(hr); + } + + template + _Success_(true) + _Translates_NTSTATUS_to_HRESULT_(status) + __declspec(noinline) inline HRESULT ReportFailure_NtStatus(__R_FN_PARAMS_FULL, NTSTATUS status) + { + const auto resultPair = ResultStatus::FromStatus(status); + ReportFailure_Base(__R_FN_CALL_FULL, resultPair); + return resultPair.hr; + } + + template<> + _Success_(true) + _Translates_NTSTATUS_to_HRESULT_(status) + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_NtStatus(__R_FN_PARAMS_FULL, NTSTATUS status) + { + const auto resultPair = ResultStatus::FromStatus(status); + ReportFailure_Base(__R_FN_CALL_FULL, resultPair); + RESULT_NORETURN_RESULT(resultPair.hr); + } + + template<> + _Success_(true) + _Translates_NTSTATUS_to_HRESULT_(status) + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_NtStatus(__R_FN_PARAMS_FULL, NTSTATUS status) + { + const auto resultPair = ResultStatus::FromStatus(status); + ReportFailure_Base(__R_FN_CALL_FULL, resultPair); + RESULT_NORETURN_RESULT(resultPair.hr); + } + + template + __declspec(noinline) inline HRESULT ReportFailure_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported) + { + wchar_t message[2048]{}; + message[0] = L'\0'; + return ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), supported).hr; + } + + template<> + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported) + { + wchar_t message[2048]{}; + message[0] = L'\0'; + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), supported).hr); + } + + template<> + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_CaughtException(__R_FN_PARAMS_FULL, SupportedExceptions supported) + { + wchar_t message[2048]{}; + message[0] = L'\0'; + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), supported).hr); + } + + template + __declspec(noinline) inline void ReportFailure_HrMsg(__R_FN_PARAMS_FULL, HRESULT hr, _Printf_format_string_ PCSTR formatString, va_list argList) + { + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + } + + template<> + __declspec(noinline) inline RESULT_NORETURN void ReportFailure_HrMsg(__R_FN_PARAMS_FULL, HRESULT hr, _Printf_format_string_ PCSTR formatString, va_list argList) + { + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + } + + template<> + __declspec(noinline) inline RESULT_NORETURN void ReportFailure_HrMsg(__R_FN_PARAMS_FULL, HRESULT hr, _Printf_format_string_ PCSTR formatString, va_list argList) + { + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + } + + template + _Success_(true) + _Translates_Win32_to_HRESULT_(err) + __declspec(noinline) inline HRESULT ReportFailure_Win32Msg(__R_FN_PARAMS_FULL, DWORD err, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + return hr; + } + + template<> + _Success_(true) + _Translates_Win32_to_HRESULT_(err) + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_Win32Msg(__R_FN_PARAMS_FULL, DWORD err, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + RESULT_NORETURN_RESULT(hr); + } + + template<> + _Success_(true) + _Translates_Win32_to_HRESULT_(err) + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_Win32Msg(__R_FN_PARAMS_FULL, DWORD err, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + RESULT_NORETURN_RESULT(hr); + } + + template + __declspec(noinline) inline DWORD ReportFailure_GetLastErrorMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto err = GetLastErrorFail(__R_FN_CALL_FULL); + auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + ::SetLastError(err); + return err; + } + + template<> + __declspec(noinline) inline RESULT_NORETURN DWORD ReportFailure_GetLastErrorMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto err = GetLastErrorFail(__R_FN_CALL_FULL); + auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + RESULT_NORETURN_RESULT(err); + } + + template<> + __declspec(noinline) inline RESULT_NORETURN DWORD ReportFailure_GetLastErrorMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto err = GetLastErrorFail(__R_FN_CALL_FULL); + auto hr = __HRESULT_FROM_WIN32(err); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + RESULT_NORETURN_RESULT(err); + } + + template + _Success_(true) + _Translates_last_error_to_HRESULT_ + __declspec(noinline) inline HRESULT ReportFailure_GetLastErrorHrMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto hr = GetLastErrorFailHr(__R_FN_CALL_FULL); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + return hr; + } + + template<> + _Success_(true) + _Translates_last_error_to_HRESULT_ + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_GetLastErrorHrMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto hr = GetLastErrorFailHr(__R_FN_CALL_FULL); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + RESULT_NORETURN_RESULT(hr); + } + + template<> + _Success_(true) + _Translates_last_error_to_HRESULT_ + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_GetLastErrorHrMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + auto hr = GetLastErrorFailHr(__R_FN_CALL_FULL); + ReportFailure_Msg(__R_FN_CALL_FULL, ResultStatus::FromResult(hr), formatString, argList); + RESULT_NORETURN_RESULT(hr); + } + + template + _Success_(true) + _Translates_NTSTATUS_to_HRESULT_(status) + __declspec(noinline) inline HRESULT ReportFailure_NtStatusMsg(__R_FN_PARAMS_FULL, NTSTATUS status, _Printf_format_string_ PCSTR formatString, va_list argList) + { + const auto resultPair = ResultStatus::FromStatus(status); + ReportFailure_Msg(__R_FN_CALL_FULL, resultPair, formatString, argList); + return resultPair.hr; + } + + template<> + _Success_(true) + _Translates_NTSTATUS_to_HRESULT_(status) + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_NtStatusMsg(__R_FN_PARAMS_FULL, NTSTATUS status, _Printf_format_string_ PCSTR formatString, va_list argList) + { + const auto resultPair = ResultStatus::FromStatus(status); + ReportFailure_Msg(__R_FN_CALL_FULL, resultPair, formatString, argList); + RESULT_NORETURN_RESULT(resultPair.hr); + } + + template<> + _Success_(true) + _Translates_NTSTATUS_to_HRESULT_(status) + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_NtStatusMsg(__R_FN_PARAMS_FULL, NTSTATUS status, _Printf_format_string_ PCSTR formatString, va_list argList) + { + const auto resultPair = ResultStatus::FromStatus(status); + ReportFailure_Msg(__R_FN_CALL_FULL, resultPair, formatString, argList); + RESULT_NORETURN_RESULT(resultPair.hr); + } + + template + __declspec(noinline) inline HRESULT ReportFailure_CaughtExceptionMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + // Pre-populate the buffer with our message, the exception message will be added to it... + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + StringCchCatW(message, ARRAYSIZE(message), L" -- "); + return ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), SupportedExceptions::Default).hr; + } + + template<> + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_CaughtExceptionMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + // Pre-populate the buffer with our message, the exception message will be added to it... + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + StringCchCatW(message, ARRAYSIZE(message), L" -- "); + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), SupportedExceptions::Default).hr); + } + + template<> + __declspec(noinline) inline RESULT_NORETURN HRESULT ReportFailure_CaughtExceptionMsg(__R_FN_PARAMS_FULL, _Printf_format_string_ PCSTR formatString, va_list argList) + { + // Pre-populate the buffer with our message, the exception message will be added to it... + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + StringCchCatW(message, ARRAYSIZE(message), L" -- "); + RESULT_NORETURN_RESULT(ReportFailure_CaughtExceptionCommon(__R_FN_CALL_FULL, message, ARRAYSIZE(message), SupportedExceptions::Default).hr); + } + + + //***************************************************************************** + // Support for throwing custom exception types + //***************************************************************************** + +#ifdef WIL_ENABLE_EXCEPTIONS + inline HRESULT GetErrorCode(_In_ ResultException &exception) WI_NOEXCEPT + { + return exception.GetErrorCode(); + } + + inline void SetFailureInfo(_In_ FailureInfo const &failure, _Inout_ ResultException &exception) WI_NOEXCEPT + { + return exception.SetFailureInfo(failure); + } + +#ifdef __cplusplus_winrt + inline HRESULT GetErrorCode(_In_ Platform::Exception^ exception) WI_NOEXCEPT + { + return exception->HResult; + } + + inline void SetFailureInfo(_In_ FailureInfo const &, _Inout_ Platform::Exception^ exception) WI_NOEXCEPT + { + // no-op -- once a PlatformException^ is created, we can't modify the message, but this function must + // exist to distinguish this from ResultException + } +#endif + + template + RESULT_NORETURN inline void ReportFailure_CustomExceptionHelper(_Inout_ T &exception, __R_FN_PARAMS_FULL, _In_opt_ PCWSTR message = nullptr) + { + // When seeing the error: "cannot convert parameter 1 from 'XXX' to 'wil::ResultException &'" + // Custom exceptions must be based upon either ResultException or Platform::Exception^ to be used with ResultException.h. + // This compilation error indicates an attempt to throw an incompatible exception type. + const HRESULT hr = GetErrorCode(exception); + + FailureInfo failure; + wchar_t debugString[2048]; + char callContextString[1024]; + + LogFailure(__R_FN_CALL_FULL, FailureType::Exception, ResultStatus::FromResult(hr), message, false, // false = does not need debug string + debugString, ARRAYSIZE(debugString), callContextString, ARRAYSIZE(callContextString), &failure); + + if (WI_IsFlagSet(failure.flags, FailureFlags::RequestFailFast)) + { + WilFailFast(failure); + } + + // push the failure info context into the custom exception class + SetFailureInfo(failure, exception); + + throw exception; + } + + template + __declspec(noreturn, noinline) inline void ReportFailure_CustomException(__R_FN_PARAMS _In_ T exception) + { + __R_FN_LOCALS_RA; + ReportFailure_CustomExceptionHelper(exception, __R_FN_CALL_FULL); + } + + template + __declspec(noreturn, noinline) inline void ReportFailure_CustomExceptionMsg(__R_FN_PARAMS _In_ T exception, _In_ _Printf_format_string_ PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + wchar_t message[2048]; + PrintLoggingMessage(message, ARRAYSIZE(message), formatString, argList); + + __R_FN_LOCALS_RA; + ReportFailure_CustomExceptionHelper(exception, __R_FN_CALL_FULL, message); + } +#endif + + namespace __R_NS_NAME + { + //***************************************************************************** + // Return Macros + //***************************************************************************** + + __R_DIRECT_METHOD(void, Return_Hr)(__R_DIRECT_FN_PARAMS HRESULT hr) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_Hr(__R_DIRECT_FN_CALL hr); + } + + _Success_(true) + _Translates_Win32_to_HRESULT_(err) + __R_DIRECT_METHOD(HRESULT, Return_Win32)(__R_DIRECT_FN_PARAMS DWORD err) WI_NOEXCEPT + { + __R_FN_LOCALS; + return wil::details::ReportFailure_Win32(__R_DIRECT_FN_CALL err); + } + + _Success_(true) + _Translates_last_error_to_HRESULT_ + __R_DIRECT_METHOD(HRESULT, Return_GetLastError)(__R_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + return wil::details::ReportFailure_GetLastErrorHr(__R_DIRECT_FN_CALL_ONLY); + } + + _Success_(true) + _Translates_NTSTATUS_to_HRESULT_(status) + __R_DIRECT_METHOD(HRESULT, Return_NtStatus)(__R_DIRECT_FN_PARAMS NTSTATUS status) WI_NOEXCEPT + { + __R_FN_LOCALS; + return wil::details::ReportFailure_NtStatus(__R_DIRECT_FN_CALL status); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + __R_DIRECT_METHOD(HRESULT, Return_CaughtException)(__R_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + return wil::details::ReportFailure_CaughtException(__R_DIRECT_FN_CALL_ONLY); + } +#endif + + __R_DIRECT_METHOD(void, Return_HrMsg)(__R_DIRECT_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__R_DIRECT_FN_CALL hr, formatString, argList); + } + + _Success_(true) + _Translates_Win32_to_HRESULT_(err) + __R_DIRECT_METHOD(HRESULT, Return_Win32Msg)(__R_DIRECT_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + return wil::details::ReportFailure_Win32Msg(__R_DIRECT_FN_CALL err, formatString, argList); + } + + _Success_(true) + _Translates_last_error_to_HRESULT_ + __R_DIRECT_METHOD(HRESULT, Return_GetLastErrorMsg)(__R_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + return wil::details::ReportFailure_GetLastErrorHrMsg(__R_DIRECT_FN_CALL formatString, argList); + } + + _Success_(true) + _Translates_NTSTATUS_to_HRESULT_(status) + __R_DIRECT_METHOD(HRESULT, Return_NtStatusMsg)(__R_DIRECT_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + return wil::details::ReportFailure_NtStatusMsg(__R_DIRECT_FN_CALL status, formatString, argList); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + __R_DIRECT_METHOD(HRESULT, Return_CaughtExceptionMsg)(__R_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + return wil::details::ReportFailure_CaughtExceptionMsg(__R_DIRECT_FN_CALL formatString, argList); + } +#endif + + //***************************************************************************** + // Log Macros + //***************************************************************************** + + _Post_satisfies_(return == hr) + __R_DIRECT_METHOD(HRESULT, Log_Hr)(__R_DIRECT_FN_PARAMS HRESULT hr) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_Hr(__R_DIRECT_FN_CALL hr); + return hr; + } + + _Post_satisfies_(return == err) + __R_DIRECT_METHOD(DWORD, Log_Win32)(__R_DIRECT_FN_PARAMS DWORD err) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_Win32(__R_DIRECT_FN_CALL err); + return err; + } + + __R_DIRECT_METHOD(DWORD, Log_GetLastError)(__R_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + return wil::details::ReportFailure_GetLastError(__R_DIRECT_FN_CALL_ONLY); + } + + _Post_satisfies_(return == status) + __R_DIRECT_METHOD(NTSTATUS, Log_NtStatus)(__R_DIRECT_FN_PARAMS NTSTATUS status) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_NtStatus(__R_DIRECT_FN_CALL status); + return status; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + __R_DIRECT_METHOD(HRESULT, Log_CaughtException)(__R_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + return wil::details::ReportFailure_CaughtException(__R_DIRECT_FN_CALL_ONLY); + } +#endif + + __R_INTERNAL_METHOD(_Log_Hr)(__R_INTERNAL_FN_PARAMS HRESULT hr) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_Hr(__R_INTERNAL_FN_CALL hr); + } + + __R_INTERNAL_METHOD(_Log_GetLastError)(__R_INTERNAL_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_GetLastError(__R_INTERNAL_FN_CALL_ONLY); + } + + __R_INTERNAL_METHOD(_Log_Win32)(__R_INTERNAL_FN_PARAMS DWORD err) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_Win32(__R_INTERNAL_FN_CALL err); + } + + __R_INTERNAL_METHOD(_Log_NullAlloc)(__R_INTERNAL_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_Hr(__R_INTERNAL_FN_CALL E_OUTOFMEMORY); + } + + __R_INTERNAL_METHOD(_Log_NtStatus)(__R_INTERNAL_FN_PARAMS NTSTATUS status) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_NtStatus(__R_INTERNAL_FN_CALL status); + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == hr) + __R_CONDITIONAL_METHOD(HRESULT, Log_IfFailed)(__R_CONDITIONAL_FN_PARAMS HRESULT hr) + { + if (FAILED(hr)) + { + __R_CALL_INTERNAL_METHOD(_Log_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + return hr; + } + + _Post_satisfies_(return == hr) + __R_CONDITIONAL_NOINLINE_METHOD(HRESULT, Log_IfFailedWithExpected)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, unsigned int expectedCount, ...) WI_NOEXCEPT + { + va_list args; + va_start(args, expectedCount); + + if (FAILED(hr)) + { + unsigned int expectedIndex; + for (expectedIndex = 0; expectedIndex < expectedCount; ++expectedIndex) + { + if (hr == va_arg(args, HRESULT)) + { + break; + } + } + + if (expectedIndex == expectedCount) + { + __R_CALL_INTERNAL_METHOD(_Log_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + } + + va_end(args); + return hr; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == ret) + __R_CONDITIONAL_METHOD(BOOL, Log_IfWin32BoolFalse)(__R_CONDITIONAL_FN_PARAMS BOOL ret) + { + if (!ret) + { + __R_CALL_INTERNAL_METHOD(_Log_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return ret; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == err) + __R_CONDITIONAL_METHOD(DWORD, Log_IfWin32Error)(__R_CONDITIONAL_FN_PARAMS DWORD err) + { + if (FAILED_WIN32(err)) + { + __R_CALL_INTERNAL_METHOD(_Log_Win32)(__R_CONDITIONAL_FN_CALL err); + } + return err; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == handle) + __R_CONDITIONAL_METHOD(HANDLE, Log_IfHandleInvalid)(__R_CONDITIONAL_FN_PARAMS HANDLE handle) + { + if (handle == INVALID_HANDLE_VALUE) + { + __R_CALL_INTERNAL_METHOD(_Log_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return handle; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == handle) + __R_CONDITIONAL_METHOD(HANDLE, Log_IfHandleNull)(__R_CONDITIONAL_FN_PARAMS HANDLE handle) + { + if (handle == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Log_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return handle; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) + __R_CONDITIONAL_TEMPLATE_METHOD(PointerT, Log_IfNullAlloc)(__R_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer) WI_NOEXCEPT + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Log_NullAlloc)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_TEMPLATE_METHOD(void, Log_IfNullAlloc)(__R_CONDITIONAL_FN_PARAMS const PointerT& pointer) WI_NOEXCEPT + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Log_NullAlloc)(__R_CONDITIONAL_FN_CALL_ONLY); + } + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == condition) + __R_CONDITIONAL_METHOD(bool, Log_HrIf)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition) + { + if (condition) + { + __R_CALL_INTERNAL_METHOD(_Log_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + return condition; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == condition) + __R_CONDITIONAL_METHOD(bool, Log_HrIfFalse)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition) + { + if (!condition) + { + __R_CALL_INTERNAL_METHOD(_Log_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + return condition; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) + __R_CONDITIONAL_TEMPLATE_METHOD(PointerT, Log_HrIfNull)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _Pre_maybenull_ PointerT pointer) WI_NOEXCEPT + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Log_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_TEMPLATE_METHOD(void, Log_HrIfNull)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _In_opt_ const PointerT& pointer) WI_NOEXCEPT + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Log_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == condition) + __R_CONDITIONAL_METHOD(bool, Log_GetLastErrorIf)(__R_CONDITIONAL_FN_PARAMS bool condition) + { + if (condition) + { + __R_CALL_INTERNAL_METHOD(_Log_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return condition; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == condition) + __R_CONDITIONAL_METHOD(bool, Log_GetLastErrorIfFalse)(__R_CONDITIONAL_FN_PARAMS bool condition) + { + if (!condition) + { + __R_CALL_INTERNAL_METHOD(_Log_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return condition; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) + __R_CONDITIONAL_TEMPLATE_METHOD(PointerT, Log_GetLastErrorIfNull)(__R_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer) WI_NOEXCEPT + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Log_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_TEMPLATE_METHOD(void, Log_GetLastErrorIfNull)(__R_CONDITIONAL_FN_PARAMS _In_opt_ const PointerT& pointer) WI_NOEXCEPT + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Log_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == status) + __R_CONDITIONAL_METHOD(NTSTATUS, Log_IfNtStatusFailed)(__R_CONDITIONAL_FN_PARAMS NTSTATUS status) + { + if (FAILED_NTSTATUS(status)) + { + __R_CALL_INTERNAL_METHOD(_Log_NtStatus)(__R_CONDITIONAL_FN_CALL status); + } + return status; + } + + _Post_satisfies_(return == hr) + __R_DIRECT_METHOD(HRESULT, Log_HrMsg)(__R_DIRECT_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__R_DIRECT_FN_CALL hr, formatString, argList); + return hr; + } + + _Post_satisfies_(return == err) + __R_DIRECT_METHOD(DWORD, Log_Win32Msg)(__R_DIRECT_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_Win32Msg(__R_DIRECT_FN_CALL err, formatString, argList); + return err; + } + + __R_DIRECT_METHOD(DWORD, Log_GetLastErrorMsg)(__R_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + return wil::details::ReportFailure_GetLastErrorMsg(__R_DIRECT_FN_CALL formatString, argList); + } + + _Post_satisfies_(return == status) + __R_DIRECT_METHOD(NTSTATUS, Log_NtStatusMsg)(__R_DIRECT_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_NtStatusMsg(__R_DIRECT_FN_CALL status, formatString, argList); + return status; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + __R_DIRECT_METHOD(HRESULT, Log_CaughtExceptionMsg)(__R_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + return wil::details::ReportFailure_CaughtExceptionMsg(__R_DIRECT_FN_CALL formatString, argList); + } +#endif + + __R_INTERNAL_NOINLINE_METHOD(_Log_HrMsg)(__R_INTERNAL_NOINLINE_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__R_INTERNAL_NOINLINE_FN_CALL hr, formatString, argList); + } + + __R_INTERNAL_NOINLINE_METHOD(_Log_GetLastErrorMsg)(__R_INTERNAL_NOINLINE_FN_PARAMS _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_GetLastErrorMsg(__R_INTERNAL_NOINLINE_FN_CALL formatString, argList); + } + + __R_INTERNAL_NOINLINE_METHOD(_Log_Win32Msg)(__R_INTERNAL_NOINLINE_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_Win32Msg(__R_INTERNAL_NOINLINE_FN_CALL err, formatString, argList); + } + + __R_INTERNAL_NOINLINE_METHOD(_Log_NullAllocMsg)(__R_INTERNAL_NOINLINE_FN_PARAMS _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__R_INTERNAL_NOINLINE_FN_CALL E_OUTOFMEMORY, formatString, argList); + } + + __R_INTERNAL_NOINLINE_METHOD(_Log_NtStatusMsg)(__R_INTERNAL_NOINLINE_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __R_FN_LOCALS; + wil::details::ReportFailure_NtStatusMsg(__R_INTERNAL_NOINLINE_FN_CALL status, formatString, argList); + } + + _Post_satisfies_(return == hr) + __R_CONDITIONAL_NOINLINE_METHOD(HRESULT, Log_IfFailedMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (FAILED(hr)) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return hr; + } + + _Post_satisfies_(return == ret) + __R_CONDITIONAL_NOINLINE_METHOD(BOOL, Log_IfWin32BoolFalseMsg)(__R_CONDITIONAL_FN_PARAMS BOOL ret, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (!ret) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return ret; + } + + _Post_satisfies_(return == err) + __R_CONDITIONAL_NOINLINE_METHOD(DWORD, Log_IfWin32ErrorMsg)(__R_CONDITIONAL_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (FAILED_WIN32(err)) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_Win32Msg)(__R_CONDITIONAL_NOINLINE_FN_CALL err, formatString, argList); + } + return err; + } + + _Post_satisfies_(return == handle) + __R_CONDITIONAL_NOINLINE_METHOD(HANDLE, Log_IfHandleInvalidMsg)(__R_CONDITIONAL_FN_PARAMS HANDLE handle, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (handle == INVALID_HANDLE_VALUE) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return handle; + } + + _Post_satisfies_(return == handle) + __R_CONDITIONAL_NOINLINE_METHOD(HANDLE, Log_IfHandleNullMsg)(__R_CONDITIONAL_FN_PARAMS HANDLE handle, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (handle == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return handle; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(PointerT, Log_IfNullAllocMsg)(__R_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_NullAllocMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL_ONLY, formatString, argList); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, Log_IfNullAllocMsg)(__R_CONDITIONAL_FN_PARAMS const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_NullAllocMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL_ONLY, formatString, argList); + } + } + + _Post_satisfies_(return == condition) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Log_HrIfMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return condition; + } + + _Post_satisfies_(return == condition) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Log_HrIfFalseMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (!condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return condition; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(PointerT, Log_HrIfNullMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, Log_HrIfNullMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _In_opt_ const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + } + + _Post_satisfies_(return == condition) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Log_GetLastErrorIfMsg)(__R_CONDITIONAL_FN_PARAMS bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return condition; + } + + _Post_satisfies_(return == condition) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Log_GetLastErrorIfFalseMsg)(__R_CONDITIONAL_FN_PARAMS bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (!condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return condition; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(PointerT, Log_GetLastErrorIfNullMsg)(__R_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, Log_GetLastErrorIfNullMsg)(__R_CONDITIONAL_FN_PARAMS _In_opt_ const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + } + + _Post_satisfies_(return == status) + __R_CONDITIONAL_NOINLINE_METHOD(NTSTATUS, Log_IfNtStatusFailedMsg)(__R_CONDITIONAL_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (FAILED_NTSTATUS(status)) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Log_NtStatusMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL status, formatString, argList); + } + return status; + } + } // namespace __R_NS_NAME + + namespace __RFF_NS_NAME + { + //***************************************************************************** + // FailFast Macros + //***************************************************************************** + + __RFF_DIRECT_NORET_METHOD(void, FailFast_Hr)(__RFF_DIRECT_FN_PARAMS HRESULT hr) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_Hr(__RFF_DIRECT_FN_CALL hr); + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_Win32)(__RFF_DIRECT_FN_PARAMS DWORD err) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_Win32(__RFF_DIRECT_FN_CALL err); + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_GetLastError)(__RFF_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_GetLastError(__RFF_DIRECT_FN_CALL_ONLY); + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_NtStatus)(__RFF_DIRECT_FN_PARAMS NTSTATUS status) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_NtStatus(__RFF_DIRECT_FN_CALL status); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + __RFF_DIRECT_NORET_METHOD(void, FailFast_CaughtException)(__RFF_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_CaughtException(__RFF_DIRECT_FN_CALL_ONLY); + } +#endif + + __RFF_INTERNAL_NORET_METHOD(_FailFast_Hr)(__RFF_INTERNAL_FN_PARAMS HRESULT hr) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_Hr(__RFF_INTERNAL_FN_CALL hr); + } + + __RFF_INTERNAL_NORET_METHOD(_FailFast_GetLastError)(__RFF_INTERNAL_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_GetLastError(__RFF_INTERNAL_FN_CALL_ONLY); + } + + __RFF_INTERNAL_NORET_METHOD(_FailFast_Win32)(__RFF_INTERNAL_FN_PARAMS DWORD err) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_Win32(__RFF_INTERNAL_FN_CALL err); + } + + __RFF_INTERNAL_NORET_METHOD(_FailFast_NullAlloc)(__RFF_INTERNAL_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_Hr(__RFF_INTERNAL_FN_CALL E_OUTOFMEMORY); + } + + __RFF_INTERNAL_NORET_METHOD(_FailFast_NtStatus)(__RFF_INTERNAL_FN_PARAMS NTSTATUS status) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_NtStatus(__RFF_INTERNAL_FN_CALL status); + } + + _Post_satisfies_(return == hr) _When_(FAILED(hr), _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(HRESULT, FailFast_IfFailed)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr) WI_NOEXCEPT + { + if (FAILED(hr)) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Hr)(__RFF_CONDITIONAL_FN_CALL hr); + } + return hr; + } + + _Post_satisfies_(return == ret) _When_(!ret, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(BOOL, FailFast_IfWin32BoolFalse)(__RFF_CONDITIONAL_FN_PARAMS BOOL ret) WI_NOEXCEPT + { + if (!ret) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_GetLastError)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return ret; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + _Post_satisfies_(return == err) _When_(FAILED_WIN32(err), _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(DWORD, FailFast_IfWin32Error)(__RFF_CONDITIONAL_FN_PARAMS DWORD err) + { + if (FAILED_WIN32(err)) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Win32)(__RFF_CONDITIONAL_FN_CALL err); + } + return err; + } + + _Post_satisfies_(return == handle) _When_(handle == INVALID_HANDLE_VALUE, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(HANDLE, FailFast_IfHandleInvalid)(__RFF_CONDITIONAL_FN_PARAMS HANDLE handle) WI_NOEXCEPT + { + if (handle == INVALID_HANDLE_VALUE) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_GetLastError)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return handle; + } + + _Post_satisfies_(return == handle) _When_(handle == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(RESULT_NORETURN_NULL HANDLE, FailFast_IfHandleNull)(__RFF_CONDITIONAL_FN_PARAMS HANDLE handle) WI_NOEXCEPT + { + if (handle == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_GetLastError)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return handle; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFast_IfNullAlloc)(__RFF_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_NullAlloc)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return pointer; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __RFF_CONDITIONAL_TEMPLATE_METHOD(void, FailFast_IfNullAlloc)(__RFF_CONDITIONAL_FN_PARAMS const PointerT& pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_NullAlloc)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(bool, FailFast_HrIf)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition) WI_NOEXCEPT + { + if (condition) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Hr)(__RFF_CONDITIONAL_FN_CALL hr); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(bool, FailFast_HrIfFalse)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition) WI_NOEXCEPT + { + if (!condition) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Hr)(__RFF_CONDITIONAL_FN_CALL hr); + } + return condition; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFast_HrIfNull)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, _Pre_maybenull_ PointerT pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Hr)(__RFF_CONDITIONAL_FN_CALL hr); + } + return pointer; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __RFF_CONDITIONAL_TEMPLATE_METHOD(void, FailFast_HrIfNull)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, _In_opt_ const PointerT& pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Hr)(__RFF_CONDITIONAL_FN_CALL hr); + } + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(bool, FailFast_GetLastErrorIf)(__RFF_CONDITIONAL_FN_PARAMS bool condition) WI_NOEXCEPT + { + if (condition) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_GetLastError)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(bool, FailFast_GetLastErrorIfFalse)(__RFF_CONDITIONAL_FN_PARAMS bool condition) WI_NOEXCEPT + { + if (!condition) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_GetLastError)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return condition; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFast_GetLastErrorIfNull)(__RFF_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_GetLastError)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return pointer; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __RFF_CONDITIONAL_TEMPLATE_METHOD(void, FailFast_GetLastErrorIfNull)(__RFF_CONDITIONAL_FN_PARAMS _In_opt_ const PointerT& pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_GetLastError)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + } + + _Post_satisfies_(return == status) _When_(FAILED_NTSTATUS(status), _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(NTSTATUS, FailFast_IfNtStatusFailed)(__RFF_CONDITIONAL_FN_PARAMS NTSTATUS status) WI_NOEXCEPT + { + if (FAILED_NTSTATUS(status)) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_NtStatus)(__RFF_CONDITIONAL_FN_CALL status); + } + return status; + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_HrMsg)(__RFF_DIRECT_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __RFF_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__RFF_DIRECT_FN_CALL hr, formatString, argList); + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_Win32Msg)(__RFF_DIRECT_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __RFF_FN_LOCALS; + wil::details::ReportFailure_Win32Msg(__RFF_DIRECT_FN_CALL err, formatString, argList); + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_GetLastErrorMsg)(__RFF_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __RFF_FN_LOCALS; + wil::details::ReportFailure_GetLastErrorMsg(__RFF_DIRECT_FN_CALL formatString, argList); + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_NtStatusMsg)(__RFF_DIRECT_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __RFF_FN_LOCALS; + wil::details::ReportFailure_NtStatusMsg(__RFF_DIRECT_FN_CALL status, formatString, argList); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + __RFF_DIRECT_NORET_METHOD(void, FailFast_CaughtExceptionMsg)(__RFF_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __RFF_FN_LOCALS; + wil::details::ReportFailure_CaughtExceptionMsg(__RFF_DIRECT_FN_CALL formatString, argList); + } +#endif + + __RFF_INTERNAL_NOINLINE_NORET_METHOD(_FailFast_HrMsg)(__RFF_INTERNAL_NOINLINE_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__RFF_INTERNAL_NOINLINE_FN_CALL hr, formatString, argList); + } + + __RFF_INTERNAL_NOINLINE_NORET_METHOD(_FailFast_GetLastErrorMsg)(__RFF_INTERNAL_NOINLINE_FN_PARAMS _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_GetLastErrorMsg(__RFF_INTERNAL_NOINLINE_FN_CALL formatString, argList); + } + + __RFF_INTERNAL_NOINLINE_NORET_METHOD(_FailFast_Win32Msg)(__RFF_INTERNAL_NOINLINE_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_Win32Msg(__RFF_INTERNAL_NOINLINE_FN_CALL err, formatString, argList); + } + + __RFF_INTERNAL_NOINLINE_NORET_METHOD(_FailFast_NullAllocMsg)(__RFF_INTERNAL_NOINLINE_FN_PARAMS _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__RFF_INTERNAL_NOINLINE_FN_CALL E_OUTOFMEMORY, formatString, argList); + } + + __RFF_INTERNAL_NOINLINE_NORET_METHOD(_FailFast_NtStatusMsg)(__RFF_INTERNAL_NOINLINE_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_NtStatusMsg(__RFF_INTERNAL_NOINLINE_FN_CALL status, formatString, argList); + } + + _Post_satisfies_(return == hr) _When_(FAILED(hr), _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(HRESULT, FailFast_IfFailedMsg)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (FAILED(hr)) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_HrMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return hr; + } + + _Post_satisfies_(return == ret) _When_(!ret, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(BOOL, FailFast_IfWin32BoolFalseMsg)(__RFF_CONDITIONAL_FN_PARAMS BOOL ret, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (!ret) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_GetLastErrorMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return ret; + } + + _Post_satisfies_(return == err) _When_(FAILED_WIN32(err), _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(DWORD, FailFast_IfWin32ErrorMsg)(__RFF_CONDITIONAL_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (FAILED_WIN32(err)) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_Win32Msg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL err, formatString, argList); + } + return err; + } + + _Post_satisfies_(return == handle) _When_(handle == INVALID_HANDLE_VALUE, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(HANDLE, FailFast_IfHandleInvalidMsg)(__RFF_CONDITIONAL_FN_PARAMS HANDLE handle, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (handle == INVALID_HANDLE_VALUE) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_GetLastErrorMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return handle; + } + + _Post_satisfies_(return == handle) _When_(handle == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(RESULT_NORETURN_NULL HANDLE, FailFast_IfHandleNullMsg)(__RFF_CONDITIONAL_FN_PARAMS HANDLE handle, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (handle == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_GetLastErrorMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return handle; + } + + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFast_IfNullAllocMsg)(__RFF_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_NullAllocMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL_ONLY, formatString, argList); + } + return pointer; + } + + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, FailFast_IfNullAllocMsg)(__RFF_CONDITIONAL_FN_PARAMS const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_NullAllocMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL_ONLY, formatString, argList); + } + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(bool, FailFast_HrIfMsg)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (condition) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_HrMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(bool, FailFast_HrIfFalseMsg)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (!condition) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_HrMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return condition; + } + + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFast_HrIfNullMsg)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_HrMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return pointer; + } + + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, FailFast_HrIfNullMsg)(__RFF_CONDITIONAL_FN_PARAMS HRESULT hr, _In_opt_ const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_HrMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(bool, FailFast_GetLastErrorIfMsg)(__RFF_CONDITIONAL_FN_PARAMS bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (condition) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_GetLastErrorMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(bool, FailFast_GetLastErrorIfFalseMsg)(__RFF_CONDITIONAL_FN_PARAMS bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (!condition) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_GetLastErrorMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return condition; + } + + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFast_GetLastErrorIfNullMsg)(__RFF_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_GetLastErrorMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return pointer; + } + + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, FailFast_GetLastErrorIfNullMsg)(__RFF_CONDITIONAL_FN_PARAMS _In_opt_ const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_GetLastErrorMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + } + + _Post_satisfies_(return == status) _When_(FAILED_NTSTATUS(status), _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(NTSTATUS, FailFast_IfNtStatusFailedMsg)(__RFF_CONDITIONAL_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (FAILED_NTSTATUS(status)) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_NtStatusMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL status, formatString, argList); + } + return status; + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_Unexpected)(__RFF_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_Hr(__RFF_DIRECT_FN_CALL E_UNEXPECTED); + } + + __RFF_INTERNAL_NORET_METHOD(_FailFast_Unexpected)(__RFF_INTERNAL_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_Hr(__RFF_INTERNAL_FN_CALL E_UNEXPECTED); + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(bool, FailFast_If)(__RFF_CONDITIONAL_FN_PARAMS bool condition) WI_NOEXCEPT + { + if (condition) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Unexpected)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(bool, FailFast_IfFalse)(__RFF_CONDITIONAL_FN_PARAMS bool condition) WI_NOEXCEPT + { + if (!condition) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Unexpected)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return condition; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + __WI_SUPPRESS_NULLPTR_ANALYSIS + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFast_IfNull)(__RFF_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Unexpected)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + return pointer; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __WI_SUPPRESS_NULLPTR_ANALYSIS + __RFF_CONDITIONAL_TEMPLATE_METHOD(void, FailFast_IfNull)(__RFF_CONDITIONAL_FN_PARAMS _In_opt_ const PointerT& pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFast_Unexpected)(__RFF_CONDITIONAL_FN_CALL_ONLY); + } + } + + __RFF_DIRECT_NORET_METHOD(void, FailFast_UnexpectedMsg)(__RFF_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + va_list argList; + va_start(argList, formatString); + __RFF_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__RFF_DIRECT_FN_CALL E_UNEXPECTED, formatString, argList); + } + + __RFF_INTERNAL_NOINLINE_NORET_METHOD(_FailFast_UnexpectedMsg)(__RFF_INTERNAL_NOINLINE_FN_PARAMS _Printf_format_string_ PCSTR formatString, va_list argList) WI_NOEXCEPT + { + __RFF_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__RFF_INTERNAL_NOINLINE_FN_CALL E_UNEXPECTED, formatString, argList); + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(bool, FailFast_IfMsg)(__RFF_CONDITIONAL_FN_PARAMS bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (condition) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_UnexpectedMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_METHOD(bool, FailFast_IfFalseMsg)(__RFF_CONDITIONAL_FN_PARAMS bool condition, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (!condition) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_UnexpectedMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return condition; + } + + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFast_IfNullMsg)(__RFF_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_UnexpectedMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return pointer; + } + + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __RFF_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, FailFast_IfNullMsg)(__RFF_CONDITIONAL_FN_PARAMS _In_opt_ const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) WI_NOEXCEPT + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __RFF_CALL_INTERNAL_NOINLINE_METHOD(_FailFast_UnexpectedMsg)(__RFF_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + } + + //***************************************************************************** + // FailFast Immediate Macros + //***************************************************************************** + + __RFF_DIRECT_NORET_METHOD(void, FailFastImmediate_Unexpected)() WI_NOEXCEPT + { + __fastfail(FAST_FAIL_FATAL_APP_EXIT); + } + + __RFF_INTERNAL_NORET_METHOD(_FailFastImmediate_Unexpected)() WI_NOEXCEPT + { + __fastfail(FAST_FAIL_FATAL_APP_EXIT); + } + + _Post_satisfies_(return == hr) _When_(FAILED(hr), _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(HRESULT, FailFastImmediate_IfFailed)(HRESULT hr) WI_NOEXCEPT + { + if (FAILED(hr)) + { + __RFF_CALL_INTERNAL_METHOD(_FailFastImmediate_Unexpected)(); + } + return hr; + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(bool, FailFastImmediate_If)(bool condition) WI_NOEXCEPT + { + if (condition) + { + __RFF_CALL_INTERNAL_METHOD(_FailFastImmediate_Unexpected)(); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(bool, FailFastImmediate_IfFalse)(bool condition) WI_NOEXCEPT + { + if (!condition) + { + __RFF_CALL_INTERNAL_METHOD(_FailFastImmediate_Unexpected)(); + } + return condition; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __RFF_CONDITIONAL_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, FailFastImmediate_IfNull)(_Pre_maybenull_ PointerT pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFastImmediate_Unexpected)(); + } + return pointer; + } + + // Should be decorated WI_NOEXCEPT, but conflicts with forceinline. + template <__RFF_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __RFF_CONDITIONAL_TEMPLATE_METHOD(void, FailFastImmediate_IfNull)(_In_opt_ const PointerT& pointer) + { + if (pointer == nullptr) + { + __RFF_CALL_INTERNAL_METHOD(_FailFastImmediate_Unexpected)(); + } + } + + _Post_satisfies_(return == status) _When_(FAILED_NTSTATUS(status), _Analysis_noreturn_) + __RFF_CONDITIONAL_METHOD(NTSTATUS, FailFastImmediate_IfNtStatusFailed)(NTSTATUS status) WI_NOEXCEPT + { + if (FAILED_NTSTATUS(status)) + { + __RFF_CALL_INTERNAL_METHOD(_FailFastImmediate_Unexpected)(); + } + return status; + } + } // namespace __RFF_NS_NAME + + namespace __R_NS_NAME + { + //***************************************************************************** + // Exception Macros + //***************************************************************************** + +#ifdef WIL_ENABLE_EXCEPTIONS + __R_DIRECT_NORET_METHOD(void, Throw_Hr)(__R_DIRECT_FN_PARAMS HRESULT hr) + { + __R_FN_LOCALS; + wil::details::ReportFailure_Hr(__R_DIRECT_FN_CALL hr); + } + + __R_DIRECT_NORET_METHOD(void, Throw_Win32)(__R_DIRECT_FN_PARAMS DWORD err) + { + __R_FN_LOCALS; + wil::details::ReportFailure_Win32(__R_DIRECT_FN_CALL err); + } + + __R_DIRECT_NORET_METHOD(void, Throw_GetLastError)(__R_DIRECT_FN_PARAMS_ONLY) + { + __R_FN_LOCALS; + wil::details::ReportFailure_GetLastError(__R_DIRECT_FN_CALL_ONLY); + } + + __R_DIRECT_NORET_METHOD(void, Throw_NtStatus)(__R_DIRECT_FN_PARAMS NTSTATUS status) + { + __R_FN_LOCALS; + wil::details::ReportFailure_NtStatus(__R_DIRECT_FN_CALL status); + } + + __R_DIRECT_NORET_METHOD(void, Throw_CaughtException)(__R_DIRECT_FN_PARAMS_ONLY) + { + __R_FN_LOCALS; + wil::details::ReportFailure_CaughtException(__R_DIRECT_FN_CALL_ONLY); + } + + __R_INTERNAL_NORET_METHOD(_Throw_Hr)(__R_INTERNAL_FN_PARAMS HRESULT hr) + { + __R_FN_LOCALS; + wil::details::ReportFailure_Hr(__R_INTERNAL_FN_CALL hr); + } + + __R_INTERNAL_NORET_METHOD(_Throw_GetLastError)(__R_INTERNAL_FN_PARAMS_ONLY) + { + __R_FN_LOCALS; + wil::details::ReportFailure_GetLastError(__R_INTERNAL_FN_CALL_ONLY); + } + + __R_INTERNAL_NORET_METHOD(_Throw_Win32)(__R_INTERNAL_FN_PARAMS DWORD err) + { + __R_FN_LOCALS; + wil::details::ReportFailure_Win32(__R_INTERNAL_FN_CALL err); + } + + __R_INTERNAL_NORET_METHOD(_Throw_NullAlloc)(__R_INTERNAL_FN_PARAMS_ONLY) + { + __R_FN_LOCALS; + wil::details::ReportFailure_Hr(__R_INTERNAL_FN_CALL E_OUTOFMEMORY); + } + + __R_INTERNAL_NORET_METHOD(_Throw_NtStatus)(__R_INTERNAL_FN_PARAMS NTSTATUS status) + { + __R_FN_LOCALS; + wil::details::ReportFailure_NtStatus(__R_INTERNAL_FN_CALL status); + } + + _Post_satisfies_(return == hr) _When_(FAILED(hr), _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(HRESULT, Throw_IfFailed)(__R_CONDITIONAL_FN_PARAMS HRESULT hr) + { + if (FAILED(hr)) + { + __R_CALL_INTERNAL_METHOD(_Throw_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + return hr; + } + + _Post_satisfies_(return == ret) _When_(!ret, _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(BOOL, Throw_IfWin32BoolFalse)(__R_CONDITIONAL_FN_PARAMS BOOL ret) + { + if (!ret) + { + __R_CALL_INTERNAL_METHOD(_Throw_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return ret; + } + + _Post_satisfies_(return == err) _When_(FAILED_WIN32(err), _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(DWORD, Throw_IfWin32Error)(__R_CONDITIONAL_FN_PARAMS DWORD err) + { + if (FAILED_WIN32(err)) + { + __R_CALL_INTERNAL_METHOD(_Throw_Win32)(__R_CONDITIONAL_FN_CALL err); + } + return err; + } + + _Post_satisfies_(return == handle) _When_(handle == INVALID_HANDLE_VALUE, _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(HANDLE, Throw_IfHandleInvalid)(__R_CONDITIONAL_FN_PARAMS HANDLE handle) + { + if (handle == INVALID_HANDLE_VALUE) + { + __R_CALL_INTERNAL_METHOD(_Throw_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return handle; + } + + _Post_satisfies_(return == handle) _When_(handle == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(RESULT_NORETURN_NULL HANDLE, Throw_IfHandleNull)(__R_CONDITIONAL_FN_PARAMS HANDLE handle) + { + if (handle == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Throw_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return handle; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, Throw_IfNullAlloc)(__R_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer) + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Throw_NullAlloc)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_TEMPLATE_METHOD(void, Throw_IfNullAlloc)(__R_CONDITIONAL_FN_PARAMS const PointerT& pointer) + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Throw_NullAlloc)(__R_CONDITIONAL_FN_CALL_ONLY); + } + } + + _Post_satisfies_(return == condition) + _When_(condition, _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(bool, Throw_HrIf)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition) + { + if (condition) + { + __R_CALL_INTERNAL_METHOD(_Throw_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + return condition; + } + + _Post_satisfies_(return == condition) + _When_(!condition, _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(bool, Throw_HrIfFalse)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition) + { + if (!condition) + { + __R_CALL_INTERNAL_METHOD(_Throw_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + return condition; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, Throw_HrIfNull)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _Pre_maybenull_ PointerT pointer) + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Throw_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_TEMPLATE_METHOD(void, Throw_HrIfNull)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _In_opt_ const PointerT& pointer) + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Throw_Hr)(__R_CONDITIONAL_FN_CALL hr); + } + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(bool, Throw_Win32If)(__R_CONDITIONAL_FN_PARAMS DWORD err, bool condition) + { + if (condition) + { + __R_CALL_INTERNAL_METHOD(_Throw_Win32)(__R_CONDITIONAL_FN_CALL err); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(bool, Throw_GetLastErrorIf)(__R_CONDITIONAL_FN_PARAMS bool condition) + { + if (condition) + { + __R_CALL_INTERNAL_METHOD(_Throw_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(bool, Throw_GetLastErrorIfFalse)(__R_CONDITIONAL_FN_PARAMS bool condition) + { + if (!condition) + { + __R_CALL_INTERNAL_METHOD(_Throw_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return condition; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, Throw_GetLastErrorIfNull)(__R_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer) + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Throw_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __R_CONDITIONAL_TEMPLATE_METHOD(void, Throw_GetLastErrorIfNull)(__R_CONDITIONAL_FN_PARAMS _In_opt_ const PointerT& pointer) + { + if (pointer == nullptr) + { + __R_CALL_INTERNAL_METHOD(_Throw_GetLastError)(__R_CONDITIONAL_FN_CALL_ONLY); + } + } + + _Post_satisfies_(return == status) + _When_(FAILED_NTSTATUS(status), _Analysis_noreturn_) + __R_CONDITIONAL_METHOD(NTSTATUS, Throw_IfNtStatusFailed)(__R_CONDITIONAL_FN_PARAMS NTSTATUS status) + { + if (FAILED_NTSTATUS(status)) + { + __R_CALL_INTERNAL_METHOD(_Throw_NtStatus)(__R_CONDITIONAL_FN_CALL status); + } + return status; + } + + __R_DIRECT_NORET_METHOD(void, Throw_HrMsg)(__R_DIRECT_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__R_DIRECT_FN_CALL hr, formatString, argList); + } + + __R_DIRECT_NORET_METHOD(void, Throw_Win32Msg)(__R_DIRECT_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_Win32Msg(__R_DIRECT_FN_CALL err, formatString, argList); + } + + __R_DIRECT_NORET_METHOD(void, Throw_GetLastErrorMsg)(__R_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_GetLastErrorMsg(__R_DIRECT_FN_CALL formatString, argList); + } + + __R_DIRECT_NORET_METHOD(void, Throw_NtStatusMsg)(__R_DIRECT_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_NtStatusMsg(__R_DIRECT_FN_CALL status, formatString, argList); + } + + __R_DIRECT_NORET_METHOD(void, Throw_CaughtExceptionMsg)(__R_DIRECT_FN_PARAMS _Printf_format_string_ PCSTR formatString, ...) + { + va_list argList; + va_start(argList, formatString); + __R_FN_LOCALS; + wil::details::ReportFailure_CaughtExceptionMsg(__R_DIRECT_FN_CALL formatString, argList); + } + + __R_INTERNAL_NOINLINE_NORET_METHOD(_Throw_HrMsg)(__R_INTERNAL_NOINLINE_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, va_list argList) + { + __R_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__R_INTERNAL_NOINLINE_FN_CALL hr, formatString, argList); + } + + __R_INTERNAL_NOINLINE_NORET_METHOD(_Throw_GetLastErrorMsg)(__R_INTERNAL_NOINLINE_FN_PARAMS _Printf_format_string_ PCSTR formatString, va_list argList) + { + __R_FN_LOCALS; + wil::details::ReportFailure_GetLastErrorMsg(__R_INTERNAL_NOINLINE_FN_CALL formatString, argList); + } + + __R_INTERNAL_NOINLINE_NORET_METHOD(_Throw_Win32Msg)(__R_INTERNAL_NOINLINE_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, va_list argList) + { + __R_FN_LOCALS; + wil::details::ReportFailure_Win32Msg(__R_INTERNAL_NOINLINE_FN_CALL err, formatString, argList); + } + + __R_INTERNAL_NOINLINE_NORET_METHOD(_Throw_NullAllocMsg)(__R_INTERNAL_NOINLINE_FN_PARAMS _Printf_format_string_ PCSTR formatString, va_list argList) + { + __R_FN_LOCALS; + wil::details::ReportFailure_HrMsg(__R_INTERNAL_NOINLINE_FN_CALL E_OUTOFMEMORY, formatString, argList); + } + + __R_INTERNAL_NOINLINE_NORET_METHOD(_Throw_NtStatusMsg)(__R_INTERNAL_NOINLINE_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, va_list argList) + { + __R_FN_LOCALS; + wil::details::ReportFailure_NtStatusMsg(__R_INTERNAL_NOINLINE_FN_CALL status, formatString, argList); + } + + _Post_satisfies_(return == hr) _When_(FAILED(hr), _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(HRESULT, Throw_IfFailedMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _Printf_format_string_ PCSTR formatString, ...) + { + if (FAILED(hr)) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return hr; + } + + _Post_satisfies_(return == ret) _When_(!ret, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(BOOL, Throw_IfWin32BoolFalseMsg)(__R_CONDITIONAL_FN_PARAMS BOOL ret, _Printf_format_string_ PCSTR formatString, ...) + { + if (!ret) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return ret; + } + + _Post_satisfies_(return == err) _When_(FAILED_WIN32(err), _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(DWORD, Throw_IfWin32ErrorMsg)(__R_CONDITIONAL_FN_PARAMS DWORD err, _Printf_format_string_ PCSTR formatString, ...) + { + if (FAILED_WIN32(err)) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_Win32Msg)(__R_CONDITIONAL_NOINLINE_FN_CALL err, formatString, argList); + } + return err; + } + + _Post_satisfies_(return == handle) _When_(handle == INVALID_HANDLE_VALUE, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(HANDLE, Throw_IfHandleInvalidMsg)(__R_CONDITIONAL_FN_PARAMS HANDLE handle, _Printf_format_string_ PCSTR formatString, ...) + { + if (handle == INVALID_HANDLE_VALUE) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return handle; + } + + _Post_satisfies_(return == handle) _When_(handle == 0, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(RESULT_NORETURN_NULL HANDLE, Throw_IfHandleNullMsg)(__R_CONDITIONAL_FN_PARAMS HANDLE handle, _Printf_format_string_ PCSTR formatString, ...) + { + if (handle == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return handle; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, Throw_IfNullAllocMsg)(__R_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_NullAllocMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL_ONLY, formatString, argList); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __WI_SUPPRESS_NULLPTR_ANALYSIS + _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, Throw_IfNullAllocMsg)(__R_CONDITIONAL_FN_PARAMS const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_NullAllocMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL_ONLY, formatString, argList); + } + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Throw_HrIfMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition, _Printf_format_string_ PCSTR formatString, ...) + { + if (condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Throw_HrIfFalseMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, bool condition, _Printf_format_string_ PCSTR formatString, ...) + { + if (!condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return condition; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + __WI_SUPPRESS_NULLPTR_ANALYSIS + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, Throw_HrIfNullMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __WI_SUPPRESS_NULLPTR_ANALYSIS + _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, Throw_HrIfNullMsg)(__R_CONDITIONAL_FN_PARAMS HRESULT hr, _In_opt_ const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_HrMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL hr, formatString, argList); + } + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Throw_Win32IfMsg)(__R_CONDITIONAL_FN_PARAMS DWORD err, bool condition, _Printf_format_string_ PCSTR formatString, ...) + { + if (condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_Win32Msg)(__R_CONDITIONAL_NOINLINE_FN_CALL err, formatString, argList); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(condition, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Throw_GetLastErrorIfMsg)(__R_CONDITIONAL_FN_PARAMS bool condition, _Printf_format_string_ PCSTR formatString, ...) + { + if (condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return condition; + } + + _Post_satisfies_(return == condition) _When_(!condition, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(bool, Throw_GetLastErrorIfFalseMsg)(__R_CONDITIONAL_FN_PARAMS bool condition, _Printf_format_string_ PCSTR formatString, ...) + { + if (!condition) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return condition; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_NOT_CLASS(PointerT)> + _Post_satisfies_(return == pointer) _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(RESULT_NORETURN_NULL PointerT, Throw_GetLastErrorIfNullMsg)(__R_CONDITIONAL_FN_PARAMS _Pre_maybenull_ PointerT pointer, _Printf_format_string_ PCSTR formatString, ...) + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + return pointer; + } + + template <__R_CONDITIONAL_PARTIAL_TEMPLATE typename PointerT, __R_ENABLE_IF_IS_CLASS(PointerT)> + __WI_SUPPRESS_NULLPTR_ANALYSIS + _When_(pointer == nullptr, _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_TEMPLATE_METHOD(void, Throw_GetLastErrorIfNullMsg)(__R_CONDITIONAL_FN_PARAMS _In_opt_ const PointerT& pointer, _Printf_format_string_ PCSTR formatString, ...) + { + if (pointer == nullptr) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_GetLastErrorMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL formatString, argList); + } + } + + _Post_satisfies_(return == status) _When_(FAILED_NTSTATUS(status), _Analysis_noreturn_) + __R_CONDITIONAL_NOINLINE_METHOD(NTSTATUS, Throw_IfNtStatusFailedMsg)(__R_CONDITIONAL_FN_PARAMS NTSTATUS status, _Printf_format_string_ PCSTR formatString, ...) + { + if (FAILED_NTSTATUS(status)) + { + va_list argList; + va_start(argList, formatString); + __R_CALL_INTERNAL_NOINLINE_METHOD(_Throw_NtStatusMsg)(__R_CONDITIONAL_NOINLINE_FN_CALL status, formatString, argList); + } + return status; + } +#endif // WIL_ENABLE_EXCEPTIONS + + } // __R_NS_NAME namespace + } // details namespace + /// @endcond + + + //***************************************************************************** + // Error Handling Policies to switch between error-handling style + //***************************************************************************** + // The following policies are used as template policies for components that can support exception, fail-fast, and + // error-code based modes. + + // Use for classes which should return HRESULTs as their error-handling policy + // Intentionally removed logging from this policy as logging is more useful at the caller. + struct err_returncode_policy + { + using result = HRESULT; + + __forceinline static HRESULT Win32BOOL(BOOL fReturn) { RETURN_IF_WIN32_BOOL_FALSE_EXPECTED(fReturn); return S_OK; } + __forceinline static HRESULT Win32Handle(HANDLE h, _Out_ HANDLE *ph) { *ph = h; RETURN_LAST_ERROR_IF_NULL_EXPECTED(h); return S_OK; } + _Post_satisfies_(return == hr) + __forceinline static HRESULT HResult(HRESULT hr) { return hr; } + __forceinline static HRESULT LastError() { return wil::details::GetLastErrorFailHr(); } + __forceinline static HRESULT LastErrorIfFalse(bool condition) { RETURN_LAST_ERROR_IF_EXPECTED(!condition); return S_OK; } + _Post_satisfies_(return == S_OK) + __forceinline static HRESULT OK() { return S_OK; } + }; + + // Use for classes which fail-fast on errors + struct err_failfast_policy + { + typedef _Return_type_success_(true) void result; + __forceinline static result Win32BOOL(BOOL fReturn) { FAIL_FAST_IF_WIN32_BOOL_FALSE(fReturn); } + __forceinline static result Win32Handle(HANDLE h, _Out_ HANDLE *ph) { *ph = h; FAIL_FAST_LAST_ERROR_IF_NULL(h); } + _When_(FAILED(hr), _Analysis_noreturn_) + __forceinline static result HResult(HRESULT hr) { FAIL_FAST_IF_FAILED(hr); } + __forceinline static result LastError() { FAIL_FAST_LAST_ERROR(); } + __forceinline static result LastErrorIfFalse(bool condition) { if (!condition) { FAIL_FAST_LAST_ERROR(); } } + __forceinline static result OK() {} + }; + +#ifdef WIL_ENABLE_EXCEPTIONS + // Use for classes which should return through exceptions as their error-handling policy + struct err_exception_policy + { + typedef _Return_type_success_(true) void result; + __forceinline static result Win32BOOL(BOOL fReturn) { THROW_IF_WIN32_BOOL_FALSE(fReturn); } + __forceinline static result Win32Handle(HANDLE h, _Out_ HANDLE *ph) { *ph = h; THROW_LAST_ERROR_IF_NULL(h); } + _When_(FAILED(hr), _Analysis_noreturn_) + __forceinline static result HResult(HRESULT hr) { THROW_IF_FAILED(hr); } + __forceinline static result LastError() { THROW_LAST_ERROR(); } + __forceinline static result LastErrorIfFalse(bool condition) { if (!condition) { THROW_LAST_ERROR(); } } + __forceinline static result OK() {} + }; +#else + // NOTE: A lot of types use 'err_exception_policy' as a default template argument and therefore it must be defined + // (MSVC is permissive about this, but other compilers are not). This will still cause compilation errors at + // template instantiation time since this type lacks required member functions. An alternative would be to have some + // 'default_err_policy' alias that would be something like 'err_failfast_policy' when exceptions are not available, + // but that may have unexpected side effects when compiling code that expects to be using exceptions + struct err_exception_policy + { + }; +#endif + +} // namespace wil + +#pragma warning(pop) + +#endif // defined(__cplusplus) && !defined(__WIL_MIN_KERNEL) && !defined(WIL_KERNEL_MODE) +#endif // __WIL_RESULTMACROS_INCLUDED diff --git a/libraries/wil/result_originate.h b/libraries/wil/result_originate.h new file mode 100644 index 0000000..02badba --- /dev/null +++ b/libraries/wil/result_originate.h @@ -0,0 +1,126 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* + +// Note: When origination is enabled by including this file, origination is done as part of the RETURN_* and THROW_* macros. Before originating +// a new error we will observe whether there is already an error payload associated with the current thread. If there is, and the HRESULTs match, +// then a new error will not be originated. Otherwise we will overwrite it with a new origination. The ABI boundary for WinRT APIs will check the +// per-thread error information. The act of checking the error clears it, so there should be minimal risk of failing to originate distinct errors +// simply because the HRESULTs match. +// +// For THROW_ macros we will examine the thread-local error storage once per throw. So typically once, with additional calls if the exception is +// caught and re-thrown. +// +// For RETURN_ macros we will have to examine the thread-local error storage once per frame as the call stack unwinds. Because error conditions +// -should- be uncommon the performance impact of checking TLS should be minimal. The more expensive part is originating the error because it must +// capture the entire stack and some additional data. + +#ifndef __WIL_RESULT_ORIGINATE_INCLUDED +#define __WIL_RESULT_ORIGINATE_INCLUDED + +#include "result.h" +#include // RestrictedErrorInfo uses BSTRs :( +#include +#include "resource.h" +#include "com.h" +#include + +namespace wil +{ + namespace details + { + // Note: The name must begin with "Raise" so that the !analyze auto-bucketing will ignore this stack frame. Otherwise this line of code gets all the blame. + inline void __stdcall RaiseRoOriginateOnWilExceptions(wil::FailureInfo const& failure) WI_NOEXCEPT + { + if ((failure.type == FailureType::Return) || (failure.type == FailureType::Exception)) + { + bool shouldOriginate = true; + + wil::com_ptr_nothrow restrictedErrorInformation; + if (GetRestrictedErrorInfo(&restrictedErrorInformation) == S_OK) + { + // This thread already has an error origination payload. Don't originate again if it has the same HRESULT that we are + // observing right now. + wil::unique_bstr descriptionUnused; + HRESULT existingHr = failure.hr; + wil::unique_bstr restrictedDescriptionUnused; + wil::unique_bstr capabilitySidUnused; + if (SUCCEEDED(restrictedErrorInformation->GetErrorDetails(&descriptionUnused, &existingHr, &restrictedDescriptionUnused, &capabilitySidUnused))) + { + shouldOriginate = (failure.hr != existingHr); + } + } + + if (shouldOriginate) + { +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + wil::unique_hmodule errorModule; + if (GetModuleHandleExW(0, L"api-ms-win-core-winrt-error-l1-1-1.dll", &errorModule)) + { + auto pfn = reinterpret_cast(GetProcAddress(errorModule.get(), "RoOriginateErrorW")); + if (pfn != nullptr) + { + pfn(failure.hr, 0, failure.pszMessage); + } + } +#else // DESKTOP | SYSTEM + ::RoOriginateErrorW(failure.hr, 0, failure.pszMessage); +#endif // DESKTOP | SYSTEM + } + else if (restrictedErrorInformation) + { + // GetRestrictedErrorInfo returns ownership of the error information. If we aren't originating, and an error was already present, + // then we need to restore the error information for later observation. + SetRestrictedErrorInfo(restrictedErrorInformation.get()); + } + } + } + + // This method will check for the presence of stowed exception data on the current thread. If such data exists, and the HRESULT + // matches the current failure, then we will call RoFailFastWithErrorContext. RoFailFastWithErrorContext in this situation will + // result in -VASTLY- improved crash bucketing. It is hard to express just how much better. In other cases we just return and + // the calling method fails fast the same way it always has. + inline void __stdcall FailfastWithContextCallback(wil::FailureInfo const& failure) WI_NOEXCEPT + { + wil::com_ptr_nothrow restrictedErrorInformation; + if (GetRestrictedErrorInfo(&restrictedErrorInformation) == S_OK) + { + wil::unique_bstr descriptionUnused; + HRESULT existingHr = failure.hr; + wil::unique_bstr restrictedDescriptionUnused; + wil::unique_bstr capabilitySidUnused; + if (SUCCEEDED(restrictedErrorInformation->GetErrorDetails(&descriptionUnused, &existingHr, &restrictedDescriptionUnused, &capabilitySidUnused)) && + (existingHr == failure.hr)) + { + // GetRestrictedErrorInfo returns ownership of the error information. We want it to be available for RoFailFastWithErrorContext + // so we must restore it via SetRestrictedErrorInfo first. + SetRestrictedErrorInfo(restrictedErrorInformation.get()); + RoFailFastWithErrorContext(existingHr); + } + else + { + // The error didn't match the current failure. Put it back in thread-local storage even though we aren't failing fast + // in this method, so it is available in the debugger just-in-case. + SetRestrictedErrorInfo(restrictedErrorInformation.get()); + } + } + } + } // namespace details +} // namespace wil + +// Automatically call RoOriginateError upon error origination by including this file +WI_HEADER_INITITALIZATION_FUNCTION(ResultStowedExceptionInitialize, [] +{ + ::wil::SetOriginateErrorCallback(::wil::details::RaiseRoOriginateOnWilExceptions); + ::wil::SetFailfastWithContextCallback(::wil::details::FailfastWithContextCallback); + return 1; +}) + +#endif // __WIL_RESULT_ORIGINATE_INCLUDED diff --git a/libraries/wil/rpc_helpers.h b/libraries/wil/rpc_helpers.h new file mode 100644 index 0000000..63fd97b --- /dev/null +++ b/libraries/wil/rpc_helpers.h @@ -0,0 +1,206 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_RPC_HELPERS_INCLUDED +#define __WIL_RPC_HELPERS_INCLUDED + +#include "result.h" +#include "resource.h" +#include "wistd_functional.h" +#include "wistd_type_traits.h" + +namespace wil +{ + + /// @cond + namespace details + { + // This call-adapter template converts a void-returning 'wistd::invoke' into + // an HRESULT-returning 'wistd::invoke' that emits S_OK. It can be eliminated + // with 'if constexpr' when C++17 is in wide use. + template struct call_adapter + { + template static HRESULT call(TArgs&& ... args) + { + return wistd::invoke(wistd::forward(args)...); + } + }; + + template<> struct call_adapter + { + template static HRESULT call(TArgs&& ... args) + { + wistd::invoke(wistd::forward(args)...); + return S_OK; + } + }; + + // Some RPC exceptions are already HRESULTs. Others are in the regular Win32 + // error space. If the incoming exception code isn't an HRESULT, wrap it. + constexpr HRESULT map_rpc_exception(DWORD code) + { + return IS_ERROR(code) ? code : __HRESULT_FROM_WIN32(code); + } + } + /// @endcond + + /** Invokes an RPC method, mapping structured exceptions to HRESULTs + Failures encountered by the RPC infrastructure (such as server crashes, authentication + errors, client parameter issues, etc.) are emitted by raising a structured exception from + within the RPC machinery. This method wraps the requested call in the usual RpcTryExcept, + RpcTryCatch, and RpcEndExcept sequence then maps the exceptions to HRESULTs for the usual + flow control machinery to use. + + Many RPC methods are defined as returning HRESULT themselves, where the HRESULT indicates + the result of the _work_. HRESULTs returned by a successful completion of the _call_ are + returned as-is. + + RPC methods that have a return type of 'void' are mapped to returning S_OK when the _call_ + completes successfully. + + For example, consider an RPC interface method defined in idl as: + ~~~ + HRESULT GetKittenState([in, ref, string] const wchar_t* name, [out, retval] KittenState** state); + ~~~ + To call this method, use: + ~~~ + wil::unique_rpc_binding binding = // typically gotten elsewhere; + wil::unique_midl_ptr state; + HRESULT hr = wil::invoke_rpc_nothrow(GetKittenState, binding.get(), L"fluffy", state.put()); + RETURN_IF_FAILED(hr); + ~~~ + */ + template HRESULT invoke_rpc_nothrow(TCall&&... args) WI_NOEXCEPT + { + RpcTryExcept + { + // Note: this helper type can be removed with C++17 enabled via + // 'if constexpr(wistd::is_same_v)' + using result_t = typename wistd::__invoke_of::type; + RETURN_IF_FAILED(details::call_adapter::call(wistd::forward(args)...)); + return S_OK; + } + RpcExcept(RpcExceptionFilter(RpcExceptionCode())) + { + RETURN_HR(details::map_rpc_exception(RpcExceptionCode())); + } + RpcEndExcept + } + + /** Invokes an RPC method, mapping structured exceptions to HRESULTs + Failures encountered by the RPC infrastructure (such as server crashes, authentication + errors, client parameter issues, etc.) are emitted by raising a structured exception from + within the RPC machinery. This method wraps the requested call in the usual RpcTryExcept, + RpcTryCatch, and RpcEndExcept sequence then maps the exceptions to HRESULTs for the usual + flow control machinery to use. + + Some RPC methods return results (such as a state enumeration or other value) directly in + their signature. This adapter writes that result into a caller-provided object then + returns S_OK. + + For example, consider an RPC interface method defined in idl as: + ~~~ + GUID GetKittenId([in, ref, string] const wchar_t* name); + ~~~ + To call this method, use: + ~~~ + wil::unique_rpc_binding binding = // typically gotten elsewhere; + GUID id; + HRESULT hr = wil::invoke_rpc_result_nothrow(id, GetKittenId, binding.get(), L"fluffy"); + RETURN_IF_FAILED(hr); + ~~~ + */ + template HRESULT invoke_rpc_result_nothrow(TResult& result, TCall&&... args) WI_NOEXCEPT + { + RpcTryExcept + { + result = wistd::invoke(wistd::forward(args)...); + return S_OK; + } + RpcExcept(RpcExceptionFilter(RpcExceptionCode())) + { + RETURN_HR(details::map_rpc_exception(RpcExceptionCode())); + } + RpcEndExcept + } + + namespace details + { + // Provides an adapter around calling the context-handle-close method on an + // RPC interface, which itself is an RPC call. + template + struct rpc_closer_t + { + static void Close(TStorage arg) WI_NOEXCEPT + { + LOG_IF_FAILED(invoke_rpc_nothrow(close_fn, &arg)); + } + }; + } + + /** Manages explicit RPC context handles + Explicit RPC context handles are used in many RPC interfaces. Most interfaces with + context handles have an explicit `FooClose([in, out] CONTEXT*)` method that lets + the server close out the context handle. As the close method itself is an RPC call, + it can fail and raise a structured exception. + + This type routes the context-handle-specific `Close` call through the `invoke_rpc_nothrow` + helper, ensuring correct cleanup and lifecycle management. + ~~~ + // Assume the interface has two methods: + // HRESULT OpenFoo([in] handle_t binding, [out] FOO_CONTEXT*); + // HRESULT UseFoo([in] FOO_CONTEXT context; + // void CloseFoo([in, out] PFOO_CONTEXT); + using unique_foo_context = wil::unique_rpc_context_handle; + unique_foo_context context; + RETURN_IF_FAILED(wil::invoke_rpc_nothrow(OpenFoo, m_binding.get(), context.put())); + RETURN_IF_FAILED(wil::invoke_rpc_nothrow(UseFoo, context.get())); + context.reset(); + ~~~ + */ + template + using unique_rpc_context_handle = unique_any::Close), details::rpc_closer_t::Close>; + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Invokes an RPC method, mapping structured exceptions to C++ exceptions + See `wil::invoke_rpc_nothrow` for additional information. Failures during the _call_ + and those returned by the _method_ are mapped to HRESULTs and thrown inside a + wil::ResultException. Using the example RPC method provided above: + ~~~ + wil::unique_midl_ptr state; + wil::invoke_rpc(GetKittenState, binding.get(), L"fluffy", state.put()); + // use 'state' + ~~~ + */ + template void invoke_rpc(TCall&& ... args) + { + THROW_IF_FAILED(invoke_rpc_nothrow(wistd::forward(args)...)); + } + + /** Invokes an RPC method, mapping structured exceptions to C++ exceptions + See `wil::invoke_rpc_result_nothrow` for additional information. Failures during the + _call_ are mapped to HRESULTs and thrown inside a `wil::ResultException`. Using the + example RPC method provided above: + ~~~ + GUID id = wil::invoke_rpc_result(GetKittenId, binding.get()); + // use 'id' + ~~~ + */ + template auto invoke_rpc_result(TCall&& ... args) + { + using result_t = typename wistd::__invoke_of::type; + result_t result{}; + THROW_IF_FAILED(invoke_rpc_result_nothrow(result, wistd::forward(args)...)); + return result; + } +#endif +} + +#endif diff --git a/libraries/wil/safecast.h b/libraries/wil/safecast.h new file mode 100644 index 0000000..3fa6d7e --- /dev/null +++ b/libraries/wil/safecast.h @@ -0,0 +1,369 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_SAFECAST_INCLUDED +#define __WIL_SAFECAST_INCLUDED + +#include "result_macros.h" +#include +#include "wistd_config.h" +#include "wistd_type_traits.h" + +namespace wil +{ + namespace details + { + // Default error case for undefined conversions in intsafe.h + template constexpr wistd::nullptr_t intsafe_conversion = nullptr; + + // is_known_safe_static_cast_v determines if a conversion is known to be safe or not. Known + // safe conversions can be handled by static_cast, this includes conversions between the same + // type, when the new type is larger than the old type but is not a signed to unsigned + // conversion, and when the two types are the same size and signed/unsigned. All other + // conversions will be assumed to be potentially unsafe, and the conversion must be handled + // by intsafe and checked. + template + constexpr bool is_known_safe_static_cast_v = + (sizeof(NewT) > sizeof(OldT) && !(wistd::is_signed_v && wistd::is_unsigned_v)) || + (sizeof(NewT) == sizeof(OldT) && ((wistd::is_signed_v && wistd::is_signed_v) || (wistd::is_unsigned_v && wistd::is_unsigned_v))); + + // Helper template to determine that NewT and OldT are both integral types. The safe_cast + // operation only supports conversions between integral types. + template + constexpr bool both_integral_v = wistd::is_integral::value && wistd::is_integral::value; + + // Note on native wchar_t (__wchar_t): + // Intsafe.h does not currently handle native wchar_t. When compiling with /Zc:wchar_t-, this is fine as wchar_t is + // typedef'd to unsigned short. However, when compiling with /Zc:wchar_t or wchar_t as a native type, the lack of + // support for native wchar_t in intsafe.h becomes an issue. To work around this, we treat native wchar_t as an + // unsigned short when passing it to intsafe.h, because the two on the Windows platform are the same size and + // share the same range according to MSDN. If the cast is to a native wchar_t, the result from intsafe.h is cast + // to a native wchar_t. + + // Intsafe does not have a defined conversion for native wchar_t + template + constexpr bool neither_native_wchar_v = !wistd::is_same::value && !wistd::is_same::value; + + // Check to see if the cast is a conversion to native wchar_t + template + constexpr bool is_cast_to_wchar_v = wistd::is_same::value && !wistd::is_same::value; + + // Check to see if the cast is a conversion from native wchar_t + template + constexpr bool is_cast_from_wchar_v = !wistd::is_same::value && wistd::is_same::value; + + // Validate the conversion to be performed has a defined mapping to an intsafe conversion + template + constexpr bool is_supported_intsafe_cast_v = intsafe_conversion != nullptr; + + // True when the conversion is between integral types and can be handled by static_cast + template + constexpr bool is_supported_safe_static_cast_v = both_integral_v && is_known_safe_static_cast_v; + + // True when the conversion is between integral types, does not involve native wchar, has + // a mapped intsafe conversion, and is unsafe. + template + constexpr bool is_supported_unsafe_cast_no_wchar_v = + both_integral_v && + !is_known_safe_static_cast_v && + neither_native_wchar_v && + is_supported_intsafe_cast_v; + + // True when the conversion is between integral types, is a cast to native wchar_t, has + // a mapped intsafe conversion, and is unsafe. + template + constexpr bool is_supported_unsafe_cast_to_wchar_v = + both_integral_v && + !is_known_safe_static_cast_v && + is_cast_to_wchar_v && + is_supported_intsafe_cast_v; + + // True when the conversion is between integral types, is a cast from native wchar_t, has + // a mapped intsafe conversion, and is unsafe. + template + constexpr bool is_supported_unsafe_cast_from_wchar_v = + both_integral_v && + !is_known_safe_static_cast_v && + is_cast_from_wchar_v && + is_supported_intsafe_cast_v; + + // True when the conversion is supported and unsafe, and may or may not involve + // native wchar_t. + template + constexpr bool is_supported_unsafe_cast_v = + is_supported_unsafe_cast_no_wchar_v || + is_supported_unsafe_cast_to_wchar_v || + is_supported_unsafe_cast_from_wchar_v; + + // True when T is any one of the primitive types that the variably sized types are defined as. + template + constexpr bool is_potentially_variably_sized_type_v = + wistd::is_same::value || + wistd::is_same::value || + wistd::is_same::value || + wistd::is_same::value || + wistd::is_same::value || + wistd::is_same::value; + + // True when either type is potentialy variably sized (e.g. size_t, ptrdiff_t) + template + constexpr bool is_potentially_variably_sized_cast_v = + is_potentially_variably_sized_type_v || + is_potentially_variably_sized_type_v; + + // Mappings of all conversions defined in intsafe.h to intsafe_conversion + // Note: Uppercase types (UINT, DWORD, SIZE_T, etc) and architecture dependent types resolve + // to the base types. The base types are used since they do not vary based on architecture. + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, char> = LongLongToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, int> = LongLongToInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, long> = LongLongToLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, short> = LongLongToShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, signed char> = LongLongToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, unsigned __int64> = LongLongToULongLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, unsigned char> = LongLongToUChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, unsigned int> = LongLongToUInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, unsigned long> = LongLongToULong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion<__int64, unsigned short> = LongLongToUShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = IntToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = IntToShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = IntToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = IntToULongLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = IntToUChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = IntToUInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = IntToULong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = IntToUShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToULongLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToUChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToUInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToULong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = LongToUShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ShortToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ShortToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ShortToULongLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ShortToUChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ShortToUInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ShortToULong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ShortToUShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = Int8ToULongLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = Int8ToUChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = Int8ToUInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = Int8ToULong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = Int8ToUShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToLongLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToUChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToUInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToULong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongLongToUShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UInt8ToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UIntToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UIntToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UIntToInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UIntToLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UIntToShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UIntToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UIntToUChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UIntToUShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongToInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongToLong; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongToShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongToUChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongToUInt; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = ULongToUShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UShortToChar; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UShortToShort; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UShortToInt8; + template<> __WI_LIBCPP_INLINE_VAR constexpr auto intsafe_conversion = UShortToUChar; + } + + // Unsafe conversion where failure results in fail fast. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast_failfast(const OldT var) + { + NewT newVar; + FAIL_FAST_IF_FAILED((details::intsafe_conversion(var, &newVar))); + return newVar; + } + + // Unsafe conversion where failure results in fail fast. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast_failfast(const OldT var) + { + NewT newVar; + FAIL_FAST_IF_FAILED((details::intsafe_conversion(static_cast(var), &newVar))); + return newVar; + } + + // Unsafe conversion where failure results in fail fast. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast_failfast(const OldT var) + { + unsigned short newVar; + FAIL_FAST_IF_FAILED((details::intsafe_conversion(var, &newVar))); + return static_cast<__wchar_t>(newVar); + } + + // This conversion is always safe, therefore a static_cast is fine. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast_failfast(const OldT var) + { + return static_cast(var); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + // Unsafe conversion where failure results in a thrown exception. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast(const OldT var) + { + NewT newVar; + THROW_IF_FAILED((details::intsafe_conversion(var, &newVar))); + return newVar; + } + + // Unsafe conversion where failure results in a thrown exception. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast(const OldT var) + { + NewT newVar; + THROW_IF_FAILED((details::intsafe_conversion(static_cast(var), &newVar))); + return newVar; + } + + // Unsafe conversion where failure results in a thrown exception. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast(const OldT var) + { + unsigned short newVar; + THROW_IF_FAILED((details::intsafe_conversion(var, &newVar))); + return static_cast<__wchar_t>(newVar); + } + + // This conversion is always safe, therefore a static_cast is fine. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast(const OldT var) + { + return static_cast(var); + } +#endif + + // This conversion is unsafe, therefore the two parameter version of safe_cast_nothrow must be used + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast_nothrow(const OldT /*var*/) + { + static_assert(!wistd::is_same_v, "This cast has the potential to fail, use the two parameter safe_cast_nothrow instead"); + } + + // This conversion is always safe, therefore a static_cast is fine. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + NewT safe_cast_nothrow(const OldT var) + { + return static_cast(var); + } + + // Unsafe conversion where an HRESULT is returned. It is up to the callee to check and handle the HRESULT + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + HRESULT safe_cast_nothrow(const OldT var, NewT* newTResult) + { + return details::intsafe_conversion(var, newTResult); + } + + // Unsafe conversion where an HRESULT is returned. It is up to the callee to check and handle the HRESULT + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + HRESULT safe_cast_nothrow(const OldT var, NewT* newTResult) + { + return details::intsafe_conversion(static_cast(var), newTResult); + } + + // Unsafe conversion where an HRESULT is returned. It is up to the callee to check and handle the HRESULT + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + HRESULT safe_cast_nothrow(const OldT var, NewT* newTResult) + { + return details::intsafe_conversion(var, reinterpret_cast(newTResult)); + } + + // This conversion is always safe, therefore a static_cast is fine. If it can be determined the conversion + // does not involve a variably sized type, then the compilation will fail and say the single parameter version + // of safe_cast_nothrow should be used instead. + template < + typename NewT, + typename OldT, + wistd::enable_if_t, int> = 0 + > + HRESULT safe_cast_nothrow(const OldT var, NewT* newTResult) + { + static_assert(details::is_potentially_variably_sized_cast_v, "This cast is always safe; use safe_cast_nothrow(value) to avoid unnecessary error handling."); + *newTResult = static_cast(var); + return S_OK; + } +} + +#endif // __WIL_SAFECAST_INCLUDED diff --git a/libraries/wil/stl.h b/libraries/wil/stl.h new file mode 100644 index 0000000..dd50530 --- /dev/null +++ b/libraries/wil/stl.h @@ -0,0 +1,196 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_STL_INCLUDED +#define __WIL_STL_INCLUDED + +#include "common.h" +#include "resource.h" +#include +#include +#include +#include +#if _HAS_CXX17 +#include +#endif + +#ifndef WI_STL_FAIL_FAST_IF +#define WI_STL_FAIL_FAST_IF FAIL_FAST_IF +#endif + +#if defined(WIL_ENABLE_EXCEPTIONS) + +namespace wil +{ + /** Secure allocator for STL containers. + The `wil::secure_allocator` allocator calls `SecureZeroMemory` before deallocating + memory. This provides a mechanism for secure STL containers such as `wil::secure_vector`, + `wil::secure_string`, and `wil::secure_wstring`. */ + template + struct secure_allocator + : public std::allocator + { + template + struct rebind + { + using other = secure_allocator; + }; + + secure_allocator() + : std::allocator() + { + } + + ~secure_allocator() = default; + + secure_allocator(const secure_allocator& a) + : std::allocator(a) + { + } + + template + secure_allocator(const secure_allocator& a) + : std::allocator(a) + { + } + + T* allocate(size_t n) + { + return std::allocator::allocate(n); + } + + void deallocate(T* p, size_t n) + { + SecureZeroMemory(p, sizeof(T) * n); + std::allocator::deallocate(p, n); + } + }; + + //! `wil::secure_vector` will be securely zeroed before deallocation. + template + using secure_vector = std::vector>; + //! `wil::secure_wstring` will be securely zeroed before deallocation. + using secure_wstring = std::basic_string, wil::secure_allocator>; + //! `wil::secure_string` will be securely zeroed before deallocation. + using secure_string = std::basic_string, wil::secure_allocator>; + + /// @cond + namespace details + { + template<> struct string_maker + { + HRESULT make(_In_reads_opt_(length) PCWSTR source, size_t length) WI_NOEXCEPT try + { + m_value = source ? std::wstring(source, length) : std::wstring(length, L'\0'); + return S_OK; + } + catch (...) + { + return E_OUTOFMEMORY; + } + + wchar_t* buffer() { return &m_value[0]; } + + HRESULT trim_at_existing_null(size_t length) { m_value.erase(length); return S_OK; } + + std::wstring release() { return std::wstring(std::move(m_value)); } + + static PCWSTR get(const std::wstring& value) { return value.c_str(); } + + private: + std::wstring m_value; + }; + } + /// @endcond + + // str_raw_ptr is an overloaded function that retrieves a const pointer to the first character in a string's buffer. + // This is the overload for std::wstring. Other overloads available in resource.h. + inline PCWSTR str_raw_ptr(const std::wstring& str) + { + return str.c_str(); + } + +#if _HAS_CXX17 + /** + zstring_view. A zstring_view is identical to a std::string_view except it is always nul-terminated (unless empty). + * zstring_view can be used for storing string literals without "forgetting" the length or that it is nul-terminated. + * A zstring_view can be converted implicitly to a std::string_view because it is always safe to use a nul-terminated + string_view as a plain string view. + * A zstring_view can be constructed from a std::string because the data in std::string is nul-terminated. + */ + template + class basic_zstring_view : public std::basic_string_view + { + using size_type = typename std::basic_string_view::size_type; + + public: + constexpr basic_zstring_view() noexcept = default; + constexpr basic_zstring_view(const basic_zstring_view&) noexcept = default; + constexpr basic_zstring_view& operator=(const basic_zstring_view&) noexcept = default; + + constexpr basic_zstring_view(const TChar* pStringData, size_type stringLength) noexcept + : std::basic_string_view(pStringData, stringLength) + { + if (pStringData[stringLength] != 0) { WI_STL_FAIL_FAST_IF(true); } + } + + template + constexpr basic_zstring_view(const TChar(&stringArray)[stringArrayLength]) noexcept + : std::basic_string_view(&stringArray[0], length_n(&stringArray[0], stringArrayLength)) + { + } + + // Construct from nul-terminated char ptr. To prevent this from overshadowing array construction, + // we disable this constructor if the value is an array (including string literal). + template::value && !std::is_array::value>* = nullptr> + constexpr basic_zstring_view(TPtr&& pStr) noexcept + : std::basic_string_view(std::forward(pStr)) {} + + constexpr basic_zstring_view(const std::basic_string& str) noexcept + : std::basic_string_view(&str[0], str.size()) {} + + // basic_string_view [] precondition won't let us read view[view.size()]; so we define our own. + WI_NODISCARD constexpr const TChar& operator[](size_type idx) const noexcept + { + WI_ASSERT(idx <= this->size() && this->data() != nullptr); + return this->data()[idx]; + } + + WI_NODISCARD constexpr const TChar* c_str() const noexcept + { + WI_ASSERT(this->data() == nullptr || this->data()[this->size()] == 0); + return this->data(); + } + + private: + // Bounds-checked version of char_traits::length, like strnlen. Requires that the input contains a null terminator. + static constexpr size_type length_n(_In_reads_opt_(buf_size) const TChar* str, size_type buf_size) noexcept + { + const std::basic_string_view view(str, buf_size); + auto pos = view.find_first_of(TChar()); + if (pos == view.npos) { WI_STL_FAIL_FAST_IF(true); } + return pos; + } + + // The following basic_string_view methods must not be allowed because they break the nul-termination. + using std::basic_string_view::swap; + using std::basic_string_view::remove_suffix; + }; + + using zstring_view = basic_zstring_view; + using zwstring_view = basic_zstring_view; +#endif // _HAS_CXX17 + +} // namespace wil + +#endif // WIL_ENABLE_EXCEPTIONS + +#endif // __WIL_STL_INCLUDED diff --git a/libraries/wil/token_helpers.h b/libraries/wil/token_helpers.h new file mode 100644 index 0000000..624f6ee --- /dev/null +++ b/libraries/wil/token_helpers.h @@ -0,0 +1,613 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_TOKEN_HELPERS_INCLUDED +#define __WIL_TOKEN_HELPERS_INCLUDED + +#ifdef _KERNEL_MODE +#error This header is not supported in kernel-mode. +#endif + +#include "resource.h" +#include +#include // for UNLEN and DNLEN +#include + +// for GetUserNameEx() +#ifndef SECURITY_WIN32 +#define SECURITY_WIN32 +#endif +#include + +namespace wil +{ + /// @cond + namespace details + { + // Template specialization for TOKEN_INFORMATION_CLASS, add more mappings here as needed + // TODO: The mapping should be reversed to be MapTokenInfoClassToStruct since there may + // be an info class value that uses the same structure. That is the case for the file + // system information. + template struct MapTokenStructToInfoClass; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenAccessInformation; static constexpr bool FixedSize = false; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenAppContainerSid; static constexpr bool FixedSize = false; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenDefaultDacl; static constexpr bool FixedSize = false; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenGroupsAndPrivileges; static constexpr bool FixedSize = false; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenIntegrityLevel; static constexpr bool FixedSize = false; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenOwner; static constexpr bool FixedSize = false; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenPrimaryGroup; static constexpr bool FixedSize = false; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenPrivileges; static constexpr bool FixedSize = false; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenUser; static constexpr bool FixedSize = false; }; + + // fixed size cases + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenElevationType; static constexpr bool FixedSize = true; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenMandatoryPolicy; static constexpr bool FixedSize = true; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenOrigin; static constexpr bool FixedSize = true; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenSource; static constexpr bool FixedSize = true; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenStatistics; static constexpr bool FixedSize = true; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenType; static constexpr bool FixedSize = true; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenImpersonationLevel; static constexpr bool FixedSize = true; }; + template<> struct MapTokenStructToInfoClass { static constexpr TOKEN_INFORMATION_CLASS infoClass = TokenElevation; static constexpr bool FixedSize = true; }; + + struct token_info_deleter + { + template void operator()(T* p) const + { + static_assert(wistd::is_trivially_destructible_v, "do not use with nontrivial types"); + ::operator delete(p); + } + }; + } + /// @endcond + + enum class OpenThreadTokenAs + { + Current, + Self + }; + + /** Open the active token. + Opens either the current thread token (if impersonating) or the current process token. Returns a token the caller + can use with methods like get_token_information<> below. By default, the token is opened for TOKEN_QUERY and as the + effective user. + + Consider using GetCurrentThreadEffectiveToken() instead of this method when eventually calling get_token_information. + This method returns a real handle to the effective token, but GetCurrentThreadEffectiveToken() is a Pseudo-handle + and much easier to manage. + ~~~~ + wil::unique_handle theToken; + RETURN_IF_FAILED(wil::open_current_access_token_nothrow(&theToken)); + ~~~~ + Callers who want more access to the token (such as to duplicate or modify the token) can pass + any mask of the token rights. + ~~~~ + wil::unique_handle theToken; + RETURN_IF_FAILED(wil::open_current_access_token_nothrow(&theToken, TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES)); + ~~~~ + Services impersonating their clients may need to request that the active token is opened on the + behalf of the service process to perform certain operations. Opening a token for impersonation access + or privilege-adjustment are examples of uses. + ~~~~ + wil::unique_handle callerToken; + RETURN_IF_FAILED(wil::open_current_access_token_nothrow(&theToken, TOKEN_QUERY | TOKEN_IMPERSONATE, OpenThreadTokenAs::Self)); + ~~~~ + @param tokenHandle Receives the token opened during the operation. Must be CloseHandle'd by the caller, or + (preferably) stored in a wil::unique_handle + @param access Bits from the TOKEN_* access mask which are passed to OpenThreadToken/OpenProcessToken + @param openAs Current to use current thread security context, or Self to use process security context. + */ + inline HRESULT open_current_access_token_nothrow(_Out_ HANDLE* tokenHandle, unsigned long access = TOKEN_QUERY, OpenThreadTokenAs openAs = OpenThreadTokenAs::Current) + { + HRESULT hr = (OpenThreadToken(GetCurrentThread(), access, (openAs == OpenThreadTokenAs::Self), tokenHandle) ? S_OK : HRESULT_FROM_WIN32(::GetLastError())); + if (hr == HRESULT_FROM_WIN32(ERROR_NO_TOKEN)) + { + hr = (OpenProcessToken(GetCurrentProcess(), access, tokenHandle) ? S_OK : HRESULT_FROM_WIN32(::GetLastError())); + } + return hr; + } + + //! Current thread or process token, consider using GetCurrentThreadEffectiveToken() instead. + inline wil::unique_handle open_current_access_token_failfast(unsigned long access = TOKEN_QUERY, OpenThreadTokenAs openAs = OpenThreadTokenAs::Current) + { + HANDLE rawTokenHandle; + FAIL_FAST_IF_FAILED(open_current_access_token_nothrow(&rawTokenHandle, access, openAs)); + return wil::unique_handle(rawTokenHandle); + } + +// Exception based function to open current thread/process access token and acquire pointer to it +#ifdef WIL_ENABLE_EXCEPTIONS + //! Current thread or process token, consider using GetCurrentThreadEffectiveToken() instead. + inline wil::unique_handle open_current_access_token(unsigned long access = TOKEN_QUERY, OpenThreadTokenAs openAs = OpenThreadTokenAs::Current) + { + HANDLE rawTokenHandle; + THROW_IF_FAILED(open_current_access_token_nothrow(&rawTokenHandle, access, openAs)); + return wil::unique_handle(rawTokenHandle); + } +#endif // WIL_ENABLE_EXCEPTIONS + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + + // Returns tokenHandle or the effective thread token if tokenHandle is null. + // Note, this returns an token handle who's lifetime is managed independently + // and it may be a pseudo token, don't free it! + inline HANDLE GetCurrentThreadEffectiveTokenWithOverride(HANDLE tokenHandle) + { + return tokenHandle ? tokenHandle : GetCurrentThreadEffectiveToken(); + } + + /** Fetches information about a token. + See GetTokenInformation on MSDN for what this method can return. For variable sized structs the information + is returned to the caller as a wil::unique_tokeninfo_ptr (like TOKEN_ORIGIN, TOKEN_USER, TOKEN_ELEVATION, etc.). For + fixed sized, the struct is returned directly. + The caller must have access to read the information from the provided token. This method works with both real + (e.g. OpenCurrentAccessToken) and pseudo (e.g. GetCurrentThreadToken) token handles. + ~~~~ + // Retrieve the TOKEN_USER structure for the current process + wil::unique_tokeninfo_ptr user; + RETURN_IF_FAILED(wil::get_token_information_nothrow(user, GetCurrentProcessToken())); + RETURN_IF_FAILED(ConsumeSid(user->User.Sid)); + ~~~~ + Not specifying the token handle is the same as specifying 'nullptr' and retrieves information about the effective token. + ~~~~ + wil::unique_tokeninfo_ptr privileges; + RETURN_IF_FAILED(wil::get_token_information_nothrow(privileges)); + for (auto const& privilege : wil::GetRange(privileges->Privileges, privileges->PrivilegeCount)) + { + RETURN_IF_FAILED(ConsumePrivilege(privilege)); + } + ~~~~ + @param tokenInfo Receives a pointer to a structure containing the results of GetTokenInformation for the requested + type. The type of selects which TOKEN_INFORMATION_CLASS will be used. + @param tokenHandle Specifies which token will be queried. When nullptr, the thread's effective current token is used. + @return S_OK on success, a FAILED hresult containing the win32 error from querying the token otherwise. + */ + + template using unique_tokeninfo_ptr = wistd::unique_ptr; + + template ::FixedSize>* = nullptr> + inline HRESULT get_token_information_nothrow(unique_tokeninfo_ptr& tokenInfo, HANDLE tokenHandle = nullptr) + { + tokenInfo.reset(); + tokenHandle = GetCurrentThreadEffectiveTokenWithOverride(tokenHandle); + + DWORD tokenInfoSize = 0; + const auto infoClass = details::MapTokenStructToInfoClass::infoClass; + RETURN_LAST_ERROR_IF(!((!GetTokenInformation(tokenHandle, infoClass, nullptr, 0, &tokenInfoSize)) && + (::GetLastError() == ERROR_INSUFFICIENT_BUFFER))); + unique_tokeninfo_ptr tokenInfoClose{ static_cast(::operator new(tokenInfoSize, std::nothrow)) }; + RETURN_IF_NULL_ALLOC(tokenInfoClose); + RETURN_IF_WIN32_BOOL_FALSE(GetTokenInformation(tokenHandle, infoClass, tokenInfoClose.get(), tokenInfoSize, &tokenInfoSize)); + tokenInfo = wistd::move(tokenInfoClose); + + return S_OK; + } + + template ::FixedSize>* = nullptr> + inline HRESULT get_token_information_nothrow(_Out_ T* tokenInfo, HANDLE tokenHandle = nullptr) + { + *tokenInfo = {}; + tokenHandle = GetCurrentThreadEffectiveTokenWithOverride(tokenHandle); + + DWORD tokenInfoSize = sizeof(T); + const auto infoClass = details::MapTokenStructToInfoClass::infoClass; + RETURN_IF_WIN32_BOOL_FALSE(GetTokenInformation(tokenHandle, infoClass, tokenInfo, tokenInfoSize, &tokenInfoSize)); + + return S_OK; + } + + namespace details + { + template::FixedSize>* = nullptr> + unique_tokeninfo_ptr GetTokenInfoWrap(HANDLE token = nullptr) + { + unique_tokeninfo_ptr temp; + policy::HResult(get_token_information_nothrow(temp, token)); + return temp; + } + + template::FixedSize>* = nullptr> + T GetTokenInfoWrap(HANDLE token = nullptr) + { + T temp{}; + policy::HResult(get_token_information_nothrow(&temp, token)); + return temp; + } + } + + //! A variant of get_token_information that fails-fast on errors retrieving the token + template + inline auto get_token_information_failfast(HANDLE token = nullptr) + { + return details::GetTokenInfoWrap(token); + } + + //! Overload of GetTokenInformationNoThrow that retrieves a token linked from the provided token + inline HRESULT get_token_information_nothrow(unique_token_linked_token& tokenInfo, HANDLE tokenHandle = nullptr) + { + static_assert(sizeof(tokenInfo) == sizeof(TOKEN_LINKED_TOKEN), "confusing size mismatch"); + tokenHandle = GetCurrentThreadEffectiveTokenWithOverride(tokenHandle); + + DWORD tokenInfoSize = 0; + RETURN_IF_WIN32_BOOL_FALSE(::GetTokenInformation(tokenHandle, TokenLinkedToken, + tokenInfo.reset_and_addressof(), sizeof(tokenInfo), &tokenInfoSize)); + return S_OK; + } + + /** Retrieves the linked-token information for a token. + Fails-fast if the link information cannot be retrieved. + ~~~~ + auto link = get_linked_token_information_failfast(GetCurrentThreadToken()); + auto tokenUser = get_token_information(link.LinkedToken); + ~~~~ + @param token Specifies the token to query. Pass nullptr to use the current effective thread token + @return unique_token_linked_token containing a handle to the linked token + */ + inline unique_token_linked_token get_linked_token_information_failfast(HANDLE token = nullptr) + { + unique_token_linked_token tokenInfo; + FAIL_FAST_IF_FAILED(get_token_information_nothrow(tokenInfo, token)); + return tokenInfo; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Fetches information about a token. + See get_token_information_nothrow for full details. + ~~~~ + auto user = wil::get_token_information(GetCurrentProcessToken()); + ConsumeSid(user->User.Sid); + ~~~~ + Pass 'nullptr' (or omit the parameter) as tokenHandle to retrieve information about the effective token. + ~~~~ + auto privs = wil::get_token_information(privileges); + for (auto& priv : wil::make_range(privs->Privileges, privs->Privilieges + privs->PrivilegeCount)) + { + if (priv.Attributes & SE_PRIVILEGE_ENABLED) + { + // ... + } + } + ~~~~ + @return A pointer to a structure containing the results of GetTokenInformation for the requested type. The type of + selects which TOKEN_INFORMATION_CLASS will be used. + @param token Specifies which token will be queried. When nullptr or not set, the thread's effective current token is used. + */ + template + inline auto get_token_information(HANDLE token = nullptr) + { + return details::GetTokenInfoWrap(token); + } + + /** Retrieves the linked-token information for a token. + Throws an exception if the link information cannot be retrieved. + ~~~~ + auto link = get_linked_token_information(GetCurrentThreadToken()); + auto tokenUser = get_token_information(link.LinkedToken); + ~~~~ + @param token Specifies the token to query. Pass nullptr to use the current effective thread token + @return unique_token_linked_token containing a handle to the linked token + */ + inline unique_token_linked_token get_linked_token_information(HANDLE token = nullptr) + { + unique_token_linked_token tokenInfo; + THROW_IF_FAILED(get_token_information_nothrow(tokenInfo, token)); + return tokenInfo; + } +#endif +#endif // _WIN32_WINNT >= _WIN32_WINNT_WIN8 + + /// @cond + namespace details + { + inline void RevertImpersonateToken(_In_ _Post_ptr_invalid_ HANDLE oldToken) + { + FAIL_FAST_IMMEDIATE_IF(!::SetThreadToken(nullptr, oldToken)); + + if (oldToken) + { + ::CloseHandle(oldToken); + } + } + } + /// @endcond + + using unique_token_reverter = wil::unique_any< + HANDLE, + decltype(&details::RevertImpersonateToken), + details::RevertImpersonateToken, + details::pointer_access_none, + HANDLE, + INT_PTR, + -1, + HANDLE>; + + /** Temporarily impersonates a token on this thread. + This method sets a new token on a thread, restoring the current token when the returned object + is destroyed. Useful for impersonating other tokens or running as 'self,' especially in services. + ~~~~ + HRESULT OpenFileAsSessionuser(PCWSTR filePath, DWORD session, _Out_ HANDLE* opened) + { + wil::unique_handle userToken; + RETURN_IF_WIN32_BOOL_FALSE(QueryUserToken(session, &userToken)); + + wil::unique_token_reverter reverter; + RETURN_IF_FAILED(wil::impersonate_token_nothrow(userToken.get(), reverter)); + + wil::unique_hfile userFile(::CreateFile(filePath, ...)); + RETURN_LAST_ERROR_IF(!userFile && (::GetLastError() != ERROR_FILE_NOT_FOUND)); + + *opened = userFile.release(); + return S_OK; + } + ~~~~ + @param token A token to impersonate, or 'nullptr' to run as the process identity. + */ + inline HRESULT impersonate_token_nothrow(HANDLE token, unique_token_reverter& reverter) + { + wil::unique_handle currentToken; + + // Get the token for the current thread. If there wasn't one, the reset will clear it as well + if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, ¤tToken)) + { + RETURN_LAST_ERROR_IF(::GetLastError() != ERROR_NO_TOKEN); + } + + // Update the current token + RETURN_IF_WIN32_BOOL_FALSE(::SetThreadToken(nullptr, token)); + + reverter.reset(currentToken.release()); // Ownership passed + return S_OK; + } + + /** Temporarily clears any impersonation on this thread. + This method resets the current thread's token to nullptr, indicating that it is not impersonating + any user. Useful for elevating to whatever identity a service or higher-privilege process might + be capable of running under. + ~~~~ + HRESULT DeleteFileRetryAsSelf(PCWSTR filePath) + { + if (!::DeleteFile(filePath)) + { + RETURN_LAST_ERROR_IF(::GetLastError() != ERROR_ACCESS_DENIED); + wil::unique_token_reverter reverter; + RETURN_IF_FAILED(wil::run_as_self_nothrow(reverter)); + RETURN_IF_FAILED(TakeOwnershipOfFile(filePath)); + RETURN_IF_FAILED(GrantDeleteAccess(filePath)); + RETURN_IF_WIN32_BOOL_FALSE(::DeleteFile(filePath)); + } + return S_OK; + } + ~~~~ + */ + inline HRESULT run_as_self_nothrow(unique_token_reverter& reverter) + { + return impersonate_token_nothrow(nullptr, reverter); + } + + inline unique_token_reverter impersonate_token_failfast(HANDLE token) + { + unique_token_reverter oldToken; + FAIL_FAST_IF_FAILED(impersonate_token_nothrow(token, oldToken)); + return oldToken; + } + + inline unique_token_reverter run_as_self_failfast() + { + return impersonate_token_failfast(nullptr); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Temporarily impersonates a token on this thread. + This method sets a new token on a thread, restoring the current token when the returned object + is destroyed. Useful for impersonating other tokens or running as 'self,' especially in services. + ~~~~ + wil::unique_hfile OpenFileAsSessionuser(_In_z_ const wchar_t* filePath, DWORD session) + { + wil::unique_handle userToken; + THROW_IF_WIN32_BOOL_FALSE(QueryUserToken(session, &userToken)); + + auto priorToken = wil::impersonate_token(userToken.get()); + + wil::unique_hfile userFile(::CreateFile(filePath, ...)); + THROW_LAST_ERROR_IF(::GetLastError() != ERROR_FILE_NOT_FOUND); + + return userFile; + } + ~~~~ + @param token A token to impersonate, or 'nullptr' to run as the process identity. + */ + inline unique_token_reverter impersonate_token(HANDLE token = nullptr) + { + unique_token_reverter oldToken; + THROW_IF_FAILED(impersonate_token_nothrow(token, oldToken)); + return oldToken; + } + + /** Temporarily clears any impersonation on this thread. + This method resets the current thread's token to nullptr, indicating that it is not impersonating + any user. Useful for elevating to whatever identity a service or higher-privilege process might + be capable of running under. + ~~~~ + void DeleteFileRetryAsSelf(_In_z_ const wchar_t* filePath) + { + if (!::DeleteFile(filePath) && (::GetLastError() == ERROR_ACCESS_DENIED)) + { + auto priorToken = wil::run_as_self(); + TakeOwnershipOfFile(filePath); + GrantDeleteAccess(filePath); + ::DeleteFile(filePath); + } + } + ~~~~ + */ + inline unique_token_reverter run_as_self() + { + return impersonate_token(nullptr); + } +#endif // WIL_ENABLE_EXCEPTIONS + + namespace details + { + template struct static_sid_t + { + BYTE Revision; + BYTE SubAuthorityCount; + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + DWORD SubAuthority[AuthorityCount]; + + PSID get() + { + return reinterpret_cast(this); + } + + template static_sid_t& operator=(const static_sid_t& source) + { + static_assert(other <= AuthorityCount, "Cannot assign from a larger static sid to a smaller one"); + + if (&this->Revision != &source.Revision) + { + memcpy(this, &source, sizeof(source)); + } + + return *this; + } + }; + } + + /** Returns a structure containing a Revision 1 SID initialized with the authorities provided + Replaces AllocateAndInitializeSid by constructing a structure laid out like a PSID, but + returned like a value. The resulting object is suitable for use with any method taking PSID, + passed by "&the_sid" or via "the_sid.get()" + ~~~~ + // Change the owner of the key to administrators + auto systemSid = wil::make_static_sid(SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS); + RETURN_IF_WIN32_ERROR(SetNamedSecurityInfo(keyPath, SE_REGISTRY_KEY, OWNER_SECURITY_INFORMATION, &systemSid, nullptr, nullptr, nullptr)); + ~~~~ + */ + template constexpr auto make_static_sid(const SID_IDENTIFIER_AUTHORITY& authority, Ts&&... subAuthorities) + { + using sid_t = details::static_sid_t; + + static_assert(sizeof...(subAuthorities) <= SID_MAX_SUB_AUTHORITIES, "too many sub authorities"); + static_assert(offsetof(sid_t, Revision) == offsetof(_SID, Revision), "layout mismatch"); + static_assert(offsetof(sid_t, SubAuthorityCount) == offsetof(_SID, SubAuthorityCount), "layout mismatch"); + static_assert(offsetof(sid_t, IdentifierAuthority) == offsetof(_SID, IdentifierAuthority), "layout mismatch"); + static_assert(offsetof(sid_t, SubAuthority) == offsetof(_SID, SubAuthority), "layout mismatch"); + + return sid_t { SID_REVISION, sizeof...(subAuthorities), authority, { static_cast(subAuthorities)... } }; + } + + //! Variant of static_sid that defaults to the NT authority + template constexpr auto make_static_nt_sid(Ts&& ... subAuthorities) + { + return make_static_sid(SECURITY_NT_AUTHORITY, wistd::forward(subAuthorities)...); + } + + /** Determines whether a specified security identifier (SID) is enabled in an access token. + This function determines whether a security identifier, described by a given set of subauthorities, is enabled + in the given access token. Note that only up to eight subauthorities can be passed to this function. + ~~~~ + bool IsGuest() + { + return wil::test_token_membership(nullptr, SECURITY_NT_AUTHORITY, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS)); + } + ~~~~ + @param result This will be set to true if and only if a security identifier described by the given set of subauthorities is enabled in the given access token. + @param token A handle to an access token. The handle must have TOKEN_QUERY access to the token, and must be an impersonation token. If token is nullptr, test_token_membership + uses the impersonation token of the calling thread. If the thread is not impersonating, the function duplicates the thread's primary token to create an impersonation token. + @param sidAuthority A reference to a SID_IDENTIFIER_AUTHORITY structure. This structure provides the top-level identifier authority value to set in the SID. + @param subAuthorities Up to 15 subauthority values to place in the SID (this is a systemwide limit) + @return S_OK on success, a FAILED hresult containing the win32 error from creating the SID or querying the token otherwise. + */ + template HRESULT test_token_membership_nothrow(_Out_ bool* result, _In_opt_ HANDLE token, + const SID_IDENTIFIER_AUTHORITY& sidAuthority, Ts&&... subAuthorities) + { + *result = false; + auto tempSid = make_static_sid(sidAuthority, wistd::forward(subAuthorities)...); + BOOL isMember; + RETURN_IF_WIN32_BOOL_FALSE(CheckTokenMembership(token, &tempSid, &isMember)); + + *result = (isMember != FALSE); + + return S_OK; + } + +#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) + /** Determine whether a token represents an app container + This method uses the passed in token and emits a boolean indicating that + whether TokenIsAppContainer is true. + ~~~~ + HRESULT OnlyIfAppContainer() + { + bool isAppContainer; + RETURN_IF_FAILED(wil::get_token_is_app_container_nothrow(nullptr, isAppContainer)); + RETURN_HR_IF(E_ACCESSDENIED, !isAppContainer); + RETURN_HR(...); + } + ~~~~ + @param token A token to get info about, or 'nullptr' to run as the current thread. + */ + inline HRESULT get_token_is_app_container_nothrow(_In_opt_ HANDLE token, bool& value) + { + DWORD isAppContainer = 0; + DWORD returnLength = 0; + RETURN_IF_WIN32_BOOL_FALSE(::GetTokenInformation( + token ? token : GetCurrentThreadEffectiveToken(), + TokenIsAppContainer, + &isAppContainer, + sizeof(isAppContainer), + &returnLength)); + + value = (isAppContainer != 0); + + return S_OK; + } + + //! A variant of get_token_is_app_container_nothrow that fails-fast on errors retrieving the token information + inline bool get_token_is_app_container_failfast(HANDLE token = nullptr) + { + bool value = false; + FAIL_FAST_IF_FAILED(get_token_is_app_container_nothrow(token, value)); + + return value; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + //! A variant of get_token_is_app_container_nothrow that throws on errors retrieving the token information + inline bool get_token_is_app_container(HANDLE token = nullptr) + { + bool value = false; + THROW_IF_FAILED(get_token_is_app_container_nothrow(token, value)); + + return value; + } +#endif // WIL_ENABLE_EXCEPTIONS +#endif // _WIN32_WINNT >= _WIN32_WINNT_WIN8 + + template bool test_token_membership_failfast(_In_opt_ HANDLE token, + const SID_IDENTIFIER_AUTHORITY& sidAuthority, Ts&&... subAuthorities) + { + bool result; + FAIL_FAST_IF_FAILED(test_token_membership_nothrow(&result, token, sidAuthority, wistd::forward(subAuthorities)...)); + return result; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + template bool test_token_membership(_In_opt_ HANDLE token, const SID_IDENTIFIER_AUTHORITY& sidAuthority, + Ts&&... subAuthorities) + { + bool result; + THROW_IF_FAILED(test_token_membership_nothrow(&result, token, sidAuthority, wistd::forward(subAuthorities)...)); + return result; + } +#endif + +} //namespace wil + +#endif // __WIL_TOKEN_HELPERS_INCLUDED diff --git a/libraries/wil/traceloggingconfig.h b/libraries/wil/traceloggingconfig.h new file mode 100644 index 0000000..33e3e9c --- /dev/null +++ b/libraries/wil/traceloggingconfig.h @@ -0,0 +1,71 @@ +#pragma once +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* + +#ifndef __WIL_TRACELOGGING_CONFIG_H +#define __WIL_TRACELOGGING_CONFIG_H + +// Configuration macro for use in TRACELOGGING_DEFINE_PROVIDER. The definition +// in this file configures the provider as a normal (non-telemetry) provider. +#define TraceLoggingOptionMicrosoftTelemetry() \ + // Empty definition for TraceLoggingOptionMicrosoftTelemetry + +// Configuration macro for use in TRACELOGGING_DEFINE_PROVIDER. The definition +// in this file configures the provider as a normal (non-telemetry) provider. +#define TraceLoggingOptionWindowsCoreTelemetry() \ + // Empty definition for TraceLoggingOptionWindowsCoreTelemetry + +// Event privacy tags. Use the PDT macro values for the tag parameter, e.g.: +// TraceLoggingWrite(..., +// TelemetryPrivacyDataTag(PDT_BrowsingHistory | PDT_ProductAndServiceUsage), +// ...); +#define TelemetryPrivacyDataTag(tag) TraceLoggingUInt64((tag), "PartA_PrivTags") +#define PDT_BrowsingHistory 0x0000000000000002u +#define PDT_DeviceConnectivityAndConfiguration 0x0000000000000800u +#define PDT_InkingTypingAndSpeechUtterance 0x0000000000020000u +#define PDT_ProductAndServicePerformance 0x0000000001000000u +#define PDT_ProductAndServiceUsage 0x0000000002000000u +#define PDT_SoftwareSetupAndInventory 0x0000000080000000u + +// Event categories specified via keywords, e.g.: +// TraceLoggingWrite(..., +// TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES), +// ...); +#define MICROSOFT_KEYWORD_CRITICAL_DATA 0x0000800000000000 // Bit 47 +#define MICROSOFT_KEYWORD_MEASURES 0x0000400000000000 // Bit 46 +#define MICROSOFT_KEYWORD_TELEMETRY 0x0000200000000000 // Bit 45 +#define MICROSOFT_KEYWORD_RESERVED_44 0x0000100000000000 // Bit 44 (reserved for future assignment) + +// Event categories specified via event tags, e.g.: +// TraceLoggingWrite(..., +// TraceLoggingEventTag(MICROSOFT_EVENTTAG_REALTIME_LATENCY), +// ...); +#define MICROSOFT_EVENTTAG_DROP_USER_IDS 0x00008000 +#define MICROSOFT_EVENTTAG_AGGREGATE 0x00010000 +#define MICROSOFT_EVENTTAG_DROP_PII_EXCEPT_IP 0x00020000 +#define MICROSOFT_EVENTTAG_COSTDEFERRED_LATENCY 0x00040000 +#define MICROSOFT_EVENTTAG_CORE_DATA 0x00080000 +#define MICROSOFT_EVENTTAG_INJECT_XTOKEN 0x00100000 +#define MICROSOFT_EVENTTAG_REALTIME_LATENCY 0x00200000 +#define MICROSOFT_EVENTTAG_NORMAL_LATENCY 0x00400000 +#define MICROSOFT_EVENTTAG_CRITICAL_PERSISTENCE 0x00800000 +#define MICROSOFT_EVENTTAG_NORMAL_PERSISTENCE 0x01000000 +#define MICROSOFT_EVENTTAG_DROP_PII 0x02000000 +#define MICROSOFT_EVENTTAG_HASH_PII 0x04000000 +#define MICROSOFT_EVENTTAG_MARK_PII 0x08000000 + +// Field categories specified via field tags, e.g.: +// TraceLoggingWrite(..., +// TraceLoggingString(szUser, "UserName", "User's name", MICROSOFT_FIELDTAG_HASH_PII), +// ...); +#define MICROSOFT_FIELDTAG_DROP_PII 0x04000000 +#define MICROSOFT_FIELDTAG_HASH_PII 0x08000000 +#endif // __WIL_TRACELOGGING_CONFIG_H \ No newline at end of file diff --git a/libraries/wil/win32_helpers.h b/libraries/wil/win32_helpers.h new file mode 100644 index 0000000..a935c87 --- /dev/null +++ b/libraries/wil/win32_helpers.h @@ -0,0 +1,898 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_WIN32_HELPERS_INCLUDED +#define __WIL_WIN32_HELPERS_INCLUDED + +#include // FILETIME, HINSTANCE +#include // GetSystemTimeAsFileTime +#include // GetProcAddress +#include // GetModuleFileNameExW (macro), K32GetModuleFileNameExW +#include +#include + +// detect std::bit_cast +#ifdef __has_include +# if (__cplusplus >= 202002L || _MSVC_LANG >= 202002L) && __has_include() +# include +# endif +#endif + +#if __cpp_lib_bit_cast >= 201806L +# define __WI_CONSTEXPR_BIT_CAST constexpr +#else +# define __WI_CONSTEXPR_BIT_CAST inline +#endif + +#include "result.h" +#include "resource.h" +#include "wistd_functional.h" +#include "wistd_type_traits.h" + +#if _HAS_CXX20 && defined(_STRING_VIEW_) && defined(_COMPARE_) +// If we're using c++20, then must be included to use the string ordinal functions +# define __WI_DEFINE_STRING_ORDINAL_FUNCTIONS +#elif !_HAS_CXX20 && defined(_STRING_VIEW_) +# define __WI_DEFINE_STRING_ORDINAL_FUNCTIONS +#endif + +namespace wistd +{ +#if defined(__WI_DEFINE_STRING_ORDINAL_FUNCTIONS) + +#if _HAS_CXX20 + + using weak_ordering = std::weak_ordering; + +#else // _HAS_CXX20 + + struct weak_ordering + { + static const weak_ordering less; + static const weak_ordering equivalent; + static const weak_ordering greater; + + [[nodiscard]] friend constexpr bool operator==(const weak_ordering left, std::nullptr_t) noexcept + { + return left.m_value == 0; + } + + [[nodiscard]] friend constexpr bool operator!=(const weak_ordering left, std::nullptr_t) noexcept + { + return left.m_value != 0; + } + + [[nodiscard]] friend constexpr bool operator<(const weak_ordering left, std::nullptr_t) noexcept + { + return left.m_value < 0; + } + + [[nodiscard]] friend constexpr bool operator>(const weak_ordering left, std::nullptr_t) noexcept + { + return left.m_value > 0; + } + + [[nodiscard]] friend constexpr bool operator<=(const weak_ordering left, std::nullptr_t) noexcept + { + return left.m_value <= 0; + } + + [[nodiscard]] friend constexpr bool operator>=(const weak_ordering left, std::nullptr_t) noexcept + { + return left.m_value >= 0; + } + + [[nodiscard]] friend constexpr bool operator==(std::nullptr_t, const weak_ordering right) noexcept + { + return right == 0; + } + + [[nodiscard]] friend constexpr bool operator!=(std::nullptr_t, const weak_ordering right) noexcept + { + return right != 0; + } + + [[nodiscard]] friend constexpr bool operator<(std::nullptr_t, const weak_ordering right) noexcept + { + return right > 0; + } + + [[nodiscard]] friend constexpr bool operator>(std::nullptr_t, const weak_ordering right) noexcept + { + return right < 0; + } + + [[nodiscard]] friend constexpr bool operator<=(std::nullptr_t, const weak_ordering right) noexcept + { + return right >= 0; + } + + [[nodiscard]] friend constexpr bool operator>=(std::nullptr_t, const weak_ordering right) noexcept + { + return right <= 0; + } + + signed char m_value; + }; + + inline constexpr weak_ordering weak_ordering::less{static_cast(-1)}; + inline constexpr weak_ordering weak_ordering::equivalent{static_cast(0)}; + inline constexpr weak_ordering weak_ordering::greater{static_cast(1)}; + +#endif // !_HAS_CXX20 + +#endif // defined(__WI_DEFINE_STRING_ORDINAL_FUNCTIONS) + +} + +namespace wil +{ + //! Strictly a function of the file system but this is the value for all known file system, NTFS, FAT. + //! CDFs has a limit of 254. + constexpr size_t max_path_segment_length = 255; + + //! Character length not including the null, MAX_PATH (260) includes the null. + constexpr size_t max_path_length = 259; + + //! 32743 Character length not including the null. This is a system defined limit. + //! The 24 is for the expansion of the roots from "C:" to "\Device\HarddiskVolume4" + //! It will be 25 when there are more than 9 disks. + constexpr size_t max_extended_path_length = 0x7FFF - 24; + + //! For {guid} string form. Includes space for the null terminator. + constexpr size_t guid_string_buffer_length = 39; + + //! For {guid} string form. Not including the null terminator. + constexpr size_t guid_string_length = 38; + +#pragma region String and identifier comparisons + // Using CompareStringOrdinal functions: + // + // Indentifiers require a locale-less (ordinal), and often case-insensitive, comparison (filenames, registry keys, XML node names, etc). + // DO NOT use locale-sensitive (lexical) comparisons for resource identifiers (e.g.wcs*() functions in the CRT). + +#if defined(__WI_DEFINE_STRING_ORDINAL_FUNCTIONS) + + namespace details + { + [[nodiscard]] inline int CompareStringOrdinal(std::wstring_view left, std::wstring_view right, bool caseInsensitive) WI_NOEXCEPT + { + // Casting from size_t (unsigned) to int (signed) should be safe from overrun to a negative, + // merely truncating the string. CompareStringOrdinal should be resilient to negatives. + return ::CompareStringOrdinal(left.data(), static_cast(left.size()), right.data(), static_cast(right.size()), caseInsensitive); + } + } + + [[nodiscard]] inline wistd::weak_ordering compare_string_ordinal(std::wstring_view left, std::wstring_view right, bool caseInsensitive) WI_NOEXCEPT + { + switch (wil::details::CompareStringOrdinal(left, right, caseInsensitive)) + { + case CSTR_LESS_THAN: + return wistd::weak_ordering::less; + case CSTR_GREATER_THAN: + return wistd::weak_ordering::greater; + default: + return wistd::weak_ordering::equivalent; + } + } + +#endif // defined(__WI_DEFINE_STRING_ORDINAL_FUNCTIONS) + +#pragma endregion + +#pragma region FILETIME helpers + // FILETIME duration values. FILETIME is in 100 nanosecond units. + namespace filetime_duration + { + long long const one_millisecond = 10000LL; + long long const one_second = 10000000LL; + long long const one_minute = 10000000LL * 60; // 600000000 or 600000000LL + long long const one_hour = 10000000LL * 60 * 60; // 36000000000 or 36000000000LL + long long const one_day = 10000000LL * 60 * 60 * 24; // 864000000000 or 864000000000LL + }; + + namespace filetime + { + constexpr unsigned long long to_int64(const FILETIME &ft) WI_NOEXCEPT + { +#if __cpp_lib_bit_cast >= 201806L + return std::bit_cast(ft); +#else + // Cannot reinterpret_cast FILETIME* to unsigned long long* + // due to alignment differences. + return (static_cast(ft.dwHighDateTime) << 32) + ft.dwLowDateTime; +#endif + } + + __WI_CONSTEXPR_BIT_CAST FILETIME from_int64(unsigned long long i64) WI_NOEXCEPT + { +#if __cpp_lib_bit_cast >= 201806L + return std::bit_cast(i64); +#else + static_assert(sizeof(i64) == sizeof(FILETIME), "sizes don't match"); + static_assert(__alignof(unsigned long long) >= __alignof(FILETIME), "alignment not compatible with type pun"); + return *reinterpret_cast(&i64); +#endif + } + + __WI_CONSTEXPR_BIT_CAST FILETIME add(_In_ FILETIME const &ft, long long delta100ns) WI_NOEXCEPT + { + return from_int64(to_int64(ft) + delta100ns); + } + + constexpr bool is_empty(const FILETIME &ft) WI_NOEXCEPT + { + return (ft.dwHighDateTime == 0) && (ft.dwLowDateTime == 0); + } + + inline FILETIME get_system_time() WI_NOEXCEPT + { + FILETIME ft; + GetSystemTimeAsFileTime(&ft); + return ft; + } + + /// Convert time as units of 100 nanoseconds to milliseconds. Fractional milliseconds are truncated. + constexpr unsigned long long convert_100ns_to_msec(unsigned long long time100ns) WI_NOEXCEPT + { + return time100ns / filetime_duration::one_millisecond; + } + + /// Convert time as milliseconds to units of 100 nanoseconds. + constexpr unsigned long long convert_msec_to_100ns(unsigned long long timeMsec) WI_NOEXCEPT + { + return timeMsec * filetime_duration::one_millisecond; + } + +#if defined(_APISETREALTIME_) && (_WIN32_WINNT >= _WIN32_WINNT_WIN7) + /// Returns the current unbiased interrupt-time count, in units of 100 nanoseconds. The unbiased interrupt-time count does not include time the system spends in sleep or hibernation. + /// + /// This API avoids prematurely shortcircuiting timing loops due to system sleep/hibernation. + /// + /// This is equivalent to GetTickCount64() except it returns units of 100 nanoseconds instead of milliseconds, and it doesn't include time the system spends in sleep or hibernation. + /// For example + /// + /// start = GetTickCount64(); + /// hibernate(); + /// ...wake from hibernation 30 minutes later...; + /// elapsed = GetTickCount64() - start; + /// // elapsed = 30min + /// + /// Do the same using unbiased interrupt-time and elapsed is 0 (or nearly so). + /// + /// @note This is identical to QueryUnbiasedInterruptTime() but returns the value as a return value (rather than an out parameter). + /// @see https://msdn.microsoft.com/en-us/library/windows/desktop/ee662307(v=vs.85).aspx + inline unsigned long long QueryUnbiasedInterruptTimeAs100ns() WI_NOEXCEPT + { + ULONGLONG now{}; + QueryUnbiasedInterruptTime(&now); + return now; + } + + /// Returns the current unbiased interrupt-time count, in units of milliseconds. The unbiased interrupt-time count does not include time the system spends in sleep or hibernation. + /// @see QueryUnbiasedInterruptTimeAs100ns + inline unsigned long long QueryUnbiasedInterruptTimeAsMSec() WI_NOEXCEPT + { + return convert_100ns_to_msec(QueryUnbiasedInterruptTimeAs100ns()); + } +#endif // _APISETREALTIME_ + } +#pragma endregion + +#pragma region RECT helpers + template + constexpr auto rect_width(rect_type const& rect) + { + return rect.right - rect.left; + } + + template + constexpr auto rect_height(rect_type const& rect) + { + return rect.bottom - rect.top; + } + + template + constexpr auto rect_is_empty(rect_type const& rect) + { + return (rect.left >= rect.right) || (rect.top >= rect.bottom); + } + + template + constexpr auto rect_contains_point(rect_type const& rect, point_type const& point) + { + return (point.x >= rect.left) && (point.x < rect.right) && (point.y >= rect.top) && (point.y < rect.bottom); + } + + template + constexpr rect_type rect_from_size(length_type x, length_type y, length_type width, length_type height) + { + rect_type rect; + rect.left = x; + rect.top = y; + rect.right = x + width; + rect.bottom = y + height; + return rect; + } +#pragma endregion + + // Use to adapt Win32 APIs that take a fixed size buffer into forms that return + // an allocated buffer. Supports many types of string representation. + // See comments below on the expected behavior of the callback. + // Adjust stackBufferLength based on typical result sizes to optimize use and + // to test the boundary cases. + template + HRESULT AdaptFixedSizeToAllocatedResult(string_type& result, wistd::function callback) WI_NOEXCEPT + { + details::string_maker maker; + + wchar_t value[stackBufferLength]{}; + value[0] = L'\0'; + size_t valueLengthNeededWithNull{}; // callback returns the number of characters needed including the null terminator. + RETURN_IF_FAILED_EXPECTED(callback(value, ARRAYSIZE(value), &valueLengthNeededWithNull)); + WI_ASSERT(valueLengthNeededWithNull > 0); + if (valueLengthNeededWithNull <= ARRAYSIZE(value)) + { + // Success case as described above, make() adds the space for the null. + RETURN_IF_FAILED(maker.make(value, valueLengthNeededWithNull - 1)); + } + else + { + // Did not fit in the stack allocated buffer, need to do 2 phase construction. + // May need to loop more than once if external conditions cause the value to change. + size_t bufferLength; + do + { + bufferLength = valueLengthNeededWithNull; + // bufferLength includes the null so subtract that as make() will add space for it. + RETURN_IF_FAILED(maker.make(nullptr, bufferLength - 1)); + + RETURN_IF_FAILED_EXPECTED(callback(maker.buffer(), bufferLength, &valueLengthNeededWithNull)); + WI_ASSERT(valueLengthNeededWithNull > 0); + + // If the value shrunk, then adjust the string to trim off the excess buffer. + if (valueLengthNeededWithNull < bufferLength) + { + RETURN_IF_FAILED(maker.trim_at_existing_null(valueLengthNeededWithNull - 1)); + } + } + while (valueLengthNeededWithNull > bufferLength); + } + result = maker.release(); + return S_OK; + } + + /** Expands the '%' quoted environment variables in 'input' using ExpandEnvironmentStringsW(); */ + template + HRESULT ExpandEnvironmentStringsW(_In_ PCWSTR input, string_type& result) WI_NOEXCEPT + { + return wil::AdaptFixedSizeToAllocatedResult(result, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNul) -> HRESULT + { + *valueLengthNeededWithNul = ::ExpandEnvironmentStringsW(input, value, static_cast(valueLength)); + RETURN_LAST_ERROR_IF(*valueLengthNeededWithNul == 0); + return S_OK; + }); + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) + /** Searches for a specified file in a specified path using ExpandEnvironmentStringsW(); */ + template + HRESULT SearchPathW(_In_opt_ PCWSTR path, _In_ PCWSTR fileName, _In_opt_ PCWSTR extension, string_type& result) WI_NOEXCEPT + { + return wil::AdaptFixedSizeToAllocatedResult(result, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNul) -> HRESULT + { + *valueLengthNeededWithNul = ::SearchPathW(path, fileName, extension, static_cast(valueLength), value, nullptr); + + if (*valueLengthNeededWithNul == 0) + { + // ERROR_FILE_NOT_FOUND is an expected return value for SearchPathW + const HRESULT searchResult = HRESULT_FROM_WIN32(::GetLastError()); + RETURN_HR_IF_EXPECTED(searchResult, searchResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); + RETURN_IF_FAILED(searchResult); + } + + // AdaptFixedSizeToAllocatedResult expects that the length will always include the NUL. + // If the result is copied to the buffer, SearchPathW returns the length of copied string, WITHOUT the NUL. + // If the buffer is too small to hold the result, SearchPathW returns the length of the required buffer WITH the nul. + if (*valueLengthNeededWithNul < valueLength) + { + (*valueLengthNeededWithNul)++; // It fit, account for the null. + } + return S_OK; + }); + } + + template + HRESULT QueryFullProcessImageNameW(HANDLE processHandle, _In_ DWORD flags, string_type& result) WI_NOEXCEPT + { + return wil::AdaptFixedSizeToAllocatedResult(result, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNul) -> HRESULT + { + DWORD lengthToUse = static_cast(valueLength); + BOOL const success = ::QueryFullProcessImageNameW(processHandle, flags, value, &lengthToUse); + RETURN_LAST_ERROR_IF((success == FALSE) && (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)); + + // On success, return the amount used; on failure, try doubling + *valueLengthNeededWithNul = success ? (static_cast(lengthToUse) + 1) : (static_cast(lengthToUse) * 2); + return S_OK; + }); + } + + /** Expands environment strings and checks path existence with SearchPathW */ + template + HRESULT ExpandEnvAndSearchPath(_In_ PCWSTR input, string_type& result) WI_NOEXCEPT + { + wil::unique_cotaskmem_string expandedName; + RETURN_IF_FAILED((wil::ExpandEnvironmentStringsW(input, expandedName))); + + // ERROR_FILE_NOT_FOUND is an expected return value for SearchPathW + const HRESULT searchResult = (wil::SearchPathW(nullptr, expandedName.get(), nullptr, result)); + RETURN_HR_IF_EXPECTED(searchResult, searchResult == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); + RETURN_IF_FAILED(searchResult); + + return S_OK; + } +#endif + + /** Looks up the environment variable 'key' and fails if it is not found. */ + template + inline HRESULT GetEnvironmentVariableW(_In_ PCWSTR key, string_type& result) WI_NOEXCEPT + { + return wil::AdaptFixedSizeToAllocatedResult(result, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNul) -> HRESULT + { + // If the function succeeds, the return value is the number of characters stored in the buffer + // pointed to by lpBuffer, not including the terminating null character. + // + // If lpBuffer is not large enough to hold the data, the return value is the buffer size, in + // characters, required to hold the string and its terminating null character and the contents of + // lpBuffer are undefined. + // + // If the function fails, the return value is zero. If the specified environment variable was not + // found in the environment block, GetLastError returns ERROR_ENVVAR_NOT_FOUND. + + ::SetLastError(ERROR_SUCCESS); + + *valueLengthNeededWithNul = ::GetEnvironmentVariableW(key, value, static_cast(valueLength)); + RETURN_LAST_ERROR_IF_EXPECTED((*valueLengthNeededWithNul == 0) && (::GetLastError() != ERROR_SUCCESS)); + if (*valueLengthNeededWithNul < valueLength) + { + (*valueLengthNeededWithNul)++; // It fit, account for the null. + } + return S_OK; + }); + } + + /** Looks up the environment variable 'key' and returns null if it is not found. */ + template + HRESULT TryGetEnvironmentVariableW(_In_ PCWSTR key, string_type& result) WI_NOEXCEPT + { + const auto hr = wil::GetEnvironmentVariableW(key, result); + RETURN_HR_IF(hr, FAILED(hr) && (hr != HRESULT_FROM_WIN32(ERROR_ENVVAR_NOT_FOUND))); + return S_OK; + } + + /** Retrieves the fully qualified path for the file containing the specified module loaded + by a given process. Note GetModuleFileNameExW is a macro.*/ + template + HRESULT GetModuleFileNameExW(_In_opt_ HANDLE process, _In_opt_ HMODULE module, string_type& path) WI_NOEXCEPT + { + auto adapter = [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNul) -> HRESULT + { + DWORD copiedCount{}; + size_t valueUsedWithNul{}; + bool copyFailed{}; + bool copySucceededWithNoTruncation{}; + if (process != nullptr) + { + // GetModuleFileNameExW truncates and provides no error or other indication it has done so. + // The only way to be sure it didn't truncate is if it didn't need the whole buffer. The + // count copied to the buffer includes the nul-character as well. + copiedCount = ::GetModuleFileNameExW(process, module, value, static_cast(valueLength)); + valueUsedWithNul = static_cast(copiedCount) + 1; + copyFailed = (0 == copiedCount); + copySucceededWithNoTruncation = !copyFailed && (copiedCount < valueLength - 1); + } + else + { + // In cases of insufficient buffer, GetModuleFileNameW will return a value equal to lengthWithNull + // and set the last error to ERROR_INSUFFICIENT_BUFFER. The count returned does not include + // the nul-character + copiedCount = ::GetModuleFileNameW(module, value, static_cast(valueLength)); + valueUsedWithNul = static_cast(copiedCount) + 1; + copyFailed = (0 == copiedCount); + copySucceededWithNoTruncation = !copyFailed && (copiedCount < valueLength); + } + + RETURN_LAST_ERROR_IF(copyFailed); + + // When the copy truncated, request another try with more space. + *valueLengthNeededWithNul = copySucceededWithNoTruncation ? valueUsedWithNul : (valueLength * 2); + + return S_OK; + }; + + return wil::AdaptFixedSizeToAllocatedResult(path, wistd::move(adapter)); + } + + /** Retrieves the fully qualified path for the file that contains the specified module. + The module must have been loaded by the current process. The path returned will use the + same format that was specified when the module was loaded. Therefore, the path can be a + long or short file name, and can have the prefix '\\?\'. */ + template + HRESULT GetModuleFileNameW(HMODULE module, string_type& path) WI_NOEXCEPT + { + return wil::GetModuleFileNameExW(nullptr, module, path); + } + + template + HRESULT GetSystemDirectoryW(string_type& result) WI_NOEXCEPT + { + return wil::AdaptFixedSizeToAllocatedResult(result, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNul) -> HRESULT + { + *valueLengthNeededWithNul = ::GetSystemDirectoryW(value, static_cast(valueLength)); + RETURN_LAST_ERROR_IF(*valueLengthNeededWithNul == 0); + if (*valueLengthNeededWithNul < valueLength) + { + (*valueLengthNeededWithNul)++; // it fit, account for the null + } + return S_OK; + }); + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) + template + HRESULT GetWindowsDirectoryW(string_type& result) WI_NOEXCEPT + { + return wil::AdaptFixedSizeToAllocatedResult(result, + [&](_Out_writes_(valueLength) PWSTR value, size_t valueLength, _Out_ size_t* valueLengthNeededWithNul) -> HRESULT + { + *valueLengthNeededWithNul = ::GetWindowsDirectoryW(value, static_cast(valueLength)); + RETURN_LAST_ERROR_IF(*valueLengthNeededWithNul == 0); + if (*valueLengthNeededWithNul < valueLength) + { + (*valueLengthNeededWithNul)++; // it fit, account for the null + } + return S_OK; + }); + } +#endif + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Expands the '%' quoted environment variables in 'input' using ExpandEnvironmentStringsW(); */ + template + string_type ExpandEnvironmentStringsW(_In_ PCWSTR input) + { + string_type result{}; + THROW_IF_FAILED((wil::ExpandEnvironmentStringsW(input, result))); + return result; + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) + /** Searches for a specified file in a specified path using SearchPathW*/ + template + string_type TrySearchPathW(_In_opt_ PCWSTR path, _In_ PCWSTR fileName, PCWSTR _In_opt_ extension) + { + string_type result{}; + HRESULT searchHR = wil::SearchPathW(path, fileName, extension, result); + THROW_HR_IF(searchHR, FAILED(searchHR) && (searchHR != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))); + return result; + } +#endif + + /** Looks up the environment variable 'key' and fails if it is not found. */ + template + string_type GetEnvironmentVariableW(_In_ PCWSTR key) + { + string_type result{}; + THROW_IF_FAILED((wil::GetEnvironmentVariableW(key, result))); + return result; + } + + /** Looks up the environment variable 'key' and returns null if it is not found. */ + template + string_type TryGetEnvironmentVariableW(_In_ PCWSTR key) + { + string_type result{}; + THROW_IF_FAILED((wil::TryGetEnvironmentVariableW(key, result))); + return result; + } + + template + string_type GetModuleFileNameW(HMODULE module = nullptr /* current process module */) + { + string_type result{}; + THROW_IF_FAILED((wil::GetModuleFileNameW(module, result))); + return result; + } + + template + string_type GetModuleFileNameExW(HANDLE process, HMODULE module) + { + string_type result{}; + THROW_IF_FAILED((wil::GetModuleFileNameExW(process, module, result))); + return result; + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) + template + string_type GetWindowsDirectoryW() + { + string_type result; + THROW_IF_FAILED((wil::GetWindowsDirectoryW(result))); + return result; + } +#endif + + template + string_type GetSystemDirectoryW() + { + string_type result; + THROW_IF_FAILED((wil::GetSystemDirectoryW(result))); + return result; + } + + template + string_type QueryFullProcessImageNameW(HANDLE processHandle = GetCurrentProcess(), DWORD flags = 0) + { + string_type result{}; + THROW_IF_FAILED((wil::QueryFullProcessImageNameW(processHandle, flags, result))); + return result; + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + + // Lookup a DWORD value under HKLM\...\Image File Execution Options\ + inline DWORD GetCurrentProcessExecutionOption(PCWSTR valueName, DWORD defaultValue = 0) + { + auto filePath = wil::GetModuleFileNameW(); + if (auto lastSlash = wcsrchr(filePath.get(), L'\\')) + { + const auto fileName = lastSlash + 1; + auto keyPath = wil::str_concat(LR"(SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\)", + fileName); + DWORD value{}, sizeofValue = sizeof(value); + if (::RegGetValueW(HKEY_LOCAL_MACHINE, keyPath.get(), valueName, +#ifdef RRF_SUBKEY_WOW6464KEY + RRF_RT_REG_DWORD | RRF_SUBKEY_WOW6464KEY, +#else + RRF_RT_REG_DWORD, +#endif + nullptr, &value, &sizeofValue) == ERROR_SUCCESS) + { + return value; + } + } + return defaultValue; + } + + // Waits for a debugger to attach to the current process based on registry configuration. + // + // Example: + // HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\explorer.exe + // WaitForDebuggerPresent=1 + // + // REG_DWORD value of + // missing or 0 -> don't break + // 1 -> wait for the debugger, continue execution once it is attached + // 2 -> wait for the debugger, break here once attached. + inline void WaitForDebuggerPresent(bool checkRegistryConfig = true) + { + for (;;) + { + auto configValue = checkRegistryConfig ? GetCurrentProcessExecutionOption(L"WaitForDebuggerPresent") : 1; + if (configValue == 0) + { + return; // not configured, don't wait + } + + if (IsDebuggerPresent()) + { + if (configValue == 2) + { + DebugBreak(); // debugger attached, SHIFT+F11 to return to the caller + } + return; // debugger now attached, continue executing + } + Sleep(500); + } + } +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + +#endif + + /** Retrieve the HINSTANCE for the current DLL or EXE using this symbol that + the linker provides for every module. This avoids the need for a global HINSTANCE variable + and provides access to this value for static libraries. */ + EXTERN_C IMAGE_DOS_HEADER __ImageBase; + inline HINSTANCE GetModuleInstanceHandle() WI_NOEXCEPT { return reinterpret_cast(&__ImageBase); } + + // GetModuleHandleExW was added to the app partition in version 22000 of the SDK +#if defined(NTDDI_WIN10_CO) ? \ + WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) : \ + WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) + // Use this in threads that can outlive the object or API call that created them. + // Without this COM, or the API caller, can unload the DLL, resulting in a crash. + // It is very important that this be the first object created in the thread proc + // as when this runs down the thread exits and no destructors of objects created before + // it will run. + [[nodiscard]] inline auto get_module_reference_for_thread() noexcept + { + HMODULE thisModule{}; + FAIL_FAST_IF(!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, L"", &thisModule)); + return wil::scope_exit([thisModule] + { + FreeLibraryAndExitThread(thisModule, 0); + }); + } +#endif + + /// @cond + namespace details + { + class init_once_completer + { + INIT_ONCE& m_once; + unsigned long m_flags = INIT_ONCE_INIT_FAILED; + public: + init_once_completer(_In_ INIT_ONCE& once) WI_NOEXCEPT : m_once(once) + { + } + + #pragma warning(push) + #pragma warning(disable:4702) // https://github.com/Microsoft/wil/issues/2 + void success() WI_NOEXCEPT + { + m_flags = 0; + } + #pragma warning(pop) + + ~init_once_completer() WI_NOEXCEPT + { + ::InitOnceComplete(&m_once, m_flags, nullptr); + } + }; + } + /// @endcond + + /** Performs one-time initialization + Simplifies using the Win32 INIT_ONCE structure to perform one-time initialization. The provided `func` is invoked + at most once. + ~~~~ + INIT_ONCE g_init{}; + ComPtr g_foo; + HRESULT MyMethod() + { + bool winner = false; + RETURN_IF_FAILED(wil::init_once_nothrow(g_init, [] + { + ComPtr foo; + RETURN_IF_FAILED(::CoCreateInstance(..., IID_PPV_ARGS(&foo)); + RETURN_IF_FAILED(foo->Startup()); + g_foo = foo; + }, &winner); + if (winner) + { + RETURN_IF_FAILED(g_foo->Another()); + } + return S_OK; + } + ~~~~ + See MSDN for more information on `InitOnceExecuteOnce`. + @param initOnce The INIT_ONCE structure to use as context for initialization. + @param func A function that will be invoked to perform initialization. If this fails, the init call + fails and the once-init is not marked as initialized. A later caller could attempt to + initialize it a second time. + @param callerCompleted Set to 'true' if this was the call that caused initialization, false otherwise. + */ + template HRESULT init_once_nothrow(_Inout_ INIT_ONCE& initOnce, T func, _Out_opt_ bool* callerCompleted = nullptr) WI_NOEXCEPT + { + BOOL pending = FALSE; + wil::assign_to_opt_param(callerCompleted, false); + + __WIL_PRIVATE_RETURN_IF_WIN32_BOOL_FALSE(InitOnceBeginInitialize(&initOnce, 0, &pending, nullptr)); + + if (pending) + { + details::init_once_completer completion(initOnce); + __WIL_PRIVATE_RETURN_IF_FAILED(func()); + completion.success(); + wil::assign_to_opt_param(callerCompleted, true); + } + + return S_OK; + } + + //! Similar to init_once_nothrow, but fails-fast if the initialization step failed. The 'callerComplete' value is + //! returned to the caller instead of being an out-parameter. + template bool init_once_failfast(_Inout_ INIT_ONCE& initOnce, T&& func) WI_NOEXCEPT + { + bool callerCompleted; + + FAIL_FAST_IF_FAILED(init_once_nothrow(initOnce, wistd::forward(func), &callerCompleted)); + + return callerCompleted; + }; + + //! Returns 'true' if this `init_once` structure has finished initialization, false otherwise. + inline bool init_once_initialized(_Inout_ INIT_ONCE& initOnce) WI_NOEXCEPT + { + BOOL pending = FALSE; + return ::InitOnceBeginInitialize(&initOnce, INIT_ONCE_CHECK_ONLY, &pending, nullptr) && !pending; + } + +#ifdef WIL_ENABLE_EXCEPTIONS + /** Performs one-time initialization + Simplifies using the Win32 INIT_ONCE structure to perform one-time initialization. The provided `func` is invoked + at most once. + ~~~~ + INIT_ONCE g_init{}; + ComPtr g_foo; + void MyMethod() + { + bool winner = wil::init_once(g_init, [] + { + ComPtr foo; + THROW_IF_FAILED(::CoCreateInstance(..., IID_PPV_ARGS(&foo)); + THROW_IF_FAILED(foo->Startup()); + g_foo = foo; + }); + if (winner) + { + THROW_IF_FAILED(g_foo->Another()); + } + } + ~~~~ + See MSDN for more information on `InitOnceExecuteOnce`. + @param initOnce The INIT_ONCE structure to use as context for initialization. + @param func A function that will be invoked to perform initialization. If this fails, the init call + fails and the once-init is not marked as initialized. A later caller could attempt to + initialize it a second time. + @returns 'true' if this was the call that caused initialization, false otherwise. + */ + template bool init_once(_Inout_ INIT_ONCE& initOnce, T func) + { + BOOL pending = FALSE; + + THROW_IF_WIN32_BOOL_FALSE(::InitOnceBeginInitialize(&initOnce, 0, &pending, nullptr)); + + if (pending) + { + details::init_once_completer completion(initOnce); + func(); + completion.success(); + return true; + } + else + { + return false; + } + } +#endif // WIL_ENABLE_EXCEPTIONS +} + +// Macro for calling GetProcAddress(), with type safety for C++ clients +// using the type information from the specified function. +// The return value is automatically cast to match the function prototype of the input function. +// +// Sample usage: +// +// auto sendMail = GetProcAddressByFunctionDeclaration(hinstMAPI, MAPISendMailW); +// if (sendMail) +// { +// sendMail(0, 0, pmm, MAPI_USE_DEFAULT, 0); +// } +// Declaration +#define GetProcAddressByFunctionDeclaration(hinst, fn) reinterpret_cast(GetProcAddress(hinst, #fn)) + +#endif // __WIL_WIN32_HELPERS_INCLUDED diff --git a/libraries/wil/win32_result_macros.h b/libraries/wil/win32_result_macros.h new file mode 100644 index 0000000..664f4b9 --- /dev/null +++ b/libraries/wil/win32_result_macros.h @@ -0,0 +1,104 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_WIN32_RESULTMACROS_INCLUDED +#define __WIL_WIN32_RESULTMACROS_INCLUDED + +#include "result_macros.h" + +// Helpers for return macros +#define __WIN32_RETURN_WIN32(error, str) __WI_SUPPRESS_4127_S do { const auto __error = (error); if (FAILED_WIN32(__error)) { __R_FN(Return_Win32)(__R_INFO(str) __error); } return __error; } __WI_SUPPRESS_4127_E while ((void)0, 0) +#define __WIN32_RETURN_GLE_FAIL(str) return __R_FN(Win32_Return_GetLastError)(__R_INFO_ONLY(str)) + +FORCEINLINE long __WIN32_FROM_HRESULT(HRESULT hr) +{ + if (SUCCEEDED(hr)) + { + return ERROR_SUCCESS; + } + return HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : hr; +} + +//***************************************************************************** +// Macros for returning failures as WIN32 error codes +//***************************************************************************** + +// Always returns a known result (WIN32 error code) - always logs failures +#define WIN32_RETURN_WIN32(error) __WIN32_RETURN_WIN32(wil::verify_win32(error), #error) +#define WIN32_RETURN_LAST_ERROR() __WIN32_RETURN_GLE_FAIL(nullptr) + +// Conditionally returns failures (WIN32 error code) - always logs failures +#define WIN32_RETURN_IF_WIN32_ERROR(error) __WI_SUPPRESS_4127_S do { const auto __errorRet = wil::verify_win32(error); if (FAILED_WIN32(__errorRet)) { __WIN32_RETURN_WIN32(__errorRet, #error); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define WIN32_RETURN_WIN32_IF(error, condition) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { __WIN32_RETURN_WIN32(wil::verify_win32(error), #condition); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define WIN32_RETURN_WIN32_IF_NULL(error, ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { __WIN32_RETURN_WIN32(wil::verify_win32(error), #ptr); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define WIN32_RETURN_LAST_ERROR_IF(condition) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { __WIN32_RETURN_GLE_FAIL(#condition); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define WIN32_RETURN_LAST_ERROR_IF_NULL(ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { __WIN32_RETURN_GLE_FAIL(#ptr); }} __WI_SUPPRESS_4127_E while ((void)0, 0) + +// Conditionally returns failures (WIN32 error code) - use for failures that are expected in common use - failures are not logged - macros are only for control flow pattern +#define WIN32_RETURN_IF_WIN32_ERROR_EXPECTED(error) __WI_SUPPRESS_4127_S do { const auto __errorRet = wil::verify_win32(error); if (FAILED_WIN32(__errorRet)) { return __errorRet; }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define WIN32_RETURN_WIN32_IF_EXPECTED(error, condition) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { return wil::verify_win32(error); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define WIN32_RETURN_WIN32_IF_NULL_EXPECTED(error, ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { return wil::verify_win32(error); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define WIN32_RETURN_LAST_ERROR_IF_EXPECTED(condition) __WI_SUPPRESS_4127_S do { if (wil::verify_bool(condition)) { return wil::verify_win32(wil::details::GetLastErrorFail()); }} __WI_SUPPRESS_4127_E while ((void)0, 0) +#define WIN32_RETURN_LAST_ERROR_IF_NULL_EXPECTED(ptr) __WI_SUPPRESS_4127_S do { if ((ptr) == nullptr) { return wil::verify_win32(wil::details::GetLastErrorFail()); }} __WI_SUPPRESS_4127_E while ((void)0, 0) + + +//***************************************************************************** +// Macros to catch and convert exceptions on failure +//***************************************************************************** + +// Use these macros *within* a catch (...) block to handle exceptions +#define WIN32_RETURN_CAUGHT_EXCEPTION() return __R_FN(Win32_Return_CaughtException)(__R_INFO_ONLY(nullptr)) + +// Use these macros in place of a catch block to handle exceptions +#define WIN32_CATCH_RETURN() catch (...) { WIN32_RETURN_CAUGHT_EXCEPTION(); } + +namespace wil +{ + //***************************************************************************** + // Public Helpers that catch -- mostly only enabled when exceptions are enabled + //***************************************************************************** + + // Win32ErrorFromCaughtException is a function that is meant to be called from within a catch(...) block. Internally + // it re-throws and catches the exception to convert it to a WIN32 error code. If an exception is of an unrecognized type + // the function will fail fast. + // + // try + // { + // // Code + // } + // catch (...) + // { + // status = wil::Win32ErrorFromCaughtException(); + // } + _Always_(_Post_satisfies_(return > 0)) + __declspec(noinline) inline long Win32ErrorFromCaughtException() WI_NOEXCEPT + { + return __WIN32_FROM_HRESULT(ResultFromCaughtException()); + } + + namespace details::__R_NS_NAME + { +#ifdef WIL_ENABLE_EXCEPTIONS + __R_DIRECT_METHOD(long, Win32_Return_CaughtException)(__R_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + return __WIN32_FROM_HRESULT(wil::details::ReportFailure_CaughtException(__R_DIRECT_FN_CALL_ONLY)); + } +#endif + + __R_DIRECT_METHOD(long, Win32_Return_GetLastError)(__R_DIRECT_FN_PARAMS_ONLY) WI_NOEXCEPT + { + __R_FN_LOCALS; + return __WIN32_FROM_HRESULT(wil::details::ReportFailure_GetLastErrorHr(__R_DIRECT_FN_CALL_ONLY)); + } + } +} + +#endif // __WIL_WIN32_RESULTMACROS_INCLUDED diff --git a/libraries/wil/winrt.h b/libraries/wil/winrt.h new file mode 100644 index 0000000..6772012 --- /dev/null +++ b/libraries/wil/winrt.h @@ -0,0 +1,2332 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_WINRT_INCLUDED +#define __WIL_WINRT_INCLUDED + +#include +#include +#include +#include +#include +#include "result.h" +#include "com.h" +#include "resource.h" +#include +#include + +#ifdef __cplusplus_winrt +#include // bring in the CRT iterator for support for C++ CX code +#endif + +/// @cond +#if defined(WIL_ENABLE_EXCEPTIONS) && !defined(__WI_HAS_STD_LESS) +#ifdef __has_include +#if __has_include() +#define __WI_HAS_STD_LESS 1 +#include +#endif // Otherwise, not using STL; don't specialize std::less +#else +// Fall back to the old way of forward declaring std::less +#define __WI_HAS_STD_LESS 1 +#pragma warning(push) +#pragma warning(disable:4643) // Forward declaring '...' in namespace std is not permitted by the C++ Standard. +namespace std +{ + template + struct less; +} +#pragma warning(pop) +#endif +#endif +#if defined(WIL_ENABLE_EXCEPTIONS) && defined(__has_include) +#if __has_include() +#define __WI_HAS_STD_VECTOR 1 +#include +#endif +#endif +/// @endcond + +// This enables this code to be used in code that uses the ABI prefix or not. +// Code using the public SDK and C++ CX code has the ABI prefix, windows internal +// is built in a way that does not. +#if !defined(MIDL_NS_PREFIX) && !defined(____x_ABI_CWindows_CFoundation_CIClosable_FWD_DEFINED__) +// Internal .idl files use the namespace without the ABI prefix. Macro out ABI for that case +#pragma push_macro("ABI") +#undef ABI +#define ABI +#endif + +namespace wil +{ + // time_t is the number of 1 - second intervals since January 1, 1970. + constexpr long long SecondsToStartOf1970 = 0x2b6109100; + constexpr long long HundredNanoSecondsInSecond = 10000000LL; + + inline __time64_t DateTime_to_time_t(ABI::Windows::Foundation::DateTime dateTime) + { + // DateTime is the number of 100 - nanosecond intervals since January 1, 1601. + return (dateTime.UniversalTime / HundredNanoSecondsInSecond - SecondsToStartOf1970); + } + + inline ABI::Windows::Foundation::DateTime time_t_to_DateTime(__time64_t timeT) + { + ABI::Windows::Foundation::DateTime dateTime; + dateTime.UniversalTime = (timeT + SecondsToStartOf1970) * HundredNanoSecondsInSecond; + return dateTime; + } + +#pragma region HSTRING Helpers + /// @cond + namespace details + { + // hstring_compare is used to assist in HSTRING comparison of two potentially non-similar string types. E.g. + // comparing a raw HSTRING with WRL's HString/HStringReference/etc. The consumer can optionally inhibit the + // deduction of array sizes by providing 'true' for the 'InhibitStringArrays' template argument. This is + // generally done in scenarios where the consumer cannot guarantee that the input argument types are perfectly + // preserved from end-to-end. E.g. if a single function in the execution path captures an array as const T&, + // then it is impossible to differentiate const arrays (where we generally do want to deduce length) from + // non-const arrays (where we generally do not want to deduce length). The consumer can also optionally choose + // to perform case-insensitive comparison by providing 'true' for the 'IgnoreCase' template argument. + template + struct hstring_compare + { + // get_buffer returns the string buffer and length for the supported string types + static const wchar_t* get_buffer(HSTRING hstr, UINT32* length) WI_NOEXCEPT + { + return ::WindowsGetStringRawBuffer(hstr, length); + } + + static const wchar_t* get_buffer(const Microsoft::WRL::Wrappers::HString& hstr, UINT32* length) WI_NOEXCEPT + { + return hstr.GetRawBuffer(length); + } + + static const wchar_t* get_buffer( + const Microsoft::WRL::Wrappers::HStringReference& hstr, + UINT32* length) WI_NOEXCEPT + { + return hstr.GetRawBuffer(length); + } + + static const wchar_t* get_buffer(const unique_hstring& str, UINT32* length) WI_NOEXCEPT + { + return ::WindowsGetStringRawBuffer(str.get(), length); + } + + template + static wistd::enable_if_t get_buffer(const wchar_t* str, UINT32* length) WI_NOEXCEPT + { + str = (str != nullptr) ? str : L""; + *length = static_cast(wcslen(str)); + return str; + } + + template + static wistd::enable_if_t< + wistd::conjunction< + wistd::is_pointer, + wistd::is_same>, wchar_t>, + wistd::bool_constant + >::value, + const wchar_t*> get_buffer(StringT str, UINT32* length) WI_NOEXCEPT + { + str = (str != nullptr) ? str : L""; + *length = static_cast(wcslen(str)); + return str; + } + + template + static wistd::enable_if_t get_buffer( + const wchar_t (&str)[Size], + UINT32* length) WI_NOEXCEPT + { + *length = Size - 1; + return str; + } + + template + static wistd::enable_if_t get_buffer(wchar_t (&str)[Size], UINT32* length) WI_NOEXCEPT + { + *length = static_cast(wcslen(str)); + return str; + } + + // Overload for std::wstring, or at least things that behave like std::wstring, without adding a dependency + // on STL headers + template + static wistd::enable_if_t().c_str())>, + wistd::is_same().length())>>, + const wchar_t*> get_buffer(const StringT& str, UINT32* length) WI_NOEXCEPT + { + *length = static_cast(str.length()); + return str.c_str(); + } + + template + static auto compare(LhsT&& lhs, RhsT&& rhs) -> + decltype(get_buffer(lhs, wistd::declval()), get_buffer(rhs, wistd::declval()), int()) + { + UINT32 lhsLength; + UINT32 rhsLength; + auto lhsBuffer = get_buffer(wistd::forward(lhs), &lhsLength); + auto rhsBuffer = get_buffer(wistd::forward(rhs), &rhsLength); + + const auto result = ::CompareStringOrdinal( + lhsBuffer, + lhsLength, + rhsBuffer, + rhsLength, + IgnoreCase ? TRUE : FALSE); + WI_ASSERT(result != 0); + + return result; + } + + template + static auto equals(LhsT&& lhs, RhsT&& rhs) WI_NOEXCEPT -> + decltype(compare(wistd::forward(lhs), wistd::forward(rhs)), bool()) + { + return compare(wistd::forward(lhs), wistd::forward(rhs)) == CSTR_EQUAL; + } + + template + static auto not_equals(LhsT&& lhs, RhsT&& rhs) WI_NOEXCEPT -> + decltype(compare(wistd::forward(lhs), wistd::forward(rhs)), bool()) + { + return compare(wistd::forward(lhs), wistd::forward(rhs)) != CSTR_EQUAL; + } + + template + static auto less(LhsT&& lhs, RhsT&& rhs) WI_NOEXCEPT -> + decltype(compare(wistd::forward(lhs), wistd::forward(rhs)), bool()) + { + return compare(wistd::forward(lhs), wistd::forward(rhs)) == CSTR_LESS_THAN; + } + + template + static auto less_equals(LhsT&& lhs, RhsT&& rhs) WI_NOEXCEPT -> + decltype(compare(wistd::forward(lhs), wistd::forward(rhs)), bool()) + { + return compare(wistd::forward(lhs), wistd::forward(rhs)) != CSTR_GREATER_THAN; + } + + template + static auto greater(LhsT&& lhs, RhsT&& rhs) WI_NOEXCEPT -> + decltype(compare(wistd::forward(lhs), wistd::forward(rhs)), bool()) + { + return compare(wistd::forward(lhs), wistd::forward(rhs)) == CSTR_GREATER_THAN; + } + + template + static auto greater_equals(LhsT&& lhs, RhsT&& rhs) WI_NOEXCEPT -> + decltype(compare(wistd::forward(lhs), wistd::forward(rhs)), bool()) + { + return compare(wistd::forward(lhs), wistd::forward(rhs)) != CSTR_LESS_THAN; + } + }; + } + /// @endcond + + //! Detects if one or more embedded null is present in an HSTRING. + inline bool HasEmbeddedNull(_In_opt_ HSTRING value) + { + BOOL hasEmbeddedNull = FALSE; + (void)WindowsStringHasEmbeddedNull(value, &hasEmbeddedNull); + return hasEmbeddedNull != FALSE; + } + + /** TwoPhaseHStringConstructor help using the 2 phase constructor pattern for HSTRINGs. + ~~~ + auto stringConstructor = wil::TwoPhaseHStringConstructor::Preallocate(size); + RETURN_IF_NULL_ALLOC(stringConstructor.Get()); + + RETURN_IF_FAILED(stream->Read(stringConstructor.Get(), stringConstructor.ByteSize(), &bytesRead)); + + // Validate stream contents, sizes must match, string must be null terminated. + RETURN_IF_FAILED(stringConstructor.Validate(bytesRead)); + + wil::unique_hstring string { stringConstructor.Promote() }; + ~~~ + + See also wil::unique_hstring_buffer. + */ + struct TwoPhaseHStringConstructor + { + TwoPhaseHStringConstructor() = delete; + TwoPhaseHStringConstructor(const TwoPhaseHStringConstructor&) = delete; + void operator=(const TwoPhaseHStringConstructor&) = delete; + + TwoPhaseHStringConstructor(TwoPhaseHStringConstructor&& other) WI_NOEXCEPT + { + m_characterLength = other.m_characterLength; + other.m_characterLength = 0; + m_maker = wistd::move(other.m_maker); + } + + static TwoPhaseHStringConstructor Preallocate(UINT32 characterLength) + { + return TwoPhaseHStringConstructor{ characterLength }; + } + + //! Returns the HSTRING after it has been populated like Detatch() or release(); be sure to put this in a RAII type to manage its lifetime. + HSTRING Promote() + { + m_characterLength = 0; + return m_maker.release().release(); + } + + ~TwoPhaseHStringConstructor() = default; + + WI_NODISCARD explicit operator PCWSTR() const + { + // This is set by WindowsPromoteStringBuffer() which must be called to + // construct this object via the static method Preallocate(). + return m_maker.buffer(); + } + + //! Returns a pointer for the buffer so it can be populated + WI_NODISCARD wchar_t* Get() const { return const_cast(m_maker.buffer()); } + //! Used to validate range of buffer when populating. + WI_NODISCARD ULONG ByteSize() const { return m_characterLength * sizeof(wchar_t); } + + /** Ensure that the size of the data provided is consistent with the pre-allocated buffer. + It seems that WindowsPreallocateStringBuffer() provides the null terminator in the buffer + (based on testing) so this can be called before populating the buffer. + */ + WI_NODISCARD HRESULT Validate(ULONG bytesRead) const + { + // Null termination is required for the buffer before calling WindowsPromoteStringBuffer(). + RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), + (bytesRead != ByteSize()) || + (Get()[m_characterLength] != L'\0')); + return S_OK; + } + + private: + TwoPhaseHStringConstructor(UINT32 characterLength) : m_characterLength(characterLength) + { + (void)m_maker.make(nullptr, characterLength); + } + + UINT32 m_characterLength; + details::string_maker m_maker; + }; + + //! A transparent less-than comparison function object that enables comparison of various string types intended for + //! use with associative containers (such as `std::set`, `std::map`, etc.) that use + //! `Microsoft::WRL::Wrappers::HString` as the key type. This removes the need for the consumer to explicitly + //! create an `HString` object when using lookup functions such as `find`, `lower_bound`, etc. For example, the + //! following scenarios would all work exactly as you would expect them to: + //! ~~~ + //! std::map map; + //! const wchar_t constArray[] = L"foo"; + //! wchar_t nonConstArray[MAX_PATH] = L"foo"; + //! + //! HString key; + //! THROW_IF_FAILED(key.Set(constArray)); + //! map.emplace(std::move(key), 42); + //! + //! HString str; + //! wil::unique_hstring uniqueStr; + //! THROW_IF_FAILED(str.Set(L"foo")); + //! THROW_IF_FAILED(str.CopyTo(&uniqueStr)); + //! + //! // All of the following return an iterator to the pair { L"foo", 42 } + //! map.find(str); + //! map.find(str.Get()); + //! map.find(HStringReference(constArray)); + //! map.find(uniqueStr); + //! map.find(std::wstring(constArray)); + //! map.find(constArray); + //! map.find(nonConstArray); + //! map.find(static_cast(constArray)); + //! ~~~ + //! The first four calls in the example above use `WindowsGetStringRawBuffer` (or equivalent) to get the string + //! buffer and length for the comparison. The fifth example uses `std::wstring::c_str` and `std::wstring::length` + //! for getting these two values. The remaining three examples use only the string buffer and call `wcslen` for the + //! length. That is, the length is *not* deduced for either array. This is because argument types are not always + //! perfectly preserved by container functions and in fact are often captured as const references making it + //! impossible to differentiate const arrays - where we can safely deduce length - from non const arrays - where we + //! cannot safely deduce length since the buffer may be larger than actually needed (e.g. creating a + //! `char[MAX_PATH]` array, but only filling it with 10 characters). The implications of this behavior is that + //! string literals that contain embedded null characters will only include the part of the buffer up to the first + //! null character. For example, the following example will result in all calls to `find` returning an end + //! iterator. + //! ~~~ + //! std::map map; + //! const wchar_t constArray[] = L"foo\0bar"; + //! wchar_t nonConstArray[MAX_PATH] = L"foo\0bar"; + //! + //! // Create the key with the embedded null character + //! HString key; + //! THROW_IF_FAILED(key.Set(constArray)); + //! map.emplace(std::move(key), 42); + //! + //! // All of the following return map.end() since they look for the string "foo" + //! map.find(constArray); + //! map.find(nonConstArray); + //! map.find(static_cast(constArray)); + //! ~~~ + //! In order to search using a string literal that contains embedded null characters, a simple alternative is to + //! first create an `HStringReference` and use that for the function call: + //! ~~~ + //! // HStringReference's constructor *will* deduce the length of const arrays + //! map.find(HStringReference(constArray)); + //! ~~~ + struct hstring_less + { + using is_transparent = void; + + template + WI_NODISCARD auto operator()(const LhsT& lhs, const RhsT& rhs) const WI_NOEXCEPT -> + decltype(details::hstring_compare::less(lhs, rhs)) + { + return details::hstring_compare::less(lhs, rhs); + } + }; + + //! A transparent less-than comparison function object whose behavior is equivalent to that of @ref hstring_less + //! with the one difference that comparisons are case-insensitive. That is, the following example will correctly + //! find the inserted value: + //! ~~~ + //! std::map map; + //! + //! HString key; + //! THROW_IF_FAILED(key.Set(L"foo")); + //! map.emplace(std::move(key), 42); + //! + //! // All of the following return an iterator to the pair { L"foo", 42 } + //! map.find(L"FOo"); + //! map.find(HStringReference(L"fOo")); + //! map.find(HStringReference(L"fOO").Get()); + //! ~~~ + struct hstring_insensitive_less + { + using is_transparent = void; + + template + WI_NODISCARD auto operator()(const LhsT& lhs, const RhsT& rhs) const WI_NOEXCEPT -> + decltype(details::hstring_compare::less(lhs, rhs)) + { + return details::hstring_compare::less(lhs, rhs); + } + }; + +#pragma endregion + + /// @cond + namespace details + { + // MapToSmartType::type is used to map a raw type into an RAII expression + // of it. This is needed when lifetime management of the type is needed, for example + // when holding them as a value produced in an iterator. + // This type has a common set of methods used to abstract the access to the value + // that is similar to ComPtr<> and the WRL Wrappers: Get(), GetAddressOf() and other operators. + // Clients of the smart type must use those to access the value. + + // TODO: Having the base definition defined will result in creating leaks if a type + // that needs resource management (e.g. PROPVARIANT) that has not specialized is used. + // + // One fix is to use std::is_enum to cover that case and leave the base definition undefined. + // That base should use static_assert to inform clients how to fix the lack of specialization. + template struct MapToSmartType + { + #pragma warning(push) + #pragma warning(disable:4702) // https://github.com/Microsoft/wil/issues/2 + struct type // T holder + { + type() = default; + type(T&& value) : m_value(wistd::forward(value)) {} + WI_NODISCARD operator T() const { return m_value; } + type& operator=(T&& value) { m_value = wistd::forward(value); return *this; } + WI_NODISCARD T Get() const { return m_value; } + + // Returning T&& to support move only types + // In case of absence of T::operator=(T&&) a call to T::operator=(const T&) will happen + T&& Get() { return wistd::move(m_value); } + + WI_NODISCARD HRESULT CopyTo(T* result) const { *result = m_value; return S_OK; } + T* GetAddressOf() { return &m_value; } + T* ReleaseAndGetAddressOf() { return &m_value; } + T* operator&() { return &m_value; } + T m_value{}; + }; + #pragma warning(pop) + }; + + // IUnknown * derived -> Microsoft::WRL::ComPtr<> + template + struct MapToSmartType::type>::value>::type> + { + typedef Microsoft::WRL::ComPtr::type> type; + }; + + // HSTRING -> Microsoft::WRL::Wrappers::HString + template <> struct MapToSmartType + { + class HStringWithRelease : public Microsoft::WRL::Wrappers::HString + { + public: + // Unlike all other WRL types HString does not have ReleaseAndGetAddressOf and + // GetAddressOf() has non-standard behavior, calling Release(). + HSTRING* ReleaseAndGetAddressOf() WI_NOEXCEPT + { + Release(); + return &hstr_; + } + }; + typedef HStringWithRelease type; + }; + + // WinRT interfaces like IVector<>, IAsyncOperation<> and IIterable<> can be templated + // on a runtime class (instead of an interface or primitive type). In these cases the objects + // produced by those interfaces implement an interface defined by the runtime class default interface. + // + // These templates deduce the type of the produced interface or pass through + // the type unmodified in the non runtime class case. + // + // for example: + // IAsyncOperation -> IAsyncOperation + + // For IVector, IVectorView. + template struct MapVectorResultType + { + template + static TResult PeekGetAtType(HRESULT(STDMETHODCALLTYPE TVector::*)(unsigned, TResult*)); + typedef decltype(PeekGetAtType(&VectorType::GetAt)) type; + }; + + // For IIterator. + template struct MapIteratorResultType + { + template + static TResult PeekCurrentType(HRESULT(STDMETHODCALLTYPE TIterable::*)(TResult*)); + typedef decltype(PeekCurrentType(&ABI::Windows::Foundation::Collections::IIterator::get_Current)) type; + }; + + // For IAsyncOperation. + template struct MapAsyncOpResultType + { + template + static TResult PeekGetResultsType(HRESULT(STDMETHODCALLTYPE TAsyncOperation::*)(TResult*)); + typedef decltype(PeekGetResultsType(&ABI::Windows::Foundation::IAsyncOperation::GetResults)) type; + }; + + // For IAsyncOperationWithProgress. + template struct MapAsyncOpProgressResultType + { + template + static TResult PeekGetResultsType(HRESULT(STDMETHODCALLTYPE TAsyncOperation::*)(TResult*)); + typedef decltype(PeekGetResultsType(&ABI::Windows::Foundation::IAsyncOperationWithProgress::GetResults)) type; + }; + + // No support for IAsyncActionWithProgress

none of these (currently) use + // a runtime class for the progress type. + } + /// @endcond +#pragma region C++ iterators for WinRT collections for use with range based for and STL algorithms + + /** Range base for and STL algorithms support for WinRT ABI collection types, IVector, IVectorView, IIterable + similar to support provided by for C++ CX. Three error handling policies are supported. + ~~~ + ComPtr collection = GetCollection(); // can be IVector, IVectorView or IIterable + + for (auto const& element : wil::get_range(collection.Get())) // exceptions + for (auto const& element : wil::get_range_nothrow(collection.Get(), &hr)) // error code + for (auto const& element : wil::get_range_failfast(collection.Get())) // fail fast + { + // use element + } + ~~~ + Standard algorithm example: + ~~~ + ComPtr> files = GetFiles(); + auto fileRange = wil::get_range_nothrow(files.Get()); + auto itFound = std::find_if(fileRange.begin(), fileRange.end(), [](ComPtr file) -> bool + { + return true; // first element in range + }); + ~~~ + */ +#pragma region exception and fail fast based IVector<>/IVectorView<> + + template + class vector_range + { + public: + typedef typename details::MapVectorResultType::type TResult; + typedef typename details::MapToSmartType::type TSmart; + + vector_range() = delete; + + explicit vector_range(_In_ VectorType *vector) : m_v(vector) + { + } + + class vector_iterator + { + public: +#ifdef _XUTILITY_ + // could be random_access_iterator_tag but missing some features + typedef ::std::bidirectional_iterator_tag iterator_category; +#endif + typedef TSmart value_type; + typedef ptrdiff_t difference_type; + typedef const TSmart* pointer; + typedef const TSmart& reference; + + // for begin() + vector_iterator(VectorType* v, unsigned int pos) + : m_v(v), m_i(pos) + { + } + + // for end() + vector_iterator() : m_v(nullptr), m_i(-1) {} + + vector_iterator(const vector_iterator& other) + { + m_v = other.m_v; + m_i = other.m_i; + err_policy::HResult(other.m_element.CopyTo(m_element.GetAddressOf())); + } + + vector_iterator& operator=(const vector_iterator& other) + { + if (this != wistd::addressof(other)) + { + m_v = other.m_v; + m_i = other.m_i; + err_policy::HResult(other.m_element.CopyTo(m_element.ReleaseAndGetAddressOf())); + } + return *this; + } + + reference operator*() + { + err_policy::HResult(m_v->GetAt(m_i, m_element.ReleaseAndGetAddressOf())); + return m_element; + } + + pointer operator->() + { + err_policy::HResult(m_v->GetAt(m_i, m_element.ReleaseAndGetAddressOf())); + return wistd::addressof(m_element); + } + + vector_iterator& operator++() + { + ++m_i; + return *this; + } + + vector_iterator& operator--() + { + --m_i; + return *this; + } + + vector_iterator operator++(int) + { + vector_iterator old(*this); + ++*this; + return old; + } + + vector_iterator operator--(int) + { + vector_iterator old(*this); + --*this; + return old; + } + + vector_iterator& operator+=(int n) + { + m_i += n; + return *this; + } + + vector_iterator& operator-=(int n) + { + m_i -= n; + return *this; + } + + WI_NODISCARD vector_iterator operator+(int n) const + { + vector_iterator ret(*this); + ret += n; + return ret; + } + + WI_NODISCARD vector_iterator operator-(int n) const + { + vector_iterator ret(*this); + ret -= n; + return ret; + } + + WI_NODISCARD ptrdiff_t operator-(const vector_iterator& other) const + { + return m_i - other.m_i; + } + + WI_NODISCARD bool operator==(const vector_iterator& other) const + { + return m_i == other.m_i; + } + + WI_NODISCARD bool operator!=(const vector_iterator& other) const + { + return m_i != other.m_i; + } + + WI_NODISCARD bool operator<(const vector_iterator& other) const + { + return m_i < other.m_i; + } + + WI_NODISCARD bool operator>(const vector_iterator& other) const + { + return m_i > other.m_i; + } + + WI_NODISCARD bool operator<=(const vector_iterator& other) const + { + return m_i <= other.m_i; + } + + WI_NODISCARD bool operator>=(const vector_iterator& other) const + { + return m_i >= other.m_i; + } + + private: + VectorType* m_v; // weak, collection must outlive iterators. + unsigned int m_i; + TSmart m_element; + }; + + vector_iterator begin() + { + return vector_iterator(m_v, 0); + } + + vector_iterator end() + { + unsigned int size; + err_policy::HResult(m_v->get_Size(&size)); + return vector_iterator(m_v, size); + } + private: + VectorType* m_v; // weak, collection must outlive iterators. + }; +#pragma endregion + +#pragma region error code based IVector<>/IVectorView<> + + template + class vector_range_nothrow + { + public: + typedef typename details::MapVectorResultType::type TResult; + typedef typename details::MapToSmartType::type TSmart; + + vector_range_nothrow() = delete; + vector_range_nothrow(const vector_range_nothrow&) = delete; + vector_range_nothrow& operator=(const vector_range_nothrow&) = delete; + + vector_range_nothrow(vector_range_nothrow&& other) WI_NOEXCEPT : + m_v(other.m_v), m_size(other.m_size), m_result(other.m_result), m_resultStorage(other.m_resultStorage), + m_currentElement(wistd::move(other.m_currentElement)) + { + } + + vector_range_nothrow(_In_ VectorType *vector, HRESULT* result = nullptr) + : m_v(vector), m_result(result ? result : &m_resultStorage) + { + *m_result = m_v->get_Size(&m_size); + } + + class vector_iterator_nothrow + { + public: +#ifdef _XUTILITY_ + // must be input_iterator_tag as use (via ++, --, etc.) of one invalidates the other. + typedef ::std::input_iterator_tag iterator_category; +#endif + typedef TSmart value_type; + typedef ptrdiff_t difference_type; + typedef const TSmart* pointer; + typedef const TSmart& reference; + + vector_iterator_nothrow() = delete; + vector_iterator_nothrow(vector_range_nothrow* range, unsigned int pos) + : m_range(range), m_i(pos) + { + } + + WI_NODISCARD reference operator*() const + { + return m_range->m_currentElement; + } + + WI_NODISCARD pointer operator->() const + { + return wistd::addressof(m_range->m_currentElement); + } + + vector_iterator_nothrow& operator++() + { + ++m_i; + m_range->get_at_current(m_i); + return *this; + } + + vector_iterator_nothrow& operator--() + { + --m_i; + m_range->get_at_current(m_i); + return *this; + } + + vector_iterator_nothrow operator++(int) + { + vector_iterator_nothrow old(*this); + ++*this; + return old; + } + + vector_iterator_nothrow operator--(int) + { + vector_iterator_nothrow old(*this); + --*this; + return old; + } + + vector_iterator_nothrow& operator+=(int n) + { + m_i += n; + m_range->get_at_current(m_i); + return *this; + } + + vector_iterator_nothrow& operator-=(int n) + { + m_i -= n; + m_range->get_at_current(m_i); + return *this; + } + + WI_NODISCARD bool operator==(vector_iterator_nothrow const& other) const + { + return FAILED(*m_range->m_result) || (m_i == other.m_i); + } + + WI_NODISCARD bool operator!=(vector_iterator_nothrow const& other) const + { + return !operator==(other); + } + + private: + vector_range_nothrow* m_range; + unsigned int m_i = 0; + }; + + vector_iterator_nothrow begin() + { + get_at_current(0); + return vector_iterator_nothrow(this, 0); + } + + vector_iterator_nothrow end() + { + return vector_iterator_nothrow(this, m_size); + } + + // Note, the error code is observed in operator!= and operator==, it always + // returns "equal" in the failed state to force the compare to the end + // iterator to return false and stop the loop. + // + // Is this ok for the general case? + void get_at_current(unsigned int i) + { + if (SUCCEEDED(*m_result) && (i < m_size)) + { + *m_result = m_v->GetAt(i, m_currentElement.ReleaseAndGetAddressOf()); + } + } + + private: + VectorType* m_v; // weak, collection must outlive iterators. + unsigned int m_size; + + // This state is shared by vector_iterator_nothrow instances. this means + // use of one iterator invalidates the other. + HRESULT* m_result; + HRESULT m_resultStorage = S_OK; // for the case where the caller does not provide the location to store the result + TSmart m_currentElement; + }; + +#pragma endregion + +#pragma region exception and fail fast based IIterable<> + + template + class iterable_range + { + public: + typedef typename details::MapIteratorResultType::type TResult; + typedef typename details::MapToSmartType::type TSmart; + + explicit iterable_range(_In_ ABI::Windows::Foundation::Collections::IIterable* iterable) + : m_iterable(iterable) + { + } + + class iterable_iterator + { + public: +#ifdef _XUTILITY_ + typedef ::std::forward_iterator_tag iterator_category; +#endif + typedef TSmart value_type; + typedef ptrdiff_t difference_type; + typedef const TSmart* pointer; + typedef const TSmart& reference; + + iterable_iterator() : m_i(-1) {} + + // for begin() + explicit iterable_iterator(_In_ ABI::Windows::Foundation::Collections::IIterable* iterable) + { + err_policy::HResult(iterable->First(&m_iterator)); + boolean hasCurrent; + err_policy::HResult(m_iterator->get_HasCurrent(&hasCurrent)); + m_i = hasCurrent ? 0 : -1; + } + + // for end() + iterable_iterator(int /*currentIndex*/) : m_i(-1) + { + } + + iterable_iterator(const iterable_iterator& other) + { + m_iterator = other.m_iterator; + m_i = other.m_i; + err_policy::HResult(other.m_element.CopyTo(m_element.GetAddressOf())); + } + + iterable_iterator& operator=(const iterable_iterator& other) + { + m_iterator = other.m_iterator; + m_i = other.m_i; + err_policy::HResult(other.m_element.CopyTo(m_element.ReleaseAndGetAddressOf())); + return *this; + } + + WI_NODISCARD bool operator==(iterable_iterator const& other) const + { + return m_i == other.m_i; + } + + WI_NODISCARD bool operator!=(iterable_iterator const& other) const + { + return !operator==(other); + } + + reference operator*() + { + err_policy::HResult(m_iterator->get_Current(m_element.ReleaseAndGetAddressOf())); + return m_element; + } + + pointer operator->() + { + err_policy::HResult(m_iterator->get_Current(m_element.ReleaseAndGetAddressOf())); + return wistd::addressof(m_element); + } + + iterable_iterator& operator++() + { + boolean hasCurrent; + err_policy::HResult(m_iterator->MoveNext(&hasCurrent)); + if (hasCurrent) + { + m_i++; + } + else + { + m_i = -1; + } + return *this; + } + + iterable_iterator operator++(int) + { + iterable_iterator old(*this); + ++*this; + return old; + } + + private: + Microsoft::WRL::ComPtr> m_iterator; + int m_i; + TSmart m_element; + }; + + iterable_iterator begin() + { + return iterable_iterator(m_iterable); + } + + iterable_iterator end() + { + return iterable_iterator(); + } + private: + // weak, collection must outlive iterators. + ABI::Windows::Foundation::Collections::IIterable* m_iterable; + }; +#pragma endregion + +#if defined(__WI_HAS_STD_VECTOR) + /** Converts WinRT vectors to std::vector by requesting the collection's data in a single + operation. This can be more efficient in terms of IPC cost than iteratively processing it. + ~~~ + ComPtr> values = GetValues(); + std::vector> allData = wil::to_vector(values); + for (ComPtr const& item : allData) + { + // use item + } + Can be used for ABI::Windows::Foundation::Collections::IVector and + ABI::Windows::Foundation::Collections::IVectorView + */ + template auto to_vector(VectorType* src) + { + using TResult = typename details::MapVectorResultType::type; + using TSmart = typename details::MapToSmartType::type; + static_assert(sizeof(TResult) == sizeof(TSmart), "result and smart sizes are different"); + std::vector output; + UINT32 expected = 0; + THROW_IF_FAILED(src->get_Size(&expected)); + if (expected > 0) + { + output.resize(expected + 1); + UINT32 fetched = 0; + THROW_IF_FAILED(src->GetMany(0, static_cast(output.size()), reinterpret_cast(output.data()), &fetched)); + THROW_HR_IF(E_CHANGED_STATE, fetched > expected); + output.resize(fetched); + } + return output; + } +#endif + +#pragma region error code base IIterable<> + template + class iterable_range_nothrow + { + public: + typedef typename details::MapIteratorResultType::type TResult; + typedef typename details::MapToSmartType::type TSmart; + + iterable_range_nothrow() = delete; + iterable_range_nothrow(const iterable_range_nothrow&) = delete; + iterable_range_nothrow& operator=(const iterable_range_nothrow&) = delete; + iterable_range_nothrow& operator=(iterable_range_nothrow &&) = delete; + + iterable_range_nothrow(iterable_range_nothrow&& other) WI_NOEXCEPT : + m_iterator(wistd::move(other.m_iterator)), m_element(wistd::move(other.m_element)), + m_resultStorage(other.m_resultStorage) + { + if (other.m_result == &other.m_resultStorage) + { + m_result = &m_resultStorage; + } + else + { + m_result = other.m_result; + } + } + + iterable_range_nothrow(_In_ ABI::Windows::Foundation::Collections::IIterable* iterable, HRESULT* result = nullptr) + : m_result(result ? result : &m_resultStorage) + { + *m_result = iterable->First(&m_iterator); + if (SUCCEEDED(*m_result)) + { + boolean hasCurrent; + *m_result = m_iterator->get_HasCurrent(&hasCurrent); + if (SUCCEEDED(*m_result) && hasCurrent) + { + *m_result = m_iterator->get_Current(m_element.ReleaseAndGetAddressOf()); + if (FAILED(*m_result)) + { + m_iterator = nullptr; // release the iterator if no elements are found + } + } + else + { + m_iterator = nullptr; // release the iterator if no elements are found + } + } + } + + class iterable_iterator_nothrow + { + public: +#ifdef _XUTILITY_ + // muse be input_iterator_tag as use of one instance invalidates the other. + typedef ::std::input_iterator_tag iterator_category; +#endif + typedef TSmart value_type; + typedef ptrdiff_t difference_type; + typedef const TSmart* pointer; + typedef const TSmart& reference; + + iterable_iterator_nothrow(_In_ iterable_range_nothrow* range, int currentIndex) : + m_range(range), m_i(currentIndex) + { + } + + WI_NODISCARD bool operator==(iterable_iterator_nothrow const& other) const + { + return FAILED(*m_range->m_result) || (m_i == other.m_i); + } + + WI_NODISCARD bool operator!=(iterable_iterator_nothrow const& other) const + { + return !operator==(other); + } + + WI_NODISCARD reference operator*() const WI_NOEXCEPT + { + return m_range->m_element; + } + + WI_NODISCARD pointer operator->() const WI_NOEXCEPT + { + return wistd::addressof(m_range->m_element); + } + + iterable_iterator_nothrow& operator++() + { + boolean hasCurrent; + *m_range->m_result = m_range->m_iterator->MoveNext(&hasCurrent); + if (SUCCEEDED(*m_range->m_result) && hasCurrent) + { + *m_range->m_result = m_range->m_iterator->get_Current(m_range->m_element.ReleaseAndGetAddressOf()); + if (SUCCEEDED(*m_range->m_result)) + { + m_i++; + } + else + { + m_i = -1; + } + } + else + { + m_i = -1; + } + return *this; + } + + iterable_range_nothrow operator++(int) + { + iterable_range_nothrow old(*this); + ++*this; + return old; + } + + private: + iterable_range_nothrow* m_range; + int m_i; + }; + + iterable_iterator_nothrow begin() + { + return iterable_iterator_nothrow(this, this->m_iterator ? 0 : -1); + } + + iterable_iterator_nothrow end() + { + return iterable_iterator_nothrow(this, -1); + } + + private: + Microsoft::WRL::ComPtr> m_iterator; + // This state is shared by all iterator instances + // so use of one iterator can invalidate another's ability to dereference + // that is allowed for input iterators. + TSmart m_element; + HRESULT* m_result; + HRESULT m_resultStorage = S_OK; + }; + +#pragma endregion + +#ifdef WIL_ENABLE_EXCEPTIONS + template vector_range> get_range(ABI::Windows::Foundation::Collections::IVector *v) + { + return vector_range>(v); + } + + template vector_range> get_range(ABI::Windows::Foundation::Collections::IVectorView *v) + { + return vector_range>(v); + } +#endif // WIL_ENABLE_EXCEPTIONS + + template vector_range, err_failfast_policy> get_range_failfast(ABI::Windows::Foundation::Collections::IVector *v) + { + return vector_range, err_failfast_policy>(v); + } + + template vector_range, err_failfast_policy> get_range_failfast(ABI::Windows::Foundation::Collections::IVectorView *v) + { + return vector_range, err_failfast_policy>(v); + } + + template vector_range_nothrow> get_range_nothrow(ABI::Windows::Foundation::Collections::IVector *v, HRESULT* result = nullptr) + { + return vector_range_nothrow>(v, result); + } + + template vector_range_nothrow> get_range_nothrow(ABI::Windows::Foundation::Collections::IVectorView *v, HRESULT* result = nullptr) + { + return vector_range_nothrow>(v, result); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + template iterable_range get_range(ABI::Windows::Foundation::Collections::IIterable *v) + { + return iterable_range(v); + } +#endif // WIL_ENABLE_EXCEPTIONS + + template iterable_range get_range_failfast(ABI::Windows::Foundation::Collections::IIterable *v) + { + return iterable_range(v); + } + + template iterable_range_nothrow get_range_nothrow(ABI::Windows::Foundation::Collections::IIterable *v, HRESULT* result = nullptr) + { + return iterable_range_nothrow(v, result); + } +} + +#pragma endregion + +#ifdef WIL_ENABLE_EXCEPTIONS + +#pragma region Global operator functions +#if defined(MIDL_NS_PREFIX) || defined(____x_ABI_CWindows_CFoundation_CIClosable_FWD_DEFINED__) +namespace ABI { +#endif + namespace Windows { + namespace Foundation { + namespace Collections { + template typename wil::vector_range>::vector_iterator begin(IVector* v) + { + return typename wil::vector_range>::vector_iterator(v, 0); + } + + template typename wil::vector_range>::vector_iterator end(IVector* v) + { + unsigned int size; + THROW_IF_FAILED(v->get_Size(&size)); + return typename wil::vector_range>::vector_iterator(v, size); + } + + template typename wil::vector_range>::vector_iterator begin(IVectorView* v) + { + return typename wil::vector_range>::vector_iterator(v, 0); + } + + template typename wil::vector_range>::vector_iterator end(IVectorView* v) + { + unsigned int size; + THROW_IF_FAILED(v->get_Size(&size)); + return typename wil::vector_range>::vector_iterator(v, size); + } + + template typename wil::iterable_range::iterable_iterator begin(IIterable* i) + { + return typename wil::iterable_range::iterable_iterator(i); + } + + template typename wil::iterable_range::iterable_iterator end(IIterable*) + { + return typename wil::iterable_range::iterable_iterator(); + } + } // namespace Collections + } // namespace Foundation + } // namespace Windows +#if defined(MIDL_NS_PREFIX) || defined(____x_ABI_CWindows_CFoundation_CIClosable_FWD_DEFINED__) +} // namespace ABI +#endif + +#endif // WIL_ENABLE_EXCEPTIONS + +#pragma endregion + +namespace wil +{ +#pragma region WinRT Async API helpers + +/// @cond +namespace details +{ + template ::value, int>::type = 0> + HRESULT CallAndHandleErrorsWithReturnType(TFunc&& func, Args&&... args) + { + return wistd::forward(func)(wistd::forward(args)...); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + template ::value, int>::type = 0> + HRESULT CallAndHandleErrorsWithReturnType(TFunc&& func, Args&&... args) + { + try + { + wistd::forward(func)(wistd::forward(args)...); + } + CATCH_RETURN(); + return S_OK; + } +#endif + + template + HRESULT CallAndHandleErrors(TFunc&& func, Args&&... args) + { + return CallAndHandleErrorsWithReturnType(func)(wistd::forward(args)...))>( + wistd::forward(func), wistd::forward(args)...); + } + + // Get the last type of a template parameter pack. + // usage: + // LastType::type boolValue; + template struct LastType + { + template struct LastTypeOfTs + { + typedef typename LastTypeOfTs::type type; + }; + + template struct LastTypeOfTs + { + typedef T type; + }; + + template + static typename LastTypeOfTs::type LastTypeOfTsFunc() {} + typedef decltype(LastTypeOfTsFunc()) type; + }; + + // Takes a member function that has an out param like F(..., IAsyncAction**) or F(..., IAsyncOperation**) + // and returns IAsyncAction* or IAsyncOperation*. + template + typename wistd::remove_pointer::type>::type GetReturnParamPointerType(HRESULT(STDMETHODCALLTYPE I::*)(P...)); + + // Use to determine the result type of the async action/operation interfaces or example + // decltype(GetAsyncResultType(action.get())) returns void + void GetAsyncResultType(ABI::Windows::Foundation::IAsyncAction*); + template void GetAsyncResultType(ABI::Windows::Foundation::IAsyncActionWithProgress

*); + template typename wil::details::MapAsyncOpResultType::type GetAsyncResultType(ABI::Windows::Foundation::IAsyncOperation*); + template typename wil::details::MapAsyncOpProgressResultType::type GetAsyncResultType(ABI::Windows::Foundation::IAsyncOperationWithProgress*); + + // Use to determine the result type of the async action/operation interfaces or example + // decltype(GetAsyncDelegateType(action.get())) returns void + ABI::Windows::Foundation::IAsyncActionCompletedHandler* GetAsyncDelegateType(ABI::Windows::Foundation::IAsyncAction*); + template ABI::Windows::Foundation::IAsyncActionWithProgressCompletedHandler

* GetAsyncDelegateType(ABI::Windows::Foundation::IAsyncActionWithProgress

*); + template ABI::Windows::Foundation::IAsyncOperationCompletedHandler* GetAsyncDelegateType(ABI::Windows::Foundation::IAsyncOperation*); + template ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler* GetAsyncDelegateType(ABI::Windows::Foundation::IAsyncOperationWithProgress*); + + template + HRESULT RunWhenCompleteAction(_In_ TIOperation operation, TFunction&& func) WI_NOEXCEPT + { + using namespace Microsoft::WRL; + typedef wistd::remove_pointer_t TIDelegate; + + auto callback = Callback, TIDelegate, TBaseAgility>>( + [func = wistd::forward(func)](TIOperation operation, ABI::Windows::Foundation::AsyncStatus status) mutable -> HRESULT + { + HRESULT hr = S_OK; + if (status != ABI::Windows::Foundation::AsyncStatus::Completed) // avoid a potentially costly marshaled QI / call if we completed successfully + { + // QI to the IAsyncInfo interface. While all operations implement this, it is + // possible that the stub has disconnected, causing the QI to fail. + ComPtr asyncInfo; + hr = operation->QueryInterface(IID_PPV_ARGS(&asyncInfo)); + if (SUCCEEDED(hr)) + { + // Save the error code result in a temporary variable to allow us + // to also retrieve the result of the COM call. If the stub has + // disconnected, this call may fail. + HRESULT errorCode = E_UNEXPECTED; + hr = asyncInfo->get_ErrorCode(&errorCode); + if (SUCCEEDED(hr)) + { + // Return the operations error code to the caller. + hr = errorCode; + } + } + } + + return CallAndHandleErrors(func, hr); + }); + RETURN_IF_NULL_ALLOC(callback); + return operation->put_Completed(callback.Get()); + } + + template + HRESULT RunWhenComplete(_In_ TIOperation operation, TFunction&& func) WI_NOEXCEPT + { + using namespace Microsoft::WRL; + using namespace ABI::Windows::Foundation::Internal; + + typedef wistd::remove_pointer_t TIDelegate; + + auto callback = Callback, TIDelegate, TBaseAgility>>( + [func = wistd::forward(func)](TIOperation operation, ABI::Windows::Foundation::AsyncStatus status) mutable -> HRESULT + { + typename details::MapToSmartType::type::TResult_complex>::type>::type result; + + HRESULT hr = S_OK; + // avoid a potentially costly marshaled QI / call if we completed successfully + if (status == ABI::Windows::Foundation::AsyncStatus::Completed) + { + hr = operation->GetResults(result.GetAddressOf()); + } + else + { + // QI to the IAsyncInfo interface. While all operations implement this, it is + // possible that the stub has disconnected, causing the QI to fail. + ComPtr asyncInfo; + hr = operation->QueryInterface(IID_PPV_ARGS(&asyncInfo)); + if (SUCCEEDED(hr)) + { + // Save the error code result in a temporary variable to allow us + // to also retrieve the result of the COM call. If the stub has + // disconnected, this call may fail. + HRESULT errorCode = E_UNEXPECTED; + hr = asyncInfo->get_ErrorCode(&errorCode); + if (SUCCEEDED(hr)) + { + // Return the operations error code to the caller. + hr = errorCode; + } + } + } + + return CallAndHandleErrors(func, hr, result.Get()); + }); + RETURN_IF_NULL_ALLOC(callback); + return operation->put_Completed(callback.Get()); + } + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + template + HRESULT WaitForCompletion(_In_ TIOperation operation, COWAIT_FLAGS flags, DWORD timeoutValue, _Out_opt_ bool* timedOut) WI_NOEXCEPT + { + typedef wistd::remove_pointer_t TIDelegate; + + class CompletionDelegate : public Microsoft::WRL::RuntimeClass, + TIDelegate, Microsoft::WRL::FtmBase> + { + public: + HRESULT RuntimeClassInitialize() + { + RETURN_HR(m_completedEventHandle.create()); + } + + HRESULT STDMETHODCALLTYPE Invoke(_In_ TIOperation, ABI::Windows::Foundation::AsyncStatus status) override + { + m_status = status; + m_completedEventHandle.SetEvent(); + return S_OK; + } + + WI_NODISCARD HANDLE GetEvent() const + { + return m_completedEventHandle.get(); + } + + WI_NODISCARD ABI::Windows::Foundation::AsyncStatus GetStatus() const + { + return m_status; + } + + private: + volatile ABI::Windows::Foundation::AsyncStatus m_status = ABI::Windows::Foundation::AsyncStatus::Started; + wil::unique_event_nothrow m_completedEventHandle; + }; + + WI_ASSERT(timedOut || (timeoutValue == INFINITE)); + assign_to_opt_param(timedOut, false); + + Microsoft::WRL::ComPtr completedDelegate; + RETURN_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&completedDelegate)); + RETURN_IF_FAILED(operation->put_Completed(completedDelegate.Get())); + + HANDLE handles[] = { completedDelegate->GetEvent() }; + DWORD dwHandleIndex; + HRESULT hr = CoWaitForMultipleHandles(flags, timeoutValue, ARRAYSIZE(handles), handles, &dwHandleIndex); + + // If the caller is listening for timedOut, and we actually timed out, set the bool and return S_OK. Otherwise, fail. + if (timedOut && (hr == RPC_S_CALLPENDING)) + { + *timedOut = true; + return S_OK; + } + RETURN_IF_FAILED(hr); + + if (completedDelegate->GetStatus() != ABI::Windows::Foundation::AsyncStatus::Completed) + { + // QI to the IAsyncInfo interface. While all operations implement this, it is + // possible that the stub has disconnected, causing the QI to fail. + Microsoft::WRL::ComPtr asyncInfo; + hr = operation->QueryInterface(IID_PPV_ARGS(&asyncInfo)); + if (SUCCEEDED(hr)) + { + // Save the error code result in a temporary variable to allow us + // to also retrieve the result of the COM call. If the stub has + // disconnected, this call may fail. + HRESULT errorCode = E_UNEXPECTED; + hr = asyncInfo->get_ErrorCode(&errorCode); + if (SUCCEEDED(hr)) + { + // Return the operations error code to the caller. + hr = errorCode; + } + } + return hr; // leave it to the caller to log failures. + } + return S_OK; + } + + template + HRESULT WaitForCompletion(_In_ TIOperation operation, _Out_ TIResults result, COWAIT_FLAGS flags, + DWORD timeoutValue, _Out_opt_ bool* timedOut) WI_NOEXCEPT + { + RETURN_IF_FAILED_EXPECTED(details::WaitForCompletion(operation, flags, timeoutValue, timedOut)); + return operation->GetResults(result); + } +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) +} +/// @endcond + +/** Set the completion callback for an async operation to run a caller provided function. +Once complete the function is called with the error code result of the operation +and the async operation result (if applicable). +The function parameter list must be (HRESULT hr) for actions, +(HRESULT hr, IResultInterface* object) for operations that produce interfaces, +and (HRESULT hr, TResult value) for operations that produce value types. +~~~ +run_when_complete(getFileOp.Get(), [](HRESULT hr, IStorageFile* file) -> void +{ + +}); +~~~ +for an agile callback use Microsoft::WRL::FtmBase +~~~ +run_when_complete(getFileOp.Get(), [](HRESULT hr, IStorageFile* file) -> void +{ + +}); +~~~ +Using the non throwing form: +~~~ +hr = run_when_complete_nothrow(getFileOp.Get(), [](HRESULT hr, IStorageFile* file) -> HRESULT +{ + +}); +~~~ +*/ + +//! Run a fuction when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler agile and run on the async thread. +template +HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncAction* operation, TFunc&& func) WI_NOEXCEPT +{ + return details::RunWhenCompleteAction(operation, wistd::forward(func)); +} + +template::type> +HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncOperation* operation, TFunc&& func) WI_NOEXCEPT +{ + return details::RunWhenComplete(operation, wistd::forward(func)); +} + +template::type> +HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncOperationWithProgress* operation, TFunc&& func) WI_NOEXCEPT +{ + return details::RunWhenComplete(operation, wistd::forward(func)); +} + +template +HRESULT run_when_complete_nothrow(_In_ ABI::Windows::Foundation::IAsyncActionWithProgress* operation, TFunc&& func) WI_NOEXCEPT +{ + return details::RunWhenCompleteAction(operation, wistd::forward(func)); +} + +#ifdef WIL_ENABLE_EXCEPTIONS +//! Run a fuction when an async operation completes. Use Microsoft::WRL::FtmBase for TAgility to make the completion handler agile and run on the async thread. +template +void run_when_complete(_In_ ABI::Windows::Foundation::IAsyncAction* operation, TFunc&& func) +{ + THROW_IF_FAILED((details::RunWhenCompleteAction(operation, wistd::forward(func)))); +} + +template::type> +void run_when_complete(_In_ ABI::Windows::Foundation::IAsyncOperation* operation, TFunc&& func) +{ + THROW_IF_FAILED((details::RunWhenComplete(operation, wistd::forward(func)))); +} + +template::type> +void run_when_complete(_In_ ABI::Windows::Foundation::IAsyncOperationWithProgress* operation, TFunc&& func) +{ + THROW_IF_FAILED((details::RunWhenComplete(operation, wistd::forward(func)))); +} + +template +void run_when_complete(_In_ ABI::Windows::Foundation::IAsyncActionWithProgress* operation, TFunc&& func) +{ + THROW_IF_FAILED((details::RunWhenCompleteAction(operation, wistd::forward(func)))); +} +#endif + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) +/** Wait for an asynchronous operation to complete (or be canceled). +Use to synchronously wait on async operations on background threads. +Do not call from UI threads or STA threads as reentrancy will result. +~~~ +ComPtr> op; +THROW_IF_FAILED(storageFileStatics->GetFileFromPathAsync(HStringReference(path).Get(), &op)); +auto file = wil::wait_for_completion(op.Get()); +~~~ +*/ +template +inline HRESULT wait_for_completion_nothrow(_In_ TAsync* operation, COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) WI_NOEXCEPT +{ + return details::WaitForCompletion(operation, flags, INFINITE, nullptr); +} + +// These forms return the result from the async operation + +template +HRESULT wait_for_completion_nothrow(_In_ ABI::Windows::Foundation::IAsyncOperation* operation, + _Out_ typename wil::details::MapAsyncOpResultType::type* result, + COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) WI_NOEXCEPT +{ + return details::WaitForCompletion(operation, result, flags, INFINITE, nullptr); +} + +template +HRESULT wait_for_completion_nothrow(_In_ ABI::Windows::Foundation::IAsyncOperationWithProgress* operation, + _Out_ typename wil::details::MapAsyncOpProgressResultType::type* result, + COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) WI_NOEXCEPT +{ + return details::WaitForCompletion(operation, result, flags, INFINITE, nullptr); +} + +// Same as above, but allows caller to specify a timeout value. +// On timeout, S_OK is returned, with timedOut set to true. + +template +inline HRESULT wait_for_completion_or_timeout_nothrow(_In_ TAsync* operation, + DWORD timeoutValue, _Out_ bool* timedOut, COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) WI_NOEXCEPT +{ + return details::WaitForCompletion(operation, flags, timeoutValue, timedOut); +} + +template +HRESULT wait_for_completion_or_timeout_nothrow(_In_ ABI::Windows::Foundation::IAsyncOperation* operation, + _Out_ typename wil::details::MapAsyncOpResultType::type* result, + DWORD timeoutValue, _Out_ bool* timedOut, COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) WI_NOEXCEPT +{ + return details::WaitForCompletion(operation, result, flags, timeoutValue, timedOut); +} + +template +HRESULT wait_for_completion_or_timeout_nothrow(_In_ ABI::Windows::Foundation::IAsyncOperationWithProgress* operation, + _Out_ typename wil::details::MapAsyncOpProgressResultType::type* result, + DWORD timeoutValue, _Out_ bool* timedOut, COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) WI_NOEXCEPT +{ + return details::WaitForCompletion(operation, result, flags, timeoutValue, timedOut); +} + +#ifdef WIL_ENABLE_EXCEPTIONS +//! Wait for an asynchronous operation to complete (or be canceled). +template +inline void wait_for_completion(_In_ TAsync* operation, COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) +{ + THROW_IF_FAILED(details::WaitForCompletion(operation, flags, INFINITE, nullptr)); +} + +template ::type>::type> +TReturn +wait_for_completion(_In_ ABI::Windows::Foundation::IAsyncOperation* operation, COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) +{ + TReturn result; + THROW_IF_FAILED(details::WaitForCompletion(operation, result.GetAddressOf(), flags, INFINITE, nullptr)); + return result; +} + +template ::type>::type> +TReturn +wait_for_completion(_In_ ABI::Windows::Foundation::IAsyncOperationWithProgress* operation, COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) +{ + TReturn result; + THROW_IF_FAILED(details::WaitForCompletion(operation, result.GetAddressOf(), flags, INFINITE, nullptr)); + return result; +} + +/** Similar to WaitForCompletion but this function encapsulates the creation of the async operation +making usage simpler. +~~~ +ComPtr launcher; // inited somewhere +auto result = call_and_wait_for_completion(launcher.Get(), &ILauncherStatics::LaunchUriAsync, uri.Get()); +~~~ +*/ +template +auto call_and_wait_for_completion(I* object, HRESULT(STDMETHODCALLTYPE I::*func)(P...), Args&&... args) +{ + Microsoft::WRL::ComPtr::type>::type>::type> op; + THROW_IF_FAILED((object->*func)(wistd::forward(args)..., &op)); + return wil::wait_for_completion(op.Get()); +} +#endif +#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM) + +#pragma endregion + +#pragma region WinRT object construction +#ifdef WIL_ENABLE_EXCEPTIONS +//! Get a WinRT activation factory object, usually using a IXXXStatics interface. +template +com_ptr GetActivationFactory(PCWSTR runtimeClass) +{ + com_ptr result; + THROW_IF_FAILED(RoGetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(runtimeClass).Get(), IID_PPV_ARGS(&result))); + return result; +} + +//! Get a WinRT object. +template +com_ptr ActivateInstance(PCWSTR runtimeClass) +{ + com_ptr result; + THROW_IF_FAILED(RoActivateInstance(Microsoft::WRL::Wrappers::HStringReference(runtimeClass).Get(), &result)); + return result.query(); +} +#endif +#pragma endregion + +#pragma region Async production helpers + +/// @cond +namespace details +{ + template + class SyncAsyncOp WrlFinal : public Microsoft::WRL::RuntimeClass, + Microsoft::WRL::AsyncBase>> + { + // typedef typename MapToSmartType::type TSmart; + using RuntimeClassT = typename SyncAsyncOp::RuntimeClassT; + InspectableClass(__super::z_get_rc_name_impl(), TrustLevel::BaseTrust); + public: + HRESULT RuntimeClassInitialize(const TResult& op) + { + m_result = op; + return S_OK; + } + + IFACEMETHODIMP put_Completed(ABI::Windows::Foundation::IAsyncOperationCompletedHandler* competed) override + { + competed->Invoke(this, ABI::Windows::Foundation::AsyncStatus::Completed); + return S_OK; + } + + IFACEMETHODIMP get_Completed(ABI::Windows::Foundation::IAsyncOperationCompletedHandler** competed) override + { + *competed = nullptr; + return S_OK; + } + + IFACEMETHODIMP GetResults(TResult* result) override + { + *result = m_result; + return S_OK; + } + + HRESULT OnStart() override { return S_OK; } + void OnClose() override { } + void OnCancel() override { } + private: + // needs to be MapToSmartType::type to hold non trial types + TResult m_result{}; + }; + + extern const __declspec(selectany) wchar_t SyncAsyncActionName[] = L"SyncActionAction"; + + class SyncAsyncActionOp WrlFinal : public Microsoft::WRL::RuntimeClass +#endif + >> + { + InspectableClass(InterfaceName_Windows_Foundation_IAsyncAction, TrustLevel::BaseTrust); + public: + IFACEMETHODIMP put_Completed(ABI::Windows::Foundation::IAsyncActionCompletedHandler* competed) override + { + competed->Invoke(this, ABI::Windows::Foundation::AsyncStatus::Completed); + return S_OK; + } + + IFACEMETHODIMP get_Completed(ABI::Windows::Foundation::IAsyncActionCompletedHandler** competed) override + { + *competed = nullptr; + return S_OK; + } + + IFACEMETHODIMP GetResults() override + { + return S_OK; + } + + HRESULT OnStart() override { return S_OK; } + void OnClose() override { } + void OnCancel() override { } + }; +} + +/// @endcond +//! Creates a WinRT async operation object that implements IAsyncOperation. Use mostly for testing and for mocking APIs. +template +HRESULT make_synchronous_async_operation_nothrow(ABI::Windows::Foundation::IAsyncOperation** result, const TResult& value) +{ + return Microsoft::WRL::MakeAndInitialize>(result, value); +} + +//! Creates a WinRT async operation object that implements IAsyncAction. Use mostly for testing and for mocking APIs. +inline HRESULT make_synchronous_async_action_nothrow(ABI::Windows::Foundation::IAsyncAction** result) +{ + return Microsoft::WRL::MakeAndInitialize(result); +} + +#ifdef WIL_ENABLE_EXCEPTIONS +//! Creates a WinRT async operation object that implements IAsyncOperation. Use mostly for testing and for mocking APIs. +// TODO: map TRealResult and TSmartResult into SyncAsyncOp. +template ::type, typename TSmartResult = typename details::MapToSmartType::type> +void make_synchronous_async_operation(ABI::Windows::Foundation::IAsyncOperation** result, const TResult& value) +{ + THROW_IF_FAILED((Microsoft::WRL::MakeAndInitialize>(result, value))); +} + +//! Creates a WinRT async operation object that implements IAsyncAction. Use mostly for testing and for mocking APIs. +inline void make_synchronous_async_action(ABI::Windows::Foundation::IAsyncAction** result) +{ + THROW_IF_FAILED((Microsoft::WRL::MakeAndInitialize(result))); +} +#endif +#pragma endregion + +#pragma region EventRegistrationToken RAII wrapper + +// unique_winrt_event_token[_cx] is an RAII wrapper around EventRegistrationToken. When the unique_winrt_event_token[_cx] is +// destroyed, the event is automatically unregistered. Declare a wil::unique_winrt_event_token[_cx] at the scope the event +// should be registered for (often they are tied to object lifetime), where T is the type of the event sender +// wil::unique_winrt_event_token_cx m_token; +// +// Macros have been defined to register for handling the event and then returning an unique_winrt_event_token[_cx]. These +// macros simply hide the function references for adding and removing the event. +// C++/CX m_token = WI_MakeUniqueWinRtEventTokenCx(ExampleEventName, sender, handler); +// ABI m_token = WI_MakeUniqueWinRtEventToken(ExampleEventName, sender, handler, &m_token); // Exception and failfast +// ABI RETURN_IF_FAILED(WI_MakeUniqueWinRtEventTokenNoThrow(ExampleEventName, sender, handler, &m_token)); // No throw variant +// +// When the wrapper is destroyed, the handler will be unregistered. You can explicitly unregister the handler prior. +// m_token.reset(); +// +// You can release the EventRegistrationToken from being managed by the wrapper by calling .release() +// m_token.release(); // DANGER: no longer being managed +// +// If you just need the value of the EventRegistrationToken you can call .get() +// m_token.get(); +// +// See "onecore\shell\tests\wil\UniqueWinRTEventTokenTests.cpp" for more examples of usage in ABI and C++/CX. + +#ifdef __cplusplus_winrt +namespace details +{ + template struct remove_reference { typedef T type; }; + template struct remove_reference { typedef T type; }; +} + +template +class unique_winrt_event_token_cx +{ + using removal_func = void(T::*)(Windows::Foundation::EventRegistrationToken); + using static_removal_func = void(__cdecl *)(Windows::Foundation::EventRegistrationToken); + +public: + unique_winrt_event_token_cx() = default; + + unique_winrt_event_token_cx(Windows::Foundation::EventRegistrationToken token, T^ sender, removal_func removalFunction) WI_NOEXCEPT : + m_token(token), + m_weakSender(sender), + m_removalFunction(removalFunction) + {} + + unique_winrt_event_token_cx(Windows::Foundation::EventRegistrationToken token, static_removal_func removalFunction) WI_NOEXCEPT : + m_token(token), + m_staticRemovalFunction(removalFunction) + {} + + unique_winrt_event_token_cx(const unique_winrt_event_token_cx&) = delete; + unique_winrt_event_token_cx& operator=(const unique_winrt_event_token_cx&) = delete; + + unique_winrt_event_token_cx(unique_winrt_event_token_cx&& other) WI_NOEXCEPT : + m_token(other.m_token), + m_weakSender(wistd::move(other.m_weakSender)), + m_removalFunction(other.m_removalFunction), + m_staticRemovalFunction(other.m_staticRemovalFunction) + { + other.m_token = {}; + other.m_weakSender = nullptr; + other.m_removalFunction = nullptr; + other.m_staticRemovalFunction = nullptr; + } + + unique_winrt_event_token_cx& operator=(unique_winrt_event_token_cx&& other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + + wistd::swap_wil(m_token, other.m_token); + wistd::swap_wil(m_weakSender, other.m_weakSender); + wistd::swap_wil(m_removalFunction, other.m_removalFunction); + wistd::swap_wil(m_staticRemovalFunction, other.m_staticRemovalFunction); + } + + return *this; + } + + ~unique_winrt_event_token_cx() WI_NOEXCEPT + { + reset(); + } + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return (m_token.Value != 0); + } + + WI_NODISCARD Windows::Foundation::EventRegistrationToken get() const WI_NOEXCEPT + { + return m_token; + } + + void reset() noexcept + { + if (m_token.Value != 0) + { + if (m_staticRemovalFunction) + { + (*m_staticRemovalFunction)(m_token); + } + else + { + auto resolvedSender = [&]() + { + try + { + return m_weakSender.Resolve(); + } + catch (...) + { + // Ignore RPC or other failures that are unavoidable in some cases + // matching wil::unique_winrt_event_token and winrt::event_revoker + return static_cast(nullptr); + } + }(); + if (resolvedSender) + { + (resolvedSender->*m_removalFunction)(m_token); + } + } + release(); + } + } + + // Stops the wrapper from managing resource and returns the EventRegistrationToken. + Windows::Foundation::EventRegistrationToken release() WI_NOEXCEPT + { + auto token = m_token; + m_token = {}; + m_weakSender = nullptr; + m_removalFunction = nullptr; + m_staticRemovalFunction = nullptr; + return token; + } + +private: + Windows::Foundation::EventRegistrationToken m_token = {}; + Platform::WeakReference m_weakSender; + removal_func m_removalFunction = nullptr; + static_removal_func m_staticRemovalFunction = nullptr; +}; + +#endif + +template +class unique_winrt_event_token +{ + using removal_func = HRESULT(__stdcall T::*)(::EventRegistrationToken); + +public: + unique_winrt_event_token() = default; + + unique_winrt_event_token(::EventRegistrationToken token, T* sender, removal_func removalFunction) WI_NOEXCEPT : + m_token(token), + m_removalFunction(removalFunction) + { + m_weakSender = wil::com_weak_query_failfast(sender); + } + + unique_winrt_event_token(const unique_winrt_event_token&) = delete; + unique_winrt_event_token& operator=(const unique_winrt_event_token&) = delete; + + unique_winrt_event_token(unique_winrt_event_token&& other) WI_NOEXCEPT : + m_token(other.m_token), + m_weakSender(wistd::move(other.m_weakSender)), + m_removalFunction(other.m_removalFunction) + { + other.m_token = {}; + other.m_removalFunction = nullptr; + } + + unique_winrt_event_token& operator=(unique_winrt_event_token&& other) WI_NOEXCEPT + { + if (this != wistd::addressof(other)) + { + reset(); + + wistd::swap_wil(m_token, other.m_token); + wistd::swap_wil(m_weakSender, other.m_weakSender); + wistd::swap_wil(m_removalFunction, other.m_removalFunction); + } + + return *this; + } + + ~unique_winrt_event_token() WI_NOEXCEPT + { + reset(); + } + + WI_NODISCARD explicit operator bool() const WI_NOEXCEPT + { + return (m_token.value != 0); + } + + WI_NODISCARD ::EventRegistrationToken get() const WI_NOEXCEPT + { + return m_token; + } + + void reset() WI_NOEXCEPT + { + if (m_token.value != 0) + { + // If T cannot be QI'ed from the weak object then T is not a COM interface. + auto resolvedSender = m_weakSender.try_query(); + if (resolvedSender) + { + FAIL_FAST_IF_FAILED((resolvedSender.get()->*m_removalFunction)(m_token)); + } + release(); + } + } + + // Stops the wrapper from managing resource and returns the EventRegistrationToken. + ::EventRegistrationToken release() WI_NOEXCEPT + { + auto token = m_token; + m_token = {}; + m_weakSender = nullptr; + m_removalFunction = nullptr; + return token; + } + +private: + ::EventRegistrationToken m_token = {}; + wil::com_weak_ref_failfast m_weakSender; + removal_func m_removalFunction = nullptr; +}; + +namespace details +{ +#ifdef __cplusplus_winrt + + // Handles registration of the event handler to the subscribing object and then wraps the EventRegistrationToken in unique_winrt_event_token. + // Not intended to be directly called. Use the WI_MakeUniqueWinRtEventTokenCx macro to abstract away specifying the functions that handle addition and removal. + template + inline wil::unique_winrt_event_token_cx make_unique_winrt_event_token_cx(T^ sender, addition_func additionFunc, removal_func removalFunc, handler^ h) + { + auto rawToken = (sender->*additionFunc)(h); + wil::unique_winrt_event_token_cx temp(rawToken, sender, removalFunc); + return temp; + } + + template + inline wil::unique_winrt_event_token_cx make_unique_winrt_static_event_token_cx(addition_func additionFunc, removal_func removalFunc, handler^ h) + { + auto rawToken = (*additionFunc)(h); + wil::unique_winrt_event_token_cx temp(rawToken, removalFunc); + return temp; + } + +#endif // __cplusplus_winrt + + // Handles registration of the event handler to the subscribing object and then wraps the EventRegistrationToken in unique_winrt_event_token. + // Not intended to be directly called. Use the WI_MakeUniqueWinRtEventToken macro to abstract away specifying the functions that handle addition and removal. + template + inline auto make_unique_winrt_event_token(T* sender, addition_func additionFunc, removal_func removalFunc, handler h, wil::unique_winrt_event_token* token_reference) + { + ::EventRegistrationToken rawToken; + err_policy::HResult((sender->*additionFunc)(h, &rawToken)); + *token_reference = wil::unique_winrt_event_token(rawToken, sender, removalFunc); + return err_policy::OK(); + } + + // Overload make function to allow for returning the constructed object when not using HRESULT based code. + template + inline typename wistd::enable_if::value, wil::unique_winrt_event_token>::type + make_unique_winrt_event_token(T* sender, addition_func additionFunc, removal_func removalFunc, handler h) + { + ::EventRegistrationToken rawToken; + err_policy::HResult((sender->*additionFunc)(h, &rawToken)); + return wil::unique_winrt_event_token(rawToken, sender, removalFunc); + } + +} // namespace details + +// Helper macros to abstract function names for event addition and removal. +#ifdef __cplusplus_winrt + +#define WI_MakeUniqueWinRtEventTokenCx(_event, _object, _handler) \ + wil::details::make_unique_winrt_event_token_cx( \ + _object, \ + &wil::details::remove_reference::type::##_event##::add, \ + &wil::details::remove_reference::type::##_event##::remove, \ + _handler) + +#define WI_MakeUniqueWinRtStaticEventTokenCx(_event, _baseType, _handler) \ + wil::details::make_unique_winrt_static_event_token_cx<_baseType>( \ + &##_baseType##::##_event##::add, \ + &##_baseType##::##_event##::remove, \ + _handler) + +#endif // __cplusplus_winrt + +#ifdef WIL_ENABLE_EXCEPTIONS + +#define WI_MakeUniqueWinRtEventToken(_event, _object, _handler) \ + wil::details::make_unique_winrt_event_token( \ + _object, \ + &wistd::remove_pointer::type::add_##_event, \ + &wistd::remove_pointer::type::remove_##_event, \ + _handler) + +#endif // WIL_ENABLE_EXCEPTIONS + +#define WI_MakeUniqueWinRtEventTokenNoThrow(_event, _object, _handler, _token_reference) \ + wil::details::make_unique_winrt_event_token( \ + _object, \ + &wistd::remove_pointer::type::add_##_event, \ + &wistd::remove_pointer::type::remove_##_event, \ + _handler, \ + _token_reference) + +#define WI_MakeUniqueWinRtEventTokenFailFast(_event, _object, _handler) \ + wil::details::make_unique_winrt_event_token( \ + _object, \ + &wistd::remove_pointer::type::add_##_event, \ + &wistd::remove_pointer::type::remove_##_event, \ + _handler) + +#pragma endregion // EventRegistrationToken RAII wrapper + +} // namespace wil + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) + +template <> +struct ABI::Windows::Foundation::IAsyncOperation : + ABI::Windows::Foundation::IAsyncOperation_impl +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperation"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperationWithProgress : + ABI::Windows::Foundation::IAsyncOperationWithProgress_impl +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationWithProgress"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperation*> : + ABI::Windows::Foundation::IAsyncOperation_impl*> +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperation*>"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperationWithProgress*, P> : + ABI::Windows::Foundation::IAsyncOperationWithProgress_impl*, P> +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationWithProgress*,P>"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperation*> : + ABI::Windows::Foundation::IAsyncOperation_impl*> +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperation*>"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperationWithProgress*, Z> : + ABI::Windows::Foundation::IAsyncOperationWithProgress_impl*, Z> +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationWithProgress*,Z>"; + } +}; + +template <> +struct ABI::Windows::Foundation::IAsyncOperationCompletedHandler : + ABI::Windows::Foundation::IAsyncOperationCompletedHandler_impl +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationCompletedHandler"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler : + ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler_impl +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationWithProgressCompletedHandler"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperationCompletedHandler*> : + ABI::Windows::Foundation::IAsyncOperationCompletedHandler_impl*> +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationCompletedHandler*>"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler*, P> : + ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler_impl*, P> +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationWithProgressCompletedHandler*,P>"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperationCompletedHandler*> : + ABI::Windows::Foundation::IAsyncOperationCompletedHandler_impl*> +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationCompletedHandler*>"; + } +}; + +template +struct ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler*, Z> : + ABI::Windows::Foundation::IAsyncOperationWithProgressCompletedHandler_impl*, Z> +{ + static const wchar_t* z_get_rc_name_impl() + { + return L"IAsyncOperationWithProgressCompletedHandler*,Z>"; + } +}; +#endif // NTDDI_VERSION >= NTDDI_WINBLUE + +#if !defined(MIDL_NS_PREFIX) && !defined(____x_ABI_CWindows_CFoundation_CIClosable_FWD_DEFINED__) +// Internal .idl files use the namespace without the ABI prefix. Macro out ABI for that case +#pragma pop_macro("ABI") +#endif + +#if __WI_HAS_STD_LESS + +namespace std +{ + //! Specialization of `std::less` for `Microsoft::WRL::Wrappers::HString` that uses `hstring_less` for the + //! comparison function object. + template <> + struct less : + public wil::hstring_less + { + }; + + //! Specialization of `std::less` for `wil::unique_hstring` that uses `hstring_less` for the comparison function + //! object. + template <> + struct less : + public wil::hstring_less + { + }; +} + +#endif + +#endif // __WIL_WINRT_INCLUDED diff --git a/libraries/wil/wistd_config.h b/libraries/wil/wistd_config.h new file mode 100644 index 0000000..820e060 --- /dev/null +++ b/libraries/wil/wistd_config.h @@ -0,0 +1,571 @@ +// -*- C++ -*- +//===--------------------------- __config ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// STL common functionality +// +// Some aspects of STL are core language concepts that should be used from all C++ code, regardless +// of whether exceptions are enabled in the component. Common library code that expects to be used +// from exception-free components want these concepts, but including STL headers directly introduces +// friction as it requires components not using STL to declare their STL version. Doing so creates +// ambiguity around whether STL use is safe in a particular component and implicitly brings in +// a long list of headers (including ) which can create further ambiguity around throwing new +// support (some routines pulled in may expect it). Secondarily, pulling in these headers also has +// the potential to create naming conflicts or other implied dependencies. +// +// To promote the use of these core language concepts outside of STL-based binaries, this file is +// selectively pulling those concepts *directly* from corresponding STL headers. The corresponding +// "std::" namespace STL functions and types should be preferred over these in code that is bound to +// STL. The implementation and naming of all functions are taken directly from STL, instead using +// "wistd" (Windows Implementation std) as the namespace. +// +// Routines in this namespace should always be considered a reflection of the *current* STL implementation +// of those routines. Updates from STL should be taken, but no "bugs" should be fixed here. +// +// New, exception-based code should not use this namespace, but instead should prefer the std:: implementation. +// Only code that is not exception-based and libraries that expect to be utilized across both exception +// and non-exception based code should utilize this functionality. + +// This header mimics libc++'s '__config' header to the extent necessary to get the wistd::* definitions compiling. Note +// that this has a few key differences since libc++'s MSVC compatability is currently not functional and a bit behind + +#ifndef _WISTD_CONFIG_H_ +#define _WISTD_CONFIG_H_ + +// DO NOT add *any* additional includes to this file -- there should be no dependencies from its usage +#include // For size_t and other necessary types + +/// @cond +#if defined(_MSC_VER) && !defined(__clang__) +# if !defined(__WI_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# define __WI_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# endif +#endif + +#ifndef __WI_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +#pragma GCC system_header +#endif + +#ifdef __GNUC__ +# define __WI_GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__) +// The __WI_GNUC_VER_NEW macro better represents the new GCC versioning scheme +// introduced in GCC 5.0. +# define __WI_GNUC_VER_NEW (__WI_GNUC_VER * 10 + __GNUC_PATCHLEVEL__) +#else +# define __WI_GNUC_VER 0 +# define __WI_GNUC_VER_NEW 0 +#endif + +// _MSVC_LANG is the more accurate way to get the C++ version in MSVC +#if defined(_MSVC_LANG) && (_MSVC_LANG > __cplusplus) +#define __WI_CPLUSPLUS _MSVC_LANG +#else +#define __WI_CPLUSPLUS __cplusplus +#endif + +#ifndef __WI_LIBCPP_STD_VER +# if __WI_CPLUSPLUS <= 201103L +# define __WI_LIBCPP_STD_VER 11 +# elif __WI_CPLUSPLUS <= 201402L +# define __WI_LIBCPP_STD_VER 14 +# elif __WI_CPLUSPLUS <= 201703L +# define __WI_LIBCPP_STD_VER 17 +# else +# define __WI_LIBCPP_STD_VER 18 // current year, or date of c++2a ratification +# endif +#endif // __WI_LIBCPP_STD_VER + +#if __WI_CPLUSPLUS < 201103L +#define __WI_LIBCPP_CXX03_LANG +#endif + +#if defined(__ELF__) +# define __WI_LIBCPP_OBJECT_FORMAT_ELF 1 +#elif defined(__MACH__) +# define __WI_LIBCPP_OBJECT_FORMAT_MACHO 1 +#elif defined(_WIN32) +# define __WI_LIBCPP_OBJECT_FORMAT_COFF 1 +#elif defined(__wasm__) +# define __WI_LIBCPP_OBJECT_FORMAT_WASM 1 +#else +# error Unknown object file format +#endif + +#if defined(__clang__) +# define __WI_LIBCPP_COMPILER_CLANG +#elif defined(__GNUC__) +# define __WI_LIBCPP_COMPILER_GCC +#elif defined(_MSC_VER) +# define __WI_LIBCPP_COMPILER_MSVC +#elif defined(__IBMCPP__) +# define __WI_LIBCPP_COMPILER_IBM +#endif + +#if defined(__WI_LIBCPP_COMPILER_MSVC) +#define __WI_PUSH_WARNINGS __pragma(warning(push)) +#define __WI_POP_WARNINGS __pragma(warning(pop)) +#elif defined(__WI_LIBCPP_COMPILER_CLANG) +#define __WI_PUSH_WARNINGS __pragma(clang diagnostic push) +#define __WI_POP_WARNINGS __pragma(clang diagnostic pop) +#else +#define __WI_PUSH_WARNINGS +#define __WI_POP_WARNINGS +#endif + +#ifdef __WI_LIBCPP_COMPILER_MSVC +#define __WI_MSVC_DISABLE_WARNING(id) __pragma(warning(disable: id)) +#else +#define __WI_MSVC_DISABLE_WARNING(id) +#endif + +#ifdef __WI_LIBCPP_COMPILER_CLANG +#define __WI_CLANG_DISABLE_WARNING(warning) __pragma(clang diagnostic ignored #warning) +#else +#define __WI_CLANG_DISABLE_WARNING(warning) +#endif + +// NOTE: MSVC, which is what we primarily target, is severly underrepresented in libc++ and checks such as +// __has_feature(...) are always false for MSVC, even when the feature being tested _is_ present in MSVC. Therefore, we +// instead modify all checks to be __WI_HAS_FEATURE_IS_UNION, etc., which provides the correct value for MSVC and falls +// back to the __has_feature(...), etc. value otherwise. We intentionally leave '__has_feature', etc. undefined for MSVC +// so that we don't accidentally use the incorrect behavior +#ifndef __WI_LIBCPP_COMPILER_MSVC + +#ifndef __has_feature +#define __has_feature(__x) 0 +#endif + +// '__is_identifier' returns '0' if '__x' is a reserved identifier provided by +// the compiler and '1' otherwise. +#ifndef __is_identifier +#define __is_identifier(__x) 1 +#endif + +#ifndef __has_cpp_attribute +#define __has_cpp_attribute(__x) 0 +#endif + +#ifndef __has_attribute +#define __has_attribute(__x) 0 +#endif + +#ifndef __has_builtin +#define __has_builtin(__x) 0 +#endif + +#if __has_feature(cxx_alignas) +# define __WI_ALIGNAS_TYPE(x) alignas(x) +# define __WI_ALIGNAS(x) alignas(x) +#else +# define __WI_ALIGNAS_TYPE(x) __attribute__((__aligned__(__alignof(x)))) +# define __WI_ALIGNAS(x) __attribute__((__aligned__(x))) +#endif + +#if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) || \ + (!defined(__WI_LIBCPP_CXX03_LANG) && defined(__GNUC__)) // All supported GCC versions +# define __WI_LIBCPP_EXPLICIT explicit +#else +# define __WI_LIBCPP_EXPLICIT +#endif + +#if __has_feature(cxx_attributes) +# define __WI_LIBCPP_NORETURN [[noreturn]] +#else +# define __WI_LIBCPP_NORETURN __attribute__ ((noreturn)) +#endif + +#define __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS +#define __WI_LIBCPP_SUPPRESS_NOEXCEPT_ANALYSIS + +// The __WI_LIBCPP_NODISCARD_ATTRIBUTE should only be used to define other +// NODISCARD macros to the correct attribute. +#if __has_cpp_attribute(nodiscard) +# define __WI_LIBCPP_NODISCARD_ATTRIBUTE [[nodiscard]] +#elif defined(__WI_LIBCPP_COMPILER_CLANG) && !defined(__WI_LIBCPP_CXX03_LANG) +# define __WI_LIBCPP_NODISCARD_ATTRIBUTE [[clang::warn_unused_result]] +#else +// We can't use GCC's [[gnu::warn_unused_result]] and +// __attribute__((warn_unused_result)), because GCC does not silence them via +// (void) cast. +# define __WI_LIBCPP_NODISCARD_ATTRIBUTE +#endif + +#define __WI_HAS_FEATURE_IS_UNION __has_feature(is_union) +#define __WI_HAS_FEATURE_IS_CLASS __has_feature(is_class) +#define __WI_HAS_FEATURE_IS_ENUM __has_feature(is_enum) +#define __WI_HAS_FEATURE_IS_CONVERTIBLE_TO __has_feature(is_convertible_to) +#define __WI_HAS_FEATURE_IS_EMPTY __has_feature(is_empty) +#define __WI_HAS_FEATURE_IS_POLYMORPHIC __has_feature(is_polymorphic) +#define __WI_HAS_FEATURE_HAS_VIRTUAL_DESTRUCTOR __has_feature(has_virtual_destructor) +#define __WI_HAS_FEATURE_REFERENCE_QUALIFIED_FUNCTIONS __has_feature(cxx_reference_qualified_functions) +#define __WI_HAS_FEATURE_IS_CONSTRUCTIBLE __has_feature(is_constructible) +#define __WI_HAS_FEATURE_IS_TRIVIALLY_CONSTRUCTIBLE __has_feature(is_trivially_constructible) +#define __WI_HAS_FEATURE_IS_TRIVIALLY_ASSIGNABLE __has_feature(is_trivially_assignable) +#define __WI_HAS_FEATURE_HAS_TRIVIAL_DESTRUCTOR __has_feature(has_trivial_destructor) +#define __WI_HAS_FEATURE_NOEXCEPT __has_feature(cxx_noexcept) +#define __WI_HAS_FEATURE_IS_POD __has_feature(is_pod) +#define __WI_HAS_FEATURE_IS_STANDARD_LAYOUT __has_feature(is_standard_layout) +#define __WI_HAS_FEATURE_IS_TRIVIALLY_COPYABLE __has_feature(is_trivially_copyable) +#define __WI_HAS_FEATURE_IS_TRIVIAL __has_feature(is_trivial) +#define __WI_HAS_FEATURE_HAS_TRIVIAL_CONSTRUCTOR __has_feature(has_trivial_constructor) || (__WI_GNUC_VER >= 403) +#define __WI_HAS_FEATURE_HAS_NOTHROW_CONSTRUCTOR __has_feature(has_nothrow_constructor) || (__WI_GNUC_VER >= 403) +#define __WI_HAS_FEATURE_HAS_NOTHROW_COPY __has_feature(has_nothrow_copy) || (__WI_GNUC_VER >= 403) +#define __WI_HAS_FEATURE_HAS_NOTHROW_ASSIGN __has_feature(has_nothrow_assign) || (__WI_GNUC_VER >= 403) + +#if !(__has_feature(cxx_noexcept)) +#define __WI_LIBCPP_HAS_NO_NOEXCEPT +#endif + +#if !__is_identifier(__has_unique_object_representations) || __WI_GNUC_VER >= 700 +#define __WI_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS +#endif + +#if !(__has_feature(cxx_variadic_templates)) +#define __WI_LIBCPP_HAS_NO_VARIADICS +#endif + +#if __has_feature(is_literal) || __WI_GNUC_VER >= 407 +#define __WI_LIBCPP_IS_LITERAL(T) __is_literal(T) +#endif + +#if __has_feature(underlying_type) || __WI_GNUC_VER >= 407 +#define __WI_LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) +#endif + +#if __has_feature(is_final) || __WI_GNUC_VER >= 407 +#define __WI_LIBCPP_HAS_IS_FINAL +#endif + +#if __has_feature(is_base_of) || defined(__GNUC__) && __WI_GNUC_VER >= 403 +#define __WI_LIBCPP_HAS_IS_BASE_OF +#endif + +#if __is_identifier(__is_aggregate) && (__WI_GNUC_VER_NEW < 7001) +#define __WI_LIBCPP_HAS_NO_IS_AGGREGATE +#endif + +#if !(__has_feature(cxx_rtti)) && !defined(__WI_LIBCPP_NO_RTTI) +#define __WI_LIBCPP_NO_RTTI +#endif + +#if !(__has_feature(cxx_variable_templates)) +#define __WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES +#endif + +#if !(__has_feature(cxx_relaxed_constexpr)) +#define __WI_LIBCPP_HAS_NO_CXX14_CONSTEXPR +#endif + +#if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700 +#define __WI_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF +#endif + +#if __has_attribute(__no_sanitize__) && !defined(__WI_LIBCPP_COMPILER_GCC) +# define __WI_LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) +#else +# define __WI_LIBCPP_NO_CFI +#endif + +#define __WI_LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) + +#if __has_attribute(internal_linkage) +# define __WI_LIBCPP_INTERNAL_LINKAGE __attribute__ ((internal_linkage)) +#else +# define __WI_LIBCPP_INTERNAL_LINKAGE __WI_LIBCPP_ALWAYS_INLINE +#endif + +#else + +// NOTE: Much of the following assumes a decently recent version of MSVC. Past versions can be supported, but will need +// to be updated to contain the proper _MSC_VER check +#define __WI_ALIGNAS_TYPE(x) alignas(x) +#define __WI_ALIGNAS(x) alignas(x) +#define __alignof__ __alignof + +#define __WI_LIBCPP_EXPLICIT explicit +#define __WI_LIBCPP_NORETURN [[noreturn]] +#define __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS __pragma(warning(suppress:26495)) +#define __WI_LIBCPP_SUPPRESS_NOEXCEPT_ANALYSIS __pragma(warning(suppress:26439)) + + +#if __WI_LIBCPP_STD_VER > 14 +#define __WI_LIBCPP_NODISCARD_ATTRIBUTE [[nodiscard]] +#else +#define __WI_LIBCPP_NODISCARD_ATTRIBUTE _Check_return_ +#endif + +#define __WI_HAS_FEATURE_IS_UNION 1 +#define __WI_HAS_FEATURE_IS_CLASS 1 +#define __WI_HAS_FEATURE_IS_ENUM 1 +#define __WI_HAS_FEATURE_IS_CONVERTIBLE_TO 1 +#define __WI_HAS_FEATURE_IS_EMPTY 1 +#define __WI_HAS_FEATURE_IS_POLYMORPHIC 1 +#define __WI_HAS_FEATURE_HAS_VIRTUAL_DESTRUCTOR 1 +#define __WI_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS 1 +#define __WI_HAS_FEATURE_REFERENCE_QUALIFIED_FUNCTIONS 1 +#define __WI_HAS_FEATURE_IS_CONSTRUCTIBLE 1 +#define __WI_HAS_FEATURE_IS_TRIVIALLY_CONSTRUCTIBLE 1 +#define __WI_HAS_FEATURE_IS_TRIVIALLY_ASSIGNABLE 1 +#define __WI_HAS_FEATURE_HAS_TRIVIAL_DESTRUCTOR 1 +#define __WI_HAS_FEATURE_NOEXCEPT 1 +#define __WI_HAS_FEATURE_IS_POD 1 +#define __WI_HAS_FEATURE_IS_STANDARD_LAYOUT 1 +#define __WI_HAS_FEATURE_IS_TRIVIALLY_COPYABLE 1 +#define __WI_HAS_FEATURE_IS_TRIVIAL 1 +#define __WI_HAS_FEATURE_HAS_TRIVIAL_CONSTRUCTOR 1 +#define __WI_HAS_FEATURE_HAS_NOTHROW_CONSTRUCTOR 1 +#define __WI_HAS_FEATURE_HAS_NOTHROW_COPY 1 +#define __WI_HAS_FEATURE_HAS_NOTHROW_ASSIGN 1 +#define __WI_HAS_FEATURE_IS_DESTRUCTIBLE 1 + +#if !defined(_CPPRTTI) && !defined(__WI_LIBCPP_NO_RTTI) +#define __WI_LIBCPP_NO_RTTI +#endif + +#define __WI_LIBCPP_IS_LITERAL(T) __is_literal_type(T) +#define __WI_LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) +#define __WI_LIBCPP_HAS_IS_FINAL +#define __WI_LIBCPP_HAS_IS_BASE_OF + +#if __WI_LIBCPP_STD_VER < 14 +#define __WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES +#endif + +#define __WI_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF +#define __WI_LIBCPP_NO_CFI + +#define __WI_LIBCPP_ALWAYS_INLINE __forceinline +#define __WI_LIBCPP_INTERNAL_LINKAGE + +#endif + +#ifndef _WIN32 + +#ifdef __LITTLE_ENDIAN__ +# if __LITTLE_ENDIAN__ +# define __WI_LIBCPP_LITTLE_ENDIAN +# endif // __LITTLE_ENDIAN__ +#endif // __LITTLE_ENDIAN__ + +#ifdef __BIG_ENDIAN__ +# if __BIG_ENDIAN__ +# define __WI_LIBCPP_BIG_ENDIAN +# endif // __BIG_ENDIAN__ +#endif // __BIG_ENDIAN__ + +#ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define __WI_LIBCPP_LITTLE_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __WI_LIBCPP_BIG_ENDIAN +# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#endif // __BYTE_ORDER__ + +#if !defined(__WI_LIBCPP_LITTLE_ENDIAN) && !defined(__WI_LIBCPP_BIG_ENDIAN) +# include +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define __WI_LIBCPP_LITTLE_ENDIAN +# elif __BYTE_ORDER == __BIG_ENDIAN +# define __WI_LIBCPP_BIG_ENDIAN +# else // __BYTE_ORDER == __BIG_ENDIAN +# error unable to determine endian +# endif +#endif // !defined(__WI_LIBCPP_LITTLE_ENDIAN) && !defined(__WI_LIBCPP_BIG_ENDIAN) + +#else // _WIN32 + +#define __WI_LIBCPP_LITTLE_ENDIAN + +#endif // _WIN32 + +#ifdef __WI_LIBCPP_HAS_NO_CONSTEXPR +# define __WI_LIBCPP_CONSTEXPR +#else +# define __WI_LIBCPP_CONSTEXPR constexpr +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +# define __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr +#else +# define __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 +#endif + +#if __WI_LIBCPP_STD_VER > 14 && !defined(__WI_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +# define __WI_LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr +#else +# define __WI_LIBCPP_CONSTEXPR_AFTER_CXX14 +#endif + +#if __WI_LIBCPP_STD_VER > 17 && !defined(__WI_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +# define __WI_LIBCPP_CONSTEXPR_AFTER_CXX17 constexpr +#else +# define __WI_LIBCPP_CONSTEXPR_AFTER_CXX17 +#endif + +#if !defined(__WI_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) && \ + (__WI_LIBCPP_STD_VER > 17 || defined(__WI_LIBCPP_ENABLE_NODISCARD)) +# define __WI_LIBCPP_NODISCARD_AFTER_CXX17 __WI_LIBCPP_NODISCARD_ATTRIBUTE +#else +# define __WI_LIBCPP_NODISCARD_AFTER_CXX17 +#endif + +#if __WI_LIBCPP_STD_VER > 14 && defined(__cpp_inline_variables) && (__cpp_inline_variables >= 201606L) +# define __WI_LIBCPP_INLINE_VAR inline +#else +# define __WI_LIBCPP_INLINE_VAR +#endif + +#ifdef __WI_LIBCPP_CXX03_LANG +#define __WI_LIBCPP_HAS_NO_UNICODE_CHARS +#define __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif + +#ifndef __SIZEOF_INT128__ +#define __WI_LIBCPP_HAS_NO_INT128 +#endif + +#if !__WI_HAS_FEATURE_NOEXCEPT && !defined(__WI_LIBCPP_HAS_NO_NOEXCEPT) +#define __WI_LIBCPP_HAS_NO_NOEXCEPT +#endif + +#ifndef __WI_LIBCPP_HAS_NO_NOEXCEPT +# define WI_NOEXCEPT noexcept +# define __WI_NOEXCEPT_(x) noexcept(x) +#else +# define WI_NOEXCEPT throw() +# define __WI_NOEXCEPT_(x) +#endif + +#if defined(__WI_LIBCPP_OBJECT_FORMAT_COFF) +#define __WI_LIBCPP_HIDDEN +#define __WI_LIBCPP_TEMPLATE_VIS +#endif // defined(__WI_LIBCPP_OBJECT_FORMAT_COFF) + +#ifndef __WI_LIBCPP_HIDDEN +# if !defined(__WI_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define __WI_LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden"))) +# else +# define __WI_LIBCPP_HIDDEN +# endif +#endif + +#ifndef __WI_LIBCPP_TEMPLATE_VIS +# if !defined(__WI_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && !defined(__WI_LIBCPP_COMPILER_MSVC) +# if __has_attribute(__type_visibility__) +# define __WI_LIBCPP_TEMPLATE_VIS __attribute__ ((__type_visibility__("default"))) +# else +# define __WI_LIBCPP_TEMPLATE_VIS __attribute__ ((__visibility__("default"))) +# endif +# else +# define __WI_LIBCPP_TEMPLATE_VIS +# endif +#endif + +#define __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_HIDDEN __WI_LIBCPP_INTERNAL_LINKAGE + +namespace wistd // ("Windows Implementation" std) +{ + using nullptr_t = decltype(__nullptr); + + template + struct __less + { + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} + + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} + + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} + + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} + }; + + template + struct __less<_T1, _T1> + { + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} + }; + + template + struct __less + { + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} + }; + + template + struct __less<_T1, const _T1> + { + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} + }; + + // These are added to wistd to enable use of min/max without having to use the windows.h min/max + // macros that some clients might not have access to. Note: the STL versions of these have debug + // checking for the less than operator and support for iterators that these implementations lack. + // Use the STL versions when you require use of those features. + + // min + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + const _Tp& + (min)(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + return __comp(__b, __a) ? __b : __a; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + const _Tp& + (min)(const _Tp& __a, const _Tp& __b) + { + return (min)(__a, __b, __less<_Tp>()); + } + + // max + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + const _Tp& + (max)(const _Tp& __a, const _Tp& __b, _Compare __comp) + { + return __comp(__a, __b) ? __b : __a; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 + const _Tp& + (max)(const _Tp& __a, const _Tp& __b) + { + return (max)(__a, __b, __less<_Tp>()); + } + + template + struct __WI_LIBCPP_TEMPLATE_VIS unary_function + { + using argument_type = _Arg; + using result_type = _Result; + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS binary_function + { + using first_argument_type = _Arg1; + using second_argument_type = _Arg2; + using result_type = _Result; + }; +} +/// @endcond + +#endif // _WISTD_CONFIG_H_ diff --git a/libraries/wil/wistd_functional.h b/libraries/wil/wistd_functional.h new file mode 100644 index 0000000..c112057 --- /dev/null +++ b/libraries/wil/wistd_functional.h @@ -0,0 +1,548 @@ +// -*- C++ -*- +//===------------------------ functional ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// STL common functionality +// +// Some aspects of STL are core language concepts that should be used from all C++ code, regardless +// of whether exceptions are enabled in the component. Common library code that expects to be used +// from exception-free components want these concepts, but including STL headers directly introduces +// friction as it requires components not using STL to declare their STL version. Doing so creates +// ambiguity around whether STL use is safe in a particular component and implicitly brings in +// a long list of headers (including ) which can create further ambiguity around throwing new +// support (some routines pulled in may expect it). Secondarily, pulling in these headers also has +// the potential to create naming conflicts or other implied dependencies. +// +// To promote the use of these core language concepts outside of STL-based binaries, this file is +// selectively pulling those concepts *directly* from corresponding STL headers. The corresponding +// "std::" namespace STL functions and types should be preferred over these in code that is bound to +// STL. The implementation and naming of all functions are taken directly from STL, instead using +// "wistd" (Windows Implementation std) as the namespace. +// +// Routines in this namespace should always be considered a reflection of the *current* STL implementation +// of those routines. Updates from STL should be taken, but no "bugs" should be fixed here. +// +// New, exception-based code should not use this namespace, but instead should prefer the std:: implementation. +// Only code that is not exception-based and libraries that expect to be utilized across both exception +// and non-exception based code should utilize this functionality. + +#ifndef _WISTD_FUNCTIONAL_H_ +#define _WISTD_FUNCTIONAL_H_ + +// DO NOT add *any* additional includes to this file -- there should be no dependencies from its usage +#include "wistd_memory.h" +#include // For __fastfail +#include // For placement new + +#if !defined(__WI_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +#pragma warning(push) +#pragma warning(disable: 4324) +#pragma warning(disable: 4800) + +/// @cond +namespace wistd // ("Windows Implementation" std) +{ + // wistd::function + // + // All of the code below is in direct support of wistd::function. This class is identical to std::function + // with the following exceptions: + // + // 1) It never allocates and is safe to use from exception-free code (custom allocators are not supported) + // 2) It's slightly bigger on the stack (64 bytes, rather than 24 for 32bit) + // 3) There is an explicit static-assert if a lambda becomes too large to hold in the internal buffer (rather than an allocation) + + template + struct __invoke_void_return_wrapper + { +#ifndef __WI_LIBCPP_CXX03_LANG + template + static _Ret __call(_Args&&... __args) { + return __invoke(wistd::forward<_Args>(__args)...); + } +#else + template + static _Ret __call(_Fn __f) { + return __invoke(__f); + } + + template + static _Ret __call(_Fn __f, _A0& __a0) { + return __invoke(__f, __a0); + } + + template + static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { + return __invoke(__f, __a0, __a1); + } + + template + static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ + return __invoke(__f, __a0, __a1, __a2); + } +#endif + }; + + template <> + struct __invoke_void_return_wrapper + { +#ifndef __WI_LIBCPP_CXX03_LANG + template + static void __call(_Args&&... __args) { + (void)__invoke(wistd::forward<_Args>(__args)...); + } +#else + template + static void __call(_Fn __f) { + __invoke(__f); + } + + template + static void __call(_Fn __f, _A0& __a0) { + __invoke(__f, __a0); + } + + template + static void __call(_Fn __f, _A0& __a0, _A1& __a1) { + __invoke(__f, __a0, __a1); + } + + template + static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { + __invoke(__f, __a0, __a1, __a2); + } +#endif + }; + + //////////////////////////////////////////////////////////////////////////////// + // FUNCTION + //============================================================================== + + // bad_function_call + + __WI_LIBCPP_NORETURN inline __WI_LIBCPP_INLINE_VISIBILITY + void __throw_bad_function_call() + { + __fastfail(7); // FAST_FAIL_FATAL_APP_EXIT + } + + template class __WI_LIBCPP_TEMPLATE_VIS function; // undefined + + namespace __function + { + + template + struct __maybe_derive_from_unary_function + { + }; + + template + struct __maybe_derive_from_unary_function<_Rp(_A1)> + : public unary_function<_A1, _Rp> + { + }; + + template + struct __maybe_derive_from_binary_function + { + }; + + template + struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> + : public binary_function<_A1, _A2, _Rp> + { + }; + + template + __WI_LIBCPP_INLINE_VISIBILITY + bool __not_null(_Fp const&) { return true; } + + template + __WI_LIBCPP_INLINE_VISIBILITY + bool __not_null(_Fp* __ptr) { return __ptr; } + + template + __WI_LIBCPP_INLINE_VISIBILITY + bool __not_null(_Ret _Class::*__ptr) { return __ptr; } + + template + __WI_LIBCPP_INLINE_VISIBILITY + bool __not_null(function<_Fp> const& __f) { return !!__f; } + + } // namespace __function + +#ifndef __WI_LIBCPP_CXX03_LANG + + namespace __function { + + template class __base; + + template + class __base<_Rp(_ArgTypes...)> + { + __base(const __base&); + __base& operator=(const __base&); + public: + __WI_LIBCPP_INLINE_VISIBILITY __base() {} + __WI_LIBCPP_INLINE_VISIBILITY virtual ~__base() {} + virtual void __clone(__base*) const = 0; + virtual void __move(__base*) = 0; + virtual void destroy() WI_NOEXCEPT = 0; + virtual _Rp operator()(_ArgTypes&& ...) = 0; + }; + + template class __func; + + template + class __func<_Fp, _Rp(_ArgTypes...)> + : public __base<_Rp(_ArgTypes...)> + { + _Fp __f_; + public: + __WI_LIBCPP_INLINE_VISIBILITY + explicit __func(_Fp&& __f) + : __f_(wistd::move(__f)) {} + + __WI_LIBCPP_INLINE_VISIBILITY + explicit __func(const _Fp& __f) + : __f_(__f) {} + + virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; + virtual void __move(__base<_Rp(_ArgTypes...)>*); + virtual void destroy() WI_NOEXCEPT; + virtual _Rp operator()(_ArgTypes&& ... __arg); + }; + + template + void + __func<_Fp, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const + { + ::new (__p) __func(__f_); + } + + template + void + __func<_Fp, _Rp(_ArgTypes...)>::__move(__base<_Rp(_ArgTypes...)>* __p) + { + ::new (__p) __func(wistd::move(__f_)); + } + + template + void + __func<_Fp, _Rp(_ArgTypes...)>::destroy() WI_NOEXCEPT + { + __f_.~_Fp(); + } + + template + _Rp + __func<_Fp, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) + { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_, wistd::forward<_ArgTypes>(__arg)...); + } + + // 'wistd::function' is most similar to 'inplace_function' in that it _only_ permits holding function objects + // that can fit within its internal buffer. Therefore, we expand this size to accommodate space for at least 12 + // pointers (__base vtable takes an additional one). + constexpr const size_t __buffer_size = 13 * sizeof(void*); + + } // __function + + // NOTE: The extra 'alignas' here is to work around the x86 compiler bug mentioned in + // https://github.com/microsoft/STL/issues/1533 to force alignment on the stack + template + class __WI_LIBCPP_TEMPLATE_VIS __WI_ALIGNAS(typename aligned_storage<__function::__buffer_size>::type) + function<_Rp(_ArgTypes...)> + : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, + public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> + { + using __base = __function::__base<_Rp(_ArgTypes...)>; + __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS + typename aligned_storage<__function::__buffer_size>::type __buf_; + __base* __f_; + + __WI_LIBCPP_NO_CFI static __base *__as_base(void *p) { + return static_cast<__base*>(p); + } + + template + struct __callable_imp + { + static const bool value = is_same::value || + is_convertible::type, + _Rp>::value; + }; + + template + struct __callable_imp<_Fp, false> + { + static constexpr bool value = false; + }; + + template + struct __callable + { + static const bool value = __callable_imp<_Fp, __lazy_and< + integral_constant, function>::value>, + __invokable<_Fp&, _ArgTypes...> + >::value>::value; + }; + + template + using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type; + public: + using result_type = _Rp; + + // construct/copy/destroy: + __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS + function() WI_NOEXCEPT : __f_(0) {} + + __WI_LIBCPP_INLINE_VISIBILITY + function(nullptr_t) WI_NOEXCEPT : __f_(0) {} + function(const function&); + function(function&&); + template> + function(_Fp); + + function& operator=(const function&); + function& operator=(function&&); + function& operator=(nullptr_t) WI_NOEXCEPT; + template> + function& operator=(_Fp&&); + + ~function(); + + // function modifiers: + void swap(function&); + + // function capacity: + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_EXPLICIT operator bool() const WI_NOEXCEPT {return __f_;} + + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; + template + bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; + public: + // function invocation: + _Rp operator()(_ArgTypes...) const; + + // NOTE: type_info is very compiler specific, and on top of that, we're operating in a namespace other than + // 'std' so all functions requiring RTTI have been removed + }; + + template + __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS + function<_Rp(_ArgTypes...)>::function(const function& __f) + { + if (__f.__f_ == nullptr) + __f_ = 0; + else + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + } + + template + __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS __WI_LIBCPP_SUPPRESS_NOEXCEPT_ANALYSIS + function<_Rp(_ArgTypes...)>::function(function&& __f) + { + if (__f.__f_ == nullptr) + __f_ = 0; + else + { + __f_ = __as_base(&__buf_); + __f.__f_->__move(__f_); + __f.__f_->destroy(); + __f.__f_ = 0; + } + } + + template + template + __WI_LIBCPP_SUPPRESS_NONINIT_ANALYSIS + function<_Rp(_ArgTypes...)>::function(_Fp __f) + : __f_(nullptr) + { + if (__function::__not_null(__f)) + { + typedef __function::__func<_Fp, _Rp(_ArgTypes...)> _FF; + static_assert(sizeof(_FF) <= sizeof(__buf_), + "The sizeof(wistd::function) has grown too large for the reserved buffer (12 pointers). Refactor to reduce size of the capture."); + __f_ = ::new(static_cast(&__buf_)) _FF(wistd::move(__f)); + } + } + + template + function<_Rp(_ArgTypes...)>& + function<_Rp(_ArgTypes...)>::operator=(const function& __f) + { + *this = nullptr; + if (__f.__f_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } + return *this; + } + + template + function<_Rp(_ArgTypes...)>& + function<_Rp(_ArgTypes...)>::operator=(function&& __f) + { + *this = nullptr; + if (__f.__f_) + { + __f_ = __as_base(&__buf_); + __f.__f_->__move(__f_); + __f.__f_->destroy(); + __f.__f_ = 0; + } + return *this; + } + + template + function<_Rp(_ArgTypes...)>& + function<_Rp(_ArgTypes...)>::operator=(nullptr_t) WI_NOEXCEPT + { + __base* __t = __f_; + __f_ = 0; + if (__t) + __t->destroy(); + return *this; + } + + template + template + function<_Rp(_ArgTypes...)>& + function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) + { + *this = nullptr; + if (__function::__not_null(__f)) + { + typedef __function::__func::type, _Rp(_ArgTypes...)> _FF; + static_assert(sizeof(_FF) <= sizeof(__buf_), + "The sizeof(wistd::function) has grown too large for the reserved buffer (12 pointers). Refactor to reduce size of the capture."); + __f_ = ::new(static_cast(&__buf_)) _FF(wistd::move(__f)); + } + + return *this; + } + + template + function<_Rp(_ArgTypes...)>::~function() + { + if (__f_) + __f_->destroy(); + } + + template + void + function<_Rp(_ArgTypes...)>::swap(function& __f) + { + if (wistd::addressof(__f) == this) + return; + if (__f_ && __f.__f_) + { + typename aligned_storage::type __tempbuf; + __base* __t = __as_base(&__tempbuf); + __f_->__move(__t); + __f_->destroy(); + __f_ = 0; + __f.__f_->__move(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = __as_base(&__buf_); + __t->__move(__as_base(&__f.__buf_)); + __t->destroy(); + __f.__f_ = __as_base(&__f.__buf_); + } + else if (__f_) + { + __f_->__move(__as_base(&__f.__buf_)); + __f_->destroy(); + __f_ = 0; + __f.__f_ = __as_base(&__f.__buf_); + } + else if (__f.__f_) + { + __f.__f_->__move(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = 0; + __f_ = __as_base(&__buf_); + } + } + + template + _Rp + function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const + { + if (__f_ == nullptr) + __throw_bad_function_call(); + return (*__f_)(wistd::forward<_ArgTypes>(__arg)...); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) WI_NOEXCEPT {return !__f;} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) WI_NOEXCEPT {return !__f;} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) WI_NOEXCEPT {return (bool)__f;} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) WI_NOEXCEPT {return (bool)__f;} + + // Provide both 'swap_wil' and 'swap' since we now have two ADL scenarios that we need to work + template + inline __WI_LIBCPP_INLINE_VISIBILITY + void + swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) + {return __x.swap(__y);} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + void + swap_wil(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) + {return __x.swap(__y);} + + // std::invoke + template + typename __invoke_of<_Fn, _Args...>::type + invoke(_Fn&& __f, _Args&&... __args) + __WI_NOEXCEPT_((__nothrow_invokable<_Fn, _Args...>::value)) + { + return wistd::__invoke(wistd::forward<_Fn>(__f), wistd::forward<_Args>(__args)...); + } + +#else // __WI_LIBCPP_CXX03_LANG + +#error wistd::function and wistd::invoke not implemented for pre-C++11 + +#endif +} +/// @endcond + +#pragma warning(pop) + +#endif // _WISTD_FUNCTIONAL_H_ diff --git a/libraries/wil/wistd_memory.h b/libraries/wil/wistd_memory.h new file mode 100644 index 0000000..5730f2f --- /dev/null +++ b/libraries/wil/wistd_memory.h @@ -0,0 +1,1038 @@ +// -*- C++ -*- +//===-------------------------- memory ------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// STL common functionality +// +// Some aspects of STL are core language concepts that should be used from all C++ code, regardless +// of whether exceptions are enabled in the component. Common library code that expects to be used +// from exception-free components want these concepts, but including STL headers directly introduces +// friction as it requires components not using STL to declare their STL version. Doing so creates +// ambiguity around whether STL use is safe in a particular component and implicitly brings in +// a long list of headers (including ) which can create further ambiguity around throwing new +// support (some routines pulled in may expect it). Secondarily, pulling in these headers also has +// the potential to create naming conflicts or other implied dependencies. +// +// To promote the use of these core language concepts outside of STL-based binaries, this file is +// selectively pulling those concepts *directly* from corresponding STL headers. The corresponding +// "std::" namespace STL functions and types should be preferred over these in code that is bound to +// STL. The implementation and naming of all functions are taken directly from STL, instead using +// "wistd" (Windows Implementation std) as the namespace. +// +// Routines in this namespace should always be considered a reflection of the *current* STL implementation +// of those routines. Updates from STL should be taken, but no "bugs" should be fixed here. +// +// New, exception-based code should not use this namespace, but instead should prefer the std:: implementation. +// Only code that is not exception-based and libraries that expect to be utilized across both exception +// and non-exception based code should utilize this functionality. + +#ifndef _WISTD_MEMORY_H_ +#define _WISTD_MEMORY_H_ + +// DO NOT add *any* additional includes to this file -- there should be no dependencies from its usage +#include "wistd_type_traits.h" + +#if !defined(__WI_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +/// @cond +namespace wistd // ("Windows Implementation" std) +{ + // allocator_traits + + template + struct __has_pointer_type : false_type {}; + + template + struct __has_pointer_type<_Tp, + typename __void_t::type> : true_type {}; + + namespace __pointer_type_imp + { + + template ::value> + struct __pointer_type + { + using type = typename _Dp::pointer; + }; + + template + struct __pointer_type<_Tp, _Dp, false> + { + using type = _Tp*; + }; + + } // __pointer_type_imp + + template + struct __pointer_type + { + using type = typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type; + }; + + template ::value && !__libcpp_is_final<_Tp>::value> + struct __compressed_pair_elem { + using _ParamT = _Tp; + using reference = _Tp&; + using const_reference = const _Tp&; + +#ifndef __WI_LIBCPP_CXX03_LANG + __WI_LIBCPP_INLINE_VISIBILITY constexpr __compressed_pair_elem() : __value_() {} + + template ::type>::value + >::type> + __WI_LIBCPP_INLINE_VISIBILITY + constexpr explicit + __compressed_pair_elem(_Up&& __u) + : __value_(wistd::forward<_Up>(__u)) + { + } + + // NOTE: Since we have not added 'tuple' to 'wistd', the 'piecewise' constructor has been removed +#else + __WI_LIBCPP_INLINE_VISIBILITY __compressed_pair_elem() : __value_() {} + __WI_LIBCPP_INLINE_VISIBILITY + __compressed_pair_elem(_ParamT __p) : __value_(wistd::forward<_ParamT>(__p)) {} +#endif + + __WI_LIBCPP_INLINE_VISIBILITY reference __get() WI_NOEXCEPT { return __value_; } + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + const_reference __get() const WI_NOEXCEPT { return __value_; } + + private: + _Tp __value_; + }; + + template + struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp { + using _ParamT = _Tp; + using reference = _Tp&; + using const_reference = const _Tp&; + using __value_type = _Tp; + +#ifndef __WI_LIBCPP_CXX03_LANG + __WI_LIBCPP_INLINE_VISIBILITY constexpr __compressed_pair_elem() = default; + + template ::type>::value + >::type> + __WI_LIBCPP_INLINE_VISIBILITY + constexpr explicit + __compressed_pair_elem(_Up&& __u) + : __value_type(wistd::forward<_Up>(__u)) + {} + + // NOTE: Since we have not added 'tuple' to 'wistd', the 'piecewise' constructor has been removed +#else + __WI_LIBCPP_INLINE_VISIBILITY __compressed_pair_elem() : __value_type() {} + __WI_LIBCPP_INLINE_VISIBILITY + __compressed_pair_elem(_ParamT __p) + : __value_type(wistd::forward<_ParamT>(__p)) {} +#endif + + __WI_LIBCPP_INLINE_VISIBILITY reference __get() WI_NOEXCEPT { return *this; } + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + const_reference __get() const WI_NOEXCEPT { return *this; } + }; + + // Tag used to construct the second element of the compressed pair. + struct __second_tag {}; + + template + class __declspec(empty_bases) __compressed_pair : private __compressed_pair_elem<_T1, 0>, + private __compressed_pair_elem<_T2, 1> { + using _Base1 = __compressed_pair_elem<_T1, 0>; + using _Base2 = __compressed_pair_elem<_T2, 1>; + + // NOTE: This static assert should never fire because __compressed_pair + // is *almost never* used in a scenario where it's possible for T1 == T2. + // (The exception is wistd::function where it is possible that the function + // object and the allocator have the same type). + static_assert((!is_same<_T1, _T2>::value), + "__compressed_pair cannot be instantated when T1 and T2 are the same type; " + "The current implementation is NOT ABI-compatible with the previous " + "implementation for this configuration"); + + public: +#ifndef __WI_LIBCPP_CXX03_LANG + template , _Dummy>::value && + __dependent_type, _Dummy>::value + >::type + > + __WI_LIBCPP_INLINE_VISIBILITY + constexpr __compressed_pair() {} + + template ::type, + __compressed_pair>::value, + bool>::type = true> + __WI_LIBCPP_INLINE_VISIBILITY constexpr explicit + __compressed_pair(_Tp&& __t) + : _Base1(wistd::forward<_Tp>(__t)), _Base2() {} + + template + __WI_LIBCPP_INLINE_VISIBILITY constexpr + __compressed_pair(__second_tag, _Tp&& __t) + : _Base1(), _Base2(wistd::forward<_Tp>(__t)) {} + + template + __WI_LIBCPP_INLINE_VISIBILITY constexpr + __compressed_pair(_U1&& __t1, _U2&& __t2) + : _Base1(wistd::forward<_U1>(__t1)), _Base2(wistd::forward<_U2>(__t2)) {} + + // NOTE: Since we have not added 'tuple' to 'wistd', the 'piecewise' constructor has been removed +#else + __WI_LIBCPP_INLINE_VISIBILITY + __compressed_pair() {} + + __WI_LIBCPP_INLINE_VISIBILITY explicit + __compressed_pair(_T1 __t1) : _Base1(wistd::forward<_T1>(__t1)) {} + + __WI_LIBCPP_INLINE_VISIBILITY + __compressed_pair(__second_tag, _T2 __t2) + : _Base1(), _Base2(wistd::forward<_T2>(__t2)) {} + + __WI_LIBCPP_INLINE_VISIBILITY + __compressed_pair(_T1 __t1, _T2 __t2) + : _Base1(wistd::forward<_T1>(__t1)), _Base2(wistd::forward<_T2>(__t2)) {} +#endif + + __WI_LIBCPP_INLINE_VISIBILITY + typename _Base1::reference first() WI_NOEXCEPT { + return static_cast<_Base1&>(*this).__get(); + } + + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + typename _Base1::const_reference first() const WI_NOEXCEPT { + return static_cast<_Base1 const&>(*this).__get(); + } + + __WI_LIBCPP_INLINE_VISIBILITY + typename _Base2::reference second() WI_NOEXCEPT { + return static_cast<_Base2&>(*this).__get(); + } + + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + typename _Base2::const_reference second() const WI_NOEXCEPT { + return static_cast<_Base2 const&>(*this).__get(); + } + + __WI_LIBCPP_INLINE_VISIBILITY + void swap(__compressed_pair& __x) + __WI_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && + __is_nothrow_swappable<_T2>::value) + { + using wistd::swap_wil; + swap_wil(first(), __x.first()); + swap_wil(second(), __x.second()); + } + }; + + // Provide both 'swap_wil' and 'swap' since we now have two ADL scenarios that we need to work + template + inline __WI_LIBCPP_INLINE_VISIBILITY + void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y) + __WI_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && + __is_nothrow_swappable<_T2>::value) { + __x.swap(__y); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + void swap_wil(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y) + __WI_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && + __is_nothrow_swappable<_T2>::value) { + __x.swap(__y); + } + + // default_delete + + template + struct __WI_LIBCPP_TEMPLATE_VIS default_delete { + static_assert(!is_function<_Tp>::value, + "default_delete cannot be instantiated for function types"); +#ifndef __WI_LIBCPP_CXX03_LANG + __WI_LIBCPP_INLINE_VISIBILITY constexpr default_delete() WI_NOEXCEPT = default; +#else + __WI_LIBCPP_INLINE_VISIBILITY default_delete() {} +#endif + template + __WI_LIBCPP_INLINE_VISIBILITY + default_delete(const default_delete<_Up>&, + typename enable_if::value>::type* = + nullptr) WI_NOEXCEPT {} + + __WI_LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const WI_NOEXCEPT { + static_assert(sizeof(_Tp) > 0, + "default_delete can not delete incomplete type"); + static_assert(!is_void<_Tp>::value, + "default_delete can not delete incomplete type"); + delete __ptr; + } + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> { + private: + template + struct _EnableIfConvertible + : enable_if::value> {}; + + public: +#ifndef __WI_LIBCPP_CXX03_LANG + __WI_LIBCPP_INLINE_VISIBILITY constexpr default_delete() WI_NOEXCEPT = default; +#else + __WI_LIBCPP_INLINE_VISIBILITY default_delete() {} +#endif + + template + __WI_LIBCPP_INLINE_VISIBILITY + default_delete(const default_delete<_Up[]>&, + typename _EnableIfConvertible<_Up>::type* = nullptr) WI_NOEXCEPT {} + + template + __WI_LIBCPP_INLINE_VISIBILITY + typename _EnableIfConvertible<_Up>::type + operator()(_Up* __ptr) const WI_NOEXCEPT { + static_assert(sizeof(_Tp) > 0, + "default_delete can not delete incomplete type"); + static_assert(!is_void<_Tp>::value, + "default_delete can not delete void type"); + delete[] __ptr; + } + }; + + + +#ifndef __WI_LIBCPP_CXX03_LANG + template + struct __unique_ptr_deleter_sfinae { + static_assert(!is_reference<_Deleter>::value, "incorrect specialization"); + using __lval_ref_type = const _Deleter&; + using __good_rval_ref_type = _Deleter&&; + using __enable_rval_overload = true_type; + }; + + template + struct __unique_ptr_deleter_sfinae<_Deleter const&> { + using __lval_ref_type = const _Deleter&; + using __bad_rval_ref_type = const _Deleter&&; + using __enable_rval_overload = false_type; + }; + + template + struct __unique_ptr_deleter_sfinae<_Deleter&> { + using __lval_ref_type = _Deleter&; + using __bad_rval_ref_type = _Deleter&&; + using __enable_rval_overload = false_type; + }; +#endif // !defined(__WI_LIBCPP_CXX03_LANG) + + template > + class __WI_LIBCPP_TEMPLATE_VIS unique_ptr { + public: + using element_type = _Tp; + using deleter_type = _Dp; + using pointer = typename __pointer_type<_Tp, deleter_type>::type; + + static_assert(!is_rvalue_reference::value, + "the specified deleter type cannot be an rvalue reference"); + + private: + __compressed_pair __ptr_; + + struct __nat { int __for_bool_; }; + +#ifndef __WI_LIBCPP_CXX03_LANG + using _DeleterSFINAE = __unique_ptr_deleter_sfinae<_Dp>; + + template + using _LValRefType = + typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; + + template + using _GoodRValRefType = + typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; + + template + using _BadRValRefType = + typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; + + template , _Dummy>::type> + using _EnableIfDeleterDefaultConstructible = + typename enable_if::value && + !is_pointer<_Deleter>::value>::type; + + template + using _EnableIfDeleterConstructible = + typename enable_if::value>::type; + + template + using _EnableIfMoveConvertible = typename enable_if< + is_convertible::value && + !is_array<_Up>::value + >::type; + + template + using _EnableIfDeleterConvertible = typename enable_if< + (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || + (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) + >::type; + + template + using _EnableIfDeleterAssignable = typename enable_if< + is_assignable<_Dp&, _UDel&&>::value + >::type; + + public: + template > + __WI_LIBCPP_INLINE_VISIBILITY + constexpr unique_ptr() WI_NOEXCEPT : __ptr_(pointer()) {} + + template > + __WI_LIBCPP_INLINE_VISIBILITY + constexpr unique_ptr(nullptr_t) WI_NOEXCEPT : __ptr_(pointer()) {} + + template > + __WI_LIBCPP_INLINE_VISIBILITY + explicit unique_ptr(pointer __p) WI_NOEXCEPT : __ptr_(__p) {} + + template >> + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(pointer __p, _LValRefType<_Dummy> __d) WI_NOEXCEPT + : __ptr_(__p, __d) {} + + template >> + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) WI_NOEXCEPT + : __ptr_(__p, wistd::move(__d)) { + static_assert(!is_reference::value, + "rvalue deleter bound to reference"); + } + + template >> + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete; + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(unique_ptr&& __u) WI_NOEXCEPT + : __ptr_(__u.release(), wistd::forward(__u.get_deleter())) { + } + + template , _Up>, + class = _EnableIfDeleterConvertible<_Ep> + > + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(unique_ptr<_Up, _Ep>&& __u) WI_NOEXCEPT + : __ptr_(__u.release(), wistd::forward<_Ep>(__u.get_deleter())) {} + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr& operator=(unique_ptr&& __u) WI_NOEXCEPT { + reset(__u.release()); + __ptr_.second() = wistd::forward(__u.get_deleter()); + return *this; + } + + template , _Up>, + class = _EnableIfDeleterAssignable<_Ep> + > + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) WI_NOEXCEPT { + reset(__u.release()); + __ptr_.second() = wistd::forward<_Ep>(__u.get_deleter()); + return *this; + } + +#else // __WI_LIBCPP_CXX03_LANG + private: + unique_ptr(unique_ptr&); + template unique_ptr(unique_ptr<_Up, _Ep>&); + + unique_ptr& operator=(unique_ptr&); + template unique_ptr& operator=(unique_ptr<_Up, _Ep>&); + + public: + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr() : __ptr_(pointer()) + { + static_assert(!is_pointer::value, + "unique_ptr constructed with null function pointer deleter"); + static_assert(is_default_constructible::value, + "unique_ptr::deleter_type is not default constructible"); + } + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(nullptr_t) : __ptr_(pointer()) + { + static_assert(!is_pointer::value, + "unique_ptr constructed with null function pointer deleter"); + } + __WI_LIBCPP_INLINE_VISIBILITY + explicit unique_ptr(pointer __p) + : __ptr_(wistd::move(__p)) { + static_assert(!is_pointer::value, + "unique_ptr constructed with null function pointer deleter"); + } + + __WI_LIBCPP_INLINE_VISIBILITY + operator __rv() { + return __rv(*this); + } + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(__rv __u) + : __ptr_(__u->release(), + wistd::forward(__u->get_deleter())) {} + + template + __WI_LIBCPP_INLINE_VISIBILITY + typename enable_if< + !is_array<_Up>::value && + is_convertible::pointer, + pointer>::value && + is_assignable::value, + unique_ptr&>::type + operator=(unique_ptr<_Up, _Ep> __u) { + reset(__u.release()); + __ptr_.second() = wistd::forward<_Ep>(__u.get_deleter()); + return *this; + } + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(pointer __p, deleter_type __d) + : __ptr_(wistd::move(__p), wistd::move(__d)) {} +#endif // __WI_LIBCPP_CXX03_LANG + + __WI_LIBCPP_INLINE_VISIBILITY + ~unique_ptr() { reset(); } + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr& operator=(nullptr_t) WI_NOEXCEPT { + reset(); + return *this; + } + + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + typename add_lvalue_reference<_Tp>::type + operator*() const { + return *__ptr_.first(); + } + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + pointer operator->() const WI_NOEXCEPT { + return __ptr_.first(); + } + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + pointer get() const WI_NOEXCEPT { + return __ptr_.first(); + } + __WI_LIBCPP_INLINE_VISIBILITY + deleter_type& get_deleter() WI_NOEXCEPT { + return __ptr_.second(); + } + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + const deleter_type& get_deleter() const WI_NOEXCEPT { + return __ptr_.second(); + } + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_EXPLICIT operator bool() const WI_NOEXCEPT { + return __ptr_.first() != nullptr; + } + + __WI_LIBCPP_INLINE_VISIBILITY + pointer release() WI_NOEXCEPT { + pointer __t = __ptr_.first(); + __ptr_.first() = pointer(); + return __t; + } + + __WI_LIBCPP_INLINE_VISIBILITY + void reset(pointer __p = pointer()) WI_NOEXCEPT { + pointer __tmp = __ptr_.first(); + __ptr_.first() = __p; + if (__tmp) + __ptr_.second()(__tmp); + } + + __WI_LIBCPP_INLINE_VISIBILITY + void swap(unique_ptr& __u) WI_NOEXCEPT { + __ptr_.swap(__u.__ptr_); + } + }; + + + template + class __WI_LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> { + public: + using element_type = _Tp; + using deleter_type = _Dp; + using pointer = typename __pointer_type<_Tp, deleter_type>::type; + + private: + __compressed_pair __ptr_; + + template + struct _CheckArrayPointerConversion : is_same<_From, pointer> {}; + + template + struct _CheckArrayPointerConversion<_FromElem*> + : integral_constant::value || + (is_same::value && + is_convertible<_FromElem(*)[], element_type(*)[]>::value) + > + {}; + +#ifndef __WI_LIBCPP_CXX03_LANG + using _DeleterSFINAE = __unique_ptr_deleter_sfinae<_Dp>; + + template + using _LValRefType = + typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type; + + template + using _GoodRValRefType = + typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type; + + template + using _BadRValRefType = + typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type; + + template , _Dummy>::type> + using _EnableIfDeleterDefaultConstructible = + typename enable_if::value && + !is_pointer<_Deleter>::value>::type; + + template + using _EnableIfDeleterConstructible = + typename enable_if::value>::type; + + template + using _EnableIfPointerConvertible = typename enable_if< + _CheckArrayPointerConversion<_Pp>::value + >::type; + + template + using _EnableIfMoveConvertible = typename enable_if< + is_array<_Up>::value && + is_same::value && + is_same::value && + is_convertible<_ElemT(*)[], element_type(*)[]>::value + >::type; + + template + using _EnableIfDeleterConvertible = typename enable_if< + (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) || + (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value) + >::type; + + template + using _EnableIfDeleterAssignable = typename enable_if< + is_assignable<_Dp&, _UDel&&>::value + >::type; + + public: + template > + __WI_LIBCPP_INLINE_VISIBILITY + constexpr unique_ptr() WI_NOEXCEPT : __ptr_(pointer()) {} + + template > + __WI_LIBCPP_INLINE_VISIBILITY + constexpr unique_ptr(nullptr_t) WI_NOEXCEPT : __ptr_(pointer()) {} + + template , + class = _EnableIfPointerConvertible<_Pp>> + __WI_LIBCPP_INLINE_VISIBILITY + explicit unique_ptr(_Pp __p) WI_NOEXCEPT + : __ptr_(__p) {} + + template >, + class = _EnableIfPointerConvertible<_Pp>> + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) WI_NOEXCEPT + : __ptr_(__p, __d) {} + + template >> + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) WI_NOEXCEPT + : __ptr_(nullptr, __d) {} + + template >, + class = _EnableIfPointerConvertible<_Pp>> + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) WI_NOEXCEPT + : __ptr_(__p, wistd::move(__d)) { + static_assert(!is_reference::value, + "rvalue deleter bound to reference"); + } + + template >> + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) WI_NOEXCEPT + : __ptr_(nullptr, wistd::move(__d)) { + static_assert(!is_reference::value, + "rvalue deleter bound to reference"); + } + + template >, + class = _EnableIfPointerConvertible<_Pp>> + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete; + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(unique_ptr&& __u) WI_NOEXCEPT + : __ptr_(__u.release(), wistd::forward(__u.get_deleter())) { + } + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr& operator=(unique_ptr&& __u) WI_NOEXCEPT { + reset(__u.release()); + __ptr_.second() = wistd::forward(__u.get_deleter()); + return *this; + } + + template , _Up>, + class = _EnableIfDeleterConvertible<_Ep> + > + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(unique_ptr<_Up, _Ep>&& __u) WI_NOEXCEPT + : __ptr_(__u.release(), wistd::forward<_Ep>(__u.get_deleter())) { + } + + template , _Up>, + class = _EnableIfDeleterAssignable<_Ep> + > + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr& + operator=(unique_ptr<_Up, _Ep>&& __u) WI_NOEXCEPT { + reset(__u.release()); + __ptr_.second() = wistd::forward<_Ep>(__u.get_deleter()); + return *this; + } + +#else // __WI_LIBCPP_CXX03_LANG + private: + template explicit unique_ptr(_Up); + + unique_ptr(unique_ptr&); + template unique_ptr(unique_ptr<_Up>&); + + unique_ptr& operator=(unique_ptr&); + template unique_ptr& operator=(unique_ptr<_Up>&); + + template + unique_ptr(_Up __u, + typename conditional< + is_reference::value, deleter_type, + typename add_lvalue_reference::type>::type, + typename enable_if::value, + __nat>::type = __nat()); + public: + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr() : __ptr_(pointer()) { + static_assert(!is_pointer::value, + "unique_ptr constructed with null function pointer deleter"); + } + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(nullptr_t) : __ptr_(pointer()) { + static_assert(!is_pointer::value, + "unique_ptr constructed with null function pointer deleter"); + } + + __WI_LIBCPP_INLINE_VISIBILITY + explicit unique_ptr(pointer __p) : __ptr_(__p) { + static_assert(!is_pointer::value, + "unique_ptr constructed with null function pointer deleter"); + } + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(pointer __p, deleter_type __d) + : __ptr_(__p, wistd::forward(__d)) {} + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(nullptr_t, deleter_type __d) + : __ptr_(pointer(), wistd::forward(__d)) {} + + __WI_LIBCPP_INLINE_VISIBILITY + operator __rv() { + return __rv(*this); + } + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr(__rv __u) + : __ptr_(__u->release(), + wistd::forward(__u->get_deleter())) {} + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr& operator=(__rv __u) { + reset(__u->release()); + __ptr_.second() = wistd::forward(__u->get_deleter()); + return *this; + } + +#endif // __WI_LIBCPP_CXX03_LANG + + public: + __WI_LIBCPP_INLINE_VISIBILITY + ~unique_ptr() { reset(); } + + __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr& operator=(nullptr_t) WI_NOEXCEPT { + reset(); + return *this; + } + + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + typename add_lvalue_reference<_Tp>::type + operator[](size_t __i) const { + return __ptr_.first()[__i]; + } + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + pointer get() const WI_NOEXCEPT { + return __ptr_.first(); + } + + __WI_LIBCPP_INLINE_VISIBILITY + deleter_type& get_deleter() WI_NOEXCEPT { + return __ptr_.second(); + } + + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + const deleter_type& get_deleter() const WI_NOEXCEPT { + return __ptr_.second(); + } + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_EXPLICIT operator bool() const WI_NOEXCEPT { + return __ptr_.first() != nullptr; + } + + __WI_LIBCPP_INLINE_VISIBILITY + pointer release() WI_NOEXCEPT { + pointer __t = __ptr_.first(); + __ptr_.first() = pointer(); + return __t; + } + + template + __WI_LIBCPP_INLINE_VISIBILITY + typename enable_if< + _CheckArrayPointerConversion<_Pp>::value + >::type + reset(_Pp __p) WI_NOEXCEPT { + pointer __tmp = __ptr_.first(); + __ptr_.first() = __p; + if (__tmp) + __ptr_.second()(__tmp); + } + + __WI_LIBCPP_INLINE_VISIBILITY + void reset(nullptr_t = nullptr) WI_NOEXCEPT { + pointer __tmp = __ptr_.first(); + __ptr_.first() = nullptr; + if (__tmp) + __ptr_.second()(__tmp); + } + + __WI_LIBCPP_INLINE_VISIBILITY + void swap(unique_ptr& __u) WI_NOEXCEPT { + __ptr_.swap(__u.__ptr_); + } + + }; + + // Provide both 'swap_wil' and 'swap' since we now have two ADL scenarios that we need to work + template + inline __WI_LIBCPP_INLINE_VISIBILITY + typename enable_if< + __is_swappable<_Dp>::value, + void + >::type + swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) WI_NOEXCEPT {__x.swap(__y);} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + typename enable_if< + __is_swappable<_Dp>::value, + void + >::type + swap_wil(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) WI_NOEXCEPT {__x.swap(__y);} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) + { + typedef typename unique_ptr<_T1, _D1>::pointer _P1; + typedef typename unique_ptr<_T2, _D2>::pointer _P2; + typedef typename common_type<_P1, _P2>::type _Vp; + return less<_Vp>()(__x.get(), __y.get()); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);} + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) WI_NOEXCEPT + { + return !__x; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) WI_NOEXCEPT + { + return !__x; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) WI_NOEXCEPT + { + return static_cast(__x); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) WI_NOEXCEPT + { + return static_cast(__x); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t) + { + typedef typename unique_ptr<_T1, _D1>::pointer _P1; + return less<_P1>()(__x.get(), nullptr); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x) + { + typedef typename unique_ptr<_T1, _D1>::pointer _P1; + return less<_P1>()(nullptr, __x.get()); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) + { + return nullptr < __x; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) + { + return __x < nullptr; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) + { + return !(nullptr < __x); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) + { + return !(__x < nullptr); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) + { + return !(__x < nullptr); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + bool + operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) + { + return !(nullptr < __x); + } + +#ifdef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + unique_ptr<_Tp, _Dp> + move(unique_ptr<_Tp, _Dp>& __t) + { + return unique_ptr<_Tp, _Dp>(__rv >(__t)); + } + +#endif +} +/// @endcond + +#endif // _WISTD_MEMORY_H_ diff --git a/libraries/wil/wistd_type_traits.h b/libraries/wil/wistd_type_traits.h new file mode 100644 index 0000000..ab81fbd --- /dev/null +++ b/libraries/wil/wistd_type_traits.h @@ -0,0 +1,4504 @@ +// -*- C++ -*- +//===------------------------ type_traits ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// STL common functionality +// +// Some aspects of STL are core language concepts that should be used from all C++ code, regardless +// of whether exceptions are enabled in the component. Common library code that expects to be used +// from exception-free components want these concepts, but including directly introduces +// friction as it requires components not using STL to declare their STL version. Doing so creates +// ambiguity around whether STL use is safe in a particular component and implicitly brings in +// a long list of headers (including ) which can create further ambiguity around throwing new +// support (some routines pulled in may expect it). Secondarily, pulling in these headers also has +// the potential to create naming conflicts or other implied dependencies. +// +// To promote the use of these core language concepts outside of STL-based binaries, this file is +// selectively pulling those concepts *directly* from corresponding STL headers. The corresponding +// "std::" namespace STL functions and types should be preferred over these in code that is bound to +// STL. The implementation and naming of all functions are taken directly from STL, instead using +// "wistd" (Windows Implementation std) as the namespace. +// +// Routines in this namespace should always be considered a reflection of the *current* STL implementation +// of those routines. Updates from STL should be taken, but no "bugs" should be fixed here. +// +// New, exception-based code should not use this namespace, but instead should prefer the std:: implementation. +// Only code that is not exception-based and libraries that expect to be utilized across both exception +// and non-exception based code should utilize this functionality. + +#ifndef _WISTD_TYPE_TRAITS_H_ +#define _WISTD_TYPE_TRAITS_H_ + +// DO NOT add *any* additional includes to this file -- there should be no dependencies from its usage +#include "wistd_config.h" + +#if !defined(__WI_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +/// @cond +namespace wistd // ("Windows Implementation" std) +{ + template struct __WI_LIBCPP_TEMPLATE_VIS pair; + template class __WI_LIBCPP_TEMPLATE_VIS reference_wrapper; + template struct __WI_LIBCPP_TEMPLATE_VIS hash; + + template + struct __void_t { typedef void type; }; + + template + struct __identity { typedef _Tp type; }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS __dependent_type : public _Tp {}; + + template + struct __WI_LIBCPP_TEMPLATE_VIS conditional {typedef _If type;}; + template + struct __WI_LIBCPP_TEMPLATE_VIS conditional {typedef _Then type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using conditional_t = typename conditional<_Bp, _If, _Then>::type; +#endif + + template struct __WI_LIBCPP_TEMPLATE_VIS __lazy_enable_if {}; + template struct __WI_LIBCPP_TEMPLATE_VIS __lazy_enable_if {typedef typename _Tp::type type;}; + + template struct __WI_LIBCPP_TEMPLATE_VIS enable_if {}; + template struct __WI_LIBCPP_TEMPLATE_VIS enable_if {typedef _Tp type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using enable_if_t = typename enable_if<_Bp, _Tp>::type; +#endif + + // addressof +#ifndef __WI_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF + + template + inline __WI_LIBCPP_CONSTEXPR_AFTER_CXX14 + __WI_LIBCPP_NO_CFI __WI_LIBCPP_INLINE_VISIBILITY + _Tp* + addressof(_Tp& __x) WI_NOEXCEPT + { + return __builtin_addressof(__x); + } + +#else + + template + inline __WI_LIBCPP_NO_CFI __WI_LIBCPP_INLINE_VISIBILITY + _Tp* + addressof(_Tp& __x) WI_NOEXCEPT + { + return reinterpret_cast<_Tp *>( + const_cast(&reinterpret_cast(__x))); + } + +#endif // __WI_LIBCPP_HAS_NO_BUILTIN_ADDRESSOF + +#if !defined(__WI_LIBCPP_CXX03_LANG) + template _Tp* addressof(const _Tp&&) WI_NOEXCEPT = delete; +#endif + + struct __two {char __lx[2];}; + + // helper class: + + template + struct __WI_LIBCPP_TEMPLATE_VIS integral_constant + { + static __WI_LIBCPP_CONSTEXPR const _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant type; + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_CONSTEXPR operator value_type() const WI_NOEXCEPT {return value;} +#if __WI_LIBCPP_STD_VER > 11 + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_INLINE_VISIBILITY + constexpr value_type operator ()() const WI_NOEXCEPT {return value;} +#endif + }; + + template + __WI_LIBCPP_CONSTEXPR const _Tp integral_constant<_Tp, __v>::value; + +#if !defined(__WI_LIBCPP_CXX03_LANG) + template + using bool_constant = integral_constant; +#define __WI_LIBCPP_BOOL_CONSTANT(__b) bool_constant<(__b)> +#else +#define __WI_LIBCPP_BOOL_CONSTANT(__b) integral_constant +#endif + + typedef __WI_LIBCPP_BOOL_CONSTANT(true) true_type; + typedef __WI_LIBCPP_BOOL_CONSTANT(false) false_type; + +#if !defined(__WI_LIBCPP_CXX03_LANG) + + // __lazy_and + + template + struct __lazy_and_impl; + + template + struct __lazy_and_impl : false_type {}; + + template <> + struct __lazy_and_impl : true_type {}; + + template + struct __lazy_and_impl : integral_constant {}; + + template + struct __lazy_and_impl : __lazy_and_impl<_Hp::type::value, _Tp...> {}; + + template + struct __lazy_and : __lazy_and_impl<_P1::type::value, _Pr...> {}; + + // __lazy_or + + template + struct __lazy_or_impl; + + template + struct __lazy_or_impl : true_type {}; + + template <> + struct __lazy_or_impl : false_type {}; + + template + struct __lazy_or_impl + : __lazy_or_impl<_Hp::type::value, _Tp...> {}; + + template + struct __lazy_or : __lazy_or_impl<_P1::type::value, _Pr...> {}; + + // __lazy_not + + template + struct __lazy_not : integral_constant {}; + + // __and_ + template struct __and_; + template<> struct __and_<> : true_type {}; + + template struct __and_<_B0> : _B0 {}; + + template + struct __and_<_B0, _B1> : conditional<_B0::value, _B1, _B0>::type {}; + + template + struct __and_<_B0, _B1, _B2, _Bn...> + : conditional<_B0::value, __and_<_B1, _B2, _Bn...>, _B0>::type {}; + + // __or_ + template struct __or_; + template<> struct __or_<> : false_type {}; + + template struct __or_<_B0> : _B0 {}; + + template + struct __or_<_B0, _B1> : conditional<_B0::value, _B0, _B1>::type {}; + + template + struct __or_<_B0, _B1, _B2, _Bn...> + : conditional<_B0::value, _B0, __or_<_B1, _B2, _Bn...> >::type {}; + + // __not_ + template + struct __not_ : conditional<_Tp::value, false_type, true_type>::type {}; + +#endif // !defined(__WI_LIBCPP_CXX03_LANG) + + // is_const + + template struct __WI_LIBCPP_TEMPLATE_VIS is_const : public false_type {}; + template struct __WI_LIBCPP_TEMPLATE_VIS is_const<_Tp const> : public true_type {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_const_v + = is_const<_Tp>::value; +#endif + + // is_volatile + + template struct __WI_LIBCPP_TEMPLATE_VIS is_volatile : public false_type {}; + template struct __WI_LIBCPP_TEMPLATE_VIS is_volatile<_Tp volatile> : public true_type {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_volatile_v + = is_volatile<_Tp>::value; +#endif + + // remove_const + + template struct __WI_LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_const {typedef _Tp type;}; +#if __WI_LIBCPP_STD_VER > 11 + template using remove_const_t = typename remove_const<_Tp>::type; +#endif + + // remove_volatile + + template struct __WI_LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_volatile {typedef _Tp type;}; +#if __WI_LIBCPP_STD_VER > 11 + template using remove_volatile_t = typename remove_volatile<_Tp>::type; +#endif + + // remove_cv + + template struct __WI_LIBCPP_TEMPLATE_VIS remove_cv + {typedef typename remove_volatile::type>::type type;}; +#if __WI_LIBCPP_STD_VER > 11 + template using remove_cv_t = typename remove_cv<_Tp>::type; +#endif + + // is_void + + template struct __libcpp_is_void : public false_type {}; + template <> struct __libcpp_is_void : public true_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_void + : public __libcpp_is_void::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_void_v + = is_void<_Tp>::value; +#endif + + // __is_nullptr_t + + template struct __is_nullptr_t_impl : public false_type {}; + template <> struct __is_nullptr_t_impl : public true_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS __is_nullptr_t + : public __is_nullptr_t_impl::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 + template struct __WI_LIBCPP_TEMPLATE_VIS is_null_pointer + : public __is_nullptr_t_impl::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_null_pointer_v + = is_null_pointer<_Tp>::value; +#endif +#endif + + // is_integral + + template struct __libcpp_is_integral : public false_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; +#ifdef _MSC_VER + template <> struct __libcpp_is_integral<__wchar_t> : public true_type {}; +#else + template <> struct __libcpp_is_integral : public true_type {}; +#endif +#ifndef __WI_LIBCPP_HAS_NO_UNICODE_CHARS + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; +#endif // __WI_LIBCPP_HAS_NO_UNICODE_CHARS + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; + template <> struct __libcpp_is_integral : public true_type {}; +#ifndef __WI_LIBCPP_HAS_NO_INT128 + template <> struct __libcpp_is_integral<__int128_t> : public true_type {}; + template <> struct __libcpp_is_integral<__uint128_t> : public true_type {}; +#endif + + template struct __WI_LIBCPP_TEMPLATE_VIS is_integral + : public __libcpp_is_integral::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_integral_v + = is_integral<_Tp>::value; +#endif + + // is_floating_point + + template struct __libcpp_is_floating_point : public false_type {}; + template <> struct __libcpp_is_floating_point : public true_type {}; + template <> struct __libcpp_is_floating_point : public true_type {}; + template <> struct __libcpp_is_floating_point : public true_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_floating_point + : public __libcpp_is_floating_point::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_floating_point_v + = is_floating_point<_Tp>::value; +#endif + + // is_array + + template struct __WI_LIBCPP_TEMPLATE_VIS is_array + : public false_type {}; + template struct __WI_LIBCPP_TEMPLATE_VIS is_array<_Tp[]> + : public true_type {}; + template struct __WI_LIBCPP_TEMPLATE_VIS is_array<_Tp[_Np]> + : public true_type {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_array_v + = is_array<_Tp>::value; +#endif + + // is_pointer + + template struct __libcpp_is_pointer : public false_type {}; + template struct __libcpp_is_pointer<_Tp*> : public true_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_pointer + : public __libcpp_is_pointer::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_pointer_v + = is_pointer<_Tp>::value; +#endif + + // is_reference + + template struct __WI_LIBCPP_TEMPLATE_VIS is_lvalue_reference : public false_type {}; + template struct __WI_LIBCPP_TEMPLATE_VIS is_lvalue_reference<_Tp&> : public true_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_rvalue_reference : public false_type {}; +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + template struct __WI_LIBCPP_TEMPLATE_VIS is_rvalue_reference<_Tp&&> : public true_type {}; +#endif + + template struct __WI_LIBCPP_TEMPLATE_VIS is_reference : public false_type {}; + template struct __WI_LIBCPP_TEMPLATE_VIS is_reference<_Tp&> : public true_type {}; +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + template struct __WI_LIBCPP_TEMPLATE_VIS is_reference<_Tp&&> : public true_type {}; +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_reference_v + = is_reference<_Tp>::value; + + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_lvalue_reference_v + = is_lvalue_reference<_Tp>::value; + + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_rvalue_reference_v + = is_rvalue_reference<_Tp>::value; +#endif + // is_union + +#if __WI_HAS_FEATURE_IS_UNION || (__WI_GNUC_VER >= 403) + + template struct __WI_LIBCPP_TEMPLATE_VIS is_union + : public integral_constant {}; + +#else + + template struct __libcpp_union : public false_type {}; + template struct __WI_LIBCPP_TEMPLATE_VIS is_union + : public __libcpp_union::type> {}; + +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_union_v + = is_union<_Tp>::value; +#endif + + // is_class + +#if __WI_HAS_FEATURE_IS_CLASS || (__WI_GNUC_VER >= 403) + + template struct __WI_LIBCPP_TEMPLATE_VIS is_class + : public integral_constant {}; + +#else + + namespace __is_class_imp + { + template char __test(int _Tp::*); + template __two __test(...); + } + + template struct __WI_LIBCPP_TEMPLATE_VIS is_class + : public integral_constant(0)) == 1 && !is_union<_Tp>::value> {}; + +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_class_v + = is_class<_Tp>::value; +#endif + + // is_same + + template struct __WI_LIBCPP_TEMPLATE_VIS is_same : public false_type {}; + template struct __WI_LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_same_v + = is_same<_Tp, _Up>::value; +#endif + + // is_function + + namespace __libcpp_is_function_imp + { + struct __dummy_type {}; + template char __test(_Tp*); + template char __test(__dummy_type); + template __two __test(...); + template _Tp& __source(int); + template __dummy_type __source(...); + } + + template ::value || + is_union<_Tp>::value || + is_void<_Tp>::value || + is_reference<_Tp>::value || + __is_nullptr_t<_Tp>::value > + struct __libcpp_is_function + : public integral_constant(__libcpp_is_function_imp::__source<_Tp>(0))) == 1> + {}; + template struct __libcpp_is_function<_Tp, true> : public false_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_function + : public __libcpp_is_function<_Tp> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_function_v + = is_function<_Tp>::value; +#endif + + // is_member_function_pointer + + // template struct __libcpp_is_member_function_pointer : public false_type {}; + // template struct __libcpp_is_member_function_pointer<_Tp _Up::*> : public is_function<_Tp> {}; + // + + template + struct __member_pointer_traits_imp + { // forward declaration; specializations later + }; + + + template struct __libcpp_is_member_function_pointer + : public false_type {}; + + template + struct __libcpp_is_member_function_pointer<_Ret _Class::*> + : public is_function<_Ret> {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_member_function_pointer + : public __libcpp_is_member_function_pointer::type>::type {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_member_function_pointer_v + = is_member_function_pointer<_Tp>::value; +#endif + + // is_member_pointer + + template struct __libcpp_is_member_pointer : public false_type {}; + template struct __libcpp_is_member_pointer<_Tp _Up::*> : public true_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_member_pointer + : public __libcpp_is_member_pointer::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_member_pointer_v + = is_member_pointer<_Tp>::value; +#endif + + // is_member_object_pointer + + template struct __WI_LIBCPP_TEMPLATE_VIS is_member_object_pointer + : public integral_constant::value && + !is_member_function_pointer<_Tp>::value> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_member_object_pointer_v + = is_member_object_pointer<_Tp>::value; +#endif + + // is_enum + +#if __WI_HAS_FEATURE_IS_ENUM || (__WI_GNUC_VER >= 403) + + template struct __WI_LIBCPP_TEMPLATE_VIS is_enum + : public integral_constant {}; + +#else + + template struct __WI_LIBCPP_TEMPLATE_VIS is_enum + : public integral_constant::value && + !is_integral<_Tp>::value && + !is_floating_point<_Tp>::value && + !is_array<_Tp>::value && + !is_pointer<_Tp>::value && + !is_reference<_Tp>::value && + !is_member_pointer<_Tp>::value && + !is_union<_Tp>::value && + !is_class<_Tp>::value && + !is_function<_Tp>::value > {}; + +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_enum_v + = is_enum<_Tp>::value; +#endif + + // is_arithmetic + + template struct __WI_LIBCPP_TEMPLATE_VIS is_arithmetic + : public integral_constant::value || + is_floating_point<_Tp>::value> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_arithmetic_v + = is_arithmetic<_Tp>::value; +#endif + + // is_fundamental + + template struct __WI_LIBCPP_TEMPLATE_VIS is_fundamental + : public integral_constant::value || + __is_nullptr_t<_Tp>::value || + is_arithmetic<_Tp>::value> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_fundamental_v + = is_fundamental<_Tp>::value; +#endif + + // is_scalar + + template struct __WI_LIBCPP_TEMPLATE_VIS is_scalar + : public integral_constant::value || + is_member_pointer<_Tp>::value || + is_pointer<_Tp>::value || + __is_nullptr_t<_Tp>::value || + is_enum<_Tp>::value > {}; + + template <> struct __WI_LIBCPP_TEMPLATE_VIS is_scalar : public true_type {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_scalar_v + = is_scalar<_Tp>::value; +#endif + + // is_object + + template struct __WI_LIBCPP_TEMPLATE_VIS is_object + : public integral_constant::value || + is_array<_Tp>::value || + is_union<_Tp>::value || + is_class<_Tp>::value > {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_object_v + = is_object<_Tp>::value; +#endif + + // is_compound + + template struct __WI_LIBCPP_TEMPLATE_VIS is_compound + : public integral_constant::value> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_compound_v + = is_compound<_Tp>::value; +#endif + + + // __is_referenceable [defns.referenceable] + + struct __is_referenceable_impl { + template static _Tp& __test(int); + template static __two __test(...); + }; + + template + struct __is_referenceable : integral_constant(0)), __two>::value> {}; + + + // add_const + + template ::value || + is_function<_Tp>::value || + is_const<_Tp>::value > + struct __add_const {typedef _Tp type;}; + + template + struct __add_const<_Tp, false> {typedef const _Tp type;}; + + template struct __WI_LIBCPP_TEMPLATE_VIS add_const + {typedef typename __add_const<_Tp>::type type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using add_const_t = typename add_const<_Tp>::type; +#endif + + // add_volatile + + template ::value || + is_function<_Tp>::value || + is_volatile<_Tp>::value > + struct __add_volatile {typedef _Tp type;}; + + template + struct __add_volatile<_Tp, false> {typedef volatile _Tp type;}; + + template struct __WI_LIBCPP_TEMPLATE_VIS add_volatile + {typedef typename __add_volatile<_Tp>::type type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using add_volatile_t = typename add_volatile<_Tp>::type; +#endif + + // add_cv + + template struct __WI_LIBCPP_TEMPLATE_VIS add_cv + {typedef typename add_const::type>::type type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using add_cv_t = typename add_cv<_Tp>::type; +#endif + + // remove_reference + + template struct __WI_LIBCPP_TEMPLATE_VIS remove_reference {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_reference<_Tp&> {typedef _Tp type;}; +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + template struct __WI_LIBCPP_TEMPLATE_VIS remove_reference<_Tp&&> {typedef _Tp type;}; +#endif + +#if __WI_LIBCPP_STD_VER > 11 + template using remove_reference_t = typename remove_reference<_Tp>::type; +#endif + + // add_lvalue_reference + + template ::value> struct __add_lvalue_reference_impl { typedef _Tp type; }; + template struct __add_lvalue_reference_impl<_Tp, true> { typedef _Tp& type; }; + + template struct __WI_LIBCPP_TEMPLATE_VIS add_lvalue_reference + {typedef typename __add_lvalue_reference_impl<_Tp>::type type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; +#endif + +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template ::value> struct __add_rvalue_reference_impl { typedef _Tp type; }; + template struct __add_rvalue_reference_impl<_Tp, true> { typedef _Tp&& type; }; + + template struct __WI_LIBCPP_TEMPLATE_VIS add_rvalue_reference + {typedef typename __add_rvalue_reference_impl<_Tp>::type type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; +#endif + +#endif // __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + // MSVC has issues compiling some source code that uses the libc++ definition of 'declval' +#ifdef _MSC_VER + template + typename add_rvalue_reference<_Tp>::type declval() WI_NOEXCEPT; +#else + template _Tp&& __declval(int); + template _Tp __declval(long); + + template + decltype(__declval<_Tp>(0)) + declval() WI_NOEXCEPT; +#endif + +#else // __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + typename add_lvalue_reference<_Tp>::type + declval(); + +#endif // __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + // __uncvref + + template + struct __uncvref { + typedef typename remove_cv::type>::type type; + }; + + template + struct __unconstref { + typedef typename remove_const::type>::type type; + }; + +#ifndef __WI_LIBCPP_CXX03_LANG + template + using __uncvref_t = typename __uncvref<_Tp>::type; +#endif + + // __is_same_uncvref + + template + struct __is_same_uncvref : is_same::type, + typename __uncvref<_Up>::type> {}; + +#if __WI_LIBCPP_STD_VER > 17 + // remove_cvref - same as __uncvref + template + struct remove_cvref : public __uncvref<_Tp> {}; + + template using remove_cvref_t = typename remove_cvref<_Tp>::type; +#endif + + + struct __any + { + __any(...); + }; + + // remove_pointer + + template struct __WI_LIBCPP_TEMPLATE_VIS remove_pointer {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_pointer<_Tp*> {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const> {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* volatile> {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_pointer<_Tp* const volatile> {typedef _Tp type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using remove_pointer_t = typename remove_pointer<_Tp>::type; +#endif + + // add_pointer + + template ::value || + is_same::type, void>::value> + struct __add_pointer_impl + {typedef typename remove_reference<_Tp>::type* type;}; + template struct __add_pointer_impl<_Tp, false> + {typedef _Tp type;}; + + template struct __WI_LIBCPP_TEMPLATE_VIS add_pointer + {typedef typename __add_pointer_impl<_Tp>::type type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using add_pointer_t = typename add_pointer<_Tp>::type; +#endif + + // type_identity +#if __WI_LIBCPP_STD_VER > 17 + template struct type_identity { typedef _Tp type; }; + template using type_identity_t = typename type_identity<_Tp>::type; +#endif + + // is_signed + + template ::value> + struct __libcpp_is_signed_impl : public __WI_LIBCPP_BOOL_CONSTANT(_Tp(-1) < _Tp(0)) {}; + + template + struct __libcpp_is_signed_impl<_Tp, false> : public true_type {}; // floating point + + template ::value> + struct __libcpp_is_signed : public __libcpp_is_signed_impl<_Tp> {}; + + template struct __libcpp_is_signed<_Tp, false> : public false_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_signed : public __libcpp_is_signed<_Tp> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_signed_v + = is_signed<_Tp>::value; +#endif + + // is_unsigned + + template ::value> + struct __libcpp_is_unsigned_impl : public __WI_LIBCPP_BOOL_CONSTANT(_Tp(0) < _Tp(-1)) {}; + + template + struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {}; // floating point + + template ::value> + struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {}; + + template struct __libcpp_is_unsigned<_Tp, false> : public false_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_unsigned : public __libcpp_is_unsigned<_Tp> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_unsigned_v + = is_unsigned<_Tp>::value; +#endif + + // rank + + template struct __WI_LIBCPP_TEMPLATE_VIS rank + : public integral_constant {}; + template struct __WI_LIBCPP_TEMPLATE_VIS rank<_Tp[]> + : public integral_constant::value + 1> {}; + template struct __WI_LIBCPP_TEMPLATE_VIS rank<_Tp[_Np]> + : public integral_constant::value + 1> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR size_t rank_v + = rank<_Tp>::value; +#endif + + // extent + + template struct __WI_LIBCPP_TEMPLATE_VIS extent + : public integral_constant {}; + template struct __WI_LIBCPP_TEMPLATE_VIS extent<_Tp[], 0> + : public integral_constant {}; + template struct __WI_LIBCPP_TEMPLATE_VIS extent<_Tp[], _Ip> + : public integral_constant::value> {}; + template struct __WI_LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], 0> + : public integral_constant {}; + template struct __WI_LIBCPP_TEMPLATE_VIS extent<_Tp[_Np], _Ip> + : public integral_constant::value> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR size_t extent_v + = extent<_Tp, _Ip>::value; +#endif + + // remove_extent + + template struct __WI_LIBCPP_TEMPLATE_VIS remove_extent + {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_extent<_Tp[]> + {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_extent<_Tp[_Np]> + {typedef _Tp type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using remove_extent_t = typename remove_extent<_Tp>::type; +#endif + + // remove_all_extents + + template struct __WI_LIBCPP_TEMPLATE_VIS remove_all_extents + {typedef _Tp type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[]> + {typedef typename remove_all_extents<_Tp>::type type;}; + template struct __WI_LIBCPP_TEMPLATE_VIS remove_all_extents<_Tp[_Np]> + {typedef typename remove_all_extents<_Tp>::type type;}; + +#if __WI_LIBCPP_STD_VER > 11 + template using remove_all_extents_t = typename remove_all_extents<_Tp>::type; +#endif + + // decay + + template + struct __decay { + typedef typename remove_cv<_Up>::type type; + }; + + template + struct __decay<_Up, true> { + public: + typedef typename conditional + < + is_array<_Up>::value, + typename remove_extent<_Up>::type*, + typename conditional + < + is_function<_Up>::value, + typename add_pointer<_Up>::type, + typename remove_cv<_Up>::type + >::type + >::type type; + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS decay + { + private: + typedef typename remove_reference<_Tp>::type _Up; + public: + typedef typename __decay<_Up, __is_referenceable<_Up>::value>::type type; + }; + +#if __WI_LIBCPP_STD_VER > 11 + template using decay_t = typename decay<_Tp>::type; +#endif + + // is_abstract + + template struct __WI_LIBCPP_TEMPLATE_VIS is_abstract + : public integral_constant {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_abstract_v + = is_abstract<_Tp>::value; +#endif + + // is_final + +#if defined(__WI_LIBCPP_HAS_IS_FINAL) + template struct __WI_LIBCPP_TEMPLATE_VIS + __libcpp_is_final : public integral_constant {}; +#else + template struct __WI_LIBCPP_TEMPLATE_VIS + __libcpp_is_final : public false_type {}; +#endif + +#if defined(__WI_LIBCPP_HAS_IS_FINAL) && __WI_LIBCPP_STD_VER > 11 + template struct __WI_LIBCPP_TEMPLATE_VIS + is_final : public integral_constant {}; +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_final_v + = is_final<_Tp>::value; +#endif + + // is_aggregate +#if __WI_LIBCPP_STD_VER > 14 && !defined(__WI_LIBCPP_HAS_NO_IS_AGGREGATE) + + template struct __WI_LIBCPP_TEMPLATE_VIS + is_aggregate : public integral_constant {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_aggregate_v + = is_aggregate<_Tp>::value; +#endif + +#endif // __WI_LIBCPP_STD_VER > 14 && !defined(__WI_LIBCPP_HAS_NO_IS_AGGREGATE) + + // is_base_of + +#ifdef __WI_LIBCPP_HAS_IS_BASE_OF + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_base_of + : public integral_constant {}; + +#else // __WI_LIBCPP_HAS_IS_BASE_OF + + namespace __is_base_of_imp + { + template + struct _Dst + { + _Dst(const volatile _Tp &); + }; + template + struct _Src + { + operator const volatile _Tp &(); + template operator const _Dst<_Up> &(); + }; + template struct __one { typedef char type; }; + template typename __one(declval<_Src<_Dp> >()))>::type __test(int); + template __two __test(...); + } + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_base_of + : public integral_constant::value && + sizeof(__is_base_of_imp::__test<_Bp, _Dp>(0)) == 2> {}; + +#endif // __WI_LIBCPP_HAS_IS_BASE_OF + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_base_of_v + = is_base_of<_Bp, _Dp>::value; +#endif + + // is_convertible + +#if __WI_HAS_FEATURE_IS_CONVERTIBLE_TO && !defined(__WI_LIBCPP_USE_IS_CONVERTIBLE_FALLBACK) + + template struct __WI_LIBCPP_TEMPLATE_VIS is_convertible + : public integral_constant::value> {}; + +#else // __WI_HAS_FEATURE_IS_CONVERTIBLE_TO + + namespace __is_convertible_imp + { + template void __test_convert(_Tp); + + template + struct __is_convertible_test : public false_type {}; + + template + struct __is_convertible_test<_From, _To, + decltype(__is_convertible_imp::__test_convert<_To>(declval<_From>()))> : public true_type + {}; + + template ::value, + bool _IsFunction = is_function<_Tp>::value, + bool _IsVoid = is_void<_Tp>::value> + struct __is_array_function_or_void {enum {value = 0};}; + template struct __is_array_function_or_void<_Tp, true, false, false> {enum {value = 1};}; + template struct __is_array_function_or_void<_Tp, false, true, false> {enum {value = 2};}; + template struct __is_array_function_or_void<_Tp, false, false, true> {enum {value = 3};}; + } + + template ::type>::value> + struct __is_convertible_check + { + static const size_t __v = 0; + }; + + template + struct __is_convertible_check<_Tp, 0> + { + static const size_t __v = sizeof(_Tp); + }; + + template ::value, + unsigned _T2_is_array_function_or_void = __is_convertible_imp::__is_array_function_or_void<_T2>::value> + struct __is_convertible + : public integral_constant::value +#if defined(__WI_LIBCPP_HAS_NO_RVALUE_REFERENCES) + && !(!is_function<_T1>::value && !is_reference<_T1>::value && is_reference<_T2>::value + && (!is_const::type>::value + || is_volatile::type>::value) + && (is_same::type, + typename remove_cv::type>::type>::value + || is_base_of::type, _T1>::value)) +#endif + > + {}; + + template struct __is_convertible<_T1, _T2, 0, 1> : public false_type {}; + template struct __is_convertible<_T1, _T2, 1, 1> : public false_type {}; + template struct __is_convertible<_T1, _T2, 2, 1> : public false_type {}; + template struct __is_convertible<_T1, _T2, 3, 1> : public false_type {}; + + template struct __is_convertible<_T1, _T2, 0, 2> : public false_type {}; + template struct __is_convertible<_T1, _T2, 1, 2> : public false_type {}; + template struct __is_convertible<_T1, _T2, 2, 2> : public false_type {}; + template struct __is_convertible<_T1, _T2, 3, 2> : public false_type {}; + + template struct __is_convertible<_T1, _T2, 0, 3> : public false_type {}; + template struct __is_convertible<_T1, _T2, 1, 3> : public false_type {}; + template struct __is_convertible<_T1, _T2, 2, 3> : public false_type {}; + template struct __is_convertible<_T1, _T2, 3, 3> : public true_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_convertible + : public __is_convertible<_T1, _T2> + { + static const size_t __complete_check1 = __is_convertible_check<_T1>::__v; + static const size_t __complete_check2 = __is_convertible_check<_T2>::__v; + }; + +#endif // __WI_HAS_FEATURE_IS_CONVERTIBLE_TO + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_convertible_v + = is_convertible<_From, _To>::value; +#endif + + // is_empty + +#if __WI_HAS_FEATURE_IS_EMPTY || (__WI_GNUC_VER >= 407) + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_empty + : public integral_constant {}; + +#else // __WI_HAS_FEATURE_IS_EMPTY + + template + struct __is_empty1 + : public _Tp + { + double __lx; + }; + + struct __is_empty2 + { + double __lx; + }; + + template ::value> + struct __libcpp_empty : public integral_constant) == sizeof(__is_empty2)> {}; + + template struct __libcpp_empty<_Tp, false> : public false_type {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_empty : public __libcpp_empty<_Tp> {}; + +#endif // __WI_HAS_FEATURE_IS_EMPTY + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_empty_v + = is_empty<_Tp>::value; +#endif + + // is_polymorphic + +#if __WI_HAS_FEATURE_IS_POLYMORPHIC + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_polymorphic + : public integral_constant {}; + +#else + + template char &__is_polymorphic_impl( + typename enable_if(declval<_Tp*>())) != 0, + int>::type); + template __two &__is_polymorphic_impl(...); + + template struct __WI_LIBCPP_TEMPLATE_VIS is_polymorphic + : public integral_constant(0)) == 1> {}; + +#endif // __WI_HAS_FEATURE_IS_POLYMORPHIC + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_polymorphic_v + = is_polymorphic<_Tp>::value; +#endif + + // has_virtual_destructor + +#if __WI_HAS_FEATURE_HAS_VIRTUAL_DESTRUCTOR || (__WI_GNUC_VER >= 403) + + template struct __WI_LIBCPP_TEMPLATE_VIS has_virtual_destructor + : public integral_constant {}; + +#else + + template struct __WI_LIBCPP_TEMPLATE_VIS has_virtual_destructor + : public false_type {}; + +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool has_virtual_destructor_v + = has_virtual_destructor<_Tp>::value; +#endif + + // has_unique_object_representations + +#if __WI_LIBCPP_STD_VER > 14 && defined(__WI_LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS) + + template struct __WI_LIBCPP_TEMPLATE_VIS has_unique_object_representations + : public integral_constant>)> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool has_unique_object_representations_v + = has_unique_object_representations<_Tp>::value; +#endif + +#endif + + // alignment_of + + template struct __WI_LIBCPP_TEMPLATE_VIS alignment_of + : public integral_constant {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR size_t alignment_of_v + = alignment_of<_Tp>::value; +#endif + + // aligned_storage + + template + struct __type_list + { + typedef _Hp _Head; + typedef _Tp _Tail; + }; + + struct __nat + { +#ifndef __WI_LIBCPP_CXX03_LANG + __nat() = delete; + __nat(const __nat&) = delete; + __nat& operator=(const __nat&) = delete; + ~__nat() = delete; +#endif + }; + + template + struct __align_type + { + static const size_t value = alignment_of<_Tp>::value; + typedef _Tp type; + }; + + struct __struct_double {long double __lx;}; + struct __struct_double4 {double __lx[4];}; + + typedef + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type, + __type_list<__align_type<__struct_double>, + __type_list<__align_type<__struct_double4>, + __type_list<__align_type, + __nat + > > > > > > > > > > __all_types; + + template struct __find_pod; + + template + struct __find_pod<__type_list<_Hp, __nat>, _Align> + { + typedef typename conditional< + _Align == _Hp::value, + typename _Hp::type, + void + >::type type; + }; + + template + struct __find_pod<__type_list<_Hp, _Tp>, _Align> + { + typedef typename conditional< + _Align == _Hp::value, + typename _Hp::type, + typename __find_pod<_Tp, _Align>::type + >::type type; + }; + + template + struct __has_pod_with_align : public integral_constant::type, void>::value> {}; + + template struct __find_max_align; + + template + struct __find_max_align<__type_list<_Hp, __nat>, _Len> : public integral_constant {}; + + template + struct __select_align + { + private: + static const size_t __min = _A2 < _A1 ? _A2 : _A1; + static const size_t __max = _A1 < _A2 ? _A2 : _A1; + public: + static const size_t value = _Len < __max ? __min : __max; + }; + + template + struct __find_max_align<__type_list<_Hp, _Tp>, _Len> + : public integral_constant::value>::value> {}; + + template ::value> + struct __aligned_storage + { + typedef typename __find_pod<__all_types, _Align>::type _Aligner; + static_assert(!is_void<_Aligner>::value, ""); + union type + { + _Aligner __align; + unsigned char __data[(_Len + _Align - 1)/_Align * _Align]; + }; + }; + +#define __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(n) \ + template \ + struct __aligned_storage<_Len, n, false>\ + {\ + struct __WI_ALIGNAS(n) type\ + {\ + unsigned char __lx[(_Len + n - 1)/n * n];\ + };\ + } + + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x8); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x10); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x20); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x40); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x80); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x100); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x200); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x400); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x800); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x1000); + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x2000); + // PE/COFF does not support alignment beyond 8192 (=0x2000) +#if !defined(__WI_LIBCPP_OBJECT_FORMAT_COFF) + __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION(0x4000); +#endif // !defined(__WI_LIBCPP_OBJECT_FORMAT_COFF) + +#undef __WI_CREATE_ALIGNED_STORAGE_SPECIALIZATION + + template ::value> + struct __WI_LIBCPP_TEMPLATE_VIS aligned_storage : public __aligned_storage<_Len, _Align> {}; + +#if __WI_LIBCPP_STD_VER > 11 + template ::value> + using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; +#endif + +#ifndef __WI_LIBCPP_HAS_NO_VARIADICS + + // aligned_union + + template + struct __static_max; + + template + struct __static_max<_I0> + { + static const size_t value = _I0; + }; + + template + struct __static_max<_I0, _I1, _In...> + { + static const size_t value = _I0 >= _I1 ? __static_max<_I0, _In...>::value : + __static_max<_I1, _In...>::value; + }; + + template + struct aligned_union + { + static const size_t alignment_value = __static_max<__alignof__(_Type0), + __alignof__(_Types)...>::value; + static const size_t __len = __static_max<_Len, sizeof(_Type0), + sizeof(_Types)...>::value; + typedef typename aligned_storage<__len, alignment_value>::type type; + }; + +#if __WI_LIBCPP_STD_VER > 11 + template using aligned_union_t = typename aligned_union<_Len, _Types...>::type; +#endif + +#endif // __WI_LIBCPP_HAS_NO_VARIADICS + + template + struct __numeric_type + { + static void __test(...); + static float __test(float); + static double __test(char); + static double __test(int); + static double __test(unsigned); + static double __test(long); + static double __test(unsigned long); + static double __test(long long); + static double __test(unsigned long long); + static double __test(double); + static long double __test(long double); + + typedef decltype(__test(declval<_Tp>())) type; + static const bool value = !is_same::value; + }; + + template <> + struct __numeric_type + { + static const bool value = true; + }; + + // __promote + + template ::value && + __numeric_type<_A2>::value && + __numeric_type<_A3>::value> + class __promote_imp + { + public: + static const bool value = false; + }; + + template + class __promote_imp<_A1, _A2, _A3, true> + { + private: + typedef typename __promote_imp<_A1>::type __type1; + typedef typename __promote_imp<_A2>::type __type2; + typedef typename __promote_imp<_A3>::type __type3; + public: + typedef decltype(__type1() + __type2() + __type3()) type; + static const bool value = true; + }; + + template + class __promote_imp<_A1, _A2, void, true> + { + private: + typedef typename __promote_imp<_A1>::type __type1; + typedef typename __promote_imp<_A2>::type __type2; + public: + typedef decltype(__type1() + __type2()) type; + static const bool value = true; + }; + + template + class __promote_imp<_A1, void, void, true> + { + public: + typedef typename __numeric_type<_A1>::type type; + static const bool value = true; + }; + + template + class __promote : public __promote_imp<_A1, _A2, _A3> {}; + + // make_signed / make_unsigned + + typedef + __type_list +#endif + > > > > > __signed_types; + + typedef + __type_list +#endif + > > > > > __unsigned_types; + + template struct __find_first; + + template + struct __find_first<__type_list<_Hp, _Tp>, _Size, true> + { + typedef _Hp type; + }; + + template + struct __find_first<__type_list<_Hp, _Tp>, _Size, false> + { + typedef typename __find_first<_Tp, _Size>::type type; + }; + + template ::type>::value, + bool = is_volatile::type>::value> + struct __apply_cv + { + typedef _Up type; + }; + + template + struct __apply_cv<_Tp, _Up, true, false> + { + typedef const _Up type; + }; + + template + struct __apply_cv<_Tp, _Up, false, true> + { + typedef volatile _Up type; + }; + + template + struct __apply_cv<_Tp, _Up, true, true> + { + typedef const volatile _Up type; + }; + + template + struct __apply_cv<_Tp&, _Up, false, false> + { + typedef _Up& type; + }; + + template + struct __apply_cv<_Tp&, _Up, true, false> + { + typedef const _Up& type; + }; + + template + struct __apply_cv<_Tp&, _Up, false, true> + { + typedef volatile _Up& type; + }; + + template + struct __apply_cv<_Tp&, _Up, true, true> + { + typedef const volatile _Up& type; + }; + + template ::value || is_enum<_Tp>::value> + struct __make_signed {}; + + template + struct __make_signed<_Tp, true> + { + typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type; + }; + + template <> struct __make_signed {}; + template <> struct __make_signed< signed short, true> {typedef short type;}; + template <> struct __make_signed {typedef short type;}; + template <> struct __make_signed< signed int, true> {typedef int type;}; + template <> struct __make_signed {typedef int type;}; + template <> struct __make_signed< signed long, true> {typedef long type;}; + template <> struct __make_signed {typedef long type;}; + template <> struct __make_signed< signed long long, true> {typedef long long type;}; + template <> struct __make_signed {typedef long long type;}; +#ifndef __WI_LIBCPP_HAS_NO_INT128 + template <> struct __make_signed<__int128_t, true> {typedef __int128_t type;}; + template <> struct __make_signed<__uint128_t, true> {typedef __int128_t type;}; +#endif + + template + struct __WI_LIBCPP_TEMPLATE_VIS make_signed + { + typedef typename __apply_cv<_Tp, typename __make_signed::type>::type>::type type; + }; + +#if __WI_LIBCPP_STD_VER > 11 + template using make_signed_t = typename make_signed<_Tp>::type; +#endif + + template ::value || is_enum<_Tp>::value> + struct __make_unsigned {}; + + template + struct __make_unsigned<_Tp, true> + { + typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type; + }; + + template <> struct __make_unsigned {}; + template <> struct __make_unsigned< signed short, true> {typedef unsigned short type;}; + template <> struct __make_unsigned {typedef unsigned short type;}; + template <> struct __make_unsigned< signed int, true> {typedef unsigned int type;}; + template <> struct __make_unsigned {typedef unsigned int type;}; + template <> struct __make_unsigned< signed long, true> {typedef unsigned long type;}; + template <> struct __make_unsigned {typedef unsigned long type;}; + template <> struct __make_unsigned< signed long long, true> {typedef unsigned long long type;}; + template <> struct __make_unsigned {typedef unsigned long long type;}; +#ifndef __WI_LIBCPP_HAS_NO_INT128 + template <> struct __make_unsigned<__int128_t, true> {typedef __uint128_t type;}; + template <> struct __make_unsigned<__uint128_t, true> {typedef __uint128_t type;}; +#endif + + template + struct __WI_LIBCPP_TEMPLATE_VIS make_unsigned + { + typedef typename __apply_cv<_Tp, typename __make_unsigned::type>::type>::type type; + }; + +#if __WI_LIBCPP_STD_VER > 11 + template using make_unsigned_t = typename make_unsigned<_Tp>::type; +#endif + +#ifdef __WI_LIBCPP_HAS_NO_VARIADICS + + template + struct __WI_LIBCPP_TEMPLATE_VIS common_type + { + public: + typedef typename common_type::type, _Vp>::type type; + }; + + template <> + struct __WI_LIBCPP_TEMPLATE_VIS common_type + { + public: + typedef void type; + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS common_type<_Tp, void, void> + { + public: + typedef typename common_type<_Tp, _Tp>::type type; + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up, void> + { + typedef typename decay() : declval<_Up>() + )>::type type; + }; + +#else // __WI_LIBCPP_HAS_NO_VARIADICS + + // bullet 1 - sizeof...(Tp) == 0 + + template + struct __WI_LIBCPP_TEMPLATE_VIS common_type {}; + + // bullet 2 - sizeof...(Tp) == 1 + + template + struct __WI_LIBCPP_TEMPLATE_VIS common_type<_Tp> + : public common_type<_Tp, _Tp> {}; + + // bullet 3 - sizeof...(Tp) == 2 + + template + struct __common_type2_imp {}; + + template + struct __common_type2_imp<_Tp, _Up, + typename __void_t() : declval<_Up>() + )>::type> + { + typedef typename decay() : declval<_Up>() + )>::type type; + }; + + template ::type, + class _DUp = typename decay<_Up>::type> + using __common_type2 = + typename conditional< + is_same<_Tp, _DTp>::value && is_same<_Up, _DUp>::value, + __common_type2_imp<_Tp, _Up>, + common_type<_DTp, _DUp> + >::type; + + template + struct __WI_LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up> + : __common_type2<_Tp, _Up> {}; + + // bullet 4 - sizeof...(Tp) > 2 + + template struct __common_types; + + template + struct __common_type_impl {}; + + template + struct __common_type_impl< + __common_types<_Tp, _Up>, + typename __void_t::type>::type> + { + typedef typename common_type<_Tp, _Up>::type type; + }; + + template + struct __common_type_impl<__common_types<_Tp, _Up, _Vp...>, + typename __void_t::type>::type> + : __common_type_impl< + __common_types::type, _Vp...> > + { + + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS common_type<_Tp, _Up, _Vp...> + : __common_type_impl<__common_types<_Tp, _Up, _Vp...> > {}; + +#if __WI_LIBCPP_STD_VER > 11 + template using common_type_t = typename common_type<_Tp...>::type; +#endif + +#endif // __WI_LIBCPP_HAS_NO_VARIADICS + + // is_assignable + + template struct __select_2nd { typedef _Tp type; }; + + template + typename __select_2nd() = declval<_Arg>())), true_type>::type + __is_assignable_test(int); + + template + false_type __is_assignable_test(...); + + + template ::value || is_void<_Arg>::value> + struct __is_assignable_imp + : public decltype((__is_assignable_test<_Tp, _Arg>(0))) {}; + + template + struct __is_assignable_imp<_Tp, _Arg, true> + : public false_type + { + }; + + template + struct is_assignable + : public __is_assignable_imp<_Tp, _Arg> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_assignable_v + = is_assignable<_Tp, _Arg>::value; +#endif + + // is_copy_assignable + + template struct __WI_LIBCPP_TEMPLATE_VIS is_copy_assignable + : public is_assignable::type, + typename add_lvalue_reference::type>::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_copy_assignable_v + = is_copy_assignable<_Tp>::value; +#endif + + // is_move_assignable + + template struct __WI_LIBCPP_TEMPLATE_VIS is_move_assignable +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + : public is_assignable::type, + typename add_rvalue_reference<_Tp>::type> {}; +#else + : public is_copy_assignable<_Tp> {}; +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_move_assignable_v + = is_move_assignable<_Tp>::value; +#endif + + // is_destructible + +#if __WI_HAS_FEATURE_IS_DESTRUCTIBLE + + template + struct is_destructible + : public integral_constant {}; + +#else + + // if it's a reference, return true + // if it's a function, return false + // if it's void, return false + // if it's an array of unknown bound, return false + // Otherwise, return "std::declval<_Up&>().~_Up()" is well-formed + // where _Up is remove_all_extents<_Tp>::type + + template + struct __is_destructible_apply { typedef int type; }; + + template + struct __is_destructor_wellformed { + template + static char __test ( + typename __is_destructible_apply().~_Tp1())>::type + ); + + template + static __two __test (...); + + static const bool value = sizeof(__test<_Tp>(12)) == sizeof(char); + }; + + template + struct __destructible_imp; + + template + struct __destructible_imp<_Tp, false> + : public integral_constant::type>::value> {}; + + template + struct __destructible_imp<_Tp, true> + : public true_type {}; + + template + struct __destructible_false; + + template + struct __destructible_false<_Tp, false> : public __destructible_imp<_Tp, is_reference<_Tp>::value> {}; + + template + struct __destructible_false<_Tp, true> : public false_type {}; + + template + struct is_destructible + : public __destructible_false<_Tp, is_function<_Tp>::value> {}; + + template + struct is_destructible<_Tp[]> + : public false_type {}; + + template <> + struct is_destructible + : public false_type {}; + +#endif // __WI_HAS_FEATURE_IS_DESTRUCTIBLE + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_destructible_v + = is_destructible<_Tp>::value; +#endif + + // move + +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + typename remove_reference<_Tp>::type&& + move(_Tp&& __t) WI_NOEXCEPT + { + typedef typename remove_reference<_Tp>::type _Up; + return static_cast<_Up&&>(__t); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + _Tp&& + forward(typename remove_reference<_Tp>::type& __t) WI_NOEXCEPT + { + return static_cast<_Tp&&>(__t); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + _Tp&& + forward(typename remove_reference<_Tp>::type&& __t) WI_NOEXCEPT + { + static_assert(!is_lvalue_reference<_Tp>::value, + "can not forward an rvalue as an lvalue"); + return static_cast<_Tp&&>(__t); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR_AFTER_CXX17 + _T1 exchange(_T1& __obj, _T2 && __new_value) + { + _T1 __old_value = wistd::move(__obj); + __obj = wistd::forward<_T2>(__new_value); + return __old_value; + } + +#else // __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + _Tp& + move(_Tp& __t) + { + return __t; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + const _Tp& + move(const _Tp& __t) + { + return __t; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + _Tp& + forward(typename remove_reference<_Tp>::type& __t) WI_NOEXCEPT + { + return __t; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + _T1 exchange(_T1& __obj, const _T2& __new_value) + { + _T1 __old_value = __obj; + __obj = __new_value; + return __old_value; + } + + template + class __rv + { + typedef typename remove_reference<_Tp>::type _Trr; + _Trr& t_; + public: + __WI_LIBCPP_INLINE_VISIBILITY + _Trr* operator->() {return &t_;} + __WI_LIBCPP_INLINE_VISIBILITY + explicit __rv(_Trr& __t) : t_(__t) {} + }; + +#endif // __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + +#if __WI_LIBCPP_STD_VER > 11 + template +#else + template +#endif + struct __WI_LIBCPP_TEMPLATE_VIS less : binary_function<_Tp, _Tp, bool> + { + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 __WI_LIBCPP_INLINE_VISIBILITY + bool operator()(const _Tp& __x, const _Tp& __y) const + {return __x < __y;} + }; + +#if __WI_LIBCPP_STD_VER > 11 + template <> + struct __WI_LIBCPP_TEMPLATE_VIS less + { + template + __WI_LIBCPP_NODISCARD_ATTRIBUTE __WI_LIBCPP_CONSTEXPR_AFTER_CXX11 __WI_LIBCPP_INLINE_VISIBILITY + auto operator()(_T1&& __t, _T2&& __u) const + __WI_NOEXCEPT_(noexcept(wistd::forward<_T1>(__t) < wistd::forward<_T2>(__u))) + -> decltype (wistd::forward<_T1>(__t) < wistd::forward<_T2>(__u)) + { return wistd::forward<_T1>(__t) < wistd::forward<_T2>(__u); } + typedef void is_transparent; + }; +#endif + +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + typename decay<_Tp>::type + __decay_copy(_Tp&& __t) + { + return wistd::forward<_Tp>(__t); + } + +#else + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + typename decay<_Tp>::type + __decay_copy(const _Tp& __t) + { + return wistd::forward<_Tp>(__t); + } + +#endif + +#ifndef __WI_LIBCPP_HAS_NO_VARIADICS + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + +#if __WI_HAS_FEATURE_REFERENCE_QUALIFIED_FUNCTIONS || \ + (defined(__WI_GNUC_VER) && __WI_GNUC_VER >= 409) + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false> + { + typedef _Class& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false> + { + typedef _Class& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> + { + typedef _Class const& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> + { + typedef _Class const& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> + { + typedef _Class volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> + { + typedef _Class volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> + { + typedef _Class const volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> + { + typedef _Class const volatile& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false> + { + typedef _Class&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false> + { + typedef _Class&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> + { + typedef _Class const&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> + { + typedef _Class const&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> + { + typedef _Class volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> + { + typedef _Class volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> + { + typedef _Class const volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> + { + typedef _Class const volatile&& _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_Param..., ...); + }; + +#endif // __WI_HAS_FEATURE_REFERENCE_QUALIFIED_FUNCTIONS || __WI_GNUC_VER >= 409 + +#else // __WI_LIBCPP_HAS_NO_VARIADICS + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(...), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, _P2); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...), true, false> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, _P2, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)() const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(...) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, _P2); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) const, true, false> + { + typedef _Class const _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, _P2, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)() volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(...) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, _P2); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) volatile, true, false> + { + typedef _Class volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, _P2, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)() const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(...) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, ...) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, ...) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, ...); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, _P2); + }; + + template + struct __member_pointer_traits_imp<_Rp (_Class::*)(_P0, _P1, _P2, ...) const volatile, true, false> + { + typedef _Class const volatile _ClassType; + typedef _Rp _ReturnType; + typedef _Rp (_FnType) (_P0, _P1, _P2, ...); + }; + +#endif // __WI_LIBCPP_HAS_NO_VARIADICS + + template + struct __member_pointer_traits_imp<_Rp _Class::*, false, true> + { + typedef _Class _ClassType; + typedef _Rp _ReturnType; + }; + + template + struct __member_pointer_traits + : public __member_pointer_traits_imp::type, + is_member_function_pointer<_Mp>::value, + is_member_object_pointer<_Mp>::value> + { + // typedef ... _ClassType; + // typedef ... _ReturnType; + // typedef ... _FnType; + }; + + + template + struct __member_pointer_class_type {}; + + template + struct __member_pointer_class_type<_Ret _ClassType::*> { + typedef _ClassType type; + }; + + // result_of + + template class result_of; + +#ifdef __WI_LIBCPP_HAS_NO_VARIADICS + + template + class __result_of + { + }; + + template + class __result_of<_Fn(), true, false> + { + public: + typedef decltype(declval<_Fn>()()) type; + }; + + template + class __result_of<_Fn(_A0), true, false> + { + public: + typedef decltype(declval<_Fn>()(declval<_A0>())) type; + }; + + template + class __result_of<_Fn(_A0, _A1), true, false> + { + public: + typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>())) type; + }; + + template + class __result_of<_Fn(_A0, _A1, _A2), true, false> + { + public: + typedef decltype(declval<_Fn>()(declval<_A0>(), declval<_A1>(), declval<_A2>())) type; + }; + + template + struct __result_of_mp; + + // member function pointer + + template + struct __result_of_mp<_Mp, _Tp, true> + : public __identity::_ReturnType> + { + }; + + // member data pointer + + template + struct __result_of_mdp; + + template + struct __result_of_mdp<_Rp _Class::*, _Tp, false> + { + typedef typename __apply_cv()), _Rp>::type& type; + }; + + template + struct __result_of_mdp<_Rp _Class::*, _Tp, true> + { + typedef typename __apply_cv<_Tp, _Rp>::type& type; + }; + + template + struct __result_of_mp<_Rp _Class::*, _Tp, false> + : public __result_of_mdp<_Rp _Class::*, _Tp, + is_base_of<_Class, typename remove_reference<_Tp>::type>::value> + { + }; + + + + template + class __result_of<_Fn(_Tp), false, true> // _Fn must be member pointer + : public __result_of_mp::type, + _Tp, + is_member_function_pointer::type>::value> + { + }; + + template + class __result_of<_Fn(_Tp, _A0), false, true> // _Fn must be member pointer + : public __result_of_mp::type, + _Tp, + is_member_function_pointer::type>::value> + { + }; + + template + class __result_of<_Fn(_Tp, _A0, _A1), false, true> // _Fn must be member pointer + : public __result_of_mp::type, + _Tp, + is_member_function_pointer::type>::value> + { + }; + + template + class __result_of<_Fn(_Tp, _A0, _A1, _A2), false, true> // _Fn must be member pointer + : public __result_of_mp::type, + _Tp, + is_member_function_pointer::type>::value> + { + }; + + // result_of + + template + class __WI_LIBCPP_TEMPLATE_VIS result_of<_Fn()> + : public __result_of<_Fn(), + is_class::type>::value || + is_function::type>::type>::value, + is_member_pointer::type>::value + > + { + }; + + template + class __WI_LIBCPP_TEMPLATE_VIS result_of<_Fn(_A0)> + : public __result_of<_Fn(_A0), + is_class::type>::value || + is_function::type>::type>::value, + is_member_pointer::type>::value + > + { + }; + + template + class __WI_LIBCPP_TEMPLATE_VIS result_of<_Fn(_A0, _A1)> + : public __result_of<_Fn(_A0, _A1), + is_class::type>::value || + is_function::type>::type>::value, + is_member_pointer::type>::value + > + { + }; + + template + class __WI_LIBCPP_TEMPLATE_VIS result_of<_Fn(_A0, _A1, _A2)> + : public __result_of<_Fn(_A0, _A1, _A2), + is_class::type>::value || + is_function::type>::type>::value, + is_member_pointer::type>::value + > + { + }; + +#endif // __WI_LIBCPP_HAS_NO_VARIADICS + + // template struct is_constructible; + + namespace __is_construct + { + struct __nat {}; + } + +#if !defined(__WI_LIBCPP_CXX03_LANG) && (!__WI_HAS_FEATURE_IS_CONSTRUCTIBLE || \ + defined(__WI_LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE)) + + template + struct __libcpp_is_constructible; + + template + struct __is_invalid_base_to_derived_cast { + static_assert(is_reference<_To>::value, "Wrong specialization"); + using _RawFrom = __uncvref_t<_From>; + using _RawTo = __uncvref_t<_To>; + static const bool value = __lazy_and< + __lazy_not>, + is_base_of<_RawFrom, _RawTo>, + __lazy_not<__libcpp_is_constructible<_RawTo, _From>> + >::value; + }; + + template + struct __is_invalid_lvalue_to_rvalue_cast : false_type { + static_assert(is_reference<_To>::value, "Wrong specialization"); + }; + + template + struct __is_invalid_lvalue_to_rvalue_cast<_ToRef&&, _FromRef&> { + using _RawFrom = __uncvref_t<_FromRef>; + using _RawTo = __uncvref_t<_ToRef>; + static const bool value = __lazy_and< + __lazy_not>, + __lazy_or< + is_same<_RawFrom, _RawTo>, + is_base_of<_RawTo, _RawFrom>> + >::value; + }; + + struct __is_constructible_helper + { + template + static void __eat(_To); + + // This overload is needed to work around a Clang bug that disallows + // static_cast(e) for non-reference-compatible types. + // Example: static_cast(declval()); + // NOTE: The static_cast implementation below is required to support + // classes with explicit conversion operators. + template (declval<_From>()))> + static true_type __test_cast(int); + + template (declval<_From>()))> + static integral_constant::value && + !__is_invalid_lvalue_to_rvalue_cast<_To, _From>::value + > __test_cast(long); + + template + static false_type __test_cast(...); + + template ()...))> + static true_type __test_nary(int); + template + static false_type __test_nary(...); + + template ()))> + static is_destructible<_Tp> __test_unary(int); + template + static false_type __test_unary(...); + }; + + template ::value> + struct __is_default_constructible + : decltype(__is_constructible_helper::__test_nary<_Tp>(0)) + {}; + + template + struct __is_default_constructible<_Tp, true> : false_type {}; + + template + struct __is_default_constructible<_Tp[], false> : false_type {}; + + template + struct __is_default_constructible<_Tp[_Nx], false> + : __is_default_constructible::type> {}; + + template + struct __libcpp_is_constructible + { + static_assert(sizeof...(_Args) > 1, "Wrong specialization"); + typedef decltype(__is_constructible_helper::__test_nary<_Tp, _Args...>(0)) + type; + }; + + template + struct __libcpp_is_constructible<_Tp> : __is_default_constructible<_Tp> {}; + + template + struct __libcpp_is_constructible<_Tp, _A0> + : public decltype(__is_constructible_helper::__test_unary<_Tp, _A0>(0)) + {}; + + template + struct __libcpp_is_constructible<_Tp&, _A0> + : public decltype(__is_constructible_helper:: + __test_cast<_Tp&, _A0>(0)) + {}; + + template + struct __libcpp_is_constructible<_Tp&&, _A0> + : public decltype(__is_constructible_helper:: + __test_cast<_Tp&&, _A0>(0)) + {}; + +#endif + +#if __WI_HAS_FEATURE_IS_CONSTRUCTIBLE + template + struct __WI_LIBCPP_TEMPLATE_VIS is_constructible + : public integral_constant + {}; +#elif !defined(__WI_LIBCPP_CXX03_LANG) + template + struct __WI_LIBCPP_TEMPLATE_VIS is_constructible + : public __libcpp_is_constructible<_Tp, _Args...>::type {}; +#else + // template struct is_constructible0; + + // main is_constructible0 test + + template + decltype((_Tp(), true_type())) + __is_constructible0_test(_Tp&); + + false_type + __is_constructible0_test(__any); + + template + decltype((_Tp(declval<_A0>()), true_type())) + __is_constructible1_test(_Tp&, _A0&); + + template + false_type + __is_constructible1_test(__any, _A0&); + + template + decltype((_Tp(declval<_A0>(), declval<_A1>()), true_type())) + __is_constructible2_test(_Tp&, _A0&, _A1&); + + template + false_type + __is_constructible2_test(__any, _A0&, _A1&); + + template + decltype((_Tp(declval<_A0>(), declval<_A1>(), declval<_A2>()), true_type())) + __is_constructible3_test(_Tp&, _A0&, _A1&, _A2&); + + template + false_type + __is_constructible3_test(__any, _A0&, _A1&, _A2&); + + template + struct __is_constructible0_imp // false, _Tp is not a scalar + : public common_type + < + decltype(__is_constructible0_test(declval<_Tp&>())) + >::type + {}; + + template + struct __is_constructible1_imp // false, _Tp is not a scalar + : public common_type + < + decltype(__is_constructible1_test(declval<_Tp&>(), declval<_A0&>())) + >::type + {}; + + template + struct __is_constructible2_imp // false, _Tp is not a scalar + : public common_type + < + decltype(__is_constructible2_test(declval<_Tp&>(), declval<_A0>(), declval<_A1>())) + >::type + {}; + + template + struct __is_constructible3_imp // false, _Tp is not a scalar + : public common_type + < + decltype(__is_constructible3_test(declval<_Tp&>(), declval<_A0>(), declval<_A1>(), declval<_A2>())) + >::type + {}; + + // handle scalars and reference types + + // Scalars are default constructible, references are not + + template + struct __is_constructible0_imp + : public is_scalar<_Tp> + {}; + + template + struct __is_constructible1_imp + : public is_convertible<_A0, _Tp> + {}; + + template + struct __is_constructible2_imp + : public false_type + {}; + + template + struct __is_constructible3_imp + : public false_type + {}; + + // Treat scalars and reference types separately + + template + struct __is_constructible0_void_check + : public __is_constructible0_imp::value || is_reference<_Tp>::value, + _Tp> + {}; + + template + struct __is_constructible1_void_check + : public __is_constructible1_imp::value || is_reference<_Tp>::value, + _Tp, _A0> + {}; + + template + struct __is_constructible2_void_check + : public __is_constructible2_imp::value || is_reference<_Tp>::value, + _Tp, _A0, _A1> + {}; + + template + struct __is_constructible3_void_check + : public __is_constructible3_imp::value || is_reference<_Tp>::value, + _Tp, _A0, _A1, _A2> + {}; + + // If any of T or Args is void, is_constructible should be false + + template + struct __is_constructible0_void_check + : public false_type + {}; + + template + struct __is_constructible1_void_check + : public false_type + {}; + + template + struct __is_constructible2_void_check + : public false_type + {}; + + template + struct __is_constructible3_void_check + : public false_type + {}; + + // is_constructible entry point + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_constructible + : public __is_constructible3_void_check::value + || is_abstract<_Tp>::value + || is_function<_Tp>::value + || is_void<_A0>::value + || is_void<_A1>::value + || is_void<_A2>::value, + _Tp, _A0, _A1, _A2> + {}; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_constructible<_Tp, __is_construct::__nat, __is_construct::__nat> + : public __is_constructible0_void_check::value + || is_abstract<_Tp>::value + || is_function<_Tp>::value, + _Tp> + {}; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_constructible<_Tp, _A0, __is_construct::__nat> + : public __is_constructible1_void_check::value + || is_abstract<_Tp>::value + || is_function<_Tp>::value + || is_void<_A0>::value, + _Tp, _A0> + {}; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_constructible<_Tp, _A0, _A1, __is_construct::__nat> + : public __is_constructible2_void_check::value + || is_abstract<_Tp>::value + || is_function<_Tp>::value + || is_void<_A0>::value + || is_void<_A1>::value, + _Tp, _A0, _A1> + {}; + + // Array types are default constructible if their element type + // is default constructible + + template + struct __is_constructible0_imp + : public is_constructible::type> + {}; + + template + struct __is_constructible1_imp + : public false_type + {}; + + template + struct __is_constructible2_imp + : public false_type + {}; + + template + struct __is_constructible3_imp + : public false_type + {}; + + // Incomplete array types are not constructible + + template + struct __is_constructible0_imp + : public false_type + {}; + + template + struct __is_constructible1_imp + : public false_type + {}; + + template + struct __is_constructible2_imp + : public false_type + {}; + + template + struct __is_constructible3_imp + : public false_type + {}; + +#endif // __WI_HAS_FEATURE_IS_CONSTRUCTIBLE + + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && !defined(__WI_LIBCPP_HAS_NO_VARIADICS) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_constructible_v + = is_constructible<_Tp, _Args...>::value; +#endif + + // is_default_constructible + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_default_constructible + : public is_constructible<_Tp> + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_default_constructible_v + = is_default_constructible<_Tp>::value; +#endif + + // is_copy_constructible + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_copy_constructible + : public is_constructible<_Tp, + typename add_lvalue_reference::type>::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_copy_constructible_v + = is_copy_constructible<_Tp>::value; +#endif + + // is_move_constructible + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_move_constructible +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + : public is_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> +#else + : public is_copy_constructible<_Tp> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_move_constructible_v + = is_move_constructible<_Tp>::value; +#endif + + // is_trivially_constructible + +#ifndef __WI_LIBCPP_HAS_NO_VARIADICS + +#if __WI_HAS_FEATURE_IS_TRIVIALLY_CONSTRUCTIBLE || __WI_GNUC_VER >= 501 + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible + : integral_constant + { + }; + +#else // !__WI_HAS_FEATURE_IS_TRIVIALLY_CONSTRUCTIBLE + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible + : false_type + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp> +#if __WI_HAS_FEATURE_HAS_TRIVIAL_CONSTRUCTOR + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + + template +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&&> +#else + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp> +#endif + : integral_constant::value> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, const _Tp&> + : integral_constant::value> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&> + : integral_constant::value> + { + }; + +#endif // !__WI_HAS_FEATURE_IS_TRIVIALLY_CONSTRUCTIBLE + +#else // __WI_LIBCPP_HAS_NO_VARIADICS + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible + : false_type + { + }; + +#if __WI_HAS_FEATURE_IS_TRIVIALLY_CONSTRUCTIBLE || __WI_GNUC_VER >= 501 + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, __is_construct::__nat, + __is_construct::__nat> + : integral_constant + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp, + __is_construct::__nat> + : integral_constant + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, const _Tp&, + __is_construct::__nat> + : integral_constant + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&, + __is_construct::__nat> + : integral_constant + { + }; + +#else // !__WI_HAS_FEATURE_IS_TRIVIALLY_CONSTRUCTIBLE + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, __is_construct::__nat, + __is_construct::__nat> + : integral_constant::value> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp, + __is_construct::__nat> + : integral_constant::value> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, const _Tp&, + __is_construct::__nat> + : integral_constant::value> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_constructible<_Tp, _Tp&, + __is_construct::__nat> + : integral_constant::value> + { + }; + +#endif // !__WI_HAS_FEATURE_IS_TRIVIALLY_CONSTRUCTIBLE + +#endif // __WI_LIBCPP_HAS_NO_VARIADICS + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && !defined(__WI_LIBCPP_HAS_NO_VARIADICS) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_constructible_v + = is_trivially_constructible<_Tp, _Args...>::value; +#endif + + // is_trivially_default_constructible + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_default_constructible + : public is_trivially_constructible<_Tp> + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_default_constructible_v + = is_trivially_default_constructible<_Tp>::value; +#endif + + // is_trivially_copy_constructible + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_copy_constructible + : public is_trivially_constructible<_Tp, typename add_lvalue_reference::type> + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_copy_constructible_v + = is_trivially_copy_constructible<_Tp>::value; +#endif + + // is_trivially_move_constructible + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_move_constructible +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + : public is_trivially_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> +#else + : public is_trivially_copy_constructible<_Tp> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_move_constructible_v + = is_trivially_move_constructible<_Tp>::value; +#endif + + // is_trivially_assignable + +#if __WI_HAS_FEATURE_IS_TRIVIALLY_ASSIGNABLE || __WI_GNUC_VER >= 501 + + template + struct is_trivially_assignable + : integral_constant + { + }; + +#else // !__WI_HAS_FEATURE_IS_TRIVIALLY_ASSIGNABLE + + template + struct is_trivially_assignable + : public false_type {}; + + template + struct is_trivially_assignable<_Tp&, _Tp> + : integral_constant::value> {}; + + template + struct is_trivially_assignable<_Tp&, _Tp&> + : integral_constant::value> {}; + + template + struct is_trivially_assignable<_Tp&, const _Tp&> + : integral_constant::value> {}; + +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + struct is_trivially_assignable<_Tp&, _Tp&&> + : integral_constant::value> {}; + +#endif // __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + +#endif // !__WI_HAS_FEATURE_IS_TRIVIALLY_ASSIGNABLE + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_assignable_v + = is_trivially_assignable<_Tp, _Arg>::value; +#endif + + // is_trivially_copy_assignable + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_copy_assignable + : public is_trivially_assignable::type, + typename add_lvalue_reference::type>::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_copy_assignable_v + = is_trivially_copy_assignable<_Tp>::value; +#endif + + // is_trivially_move_assignable + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_move_assignable + : public is_trivially_assignable::type, +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + typename add_rvalue_reference<_Tp>::type> +#else + typename add_lvalue_reference<_Tp>::type> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_move_assignable_v + = is_trivially_move_assignable<_Tp>::value; +#endif + + // is_trivially_destructible + +#if __WI_HAS_FEATURE_HAS_TRIVIAL_DESTRUCTOR || (__WI_GNUC_VER >= 403) + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_destructible + : public integral_constant::value && __has_trivial_destructor(_Tp)> {}; + +#else + + template struct __libcpp_trivial_destructor + : public integral_constant::value || + is_reference<_Tp>::value> {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_destructible + : public __libcpp_trivial_destructor::type> {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_destructible<_Tp[]> + : public false_type {}; + +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_destructible_v + = is_trivially_destructible<_Tp>::value; +#endif + + // is_nothrow_constructible + +#if 0 + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible + : public integral_constant + { + }; + +#else + +#ifndef __WI_LIBCPP_HAS_NO_VARIADICS + +#if !defined(__WI_LIBCPP_HAS_NO_NOEXCEPT) || (__WI_GNUC_VER >= 407 && __cplusplus >= 201103L) + + template struct __libcpp_is_nothrow_constructible; + + template + struct __libcpp_is_nothrow_constructible + : public integral_constant()...))> + { + }; + + template + void __implicit_conversion_to(_Tp) noexcept { } + + template + struct __libcpp_is_nothrow_constructible + : public integral_constant(declval<_Arg>()))> + { + }; + + template + struct __libcpp_is_nothrow_constructible + : public false_type + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible + : __libcpp_is_nothrow_constructible::value, is_reference<_Tp>::value, _Tp, _Args...> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp[_Ns]> + : __libcpp_is_nothrow_constructible::value, is_reference<_Tp>::value, _Tp> + { + }; + +#else // !defined(__WI_LIBCPP_HAS_NO_NOEXCEPT) + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible + : false_type + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp> +#if __WI_HAS_FEATURE_HAS_NOTHROW_CONSTRUCTOR + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + + template +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp, _Tp&&> +#else + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp, _Tp> +#endif +#if __WI_HAS_FEATURE_HAS_NOTHROW_COPY + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp, const _Tp&> +#if __WI_HAS_FEATURE_HAS_NOTHROW_COPY + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp, _Tp&> +#if __WI_HAS_FEATURE_HAS_NOTHROW_COPY + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + +#endif // !defined(__WI_LIBCPP_HAS_NO_NOEXCEPT) + +#else // __WI_LIBCPP_HAS_NO_VARIADICS + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible + : false_type + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp, __is_construct::__nat, + __is_construct::__nat> +#if __WI_HAS_FEATURE_HAS_NOTHROW_CONSTRUCTOR + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp, _Tp, + __is_construct::__nat> +#if __WI_HAS_FEATURE_HAS_NOTHROW_COPY + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp, const _Tp&, + __is_construct::__nat> +#if __WI_HAS_FEATURE_HAS_NOTHROW_COPY + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_constructible<_Tp, _Tp&, + __is_construct::__nat> +#if __WI_HAS_FEATURE_HAS_NOTHROW_COPY + : integral_constant +#else + : integral_constant::value> +#endif + { + }; + +#endif // __WI_LIBCPP_HAS_NO_VARIADICS +#endif // __has_feature(is_nothrow_constructible) + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) && !defined(__WI_LIBCPP_HAS_NO_VARIADICS) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_nothrow_constructible_v + = is_nothrow_constructible<_Tp, _Args...>::value; +#endif + + // is_nothrow_default_constructible + + template struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_default_constructible + : public is_nothrow_constructible<_Tp> + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_nothrow_default_constructible_v + = is_nothrow_default_constructible<_Tp>::value; +#endif + + // is_nothrow_copy_constructible + + template struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_copy_constructible + : public is_nothrow_constructible<_Tp, + typename add_lvalue_reference::type>::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_nothrow_copy_constructible_v + = is_nothrow_copy_constructible<_Tp>::value; +#endif + + // is_nothrow_move_constructible + + template struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_move_constructible +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + : public is_nothrow_constructible<_Tp, typename add_rvalue_reference<_Tp>::type> +#else + : public is_nothrow_copy_constructible<_Tp> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_nothrow_move_constructible_v + = is_nothrow_move_constructible<_Tp>::value; +#endif + + // is_nothrow_assignable + +#if !defined(__WI_LIBCPP_HAS_NO_NOEXCEPT) || (__WI_GNUC_VER >= 407 && __cplusplus >= 201103L) + + template struct __libcpp_is_nothrow_assignable; + + template + struct __libcpp_is_nothrow_assignable + : public false_type + { + }; + + template + struct __libcpp_is_nothrow_assignable + : public integral_constant() = declval<_Arg>()) > + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_assignable + : public __libcpp_is_nothrow_assignable::value, _Tp, _Arg> + { + }; + +#else // !defined(__WI_LIBCPP_HAS_NO_NOEXCEPT) + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_assignable + : public false_type {}; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_assignable<_Tp&, _Tp> +#if __WI_HAS_FEATURE_HAS_NOTHROW_ASSIGN + : integral_constant {}; +#else + : integral_constant::value> {}; +#endif + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_assignable<_Tp&, _Tp&> +#if __WI_HAS_FEATURE_HAS_NOTHROW_ASSIGN + : integral_constant {}; +#else + : integral_constant::value> {}; +#endif + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_assignable<_Tp&, const _Tp&> +#if __WI_HAS_FEATURE_HAS_NOTHROW_ASSIGN + : integral_constant {}; +#else + : integral_constant::value> {}; +#endif + +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + struct is_nothrow_assignable<_Tp&, _Tp&&> +#if __WI_HAS_FEATURE_HAS_NOTHROW_ASSIGN + : integral_constant {}; +#else + : integral_constant::value> {}; +#endif + +#endif // __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + +#endif // !defined(__WI_LIBCPP_HAS_NO_NOEXCEPT) + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_nothrow_assignable_v + = is_nothrow_assignable<_Tp, _Arg>::value; +#endif + + // is_nothrow_copy_assignable + + template struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_copy_assignable + : public is_nothrow_assignable::type, + typename add_lvalue_reference::type>::type> {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_nothrow_copy_assignable_v + = is_nothrow_copy_assignable<_Tp>::value; +#endif + + // is_nothrow_move_assignable + + template struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_move_assignable + : public is_nothrow_assignable::type, +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + typename add_rvalue_reference<_Tp>::type> +#else + typename add_lvalue_reference<_Tp>::type> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_nothrow_move_assignable_v + = is_nothrow_move_assignable<_Tp>::value; +#endif + + // is_nothrow_destructible + +#if !defined(__WI_LIBCPP_HAS_NO_NOEXCEPT) || (__WI_GNUC_VER >= 407 && __cplusplus >= 201103L) + + template struct __libcpp_is_nothrow_destructible; + + template + struct __libcpp_is_nothrow_destructible + : public false_type + { + }; + + template + struct __libcpp_is_nothrow_destructible + : public integral_constant().~_Tp()) > + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_destructible + : public __libcpp_is_nothrow_destructible::value, _Tp> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[_Ns]> + : public is_nothrow_destructible<_Tp> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&> + : public true_type + { + }; + +#ifndef __WI_LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp&&> + : public true_type + { + }; + +#endif + +#else + + template struct __libcpp_nothrow_destructor + : public integral_constant::value || + is_reference<_Tp>::value> {}; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_destructible + : public __libcpp_nothrow_destructor::type> {}; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_destructible<_Tp[]> + : public false_type {}; + +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_nothrow_destructible_v + = is_nothrow_destructible<_Tp>::value; +#endif + + // is_pod + +#if __WI_HAS_FEATURE_IS_POD || (__WI_GNUC_VER >= 403) + + template struct __WI_LIBCPP_TEMPLATE_VIS is_pod + : public integral_constant {}; + +#else + + template struct __WI_LIBCPP_TEMPLATE_VIS is_pod + : public integral_constant::value && + is_trivially_copy_constructible<_Tp>::value && + is_trivially_copy_assignable<_Tp>::value && + is_trivially_destructible<_Tp>::value> {}; + +#endif + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_pod_v + = is_pod<_Tp>::value; +#endif + + // is_literal_type; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_literal_type +#ifdef __WI_LIBCPP_IS_LITERAL + : public integral_constant +#else + : integral_constant::type>::value || + is_reference::type>::value> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_literal_type_v + = is_literal_type<_Tp>::value; +#endif + + // is_standard_layout; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_standard_layout +#if __WI_HAS_FEATURE_IS_STANDARD_LAYOUT || (__WI_GNUC_VER >= 407) + : public integral_constant +#else + : integral_constant::type>::value> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_standard_layout_v + = is_standard_layout<_Tp>::value; +#endif + + // is_trivially_copyable; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivially_copyable +#if __WI_HAS_FEATURE_IS_TRIVIALLY_COPYABLE + : public integral_constant +#elif __WI_GNUC_VER >= 501 + : public integral_constant::value && __is_trivially_copyable(_Tp)> +#else + : integral_constant::type>::value> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivially_copyable_v + = is_trivially_copyable<_Tp>::value; +#endif + + // is_trivial; + + template struct __WI_LIBCPP_TEMPLATE_VIS is_trivial +#if __WI_HAS_FEATURE_IS_TRIVIAL || __WI_GNUC_VER >= 407 + : public integral_constant +#else + : integral_constant::value && + is_trivially_default_constructible<_Tp>::value> +#endif + {}; + +#if __WI_LIBCPP_STD_VER > 11 && !defined(__WI_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) + template + __WI_LIBCPP_INLINE_VAR __WI_LIBCPP_CONSTEXPR bool is_trivial_v + = is_trivial<_Tp>::value; +#endif + + template struct __is_reference_wrapper_impl : public false_type {}; + template struct __is_reference_wrapper_impl > : public true_type {}; + template struct __is_reference_wrapper + : public __is_reference_wrapper_impl::type> {}; + +#ifndef __WI_LIBCPP_CXX03_LANG + + template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> + using __enable_if_bullet1 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + + template ::type, + class _DecayA0 = typename decay<_A0>::type> + using __enable_if_bullet2 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + + template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> + using __enable_if_bullet3 = typename enable_if + < + is_member_function_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + + template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> + using __enable_if_bullet4 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && is_base_of<_ClassT, _DecayA0>::value + >::type; + + template ::type, + class _DecayA0 = typename decay<_A0>::type> + using __enable_if_bullet5 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && __is_reference_wrapper<_DecayA0>::value + >::type; + + template ::type, + class _DecayA0 = typename decay<_A0>::type, + class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> + using __enable_if_bullet6 = typename enable_if + < + is_member_object_pointer<_DecayFp>::value + && !is_base_of<_ClassT, _DecayA0>::value + && !__is_reference_wrapper<_DecayA0>::value + >::type; + + // __invoke forward declarations + + // fall back - none of the bullets + +#define __WI_LIBCPP_INVOKE_RETURN(...) \ + __WI_NOEXCEPT_(__WI_NOEXCEPT_(__VA_ARGS__)) -> decltype(__VA_ARGS__) \ + { return __VA_ARGS__; } + + template + auto __invoke(__any, _Args&& ...__args) -> __nat; + + template + auto __invoke_constexpr(__any, _Args&& ...__args) -> __nat; + + // bullets 1, 2 and 3 + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + auto + __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + __WI_LIBCPP_INVOKE_RETURN((wistd::forward<_A0>(__a0).*__f)(wistd::forward<_Args>(__args)...)) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_CONSTEXPR auto + __invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + __WI_LIBCPP_INVOKE_RETURN((wistd::forward<_A0>(__a0).*__f)(wistd::forward<_Args>(__args)...)) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + auto + __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + __WI_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(wistd::forward<_Args>(__args)...)) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_CONSTEXPR auto + __invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + __WI_LIBCPP_INVOKE_RETURN((__a0.get().*__f)(wistd::forward<_Args>(__args)...)) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + auto + __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + __WI_LIBCPP_INVOKE_RETURN(((*wistd::forward<_A0>(__a0)).*__f)(wistd::forward<_Args>(__args)...)) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_CONSTEXPR auto + __invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) + __WI_LIBCPP_INVOKE_RETURN(((*wistd::forward<_A0>(__a0)).*__f)(wistd::forward<_Args>(__args)...)) + + // bullets 4, 5 and 6 + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + auto + __invoke(_Fp&& __f, _A0&& __a0) + __WI_LIBCPP_INVOKE_RETURN(wistd::forward<_A0>(__a0).*__f) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_CONSTEXPR auto + __invoke_constexpr(_Fp&& __f, _A0&& __a0) + __WI_LIBCPP_INVOKE_RETURN(wistd::forward<_A0>(__a0).*__f) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + auto + __invoke(_Fp&& __f, _A0&& __a0) + __WI_LIBCPP_INVOKE_RETURN(__a0.get().*__f) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_CONSTEXPR auto + __invoke_constexpr(_Fp&& __f, _A0&& __a0) + __WI_LIBCPP_INVOKE_RETURN(__a0.get().*__f) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + auto + __invoke(_Fp&& __f, _A0&& __a0) + __WI_LIBCPP_INVOKE_RETURN((*wistd::forward<_A0>(__a0)).*__f) + + template > + inline __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_CONSTEXPR auto + __invoke_constexpr(_Fp&& __f, _A0&& __a0) + __WI_LIBCPP_INVOKE_RETURN((*wistd::forward<_A0>(__a0)).*__f) + + // bullet 7 + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + auto + __invoke(_Fp&& __f, _Args&& ...__args) + __WI_LIBCPP_INVOKE_RETURN(wistd::forward<_Fp>(__f)(wistd::forward<_Args>(__args)...)) + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + __WI_LIBCPP_CONSTEXPR auto + __invoke_constexpr(_Fp&& __f, _Args&& ...__args) + __WI_LIBCPP_INVOKE_RETURN(wistd::forward<_Fp>(__f)(wistd::forward<_Args>(__args)...)) + +#undef __WI_LIBCPP_INVOKE_RETURN + + // __invokable + + template + struct __invokable_r + { + // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, + // or incomplete array types as required by the standard. + using _Result = decltype( + __invoke(declval<_Fp>(), declval<_Args>()...)); + + using type = + typename conditional< + !is_same<_Result, __nat>::value, + typename conditional< + is_void<_Ret>::value, + true_type, + is_convertible<_Result, _Ret> + >::type, + false_type + >::type; + static const bool value = type::value; + }; + + template + using __invokable = __invokable_r; + + template + struct __nothrow_invokable_r_imp { + static const bool value = false; + }; + + template + struct __nothrow_invokable_r_imp + { + typedef __nothrow_invokable_r_imp _ThisT; + + template + static void __test_noexcept(_Tp) noexcept; + + static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>( + __invoke(declval<_Fp>(), declval<_Args>()...))); + }; + + template + struct __nothrow_invokable_r_imp + { + static const bool value = noexcept( + __invoke(declval<_Fp>(), declval<_Args>()...)); + }; + + template + using __nothrow_invokable_r = + __nothrow_invokable_r_imp< + __invokable_r<_Ret, _Fp, _Args...>::value, + is_void<_Ret>::value, + _Ret, _Fp, _Args... + >; + + template + using __nothrow_invokable = + __nothrow_invokable_r_imp< + __invokable<_Fp, _Args...>::value, + true, void, _Fp, _Args... + >; + + template + struct __invoke_of + : public enable_if< + __invokable<_Fp, _Args...>::value, + typename __invokable_r::_Result> + { + }; + + // result_of + + template + class __WI_LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)> + : public __invoke_of<_Fp, _Args...> + { + }; + +#if __WI_LIBCPP_STD_VER > 11 + template using result_of_t = typename result_of<_Tp>::type; +#endif + +#if __WI_LIBCPP_STD_VER > 14 + + // invoke_result + + template + struct __WI_LIBCPP_TEMPLATE_VIS invoke_result + : __invoke_of<_Fn, _Args...> + { + }; + + template + using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; + + // is_invocable + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_invocable + : integral_constant::value> {}; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_invocable_r + : integral_constant::value> {}; + + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_invocable_v + = is_invocable<_Fn, _Args...>::value; + + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_invocable_r_v + = is_invocable_r<_Ret, _Fn, _Args...>::value; + + // is_nothrow_invocable + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_invocable + : integral_constant::value> {}; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r + : integral_constant::value> {}; + + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_nothrow_invocable_v + = is_nothrow_invocable<_Fn, _Args...>::value; + + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_nothrow_invocable_r_v + = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; + +#endif // __WI_LIBCPP_STD_VER > 14 + +#endif // !defined(__WI_LIBCPP_CXX03_LANG) + + template struct __is_swappable; + template struct __is_nothrow_swappable; + + template + inline __WI_LIBCPP_INLINE_VISIBILITY +#ifndef __WI_LIBCPP_CXX03_LANG + typename enable_if + < + is_move_constructible<_Tp>::value && + is_move_assignable<_Tp>::value + >::type +#else + void +#endif + swap_wil(_Tp& __x, _Tp& __y) __WI_NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && + is_nothrow_move_assignable<_Tp>::value) + { + _Tp __t(wistd::move(__x)); + __x = wistd::move(__y); + __y = wistd::move(__t); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + _ForwardIterator2 + swap_ranges_wil(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) + { + for(; __first1 != __last1; ++__first1, (void) ++__first2) + swap_wil(*__first1, *__first2); + return __first2; + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + typename enable_if< + __is_swappable<_Tp>::value + >::type + swap_wil(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) __WI_NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) + { + wistd::swap_ranges_wil(__a, __a + _Np, __b); + } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY + void + iter_swap_wil(_ForwardIterator1 __a, _ForwardIterator2 __b) + // __WI_NOEXCEPT_(__WI_NOEXCEPT_(swap_wil(*__a, *__b))) + __WI_NOEXCEPT_(__WI_NOEXCEPT_(swap_wil(*declval<_ForwardIterator1>(), + *declval<_ForwardIterator2>()))) + { + swap_wil(*__a, *__b); + } + + // __swappable + + namespace __detail + { + // ALL generic swap overloads MUST already have a declaration available at this point. + + template ::value && !is_void<_Up>::value> + struct __swappable_with + { + template + static decltype(swap_wil(declval<_LHS>(), declval<_RHS>())) + __test_swap(int); + template + static __nat __test_swap(long); + + // Extra parens are needed for the C++03 definition of decltype. + typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; + typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; + + static const bool value = !is_same<__swap1, __nat>::value + && !is_same<__swap2, __nat>::value; + }; + + template + struct __swappable_with<_Tp, _Up, false> : false_type {}; + + template ::value> + struct __nothrow_swappable_with { + static const bool value = +#ifndef __WI_LIBCPP_HAS_NO_NOEXCEPT + noexcept(swap_wil(declval<_Tp>(), declval<_Up>())) + && noexcept(swap_wil(declval<_Up>(), declval<_Tp>())); +#else + false; +#endif + }; + + template + struct __nothrow_swappable_with<_Tp, _Up, false> : false_type {}; + + } // __detail + + template + struct __is_swappable + : public integral_constant::value> + { + }; + + template + struct __is_nothrow_swappable + : public integral_constant::value> + { + }; + +#if __WI_LIBCPP_STD_VER > 14 + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_swappable_with + : public integral_constant::value> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_swappable + : public conditional< + __is_referenceable<_Tp>::value, + is_swappable_with< + typename add_lvalue_reference<_Tp>::type, + typename add_lvalue_reference<_Tp>::type>, + false_type + >::type + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_swappable_with + : public integral_constant::value> + { + }; + + template + struct __WI_LIBCPP_TEMPLATE_VIS is_nothrow_swappable + : public conditional< + __is_referenceable<_Tp>::value, + is_nothrow_swappable_with< + typename add_lvalue_reference<_Tp>::type, + typename add_lvalue_reference<_Tp>::type>, + false_type + >::type + { + }; + + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_swappable_with_v + = is_swappable_with<_Tp, _Up>::value; + + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_swappable_v + = is_swappable<_Tp>::value; + + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_nothrow_swappable_with_v + = is_nothrow_swappable_with<_Tp, _Up>::value; + + template + __WI_LIBCPP_INLINE_VAR constexpr bool is_nothrow_swappable_v + = is_nothrow_swappable<_Tp>::value; + +#endif // __WI_LIBCPP_STD_VER > 14 + +#ifdef __WI_LIBCPP_UNDERLYING_TYPE + + template + struct underlying_type + { + typedef __WI_LIBCPP_UNDERLYING_TYPE(_Tp) type; + }; + +#if __WI_LIBCPP_STD_VER > 11 + template using underlying_type_t = typename underlying_type<_Tp>::type; +#endif + +#else // __WI_LIBCPP_UNDERLYING_TYPE + + template + struct underlying_type + { + static_assert(_Support, "The underyling_type trait requires compiler " + "support. Either no such support exists or " + "libc++ does not know how to use it."); + }; + +#endif // __WI_LIBCPP_UNDERLYING_TYPE + + + template ::value> + struct __sfinae_underlying_type + { + typedef typename underlying_type<_Tp>::type type; + typedef decltype(((type)1) + 0) __promoted_type; + }; + + template + struct __sfinae_underlying_type<_Tp, false> {}; + + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + int __convert_to_integral(int __val) { return __val; } + + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + unsigned __convert_to_integral(unsigned __val) { return __val; } + + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + long __convert_to_integral(long __val) { return __val; } + + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + unsigned long __convert_to_integral(unsigned long __val) { return __val; } + + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + long long __convert_to_integral(long long __val) { return __val; } + + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + unsigned long long __convert_to_integral(unsigned long long __val) {return __val; } + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + typename enable_if::value, long long>::type + __convert_to_integral(_Fp __val) { return __val; } + +#ifndef __WI_LIBCPP_HAS_NO_INT128 + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + __int128_t __convert_to_integral(__int128_t __val) { return __val; } + + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + __uint128_t __convert_to_integral(__uint128_t __val) { return __val; } +#endif + + template + inline __WI_LIBCPP_INLINE_VISIBILITY __WI_LIBCPP_CONSTEXPR + typename __sfinae_underlying_type<_Tp>::__promoted_type + __convert_to_integral(_Tp __val) { return __val; } + +#ifndef __WI_LIBCPP_CXX03_LANG + + template + struct __has_operator_addressof_member_imp + { + template + static auto __test(int) + -> typename __select_2nd().operator&()), true_type>::type; + template + static auto __test(long) -> false_type; + + static const bool value = decltype(__test<_Tp>(0))::value; + }; + + template + struct __has_operator_addressof_free_imp + { + template + static auto __test(int) + -> typename __select_2nd())), true_type>::type; + template + static auto __test(long) -> false_type; + + static const bool value = decltype(__test<_Tp>(0))::value; + }; + + template + struct __has_operator_addressof + : public integral_constant::value + || __has_operator_addressof_free_imp<_Tp>::value> + {}; + +#endif // __WI_LIBCPP_CXX03_LANG + +#ifndef __WI_LIBCPP_CXX03_LANG + + template using void_t = void; + +# ifndef __WI_LIBCPP_HAS_NO_VARIADICS + template + struct conjunction : __and_<_Args...> {}; + template + __WI_LIBCPP_INLINE_VAR constexpr bool conjunction_v + = conjunction<_Args...>::value; + + template + struct disjunction : __or_<_Args...> {}; + template + __WI_LIBCPP_INLINE_VAR constexpr bool disjunction_v + = disjunction<_Args...>::value; + + template + struct negation : __not_<_Tp> {}; + template + __WI_LIBCPP_INLINE_VAR constexpr bool negation_v + = negation<_Tp>::value; +# endif // __WI_LIBCPP_HAS_NO_VARIADICS +#endif // __WI_LIBCPP_CXX03_LANG + + // These traits are used in __tree and __hash_table +#ifndef __WI_LIBCPP_CXX03_LANG + struct __extract_key_fail_tag {}; + struct __extract_key_self_tag {}; + struct __extract_key_first_tag {}; + + template ::type> + struct __can_extract_key + : conditional::value, __extract_key_self_tag, + __extract_key_fail_tag>::type {}; + + template + struct __can_extract_key<_Pair, _Key, pair<_First, _Second>> + : conditional::type, _Key>::value, + __extract_key_first_tag, __extract_key_fail_tag>::type {}; + + // __can_extract_map_key uses true_type/false_type instead of the tags. + // It returns true if _Key != _ContainerValueTy (the container is a map not a set) + // and _ValTy == _Key. + template ::type> + struct __can_extract_map_key + : integral_constant::value> {}; + + // This specialization returns __extract_key_fail_tag for non-map containers + // because _Key == _ContainerValueTy + template + struct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> + : false_type {}; + +#endif + +#if __WI_LIBCPP_STD_VER > 17 + enum class endian + { + little = 0xDEAD, + big = 0xFACE, +#if defined(__WI_LIBCPP_LITTLE_ENDIAN) + native = little +#elif defined(__WI_LIBCPP_BIG_ENDIAN) + native = big +#else + native = 0xCAFE +#endif + }; +#endif +} +/// @endcond + +#endif // _WISTD_TYPE_TRAITS_H_ diff --git a/libraries/wil/wrl.h b/libraries/wil/wrl.h new file mode 100644 index 0000000..1106cab --- /dev/null +++ b/libraries/wil/wrl.h @@ -0,0 +1,127 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. +// +//********************************************************* +#ifndef __WIL_WRL_INCLUDED +#define __WIL_WRL_INCLUDED + +#include +#include "result.h" +#include "common.h" // wistd type_traits helpers +#include // GetModuleHandleW + +/// @cond +EXTERN_C IMAGE_DOS_HEADER __ImageBase; +/// @endcond + +namespace wil +{ + +#ifdef WIL_ENABLE_EXCEPTIONS +#pragma region Object construction helpers that throw exceptions + + /** Used to construct a RuntimeClass based object that uses 2 phase construction. + Construct a RuntimeClass based object that uses 2 phase construction (by implementing + RuntimeClassInitialize() and returning error codes for failures. + ~~~~ + // SomeClass uses 2 phase initialization by implementing RuntimeClassInitialize() + auto someClass = MakeAndInitializeOrThrow(L"input", true); + ~~~~ */ + + template + Microsoft::WRL::ComPtr MakeAndInitializeOrThrow(TArgs&&... args) + { + Microsoft::WRL::ComPtr obj; + THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize(&obj, Microsoft::WRL::Details::Forward(args)...)); + return obj; + } + + /** Used to construct an RuntimeClass based object that uses exceptions in its constructor (and does + not require 2 phase construction). + ~~~~ + // SomeClass uses exceptions for error handling in its constructor. + auto someClass = MakeOrThrow(L"input", true); + ~~~~ */ + + template + Microsoft::WRL::ComPtr MakeOrThrow(TArgs&&... args) + { + // This is how you can detect the presence of RuntimeClassInitialize() and find dangerous use. + // Unfortunately this produces false positives as all RuntimeClass derived classes have + // a RuntimeClassInitialize() method from their base class. + // static_assert(!std::is_member_function_pointer::value, + // "class has a RuntimeClassInitialize member, use MakeAndInitializeOrThrow instead"); + auto obj = Microsoft::WRL::Make(Microsoft::WRL::Details::Forward(args)...); + THROW_IF_NULL_ALLOC(obj.Get()); + return obj; + } +#pragma endregion + +#endif // WIL_ENABLE_EXCEPTIONS + + /** By default WRL Callback objects are not agile, use this to make an agile one. Replace use of Callback<> with MakeAgileCallback<>. + Will return null on failure, translate that into E_OUTOFMEMORY using XXX_IF_NULL_ALLOC() + from wil\result.h to test the result. */ + template + ::Microsoft::WRL::ComPtr MakeAgileCallbackNoThrow(Args&&... args) WI_NOEXCEPT + { + using namespace Microsoft::WRL; + return Callback, TDelegateInterface, FtmBase>>(wistd::forward(args)...); + } + +#ifdef WIL_ENABLE_EXCEPTIONS + template + ::Microsoft::WRL::ComPtr MakeAgileCallback(Args&&... args) + { + auto result = MakeAgileCallbackNoThrow(wistd::forward(args)...); + THROW_IF_NULL_ALLOC(result); + return result; + } +#endif // WIL_ENABLE_EXCEPTIONS + + /** Holds a reference to the host WRL module to prevent it from being unloaded. + Normally, the reference is held implicitly because you are a member function + of a DLL-hosted COM object, or because you retain a strong reference + to some DLL-hosted COM object, but if those do not apply to you, then you + will need to hold a reference explicitly. For examples (and for the C++/WinRT + equivalent), see winrt_module_reference. + */ + struct [[nodiscard]] wrl_module_reference + { + wrl_module_reference() + { + if (auto modulePtr = ::Microsoft::WRL::GetModuleBase()) + { + modulePtr->IncrementObjectCount(); + } + else + { +#ifdef GET_MODULE_HANDLE_EX_FLAG_PIN + // If this assertion fails, then you are using wrl_module_reference + // from a DLL that does not host WRL objects, and the module reference + // has no effect. + WI_ASSERT(reinterpret_cast(&__ImageBase) == GetModuleHandleW(nullptr)); +#endif + } + } + + wrl_module_reference(wrl_module_reference const&) : wrl_module_reference() {} + + ~wrl_module_reference() + { + if (auto modulePtr = ::Microsoft::WRL::GetModuleBase()) + { + modulePtr->DecrementObjectCount(); + } + } + }; + +} // namespace wil + +#endif // __WIL_WRL_INCLUDED diff --git a/res/windhawk-symbol-helper.ico b/res/windhawk-symbol-helper.ico new file mode 100644 index 0000000..d5d95d7 Binary files /dev/null and b/res/windhawk-symbol-helper.ico differ diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..cba6f85 --- /dev/null +++ b/resource.h @@ -0,0 +1,32 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by windhawk-symbol-helper.rc +// +#define IDD_ABOUTBOX 100 +#define IDR_MAINFRAME 128 +#define IDD_MAINDLG 129 +#define IDC_STATIC_ENGINE_DIR 1000 +#define IDC_ENGINE_DIR 1001 +#define IDC_STATIC_SYMBOLS_DIR 1002 +#define IDC_SYMBOLS_DIR 1003 +#define IDC_STATIC_SYMBOL_SERVER 1004 +#define IDC_SYMBOL_SERVER 1005 +#define IDC_STATIC_TARGET_EXECUTABLE 1006 +#define IDC_TARGET_EXECUTABLE 1007 +#define IDC_UNDECORATED 1008 +#define IDC_DECORATED 1009 +#define IDC_LOG 1010 +#define IDC_STATIC_RESULTS 1011 +#define IDC_RESULTS 1012 +#define IDC_RESULTS_PLACEHOLDER 1013 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 202 +#define _APS_NEXT_COMMAND_VALUE 32776 +#define _APS_NEXT_CONTROL_VALUE 1014 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..630eebd Binary files /dev/null and b/screenshot.png differ diff --git a/stdafx.cpp b/stdafx.cpp new file mode 100644 index 0000000..fd4f341 --- /dev/null +++ b/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/stdafx.h b/stdafx.h new file mode 100644 index 0000000..4a1cf0b --- /dev/null +++ b/stdafx.h @@ -0,0 +1,70 @@ +#pragma once + +// Change these values to use different versions +#define WINVER 0x0601 +#define _WIN32_WINNT 0x0601 +#define _WIN32_IE 0x0700 +#define _RICHEDIT_VER 0x0500 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define NOMINMAX + +// WTL + +#define _WTL_NO_CSTRING +#define _WTL_NO_WTYPES +#define _WTL_NO_UNION_CLASSES +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS + +#include +#include +#include + +#include +extern CAppModule _Module; + +#include + +#include // must be included before atlfind.h + +#include +#include +#include +#include + +// Windows + +#include + +// STL + +#include +#include +#include +#include +#include +#include + +// Libraries + +#include // must be included before other wil includes + +#include +#include + +#include +#include + +// clang-format off + +#if defined _M_IX86 + #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_IA64 + #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 + #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else + #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif + +// clang-format on diff --git a/symbol_enum.cpp b/symbol_enum.cpp new file mode 100644 index 0000000..612788d --- /dev/null +++ b/symbol_enum.cpp @@ -0,0 +1,405 @@ +#include "stdafx.h" + +#include "symbol_enum.h" + +namespace { + +std::filesystem::path g_enginePath; +SymbolEnum::Callbacks* g_symbolServerCallbacks; + +void VLogLine(PCWSTR format, va_list args) { + WCHAR buffer[1025]; + int len = _vsnwprintf_s(buffer, _TRUNCATE, format, args); + if (len == -1) { + // Truncation occurred. + len = _countof(buffer) - 1; + } + + while (--len >= 0 && buffer[len] == L'\n') { + // Skip all newlines at the end. + } + + // Leave only a single trailing newline. + if (buffer[len + 1] == L'\n' && buffer[len + 2] == L'\n') { + buffer[len + 2] = L'\0'; + } + + OutputDebugString(buffer); +} + +void LogLine(PCWSTR format, ...) { + va_list args; + va_start(args, format); + VLogLine(format, args); + va_end(args); +} + +#define LOG(format, ...) \ + LogLine(L"[!] SymbolEnum (%S): " format L"\n", __FUNCTION__, __VA_ARGS__) +#define VERBOSE(format, ...) \ + LogLine(L"[+] SymbolEnum (%S): " format L"\n", __FUNCTION__, __VA_ARGS__) + +std::wstring GetSymbolsSearchPath(PCWSTR symbolsPath, PCWSTR symbolServer) { + std::wstring symSearchPath = L"srv*"; + symSearchPath += symbolsPath; + symSearchPath += L'*'; + symSearchPath += symbolServer; + + return symSearchPath; +} + +void LogSymbolServerEvent(PCSTR msg) { + // Trim leading and trailing whitespace and control characters (mainly \b + // which is used for console output). + + PCSTR p = msg; + while (*p != '\0' && (isspace(*p) || iscntrl(*p))) { + p++; + } + + if (*p == '\0') { + return; + } + + size_t len = strlen(p); + while (len > 0 && (isspace(p[len - 1]) || iscntrl(p[len - 1]))) { + len--; + } + + VERBOSE(L"%.*S", len, p); +} + +int PercentFromSymbolServerEvent(PCSTR msg) { + size_t msgLen = strlen(msg); + while (msgLen > 0 && isspace(msg[msgLen - 1])) { + msgLen--; + } + + constexpr char suffix[] = " percent"; + constexpr size_t suffixLen = ARRAYSIZE(suffix) - 1; + + if (msgLen <= suffixLen || + strncmp(suffix, msg + msgLen - suffixLen, suffixLen) != 0) { + return -1; + } + + char percentStr[] = "000"; + int digitsCount = 0; + + for (size_t i = 1; i <= 3; i++) { + if (i > msgLen - suffixLen) { + break; + } + + char p = msg[msgLen - suffixLen - i]; + if (p < '0' || p > '9') { + break; + } + + percentStr[3 - i] = p; + digitsCount++; + } + + if (digitsCount == 0) { + return -1; + } + + int percent = (percentStr[0] - '0') * 100 + (percentStr[1] - '0') * 10 + + (percentStr[2] - '0'); + if (percent > 100) { + return -1; + } + + return percent; +} + +void** FindImportPtr(HMODULE hFindInModule, + PCSTR pModuleName, + PCSTR pImportName) { + IMAGE_DOS_HEADER* pDosHeader; + IMAGE_NT_HEADERS* pNtHeader; + ULONG_PTR ImageBase; + IMAGE_IMPORT_DESCRIPTOR* pImportDescriptor; + ULONG_PTR* pOriginalFirstThunk; + ULONG_PTR* pFirstThunk; + ULONG_PTR ImageImportByName; + + // Init + pDosHeader = (IMAGE_DOS_HEADER*)hFindInModule; + pNtHeader = (IMAGE_NT_HEADERS*)((char*)pDosHeader + pDosHeader->e_lfanew); + + if (!pNtHeader->OptionalHeader.DataDirectory[1].VirtualAddress) + return nullptr; + + ImageBase = (ULONG_PTR)hFindInModule; + pImportDescriptor = + (IMAGE_IMPORT_DESCRIPTOR*)(ImageBase + + pNtHeader->OptionalHeader.DataDirectory[1] + .VirtualAddress); + + // Search! + while (pImportDescriptor->OriginalFirstThunk) { + if (lstrcmpiA((char*)(ImageBase + pImportDescriptor->Name), + pModuleName) == 0) { + pOriginalFirstThunk = + (ULONG_PTR*)(ImageBase + pImportDescriptor->OriginalFirstThunk); + ImageImportByName = *pOriginalFirstThunk; + + pFirstThunk = + (ULONG_PTR*)(ImageBase + pImportDescriptor->FirstThunk); + + while (ImageImportByName) { + if (!(ImageImportByName & IMAGE_ORDINAL_FLAG)) { + if ((ULONG_PTR)pImportName & ~0xFFFF) { + ImageImportByName += sizeof(WORD); + + if (lstrcmpA((char*)(ImageBase + ImageImportByName), + pImportName) == 0) + return (void**)pFirstThunk; + } + } else { + if (((ULONG_PTR)pImportName & ~0xFFFF) == 0) + if ((ImageImportByName & 0xFFFF) == + (ULONG_PTR)pImportName) + return (void**)pFirstThunk; + } + + pOriginalFirstThunk++; + ImageImportByName = *pOriginalFirstThunk; + + pFirstThunk++; + } + } + + pImportDescriptor++; + } + + return nullptr; +} + +BOOL CALLBACK SymbolServerCallback(UINT_PTR action, + ULONG64 data, + ULONG64 context) { + SymbolEnum::Callbacks* callbacks = g_symbolServerCallbacks; + if (!callbacks) { + return FALSE; + } + + switch (action) { + case SSRVACTION_QUERYCANCEL: { + if (callbacks->queryCancel) { + ULONG64* doCancel = (ULONG64*)data; + *doCancel = callbacks->queryCancel(); + return TRUE; + } + return FALSE; + } + + case SSRVACTION_EVENT: { + IMAGEHLP_CBA_EVENT* evt = (IMAGEHLP_CBA_EVENT*)data; + LogSymbolServerEvent(evt->desc); + if (callbacks->notifyLog) { + callbacks->notifyLog(evt->desc); + } + int percent = PercentFromSymbolServerEvent(evt->desc); + if (percent >= 0 && callbacks->notifyProgress) { + callbacks->notifyProgress(percent); + } + return TRUE; + } + } + + return FALSE; +} + +HMODULE WINAPI MsdiaLoadLibraryExWHook(LPCWSTR lpLibFileName, + HANDLE hFile, + DWORD dwFlags) { + if (wcscmp(lpLibFileName, L"SYMSRV.DLL") != 0) { + return LoadLibraryExW(lpLibFileName, hFile, dwFlags); + } + + try { + DWORD dwNewFlags = dwFlags; + dwNewFlags |= LOAD_WITH_ALTERED_SEARCH_PATH; + + // Strip flags incompatible with LOAD_WITH_ALTERED_SEARCH_PATH. + dwNewFlags &= ~LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR; + dwNewFlags &= ~LOAD_LIBRARY_SEARCH_APPLICATION_DIR; + dwNewFlags &= ~LOAD_LIBRARY_SEARCH_USER_DIRS; + dwNewFlags &= ~LOAD_LIBRARY_SEARCH_SYSTEM32; + dwNewFlags &= ~LOAD_LIBRARY_SEARCH_DEFAULT_DIRS; + + auto symsrvPath = g_enginePath / L"symsrv_windhawk.dll"; + HMODULE symsrvModule = + LoadLibraryExW(symsrvPath.c_str(), hFile, dwNewFlags); + if (!symsrvModule) { + DWORD error = GetLastError(); + LOG(L"Couldn't load symsrv: %u", error); + SetLastError(error); + return symsrvModule; + } + + PSYMBOLSERVERSETOPTIONSPROC pSymbolServerSetOptions = + reinterpret_cast( + GetProcAddress(symsrvModule, "SymbolServerSetOptions")); + if (pSymbolServerSetOptions) { + pSymbolServerSetOptions(SSRVOPT_UNATTENDED, TRUE); + pSymbolServerSetOptions(SSRVOPT_CALLBACK, + (ULONG_PTR)SymbolServerCallback); + pSymbolServerSetOptions(SSRVOPT_TRACE, TRUE); + } else { + LOG(L"Couldn't find SymbolServerSetOptions"); + } + + return symsrvModule; + } catch (const std::exception& e) { + LOG(L"Couldn't load symsrv: %S", e.what()); + SetLastError(ERROR_MOD_NOT_FOUND); + return nullptr; + } +} + +} // namespace + +SymbolEnum::SymbolEnum(HMODULE moduleBase, + PCWSTR enginePath, + PCWSTR symbolsPath, + PCWSTR symbolServer, + Callbacks callbacks) { + if (!moduleBase) { + moduleBase = GetModuleHandle(nullptr); + } + + std::wstring modulePath = wil::GetModuleFileName(moduleBase); + + SymbolEnum(modulePath.c_str(), moduleBase, enginePath, symbolsPath, + symbolServer, std::move(callbacks)); +} + +SymbolEnum::SymbolEnum(PCWSTR modulePath, + HMODULE moduleBase, + PCWSTR enginePath, + PCWSTR symbolsPath, + PCWSTR symbolServer, + Callbacks callbacks) + : m_moduleBase(moduleBase) { +#ifdef _WIN64 + g_enginePath = std::filesystem::path(enginePath) / L"64"; +#else + g_enginePath = std::filesystem::path(enginePath) / L"32"; +#endif + + wil::com_ptr diaSource = LoadMsdia(); + + std::wstring symSearchPath = + GetSymbolsSearchPath(symbolsPath, symbolServer); + + g_symbolServerCallbacks = &callbacks; + auto msdiaCallbacksCleanup = + wil::scope_exit([] { g_symbolServerCallbacks = nullptr; }); + + THROW_IF_FAILED( + diaSource->loadDataForExe(modulePath, symSearchPath.c_str(), nullptr)); + + wil::com_ptr diaSession; + THROW_IF_FAILED(diaSource->openSession(&diaSession)); + + wil::com_ptr diaGlobal; + THROW_IF_FAILED(diaSession->get_globalScope(&diaGlobal)); + + THROW_IF_FAILED( + diaGlobal->findChildren(SymTagNull, nullptr, nsNone, &m_diaSymbols)); +} + +std::optional SymbolEnum::GetNextSymbol( + bool compatDemangling) { + while (true) { + wil::com_ptr diaSymbol; + ULONG count = 0; + HRESULT hr = m_diaSymbols->Next(1, &diaSymbol, &count); + THROW_IF_FAILED(hr); + + if (hr == S_FALSE || count == 0) { + return std::nullopt; + } + + DWORD currentSymbolRva; + hr = diaSymbol->get_relativeVirtualAddress(¤tSymbolRva); + THROW_IF_FAILED(hr); + if (hr == S_FALSE) { + continue; // no RVA + } + + // Temporary compatibility code. + if (compatDemangling) { + // get_undecoratedName uses 0x20800 as flags: + // * UNDNAME_32_BIT_DECODE (0x800) + // * UNDNAME_NO_PTR64 (0x20000) + // For some reason, the old msdia version still included ptr64 in + // the output. For compatibility, use get_undecoratedNameEx and + // don't pass this flag. + const DWORD kUndname32BitDecode = 0x800; + hr = diaSymbol->get_undecoratedNameEx(kUndname32BitDecode, + &m_currentSymbolName); + } else { + hr = diaSymbol->get_undecoratedName(&m_currentSymbolName); + } + THROW_IF_FAILED(hr); + if (hr == S_FALSE) { + m_currentSymbolName.reset(); // no name + } + + hr = diaSymbol->get_name(&m_currentDecoratedSymbolName); + THROW_IF_FAILED(hr); + if (hr == S_FALSE) { + m_currentDecoratedSymbolName.reset(); // no name + } + + return SymbolEnum::Symbol{ + reinterpret_cast(reinterpret_cast(m_moduleBase) + + currentSymbolRva), + m_currentSymbolName.get(), m_currentDecoratedSymbolName.get()}; + } +} + +wil::com_ptr SymbolEnum::LoadMsdia() { + auto msdiaPath = g_enginePath / L"msdia140_windhawk.dll"; + + m_msdiaModule.reset(LoadLibraryEx(msdiaPath.c_str(), nullptr, + LOAD_WITH_ALTERED_SEARCH_PATH)); + THROW_LAST_ERROR_IF_NULL(m_msdiaModule); + + // msdia loads symsrv.dll by using the following call: + // LoadLibraryExW(L"SYMSRV.DLL"); + // This is problematic for the following reasons: + // * If another file named symsrv.dll is already loaded, + // it will be used instead. + // * If not, the library loading search path doesn't include our folder + // by default. + // Especially due to the first point, we patch msdia in memory to use + // the full path to our copy of symsrv.dll. + // Also, to prevent from other msdia instances to load our version of + // symsrv, we name it differently. + + void** msdiaLoadLibraryExWPtr = + FindImportPtr(m_msdiaModule.get(), "kernel32.dll", "LoadLibraryExW"); + + DWORD dwOldProtect; + THROW_IF_WIN32_BOOL_FALSE( + VirtualProtect(msdiaLoadLibraryExWPtr, sizeof(*msdiaLoadLibraryExWPtr), + PAGE_EXECUTE_READWRITE, &dwOldProtect)); + *msdiaLoadLibraryExWPtr = MsdiaLoadLibraryExWHook; + THROW_IF_WIN32_BOOL_FALSE(VirtualProtect(msdiaLoadLibraryExWPtr, + sizeof(*msdiaLoadLibraryExWPtr), + dwOldProtect, &dwOldProtect)); + + wil::com_ptr diaSource; + THROW_IF_FAILED(NoRegCoCreate(msdiaPath.c_str(), CLSID_DiaSource, + IID_PPV_ARGS(&diaSource))); + + // Decrements the reference count incremented by NoRegCoCreate. + FreeLibrary(m_msdiaModule.get()); + + return diaSource; +} diff --git a/symbol_enum.h b/symbol_enum.h new file mode 100644 index 0000000..5e59acb --- /dev/null +++ b/symbol_enum.h @@ -0,0 +1,39 @@ +#pragma once + +class SymbolEnum { + public: + struct Callbacks { + std::function queryCancel; + std::function notifyProgress; + std::function notifyLog; + }; + + SymbolEnum(HMODULE moduleBase, + PCWSTR enginePath, + PCWSTR symbolsPath, + PCWSTR symbolServer, + Callbacks callbacks = {}); + SymbolEnum(PCWSTR modulePath, + HMODULE moduleBase, + PCWSTR enginePath, + PCWSTR symbolsPath, + PCWSTR symbolServer, + Callbacks callbacks = {}); + + struct Symbol { + void* address; + PCWSTR name; + PCWSTR nameDecorated; + }; + + std::optional GetNextSymbol(bool compatDemangling); + + private: + wil::com_ptr LoadMsdia(); + + HMODULE m_moduleBase; + wil::unique_hmodule m_msdiaModule; + wil::com_ptr m_diaSymbols; + wil::unique_bstr m_currentSymbolName; + wil::unique_bstr m_currentDecoratedSymbolName; +}; diff --git a/view.h b/view.h new file mode 100644 index 0000000..29ce048 --- /dev/null +++ b/view.h @@ -0,0 +1,93 @@ +#include "finddlg.h" + +class CEditView : + public CWindowImpl, + public CEditCommands, + public CEditFindReplaceImpl +{ +protected: + typedef CEditView thisClass; + typedef CEditCommands editCommandsClass; + typedef CEditFindReplaceImpl findReplaceClass; + +public: + DECLARE_WND_SUPERCLASS(NULL, CEdit::GetWndClassName()) + + BOOL PreTranslateMessage(MSG* pMsg) + { + // In non Multi-thread SDI cases, CFindReplaceDialogWithMessageFilter will add itself to the + // global message filters list. In our case, we'll call it directly. + if(m_pFindReplaceDialog != NULL) + { + if(m_pFindReplaceDialog->PreTranslateMessage(pMsg)) + return TRUE; + } + return FALSE; + } + + BEGIN_MSG_MAP(CEditView) + MESSAGE_HANDLER(WM_CREATE, OnCreate) + + CHAIN_MSG_MAP_ALT(editCommandsClass, 1) + + CHAIN_MSG_MAP_ALT(findReplaceClass, 1) + END_MSG_MAP() + + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) + { + LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); + + LimitText(0); + + return lRet; + } + +// Overrides from CEditFindReplaceImpl + CFindReplaceDialogWithMessageFilter* CreateFindReplaceDialog(BOOL bFindOnly, // TRUE for Find, FALSE for FindReplace + LPCTSTR lpszFindWhat, + LPCTSTR lpszReplaceWith = NULL, + DWORD dwFlags = FR_DOWN, + HWND hWndParent = NULL) + { + // In non Multi-Threaded SDI cases, we'd pass in the message loop to CFindReplaceDialogWithMessageFilter. + // In our case, we'll call PreTranslateMessage directly from this class. + //CFindReplaceDialogWithMessageFilter* findReplaceDialog = + // new CFindReplaceDialogWithMessageFilter(_Module.GetMessageLoop()); + CFindReplaceDialogWithMessageFilter* findReplaceDialog = + new CFindReplaceDialogWithMessageFilter(NULL); + + if(findReplaceDialog == NULL) + { + ::MessageBeep(MB_ICONHAND); + } + else + { + HWND hWndFindReplace = findReplaceDialog->Create(bFindOnly, + lpszFindWhat, lpszReplaceWith, dwFlags, hWndParent); + if(hWndFindReplace == NULL) + { + delete findReplaceDialog; + findReplaceDialog = NULL; + } + else + { + findReplaceDialog->SetActiveWindow(); + findReplaceDialog->ShowWindow(SW_SHOW); + } + } + + return findReplaceDialog; + } + + DWORD GetFindReplaceDialogFlags(void) const + { + DWORD dwFlags = FR_HIDEWHOLEWORD; + + if(m_bFindDown) + dwFlags |= FR_DOWN; + if(m_bMatchCase) + dwFlags |= FR_MATCHCASE; + + return dwFlags; + } +}; diff --git a/windhawk-symbol-helper.cpp b/windhawk-symbol-helper.cpp new file mode 100644 index 0000000..3bb7835 --- /dev/null +++ b/windhawk-symbol-helper.cpp @@ -0,0 +1,39 @@ +#include "stdafx.h" + +#include "MainDlg.h" + +CAppModule _Module; + +int WINAPI _tWinMain(HINSTANCE hInstance, + HINSTANCE /*hPrevInstance*/, + LPTSTR /*lpstrCmdLine*/, + int nCmdShow) { + HRESULT hRes = ::CoInitialize(NULL); + ATLASSERT(SUCCEEDED(hRes)); + + AtlInitCommonControls( + ICC_BAR_CLASSES); // add flags to support other controls + + hRes = _Module.Init(NULL, hInstance); + ATLASSERT(SUCCEEDED(hRes)); + + CMessageLoop theLoop; + _Module.AddMessageLoop(&theLoop); + + CMainDlg dlgMain; + int nRet = 0; + + if (dlgMain.Create(nullptr)) { + dlgMain.ShowWindow(nCmdShow); + nRet = theLoop.Run(); + } else { + ATLTRACE(L"Main dialog creation failed!\n"); + } + + _Module.RemoveMessageLoop(); + + _Module.Term(); + ::CoUninitialize(); + + return nRet; +} diff --git a/windhawk-symbol-helper.h b/windhawk-symbol-helper.h new file mode 100644 index 0000000..f75ed45 --- /dev/null +++ b/windhawk-symbol-helper.h @@ -0,0 +1 @@ +// windhawk-symbol-helper.h diff --git a/windhawk-symbol-helper.rc b/windhawk-symbol-helper.rc new file mode 100644 index 0000000..232b2fa --- /dev/null +++ b/windhawk-symbol-helper.rc @@ -0,0 +1,279 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "atlres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""atlres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "res\\windhawk-symbol-helper.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG 0, 0, 187, 102 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,130,81,50,14 + CTEXT "windhawk-symbol-helper Application v1.0\n\n(c) Copyright 2023",IDC_STATIC,25,57,78,32 + ICON IDR_MAINFRAME,IDC_STATIC,55,26,18,20 + GROUPBOX "",IDC_STATIC,7,7,115,88 +END + +IDD_MAINDLG DIALOGEX 0, 0, 277, 296 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Windhawk Symbol Helper" +FONT 9, "Segoe UI", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "Get &symbols",IDOK,7,275,50,14 + PUSHBUTTON "&About",ID_APP_ABOUT,114,275,50,14 + PUSHBUTTON "Close",IDCANCEL,220,275,50,14 + LTEXT "&Engine folder that contains symsrv_windhawk.dll and msdia140_windhawk.dll:",IDC_STATIC_ENGINE_DIR,7,7,263,8 + EDITTEXT IDC_ENGINE_DIR,7,17,263,12,ES_AUTOHSCROLL + LTEXT "Symbols &folder:",IDC_STATIC_SYMBOLS_DIR,7,34,263,8 + EDITTEXT IDC_SYMBOLS_DIR,7,44,263,12,ES_AUTOHSCROLL + LTEXT "Symbol ser&ver:",IDC_STATIC_SYMBOL_SERVER,7,61,263,8 + EDITTEXT IDC_SYMBOL_SERVER,7,71,263,12,ES_AUTOHSCROLL + LTEXT "Target e&xecutable:",IDC_STATIC_TARGET_EXECUTABLE,7,88,263,8 + EDITTEXT IDC_TARGET_EXECUTABLE,7,98,263,12,ES_AUTOHSCROLL + CONTROL "&Undecorated",IDC_UNDECORATED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,115,55,10 + CONTROL "&Decorated",IDC_DECORATED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,115,47,10 + CONTROL "&Log",IDC_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,115,27,10 + LTEXT "&Results:",IDC_STATIC_RESULTS,7,130,263,8 + LTEXT "Static",IDC_RESULTS_PLACEHOLDER,7,140,263,129,NOT WS_VISIBLE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 180 + TOPMARGIN, 7 + BOTTOMMARGIN, 95 + END + + IDD_MAINDLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 270 + TOPMARGIN, 7 + BOTTOMMARGIN, 289 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_MAINFRAME ACCELERATORS +BEGIN + "F", ID_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT + VK_F3, ID_EDIT_REPEAT, VIRTKEY, NOINVERT + VK_F3, ID_EDIT_REPEAT, VIRTKEY, SHIFT, NOINVERT + "H", ID_EDIT_REPLACE, VIRTKEY, CONTROL, NOINVERT + "R", ID_EDIT_REPLACE, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "FileDescription", "windhawk-symbol-helper Module" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "windhawk-symbol-helper" + VALUE "LegalCopyright", "Copyright 2023" + VALUE "OriginalFilename", "windhawk-symbol-helper.exe" + VALUE "ProductName", "windhawk-symbol-helper Module" + VALUE "ProductVersion", "1, 0, 0, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +IDD_MAINDLG AFX_DIALOG_LAYOUT +BEGIN + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDR_MAINFRAME "windhawk-symbol-helper" +END + +STRINGTABLE +BEGIN + ID_FILE_NEW "Create a new document\nNew" + ID_FILE_OPEN "Open an existing document\nOpen" + ID_FILE_CLOSE "Close the active document\nClose" + ID_FILE_SAVE "Save the active document\nSave" + ID_FILE_SAVE_AS "Save the active document with a new name\nSave As" + ID_FILE_PAGE_SETUP "Change the printing options\nPage Setup" + ID_FILE_PRINT_SETUP "Change the printer and printing options\nPrint Setup" + ID_FILE_PRINT "Print the active document\nPrint" + ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview" +END + +STRINGTABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright\nAbout" + ID_APP_EXIT "Quit the application; prompts to save documents\nExit" +END + +STRINGTABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane\nNext Pane" + ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane" +END + +STRINGTABLE +BEGIN + ID_WINDOW_NEW "Open another window for the active document\nNew Window" + ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons" + ID_WINDOW_CASCADE "Arrange windows so they overlap\nCascade Windows" + ID_WINDOW_TILE_HORZ "Arrange windows as non-overlapping tiles\nTile Windows" + ID_WINDOW_TILE_VERT "Arrange windows as non-overlapping tiles\nTile Windows" + ID_WINDOW_SPLIT "Split the active window into panes\nSplit" +END + +STRINGTABLE +BEGIN + ID_EDIT_CLEAR "Erase the selection\nErase" + ID_EDIT_CLEAR_ALL "Erase everything\nErase All" + ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy" + ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut" + ID_EDIT_FIND "Find the specified text\nFind" + ID_EDIT_PASTE "Insert Clipboard contents\nPaste" + ID_EDIT_REPEAT "Repeat the last action\nRepeat" + ID_EDIT_REPLACE "Replace specific text with different text\nReplace" + ID_EDIT_SELECT_ALL "Select the entire document\nSelect All" + ID_EDIT_UNDO "Undo the last action\nUndo" + ID_EDIT_REDO "Redo the previously undone action\nRedo" +END + +STRINGTABLE +BEGIN + ATL_IDS_SCSIZE "Change the window size" + ATL_IDS_SCMOVE "Change the window position" + ATL_IDS_SCMINIMIZE "Reduce the window to an icon" + ATL_IDS_SCMAXIMIZE "Enlarge the window to full size" + ATL_IDS_SCNEXTWINDOW "Switch to the next document window" + ATL_IDS_SCPREVWINDOW "Switch to the previous document window" + ATL_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE +BEGIN + ATL_IDS_SCRESTORE "Restore the window to normal size" + ATL_IDS_SCTASKLIST "Activate Task List" + ATL_IDS_MDICHILD "Activate this window" +END + +STRINGTABLE +BEGIN + ATL_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE +BEGIN + ATL_IDS_MRU_FILE "Open this document" +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + diff --git a/windhawk-symbol-helper.sln b/windhawk-symbol-helper.sln new file mode 100644 index 0000000..efaaa86 --- /dev/null +++ b/windhawk-symbol-helper.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34031.279 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windhawk-symbol-helper", "windhawk-symbol-helper.vcxproj", "{5087A507-4250-43E8-8763-31C652DC50AA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5087A507-4250-43E8-8763-31C652DC50AA}.Debug|x64.ActiveCfg = Debug|x64 + {5087A507-4250-43E8-8763-31C652DC50AA}.Debug|x64.Build.0 = Debug|x64 + {5087A507-4250-43E8-8763-31C652DC50AA}.Debug|x86.ActiveCfg = Debug|Win32 + {5087A507-4250-43E8-8763-31C652DC50AA}.Debug|x86.Build.0 = Debug|Win32 + {5087A507-4250-43E8-8763-31C652DC50AA}.Release|x64.ActiveCfg = Release|x64 + {5087A507-4250-43E8-8763-31C652DC50AA}.Release|x64.Build.0 = Release|x64 + {5087A507-4250-43E8-8763-31C652DC50AA}.Release|x86.ActiveCfg = Release|Win32 + {5087A507-4250-43E8-8763-31C652DC50AA}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {739833D1-B751-4A94-8D4B-794BBB640A2B} + EndGlobalSection +EndGlobal diff --git a/windhawk-symbol-helper.vcxproj b/windhawk-symbol-helper.vcxproj new file mode 100644 index 0000000..8ad1eba --- /dev/null +++ b/windhawk-symbol-helper.vcxproj @@ -0,0 +1,249 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {5087A507-4250-43E8-8763-31C652DC50AA} + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + Unicode + + + + + + + + + + + + + + + + + + + + + true + C:\WTL10\Include;$(ProjectDir)libraries;$(IncludePath) + $(ProjectDir)libraries;$(LibraryPath) + + + true + C:\WTL10\Include;$(ProjectDir)libraries;$(IncludePath) + $(ProjectDir)libraries;$(LibraryPath) + + + false + C:\WTL10\Include;$(ProjectDir)libraries;$(IncludePath) + $(ProjectDir)libraries;$(LibraryPath) + + + false + C:\WTL10\Include;$(ProjectDir)libraries;$(IncludePath) + $(ProjectDir)libraries;$(LibraryPath) + + + + Use + Level3 + MultiThreadedDebug + EditAndContinue + EnableFastChecks + Disabled + _WINDOWS;STRICT;_DEBUG;%(PreprocessorDefinitions) + stdcpp20 + /d1trimfile:"$(SolutionDir)\" %(AdditionalOptions) + + + Windows + true + dia/lib/amd64/diaguids.lib;%(AdditionalDependencies) + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) + + + false + _DEBUG;%(PreprocessorDefinitions) + windhawk-symbol-helper.h + windhawk-symbol-helper_i.c + windhawk-symbol-helper_p.c + true + $(IntDir)/windhawk-symbol-helper.tlb + + + + + + Use + Level3 + MultiThreadedDebug + EditAndContinue + EnableFastChecks + Disabled + WIN32;_WINDOWS;STRICT;_DEBUG;%(PreprocessorDefinitions) + stdcpp20 + /d1trimfile:"$(SolutionDir)\" %(AdditionalOptions) + + + Windows + true + dia/lib/diaguids.lib;%(AdditionalDependencies) + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) + + + false + Win32 + _DEBUG;%(PreprocessorDefinitions) + windhawk-symbol-helper.h + windhawk-symbol-helper_i.c + windhawk-symbol-helper_p.c + true + $(IntDir)/windhawk-symbol-helper.tlb + + + + + + Use + Level3 + MultiThreaded + Sync + + WIN32;_WINDOWS;STRICT;NDEBUG;%(PreprocessorDefinitions) + stdcpp20 + /d1trimfile:"$(SolutionDir)\" %(AdditionalOptions) + + + Windows + dia/lib/diaguids.lib;%(AdditionalDependencies) + false + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) + + + false + Win32 + NDEBUG;%(PreprocessorDefinitions) + windhawk-symbol-helper.h + windhawk-symbol-helper_i.c + windhawk-symbol-helper_p.c + true + $(IntDir)/windhawk-symbol-helper.tlb + + + + + + Use + Level3 + MultiThreaded + Sync + + _WINDOWS;STRICT;NDEBUG;%(PreprocessorDefinitions) + stdcpp20 + /d1trimfile:"$(SolutionDir)\" %(AdditionalOptions) + + + Windows + dia/lib/amd64/diaguids.lib;%(AdditionalDependencies) + false + + + 0x0409 + $(IntDir);%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions) + + + false + NDEBUG;%(PreprocessorDefinitions) + windhawk-symbol-helper.h + windhawk-symbol-helper_i.c + windhawk-symbol-helper_p.c + true + $(IntDir)/windhawk-symbol-helper.tlb + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/windhawk-symbol-helper.vcxproj.filters b/windhawk-symbol-helper.vcxproj.filters new file mode 100644 index 0000000..07b9ab6 --- /dev/null +++ b/windhawk-symbol-helper.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {1f659fff-1524-49ec-ae52-eb976679c22a} + cpp;c;cxx;def;odl;idl;hpj;bat;asm + + + {01d3f90e-c5c1-4a89-9508-00eb58603f6e} + h;hpp;hxx;hm;inl;inc + + + {ef0d9713-3f11-4940-8978-ae6d3a24e1f8} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file