Leaked source code of windows server 2003
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.
 
 
 
 
 
 

843 lines
27 KiB

/*----------------------------------------------------------------------
pnpadd.c - Handle pnp adding devices.
|----------------------------------------------------------------------*/
#include "precomp.h"
#ifdef NT50
NTSTATUS AddBoardDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo,
OUT PDEVICE_OBJECT *NewDevObj);
NTSTATUS AddPortDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo,
OUT PDEVICE_OBJECT *NewDevObj,
IN int port_index);
NTSTATUS CheckPortName(
IN PDEVICE_OBJECT Pdo,
IN PSERIAL_DEVICE_EXTENSION ParentExt,
IN int port_index);
#define CFG_ID_ISA_BRD_INDEX 0
#define CFG_ID_NODE_INDEX 1
static int read_config_data(PDEVICE_OBJECT Pdo, int *ret_val, int val_id);
static int write_config_data(PDEVICE_OBJECT Pdo, int val, int val_id);
static int derive_unique_node_index(int *ret_val);
static int GetPnpIdStr(PDEVICE_OBJECT Pdo, char *ret_val);
/*----------------------------------------------------------------------
SerialAddDevice -
This routine creates a functional device object for boards or
com ports in the system and attaches them to the physical device
objects for the boards or ports.
Arguments:
DriverObject - a pointer to the object for this driver
PhysicalDeviceObject - a pointer to the physical object we need to attach to
Return Value:
status from device creation and initialization
|----------------------------------------------------------------------*/
NTSTATUS SerialAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo)
{
PDEVICE_OBJECT fdo = NULL;
PDEVICE_OBJECT lowerDevice = NULL;
PDEVICE_OBJECT NewDevObj = NULL;
NTSTATUS status;
#if DBG_STACK
int i;
#endif
int stat;
int board_device = 1; // asume pnp board device(not pnp port)
//PDEVICE_OBJECT deviceOjbect;
PSERIAL_DEVICE_EXTENSION deviceExtension;
ULONG resultLength;
USTR_240 *us; // equal to 240 normal chars length
char *ptr;
int port_index;
// Using stack array instead of static buffer for unicode conversion
char cstr[320];
//char temp_szNt50DevObjName[80];
#if DBG_STACK
DWORD stkchkend;
DWORD stkchk;
DWORD *stkptr;
#endif
MyKdPrint(D_PnpAdd,("RK:SerialAddDevice Start DrvObj:%x, PDO:%x\n",
DriverObject, Pdo))
MyKdPrint(D_Pnp, ("SerialAddDevice\n"))
#if DBG_STACK
stkchk = 0;
stkptr = (DWORD *)&DriverObject;
for (i=0; i<50; i++)
{
stkchk += *stkptr++;
}
#endif
//PAGED_CODE();
if (Pdo == NULL) {
// Bugbug: This is where enumeration occurs.
// One possible use for this is to add the user defined
// ports from the registry
// For now: just return no more devices
MyKdPrint(D_Error, ("NullPDO.\n"))
return (STATUS_NO_MORE_ENTRIES);
}
us = ExAllocatePool(NonPagedPool, sizeof(USTR_240));
if ( us == NULL ) {
MyKdPrint(D_Error, ("SerialAddDevice no memory.\n"))
return STATUS_INSUFFICIENT_RESOURCES;
}
// configure the unicode string to: point the buffer ptr to the wstr.
us->ustr.Buffer = us->wstr;
us->ustr.Length = 0;
us->ustr.MaximumLength = sizeof(USTR_240) - sizeof(UNICODE_STRING);
// get the friendly name
// "Comtrol xxxx xx" for board, "Comtrol Port(COM24)" for port.
status = IoGetDeviceProperty (Pdo,
DevicePropertyFriendlyName,
us->ustr.MaximumLength,
us->ustr.Buffer,
&resultLength);
us->ustr.Length = (USHORT) resultLength;
// ptr = UToC1(&us->ustr);
ptr = UToCStr( cstr,
&us->ustr,
sizeof( cstr ));
MyKdPrint(D_Pnp, ("FriendlyName:%s\n", ptr))
// get the class-name
// "MultiPortSerial" for board, "Ports" for port.
status = IoGetDeviceProperty (Pdo,
DevicePropertyClassName, // Ports
us->ustr.MaximumLength,
us->ustr.Buffer,
&resultLength);
us->ustr.Length = (USHORT) resultLength;
// ptr = UToC1(&us->ustr);
ptr = UToCStr( cstr,
&us->ustr,
sizeof( cstr ));
MyKdPrint(D_Pnp, ("ClassName:%s\n", ptr))
if (my_toupper(*ptr) == 'P') // "Ports"
{
MyKdPrint(D_Pnp, ("A Port!\n"))
board_device = 0; // its a port pnp device
}
// else it's the default: a board device
// get the dev-desc
// "RocketPort Port0" for port, "RocketPort 8 Port, ISA-BUS" for board
status = IoGetDeviceProperty (Pdo,
DevicePropertyDeviceDescription,
us->ustr.MaximumLength,
us->ustr.Buffer,
&resultLength);
us->ustr.Length = (USHORT) resultLength;
// ptr = UToC1(&us->ustr);
ptr = UToCStr( cstr,
&us->ustr,
sizeof( cstr ));
MyKdPrint(D_Pnp, ("DevDesc:%s\n", ptr))
// Find out what the PnP manager thinks my NT Hardware ID is
// "CtmPort0000" for port, "rckt1002" for isa-board
// for pci we are getting a huge string, 400 bytes long, not good...
status = IoGetDeviceProperty (Pdo,
DevicePropertyHardwareID, // port0000
us->ustr.MaximumLength,
us->ustr.Buffer,
&resultLength);
MyKdPrint(D_Pnp, ("status:%d\n", status))
us->ustr.Length = (USHORT) resultLength;
MyKdPrint(D_Pnp, ("Len:%d\n",resultLength))
// ptr = UToC1(&us->ustr);
ptr = UToCStr( cstr,
&us->ustr,
sizeof( cstr ));
MyKdPrint(D_Pnp, ("DevHdwID:%s\n", ptr))
if (board_device) // record board type according to pnp
{
// if (strlen(ptr) < 12)
// {
// i = gethint(&ptr[4], NULL);
// MyKdPrint(D_Pnp, ("HdwID:%d\n", i))
// Hardware_Id = i;
// }
}
else // its a port pnp device, find the port-index
{
while ((*ptr != 0) && (*ptr != '0'))
++ptr;
port_index = getint(ptr, NULL);
MyKdPrint(D_Pnp, ("port_index:%d\n", port_index))
}
#if 0
// key name
// {50906CB8-BA12-11D1-BF5D-0000F805F530}\0001 for board
status = IoGetDeviceProperty (Pdo,
DevicePropertyDriverKeyName, // 4D36....
us->ustr.MaximumLength,
us->ustr.Buffer,
&resultLength);
us->ustr.Length = (USHORT) resultLength;
MyKdPrint(D_Pnp, ("KeyName:%s\n", UToC1(&us->ustr)))
// Find out what the PnP manager thinks my NT Hardware ID is
// \Device\003354 typical
status = IoGetDeviceProperty (Pdo,
DevicePropertyPhysicalDeviceObjectName, // \Device\003354
us->ustr.MaximumLength,
us->ustr.Buffer,
&resultLength);
us->ustr.Length = (USHORT) resultLength;
MyKdPrint(D_Pnp, ("DevName:%s\n", UToC1(&us->ustr)))
if (board_device)
{
int i,j;
// we need to use this later as this is what our config data is
// stored under. Since we want to read in our config before
// creating the board and port extensions(where the config
// record eventually ends up), we setup the first entry in
// the static array of device configuration records as our
// own as a temporary measure so our read options routine
// has a place to put the config data.
strcpy(temp_szNt50DevObjName, UToC1(&us->ustr));
// strip off the forward slashes
i=0;
j=0;
while (temp_szNt50DevObjName[i] != 0)
{
if (temp_szNt50DevObjName[i] != '\\')
temp_szNt50DevObjName[j++] = temp_szNt50DevObjName[i];
i++;
}
temp_szNt50DevObjName[j] = 0;
}
#endif
ExFreePool(us);
us = NULL;
MyKdPrint(D_Pnp, ("CreateFdo\n"))
if (board_device)
{
status = AddBoardDevice(DriverObject, Pdo, &NewDevObj);
if (status != STATUS_SUCCESS)
{
MyKdPrint(D_Error, ("Err, Creating Board Obj\n"))
return status;
}
deviceExtension = NewDevObj->DeviceExtension;
//strcpy(deviceExtension->config->szNt50DevObjName, temp_szNt50DevObjName);
// read in our device configuration from the registry
stat = read_device_options(deviceExtension);
} // board device
else
{
status = AddPortDevice(DriverObject, Pdo, &NewDevObj, port_index);
}
if (status != STATUS_SUCCESS)
{
MyKdPrint(D_Error,("Error on NewPort Create!\n"))
return status;
}
fdo = NewDevObj;
// Layer our FDO on top of the PDO
// The return value is a pointer to the device object to which the
// fdo is actually attached.
lowerDevice = IoAttachDeviceToDeviceStack(fdo, Pdo);
MyKdPrint(D_PnpAdd,("RK:SerialAddDevice New FDO:%x, Ext:%x TopOfStack:%x\n",
fdo, fdo->DeviceExtension, lowerDevice))
// No status. Do the best we can.
MyAssert(lowerDevice);
// fdo source, pdo is target, save handle to lower device object
deviceExtension = fdo->DeviceExtension;
deviceExtension->LowerDeviceObject = lowerDevice;
deviceExtension->Pdo = Pdo; // save off the handle to the pdo
// Set the stack requirement for this device object to 2 + the size of the
// lower device's stack size. This will allow the same Irp that comes in
// for Open and Close calls to be used for the PoCallDriver calls to change
// the power state of the device.
// fdo->StackSize = lowerDevice->StackSize + 2;
fdo->Flags |= DO_POWER_PAGABLE;
#if DBG_STACK
stkchkend = 0;
stkptr = (DWORD *)&DriverObject;
for (i=0; i<50; i++)
{
stkchkend += *stkptr++;
}
if (stkchkend != stkchk)
{
MyKdPrint(D_Error, ("Err, ******** STACK CHECK FAIL!!!!\n"))
}
else
{
MyKdPrint(D_Error, ("OK Stack chk\n"))
}
#endif
MyKdPrint(D_PnpAdd, ("End SerialAddDevice\n"))
MyKdPrint(D_Pnp, ("End SerialAddDevice\n"))
return status;
}
/*----------------------------------------------------------------------
AddBoardDevice - Setup and Create a board device in response to
AddDevice ioctl.
|----------------------------------------------------------------------*/
NTSTATUS AddBoardDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo,
OUT PDEVICE_OBJECT *NewDevObj)
{
PSERIAL_DEVICE_EXTENSION NewExtension = NULL;
NTSTATUS status = STATUS_SUCCESS;
char tmpstr[110];
ULONG Hardware_ID = 0;
int num_ports = 0;
int stat;
static int max_isa_board_index = 0;
int device_node_index = -1;
int isa_board_index = -1;
MyKdPrint(D_Pnp, ("AddBoardDevice\n"))
// Find out what the PnP manager thinks my NT pnp Hardware ID is
tmpstr[0] = 0;
stat = GetPnpIdStr(Pdo, tmpstr);
if (stat)
{
MyKdPrint(D_Error, ("Err, HdwID 1B\n"))
}
MyKdPrint(D_Test, ("DevHdwID:%s\n", tmpstr))
// Parse this info, tells us what type of board we have
stat = HdwIDStrToID(&Hardware_ID, tmpstr);
if (stat)
{
MyKdPrint(D_Error, ("Err, HdwID 1A:%s\n", tmpstr))
}
MyKdPrint(D_Pnp, ("HdwID:%x\n", Hardware_ID))
// Read in our Node Index, see if we are new...
stat = read_config_data(Pdo, &device_node_index, CFG_ID_NODE_INDEX);
if (stat) // not exist
{
derive_unique_node_index(&device_node_index);
MyKdPrint(D_Test, ("Derive Node ID:%d\n", device_node_index))
stat = write_config_data(Pdo, device_node_index, CFG_ID_NODE_INDEX);
}
else
{
MyKdPrint(D_Test, ("Node ID:%d\n", device_node_index))
}
if (device_node_index < 0)
device_node_index = 0;
#ifdef S_RK
// try to order the ISA boards
if ((Hardware_ID >= 0x1000) && (Hardware_ID <= 0x2fff)) // its ISA
{
stat = read_config_data(Pdo, &isa_board_index, CFG_ID_ISA_BRD_INDEX);
MyKdPrint(D_Pnp,("Read isa_board_index:%d\n", isa_board_index))
}
#endif
//----- create a board device
Driver.Stop_Poll = 1; // flag to stop poll access
if (Driver.driver_ext == NULL)
{
status = CreateDriverDevice(Driver.GlobalDriverObject,
&NewExtension); // create the driver device
#ifdef S_VS
init_eth_start();
#endif
}
status = CreateBoardDevice(Driver.GlobalDriverObject,
&NewExtension); // create the board device
*NewDevObj = NewExtension->DeviceObject;
if (status != STATUS_SUCCESS)
{
Driver.Stop_Poll = 0; // flag to stop poll access
Eprintf("CreateBoardDevice Err1A");
return status;
}
// DoPnpAssoc(Pdo);
// copy over our key name used to find config info in the registry
Sprintf(NewExtension->config->szNt50DevObjName, "Device%d", device_node_index);
#if 0
//strcpy(NewExtension->config->szNt50DevObjName, PnpKeyName);
#endif
NewExtension->config->Hardware_ID = Hardware_ID;
num_ports = id_to_num_ports(Hardware_ID);
MyKdPrint(D_Test, ("NumPorts:%d\n", num_ports))
// read in our device configuration from the registry
stat = read_device_options(NewExtension);
//if (!(Hardware_ID == NET_DEVICE_VS1000)) // jam in
// NewExtension->config->NumPorts = num_ports;
if (NewExtension->config->NumPorts == 0)
NewExtension->config->NumPorts = num_ports;
// check for ModemDevice, etc.
if (IsModemDevice(Hardware_ID))
NewExtension->config->ModemDevice = 1;
MyKdPrint(D_Pnp, ("Num Ports:%d\n",NewExtension->config->NumPorts))
#ifdef S_RK
// try to order the ISA boards
if ((Hardware_ID >= 0x1000) && (Hardware_ID <= 0x2fff)) // its ISA
{
if (isa_board_index == -1) // new
{
isa_board_index = max_isa_board_index;
stat = write_config_data(Pdo, isa_board_index, CFG_ID_ISA_BRD_INDEX);
MyKdPrint(D_Pnp,("Save IsaIndex:%d\n", isa_board_index))
}
// bump so next isa board gets new index
if (max_isa_board_index >= isa_board_index)
max_isa_board_index = isa_board_index + 1;
NewExtension->config->ISABrdIndex = isa_board_index;
} // isa board
#endif
Driver.Stop_Poll = 0; // flag to stop poll access
status = STATUS_SUCCESS;
return status;
}
/*----------------------------------------------------------------------
derive_unique_node_index -
|----------------------------------------------------------------------*/
static int derive_unique_node_index(int *ret_val)
{
HANDLE DrvHandle = NULL;
HANDLE DevHandle = NULL;
char tmpstr[40];
int i, stat;
// force a creation of "Parameters" if not exist
stat = our_open_driver_reg(&DrvHandle, KEY_ALL_ACCESS);
for (i=0; i< 100; i++)
{
Sprintf(tmpstr,"Device%d", i);
stat = our_open_key(&DevHandle,
DrvHandle, tmpstr, KEY_READ);
if (stat) // does not exist
{
// create it, so next one won't pick up the same
stat = our_open_key(&DevHandle,
DrvHandle, tmpstr, KEY_ALL_ACCESS);
ZwClose(DevHandle);
ZwClose(DrvHandle);
*ret_val = i;
return 0; // ok
}
}
ZwClose(DevHandle);
ZwClose(DrvHandle);
return 1; // err
}
/*----------------------------------------------------------------------
GetPnpIdStr -
|----------------------------------------------------------------------*/
static int GetPnpIdStr(PDEVICE_OBJECT Pdo, char *ret_val)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustr;
ULONG resultLength = 0;
char *ptr;
// configure the unicode string to: point the buffer ptr to the wstr.
ustr.Buffer = ExAllocatePool(PagedPool, 1002);
if ( ustr.Buffer == NULL ) {
return -1;
}
ustr.Length = 0;
ustr.MaximumLength = 1000;
MyKdPrint(D_Pnp, ("AddBoardDevice\n"))
// Find out what the PnP manager thinks my NT Hardware ID is
// "CtmPort0000" for port, "rckt1002" for isa-board
// for pci we are getting a multi-wstring, 400 bytes long with
// "PCI\VEN_11FE&DEV_0003&SUBSYS00000...",0,"PCI\VEN.."
status = IoGetDeviceProperty (Pdo,
DevicePropertyHardwareID, // port0000
ustr.MaximumLength,
ustr.Buffer,
&resultLength);
ustr.Length = (USHORT) resultLength;
if (ustr.Length > 100)
ustr.Length = 100; // limit
ptr = UToC1(&ustr);
strcpy(ret_val, ptr);
ExFreePool(ustr.Buffer);
MyKdPrint(D_Pnp, ("DevHdwID:%s\n", ret_val))
return 0;
}
#if 0
/*----------------------------------------------------------------------
DoPnpAssoc - Weird pnp stuff I haven't figured out yet
|----------------------------------------------------------------------*/
static int DoPnpAssoc(PDEVICE_OBJECT Pdo)
{
if (!Driver.NoPnpPorts)
{
#ifdef DO_BUS_SHINGLES
//
// Tell the PlugPlay system that this device will need an interface
// device class shingle.
//
// It may be that the driver cannot hang the shingle until it starts
// the device itself, so that it can query some of its properties.
// (Aka the shingles guid (or ref string) is based on the properties
// of the device.)
//
status = IoRegisterDeviceInterface (
Pdo, // BusPhysicalDeviceObject
(LPGUID) &GUID_CTMPORT_BUS_ENUMERATOR,
NULL, // No ref string
&NewExtension->DevClassAssocName);
#endif
//
// If for any reason you need to save values in a safe location that
// clients of this DeviceClassAssociate might be interested in reading
// here is the time to do so, with the function
// IoOpenDeviceClassRegistryKey
// the symbolic link name used is was returned in
// deviceData->DevClassAssocName (the same name which is returned by
// IoGetDeviceClassAssociations and the SetupAPI equivs.
//
//status = IoGetDeviceProperty (BusPhysicalDeviceObject,
// DevicePropertyPhysicalDeviceObjectName,
// 0,
// NULL,
// &nameLength);
//IoGetDeviceProperty (BusPhysicalDeviceObject,
// DevicePropertyPhysicalDeviceObjectName,
// nameLength,
// deviceName,
// &nameLength);
//Game_KdPrint (deviceData, GAME_DBG_SS_TRACE,
// ("AddDevice: %x to %x->%x (%ws) \n",
// deviceObject,
// NewExtension->TopOfStack,
// BusPhysicalDeviceObject,
// deviceName));
//
// Turn on the shingle and point it to the given device object.
//
#ifdef DO_BUS_SHINGLES
status = IoSetDeviceInterfaceState (
&NewExtension->DevClassAssocName,
TRUE);
if (!NT_SUCCESS (status)) {
Game_KdPrint (deviceData, GAME_DBG_SS_ERROR,
("AddDevice: IoSetDeviceClass failed (%x)", status));
return status;
}
#endif
//IoInvalidateDeviceRelations (NewExtension->DeviceObject, BusRelations);
} // !NoPnpPorts
#endif
/*----------------------------------------------------------------------
write_config_data -
|----------------------------------------------------------------------*/
static int write_config_data(PDEVICE_OBJECT Pdo, int val, int val_id)
{
HANDLE keyHandle;
NTSTATUS status = STATUS_SUCCESS;
USTR_40 uname;
status = IoOpenDeviceRegistryKey(Pdo, PLUGPLAY_REGKEY_DRIVER,
KEY_WRITE, &keyHandle);
if (!NT_SUCCESS(status))
{
MyKdPrint(D_Error, ("Err7V\n"))
return 1;
}
switch(val_id)
{
case CFG_ID_ISA_BRD_INDEX:
CToUStr((PUNICODE_STRING)&uname, "isa_board_index", sizeof(uname));
break;
case CFG_ID_NODE_INDEX:
CToUStr((PUNICODE_STRING)&uname, "CtmNodeId", sizeof(uname));
break;
}
status = ZwSetValueKey (keyHandle,
(PUNICODE_STRING) &uname,
0, // type optional
REG_DWORD,
&val,
sizeof(REG_DWORD));
if (!NT_SUCCESS(status))
{
MyKdPrint(D_Error, ("Err8V\n"))
}
ZwClose(keyHandle);
return 0;
}
/*----------------------------------------------------------------------
read_config_data -
|----------------------------------------------------------------------*/
static int read_config_data(PDEVICE_OBJECT Pdo, int *ret_val, int val_id)
{
HANDLE keyHandle;
NTSTATUS status = STATUS_SUCCESS;
ULONG tmparr[100];
USTR_40 uname;
PKEY_VALUE_PARTIAL_INFORMATION parInfo =
(PKEY_VALUE_PARTIAL_INFORMATION) &tmparr[0];
ULONG length;
int ret_stat = 1; // err
//----- go grab some configuration info from registry
// PLUGPLAY_REGKEY_DRIVER opens up the control\class\{guid}\node
// PLUGPLAY_REGKEY_DEVICE opens up the enum\enum-type\node\Device Parameters
status = IoOpenDeviceRegistryKey(Pdo,
PLUGPLAY_REGKEY_DRIVER,
STANDARD_RIGHTS_READ,
&keyHandle);
if (!NT_SUCCESS(status))
{
return 2; // err
}
switch(val_id)
{
case CFG_ID_ISA_BRD_INDEX:
CToUStr((PUNICODE_STRING)&uname, "isa_board_index", sizeof(uname));
break;
case CFG_ID_NODE_INDEX:
CToUStr((PUNICODE_STRING)&uname, "CtmNodeId", sizeof(uname));
break;
}
// try to order the ISA boards
status = ZwQueryValueKey (keyHandle,
(PUNICODE_STRING) &uname,
KeyValuePartialInformation,
parInfo,
sizeof(tmparr),
&length);
if (NT_SUCCESS(status))
{
if (parInfo->Type == REG_DWORD)
{
ret_stat = 0; // ok
*ret_val = *((ULONG *) &parInfo->Data[0]);
//MyKdPrint(D_Pnp,("Read isa_board_index:%d\n", isa_board_index))
}
}
ZwClose(keyHandle);
return ret_stat;
}
/*----------------------------------------------------------------------
AddPortDevice - Setup and Create a pnp port device in response to
AddDevice ioctl. This can be caused by either:
* pdo port objects ejected from our driver at board startup.
|----------------------------------------------------------------------*/
NTSTATUS AddPortDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo,
OUT PDEVICE_OBJECT *NewDevObj,
IN int port_index)
{
NTSTATUS status = STATUS_SUCCESS;
PSERIAL_DEVICE_EXTENSION NewExtension;
PSERIAL_DEVICE_EXTENSION ext;
PSERIAL_DEVICE_EXTENSION ParExt;
MyKdPrint(D_Pnp, ("AddPortDevice\n"))
// Find the parent device
ext = (PSERIAL_DEVICE_EXTENSION) Pdo->DeviceExtension;
if (ext == NULL)
{
MyKdPrint(D_Pnp, ("Er7E\n"))
return STATUS_SERIAL_NO_DEVICE_INITED;
}
else
ParExt = ext->board_ext;
CheckPortName(Pdo, ParExt, port_index);
//----- create a port device
Driver.Stop_Poll = 1; // flag to stop poll access
status = CreatePortDevice(
Driver.GlobalDriverObject,
ParExt, // parent ext.
&NewExtension, // new device ext.
port_index, // port index, channel number
1); // is_fdo
if (status != STATUS_SUCCESS)
{
Driver.Stop_Poll = 0; // flag to stop poll access
MyKdPrint(D_Error, ("Error Creating Port\n"))
return STATUS_SERIAL_NO_DEVICE_INITED;
}
if (status == STATUS_SUCCESS)
{
*NewDevObj = NewExtension->DeviceObject;
status = StartPortHardware(NewExtension, port_index);
if (status != STATUS_SUCCESS)
{
Driver.Stop_Poll = 0; // flag to stop poll access
MyKdPrint(D_Error, ("5D\n"))
// bugbug: should delete our port here
return STATUS_SERIAL_NO_DEVICE_INITED;
}
}
if (!NT_SUCCESS(status)) {
Driver.Stop_Poll = 0; // flag to stop poll access
Eprintf("CreateBoardDevice Err1A");
return status;
}
Driver.Stop_Poll = 0; // flag to stop poll access
status = STATUS_SUCCESS;
return status;
}
/*----------------------------------------------------------------------
CheckPortName - Make sure the port-name for us in the registry works.
Get the pnp-port name held in the enum branch, if ours does not match,
then change it to match(use the pnp-port name.)
|----------------------------------------------------------------------*/
NTSTATUS CheckPortName(
IN PDEVICE_OBJECT Pdo,
IN PSERIAL_DEVICE_EXTENSION ParentExt,
IN int port_index)
{
HANDLE keyHandle;
NTSTATUS status;
char namestr[20];
PORT_CONFIG *port_config;
MyKdPrint(D_Pnp, ("CheckPortName\n"))
//----- go grab PORTNAME configuration info from registry
// serial keeps params under ENUM branch so we open DEVICE not DRIVER
// which is considered CLASS area.
// opens: enum\device\node\Device Parameters area
// status = IoOpenDeviceRegistryKey(Pdo, PLUGPLAY_REGKEY_DRIVER,
namestr[0] = 0;
status = IoOpenDeviceRegistryKey(Pdo,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_READ,
&keyHandle);
// go get "Device Parameters\PortName"="COM5"
// also, key params: PollingPeriod=, Serenumerable=
if (NT_SUCCESS(status))
{
status = get_reg_value(keyHandle, namestr, "PortName", 15);
if (status) // err
{
namestr[0] = 0;
MyKdPrint(D_Error, ("No PortName\n"))
}
else
{
MyKdPrint(D_Pnp, ("PortName:%s\n", namestr))
}
ZwClose(keyHandle);
}
if ((strlen(namestr) > 10) || (strlen(namestr) <= 0))
{
MyKdPrint(D_Error, ("Bad PortName Er1E\n"))
}
port_config = &ParentExt->config->port[port_index];
if (my_lstricmp(port_config->Name, namestr) != 0) // it does not match!
{
MyKdPrint(D_Pnp, ("port name fixup to:%s, from%s\n",
namestr, port_config->Name))
// fix it, use one assigned by port class installer
strcpy(port_config->Name, namestr);
write_port_name(ParentExt, port_index);
}
return 0;
}
#endif // nt50