On Sep 11 00:12, John Carey wrote: > On Sep 04 02:26 Corinna Vinschen wrote: > > The problem only starts with Vista. I have no objections to use > > undocumented features, if they work. If there's any way to replace the > > cwd handle with our own *and* keep the Win32 API happy, I'll take it. > > I think I've found a way to open the directory handle for backup intent > on Vista and later versions. Essentially, I emulate the new things that > SetCurrentDirectory() is doing, but in order to get the necessary > addresses, I have to do some very ugly hacks. > > The proof-of-concept code follows (and is also attached). It includes > an analysis of what is going on--to the extent that I know what is going > on, of course. Please let me know what you think.
First of all, I'm thoroughly impressed. This looks like a lot of detective work and I'm also impressed by the amount of time you apparently put into this. I'm hopeful we can create something for Cygwin from this. I have just a few discussing points for now. > The PEB does NOT seem to point to any VistaCwd instances. Instead, That puzzles me a bit... > After creating the new VistaCwd instance; call it newCwd, the > SetCurrentDirectory () implementation modifies the PEB and Cwd > under a lock on CwdCS, as follows: > > Params.CurrentDirectoryHandle = newCwd.DirectoryHandle; > > Params.CurrentDirectoryName.Buffer = newCwd.Path.Buffer; ...because, at this point it *does* point to the newCWD, even if only indirectly. Let's name the VistaCwd structure Cwd points to "curCwd" for now. Since we have the address of curCwd.Path.Buffer in Params.CurrentDirectoryName.Buffer, we can infer the address of curCwd from here, right? It's start is just a constant offset from the Buffer address. Given that, wouldn't it be potentially possible to override the content of curCwd? The problem is probably (just as in my old Cygwin code up to 1.7.5) to make sure that this is thread safe. Probably we would still need CwdCS. > cout << showbase << hex << (size_t)CwdCS > << " <== critical section" << endl; > cout << showbase << hex << (size_t)Cwd > << " <== Vista++ CWD struct pointer" << endl; Is there any connection between these two addresses, like, say, they are side by side? Can't we find Cwd by scanning the .data segment of ntdll.h for the address we inferred from the Params.CurrentDirectoryName.Buffer value? 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