using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using static Vanara.PInvoke.Ole32;
namespace Vanara.PInvoke;
/// Items from the PortableDeviceApi.dll
public static partial class PortableDeviceApi
{
private const string Lib_PortableDeviceApi = "PortableDeviceApi.dll";
private delegate HRESULT PDMStrArrGet(string[]? arr, ref uint cnt);
private delegate HRESULT PDMStrGet(string devId, StringBuilder? str, ref uint sz);
///
/// The IEnumPortableDeviceObjectIDs interface enumerates the objects on a portable device. Get this interface initially by
/// calling IPortableDeviceContent::EnumObjects on a device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-ienumportabledeviceobjectids
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IEnumPortableDeviceObjectIDs")]
[ComImport, Guid("10ECE955-CF41-4728-BFA0-41EEDF1BBF19"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumPortableDeviceObjectIDs : Vanara.Collections.ICOMEnum
{
/// The Next method retrieves the next one or more object IDs in the enumeration sequence.
/// A count of the objects requested.
///
/// An array of LPWSTR pointers, each specifying a retrieved object ID. The caller must allocate an array of cObjects
/// LPWSTR elements. The caller must free both the array and the returned strings. The strings are freed by calling CoTaskMemFree.
///
///
/// On input, this parameter is ignored. On output, the number of IDs actually retrieved. If no object IDs are released and the
/// return value is S_FALSE, there are no more objects to enumerate.
///
///
/// The method returns an HRESULT. Possible values include, but are not limited to, those in the following table.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// The method succeeded.
///
/// -
/// S_FALSE
/// There are no more objects to enumerate.
///
///
///
///
///
/// If fewer than the requested number of elements remain in the sequence, this method retrieves the remaining elements. The
/// number of elements that are actually retrieved is returned through pcFetched (unless the caller passed in NULL for that
/// parameter). Enumerated objects are all peers—that is, enumerating children of an object will enumerate only direct children,
/// not grandchild or deeper objects.
///
/// Examples
///
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-ienumportabledeviceobjectids-next
// HRESULT Next( [in] ULONG cObjects, [in, out] LPWSTR *pObjIDs, [in, out] ULONG *pcFetched );
[PreserveSig]
HRESULT Next(uint cObjects, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] pObjIDs, out uint pcFetched);
/// The Skip method skips a specified number of objects in the enumeration sequence.
/// The number of objects to skip.
///
/// The method returns an HRESULT. Possible values include, but are not limited to, those in the following table.
///
///
/// Return code
/// Description
///
/// -
/// S_OK
/// The method succeeded.
///
/// -
/// S_FALSE
///
/// The specified number of objects could not be skipped (for instance, if fewer than cObjects remained in the enumeration sequence).
///
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-ienumportabledeviceobjectids-skip
// HRESULT Skip( [in] ULONG cObjects );
[PreserveSig]
HRESULT Skip([In] uint cObjects);
/// The Reset method resets the enumeration sequence to the beginning.
///
/// There is no guarantee that the same objects will be enumerated after this method is called. This is because objects that
/// were enumerated previously might have been deleted or new objects might have been added.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-ienumportabledeviceobjectids-reset
// HRESULT Reset();
void Reset();
///
/// The Clone method duplicates the current IEnumPortableDeviceObjectIDs interface.
/// Not implemented in this release.
///
/// An enumeration interface. The caller must release this interface when it is finished with the interface.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-ienumportabledeviceobjectids-clone
// HRESULT Clone( [out] IEnumPortableDeviceObjectIDs **ppEnum );
IEnumPortableDeviceObjectIDs Clone();
/// The Cancel method cancels a pending operation.
///
/// This method cancels all pending operations on the current device handle, which corresponds to a session associated with an
/// IPortableDevice interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-ienumportabledeviceobjectids-cancel
// HRESULT Cancel();
void Cancel();
}
///
/// The IPortableDevice interface provides access to a portable device.
///
/// To create and open this interface, first call CoCreateInstance with CLSID_PortableDeviceFTM or
/// CLSID_PortableDevice to retrieve an IPortableDevice interface, and then call Open to open a connection to the device.
///
///
///
///
/// The client interfaces are designed to be used for any WPD object; it is not necessary to create a new instance for each object
/// referenced by the application. After an application opens an instance of the IPortableDevice interface, it should open
/// and cache any other WPD client interfaces that it will require.
///
///
/// For Windows 7, IPortableDevice supports two CLSIDs for CoCreateInstance. CLSID_PortableDevice returns an
/// IPortableDevice pointer that does not aggregate the free-threaded marshaler; CLSID_PortableDeviceFTM is a new
/// CLSID that returns an IPortableDevice pointer that aggregates the free-threaded marshaler. Both pointers support the same
/// functionality otherwise.
///
///
/// Applications that live in Single Threaded Apartments should use CLSID_PortableDeviceFTM as this eliminates the overhead
/// of interface pointer marshaling. CLSID_PortableDevice is still supported for legacy applications.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevice
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDevice")]
[ComImport, Guid("625e2df8-6392-4cf0-9ad1-3cfa5f17775c"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(PortableDevice))]
public interface IPortableDevice
{
/// The Open method opens a connection between the application and the device.
///
/// A pointer to a that contains the Plug and Play ID string for the device. You can get this string by calling IPortableDeviceManager::GetDevices.
///
///
///
/// A pointer to an IPortableDeviceValues interface that holds information that identifies the application to the device. This
/// interface holds PROPERTYKEY/value pairs that try to identify an application uniquely. Although the presence of a
/// CoCreated interface is required, the application is not required to send any key/value pairs. However, sending data might
/// improve performance. Typical key/value pairs include the application name, major and minor version, and build number.
///
/// See properties beginning with "WPD_CLIENT_" in the Properties section.
///
///
///
/// A device must be opened before you can call any methods on it. (Note that the IPortableDeviceManager methods do not require
/// you to open a device before calling any methods.) However, usually you do not need to call Close.
///
///
/// Administrators can restrict the access of portable devices to computers running on a network. For example, an administrator
/// may restrict all Guest users to read-only access, while Authenticated users are given read/write access.
///
///
/// Due to these security issues, if your application will not perform write operations, it should call the Open method
/// and request read-only access by specifying GENERIC_READ for the WPD_CLIENT_DESIRED_ACCESS property that it supplies in the
/// pClientInfo parameter.
///
///
/// If your application requires write operations, it should call the Open method as shown in the following example code.
/// The first time, it should request read/write access by passing the default WPD_CLIENT_DESIRED_ACCESS property in the
/// pClientInfo parameter. If this first call fails and returns E_ACCESSDENIED, your application should call the Open
/// method a second time and request read-only access by specifying GENERIC_READ for the WPD_CLIENT_DESIRED_ACCESS property that
/// it supplies in the pClientInfo parameter.
///
///
/// Applications that live in Single Threaded Apartments should use CLSID_PortableDeviceFTM, as this eliminates the
/// overhead of interface pointer marshaling. CLSID_PortableDevice is still supported for legacy applications.
///
/// Examples
///
/// #define CLIENT_NAME L"My WPD Application" #define CLIENT_MAJOR_VER 1 #define CLIENT_MINOR_VER 0 #define CLIENT_REVISION 0 HRESULT OpenDevice(LPCWSTR wszPnPDeviceID, IPortableDevice** ppDevice) { HRESULT hr = S_OK; IPortableDeviceValues* pClientInformation = NULL; IPortableDevice* pDevice = NULL; if ((wszPnPDeviceID == NULL) || (ppDevice == NULL)) { hr = E_INVALIDARG; return hr; } // CoCreate an IPortableDeviceValues interface to hold the client information. hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**) &pClientInformation); if (SUCCEEDED(hr)) { HRESULT ClientInfoHR = S_OK; // Attempt to set all properties for client information. If we fail to set // any of the properties below it is OK. Failing to set a property in the // client information isn't a fatal error. ClientInfoHR = pClientInformation->SetStringValue(WPD_CLIENT_NAME, CLIENT_NAME); if (FAILED(ClientInfoHR)) { // Failed to set WPD_CLIENT_NAME } ClientInfoHR = pClientInformation->SetUnsignedIntegerValue(WPD_CLIENT_MAJOR_VERSION, CLIENT_MAJOR_VER); if (FAILED(ClientInfoHR)) { // Failed to set WPD_CLIENT_MAJOR_VERSION } ClientInfoHR = pClientInformation->SetUnsignedIntegerValue(WPD_CLIENT_MINOR_VERSION, CLIENT_MINOR_VER); if (FAILED(ClientInfoHR)) { // Failed to set WPD_CLIENT_MINOR_VERSION } ClientInfoHR = pClientInformation->SetUnsignedIntegerValue(WPD_CLIENT_REVISION, CLIENT_REVISION); if (FAILED(ClientInfoHR)) { // Failed to set WPD_CLIENT_REVISION } } else { // Failed to CoCreateInstance CLSID_PortableDeviceValues for client information } ClientInfoHR = pClientInformation->SetUnsignedIntegerValue(WPD_CLIENT_SECURITY_QUALITY_OF_SERVICE, SECURITY_IMPERSONATION); if (FAILED(ClientInfoHR)) { // Failed to set WPD_CLIENT_SECURITY_QUALITY_OF_SERVICE } if (SUCCEEDED(hr)) { // CoCreate an IPortableDevice interface hr = CoCreateInstance(CLSID_PortableDeviceFTM, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDevice, (VOID**) &pDevice); if (SUCCEEDED(hr)) { // Attempt to open the device using the PnPDeviceID string given // to this function and the newly created client information. // Note that we're attempting to open the device the first // time using the default (read/write) access. If this fails // with E_ACCESSDENIED, we'll attempt to open a second time // with read-only access. hr = pDevice->Open(wszPnPDeviceID, pClientInformation); if (hr == E_ACCESSDENIED) { // Attempt to open for read-only access pClientInformation->SetUnsignedIntegerValue( WPD_CLIENT_DESIRED_ACCESS, GENERIC_READ); hr = pDevice->Open(wszPnPDeviceID, pClientInformation); } if (SUCCEEDED(hr)) { // The device successfully opened, obtain an instance of the Device into // ppDevice so the caller can be returned an opened IPortableDevice. hr = pDevice->QueryInterface(IID_IPortableDevice, (VOID**)ppDevice); if (FAILED(hr)) { // Failed to QueryInterface the opened IPortableDevice } } } else { // Failed to CoCreateInstance CLSID_PortableDevice } } // Release the IPortableDevice when finished if (pDevice != NULL) { pDevice->Release(); pDevice = NULL; } // Release the IPortableDeviceValues that contains the client information when finished if (pClientInformation != NULL) { pClientInformation->Release(); pClientInformation = NULL; } return hr; }
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-open HRESULT Open(
// [in] LPCWSTR pszPnPDeviceID, [in] IPortableDeviceValues *pClientInfo );
void Open([In, MarshalAs(UnmanagedType.LPWStr)] string pszPnPDeviceID, [In] IPortableDeviceValues pClientInfo);
/// The SendCommand method sends a command to the device and retrieves the results synchronously.
/// Currently not used; specify zero.
///
///
/// Pointer to an IPortableDeviceValues interface that specifies the command and parameters to call on the device. This
/// interface must include the following two values to indicate the command. Additional parameters vary depending on the
/// command. For a list of the parameters that are required for each command, see Commands.
///
///
///
/// Command or property
/// Description
///
/// -
/// WPD_PROPERTY_COMMON_COMMAND_CATEGORY
/// The category GUID of the command to send. For example, to reset a device, you would send WPD_COMMAND_COMMON_RESET_DEVICE.fmtid.
///
/// -
/// WPD_PROPERTY_COMMON_COMMAND_ID
/// The PID of the command to send. For example, to reset a device, you would send WPD_COMMAND_COMMON_RESET_DEVICE.pid.
///
///
///
///
/// An IPortableDeviceValues interface that indicates the results of the command results, including success or failure, and any
/// command values returned by the device. The caller must release this interface when it is done with it. The retrieved values
/// vary by command; see the appropriate command documentation in Commands to learn what values are returned by each command call.
///
///
///
/// This function is used to send a command directly to the driver. A command is a PROPERTYKEY that is sent to the driver
/// to indicate the expected action, along with a list of required parameters. Each command has a list of required and optional
/// parameters and results that must be packaged with the command for the driver to perform the requested action. A list of
/// commands defined by Windows Portable Devices, with the required parameters and return values, is given in Commands.
///
///
/// Most Windows Portable Devices methods actually work by sending one or more of the Windows Portable Devices commands for you
/// and wrapping the parameters for you. Some commands have no corresponding Windows Portable Devices methods. The only way to
/// call these commands is by using SendCommand. The following commands have no corresponding method:
///
///
/// -
/// WPD_COMMAND_COMMON_RESET_DEVICE
///
/// -
/// WPD_COMMAND_DEVICE_HINTS_GET_CONTENT_LOCATION
///
/// -
/// WPD_COMMAND_SMS_SEND
///
/// -
/// WPD_COMMAND_STILL_IMAGE_CAPTURE_INITIATE
///
/// -
/// WPD_COMMAND_STORAGE_EJECT
///
///
/// You also must call SendCommand to send any custom driver commands driver.
///
/// Some custom commands may require a specific Input/Output Control Code (IOCTL) access level. Your application sets this
/// access level by calling the IPortableDeviceValues::SetUnsignedIntegerValue method on the command parameters that it passes
/// to the SendCommand method. For example, if a custom command requires read-only access, you would call
/// SetUnsignedIntegerValue and pass WPD_API_OPTION_IOCTL_ACCESS as the first argument and FILE_READ_ACCESS as the second
/// argument. By updating these command parameters, your application ensures that the Windows Portable Devices API issues the
/// command with the read-only IOCTL.
///
///
/// Errors that are encountered by the driver while processing a command are retrieved by the ppResults parameter, not by the
/// SendCommand return value. The return value of this method is any error (or success) code that is encountered while
/// sending the command to the driver.
///
///
/// If a driver does not support the specified command, this method will succeed, but the only guaranteed element in the
/// returned ppResults parameter will be WPD_PROPERTY_COMMON_HRESULT, which will contain E_NOTIMPL. You can verify whether a
/// driver supports a command by calling IPortableDeviceCapabilities::GetSupportedCommands before calling a command.
///
///
/// If a command supports options (such as delete recursively or delete nonrecursively), you can query for supported options by
/// calling IPortableDeviceCapabilities::GetCommandOptions.
///
///
/// There is no option to set a timeout in a call to SendCommand but the developer can attempt to cancel the command by
/// calling IPortableDevice::Cancel from a separate thread.
///
/// Examples
///
/// // void ResetDevice(IPortableDevice* pDevice) { HRESULT hr = S_OK; CComPtr<IPortableDeviceValues> pDevValues; hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**) &pDevValues); if (SUCCEEDED(hr)) { if (pDevValues != NULL) { hr = pDevValues->SetGuidValue(WPD_PROPERTY_COMMON_COMMAND_CATEGORY, WPD_COMMAND_COMMON_RESET_DEVICE.fmtid); if (FAILED(hr)) { printf("! IPortableDeviceValues::SetGuidValue failed, hr= 0x%lx\n", hr); } hr = pDevValues->SetUnsignedIntegerValue(WPD_PROPERTY_COMMON_COMMAND_ID, WPD_COMMAND_COMMON_RESET_DEVICE.pid); if (FAILED(hr)) { printf("! IPortableDeviceValues::SetGuidValue failed, hr= 0x%lx\n", hr); } } } hr = pDevice->SendCommand(0, pDevValues, &pDevValues); if (FAILED(hr)) { printf("! Failed to reset the device, hr = 0x%lx\n",hr); } else printf("Device successfully reset\n"); return; } //
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-sendcommand HRESULT
// SendCommand( [in] const DWORD dwFlags, [in] IPortableDeviceValues *pParameters, [out] IPortableDeviceValues **ppResults );
IPortableDeviceValues SendCommand([Optional] uint dwFlags, [In] IPortableDeviceValues pParameters);
/// The Content method retrieves an interface that you can use to access objects on a device.
///
/// An IPortableDeviceContent interface that is used to access the content on a device. The caller must release this interface
/// when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-content HRESULT
// Content( [out] IPortableDeviceContent **ppContent );
IPortableDeviceContent Content();
/// The Capabilities method retrieves an interface used to query the capabilities of a portable device.
///
/// An IPortableDeviceCapabilities interface that can describe the device's capabilities. The caller must release this interface
/// when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-capabilities
// HRESULT Capabilities( [out] IPortableDeviceCapabilities **ppCapabilities );
IPortableDeviceCapabilities Capabilities();
/// The Cancel method cancels a pending operation on this interface.
///
///
/// If your application invokes the WPD API from multiple threads, each thread should create a new instance of the
/// IPortableDevice interface. Doing this ensures that any cancel operation affects only the I/O for the affected thread.
///
///
/// If an IStream write operation is underway when the Cancel method is invoked, your application should discard
/// all changes by invoking the IStream::Revert method. Once the changes are discarded, the application should also close
/// the stream by invoking the IUnknown::Release method.
///
///
/// Also, note that if the Cancel method is invoked before an IStream::Write method has completed, the data being
/// written may be corrupted.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-cancel HRESULT Cancel();
void Cancel();
/// The Close method closes the connection with the device.
///
/// You should not usually need to call this method yourself. When the last reference to the IPortableDevice interface is
/// released, Windows Portable Devices calls Close for you. Calling this method manually forces the connection to the
/// device to close, and any Windows Portable Devices objects hosted on this device will cease to function. You can call Open to
/// reopen the connection.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-close HRESULT Close();
void Close();
/// The Advise method registers an application-defined callback that receives device events.
/// DWORD that specifies option flags.
/// Pointer to a callback object.
/// This parameter is ignored and should be set to NULL.
///
/// A string that represents a unique context ID. This is used to unregister for callbacks when calling Unadvise.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-advise HRESULT
// Advise( [in] const DWORD dwFlags, [in] IPortableDeviceEventCallback *pCallback, [in] IPortableDeviceValues *pParameters,
// [out] LPWSTR *ppszCookie );
void Advise([Optional] uint dwFlags, IPortableDeviceEventCallback pCallback, [Optional] IPortableDeviceValues? pParameters, [MarshalAs(UnmanagedType.LPWStr)] out string ppszCookie);
///
/// The Unadvise method unregisters a client from receiving callback notifications. You must call this method if you
/// called Advise previously.
///
/// A unique context ID. This was retrieved in the initial call to IPortableDevice::Advise.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-unadvise HRESULT
// Unadvise( [in] LPCWSTR pszCookie );
void Unadvise([In, MarshalAs(UnmanagedType.LPWStr)] string pszCookie);
///
/// The GetPnPDeviceID method retrieves the Plug and Play (PnP) device identifier that the application used to open the device.
///
/// The Plug and Play ID string for the device.
///
///
/// After the application is through using the string returned by this method, it must call the CoTaskMemFree function to free
/// the string.
///
/// The ppszPnPDeviceID argument must not be set to NULL.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevice-getpnpdeviceid
// HRESULT GetPnPDeviceID( [out] LPWSTR *ppszPnPDeviceID );
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetPnPDeviceID();
}
///
/// The IPortableDeviceCapabilities interface a variety of device capabilities, including supported formats, commands, and
/// functional objects. You can retrieve this interface from a device by calling IPortableDevice::Capabilities.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevicecapabilities
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceCapabilities")]
[ComImport, Guid("2C8C6DBF-E3DC-4061-BECC-8542E810D126"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceCapabilities
{
/// The GetSupportedCommands method retrieves a list of all the supported commands for this device.
///
/// An IPortableDeviceKeyCollection interface that holds all the valid commands. For a list of commands that are defined by
/// Windows Portable Devices, see Commands. The caller must release this interface when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getsupportedcommands
// HRESULT GetSupportedCommands( [out] IPortableDeviceKeyCollection **ppCommands );
IPortableDeviceKeyCollection GetSupportedCommands();
/// The GetCommandOptions method retrieves all the supported options for the specified command on the device.
///
/// A REFPROPERTYKEY that specifies a command to query for supported options. For a list of the commands that are defined
/// by Windows Portable Devices, see Commands.
///
///
/// An IPortableDeviceValues interface that contains the supported options. If no options are supported, this will not contain
/// any values. The caller must release this interface when it is done with it. For more information, see Remarks.
///
///
///
/// This method is called by applications that want to call a command directly on the driver by calling
/// IPortableDevice::SendCommand. Some commands allow the caller to specify additional options. For example, some drivers
/// support recursive child deletion when deleting an object using the WPD_COMMAND_OBJECT_MANAGEMENT_DELETE_OBJECTS command.
///
///
/// If an option is a simple Boolean value, the key of the retrieved IPortableDeviceValues interface will be the name of the
/// option, and the PROPVARIANT value will be a VT_BOOL value of True or False. If an option has several values, the
/// retrieved PROPVARIANT value will be a collection type that holds the supported values.
///
///
/// If this method is called for the WPD_COMMAND_STORAGE_FORMAT command and the ppOptions parameter is set to
/// WPD_OPTION_VALID_OBJECT_IDS, the driver will return an IPortableDevicePropVariant collection of type VT_LPWSTR that
/// specifies the identifiers for each object on the device that can be formatted. (If this option does not exist, the format
/// command is available for all objects.)
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getcommandoptions
// HRESULT GetCommandOptions( [in] REFPROPERTYKEY Command, [out] IPortableDeviceValues **ppOptions );
IPortableDeviceValues GetCommandOptions(in PROPERTYKEY Command);
/// The GetFunctionalCategories method retrieves all functional categories supported by the device.
///
/// An IPortableDevicePropVariantCollection interface that holds all the functional categories for this device. The values will
/// be GUID s of type VT_CLSID in the retrieved PROPVARIANT values. The caller must release this interface when it
/// is done with it.
///
///
///
/// Functional categories describe the types of functions that a device can perform, such as image capture, audio capture, and
/// storage. This method is typically very fast, because the driver usually queries the device only on startup and caches the results.
///
/// Examples
/// For an example of how to use this method see Retrieving the Functional Categories Supported by a Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getfunctionalcategories
// HRESULT GetFunctionalCategories( [out] IPortableDevicePropVariantCollection **ppCategories );
IPortableDevicePropVariantCollection GetFunctionalCategories();
/// The GetFunctionalObjects method retrieves all functional objects that match a specified category on the device.
///
/// A REFGUID that specifies the category to search for. This can be WPD_FUNCTIONAL_CATEGORY_ALL to return all functional objects.
///
///
/// An IPortableDevicePropVariantCollection interface that contains the object IDs of the functional objects as strings (type
/// VT_LPWSTR in the retrieved PROPVARIANT items). If no objects of the requested type are found, this will be an empty
/// collection (not NULL). The caller must release this interface when it is done with it.
///
///
///
/// This operation is usually fast, because the driver does not need to perform a full content enumeration, and the number of
/// retrieved functional objects is typically less than 10. If no objects of the requested type are found, this method will not
/// return an error, but returns an empty collection for ppObjectIDs.
///
/// Examples
/// For an example of how to use this method, see Retrieving the Functional Object Identifiers for a Device
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getfunctionalobjects
// HRESULT GetFunctionalObjects( [in] REFGUID Category, [out] IPortableDevicePropVariantCollection **ppObjectIDs );
IPortableDevicePropVariantCollection GetFunctionalObjects(in Guid Category);
///
/// The GetSupportedContentTypes method retrieves all supported content types for a specified functional object type on a device.
///
///
/// A REFGUID that specifies a functional object category. To get a list of functional categories on the device, call IPortableDeviceCapabilities::GetFunctionalCategories.
///
///
/// An IPortableDevicePropVariantCollection interface that lists all the supported object types for the specified functional
/// object category. These object types will be GUID values of type VT_CLSID in the retrieved PROPVARIANT items.
/// See Requirements for Objects for a list of object types defined by Windows Portable Devices. The caller must release this
/// interface when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getsupportedcontenttypes
// HRESULT GetSupportedContentTypes( [in] REFGUID Category, [out] IPortableDevicePropVariantCollection **ppContentTypes );
IPortableDevicePropVariantCollection GetSupportedContentTypes(in Guid Category);
///
/// The GetSupportedFormats method retrieves the supported formats for a specified object type on the device. For
/// example, specifying audio objects might return WPD_OBJECT_FORMAT_WMA, WPD_OBJECT_FORMAT_WAV, and WPD_OBJECT_FORMAT_MP3.
///
///
/// A REFGUID that specifies a content type, such as image, audio, or video. For a list of content types that are defined
/// by Windows Portable Devices, see Requirements for Objects.
///
///
/// An IPortableDevicePropVariantCollection interface that lists the supported formats for the specified content type. These are
/// GUID values (type VT_CLSID) in the retrieved collection items. For a list of formats that are supported by Windows Portable
/// Devices, see Object Formats. The caller must release this interface when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getsupportedformats
// HRESULT GetSupportedFormats( [in] REFGUID ContentType, [out] IPortableDevicePropVariantCollection **ppFormats );
IPortableDevicePropVariantCollection GetSupportedFormats(in Guid ContentType);
///
/// The GetSupportedFormatProperties method retrieves the properties supported by objects of a specified format on the device.
///
///
/// A REFGUID that specifies the format of the object. For a list of formats that are defined by Windows Portable
/// Devices, see Object Formats.
///
///
/// An IPortableDeviceKeyCollection interface that contains the supported properties for the specified format. For a list of
/// properties defined by Windows Portable Devices, see Properties and Attributes. The caller must release this interface when
/// it is done with it.
///
///
/// You can specify WPD_OBJECT_FORMAT_ALL for the Format parameter to retrieve the complete set of property attributes.
///
/// If an object does not have a value assigned to a specific property, or if the property was deleted, a device might not
/// report the property at all when enumerating its properties. Another device might report the property, but with an empty
/// string or a value of zero. In order to avoid this inconsistency, you can call this method to learn all the properties you
/// can set on a specific object.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getsupportedformatproperties
// HRESULT GetSupportedFormatProperties( [in] REFGUID Format, [out] IPortableDeviceKeyCollection **ppKeys );
IPortableDeviceKeyCollection GetSupportedFormatProperties(in Guid Format);
///
/// The GetFixedPropertyAttributes method retrieves the standard property attributes for a specified property and format.
/// Standard attributes are those that have the same value for all objects of the same format. For example, one device might not
/// allow users to modify video file names; this device would return WPD_PROPERTY_ATTRIBUTE_CAN_WRITE with a value of
/// False for WMV formatted objects. Attributes that can have different values for a format, or optional attributes, are not returned.
///
///
/// A REFGUID that specifies the format of the objects of interest. For format GUID values, see Object Formats.
///
///
/// A REFPROPERTYKEY that specifies the property that you want to know the attributes of. Properties defined by Windows
/// Portable Devices are listed in Properties and Attributes.
///
///
/// An IPortableDeviceValues interface that holds the attributes and their values. The caller must release this interface when
/// it is done with it.
///
///
/// You can specify WPD_OBJECT_FORMAT_ALL for the Format parameter to retrieve the complete set of property attributes.
///
/// Attributes describe properties. Example attributes are WPD_PROPERTY_ATTRIBUTE_CAN_READ and
/// WPD_PROPERTY_ATTRIBUTE_CAN_WRITE. This method does not retrieve resource attributes.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getfixedpropertyattributes
// HRESULT GetFixedPropertyAttributes( [in] REFGUID Format, [in] REFPROPERTYKEY Key, [out] IPortableDeviceValues **ppAttributes );
IPortableDeviceValues? GetFixedPropertyAttributes(in Guid Format, in PROPERTYKEY Key);
/// The Cancel method cancels a pending request on this interface.
///
/// This method cancels all pending operations on the current device handle, which corresponds to a session associated with an
/// IPortableDevice interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-cancel
// HRESULT Cancel();
void Cancel();
/// The GetSupportedEvents method retrieves the supported events for this device.
///
/// An IPortableDevicePropVariantCollection interface that lists the supported events. The caller must release this interface
/// when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-getsupportedevents
// HRESULT GetSupportedEvents( [out] IPortableDevicePropVariantCollection **ppEvents );
IPortableDevicePropVariantCollection GetSupportedEvents();
/// The GetEventOptions method retrieves all the supported options for the specified event on the device.
///
/// A REFGUID that specifies a event to query for supported options. For a list of the events that are defined by Windows
/// Portable Devices, see Events.
///
///
/// An IPortableDeviceValues interface that contains the supported options. If no options are supported, this will not contain
/// any values. The caller must release this interface when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecapabilities-geteventoptions
// HRESULT GetEventOptions( [in] REFGUID Event, [out] IPortableDeviceValues **ppOptions );
IPortableDeviceValues GetEventOptions(in Guid Event);
}
///
/// The IPortableDeviceContent interface provides methods to create, enumerate, examine, and delete content on a device. To
/// get this interface, call IPortableDevice::Content.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevicecontent
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceContent")]
[ComImport, Guid("6A96ED84-7C73-4480-9938-BF5AF477D426"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceContent
{
///
/// The EnumObjects method retrieves an interface that is used to enumerate the immediate child objects of an object. It
/// has an optional filter that can enumerate objects with specific properties.
///
/// Currently ignored; specify zero.
///
/// The ID of the parent. This can be an empty string (but not a NULL
/// pointer) or the defined constant WPD_DEVICE_OBJECT_ID to indicate the device root.
///
/// This parameter is ignored and should be set to NULL.
///
/// An IEnumPortableDeviceObjectIDs interface that is used to enumerate the objects that are found. The caller must release this
/// interface when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-enumobjects
// HRESULT EnumObjects( [in] const DWORD dwFlags, [in] LPCWSTR pszParentObjectID, [in] IPortableDeviceValues *pFilter, [out]
// IEnumPortableDeviceObjectIDs **ppEnum );
IEnumPortableDeviceObjectIDs EnumObjects([Optional] uint dwFlags, [In, MarshalAs(UnmanagedType.LPWStr)] string pszParentObjectID,
[In, Optional] IPortableDeviceValues? pFilter);
///
/// The Properties method retrieves the interface that is required to get or set properties on an object on the device.
///
///
/// An IPortableDeviceProperties interface that is used to get or set object properties. The caller must release this interface
/// when it is done with it.
///
///
///
/// The retrieved interface is not specific to a particular object on the device; it is specific only to the device. You must
/// specify the ID of the object you want when requesting or setting properties.
///
/// Examples
/// For an example of how to use this method, see Setting Properties for a Single Object.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-properties
// HRESULT Properties( [out] IPortableDeviceProperties **ppProperties );
IPortableDeviceProperties Properties();
///
/// The Transfer method retrieves an interface that is used to read from or write to the content data of an existing object resource.
///
///
/// An IPortableDeviceResources interface that is used to modify an object's resources. The caller must release this interface
/// when it is done with it.
///
///
/// This method is typically used to read from an existing object.
/// Examples
/// For an example of how to use this method, see Adding a Resource to an Object.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-transfer
// HRESULT Transfer( [out] IPortableDeviceResources **ppResources );
IPortableDeviceResources Transfer();
/// The CreateObjectWithPropertiesOnly method creates an object with only properties on the device.
///
/// An IPortableDeviceValues collection of properties to assign to the object. For a list of required and optional properties
/// for an object, see Requirements for Objects.
///
///
/// An optional string to receive the name of the new object. Can be NULL, if not needed. Windows Portable Devices
/// defines the constant WPD_DEVICE_OBJECT_ID to represent a device. The SDK allocates this memory; the caller must release it
/// using CoTaskMemFree.
///
///
///
/// Some objects are only a collection of properties—such as a folder, which is only a collection of pointers to other
/// objects—while other objects are both properties and data—such as an audio file, which contains all the properties and the
/// actual music bits. This method is used to create an object that contains only properties. To create an object with both
/// properties and data, use CreateObjectWithPropertiesAndData.
///
/// This method is synchronous; when it returns, the new object should be present on the device.
///
/// The object that the driver actually creates might be a properties-and-data object, depending on what type of object is most
/// convenient for the driver. To check what kind of object the driver has created, request the WPD_OBJECT_FORMAT property of
/// the new object.
///
/// The object will be created on the device when this method returns.
/// Examples
/// For an example of how to use this method, see Transferring a Properties-Only Object to the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-createobjectwithpropertiesonly
// HRESULT CreateObjectWithPropertiesOnly( IPortableDeviceValues *pValues, [in, out] LPWSTR *ppszObjectID );
[return: MarshalAs(UnmanagedType.LPWStr)]
string CreateObjectWithPropertiesOnly(IPortableDeviceValues pValues);
/// The CreateObjectWithPropertiesAndData method creates an object with both properties and data on the device.
///
/// An IPortableDeviceValues collection of properties to assign to the object. For a list of required and optional
/// properties for an object, see Requirements for Objects.
///
///
/// An IStream interface that the application uses to send the object data to the device. The object will not be created
/// on the device until the application sends the data by calling ppData-> Commit. To abandon a data transfer in
/// progress, you can call ppData -> Revert. The caller must release this interface when it is done with it. The
/// underlying object extends both IStream and IPortableDeviceDataStream.
///
///
/// An optional DWORD pointer that specifies the optimal buffer size for the application to use when writing the data to
/// ppData. The application can specify TRUE to ignore this.
///
///
/// An optional unique, ID that is used to identify this creation request in the application's implementation of
/// IPortableDeviceEventCallback (if implemented). When the device finishes creating the object, it will send this identifier to
/// the callback function. This identifier allows an application to monitor object creation in a different thread from the one
/// that called CreateObjectWithPropertiesOnly. The SDK allocates this memory, and the caller must release it using CoTaskMemFree.
///
///
///
/// Some objects are only a collection of properties—such as a folder, which is only a collection of pointers to other
/// objects—while other objects are both properties and data—such as an audio file, which contains all the properties and the
/// actual music bits. This method is used to create an object that requires both properties and data. To create a
/// properties-only object, call CreateObjectWithPropertiesOnly.
///
///
/// Because the object is not created until the application calls Commit on the retrieved IStream ppData, the
/// object will not have an ID until Commit is called on it. Commit is synchronous, so when that method returns
/// successfully, the object will exist on the device.
///
///
/// After calling Commit to create the object, call QueryInterface on ppData for IPortableDeviceDataStream, and
/// then call IPortableDeviceDataStream::GetObjectID to get the ID of the newly created object.
///
/// Examples
/// For an example of how to use this method, see Transferring an Image or Music File to the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-createobjectwithpropertiesanddata
// HRESULT CreateObjectWithPropertiesAndData( IPortableDeviceValues *pValues, [out] IStream **ppData, [in, out] DWORD
// *pdwOptimalWriteBufferSize, [in, out] LPWSTR *ppszCookie );
[return: MarshalAs(UnmanagedType.LPWStr)]
string CreateObjectWithPropertiesAndData(IPortableDeviceValues pValues, out IStream ppData, [In, Out] ref uint pdwOptimalWriteBufferSize);
/// The Delete method deletes one or more objects from the device.
/// One of the DELETE_OBJECT_OPTIONS enumerators.
///
/// Pointer to an IPortableDevicePropVariantCollection interface that holds one or more null-terminated strings (type VT_LPWSTR)
/// specifying the object IDs of the objects to delete.
///
///
/// Optional. On return, this parameter contains a collection of VT_ERROR values indicating the success or failure of the
/// operation. The first element returned in ppResults corresponds to the first object in the pObjectIDs collection, the second
/// element returned in ppResults corresponds to the second object in the pObjectIDs collection, and so on. This parameter can
/// be NULL if the application is not concerned with the results.
///
///
///
/// To see if recursive deletion is supported, call IPortableDeviceCapabilities::GetCommandOptions. If the retrieved
/// IPortableDeviceValues interface contains a property value called WPD_OPTION_OBJECT_MANAGEMENT_RECURSIVE_DELETE_SUPPORTED
/// with a boolVal value of True, the device supports recursive deletion.
///
/// The following table lists the possible return codes that may appear in the collection at which ppResults points.
/// Examples
/// For an example of how to use this method, see Deleting Content from the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-delete
// HRESULT Delete( [in] const DWORD dwOptions, [in] IPortableDevicePropVariantCollection *pObjectIDs, [in, out]
// IPortableDevicePropVariantCollection **ppResults );
IPortableDevicePropVariantCollection Delete(DELETE_OBJECT_OPTIONS dwOptions, IPortableDevicePropVariantCollection pObjectIDs);
///
/// The GetObjectIDsFromPersistentUniqueIDs method retrieves the current object ID of one or more objects, given their
/// persistent unique IDs (PUIDs).
///
///
/// Pointer to an IPortableDevicePropVariantCollection interface that contains one or more persistent unique ID (PUID) string
/// values (type VT_LPWSTR).
///
///
/// Pointer to an IPortableDevicePropVariantCollection interface pointer that contains the retrieved object IDs, as type
/// VT_LPWSTR. The retrieved IDs will be in the same order as the submitted PUIDs; if a value could not be found, it is
/// indicated by an empty string. The caller must release this interface when it is done with it.
///
///
///
/// Windows Portable Devices Object IDs are unique across the device, but may be different across sessions. An Object ID can
/// change when the application reconnects to the device.
///
///
/// Certain applications, such as synchronization engines, require a way to identify the object across connection sessions.
/// Every object has a WPD_OBJECT_PERSISTENT_UNIQUE_ID property, which indicates an identifier that is persistent across
/// sessions. Applications can read and save this property in their initial session, by calling the Properties method.
///
/// Examples
/// For an example of how to use this method, see Retrieving an Object Identifier from a Persistent Unique Identifier
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-getobjectidsfrompersistentuniqueids
// HRESULT GetObjectIDsFromPersistentUniqueIDs( [in] IPortableDevicePropVariantCollection *pPersistentUniqueIDs, [out]
// IPortableDevicePropVariantCollection **ppObjectIDs );
IPortableDevicePropVariantCollection GetObjectIDsFromPersistentUniqueIDs(IPortableDevicePropVariantCollection pPersistentUniqueIDs);
/// The Cancel method cancels a pending operation called on this interface.
///
/// This method cancels all pending operations on the current device handle, which corresponds to a session associated with an
/// IPortableDevice interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-cancel
// HRESULT Cancel();
void Cancel();
/// The Move method moves one or more objects from one location on the device to another.
///
/// Pointer to an IPortableDevicePropVariantCollection interface that holds one or more null-terminated strings (type VT_LPWSTR)
/// specifying the object IDs of the objects to be moved.
///
/// The ID of the destination.
///
/// Optional. On return, this parameter contains a collection of VT_ERROR values indicating the success or failure of the
/// operation. The first element returned in ppResults corresponds to the first object in the pObjectIDs collection, the second
/// element returned in ppResults corresponds to the second object in the pObjectIDs collection, and so on. This parameter can
/// be NULL if the application is not concerned with the results.
///
///
///
/// If the specified device supports move operations on a functional storage, the pszDestinationFolderObjectID parameter may
/// specify the identifier for a functional storage.
///
/// Examples
/// For an example of how to use this method, see Moving Content on the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-move HRESULT
// Move( [in] IPortableDevicePropVariantCollection *pObjectIDs, [in] LPCWSTR pszDestinationFolderObjectID, [in, out]
// IPortableDevicePropVariantCollection **ppResults );
IPortableDevicePropVariantCollection Move(IPortableDevicePropVariantCollection pObjectIDs, [MarshalAs(UnmanagedType.LPWStr)] string pszDestinationFolderObjectID);
/// The Copy method copies objects from one location on a device to another.
/// A collection of object identifiers for the objects that this method will copy.
///
/// An object identifier for the destination folder (or functional storage) into which this method will copy the specified objects.
///
///
/// A collection of VT_ERROR values indicating the success or failure of copying a particular element. The first error value
/// corresponds to the first object in the collection of object identifiers, the second to the second element, and so on. This
/// argument can be NULL.
///
///
/// If the specified device supports copy operations to a functional storage, the pszDestinationFolderObjectID parameter may
/// specify the identifier for a functional storage.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-copy HRESULT
// Copy( IPortableDevicePropVariantCollection *pObjectIDs, LPCWSTR pszDestinationFolderObjectID, [out]
// IPortableDevicePropVariantCollection **ppResults );
IPortableDevicePropVariantCollection Copy(IPortableDevicePropVariantCollection pObjectIDs, [MarshalAs(UnmanagedType.LPWStr)] string pszDestinationFolderObjectID);
}
///
/// The IPortableDeviceContent2 interface defines additional methods that provide access to content found on a device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevicecontent2
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceContent2")]
[ComImport, Guid("9B4ADD96-F6BF-4034-8708-ECA72BF10554"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceContent2 : IPortableDeviceContent
{
///
/// The EnumObjects method retrieves an interface that is used to enumerate the immediate child objects of an object. It
/// has an optional filter that can enumerate objects with specific properties.
///
/// Currently ignored; specify zero.
///
/// The ID of the parent. This can be an empty string (but not a NULL
/// pointer) or the defined constant WPD_DEVICE_OBJECT_ID to indicate the device root.
///
/// This parameter is ignored and should be set to NULL.
///
/// An IEnumPortableDeviceObjectIDs interface that is used to enumerate the objects that are found. The caller must release this
/// interface when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-enumobjects
// HRESULT EnumObjects( [in] const DWORD dwFlags, [in] LPCWSTR pszParentObjectID, [in] IPortableDeviceValues *pFilter, [out]
// IEnumPortableDeviceObjectIDs **ppEnum );
new IEnumPortableDeviceObjectIDs EnumObjects([Optional] uint dwFlags, [In, MarshalAs(UnmanagedType.LPWStr)] string pszParentObjectID,
[In, Optional] IPortableDeviceValues? pFilter);
///
/// The Properties method retrieves the interface that is required to get or set properties on an object on the device.
///
///
/// An IPortableDeviceProperties interface that is used to get or set object properties. The caller must release this interface
/// when it is done with it.
///
///
///
/// The retrieved interface is not specific to a particular object on the device; it is specific only to the device. You must
/// specify the ID of the object you want when requesting or setting properties.
///
/// Examples
/// For an example of how to use this method, see Setting Properties for a Single Object.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-properties
// HRESULT Properties( [out] IPortableDeviceProperties **ppProperties );
new IPortableDeviceProperties Properties();
///
/// The Transfer method retrieves an interface that is used to read from or write to the content data of an existing object resource.
///
///
/// An IPortableDeviceResources interface that is used to modify an object's resources. The caller must release this interface
/// when it is done with it.
///
///
/// This method is typically used to read from an existing object.
/// Examples
/// For an example of how to use this method, see Adding a Resource to an Object.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-transfer
// HRESULT Transfer( [out] IPortableDeviceResources **ppResources );
new IPortableDeviceResources Transfer();
/// The CreateObjectWithPropertiesOnly method creates an object with only properties on the device.
///
/// An IPortableDeviceValues collection of properties to assign to the object. For a list of required and optional properties
/// for an object, see Requirements for Objects.
///
///
/// An optional string to receive the name of the new object. Can be NULL, if not needed. Windows Portable Devices
/// defines the constant WPD_DEVICE_OBJECT_ID to represent a device. The SDK allocates this memory; the caller must release it
/// using CoTaskMemFree.
///
///
///
/// Some objects are only a collection of properties—such as a folder, which is only a collection of pointers to other
/// objects—while other objects are both properties and data—such as an audio file, which contains all the properties and the
/// actual music bits. This method is used to create an object that contains only properties. To create an object with both
/// properties and data, use CreateObjectWithPropertiesAndData.
///
/// This method is synchronous; when it returns, the new object should be present on the device.
///
/// The object that the driver actually creates might be a properties-and-data object, depending on what type of object is most
/// convenient for the driver. To check what kind of object the driver has created, request the WPD_OBJECT_FORMAT property of
/// the new object.
///
/// The object will be created on the device when this method returns.
/// Examples
/// For an example of how to use this method, see Transferring a Properties-Only Object to the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-createobjectwithpropertiesonly
// HRESULT CreateObjectWithPropertiesOnly( IPortableDeviceValues *pValues, [in, out] LPWSTR *ppszObjectID );
[return: MarshalAs(UnmanagedType.LPWStr)]
new string CreateObjectWithPropertiesOnly(IPortableDeviceValues pValues);
/// The CreateObjectWithPropertiesAndData method creates an object with both properties and data on the device.
///
/// An IPortableDeviceValues collection of properties to assign to the object. For a list of required and optional
/// properties for an object, see Requirements for Objects.
///
///
/// An IStream interface that the application uses to send the object data to the device. The object will not be created
/// on the device until the application sends the data by calling ppData-> Commit. To abandon a data transfer in
/// progress, you can call ppData -> Revert. The caller must release this interface when it is done with it. The
/// underlying object extends both IStream and IPortableDeviceDataStream.
///
///
/// An optional DWORD pointer that specifies the optimal buffer size for the application to use when writing the data to
/// ppData. The application can specify TRUE to ignore this.
///
///
/// An optional unique, ID that is used to identify this creation request in the application's implementation of
/// IPortableDeviceEventCallback (if implemented). When the device finishes creating the object, it will send this identifier to
/// the callback function. This identifier allows an application to monitor object creation in a different thread from the one
/// that called CreateObjectWithPropertiesOnly. The SDK allocates this memory, and the caller must release it using CoTaskMemFree.
///
///
///
/// Some objects are only a collection of properties—such as a folder, which is only a collection of pointers to other
/// objects—while other objects are both properties and data—such as an audio file, which contains all the properties and the
/// actual music bits. This method is used to create an object that requires both properties and data. To create a
/// properties-only object, call CreateObjectWithPropertiesOnly.
///
///
/// Because the object is not created until the application calls Commit on the retrieved IStream ppData, the
/// object will not have an ID until Commit is called on it. Commit is synchronous, so when that method returns
/// successfully, the object will exist on the device.
///
///
/// After calling Commit to create the object, call QueryInterface on ppData for IPortableDeviceDataStream, and
/// then call IPortableDeviceDataStream::GetObjectID to get the ID of the newly created object.
///
/// Examples
/// For an example of how to use this method, see Transferring an Image or Music File to the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-createobjectwithpropertiesanddata
// HRESULT CreateObjectWithPropertiesAndData( IPortableDeviceValues *pValues, [out] IStream **ppData, [in, out] DWORD
// *pdwOptimalWriteBufferSize, [in, out] LPWSTR *ppszCookie );
[return: MarshalAs(UnmanagedType.LPWStr)]
new string CreateObjectWithPropertiesAndData(IPortableDeviceValues pValues, out IStream ppData, [In, Out] ref uint pdwOptimalWriteBufferSize);
/// The Delete method deletes one or more objects from the device.
/// One of the DELETE_OBJECT_OPTIONS enumerators.
///
/// Pointer to an IPortableDevicePropVariantCollection interface that holds one or more null-terminated strings (type VT_LPWSTR)
/// specifying the object IDs of the objects to delete.
///
///
/// Optional. On return, this parameter contains a collection of VT_ERROR values indicating the success or failure of the
/// operation. The first element returned in ppResults corresponds to the first object in the pObjectIDs collection, the second
/// element returned in ppResults corresponds to the second object in the pObjectIDs collection, and so on. This parameter can
/// be NULL if the application is not concerned with the results.
///
///
///
/// To see if recursive deletion is supported, call IPortableDeviceCapabilities::GetCommandOptions. If the retrieved
/// IPortableDeviceValues interface contains a property value called WPD_OPTION_OBJECT_MANAGEMENT_RECURSIVE_DELETE_SUPPORTED
/// with a boolVal value of True, the device supports recursive deletion.
///
/// The following table lists the possible return codes that may appear in the collection at which ppResults points.
/// Examples
/// For an example of how to use this method, see Deleting Content from the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-delete
// HRESULT Delete( [in] const DWORD dwOptions, [in] IPortableDevicePropVariantCollection *pObjectIDs, [in, out]
// IPortableDevicePropVariantCollection **ppResults );
new IPortableDevicePropVariantCollection Delete(DELETE_OBJECT_OPTIONS dwOptions, IPortableDevicePropVariantCollection pObjectIDs);
///
/// The GetObjectIDsFromPersistentUniqueIDs method retrieves the current object ID of one or more objects, given their
/// persistent unique IDs (PUIDs).
///
///
/// Pointer to an IPortableDevicePropVariantCollection interface that contains one or more persistent unique ID (PUID) string
/// values (type VT_LPWSTR).
///
///
/// Pointer to an IPortableDevicePropVariantCollection interface pointer that contains the retrieved object IDs, as type
/// VT_LPWSTR. The retrieved IDs will be in the same order as the submitted PUIDs; if a value could not be found, it is
/// indicated by an empty string. The caller must release this interface when it is done with it.
///
///
///
/// Windows Portable Devices Object IDs are unique across the device, but may be different across sessions. An Object ID can
/// change when the application reconnects to the device.
///
///
/// Certain applications, such as synchronization engines, require a way to identify the object across connection sessions.
/// Every object has a WPD_OBJECT_PERSISTENT_UNIQUE_ID property, which indicates an identifier that is persistent across
/// sessions. Applications can read and save this property in their initial session, by calling the Properties method.
///
/// Examples
/// For an example of how to use this method, see Retrieving an Object Identifier from a Persistent Unique Identifier
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-getobjectidsfrompersistentuniqueids
// HRESULT GetObjectIDsFromPersistentUniqueIDs( [in] IPortableDevicePropVariantCollection *pPersistentUniqueIDs, [out]
// IPortableDevicePropVariantCollection **ppObjectIDs );
new IPortableDevicePropVariantCollection GetObjectIDsFromPersistentUniqueIDs(IPortableDevicePropVariantCollection pPersistentUniqueIDs);
/// The Cancel method cancels a pending operation called on this interface.
///
/// This method cancels all pending operations on the current device handle, which corresponds to a session associated with an
/// IPortableDevice interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-cancel
// HRESULT Cancel();
new void Cancel();
/// The Move method moves one or more objects from one location on the device to another.
///
/// Pointer to an IPortableDevicePropVariantCollection interface that holds one or more null-terminated strings (type VT_LPWSTR)
/// specifying the object IDs of the objects to be moved.
///
/// The ID of the destination.
///
/// Optional. On return, this parameter contains a collection of VT_ERROR values indicating the success or failure of the
/// operation. The first element returned in ppResults corresponds to the first object in the pObjectIDs collection, the second
/// element returned in ppResults corresponds to the second object in the pObjectIDs collection, and so on. This parameter can
/// be NULL if the application is not concerned with the results.
///
///
///
/// If the specified device supports move operations on a functional storage, the pszDestinationFolderObjectID parameter may
/// specify the identifier for a functional storage.
///
/// Examples
/// For an example of how to use this method, see Moving Content on the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-move HRESULT
// Move( [in] IPortableDevicePropVariantCollection *pObjectIDs, [in] LPCWSTR pszDestinationFolderObjectID, [in, out]
// IPortableDevicePropVariantCollection **ppResults );
new IPortableDevicePropVariantCollection Move(IPortableDevicePropVariantCollection pObjectIDs, [MarshalAs(UnmanagedType.LPWStr)] string pszDestinationFolderObjectID);
/// The Copy method copies objects from one location on a device to another.
/// A collection of object identifiers for the objects that this method will copy.
///
/// An object identifier for the destination folder (or functional storage) into which this method will copy the specified objects.
///
///
/// A collection of VT_ERROR values indicating the success or failure of copying a particular element. The first error value
/// corresponds to the first object in the collection of object identifiers, the second to the second element, and so on. This
/// argument can be NULL.
///
///
/// If the specified device supports copy operations to a functional storage, the pszDestinationFolderObjectID parameter may
/// specify the identifier for a functional storage.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent-copy HRESULT
// Copy( IPortableDevicePropVariantCollection *pObjectIDs, LPCWSTR pszDestinationFolderObjectID, [out]
// IPortableDevicePropVariantCollection **ppResults );
new IPortableDevicePropVariantCollection Copy(IPortableDevicePropVariantCollection pObjectIDs, [MarshalAs(UnmanagedType.LPWStr)] string pszDestinationFolderObjectID);
///
/// The UpdateObjectWithPropertiesAndData method updates an object by using properties and data found on the device.
///
/// The identifier of the object to update.
/// The IPortableDeviceValues interface that specifies the object properties to be updated.
/// The IStream interface through which the object data is sent to the device.
///
/// The optimal buffer size for writing the object data to ppData, or NULL if the buffer size is ignored.
///
///
///
/// Device formats and object formats can derive some of their object properties from the data itself. Or, they can have
/// property values that depend on the data. For example, a music track has a duration property that is specified when an
/// application calls the IPortableDeviceContent::CreateObjectWithPropertiesAndData method. If this track is stored as a default
/// resource (WPD_RESOURCE_DEFAULT), the application might update it. The application additionally mighthave to update the
/// duration property. This method lets the application perform both updates at the same time.
///
/// An update is incomplete until the IStream::Commit method is called on the object referenced by the ppData parameter.
///
/// To abandon a data transfer in progress, an application should call the IStream::Revert method on the object
/// referenced by the ppData parameter.
///
///
/// The IStream interface object referenced by the ppData parameter must be released after the update operation is
/// complete, or, is canceled.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicecontent2-updateobjectwithpropertiesanddata
// HRESULT UpdateObjectWithPropertiesAndData( [in] LPCWSTR pszObjectID, [in] IPortableDeviceValues *pProperties, [out] IStream
// **ppData, [in, out] DWORD *pdwOptimalWriteBufferSize );
void UpdateObjectWithPropertiesAndData([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID, IPortableDeviceValues pProperties,
out IStream ppData, out uint pdwOptimalWriteBufferSize);
}
///
/// The IPortableDeviceDataStream interface exposes additional methods on an IStream that is used for data transfers.
/// It is obtained by calling QueryInterface on the IStream that is retrieved by IPortableDeviceResources::GetStream
/// or IPortableDeviceContent::CreateObjectWithPropertiesAndData.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevicedatastream
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceDataStream")]
[ComImport, Guid("88e04db3-1012-4d64-9996-f703a950d3f4"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceDataStream : IStream
{
///
new void Read(byte[] pv, int cb, IntPtr pcbRead);
///
new void Write(byte[] pv, int cb, IntPtr pcbWritten);
///
new void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition);
///
new void SetSize(long libNewSize);
///
new void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten);
///
new void Commit(int grfCommitFlags);
///
new void Revert();
///
new void LockRegion(long libOffset, long cb, int dwLockType);
///
new void UnlockRegion(long libOffset, long cb, int dwLockType);
///
new void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag);
///
new void Clone(out IStream ppstm);
///
/// The GetObjectID method retrieves the object ID of the resource that was written to the device. This method is only
/// valid after calling IStream::Commit on the data stream.
///
/// The ID of the object just transferred to the device.
///
/// An object ID is created after the object is created on the device. Therefore, a new object that is created by calling
/// IPortableDeviceContent::CreateObjectWithPropertiesAndData will not have an ID assigned until the application calls
/// Commit on the data transfer stream.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicedatastream-getobjectid
// HRESULT GetObjectID( [out] LPWSTR *ppszObjectID );
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetObjectID();
/// The Cancel method cancels a call in progress on this interface.
///
/// This method cancels all pending operations on the current device handle, which corresponds to a session associated with an
/// IPortableDevice interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicedatastream-cancel
// HRESULT Cancel();
void Cancel();
}
/// Represents a factory that can instantiate a WPD Automation Device object.
///
///
/// The IPortableDeviceDispatchFactory interface can be CoCreated directly using CLSID_PortableDeviceDispatchFactory
/// as in the following code.
///
///
///
///
/// Examples
///
/// For an example of how to use the IPortableDeviceDispatchFactory interface to instantiate a WPD Automation Device
/// object, see Instantiating the WPD Automation Factory Interface.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevicedispatchfactory
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceDispatchFactory")]
[ComImport, Guid("5e1eafc3-e3d7-4132-96fa-759c0f9d1e0f"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(PortableDeviceDispatchFactory))]
public interface IPortableDeviceDispatchFactory
{
/// Instantiates a WPD Automation Device object for a given WPD device identifier.
///
/// A pointer to a String that is used by Plug-and-play to identify a currently connected WPD device. The Plug and Play
/// (PnP) identifier for a particular device can be obtained from the IPortableDeviceManager::GetDevices method in the WPD
/// C++/COM API.
///
/// Contains a pointer to the IDispatch implementation for the WPD Automation Device object.
///
/// For an example of how to use GetDeviceDispatch method to instantiate a WPD Automation Device object, see
/// Instantiating the WPD Automation Factory Interface.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicedispatchfactory-getdevicedispatch
// HRESULT GetDeviceDispatch( [in] LPCWSTR pszPnPDeviceID, [out] IDispatch **ppDeviceDispatch );
[return: MarshalAs(UnmanagedType.IDispatch)]
object GetDeviceDispatch([MarshalAs(UnmanagedType.LPWStr)] string pszPnPDeviceID);
}
///
/// The IPortableDeviceEventCallback interface implemented by the application to receive asynchronous callbacks if an
/// application has registered to receive them by calling IPortableDevice::Advise.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledeviceeventcallback
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceEventCallback")]
[ComImport, Guid("A8792A31-F385-493C-A893-40F64EB45F6E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceEventCallback
{
/// The OnEvent method is called by the SDK to notify the application about asynchronous events.
/// Pointer to an IPortableDeviceValues interface that contains event details.
/// Any values returned by the application are ignored by Windows Portable Devices.
///
/// The application must register to receive events by calling IPortableDevice::Advise.
/// Examples
/// For an example of how to use this method, see Handling Events from the Device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceeventcallback-onevent
// HRESULT OnEvent( [in] IPortableDeviceValues *pEventParameters );
void OnEvent([Optional] IPortableDeviceValues? pEventParameters);
}
///
///
/// Enumerates devices that are connected to the computer and provides a simple way to request installation information, including
/// manufacturer, friendly name, and description. This is typically the first Windows Portable Devices interface created by an
/// application. To create an instance of this interface, call CoCreateInstance and specify CLSID_PortableDeviceManager.
///
///
/// The properties that are requested using this interface can also be requested by using the IPortableDeviceProperties interface.
/// However, that interface requires several steps to acquire; using this interface is a much simpler way to request device information.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevicemanager
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceManager")]
[ComImport, Guid("a1567595-4c2f-4574-a6fa-ecef917b9a40"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(PortableDeviceManager))]
public interface IPortableDeviceManager
{
/// Retrieves a list of portable devices connected to the computer.
///
/// A caller-allocated array of strings that holds the Plug and Play names of all of the connected devices. To learn the
/// required size for this parameter, first call this method with this parameter set to NULL and pcPnPDeviceIDs set to
/// zero, and then allocate a buffer according to the value retrieved by pcPnPDeviceIDs. These names can be used by
/// IPortableDevice::Open to create a connection to a device.
///
///
/// On input, the number of values that pPnPDeviceIDs can hold. On output, a pointer to the number of devices actually written
/// to pPnPDeviceIDs.
///
///
///
/// The list of devices is generated when the device manager is instantiated; it does not refresh as devices connect and
/// disconnect. To refresh the list of connected devices, call RefreshDeviceList.
///
///
/// The API allocates the memory for each string pointed to by the pPnPDeviceIDs array. Once your application no longer needs
/// these strings, it must iterate through this array and free the associated memory by calling the CoTaskMemFree function.
///
/// Examples
///
/// For an example of how to use this method to enumerate devices, see Enumerating Devices. For an example of how to use this
/// method to enumerate Services, see Enumerating Services.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicemanager-getdevices
// HRESULT GetDevices( [in, out] LPWSTR *pPnPDeviceIDs, [in, out] DWORD *pcPnPDeviceIDs );
[PreserveSig]
HRESULT GetDevices([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1)] string[]? pPnPDeviceIDs,
ref uint pcPnPDeviceIDs);
/// The RefreshDeviceList method refreshes the list of devices that are connected to the computer.
///
///
/// When the IPortableDeviceManager interface is instantiated the first time, it generates a list of the devices that are
/// connected. However, devices can connect and disconnect from the computer, making the original list obsolete. This method
/// enables an application to refresh the list of connected devices.
///
///
/// This method is less resource-intensive than instantiating a new device manager to generate a new device list. However, it
/// does require some resources; therefore, we recommend that you do not call this method arbitrarily. The best solution is to
/// have the application register to get device arrival and removal notifications, and when a notification is received, have the
/// application call this function.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicemanager-refreshdevicelist
// HRESULT RefreshDeviceList();
void RefreshDeviceList();
/// Retrieves the user-friendly name for the device.
///
/// The device's Plug and Play ID. You can retrieve a list of Plug and Play names of all devices that are connected to the
/// computer by calling GetDevices.
///
///
/// A caller-allocated buffer that is used to hold the user-friendly name for the device. To learn the required size for this
/// parameter, first call this method with this parameter set to NULL and pcchDeviceFriendlyName set to 0; the
/// method will succeed and set pcchDeviceFriendlyName to the required buffer size to hold the device-friendly name, including
/// the termination character.
///
///
/// On input, the maximum number of characters that pDeviceFriendlyName can hold, not including the termination character. On
/// output, the number of characters that is returned by pDeviceFriendlyName, not including the termination character.
///
///
/// A device is not required to support this method. If this method fails to retrieve a name, try requesting the WPD_OBJECT_NAME
/// property of the device object (the object with the ID WPD_DEVICE_OBJECT_ID).
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicemanager-getdevicefriendlyname
// HRESULT GetDeviceFriendlyName( [in] LPCWSTR pszPnPDeviceID, [in, out] WCHAR *pDeviceFriendlyName, [in, out] DWORD
// *pcchDeviceFriendlyName );
[PreserveSig]
HRESULT GetDeviceFriendlyName([In, MarshalAs(UnmanagedType.LPWStr)] string pszPnPDeviceID, [In, Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder? pDeviceFriendlyName,
[In, Out] ref uint pcchDeviceFriendlyName);
/// Retrieves the description of a device.
///
/// The device's Plug and Play ID. You can retrieve a list of Plug and Play names of devices that are currently connected by
/// calling GetDevices.
///
///
/// A caller-allocated buffer to hold the user-description name of the device. The caller must allocate the memory for this
/// parameter. To learn the required size for this parameter, first call this method with this parameter set to NULL and
/// pcchDeviceDescription set to 0; the method will succeed and set pcchDeviceDescription to the required buffer size to
/// hold the device-friendly name, including the termination character.
///
///
/// The number of characters (not including the termination character) in pDeviceDescription. On input, the maximum length of
/// pDeviceDescription; on output, the length of the returned string in pDeviceDescription.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicemanager-getdevicedescription
// HRESULT GetDeviceDescription( [in] LPCWSTR pszPnPDeviceID, [in, out] WCHAR *pDeviceDescription, [in, out] DWORD
// *pcchDeviceDescription );
[PreserveSig]
HRESULT GetDeviceDescription([In, MarshalAs(UnmanagedType.LPWStr)] string pszPnPDeviceID, [In, Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder? pDeviceDescription,
[In, Out] ref uint pcchDeviceDescription);
/// Retrieves the name of the device manufacturer.
///
/// The device's Plug and Play ID. You can retrieve a list of Plug and Play names of all devices that are connected to the
/// computer by calling GetDevices.
///
///
/// A caller-allocated buffer that holds the name of the device manufacturer. To learn the required size for this parameter,
/// first call this method with this parameter set to NULL and pcchDeviceManufacturer set to 0; the method will
/// succeed and set pcchDeviceManufacturer to the required buffer size to hold the device-friendly name, including the
/// termination character.
///
///
/// On input, the maximum number of characters that pDeviceManufacturer can hold, not including the termination character. On
/// output, the number of characters returned by pDeviceManufacturer, not including the termination character.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicemanager-getdevicemanufacturer
// HRESULT GetDeviceManufacturer( [in] LPCWSTR pszPnPDeviceID, [in, out] WCHAR *pDeviceManufacturer, [in, out] DWORD
// *pcchDeviceManufacturer );
[PreserveSig]
HRESULT GetDeviceManufacturer([In, MarshalAs(UnmanagedType.LPWStr)] string pszPnPDeviceID, [In, Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder? pDeviceManufacturer,
[In, Out] ref uint pcchDeviceManufacturer);
///
/// Retrieves a property value stored by the device on the computer. (These are not standard properties that are defined by
/// Windows Portable Devices.)
///
///
/// The device's Plug and Play ID. You can retrieve a list of Plug and Play names of all devices that are connected to the
/// computer by calling GetDevices.
///
///
/// The name of the property to request. These are custom property names defined by a device manufacturer.
///
///
/// A caller-allocated buffer to hold the retrieved data. To get the size required, call this method with this parameter set to
/// NULL and pcbData set to zero, and the required size will be retrieved in pcbData. This call will also return an error
/// that can be ignored. See Return Values.
///
/// The size of the buffer allocated or returned by pData, in bytes.
///
/// A constant describing the type of data returned in pData. The values for this parameter are the same types used to describe
/// the lpType parameter of the Platform SDK function RegQueryValueEx.
///
///
///
/// These property values are stored on device installation, or stored by a device during operation so that they can be
/// persisted across connection sessions. An application must know the exact name of the property, which is specified by the
/// device itself; therefore, this method is intended to be used by device developers who are creating their own applications.
///
///
/// To get Windows Portable Devices properties from the device object, call IPortableDeviceProperties::GetValues, and specify
/// the device object with WPD_DEVICE_OBJECT_ID.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicemanager-getdeviceproperty
// HRESULT GetDeviceProperty( [in] LPCWSTR pszPnPDeviceID, [in] LPCWSTR pszDevicePropertyName, [in, out] BYTE *pData, [in, out]
// DWORD *pcbData, [in, out] DWORD *pdwType );
[PreserveSig]
HRESULT GetDeviceProperty([MarshalAs(UnmanagedType.LPWStr)] string pszPnPDeviceID, [MarshalAs(UnmanagedType.LPWStr)] string pszDevicePropertyName,
[In, Out] IntPtr pData, ref uint pcbData, out REG_VALUE_TYPE pdwType);
///
/// The GetPrivateDevices method retrieves a list of private portable devices connected to the computer. These private
/// devices are only accessible through an application that is designed for these particular devices.
///
///
/// A caller-allocated array of strings that holds the Plug and Play names of all of the connected devices. To learn the
/// required size for this parameter, first call this method with this parameter set to NULL and pcPnPDeviceIDs set to
/// zero, and then allocate a buffer according to the value retrieved by pcPnPDeviceIDs. These names can be used by
/// IPortableDevice::Open to create a connection to a device.
///
///
/// On input, the number of values that pPnPDeviceIDs can hold. On output, a pointer to the number of devices actually written
/// to pPnPDeviceIDs.
///
///
///
/// In order to write an application that communicates with a private device, you must have knowledge of the custom
/// functionality exposed by a particular device driver. The description of this functionality must be obtained from the device manufacturer.
///
///
/// The list of devices is generated when the device manager is instantiated; it does not refresh as devices connect and
/// disconnect. To refresh the list of connected devices, call RefreshDeviceList.
///
///
/// The API allocates the memory for each string pointed to by the pPnPDeviceIDs array. Once your application no longer needs
/// these strings, it must iterate through this array and free the associated memory by calling the CoTaskMemFree function.
///
///
/// A private device may not respond correctly to the standard Windows Portable Devices function calls that perform object
/// enumeration, resource transfer, retrieval of device capabilities, and so on.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicemanager-getprivatedevices
// HRESULT GetPrivateDevices( [in, out] LPWSTR *pPnPDeviceIDs, [in, out] DWORD *pcPnPDeviceIDs );
[PreserveSig]
HRESULT GetPrivateDevices([In, Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 1)] string[]? pPnPDeviceIDs, ref uint pcPnPDeviceIDs);
}
///
/// The IPortableDeviceProperties interface retrieves, adds, or deletes properties from an object on a device, or the device
/// itself. To get this interface, call IPortableDeviceContent::Properties on an object. To get this interface for the object,
/// specify WPD_DEVICE_OBJECT_ID in GetValues.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledeviceproperties
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceProperties")]
[ComImport, Guid("7F6D695C-03DF-4439-A809-59266BEEE3A6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceProperties
{
///
/// The GetSupportedProperties method retrieves a list of properties that a specified object supports. Note that not all
/// of these properties may actually have values.
///
/// The object ID of the object to query. To specify the device, use WPD_DEVICE_OBJECT_ID.
///
/// An IPortableDeviceKeyCollection interface that contains the supported properties. For a list of properties defined by
/// Windows Portable Devices, see Properties and Attributes. The caller must release this interface when it is done with it.
///
/// To get the values of supported properties, call GetPropertyAttributes.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceproperties-getsupportedproperties
// HRESULT GetSupportedProperties( [in] LPCWSTR pszObjectID, [out] IPortableDeviceKeyCollection **ppKeys );
IPortableDeviceKeyCollection GetSupportedProperties([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID);
/// The GetPropertyAttributes method retrieves attributes of a specified object property on a device.
/// The object ID of the object to query. To specify the device, use WPD_DEVICE_OBJECT_ID.
///
/// A REFPROPERTYKEY that specifies the property to query for. You can retrieve a list of supported properties by calling
/// GetSupportedProperties. For a list of properties that are defined by Windows Portable Devices, see Properties and Attributes.
///
///
/// An IPortableDeviceValues interface that holds the retrieved property attributes. These are PROPERTYKEY/value pairs, where
/// the PROPERTYKEY is the property, and the value data type depends on the specific property. The caller must release
/// this interface when it is done with it. Attributes defined by Windows Portable Devices can be found on the Properties and
/// Attributes page.
///
///
///
/// Property attributes describe a property's access rights, valid values, and other information. For example, a property can
/// have a WPD_PROPERTY_ATTRIBUTE_CAN_DELETE value set to False to prevent deletion, and have a range of valid values stored as
/// individual entries.
///
/// Examples
/// For an example of how to use this method, see Setting Properties for a Single Object.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceproperties-getpropertyattributes
// HRESULT GetPropertyAttributes( [in] LPCWSTR pszObjectID, [in] REFPROPERTYKEY Key, [out] IPortableDeviceValues **ppAttributes );
IPortableDeviceValues GetPropertyAttributes([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID, in PROPERTYKEY Key);
/// The GetValues method retrieves a list of specified properties from a specified object on a device.
/// The ID of the object to query. To specify the device, use WPD_DEVICE_OBJECT_ID.
///
/// Pointer to an IPortableDeviceKeyCollection interface that contains one or more properties to query for. If this is
/// NULL, all properties will be retrieved. See Properties and Attributes for a list of properties that are defined by
/// Windows Portable Devices.
///
///
/// An IPortableDeviceValues interface that contains the requested property values. These will be returned as PROPERTYKEY/value
/// pairs, where the data type of the value depends on the property. If a value could not be retrieved for some reason, the
/// returned type will be VT_ERROR, and contain an HRESULT value describing the retrieval error. The caller must release this
/// interface when it is done with it.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceproperties-getvalues
// HRESULT GetValues( [in] LPCWSTR pszObjectID, [in] IPortableDeviceKeyCollection *pKeys, [out] IPortableDeviceValues **ppValues );
IPortableDeviceValues GetValues([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID, IPortableDeviceKeyCollection? pKeys);
/// The SetValues method adds or modifies one or more properties on a specified object on a device.
/// The object ID of the object to modify. To specify the device, use WPD_DEVICE_OBJECT_ID.
///
/// Pointer to an IPortableDeviceValues interface that contains one or more property/value pairs to set. Existing values will be overwritten.
///
///
/// An IPortableDeviceValues interface that contains a collection of property/HRESULT values. Each value (type VT_ERROR)
/// describes the success or failure of the property set attempt. The caller must release this interface when it is done with it.
///
///
///
/// To delete a property, call IPortableDeviceProperties::Delete. A property can be deleted only if its
/// WPD_PROPERTY_ATTRIBUTE_CAN_WRITE attribute is True. This attribute can be retrieved by calling GetPropertyAttributes.
///
/// Examples
/// For an example of how to use this method, see Setting Properties for a Single Object.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceproperties-setvalues
// HRESULT SetValues( [in] LPCWSTR pszObjectID, [in] IPortableDeviceValues *pValues, [out] IPortableDeviceValues **ppResults );
IPortableDeviceValues SetValues([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID, IPortableDeviceValues pValues);
/// The Delete method deletes specified properties from a specified object on a device.
/// The ID of the object whose properties you will delete. To specify the device, use WPD_DEVICE_OBJECT_ID.
///
/// Pointer to an IPortableDeviceKeyCollection interface that specifies which properties to delete. For a list of properties
/// defined by Windows Portable Devices, see Properties and Attributes.
///
///
///
/// Properties can be deleted only if their WPD_PROPERTY_ATTRIBUTE_CAN_DELETE attribute is True. This attribute can be retrieved
/// by calling GetPropertyAttributes.
///
///
/// The driver has no way to indicate partial success; that is, if only some properties could be deleted, the driver will return
/// S_FALSE, but this method does not indicate which properties were successfully deleted. The only way to learn which
/// properties were deleted is to request all properties by calling IPortableDeviceProperties::GetValues.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceproperties-delete
// HRESULT Delete( [in] LPCWSTR pszObjectID, [in] IPortableDeviceKeyCollection *pKeys );
void Delete([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID, IPortableDeviceKeyCollection pKeys);
/// The Cancel method cancels a pending call.
///
/// This method cancels all pending operations on the current device handle, which corresponds to a session associated with an
/// IPortableDevice interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceproperties-cancel
// HRESULT Cancel();
void Cancel();
}
///
///
/// The IPortableDevicePropertiesBulk interface queries or sets multiple properties on multiple objects on a device,
/// asynchronously. Information is returned by an application-implemented IPortableDevicePropertiesBulkCallback interface.
///
///
/// To get this interface, call QueryInterface on IPortableDeviceProperties. If the device does not support bulk
/// operations, this call will fail with E_NOINTERFACE.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevicepropertiesbulk
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDevicePropertiesBulk")]
[ComImport, Guid("482b05c0-4056-44ed-9e0f-5e23b009da93"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDevicePropertiesBulk
{
///
/// The QueueGetValuesByObjectList method queues a request for one or more specified properties from one or more
/// specified objects on the device.
///
///
/// Pointer to an IPortableDevicePropVariantCollection interface that lists the object IDs of all the objects to query. These
/// will be of type VT_LPWSTR.
///
///
/// Pointer to an IPortableDeviceKeyCollection interface that specifies the properties to request. For a list of properties
/// defined by Windows Portable Devices, see Properties and Attributes. Specify NULL to indicate all properties from the
/// specified objects.
///
///
/// Pointer to an application-implemented IPortableDevicePropertiesBulkCallback interface that will receive the information as
/// it is retrieved.
///
///
/// Pointer to a GUID that is used to start, cancel, or identify the request IPortableDevicePropertiesBulkCallback
/// callbacks, if implemented.
///
///
///
/// The queued request is not started until the application calls Start. For more information on how to use this method, see
/// IPortableDevicePropertiesBulk Interface.
///
///
/// Due to performance issues, some devices may not return a comprehensive list of properties when the pKeys parameter is NULL.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicepropertiesbulk-queuegetvaluesbyobjectlist
// HRESULT QueueGetValuesByObjectList( [in] IPortableDevicePropVariantCollection *pObjectIDs, [in] IPortableDeviceKeyCollection
// *pKeys, [in] IPortableDevicePropertiesBulkCallback *pCallback, [out] GUID *pContext );
void QueueGetValuesByObjectList(IPortableDevicePropVariantCollection pObjectIDs, [Optional] IPortableDeviceKeyCollection? pKeys,
IPortableDevicePropertiesBulkCallback pCallback, out Guid pContext);
///
/// The QueueGetValuesByObjectFormat interface queues a request for properties of objects of a specific format on a device.
///
///
/// Pointer to a GUID that specifies the object format. Only objects of this type are queried.
///
///
/// The object ID of the parent object where the search should begin. To search all the objects on a device, specify WPD_DEVICE_OBJECT_ID.
///
///
/// The maximum depth to search below the parent, where 1 means immediate children only. It is acceptable for this number to be
/// greater than the actual number of levels. To search to any depth, specify 0xFFFFFFFF
///
///
/// Pointer to an IPortableDeviceKeyCollection interface that contains the properties to retrieve. For a list of
/// properties that are defined by Windows Portable Devices, see Properties and Attributes. Specify NULL to indicate all
/// properties from the specified format.
///
///
/// Pointer to an application-implemented IPortableDevicePropertiesBulkCallback interface that will receive the information as
/// it is retrieved.
///
///
/// Pointer to a GUID that will be used to start, cancel, or identify the request in
/// IPortableDevicePropertiesBulkCallback callbacks, if implemented.
///
///
///
/// If you specify WPD_OBJECT_FORMAT_ALL for the pguidObjectFormat parameter, this method will return properties for all objects
/// on the device.
///
///
/// If the pszParentObjectID parameter is set to an empty string (""), the method will perform a search that is dependent on the
/// dwDepth parameter as described in the following table.
///
///
///
/// dwDepth
/// Method returns
///
/// -
/// 0
/// No results
///
/// -
/// 1
/// Values for the specified device only.
///
/// -
/// 2
/// Values for the specified device and all functional objects found on that device.
///
///
///
/// If the pszParentObjectID parameter is set to WPD_DEVICE_OBJECT_ID, the method will perform a search that is dependent on the
/// dwDepth parameter as described in the following table.
///
///
///
/// dwDepth
/// Method returns
///
/// -
/// 0
/// Values for the specified device only.
///
/// -
/// 1
/// Values for the specified device and all functional objects found on that device.
///
///
///
/// The queued request is not started until the application calls Start. For more information on how to use this method, see
/// IPortableDevicePropertiesBulk Interface.
///
///
/// Due to performance issues, some devices may not return a comprehensive list of properties when the pKeys parameter is NULL.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicepropertiesbulk-queuegetvaluesbyobjectformat
// HRESULT QueueGetValuesByObjectFormat( [in] REFGUID pguidObjectFormat, [in] LPCWSTR pszParentObjectID, [in] const DWORD
// dwDepth, [in] IPortableDeviceKeyCollection *pKeys, [in] IPortableDevicePropertiesBulkCallback *pCallback, [out] GUID
// *pContext );
void QueueGetValuesByObjectFormat(in Guid pguidObjectFormat,
[MarshalAs(UnmanagedType.LPWStr)] string pszParentObjectID, uint dwDepth,
[Optional] IPortableDeviceKeyCollection? pKeys, IPortableDevicePropertiesBulkCallback pCallback, out Guid pContext);
///
/// The QueueSetValuesByObjectList method queues a request to set one or more specified values on one or more specified
/// objects on the device.
///
///
/// Pointer to an IPortableDeviceValuesCollection interface that contains the properties and values to set on specified objects.
/// This interface holds one or more IPortableDeviceValues interfaces, each representing a single object. Each
/// IPortableDeviceValues interface holds a collection of key/value pairs, where the key is the PROPERTYKEY
/// identifying the property, and the value is a data type that varies by property. Each IPortableDeviceValues interface
/// also holds one WPD_OBJECT_ID property that identifies the object to which this interface refers.
///
///
/// Pointer to an application-implemented IPortableDevicePropertiesBulkCallback interface that will receive the information as
/// it is retrieved.
///
///
/// Pointer to a GUID that is used to start, cancel, or identify the request to any client-implemented
/// IPortableDevicePropertiesBulkCallback callbacks.
///
///
/// The queued request is not started until the application calls Start. For more information on how to use this method, see
/// IPortableDevicePropertiesBulk Interface.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicepropertiesbulk-queuesetvaluesbyobjectlist
// HRESULT QueueSetValuesByObjectList( [in] IPortableDeviceValuesCollection *pObjectValues, [in]
// IPortableDevicePropertiesBulkCallback *pCallback, [out] GUID *pContext );
void QueueSetValuesByObjectList(IPortableDeviceValuesCollection pObjectValues,
IPortableDevicePropertiesBulkCallback pCallback, out Guid pContext);
/// The Start method starts a queued operation.
///
/// A pointer to a GUID that identifies the operation to start. This value is generated by a Queue... method of this interface.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicepropertiesbulk-start
// HRESULT Start( [in] REFGUID pContext );
void Start(in Guid pContext);
/// The Cancel method cancels a pending properties request.
///
/// Pointer to a context GUID that was retrieved when an asynchronous request was started by calling one of the Queue... methods.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicepropertiesbulk-cancel
// HRESULT Cancel( [in] REFGUID pContext );
void Cancel(in Guid pContext);
}
///
///
/// The IPortableDevicePropertiesBulkCallback interface is implemented by the application to track the progress of an
/// asynchronous operation that was begun by using the IPortableDevicePropertiesBulk interface.
///
///
/// After the application calls IPortableDevicePropertiesBulk::Start, Windows Portable Devices calls
/// IPortableDevicePropertiesBulkCallback::OnStart first, and then repeatedly calls
/// IPortableDevicePropertiesBulkCallback::OnProgress with information until the operation is completed or the application
/// calls IPortableDevicePropertiesBulk::Cancel or returns an error value for OnProgress. Finally, regardless of whether the
/// operation completed successfully, Windows Portable Devices calls IPortableDevicePropertiesBulkCallback::OnEnd.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledevicepropertiesbulkcallback
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDevicePropertiesBulkCallback")]
[ComImport, Guid("9deacb80-11e8-40e3-a9f3-f557986a7845"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDevicePropertiesBulkCallback
{
///
/// The OnStart method is called by the SDK when a bulk operation started by IPortableDevicePropertiesBulk::Start is
/// about to begin.
///
///
/// Pointer to a GUID that identifies which operation has started. This value is produced by a Queue... method of the
/// IPortableDevicePropertiesBulk interface.
///
///
/// The application should return either S_OK or an error code to abandon the operation. The application should handle all error
/// codes in the same manner.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicepropertiesbulkcallback-onstart
// HRESULT OnStart( [in] REFGUID pContext );
[PreserveSig]
HRESULT OnStart(in Guid pContext);
///
/// The OnProgress method is called by the SDK when a bulk operation started by IPortableDevicePropertiesBulk::Start has
/// sent data to the device and received some information back.
///
///
/// Pointer to a GUID that identifies which operation is in progress. This value is produced by a Queue... method of the
/// IPortableDevicePropertiesBulk interface.
///
///
/// Pointer to an IPortableDeviceValuesCollection interface that contains the results retrieved from the device. This interface
/// will hold one or more IPortableDeviceValues interfaces. Each of these interfaces will hold one WPD_OBJECT_ID property with a
/// string value (VT_LPSTR) specifying the object ID of the object that these values pertain to. The rest of the values in each
/// IPortableDeviceValues interface vary, depending on the bulk operation being reported. For the
/// QueueGetValuesByObjectFormat and QueueGetValuesByObjectList methods, they will be retrieved values of varying
/// types. For QueueSetValuesByObjectList, they will be VT_ERRORHRESULT values for any errors encountered when
/// setting values.
///
///
/// The application should return either S_OK, or an error code to abandon the operation. All error codes are handled the same way.
///
///
/// This method can be called once or multiple times, depending on how large the operation is.
///
/// This method does not necessarily retrieve all properties at once, nor does it return the properties in a particular order.
///
/// If this method is called multiple times, it may return properties for the same object identifier each time.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicepropertiesbulkcallback-onprogress
// HRESULT OnProgress( [in] REFGUID pContext, [in] IPortableDeviceValuesCollection *pResults );
[PreserveSig]
HRESULT OnProgress(in Guid pContext, IPortableDeviceValuesCollection pResults);
///
/// The OnEnd method is called by the SDK when a bulk operation that is started by IPortableDevicePropertiesBulk::Start
/// is completed.
///
///
/// Pointer to a GUID that identifies which operation has finished. This value is produced by a Queue... method of the
/// IPortableDevicePropertiesBulk interface.
///
/// Contains any errors returned by the driver after the bulk operation has completed.
/// The method's return value is ignored.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicepropertiesbulkcallback-onend
// HRESULT OnEnd( [in] REFGUID pContext, [out] HRESULT hrStatus );
void OnEnd(in Guid pContext, HRESULT hrStatus);
}
///
/// The IPortableDeviceResources interface provides access to an object's raw data. Use this interface to read or write
/// resources in an object. To get this interface, call IPortableDeviceContent::Transfer.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledeviceresources
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceResources")]
[ComImport, Guid("FD8878AC-D841-4D17-891C-E6829CDB6934"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceResources
{
/// The GetSupportedResources method retrieves a list of resources that are supported by a specific object.
/// The ID of the object.
///
/// An IPortableDeviceKeyCollection interface that holds a collection of PROPERTYKEY values specifying resource types
/// supported by this object type. If the object cannot hold resources, this will be an empty collection. The caller must
/// release this interface when it is done with it.
///
///
/// The list of resources returned by this method includes all resources that the object can support. This does not mean that
/// all the listed resources actually have data, but that the object is capable of supporting each listed resource.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceresources-getsupportedresources
// HRESULT GetSupportedResources( [in] LPCWSTR pszObjectID, [out] IPortableDeviceKeyCollection **ppKeys );
IPortableDeviceKeyCollection GetSupportedResources([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID);
/// The GetResourceAttributes method retrieves all attributes from a specified resource in an object.
/// The object ID of the object hosting the resource.
/// A REFPROPERTYKEY that specifies which resource to query.
///
/// Pointer to an IPortableDeviceValues interface pointer that holds PROPERTYKEY/ PROPVARIANT pairs that describe
/// each attribute and its value, respectively. The value types of the attribute values vary. If a property could not be
/// returned, the value for the returned property will be VT_ERROR, and the PROPVARIANT scode member will contain
/// the HRESULT of that particular failure.
///
///
/// Resource attributes describe the access rights, size, format, and other information related to a resource. For example, the
/// attributes for an audio annotation resource on an image object may specify the bit rate, channel count, and data format of
/// the audio.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceresources-getresourceattributes
// HRESULT GetResourceAttributes( [in] LPCWSTR pszObjectID, [in] REFPROPERTYKEY Key, [out] IPortableDeviceValues
// **ppResourceAttributes );
IPortableDeviceValues GetResourceAttributes([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID, in PROPERTYKEY Key);
///
/// The GetStream method gets an IStream interface with which to read or write the content data in an object on a
/// device. The retrieved interface enables you to read from or write to the object data.
///
/// The object ID of the object.
///
/// A REFPROPERTYKEY that specifies which resource to read. You can retrieve the keys of all the object's resources by
/// calling GetSupportedResources.
///
///
/// One of the following access modes:
///
/// -
/// STGM_READ (Read-only access.)
///
/// -
/// STGM_WRITE (Write-only access.)
///
/// -
/// STGM_READWRITE (Read/write access.)
///
///
///
///
/// An optional pointer to a DWORD that specifies an estimate of the best buffer size to use when reading or writing data
/// by using ppStream. A driver is required to support this value.
///
///
/// Pointer to an IStream interface pointer. This interface is used to read and write data to the object. The caller must
/// release this interface when it is done with it.
///
///
///
/// The retrieved stream cannot read the contents of a folder recursively. To copy all the resources in an object, specify
/// WPD_RESOURCE_DEFAULT for Key.
///
/// If the object does not support resources, this method will return an error, and ppStream will be NULL.
///
/// Applications should use the buffer size returned by pdwOptimalBufferSize when allocating the buffer for read or write operations.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceresources-getstream
// HRESULT GetStream( [in] LPCWSTR pszObjectID, [in] REFPROPERTYKEY Key, [in] const DWORD dwMode, [in, out] DWORD
// *pdwOptimalBufferSize, [out] IStream **ppStream );
IStream GetStream([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID, in PROPERTYKEY Key, STGM dwMode, out uint pdwOptimalBufferSize);
/// The Delete method deletes one or more resources from the object identified by the pszObjectID parameter.
/// The object ID of the object.
///
/// Pointer to an IPortableDeviceKeyCollection interface that lists which resources to delete. You can find out what resources
/// the object has by calling GetSupportedResources.
///
///
///
/// An object can have several resources. For instance, an object may contain image data, thumbnail image data, and audio data.
///
/// An application can retrieve a list of supported resources by calling the GetSupportedResources method.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceresources-delete
// HRESULT Delete( [in] LPCWSTR pszObjectID, [in] IPortableDeviceKeyCollection *pKeys );
void Delete([MarshalAs(UnmanagedType.LPWStr)] string pszObjectID, IPortableDeviceKeyCollection pKeys);
/// The Cancel method cancels a pending operation.
///
/// This method cancels all pending operations on the current device handle, which corresponds to a session associated with an
/// IPortableDevice interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceresources-cancel
// HRESULT Cancel();
void Cancel();
/// The CreateResource method creates a resource.
///
/// Pointer to the following object parameter attributes.
///
///
/// Attribute
/// Description
///
/// -
/// WPD_OBJECT_NAME
/// The object name.
///
/// -
/// WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE
/// The total size of the resource data stream.
///
/// -
/// WPD_RESOURCE_ATTRIBUTE_FORMAT
/// The format of the resource data stream.
///
/// -
/// WPD_RESOURCE_ATTRIBUTE_RESOURCE_KEY
/// The resource key.
///
///
///
/// Pointer to a stream into which the caller can write resource data.
///
/// Pointer to a value that specifies the optimal buffer size when writing to the stream. This parameter is optional.
///
/// Pointer to a cookie that identifies the resource creation request. This parameter is optional.
///
///
/// When an application calls this method, it must specify the resource attributes and it must write the required data to the
/// stream that this method returns.
///
///
/// A resource is not created when the method returns; it is created when the application commits the data by calling the
/// Commit method on the stream at which ppData points.
///
///
/// To cancel the data transfer to a resource, the application must call the Revert method on the stream at which ppData
/// points. Once the transfer is canceled, the application must invoke IUnknown::Release to close the stream.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceresources-createresource
// HRESULT CreateResource( [in] IPortableDeviceValues *pResourceAttributes, [out] IStream **ppData, [out] DWORD
// *pdwOptimalWriteBufferSize, [out] LPWSTR *ppszCookie );
void CreateResource(IPortableDeviceValues pResourceAttributes, out IStream ppData, out uint pdwOptimalWriteBufferSize, [MarshalAs(UnmanagedType.LPWStr)] out string ppszCookie);
}
/// The IPortableDeviceService interface provides access to a service.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledeviceservice
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceService")]
[ComImport, Guid("D3BD3A44-D7B5-40A9-98B7-2FA4D01DEC08"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), CoClass(typeof(PortableDeviceService))]
public interface IPortableDeviceService
{
/// The Open method opens a connection to the service.
///
/// The Plug and Play (PnP) identifier for the service, which is the same identifier that is retrieved by the GetPnPServiceId method.
///
/// The IPortableDeviceValues interface specifying the client information.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-open HRESULT
// Open( [in] LPCWSTR pszPnPServiceID, [in] IPortableDeviceValues *pClientInfo );
void Open([MarshalAs(UnmanagedType.LPWStr)] string pszPnPServiceID, IPortableDeviceValues pClientInfo);
/// The Capabilities method retrieves the service capabilities.
/// The IPortableDeviceServiceCapabilities interface specifying the capabilities of the service.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-capabilities
// HRESULT Capabilities( [out] IPortableDeviceServiceCapabilities **ppCapabilities );
IPortableDeviceServiceCapabilities Capabilities();
/// The Content method retrieves access to the service content.
/// The IPortableDeviceContent2 interface that accesses the service content.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-content
// HRESULT Content( [out] IPortableDeviceContent2 **ppContent );
IPortableDeviceContent2 Content();
///
/// The Methods method retrieves the IPortableDeviceServiceMethods interface that is used to invoke custom functionality
/// on the service.
///
/// The IPortableDeviceServiceMethods interface used for invoking methods on the given service.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-methods
// HRESULT Methods( [out] IPortableDeviceServiceMethods **ppMethods );
IPortableDeviceServiceMethods Methods();
/// The Cancel method cancels a pending operation on this interface.
///
///
/// This method cancels all pending operations on the current device handle, which corresponds to a session associated with an
/// IPortableDeviceService interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
///
/// If your application invokes the WPD API from multiple threads, each thread should create a new instance of the
/// IPortableDeviceService interface. Doing this ensures that any cancel operation affects only the I/O for the affected thread.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-cancel
// HRESULT Cancel();
void Cancel();
/// The Close method releases the connection to the service.
///
///
/// Applications typically won't call this method, as the Windows Portable Devices (WPD) API automatically calls it when the
/// last reference to a service is removed.
///
///
/// When an application does call this method, the WPD API releases the service connection, so that any WPD objects attached to
/// the service will return the E_WPD_SERVICE_NOT_OPEN error.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-close
// HRESULT Close();
void Close();
///
/// The GetServiceObjectID method retrieves an object identifier for the service. This object identifier can be used to
/// access the properties of the service, for example.
///
/// The retrieved service object identifier.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-getserviceobjectid
// HRESULT GetServiceObjectID( [out] LPWSTR *ppszServiceObjectID );
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetServiceObjectID();
/// The GetPnPServiceID method retrieves a Plug and Play (PnP) identifier for the service.
/// The retrieved PnP identifier, which is the same identifier that was passed to the Open method.
///
/// The Open method must be called on the service before a PnP identifier can be retrieved.
///
/// When an application no longer needs the PnP identifier, it should call the CoTaskMemFree function to free the
/// identifier memory.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-getpnpserviceid
// HRESULT GetPnPServiceID( [out] LPWSTR *ppszPnPServiceID );
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetPnPServiceID();
/// The Advise method registers an application-defined callback object that receives service events.
/// Not used.
/// The IPortableDeviceEventCallback interface specifying the callback object to register.
///
/// The IPortableDeviceValues interface specifying the event-registration parameters, or NULL if the callback object is
/// to receive all service events.
///
///
/// The unique context ID for the callback object. This value matches that used by the Unadvise method to unregister the
/// callback object.
///
///
/// During cleanup, an application should unregister the callback object by calling the Unadvise method, and then release the
/// memory referenced by the ppszCookie parameter by calling the CoTaskMemFree function.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-advise
// HRESULT Advise( [in] const DWORD dwFlags, [in] IPortableDeviceEventCallback *pCallback, [in] IPortableDeviceValues
// *pParameters, [out] LPWSTR *ppszCookie );
void Advise([In, Optional] uint dwFlags, IPortableDeviceEventCallback pCallback, [In, Optional] IPortableDeviceValues? pParameters,
[MarshalAs(UnmanagedType.LPWStr)] out string ppszCookie);
/// The Unadvise method unregisters a service event callback object.
///
/// The unique context ID for the application-supplied callback object. This value matches that yielded by the ppszCookie
/// parameter of the Advise method.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-unadvise
// HRESULT Unadvise( [in] LPCWSTR pszCookie );
void Unadvise([MarshalAs(UnmanagedType.LPWStr)] string pszCookie);
/// The SendCommand method sends a standard WPD command and its parameters to the service.
/// Not used.
/// The IPortableDeviceValues interface specifying the command parameters.
/// The IPortableDeviceValues interface specifying the command results.
///
///
/// This method should only be used to send standard WPD commands to the service. To invoke service methods, use the
/// IPortableDeviceServiceMethods interface.
///
///
/// This method may fail even though it returns S_OK as its HRESULT value. To determine if a command succeeded, an
/// application should always examine the properties referenced by the ppResults parameter:
///
///
/// -
/// The WPD_PROPERTY_COMMON_HRESULT property indicates if the command succeeded.
///
/// -
/// If the command failed, the WPD_PROPERTY_COMMON_DRIVER_ERROR_CODE property will contain driver-specific error codes.
///
///
/// The object referenced by the pParameters parameter must specify at least these properties:
///
/// -
///
/// WPD_PROPERTY_COMMON_COMMAND_CATEGORY, which should contain a command category, such as the fmtid member of the
/// WPD_COMMAND_COMMON_RESET_DEVICE property
///
///
/// -
///
/// WPD_PROPERTY_COMMON_COMMAND_ID, which should contain a command identifier, such as the pid member of the
/// WPD_COMMAND_COMMON_RESET_DEVICE property.
///
///
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservice-sendcommand
// HRESULT SendCommand( [in] const DWORD dwFlags, [in] IPortableDeviceValues *pParameters, [out] IPortableDeviceValues
// **ppResults );
void SendCommand([In, Optional] uint dwFlags, IPortableDeviceValues pParameters, out IPortableDeviceValues ppResults);
}
///
/// Clients use this interface to asynchronously open an IPortableDeviceService instance. This is used when opening a service can
/// involve a user consent prompt.
///
[PInvokeData("portabledeviceapi.h")]
[ComImport, Guid("e56b0534-d9b9-425c-9b99-75f97cb3d7c8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceServiceActivation
{
///
[PreserveSig]
HRESULT OpenAsync([MarshalAs(UnmanagedType.LPWStr)] string pszPnPServiceID, IPortableDeviceValues pClientInfo, IPortableDeviceServiceOpenCallback pCallback);
///
[PreserveSig]
HRESULT CancelOpenAsync();
}
/// The IPortableDeviceServiceCapabilities interface retrieves information describing the capabilities of a service.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledeviceservicecapabilities
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceServiceCapabilities")]
[ComImport, Guid("24DBD89D-413E-43E0-BD5B-197F3C56C886"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceServiceCapabilities
{
/// The GetSupportedMethods method retrieves the methods supported by the service.
/// The IPortableDevicePropVariantCollection interface that receives the list of methods.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getsupportedmethods
// HRESULT GetSupportedMethods( [out] IPortableDevicePropVariantCollection **ppMethods );
IPortableDevicePropVariantCollection GetSupportedMethods();
///
/// The GetSupportedMethodsByFormat method retrieves the methods supported by the service for the specified format.
///
/// The format whose supported methods are retrieved.
/// The IPortableDevicePropVariantCollection interface that receives the list of methods.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getsupportedmethodsbyformat
// HRESULT GetSupportedMethodsByFormat( [in] REFGUID Format, [out] IPortableDevicePropVariantCollection **ppMethods );
IPortableDevicePropVariantCollection GetSupportedMethodsByFormat(in Guid Format);
/// The GetMethodAttributes method retrieves the attributes used to describe a given method.
/// The method whose attributes are retrieved.
/// The IPortableDeviceValues interface that receives the list of attributes.
///
///
/// Possible attributes include the WPD_METHOD_ATTRIBUTE_NAME, WPD_METHOD_ATTRIBUTE_ASSOCIATED_FORMAT,
/// WPD_METHOD_ATTRIBUTE_ACCESS, and WPD_METHOD_ATTRIBUTE_PARAMETERS properties.
///
/// Examples
/// For an example of how to use this method, see Retrieving Supported Service Methods.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getmethodattributes
// HRESULT GetMethodAttributes( [in] REFGUID Method, [out] IPortableDeviceValues **ppAttributes );
IPortableDeviceValues GetMethodAttributes(in Guid Method);
/// The GetMethodParameterAttributes method retrieves the attributes used to describe a given method parameter.
/// The method that contains the parameter whose attributes are retrieved.
/// The parameter whose attributes are retrieved.
/// The IPortableDeviceValues interface that receives the list of attributes.
///
///
/// Possible attributes include the WPD_PARAMETER_ATTRIBUTE_ORDER, WPD_PARAMETER_ATTRIBUTE_USAGE,
/// WPD_PARAMETER_ATTRIBUTE_NAME, and WPD_PARAMETER_ATTRIBUTE_VARTYPE properties.
///
/// Examples
/// For an example of how to use this method, see Retrieving Supported Service Methods.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getmethodparameterattributes
// HRESULT GetMethodParameterAttributes( REFGUID Method, [in] REFPROPERTYKEY Parameter, [out] IPortableDeviceValues
// **ppAttributes );
IPortableDeviceValues GetMethodParameterAttributes(in Guid Method, in PROPERTYKEY Parameter);
/// The GetSupportedFormats method retrieves the formats supported by the service.
/// The IPortableDevicePropVariantCollection interface that receives the list of formats.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getsupportedformats
// HRESULT GetSupportedFormats( [out] IPortableDevicePropVariantCollection **ppFormats );
IPortableDevicePropVariantCollection GetSupportedFormats();
/// The GetFormatAttributes method retrieves the attributes of a format.
/// The format whose attributes are retrieved.
/// The IPortableDeviceValues interface that receives the list of attributes.
///
/// WPD_FORMAT_ATTRIBUTE_NAME is an example of a commonly retrieved attribute.
/// Examples
/// For an example of how to use this method, see Retrieving Supported Service Formats.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getformatattributes
// HRESULT GetFormatAttributes( [in] REFGUID Format, [out] IPortableDeviceValues **ppAttributes );
IPortableDeviceValues GetFormatAttributes(in Guid Format);
///
/// The GetSupportedFormatProperties method retrieves the properties supported by the service for the specified format.
///
/// The format whose properties are retrieved.
/// The IPortableDeviceKeyCollection interface that receives the list of properties.
///
/// The retrieved property collection is a superset of all properties supported by an object of the specified format.
///
/// An application can also retrieve the properties for an object by calling the IPortableDeviceService::SendCommand method with
/// the WPD_COMMAND_OBJECT_PROPERTIES_GET_SUPPORTED property passed as the command identifier. However, the
/// GetSupportedFormatProperties method is typically faster than the IPortableDeviceService::SendCommand method.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getsupportedformatproperties
// HRESULT GetSupportedFormatProperties( [in] REFGUID Format, [out] IPortableDeviceKeyCollection **ppKeys );
IPortableDeviceKeyCollection GetSupportedFormatProperties(in Guid Format);
/// The GetFormatPropertyAttributes method retrieves the attributes of a format property.
/// The format whose property has its attributes retrieved.
/// The property whose attributes are retrieved.
/// The IPortableDeviceValues interface that receives the list of attributes.
///
///
/// A Windows Portable Devices (WPD) driver often treats objects of a given format the same. Many properties will therefore have
/// attributes that are identical across all objects of that format. This method retrieves such attributes.
///
/// Note that this method will not retrieve attributes that differ across object instances.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getformatpropertyattributes
// HRESULT GetFormatPropertyAttributes( [in] REFGUID Format, [in] REFPROPERTYKEY Property, [out] IPortableDeviceValues
// **ppAttributes );
IPortableDeviceValues GetFormatPropertyAttributes(in Guid Format, in PROPERTYKEY Property);
/// The GetSupportedEvents method retrieves the events supported by the service.
/// The IPortableDevicePropVariantCollection interface that receives the list of events.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getsupportedevents
// HRESULT GetSupportedEvents( [out] IPortableDevicePropVariantCollection **ppEvents );
IPortableDevicePropVariantCollection GetSupportedEvents();
/// The GetEventAttributes method retrieves the attributes of an event.
/// The event whose attributes are retrieved.
/// The IPortableDeviceValues interface that receives the list of attributes.
///
///
/// Possible attributes include the WPD_EVENT_ATTRIBUTE_NAME, WPD_EVENT_ATTRIBUTE_PARAMETERS, and WPD_EVENT_ATTRIBUTE_OPTIONS properties.
///
/// Examples
/// For an example of how to use this method, see Retrieving Supported Service Events.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-geteventattributes
// HRESULT GetEventAttributes( [in] REFGUID Event, [out] IPortableDeviceValues **ppAttributes );
IPortableDeviceValues GetEventAttributes(in Guid Event);
/// The GetEventParameterAttributes method retrieves the attributes of an event parameter.
/// The event that contains the parameter whose attributes are retrieved.
/// The parameter whose attributes are retrieved.
/// The IPortableDeviceValues interface that receives the list of attributes.
///
/// Possible attribute values include the WPD_PARAMETER_ATTRIBUTE_VARTYPE and WPD_PARAMETER_ATTRIBUTE_FORM properties.
/// Examples
/// For an example of how to use this method, see Retrieving Supported Service Events.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-geteventparameterattributes
// HRESULT GetEventParameterAttributes( REFGUID Event, [in] REFPROPERTYKEY Parameter, [out] IPortableDeviceValues **ppAttributes );
IPortableDeviceValues GetEventParameterAttributes(in Guid Event, in PROPERTYKEY Parameter);
/// The GetInheritedServices method retrieves the services having the specified inheritance type.
/// The type of inherited services to retrieve.
///
/// The IPortableDevicePropVariantCollection interface that receives the list of services. If no inherited services are found,
/// an empty collection is returned.
///
///
///
/// Currently, device services may only inherit by implementing an abstract service. This is analogous to how a class implements
/// methods of an abstract interface or a virtual class in object-oriented programming. By implementing an abstract service, a
/// device service will support all formats, properties, and method behavior that the abstract service describes. For instance,
/// a Contacts service may implement the Anchor Sync abstract service, where the device stores markers indicating
/// which contacts were updated since the last synchronization with the PC.
///
///
/// Possible values for the dwInheritanceType parameter are those defined in the WPD_SERVICE_INHERITANCE_TYPES enumeration. (For
/// Windows 7, only the WPD_SERVICE_INHERITANCE_IMPLEMENTATION enumeration constant is supported.)
///
///
/// If the value of the dwInheritanceType parameter is WPD_SERVICE_INHERITANCE_IMPLEMENTATION, each item in the
/// collection specified by the ppServices parameter has variant type VT_CLSID.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getinheritedservices
// HRESULT GetInheritedServices( [in] const DWORD dwInheritanceType, [out] IPortableDevicePropVariantCollection **ppServices );
IPortableDevicePropVariantCollection GetInheritedServices([In] WPD_SERVICE_INHERITANCE_TYPES dwInheritanceType);
/// The GetFormatRenderingProfiles method retrieves the rendering profiles of a format.
/// The format whose rendering profiles are retrieved.
/// The IPortableDeviceValuesCollection object that receives the list of rendering profiles.
///
/// The rendering profiles are similar to what the WPD_FUNCTIONAL_CATEGORY_RENDERING_INFORMATION functional object returns for
/// device-wide rendering profiles, so that the DisplayRenderingProfile helper function described in Retrieving the
/// Rendering Capabilities Supported by a Device could be used here as well. But there are differences: The
/// GetFormatRenderingProfiles method retrieves only rendering profiles that apply to the selected service and have been
/// filtered by format.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getformatrenderingprofiles
// HRESULT GetFormatRenderingProfiles( [in] REFGUID Format, [out] IPortableDeviceValuesCollection **ppRenderingProfiles );
IPortableDeviceValuesCollection GetFormatRenderingProfiles(in Guid Format);
/// The GetSupportedCommands method retrieves the commands supported by the service.
/// The IPortableDeviceKeyCollection interface that receives the list of commands.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getsupportedcommands
// HRESULT GetSupportedCommands( [out] IPortableDeviceKeyCollection **ppCommands );
IPortableDeviceKeyCollection GetSupportedCommands();
/// The GetCommandOptions method retrieves the options of a WPD command.
/// The command whose options are retrieved.
/// The IPortableDeviceValues interface that receives the list of options.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-getcommandoptions
// HRESULT GetCommandOptions( [in] REFPROPERTYKEY Command, [out] IPortableDeviceValues **ppOptions );
IPortableDeviceValues GetCommandOptions(in PROPERTYKEY Command);
/// The Cancel method cancels a pending operation.
///
/// This method cancels all pending operations on the current service handle, which corresponds to a session associated with an
/// IPortableDeviceService interface. The Windows Portable Devices (WPD) API does not support targeted cancellation of specific operations.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicecapabilities-cancel
// HRESULT Cancel();
void Cancel();
}
///
/// The IPortableDeviceServiceManager interface retrieves the device associated with a service and the list of services found
/// on a device.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledeviceservicemanager
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceServiceManager")]
[ComImport, Guid("a8abc4e9-a84a-47a9-80b3-c5d9b172a961"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceServiceManager
{
/// The GetDeviceServices method retrieves a list of the services associated with the specified device.
/// The Plug and Play (PnP) identifier of the device.
///
/// A reference to a globally unique identifier (GUID) that specifies the category of services to retrieve. If the referenced
/// identifier is GUID_DEVINTERFACE_WPD_SERVICE, this method will retrieve all services supported by the device.
///
///
/// A user-allocated array of pointers to strings. When the method returns, the array contains the retrieved PnP service identifiers.
///
///
/// The number of elements in the array specified by the pServices parameter. This value represents the maximum number of
/// service identifiers that will be retrieved. When the method returns, this parameter contains the number of identifiers
/// actually retrieved.
///
///
///
/// If this method succeeds, the application should call the FreePortableDevicePnPIDs function to free the array referenced by
/// the pServices parameter.
///
/// An application can retrieve the PnP identifier for a device by calling the IPortableDeviceManager::GetDevices method.
///
/// Applications that use Single Threaded Apartments should use CLSID_PortableDeviceServiceFTM as this eliminates the
/// overhead of interface pointer marshaling. CLSID_PortableDeviceService is still supported for legacy applications.
///
/// Examples
/// The following example shows how to retrieve a list of services for all devices.
///
/// #include "stdafx.h" #include "atlbase.h" #include "portabledeviceapi.h" #include "portabledevice.h" HRESULT GetServiceName( LPCWSTR pszPnpServiceID, LPWSTR* ppszServiceName); HRESULT EnumerateServicesForDevice( IPortableDeviceServiceManager* pPortableDeviceServiceManager, LPCWSTR pszPnpDeviceID); int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = S_OK; DWORD cPnPDeviceIDs = 0; LPWSTR* pPnpDeviceIDs = NULL; CComPtr<IPortableDeviceManager> pPortableDeviceManager; CComPtr<IPortableDeviceServiceManager> pPortableDeviceServiceManager; // Initialize COM for COINIT_MULTITHREADED hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // CoCreate the IPortableDeviceManager interface to enumerate // portable devices and to get information about them. if (hr == S_OK) { hr = CoCreateInstance(CLSID_PortableDeviceManager, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceManager, (VOID**) &pPortableDeviceManager); } if (hr == S_OK) { // Get the PortableDeviceServiceManager interface // by calling QueryInterface from IPortableDeviceManager hr = pPortableDeviceManager->QueryInterface (IID_IPortableDeviceServiceManager, (VOID**) &pPortableDeviceServiceManager); } // Get the number of devices on the system if (hr == S_OK) { hr = pPortableDeviceManager->GetDevices(NULL, &cPnPDeviceIDs); } // If we have at least 1 device, // continue to query the list of services for each device if ((hr == S_OK) && (cPnPDeviceIDs > 0)) { pPnpDeviceIDs = new LPWSTR[cPnPDeviceIDs]; if (pPnpDeviceIDs != NULL) { hr = pPortableDeviceManager->GetDevices (pPnpDeviceIDs, &cPnPDeviceIDs); if (SUCCEEDED(hr)) { for (DWORD dwIndex = 0; dwIndex < cPnPDeviceIDs; dwIndex++) { hr = EnumerateServicesForDevice (pPortableDeviceServiceManager, pPnpDeviceIDs[dwIndex]); } } // Free all returned PnPDeviceID strings FreePortableDevicePnPIDs(pPnpDeviceIDs, cPnPDeviceIDs); // Delete the array of LPWSTR pointers delete [] pPnpDeviceIDs; pPnpDeviceIDs = NULL; } } return 0; } HRESULT EnumerateServicesForDevice( IPortableDeviceServiceManager* pPortableDeviceServiceManager, LPCWSTR pszPnpDeviceID) { HRESULT hr = S_OK; DWORD cPnpServiceIDs = 0; LPWSTR* pPnpServiceIDs = NULL; if (pPortableDeviceServiceManager == NULL) { return E_POINTER; } // Get the number of services for the device if (hr == S_OK) { hr = pPortableDeviceServiceManager->GetDeviceServices( pszPnpDeviceID, GUID_DEVINTERFACE_WPD_SERVICE, NULL, &cPnpServiceIDs); } // If we have at least 1, continue to gather information about // each service and populate the device information array. if ((hr == S_OK) && (cPnpServiceIDs > 0)) { pPnpServiceIDs = new LPWSTR[cPnpServiceIDs]; if (pPnpServiceIDs != NULL) { // Get a list of all services on the given device. // To query a give type of service (e.g. the Contacts Service), // a service GUID can be provided here instead of // GUID_DEVINTERFACE_WPD_SERVICE which returns all services DWORD dwIndex = 0; hr = pPortableDeviceServiceManager->GetDeviceServices (pszPnpDeviceID, GUID_DEVINTERFACE_WPD_SERVICE, pPnpServiceIDs, &cPnpServiceIDs); if (SUCCEEDED(hr)) { // For each service found, read the name property for (dwIndex = 0; dwIndex < cPnpServiceIDs && SUCCEEDED(hr); dwIndex++) { LPWSTR pszServiceName = NULL; hr = GetServiceName(pPnpServiceIDs[dwIndex], &pszServiceName); CoTaskMemFree(pszServiceName); } } FreePortableDevicePnPIDs(pPnpServiceIDs, cPnpServiceIDs); // Delete the array of LPWSTR pointers delete [] pPnpServiceIDs; pPnpServiceIDs = NULL; } } } HRESULT GetServiceName( LPCWSTR pszPnpServiceID, LPWSTR* ppszServiceName) { HRESULT hr = S_OK; LPWSTR pszServiceID = NULL; LPWSTR pszServiceObjectID = NULL; CComPtr<IPortableDeviceValues> pClientInfo; CComPtr<IPortableDeviceValues> pPropertyValues; CComPtr<IPortableDeviceService> pService; CComPtr<IPortableDeviceContent2> pContent; CComPtr<IPortableDeviceProperties>pProperties; CComPtr<IPortableDeviceKeyCollection> pPropertiesToRead; hr = CoCreateInstance(CLSID_PortableDeviceServiceFTM, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceService, (VOID**) &pService); if (hr == S_OK) { // CoCreate an IPortableDeviceValues interface // to hold the client information. hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**) & pClientInfo); if ((hr == S_OK) && (pClientInfo!= NULL)) { hr = pClientInfo->SetStringValue (WPD_CLIENT_NAME, L"Service Sample Application"); if (hr == S_OK) { hr = pClientInfo->SetUnsignedIntegerValue( WPD_CLIENT_MAJOR_VERSION, 1); } if (hr == S_OK) { hr = pClientInfo->SetUnsignedIntegerValue( WPD_CLIENT_MINOR_VERSION, 0); } if (hr == S_OK) { hr = pClientInfo->SetUnsignedIntegerValue( WPD_CLIENT_REVISION, 0); } if (hr == S_OK) { hr = pClientInfo->SetUnsignedIntegerValue( WPD_CLIENT_SECURITY_QUALITY_OF_SERVICE, SECURITY_IMPERSONATION); } if (hr == S_OK) { // Open a connection to the service hr = pService->Open(pszPnpServiceID, pClientInfo); } if (hr == S_OK) { hr = pService->GetServiceObjectID(&pszServiceID); } if (hr == S_OK) { hr = pService->Content(&pContent); } if (hr == S_OK) { hr = pContent->Properties(&pProperties); } // Create a IPortableDeviceKeyCollection // containing the single PROPERTYKEY if (hr == S_OK) { hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceKeyCollection, (VOID**) &pPropertiesToRead); } // Add our property key if (hr == S_OK) { hr = pPropertiesToRead->Add(WPD_OBJECT_NAME); } if (hr == S_OK) { hr = pProperties->GetValues( pszServiceID, pPropertiesToRead, &pPropertyValues); } if (hr == S_OK) { hr = pPropertyValues->GetStringValue( WPD_OBJECT_NAME, ppszServiceName); } CoTaskMemFree(pszServiceObjectID); return hr; } } }
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicemanager-getdeviceservices
// HRESULT GetDeviceServices( [in] LPCWSTR pszPnPDeviceID, [in] REFGUID guidServiceCategory, [in, out] LPWSTR *pServices, [in,
// out] DWORD *pcServices );
void GetDeviceServices([MarshalAs(UnmanagedType.LPWStr)] string pszPnPDeviceID, in Guid guidServiceCategory,
[Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] pServices, ref uint pcServices);
/// The GetDeviceForService method retrieves the device associated with the specified service.
/// The Plug and Play (PnP) identifier of the service.
/// The retrieved PnP identifier of the device associated with the service.
///
/// Neither the pszPnPServiceID parameter nor the pszPnPDeviceID parameter can be NULL.
/// An application can retrieve a PnP service identifier by calling the GetDeviceServices method.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicemanager-getdeviceforservice
// HRESULT GetDeviceForService( [in] LPCWSTR pszPnPServiceID, [out] LPWSTR *ppszPnPDeviceID );
[return: MarshalAs(UnmanagedType.LPWStr)]
string GetDeviceForService([MarshalAs(UnmanagedType.LPWStr)] string pszPnPServiceID);
}
///
///
/// The IPortableDeviceServiceMethodCallback interface contains a method that applications use to track the completion of a
/// callback method. Applications that call service methods asynchronously may implement this interface, and supply it as a
/// parameter to IPortableDeviceServiceMethods::InvokeAsync.
///
///
/// Each asynchronous method invocation uses the application-supplied callback object as its context. Therefore, an application that
/// intends to simultaneously invoke multiple methods should avoid reusing the callback object. Instead, the application should
/// provide a unique instance of the callback object for each call to InvokeAsync
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledeviceservicemethodcallback
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceServiceMethodCallback")]
[ComImport, Guid("C424233C-AFCE-4828-A756-7ED7A2350083"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceServiceMethodCallback
{
/// The OnComplete method indicates that a callback method has completed execution.
/// The overall status of the method.
///
/// An IPortableDeviceValues interface that contains the method-execution results. This is empty if the method returns no results.
///
/// If the method succeeds, it returns S_OK. Any other HRESULT value indicates that the call failed.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicemethodcallback-oncomplete
// HRESULT OnComplete( [in] HRESULT hrStatus, [in] IPortableDeviceValues *pResults );
[PreserveSig]
HRESULT OnComplete(HRESULT hrStatus, IPortableDeviceValues pResults);
}
/// The IPortableDeviceServiceMethods interface invokes, or cancels invocation of, a method on a service.
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nn-portabledeviceapi-iportabledeviceservicemethods
[PInvokeData("portabledeviceapi.h", MSDNShortId = "NN:portabledeviceapi.IPortableDeviceServiceMethods")]
[ComImport, Guid("E20333C9-FD34-412D-A381-CC6F2D820DF7"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceServiceMethods
{
/// The Invoke method synchronously invokes a method.
/// The method to invoke.
///
/// A pointer to an IPortableDeviceValues interface that contains the parameters of the invoked method, or NULL to
/// indicate that the method has no parameters.
///
///
/// The address of a pointer to an IPortableDeviceValues interface that receives the method results, or NULL to ignore
/// the method results.
///
///
///
/// The method invocation is synchronous and will not return until the method has completed. For long-running methods, your
/// application should call the InvokeAsync method instead.
///
/// Examples
/// For an example of how to use this method, see Invoking Service Methods
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicemethods-invoke
// HRESULT Invoke( [in] REFGUID Method, [in] IPortableDeviceValues *pParameters, [in, out] IPortableDeviceValues **ppResults );
void Invoke(in Guid Method, [Optional] IPortableDeviceValues? pParameters, out IPortableDeviceValues ppResults);
/// The InvokeAsync method asynchronously invokes a method.
/// The method to invoke.
///
/// A pointer to an IPortableDeviceValues interface that contains the parameters of the invoked method, or NULL to
/// indicate that the method has no parameters.
///
///
/// A pointer to an application-supplied IPortableDeviceServiceMethodCallback callback object that receives the method results,
/// or NULL to ignore the method results.
///
///
///
/// When invoking multiple methods, clients can create a separate instance of the IPortableDeviceServiceMethodCallback interface
/// for each invocation, saving a context with that instance object before passing it to the InvokeAsync method. This
/// way, the method operation can be identified when the OnComplete method is called. Use of a unique object for each invocation
/// also allows targeted cancellation of an operation by the Cancel method.
///
/// Examples
/// For an example of how to use this method, see Invoking Service Methods Asynchronously.
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicemethods-invokeasync
// HRESULT InvokeAsync( [in] REFGUID Method, [in] IPortableDeviceValues *pParameters, [in] IPortableDeviceServiceMethodCallback
// *pCallback );
void InvokeAsync(in Guid Method, [Optional] IPortableDeviceValues? pParameters, [Optional] IPortableDeviceServiceMethodCallback? pCallback);
/// The Cancel method cancels a pending method invocation.
///
/// A pointer to the callback object whose method invocation is to be canceled, or NULL to cancel all pending method invocations.
///
///
///
/// A callback object identifies a method invocation. If the same callback object is reused for multiple calls to the
/// InvokeAsync method, all method invocations arising from these calls will be cancelled.
///
///
/// To enable targeted cancellation of a specific method invocation, pass a unique instance of the
/// IPortableDeviceServiceMethodCallback interface to the InvokeAsync method.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledeviceservicemethods-cancel
// HRESULT Cancel( [in] IPortableDeviceServiceMethodCallback *pCallback );
void Cancel([Optional] IPortableDeviceServiceMethodCallback? pCallback);
}
/// Callback interface for implemented by clients for retrieving results of an asynchronous service open.
[PInvokeData("portabledeviceapi.h")]
[ComImport, Guid("bced49c8-8efe-41ed-960b-61313abd47a9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPortableDeviceServiceOpenCallback
{
///
[PreserveSig]
HRESULT OnComplete(HRESULT hrStatus);
}
/// Enumerates the items in the collection.
/// The instance.
/// A sequence of values from the collection.
public static IEnumerable Enumerate(this IEnumPortableDeviceObjectIDs intf) =>
new Vanara.Collections.IEnumFromCom(intf.Next, intf.Reset);
/// Retrieves the description of a device.
/// The instance used to get the name.
/// The device's Plug and Play ID.
/// The user-description name of the device.
public static string GetDeviceDescription(this IPortableDeviceManager manager, string pszPnPDeviceID) => PDMGetString(manager.GetDeviceDescription, pszPnPDeviceID);
/// Retrieves the user-friendly name for the device.
/// The instance used to get the name.
/// The device's Plug and Play ID.
/// The user-friendly name for the device.
///
/// A device is not required to support this method. If this method fails to retrieve a name, try requesting the WPD_OBJECT_NAME
/// property of the device object (the object with the ID WPD_DEVICE_OBJECT_ID).
///
public static string GetDeviceFriendlyName(this IPortableDeviceManager manager, string pszPnPDeviceID) => PDMGetString(manager.GetDeviceFriendlyName, pszPnPDeviceID);
/// Retrieves the name of the device manufacturer.
/// The instance used to get the name.
/// The device's Plug and Play ID.
/// The name of the device manufacturer.
public static string GetDeviceManufacturer(this IPortableDeviceManager manager, string pszPnPDeviceID) => PDMGetString(manager.GetDeviceManufacturer, pszPnPDeviceID);
///
/// Retrieves a property value stored by the device on the computer. (These are not standard properties that are defined by Windows
/// Portable Devices.)
///
/// The type of the value to return.
/// The instance used to get the device property.
///
/// The device's Plug and Play ID. You can retrieve a list of Plug and Play names of all devices that are connected to the computer
/// by calling GetDevices.
///
///
/// The name of the property to request. These are custom property names defined by a device manufacturer.
///
/// The retrieved data. This call will also return an error that can be ignored. See Return Values.
///
///
/// These property values are stored on device installation, or stored by a device during operation so that they can be persisted
/// across connection sessions. An application must know the exact name of the property, which is specified by the device itself;
/// therefore, this method is intended to be used by device developers who are creating their own applications.
///
///
/// To get Windows Portable Devices properties from the device object, call IPortableDeviceProperties::GetValues, and specify the
/// device object with WPD_DEVICE_OBJECT_ID.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/portabledeviceapi/nf-portabledeviceapi-iportabledevicemanager-getdeviceproperty
// HRESULT GetDeviceProperty( [in] LPCWSTR pszPnPDeviceID, [in] LPCWSTR pszDevicePropertyName, [in, out] BYTE *pData, [in, out]
// DWORD *pcbData, [in, out] DWORD *pdwType );
public static T? GetDeviceProperty(this IPortableDeviceManager manager, string pszPnPDeviceID, string pszDevicePropertyName)
{
var sz = 0U;
manager.GetDeviceProperty(pszPnPDeviceID, pszDevicePropertyName, default, ref sz, out _);
if (sz == 0)
return default;
using var mem = new SafeCoTaskMemHandle(sz);
manager.GetDeviceProperty(pszPnPDeviceID, pszDevicePropertyName, mem, ref sz, out var type);
return (T?)type.GetValue(mem, mem.Size);
}
/// Retrieves a list of portable devices connected to the computer.
/// The instance used to get the list of devices.
///
/// If set to , calls before retrieving the name;
/// otherwise the device names will represent those available then the instance was created.
///
///
/// An array of strings that holds the Plug and Play names of all of the connected devices. These names can be used by
/// IPortableDevice::Open to create a connection to a device.
///
public static string[] GetDevices(this IPortableDeviceManager manager, bool forceRefresh = false)
{
if (forceRefresh)
manager.RefreshDeviceList();
return PDMGetStrings(manager.GetDevices);
}
///
/// Retrieves a list of private portable devices connected to the computer. These private devices are only accessible through an
/// application that is designed for these particular devices.
///
/// The instance used to get the list of devices.
///
/// An array of strings that holds the Plug and Play names of all of the connected devices. These names can be used by
/// IPortableDevice::Open to create a connection to a device.
///
public static string[] GetPrivateDevices(this IPortableDeviceManager manager) => PDMGetStrings(manager.GetPrivateDevices);
private static string PDMGetString(PDMStrGet func, string devId)
{
var cnt = 0U;
var hr = func(devId, null, ref cnt);
if (cnt == 0)
return string.Empty;
if (hr.Failed && hr != HRESULT.HRESULT_FROM_WIN32(Win32Error.ERROR_INSUFFICIENT_BUFFER))
throw hr.GetException()!;
var sb = new StringBuilder((int)cnt + 1);
if (cnt > 0)
func(devId, sb, ref cnt).ThrowIfFailed();
return sb.ToString();
}
private static string[] PDMGetStrings(PDMStrArrGet func)
{
var cnt = 0U;
var hr = func(null, ref cnt);
if (cnt == 0)
return new string[0];
if (hr.Failed && hr != HRESULT.HRESULT_FROM_WIN32(Win32Error.ERROR_INSUFFICIENT_BUFFER))
throw hr.GetException()!;
var devices = new string[cnt];
if (cnt > 0)
func(devices, ref cnt).ThrowIfFailed();
return devices;
}
/// PortableDevice Class
[ComImport, Guid("728a21c5-3d9e-48d7-9810-864848f0f404"), ClassInterface(ClassInterfaceType.None)]
public class PortableDevice { }
/// PortableDeviceDispatchFactory Class
[ComImport, Guid("43232233-8338-4658-ae01-0b4ae830b6b0"), ClassInterface(ClassInterfaceType.None)]
public class PortableDeviceDispatchFactory { }
/// PortableDeviceFTM Class
[ComImport, Guid("f7c0039a-4762-488a-b4b3-760ef9a1ba9b"), ClassInterface(ClassInterfaceType.None)]
public class PortableDeviceFTM { }
/// PortableDeviceManager Class
[ComImport, Guid("0af10cec-2ecd-4b92-9581-34f6ae0637f3"), ClassInterface(ClassInterfaceType.None)]
public class PortableDeviceManager { }
/// PortableDeviceService Class
[ComImport, Guid("ef5db4c2-9312-422c-9152-411cd9c4dd84"), ClassInterface(ClassInterfaceType.None)]
public class PortableDeviceService { }
/// PortableDeviceServiceFTM Class
[ComImport, Guid("1649b154-c794-497a-9b03-f3f0121302f3"), ClassInterface(ClassInterfaceType.None)]
public class PortableDeviceServiceFTM { }
}