ReactOS  0.4.14-dev-614-gbfd8a84
detect.c File Reference
#include "serenum.h"
#include <debug.h>
Include dependency graph for detect.c:

Go to the source code of this file.

Macros

#define BEGIN_ID   '('
 
#define END_ID   ')'
 

Functions

static NTSTATUS DeviceIoControl (IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG_PTR InputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PULONG_PTR OutputBufferSize)
 
static NTSTATUS ReadBytes (IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
 
static NTSTATUS ReportDetectedDevice (IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING DeviceDescription, IN PUNICODE_STRING DeviceId, IN PUNICODE_STRING InstanceId, IN PUNICODE_STRING HardwareIds, IN PUNICODE_STRING CompatibleIds)
 
static BOOLEAN IsValidPnpIdString (IN PUCHAR Buffer, IN ULONG BufferLength)
 
static NTSTATUS ReportDetectedPnpDevice (IN PUCHAR Buffer, IN ULONG BufferLength)
 
static NTSTATUS Wait (IN ULONG milliseconds)
 
NTSTATUS SerenumDetectPnpDevice (IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT LowerDevice)
 
NTSTATUS SerenumDetectLegacyDevice (IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT LowerDevice)
 

Macro Definition Documentation

◆ BEGIN_ID

#define BEGIN_ID   '('

Definition at line 206 of file detect.c.

◆ END_ID

#define END_ID   ')'

Definition at line 207 of file detect.c.

Function Documentation

◆ DeviceIoControl()

static NTSTATUS DeviceIoControl ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  CtlCode,
IN PVOID InputBuffer  OPTIONAL,
IN ULONG_PTR  InputBufferSize,
IN OUT PVOID OutputBuffer  OPTIONAL,
IN OUT PULONG_PTR  OutputBufferSize 
)
static

Definition at line 17 of file detect.c.

24 {
25  KEVENT Event;
26  PIRP Irp;
29 
31 
35  InputBufferSize,
37  (OutputBufferSize) ? *OutputBufferSize : 0,
38  FALSE,
39  &Event,
40  &IoStatus);
41  if (Irp == NULL)
42  {
43  WARN_(SERENUM, "IoBuildDeviceIoControlRequest() failed\n");
45  }
46 
48 
49  if (Status == STATUS_PENDING)
50  {
51  INFO_(SERENUM, "Operation pending\n");
53  Status = IoStatus.Status;
54  }
55 
56  if (OutputBufferSize)
57  {
58  *OutputBufferSize = IoStatus.Information;
59  }
60 
61  return Status;
62 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define INFO_(ch,...)
Definition: debug.h:159
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
CHAR InputBuffer[80]
Definition: conmgr.c:33
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
#define STATUS_PENDING
Definition: ntstatus.h:82
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define WARN_(ch,...)
Definition: debug.h:157

Referenced by SerenumDetectLegacyDevice(), and SerenumDetectPnpDevice().

◆ IsValidPnpIdString()

static BOOLEAN IsValidPnpIdString ( IN PUCHAR  Buffer,
IN ULONG  BufferLength 
)
static

Definition at line 176 of file detect.c.

179 {
181 
182  /* FIXME: IsValidPnpIdString not implemented */
184  String.Length = String.MaximumLength = BufferLength;
185  String.Buffer = (PCHAR)Buffer;
186  ERR_(SERENUM, "Buffer %Z\n", &String);
187  return TRUE;
188 }
#define TRUE
Definition: types.h:120
#define ERR_(ch,...)
Definition: debug.h:156
static WCHAR String[]
Definition: stringtable.c:55
_In_ ULONG BufferLength
Definition: usbdlib.h:225
Definition: bufpool.h:45
#define PCHAR
Definition: match.c:90
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by SerenumDetectPnpDevice().

◆ ReadBytes()

static NTSTATUS ReadBytes ( IN PDEVICE_OBJECT  LowerDevice,
OUT PUCHAR  Buffer,
IN ULONG  BufferSize,
OUT PULONG_PTR  FilledBytes 
)
static

Definition at line 65 of file detect.c.

70 {
71  PIRP Irp;
72  IO_STATUS_BLOCK ioStatus;
73  KEVENT event;
76 
78  zero.QuadPart = 0;
81  LowerDevice,
83  &zero,
84  &event,
85  &ioStatus);
86  if (!Irp)
87  return FALSE;
88 
89  Status = IoCallDriver(LowerDevice, Irp);
90  if (Status == STATUS_PENDING)
91  {
93  Status = ioStatus.Status;
94  }
95  INFO_(SERENUM, "Bytes received: %lu/%lu\n",
96  ioStatus.Information, BufferSize);
97  *FilledBytes = ioStatus.Information;
98  return Status;
99 }
#define INFO_(ch,...)
Definition: debug.h:159
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define STATUS_PENDING
Definition: ntstatus.h:82
#define BufferSize
Definition: classpnp.h:419
static double zero
Definition: j0_y0.c:96
struct _cl_event * event
Definition: glext.h:7739
Status
Definition: gdiplustypes.h:24
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MJ_READ
Definition: rdpdr.c:46

Referenced by SerenumDetectLegacyDevice(), and SerenumDetectPnpDevice().

◆ ReportDetectedDevice()

static NTSTATUS ReportDetectedDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN PUNICODE_STRING  DeviceDescription,
IN PUNICODE_STRING  DeviceId,
IN PUNICODE_STRING  InstanceId,
IN PUNICODE_STRING  HardwareIds,
IN PUNICODE_STRING  CompatibleIds 
)
static

Definition at line 102 of file detect.c.

109 {
111  PPDO_DEVICE_EXTENSION PdoDeviceExtension = NULL;
112  PFDO_DEVICE_EXTENSION FdoDeviceExtension;
114 
115  TRACE_(SERENUM, "ReportDetectedDevice() called with %wZ (%wZ) detected\n", DeviceId, DeviceDescription);
116 
118  DeviceObject->DriverObject,
119  sizeof(PDO_DEVICE_EXTENSION),
120  NULL,
123  FALSE,
124  &Pdo);
125  if (!NT_SUCCESS(Status)) goto ByeBye;
126 
129  PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
130  FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
131  RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
132  PdoDeviceExtension->Common.IsFDO = FALSE;
134  if (!NT_SUCCESS(Status)) goto ByeBye;
136  if (!NT_SUCCESS(Status)) goto ByeBye;
138  if (!NT_SUCCESS(Status)) goto ByeBye;
140  if (!NT_SUCCESS(Status)) goto ByeBye;
142  if (!NT_SUCCESS(Status)) goto ByeBye;
143 
144  /* Device attached to serial port (Pdo) may delegate work to
145  * serial port stack (Fdo = DeviceObject variable) */
147 
148  FdoDeviceExtension->AttachedPdo = Pdo;
149  PdoDeviceExtension->AttachedFdo = DeviceObject;
150 
153 
154  return STATUS_SUCCESS;
155 
156 ByeBye:
157  if (Pdo)
158  {
159  ASSERT(PdoDeviceExtension);
160  if (PdoDeviceExtension->DeviceDescription.Buffer)
161  RtlFreeUnicodeString(&PdoDeviceExtension->DeviceDescription);
162  if (PdoDeviceExtension->DeviceId.Buffer)
163  RtlFreeUnicodeString(&PdoDeviceExtension->DeviceId);
164  if (PdoDeviceExtension->InstanceId.Buffer)
165  RtlFreeUnicodeString(&PdoDeviceExtension->InstanceId);
166  if (PdoDeviceExtension->HardwareIds.Buffer)
167  RtlFreeUnicodeString(&PdoDeviceExtension->HardwareIds);
168  if (PdoDeviceExtension->CompatibleIds.Buffer)
169  RtlFreeUnicodeString(&PdoDeviceExtension->CompatibleIds);
171  }
172  return Status;
173 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define DO_POWER_PAGABLE
_In_ PDEVICE_OBJECT Pdo
Definition: classpnp.h:301
LONG NTSTATUS
Definition: precomp.h:26
struct _PDO_DEVICE_EXTENSION * PPDO_DEVICE_EXTENSION
UNICODE_STRING HardwareIds
Definition: serenum.h:54
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:109
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:907
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define DO_BUS_ENUMERATED_DEVICE
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:55
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
#define TRACE_(x)
Definition: compat.h:66
PDEVICE_OBJECT AttachedFdo
Definition: parport.h:59
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS DuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: misc.c:72
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
UNICODE_STRING DeviceId
Definition: serenum.h:52
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
UNICODE_STRING DeviceDescription
Definition: pci.h:69
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
UNICODE_STRING CompatibleIds
Definition: serenum.h:55
PDEVICE_OBJECT AttachedPdo[2]
Definition: parport.h:44
return STATUS_SUCCESS
Definition: btrfs.c:2938
UNICODE_STRING InstanceId
Definition: serenum.h:53

Referenced by SerenumDetectLegacyDevice().

◆ ReportDetectedPnpDevice()

static NTSTATUS ReportDetectedPnpDevice ( IN PUCHAR  Buffer,
IN ULONG  BufferLength 
)
static

Definition at line 191 of file detect.c.

194 {
196 
197  /* FIXME: ReportDetectedPnpDevice not implemented */
199  String.Length = String.MaximumLength = BufferLength;
200  String.Buffer = (PCHAR)Buffer;
201  ERR_(SERENUM, "Buffer %Z\n", &String);
202  /* Call ReportDetectedDevice */
203  return STATUS_SUCCESS;
204 }
#define ERR_(ch,...)
Definition: debug.h:156
static WCHAR String[]
Definition: stringtable.c:55
_In_ ULONG BufferLength
Definition: usbdlib.h:225
Definition: bufpool.h:45
#define PCHAR
Definition: match.c:90
#define UNIMPLEMENTED
Definition: debug.h:114
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by SerenumDetectPnpDevice().

◆ SerenumDetectLegacyDevice()

NTSTATUS SerenumDetectLegacyDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN PDEVICE_OBJECT  LowerDevice 
)

Definition at line 444 of file detect.c.

447 {
448  HANDLE Handle = NULL;
449  ULONG Fcr, Mcr;
450  ULONG BaudRate;
451  ULONG Command;
452  SERIAL_TIMEOUTS Timeouts;
454  ULONG i, Count = 0;
455  UCHAR Buffer[16];
457  UNICODE_STRING DeviceId;
459  UNICODE_STRING HardwareIds;
460  UNICODE_STRING CompatibleIds;
462 
463  TRACE_(SERENUM, "SerenumDetectLegacyDevice(DeviceObject %p, LowerDevice %p)\n",
464  DeviceObject,
465  LowerDevice);
466 
467  RtlZeroMemory(Buffer, sizeof(Buffer));
468 
469  /* Open port */
471  LowerDevice,
473  NULL,
474  0,
475  NULL,
476  KernelMode,
477  &Handle);
478  if (!NT_SUCCESS(Status)) return Status;
479 
480  /* Reset UART */
481  TRACE_(SERENUM, "Reset UART\n");
482  Mcr = 0; /* MCR: DTR/RTS/OUT2 off */
484  &Mcr, sizeof(Mcr), NULL, NULL);
485  if (!NT_SUCCESS(Status)) goto ByeBye;
486 
487  /* Set communications parameters */
488  TRACE_(SERENUM, "Set communications parameters\n");
489  /* DLAB off */
490  Fcr = 0;
492  &Fcr, sizeof(Fcr), NULL, NULL);
493  if (!NT_SUCCESS(Status)) goto ByeBye;
494  /* Set serial port speed */
495  BaudRate = 1200;
497  &BaudRate, sizeof(BaudRate), NULL, NULL);
498  if (!NT_SUCCESS(Status)) goto ByeBye;
499  /* Set LCR */
500  LCR.WordLength = 7;
501  LCR.Parity = NO_PARITY;
502  LCR.StopBits = STOP_BITS_2;
504  &LCR, sizeof(LCR), NULL, NULL);
505  if (!NT_SUCCESS(Status)) goto ByeBye;
506 
507  /* Flush receive buffer */
508  TRACE_(SERENUM, "Flush receive buffer\n");
511  &Command, sizeof(Command), NULL, NULL);
512  if (!NT_SUCCESS(Status)) goto ByeBye;
513  /* Wait 100 ms */
514  Wait(100);
515 
516  /* Enable DTR/RTS */
517  TRACE_(SERENUM, "Enable DTR/RTS\n");
519  NULL, 0, NULL, NULL);
520  if (!NT_SUCCESS(Status)) goto ByeBye;
522  NULL, 0, NULL, NULL);
523  if (!NT_SUCCESS(Status)) goto ByeBye;
524 
525  /* Set timeout to 500 microseconds */
526  TRACE_(SERENUM, "Set timeout to 500 microseconds\n");
527  Timeouts.ReadIntervalTimeout = 100;
528  Timeouts.ReadTotalTimeoutMultiplier = 0;
529  Timeouts.ReadTotalTimeoutConstant = 500;
532  &Timeouts, sizeof(Timeouts), NULL, NULL);
533  if (!NT_SUCCESS(Status)) goto ByeBye;
534 
535  /* Fill the read buffer */
536  TRACE_(SERENUM, "Fill the read buffer\n");
537  Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer)/sizeof(Buffer[0]), (PVOID)&Count);
538  if (!NT_SUCCESS(Status)) goto ByeBye;
539 
540  RtlInitUnicodeString(&DeviceId, L"Serenum\\Mouse");
541  RtlInitUnicodeString(&InstanceId, L"0000"); /* FIXME */
542  for (i = 0; i < Count; i++)
543  {
544  if (Buffer[i] == 'B')
545  {
546  /* Sign for Microsoft Ballpoint */
547  /* Hardware id: *PNP0F09
548  * Compatible id: *PNP0F0F, SERIAL_MOUSE
549  */
550  RtlInitUnicodeString(&DeviceDescription, L"Microsoft Ballpoint device");
551  SerenumInitMultiSzString(&HardwareIds, "*PNP0F09", NULL);
552  SerenumInitMultiSzString(&CompatibleIds, "*PNP0F0F", "SERIAL_MOUSE", NULL);
554  &DeviceDescription, &DeviceId, &InstanceId, &HardwareIds, &CompatibleIds);
555  RtlFreeUnicodeString(&HardwareIds);
556  RtlFreeUnicodeString(&CompatibleIds);
557  goto ByeBye;
558  }
559  else if (Buffer[i] == 'M')
560  {
561  /* Sign for Microsoft Mouse protocol followed by button specifier */
562  if (i == sizeof(Buffer) - 1)
563  {
564  /* Overflow Error */
566  goto ByeBye;
567  }
568  switch (Buffer[i + 1])
569  {
570  case '3':
571  /* Hardware id: *PNP0F08
572  * Compatible id: SERIAL_MOUSE
573  */
574  RtlInitUnicodeString(&DeviceDescription, L"Microsoft Mouse with 3-buttons");
575  SerenumInitMultiSzString(&HardwareIds, "*PNP0F08", NULL);
576  SerenumInitMultiSzString(&CompatibleIds, "SERIAL_MOUSE", NULL);
577  break;
578  default:
579  /* Hardware id: *PNP0F01
580  * Compatible id: SERIAL_MOUSE
581  */
582  RtlInitUnicodeString(&DeviceDescription, L"Microsoft Mouse with 2-buttons or Microsoft Wheel Mouse");
583  SerenumInitMultiSzString(&HardwareIds, "*PNP0F01", NULL);
584  SerenumInitMultiSzString(&CompatibleIds, "SERIAL_MOUSE", NULL);
585  break;
586  }
588  &DeviceDescription, &DeviceId, &InstanceId, &HardwareIds, &CompatibleIds);
589  RtlFreeUnicodeString(&HardwareIds);
590  RtlFreeUnicodeString(&CompatibleIds);
591  goto ByeBye;
592  }
593  }
594 
596 
597 ByeBye:
598  /* Close port */
599  if (Handle)
600  ZwClose(Handle);
601  return Status;
602 }
#define SERIAL_PURGE_RXCLEAR
Definition: serial.c:96
static NTSTATUS Wait(IN ULONG milliseconds)
Definition: detect.c:210
#define IOCTL_SERIAL_SET_BAUD_RATE
Definition: ntddser.h:82
ULONG WriteTotalTimeoutConstant
Definition: ntddser.h:307
#define IOCTL_SERIAL_SET_FIFO_CONTROL
Definition: ntddser.h:92
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS SerenumInitMultiSzString(OUT PUNICODE_STRING Destination,...)
Definition: misc.c:20
ULONG ReadTotalTimeoutConstant
Definition: ntddser.h:305
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
Definition: shell.h:41
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2739
#define IOCTL_SERIAL_SET_LINE_CONTROL
Definition: ntddser.h:96
#define IOCTL_SERIAL_SET_DTR
Definition: ntddser.h:90
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
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:907
ULONG ReadTotalTimeoutMultiplier
Definition: ntddser.h:304
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
static NTSTATUS ReportDetectedDevice(IN PDEVICE_OBJECT DeviceObject, IN PUNICODE_STRING DeviceDescription, IN PUNICODE_STRING DeviceId, IN PUNICODE_STRING InstanceId, IN PUNICODE_STRING HardwareIds, IN PUNICODE_STRING CompatibleIds)
Definition: detect.c:102
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:65
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define TRACE_(x)
Definition: compat.h:66
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
_In_ HANDLE Handle
Definition: extypes.h:390
ULONG WriteTotalTimeoutMultiplier
Definition: ntddser.h:306
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct Command Command
ULONG ReadIntervalTimeout
Definition: ntddser.h:303
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define LCR
Definition: serial_port.h:65
#define STOP_BITS_2
Definition: serial.c:87
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define NO_PARITY
Definition: serial.c:89
#define IOCTL_SERIAL_SET_MODEM_CONTROL
Definition: ntddser.h:98
static NTSTATUS DeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG_PTR InputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PULONG_PTR OutputBufferSize)
Definition: detect.c:17
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define IOCTL_SERIAL_SET_RTS
Definition: ntddser.h:102
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define IOCTL_SERIAL_SET_TIMEOUTS
Definition: ntddser.h:104

Referenced by SerenumFdoQueryBusRelations().

◆ SerenumDetectPnpDevice()

NTSTATUS SerenumDetectPnpDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN PDEVICE_OBJECT  LowerDevice 
)

Definition at line 223 of file detect.c.

226 {
227  HANDLE Handle = NULL;
228  UCHAR Buffer[256];
229  ULONG BaudRate;
230  ULONG_PTR TotalBytesReceived = 0;
231  ULONG_PTR Size;
232  ULONG Msr, Purge;
233  ULONG i;
234  BOOLEAN BufferContainsBeginId = FALSE;
235  BOOLEAN BufferContainsEndId = FALSE;
237  SERIAL_TIMEOUTS Timeouts;
238  SERIALPERF_STATS PerfStats;
240 
241  /* Open port */
243  LowerDevice,
245  NULL,
246  0,
247  NULL,
248  KernelMode,
249  &Handle);
250  if (!NT_SUCCESS(Status)) goto ByeBye;
251 
252  /* 1. COM port initialization, check for device enumerate */
253  TRACE_(SERENUM, "COM port initialization, check for device enumerate\n");
255  NULL, 0, NULL, NULL);
256  if (!NT_SUCCESS(Status)) goto ByeBye;
258  NULL, 0, NULL, NULL);
259  if (!NT_SUCCESS(Status)) goto ByeBye;
260  Wait(200);
261  Size = sizeof(Msr);
263  NULL, 0, &Msr, &Size);
264  if (!NT_SUCCESS(Status)) goto ByeBye;
265  if ((Msr & SERIAL_DSR_STATE) == 0) goto DisconnectIdle;
266 
267  /* 2. COM port setup, 1st phase */
268  TRACE_(SERENUM, "COM port setup, 1st phase\n");
269  BaudRate = 1200;
271  &BaudRate, sizeof(BaudRate), NULL, 0);
272  if (!NT_SUCCESS(Status)) goto ByeBye;
273  Lcr.WordLength = 7;
274  Lcr.Parity = NO_PARITY;
275  Lcr.StopBits = STOP_BIT_1;
277  &Lcr, sizeof(Lcr), NULL, NULL);
278  if (!NT_SUCCESS(Status)) goto ByeBye;
280  NULL, 0, NULL, NULL);
281  if (!NT_SUCCESS(Status)) goto ByeBye;
283  NULL, 0, NULL, NULL);
284  if (!NT_SUCCESS(Status)) goto ByeBye;
285  Wait(200);
287  NULL, 0, NULL, NULL);
288  if (!NT_SUCCESS(Status)) goto ByeBye;
289  Wait(200);
290 
291  /* 3. Wait for response, 1st phase */
292  TRACE_(SERENUM, "Wait for response, 1st phase\n");
294  NULL, 0, NULL, NULL);
295  if (!NT_SUCCESS(Status)) goto ByeBye;
296  Timeouts.ReadIntervalTimeout = 0;
297  Timeouts.ReadTotalTimeoutMultiplier = 0;
298  Timeouts.ReadTotalTimeoutConstant = 200;
301  &Timeouts, sizeof(Timeouts), NULL, NULL);
302  if (!NT_SUCCESS(Status)) goto ByeBye;
303  Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer), &Size);
304  if (!NT_SUCCESS(Status)) goto ByeBye;
305  if (Size != 0) goto CollectPnpComDeviceId;
306 
307  /* 4. COM port setup, 2nd phase */
308  TRACE_(SERENUM, "COM port setup, 2nd phase\n");
310  NULL, 0, NULL, NULL);
311  if (!NT_SUCCESS(Status)) goto ByeBye;
313  NULL, 0, NULL, NULL);
314  if (!NT_SUCCESS(Status)) goto ByeBye;
317  &Purge, sizeof(ULONG), NULL, NULL);
318  if (!NT_SUCCESS(Status)) goto ByeBye;
319  Wait(200);
320 
321  /* 5. Wait for response, 2nd phase */
322  TRACE_(SERENUM, "Wait for response, 2nd phase\n");
324  NULL, 0, NULL, NULL);
325  if (!NT_SUCCESS(Status)) goto ByeBye;
327  NULL, 0, NULL, NULL);
328  if (!NT_SUCCESS(Status)) goto ByeBye;
329  Status = ReadBytes(LowerDevice, Buffer, 1, &TotalBytesReceived);
330  if (!NT_SUCCESS(Status)) goto ByeBye;
331  if (TotalBytesReceived != 0) goto CollectPnpComDeviceId;
332  Size = sizeof(Msr);
334  NULL, 0, &Msr, &Size);
335  if (!NT_SUCCESS(Status)) goto ByeBye;
336  if ((Msr & SERIAL_DSR_STATE) == 0) goto VerifyDisconnect; else goto ConnectIdle;
337 
338  /* 6. Collect PnP COM device ID */
339 CollectPnpComDeviceId:
340  TRACE_(SERENUM, "Collect PnP COM device ID\n");
341  Timeouts.ReadIntervalTimeout = 200;
342  Timeouts.ReadTotalTimeoutMultiplier = 0;
343  Timeouts.ReadTotalTimeoutConstant = 2200;
345  &Timeouts, sizeof(Timeouts), NULL, NULL);
346  if (!NT_SUCCESS(Status)) goto ByeBye;
347  Status = ReadBytes(LowerDevice, &Buffer[TotalBytesReceived], sizeof(Buffer) - TotalBytesReceived, &Size);
348  if (!NT_SUCCESS(Status)) goto ByeBye;
349  TotalBytesReceived += Size;
350  Size = sizeof(PerfStats);
352  NULL, 0, &PerfStats, &Size);
353  if (!NT_SUCCESS(Status)) goto ByeBye;
354  if (PerfStats.FrameErrorCount + PerfStats.ParityErrorCount != 0) goto ConnectIdle;
355  for (i = 0; i < TotalBytesReceived; i++)
356  {
357  if (Buffer[i] == BEGIN_ID) BufferContainsBeginId = TRUE;
358  if (Buffer[i] == END_ID) BufferContainsEndId = TRUE;
359  }
360  if (TotalBytesReceived == 1 || BufferContainsEndId)
361  {
362  if (IsValidPnpIdString(Buffer, TotalBytesReceived))
363  {
364  Status = ReportDetectedPnpDevice(Buffer, TotalBytesReceived);
365  goto ByeBye;
366  }
367  goto ConnectIdle;
368  }
369  if (!BufferContainsBeginId) goto ConnectIdle;
370  if (!BufferContainsEndId) goto ConnectIdle;
371  Size = sizeof(Msr);
373  NULL, 0, &Msr, &Size);
374  if (!NT_SUCCESS(Status)) goto ByeBye;
375  if ((Msr & SERIAL_DSR_STATE) == 0) goto VerifyDisconnect;
376 
377  /* 7. Verify disconnect */
378 VerifyDisconnect:
379  TRACE_(SERENUM, "Verify disconnect\n");
381  NULL, 0, NULL, NULL);
382  if (!NT_SUCCESS(Status)) goto ByeBye;
384  NULL, 0, NULL, NULL);
385  if (!NT_SUCCESS(Status)) goto ByeBye;
386  Wait(5000);
387  goto DisconnectIdle;
388 
389  /* 8. Connect idle */
390 ConnectIdle:
391  TRACE_(SERENUM, "Connect idle\n");
393  NULL, 0, NULL, NULL);
394  if (!NT_SUCCESS(Status)) goto ByeBye;
396  NULL, 0, NULL, NULL);
397  if (!NT_SUCCESS(Status)) goto ByeBye;
398  BaudRate = 300;
400  &BaudRate, sizeof(BaudRate), NULL, NULL);
401  if (!NT_SUCCESS(Status)) goto ByeBye;
402  Lcr.WordLength = 7;
403  Lcr.Parity = NO_PARITY;
404  Lcr.StopBits = STOP_BIT_1;
406  &Lcr, sizeof(Lcr), NULL, NULL);
407  if (!NT_SUCCESS(Status)) goto ByeBye;
408  if (TotalBytesReceived == 0)
410  else
412  goto ByeBye;
413 
414  /* 9. Disconnect idle */
415 DisconnectIdle:
416  TRACE_(SERENUM, "Disconnect idle\n");
417  /* FIXME: report to OS device removal, if it was present */
419  NULL, 0, NULL, NULL);
420  if (!NT_SUCCESS(Status)) goto ByeBye;
422  NULL, 0, NULL, NULL);
423  if (!NT_SUCCESS(Status)) goto ByeBye;
424  BaudRate = 300;
426  &BaudRate, sizeof(BaudRate), NULL, NULL);
427  if (!NT_SUCCESS(Status)) goto ByeBye;
428  Lcr.WordLength = 7;
429  Lcr.Parity = NO_PARITY;
430  Lcr.StopBits = STOP_BIT_1;
432  &Lcr, sizeof(Lcr), NULL, NULL);
433  if (!NT_SUCCESS(Status)) goto ByeBye;
435 
436 ByeBye:
437  /* Close port */
438  if (Handle)
439  ZwClose(Handle);
440  return Status;
441 }
#define SERIAL_PURGE_RXCLEAR
Definition: serial.c:96
#define TRUE
Definition: types.h:120
#define STOP_BIT_1
Definition: ntddser.h:215
static BOOLEAN IsValidPnpIdString(IN PUCHAR Buffer, IN ULONG BufferLength)
Definition: detect.c:176
static NTSTATUS Wait(IN ULONG milliseconds)
Definition: detect.c:210
#define IOCTL_SERIAL_SET_BAUD_RATE
Definition: ntddser.h:82
ULONG WriteTotalTimeoutConstant
Definition: ntddser.h:307
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
ULONG ReadTotalTimeoutConstant
Definition: ntddser.h:305
LONG NTSTATUS
Definition: precomp.h:26
#define IOCTL_SERIAL_CLR_RTS
Definition: ntddser.h:46
#define SERIAL_DSR_STATE
Definition: ntddser.h:430
NTSTATUS NTAPI ObOpenObjectByPointer(IN PVOID Object, IN ULONG HandleAttributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PHANDLE Handle)
Definition: obhandle.c:2739
#define IOCTL_SERIAL_SET_LINE_CONTROL
Definition: ntddser.h:96
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IOCTL_SERIAL_SET_DTR
Definition: ntddser.h:90
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
#define IOCTL_SERIAL_GET_MODEMSTATUS
Definition: ntddser.h:64
#define IOCTL_SERIAL_PURGE
Definition: ntddser.h:78
#define BEGIN_ID
Definition: detect.c:206
unsigned char BOOLEAN
ULONG ReadTotalTimeoutMultiplier
Definition: ntddser.h:304
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define END_ID
Definition: detect.c:207
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:65
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define TRACE_(x)
Definition: compat.h:66
_In_ HANDLE Handle
Definition: extypes.h:390
ULONG WriteTotalTimeoutMultiplier
Definition: ntddser.h:306
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG ReadIntervalTimeout
Definition: ntddser.h:303
unsigned char UCHAR
Definition: xmlstorage.h:181
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define IOCTL_SERIAL_GET_STATS
Definition: ntddser.h:68
Status
Definition: gdiplustypes.h:24
#define SERIAL_PURGE_RXABORT
Definition: serial.c:94
#define NO_PARITY
Definition: serial.c:89
#define IOCTL_SERIAL_CLR_DTR
Definition: ntddser.h:44
ULONG FrameErrorCount
Definition: ntddser.h:296
static NTSTATUS DeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG_PTR InputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PULONG_PTR OutputBufferSize)
Definition: detect.c:17
unsigned int ULONG
Definition: retypes.h:1
#define IOCTL_SERIAL_SET_RTS
Definition: ntddser.h:102
static NTSTATUS ReportDetectedPnpDevice(IN PUCHAR Buffer, IN ULONG BufferLength)
Definition: detect.c:191
ULONG ParityErrorCount
Definition: ntddser.h:299
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define IOCTL_SERIAL_SET_TIMEOUTS
Definition: ntddser.h:104

Referenced by SerenumFdoQueryBusRelations().

◆ Wait()

static NTSTATUS Wait ( IN ULONG  milliseconds)
static

Definition at line 210 of file detect.c.

212 {
213  KTIMER Timer;
215 
216  DueTime.QuadPart = milliseconds * -10;
220 }
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
_In_ LARGE_INTEGER DueTime
Definition: kefuncs.h:524
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
UINT Timer
Definition: capclock.c:11
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by SerenumDetectLegacyDevice(), and SerenumDetectPnpDevice().