I have a DLL that exports a class that allows a program to access a
unique system resource.

At the moment, the DLL is implemented as a singleton such that any
thread in a given process is using the same resource handle.
But, if a second, unrelated process loads the DLL and accesses it,
this process will try to create its own handle to the resource which
fails because it's already in use by the first process.

How do I give the second process access to the handle that's being
used by the first process so that both can query the resource?

Thanks,
PaulH

Re: multi-process singleton DLL by Ben

Ben
Mon Jul 23 10:47:15 CDT 2007


"PaulH" <paul.heil@gmail.com> wrote in message
news:1185203158.770652.52140@r34g2000hsd.googlegroups.com...
>I have a DLL that exports a class that allows a program to access a
> unique system resource.
>
> At the moment, the DLL is implemented as a singleton such that any
> thread in a given process is using the same resource handle.
> But, if a second, unrelated process loads the DLL and accesses it,
> this process will try to create its own handle to the resource which
> fails because it's already in use by the first process.
>
> How do I give the second process access to the handle that's being
> used by the first process so that both can query the resource?

Pick an IPC method, any method. Note that to do this cleanly, it is
necessary that a separate process be set up to "own" the true handle,
because if the owning process closes the resource will be released.

Named pipes would probably be a good choice, because the proxy process can
detect abnormal termination of a client.

>
> Thanks,
> PaulH
>



Re: multi-process singleton DLL by PaulH

PaulH
Mon Jul 23 12:00:47 CDT 2007

Instead of using IPC, wouldn't it be possible to use DuplicateHandle()
such that ProcessA opens the DLL and gets the original resource
handle, then Process B opens the DLL and gets a DuplicateHandle()?

I'm glad you mentioned the second process. I didn't consider what
would happen to Process B if Process A closed the resource. What about
using the DLL to keep a reference count of all the handles created,
then it could wait for the reference to become 0 before it really
releases the resource. Would that work?

Thanks,
Paul

On Jul 23, 10:47 am, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> "PaulH" <paul.h...@gmail.com> wrote in message
>
> news:1185203158.770652.52140@r34g2000hsd.googlegroups.com...
>
> >I have a DLL that exports a class that allows a program to access a
> > unique system resource.
>
> > At the moment, the DLL is implemented as a singleton such that any
> > thread in a given process is using the same resource handle.
> > But, if a second, unrelated process loads the DLL and accesses it,
> > this process will try to create its own handle to the resource which
> > fails because it's already in use by the first process.
>
> > How do I give the second process access to the handle that's being
> > used by the first process so that both can query the resource?
>
> Pick an IPC method, any method. Note that to do this cleanly, it is
> necessary that a separate process be set up to "own" the true handle,
> because if the owning process closes the resource will be released.
>
> Named pipes would probably be a good choice, because the proxy process can
> detect abnormal termination of a client.
>
>
>
> > Thanks,
> > PaulH



Re: multi-process singleton DLL by Alex

Alex
Mon Jul 23 13:30:54 CDT 2007

"PaulH" wrote:
> Instead of using IPC, wouldn't it be possible to use
> DuplicateHandle()
> such that ProcessA opens the DLL and gets the original
> resource
> handle, then Process B opens the DLL and gets a
> DuplicateHandle()?

You will need IPC in any case. In order to use
`DuplicateHandle' in ProcessB you will need to communicate
source handle from ProcessA.

> I'm glad you mentioned the second process. I didn't
> consider what
> would happen to Process B if Process A closed the
> resource. What about
> using the DLL to keep a reference count of all the handles
> created,
> then it could wait for the reference to become 0 before it
> really
> releases the resource. Would that work?

No, it wouldn't. DLL cannot count or wait. It is just a
chunk of executable code, which is loaded into a process.
Think about it as of text file. Suppose you open the same
text file with two instances of Notepad. Now each Notepad
has its own copy of text in memory. You can do whatever you
want with the text in one Notepad, but it won't change the
text in the other one.

If the resource you want to share is kernel object, then it
will stay alive until there is a handle to it. It is not
important which process will contain the handle.

Alex


Re: multi-process singleton DLL by Ben

Ben
Mon Jul 23 13:34:29 CDT 2007


"PaulH" <paul.heil@gmail.com> wrote in message
news:1185210047.440472.182490@g4g2000hsf.googlegroups.com...
> Instead of using IPC, wouldn't it be possible to use DuplicateHandle()
> such that ProcessA opens the DLL and gets the original resource
> handle, then Process B opens the DLL and gets a DuplicateHandle()?
>
> I'm glad you mentioned the second process. I didn't consider what
> would happen to Process B if Process A closed the resource. What about
> using the DLL to keep a reference count of all the handles created,
> then it could wait for the reference to become 0 before it really
> releases the resource. Would that work?

What if I call TerminateProcess on process A? (Perhaps via Task Manager ->
End Process) Then

(1) Your cleanup code in process A won't run.
(2) Any resources owned by process A get freed by Windows.

I'm not sure, maybe DuplicateHandle fixes problem #2. #1 is still going to
be a big problem. Even to call DuplicateHandle the second process needs a
handle to the first, and the value of the resource handle inside the first
process. This is non-trivial when the first process quits. Then you have
to replace the shared data with another process's copy of the handle...
you're going to need shared segments and cross-process (named) mutexes to
synchronize access to the shared data. Probably easier to just go with a
named pipe.



Re: multi-process singleton DLL by PaulH

PaulH
Mon Jul 23 15:56:52 CDT 2007

So, to get this to work I will have to create another program which
creates an IPC server and manages the DLL resource. The original
programs which access the resource will have to be IPC clients and get
their handles from the server program?

Since that's a lot of work, I'm going to go temporarily in to denial
mode and hope that if I explain my problem in more detail somebody
will say "well, why didn't you just say that in the first place,
knuklehead! there's a much easier solution!":

I have two applications that query an 802.11 NDIS protocol driver for
information. They both interface using this DLL I wrote to take care
of all the IOCTL_ stuff and abstract it out to nice querying commands
like GetNoise() and IsConnected(). Under WinCE, all is good in the
world. But, when I ported this to XP, only one application at a time
could bind to the protocol driver, the other would get "The requested
resource is in use." errors.
So, I'm trying to find a way to modify the DLL such that the first
process that loads it and runs the Open() function goes through the
procedure of opening the protocol driver and binding to it. If the DLL
is loaded by a second process, while it's still being used by the
first process, then it just uses the bindings created by the first
process.

Am I still in the same boat?

Any idea why this isn't a problem under WinCE?

Thanks,
Paul

On Jul 23, 1:34 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> "PaulH" <paul.h...@gmail.com> wrote in message
>
> news:1185210047.440472.182490@g4g2000hsf.googlegroups.com...
>
> > Instead of using IPC, wouldn't it be possible to use DuplicateHandle()
> > such that ProcessA opens the DLL and gets the original resource
> > handle, then Process B opens the DLL and gets a DuplicateHandle()?
>
> > I'm glad you mentioned the second process. I didn't consider what
> > would happen to Process B if Process A closed the resource. What about
> > using the DLL to keep a reference count of all the handles created,
> > then it could wait for the reference to become 0 before it really
> > releases the resource. Would that work?
>
> What if I call TerminateProcess on process A? (Perhaps via Task Manager ->
> End Process) Then
>
> (1) Your cleanup code in process A won't run.
> (2) Any resources owned by process A get freed by Windows.
>
> I'm not sure, maybe DuplicateHandle fixes problem #2. #1 is still going to
> be a big problem. Even to call DuplicateHandle the second process needs a
> handle to the first, and the value of the resource handle inside the first
> process. This is non-trivial when the first process quits. Then you have
> to replace the shared data with another process's copy of the handle...
> you're going to need shared segments and cross-process (named) mutexes to
> synchronize access to the shared data. Probably easier to just go with a
> named pipe.



Re: multi-process singleton DLL by Ben

Ben
Mon Jul 23 17:25:24 CDT 2007


"PaulH" <paul.heil@gmail.com> wrote in message
news:1185224212.162968.141160@n2g2000hse.googlegroups.com...
> So, to get this to work I will have to create another program which
> creates an IPC server and manages the DLL resource. The original
> programs which access the resource will have to be IPC clients and get
> their handles from the server program?
>
> Since that's a lot of work, I'm going to go temporarily in to denial
> mode and hope that if I explain my problem in more detail somebody
> will say "well, why didn't you just say that in the first place,
> knuklehead! there's a much easier solution!":
>
> I have two applications that query an 802.11 NDIS protocol driver for
> information. They both interface using this DLL I wrote to take care
> of all the IOCTL_ stuff and abstract it out to nice querying commands
> like GetNoise() and IsConnected(). Under WinCE, all is good in the

Is it your driver? Make it allow multiple processes to open the device.

If you can't change the driver, you're still in good shape. All the IPC
stuff will still be hidden inside the client DLL which each of the
applications use. The DLL won't use DeviceIoControl any more, it will
communicate with the IPC server, which issues the actual IOCTLs.

> world. But, when I ported this to XP, only one application at a time
> could bind to the protocol driver, the other would get "The requested
> resource is in use." errors.
> So, I'm trying to find a way to modify the DLL such that the first
> process that loads it and runs the Open() function goes through the
> procedure of opening the protocol driver and binding to it. If the DLL
> is loaded by a second process, while it's still being used by the
> first process, then it just uses the bindings created by the first
> process.
>
> Am I still in the same boat?
>
> Any idea why this isn't a problem under WinCE?
>
> Thanks,
> Paul
>
> On Jul 23, 1:34 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
>> "PaulH" <paul.h...@gmail.com> wrote in message
>>
>> news:1185210047.440472.182490@g4g2000hsf.googlegroups.com...
>>
>> > Instead of using IPC, wouldn't it be possible to use DuplicateHandle()
>> > such that ProcessA opens the DLL and gets the original resource
>> > handle, then Process B opens the DLL and gets a DuplicateHandle()?
>>
>> > I'm glad you mentioned the second process. I didn't consider what
>> > would happen to Process B if Process A closed the resource. What about
>> > using the DLL to keep a reference count of all the handles created,
>> > then it could wait for the reference to become 0 before it really
>> > releases the resource. Would that work?
>>
>> What if I call TerminateProcess on process A? (Perhaps via Task
>> Manager ->
>> End Process) Then
>>
>> (1) Your cleanup code in process A won't run.
>> (2) Any resources owned by process A get freed by Windows.
>>
>> I'm not sure, maybe DuplicateHandle fixes problem #2. #1 is still going
>> to
>> be a big problem. Even to call DuplicateHandle the second process needs
>> a
>> handle to the first, and the value of the resource handle inside the
>> first
>> process. This is non-trivial when the first process quits. Then you
>> have
>> to replace the shared data with another process's copy of the handle...
>> you're going to need shared segments and cross-process (named) mutexes to
>> synchronize access to the shared data. Probably easier to just go with a
>> named pipe.
>
>



Re: multi-process singleton DLL by Brian

Brian
Mon Jul 23 18:09:10 CDT 2007

The problem of trying to come up with a "singleton" DLL is that you have no control over the
lifetime of the DLL itself. It can unload at any time without warning (for example, when
the client exits unexpectedly).

To gain lifetime control, you really need to have a service that handles the common
resources on behalf of the client, and this is the approach that Ben is suggesting.

(I'm not exactly certain what you are trying to gain by creating a singleton in the first
place. If all you are trying to do is help the developer with some of the esoteric IOCTL_ calls, perhaps you can simply provide a
DLL that provides that functionality. Typically
each client should be able to open their own connection to an NDIS driver, if the driver
has been written for XP.)

HTH

Brian






Re: multi-process singleton DLL by Ben

Ben
Tue Jul 24 08:52:55 CDT 2007


"Brian Muth" <bmuth@mvps.org> wrote in message
news:eCFI75XzHHA.5992@TK2MSFTNGP02.phx.gbl...
> The problem of trying to come up with a "singleton" DLL is that you have
> no control over the
> lifetime of the DLL itself. It can unload at any time without warning (for
> example, when
> the client exits unexpectedly).
>
> To gain lifetime control, you really need to have a service that handles
> the common
> resources on behalf of the client, and this is the approach that Ben is
> suggesting.
>
> (I'm not exactly certain what you are trying to gain by creating a
> singleton in the first
> place. If all you are trying to do is help the developer with some of the
> esoteric IOCTL_ calls, perhaps you can simply provide a DLL that provides
> that functionality. Typically

Apparently that's what the OP has done, but is hitting sharing violation on
the second connection. Perhaps it's just a matter of setting the right
FILE_SHARE_* flags in the CreateFile call.

> each client should be able to open their own connection to an NDIS driver,
> if the driver
> has been written for XP.)
>
> HTH
>
> Brian
>
>
>
>
>



Re: multi-process singleton DLL by PaulH

PaulH
Tue Jul 24 09:07:09 CDT 2007

On Jul 23, 6:09 pm, "Brian Muth" <bm...@mvps.org> wrote:
> The problem of trying to come up with a "singleton" DLL is that you have no control over the
> lifetime of the DLL itself. It can unload at any time without warning (for example, when
> the client exits unexpectedly).
>
> To gain lifetime control, you really need to have a service that handles the common
> resources on behalf of the client, and this is the approach that Ben is suggesting.
>
> (I'm not exactly certain what you are trying to gain by creating a singleton in the first
> place. If all you are trying to do is help the developer with some of the esoteric IOCTL_ calls, perhaps you can simply provide a
> DLL that provides that functionality. Typically
> each client should be able to open their own connection to an NDIS driver, if the driver
> has been written for XP.)
>
> HTH
>
> Brian

I wrote the DLL because I write a lot of tools that use this
functionality, so it was just easier to have a common DLL than to have
the same class repeated over and over in code. I made it a singleton
because many of these programs are multi-threaded and I wanted each
thread to use the same instance of the class exported from the DLL. In
the WinCE world this also means all processes use the same instance.

As far as I know, only one binding to a protocol driver is allowed at
a time. The uiotest application in the NDISPROT sample from the
WINDDK, for example, can't have two instances running at the same
time.

-PaulH


Re: multi-process singleton DLL by PaulH

PaulH
Tue Jul 24 09:10:07 CDT 2007

On Jul 23, 5:25 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> "PaulH" <paul.h...@gmail.com> wrote in message
>
> news:1185224212.162968.141160@n2g2000hse.googlegroups.com...
>
> > So, to get this to work I will have to create another program which
> > creates an IPC server and manages the DLL resource. The original
> > programs which access the resource will have to be IPC clients and get
> > their handles from the server program?
>
> > Since that's a lot of work, I'm going to go temporarily in to denial
> > mode and hope that if I explain my problem in more detail somebody
> > will say "well, why didn't you just say that in the first place,
> > knuklehead! there's a much easier solution!":
>
> > I have two applications that query an 802.11 NDIS protocol driver for
> > information. They both interface using this DLL I wrote to take care
> > of all the IOCTL_ stuff and abstract it out to nice querying commands
> > like GetNoise() and IsConnected(). Under WinCE, all is good in the
>
> Is it your driver? Make it allow multiple processes to open the device.
>
> If you can't change the driver, you're still in good shape. All the IPC
> stuff will still be hidden inside the client DLL which each of the
> applications use. The DLL won't use DeviceIoControl any more, it will
> communicate with the IPC server, which issues the actual IOCTLs.
>
> > world. But, when I ported this to XP, only one application at a time
> > could bind to the protocol driver, the other would get "The requested
> > resource is in use." errors.
> > So, I'm trying to find a way to modify the DLL such that the first
> > process that loads it and runs the Open() function goes through the
> > procedure of opening the protocol driver and binding to it. If the DLL
> > is loaded by a second process, while it's still being used by the
> > first process, then it just uses the bindings created by the first
> > process.
>
> > Am I still in the same boat?
>
> > Any idea why this isn't a problem under WinCE?
>
> > Thanks,
> > Paul
>
> > On Jul 23, 1:34 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> >> "PaulH" <paul.h...@gmail.com> wrote in message
>
> >>news:1185210047.440472.182490@g4g2000hsf.googlegroups.com...
>
> >> > Instead of using IPC, wouldn't it be possible to use DuplicateHandle()
> >> > such that ProcessA opens the DLL and gets the original resource
> >> > handle, then Process B opens the DLL and gets a DuplicateHandle()?
>
> >> > I'm glad you mentioned the second process. I didn't consider what
> >> > would happen to Process B if Process A closed the resource. What about
> >> > using the DLL to keep a reference count of all the handles created,
> >> > then it could wait for the reference to become 0 before it really
> >> > releases the resource. Would that work?
>
> >> What if I call TerminateProcess on process A? (Perhaps via Task
> >> Manager ->
> >> End Process) Then
>
> >> (1) Your cleanup code in process A won't run.
> >> (2) Any resources owned by process A get freed by Windows.
>
> >> I'm not sure, maybe DuplicateHandle fixes problem #2. #1 is still going
> >> to
> >> be a big problem. Even to call DuplicateHandle the second process needs
> >> a
> >> handle to the first, and the value of the resource handle inside the
> >> first
> >> process. This is non-trivial when the first process quits. Then you
> >> have
> >> to replace the shared data with another process's copy of the handle...
> >> you're going to need shared segments and cross-process (named) mutexes to
> >> synchronize access to the shared data. Probably easier to just go with a
> >> named pipe.

I haven't actually seen the protocol driver code, though I know it's
modeled after the NDISPROT example in the WinDDK. Do you happen to
know off the top of your head how that could be modified to allow
simultaneous bindings from different processes?

Thanks,
PaulH


Re: multi-process singleton DLL by PaulH

PaulH
Tue Jul 24 12:42:16 CDT 2007

On Jul 24, 8:52 am, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> "Brian Muth" <bm...@mvps.org> wrote in message
>
> news:eCFI75XzHHA.5992@TK2MSFTNGP02.phx.gbl...
>
>
>
> > The problem of trying to come up with a "singleton" DLL is that you have
> > no control over the
> > lifetime of the DLL itself. It can unload at any time without warning (for
> > example, when
> > the client exits unexpectedly).
>
> > To gain lifetime control, you really need to have a service that handles
> > the common
> > resources on behalf of the client, and this is the approach that Ben is
> > suggesting.
>
> > (I'm not exactly certain what you are trying to gain by creating a
> > singleton in the first
> > place. If all you are trying to do is help the developer with some of the
> > esoteric IOCTL_ calls, perhaps you can simply provide a DLL that provides
> > that functionality. Typically
>
> Apparently that's what the OP has done, but is hitting sharing violation on
> the second connection. Perhaps it's just a matter of setting the right
> FILE_SHARE_* flags in the CreateFile call.
>
> > each client should be able to open their own connection to an NDIS driver,
> > if the driver
> > has been written for XP.)
>
> > HTH
>
> > Brian

I run the CreateFile() with GENERIC_READ | GENERIC_WRITE. In WinCE, I
actually only need GENERIC_READ capability, but the
IOCTL_NDISUIO_BIND_WAIT call under XP fails with an "Access is
denied." error without the GENERIC_WRITE.

I tried FILE_SHARE_READ / FILE_SHARE_WRITE and they seem to give
exactly the same result as GENERIC_READ / GENERIC_WRITE.

-PaulH


Re: multi-process singleton DLL by PaulH

PaulH
Tue Jul 24 13:47:26 CDT 2007

On Jul 24, 8:52 am, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> "Brian Muth" <bm...@mvps.org> wrote in message
>
> news:eCFI75XzHHA.5992@TK2MSFTNGP02.phx.gbl...
>
>
>
> > The problem of trying to come up with a "singleton" DLL is that you have
> > no control over the
> > lifetime of the DLL itself. It can unload at any time without warning (for
> > example, when
> > the client exits unexpectedly).
>
> > To gain lifetime control, you really need to have a service that handles
> > the common
> > resources on behalf of the client, and this is the approach that Ben is
> > suggesting.
>
> > (I'm not exactly certain what you are trying to gain by creating a
> > singleton in the first
> > place. If all you are trying to do is help the developer with some of the
> > esoteric IOCTL_ calls, perhaps you can simply provide a DLL that provides
> > that functionality. Typically
>
> Apparently that's what the OP has done, but is hitting sharing violation on
> the second connection. Perhaps it's just a matter of setting the right
> FILE_SHARE_* flags in the CreateFile call.
>
> > each client should be able to open their own connection to an NDIS driver,
> > if the driver
> > has been written for XP.)
>
> > HTH
>
> > Brian

In the CreateFile() call, I use GENERIC_READ | GENERIC_WRITE. In WinCE
land, I don't actually need the GENERIC_WRITE, but under XP, I get an
"Access is denied." error during the IOCTL_NDISUIO_BIND_WAIT call if I
don't have it.

I've tried FILE_SHARE_READ | FILE_SHARE_WRITE, but it has the same
results as the GENERIC_ flags.

Thanks,
-PaulH


Re: multi-process singleton DLL by Ben

Ben
Tue Jul 24 16:08:36 CDT 2007

> I run the CreateFile() with GENERIC_READ | GENERIC_WRITE. In WinCE, I
> actually only need GENERIC_READ capability, but the
> IOCTL_NDISUIO_BIND_WAIT call under XP fails with an "Access is
> denied." error without the GENERIC_WRITE.
>
> I tried FILE_SHARE_READ / FILE_SHARE_WRITE and they seem to give
> exactly the same result as GENERIC_READ / GENERIC_WRITE.

Huh?

FILE_SHARE_READ | FILE_SHARE_WRITE goes in the third argument, SharingMode.
It doesn't replace the DesiredAccess (second argument). Also every caller
needs to specify sharing for it to work.



Re: multi-process singleton DLL by PaulH

PaulH
Wed Jul 25 12:04:52 CDT 2007

On Jul 24, 4:08 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospam> wrote:
> > I run the CreateFile() with GENERIC_READ | GENERIC_WRITE. In WinCE, I
> > actually only need GENERIC_READ capability, but the
> > IOCTL_NDISUIO_BIND_WAIT call under XP fails with an "Access is
> > denied." error without the GENERIC_WRITE.
>
> > I tried FILE_SHARE_READ / FILE_SHARE_WRITE and they seem to give
> > exactly the same result as GENERIC_READ / GENERIC_WRITE.
>
> Huh?
>
> FILE_SHARE_READ | FILE_SHARE_WRITE goes in the third argument, SharingMode.
> It doesn't replace the DesiredAccess (second argument). Also every caller
> needs to specify sharing for it to work.

Actually, that did work to an extent. I don't know why I didn't
consider doing that before! The IOCTL_NDISUIO_BIND_WAIT succeeds just
fine now.
Unfortunately, the IOCTL_NDISUIO_OPEN_DEVICE now fails with "The
requested resource is in use.".

-PaulH