📄 crio.c
字号:
//
// Copyright (c) 2004 Golden Bits Software, Inc.
// All rights reserved
// www.goldenbits.com
//
// WARNING: For sample/demonstration use only, no warranty
// of any kind.
//
// CrIO.c
//
// Desc: Code to create, close, perform IO
//
#include "ntddk.h"
#include "wmilib.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "CrMain.h"
#include "CrPnp.h"
#include "..\Include\UsbCryptAppInc.h"
// ==================== UsbCrypt_Create() =============
// Desc: Creates open file handle do our USB device.
// Saves a pointer to the USB pipe handles in the
// FsContext of the open handle.
//
// Returns: STATUS_SUCCESS or failure.
//
NTSTATUS UsbCrypt_Create(IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp)
{
PCRYPT_HANDLE_INFO pCryptInfo;
PUSB_CRYPT_EXT pCryptExt = (PUSB_CRYPT_EXT)pDeviceObject->DeviceExtension;
PIO_STACK_LOCATION pIrpStack;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// set crypt handle info
pCryptInfo = ExAllocatePoolWithTag(PagedPool, sizeof(CRYPT_HANDLE_INFO),
CRYT_MEM_TAG);
if(pCryptInfo == NULL)
{
USB_TRACE("UsbCrypt_Create(): Failed to alloc memory for crypt handle\n");
pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
// set default as encryption
RtlCopyMemory(pCryptInfo, &pCryptExt->EncryptionInfo,
sizeof(CRYPT_HANDLE_INFO));
// save off handle context into file context
// we'll use this later to when processing an
// IO to the device
pIrpStack->FileObject->FsContext = pCryptInfo;
// complete request
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// ==================== UsbCrypt_Close() =============
// Desc: Closes an open file handle and frees the memory
// allocated for the USB pipe handles.
//
// Returns: STATUS_SUCCESS
//
NTSTATUS UsbCrypt_Close(IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp)
{
PUSB_CRYPT_EXT pCryptExt = (PUSB_CRYPT_EXT)pDeviceObject->DeviceExtension;
PIO_STACK_LOCATION pIrpStack;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// delete memory allocated for crypt handle info
if(pIrpStack->FileObject->FsContext != NULL)
{
ExFreePool(pIrpStack->FileObject->FsContext);
pIrpStack->FileObject->FsContext = NULL;
}
// complete request
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// ==================== UsbCrypt_Read() =============
// Desc: Reads data from the USB device. The pipe handles
// saved in the memory pointed to by FsContext is used
// to perform the actual read.
//
// Returns: STATUS_SUCCESS or NT Status failure
//
NTSTATUS UsbCrypt_Read(IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp)
{
NTSTATUS Status;
PUSB_CRYPT_EXT pCryptExt;
USBD_PIPE_HANDLE PipeHandle;
PIO_STACK_LOCATION pStack;
PCRYPT_HANDLE_INFO pHInfo;
ULONG ulBufXferLen;
PBYTE pReadBuf;
pCryptExt = (PUSB_CRYPT_EXT)pDeviceObject->DeviceExtension;
// check our device state
if(GET_CURRENT_PNP_STATE(pCryptExt) != Working)
{
// complete IRP with error status
pIrp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_STATE;
}
// get pointer to device stack and associated
// arguments for input/ouput
pStack = IoGetCurrentIrpStackLocation(pIrp);
pHInfo = (PCRYPT_HANDLE_INFO)pStack->FileObject->FsContext;
// sanity check
ASSERT(pHInfo != NULL);
// grab IO lock so we don't get removed while
// we've got an IO in process
IoAcquireRemoveLock(&pCryptExt->RemoveLock, (PVOID)CRYT_MEM_TAG);
// get correct pipe handle for our read operation
// we're "outputting" data to the host
PipeHandle = pHInfo->OutputPipe;
// get buffer to write data to device, since we're
// using DirectIO method, the buffer should be
// setup for us (i.e. locked and mapped). However, we'll
// call MmGetSystemAddressForMdlSafe() to insure the buffer
// is locked and mapped to system space
pReadBuf = (PBYTE)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,
NormalPagePriority);
// get max len to write, if greater than waht our USB device
// can handle then we'll just truncate. The amount of
// data you can transfer to your device depends on the
// device itself. Our simple device an only handle
// a small amount of data.
//
// If your device can not handle the entire transfer,
// an alternative is to break up the IO into multiple
// transfers.
ulBufXferLen = MmGetMdlByteCount(pIrp->MdlAddress);
ulBufXferLen = ulBufXferLen > MAX_CRYPT_TRANSFER ?
MAX_CRYPT_TRANSFER : ulBufXferLen;
// NOTE: The pipe handle determines if we're sending
// or recieving data to/from the USB device.
Status = SendBulkIntTransfer(pDeviceObject, pReadBuf,
ulBufXferLen, PipeHandle,
TRUE, &ulBufXferLen);
// complete request
pIrp->IoStatus.Status = Status;
pIrp->IoStatus.Information = ulBufXferLen;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
// Release IO lock
IoReleaseRemoveLock(&pCryptExt->RemoveLock, (PVOID)CRYT_MEM_TAG);
return STATUS_SUCCESS;
}
// ==================== UsbCrypt_Write() =============
// Desc: Writes data from the USB device. The pipe handles
// saved in the memory pointed to by FsContext is used
// to perform the actual read.
//
// Returns: STATUS_SUCCESS or NT Status failure
//
NTSTATUS UsbCrypt_Write(IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp)
{
NTSTATUS Status;
PUSB_CRYPT_EXT pCryptExt;
USBD_PIPE_HANDLE PipeHandle;
PIO_STACK_LOCATION pStack;
PCRYPT_HANDLE_INFO pHInfo;
ULONG ulBufXferLen;
PBYTE pWriteBuf;
pCryptExt = (PUSB_CRYPT_EXT)pDeviceObject->DeviceExtension;
// check our device state
if(GET_CURRENT_PNP_STATE(pCryptExt) != Working)
{
// complete IRP with error status
pIrp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_STATE;
}
// get pointer to device stack and associated
// arguments for input/ouput
pStack = IoGetCurrentIrpStackLocation(pIrp);
pHInfo = (PCRYPT_HANDLE_INFO)pStack->FileObject->FsContext;
// sanity check
ASSERT(pHInfo != NULL);
// grab IO lock so we don't get removed while
// we've got an IO in process
IoAcquireRemoveLock(&pCryptExt->RemoveLock, (PVOID)CRYT_MEM_TAG);
// get correct pipe handle for our write operation
// we're "inputting" data to the USB device
PipeHandle = pHInfo->InputPipe;
// get buffer to write data to device, since we're
// using DirectIO method, the buffer should be
// setup for us (i.e. locked and mapped). However, we'll
// call MmGetSystemAddressForMdlSafe() to insure the buffer
// is locked and mapped to system space
pWriteBuf = (PBYTE)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,
NormalPagePriority);
// get max len to write, if greater than waht our USB device
// can handle then we'll just truncate. The amount of
// data you can transfer to your device depends on the
// device itself. Our simple device an only handle
// a small amount of data.
//
// If your device can not handle the entire transfer,
// an alternative is to break up the IO into multiple
// transfers.
ulBufXferLen = MmGetMdlByteCount(pIrp->MdlAddress);
ulBufXferLen = ulBufXferLen > MAX_CRYPT_TRANSFER ?
MAX_CRYPT_TRANSFER : ulBufXferLen;
// NOTE: The pipe handle determines if we're sending
// or recieving data to/from the USB device.
Status = SendBulkIntTransfer(pDeviceObject, pWriteBuf,
ulBufXferLen, PipeHandle,
FALSE, &ulBufXferLen);
// complete request
pIrp->IoStatus.Status = Status;
pIrp->IoStatus.Information = ulBufXferLen;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
// Release IO lock
IoReleaseRemoveLock(&pCryptExt->RemoveLock, (PVOID)CRYT_MEM_TAG);
return Status;
}
// ==================== UsbCrypt_DeviceCtrl() =============
// Desc: Handles IOCTLs from user app.
//
// Returns: STATUS_SUCCESS or NT Status failure
//
NTSTATUS UsbCrypt_DeviceCtrl(IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp)
{
PIO_STACK_LOCATION pIrpStack;
ULONG ulInputLen, ulOutLen;
ULONG ulIoCode, ulInfoLen;
ULONG ulFunctionType;
NTSTATUS Status;
PUSB_CRYPT_EXT pCryptExt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -