Subject: Re: Cygwin | Cygwin Compatibility Issue report ID 386608.
From: Corinna Vinschen <[email-masked]>
To: "Anuja Singh (MP Tech Consulting LLC)" <[email-masked]>
Cc: [email-masked]
Date: Fri, 27 Apr 2012 14:15:33 +0200
List-Id: <cygwin.cygwin.com>

Hi Anuja,

On Apr 27 12:15, Corinna Vinschen wrote:
> [...]
> > Tester/Developer Notes: 
> >       	Cygwin manually scans ntdll.dll to find the address of the global variable used to access the current working directory. It fails to do this on Windows 8, hence the 	error every time the DLL loads. The error of this function is as follows:
> >              "find_fast_cwd: WARNING: Couldn't compute FAST_CWD pointer". 
> 
> Thanks for the report.  It had been fixed for the Developer Preview, but
> I just saw that it is broken again for the Consumer Preview.  I'll take
> a stab at fixing that in the next couple of days.

FYI, I have fixed that in CVS:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/winsup/cygwin/path.cc.diff?cvsroot=src&r1=1.661&r2=1.662

The problem only occurs on Windows 8 CP 32 bit.  It looks like the
RtlEnterCriticalSection function has been inlined, so the Cygwin
function searching the global FAST_CWD pointer, which expected a call to
RtlEnterCriticalSection, didn't work anymore.  WOW64 is not affected
apparently.

The remainder of my previous mail is still valid, though, and I'm
looking forward to discuss this issue as outlined below.

> > 	Cygwin is taking a direct dependency on a global variable in ntdll.dll which will likely break the app every time the DLL revs.  You should consider using other methods 	to maintain compatibility.
> 
> Yes, we search for this variable manually, and we are aware that an
> upstream change in ntdll.dll might break Cygwin in this regard.
> Fortunately, if Cygwin can't find this global variable, it has a backup
> method to set the CWD as it needs to, so CYgwin applications will run,
> nevertheless.
> 
> Please let me explain the motivation behind using this undocumented
> global variable.  Keep in mind that Cygwin is a POSIX emulation layer,
> so there are certain expectations from the application's point of view.
> 
> The only call in the Win32 subsystem to change the CWD is
> SetCurrentDirectory.  SetCurrentDirectory has a couple of disadvantages:
> 
> - SetCurrentDirectory only supports paths of up to MAX_PATH - 1 chars,
>   including a trailing backslash.  That's an absolute restriction, even
>   when using the UNICODE API (static buffer).  Cygwin supports up to 32K
>   paths, just like the UNICODE API usually does.
> 
> - SetCurrentDirectory fails for directories with strict permissions even
>   for processes with the SE_BACKUP_NAME privilege enabled.  The reason
>   is apparently that SetCurrentDirectory calls NtOpenFile without the
>   FILE_OPEN_FOR_BACKUP_INTENT flag set.  An admin user should be able to
>   chdir into any directory.
> 
> - SetCurrentDirectory does not support case-sensitivity.  Cygwin does.
> 
> - Unlinking a CWD fails because SetCurrentDirectory calls NtOpenFile
>   without the FILE_SHARE_DELETE sharing mode set.  Cygwin supports this
>   notion.
> 
> Therefore we decided to do without SetCurrentDirectory and to manipulate
> the CWD manually.  In the first place, the CWD handle is created with
> FILE_SHARE_DELETE sharing mode and with the FILE_OPEN_FOR_BACKUP_INTENT
> flag set.  This worked fine up to Windows Server 2003 R2.
> 
> But it broke with Windows Vista in a subtil way.  It turned out that
> Vista introduced some structure we call "struct FAST_CWD".  The problem
> now being that the CWD handle is not only stored in the
> RTL_USER_PROCESS_PARAMETERS block, but additionally in a dynamically
> allocated FAST_CWD block. 
> 
> To make a long story short, unfortunately this structure and how to
> access it is not documented, nor is the global variable keeping its
> address exported from ntdll.dll.
> 
> Obviously, we didn't want to drop the much more POSIX-like behaviour of
> Cygwin's chdir call with Vista.  So the result was that we added code to
> figure out where the global variable is stored, plus a heuristic which
> tries to evaluate the layout of the FAST_CWD structure.  All the code to
> do this you can find in the CVS repository, in the file path.cc:
> http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/path.cc?rev=1.661&content-type=text/x-cvsweb-markup&cvsroot=src
> starting at about line 3500.  The structure layout is defined in
> cygheap.h:
> http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/cygheap.h?rev=1.158&content-type=text/x-cvsweb-markup&cvsroot=src
> at about line 220.
> 
> So we are willing to keep this code in shape, even if the layout of the
> code and the structure changes again.
> 
> However, I'm wondering if there is a chance that Microsoft could open up
> this part of ntdll.dll and export the global variable and document the
> layout of the structure we call "FAST_CWD".
> 
> Alternatively, if there is any other way to accomplish the above in an
> officially blessed way, we would certainly be eager to learn it.
> 
> Is there a chance to discuss this issue with one of the developers or
> program managers of the kernel team?
> 
> 
> Thanks in advance,
> Corinna

Thanks,
Corinna

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

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple