1 /* 2 * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: drivers/input/i8042prt/misc.c 5 * PURPOSE: Miscellaneous operations 6 * PROGRAMMERS: Copyright 2006-2007 Herv� Poussineau (hpoussin@reactos.org) 7 */ 8 9 /* INCLUDES ******************************************************************/ 10 11 #include "i8042prt.h" 12 13 #include <debug.h> 14 15 /* FUNCTIONS *****************************************************************/ 16 17 static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion; 18 19 static NTSTATUS NTAPI 20 ForwardIrpAndWaitCompletion( 21 IN PDEVICE_OBJECT DeviceObject, 22 IN PIRP Irp, 23 IN PVOID Context) 24 { 25 UNREFERENCED_PARAMETER(DeviceObject); 26 __analysis_assume(Context != NULL); 27 if (Irp->PendingReturned) 28 KeSetEvent(Context, IO_NO_INCREMENT, FALSE); 29 return STATUS_MORE_PROCESSING_REQUIRED; 30 } 31 32 NTSTATUS NTAPI 33 ForwardIrpAndWait( 34 IN PDEVICE_OBJECT DeviceObject, 35 IN PIRP Irp) 36 { 37 KEVENT Event; 38 NTSTATUS Status; 39 PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; 40 ASSERT(LowerDevice); 41 42 KeInitializeEvent(&Event, NotificationEvent, FALSE); 43 IoCopyCurrentIrpStackLocationToNext(Irp); 44 45 IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); 46 47 Status = IoCallDriver(LowerDevice, Irp); 48 if (Status == STATUS_PENDING) 49 { 50 Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); 51 if (NT_SUCCESS(Status)) 52 Status = Irp->IoStatus.Status; 53 } 54 55 return Status; 56 } 57 58 NTSTATUS NTAPI 59 ForwardIrpAndForget( 60 IN PDEVICE_OBJECT DeviceObject, 61 IN PIRP Irp) 62 { 63 PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; 64 65 ASSERT(LowerDevice); 66 67 IoSkipCurrentIrpStackLocation(Irp); 68 return IoCallDriver(LowerDevice, Irp); 69 } 70 71 NTSTATUS 72 DuplicateUnicodeString( 73 IN ULONG Flags, 74 IN PCUNICODE_STRING SourceString, 75 OUT PUNICODE_STRING DestinationString) 76 { 77 if (SourceString == NULL || DestinationString == NULL 78 || SourceString->Length > SourceString->MaximumLength 79 || (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL) 80 || Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4) 81 { 82 return STATUS_INVALID_PARAMETER; 83 } 84 85 86 if ((SourceString->Length == 0) 87 && (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE | 88 RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING))) 89 { 90 DestinationString->Length = 0; 91 DestinationString->MaximumLength = 0; 92 DestinationString->Buffer = NULL; 93 } 94 else 95 { 96 USHORT DestMaxLength = SourceString->Length; 97 98 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE) 99 DestMaxLength += sizeof(UNICODE_NULL); 100 101 DestinationString->Buffer = ExAllocatePoolWithTag(PagedPool, DestMaxLength, I8042PRT_TAG); 102 if (DestinationString->Buffer == NULL) 103 return STATUS_NO_MEMORY; 104 105 RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length); 106 DestinationString->Length = SourceString->Length; 107 DestinationString->MaximumLength = DestMaxLength; 108 109 if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE) 110 DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0; 111 } 112 113 return STATUS_SUCCESS; 114 } 115