UsbDk: USB devices lists synchronization logic
This patch introduces logic for synchronization of our USB devices list with DEVICE_RELATIONS structure received on QDR. Signed-off-by: Dmitry Fleytman <dfleytma@redhat.com>
This commit is contained in:
parent
ed5be722ea
commit
17a328fb71
2 changed files with 57 additions and 1 deletions
|
|
@ -170,6 +170,51 @@ void CDeviceRelations::PushBack(PDEVICE_OBJECT Relation)
|
|||
m_Relations->Objects[m_PushPosition++] = Relation;
|
||||
}
|
||||
|
||||
void CUsbDkFilterDevice::DropRemovedDevices(const CDeviceRelations &Relations)
|
||||
{
|
||||
m_ChildrenDevices.ForEachDetachedIf([&Relations](CUsbDkChildDevice *Child) { return !Relations.Contains(*Child); },
|
||||
[](CUsbDkChildDevice *Child) -> bool { delete Child; return true; });
|
||||
}
|
||||
|
||||
void CUsbDkFilterDevice::AddNewDevices(const CDeviceRelations &Relations)
|
||||
{
|
||||
Relations.ForEachIf([this](PDEVICE_OBJECT PDO){ return !IsChildRegistered(PDO); },
|
||||
[this](PDEVICE_OBJECT PDO){ RegisterNewChild(PDO); return true; });
|
||||
}
|
||||
|
||||
void CUsbDkFilterDevice::RegisterNewChild(PDEVICE_OBJECT PDO)
|
||||
{
|
||||
CWdmDeviceAccess pdoAccess(PDO);
|
||||
CObjHolder<CRegText> DevID(pdoAccess.GetDeviceID());
|
||||
|
||||
if (!DevID || DevID->empty())
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! No Device IDs read");
|
||||
return;
|
||||
}
|
||||
|
||||
CObjHolder<CRegText> InstanceID(pdoAccess.GetInstanceID());
|
||||
|
||||
if (!InstanceID || InstanceID->empty())
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! No Instance ID read");
|
||||
return;
|
||||
}
|
||||
|
||||
CUsbDkChildDevice *Device = new CUsbDkChildDevice(DevID, InstanceID, PDO);
|
||||
|
||||
if (Device == nullptr)
|
||||
{
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FILTERDEVICE, "%!FUNC! Cannot allocate child device instance");
|
||||
return;
|
||||
}
|
||||
|
||||
DevID.detach();
|
||||
InstanceID.detach();
|
||||
|
||||
m_ChildrenDevices.PushBack(Device);
|
||||
}
|
||||
|
||||
void CUsbDkFilterDevice::ClearChildrenList()
|
||||
{
|
||||
m_ChildrenDevices.ForEachDetached([](CUsbDkChildDevice* Child) { delete Child; return true; });
|
||||
|
|
|
|||
|
|
@ -34,9 +34,12 @@ public:
|
|||
PCWCHAR InstanceID() const { return *m_InstanceID->begin(); }
|
||||
PDEVICE_OBJECT PDO() const { ObReferenceObject(m_PDO); return m_PDO; }
|
||||
|
||||
bool Match(PCWCHAR deviceID, PCWCHAR instanceID)
|
||||
bool Match(PCWCHAR deviceID, PCWCHAR instanceID) const
|
||||
{ return m_DeviceID->Match(deviceID) && m_InstanceID->Match(instanceID); }
|
||||
|
||||
bool Match(PDEVICE_OBJECT PDO) const
|
||||
{ return m_PDO == PDO; }
|
||||
|
||||
void Dump();
|
||||
|
||||
PLIST_ENTRY GetListEntry()
|
||||
|
|
@ -55,6 +58,8 @@ private:
|
|||
CUsbDkChildDevice& operator= (const CUsbDkChildDevice&) = delete;
|
||||
};
|
||||
|
||||
class CDeviceRelations;
|
||||
|
||||
class CUsbDkFilterDevice : private CWdfDevice, public CAllocatable<NonPagedPool, 'DFHR'>
|
||||
{
|
||||
public:
|
||||
|
|
@ -101,6 +106,12 @@ private:
|
|||
bool ShouldAttach();
|
||||
void ClearChildrenList();
|
||||
|
||||
void DropRemovedDevices(const CDeviceRelations &Relations);
|
||||
void AddNewDevices(const CDeviceRelations &Relations);
|
||||
bool IsChildRegistered(PDEVICE_OBJECT PDO)
|
||||
{ return !m_ChildrenDevices.ForEachIf([PDO](CUsbDkChildDevice *Child){ return Child->Match(PDO); }, ConstFalse); }
|
||||
void RegisterNewChild(PDEVICE_OBJECT PDO);
|
||||
|
||||
CWdfWorkitem m_QDRCompletionWorkItem;
|
||||
|
||||
PIRP m_QDRIrp = nullptr;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue