I wrote several months ago asking where to get started. I got several
links which were helpful, and after some delay I finally got the
hardware so I can start testing actual drivers (hardware was supposed to
be available in July or August but stuff happened to delay it).
The drivers I need to do are pretty simple functionally. They talk in
the outside world with a testing device. Currently they have two
hardware interfaces to the testing device: parallel port (EPP mode) and
through an ISA card of their own design. The ISA card is not PnP and
only has three 8 bit I/O registers read and write.
Up until now they have been using a driver called PortTalk which is
freeware originally intended for Win 9x. It works with NT OSs up to XP,
but only in Administrator mode.
I have a number of requirements for new drivers to replace PortTalk:
- Needs to work in non-Administrator mode after installation
- Needs to work under Win 7 32 bit (Vista would be a nice to have, but
they plan to skip Vista and go directly to 7 for the next version of
their system) - After getting drivers to work for parallel and ISA, they want a newer
technology driver. USB is the desired choice, but PCI is an acceptable
fallback. That’s only after I get the first two working.
In the Windows 7 DDK, I found a sample for port I/O that is very close
to what I need and I modified it for my uses for the ISA driver. I also
found source for a parallel driver on the internet called inpout32.sys
that does exactly what I want for the parallel driver, so I made some
minor changes to it and am using it.
I’ve been able to get the parallel driver to work as expected under XP
as Administrator. If I log off and long back on as a non-Admin user
without rebooting, it will work on there too, but won’t work on a fresh
boot into the non-Admin user.
I’ve got a head scratcher with the ISA driver and it won’t load.
Neither load under Win 7.
I am using auto load driver and service code, which I think may be why
they won’t work under 7 and the non-Admin mode in XP won’t work on a
fresh boot. In various examples I’ve found they are all variations on
the code I’m using. I’ve included it at the bottom of this message.
I inserted a bunch of MessageBox code to try and track what’s going on.
I need to do all testing of the ISA driver on a system other than my
development system (modern computers with ISA buses are hard to find).
I’m also testing the parallel port version there too.
Here are my questions and more specifics on my problems:
- Where is the Service Control Manager in the system? I have searched
the registry and Device Manager for references to my drivers. I was
able to remove the Parallel port driver from the system by deleting it
from the driver tree in Device Manager and deleting all references to it
in the registry (which was either 4 or 5 if I remember right). Next
call to the program installs the driver again and everything is OK under
XP Admin.
With ISA, the Service Control Manager seems to think the driver (called
MTIsaDrv) is already installed. In StartService, OpenSCManager works,
then OpenService returns a handle, but StartService fails. I have
triple checked and there is a driver named MTIsaDrv.sys in the
Windows\System32\drivers directory (right next to inpout32.sys when
sorted by date). The error code I get is ERROR_FILE_NOT_FOUND
I have searched the registry and there are no references to MTIsaDrv at
all. So where is the Service Control Manager seeing the driver service?
Similarly, there are no services in the service manager or drivers
listed in Device Manager. - When I was configuring Win 7 I ran into many cases where even though
I was logged into an account with Admin privileges, the system would
squawk at me saying things needed to be elevated to run. It appears
that the default for accounts with Admin privileges is to run with those
permissions off and you have to turn them on case by case. To run with
non-Admin privileges should the driver and service be installed and
turned on outside the program and then the program just connects to the
service? Looking back at my notes, it doesn’t look like I documented
the errors I got perfectly, but I recall getting ERROR_FILE_NOT_FOUND in
this case too. I recall seeing ERROR_ACCESS_DENIED, but I think that’s
when I accidentally tried to install the old PortTalk driver.
int LoadMTDriver(char *name)
{
char str[100];
DWORD err;
if(SystemVersion()==1)
return -1; //Trying to run on Windows 9x, not supported
sprintf(str,“\\.\%s”,name);
/* Open Driver */
DriverHandle = CreateFile(str,GENERIC_READ,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(DriverHandle == INVALID_HANDLE_VALUE)
{
/* Start or Install Driver */
StartDriver(name);
/* Then try to open once more, before failing */
DriverHandle = CreateFile(str,GENERIC_READ,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(DriverHandle == INVALID_HANDLE_VALUE)
{
err = GetLastError();
sprintf(str,“Can’t access %s driver, error=%d”,name,err);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
return (char)-1; //WDO 6/23/10 Add cast
}
//DEBUG!!!
else
{
sprintf(str,“01 Load driver %s succeeded, DriverHandle=0x%x”,name,
DriverHandle);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
}
//DEBUG!!!
else
{
sprintf(str,“02 Load driver %s succeeded, DriverHandle=0x%x”,name,
DriverHandle);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
return 0;
}
//************************************************************
unsigned char StartDriver(char *name)
{
SC_HANDLE SchSCManager;
SC_HANDLE schService;
BOOL ret;
DWORD err;
char str[100];
/* Open Handle to Service Control Manager */
SchSCManager = OpenSCManager (NULL, /* machine (NULL == local) */
NULL, /* database (NULL == default) */
SC_MANAGER_ALL_ACCESS); /* access required */
if (SchSCManager == NULL)
{
err = GetLastError();
if ( err == ERROR_ACCESS_DENIED)
{
sprintf(str,“Can’t open service control manager for %s driver: Access
Denied”,name);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
return(0);
}
else
{
sprintf(str,“%s driver: Failed to open service control manager, error
code=0x%x”,name,err);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
}
/* Open a Handle to the Service Database */
sprintf(str, “%s”,name);
schService = OpenService(SchSCManager, /* handle to service control
manager database */
str, /* pointer to name of service to start */
SERVICE_ALL_ACCESS); /* type of access to service */
if (schService == NULL)
{
err=GetLastError();
switch (err)
{
case ERROR_ACCESS_DENIED:
sprintf(str, “Error - Rights error to %s service”,name);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
return(0);
case ERROR_INVALID_NAME:
sprintf(str, “Error - Invalid service name for %s driver”,name);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
return(0);
case ERROR_SERVICE_DOES_NOT_EXIST:
InstallMTDriver(name);
//Need to start again
sprintf(str,“%s”,name);
schService = OpenService(SchSCManager, /* handle to service
control manager database */
str, /* pointer to name of service to start */
SERVICE_ALL_ACCESS); /* type of access to service */
if(schService==NULL)
{
sprintf(str, “Error - Can’t open %s service after two attempts”,name);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
//DEBUG!!!
else
{
sprintf(str,“01 Start driver %s open service succeeded,
schService=0x%x”,name, schService);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
break;
default:
sprintf(str,“Error Installing %s Driver, code=0x%x”,name,err);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
break;
}
return 0;
}
//DEBUG!!!
else
{
sprintf(str,“02 Start driver %s open service succeeded,
schService=0x%x”,name, schService);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
/* Start the Driver. Errors will occur here if .SYS file doesn’t
exist */
ret = StartService (schService, /* service identifier */
0, /* number of arguments */
NULL); /* pointer to arguments */
if (!ret)
{
err = GetLastError();
if (err != ERROR_SERVICE_ALREADY_RUNNING)
{
sprintf(str,“Error starting %s service, error code=0x%x”,name,err);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
return(0);
}
}
/* Close handle to Service Control Manager */
CloseServiceHandle (schService);
return(TRUE);
}
//***************************************************
void InstallMTDriver(char *name)
{
SC_HANDLE SchSCManager;
SC_HANDLE schService;
DWORD err;
char DriverFileName[80];
char str[100];
char strx[200];
//Assume driver is already in the system32\driver directory. The
program installer puts it there.
//DEBUG!!!
sprintf(str,“%s: Install driver”,name);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
if(!GetSystemDirectory(DriverFileName, 55))
{
sprintf(str,“%s: Attempt to get system directory name failed”,name);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
/* Append our Driver Name */
sprintf(str,“\Drivers\%s”,name);
lstrcat(DriverFileName,str);
/* Open Handle to Service Control Manager */
SchSCManager = OpenSCManager (NULL, /* machine (NULL == local) */
NULL, /* database (NULL == default) */
SC_MANAGER_ALL_ACCESS); /* access required */
/* Create Service/Driver - This adds the appropriate registry keys in */
/* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services - It doesn’t */
/* care if the driver exists, or if the path is correct. */
sprintf(str,“System32\Drivers\%s.sys”,name);
schService = CreateService (SchSCManager, /* SCManager database */
name, /* name of service */
name, /* name to display */
SERVICE_ALL_ACCESS, /* desired
access */
SERVICE_KERNEL_DRIVER, /* service
type */
SERVICE_DEMAND_START, /* start type */
SERVICE_ERROR_NORMAL, /* error
control type */
str, /* service’s binary */
NULL, /* no load ordering
group */
NULL, /* no tag identifier */
NULL, /* no dependencies */
NULL, /* LocalSystem
account */
NULL /* no password */
);
if (schService == NULL)
{
err = GetLastError();
if (err == ERROR_SERVICE_EXISTS)
{
sprintf(str,“%s driver install: Attempt to install driver
found it already installed. There may be a system misconfiguration”,name);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
else
sprintf(str,“%s driver install: Unknown error installing
the driver”,name);
MessageBox(NULL, str, “DeviceIoControl”, MB_OK);
}
else
{
//TEMP DEBUG
sprintf(strx,“%s driver install success path=%s”,name,str);
MessageBox(NULL, strx, “DeviceIoControl”, MB_OK);
}
/* Close Handle to Service Control Manager */
CloseServiceHandle (schService);
}