* 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:
parent
c4c8d06b1a
commit
cbe2437b28
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue