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("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
48 SourceString
= &DeviceExtension
->DeviceId
;
51 case BusQueryHardwareIDs
:
53 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
54 SourceString
= &DeviceExtension
->HardwareIds
;
57 case BusQueryCompatibleIDs
:
58 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
59 SourceString
= &DeviceExtension
->CompatibleIds
;
61 case BusQueryInstanceID
:
63 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
64 SourceString
= &DeviceExtension
->InstanceId
;
68 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
70 return STATUS_NOT_SUPPORTED
;
73 Status
= RtlDuplicateUnicodeString(
74 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
77 *Information
= (ULONG_PTR
)String
.Buffer
;
82 SerenumPdoQueryDeviceRelations(
83 IN PDEVICE_OBJECT DeviceObject
,
84 OUT PDEVICE_RELATIONS
* pDeviceRelations
)
86 PFDO_DEVICE_EXTENSION DeviceExtension
;
87 PDEVICE_RELATIONS DeviceRelations
;
89 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
90 ASSERT(DeviceExtension
->Common
.IsFDO
);
92 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePoolWithTag(
94 sizeof(DEVICE_RELATIONS
),
97 return STATUS_INSUFFICIENT_RESOURCES
;
99 ObReferenceObject(DeviceObject
);
100 DeviceRelations
->Count
= 1;
101 DeviceRelations
->Objects
[0] = DeviceObject
;
103 *pDeviceRelations
= DeviceRelations
;
104 return STATUS_SUCCESS
;
109 IN PDEVICE_OBJECT DeviceObject
,
113 PIO_STACK_LOCATION Stack
;
114 ULONG_PTR Information
= 0;
117 Stack
= IoGetCurrentIrpStackLocation(Irp
);
118 MinorFunction
= Stack
->MinorFunction
;
120 switch (MinorFunction
)
122 /* FIXME: do all these minor functions
123 IRP_MN_QUERY_REMOVE_DEVICE 0x1
124 IRP_MN_REMOVE_DEVICE 0x2
125 IRP_MN_CANCEL_REMOVE_DEVICE 0x3
126 IRP_MN_STOP_DEVICE 0x4
127 IRP_MN_QUERY_STOP_DEVICE 0x5
128 IRP_MN_CANCEL_STOP_DEVICE 0x6
129 IRP_MN_QUERY_DEVICE_RELATIONS / EjectionRelations (optional) 0x7
130 IRP_MN_QUERY_INTERFACE (required or optional) 0x8
131 IRP_MN_READ_CONFIG (required or optional) 0xf
132 IRP_MN_WRITE_CONFIG (required or optional) 0x10
133 IRP_MN_EJECT (required or optional) 0x11
134 IRP_MN_SET_LOCK (required or optional) 0x12
135 IRP_MN_QUERY_ID / BusQueryDeviceID 0x13
136 IRP_MN_QUERY_ID / BusQueryCompatibleIDs (optional) 0x13
137 IRP_MN_QUERY_ID / BusQueryInstanceID (optional) 0x13
138 IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
139 IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
140 IRP_MN_SURPRISE_REMOVAL 0x17
142 case IRP_MN_START_DEVICE
: /* 0x0 */
144 DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
145 Status
= SerenumPdoStartDevice(DeviceObject
);
148 case IRP_MN_QUERY_DEVICE_RELATIONS
: /* 0x7 */
150 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
152 case RemovalRelations
:
154 return ForwardIrpToAttachedFdoAndForget(DeviceObject
, Irp
);
156 case TargetDeviceRelation
:
158 PDEVICE_RELATIONS DeviceRelations
= NULL
;
159 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
160 Status
= SerenumPdoQueryDeviceRelations(DeviceObject
, &DeviceRelations
);
161 Information
= (ULONG_PTR
)DeviceRelations
;
166 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
167 Stack
->Parameters
.QueryDeviceRelations
.Type
);
169 Status
= STATUS_NOT_IMPLEMENTED
;
175 case IRP_MN_QUERY_CAPABILITIES
: /* 0x9 */
177 PDEVICE_CAPABILITIES DeviceCapabilities
;
179 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
181 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)Stack
->Parameters
.DeviceCapabilities
.Capabilities
;
182 /* FIXME: capabilities can change with connected device */
183 DeviceCapabilities
->LockSupported
= FALSE
;
184 DeviceCapabilities
->EjectSupported
= FALSE
;
185 DeviceCapabilities
->Removable
= TRUE
;
186 DeviceCapabilities
->DockDevice
= FALSE
;
187 DeviceCapabilities
->UniqueID
= FALSE
;
188 DeviceCapabilities
->SilentInstall
= FALSE
;
189 DeviceCapabilities
->RawDeviceOK
= TRUE
;
190 DeviceCapabilities
->SurpriseRemovalOK
= TRUE
;
191 DeviceCapabilities
->HardwareDisabled
= FALSE
; /* FIXME */
192 //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
193 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
; /* FIXME */
194 for (i
= 0; i
< PowerSystemMaximum
; i
++)
195 DeviceCapabilities
->DeviceState
[i
] = PowerDeviceD3
; /* FIXME */
196 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
197 DeviceCapabilities
->D1Latency
= 0; /* FIXME */
198 DeviceCapabilities
->D2Latency
= 0; /* FIXME */
199 DeviceCapabilities
->D3Latency
= 0; /* FIXME */
200 Status
= STATUS_SUCCESS
;
203 case IRP_MN_QUERY_RESOURCES
: /* 0xa */
205 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
206 /* Serial devices don't need resources, except the ones of
207 * the serial port. This PDO is the serial device PDO, so
208 * report no resource by not changing Information and
211 Information
= Irp
->IoStatus
.Information
;
212 Status
= Irp
->IoStatus
.Status
;
215 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
: /* 0xb */
217 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
218 /* Serial devices don't need resources, except the ones of
219 * the serial port. This PDO is the serial device PDO, so
220 * report no resource by not changing Information and
223 Information
= Irp
->IoStatus
.Information
;
224 Status
= Irp
->IoStatus
.Status
;
227 case IRP_MN_QUERY_DEVICE_TEXT
: /* 0xc */
229 switch (Stack
->Parameters
.QueryDeviceText
.DeviceTextType
)
231 case DeviceTextDescription
:
233 PUNICODE_STRING Source
;
235 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
237 Source
= &((PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->DeviceDescription
;
238 Description
= ExAllocatePoolWithTag(PagedPool
, Source
->Length
+ sizeof(WCHAR
), SERENUM_TAG
);
240 Status
= STATUS_INSUFFICIENT_RESOURCES
;
243 RtlCopyMemory(Description
, Source
->Buffer
, Source
->Length
);
244 Description
[Source
->Length
/ sizeof(WCHAR
)] = L
'\0';
245 Information
= (ULONG_PTR
)Description
;
246 Status
= STATUS_SUCCESS
;
250 case DeviceTextLocationInformation
:
252 /* We don't have any text location to report,
253 * and this query is optional, so ignore it.
255 Information
= Irp
->IoStatus
.Information
;
256 Status
= Irp
->IoStatus
.Status
;
261 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
262 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("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
283 BusInfo
= (PPNP_BUS_INFORMATION
)ExAllocatePoolWithTag(PagedPool
, sizeof(PNP_BUS_INFORMATION
), SERENUM_TAG
);
285 Status
= STATUS_INSUFFICIENT_RESOURCES
;
289 &BusInfo
->BusTypeGuid
,
290 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
,
291 sizeof(BusInfo
->BusTypeGuid
));
292 BusInfo
->LegacyBusType
= PNPBus
;
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("IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
306 Information
= Irp
->IoStatus
.Information
;
307 Status
= Irp
->IoStatus
.Status
;
311 Irp
->IoStatus
.Information
= Information
;
312 Irp
->IoStatus
.Status
= Status
;
313 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);