/// The <c>SetupDiGetClassDevs</c> function returns a handle to a device information set that contains requested device information
/// elements for a local computer.
/// </summary>
/// <param name="ClassGuid">
/// A pointer to the GUID for a device setup class or a device interface class. This pointer is optional and can be <c>NULL</c>. For
/// more information about how to set ClassGuid, see the following <c>Remarks</c> section.
/// </param>
/// <param name="Enumerator">
/// <para>A pointer to a NULL-terminated string that specifies:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// An identifier (ID) of a Plug and Play (PnP) enumerator. This ID can either be the value's globally unique identifier (GUID) or
/// symbolic name. For example, "PCI" can be used to specify the PCI PnP value. Other examples of symbolic names for PnP values
/// include "USB," "PCMCIA," and "SCSI".
/// </term>
/// </item>
/// <item>
/// <term>A PnP device instance ID. When specifying a PnP device instance ID, DIGCF_DEVICEINTERFACE must be set in the Flags parameter.</term>
/// </item>
/// </list>
/// <para>This pointer is optional and can be</para>
/// <para>NULL</para>
/// <para>. If an</para>
/// <para>enumeration</para>
/// <para>value is not used to select devices, set</para>
/// <para>Enumerator</para>
/// <para>to</para>
/// <para>NULL</para>
/// <para>For more information about how to set the Enumerator value, see the following <c>Remarks</c> section.</para>
/// </param>
/// <param name="hwndParent">
/// A handle to the top-level window to be used for a user interface that is associated with installing a device instance in the
/// device information set. This handle is optional and can be <c>NULL</c>.
/// </param>
/// <param name="Flags">
/// <para>
/// A variable of type DWORD that specifies control options that filter the device information elements that are added to the device
/// information set. This parameter can be a bitwise OR of zero or more of the following flags. For more information about combining
/// these flags, see the following <c>Remarks</c> section.
/// </para>
/// <para>DIGCF_ALLCLASSES</para>
/// <para>Return a list of installed devices for all device setup classes or all device interface classes.</para>
/// <para>DIGCF_DEVICEINTERFACE</para>
/// <para>
/// Return devices that support device interfaces for the specified device interface classes. This flag must be set in the Flags
/// parameter if the Enumerator parameter specifies a device instance ID.
/// </para>
/// <para>DIGCF_DEFAULT</para>
/// <para>
/// Return only the device that is associated with the system default device interface, if one is set, for the specified device
/// interface classes.
/// </para>
/// <para>DIGCF_PRESENT</para>
/// <para>Return only devices that are currently present in a system.</para>
/// <para>DIGCF_PROFILE</para>
/// <para>Return only devices that are a part of the current hardware profile.</para>
/// </param>
/// <returns>
/// If the operation succeeds, <c>SetupDiGetClassDevs</c> returns a handle to a device information set that contains all installed
/// devices that matched the supplied parameters. If the operation fails, the function returns INVALID_HANDLE_VALUE. To get extended
/// error information, call GetLastError.
/// </returns>
/// <remarks>
/// <para>
/// The caller of <c>SetupDiGetClassDevs</c> must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList.
/// </para>
/// <para>Call SetupDiGetClassDevsEx to retrieve the devices for a class on a remote computer.</para>
/// <para>Device Setup Class Control Options</para>
/// <para>
/// Use the following filtering options to control whether <c>SetupDiGetClassDevs</c> returns devices for all device setup classes
/// or only for a specified device setup class:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>To return devices for all device setup classes, set the DIGCF_ALLCLASSES flag, and set the ClassGuid parameter to <c>NULL</c>.</term>
/// </item>
/// <item>
/// <term>
/// To return devices only for a specific device setup class, do not set DIGCF_ALLCLASSES, and use ClassGuid to supply the GUID of
/// the device setup class.
/// </term>
/// </item>
/// </list>
/// <para>
/// In addition, you can use the following filtering options in combination with one another to further restrict which devices are returned:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>To return only devices that are present in the system, set the DIGCF_PRESENT flag.</term>
/// </item>
/// <item>
/// <term>To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag.</term>
/// </item>
/// <item>
/// <term>
/// To return devices only for a specific PnP enumerator, use the Enumerator parameter to supply the GUID or symbolic name of the
/// enumerator. If Enumerator is <c>NULL</c>, <c>SetupDiGetClassDevs</c> returns devices for all PnP enumerators.
/// </term>
/// </item>
/// </list>
/// <para>Device Interface Class Control Options</para>
/// <para>
/// Use the following filtering options to control whether <c>SetupDiGetClassDevs</c> returns devices that support any device
/// interface class or only devices that support a specified device interface class:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// To return devices that support a device interface of any class, set the DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES
/// flag, and set ClassGuid to <c>NULL</c>. The function adds to the device information set a device information element that
/// represents such a device and then adds to the device information element a device interface list that contains all the device
/// interfaces that the device supports.
/// </term>
/// </item>
/// <item>
/// <term>
/// To return only devices that support a device interface of a specified class, set the DIGCF_DEVICEINTERFACE flag and use the
/// ClassGuid parameter to supply the class GUID of the device interface class. The function adds to the device information set a
/// device information element that represents such a device and then adds a device interface of the specified class to the device
/// interface list for that device information element.
/// </term>
/// </item>
/// </list>
/// <para>
/// In addition, you can use the following filtering options to control whether <c>SetupDiGetClassDevs</c> returns only devices that
/// support the system default interface for device interface classes:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// To return only the device that supports the system default interface, if one is set, for a specified device interface class, set
/// the DIGCF_DEVICEINTERFACE flag, set the DIGCF_DEFAULT flag, and use ClassGuid to supply the class GUID of the device interface
/// class. The function adds to the device information set a device information element that represents such a device and then adds
/// the system default interface to the device interface list for that device information element.
/// </term>
/// </item>
/// <item>
/// <term>
/// To return a device that supports a system default interface for an unspecified device interface class, set the
/// DIGCF_DEVICEINTERFACE flag, set the DIGCF_ALLCLASSES flag, set the DIGCF_DEFAULT flag, and set ClassGuid to <c>NULL</c>. The
/// function adds to the device information set a device information element that represents such a device and then adds the system
/// default interface to the device interface list for that device information element.
/// </term>
/// </item>
/// </list>
/// <para>You can also use the following options in combination with the other options to further restrict which devices are returned:</para>
/// <list type="bullet">
/// <item>
/// <term>To return only devices that are present in the system, set the DIGCF_PRESENT flag.</term>
/// </item>
/// <item>
/// <term>To return only devices that are part of the current hardware profile, set the DIGCF_PROFILE flag.</term>
/// </item>
/// <item>
/// <term>
/// To return only a specific device, set the DIGCF_DEVICEINTERFACE flag and use the Enumerator parameter to supply the device
/// instance ID of the device. To include all possible devices, set Enumerator to <c>NULL</c>.
/// </term>
/// </item>
/// </list>
/// <para>Examples</para>
/// <para>The following are some examples of how to use the <c>SetupDiGetClassDevs</c> function.</para>
/// <para><c>Example 1:</c> Build a list of all devices in the system, including devices that are not currently present.</para>
/// <summary>The <c>SetupDiGetDeviceProperty</c> function retrieves a device instance property.</summary>
/// <param name="DeviceInfoSet">
/// A handle to a device information set that contains a device instance for which to retrieve a device instance property.
/// </param>
/// <param name="DeviceInfoData">
/// A pointer to the SP_DEVINFO_DATA structure that represents the device instance for which to retrieve a device instance property.
/// </param>
/// <param name="PropertyKey">
/// A pointer to a DEVPROPKEY structure that represents the device property key of the requested device instance property.
/// </param>
/// <param name="PropertyType">
/// A pointer to a DEVPROPTYPE-typed variable that receives the property-data-type identifier of the requested device instance
/// property, where the property-data-type identifier is the bitwise OR between a base-data-type identifier and, if the base-data
/// type is modified, a property-data-type modifier.
/// </param>
/// <param name="PropertyBuffer">
/// A pointer to a buffer that receives the requested device instance property. <c>SetupDiGetDeviceProperty</c> retrieves the
/// requested property only if the buffer is large enough to hold all the property value data. The pointer can be <c>NULL</c>. If
/// the pointer is set to <c>NULL</c> and RequiredSize is supplied, <c>SetupDiGetDeviceProperty</c> returns the size of the
/// property, in bytes, in *RequiredSize.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to <c>NULL</c>, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="RequiredSize">
/// A pointer to a DWORD-typed variable that receives the size, in bytes, of either the device instance property if the property is
/// retrieved or the required buffer size if the buffer is not large enough. This pointer can be set to <c>NULL</c>.
/// </param>
/// <param name="Flags">This parameter must be set to zero.</param>
/// <returns>
/// <para>
/// <c>SetupDiGetDeviceProperty</c> returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c>, and the logged
/// error can be retrieved by calling GetLastError.
/// </para>
/// <para>The following table includes some of the more common error codes that this function might log.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_FLAGS</term>
/// <term>The value of Flags is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The device information set that is specified by DevInfoSet is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>A supplied parameter is not valid. One possibility is that the device information element is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_REG_PROPERTY</term>
/// <term>The property key that is supplied by PropertyKey is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_DATA</term>
/// <term>An unspecified internal data value was not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_USER_BUFFER</term>
/// <term>A user buffer is not valid. One possibility is that PropertyBuffer is NULL and PropertBufferSize is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_SUCH_DEVINST</term>
/// <term>The device instance that is specified by DevInfoData does not exist.</term>
/// </item>
/// <item>
/// <term>ERROR_INSUFFICIENT_BUFFER</term>
/// <term>
/// The PropertyBuffer buffer is too small to hold the requested property value, or an internal data buffer that was passed to a
/// system call was too small.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>There was not enough system memory available to complete the operation.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_FOUND</term>
/// <term>The requested device property does not exist.</term>
/// </item>
/// <item>
/// <term>ERROR_ACCESS_DENIED</term>
/// <term>The caller does not have Administrator privileges.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>SetupDiGetDeviceProperty</c> is part of the unified device property model.</para>
/// <para>SetupAPI supports only a Unicode version of <c>SetupDiGetDeviceProperty</c>.</para>
/// <para>To obtain the device property keys that represent the device properties that are set for a device instance, call SetupDiGetDevicePropertyKeys.</para>
/// <para>To set a device instance property, call SetupDiSetDeviceProperty.</para>
/// <summary>The <c>SetupDiGetDeviceProperty</c> function retrieves a device instance property.</summary>
/// <param name="DeviceInfoSet">
/// A handle to a device information set that contains a device instance for which to retrieve a device instance property.
/// </param>
/// <param name="DeviceInfoData">
/// A pointer to the SP_DEVINFO_DATA structure that represents the device instance for which to retrieve a device instance property.
/// </param>
/// <param name="PropertyKey">
/// A pointer to a DEVPROPKEY structure that represents the device property key of the requested device instance property.
/// </param>
/// <param name="Value">
/// A pointer to a buffer that receives the requested device instance property. <c>SetupDiGetDeviceProperty</c> retrieves the
/// requested property only if the buffer is large enough to hold all the property value data. The pointer can be <c>NULL</c>. If
/// the pointer is set to <c>NULL</c> and RequiredSize is supplied, <c>SetupDiGetDeviceProperty</c> returns the size of the
/// property, in bytes, in *RequiredSize.
/// </param>
/// <returns>
/// <para>
/// <c>SetupDiGetDeviceProperty</c> returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c>, and the logged
/// error can be retrieved by calling GetLastError.
/// </para>
/// <para>The following table includes some of the more common error codes that this function might log.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_FLAGS</term>
/// <term>The value of Flags is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The device information set that is specified by DevInfoSet is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>A supplied parameter is not valid. One possibility is that the device information element is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_REG_PROPERTY</term>
/// <term>The property key that is supplied by PropertyKey is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_DATA</term>
/// <term>An unspecified internal data value was not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_USER_BUFFER</term>
/// <term>A user buffer is not valid. One possibility is that PropertyBuffer is NULL and PropertBufferSize is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_SUCH_DEVINST</term>
/// <term>The device instance that is specified by DevInfoData does not exist.</term>
/// </item>
/// <item>
/// <term>ERROR_INSUFFICIENT_BUFFER</term>
/// <term>
/// The PropertyBuffer buffer is too small to hold the requested property value, or an internal data buffer that was passed to a
/// system call was too small.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>There was not enough system memory available to complete the operation.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_FOUND</term>
/// <term>The requested device property does not exist.</term>
/// </item>
/// <item>
/// <term>ERROR_ACCESS_DENIED</term>
/// <term>The caller does not have Administrator privileges.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>SetupDiGetDeviceProperty</c> is part of the unified device property model.</para>
/// <para>SetupAPI supports only a Unicode version of <c>SetupDiGetDeviceProperty</c>.</para>
/// <para>To obtain the device property keys that represent the device properties that are set for a device instance, call SetupDiGetDevicePropertyKeys.</para>
/// <para>To set a device instance property, call SetupDiSetDeviceProperty.</para>
/// The <c>SetupDiGetDevicePropertyKeys</c> function retrieves an array of the device property keys that represent the device
/// properties that are set for a device instance.
/// </summary>
/// <param name="DeviceInfoSet">
/// A handle to a device information set. This device information set contains the device instance for which this function retrieves
/// an array of device property keys. The property keys represent the device properties that are set for the device instance.
/// </param>
/// <param name="DeviceInfoData">
/// A pointer to an SP_DEVINFO_DATA structure that represents the device instance for which to retrieve the requested array of
/// device property keys.
/// </param>
/// <param name="PropertyKeyArray">
/// A pointer to a buffer that receives an array of DEVPROPKEY-typed values, where each value is a device property key that
/// represents a device property that is set for the device instance. The pointer is optional and can be <c>NULL</c>. For more
/// information, see the <c>Remarks</c> section later in this topic.
/// </param>
/// <param name="PropertyKeyCount">
/// The size, in DEVPROPKEY-typed values, of the PropertyKeyArray buffer. If PropertyKeyArray is set to <c>NULL</c>,
/// PropertyKeyCount must be set to zero.
/// </param>
/// <param name="RequiredPropertyKeyCount">
/// A pointer to a DWORD-typed variable that receives the number of requested device property keys. The pointer is optional and can
/// be set to <c>NULL</c>.
/// </param>
/// <param name="Flags">This parameter must be set to zero.</param>
/// <returns>
/// <para>
/// <c>SetupDiGetDevicePropertyKeys</c> returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c>, and the logged
/// error can be retrieved by calling GetLastError.
/// </para>
/// <para>The following table includes some of the more common error codes that this function might log.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_FLAGS</term>
/// <term>The value of Flags is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The device information set that is specified by DevInfoSet is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>A supplied parameter is not valid. One possibility is that the device information element is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_DATA</term>
/// <term>An internal data value is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_USER_BUFFER</term>
/// <term>A user buffer is not valid. One possibility is that PropertyKeyArray is NULL and PropertKeyCount is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_SUCH_DEVINST</term>
/// <term>The device instance that is specified by DevInfoData does not exist.</term>
/// </item>
/// <item>
/// <term>ERROR_INSUFFICIENT_BUFFER</term>
/// <term>The PropertyKeyArray buffer is too small to hold all the requested property keys.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>There was not enough system memory available to complete the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>SetupDiGetDevicePropertyKeys</c> is part of the unified device property model.</para>
/// <para>
/// If the ProperKeyArray buffer is not large enough to hold all the requested property keys, <c>SetupDiGetDevicePropertyKeys</c>
/// does not retrieve any property keys and returns ERROR_INSUFFICIENT_BUFFER. If the caller supplied a RequiredPropertyKeyCount
/// pointer, <c>SetupDiGetDevicePropertyKeys</c> sets the value of *RequiredPropertyKeyCount to the required size, in
/// DEVPROPKEY-typed values, of the PropertyKeyArray buffer.
/// </para>
/// <para>To retrieve a device instance property, call SetupDiGetDeviceProperty, and to set a device instance property, call SetupDiSetDeviceProperty.</para>