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.org)
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 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
49 SourceString
= &DeviceExtension
->DeviceId
;
52 case BusQueryHardwareIDs
:
54 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
55 SourceString
= &DeviceExtension
->HardwareIds
;
58 case BusQueryCompatibleIDs
:
59 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
60 SourceString
= &DeviceExtension
->CompatibleIds
;
62 case BusQueryInstanceID
:
64 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
65 SourceString
= &DeviceExtension
->InstanceId
;
69 WARN_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
71 return STATUS_NOT_SUPPORTED
;
74 Status
= DuplicateUnicodeString(
75 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
78 *Information
= (ULONG_PTR
)String
.Buffer
;
83 SerenumPdoQueryDeviceRelations(
84 IN PDEVICE_OBJECT DeviceObject
,
85 OUT PDEVICE_RELATIONS
* pDeviceRelations
)
87 PFDO_DEVICE_EXTENSION DeviceExtension
;
88 PDEVICE_RELATIONS DeviceRelations
;
90 DeviceExtension
= (PFDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
91 ASSERT(DeviceExtension
->Common
.IsFDO
);
93 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePoolWithTag(
95 sizeof(DEVICE_RELATIONS
),
98 return STATUS_INSUFFICIENT_RESOURCES
;
100 ObReferenceObject(DeviceObject
);
101 DeviceRelations
->Count
= 1;
102 DeviceRelations
->Objects
[0] = DeviceObject
;
104 *pDeviceRelations
= DeviceRelations
;
105 return STATUS_SUCCESS
;
110 IN PDEVICE_OBJECT DeviceObject
,
114 PIO_STACK_LOCATION Stack
;
115 ULONG_PTR Information
= 0;
118 Stack
= IoGetCurrentIrpStackLocation(Irp
);
119 MinorFunction
= Stack
->MinorFunction
;
121 switch (MinorFunction
)
123 /* FIXME: do all these minor functions
124 IRP_MN_QUERY_REMOVE_DEVICE 0x1
125 IRP_MN_REMOVE_DEVICE 0x2
126 IRP_MN_CANCEL_REMOVE_DEVICE 0x3
127 IRP_MN_STOP_DEVICE 0x4
128 IRP_MN_QUERY_STOP_DEVICE 0x5
129 IRP_MN_CANCEL_STOP_DEVICE 0x6
130 IRP_MN_QUERY_DEVICE_RELATIONS / EjectionRelations (optional) 0x7
131 IRP_MN_QUERY_INTERFACE (required or optional) 0x8
132 IRP_MN_READ_CONFIG (required or optional) 0xf
133 IRP_MN_WRITE_CONFIG (required or optional) 0x10
134 IRP_MN_EJECT (required or optional) 0x11
135 IRP_MN_SET_LOCK (required or optional) 0x12
136 IRP_MN_QUERY_ID / BusQueryDeviceID 0x13
137 IRP_MN_QUERY_ID / BusQueryCompatibleIDs (optional) 0x13
138 IRP_MN_QUERY_ID / BusQueryInstanceID (optional) 0x13
139 IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
140 IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
141 IRP_MN_SURPRISE_REMOVAL 0x17
143 case IRP_MN_START_DEVICE
: /* 0x0 */
145 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
146 Status
= SerenumPdoStartDevice(DeviceObject
);
149 case IRP_MN_QUERY_DEVICE_RELATIONS
: /* 0x7 */
151 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
153 case RemovalRelations
:
155 return ForwardIrpToAttachedFdoAndForget(DeviceObject
, Irp
);
157 case TargetDeviceRelation
:
159 PDEVICE_RELATIONS DeviceRelations
= NULL
;
160 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
161 Status
= SerenumPdoQueryDeviceRelations(DeviceObject
, &DeviceRelations
);
162 Information
= (ULONG_PTR
)DeviceRelations
;
167 WARN_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
168 Stack
->Parameters
.QueryDeviceRelations
.Type
);
170 Status
= STATUS_NOT_IMPLEMENTED
;
176 case IRP_MN_QUERY_CAPABILITIES
: /* 0x9 */
178 PDEVICE_CAPABILITIES DeviceCapabilities
;
180 TRACE_(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 TRACE_(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 TRACE_(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 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
238 Source
= &((PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->DeviceDescription
;
239 Description
= ExAllocatePoolWithTag(PagedPool
, Source
->Length
+ sizeof(WCHAR
), SERENUM_TAG
);
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 WARN_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
263 Stack
->Parameters
.QueryDeviceText
.DeviceTextType
);
265 Status
= STATUS_NOT_SUPPORTED
;
270 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
: /* 0xd */
272 return ForwardIrpToAttachedFdoAndForget(DeviceObject
, Irp
);
274 case IRP_MN_QUERY_ID
: /* 0x13 */
276 Status
= SerenumPdoQueryId(DeviceObject
, Irp
, &Information
);
279 case IRP_MN_QUERY_BUS_INFORMATION
: /* 0x15 */
281 PPNP_BUS_INFORMATION BusInfo
;
282 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
284 BusInfo
= (PPNP_BUS_INFORMATION
)ExAllocatePoolWithTag(PagedPool
, sizeof(PNP_BUS_INFORMATION
), SERENUM_TAG
);
286 Status
= STATUS_INSUFFICIENT_RESOURCES
;
290 &BusInfo
->BusTypeGuid
,
291 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
,
292 sizeof(BusInfo
->BusTypeGuid
));
293 BusInfo
->LegacyBusType
= PNPBus
;
294 /* We're the only serial bus enumerator on the computer */
295 BusInfo
->BusNumber
= 0;
296 Information
= (ULONG_PTR
)BusInfo
;
297 Status
= STATUS_SUCCESS
;
303 /* We can't forward request to the lower driver, because
304 * we are a Pdo, so we don't have lower driver... */
305 WARN_(SERENUM
, "IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction
);
307 Information
= Irp
->IoStatus
.Information
;
308 Status
= Irp
->IoStatus
.Status
;
312 Irp
->IoStatus
.Information
= Information
;
313 Irp
->IoStatus
.Status
= Status
;
314 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);