📄 plugplay.c
字号:
/*******************************************************************************
* Copyright (c) 2006 PLX Technology, Inc.
*
* PLX Technology Inc. licenses this software under specific terms and
* conditions. Use of any of the software or derviatives thereof in any
* product without a PLX Technology chip is strictly prohibited.
*
* PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
* EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. PLX makes no guarantee
* or representations regarding the use of, or the results of the use of,
* the software and documentation in terms of correctness, accuracy,
* reliability, currentness, or otherwise; and you rely on the software,
* documentation and results solely at your own risk.
*
* IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
* LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
* OF ANY KIND. IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
* PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
*
******************************************************************************/
/******************************************************************************
*
* File Name:
*
* PlugPlay.c
*
* Description:
*
* Plug 'n' Play handler functions
*
* Revision History:
*
* 02-01-06 : PCI SDK v4.40
*
******************************************************************************/
#include "Dispatch.h"
#include "Driver.h"
#include "GlobalVars.h"
#include "PciSupport.h"
#include "PlugPlay.h"
#include "SupportFunc.h"
/**************************************************************
* The following IRP minor code is erroneously not included
* in the Windows DDK "wdm.h" file. It is, however, included
* in the "ntddk.h" file. Until this is fixed by Microsoft,
* the definition is provided here so the driver will build.
*************************************************************/
#if !defined(IRP_MN_QUERY_LEGACY_BUS_INFORMATION)
#define IRP_MN_QUERY_LEGACY_BUS_INFORMATION 0x18
#endif
/******************************************************************************
*
* Function : Dispatch_Pnp
*
* Description: Handle PnP requests
*
******************************************************************************/
NTSTATUS
Dispatch_Pnp(
PDEVICE_OBJECT fdo,
PIRP pIrp
)
{
BOOLEAN Unlock;
NTSTATUS status;
PIO_STACK_LOCATION stack;
if (!PlxLockDevice(fdo->DeviceExtension))
{
return PlxCompleteIrpWithInformation(
pIrp,
STATUS_DELETE_PENDING,
0
);
}
DebugPrintf((
"Received PNP Message (IRP=0x%p) ==> ",
pIrp
));
Unlock = TRUE;
stack =
IoGetCurrentIrpStackLocation(
pIrp
);
// Check minor code
switch (stack->MinorFunction)
{
case IRP_MN_START_DEVICE:
DebugPrintf_NoInfo(("IRP_MN_START_DEVICE\n"));
status =
HandleStartDevice(
fdo,
pIrp
);
break;
case IRP_MN_STOP_DEVICE:
DebugPrintf_NoInfo(("IRP_MN_STOP_DEVICE\n"));
status =
HandleStopDevice(
fdo,
pIrp
);
break;
case IRP_MN_REMOVE_DEVICE:
DebugPrintf_NoInfo(("IRP_MN_REMOVE_DEVICE\n"));
Unlock = FALSE;
status =
HandleRemoveDevice(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
DebugPrintf_NoInfo(("IRP_MN_QUERY_REMOVE_DEVICE\n"));
status =
HandleQueryRemoveDevice(
fdo,
pIrp
);
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
DebugPrintf_NoInfo(("IRP_MN_CANCEL_REMOVE_DEVICE\n"));
status =
HandleCancelRemoveDevice(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_STOP_DEVICE:
DebugPrintf_NoInfo(("IRP_MN_QUERY_STOP_DEVICE\n"));
status =
HandleQueryRemoveDevice(
fdo,
pIrp
);
break;
case IRP_MN_CANCEL_STOP_DEVICE:
DebugPrintf_NoInfo(("IRP_MN_CANCEL_STOP_DEVICE\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_DEVICE_RELATIONS:
DebugPrintf_NoInfo(("IRP_MN_QUERY_DEVICE_RELATIONS\n"));
status =
HandleQueryDeviceRelations(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_INTERFACE:
DebugPrintf_NoInfo(("IRP_MN_QUERY_INTERFACE\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_CAPABILITIES:
DebugPrintf_NoInfo(("IRP_MN_QUERY_CAPABILITIES\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_RESOURCES:
DebugPrintf_NoInfo(("IRP_MN_QUERY_RESOURCES\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
DebugPrintf_NoInfo(("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_DEVICE_TEXT:
DebugPrintf_NoInfo(("IRP_MN_QUERY_DEVICE_TEXT\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
DebugPrintf_NoInfo(("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_READ_CONFIG:
DebugPrintf_NoInfo(("IRP_MN_READ_CONFIG\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_WRITE_CONFIG:
DebugPrintf_NoInfo(("IRP_MN_WRITE_CONFIG\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_EJECT:
DebugPrintf_NoInfo(("IRP_MN_EJECT\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_SET_LOCK:
DebugPrintf_NoInfo(("IRP_MN_SET_LOCK\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_ID:
DebugPrintf_NoInfo(("IRP_MN_QUERY_ID\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_PNP_DEVICE_STATE:
DebugPrintf_NoInfo(("IRP_MN_QUERY_PNP_DEVICE_STATE\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_BUS_INFORMATION:
DebugPrintf_NoInfo(("IRP_MN_QUERY_BUS_INFORMATION\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
DebugPrintf_NoInfo(("IRP_MN_DEVICE_USAGE_NOTIFICATION\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_SURPRISE_REMOVAL:
DebugPrintf_NoInfo(("IRP_MN_SURPRISE_REMOVAL\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
DebugPrintf_NoInfo(("IRP_MN_QUERY_LEGACY_BUS_INFORMATION\n"));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
default:
DebugPrintf_NoInfo(("Unsupported IRP_MN_Xxx (0x%08x)\n", stack->MinorFunction));
status =
DefaultPnpHandler(
fdo,
pIrp
);
break;
}
if (Unlock == TRUE)
{
PlxUnlockDevice(
fdo->DeviceExtension
);
}
return status;
}
/******************************************************************************
*
* Function : DefaultPnpHandler
*
* Description: Handle standard PnP requests
*
******************************************************************************/
NTSTATUS
DefaultPnpHandler(
PDEVICE_OBJECT fdo,
PIRP pIrp
)
{
DebugPrintf(("Forwarded IRP to next lower driver\n"));
IoSkipCurrentIrpStackLocation(
pIrp
);
return IoCallDriver(
((DEVICE_EXTENSION *)fdo->DeviceExtension)->pLowerDeviceObject,
pIrp
);
}
/******************************************************************************
*
* Function : HandleQueryRemoveDevice
*
* Description: Handle the IRP_MN_QUERY_REMOVE_DEVICE PnP request
*
******************************************************************************/
NTSTATUS
HandleQueryRemoveDevice(
PDEVICE_OBJECT fdo,
PIRP pIrp
)
{
DEVICE_EXTENSION *pdx;
/********************************************************
* Since the first device the driver owns is responsible
* for the global common buffer, it can only be removed
* if it is the last remaining device. The device is
* identified by the serial number. If other devices
* exist, the QUERY_REMOVE_DEVICE must fail.
*******************************************************/
pdx = fdo->DeviceExtension;
// Check if more than one device is owned
if (Gbl_DeviceCount > 1)
{
// This is not the only device left, check serial number
if (_stricmp(
PLX_DRIVER_NAME "-0",
pdx->Device.SerialNumber
) == 0)
{
DebugPrintf((
"ERROR - Device owns shared resources in use, cannot remove at this time\n"
));
// Device is first one, cannot be removed at this time
return PlxCompleteIrpWithInformation(
pIrp,
STATUS_DEVICE_BUSY,
0
);
}
}
// Succeed the IRP and pass to next driver
pIrp->IoStatus.Status = STATUS_SUCCESS;
// Pass to next driver in stack
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -