📄 crpnp.c
字号:
if(!NT_SUCCESS(Status))
{
USB_TRACE("StartUSBCryptDevice() Error, failed to start lower device driver.\n");
return Status;
}
// configure the driver and USB device
Status = ConfigureDriver(pDeviceObject);
IoSetDeviceInterfaceState(&pUsbCryptExt->OurInterfaceName, TRUE);
// start our work item to get decryption byte
// progress
if(pUsbCryptExt->pProgressWkItem != NULL)
{
IoQueueWorkItem(pUsbCryptExt->pProgressWkItem,
GetProgress, // func which gets called
DelayedWorkQueue, NULL);
}
return Status;
}
// ================= IrpGenericCompletionRoutine() ================
// Desc: Handles IRP completion callback, doesn't do any special
// processing
//
// Returns: STATUS_MORE_PROCESSING_REQUIRED
//
NTSTATUS IrpGenericCompletionRoutine(IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp,
IN PVOID pContext)
{
PKEVENT pIrpWait = pContext;
// set event, this should cause the IRP
// processing to continue
KeSetEvent(pIrpWait, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
// ============== StopUSBCryptDevice() ====================
// Desc: Stops all IO to USB device and deconfigures
// USB device.
//
// Returns: Success
//
NTSTATUS StopUSBCryptDevice(IN PDEVICE_OBJECT pDevObj,
IN PUSB_CRYPT_EXT pCryptExt)
{
ULONG UrbLen;
PURB pUrbReq;
NTSTATUS NtStatus;
// set PNP flag to stopped
SET_NEW_PNP_STATE(pCryptExt, Stopped);
// have to aquire remove lock an addition time
// before releasing and waiting
IoAcquireRemoveLock(&pCryptExt->RemoveLock, (PVOID)CRYT_MEM_TAG);
// wait for IOs to complete
// NOTE: This call will block until all of the previously
// acquired locks have been released.
IoReleaseRemoveLockAndWait(&pCryptExt->RemoveLock, (PVOID)CRYT_MEM_TAG);
// now de-configure device, here will send the USB
// device, we do this by selecting a NULL device
// configuration
UrbLen = sizeof(struct _URB_SELECT_CONFIGURATION);
pUrbReq = ExAllocatePool(NonPagedPool, UrbLen);
if(pUrbReq == NULL)
return STATUS_NO_MEMORY;
UsbBuildSelectConfigurationRequest(pUrbReq, (USHORT)UrbLen, NULL);
NtStatus = SendUSBRequest(pDevObj, pUrbReq, TRUE);
// free memory
ExFreePool(pUrbReq);
// free previously allocated memory used
// to save off interface information
if(pCryptExt->pConfigDesc != NULL)
{
ExFreePool(pCryptExt->pConfigDesc);
pCryptExt->pConfigDesc = NULL;
}
// free first interface - the encryption
// interface
if(pCryptExt->pEncryptIFInfo != NULL)
{
ExFreePool(pCryptExt->pEncryptIFInfo);
pCryptExt->pEncryptIFInfo = NULL;
}
// free second interface, the compression
// intrface
if(pCryptExt->pDecryptIFInfo != NULL)
{
ExFreePool(pCryptExt->pDecryptIFInfo);
pCryptExt->pDecryptIFInfo = NULL;
}
return NtStatus;
}
// ============== RemoveCryptDevice() ====================
// Desc: Handles removing device
//
// Returns: NTSTATUS
//
NTSTATUS RemoveCryptDevice(IN PDEVICE_OBJECT pDevObj,
IN PUSB_CRYPT_EXT pCryptExt,
IN PIRP pIrp)
{
// first stop all IO to device
StopUSBCryptDevice(pDevObj, pCryptExt);
// power down device
// free work item
if(pCryptExt->pProgressWkItem != NULL)
{
IoFreeWorkItem(pCryptExt->pProgressWkItem);
pCryptExt->pProgressWkItem = NULL;
}
IoSetDeviceInterfaceState(&pCryptExt->OurInterfaceName, FALSE);
// deregister WMI
IoWMIRegistrationControl(pDevObj, WMIREG_ACTION_DEREGISTER);
// delete symbolic link name
RtlFreeUnicodeString(&pCryptExt->OurInterfaceName);
// call lower device
IoSkipCurrentIrpStackLocation(pIrp);
IoCallDriver(pCryptExt->pTopStackDeviceObject, pIrp);
// detach our device from dev stack
IoDetachDevice(pCryptExt->pTopStackDeviceObject);
// delete device object
IoDeleteDevice(pDevObj);
return STATUS_SUCCESS;
}
// ============== CancelRemove() ====================
// Desc: Handles cancel remove IRP_MN_CANCEL_REMOVE IRP.
//
// Returns: NTSTATUS
//
NTSTATUS CancelRemove(IN PUSB_CRYPT_EXT pCryptExt,
IN PIRP pIrp)
{
KEVENT IrpWaitEvent;
NTSTATUS Status;
// send to lower device first
KeInitializeEvent(&IrpWaitEvent, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine(pIrp,
(PIO_COMPLETION_ROUTINE)IrpGenericCompletionRoutine,
(PVOID)&IrpWaitEvent,
TRUE,
TRUE,
TRUE);
// remember IoCallDriver() can be asynchronous
Status = IoCallDriver(pCryptExt->pTopStackDeviceObject, pIrp);
if(Status == STATUS_PENDING)
{
KeWaitForSingleObject(&IrpWaitEvent,
Executive,
KernelMode,
FALSE,
NULL);
// set return status
Status = pIrp->IoStatus.Status;
}
if(NT_SUCCESS(Status))
{
// restore previous dev state
RESTORE_PREVIOUS_PNP_STATE(pCryptExt);
// should be in working state
ASSERT(GET_CURRENT_PNP_STATE(pCryptExt) == Working);
}
else
{
USB_TRACE("CancelRemove() Lower driver failed IRP_MN_CANCEL_REMOVAL\n");
}
return Status;
}
NTSTATUS USBCryptSurpriseRemoval(IN PDEVICE_OBJECT pDeviceObject,
IN PUSB_CRYPT_EXT pCryptExt)
{
// This function needs to be implemented....
// Should abort any outstanding requests to USB
// device
// TODO: ****
return STATUS_SUCCESS;
}
// ============== CryptCapabilities() ====================
// Desc: Handles PNP Query capabilities IRP
//
// Returns: Success
//
NTSTATUS CryptCapabilities(IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp)
{
ULONG i;
KEVENT event;
NTSTATUS ntStatus;
PDEVICE_CAPABILITIES pDevCaps;
PIO_STACK_LOCATION pIrpStack;
PUSB_CRYPT_EXT pCryptExt;
USB_TRACE("CryptCapabilities()\n");
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
pCryptExt = (PUSB_CRYPT_EXT)pDeviceObject->DeviceExtension;
pDevCaps = pIrpStack->Parameters.DeviceCapabilities.Capabilities;
// sanity check
if(pDevCaps->Version < 1 || pDevCaps->Size < sizeof(DEVICE_CAPABILITIES))
{
USB_TRACE("CryptCapabilities() failed\n");
ntStatus = STATUS_UNSUCCESSFUL;
return ntStatus;
}
//
// Add in the SurpriseRemovalOK bit before passing it down.
//
pDevCaps->SurpriseRemovalOK = TRUE;
pIrp->IoStatus.Status = STATUS_SUCCESS;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(pIrp);
//
// We will just handle this IRP on the way down adding our
// own capabilities. We'll set a completion routine
// here. This lets us examine the DEVICE_CAPABILITIES
// struct after the lower layer drivers have had a chance
// to process this IRP.
IoSetCompletionRoutine(pIrp,
(PIO_COMPLETION_ROUTINE)IrpGenericCompletionRoutine,
(PVOID)&event,
TRUE,
TRUE,
TRUE);
ntStatus = IoCallDriver(pCryptExt->pTopStackDeviceObject, pIrp);
// If we needed to remove a capability then we would remove
// the capability here. For now we'll just leave it untouched
USB_TRACE("CryptCapabilities() - end\n");
return ntStatus;
}
PCHAR PnPMinorFunctionString(UCHAR MinorFunction)
{
switch (MinorFunction)
{
case IRP_MN_START_DEVICE:
return "IRP_MN_START_DEVICE";
case IRP_MN_QUERY_REMOVE_DEVICE:
return "IRP_MN_QUERY_REMOVE_DEVICE";
case IRP_MN_REMOVE_DEVICE:
return "IRP_MN_REMOVE_DEVICE";
case IRP_MN_CANCEL_REMOVE_DEVICE:
return "IRP_MN_CANCEL_REMOVE_DEVICE";
case IRP_MN_STOP_DEVICE:
return "IRP_MN_STOP_DEVICE";
case IRP_MN_QUERY_STOP_DEVICE:
return "IRP_MN_QUERY_STOP_DEVICE";
case IRP_MN_CANCEL_STOP_DEVICE:
return "IRP_MN_CANCEL_STOP_DEVICE";
case IRP_MN_QUERY_DEVICE_RELATIONS:
return "IRP_MN_QUERY_DEVICE_RELATIONS";
case IRP_MN_QUERY_INTERFACE:
return "IRP_MN_QUERY_INTERFACE";
case IRP_MN_QUERY_CAPABILITIES:
return "IRP_MN_QUERY_CAPABILITIES";
case IRP_MN_QUERY_RESOURCES:
return "IRP_MN_QUERY_RESOURCES";
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
case IRP_MN_QUERY_DEVICE_TEXT:
return "IRP_MN_QUERY_DEVICE_TEXT";
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
case IRP_MN_READ_CONFIG:
return "IRP_MN_READ_CONFIG";
case IRP_MN_WRITE_CONFIG:
return "IRP_MN_WRITE_CONFIG";
case IRP_MN_EJECT:
return "IRP_MN_EJECT";
case IRP_MN_SET_LOCK:
return "IRP_MN_SET_LOCK";
case IRP_MN_QUERY_ID:
return "IRP_MN_QUERY_ID";
case IRP_MN_QUERY_PNP_DEVICE_STATE:
return "IRP_MN_QUERY_PNP_DEVICE_STATE";
case IRP_MN_QUERY_BUS_INFORMATION:
return "IRP_MN_QUERY_BUS_INFORMATION";
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
case IRP_MN_SURPRISE_REMOVAL:
return "IRP_MN_SURPRISE_REMOVAL";
default:
return "IRP_MN_<unknown>";
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -