From: Corinna Vinschen on
Hi,

this puzzles me a lot. Consider the below, self-contained example code.
It creates a new process handle to the own process, either by calling
DuplicateHandle() or by just calling OpenProcess(), depending on the
value of the DUP_PROCESS_HANDLE define. Which one of them you use
doesn't matter for the outcome of the test.

Then it opens a handle to the console output buffer and tries to
duplicate the handle returned by CreateFile for usage within the same
process.

The first call to DuplicateHandle(), which uses the real process handle
fails with ERROR_INVALID_PARAMETER. The second call to DuplicateHandle(),
which uses the pseudo process handle works fine:

C:\foo\bar> dup-stdout-test
Dup stdout with real proc handle fails with 87
Dup stdout with pseudo proc handle works

Why on earth does duplicating a console handle work for the pseudo
process handle but not for the real process handle? Is there any
sensible explanation for this weird behaviour? There's no hint in the
knowledge base that this is a known problem.

=== SNIP ===
#include <stdio.h>
#include <windows.h>

#ifndef DUP_PROCESS_HANDLE
#define DUP_PROCESS_HANDLE 0
#endif

int
main (int argc, char **argv)
{
HANDLE hMainProc;
HANDLE out, err;

#if DUP_PROCESS_HANDLE == 1
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
GetCurrentProcess (), &hMainProc,
0, FALSE, DUPLICATE_SAME_ACCESS))
{
fprintf (stderr, "Dup process fails with %lu\n", GetLastError ());
return 1;
}
#else
hMainProc = OpenProcess (PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId ());
if (!hMainProc)
{
fprintf (stderr, "Open process fails with %lu\n", GetLastError ());
return 1;
}
#endif
out = CreateFile ("CONOUT$", GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, 0, 0);
if (out == INVALID_HANDLE_VALUE)
{
fprintf (stderr, "Create stdout fails with %lu\n", GetLastError ());
return 1;
}
if (!DuplicateHandle (hMainProc, out,
hMainProc, &err,
0, TRUE, DUPLICATE_SAME_ACCESS))
fprintf (stderr, "Dup stdout with real proc handle fails with %lu\n",
GetLastError ());
else
fprintf (stderr, "Dup stdout with real proc handle works\n");
if (!DuplicateHandle (GetCurrentProcess (), out,
GetCurrentProcess (), &err,
0, TRUE, DUPLICATE_SAME_ACCESS))
fprintf (stderr, "Dup stdout with pseudo proc handle fails with %lu\n",
GetLastError ());
else
fprintf (stderr, "Dup stdout with pseudo proc handle works\n");
return 0;
}
=== SNAP ===


Corinna

--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
From: Vincent Fatica on
On Thu, 26 Nov 2009 10:50:35 +0000 (UTC), Corinna Vinschen
<corinna(a)community.nospam> wrote:

|Why on earth does duplicating a console handle work for the pseudo
|process handle but not for the real process handle? Is there any
|sensible explanation for this weird behaviour? There's no hint in the
|knowledge base that this is a known problem.

I don't have a full explanation, but without mentioning "real" handles to the
current process, the docs for DuplicateHandle say, without qualification,

"The source process uses the GetCurrentProcess function to get a handle to
itself."
--
- Vince
From: Corinna Vinschen on
Vincent Fatica wrote:
> On Thu, 26 Nov 2009 10:50:35 +0000 (UTC), Corinna Vinschen
> <corinna(a)community.nospam> wrote:
>
> |Why on earth does duplicating a console handle work for the pseudo
> |process handle but not for the real process handle? Is there any
> |sensible explanation for this weird behaviour? There's no hint in the
> |knowledge base that this is a known problem.
>
> I don't have a full explanation, but without mentioning "real" handles to the
> current process, the docs for DuplicateHandle say, without qualification,
>
> "The source process uses the GetCurrentProcess function to get a handle to
> itself."

I always thought of this as being an easy way to refer to the own
process handle, rather than being the only way allowed. A duplicate of
the GetCurrentProcess() handle and the handle fetched by OpenProcess()
should be equivalent to GetCurrentProcess() from the DuplicateHandle
point of view. And they are, except in case of the console for some
reason.


Corinna

--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
From: Pavel A. on
Corinna,

What Windows version are you testing on? Console windows have changed on NT
6 vs. NT 5.

--pa


"Corinna Vinschen" <corinna(a)community.nospam> wrote in message
news:her019$5r6$1(a)perth.hirmke.de...
> Vincent Fatica wrote:
>> On Thu, 26 Nov 2009 10:50:35 +0000 (UTC), Corinna Vinschen
>> <corinna(a)community.nospam> wrote:
>>
>> |Why on earth does duplicating a console handle work for the pseudo
>> |process handle but not for the real process handle? Is there any
>> |sensible explanation for this weird behaviour? There's no hint in the
>> |knowledge base that this is a known problem.
>>
>> I don't have a full explanation, but without mentioning "real" handles to
>> the
>> current process, the docs for DuplicateHandle say, without qualification,
>>
>> "The source process uses the GetCurrentProcess function to get a handle
>> to
>> itself."
>
> I always thought of this as being an easy way to refer to the own
> process handle, rather than being the only way allowed. A duplicate of
> the GetCurrentProcess() handle and the handle fetched by OpenProcess()
> should be equivalent to GetCurrentProcess() from the DuplicateHandle
> point of view. And they are, except in case of the console for some
> reason.
>
>
> Corinna
>
> --
> Corinna Vinschen
> Cygwin Project Co-Leader
> Red Hat

From: Alexander Grigoriev on
I suppose DuplicateHandle uses a special code path to duplicate
in-process-only handles, such as console. The remarks says "Console handles
can be duplicated for use only in the same process". It won't bother to
guess if a handle is for the current process; it needs GetCurrentProcess().

"Corinna Vinschen" <corinna(a)community.nospam> wrote in message
news:her019$5r6$1(a)perth.hirmke.de...
> Vincent Fatica wrote:
>> On Thu, 26 Nov 2009 10:50:35 +0000 (UTC), Corinna Vinschen
>> <corinna(a)community.nospam> wrote:
>>
>> |Why on earth does duplicating a console handle work for the pseudo
>> |process handle but not for the real process handle? Is there any
>> |sensible explanation for this weird behaviour? There's no hint in the
>> |knowledge base that this is a known problem.
>>
>> I don't have a full explanation, but without mentioning "real" handles to
>> the
>> current process, the docs for DuplicateHandle say, without qualification,
>>
>> "The source process uses the GetCurrentProcess function to get a handle
>> to
>> itself."
>
> I always thought of this as being an easy way to refer to the own
> process handle, rather than being the only way allowed. A duplicate of
> the GetCurrentProcess() handle and the handle fetched by OpenProcess()
> should be equivalent to GetCurrentProcess() from the DuplicateHandle
> point of view. And they are, except in case of the console for some
> reason.
>
>
> Corinna
>
> --
> Corinna Vinschen
> Cygwin Project Co-Leader
> Red Hat