* autoload.cc (RtlAnsiStringToUnicodeString): Define.

(RtlOemStringToUnicodeString): Define.
	* ntdll.h (struct _RTL_USER_PROCESS_PARAMETERS): Define.
	(struct _PEB): Redefine with a bit of content.
	(RtlAnsiStringToUnicodeString): Declare.
	(RtlOemStringToUnicodeString): Declare.
	* path.cc: Include ntdll.h.
	(_upp): New global variable pointing to user process parameter block.
	(get_user_proc_parms): New static function to retrieve user process
	parameter block.
	(close_user_proc_parms_cwd_handle): New function to close handle to
	current working directory in user process parameter block.
	(cwdstuff::init): Drop redundant declaration of dynamically_loaded.
	Set current dir only on 9x.  Call close_user_proc_parms_cwd_handle
	on NT instead.
	(cwdstuff::keep_in_sync): Only on 9x.
	(cwdstuff::set): Keep behaviour on 9x.  On NT write cwd path into user
	process parameter block and set cwd handle to NULL.  Fix comments to
	reflect new behaviour.
This commit is contained in:
Corinna Vinschen 2007-01-16 18:01:06 +00:00
parent c4c8d06b1a
commit cbe2437b28
4 changed files with 144 additions and 16 deletions

View File

@ -1,3 +1,25 @@
2007-01-16 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (RtlAnsiStringToUnicodeString): Define.
(RtlOemStringToUnicodeString): Define.
* ntdll.h (struct _RTL_USER_PROCESS_PARAMETERS): Define.
(struct _PEB): Redefine with a bit of content.
(RtlAnsiStringToUnicodeString): Declare.
(RtlOemStringToUnicodeString): Declare.
* path.cc: Include ntdll.h.
(_upp): New global variable pointing to user process parameter block.
(get_user_proc_parms): New static function to retrieve user process
parameter block.
(close_user_proc_parms_cwd_handle): New function to close handle to
current working directory in user process parameter block.
(cwdstuff::init): Drop redundant declaration of dynamically_loaded.
Set current dir only on 9x. Call close_user_proc_parms_cwd_handle
on NT instead.
(cwdstuff::keep_in_sync): Only on 9x.
(cwdstuff::set): Keep behaviour on 9x. On NT write cwd path into user
process parameter block and set cwd handle to NULL. Fix comments to
reflect new behaviour.
2007-01-16 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::ioctl): Handle SIOCGIFINDEX.

View File

@ -409,9 +409,11 @@ LoadDLLfuncNt (NtSetInformationFile, 20, ntdll)
LoadDLLfuncNt (NtSetSecurityObject, 12, ntdll)
LoadDLLfuncNt (NtUnlockVirtualMemory, 16, ntdll)
LoadDLLfuncNt (NtUnmapViewOfSection, 8, ntdll)
LoadDLLfuncNt (RtlAnsiStringToUnicodeString, 12, ntdll)
LoadDLLfuncNt (RtlInitUnicodeString, 8, ntdll)
LoadDLLfuncNt (RtlIsDosDeviceName_U, 4, ntdll)
LoadDLLfuncNt (RtlNtStatusToDosError, 4, ntdll)
LoadDLLfuncNt (RtlOemStringToUnicodeString, 12, ntdll)
LoadDLLfuncEx (EnumProcessModules, 16, psapi, 1)
LoadDLLfuncEx (GetModuleFileNameExA, 16, psapi, 1)

View File

@ -428,7 +428,48 @@ typedef struct _KERNEL_USER_TIMES
LARGE_INTEGER UserTime;
} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;
typedef void *PPEB;
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
ULONG AllocationSize;
ULONG Size;
ULONG Flags;
ULONG DebugFlags;
HANDLE hConsole;
ULONG ProcessGroup;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
UNICODE_STRING CurrentDirectoryName;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PWSTR Environment;
ULONG dwX;
ULONG dwY;
ULONG dwXSize;
ULONG dwYSize;
ULONG dwXCountChars;
ULONG dwYCountChars;
ULONG dwFillAttribute;
ULONG dwFlags;
ULONG wShowWindow;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopInfo;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeInfo;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB
{
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[9];
PVOID LoaderData;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
BYTE Reserved3[448];
ULONG SessionId;
} PEB, *PPEB;
typedef struct _PROCESS_BASIC_INFORMATION
{
@ -669,7 +710,11 @@ extern "C"
PSECURITY_DESCRIPTOR);
NTSTATUS NTAPI NtUnlockVirtualMemory (HANDLE, PVOID *, ULONG *, ULONG);
NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID);
NTSTATUS NTAPI RtlAnsiStringToUnicodeString (PUNICODE_STRING, PANSI_STRING,
BOOLEAN);
VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
ULONG NTAPI RtlIsDosDeviceName_U (PCWSTR);
ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
NTSTATUS NTAPI RtlOemStringToUnicodeString (PUNICODE_STRING, POEM_STRING,
BOOLEAN);
}

View File

@ -77,6 +77,7 @@ details. */
#include "cygtls.h"
#include "environ.h"
#include <assert.h>
#include <ntdll.h>
bool dos_file_warning = true;
static int normalize_win32_path (const char *, char *, char *&);
@ -4153,18 +4154,50 @@ cwdstuff::get_hash ()
extern char windows_system_directory[];
static PRTL_USER_PROCESS_PARAMETERS _upp NO_COPY;
static PRTL_USER_PROCESS_PARAMETERS
get_user_proc_parms ()
{
if (!_upp)
{
NTSTATUS stat;
PROCESS_BASIC_INFORMATION pbi;
stat = NtQueryInformationProcess (GetCurrentProcess (),
ProcessBasicInformation,
&pbi, sizeof pbi, NULL);
if (!NT_SUCCESS (stat))
api_fatal ("Can't retrieve process parameters, status %p", stat);
_upp = pbi.PebBaseAddress->ProcessParameters;
}
return _upp;
}
static void
close_user_proc_parms_cwd_handle ()
{
PHANDLE phdl = &get_user_proc_parms ()->CurrentDirectoryHandle;
if (*phdl)
{
NtClose (*phdl);
*phdl = NULL;
}
}
/* Initialize cygcwd 'muto' for serializing access to cwd info. */
void
cwdstuff::init ()
{
extern int dynamically_loaded;
cwd_lock.init ("cwd_lock");
get_initial ();
if (!dynamically_loaded && !keep_in_sync ())
{
/* Actually chdir into the system dir to avoid cwd problems. See comment
in cwdstuff::set below. */
SetCurrentDirectory (windows_system_directory);
/* Actually chdir into the system dir to avoid cwd problems on 9x.
See comment in cwdstuff::set below. */
if (!wincap.can_open_directories ())
SetCurrentDirectory (windows_system_directory);
else
close_user_proc_parms_cwd_handle ();
}
cwd_lock.release ();
}
@ -4172,12 +4205,14 @@ cwdstuff::init ()
void
cwdstuff::keep_in_sync (bool val)
{
sync = val;
SetCurrentDirectory (val ? win32 : windows_system_directory);
if (!wincap.can_open_directories ())
{
sync = val;
SetCurrentDirectory (val ? win32 : windows_system_directory);
}
}
/* Get initial cwd. Should only be called once in a
process tree. */
/* Get initial cwd. Should only be called once in a process tree. */
bool
cwdstuff::get_initial ()
{
@ -4209,7 +4244,7 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
/* If a Cygwin application called cygwin_internal(CW_SYNC_WINENV),
then it's about to call native Windows functions. This also
sets the keep_in_sync flag so that we actually chdir into the
native directory to avoid confusion. */
native directory on 9x to avoid confusion. */
if (!SetCurrentDirectory (win32_cwd))
{
__seterrno ();
@ -4218,13 +4253,20 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
}
else
{
/* Check if we *could* chdir, if we actually would.
Why don't we actually chdir? For two reasons:
/* We don't actually chdir on 9x but stay in the system dir.
On NT we utilize the user parameter block. The directory is
stored manually, but the handle to the directory is always
closed and set to NULL. This way the directory isn't blocked
even if it's the cwd of a Cygwin process.
Why the hassle?
- A process has always an open handle to the current working
directory which disallows manipulating this directory.
POSIX allows to remove a directory if the permissions are
ok. The fact that its the cwd of some process doesn't matter.
POSIX allows to remove a directory if the permissions are ok.
The fact that its the cwd of some process doesn't matter.
- SetCurrentDirectory fails for directories with strict
permissions even for processes with the SE_BACKUP_NAME
privilege enabled. The reason is apparently that
@ -4243,7 +4285,7 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
}
if (wincap.can_open_directories ())
{
HANDLE h = CreateFile (win32_cwd, GENERIC_READ,
HANDLE h = CreateFile (win32_cwd, FILE_TRAVERSE,
wincap.shared (), NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
@ -4251,6 +4293,23 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
__seterrno ();
goto out;
}
ULONG len = strlen (win32_cwd);
ANSI_STRING as = {len, len + 2, (PCHAR) alloca (len + 2)};
strcpy (as.Buffer, win32_cwd);
if (as.Buffer[len - 1] != '\\')
{
strcpy (as.Buffer + len, "\\");
++as.Length;
}
if (current_codepage == ansi_cp)
RtlAnsiStringToUnicodeString (
&get_user_proc_parms ()->CurrentDirectoryName,
&as, FALSE);
else
RtlOemStringToUnicodeString (
&get_user_proc_parms ()->CurrentDirectoryName,
&as, FALSE);
close_user_proc_parms_cwd_handle ();
CloseHandle (h);
}
}