![]() |
![]() |
|
|||||||
| Register | Forum Rules | Getting Started! - Guide | Blog | Videos | Gallery | Members List | Social Groups | Mark Forums Read |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Guest
Posts: n/a
|
a question in MS sample code about PoRequestPowerIrp
HI All I have a question about MS sample code BulkUsb. In the follow piece of code, it seems the "irpContext" be ExFreePool two times in certain situation. Please See my Comments. It 's helpful for me if you can correct me. thanks thanks VOID IdleNotificationCallback( IN PDEVICE_EXTENSION DeviceExtension ) /*++ Routine Description: "A pointer to a callback function in your driver is passed down the stack with this IOCTL, and it is this callback function that is called by USBHUB when it safe for your device to power down." "When the callback in your driver is called, all you really need to do is to to first ensure that a WaitWake Irp has been submitted for your device, if remote wake is possible for your device and then request a SetD2 (or DeviceWake)" Arguments: DeviceExtension - pointer to device extension Return Value: NT status value --*/ { NTSTATUS ntStatus; POWER_STATE powerState; KEVENT irpCompletionEvent; PIRP_COMPLETION_CONTEXT irpContext; BulkUsb_DbgPrint(3, ("IdleNotificationCallback - begins\n")); // // Dont idle, if the device was just disconnected or being stopped // i.e. return for the following DeviceState(s) // NotStarted, Stopped, PendingStop, PendingRemove, SurpriseRemoved, Removed // if(DeviceExtension->DeviceState != Working) { return; } // // If there is not already a WW IRP pending, submit one now // if(DeviceExtension->WaitWakeEnable) { IssueWaitWake(DeviceExtension); } // // power down the device // irpContext = (PIRP_COMPLETION_CONTEXT) ExAllocatePool(NonPagedPool, sizeof(IRP_COMPLETION_CONTEXT)); if(!irpContext) { BulkUsb_DbgPrint(1, ("Failed to alloc memory for irpContext\n")); ntStatus = STATUS_INSUFFICIENT_RESOURCES; } else { // // increment the count. In the HoldIoRequestWorkerRoutine, the // count is decremented twice (one for the system Irp and the // other for the device Irp. An increment here compensates for // the sytem irp..The decrement corresponding to this increment // is in the completion function // BulkUsb_DbgPrint(3, ("IdleNotificationCallback::")); BulkUsb_IoIncrement(DeviceExtension); powerState.DeviceState = DeviceExtension->PowerDownLevel; KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE); irpContext->DeviceExtension = DeviceExtension; irpContext->Event = &irpCompletionEvent; ntStatus = PoRequestPowerIrp( DeviceExtension->PhysicalDeviceObject, IRP_MN_SET_POWER, powerState, (PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc, irpContext, NULL); if(STATUS_PENDING == ntStatus) { BulkUsb_DbgPrint(3, ("IdleNotificationCallback::" "waiting for the power irp to complete\n")); KeWaitForSingleObject(&irpCompletionEvent, Executive, KernelMode, FALSE, NULL); } } ////////// My Comment ////if ntStatus is a Error code from "PoRequestPowerIrp" ,then ////ExFreePool(irpContext) will be called by one time. //// if(!NT_SUCCESS(ntStatus)) { if(irpContext) { ExFreePool(irpContext); } } BulkUsb_DbgPrint(3, ("IdleNotificationCallback - ends\n")); } VOID PoIrpCompletionFunc( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, IN PVOID Context, IN PIO_STATUS_BLOCK IoStatus ) /*++ Routine Description: Completion routine for power irp PoRequested in IdleNotificationCallback. Arguments: DeviceObject - pointer to device object MinorFunciton - minor function for the irp. PowerState - irp power state Context - context passed to the completion function IoStatus - status block. Return Value: None --*/ { PIRP_COMPLETION_CONTEXT irpContext; UNREFERENCED_PARAMETER( DeviceObject ); UNREFERENCED_PARAMETER( MinorFunction ); UNREFERENCED_PARAMETER( PowerState ); UNREFERENCED_PARAMETER( IoStatus ); // // initialize variables // irpContext = NULL; if(Context) { irpContext = (PIRP_COMPLETION_CONTEXT) Context; } // // all we do is set the event and decrement the count // ///////////My Comments ///// This completeFunction will Free the irpContext the Second time. ///// ????????. is It correct ????? if(irpContext) { KeSetEvent(irpContext->Event, 0, FALSE); BulkUsb_DbgPrint(3, ("PoIrpCompletionFunc::")); BulkUsb_IoDecrement(irpContext->DeviceExtension); ExFreePool(irpContext); } return; } |
|
|
|
#2 |
|
Guest
Posts: n/a
|
Re: a question in MS sample code about PoRequestPowerIrp
you should not use bulkusb as a template for your driver, you should start
with a KMDF sample in the wdk (like src\kmdf\USBSAMP) d -- Please do not send e-mail directly to this alias. this alias is for newsgroup purposes only. This posting is provided "AS IS" with no warranties, and confers no rights. "rech" <rech@discussions.microsoft.com> wrote in message news 1F37E4A-652E-4451-B14F-620D819AA7E1@microsoft.com...> > HI All > I have a question about MS sample code BulkUsb. > In the follow piece of code, it seems the "irpContext" be ExFreePool two > times in certain situation. > Please See my Comments. > > It 's helpful for me if you can correct me. > > thanks > thanks > > > > > VOID > IdleNotificationCallback( > IN PDEVICE_EXTENSION DeviceExtension > ) > /*++ > > Routine Description: > > "A pointer to a callback function in your driver is passed down the stack > with > this IOCTL, and it is this callback function that is called by USBHUB > when it > safe for your device to power down." > > "When the callback in your driver is called, all you really need to do is > to > to first ensure that a WaitWake Irp has been submitted for your device, > if > remote wake is possible for your device and then request a SetD2 (or > DeviceWake)" > > Arguments: > > DeviceExtension - pointer to device extension > > Return Value: > > NT status value > > --*/ > { > NTSTATUS ntStatus; > POWER_STATE powerState; > KEVENT irpCompletionEvent; > PIRP_COMPLETION_CONTEXT irpContext; > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback - begins\n")); > > // > // Dont idle, if the device was just disconnected or being stopped > // i.e. return for the following DeviceState(s) > // NotStarted, Stopped, PendingStop, PendingRemove, SurpriseRemoved, > Removed > // > > if(DeviceExtension->DeviceState != Working) { > > return; > } > > // > // If there is not already a WW IRP pending, submit one now > // > if(DeviceExtension->WaitWakeEnable) { > > IssueWaitWake(DeviceExtension); > } > > > // > // power down the device > // > > irpContext = (PIRP_COMPLETION_CONTEXT) > ExAllocatePool(NonPagedPool, > sizeof(IRP_COMPLETION_CONTEXT)); > > if(!irpContext) { > > BulkUsb_DbgPrint(1, ("Failed to alloc memory for irpContext\n")); > ntStatus = STATUS_INSUFFICIENT_RESOURCES; > } > else { > > // > // increment the count. In the HoldIoRequestWorkerRoutine, the > // count is decremented twice (one for the system Irp and the > // other for the device Irp. An increment here compensates for > // the sytem irp..The decrement corresponding to this increment > // is in the completion function > // > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback::")); > BulkUsb_IoIncrement(DeviceExtension); > > powerState.DeviceState = DeviceExtension->PowerDownLevel; > > KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE); > > irpContext->DeviceExtension = DeviceExtension; > irpContext->Event = &irpCompletionEvent; > > ntStatus = PoRequestPowerIrp( > DeviceExtension->PhysicalDeviceObject, > IRP_MN_SET_POWER, > powerState, > (PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc, > irpContext, > NULL); > > if(STATUS_PENDING == ntStatus) { > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback::" > "waiting for the power irp to complete\n")); > > KeWaitForSingleObject(&irpCompletionEvent, > Executive, > KernelMode, > FALSE, > NULL); > } > } > ////////// My Comment > ////if ntStatus is a Error code from "PoRequestPowerIrp" ,then > ////ExFreePool(irpContext) will be called by one time. > //// > if(!NT_SUCCESS(ntStatus)) { > > if(irpContext) { > > ExFreePool(irpContext); > } > } > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback - ends\n")); > } > > > VOID > PoIrpCompletionFunc( > IN PDEVICE_OBJECT DeviceObject, > IN UCHAR MinorFunction, > IN POWER_STATE PowerState, > IN PVOID Context, > IN PIO_STATUS_BLOCK IoStatus > ) > /*++ > > Routine Description: > > Completion routine for power irp PoRequested in > IdleNotificationCallback. > > Arguments: > > DeviceObject - pointer to device object > MinorFunciton - minor function for the irp. > PowerState - irp power state > Context - context passed to the completion function > IoStatus - status block. > > Return Value: > > None > > --*/ > { > PIRP_COMPLETION_CONTEXT irpContext; > > UNREFERENCED_PARAMETER( DeviceObject ); > UNREFERENCED_PARAMETER( MinorFunction ); > UNREFERENCED_PARAMETER( PowerState ); > UNREFERENCED_PARAMETER( IoStatus ); > > // > // initialize variables > // > irpContext = NULL; > > if(Context) { > > irpContext = (PIRP_COMPLETION_CONTEXT) Context; > } > > // > // all we do is set the event and decrement the count > // > ///////////My Comments > ///// This completeFunction will Free the irpContext the Second time. > ///// ????????. is It correct ????? > if(irpContext) { > > KeSetEvent(irpContext->Event, 0, FALSE); > > BulkUsb_DbgPrint(3, ("PoIrpCompletionFunc::")); > BulkUsb_IoDecrement(irpContext->DeviceExtension); > > ExFreePool(irpContext); > > } > > return; > } |
|
|
|
#3 |
|
Guest
Posts: n/a
|
Re: a question in MS sample code about PoRequestPowerIrp
and no, it is not freed twice. if PoRequestPowerIrp returns !NT_SUCCESS,
the po completion routine will not run. d -- Please do not send e-mail directly to this alias. this alias is for newsgroup purposes only. This posting is provided "AS IS" with no warranties, and confers no rights. "rech" <rech@discussions.microsoft.com> wrote in message news 1F37E4A-652E-4451-B14F-620D819AA7E1@microsoft.com...> > HI All > I have a question about MS sample code BulkUsb. > In the follow piece of code, it seems the "irpContext" be ExFreePool two > times in certain situation. > Please See my Comments. > > It 's helpful for me if you can correct me. > > thanks > thanks > > > > > VOID > IdleNotificationCallback( > IN PDEVICE_EXTENSION DeviceExtension > ) > /*++ > > Routine Description: > > "A pointer to a callback function in your driver is passed down the stack > with > this IOCTL, and it is this callback function that is called by USBHUB > when it > safe for your device to power down." > > "When the callback in your driver is called, all you really need to do is > to > to first ensure that a WaitWake Irp has been submitted for your device, > if > remote wake is possible for your device and then request a SetD2 (or > DeviceWake)" > > Arguments: > > DeviceExtension - pointer to device extension > > Return Value: > > NT status value > > --*/ > { > NTSTATUS ntStatus; > POWER_STATE powerState; > KEVENT irpCompletionEvent; > PIRP_COMPLETION_CONTEXT irpContext; > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback - begins\n")); > > // > // Dont idle, if the device was just disconnected or being stopped > // i.e. return for the following DeviceState(s) > // NotStarted, Stopped, PendingStop, PendingRemove, SurpriseRemoved, > Removed > // > > if(DeviceExtension->DeviceState != Working) { > > return; > } > > // > // If there is not already a WW IRP pending, submit one now > // > if(DeviceExtension->WaitWakeEnable) { > > IssueWaitWake(DeviceExtension); > } > > > // > // power down the device > // > > irpContext = (PIRP_COMPLETION_CONTEXT) > ExAllocatePool(NonPagedPool, > sizeof(IRP_COMPLETION_CONTEXT)); > > if(!irpContext) { > > BulkUsb_DbgPrint(1, ("Failed to alloc memory for irpContext\n")); > ntStatus = STATUS_INSUFFICIENT_RESOURCES; > } > else { > > // > // increment the count. In the HoldIoRequestWorkerRoutine, the > // count is decremented twice (one for the system Irp and the > // other for the device Irp. An increment here compensates for > // the sytem irp..The decrement corresponding to this increment > // is in the completion function > // > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback::")); > BulkUsb_IoIncrement(DeviceExtension); > > powerState.DeviceState = DeviceExtension->PowerDownLevel; > > KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE); > > irpContext->DeviceExtension = DeviceExtension; > irpContext->Event = &irpCompletionEvent; > > ntStatus = PoRequestPowerIrp( > DeviceExtension->PhysicalDeviceObject, > IRP_MN_SET_POWER, > powerState, > (PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc, > irpContext, > NULL); > > if(STATUS_PENDING == ntStatus) { > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback::" > "waiting for the power irp to complete\n")); > > KeWaitForSingleObject(&irpCompletionEvent, > Executive, > KernelMode, > FALSE, > NULL); > } > } > ////////// My Comment > ////if ntStatus is a Error code from "PoRequestPowerIrp" ,then > ////ExFreePool(irpContext) will be called by one time. > //// > if(!NT_SUCCESS(ntStatus)) { > > if(irpContext) { > > ExFreePool(irpContext); > } > } > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback - ends\n")); > } > > > VOID > PoIrpCompletionFunc( > IN PDEVICE_OBJECT DeviceObject, > IN UCHAR MinorFunction, > IN POWER_STATE PowerState, > IN PVOID Context, > IN PIO_STATUS_BLOCK IoStatus > ) > /*++ > > Routine Description: > > Completion routine for power irp PoRequested in > IdleNotificationCallback. > > Arguments: > > DeviceObject - pointer to device object > MinorFunciton - minor function for the irp. > PowerState - irp power state > Context - context passed to the completion function > IoStatus - status block. > > Return Value: > > None > > --*/ > { > PIRP_COMPLETION_CONTEXT irpContext; > > UNREFERENCED_PARAMETER( DeviceObject ); > UNREFERENCED_PARAMETER( MinorFunction ); > UNREFERENCED_PARAMETER( PowerState ); > UNREFERENCED_PARAMETER( IoStatus ); > > // > // initialize variables > // > irpContext = NULL; > > if(Context) { > > irpContext = (PIRP_COMPLETION_CONTEXT) Context; > } > > // > // all we do is set the event and decrement the count > // > ///////////My Comments > ///// This completeFunction will Free the irpContext the Second time. > ///// ????????. is It correct ????? > if(irpContext) { > > KeSetEvent(irpContext->Event, 0, FALSE); > > BulkUsb_DbgPrint(3, ("PoIrpCompletionFunc::")); > BulkUsb_IoDecrement(irpContext->DeviceExtension); > > ExFreePool(irpContext); > > } > > return; > } |
|
|
|
#4 |
|
Guest
Posts: n/a
|
Re: a question in MS sample code about PoRequestPowerIrp
Hi Doron
Thank you very much. I just use the bulkusb for study purpose.I think the WDK may do the same thing . Yes ,your are right. //DDK said: If PoRequestPowerIrp returns a status other than STATUS_PENDING, the routine did not send a device power IRP and the CompletionFunction is not called. "Doron Holan [MSFT]" wrote: > and no, it is not freed twice. if PoRequestPowerIrp returns !NT_SUCCESS, > the po completion routine will not run. > > d > > -- > Please do not send e-mail directly to this alias. this alias is for > newsgroup purposes only. > This posting is provided "AS IS" with no warranties, and confers no rights. > > > "rech" <rech@discussions.microsoft.com> wrote in message > news 1F37E4A-652E-4451-B14F-620D819AA7E1@microsoft.com...> > > > HI All > > I have a question about MS sample code BulkUsb. > > In the follow piece of code, it seems the "irpContext" be ExFreePool two > > times in certain situation. > > Please See my Comments. > > > > It 's helpful for me if you can correct me. > > > > thanks > > thanks > > > > > > > > > > VOID > > IdleNotificationCallback( > > IN PDEVICE_EXTENSION DeviceExtension > > ) > > /*++ > > > > Routine Description: > > > > "A pointer to a callback function in your driver is passed down the stack > > with > > this IOCTL, and it is this callback function that is called by USBHUB > > when it > > safe for your device to power down." > > > > "When the callback in your driver is called, all you really need to do is > > to > > to first ensure that a WaitWake Irp has been submitted for your device, > > if > > remote wake is possible for your device and then request a SetD2 (or > > DeviceWake)" > > > > Arguments: > > > > DeviceExtension - pointer to device extension > > > > Return Value: > > > > NT status value > > > > --*/ > > { > > NTSTATUS ntStatus; > > POWER_STATE powerState; > > KEVENT irpCompletionEvent; > > PIRP_COMPLETION_CONTEXT irpContext; > > > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback - begins\n")); > > > > // > > // Dont idle, if the device was just disconnected or being stopped > > // i.e. return for the following DeviceState(s) > > // NotStarted, Stopped, PendingStop, PendingRemove, SurpriseRemoved, > > Removed > > // > > > > if(DeviceExtension->DeviceState != Working) { > > > > return; > > } > > > > // > > // If there is not already a WW IRP pending, submit one now > > // > > if(DeviceExtension->WaitWakeEnable) { > > > > IssueWaitWake(DeviceExtension); > > } > > > > > > // > > // power down the device > > // > > > > irpContext = (PIRP_COMPLETION_CONTEXT) > > ExAllocatePool(NonPagedPool, > > sizeof(IRP_COMPLETION_CONTEXT)); > > > > if(!irpContext) { > > > > BulkUsb_DbgPrint(1, ("Failed to alloc memory for irpContext\n")); > > ntStatus = STATUS_INSUFFICIENT_RESOURCES; > > } > > else { > > > > // > > // increment the count. In the HoldIoRequestWorkerRoutine, the > > // count is decremented twice (one for the system Irp and the > > // other for the device Irp. An increment here compensates for > > // the sytem irp..The decrement corresponding to this increment > > // is in the completion function > > // > > > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback::")); > > BulkUsb_IoIncrement(DeviceExtension); > > > > powerState.DeviceState = DeviceExtension->PowerDownLevel; > > > > KeInitializeEvent(&irpCompletionEvent, NotificationEvent, FALSE); > > > > irpContext->DeviceExtension = DeviceExtension; > > irpContext->Event = &irpCompletionEvent; > > > > ntStatus = PoRequestPowerIrp( > > DeviceExtension->PhysicalDeviceObject, > > IRP_MN_SET_POWER, > > powerState, > > (PREQUEST_POWER_COMPLETE) PoIrpCompletionFunc, > > irpContext, > > NULL); > > > > if(STATUS_PENDING == ntStatus) { > > > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback::" > > "waiting for the power irp to complete\n")); > > > > KeWaitForSingleObject(&irpCompletionEvent, > > Executive, > > KernelMode, > > FALSE, > > NULL); > > } > > } > > ////////// My Comment > > ////if ntStatus is a Error code from "PoRequestPowerIrp" ,then > > ////ExFreePool(irpContext) will be called by one time. > > //// > > if(!NT_SUCCESS(ntStatus)) { > > > > if(irpContext) { > > > > ExFreePool(irpContext); > > } > > } > > > > BulkUsb_DbgPrint(3, ("IdleNotificationCallback - ends\n")); > > } > > > > > > VOID > > PoIrpCompletionFunc( > > IN PDEVICE_OBJECT DeviceObject, > > IN UCHAR MinorFunction, > > IN POWER_STATE PowerState, > > IN PVOID Context, > > IN PIO_STATUS_BLOCK IoStatus > > ) > > /*++ > > > > Routine Description: > > > > Completion routine for power irp PoRequested in > > IdleNotificationCallback. > > > > Arguments: > > > > DeviceObject - pointer to device object > > MinorFunciton - minor function for the irp. > > PowerState - irp power state > > Context - context passed to the completion function > > IoStatus - status block. > > > > Return Value: > > > > None > > > > --*/ > > { > > PIRP_COMPLETION_CONTEXT irpContext; > > > > UNREFERENCED_PARAMETER( DeviceObject ); > > UNREFERENCED_PARAMETER( MinorFunction ); > > UNREFERENCED_PARAMETER( PowerState ); > > UNREFERENCED_PARAMETER( IoStatus ); > > > > // > > // initialize variables > > // > > irpContext = NULL; > > > > if(Context) { > > > > irpContext = (PIRP_COMPLETION_CONTEXT) Context; > > } > > > > // > > // all we do is set the event and decrement the count > > // > > ///////////My Comments > > ///// This completeFunction will Free the irpContext the Second time. > > ///// ????????. is It correct ????? > > if(irpContext) { > > > > KeSetEvent(irpContext->Event, 0, FALSE); > > > > BulkUsb_DbgPrint(3, ("PoIrpCompletionFunc::")); > > BulkUsb_IoDecrement(irpContext->DeviceExtension); > > > > ExFreePool(irpContext); > > > > } > > > > return; > > } > > |
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|
< Home - Windows Help - MS Office Help - Hardware Support >
| New To Site? | Need Help? |