@@ -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-
10297exit :
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+
17171760exit :
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 );
0 commit comments