Discussion:
Add support for Windows 8, first step
Corinna Vinschen
2011-10-13 10:33:32 UTC
Permalink
Hi Teemu,


I move the discussion over to the cygwin-developers list.
Hello Corinna,
First of all, we need a copyright assignment from you before we can
accept non-trivial patches to Cygwin, see http://cygwin.com/contrib.html,
the "Before you get started" section.
I am going to do that just in case I actually get something working
(see below).
Cool.
Windows 8 will very likely support the FAST_CWD stuff, the problem is
just to find out how to find the global pointer pointing to the current
FAST_CWD structure, and then, if the FAST_CWD structure changed.
It does do that, the code looks almost the same as in Windows 7.
There are some differences that I haven't figured out yet. But I
might actually wait for a beta version of Windows 8 before going
forward.
Your original mail got me thinking, so I installed the Windows 8 preview
in qemu/kvm, reverted the system to the good old start menu(*), and
installed Cygwin.

First I inspected the FAST_CWD datastructure, and from what I can see,
it resembles closely the *old* structure used before KB 2393802 on Vista
and W7:

typedef struct _FAST_CWD_8 {
LONG ReferenceCount;
HANDLE DirectoryHandle;
ULONG OldDismountCount;
UNICODE_STRING Path;
LONG FSCharacteristics;
WCHAR Buffer[MAX_PATH];
} FAST_CWD_8, *PFAST_CWD_8;

See? The only difference is apparently the addition of the
FSCharacteristics member from the current FAST_CWD structure on
Vista/W7.

That makes me a bit suspicious. Why on earth should the structure
layout be changed back without need? Maybe it has something to do
with an optimized structure layout on 64 bit?!?

Anyway, I will check in a patch, today or tomorrow, which adds code
to use the new structure on W8.
Therefore I don't want to disable this message. If you're interested
to get rid of it, it would be most helpful trying to track down how to
find the global FAST_CWD pointer in W8.
If I understood the code correctly f_cwd_ptr is the location of
ntdll!RtlpCurDirRef and find_fast_cwd_pointer tries to find that
location.
Right, that's the idea since RtlpCurDirRef is not exported from ntdll,
unfortunately.
For some reason I couldn't get breakpoints working when
debugging cygwin1.dll so I did some disassembling and found the
correct location for ntdll!RtlpCurDirRef in Windows 8 version of
ntdll (wow64).
Any hints for debugging the Cygwin dll itself as find_fast_cwd runs
once per session so it has been very difficult trying to get a
working breakpoint.
That's easy. Start a GDB session for, say /bin/ls. Before starting the
process, set a breakpoint on 'cwdstuff::override_win32_cwd'. Then `run'
to the breakpoint. The only reason that find_fast_cwd() isn't called is
the fact that the global fast_cwd_ptr pointer is not -1. So just set it
to -1 and then you can step through find_fast_cwd() and
find_fast_cwd_pointer().


Corinna


(*) I really hope Microsoft doesn't remove the old start menu entirely
from the OS. The new GUI which is supposed to replace the start
menu is only useful for tablets and playing, but not for serious
work, IMO.
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat
Corinna Vinschen
2011-10-13 15:52:16 UTC
Permalink
Post by Corinna Vinschen
Windows 8 will very likely support the FAST_CWD stuff, the problem is
just to find out how to find the global pointer pointing to the current
FAST_CWD structure, and then, if the FAST_CWD structure changed.
It does do that, the code looks almost the same as in Windows 7.
There are some differences that I haven't figured out yet. But I
might actually wait for a beta version of Windows 8 before going
forward.
Your original mail got me thinking, so I installed the Windows 8 preview
in qemu/kvm, reverted the system to the good old start menu(*), and
installed Cygwin.
First I inspected the FAST_CWD datastructure, and from what I can see,
it resembles closely the *old* structure used before KB 2393802 on Vista
typedef struct _FAST_CWD_8 {
LONG ReferenceCount;
HANDLE DirectoryHandle;
ULONG OldDismountCount;
UNICODE_STRING Path;
LONG FSCharacteristics;
WCHAR Buffer[MAX_PATH];
} FAST_CWD_8, *PFAST_CWD_8;
See? The only difference is apparently the addition of the
FSCharacteristics member from the current FAST_CWD structure on
Vista/W7.
That makes me a bit suspicious. Why on earth should the structure
layout be changed back without need? Maybe it has something to do
with an optimized structure layout on 64 bit?!?
Anyway, I will check in a patch, today or tomorrow, which adds code
to use the new structure on W8.
I just checked in my patch. I introduced a new class fcwd_access_t
which hides the implementation details so find_fast_cwd and
cwdstuff::override_win32_cwd don't have to know the actual structure
layout. Thus, if a nother FAST_CWD structure comes along, we only have
to change (hopefully) a bit of code in fcwd_access_t.

I didn't try to find out how to compute fast_cwd_ptr on W8 yet, but
at least the FAST_CWD stuff should work fine using the "couldn't compute
fast_cwd_ptr hack" in cwdstuff::override_win32_cwd on W8 now...


Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat
Corinna Vinschen
2011-10-13 16:51:09 UTC
Permalink
Post by Corinna Vinschen
Post by Corinna Vinschen
Anyway, I will check in a patch, today or tomorrow, which adds code
to use the new structure on W8.
I just checked in my patch. I introduced a new class fcwd_access_t
which hides the implementation details so find_fast_cwd and
cwdstuff::override_win32_cwd don't have to know the actual structure
layout. Thus, if a nother FAST_CWD structure comes along, we only have
to change (hopefully) a bit of code in fcwd_access_t.
I didn't try to find out how to compute fast_cwd_ptr on W8 yet, but
at least the FAST_CWD stuff should work fine using the "couldn't compute
fast_cwd_ptr hack" in cwdstuff::override_win32_cwd on W8 now...
I just checked in a patch to find_fast_cwd_pointer which allows to
compute fast_cwd_ptr on W8 as well. It was pretty simple. The only
crucial difference in the code was the usage of "push crit-sect-addr"
instead of "mov edi, crit-sect-addr; push edi", which changes the
address of the next instruction by a single byte.


Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat
Teemu Nätkinniemi
2011-10-13 16:57:09 UTC
Permalink
Post by Corinna Vinschen
I just checked in a patch to find_fast_cwd_pointer which allows to
compute fast_cwd_ptr on W8 as well. It was pretty simple. The only
crucial difference in the code was the usage of "push crit-sect-addr"
instead of "mov edi, crit-sect-addr; push edi", which changes the
address of the next instruction by a single byte.
Well, that saved me from a lot of work :) I'll test the patches tomorrow.
Teemu Nätkinniemi
2011-10-18 11:57:51 UTC
Permalink
Post by Corinna Vinschen
I just checked in a patch to find_fast_cwd_pointer which allows to
compute fast_cwd_ptr on W8 as well. It was pretty simple. The only
crucial difference in the code was the usage of "push crit-sect-addr"
instead of "mov edi, crit-sect-addr; push edi", which changes the
address of the next instruction by a single byte.
Just tested and it seems to work fine apart from one problem. When LANG
is set to default C.UTF-8 I get random fork errors. I found a workaround
because I don't like to use Cygwin in Finnish so setting LANG=C fixes
the problem. I've attached a log that shows the errors. Otherwise Cygwin
works fine with your latest patch, I managed to compile Cygwin itself
without any problems.
Corinna Vinschen
2011-10-18 15:53:48 UTC
Permalink
Post by Teemu Nätkinniemi
Post by Corinna Vinschen
I just checked in a patch to find_fast_cwd_pointer which allows to
compute fast_cwd_ptr on W8 as well. It was pretty simple. The only
crucial difference in the code was the usage of "push crit-sect-addr"
instead of "mov edi, crit-sect-addr; push edi", which changes the
address of the next instruction by a single byte.
Just tested and it seems to work fine apart from one problem. When
LANG is set to default C.UTF-8 I get random fork errors. I found a
workaround because I don't like to use Cygwin in Finnish so setting
LANG=C fixes the problem.
C.UTF-8 works fine for me. Sure that this isn't just a rebase problem?
Post by Teemu Nätkinniemi
1442 [main] make 3756 C:\cygwin\bin\make.exe: *** fatal error in forked process - recreate_mmaps_after_fork_failed
The mmaps couldn't be recreated, which points to a DLL collision.


Corinna
--
Corinna Vinschen Please, send mails regarding Cygwin to
Cygwin Project Co-Leader cygwin AT cygwin DOT com
Red Hat
Loading...