# Copyright © 2008, Microsoft Corporation. All rights reserved.
#CL_Utility
function GetProblematicFunctionForObject([string]$DDOContainerID)
{
$GetProblematicFunctionSource = @"
using System;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;
namespace Microsoft.Windows.Diagnosis
{
[StructLayout(LayoutKind.Sequential)]
public struct PropVariant
{
#region struct fields
// The layout of these elements needs to be maintained.
//
// NOTE: We could use LayoutKind.Explicit, but we want
// to maintain that the IntPtr may be 8 bytes on
// 64-bit architectures, so we'll let the CLR keep
// us aligned.
//
// NOTE: In order to allow x64 compat, we need to allow for
// expansion of the IntPtr. However, the BLOB struct
// uses a 4-byte int, followed by an IntPtr, so
// although the p field catches most pointer values,
// we need an additional 4-bytes to get the BLOB
// pointer. The p2 field provides this, as well as
// the last 4-bytes of an 8-byte value on 32-bit
// architectures.
// This is actually a VarEnum value, but the VarEnum type
// shifts the layout of the struct by 4 bytes instead of the
// expected 2.
ushort vt;
ushort wReserved1;
ushort wReserved2;
ushort wReserved3;
IntPtr p;
int p2;
#endregion // struct fields
#region union members
sbyte cVal // CHAR cVal;
{
get { return (sbyte)GetDataBytes()[0]; }
}
byte bVal // UCHAR bVal;
{
get { return GetDataBytes()[0]; }
}
short iVal // SHORT iVal;
{
get { return BitConverter.ToInt16(GetDataBytes(), 0); }
}
ushort uiVal // USHORT uiVal;
{
get { return BitConverter.ToUInt16(GetDataBytes(), 0); }
}
int lVal // LONG lVal;
{
get { return BitConverter.ToInt32(GetDataBytes(), 0); }
}
uint ulVal // ULONG ulVal;
{
get { return BitConverter.ToUInt32(GetDataBytes(), 0); }
}
long hVal // LARGE_INTEGER hVal;
{
get { return BitConverter.ToInt64(GetDataBytes(), 0); }
}
ulong uhVal // ULARGE_INTEGER uhVal;
{
get { return BitConverter.ToUInt64(GetDataBytes(), 0); }
}
float fltVal // FLOAT fltVal;
{
get { return BitConverter.ToSingle(GetDataBytes(), 0); }
}
double dblVal // DOUBLE dblVal;
{
get { return BitConverter.ToDouble(GetDataBytes(), 0); }
}
bool boolVal // VARIANT_BOOL boolVal;
{
get { return (iVal == 0 ? false : true); }
}
int scode // SCODE scode;
{
get { return lVal; }
}
decimal cyVal // CY cyVal;
{
get { return decimal.FromOACurrency(hVal); }
}
DateTime date // DATE date;
{
get { return DateTime.FromOADate(dblVal); }
}
#endregion // union members
///
/// Gets a byte array containing the data bits of the struct.
///
/// A byte array that is the combined size of the data bits.
private byte[] GetDataBytes()
{
byte[] ret = new byte[IntPtr.Size + sizeof(int)];
if (IntPtr.Size == 4)
BitConverter.GetBytes(p.ToInt32()).CopyTo(ret, 0);
else if (IntPtr.Size == 8)
BitConverter.GetBytes(p.ToInt64()).CopyTo(ret, 0);
BitConverter.GetBytes(p2).CopyTo(ret, IntPtr.Size);
return ret;
}
///
/// Called to properly clean up the memory referenced by a PropVariant instance.
///
[DllImport("ole32.dll")]
private extern static int PropVariantClear(ref PropVariant pvar);
///
/// Called to clear the PropVariant's referenced and local memory.
///
///
/// You must call Clear to avoid memory leaks.
///
public void Clear()
{
// Can't pass "this" by ref, so make a copy to call PropVariantClear with
PropVariant var = this;
PropVariantClear(ref var);
// Since we couldn't pass "this" by ref, we need to clear the member fields manually
// NOTE: PropVariantClear already freed heap data for us, so we are just setting
// our references to null.
vt = (ushort)VarEnum.VT_EMPTY;
wReserved1 = wReserved2 = wReserved3 = 0;
p = IntPtr.Zero;
p2 = 0;
}
///
/// Gets the variant type.
///
public VarEnum Type
{
get { return (VarEnum)vt; }
}
///
/// Gets the variant value.
///
public object Value
{
get
{
// TODO: Add support for reference types (ie. VT_REF | VT_I1)
// TODO: Add support for safe arrays
switch ((VarEnum)vt)
{
case VarEnum.VT_I1:
return cVal;
case VarEnum.VT_UI1:
return bVal;
case VarEnum.VT_I2:
return iVal;
case VarEnum.VT_UI2:
return uiVal;
case VarEnum.VT_I4:
case VarEnum.VT_INT:
return lVal;
case VarEnum.VT_UI4:
case VarEnum.VT_UINT:
return ulVal;
case VarEnum.VT_I8:
return hVal;
case VarEnum.VT_UI8:
return uhVal;
case VarEnum.VT_R4:
return fltVal;
case VarEnum.VT_R8:
return dblVal;
case VarEnum.VT_BOOL:
return boolVal;
case VarEnum.VT_ERROR:
return scode;
case VarEnum.VT_CY:
return cyVal;
case VarEnum.VT_DATE:
return date;
case VarEnum.VT_FILETIME:
return DateTime.FromFileTime(hVal);
case VarEnum.VT_BSTR:
return Marshal.PtrToStringBSTR(p);
case VarEnum.VT_BLOB:
byte[] blobData = new byte[lVal];
IntPtr pBlobData;
if (IntPtr.Size == 4)
{
pBlobData = new IntPtr(p2);
}
else if (IntPtr.Size == 8)
{
// In this case, we need to derive a pointer at offset 12,
// because the size of the blob is represented as a 4-byte int
// but the pointer is immediately after that.
pBlobData = new IntPtr(BitConverter.ToInt64(GetDataBytes(), sizeof(int)));
}
else
throw new NotSupportedException();
Marshal.Copy(pBlobData, blobData, 0, lVal);
return blobData;
case VarEnum.VT_LPSTR:
return Marshal.PtrToStringAnsi(p);
case VarEnum.VT_LPWSTR:
return Marshal.PtrToStringUni(p);
case VarEnum.VT_UNKNOWN:
return Marshal.GetObjectForIUnknown(p);
case VarEnum.VT_DISPATCH:
return p;
case VarEnum.VT_CLSID:
return Marshal.PtrToStructure(p, typeof(Guid));
default:
throw new NotSupportedException("The type of this variable is not support ('" + vt.ToString() + "')");
}
}
}
}
public class DDOManager
{
//
//Define const and static varialbe
//
#region
public const UInt32 S_OK = 0;
public const UInt32 CLSCTX_ALL = 23;
public const UInt32 STGM_READ = 0;
public static Guid CLSID_FunctionDiscovery = new Guid("C72BE2EC-8E90-452c-B29A-AB8FF1C071FC");
public static Guid IID_IFunctionDiscovery = new Guid("4DF99B70-E148-4432-B004-4C9EEB535A5E");
public static Guid IID_IFunctionInstanceCollection = new Guid("F0A3D895-855C-42A2-948D-2F97D450ECB1");
public static Guid SID_EnumDeviceFunction = new Guid("13E0E9E2-C3FA-4E3C-906E-64502FA4DC95");
public static Guid SID_EnumInterface = new Guid("40eab0b9-4d7f-4b53-a334-1581dd9041f4");
public static PROPERTYKEY PKEY_NAME = new PROPERTYKEY(new Guid("B725F130-47EF-101A-A5F1-02608C9EEBAC"), 10);
public static PROPERTYKEY PKEY_DeviceInterface_FriendlyName = new PROPERTYKEY(new Guid("026E516E-B814-414B-83CD-856D6FEF4822"), 2);
public static PROPERTYKEY PKEY_DeviceInterface_ClassGuid = new PROPERTYKEY(new Guid("026E516E-B814-414B-83CD-856D6FEF4822"), 4);
public static PROPERTYKEY PKEY_DeviceInterface_DevicePath = new PROPERTYKEY(new Guid("53808008-07BB-4661-BC3C-B5953E708560"), 1);
public static PROPERTYKEY PKEY_Device_InstanceId = new PROPERTYKEY(new Guid("78C34FC8-104A-4ACA-9EA4-524D52996E57"), 256);
public static PROPERTYKEY PKEY_Device_ConfigFlags = new PROPERTYKEY(new Guid("A45C254E-DF1C-4EFD-8020-67D146A850E0"), 12);
public static PROPERTYKEY PKEY_Device_ProblemCode = new PROPERTYKEY(new Guid("4340A6C5-93FA-4706-972C-7B648008A5A7"), 3);
public static PROPERTYKEY PKEY_Device_ContainerId = new PROPERTYKEY(new Guid("8c7ed206-3f8a-4827-b3ab-ae9e1faefc6c"), 2);
public static PROPERTYKEY PKEY_Device_DriverInfPath = new PROPERTYKEY(new Guid("a8b865dd-2e3d-4094-ad97-e593a70c75d6"), 5);
public static readonly Guid Guid_DeviceType_Printer = new Guid("0ECEF634-6EF0-472A-8085-5AD023ECBCCD");
public const string FCTN_CATEGORY_DEVICEDISPLAYOBJECTS = "Provider\\Microsoft.Base.DeviceDisplayObjects";
public const string FCTN_CATEGORY_PNP = "Provider\\Microsoft.Base.PnP";
#endregion
//
//Define useful enum and struct
//
#region
public enum HardDeviceType
{
PNPDevice = 0,
Printer
};
public enum SystemVisibilityFlags
{
SVF_SYSTEM = 0,
SVF_USER
};
public struct DeviceInfo
{
private string deviceName;
private HardDeviceType type;
private string deviceID;
public string DeviceName
{
get
{
return deviceName;
}
set
{
deviceName = value;
}
}
public HardDeviceType Type
{
get
{
return type;
}
set
{
type = value;
}
}
public string DeviceID
{
get
{
return deviceID;
}
set
{
deviceID = value;
}
}
};
public struct PROPERTYKEY
{
public PROPERTYKEY(Guid InputId, UInt32 InputPid)
{
fmtid = InputId;
pid = InputPid;
}
Guid fmtid;
UInt32 pid;
};
#endregion
//
//P/Invoke Win32 APIs
//
#region
[DllImport("ole32.dll", EntryPoint = "CoCreateInstance", SetLastError = true)]
public static extern UInt32 CoCreateInstance(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] object inner, uint context, ref Guid id, ref IntPtr pointer);
#endregion
//
//P/Invoke COM Interfaces
//
#region
[Guid("4DF99B70-E148-4432-B004-4C9EEB535A5E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFunctionDiscovery
{
UInt32 GetInstanceCollection([MarshalAs(UnmanagedType.LPWStr)] string pszCategory,
IntPtr pszSubCategory,
[MarshalAs(UnmanagedType.Bool)]bool fIncludeAllSubCategories,
ref IntPtr ppIFunctionInstanceCollection);
UInt32 GetInstance([MarshalAs(UnmanagedType.LPWStr)] ref string pszFunctionInstanceIdentity,
ref IntPtr ppIFunctionInstance);
UInt32 CreateInstanceCollectionQuery([MarshalAs(UnmanagedType.LPWStr)] string pszCategory,
[MarshalAs(UnmanagedType.LPWStr)] string pszSubCategory,
[MarshalAs(UnmanagedType.Bool)] bool fIncludeAllSubCategories,
IntPtr pIFunctionDiscoveryNotification,
IntPtr pfdqcQueryContext,
ref IntPtr ppIFunctionInstanceCollectionQuery);
UInt32 CreateInstanceQuery([MarshalAs(UnmanagedType.LPWStr)] string pszFunctionInstanceIdentity,
IntPtr pIFunctionDiscoveryNotification,
IntPtr pfdqcQueryContext,
ref IntPtr ppIFunctionInstanceQuery);
UInt32 AddInstance(SystemVisibilityFlags enumSystemVisibility,
[MarshalAs(UnmanagedType.LPWStr)] string pszCategory,
[MarshalAs(UnmanagedType.LPWStr)] string pszSubCategory,
[MarshalAs(UnmanagedType.LPWStr)] string pszCategoryIdentity,
ref IntPtr ppIFunctionInstance);
UInt32 RemoveInstance(SystemVisibilityFlags enumSystemVisibility,
[MarshalAs(UnmanagedType.LPWStr)] string pszCategory,
[MarshalAs(UnmanagedType.LPWStr)] string pszSubCategory,
[MarshalAs(UnmanagedType.LPWStr)] string pszCategoryIdentity);
}
[Guid("F0A3D895-855C-42A2-948D-2F97D450ECB1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFunctionInstanceCollection
{
UInt32 GetCount(ref UInt32 pdwCount);
UInt32 Get([MarshalAs(UnmanagedType.LPWStr)] string pszInstanceIdentity,
ref UInt32 pdwIndex,
ref IntPtr ppIFunctionInstance);
UInt32 Item(UInt32 dwIndex, ref IntPtr ppIFunctionInstance);
UInt32 Add(IntPtr pIFunctionInstance);
UInt32 Remove(UInt32 dwIndex, ref IntPtr ppIFunctionInstance);
UInt32 Delete(UInt32 dwIndex);
UInt32 DeleteAll();
}
[Guid("6D5140C1-7436-11CE-8034-00AA006009FA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IServiceProvider
{
UInt32 QueryService(ref Guid guidService, ref Guid riid, ref IntPtr ppvObject);
UInt32 QueryService(ref Guid guidService, ref IntPtr pp);
}
[Guid("33591C10-0BED-4F02-B0AB-1530D5533EE9"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IFunctionInstance
{
UInt32 QueryService(ref Guid guidService, ref Guid riid, ref IntPtr ppvObject);
UInt32 GetID([MarshalAs(UnmanagedType.LPWStr)] ref string ppszCoMemIdentity);
UInt32 GetProviderInstanceID([MarshalAs(UnmanagedType.LPWStr)] ref string ppszCoMemProviderInstanceIdentity);
UInt32 OpenPropertyStore(UInt32 dwStgAccess, ref IntPtr ppIPropertyStore);
UInt32 GetCategory([MarshalAs(UnmanagedType.LPWStr)] ref string ppszCoMemCategory, [MarshalAs(UnmanagedType.LPWStr)] ref string ppszCoMemSubCategory);
}
[Guid("886d8eeb-8cf2-4446-8d02-cdba1dbdcf99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPropertyStore
{
UInt32 GetCount(ref UInt32 cProps);
UInt32 GetAt(UInt32 iProp, ref PROPERTYKEY pkey);
UInt32 GetValue(ref PROPERTYKEY key, ref PropVariant pv);
UInt32 SetValue(ref PROPERTYKEY key, ref PropVariant propvar);
UInt32 Commit();
};
#endregion
public static bool IsPrinterDevice(IFunctionInstance DeviceDisplayObject, ref DeviceInfo printerInfo)
{
bool isPrinter = false;
Guid devicTypeID = Guid.Empty;
UInt32 serviceCount = 0;
UInt32 deviceFunctionCount = 0;
IntPtr deviceFICollectionPtr = IntPtr.Zero;
IntPtr serviceFICollectionPtr = IntPtr.Zero;
IntPtr deviceFunctionInstancePtr = IntPtr.Zero;
IntPtr serviceFunctionInstancePtr = IntPtr.Zero;
IntPtr propertyStorePtr = IntPtr.Zero;
IFunctionInstanceCollection deviceFICollection = null;
IFunctionInstanceCollection serviceFICollection = null;
IFunctionInstance deviceFunctionInstance = null;
IFunctionInstance serviceFunctionInstance = null;
IPropertyStore propertyStore = null;
PropVariant variantData = new PropVariant();
//
//Enumerate device function instances
//
DeviceDisplayObject.QueryService(ref SID_EnumDeviceFunction, ref IID_IFunctionInstanceCollection, ref deviceFICollectionPtr);
deviceFICollection = (IFunctionInstanceCollection)Marshal.GetObjectForIUnknown(deviceFICollectionPtr);
deviceFICollection.GetCount(ref deviceFunctionCount);
for (UInt32 i = 0; i < deviceFunctionCount; i++)
{
deviceFICollection.Item(i, ref deviceFunctionInstancePtr);
if (IntPtr.Zero != deviceFunctionInstancePtr)
{
deviceFunctionInstance = (IFunctionInstance)Marshal.GetObjectForIUnknown(deviceFunctionInstancePtr);
//
//Enumerate service for a device function instance
//
deviceFunctionInstance.QueryService(ref SID_EnumInterface, ref IID_IFunctionInstanceCollection, ref serviceFICollectionPtr);
if (IntPtr.Zero != serviceFICollectionPtr)
{
serviceFICollection = (IFunctionInstanceCollection)Marshal.GetObjectForIUnknown(serviceFICollectionPtr);
serviceFICollection.GetCount(ref serviceCount);
for (UInt32 j = 0; j < serviceCount; j++)
{
serviceFICollection.Item(j, ref serviceFunctionInstancePtr);
if (IntPtr.Zero != serviceFunctionInstancePtr)
{
serviceFunctionInstance = (IFunctionInstance)Marshal.GetObjectForIUnknown(serviceFunctionInstancePtr);
serviceFunctionInstance.OpenPropertyStore(STGM_READ, ref propertyStorePtr);
if (IntPtr.Zero != propertyStorePtr)
{
propertyStore = (IPropertyStore)Marshal.GetObjectForIUnknown(propertyStorePtr);
propertyStore.GetValue(ref PKEY_DeviceInterface_ClassGuid, ref variantData);
if (VarEnum.VT_CLSID != variantData.Type)
{
variantData.Clear();
Marshal.Release(propertyStorePtr);
continue;
}
devicTypeID = (Guid)variantData.Value;
variantData.Clear();
if (devicTypeID.Equals(Guid_DeviceType_Printer))
{
isPrinter = true;
propertyStore.GetValue(ref PKEY_DeviceInterface_DevicePath, ref variantData);
printerInfo.DeviceName = variantData.Value.ToString();
printerInfo.Type = HardDeviceType.Printer;
variantData.Clear();
Marshal.Release(propertyStorePtr);
break;
}
Marshal.Release(propertyStorePtr);
}
Marshal.Release(serviceFunctionInstancePtr);
}
}
Marshal.Release(serviceFICollectionPtr);
}
Marshal.Release(deviceFunctionInstancePtr);
}
}
if (IntPtr.Zero != deviceFICollectionPtr)
{
Marshal.Release(deviceFICollectionPtr);
}
return isPrinter;
}
public static ArrayList GetDeviceInfo(IFunctionInstance deviceDisplayObject)
{
ArrayList deviceInfoAry = new ArrayList();
DeviceInfo deviceDataInfo = new DeviceInfo();
if (IsPrinterDevice(deviceDisplayObject, ref deviceDataInfo))
{
deviceInfoAry.Add(deviceDataInfo);
}
else
{
deviceInfoAry = GetPnPDeviceInfo(deviceDisplayObject);
}
return deviceInfoAry;
}
public static ArrayList GetPnPDeviceInfo(IFunctionInstance DeviceDisplayObject)
{
ArrayList DeviceInfoArray = new ArrayList();
UInt32 ResultCode = 0;
UInt32 FunctionCount = 0;
DeviceInfo ResultDeviceInfo = new DeviceInfo();
IntPtr FICollectionPtr = IntPtr.Zero;
IntPtr FunctionInstancePtr = IntPtr.Zero;
IntPtr PropertyStorePtr = IntPtr.Zero;
IFunctionInstanceCollection FICollection = null;
IFunctionInstance FunctionInstance = null;
IPropertyStore PropertyStore = null;
PropVariant VariantData = new PropVariant();
bool NoDriver = false;
string Category = null;
string SubCategory = null;
//
//Enumerate device function instance for DDO
//
DeviceDisplayObject.QueryService(ref SID_EnumDeviceFunction, ref IID_IFunctionInstanceCollection, ref FICollectionPtr);
if (IntPtr.Zero != FICollectionPtr)
{
FICollection = (IFunctionInstanceCollection)Marshal.GetObjectForIUnknown(FICollectionPtr);
ResultCode = FICollection.GetCount(ref FunctionCount);
for (UInt32 i = 0; i < FunctionCount; i++)
{
ResultCode = FICollection.Item(i, ref FunctionInstancePtr);
if (IntPtr.Zero != FunctionInstancePtr)
{
FunctionInstance = (IFunctionInstance)Marshal.GetObjectForIUnknown(FunctionInstancePtr);
ResultCode = FunctionInstance.GetCategory(ref Category, ref SubCategory);
if (Category != null && Category.Equals(FCTN_CATEGORY_PNP))
{
ResultCode = FunctionInstance.OpenPropertyStore(STGM_READ, ref PropertyStorePtr);
if (IntPtr.Zero != PropertyStorePtr)
{
PropertyStore = (IPropertyStore)Marshal.GetObjectForIUnknown(PropertyStorePtr);
ResultCode = PropertyStore.GetValue(ref PKEY_NAME, ref VariantData);
if (VarEnum.VT_EMPTY != VariantData.Type)
{
ResultDeviceInfo.DeviceName = VariantData.Value.ToString();
VariantData.Clear();
}
else
{
ResultDeviceInfo.DeviceName = string.Empty;
}
ResultDeviceInfo.Type = HardDeviceType.PNPDevice;
ResultCode = PropertyStore.GetValue(ref PKEY_Device_ProblemCode, ref VariantData);
if (VariantData.Type == VarEnum.VT_UI4)
{
int ConfigManagerErrorCode = Convert.ToInt32(VariantData.Value);
VariantData.Clear();
ResultCode = PropertyStore.GetValue(ref PKEY_Device_DriverInfPath, ref VariantData);
NoDriver = (VariantData.Type == VarEnum.VT_EMPTY);
VariantData.Clear();
if (0 != ConfigManagerErrorCode || NoDriver)
{
ResultCode = PropertyStore.GetValue(ref PKEY_Device_InstanceId, ref VariantData);
ResultDeviceInfo.DeviceID = VariantData.Value.ToString();
VariantData.Clear();
DeviceInfoArray.Add(ResultDeviceInfo);
}
}
Marshal.Release(PropertyStorePtr);
}
}
Marshal.Release(FunctionInstancePtr);
}
}
Marshal.Release(FICollectionPtr);
}
return DeviceInfoArray;
}
public static ArrayList DiagnosticDeviceDisplayObject(Guid TargetContainerID)
{
ArrayList ProblemDeviceInfo = null;
UInt32 ResultCode = 0;
UInt32 InstanceCount = 0;
IntPtr FunctionDiscoveryPtr = IntPtr.Zero;
IntPtr FICollectionPtr = IntPtr.Zero;
IntPtr FunctionInstancePtr = IntPtr.Zero;
IntPtr PropertyStorePtr = IntPtr.Zero;
IFunctionDiscovery FunctionDiscovery = null;
IFunctionInstanceCollection FICollection = null;
IFunctionInstance FunctionInstance = null;
IPropertyStore PropertyStore = null;
PropVariant VariantData = new PropVariant();
ResultCode = CoCreateInstance(ref CLSID_FunctionDiscovery, null, CLSCTX_ALL, ref IID_IFunctionDiscovery, ref FunctionDiscoveryPtr);
if (IntPtr.Zero != FunctionDiscoveryPtr)
{
FunctionDiscovery = (IFunctionDiscovery)Marshal.GetObjectForIUnknown(FunctionDiscoveryPtr);
ResultCode = FunctionDiscovery.GetInstanceCollection(FCTN_CATEGORY_DEVICEDISPLAYOBJECTS, IntPtr.Zero, false, ref FICollectionPtr);
if (IntPtr.Zero != FICollectionPtr)
{
FICollection = (IFunctionInstanceCollection)Marshal.GetObjectForIUnknown(FICollectionPtr);
ResultCode = FICollection.GetCount(ref InstanceCount);
for (UInt32 i = 0; i < InstanceCount; i++)
{
ResultCode = FICollection.Item(i, ref FunctionInstancePtr);
if (IntPtr.Zero != FunctionInstancePtr)
{
FunctionInstance = (IFunctionInstance)Marshal.GetObjectForIUnknown(FunctionInstancePtr);
ResultCode = FunctionInstance.OpenPropertyStore(STGM_READ, ref PropertyStorePtr);
if (IntPtr.Zero != PropertyStorePtr)
{
PropertyStore = (IPropertyStore)Marshal.GetObjectForIUnknown(PropertyStorePtr);
ResultCode = PropertyStore.GetValue(ref PKEY_NAME, ref VariantData);
string DeviceObjectName = VariantData.Value.ToString();
VariantData.Clear();
ResultCode = PropertyStore.GetValue(ref PKEY_Device_ContainerId, ref VariantData);
Guid ContainerID = (Guid)VariantData.Value;
VariantData.Clear();
if (TargetContainerID.Equals(ContainerID))
{
ProblemDeviceInfo = GetDeviceInfo(FunctionInstance);
Marshal.Release(FunctionInstancePtr);
Marshal.Release(PropertyStorePtr);
break;
}
Marshal.Release(PropertyStorePtr);
}
Marshal.Release(FunctionInstancePtr);
}
}
Marshal.Release(FICollectionPtr);
}
Marshal.Release(FunctionDiscoveryPtr);
}
return ProblemDeviceInfo;
}
}
}
"@
Add-Type -TypeDefinition $GetProblematicFunctionSource
$DDOManagerObject = [Microsoft.Windows.Diagnosis.DDOManager]
[Guid]$guidContainer = new-object -TypeName System.Guid($DDOContainerID)
$DeviceIDArray = $DDOManagerObject::DiagnosticDeviceDisplayObject($guidContainer)
return $DeviceIDArray
}