2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Serial enumerator driver
4 * FILE: drivers/bus/serenum/pdo.c
5 * PURPOSE: IRP_MJ_PNP operations for PDOs
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.com)
14 SerenumPdoStartDevice(
15 IN PDEVICE_OBJECT DeviceObject
)
17 PPDO_DEVICE_EXTENSION DeviceExtension
;
19 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
21 ASSERT(DeviceExtension
->Common
.PnpState
== dsStopped
);
23 DeviceExtension
->Common
.PnpState
= dsStarted
;
24 return STATUS_SUCCESS
;
29 IN PDEVICE_OBJECT DeviceObject
,
31 OUT ULONG_PTR
* Information
)
33 PPDO_DEVICE_EXTENSION DeviceExtension
;
35 PUNICODE_STRING SourceString
;
36 UNICODE_STRING String
;
39 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
40 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
41 RtlInitUnicodeString(&String
, NULL
);
45 case BusQueryDeviceID
:
47 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
48 SourceString
= &DeviceExtension
->DeviceId
;
51 case BusQueryHardwareIDs
:
53 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
54 SourceString
= &DeviceExtension
->HardwareIds
;
57 case BusQueryCompatibleIDs
:
58 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
59 SourceString
= &DeviceExtension
->CompatibleIds
;
61 case BusQueryInstanceID
:
63 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
64 SourceString
= &DeviceExtension
->InstanceId
;
68 DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
69 return STATUS_NOT_SUPPORTED
;
72 Status
= RtlDuplicateUnicodeString(
73 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
76 *Information
= (ULONG_PTR
)String
.Buffer
;
81 SerenumPdoQueryDeviceRelations(
82 IN PDEVICE_OBJECT DeviceObject
,
83 OUT PDEVICE_RELATIONS
* pDeviceRelations
)
85 PFDO_DEVICE_EXTENSION DeviceExtension
;
86 PDEVICE_RELATIONS DeviceRelations
;
88 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
89 ASSERT(DeviceExtension
->Common
.IsFDO
);
91 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePoolWithTag(
93 sizeof(DEVICE_RELATIONS
),
96 return STATUS_INSUFFICIENT_RESOURCES
;
98 ObReferenceObject(DeviceObject
);
99 DeviceRelations
->Count
= 1;
100 DeviceRelations
->Objects
[0] = DeviceObject
;
102 *pDeviceRelations
= DeviceRelations
;
103 return STATUS_SUCCESS
;
108 IN PDEVICE_OBJECT DeviceObject
,
112 PIO_STACK_LOCATION Stack
;
113 ULONG_PTR Information
= 0;
116 Stack
= IoGetCurrentIrpStackLocation(Irp
);
117 MinorFunction
= Stack
->MinorFunction
;
119 switch (MinorFunction
)
121 /* FIXME: do all these minor functions
122 IRP_MN_QUERY_REMOVE_DEVICE 0x1
123 IRP_MN_REMOVE_DEVICE 0x2
124 IRP_MN_CANCEL_REMOVE_DEVICE 0x3
125 IRP_MN_STOP_DEVICE 0x4
126 IRP_MN_QUERY_STOP_DEVICE 0x5
127 IRP_MN_CANCEL_STOP_DEVICE 0x6
128 IRP_MN_QUERY_DEVICE_RELATIONS / EjectionRelations (optional) 0x7
129 IRP_MN_QUERY_INTERFACE (required or optional) 0x8
130 IRP_MN_READ_CONFIG (required or optional) 0xf
131 IRP_MN_WRITE_CONFIG (required or optional) 0x10
132 IRP_MN_EJECT (required or optional) 0x11
133 IRP_MN_SET_LOCK (required or optional) 0x12
134 IRP_MN_QUERY_ID / BusQueryDeviceID 0x13
135 IRP_MN_QUERY_ID / BusQueryCompatibleIDs (optional) 0x13
136 IRP_MN_QUERY_ID / BusQueryInstanceID (optional) 0x13
137 IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
138 IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
139 IRP_MN_SURPRISE_REMOVAL 0x17
141 case IRP_MN_START_DEVICE
: /* 0x0 */
143 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
144 Status
= SerenumPdoStartDevice(DeviceObject
);
147 case IRP_MN_QUERY_DEVICE_RELATIONS
: /* 0x7 */
149 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
151 case RemovalRelations
:
153 return ForwardIrpToAttachedFdoAndForget(DeviceObject
, Irp
);
155 case TargetDeviceRelation
:
157 PDEVICE_RELATIONS DeviceRelations
= NULL
;
158 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
159 Status
= SerenumPdoQueryDeviceRelations(DeviceObject
, &DeviceRelations
);
160 Information
= (ULONG_PTR
)DeviceRelations
;
165 DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
166 Stack
->Parameters
.QueryDeviceRelations
.Type
);
167 Status
= STATUS_NOT_IMPLEMENTED
;
173 case IRP_MN_QUERY_CAPABILITIES
: /* 0x9 */
175 PDEVICE_CAPABILITIES DeviceCapabilities
;
177 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
179 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)Stack
->Parameters
.DeviceCapabilities
.Capabilities
;
180 /* FIXME: capabilities can change with connected device */
181 DeviceCapabilities
->LockSupported
= FALSE
;
182 DeviceCapabilities
->EjectSupported
= FALSE
;
183 DeviceCapabilities
->Removable
= TRUE
;
184 DeviceCapabilities
->DockDevice
= FALSE
;
185 DeviceCapabilities
->UniqueID
= FALSE
;
186 DeviceCapabilities
->SilentInstall
= FALSE
;
187 DeviceCapabilities
->RawDeviceOK
= TRUE
;
188 DeviceCapabilities
->SurpriseRemovalOK
= TRUE
;
189 DeviceCapabilities
->HardwareDisabled
= FALSE
; /* FIXME */
190 //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
191 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
; /* FIXME */
192 for (i
= 0; i
< PowerSystemMaximum
; i
++)
193 DeviceCapabilities
->DeviceState
[i
] = PowerDeviceD3
; /* FIXME */
194 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
195 DeviceCapabilities
->D1Latency
= 0; /* FIXME */
196 DeviceCapabilities
->D2Latency
= 0; /* FIXME */
197 DeviceCapabilities
->D3Latency
= 0; /* FIXME */
198 Status
= STATUS_SUCCESS
;
201 case IRP_MN_QUERY_RESOURCES
: /* 0xa */
203 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
204 /* Serial devices don't need resources, except the ones of
205 * the serial port. This PDO is the serial device PDO, so
206 * report no resource by not changing Information and
209 Information
= Irp
->IoStatus
.Information
;
210 Status
= Irp
->IoStatus
.Status
;
213 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
: /* 0xb */
215 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
216 /* Serial devices don't need resources, except the ones of
217 * the serial port. This PDO is the serial device PDO, so
218 * report no resource by not changing Information and
221 Information
= Irp
->IoStatus
.Information
;
222 Status
= Irp
->IoStatus
.Status
;
225 case IRP_MN_QUERY_DEVICE_TEXT
: /* 0xc */
227 switch (Stack
->Parameters
.QueryDeviceText
.DeviceTextType
)
229 case DeviceTextDescription
:
231 PUNICODE_STRING Source
;
233 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
235 Source
= &((PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->DeviceDescription
;
236 Description
= ExAllocatePoolWithTag(PagedPool
, Source
->Length
+ sizeof(WCHAR
), SERENUM_TAG
);
238 Status
= STATUS_INSUFFICIENT_RESOURCES
;
241 RtlCopyMemory(Description
, Source
->Buffer
, Source
->Length
);
242 Description
[Source
->Length
/ sizeof(WCHAR
)] = L
'\0';
243 Information
= (ULONG_PTR
)Description
;
244 Status
= STATUS_SUCCESS
;
248 case DeviceTextLocationInformation
:
250 /* We don't have any text location to report,
251 * and this query is optional, so ignore it.
253 Information
= Irp
->IoStatus
.Information
;
254 Status
= Irp
->IoStatus
.Status
;
259 DPRINT1("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
260 Stack
->Parameters
.QueryDeviceText
.DeviceTextType
);
261 Status
= STATUS_NOT_SUPPORTED
;
266 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
: /* 0xd */
268 return ForwardIrpToAttachedFdoAndForget(DeviceObject
, Irp
);
270 case IRP_MN_QUERY_ID
: /* 0x13 */
272 Status
= SerenumPdoQueryId(DeviceObject
, Irp
, &Information
);
275 case IRP_MN_QUERY_BUS_INFORMATION
: /* 0x15 */
277 PPNP_BUS_INFORMATION BusInfo
;
278 DPRINT("Serenum: IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
280 BusInfo
= (PPNP_BUS_INFORMATION
)ExAllocatePoolWithTag(PagedPool
, sizeof(PNP_BUS_INFORMATION
), SERENUM_TAG
);
282 Status
= STATUS_INSUFFICIENT_RESOURCES
;
286 &BusInfo
->BusTypeGuid
,
287 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
,
288 sizeof(BusInfo
->BusTypeGuid
));
289 BusInfo
->LegacyBusType
= PNPBus
;
290 /* We're the only serial bus enumerator on the computer */
291 BusInfo
->BusNumber
= 0;
292 Information
= (ULONG_PTR
)BusInfo
;
293 Status
= STATUS_SUCCESS
;
299 /* We can't forward request to the lower driver, because
300 * we are a Pdo, so we don't have lower driver... */
301 DPRINT1("Serenum: IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
302 Information
= Irp
->IoStatus
.Information
;
303 Status
= Irp
->IoStatus
.Status
;
307 Irp
->IoStatus
.Information
= Information
;
308 Irp
->IoStatus
.Status
= Status
;
309 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);