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)
13 SerenumPdoStartDevice(
14 IN PDEVICE_OBJECT DeviceObject
)
16 PPDO_DEVICE_EXTENSION DeviceExtension
;
18 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
20 ASSERT(DeviceExtension
->Common
.PnpState
== dsStopped
);
22 DeviceExtension
->Common
.PnpState
= dsStarted
;
23 return STATUS_SUCCESS
;
28 IN PDEVICE_OBJECT DeviceObject
,
30 OUT ULONG_PTR
* Information
)
32 PPDO_DEVICE_EXTENSION DeviceExtension
;
34 PUNICODE_STRING SourceString
;
35 UNICODE_STRING String
;
38 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
39 DeviceExtension
= (PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
40 RtlInitUnicodeString(&String
, NULL
);
44 case BusQueryDeviceID
:
46 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
47 SourceString
= &DeviceExtension
->DeviceId
;
50 case BusQueryHardwareIDs
:
52 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
53 SourceString
= &DeviceExtension
->HardwareIds
;
56 case BusQueryCompatibleIDs
:
57 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
58 SourceString
= &DeviceExtension
->CompatibleIds
;
60 case BusQueryInstanceID
:
62 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
63 SourceString
= &DeviceExtension
->InstanceId
;
67 WARN_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
69 return STATUS_NOT_SUPPORTED
;
72 Status
= DuplicateUnicodeString(
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 TRACE_(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 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
159 Status
= SerenumPdoQueryDeviceRelations(DeviceObject
, &DeviceRelations
);
160 Information
= (ULONG_PTR
)DeviceRelations
;
165 WARN_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
166 Stack
->Parameters
.QueryDeviceRelations
.Type
);
168 Status
= STATUS_NOT_IMPLEMENTED
;
174 case IRP_MN_QUERY_CAPABILITIES
: /* 0x9 */
176 PDEVICE_CAPABILITIES DeviceCapabilities
;
178 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
180 DeviceCapabilities
= (PDEVICE_CAPABILITIES
)Stack
->Parameters
.DeviceCapabilities
.Capabilities
;
181 /* FIXME: capabilities can change with connected device */
182 DeviceCapabilities
->LockSupported
= FALSE
;
183 DeviceCapabilities
->EjectSupported
= FALSE
;
184 DeviceCapabilities
->Removable
= TRUE
;
185 DeviceCapabilities
->DockDevice
= FALSE
;
186 DeviceCapabilities
->UniqueID
= FALSE
;
187 DeviceCapabilities
->SilentInstall
= FALSE
;
188 DeviceCapabilities
->RawDeviceOK
= TRUE
;
189 DeviceCapabilities
->SurpriseRemovalOK
= TRUE
;
190 DeviceCapabilities
->HardwareDisabled
= FALSE
; /* FIXME */
191 //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
192 DeviceCapabilities
->DeviceState
[0] = PowerDeviceD0
; /* FIXME */
193 for (i
= 0; i
< PowerSystemMaximum
; i
++)
194 DeviceCapabilities
->DeviceState
[i
] = PowerDeviceD3
; /* FIXME */
195 //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
196 DeviceCapabilities
->D1Latency
= 0; /* FIXME */
197 DeviceCapabilities
->D2Latency
= 0; /* FIXME */
198 DeviceCapabilities
->D3Latency
= 0; /* FIXME */
199 Status
= STATUS_SUCCESS
;
202 case IRP_MN_QUERY_RESOURCES
: /* 0xa */
204 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
205 /* Serial devices don't need resources, except the ones of
206 * the serial port. This PDO is the serial device PDO, so
207 * report no resource by not changing Information and
210 Information
= Irp
->IoStatus
.Information
;
211 Status
= Irp
->IoStatus
.Status
;
214 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
: /* 0xb */
216 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
217 /* Serial devices don't need resources, except the ones of
218 * the serial port. This PDO is the serial device PDO, so
219 * report no resource by not changing Information and
222 Information
= Irp
->IoStatus
.Information
;
223 Status
= Irp
->IoStatus
.Status
;
226 case IRP_MN_QUERY_DEVICE_TEXT
: /* 0xc */
228 switch (Stack
->Parameters
.QueryDeviceText
.DeviceTextType
)
230 case DeviceTextDescription
:
232 PUNICODE_STRING Source
;
234 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription\n");
236 Source
= &((PPDO_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->DeviceDescription
;
237 Description
= ExAllocatePoolWithTag(PagedPool
, Source
->Length
+ sizeof(WCHAR
), SERENUM_TAG
);
239 Status
= STATUS_INSUFFICIENT_RESOURCES
;
242 RtlCopyMemory(Description
, Source
->Buffer
, Source
->Length
);
243 Description
[Source
->Length
/ sizeof(WCHAR
)] = L
'\0';
244 Information
= (ULONG_PTR
)Description
;
245 Status
= STATUS_SUCCESS
;
249 case DeviceTextLocationInformation
:
251 /* We don't have any text location to report,
252 * and this query is optional, so ignore it.
254 Information
= Irp
->IoStatus
.Information
;
255 Status
= Irp
->IoStatus
.Status
;
260 WARN_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
261 Stack
->Parameters
.QueryDeviceText
.DeviceTextType
);
263 Status
= STATUS_NOT_SUPPORTED
;
268 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
: /* 0xd */
270 return ForwardIrpToAttachedFdoAndForget(DeviceObject
, Irp
);
272 case IRP_MN_QUERY_ID
: /* 0x13 */
274 Status
= SerenumPdoQueryId(DeviceObject
, Irp
, &Information
);
277 case IRP_MN_QUERY_BUS_INFORMATION
: /* 0x15 */
279 PPNP_BUS_INFORMATION BusInfo
;
280 TRACE_(SERENUM
, "IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
282 BusInfo
= (PPNP_BUS_INFORMATION
)ExAllocatePoolWithTag(PagedPool
, sizeof(PNP_BUS_INFORMATION
), SERENUM_TAG
);
284 Status
= STATUS_INSUFFICIENT_RESOURCES
;
288 &BusInfo
->BusTypeGuid
,
289 &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
,
290 sizeof(BusInfo
->BusTypeGuid
));
291 BusInfo
->LegacyBusType
= PNPBus
;
292 /* We're the only serial bus enumerator on the computer */
293 BusInfo
->BusNumber
= 0;
294 Information
= (ULONG_PTR
)BusInfo
;
295 Status
= STATUS_SUCCESS
;
301 /* We can't forward request to the lower driver, because
302 * we are a Pdo, so we don't have lower driver... */
303 WARN_(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
);