34be2fbf974a46359f9ff3a08c48f92337273a5d
[reactos.git] / reactos / drivers / crypto / ksecdd / dispatch.c
1 /*
2 * PROJECT: ReactOS Drivers
3 * COPYRIGHT: See COPYING in the top level directory
4 * PURPOSE: Kernel Security Support Provider Interface Driver
5 *
6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include "ksecdd.h"
12
13 #define NDEBUG
14 #include <debug.h>
15
16
17 /* FUNCTIONS ******************************************************************/
18
19 static
20 NTSTATUS
21 KsecQueryFileInformation(
22 PVOID InfoBuffer,
23 FILE_INFORMATION_CLASS FileInformationClass,
24 PSIZE_T BufferLength)
25 {
26 PFILE_STANDARD_INFORMATION StandardInformation;
27
28 /* Only FileStandardInformation is supported */
29 if (FileInformationClass != FileStandardInformation)
30 {
31 return STATUS_INVALID_INFO_CLASS;
32 }
33
34 /* Validate buffer size */
35 if (*BufferLength >= sizeof(FILE_STANDARD_INFORMATION))
36 {
37 *BufferLength = sizeof(FILE_STANDARD_INFORMATION);
38 return STATUS_INFO_LENGTH_MISMATCH;
39 }
40
41 /* Fill the structure */
42 StandardInformation = (PFILE_STANDARD_INFORMATION)InfoBuffer;
43 StandardInformation->AllocationSize.QuadPart = 0;
44 StandardInformation->EndOfFile.QuadPart = 0;
45 StandardInformation->NumberOfLinks = 1;
46 StandardInformation->DeletePending = FALSE;
47 StandardInformation->Directory = FALSE;
48 *BufferLength = sizeof(FILE_STANDARD_INFORMATION);
49
50 return STATUS_SUCCESS;
51 }
52
53 static
54 NTSTATUS
55 KsecQueryVolumeInformation(
56 PVOID InfoBuffer,
57 FS_INFORMATION_CLASS FsInformationClass,
58 PSIZE_T BufferLength)
59 {
60 PFILE_FS_DEVICE_INFORMATION DeviceInformation;
61
62 /* Only FileFsDeviceInformation is supported */
63 if (FsInformationClass != FileFsDeviceInformation)
64 {
65 return STATUS_INVALID_INFO_CLASS;
66 }
67
68 /* Validate buffer size */
69 if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
70 {
71 *BufferLength = sizeof(FILE_FS_DEVICE_INFORMATION);
72 return STATUS_INFO_LENGTH_MISMATCH;
73 }
74
75 /* Fill the structure */
76 DeviceInformation = (PFILE_FS_DEVICE_INFORMATION)InfoBuffer;
77 DeviceInformation->DeviceType = FILE_DEVICE_NULL;
78 DeviceInformation->Characteristics = 0;
79 *BufferLength = sizeof(FILE_FS_DEVICE_INFORMATION);
80
81 return STATUS_SUCCESS;
82 }
83
84 static
85 NTSTATUS
86 KsecDeviceControl(
87 ULONG IoControlCode,
88 PVOID Buffer,
89 SIZE_T InputLength,
90 PSIZE_T OutputLength)
91 {
92 NTSTATUS Status;
93
94 Status = STATUS_SUCCESS;
95
96 /* Check ioctl code */
97 switch (IoControlCode)
98 {
99 case IOCTL_KSEC_GEN_RANDOM:
100
101 Status = KsecGenRandom(Buffer, *OutputLength);
102 break;
103
104 default:
105 DPRINT1("Unhandled control code 0x%lx\n", IoControlCode);
106 __debugbreak();
107 return STATUS_INVALID_PARAMETER;
108 }
109
110 return Status;
111 }
112
113 NTSTATUS
114 NTAPI
115 KsecDdDispatch(
116 PDEVICE_OBJECT DeviceObject,
117 PIRP Irp)
118 {
119 PIO_STACK_LOCATION IoStackLocation;
120 ULONG_PTR Information;
121 NTSTATUS Status;
122 PVOID Buffer;
123 SIZE_T InputLength, OutputLength;
124 FILE_INFORMATION_CLASS FileInfoClass;
125 FS_INFORMATION_CLASS FsInfoClass;
126 ULONG IoControlCode;
127
128 IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
129
130 switch (IoStackLocation->MajorFunction)
131 {
132 case IRP_MJ_CREATE:
133 case IRP_MJ_CLOSE:
134
135 /* Just return success */
136 Status = STATUS_SUCCESS;
137 Information = 0;
138 break;
139
140 case IRP_MJ_READ:
141
142 /* There is nothing to read */
143 Status = STATUS_END_OF_FILE;
144 Information = 0;
145 break;
146
147 case IRP_MJ_WRITE:
148
149 /* Pretend to have written everything */
150 Status = STATUS_SUCCESS;
151 Information = IoStackLocation->Parameters.Write.Length;
152 break;
153
154 case IRP_MJ_QUERY_INFORMATION:
155
156 /* Extract the parameters */
157 Buffer = Irp->AssociatedIrp.SystemBuffer;
158 OutputLength = IoStackLocation->Parameters.QueryFile.Length;
159 FileInfoClass = IoStackLocation->Parameters.QueryFile.FileInformationClass;
160
161 /* Call the internal function */
162 Status = KsecQueryFileInformation(Buffer,
163 FileInfoClass,
164 &OutputLength);
165 Information = OutputLength;
166 break;
167
168 case IRP_MJ_QUERY_VOLUME_INFORMATION:
169
170 /* Extract the parameters */
171 Buffer = Irp->AssociatedIrp.SystemBuffer;
172 OutputLength = IoStackLocation->Parameters.QueryVolume.Length;
173 FsInfoClass = IoStackLocation->Parameters.QueryVolume.FsInformationClass;
174
175 /* Call the internal function */
176 Status = KsecQueryVolumeInformation(Buffer,
177 FsInfoClass,
178 &OutputLength);
179 Information = OutputLength;
180 break;
181
182 case IRP_MJ_DEVICE_CONTROL:
183
184 /* Extract the parameters */
185 Buffer = Irp->AssociatedIrp.SystemBuffer;
186 InputLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
187 OutputLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
188 IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
189
190 /* Call the internal function */
191 Status = KsecDeviceControl(IoControlCode,
192 Buffer,
193 InputLength,
194 &OutputLength);
195 Information = OutputLength;
196 break;
197
198 default:
199 DPRINT1("Unhandled major function %lu!\n",
200 IoStackLocation->MajorFunction);
201 ASSERT(FALSE);
202 }
203
204 /* Return the information */
205 Irp->IoStatus.Status = Status;
206 Irp->IoStatus.Information = Information;
207
208 /* Complete the request */
209 IoCompleteRequest(Irp, IO_NO_INCREMENT);
210
211 return Status;
212 }