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