Windows 7 - NtCreateProcess and fork

Asked By IkerArizmend on 18-Apr-08 12:55 PM
Is it possible to implement something that resembles
UNIX fork() with NtCreateProcess/NtCreateThread and
which is usable for non-GUI applications running under
the Win32 subsystem? The CreateProcess API provides
handle inheritance, so that part seems compatible with
Win32. However, whether a parent's address space can be
usefully inherited by a child is not clear. There are
suggestions on the web that setting SectionHandle to
NULL goes some way towards this, but I could find nothing
on the impact this would have on Win32 DLLs already
mapped by the parent, the setup of a child's stack,
registration of the child with Win32, etc.

Regards,
Iker Arizmendi




Johannes Passing replied on 20-Apr-08 05:56 AM
Implementing fork is possible with the native API. The key to creating a
process with cloned address space, handles and token should be (besides
making all handles inheritable) to pass the handle of the parent process
to the 4th parameter (InheritFromProcessHandle) and TRUE to the 5th
(InheritHandles) parameter of ZwCreateProcess.

However, using ZwCreateProcess, informing CSRSS and everything else
necessary to create a process using the native API is pretty tedious -
and all undocumented.

I also think there are good reasons for this functionality not to be
exposed to the Win32 API. Therefore, I am not quite convinced that using
fork for Win32 processes is a very promising solution...

--Johannes



--
Johannes Passing - http://int3.de/
IkerArizmend replied on 21-Apr-08 01:02 PM
I understand that these APIs are not meant for "public"
consumption. The request isn't for any official docs, nor
for support of any kind. I'm just looking for informal
pointers and discussion from folks in the know.

As to whether a Win32 fork would be promising, I think
the answer to that is "yes". Of course, not all applications
benefit from the availability of fork, but some do. And for
authors of the latter I think a Win32 fork would be a
very welcome addition.

Iker
Mikep replied on 21-Apr-08 03:57 PM
Gary Nebbett describes an implementation in his book Windows NT/2000 Native
API ---

http://books.google.com/books?hl=en&id=Fp1ct-bKYdcC&dq=%22gary+nebbett%22+windows+api&printsec=frontcover&source=web&ots=ciLzfYAKbI&sig=8qIdnRiHutRSrNFT_dEkwrnUchA#PPP1,M1

MIke
JD replied on 22-Apr-08 10:28 AM
You can take a look to see how Cygwin implemented this.  Cygwin is a Unix
emulation library and I recall reading about how they implemented fork().
IkerArizmend replied on 22-Apr-08 03:06 PM
Because the Cygwin project relied solely on Win32 APIs its fork implementation
is non-COW and inefficient in those cases where a fork is not followed by
exec.
It's also rather complex. See here (section 5.6) for details:


http://www.redhat.com/support/wpapers/cygnus/cygnus_cygwin/architecture.html

Regards,
Iker
Corinna Vinschen replied on 26-Apr-08 04:14 PM
This document is rather old, 10 years or so.  While we're still using
Win32 calls to emulate fork, the method has changed noticably.
Especially, we don't create the child process in the suspended state
anymore, unless specific datastructes need a special handling in the
parent before they get copied to the child.  In the current 1.5.25
release the only case for a suspended child are open sockets in the
parent.  The upcoming 1.7.0 release will not suspend at all.

One reason not to use ZwCreateProcess was that up to the 1.5.25 release
we're still supporting Windows 9x users.  However, two attempts to use
ZwCreateProcess on NT-based systems failed for one reason or another.

It would be really nice if this stuff would be better or at all
documented, especially a couple of datastructures and how to connect a
process to a subsystem.  While fork is not a Win32 concept, I don't see
that it would be a bad thing to make fork easier to implement.


Corinna

--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat