3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS Serial enumerator driver
5 * FILE: drivers/bus/serenum/pdo.c
6 * PURPOSE: IRP_MJ_PNP operations for PDOs
8 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.com)
15 SerenumPdoStartDevice(
16 IN PDEVICE_OBJECT DeviceObject
)
18 PPDO_DEVICE_EXTENSION DeviceExtension
;
20 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
22 ASSERT(DeviceExtension
->Common
.PnpState
== dsStopped
);
24 DeviceExtension
->Common
.PnpState
= dsStarted
;
25 return STATUS_SUCCESS
;
30 IN PDEVICE_OBJECT DeviceObject
,
32 OUT ULONG_PTR
* Information
)
34 PPDO_DEVICE_EXTENSION DeviceExtension
;
36 PUNICODE_STRING SourceString
;
37 UNICODE_STRING String
;
40 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
41 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
42 RtlInitUnicodeString(&String
, NULL
);
46 case BusQueryDeviceID
:
48 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
49 SourceString
= &DeviceExtension
->DeviceId
;
52 case BusQueryHardwareIDs
:
54 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
55 SourceString
= &DeviceExtension
->HardwareIds
;
58 case BusQueryCompatibleIDs
:
59 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
60 SourceString
= &DeviceExtension
->CompatibleIds
;
62 case BusQueryInstanceID
:
64 /* We don't have any instance id to report, and
65 * this query is optional, so ignore it.
67 *Information
= Irp
->IoStatus
.Information
;
68 return Irp
->IoStatus
.Status
;
71 DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
72 return STATUS_NOT_SUPPORTED
;
75 Status
= SerenumDuplicateUnicodeString(
79 *Information
= (ULONG_PTR
)String
.Buffer
;
84 SerenumPdoQueryDeviceRelations(
85 IN PDEVICE_OBJECT DeviceObject
,
86 OUT PDEVICE_RELATIONS
* pDeviceRelations
)
88 PFDO_DEVICE_EXTENSION DeviceExtension
;
89 PDEVICE_RELATIONS DeviceRelations
;
91 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
92 ASSERT(DeviceExtension
->Common
.IsFDO
);
94 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePoolWithTag(
96 sizeof(DEVICE_RELATIONS
),
99 return STATUS_INSUFFICIENT_RESOURCES
;
101 ObReferenceObject(DeviceObject
);
102 DeviceRelations
->Count
= 1;
103 DeviceRelations
->Objects
[0] = DeviceObject
;
105 *pDeviceRelations
= DeviceRelations
;
106 return STATUS_SUCCESS
;
111 IN PDEVICE_OBJECT DeviceObject
,
115 PIO_STACK_LOCATION Stack
;
116 ULONG_PTR Information
= 0;
119 Stack
= IoGetCurrentIrpStackLocation(Irp
);
120 MinorFunction
= Stack
->MinorFunction
;
122 switch (MinorFunction
)
124 /* FIXME: do all these minor functions
125 IRP_MN_QUERY_REMOVE_DEVICE 0x1
126 IRP_MN_REMOVE_DEVICE 0x2
127 IRP_MN_CANCEL_REMOVE_DEVICE 0x3
128 IRP_MN_STOP_DEVICE 0x4
129 IRP_MN_QUERY_STOP_DEVICE 0x5
130 IRP_MN_CANCEL_STOP_DEVICE 0x6
131 IRP_MN_QUERY_DEVICE_RELATIONS / EjectionRelations (optional) 0x7
132 IRP_MN_QUERY_INTERFACE (required or optional) 0x8
133 IRP_MN_READ_CONFIG (required or optional) 0xf
134 IRP_MN_WRITE_CONFIG (required or optional) 0x10
135 IRP_MN_EJECT (required or optional) 0x11
136 IRP_MN_SET_LOCK (required or optional) 0x12
137 IRP_MN_QUERY_ID / BusQueryDeviceID 0x13
138 IRP_MN_QUERY_ID / BusQueryCompatibleIDs (optional) 0x13
139 IRP_MN_QUERY_ID / BusQueryInstanceID (optional) 0x13
140 IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
141 IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
142 IRP_MN_SURPRISE_REMOVAL 0x17
144 case IRP_MN_START_DEVICE
: /* 0x0 */
146 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
147 Status
= SerenumPdoStartDevice(DeviceObject
);
150 case IRP_MN_QUERY_DEVICE_RELATIONS
: /* 0x7 */
152 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
154 case RemovalRelations
:
156 return ForwardIrpToAttachedFdoAndForget(DeviceObject
, Irp
);
158 case TargetDeviceRelation
:
160 PDEVICE_RELATIONS DeviceRelations
= NULL
;
161 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
162 Status
= SerenumPdoQueryDeviceRelations(DeviceObject
, &DeviceRelations
);
163 Information
= (ULONG_PTR
)DeviceRelations
;
168 DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
169 Stack
->Parameters
.QueryDeviceRelations
.Type
);
170 Status
= STATUS_NOT_IMPLEMENTED
;
176 case IRP_MN_QUERY_CAPABILITIES
: /* 0x9 */
178 PDEVICE_CAPABILITIES DeviceCapabilities
;
180 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
182 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)Stack
->Parameters
.DeviceCapabilities
.Capabilities
;
183 /* FIXME: capabilities can change with connected device */
184 DeviceCapabilities
->LockSupported
= FALSE
;
185 DeviceCapabilities
->EjectSupported
= FALSE
;
186 DeviceCapabilities
->Removable
= TRUE
;
187 DeviceCapabilities
->DockDevice
= FALSE
;
188 DeviceCapabilities
->UniqueID
= FALSE
;
189 DeviceCapabilities
->SilentInstall
= FALSE
;
190 DeviceCapabilities
->RawDeviceOK
= TRUE
;
191 DeviceCapabilities
->SurpriseRemovalOK
= TRUE
;
192 DeviceCapabilities
->HardwareDisabled
= FALSE
; /* FIXME */
193 //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
194 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
; /* FIXME */
195 for (i
= 0; i
< PowerSystemMaximum
; i
++)
196 DeviceCapabilities
->DeviceState
[i
] = PowerDeviceD3
; /* FIXME */
197 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
198 DeviceCapabilities
->D1Latency
= 0; /* FIXME */
199 DeviceCapabilities
->D2Latency
= 0; /* FIXME */
200 DeviceCapabilities
->D3Latency
= 0; /* FIXME */
201 Status
= STATUS_SUCCESS
;
204 case IRP_MN_QUERY_RESOURCES
: /* 0xa */
206 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
207 /* Serial devices don't need resources, except the ones of
208 * the serial port. This PDO is the serial device PDO, so
209 * report no resource by not changing Information and
212 Information
= Irp
->IoStatus
.Information
;
213 Status
= Irp
->IoStatus
.Status
;
216 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
: /* 0xb */
218 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
219 /* Serial devices don't need resources, except the ones of
220 * the serial port. This PDO is the serial device PDO, so
221 * report no resource by not changing Information and
224 Information
= Irp
->IoStatus
.Information
;
225 Status
= Irp
->IoStatus
.Status
;
228 case IRP_MN_QUERY_DEVICE_TEXT
: /* 0xc */
230 switch (Stack
->Parameters
.QueryDeviceText
.DeviceTextType
)
232 case DeviceTextDescription
:
234 PUNICODE_STRING Source
;
236 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
238 Source
= &((PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->DeviceDescription
;
239 Description
= ExAllocatePool(PagedPool
, Source
->Length
+ sizeof(WCHAR
));
241 Status
= STATUS_INSUFFICIENT_RESOURCES
;
244 RtlCopyMemory(Description
, Source
->Buffer
, Source
->Length
);
245 Description
[Source
->Length
/ sizeof(WCHAR
)] = L
'\0';
246 Information
= (ULONG_PTR
)Description
;
247 Status
= STATUS_SUCCESS
;
251 case DeviceTextLocationInformation
:
253 /* We don't have any text location to report,
254 * and this query is optional, so ignore it.
256 Information
= Irp
->IoStatus
.Information
;
257 Status
= Irp
->IoStatus
.Status
;
262 DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
263 Stack
->Parameters
.QueryDeviceText
.DeviceTextType
);
264 Status
= STATUS_NOT_SUPPORTED
;
269 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
: /* 0xd */
271 return ForwardIrpToAttachedFdoAndForget(DeviceObject
, Irp
);
273 case IRP_MN_QUERY_ID
: /* 0x13 */
275 Status
= SerenumPdoQueryId(DeviceObject
, Irp
, &Information
);
278 case IRP_MN_QUERY_BUS_INFORMATION
: /* 0x15 */
280 PPNP_BUS_INFORMATION BusInfo
;
281 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
283 BusInfo
= (PPNP_BUS_INFORMATION
)ExAllocatePool(PagedPool
, sizeof(PNP_BUS_INFORMATION
));
285 Status
= STATUS_INSUFFICIENT_RESOURCES
;
288 BusInfo
->BusTypeGuid
= GUID_BUS_TYPE_SERENUM
;
289 /* FIXME: real value should be PNPBus, but PNPBus seems to be
290 * the only value in INTERFACE_TYPE enum that doesn't work...
292 BusInfo
->LegacyBusType
= PNPISABus
;
293 /* We're the only serial bus enumerator on the computer */
294 BusInfo
->BusNumber
= 0;
295 Information
= (ULONG_PTR
)BusInfo
;
296 Status
= STATUS_SUCCESS
;
302 /* We can't forward request to the lower driver, because
303 * we are a Pdo, so we don't have lower driver... */
304 DPRINT1("Serenum: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
305 Information
= Irp
->IoStatus
.Information
;
306 Status
= Irp
->IoStatus
.Status
;
310 Irp
->IoStatus
.Information
= Information
;
311 Irp
->IoStatus
.Status
= Status
;
312 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);