ReactOS 0.4.16-dev-125-g798ea90
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{
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
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}
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
Status
Definition: gdiplustypes.h:25
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
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 IoCallDriver
Definition: irp.c:1225
#define STATUS_PENDING
Definition: ntstatus.h:82
#define INFO_(ch,...)
Definition: debug.h:159
#define WARN_(ch,...)
Definition: debug.h:157
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
@ Suspended
Definition: ketypes.h:420

◆ 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 UNIMPLEMENTED
Definition: debug.h:118
Definition: bufpool.h:45
#define TRUE
Definition: types.h:120
#define PCHAR
Definition: match.c:90
#define ERR_(ch,...)
Definition: debug.h:156
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433

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;
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);
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}
struct _cl_event * event
Definition: glext.h:7739
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
#define IRP_MJ_READ
Definition: rdpdr.c:46
int zero
Definition: sehframes.cpp:29
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

◆ 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
128 Pdo->Flags |= DO_POWER_PAGABLE;
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) */
146 Pdo->StackSize = DeviceObject->StackSize + 1;
147
148 FdoDeviceExtension->AttachedPdo = Pdo;
149 PdoDeviceExtension->AttachedFdo = DeviceObject;
150
151 Pdo->Flags |= DO_BUFFERED_IO;
152 Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
153
154 return STATUS_SUCCESS;
155
156ByeBye:
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 NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define TRACE_(x)
Definition: compat.h:76
struct _PDO_DEVICE_EXTENSION * PPDO_DEVICE_EXTENSION
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
_Must_inspect_result_ _In_opt_ PVOID _In_opt_ PVOID InstanceId
Definition: fsrtlfuncs.h:908
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
NTSTATUS DuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: misc.c:31
#define ASSERT(a)
Definition: mode.c:44
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
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
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:49
#define STATUS_SUCCESS
Definition: shellext.h:65
PDEVICE_OBJECT AttachedPdo[2]
Definition: parport.h:44
UNICODE_STRING InstanceId
Definition: serenum.h:53
UNICODE_STRING DeviceDescription
Definition: pci.h:73
UNICODE_STRING HardwareIds
Definition: serenum.h:54
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:59
UNICODE_STRING CompatibleIds
Definition: serenum.h:55
PDEVICE_OBJECT AttachedFdo
Definition: parport.h:59
UNICODE_STRING DeviceId
Definition: serenum.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_ WDFDRIVER _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT _In_opt_ PDEVICE_OBJECT Pdo
Definition: wdfminiport.h:72
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:432
#define DO_BUS_ENUMERATED_DEVICE
#define DO_POWER_PAGABLE

◆ 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}

Referenced by SerenumDetectPnpDevice().

◆ SerenumDetectLegacyDevice()

NTSTATUS SerenumDetectLegacyDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN PDEVICE_OBJECT  LowerDevice 
)

Definition at line 444 of file detect.c.

447{
449 ULONG Fcr, Mcr;
450 ULONG BaudRate;
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",
465 LowerDevice);
466
467 RtlZeroMemory(Buffer, sizeof(Buffer));
468
469 /* Open port */
471 LowerDevice,
473 NULL,
474 0,
475 NULL,
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
597ByeBye:
598 /* Close port */
599 if (Handle)
601 return Status;
602}
static NTSTATUS DeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer OPTIONAL, IN SIZE_T InputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PSIZE_T OutputBufferSize)
Definition: detect.c:19
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:67
NTSTATUS SerenumInitMultiSzString(OUT PUNICODE_STRING Destination,...)
Definition: misc.c:18
ULONG ReportDetectedDevice
Definition: ramdisk.c:117
ULONG Handle
Definition: gdb_input.c:15
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 OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define STOP_BITS_2
Definition: serial.c:87
#define SERIAL_PURGE_RXCLEAR
Definition: serial.c:96
#define NO_PARITY
Definition: serial.c:89
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
int Count
Definition: noreturn.cpp:7
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define IOCTL_SERIAL_SET_LINE_CONTROL
Definition: ntddser.h:96
#define IOCTL_SERIAL_SET_TIMEOUTS
Definition: ntddser.h:104
#define IOCTL_SERIAL_SET_MODEM_CONTROL
Definition: ntddser.h:98
#define IOCTL_SERIAL_SET_FIFO_CONTROL
Definition: ntddser.h:92
#define IOCTL_SERIAL_SET_BAUD_RATE
Definition: ntddser.h:82
#define IOCTL_SERIAL_SET_DTR
Definition: ntddser.h:90
#define IOCTL_SERIAL_SET_RTS
Definition: ntddser.h:102
#define L(x)
Definition: ntvdm.h:50
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:2742
Definition: shell.h:41
ULONG WriteTotalTimeoutMultiplier
Definition: ntddser.h:306
ULONG ReadTotalTimeoutConstant
Definition: ntddser.h:305
ULONG WriteTotalTimeoutConstant
Definition: ntddser.h:307
ULONG ReadTotalTimeoutMultiplier
Definition: ntddser.h:304
ULONG ReadIntervalTimeout
Definition: ntddser.h:303
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by SerenumFdoQueryBusRelations().

◆ SerenumDetectPnpDevice()

NTSTATUS SerenumDetectPnpDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN PDEVICE_OBJECT  LowerDevice 
)

Definition at line 223 of file detect.c.

226{
228 UCHAR Buffer[256];
229 ULONG BaudRate;
230 ULONG_PTR TotalBytesReceived = 0;
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,
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 */
339CollectPnpComDeviceId:
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 */
378VerifyDisconnect:
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 */
390ConnectIdle:
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 */
415DisconnectIdle:
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
436ByeBye:
437 /* Close port */
438 if (Handle)
440 return Status;
441}
unsigned char BOOLEAN
static NTSTATUS ReportDetectedPnpDevice(IN PUCHAR Buffer, IN ULONG BufferLength)
Definition: detect.c:191
static BOOLEAN IsValidPnpIdString(IN PUCHAR Buffer, IN ULONG BufferLength)
Definition: detect.c:176
#define BEGIN_ID
Definition: detect.c:206
#define END_ID
Definition: detect.c:207
#define SERIAL_PURGE_RXABORT
Definition: serial.c:94
#define STOP_BIT_1
Definition: ntddser.h:215
#define SERIAL_DSR_STATE
Definition: ntddser.h:430
#define IOCTL_SERIAL_GET_STATS
Definition: ntddser.h:68
#define IOCTL_SERIAL_CLR_DTR
Definition: ntddser.h:44
#define IOCTL_SERIAL_CLR_RTS
Definition: ntddser.h:46
#define IOCTL_SERIAL_GET_MODEMSTATUS
Definition: ntddser.h:64
#define IOCTL_SERIAL_PURGE
Definition: ntddser.h:78
ULONG ParityErrorCount
Definition: ntddser.h:299
ULONG FrameErrorCount
Definition: ntddser.h:296
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by SerenumFdoQueryBusRelations().

◆ Wait()

static NTSTATUS Wait ( IN ULONG  milliseconds)
static

Definition at line 210 of file detect.c.

212{
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
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:190
@ Executive
Definition: ketypes.h:415