Exemple #1
0
NTSTATUS
NdasPortFdoDispatchSystemControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
	NTSTATUS status;
	PNDASPORT_FDO_EXTENSION FdoExtension;
    SYSCTL_IRP_DISPOSITION disposition;
	PIO_STACK_LOCATION irpStack;
	ULONG isRemoved;

    FdoExtension = (PNDASPORT_FDO_EXTENSION) DeviceObject->DeviceExtension;

	irpStack = IoGetCurrentIrpStackLocation(Irp);

	isRemoved = NpAcquireRemoveLock(FdoExtension->CommonExtension, Irp);
	if (isRemoved)
	{
		return NpReleaseRemoveLockAndCompleteIrp(
			FdoExtension->CommonExtension,
			Irp,
			STATUS_NO_SUCH_DEVICE);
	}

#ifdef RUN_WPP
#ifdef WPP_TRACE_W2K_COMPATABILITY

    //
    // One of the mythical things that people tell you that
    //  you need to do to get WPP tracing to work on Windows
    //  2000 is to call the WPP_SYSTEMCONTROL macro in your
    //  DriverEntry entry point. The problem with this is that
    //  what is does is actually trash your IRP_MJ_SYSTEM_CONTROL
    //  entry point, meaning that you can no longer expose your
    //  driver through WMI. What we will do to get around this
    //  is to incorporate a call to the function that the WPP
    //  IRP_MJ_SYSTEM_CONTROL handler calls in order to handle
    //  WPP data. By doing this, we can satisfy WPP while
    //  also supporting our own WMI data.
    //
    //  You can find the code for the WPP SYSTEM_CONTROL
    //  handler (WPPSystemControlDispatch) in the km-init.tpl
    //  file located in the DDK's bin\wppconfig directory.
    //
    if (DeviceObject == (PDEVICE_OBJECT)irpStack->Parameters.WMI.ProviderId) 
	{
        //
        // If this is a REG_INFO request and we have not registered
        //  with WMI yet, we must zero the buffer. The reason for this
        //  is that the WPP code will just blindly use it without
        //  verifying any of the members of the structure. We learned
        //  this trick from the WPPSystemControl handler code in
        //  km-init.tpl
        //
        if (irpStack->MinorFunction == IRP_MN_REGINFO && !FdoExtension->IsWmiRegistered) 
		{
            RtlZeroMemory(
				irpStack->Parameters.WMI.Buffer,
                irpStack->Parameters.WMI.BufferSize);
        }

        //
        // Yet another nice thing about trying to get tracing and WMI
        //  support working is that we can NOT allow an IRP_MN_REGINFO_EX
        //  request to get to the WMI library, we must do the registering
        //  of WMI through an IRP_MN_REGINFO request.
        //
        // Why? Because the W2K tracing code has no idea what an
        //  IRP_MN_REGINFO_EX is, so it will refuse to setup the
        //  parts necessary for WPP tracing support. So, if
        //  we see an IRP_MN_REGINFO_EX request come in and we're
        //  built for Windows 2000, that means that we need to
        //  reject it to force the code to send us an IRP_MN_REGINFO
        //  request instead.
        //
        // IRP_MN_REGINFO_EX isn't defined for Windows 2000, so we use
        //  its constant value of 0xb here.
        //
        if (IRP_MN_REGINFO_EX == irpStack->MinorFunction) 
		{
            //
            // Fail the request
            //
			return NpReleaseRemoveLockAndCompleteIrpEx(
				FdoExtension->CommonExtension,
				Irp,
				STATUS_INVALID_DEVICE_REQUEST,
				0,
				IO_NO_INCREMENT);
        }

    }

#endif // W2K
#endif //RUN_WPP

    //
    // Call WMILIB to process the request.
    //

    status = WmiSystemControl(
		&FdoExtension->WmiLibInfo,
        DeviceObject,
        Irp,
        &disposition);

    //
    // Check the disposition of the request, so that we can determine
    // what to do.
    //

    switch(disposition) {

        case IrpProcessed:
        {
            //
            // This IRP has been processed and may be completed or pending.
			//
			
			//
			// DispatchWmiXXXX routine is responsible to hold the remove lock.
			// WmiRoutine or our DispatchWmiXXX may later complete the IRP.
			// We just release our remove lock here.
			//
			NpReleaseRemoveLock(
				FdoExtension->CommonExtension, 
				Irp);
			return status;
        }
       
        case IrpNotCompleted:
        {
			NTSTATUS wppStatus = STATUS_SUCCESS;
#ifdef RUN_WPP
#ifdef WPP_TRACE_W2K_COMPATABILITY
			ULONG bytesReturned;

            //
            // If the WMILIB didn't complete the IRP, then let's
            //  see if WPP will.
            //
			KdPrint(("NDASPORT.SYS: WPP_TRACE_CONTROL (MN=%X)\n", irpStack->MinorFunction));
            wppStatus = WPP_TRACE_CONTROL(
				irpStack->MinorFunction,
                irpStack->Parameters.WMI.Buffer,
                irpStack->Parameters.WMI.BufferSize,
                bytesReturned);

            if (!NT_SUCCESS(status) &&
                NT_SUCCESS(wppStatus)) 
			{
                //
                // WMILIB failed the IRP, but WPP completed it
                //  with success. Therefore, we'll change the IRP's
                //  status and bytes returned count to what WPP
                //  would like them to be.
                //
                Irp->IoStatus.Status = wppStatus;
                Irp->IoStatus.Information = bytesReturned;
                status = wppStatus;
            }

#endif // W2K
#endif //RUN_WPP
 
            //
            // This IRP has not been completed, but has been fully processed.
            // we will complete it now.
            //
			return NpReleaseRemoveLockAndCompleteIrp(
				FdoExtension->CommonExtension,
				Irp,
				wppStatus);
        }
       
        case IrpForward:
        case IrpNotWmi:
        {
            //
            // This IRP is either not a WMI IRP or is a WMI IRP targeted
            // at a device lower in the stack.

			return NpReleaseRemoveLockAndForwardIrp(
				FdoExtension->CommonExtension,
				Irp);
        }
                                   
        default:
        {
             //
            // We really should never get here, but if we do just forward.... 
            //
            ASSERTMSG("Unkown SYSCTL_IRP_DISPOSITION from WmiSystemControl",
                      FALSE);
			return NpReleaseRemoveLockAndForwardIrp(
				FdoExtension->CommonExtension,
				Irp);
       }       
    }
}
Exemple #2
0
NTSTATUS
PciDrvSystemControl (
    PDEVICE_OBJECT  DeviceObject,
    PIRP            Irp
    )
/*++
Routine Description

    We have just received a System Control IRP.

    Assume that this is a WMI IRP and
    call into the WMI system library and let it handle this IRP for us.

--*/
{
    PFDO_DATA               fdoData;
    SYSCTL_IRP_DISPOSITION  disposition;
    NTSTATUS                status;
    PIO_STACK_LOCATION      stack;

    PAGED_CODE();

    stack = IoGetCurrentIrpStackLocation (Irp);

    DebugPrint(TRACE, DBG_WMI, "FDO %s\n",
                WMIMinorFunctionString(stack->MinorFunction));

    fdoData = (PFDO_DATA) DeviceObject->DeviceExtension;

    PciDrvPowerUpDevice(fdoData, TRUE);

    PciDrvIoIncrement (fdoData);

    if (fdoData->DevicePnPState == Deleted) {
        Irp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        PciDrvIoDecrement (fdoData);
        return status;
    }

    status = WmiSystemControl(&fdoData->WmiLibInfo,
                                 DeviceObject,
                                 Irp,
                                 &disposition);

    //
    // Following code is required if we want to do tracing in WIN2K.
    // Tracing is enabled or disabled explicitly by sending WMI
    // control events on Win2K.
    //
#if defined(WIN2K) && defined(EVENT_TRACING)

    if (disposition != IrpProcessed &&
            DeviceObject == (PDEVICE_OBJECT)stack->Parameters.WMI.ProviderId) {
        ULONG returnSize = 0;

        DebugPrint(INFO, DBG_WMI, "Calling WPP_TRACE_CONTROL\n");

        WPP_TRACE_CONTROL(stack->MinorFunction,
                          stack->Parameters.WMI.Buffer,
                          stack->Parameters.WMI.BufferSize,
                          returnSize);
    }
#endif

    switch(disposition)
    {
        case IrpProcessed:
        {
            //
            // This irp has been processed and may be completed or pending.
            break;
        }

        case IrpNotCompleted:
        {
            //
            // This irp has not been completed, but has been fully processed.
            // we will complete it now
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            break;
        }

        case IrpForward:
        case IrpNotWmi:
        {
            //
            // This irp is either not a WMI irp or is a WMI irp targeted
            // at a device lower in the stack.
            IoSkipCurrentIrpStackLocation (Irp);
            status = IoCallDriver (fdoData->NextLowerDriver, Irp);
            break;
        }

        default:
        {
            //
            // We really should never get here, but if we do just forward....
            ASSERT(FALSE);
            IoSkipCurrentIrpStackLocation (Irp);
            status = IoCallDriver (fdoData->NextLowerDriver, Irp);
            break;
        }
    }

    PciDrvIoDecrement(fdoData);

    return(status);
}