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