By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,993 Members | 1,947 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,993 IT Pros & Developers. It's quick & easy.

Is C# support load device driver?

P: n/a
I wrote a simple virtual device driver int15.sys, Is C# support load the
device driver from AP?
Nov 16 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Steve wrote:
I wrote a simple virtual device driver int15.sys, Is C# support load the
device driver from AP?


Aren't drivers used by the OS (windows) ? So how did you plan to use this
driver?

Frans.

--
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Microsoft C# MVP
Nov 16 '05 #2

P: n/a
Nope, yoou can interact directly with them vice the DeviceIOControl API. I've done this in the past to write to area of the physical disk that win32 doesn't support.

So I guess to be able to interact with a device driver from C# you'd have to P/Invoke to DeviceIOControl

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn***************@msnews.microsoft.com>

Steve wrote:
I wrote a simple virtual device driver int15.sys, Is C# support load the
device driver from AP?


Aren't drivers used by the OS (windows) ? So how did you plan to use this
driver?

Frans.

--
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Microsoft C# MVP

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.766 / Virus Database: 513 - Release Date: 17/09/2004

[microsoft.public.dotnet.languages.csharp]
Nov 16 '05 #3

P: n/a
Yes, you are right, after I load device driver, I can use DeviceIOControl, I
wrote a virtual device driver, int15h.sys,
the purpose of this device driver is provide a interface to BIOS int15h, we
also modify the BIOS int15h, support
wireless/bluetooth power on/off, AP through virtual device driver, can power
on/off PC system wireless/bluetooth.

I need to load int15h.sys before I use DeviceIOControl, in C++, I found some
API
int SCManager = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
GetServiceName(Path, Driver, DeviceName);
int dwStatus = DriverInstall(SCManager, Path, Driver);
int dwStatus1 = DriverStart(SCManager, Driver);
can load the driver, my question is "Can C# support load device driver?"
"Richard Blewett [DevelopMentor]" wrote:
Nope, yoou can interact directly with them vice the DeviceIOControl API. I've done this in the past to write to area of the physical disk that win32 doesn't support.

So I guess to be able to interact with a device driver from C# you'd have to P/Invoke to DeviceIOControl

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn***************@msnews.microsoft.com>

Steve wrote:
> I wrote a simple virtual device driver int15.sys, Is C# support load the
> device driver from AP?


Aren't drivers used by the OS (windows) ? So how did you plan to use this
driver?

Frans.

--
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Microsoft C# MVP

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.766 / Virus Database: 513 - Release Date: 17/09/2004

[microsoft.public.dotnet.languages.csharp]

Nov 16 '05 #4

P: n/a
Can you not use CreateFile to open the device?

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<EA**********************************@microsoft.co m>

Yes, you are right, after I load device driver, I can use DeviceIOControl, I
wrote a virtual device driver, int15h.sys,
the purpose of this device driver is provide a interface to BIOS int15h, we
also modify the BIOS int15h, support
wireless/bluetooth power on/off, AP through virtual device driver, can power
on/off PC system wireless/bluetooth.

I need to load int15h.sys before I use DeviceIOControl, in C++, I found some
API
int SCManager = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
GetServiceName(Path, Driver, DeviceName);
int dwStatus = DriverInstall(SCManager, Path, Driver);
int dwStatus1 = DriverStart(SCManager, Driver);
can load the driver, my question is "Can C# support load device driver?"
"Richard Blewett [DevelopMentor]" wrote:
Nope, yoou can interact directly with them vice the DeviceIOControl API. I've done this in the past to write to area of the physical disk that win32 doesn't support.

So I guess to be able to interact with a device driver from C# you'd have to P/Invoke to DeviceIOControl

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn***************@msnews.microsoft.com>

Steve wrote:
I wrote a simple virtual device driver int15.sys, Is C# support load the
device driver from AP?


Aren't drivers used by the OS (windows) ? So how did you plan to use this
driver?

Frans.

--
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Microsoft C# MVP

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.766 / Virus Database: 513 - Release Date: 17/09/2004

[microsoft.public.dotnet.languages.csharp]


---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.766 / Virus Database: 513 - Release Date: 17/09/2004

[microsoft.public.dotnet.languages.csharp]
Nov 16 '05 #5

P: n/a
Yes, before DeviceIOControl, use CreateFile to get a handle.
if not support load driver in C#, is anyone know the dllentry for
GetServiceName
DriverInstall
DriverStart
For I only found OpenSCManager from MSDN
[DllImport("advapi32.dll")]
int SCManager = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);

"Richard Blewett [DevelopMentor]" wrote:
Can you not use CreateFile to open the device?

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<EA**********************************@microsoft.co m>

Yes, you are right, after I load device driver, I can use DeviceIOControl, I
wrote a virtual device driver, int15h.sys,
the purpose of this device driver is provide a interface to BIOS int15h, we
also modify the BIOS int15h, support
wireless/bluetooth power on/off, AP through virtual device driver, can power
on/off PC system wireless/bluetooth.

I need to load int15h.sys before I use DeviceIOControl, in C++, I found some
API
int SCManager = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
GetServiceName(Path, Driver, DeviceName);
int dwStatus = DriverInstall(SCManager, Path, Driver);
int dwStatus1 = DriverStart(SCManager, Driver);
can load the driver, my question is "Can C# support load device driver?"
"Richard Blewett [DevelopMentor]" wrote:
> Nope, yoou can interact directly with them vice the DeviceIOControl API. I've done this in the past to write to area of the physical disk that win32 doesn't support.
>
> So I guess to be able to interact with a device driver from C# you'd have to P/Invoke to DeviceIOControl
>
> Regards
>
> Richard Blewett - DevelopMentor
> http://staff.develop.com/richardb/weblog
>
> nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn***************@msnews.microsoft.com>
>
> Steve wrote:
>
> > I wrote a simple virtual device driver int15.sys, Is C# support load the
> > device driver from AP?

>
> Aren't drivers used by the OS (windows) ? So how did you plan to use this
> driver?
>
> Frans.
>
> --
> Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
> My .NET Blog: http://weblogs.asp.net/fbouma
> Microsoft C# MVP
>
> ---
> Incoming mail is certified Virus Free.
> Checked by AVG anti-virus system (http://www.grisoft.com).
> Version: 6.0.766 / Virus Database: 513 - Release Date: 17/09/2004
>
>
>
> [microsoft.public.dotnet.languages.csharp]
>


---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.766 / Virus Database: 513 - Release Date: 17/09/2004

[microsoft.public.dotnet.languages.csharp]

Nov 16 '05 #6

P: n/a
Richard Blewett [DevelopMentor] wrote:
Nope, yoou can interact directly with them vice the DeviceIOControl API.
I've done this in the past to write to area of the physical disk that win32
doesn't support.

So I guess to be able to interact with a device driver from C# you'd have
to P/Invoke to DeviceIOControl
(just to make it clear to me, not to nittpick ;))
But isn't this just a wrapper around Windows' device manager? There is no
way you will be able to poke into hardware without a kernel space module, as
everything is virtualized: you can't simply throw an interrupt or set an
address to a value to change some hardware's internal settings (at least
that's what I know of it).

Frans.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn0dnlt0
z3*******@msnews.microsoft.com>

Steve wrote:
> I wrote a simple virtual device driver int15.sys, Is C# support load the
> device driver from AP?


Aren't drivers used by the OS (windows) ? So how did you plan to use this
driver?

--
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Microsoft C# MVP
Nov 16 '05 #7

P: n/a
DeviceIOControl is simply a way of passing "op-codes" to a kernel mode device driver and retrieving the results. You obviously can't *write* a device driver in C# but you can interrogate a device driver via pinvoke.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn***************@msnews.microsoft.com>

Richard Blewett [DevelopMentor] wrote:
Nope, yoou can interact directly with them vice the DeviceIOControl API.
I've done this in the past to write to area of the physical disk that win32
doesn't support.

So I guess to be able to interact with a device driver from C# you'd have
to P/Invoke to DeviceIOControl
(just to make it clear to me, not to nittpick ;))
But isn't this just a wrapper around Windows' device manager? There is no
way you will be able to poke into hardware without a kernel space module, as
everything is virtualized: you can't simply throw an interrupt or set an
address to a value to change some hardware's internal settings (at least
that's what I know of it).

Frans.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn0dnlt0
z3*******@msnews.microsoft.com>

Steve wrote:
I wrote a simple virtual device driver int15.sys, Is C# support load the
device driver from AP?


Aren't drivers used by the OS (windows) ? So how did you plan to use this
driver?

--
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Microsoft C# MVP

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.766 / Virus Database: 513 - Release Date: 17/09/2004

[microsoft.public.dotnet.languages.csharp]
Nov 16 '05 #8

P: n/a

"Steve" <St***@discussions.microsoft.com> wrote in message
news:D4**********************************@microsof t.com...
Yes, before DeviceIOControl, use CreateFile to get a handle.
if not support load driver in C#, is anyone know the dllentry for
GetServiceName
DriverInstall
DriverStart
For I only found OpenSCManager from MSDN
[DllImport("advapi32.dll")]
int SCManager = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);

Drivers are no different than services in Windows, they are controled
(loaded, unloaded etc..) by the SCM, but before you can do this they need to
be installed/registered into the SC database (Registry). You can do this
from C# using the System.Management classes (and the WMI class
Win32_BaseService).
First you have to create a Win32_BaseService class describing your driver
(supplying stuff like PathName="\Mydrivers\MyDriver.sys") by calling
"Create" on the Win32_BaseService WMI Class.
Once you have this (registration) done you can call any of the methods like
"StartService", "StopService", "ChangeService" on an instance of this WMI
class.

Willy.
Nov 16 '05 #9

P: n/a
All,

Thanks for the help about this issue.

Willy,

I think you answer my question, for I am new in C#, I will try figure out
how to implement based on your suggestion, really appreciated.

"Willy Denoyette [MVP]" wrote:

"Steve" <St***@discussions.microsoft.com> wrote in message
news:D4**********************************@microsof t.com...
Yes, before DeviceIOControl, use CreateFile to get a handle.
if not support load driver in C#, is anyone know the dllentry for
GetServiceName
DriverInstall
DriverStart
For I only found OpenSCManager from MSDN
[DllImport("advapi32.dll")]
int SCManager = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);

Drivers are no different than services in Windows, they are controled
(loaded, unloaded etc..) by the SCM, but before you can do this they need to
be installed/registered into the SC database (Registry). You can do this
from C# using the System.Management classes (and the WMI class
Win32_BaseService).
First you have to create a Win32_BaseService class describing your driver
(supplying stuff like PathName="\Mydrivers\MyDriver.sys") by calling
"Create" on the Win32_BaseService WMI Class.
Once you have this (registration) done you can call any of the methods like
"StartService", "StopService", "ChangeService" on an instance of this WMI
class.

Willy.

Nov 16 '05 #10

P: n/a
Richard Blewett [DevelopMentor] wrote:
DeviceIOControl is simply a way of passing "op-codes" to a kernel mode
device driver and retrieving the results. You obviously can't write a
device driver in C# but you can interrogate a device driver via pinvoke.
ok thanks for the info, Richard :)

FB

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn0dnn7g
y4*******@msnews.microsoft.com>

Richard Blewett [DevelopMentor] wrote:
> Nope, yoou can interact directly with them vice the DeviceIOControl API.
> I've done this in the past to write to area of the physical disk that

win32 > doesn't support.
>
> So I guess to be able to interact with a device driver from C# you'd have
> to P/Invoke to DeviceIOControl


(just to make it clear to me, not to nittpick ;))
But isn't this just a wrapper around Windows' device manager? There is no
way you will be able to poke into hardware without a kernel space module,
as everything is virtualized: you can't simply throw an interrupt or set an
address to a value to change some hardware's internal settings (at least
that's what I know of it).

Frans.
>
> Regards
>
> Richard Blewett - DevelopMentor
> http://staff.develop.com/richardb/weblog
>
>
>

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<xn0dnlt0
z3*******@msnews.microsoft.com> >
> Steve wrote:
>
> > I wrote a simple virtual device driver int15.sys, Is C# support load

the > > device driver from AP?
>
> Aren't drivers used by the OS (windows) ? So how did you plan to use this
> driver?

Nov 16 '05 #11

P: n/a

"Steve" <St***@discussions.microsoft.com> wrote in message
news:82**********************************@microsof t.com...
All,

Thanks for the help about this issue.

Willy,

I think you answer my question, for I am new in C#, I will try figure out
how to implement based on your suggestion, really appreciated.

"Willy Denoyette [MVP]" wrote:


Steve,

I would never use C# for this, but here's a sample class that illustrates
how to manage driver loading/unloading using both PInvoke interop and WMI.

Note this is no production code, it's only meant to illustrate how to:
- load a driver.
- start the driver
- open the device
- stop the driver
- unload the driver
using C#.
usage:
Win32Driver driver = new Win32Driver(driverName,
@"c:\\folder\\mydriver.sys");
if (driver.LoadDeviceDriver()){
IntPtr handle = driver.OpenDevice();
// use device using ....DeviceIoControl(handle,....) see class code for
signature
}
//unload when done
driver.UnloadDeviceDriver();


// the class file
public sealed class Win32Driver : IDisposable
{
string driverName;
string execPath;
IntPtr fileHandle;
public Win32Driver(string driver, string driverExecPath)
{
this.driverName = driver;
this.execPath = driverExecPath;
}
~Win32Driver()
{
// BUG - should never rely on finalizer to clean-up unmanaged resources
Dispose();
}
private void CloseStuff()
{
if(fileHandle != INVALID_HANDLE_VALUE)
{
fileHandle = INVALID_HANDLE_VALUE;
CloseHandle(fileHandle);
}
}

public void Dispose()
{
CloseStuff();
GC.SuppressFinalize(this);
}

private readonly static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
private const int SC_MANAGER_CONNECT = 0x0001;
private const int SC_MANAGER_CREATE_SERVICE = 0x0002;
private const int SC_MANAGER_ENUMERATE_SERVICE = 0x0004;
private const int SC_MANAGER_LOCK = 0x0008;
private const int SC_MANAGER_QUERY_LOCK_STATUS = 0x0010;
private const int SC_MANAGER_MODIFY_BOOT_CONFIG =0x0020;
private const int SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
SC_MANAGER_CONNECT |
SC_MANAGER_CREATE_SERVICE |
SC_MANAGER_ENUMERATE_SERVICE |
SC_MANAGER_LOCK |
SC_MANAGER_QUERY_LOCK_STATUS |
SC_MANAGER_MODIFY_BOOT_CONFIG;

private const int SERVICE_QUERY_CONFIG = 0x0001;
private const int SERVICE_CHANGE_CONFIG = 0x0002;
private const int SERVICE_QUERY_STATUS = 0x0004;
private const int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
private const int SERVICE_START = 0x0010;
private const int SERVICE_STOP = 0x0020;
private const int SERVICE_PAUSE_CONTINUE = 0x0040;
private const int SERVICE_INTERROGATE = 0x0080;
private const int SERVICE_USER_DEFINED_CONTROL = 0x0100;

private const int SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED
|
SERVICE_QUERY_CONFIG |
SERVICE_CHANGE_CONFIG |
SERVICE_QUERY_STATUS |
SERVICE_ENUMERATE_DEPENDENTS |
SERVICE_START |
SERVICE_STOP |
SERVICE_PAUSE_CONTINUE |
SERVICE_INTERROGATE |
SERVICE_USER_DEFINED_CONTROL;

private const int SERVICE_DEMAND_START = 0x00000003;
private const int SERVICE_KERNEL_DRIVER = 0x00000001;
private const int SERVICE_ERROR_NORMAL = 0x00000001;

private const uint GENERIC_READ = 0x80000000;
private const uint FILE_SHARE_READ = 1;
private const uint FILE_SHARE_WRITE = 2;
private const uint OPEN_EXISTING = 3;
private const uint IOCTL_SHOCKMGR_READ_ACCELEROMETER_DATA = 0x733fc;
private const int FACILITY_WIN32 = unchecked((int)0x80070000);
private IntPtr handle = INVALID_HANDLE_VALUE;

[DllImport("advapi32", SetLastError = true)]
internal static extern IntPtr OpenSCManager(string machineName, string
databaseName, uint dwDesiredAccess);
[DllImport("advapi32", SetLastError = true)]
internal static extern IntPtr CreateService(IntPtr hSCManager, string
serviceName, string displayName,
uint dwDesiredAccess, uint serviceType, uint startType, uint
errorControl,
string lpBinaryPathName, string lpLoadOrderGroup, string lpdwTagId,
string lpDependencies,
string lpServiceStartName, string lpPassword);

[DllImport("advapi32")]
internal static extern bool CloseServiceHandle(IntPtr handle);
[DllImport("kernel32", SetLastError = true)]
internal static extern IntPtr CreateFile(string lpFileName, uint
dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint
dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

[DllImport("kernel32")]
internal static extern void CloseHandle(IntPtr handle);

[DllImport("kernel32", SetLastError = true)]
private static extern bool DeviceIoControl(IntPtr hDevice, uint
dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer,
uint nOutBufferSize, ref uint lpBytesReturned, IntPtr lpOverlapped);
internal bool LoadDeviceDriver()
{
IntPtr scHandle = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
if (scHandle != INVALID_HANDLE_VALUE)
{
IntPtr hService = CreateService(scHandle, this.driverName,
this.driverName, SERVICE_ALL_ACCESS
, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL
,execPath, null, null, null, null, null);
if (hService != IntPtr.Zero)
{
CloseServiceHandle(hService); // close both handles
CloseServiceHandle(scHandle);
// Start the driver using System.Management (WMI)
if (ExecuteSCMOperationOnDriver(this.driverName, "StartService") == 0)
return true;
}
else
if (Marshal.GetLastWin32Error()== 1073) // Driver/Service already in DB
{
CloseServiceHandle(scHandle);
// Start the driver using System.Management (WMI)
if (ExecuteSCMOperationOnDriver(this.driverName, "StartService") == 0)
return true;
}
Marshal.ThrowExceptionForHR(HRESULT_FROM_WIN32(Mar shal.GetLastWin32Error()));
}
return false;
}

internal bool UnloadDeviceDriver()
{
int ret = 0;
if (fileHandle != IntPtr.Zero && fileHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(fileHandle);
}
if ((ret = ExecuteSCMOperationOnDriver(driverName, "StopService")) == 0)
{
ret = ExecuteSCMOperationOnDriver(driverName, "Delete");
}
if (ret != 0)
{
return false;
}
return true;
}

private static int ExecuteSCMOperationOnDriver(string driverName, string
operation)
{
ManagementPath path = new ManagementPath();
path.Server = ".";
path.NamespacePath = @"root\CIMV2";
path.RelativePath = @"Win32_BaseService.Name='" + driverName +"'";
using(ManagementObject o = new ManagementObject(path))
{
ManagementBaseObject outParams = o.InvokeMethod(operation,
null, null);
return Convert.ToInt32(outParams.Properties["ReturnValue"].Value);
}
}
internal IntPtr OpenDevice()
{
fileHandle = CreateFile("\\\\.\\" + driverName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
IntPtr.Zero);
if(handle == INVALID_HANDLE_VALUE)
{
Marshal.ThrowExceptionForHR(HRESULT_FROM_WIN32(Mar shal.GetLastWin32Error()));
}
return fileHandle;
}
private static int HRESULT_FROM_WIN32(int x)
{
return x <= 0 ? x : ((x & 0x0000FFFF) | FACILITY_WIN32);
}
}
Nov 16 '05 #12

P: n/a
Willy,

Thanks a lot, I tried your solution and used
ServiceController[] scServices;
scServices = ServiceController.GetDevices();

I can see my driver is loaded.

B. RGDS
Steve
"Willy Denoyette [MVP]" wrote:

"Steve" <St***@discussions.microsoft.com> wrote in message
news:82**********************************@microsof t.com...
All,

Thanks for the help about this issue.

Willy,

I think you answer my question, for I am new in C#, I will try figure out
how to implement based on your suggestion, really appreciated.

"Willy Denoyette [MVP]" wrote:


Steve,

I would never use C# for this, but here's a sample class that illustrates
how to manage driver loading/unloading using both PInvoke interop and WMI.

Note this is no production code, it's only meant to illustrate how to:
- load a driver.
- start the driver
- open the device
- stop the driver
- unload the driver
using C#.
usage:
Win32Driver driver = new Win32Driver(driverName,
@"c:\\folder\\mydriver.sys");
if (driver.LoadDeviceDriver()){
IntPtr handle = driver.OpenDevice();
// use device using ....DeviceIoControl(handle,....) see class code for
signature
}
//unload when done
driver.UnloadDeviceDriver();


// the class file
public sealed class Win32Driver : IDisposable
{
string driverName;
string execPath;
IntPtr fileHandle;
public Win32Driver(string driver, string driverExecPath)
{
this.driverName = driver;
this.execPath = driverExecPath;
}
~Win32Driver()
{
// BUG - should never rely on finalizer to clean-up unmanaged resources
Dispose();
}
private void CloseStuff()
{
if(fileHandle != INVALID_HANDLE_VALUE)
{
fileHandle = INVALID_HANDLE_VALUE;
CloseHandle(fileHandle);
}
}

public void Dispose()
{
CloseStuff();
GC.SuppressFinalize(this);
}

private readonly static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
private const int SC_MANAGER_CONNECT = 0x0001;
private const int SC_MANAGER_CREATE_SERVICE = 0x0002;
private const int SC_MANAGER_ENUMERATE_SERVICE = 0x0004;
private const int SC_MANAGER_LOCK = 0x0008;
private const int SC_MANAGER_QUERY_LOCK_STATUS = 0x0010;
private const int SC_MANAGER_MODIFY_BOOT_CONFIG =0x0020;
private const int SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
SC_MANAGER_CONNECT |
SC_MANAGER_CREATE_SERVICE |
SC_MANAGER_ENUMERATE_SERVICE |
SC_MANAGER_LOCK |
SC_MANAGER_QUERY_LOCK_STATUS |
SC_MANAGER_MODIFY_BOOT_CONFIG;

private const int SERVICE_QUERY_CONFIG = 0x0001;
private const int SERVICE_CHANGE_CONFIG = 0x0002;
private const int SERVICE_QUERY_STATUS = 0x0004;
private const int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
private const int SERVICE_START = 0x0010;
private const int SERVICE_STOP = 0x0020;
private const int SERVICE_PAUSE_CONTINUE = 0x0040;
private const int SERVICE_INTERROGATE = 0x0080;
private const int SERVICE_USER_DEFINED_CONTROL = 0x0100;

private const int SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED
|
SERVICE_QUERY_CONFIG |
SERVICE_CHANGE_CONFIG |
SERVICE_QUERY_STATUS |
SERVICE_ENUMERATE_DEPENDENTS |
SERVICE_START |
SERVICE_STOP |
SERVICE_PAUSE_CONTINUE |
SERVICE_INTERROGATE |
SERVICE_USER_DEFINED_CONTROL;

private const int SERVICE_DEMAND_START = 0x00000003;
private const int SERVICE_KERNEL_DRIVER = 0x00000001;
private const int SERVICE_ERROR_NORMAL = 0x00000001;

private const uint GENERIC_READ = 0x80000000;
private const uint FILE_SHARE_READ = 1;
private const uint FILE_SHARE_WRITE = 2;
private const uint OPEN_EXISTING = 3;
private const uint IOCTL_SHOCKMGR_READ_ACCELEROMETER_DATA = 0x733fc;
private const int FACILITY_WIN32 = unchecked((int)0x80070000);
private IntPtr handle = INVALID_HANDLE_VALUE;

[DllImport("advapi32", SetLastError = true)]
internal static extern IntPtr OpenSCManager(string machineName, string
databaseName, uint dwDesiredAccess);
[DllImport("advapi32", SetLastError = true)]
internal static extern IntPtr CreateService(IntPtr hSCManager, string
serviceName, string displayName,
uint dwDesiredAccess, uint serviceType, uint startType, uint
errorControl,
string lpBinaryPathName, string lpLoadOrderGroup, string lpdwTagId,
string lpDependencies,
string lpServiceStartName, string lpPassword);

[DllImport("advapi32")]
internal static extern bool CloseServiceHandle(IntPtr handle);
[DllImport("kernel32", SetLastError = true)]
internal static extern IntPtr CreateFile(string lpFileName, uint
dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint
dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);

[DllImport("kernel32")]
internal static extern void CloseHandle(IntPtr handle);

[DllImport("kernel32", SetLastError = true)]
private static extern bool DeviceIoControl(IntPtr hDevice, uint
dwIoControlCode, IntPtr lpInBuffer, uint nInBufferSize, IntPtr lpOutBuffer,
uint nOutBufferSize, ref uint lpBytesReturned, IntPtr lpOverlapped);
internal bool LoadDeviceDriver()
{
IntPtr scHandle = OpenSCManager(null, null, SC_MANAGER_ALL_ACCESS);
if (scHandle != INVALID_HANDLE_VALUE)
{
IntPtr hService = CreateService(scHandle, this.driverName,
this.driverName, SERVICE_ALL_ACCESS
, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL
,execPath, null, null, null, null, null);
if (hService != IntPtr.Zero)
{
CloseServiceHandle(hService); // close both handles
CloseServiceHandle(scHandle);
// Start the driver using System.Management (WMI)
if (ExecuteSCMOperationOnDriver(this.driverName, "StartService") == 0)
return true;
}
else
if (Marshal.GetLastWin32Error()== 1073) // Driver/Service already in DB
{
CloseServiceHandle(scHandle);
// Start the driver using System.Management (WMI)
if (ExecuteSCMOperationOnDriver(this.driverName, "StartService") == 0)
return true;
}
Marshal.ThrowExceptionForHR(HRESULT_FROM_WIN32(Mar shal.GetLastWin32Error()));
}
return false;
}

internal bool UnloadDeviceDriver()
{
int ret = 0;
if (fileHandle != IntPtr.Zero && fileHandle != INVALID_HANDLE_VALUE)
{
CloseHandle(fileHandle);
}
if ((ret = ExecuteSCMOperationOnDriver(driverName, "StopService")) == 0)
{
ret = ExecuteSCMOperationOnDriver(driverName, "Delete");
}
if (ret != 0)
{
return false;
}
return true;
}

private static int ExecuteSCMOperationOnDriver(string driverName, string
operation)
{
ManagementPath path = new ManagementPath();
path.Server = ".";
path.NamespacePath = @"root\CIMV2";
path.RelativePath = @"Win32_BaseService.Name='" + driverName +"'";
using(ManagementObject o = new ManagementObject(path))
{
ManagementBaseObject outParams = o.InvokeMethod(operation,
null, null);
return Convert.ToInt32(outParams.Properties["ReturnValue"].Value);
}
}
internal IntPtr OpenDevice()
{
fileHandle = CreateFile("\\\\.\\" + driverName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0,
IntPtr.Zero);
if(handle == INVALID_HANDLE_VALUE)
{
Marshal.ThrowExceptionForHR(HRESULT_FROM_WIN32(Mar shal.GetLastWin32Error()));
}
return fileHandle;
}
private static int HRESULT_FROM_WIN32(int x)
{
return x <= 0 ? x : ((x & 0x0000FFFF) | FACILITY_WIN32);
}
}

Nov 16 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.