f1d011aeb07bb2f541d1940cca8ea982f80af06f
[reactos.git] / drivers / usb / usbccgp / pdo.c
1 /*
2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbccgp/pdo.c
5 * PURPOSE: USB device driver.
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
9 * Cameron Gutman
10 */
11
12 #include "usbccgp.h"
13
14 NTSTATUS
15 USBCCGP_PdoHandleQueryDeviceText(
16 IN PDEVICE_OBJECT DeviceObject,
17 IN OUT PIRP Irp)
18 {
19 LPWSTR Buffer;
20 PPDO_DEVICE_EXTENSION PDODeviceExtension;
21
22 //
23 // get device extension
24 //
25 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
26
27 //
28 // is there a device description
29 //
30 if (PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length)
31 {
32 //
33 // allocate buffer
34 //
35 Buffer = AllocateItem(NonPagedPool, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length + sizeof(WCHAR));
36 if (!Buffer)
37 {
38 //
39 // no memory
40 //
41 return STATUS_INSUFFICIENT_RESOURCES;
42 }
43
44 //
45 // copy buffer
46 //
47 Irp->IoStatus.Information = (ULONG_PTR)Buffer;
48 RtlCopyMemory(Buffer, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Buffer, PDODeviceExtension->FunctionDescriptor->FunctionDescription.Length);
49 return STATUS_SUCCESS;
50 }
51
52 //
53 // FIXME use GenericCompositeUSBDeviceString
54 //
55 UNIMPLEMENTED
56 return Irp->IoStatus.Status;
57 }
58
59 NTSTATUS
60 USBCCGP_PdoHandleDeviceRelations(
61 IN PDEVICE_OBJECT DeviceObject,
62 IN OUT PIRP Irp)
63 {
64 PDEVICE_RELATIONS DeviceRelations;
65 PIO_STACK_LOCATION IoStack;
66
67 DPRINT1("USBCCGP_PdoHandleDeviceRelations\n");
68
69 //
70 // get current irp stack location
71 //
72 IoStack = IoGetCurrentIrpStackLocation(Irp);
73
74 //
75 // check if relation type is BusRelations
76 //
77 if (IoStack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
78 {
79 //
80 // PDO handles only target device relation
81 //
82 return Irp->IoStatus.Status;
83 }
84
85 //
86 // allocate device relations
87 //
88 DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
89 if (!DeviceRelations)
90 {
91 //
92 // no memory
93 //
94 return STATUS_INSUFFICIENT_RESOURCES;
95 }
96
97 //
98 // initialize device relations
99 //
100 DeviceRelations->Count = 1;
101 DeviceRelations->Objects[0] = DeviceObject;
102 ObReferenceObject(DeviceObject);
103
104 //
105 // store result
106 //
107 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
108
109 //
110 // completed successfully
111 //
112 return STATUS_SUCCESS;
113 }
114
115 NTSTATUS
116 USBCCGP_PdoHandleQueryId(
117 PDEVICE_OBJECT DeviceObject,
118 PIRP Irp)
119 {
120 PIO_STACK_LOCATION IoStack;
121 PUNICODE_STRING DeviceString = NULL;
122 UNICODE_STRING TempString;
123 PPDO_DEVICE_EXTENSION PDODeviceExtension;
124 NTSTATUS Status;
125 LPWSTR Buffer;
126
127 //
128 // get current irp stack location
129 //
130 IoStack = IoGetCurrentIrpStackLocation(Irp);
131
132 //
133 // get device extension
134 //
135 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
136
137
138 if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
139 {
140 //
141 // handle query device id
142 //
143 Status = USBCCGP_SyncForwardIrp(PDODeviceExtension->NextDeviceObject, Irp);
144
145 //
146 // FIXME append interface id
147 //
148 ASSERT(FALSE);
149 return Status;
150 }
151 else if (IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
152 {
153 //
154 // handle instance id
155 //
156 DeviceString = &PDODeviceExtension->FunctionDescriptor->HardwareId;
157 }
158 else if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
159 {
160 //
161 // handle instance id
162 //
163 RtlInitUnicodeString(&TempString, L"0000");
164 DeviceString = &TempString;
165 }
166 else if (IoStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
167 {
168 //
169 // handle instance id
170 //
171 DeviceString = &PDODeviceExtension->FunctionDescriptor->CompatibleId;
172 }
173
174 //
175 // sanity check
176 //
177 ASSERT(DeviceString != NULL);
178
179 //
180 // allocate buffer
181 //
182 Buffer = AllocateItem(NonPagedPool, DeviceString->Length + sizeof(WCHAR));
183 if (!Buffer)
184 {
185 //
186 // no memory
187 //
188 return STATUS_INSUFFICIENT_RESOURCES;
189 }
190
191 //
192 // copy buffer
193 //
194 Irp->IoStatus.Information = (ULONG_PTR)Buffer;
195 RtlCopyMemory(Buffer, DeviceString->Buffer, DeviceString->Length);
196 return STATUS_SUCCESS;
197 }
198
199 NTSTATUS
200 PDO_HandlePnp(
201 PDEVICE_OBJECT DeviceObject,
202 PIRP Irp)
203 {
204 PIO_STACK_LOCATION IoStack;
205 PPDO_DEVICE_EXTENSION PDODeviceExtension;
206 NTSTATUS Status;
207
208 //
209 // get current stack location
210 //
211 IoStack = IoGetCurrentIrpStackLocation(Irp);
212
213 //
214 // get device extension
215 //
216 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
217
218 //
219 // sanity check
220 //
221 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
222
223 switch(IoStack->MinorFunction)
224 {
225 case IRP_MN_QUERY_DEVICE_RELATIONS:
226 {
227 //
228 // handle device relations
229 //
230 Status = USBCCGP_PdoHandleDeviceRelations(DeviceObject, Irp);
231 break;
232 }
233 case IRP_MN_QUERY_DEVICE_TEXT:
234 {
235 //
236 // handle query device text
237 //
238 Status = USBCCGP_PdoHandleQueryDeviceText(DeviceObject, Irp);
239 break;
240 }
241 case IRP_MN_QUERY_ID:
242 {
243 //
244 // handle request
245 //
246 Status = USBCCGP_PdoHandleQueryId(DeviceObject, Irp);
247 break;
248 }
249 case IRP_MN_REMOVE_DEVICE:
250 {
251 DPRINT1("IRP_MN_REMOVE_DEVICE\n");
252
253 /* Complete the IRP */
254 Irp->IoStatus.Status = STATUS_SUCCESS;
255 IoCompleteRequest(Irp, IO_NO_INCREMENT);
256
257 /* Delete the device object */
258 IoDeleteDevice(DeviceObject);
259
260 return STATUS_SUCCESS;
261 }
262 case IRP_MN_QUERY_CAPABILITIES:
263 {
264 //
265 // copy device capabilities
266 //
267 RtlCopyMemory(IoStack->Parameters.DeviceCapabilities.Capabilities, &PDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES));
268
269 /* Complete the IRP */
270 Irp->IoStatus.Status = STATUS_SUCCESS;
271 IoCompleteRequest(Irp, IO_NO_INCREMENT);
272 return STATUS_SUCCESS;
273 }
274 case IRP_MN_START_DEVICE:
275 {
276 //
277 // no-op for PDO
278 //
279 DPRINT1("[USBCCGP] PDO IRP_MN_START\n");
280 Status = STATUS_SUCCESS;
281 break;
282 }
283 default:
284 {
285 //
286 // do nothing
287 //
288 Status = Irp->IoStatus.Status;
289 }
290 }
291
292 //
293 // complete request
294 //
295 if (Status != STATUS_PENDING)
296 {
297 //
298 // store result
299 //
300 Irp->IoStatus.Status = Status;
301
302 //
303 // complete request
304 //
305 IoCompleteRequest(Irp, IO_NO_INCREMENT);
306 }
307
308 //
309 // done processing
310 //
311 return Status;
312
313 }
314
315
316 NTSTATUS
317 PDO_Dispatch(
318 PDEVICE_OBJECT DeviceObject,
319 PIRP Irp)
320 {
321 PIO_STACK_LOCATION IoStack;
322 NTSTATUS Status;
323
324 /* get stack location */
325 IoStack = IoGetCurrentIrpStackLocation(Irp);
326
327 switch(IoStack->MajorFunction)
328 {
329 case IRP_MJ_PNP:
330 return PDO_HandlePnp(DeviceObject, Irp);
331 default:
332 DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction);
333 ASSERT(FALSE);
334 Status = Irp->IoStatus.Status;
335 IoCompleteRequest(Irp, IO_NO_INCREMENT);
336 return Status;
337 }
338
339 }