Hi,
in my device driver devicecontrol dispatch routine I have a critical part that must not be executed synchronly.
void* p=NULL;
//…
INLINE NTSTATUS DispatchDeviceControl(PDEVICE_OBJECT pDevice, PIRP pIRP)
{
//…
case IOCTL_CPY:
p=ExAllocatePool(NonPagedPool, 1024);
// work with p
ExFreePool(p);
break;
//…
}
Unfortunately I create many devices and many usermode applications are able to “call” this IOCTL the same time, which cause some very serious errors. How can I prevent this? Do I really have to add a reference bool, which is atomicly set to true when the code is entered and to false when I am done and which prevent simultanly execution of this part?!
I need help!
Daniel.
Well one has to ask why p is a global, instead of a local, where the having
more than one copy would not cause a problem, but I expect there is some
access to something that is a concern. You need a synchronization
primative, in this case probably a mutex or a resource acquired
exclusively.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
http://www.windrvr.com
Remove StopSpam from the email to reply
wrote in message news:xxxxx@ntdev…
> Hi,
> in my device driver devicecontrol dispatch routine I have a critical part
> that must not be executed synchronly.
>
> void* p=NULL;
> //…
> INLINE NTSTATUS DispatchDeviceControl(PDEVICE_OBJECT pDevice, PIRP pIRP)
> {
> //…
> case IOCTL_CPY:
> p=ExAllocatePool(NonPagedPool, 1024);
> // work with p
> ExFreePool(p);
> break;
> //…
> }
>
> Unfortunately I create many devices and many usermode applications are
> able to “call” this IOCTL the same time, which cause some very serious
> errors. How can I prevent this? Do I really have to add a reference bool,
> which is atomicly set to true when the code is entered and to false when
> I am done and which prevent simultanly execution of this part?!
>
> I need help!
>
> Daniel.
>
This was just a simple example. In fact it is more complicated, because a global vector (allocated with ExAllocatePool and NonPagedPool) is changed and it causes some very strange errors when two usermode applications try to change that vector the same time 
Anyway, would KeEnterCriticalRegion do the job?
Thank you 
Daniel
No, this is not a synchronization primative, it protects against APC’s but
not against two requests. Either you need a synchronization primative as
in my last post, or can you do this with InterlockedXXX operations to
change the value you need to?
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
http://www.windrvr.com
Remove StopSpam from the email to reply
wrote in message news:xxxxx@ntdev…
> This was just a simple example. In fact it is more complicated, because a
> global vector (allocated with ExAllocatePool and NonPagedPool) is changed
> and it causes some very strange errors when two usermode applications try
> to change that vector the same time 
>
> Anyway, would KeEnterCriticalRegion do the job?
>
> Thank you 
> Daniel
>
I don’t think the Interlockedxxx functions will work in this case as
he seems to need to protect a block of code, not just a single
assingment.
For the OP, here is a link that explains mutex objects and some
alternatives that are faster.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/kernel_d/hh/Kernel_d/Synchro_3ec79760-d1c4-4c86-9893-2a7d738ec64a.xml.asp
Beverly
On 10/18/06, Don Burn wrote:
> No, this is not a synchronization primative, it protects against APC’s but
> not against two requests. Either you need a synchronization primative as
> in my last post, or can you do this with InterlockedXXX operations to
> change the value you need to?
>
>
>
> –
> Don Burn (MVP, Windows DDK)
> Windows 2k/XP/2k3 Filesystem and Driver Consulting
> http://www.windrvr.com
> Remove StopSpam from the email to reply
>
>
> wrote in message news:xxxxx@ntdev…
> > This was just a simple example. In fact it is more complicated, because a
> > global vector (allocated with ExAllocatePool and NonPagedPool) is changed
> > and it causes some very strange errors when two usermode applications try
> > to change that vector the same time 
> >
> > Anyway, would KeEnterCriticalRegion do the job?
> >
> > Thank you 
> > Daniel
> >
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>
A reference bool? No you need to use the appropriate locking primitive.
This is not really a driver programming question it is more like a
multi-threaded programming 101 question. The kernel provides several
different types of locks, all of which can serialize a section of code,
but only some of which are going to be appropriate for your design.
Which of these locks you should use, if any, depends on “// work with p”
and how “// work with p” interacts with the rest of your design. From
the information you have provided, ‘p’ appears to be a local variable
and thus is itself not a problem with respect to multiple threads of
execution as each thread will have its own copy of ‘p’.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.de
Sent: Wednesday, October 18, 2006 12:47 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Preventing multiple operation?
Hi,
in my device driver devicecontrol dispatch routine I have a critical
part that must not be executed synchronly.
void* p=NULL;
//…
INLINE NTSTATUS DispatchDeviceControl(PDEVICE_OBJECT pDevice, PIRP pIRP)
{
//…
case IOCTL_CPY:
p=ExAllocatePool(NonPagedPool, 1024);
// work with p
ExFreePool(p);
break;
//…
}
Unfortunately I create many devices and many usermode applications are
able to “call” this IOCTL the same time, which cause some very serious
errors. How can I prevent this? Do I really have to add a reference
bool, which is atomicly set to true when the code is entered and to
false when I am done and which prevent simultanly execution of this
part?!
I need help!
Daniel.
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer
> This was just a simple example. In fact it is more complicated, because a global vector (allocated with ExAllocatePool and
NonPagedPool) is changed and it causes some very strange errors when two usermode applications try to change that vector the same
time 
Why has it to change ? You do mention why it is declared globally. Also allocating /releasing memory all the time is not
recommended. Think about fragmentation of the memory.
Anyway, would KeEnterCriticalRegion do the job?
If you do spend much time within the exclusive code to run , you can use a spinlock too.
Christiaan
Thank you 
Daniel
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
xxxxx@yahoo.de wrote:
Hi,
in my device driver devicecontrol dispatch routine I have a critical part that must not be executed synchronly.
void* p=NULL;
//…
INLINE NTSTATUS DispatchDeviceControl(PDEVICE_OBJECT pDevice, PIRP pIRP)
{
//…
case IOCTL_CPY:
p=ExAllocatePool(NonPagedPool, 1024);
// work with p
ExFreePool(p);
break;
//…
}
Unfortunately I create many devices and many usermode applications are able to “call” this IOCTL the same time, which cause some very serious errors. How can I prevent this? Do I really have to add a reference bool, which is atomicly set to true when the code is entered and to false when I am done and which prevent simultanly execution of this part?!
This is exactly what mutexes and spinlocks are for.
Why is “p” a global variable? That’s almost always a design error. In
that particular case, there’s no reason why it couldn’t be local to
DispatchDeviceControl.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
As I said it was just an example. In fact it is an vector (array which size changes at runtime), and all device must access it from everywhere, so it is data is stored in NonPagedPool-memory and the vector itself is global!
Anyway, I will use KeAcquireInStackQueuedSpinLock and KeReleaseInStackQueuedSpinLock; those functions seems to be the ones I need. Just one question. What does them exactly do? Does they prevent any other function to be executed or does it prevent that exactly the SpinLock-protected code part is executed more than once while the spin lock is acquired.
Thank you all 
Daniel
Oh, my post is full of language mistakes. Sorry for that 
Anyway, I just found the answer to my question. Of course it is the second 
xxxxx@yahoo.de wrote:
This was just a simple example. In fact it is more complicated, because a global vector (allocated with ExAllocatePool and NonPagedPool) is changed and it causes some very strange errors when two usermode applications try to change that vector the same time 
A global vector is just as bad a design as a global variable. Remember
that a single driver can drive multiple instances of the hardware, and
there is very rarely any interaction between those instances. Data you
think of as “global” is usually “local to this instance”, and should be
in the device extension.
Anyway, would KeEnterCriticalRegion do the job?
ExInitializeFastMutex, KeInitializeSpinLock, and KeInitializeMutex are
the places you should start looking…
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Spinlocks, mutexes and resources all protect based on the given lock. So
they do not prevent other functions to run, only they prevent the
acquistion of the lock while it is exclusively held. One problem with spin
locks is that many other functions cannot be run, so for instance if you
need to allocate memory to change the size of the vector, a spin lock
cannot be held.
I would look at resources, they have the advantage they can be taken shared
or exclusive, so if most request only read the vector, and a few write it
you can have multiple read requests running concurrently.
–
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
http://www.windrvr.com
Remove StopSpam from the email to reply
wrote in message news:xxxxx@ntdev…
> As I said it was just an example. In fact it is an vector (array which
> size changes at runtime), and all device must access it from everywhere,
> so it is data is stored in NonPagedPool-memory and the vector itself is
> global!
>
> Anyway, I will use KeAcquireInStackQueuedSpinLock and
> KeReleaseInStackQueuedSpinLock; those functions seems to be the ones I
> need. Just one question. What does them exactly do? Does they prevent
> any other function to be executed or does it prevent that exactly the
> SpinLock-protected code part is executed more than once while the spin
> lock is acquired.
>
> Thank you all 
>
> Daniel
>
Uhm, you are right. I should check everywhere wheather the vector is changing. Unfortunately my vector is accessed like this and at the moment I don’t have seperate functions for read and write access.
template Vector;
//…
Vector.PushBack(0);
//…
int iFirstElement=Vector.GetLastElement(); //returns a reference on the first int-element
Vector.GetLastElement()=100;
//…
So, if I am 100% correct, I should add a GetLastElement-unction which returns a reference and a GetLastElement-function which returns a const reference. In the GetLastElement-function which returns the reference I should acquire a lock which is released manually after I am done with changing the value; and also the same lock should be acquired and released in the AddElement, RemoveElement… functions. In the function which returns the const reference I just have to check wheather that SpinLock is aquired or not?!
Damn, kernel mode programming is so hard. I wanna go back to good old usermode 
Bye…
Sending this the 2nd time, the first send weren’t added 
You should probably master basic user-mode multi-threaded programming before trying to do whatever you’re doing in kernel-mode. There are lots of resources to learn about multi-threaded programming. Kernel-mode is not the place to start learning this; it’s an order of magnitude more difficult to get right, and the consequences of mistakes are far more painful. It’s like starting a career in medicine by tinkering in brain surgery.
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.de
Sent: Wednesday, October 18, 2006 12:26 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Preventing multiple operation?
Uhm, you are right. I should check everywhere wheather the vector is changing. Unfortunately my vector is accessed like this and at the moment I don’t have seperate functions for read and write access.
template Vector;
//…
Vector.PushBack(0);
//…
int iFirstElement=Vector.GetLastElement(); //returns a reference on the first int-element Vector.GetLastElement()=100; //…
So, if I am 100% correct, I should add a GetLastElement-unction which returns a reference and a GetLastElement-function which returns a const reference. In the GetLastElement-function which returns the reference I should acquire a lock which is released manually after I am done with changing the value; and also the same lock should be acquired and released in the AddElement, RemoveElement… functions. In the function which returns the const reference I just have to check wheather that SpinLock is aquired or not?!
Damn, kernel mode programming is so hard. I wanna go back to good old usermode 
Bye…
Sending this the 2nd time, the first send weren’t added 
—
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
Uhm, you are right. I should check everywhere wheather the vector is changing. Unfortunately my vector is accessed like this and at the moment I don’t have seperate functions for read and write access.
template Vector;
//…
Vector.PushBack(0);
//…
int iFirstElement=Vector.GetLastElement(); //returns a reference on the first int-element
Vector.GetLastElement()=100;
//…
So, if I am 100% correct, I should add a GetLastElement-unction which returns a reference and a GetLastElement-function which returns a const reference. In the GetLastElement-function which returns the reference I should acquire a lock which is released manually after I am done with changing the value; and also the same lock should be acquired and released in the AddElement, RemoveElement… functions. In the function which returns the const reference I just have to check wheather that SpinLock is aquired or not?!
Damn, kernel mode programming is so hard. I wanna go back to good old usermode 
Bye…
Does this code snippet means that you are using a kind of user mode STL code within
a driver ? Personally , I don’t think it is a good idea (…) . The driver “ExInterlockedIxxxxxTailList”
functions are a better choice …
Christiaan
----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Wednesday, October 18, 2006 9:17 PM
Subject: RE:[ntdev] Preventing multiple operation?
> Uhm, you are right. I should check everywhere wheather the vector is changing. Unfortunately my vector is accessed like this and
at the moment I don’t have seperate functions for read and write access.
>
> template Vector;
> //…
> Vector.PushBack(0);
> //…
> int iFirstElement=Vector.GetLastElement(); //returns a reference on the first int-element
> Vector.GetLastElement()=100;
> //…
>
> So, if I am 100% correct, I should add a GetLastElement-unction which returns a reference and a GetLastElement-function which
returns a const reference. In the GetLastElement-function which returns the reference I should acquire a lock which is released
manually after I am done with changing the value; and also the same lock should be acquired and released in the AddElement,
RemoveElement… functions. In the function which returns the const reference I just have to check wheather that SpinLock is aquired
or not?!
>
> Damn, kernel mode programming is so hard. I wanna go back to good old usermode 
>
> Bye…
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
That would be a huge problem. You need to forget about STL in the
kernel, it is mostly a non-starter for a variety of reasons. I wondered
exactly what you meant by ‘vector’ now I know. Yes kernel mode is hard.
Might I suggest that you look into KMDF rather than using the WDM DDK as
it provides an object oriented interface (although in C, not C++) and
will reduce drastically the complexity of what you have to deal with
here.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@yahoo.de
Sent: Wednesday, October 18, 2006 3:17 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Preventing multiple operation?
Uhm, you are right. I should check everywhere wheather the vector is
changing. Unfortunately my vector is accessed like this and at the
moment I don’t have seperate functions for read and write access.
template Vector;
//…
Vector.PushBack(0);
//…
int iFirstElement=Vector.GetLastElement(); //returns a reference on the
first int-element
Vector.GetLastElement()=100;
//…
So, if I am 100% correct, I should add a GetLastElement-unction which
returns a reference and a GetLastElement-function which returns a const
reference. In the GetLastElement-function which returns the reference I
should acquire a lock which is released manually after I am done with
changing the value; and also the same lock should be acquired and
released in the AddElement, RemoveElement… functions. In the function
which returns the const reference I just have to check wheather that
SpinLock is aquired or not?!
Damn, kernel mode programming is so hard. I wanna go back to good old
usermode 
Bye…
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer
Use some kind of lock - spinlock, FAST_MUTEX, ERESOURCE or such.
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com
----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Wednesday, October 18, 2006 8:46 PM
Subject: [ntdev] Preventing multiple operation?
> Hi,
> in my device driver devicecontrol dispatch routine I have a critical part
that must not be executed synchronly.
>
> void* p=NULL;
> //…
> INLINE NTSTATUS DispatchDeviceControl(PDEVICE_OBJECT pDevice, PIRP pIRP)
> {
> //…
> case IOCTL_CPY:
> p=ExAllocatePool(NonPagedPool, 1024);
> // work with p
> ExFreePool(p);
> break;
> //…
> }
>
> Unfortunately I create many devices and many usermode applications are able
to “call” this IOCTL the same time, which cause some very serious errors. How
can I prevent this? Do I really have to add a reference bool, which is atomicly
set to true when the code is entered and to false when I am done and which
prevent simultanly execution of this part?!
>
> I need help!
>
> Daniel.
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer
>need. Just one question. What does them exactly do? Does they prevent
any other function to be executed or does it prevent that exactly the
SpinLock-protected code part is executed more than once while the spin lock is
acquired.
They prevent the spinlock to be acquired twice, before the first acquisitor
will release it. The second acquisition attempt will spin in a dead loop,
burning the CPU cycles. This is one drawback of a spinlock.
Another is - spinlock raises to DISPATCH_LEVEL, which causes a set of
implications in the code executed while holding a spinlock.
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com