reactos/drivers/usb/nt4compat/usbdriver/keyboard.c
Amine Khaldi 6c0c23cb53 [CMAKE]
- Sync with trunk head (r50270)
- This also reverts r49298.

svn path=/branches/cmake-bringup/; revision=50271
2011-01-03 00:33:31 +00:00

585 lines
20 KiB
C

/*
* PROJECT: ReactOS USB Drivers
* COPYRIGHT: GPL - See COPYING in the top level directory
* FILE: keyboard.c
* PURPOSE: Generic USB keyboard driver
* PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
*/
#include "usbdriver.h"
NTSTATUS
AddRegistryEntry(IN PCWSTR PortTypeName,
IN PUNICODE_STRING DeviceName,
IN PCWSTR RegistryPath);
BOOLEAN kbd_connect(PDEV_CONNECT_DATA dev_mgr, DEV_HANDLE dev_handle);
BOOLEAN kbd_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
BOOLEAN kbd_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
VOID kbd_irq(PURB purb, PVOID pcontext);
static NTSTATUS
KeyboardCreateDevice(IN PDRIVER_OBJECT DriverObject, IN PKEYBOARD_DRVR_EXTENSION DriverExtension);
void * memscan(void * addr, int c, size_t size);
static UCHAR usb_kbd_keycode[256] =
{
0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
150,158,159,128,136,177,178,176,142,152,173,140
};
/* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */
typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION {
USHORT NumberOfIndicatorKeys;
INDICATOR_LIST IndicatorList[3];
} LOCAL_KEYBOARD_INDICATOR_TRANSLATION, *PLOCAL_KEYBOARD_INDICATOR_TRANSLATION;
static LOCAL_KEYBOARD_INDICATOR_TRANSLATION IndicatorTranslation = { 3, {
{0x3A, KEYBOARD_CAPS_LOCK_ON},
{0x45, KEYBOARD_NUM_LOCK_ON},
{0x46, KEYBOARD_SCROLL_LOCK_ON}}};
BOOLEAN
kbd_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
{
PKEYBOARD_DRVR_EXTENSION pdrvr_ext;
if (dev_mgr == NULL || pdriver == NULL)
return FALSE;
//init driver structure, no PNP table functions
pdriver->driver_desc.flags = USB_DRIVER_FLAG_IF_CAPABLE;
pdriver->driver_desc.vendor_id = 0xffff; // USB Vendor ID
pdriver->driver_desc.product_id = 0xffff; // USB Product ID.
pdriver->driver_desc.release_num = 0x100; // Release Number of Device
pdriver->driver_desc.config_val = 0; // Configuration Value
pdriver->driver_desc.if_num = 0; // Interface Number
pdriver->driver_desc.if_class = USB_CLASS_HID; // Interface Class
pdriver->driver_desc.if_sub_class = 1; // Interface SubClass
pdriver->driver_desc.if_protocol = 1; // Interface Protocol
pdriver->driver_desc.driver_name = "USB Keyboard driver"; // Driver name for Name Registry
pdriver->driver_desc.dev_class = USB_CLASS_HID;
pdriver->driver_desc.dev_sub_class = 1; // Device Subclass
pdriver->driver_desc.dev_protocol = 1; // Protocol Info.
pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(KEYBOARD_DRVR_EXTENSION));
if (!pdriver->driver_ext) return FALSE;
pdriver->driver_ext_size = sizeof(KEYBOARD_DRVR_EXTENSION);
RtlZeroMemory(pdriver->driver_ext, sizeof(KEYBOARD_DRVR_EXTENSION));
pdrvr_ext = (PKEYBOARD_DRVR_EXTENSION) pdriver->driver_ext;
pdrvr_ext->dev_mgr = dev_mgr;
pdriver->disp_tbl.version = 1;
pdriver->disp_tbl.dev_connect = kbd_connect;
pdriver->disp_tbl.dev_disconnect = kbd_disconnect;
pdriver->disp_tbl.dev_stop = kbd_stop;
pdriver->disp_tbl.dev_reserved = NULL;
// Create the device
KeyboardCreateDevice(dev_mgr->usb_driver_obj, pdrvr_ext);
usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_driver_init(): keyboard driver is initialized\n"));
return TRUE;
}
BOOLEAN
kbd_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
{
//PMOUSE_DRVR_EXTENSION pdrvr_ext;
if (dev_mgr == NULL || pdriver == NULL)
return FALSE;
//pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext;
//umss_delete_port_device(pdrvr_ext->port_dev_obj);
//pdrvr_ext->port_dev_obj = NULL;
//ASSERT(IsListEmpty(&pdrvr_ext->dev_list) == TRUE);
usb_free_mem(pdriver->driver_ext);
pdriver->driver_ext = NULL;
pdriver->driver_ext_size = 0;
usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_driver_destroy(): keyboard driver is destroyed\n"));
return TRUE;
}
BOOLEAN
kbd_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle)
{
PURB purb;
NTSTATUS status;
PUSB_DEV_MANAGER dev_mgr;
PUSB_DRIVER pdrvr;
PUSB_DEV pdev;
PKEYBOARD_DRVR_EXTENSION pdev_ext;
PUSB_ENDPOINT_DESC pendp_desc = NULL;
ULONG MaxPacketSize;
usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_connect(): entering...\n"));
dev_mgr = param->dev_mgr;
pdrvr = param->pdriver;
pdev_ext = (PKEYBOARD_DRVR_EXTENSION)pdrvr->driver_ext;
pdev_ext->dev_handle = dev_handle;
// Lock USB Device
status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
if (status != STATUS_SUCCESS)
{
usb_dbg_print(DBGLVL_MEDIUM, ("kbd_connect(): unable to query&lock device, status=0x%x\n", status));
return FALSE;
}
// Get pointer to the endpoint descriptor
pendp_desc = pdev->usb_config->interf[0].endp[0].pusb_endp_desc;
// Store max packet size
MaxPacketSize = pendp_desc->wMaxPacketSize;
if (MaxPacketSize > 8)
MaxPacketSize = 8;
// Unlock USB Device
usb_unlock_dev(pdev);
// Send interrupt URB
purb = usb_alloc_mem(NonPagedPool, sizeof(URB));
if (purb == NULL)
return FALSE;
RtlZeroMemory(purb, sizeof(URB));
RtlZeroMemory(pdev_ext->kbd_old, 8);
// Build a URB for our interrupt transfer
UsbBuildInterruptOrBulkTransferRequest(purb,
usb_make_handle((dev_handle >> 16), 0, 0),
(PUCHAR)&pdev_ext->kbd_data,
MaxPacketSize, //use max packet size
kbd_irq,
pdev_ext->device_ext,
0);
// Call USB driver stack
status = usb_submit_urb(pdev_ext->dev_mgr, purb);
if (status != STATUS_PENDING)
{
usb_free_mem(purb);
purb = NULL;
}
return TRUE;
}
VOID
kbd_irq(PURB purb, PVOID pcontext)
{
KEYBOARD_INPUT_DATA KeyboardInputData[20];
ULONG DataPrepared=0, DataConsumed, i;
UCHAR ScanCode;
NTSTATUS status;
PKEYBOARD_DRVR_EXTENSION pdev_ext;
PKEYBOARD_DEVICE_EXTENSION DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)pcontext;
PUCHAR data, data_old;
usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_irq(): called\n"));
ASSERT(purb);
if (purb->status != STATUS_SUCCESS)
{
usb_dbg_print(DBGLVL_MAXIMUM, ("kbd_irq(): purb->status 0x%08X\n", purb->status));
return;
}
pdev_ext = DeviceExtension->DriverExtension;
data = pdev_ext->kbd_data;
data_old = pdev_ext->kbd_old;
usb_dbg_print(DBGLVL_MAXIMUM, ("Kbd input: %d %d %d %d %d %d %d %d\n", data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7]));
// Zero initial kbd data array
RtlZeroMemory(&KeyboardInputData[0], sizeof(KeyboardInputData));
// Scan modifier keys
for (i=0; i<8; i++)
{
ScanCode = usb_kbd_keycode[i + 224];
if (((data[0] >> i) & 1) != ((data_old[0] >> i) & 1))
{
usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key p/r %d\n", ScanCode, (data[0] >> i) & 1));
KeyboardInputData[DataPrepared].MakeCode = ScanCode;
if ((data[0] >> i) & 1)
KeyboardInputData[DataPrepared].Flags |= KEY_MAKE;
else
KeyboardInputData[DataPrepared].Flags |= KEY_BREAK;
DataPrepared++;
}
}
// Scan normal keys
for (i=2; i<8; i++)
{
if (data_old[i] > 3 && memscan(data + 2, data_old[i], 6) == data + 8)
{
if (usb_kbd_keycode[data_old[i]])
{
// key released
usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key released 1\n", usb_kbd_keycode[data_old[i]]));
KeyboardInputData[DataPrepared].MakeCode = usb_kbd_keycode[data_old[i]];
KeyboardInputData[DataPrepared].Flags |= KEY_BREAK;
DataPrepared++;
}
}
if (data[i] > 3 && memscan(data_old + 2, data[i], 6) == data_old + 8)
{
if (usb_kbd_keycode[data[i]])
{
// key pressed
usb_dbg_print(DBGLVL_MAXIMUM, ("Scan %d key pressed 1\n", usb_kbd_keycode[data[i]]));
KeyboardInputData[DataPrepared].MakeCode = usb_kbd_keycode[data[i]];
KeyboardInputData[DataPrepared].Flags |= KEY_MAKE;
DataPrepared++;
}
}
}
// Commit the input data somewhere...
if (DeviceExtension->ConnectData.ClassService && DataPrepared > 0)
{
KIRQL OldIrql;
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
(*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ConnectData.ClassService)(
DeviceExtension->ConnectData.ClassDeviceObject,
&KeyboardInputData[0],
(&KeyboardInputData[0])+DataPrepared,
&DataConsumed);
KeLowerIrql(OldIrql);
}
// Save old keyboard data
RtlCopyMemory(pdev_ext->kbd_old, data, 8);
// resubmit the urb
status = usb_submit_urb(pdev_ext->dev_mgr, purb);
}
BOOLEAN
kbd_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
{
UNREFERENCED_PARAMETER(dev_handle);
UNREFERENCED_PARAMETER(dev_mgr);
return TRUE;
}
BOOLEAN
kbd_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle)
{
PDEVICE_OBJECT dev_obj;
NTSTATUS status;
PUSB_DEV pdev;
PUSB_DRIVER pdrvr;
if (dev_mgr == NULL || dev_handle == 0)
return FALSE;
pdev = NULL;
//special use of the lock dev, simply use this routine to get the dev
status = usb_query_and_lock_dev(dev_mgr, dev_handle, &pdev);
if (pdev == NULL)
{
return FALSE;
}
if (status == STATUS_SUCCESS)
{
// must be a bug
TRAP();
usb_unlock_dev(pdev);
}
pdrvr = pdev->dev_driver;
dev_obj = pdev->dev_obj;
pdev = NULL;
return TRUE;//umss_delete_device(dev_mgr, pdrvr, dev_obj, FALSE);
}
VOID
kbd_setleds(PKEYBOARD_DEVICE_EXTENSION DeviceExtension)
{
PURB Urb;
PUSB_CTRL_SETUP_PACKET Setup;
NTSTATUS Status;
// Set LEDs request
Urb = usb_alloc_mem(NonPagedPool, sizeof(URB));
if (!Urb) return;
RtlZeroMemory(Urb, sizeof(URB));
DeviceExtension->DriverExtension->leds_old = 0;
DeviceExtension->DriverExtension->leds = 7;
// Convert from LedFlags to USB format
//DeviceExtension->KeyboardIndicators.LedFlags
// Build a URB for setting LEDs
Setup = (PUSB_CTRL_SETUP_PACKET)Urb->setup_packet;
urb_init((Urb));
Urb->endp_handle = usb_make_handle((DeviceExtension->DriverExtension->dev_handle >> 16), 0, 0) | 0xffff;
Urb->data_buffer = &DeviceExtension->DriverExtension->leds;
Urb->data_length = 1;
Urb->completion = NULL;
Urb->context = NULL;
Urb->reference = 0;
Setup->bmRequestType = USB_DT_HID;
Setup->bRequest = USB_REQ_SET_CONFIGURATION;
Setup->wValue = USB_DT_CONFIG << 8;
Setup->wIndex = 0;
Setup->wLength = 1;
// Call USB driver stack
Status = usb_submit_urb(DeviceExtension->DriverExtension->dev_mgr, Urb);
if (Status != STATUS_PENDING)
{
usb_free_mem(Urb);
}
}
// Dispatch routine for our IRPs
NTSTATUS
KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
DeviceExtension = DeviceObject->DeviceExtension;
usb_dbg_print(DBGLVL_MAXIMUM, ("KbdDispatch(DO %p, code 0x%lx) called\n",
DeviceObject,
IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode));
if (DeviceObject == DeviceExtension->Fdo)
{
// it's keyboard's IOCTL
PIO_STACK_LOCATION Stack;
Irp->IoStatus.Information = 0;
Stack = IoGetCurrentIrpStackLocation(Irp);
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_INTERNAL_KEYBOARD_CONNECT:
usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_INTERNAL_KEYBOARD_CONNECT\n"));
if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) {
usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT "
"invalid buffer size\n"));
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
goto intcontfailure;
}
RtlCopyMemory(&DeviceExtension->ConnectData,
Stack->Parameters.DeviceIoControl.Type3InputBuffer,
sizeof(CONNECT_DATA));
Status = STATUS_SUCCESS;
break;
case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n"));
if (Stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(KEYBOARD_ATTRIBUTES)) {
usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES: "
"invalid buffer size\n"));
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
goto intcontfailure;
}
/*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
&DevExt->KeyboardAttributes,
sizeof(KEYBOARD_ATTRIBUTES));*/
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
case IOCTL_KEYBOARD_QUERY_INDICATORS:
usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_QUERY_INDICATORS\n"));
if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KEYBOARD_INDICATOR_PARAMETERS))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
RtlCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
&DeviceExtension->KeyboardIndicators,
sizeof(KEYBOARD_INDICATOR_PARAMETERS));
Irp->IoStatus.Information = sizeof(KEYBOARD_INDICATOR_PARAMETERS);
Status = STATUS_SUCCESS;
}
break;
case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_QUERY_TYPEMATIC\n"));
if (Stack->Parameters.DeviceIoControl.OutputBufferLength <
sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) {
usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC: "
"invalid buffer size\n"));
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
goto intcontfailure;
}
/*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
&DevExt->KeyboardTypematic,
sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
Status = STATUS_SUCCESS;
break;
case IOCTL_KEYBOARD_SET_INDICATORS:
usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_SET_INDICATORS\n"));
if (Stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(KEYBOARD_INDICATOR_PARAMETERS)) {
usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_KEYBOARD_SET_INDICTATORS: "
"invalid buffer size\n"));
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
goto intcontfailure;
}
RtlCopyMemory(&DeviceExtension->KeyboardIndicators,
Irp->AssociatedIrp.SystemBuffer,
sizeof(KEYBOARD_INDICATOR_PARAMETERS));
//DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags);
kbd_setleds(DeviceExtension);
Status = STATUS_SUCCESS;
break;
case IOCTL_KEYBOARD_SET_TYPEMATIC:
usb_dbg_print(DBGLVL_MAXIMUM, ("IOCTL_KEYBOARD_SET_TYPEMATIC\n"));
if (Stack->Parameters.DeviceIoControl.InputBufferLength <
sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) {
usb_dbg_print(DBGLVL_MAXIMUM, ("Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC "
"invalid buffer size\n"));
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
goto intcontfailure;
}
/*RtlCopyMemory(&DevExt->KeyboardTypematic,
Irp->AssociatedIrp.SystemBuffer,
sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
Status = STATUS_SUCCESS;
break;
case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION))
{
Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
RtlCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
&IndicatorTranslation,
sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));
Irp->IoStatus.Information = sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION);
Status = STATUS_SUCCESS;
}
break;
default:
Status = STATUS_SUCCESS;//STATUS_INVALID_DEVICE_REQUEST;
break;
}
intcontfailure:
Status = Irp->IoStatus.Status;
}
if (Status == STATUS_INVALID_DEVICE_REQUEST)
{
usb_dbg_print(DBGLVL_MINIMUM, ("Invalid internal device request!\n"));
}
Irp->IoStatus.Status = Status;
if (Status != STATUS_PENDING)
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
static NTSTATUS
KeyboardCreateDevice(IN PDRIVER_OBJECT DriverObject, IN PKEYBOARD_DRVR_EXTENSION DriverExtension)
{
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardPortUSB");
PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
PDEVICE_OBJECT Fdo;
NTSTATUS Status;
Status = AddRegistryEntry(L"KeyboardPort", &DeviceName, L"REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\usbdriver");
if (!NT_SUCCESS(Status))
{
usb_dbg_print(DBGLVL_MINIMUM, ("AddRegistryEntry() for usb keyboard driver failed with status 0x%08lx\n", Status));
return Status;
}
Status = IoCreateDevice(DriverObject,
sizeof(KEYBOARD_DEVICE_EXTENSION),
&DeviceName,
FILE_DEVICE_KEYBOARD,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&Fdo);
if (!NT_SUCCESS(Status))
{
usb_dbg_print(DBGLVL_MINIMUM, ("IoCreateDevice() for usb keyboard driver failed with status 0x%08lx\n", Status));
return Status;
}
DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(KEYBOARD_DEVICE_EXTENSION));
DeviceExtension->hdr.dispatch = KbdDispatch;
DeviceExtension->DriverExtension = DriverExtension;
DriverExtension->device_ext = DeviceExtension;
DeviceExtension->Fdo = Fdo;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
usb_dbg_print(DBGLVL_MEDIUM, ("Created keyboard Fdo: %p\n", Fdo));
return STATUS_SUCCESS;
}
/**
* memscan - Find a character in an area of memory.
* @addr: The memory area
* @c: The byte to search for
* @size: The size of the area.
*
* returns the address of the first occurrence of @c, or 1 byte past
* the area if @c is not found
*/
void * memscan(void * addr, int c, size_t size)
{
unsigned char * p = (unsigned char *) addr;
while (size) {
if (*p == c)
return (void *) p;
p++;
size--;
}
return (void *) p;
}