You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
5.7 KiB
224 lines
5.7 KiB
/*++
|
|
Module Name:
|
|
|
|
ENUM.C
|
|
|
|
Abstract:
|
|
|
|
This module contains the enumeration code needed to enumerate
|
|
all ports on multiport board, and ceate the PDOs.
|
|
|
|
|
|
Environment:
|
|
|
|
kernel mode only
|
|
|
|
Notes:
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include <ntddk.h>
|
|
#include <ntddser.h>
|
|
#include "mxenum.h"
|
|
#include "mxlog.h"
|
|
|
|
|
|
static const PHYSICAL_ADDRESS SerialPhysicalZero = {0};
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGE, MxenumCreatePDO)
|
|
#pragma alloc_text(PAGE, MxenumInitPDO)
|
|
#endif
|
|
|
|
void
|
|
MxenumInitPDO (
|
|
PDEVICE_OBJECT Pdo,
|
|
PFDO_DEVICE_DATA FdoData)
|
|
|
|
/*
|
|
Description:
|
|
Common code to initialize a newly created serenum pdo.
|
|
Called either when the control panel exposes a device or when Serenum senses
|
|
a new device was attached.
|
|
|
|
Parameters:
|
|
Pdo - The pdo
|
|
FdoData - The fdo's device extension
|
|
Exposed - Was this pdo was found by serenum (FALSE) or was it was EXPOSEd by
|
|
a control panel applet (TRUE)?
|
|
*/
|
|
{
|
|
ULONG FdoFlags = FdoData->Self->Flags;
|
|
PPDO_DEVICE_DATA pdoData = Pdo->DeviceExtension;
|
|
NTSTATUS status;
|
|
ULONG j;
|
|
HANDLE keyHandle;
|
|
|
|
PAGED_CODE();
|
|
|
|
Pdo->Flags |= DO_BUFFERED_IO;
|
|
|
|
//
|
|
// Increment the pdo's stacksize so that it can pass irps through
|
|
//
|
|
Pdo->StackSize += FdoData->Self->StackSize;
|
|
|
|
//
|
|
// Initialize the rest of the device extension
|
|
//
|
|
pdoData->IsFDO = FALSE;
|
|
pdoData->Self = Pdo;
|
|
|
|
pdoData->ParentFdo = FdoData->Self;
|
|
|
|
pdoData->Started = FALSE; // irp_mn_start has yet to be received
|
|
pdoData->Attached = TRUE; // attached to the bus
|
|
pdoData->Removed = FALSE; // no irp_mn_remove as of yet
|
|
|
|
pdoData->DeviceState = PowerDeviceD0;
|
|
pdoData->SystemState = PowerSystemWorking;
|
|
|
|
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
|
Pdo->Flags |= DO_POWER_PAGABLE;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
MxenumCreatePDO(IN PFDO_DEVICE_DATA FdoData)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This enumerates the serenum bus which is represented by Fdo (a pointer
|
|
to the device object representing the serial bus). It creates new PDOs
|
|
for any new devices which have been discovered since the last enumeration
|
|
|
|
Arguments:
|
|
|
|
FdoData - Pointer to the fdo's device extension
|
|
for the serial bus which needs to be enumerated
|
|
|
|
Return value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
{
|
|
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
UNICODE_STRING pdoUniName;
|
|
PDEVICE_OBJECT pdo;
|
|
PPDO_DEVICE_DATA pdoData;
|
|
ULONG i,j;
|
|
WCHAR pdoName[] = MXENUM_PDO_NAME_BASE;
|
|
UCHAR hardwareId[] = MXENUM_PDO_HARDWARE_ID;
|
|
UCHAR deviceId[] = MXENUM_PDO_DEVICE_ID;
|
|
ULONG FdoFlags = FdoData->Self->Flags;
|
|
|
|
|
|
PAGED_CODE();
|
|
|
|
MxenumKdPrint (MXENUM_DBG_TRACE,("MxenumCreatePDO\n"));
|
|
|
|
RtlInitUnicodeString(&pdoUniName, pdoName);
|
|
|
|
for (i = 0; i < FdoData->NumPorts;i++) {
|
|
|
|
PDEVICE_OBJECT currentDevice,previousDevice;
|
|
|
|
//
|
|
// Allocate a pdo
|
|
//
|
|
|
|
|
|
pdoName[19] = (WCHAR)('0' + FdoData->BoardIndex / 10);
|
|
deviceId[14] = (UCHAR)pdoName[19];
|
|
pdoName[20] = (WCHAR)('0' + FdoData->BoardIndex % 10);
|
|
deviceId[15] = (UCHAR)pdoName[20];
|
|
pdoName[22] = (WCHAR)('0' + i / 100);
|
|
deviceId[17] = hardwareId[6] = (UCHAR)pdoName[22];
|
|
pdoName[23] = (WCHAR)('0' + (i % 100)/10);
|
|
deviceId[18] = hardwareId[7] = (UCHAR)pdoName[23];
|
|
pdoName[24] = (WCHAR)('0' + (i % 100)%10);
|
|
deviceId[19] = hardwareId[8] = (UCHAR)pdoName[24] ;
|
|
|
|
|
|
previousDevice = currentDevice = FdoData->AttachedPDO;
|
|
while (currentDevice != NULL) {
|
|
|
|
for (j = 0;(j < strlen(deviceId))&&(j < (ULONG)((PPDO_DEVICE_DATA)(currentDevice->DeviceExtension))->DeviceIDs.Length >> 1);j++) {
|
|
if (deviceId[j] != ((PPDO_DEVICE_DATA)(currentDevice->DeviceExtension))->DeviceIDs.Buffer[j])
|
|
break;
|
|
}
|
|
if (j == strlen(deviceId))
|
|
break;
|
|
previousDevice = currentDevice;
|
|
currentDevice = ((PPDO_DEVICE_DATA)(currentDevice->DeviceExtension))->Next;
|
|
}
|
|
|
|
if (currentDevice == NULL) { // New,create one
|
|
status = IoCreateDevice(FdoData->Self->DriverObject,
|
|
sizeof(PDO_DEVICE_DATA), &pdoUniName,
|
|
FILE_DEVICE_SERIAL_PORT,
|
|
FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &pdo);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
MxenumKdPrint(MXENUM_DBG_TRACE, ("Create device failed\n"));
|
|
continue;
|
|
|
|
}
|
|
if (previousDevice)
|
|
((PPDO_DEVICE_DATA)(previousDevice->DeviceExtension))->Next = pdo;
|
|
else
|
|
FdoData->AttachedPDO = pdo;
|
|
MxenumInitPDO(pdo, FdoData);
|
|
pdoData = pdo->DeviceExtension;
|
|
pdoData->PortIndex = i; // port indexed from 0
|
|
|
|
}
|
|
else {
|
|
continue;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Initialize the rest of the device object
|
|
|
|
if (pdoData->HardwareIDs.Buffer)
|
|
ExFreePool(pdoData->HardwareIDs.Buffer);
|
|
pdoData->HardwareIDs.Buffer = NULL;
|
|
|
|
MxenumInitMultiString( &pdoData->HardwareIDs,hardwareId ,
|
|
NULL);
|
|
if (pdoData->CompIDs.Buffer)
|
|
ExFreePool(pdoData->CompIDs.Buffer);
|
|
pdoData->CompIDs.Buffer = NULL;
|
|
|
|
MxenumInitMultiString( &pdoData->CompIDs,
|
|
MXENUM_PDO_COMPATIBLE_ID,
|
|
NULL);
|
|
if (pdoData->DeviceIDs.Buffer)
|
|
ExFreePool(pdoData->DeviceIDs.Buffer);
|
|
pdoData->DeviceIDs.Buffer = NULL;
|
|
|
|
MxenumInitMultiString(&pdoData->DeviceIDs,
|
|
deviceId,
|
|
NULL);
|
|
FdoData->NumPDOs++;
|
|
|
|
|
|
}
|
|
|
|
|
|
// EnumPDOsErr:;
|
|
|
|
return status;
|
|
}
|
|
|