Skip to content

Commit 280c89a

Browse files
authored
wdfserial: fix diag port re-enumeration by clearing DeviceRemoveEvent, incrementing QCDeviceGeneration, and refreshing ReportDeviceName on D0Entry (#103)
1 parent c1ffc79 commit 280c89a

3 files changed

Lines changed: 65 additions & 5 deletions

File tree

src/windows/wdfserial/QCMAIN.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(REQUEST_CONTEXT, QCReqGetContext)
401401
// Registry Value Names
402402
#define VEN_DEV_PORT L"AssignedPortForQCDevice"
403403
#define VEN_DEV_TIME L"QCDeviceStamp"
404+
#define VEN_DEV_GENERATION L"QCDeviceGeneration"
404405
#define VEN_DEV_SERNUM L"QCDeviceSerialNumber"
405406
#define VEN_DEV_MSM_SERNUM L"QCDeviceMsmSerialNumber"
406407
#define VEN_DEV_PROTOC L"QCDeviceProtocol"

src/windows/wdfserial/QCPNP.c

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,6 @@ NTSTATUS QCPNP_EvtDeviceAdd
9494
goto exit;
9595
}
9696

97-
if (pDevContext->FdoDeviceType == FILE_DEVICE_SERIAL_PORT)
98-
{
99-
QCPNP_ReportDeviceName(pDevContext);
100-
}
101-
10297
exit:
10398
if (!NT_SUCCESS(status))
10499
{
@@ -267,6 +262,50 @@ NTSTATUS QCPNP_SetStamp
267262
return STATUS_SUCCESS;
268263
}
269264

265+
/****************************************************************************
266+
*
267+
* function: QCPNP_IncrementGeneration
268+
*
269+
* purpose: Increments QCDeviceGeneration DWORD in the driver registry key
270+
* on every PrepareHardware so QDS can detect a re-enumeration even
271+
* when DevDesc/DevName/SerNum are identical across reboots.
272+
*
273+
* arguments:pDevContext = pointer to the device context.
274+
*
275+
* returns: NT Status
276+
*
277+
****************************************************************************/
278+
NTSTATUS QCPNP_IncrementGeneration(PDEVICE_CONTEXT pDevContext)
279+
{
280+
NTSTATUS status = STATUS_SUCCESS;
281+
WDFDEVICE device = pDevContext->Device;
282+
WDFKEY key;
283+
ULONG genValue = 0;
284+
DECLARE_CONST_UNICODE_STRING(valueName, VEN_DEV_GENERATION);
285+
286+
status = WdfDeviceOpenRegistryKey(device, PLUGPLAY_REGKEY_DRIVER,
287+
KEY_QUERY_VALUE | KEY_SET_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &key);
288+
if (!NT_SUCCESS(status))
289+
{
290+
return status;
291+
}
292+
293+
WdfRegistryQueryValue(key, &valueName, REG_DWORD, &genValue, sizeof(genValue), NULL);
294+
WdfRegistryClose(key);
295+
296+
genValue++;
297+
status = QCMAIN_SetDriverRegistryDword((LPWSTR)valueName.Buffer, genValue, pDevContext);
298+
299+
QCSER_DbgPrint
300+
(
301+
QCSER_DBG_MASK_CONTROL,
302+
QCSER_DBG_LEVEL_DETAIL,
303+
("<%ws> QCPNP_IncrementGeneration new generation: %lu, status: 0x%x\n",
304+
pDevContext->PortName, genValue, status)
305+
);
306+
return status;
307+
}
308+
270309
/****************************************************************************
271310
*
272311
* function: QCPNP_DeviceCreate
@@ -1714,6 +1753,10 @@ NTSTATUS QCPNP_EvtDevicePrepareHardware
17141753
status = QCPNP_RegisterWmiPowerGuid(pDevContext);
17151754
}
17161755

1756+
// Increment QCDeviceGeneration so QDS can detect a re-enumeration even
1757+
// when the device identity (DevDesc/DevName/SerNum) is unchanged.
1758+
QCPNP_IncrementGeneration(pDevContext);
1759+
17171760
exit:
17181761
if (!NT_SUCCESS(status))
17191762
{
@@ -2234,6 +2277,14 @@ NTSTATUS QCPNP_EvtDeviceD0Entry
22342277
QCSER_DBG_LEVEL_TRACE,
22352278
("<%ws> QCPNP_EvtDeviceD0Entry Completed!\n", pDevContext->PortName)
22362279
);
2280+
2281+
// Re-announce diag device name to parent/filter on every D0 entry.
2282+
// EvtDeviceAdd fires only once; D0Entry fires on each re-enumeration.
2283+
if (pDevContext->FdoDeviceType == FILE_DEVICE_SERIAL_PORT)
2284+
{
2285+
QCPNP_ReportDeviceName(pDevContext);
2286+
}
2287+
22372288
return STATUS_SUCCESS;
22382289
}
22392290

@@ -3280,6 +3331,9 @@ NTSTATUS QCPNP_SetupIoThreadsAndQueues
32803331
LARGE_INTEGER threadInitTimeout;
32813332
threadInitTimeout.QuadPart = WDF_REL_TIMEOUT_IN_MS(QCPNP_THREAD_INIT_TIMEOUT_MS);
32823333

3334+
// Clear stale removal signal in case we're re-entering after a removal cycle
3335+
KeClearEvent(&pDevContext->DeviceRemoveEvent);
3336+
32833337
// Init write request list, lock and events
32843338
InitializeListHead(&pDevContext->WriteRequestPendingList);
32853339
WdfSpinLockCreate(WDF_NO_OBJECT_ATTRIBUTES, &pDevContext->WriteRequestPendingListLock);

src/windows/wdfserial/QCPNP.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,9 @@ NTSTATUS QCPNP_SetStamp
184184
PDEVICE_CONTEXT pDevContext,
185185
BOOLEAN Startup
186186
);
187+
188+
NTSTATUS QCPNP_IncrementGeneration
189+
(
190+
PDEVICE_CONTEXT pDevContext
191+
);
187192
#endif // QCPNP_H

0 commit comments

Comments
 (0)