ReactOS  0.4.15-dev-1207-g698a8e6
pdo.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS ISA PnP Bus driver
3  * FILE: pdo.c
4  * PURPOSE: PDO-specific code
5  * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
6  * HervĂ© Poussineau
7  */
8 
9 #include <isapnp.h>
10 
11 #define NDEBUG
12 #include <debug.h>
13 
15 NTAPI
18  IN PIRP Irp,
20 {
21  PDEVICE_RELATIONS DeviceRelations;
22 
23  if (IrpSp->Parameters.QueryDeviceRelations.Type == RemovalRelations &&
24  PdoExt->Common.Self == PdoExt->FdoExt->DataPortPdo)
25  {
26  return IsaPnpFillDeviceRelations(PdoExt->FdoExt, Irp, FALSE);
27  }
28 
29  if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
30  return Irp->IoStatus.Status;
31 
32  DeviceRelations = ExAllocatePool(PagedPool, sizeof(*DeviceRelations));
33  if (!DeviceRelations)
34  return STATUS_NO_MEMORY;
35 
36  DeviceRelations->Count = 1;
37  DeviceRelations->Objects[0] = PdoExt->Common.Self;
39 
40  Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
41 
42  return STATUS_SUCCESS;
43 }
44 
46 NTAPI
49  IN PIRP Irp,
51 {
53  PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
54  ULONG i;
55 
56  DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
57  if (DeviceCapabilities->Version != 1)
59 
60  if (LogDev)
61  {
62  DeviceCapabilities->UniqueID = TRUE;
63  DeviceCapabilities->Address = LogDev->CSN;
64  }
65  else
66  {
67  DeviceCapabilities->UniqueID = FALSE;
68  DeviceCapabilities->RawDeviceOK = TRUE;
69  DeviceCapabilities->SilentInstall = TRUE;
70  }
71 
72  for (i = 0; i < POWER_SYSTEM_MAXIMUM; i++)
73  DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
75 
76  return STATUS_SUCCESS;
77 }
78 
80 NTAPI
83  IN PIRP Irp,
85 {
86  Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
87  return STATUS_SUCCESS;
88 }
89 
91 NTAPI
94  IN PIRP Irp,
96 {
98  PWCHAR Buffer;
99 
100  switch (IrpSp->Parameters.QueryId.IdType)
101  {
102  case BusQueryDeviceID:
103  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
104  Source = &PdoExt->DeviceID;
105  break;
106 
107  case BusQueryHardwareIDs:
108  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
109  Source = &PdoExt->HardwareIDs;
110  break;
111 
113  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
114  Source = &PdoExt->CompatibleIDs;
115  break;
116 
117  case BusQueryInstanceID:
118  DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
120  break;
121 
122  default:
123  DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n",
124  IrpSp->Parameters.QueryId.IdType);
125  return Irp->IoStatus.Status;
126  }
127 
128  if (!Source->Buffer)
129  return Irp->IoStatus.Status;
130 
131  Buffer = ExAllocatePool(PagedPool, Source->MaximumLength);
132  if (!Buffer)
133  return STATUS_NO_MEMORY;
134 
135  RtlCopyMemory(Buffer, Source->Buffer, Source->MaximumLength);
136  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
137  return STATUS_SUCCESS;
138 }
139 
140 NTSTATUS
141 NTAPI
144  IN PIRP Irp,
146 {
147  ULONG ListSize;
149 
150  if (!PdoExt->ResourceList)
151  return Irp->IoStatus.Status;
152 
153  ListSize = PdoExt->ResourceListSize;
155  if (!ResourceList)
156  return STATUS_NO_MEMORY;
157 
158  RtlCopyMemory(ResourceList, PdoExt->ResourceList, ListSize);
159  Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
160  return STATUS_SUCCESS;
161 }
162 
163 NTSTATUS
164 NTAPI
167  IN PIRP Irp,
169 {
170  ULONG ListSize;
171  PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
172 
173  if (!PdoExt->RequirementsList)
174  return Irp->IoStatus.Status;
175 
176  ListSize = PdoExt->RequirementsList->ListSize;
177  RequirementsList = ExAllocatePool(PagedPool, ListSize);
178  if (!RequirementsList)
179  return STATUS_NO_MEMORY;
180 
181  RtlCopyMemory(RequirementsList, PdoExt->RequirementsList, ListSize);
182  Irp->IoStatus.Information = (ULONG_PTR)RequirementsList;
183  return STATUS_SUCCESS;
184 }
185 
186 static
187 NTSTATUS
188 NTAPI
190  IN PISAPNP_FDO_EXTENSION FdoExt,
192 {
193  PCM_RESOURCE_LIST ResourceList = IrpSp->Parameters.StartDevice.AllocatedResources;
195  KIRQL OldIrql;
196  ULONG i;
197 
198  if (!ResourceList || ResourceList->Count != 1)
199  {
200  DPRINT1("No resource list (%p) or bad count (%d)\n", ResourceList, ResourceList ? ResourceList->Count : 0);
202  }
203  if (ResourceList->List[0].PartialResourceList.Version != 1
204  || ResourceList->List[0].PartialResourceList.Revision != 1)
205  {
206  DPRINT1("Bad resource list version (%d.%d)\n", ResourceList->List[0].PartialResourceList.Version, ResourceList->List[0].PartialResourceList.Revision);
208  }
209  for (i = 0; i < ResourceList->List[0].PartialResourceList.Count; i++)
210  {
211  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
212  if (PartialDescriptor->Type == CmResourceTypePort && PartialDescriptor->u.Port.Length > 1 && !FdoExt->ReadDataPort)
213  {
214  PUCHAR ReadDataPort = ULongToPtr(PartialDescriptor->u.Port.Start.u.LowPart + 3);
215  if (NT_SUCCESS(IsaHwTryReadDataPort(ReadDataPort)))
216  {
217  /* we detected some ISAPNP cards */
218  FdoExt->ReadDataPort = ReadDataPort;
219  KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
220  Status = IsaHwFillDeviceList(FdoExt);
221  KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
222  if (FdoExt->DeviceCount > 0)
223  {
225  IoInvalidateDeviceRelations(FdoExt->DataPortPdo, RemovalRelations);
226  }
227  }
228  else
229  {
230  /* mark read data port as started, even if no card has been detected */
232  }
233  }
234  }
235  return Status;
236 }
237 
238 static
239 NTSTATUS
240 NTAPI
242  IN PDEVICE_OBJECT Tdo,
243  IN PIRP SubIrp,
244  PVOID NeedsVote)
245 {
247  PIRP Irp = (PIRP)SubStack->Parameters.Others.Argument1;
248  ObDereferenceObject(Tdo);
249 
250  if (SubIrp->IoStatus.Status == STATUS_NOT_SUPPORTED)
251  {
252  if (NeedsVote)
253  {
254  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
255  }
256  }
257  else
258  {
259  Irp->IoStatus = SubIrp->IoStatus;
260  }
261 
262  IoFreeIrp(SubIrp);
265 }
266 
267 NTSTATUS
268 NTAPI
271  IN PIRP Irp,
272  IN BOOLEAN NeedsVote)
273 {
274  PDEVICE_OBJECT Fdo = PdoExt->FdoExt->Common.Self;
276 
278  PIRP SubIrp = IoAllocateIrp(Tdo->StackSize + 1, FALSE);
280 
281  SubStack->DeviceObject = Tdo;
282  SubStack->Parameters.Others.Argument1 = (PVOID)Irp;
283 
285  SubStack = IoGetNextIrpStackLocation(SubIrp);
287  SubStack->Control = 0;
289 
292  IoCallDriver(Tdo, SubIrp);
293  return STATUS_PENDING;
294 }
295 
296 NTSTATUS
297 NTAPI
300  IN PIRP Irp,
302 {
303  NTSTATUS Status = Irp->IoStatus.Status;
304 
305  switch (IrpSp->MinorFunction)
306  {
307  case IRP_MN_START_DEVICE:
308  if (PdoExt->IsaPnpDevice)
309  Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
310  else
312 
313  if (NT_SUCCESS(Status))
314  PdoExt->Common.State = dsStarted;
315  break;
316 
317  case IRP_MN_STOP_DEVICE:
318  if (PdoExt->IsaPnpDevice)
319  Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
320  else
322 
323  if (NT_SUCCESS(Status))
324  PdoExt->Common.State = dsStopped;
325  break;
326 
329  break;
330 
333  break;
334 
336  if (PdoExt->Common.Self == PdoExt->FdoExt->DataPortPdo)
338  break;
339 
342  break;
343 
346  break;
347 
348  case IRP_MN_QUERY_ID:
350  break;
351 
361  break;
362 
363  case IRP_MN_READ_CONFIG:
364  case IRP_MN_WRITE_CONFIG:
365  case IRP_MN_EJECT:
366  case IRP_MN_SET_LOCK:
370 
371  default:
372  DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
373  break;
374  }
375 
376  Irp->IoStatus.Status = Status;
378 
379  return Status;
380 }
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IN
Definition: typedefs.h:39
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define IRP_MN_QUERY_RESOURCES
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
#define IRP_MN_QUERY_RESOURCE_REQUIREMENTS
#define IRP_MN_WRITE_CONFIG
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2143
NTSTATUS NTAPI IsaPnpFillDeviceRelations(IN PISAPNP_FDO_EXTENSION FdoExt, IN PIRP Irp, IN BOOLEAN IncludeDataPort)
Definition: isapnp.c:411
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
PUSBHUB_PORT_PDO_EXTENSION NTAPI PdoExt(IN PDEVICE_OBJECT DeviceObject)
Definition: usbhub.c:133
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define IRP_MN_EJECT
IO_STATUS_BLOCK IoStatus
uint16_t * PWCHAR
Definition: typedefs.h:56
NTSTATUS NTAPI IsaPdoQueryCapabilities(IN PISAPNP_PDO_EXTENSION PdoExt, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pdo.c:47
const MUI_LANGUAGE_RESOURCE ResourceList[]
Definition: muilanguages.h:414
NTSTATUS NTAPI IsaPdoPnp(IN PISAPNP_PDO_EXTENSION PdoExt, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pdo.c:298
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS NTAPI IsaPdoRepeatRequest(IN PISAPNP_PDO_EXTENSION PdoExt, IN PIRP Irp, IN BOOLEAN NeedsVote)
Definition: pdo.c:269
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define IRP_MN_QUERY_REMOVE_DEVICE
NTSTATUS NTAPI IsaHwTryReadDataPort(IN PUCHAR ReadDataPort)
Definition: hardware.c:591
COMMON_DEVICE_EXTENSION Common
Definition: usbhub.h:204
NTSTATUS NTAPI IsaPdoQueryDeviceRelations(IN PISAPNP_PDO_EXTENSION PdoExt, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pdo.c:16
unsigned char BOOLEAN
_In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: cdrom.h:1146
#define IoCompleteRequest
Definition: irp.c:1240
#define DeviceCapabilities
Definition: wingdi.h:4448
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
NTSTATUS NTAPI IsaPdoQueryResourceRequirements(IN PISAPNP_PDO_EXTENSION PdoExt, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pdo.c:165
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define IRP_MN_READ_CONFIG
#define IRP_MN_QUERY_STOP_DEVICE
NTSTATUS NTAPI IsaPdoQueryResources(IN PISAPNP_PDO_EXTENSION PdoExt, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pdo.c:142
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
static NTSTATUS NTAPI IsaPdoStartReadPort(IN PISAPNP_FDO_EXTENSION FdoExt, IN PIO_STACK_LOCATION IrpSp)
Definition: pdo.c:189
#define IRP_MN_STOP_DEVICE
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@386 Port
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define IRP_MN_START_DEVICE
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:989
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
#define IRP_MN_QUERY_DEVICE_TEXT
struct _IRP * PIRP
NTSTATUS NTAPI IsaPdoQueryPnpDeviceState(IN PISAPNP_PDO_EXTENSION PdoExt, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pdo.c:81
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define IRP_MN_QUERY_BUS_INFORMATION
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI IsaHwActivateDevice(IN PISAPNP_LOGICAL_DEVICE LogicalDevice)
Definition: hardware.c:599
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
static NTSTATUS NTAPI IsaPdoOnRepeaterComplete(IN PDEVICE_OBJECT Tdo, IN PIRP SubIrp, PVOID NeedsVote)
Definition: pdo.c:241
* PDEVICE_CAPABILITIES
Definition: iotypes.h:948
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2486
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IRP_MN_QUERY_DEVICE_RELATIONS
NTSTATUS NTAPI IsaHwDeactivateDevice(IN PISAPNP_LOGICAL_DEVICE LogicalDevice)
Definition: hardware.c:610
#define DPRINT1
Definition: precomp.h:8
#define ObReferenceObject
Definition: obfuncs.h:204
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define IRP_MN_SET_LOCK
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define ULONG_PTR
Definition: config.h:101
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IRP_MN_CANCEL_STOP_DEVICE
#define IRP_MN_DEVICE_USAGE_NOTIFICATION
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384 u
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSTATUS NTAPI IsaPdoQueryId(IN PISAPNP_PDO_EXTENSION PdoExt, IN PIRP Irp, IN PIO_STACK_LOCATION IrpSp)
Definition: pdo.c:92
NTSTATUS NTAPI IsaHwFillDeviceList(IN PISAPNP_FDO_EXTENSION FdoExt)
Definition: hardware.c:621
IoMarkIrpPending(Irp)
#define POWER_SYSTEM_MAXIMUM
Definition: ntpoapi.h:45
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2676
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define IRP_MN_QUERY_CAPABILITIES