* Makefile.in (DLL_IMPORTS): Add libntdll.a.

* autoload.cc: Remove all symbols from advapi32.dll, kernel32.dll and
	ntdll.dll available on all platforms since NT4.

	Throughout remove all usage of wincap.is_winnt.
	* dcrt0.cc (dll_crt0_0): Remove call to mmap_init.
	* fhandler.h (class fhandler_base): Remove has_changed flag.
	(fhandler_disk_file::touch_ctime): Remove declaration.
	(fhandler_disk_file::readdir_9x): Ditto.
	(fhandler_disk_file::touch_ctime): Remove.
	(fhandler_disk_file::readdir_9x): Remove.
	(fhandler_disk_file::closedir): Call NtClose instead of CloseHandle.
	* mmap.cc: Throughout call CreateMapping and MapView directly.
	(VirtualProt9x): Remove.
	(VirtualProtNT): Remove.
	(VirtualProtEx9x): Remove.
	(VirtualProtExNT): Remove.
	(VirtualProtect): Remove define.
	(VirtualProtectEx): Remove define.
	(CreateMapping9x): Remove.
	(CreateMappingNT): Rename to CreateMapping.
	(MapView9x): Remove.
	(MapViewNT): Rename to MapView.
	(struct mmap_func_t): Remove definition.
	(mmap_funcs_9x): Remove.
	(mmap_funcs_nt): Remove.
	(mmap_func): Remove.
	(mmap_init): Remove.
	* net.cc (getdomainname): Drop comment. Use NT4 registry key only.
	(get_95_ifconf): Remove.
	* pinfo.cc (winpids::enumNT): Rename to winpids::enum_processes.
	(winpids::enum9x): Remove.
	(winpids::set): Just call enum_processes directly.
	(winpids::enum_init): Ditto.
	* pinfo.h (class winpids): Drop enum_processes pointer.  Rename
	enumNT to enum_processes.  Drop enum9x declaration.  Drop initialization
	of enum_processes throughout.
	* registry.cc (get_registry_hive_path): Just create NT key.
	(load_registry_hive): Only load NT specific file.
	* syscalls.cc (unlink_9x): Remove.
	(unlink): Just call unlink_nt.
	* wincap.cc: Remove is_winnt flag throughout.
	* wincap.h: Ditto.
	* winsup.h: Remove mmap_init declaration.
This commit is contained in:
Corinna Vinschen
2007-02-22 10:54:47 +00:00
parent 8782b2a2af
commit 570858c30f
24 changed files with 485 additions and 1252 deletions

View File

@@ -210,90 +210,61 @@ path_conv::isgood_inode (__ino64_t ino) const
int __stdcall
fhandler_base::fstat_by_handle (struct __stat64 *buf)
{
BY_HANDLE_FILE_INFORMATION local;
NTSTATUS status;
IO_STATUS_BLOCK io;
/* The entries potentially contain a name of MAX_PATH wide characters. */
const DWORD fvi_size = 2 * CYG_MAX_PATH
+ sizeof (FILE_FS_VOLUME_INFORMATION);
const DWORD fai_size = 2 * CYG_MAX_PATH + sizeof (FILE_ALL_INFORMATION);
if (wincap.is_winnt ())
PFILE_FS_VOLUME_INFORMATION pfvi = (PFILE_FS_VOLUME_INFORMATION)
alloca (fvi_size);
PFILE_ALL_INFORMATION pfai = (PFILE_ALL_INFORMATION) alloca (fai_size);
status = NtQueryVolumeInformationFile (get_handle (), &io, pfvi, fvi_size,
FileFsVolumeInformation);
if (!NT_SUCCESS (status))
{
NTSTATUS status;
IO_STATUS_BLOCK io;
/* The entries potentially contain a name of MAX_PATH wide characters. */
const DWORD fvi_size = 2 * CYG_MAX_PATH
+ sizeof (FILE_FS_VOLUME_INFORMATION);
const DWORD fai_size = 2 * CYG_MAX_PATH + sizeof (FILE_ALL_INFORMATION);
PFILE_FS_VOLUME_INFORMATION pfvi = (PFILE_FS_VOLUME_INFORMATION)
alloca (fvi_size);
PFILE_ALL_INFORMATION pfai = (PFILE_ALL_INFORMATION) alloca (fai_size);
status = NtQueryVolumeInformationFile (get_handle (), &io, pfvi, fvi_size,
FileFsVolumeInformation);
if (!NT_SUCCESS (status))
{
debug_printf ("%u = NtQueryVolumeInformationFile)",
RtlNtStatusToDosError (status));
pfvi->VolumeSerialNumber = 0; /* Set to pc.volser () in helper. */
}
status = NtQueryInformationFile (get_handle (), &io, pfai, fai_size,
FileAllInformation);
if (NT_SUCCESS (status))
{
/* If the change time is 0, it's a file system which doesn't
support a change timestamp. In that case use the LastWriteTime
entry, as in other calls to fstat_helper. */
if (pc.is_rep_symlink ())
pfai->BasicInformation.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
pc.file_attributes (pfai->BasicInformation.FileAttributes);
return fstat_helper (buf,
pfai->BasicInformation.ChangeTime.QuadPart ?
*(FILETIME *) &pfai->BasicInformation.ChangeTime :
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
*(FILETIME *) &pfai->BasicInformation.LastAccessTime,
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
pfvi->VolumeSerialNumber,
pfai->StandardInformation.EndOfFile.QuadPart,
pfai->StandardInformation.AllocationSize.QuadPart,
pfai->InternalInformation.FileId.QuadPart,
pfai->StandardInformation.NumberOfLinks,
pfai->BasicInformation.FileAttributes);
}
debug_printf ("%u = NtQueryInformationFile)",
debug_printf ("%u = NtQueryVolumeInformationFile)",
RtlNtStatusToDosError (status));
pfvi->VolumeSerialNumber = 0; /* Set to pc.volser () in helper. */
}
status = NtQueryInformationFile (get_handle (), &io, pfai, fai_size,
FileAllInformation);
if (NT_SUCCESS (status))
{
/* If the change time is 0, it's a file system which doesn't
support a change timestamp. In that case use the LastWriteTime
entry, as in other calls to fstat_helper. */
if (pc.is_rep_symlink ())
pfai->BasicInformation.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
pc.file_attributes (pfai->BasicInformation.FileAttributes);
return fstat_helper (buf,
pfai->BasicInformation.ChangeTime.QuadPart ?
*(FILETIME *) &pfai->BasicInformation.ChangeTime :
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
*(FILETIME *) &pfai->BasicInformation.LastAccessTime,
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
pfvi->VolumeSerialNumber,
pfai->StandardInformation.EndOfFile.QuadPart,
pfai->StandardInformation.AllocationSize.QuadPart,
pfai->InternalInformation.FileId.QuadPart,
pfai->StandardInformation.NumberOfLinks,
pfai->BasicInformation.FileAttributes);
}
BOOL res = GetFileInformationByHandle (get_handle (), &local);
debug_printf ("%d = GetFileInformationByHandle (%s, %d)",
res, get_win32_name (), get_handle ());
/* GetFileInformationByHandle will fail if it's given stdio handle or pipe.
It also fails on 9x when trying to access directories on shares. */
if (!res)
{
memset (&local, 0, sizeof (local));
local.nFileSizeLow = GetFileSize (get_handle (), &local.nFileSizeHigh);
/* Even GetFileSize fails on 9x when trying to access directories
on shares. In this case reset filesize to 0. */
if (local.nFileSizeLow == 0xffffffff && GetLastError ())
local.nFileSizeLow = 0;
local.dwFileAttributes = DWORD (pc);
}
else
{
if (pc.is_rep_symlink ())
local.dwFileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
pc.file_attributes (local.dwFileAttributes);
}
return fstat_helper (buf,
local.ftLastWriteTime, /* see fstat_helper comment */
local.ftLastAccessTime,
local.ftLastWriteTime,
local.dwVolumeSerialNumber,
(ULONGLONG) local.nFileSizeHigh << 32
| local.nFileSizeLow,
-1LL,
(ULONGLONG) local.nFileIndexHigh << 32
| local.nFileIndexLow,
local.nNumberOfLinks,
local.dwFileAttributes);
debug_printf ("%u = NtQueryInformationFile)",
RtlNtStatusToDosError (status));
/* Last resort */
FILETIME ft = { 0, 0 };
DWORD lowfs, highfs;
lowfs = GetFileSize (get_handle (), &highfs);
if (lowfs == 0xffffffff && GetLastError ())
lowfs = highfs = 0;
return fstat_helper (buf, ft, ft, ft, 0, (ULONGLONG) highfs << 32 | lowfs,
-1LL, 0ULL, 1, DWORD (pc));
}
int __stdcall
@@ -556,26 +527,9 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
int __stdcall
fhandler_disk_file::fstat (struct __stat64 *buf)
{
/* Changing inode data requires setting ctime (only 9x). */
if (has_changed ())
touch_ctime ();
return fstat_fs (buf);
}
void
fhandler_disk_file::touch_ctime ()
{
FILETIME ft;
GetSystemTimeAsFileTime (&ft);
/* Modification time is touched if the file data has changed as well.
This happens for instance on write() or ftruncate(). */
if (!SetFileTime (get_io_handle (), NULL, NULL, &ft))
debug_printf ("SetFileTime (%s) failed, %E", get_win32_name ());
else
has_changed (false);
}
int __stdcall
fhandler_disk_file::fchmod (mode_t mode)
{
@@ -623,10 +577,6 @@ fhandler_disk_file::fchmod (mode_t mode)
/* Correct NTFS security attributes have higher priority */
res = 0;
/* Set ctime on success. */
if (!res && !wincap.is_winnt ())
has_changed (true);
if (oret)
close ();
@@ -783,9 +733,6 @@ fhandler_disk_file::fadvise (_off64_t offset, _off64_t length, int advice)
return -1;
}
if (!wincap.is_winnt ())
return 0;
/* Windows only supports advice flags for the whole file. We're using
a simplified test here so that we don't have to ask for the actual
file size. Length == 0 means all bytes starting at offset anyway.
@@ -835,6 +782,10 @@ fhandler_disk_file::ftruncate (_off64_t length, bool allow_truncate)
{
_off64_t actual_length;
DWORD size_high = 0;
NTSTATUS status;
IO_STATUS_BLOCK io;
FILE_END_OF_FILE_INFORMATION feofi;
actual_length = GetFileSize (get_handle (), &size_high);
actual_length += ((_off64_t) size_high) << 32;
@@ -843,49 +794,27 @@ fhandler_disk_file::ftruncate (_off64_t length, bool allow_truncate)
if (!allow_truncate && length < actual_length)
return 0;
if (wincap.is_winnt ())
feofi.EndOfFile.QuadPart = length;
/* Create sparse files only when called through ftruncate, not when
called through posix_fallocate. */
if (allow_truncate
&& get_fs_flags (FILE_SUPPORTS_SPARSE_FILES)
&& length >= actual_length + (128 * 1024))
{
NTSTATUS status;
IO_STATUS_BLOCK io;
FILE_END_OF_FILE_INFORMATION feofi;
feofi.EndOfFile.QuadPart = length;
/* Create sparse files only when called through ftruncate, not when
called through posix_fallocate. */
if (allow_truncate
&& get_fs_flags (FILE_SUPPORTS_SPARSE_FILES)
&& length >= actual_length + (128 * 1024))
{
DWORD dw;
BOOL r = DeviceIoControl (get_handle (),
FSCTL_SET_SPARSE, NULL, 0, NULL,
0, &dw, NULL);
syscall_printf ("%d = DeviceIoControl(%p, FSCTL_SET_SPARSE)",
r, get_handle ());
}
status = NtSetInformationFile (get_handle (), &io,
&feofi, sizeof feofi,
FileEndOfFileInformation);
if (!NT_SUCCESS (status))
__seterrno_from_nt_status (status);
else
res = 0;
DWORD dw;
BOOL r = DeviceIoControl (get_handle (),
FSCTL_SET_SPARSE, NULL, 0, NULL,
0, &dw, NULL);
syscall_printf ("%d = DeviceIoControl(%p, FSCTL_SET_SPARSE)",
r, get_handle ());
}
status = NtSetInformationFile (get_handle (), &io,
&feofi, sizeof feofi,
FileEndOfFileInformation);
if (!NT_SUCCESS (status))
__seterrno_from_nt_status (status);
else
{
_off64_t prev_loc = lseek (0, SEEK_CUR);
if (lseek (length, SEEK_SET) >= 0)
{
int res_bug = write (&res, 0);
if (!SetEndOfFile (get_handle ()))
__seterrno ();
else
res = res_bug;
/* restore original file pointer location */
lseek (prev_loc, SEEK_SET);
}
}
res = 0;
}
return res;
}
@@ -1050,9 +979,6 @@ docopy:
__seterrno ();
return -1;
}
/* Set ctime on success (copy gets it automatically). */
if (!wincap.is_winnt ())
has_changed (true);
close ();
fhandler_disk_file fh (newpc);
fh.query_open (query_write_attributes);
@@ -1200,12 +1126,6 @@ out:
int
fhandler_disk_file::close ()
{
if (!hExeced)
{
/* Changing inode data requires setting ctime (only 9x). */
if (has_changed ())
touch_ctime ();
}
return close_fs ();
}
@@ -1462,16 +1382,10 @@ fhandler_disk_file::rmdir ()
(DWORD) pc & ~FILE_ATTRIBUTE_READONLY);
DWORD err, att = 0;
int rc;
if (wincap.is_winnt ())
{
rc = !(err = unlink_nt (pc, pc.has_attribute (FILE_ATTRIBUTE_READONLY)));
if (err)
SetLastError (err);
}
else
rc = RemoveDirectory (get_win32_name ());
int rc = !(err = unlink_nt (pc, pc.has_attribute (FILE_ATTRIBUTE_READONLY)));
if (err)
SetLastError (err);
if (isremote () && exists ())
att = GetFileAttributes (get_win32_name ());
@@ -1503,10 +1417,6 @@ fhandler_disk_file::rmdir ()
__seterrno_from_win_error (err);
/* Directory still exists, restore its characteristics. */
if (!wincap.is_winnt () && pc.has_attribute (FILE_ATTRIBUTE_READONLY))
SetFileAttributes (get_win32_name (), (DWORD) pc);
return res;
}
@@ -1547,9 +1457,8 @@ fhandler_disk_file::opendir ()
set_errno (ENAMETOOLONG);
else if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL)
set_errno (ENOMEM);
else if ((dir->__d_dirname = (char *) malloc (wincap.is_winnt ()
? sizeof (struct __DIR_cache)
: len + 3)) == NULL)
else if ((dir->__d_dirname = (char *) malloc ( sizeof (struct __DIR_cache)))
== NULL)
{
set_errno (ENOMEM);
goto free_dir;
@@ -1586,47 +1495,45 @@ fhandler_disk_file::opendir ()
&& pc.normalized_path[1] == '\0')
? dirent_isroot : 0;
dir->__d_internal = (unsigned) new __DIR_mounts (pc.normalized_path);
if (wincap.is_winnt ())
{
d_cachepos (dir) = 0;
if (!pc.iscygdrive ())
{
OBJECT_ATTRIBUTES attr;
WCHAR wpath[CYG_MAX_PATH + 10];
UNICODE_STRING upath = {0, sizeof (wpath), wpath};
IO_STATUS_BLOCK io;
NTSTATUS status;
SECURITY_ATTRIBUTES sa = sec_none;
pc.get_nt_native_path (upath);
InitializeObjectAttributes (&attr, &upath,
OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
NULL, sa.lpSecurityDescriptor);
status = NtOpenFile (&dir->__handle,
SYNCHRONIZE | FILE_LIST_DIRECTORY,
&attr, &io, wincap.shared (),
FILE_SYNCHRONOUS_IO_NONALERT
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto free_mounts;
}
d_cachepos (dir) = 0;
/* FileIdBothDirectoryInformation is apparently unsupported on
XP when accessing directories on UDF. When trying to use it
so, NtQueryDirectoryFile returns with STATUS_ACCESS_VIOLATION.
It's not clear if the call isn't also unsupported on other
OS/FS combinations (say, Win2K/CDFS or so). Instead of
testing in readdir for yet another error code, let's use
FileIdBothDirectoryInformation only on filesystems supporting
persistent ACLs, FileBothDirectoryInformation otherwise. */
if (pc.hasgood_inode ())
{
dir->__flags |= dirent_set_d_ino;
if (wincap.has_fileid_dirinfo ())
dir->__flags |= dirent_get_d_ino;
}
if (!pc.iscygdrive ())
{
OBJECT_ATTRIBUTES attr;
WCHAR wpath[CYG_MAX_PATH + 10];
UNICODE_STRING upath = {0, sizeof (wpath), wpath};
IO_STATUS_BLOCK io;
NTSTATUS status;
SECURITY_ATTRIBUTES sa = sec_none;
pc.get_nt_native_path (upath);
InitializeObjectAttributes (&attr, &upath,
OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
NULL, sa.lpSecurityDescriptor);
status = NtOpenFile (&dir->__handle,
SYNCHRONIZE | FILE_LIST_DIRECTORY,
&attr, &io, wincap.shared (),
FILE_SYNCHRONOUS_IO_NONALERT
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
goto free_mounts;
}
/* FileIdBothDirectoryInformation is apparently unsupported on
XP when accessing directories on UDF. When trying to use it
so, NtQueryDirectoryFile returns with STATUS_ACCESS_VIOLATION.
It's not clear if the call isn't also unsupported on other
OS/FS combinations (say, Win2K/CDFS or so). Instead of
testing in readdir for yet another error code, let's use
FileIdBothDirectoryInformation only on filesystems supporting
persistent ACLs, FileBothDirectoryInformation otherwise. */
if (pc.hasgood_inode ())
{
dir->__flags |= dirent_set_d_ino;
if (wincap.has_fileid_dirinfo ())
dir->__flags |= dirent_get_d_ino;
}
}
/* Filling fd with `this' (aka storing this in the file descriptor table
@@ -1755,9 +1662,6 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
char fname[CYG_MAX_PATH];
IO_STATUS_BLOCK io;
if (!wincap.is_winnt ())
return readdir_9x (dir, de);
/* d_cachepos always refers to the next cache entry to use. If it's 0
we must reload the cache. */
if (d_cachepos (dir) == 0)
@@ -1911,55 +1815,6 @@ go_ahead:
return res;
}
int
fhandler_disk_file::readdir_9x (DIR *dir, dirent *de)
{
WIN32_FIND_DATA buf;
int res = 0;
if (!dir->__handle)
{
res = ENMFILE;
goto out;
}
DWORD lasterr;
if (dir->__d_position != 0)
lasterr = FindNextFileA (dir->__handle, &buf) ? 0 : GetLastError ();
else if (dir->__handle != INVALID_HANDLE_VALUE)
{
res = EBADF;
goto out;
}
else
{
int len = strlen (dir->__d_dirname);
strcpy (dir->__d_dirname + len, "*");
dir->__handle = FindFirstFile (dir->__d_dirname, &buf);
dir->__d_dirname[len] = '\0';
if (dir->__handle != INVALID_HANDLE_VALUE)
lasterr = 0;
else if ((lasterr = GetLastError ()) != ERROR_NO_MORE_FILES)
{
res = geterrno_from_win_error (lasterr);
goto out;
}
}
if (!lasterr)
de->d_ino = d_mounts (dir)->check_mount (buf.cFileName, de->d_ino);
if (!(res = readdir_helper (dir, de, lasterr, buf.dwFileAttributes,
buf.cFileName)))
dir->__d_position++;
else
{
FindClose (dir->__handle);
dir->__handle = NULL;
}
out:
syscall_printf ("%d = readdir (%p, %p) (%s)", res, dir, &de, res ? "***" : de->d_name);
return res;
}
_off64_t
fhandler_disk_file::telldir (DIR *dir)
{
@@ -1978,45 +1833,36 @@ fhandler_disk_file::seekdir (DIR *dir, _off64_t loc)
void
fhandler_disk_file::rewinddir (DIR *dir)
{
if (wincap.is_winnt ())
d_cachepos (dir) = 0;
if (wincap.has_buggy_restart_scan () && isremote ())
{
d_cachepos (dir) = 0;
if (wincap.has_buggy_restart_scan () && isremote ())
{
/* This works around a W2K bug. The RestartScan parameter in calls
to NtQueryDirectoryFile on remote shares is ignored, thus
resulting in not being able to rewind on remote shares. By
reopening the directory, we get a fresh new directory pointer. */
UNICODE_STRING fname = {0, CYG_MAX_PATH * 2, (WCHAR *) L""};
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
IO_STATUS_BLOCK io;
HANDLE new_dir;
/* This works around a W2K bug. The RestartScan parameter in calls
to NtQueryDirectoryFile on remote shares is ignored, thus
resulting in not being able to rewind on remote shares. By
reopening the directory, we get a fresh new directory pointer. */
UNICODE_STRING fname = {0, CYG_MAX_PATH * 2, (WCHAR *) L""};
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
IO_STATUS_BLOCK io;
HANDLE new_dir;
InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE,
dir->__handle, NULL);
status = NtOpenFile (&new_dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
&attr, &io, wincap.shared (),
FILE_SYNCHRONOUS_IO_NONALERT
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (stat))
debug_printf ("Unable to reopen dir %s, NT error: 0x%08x, "
"win32: %lu", get_name (), status,
RtlNtStatusToDosError (status));
else
{
CloseHandle (dir->__handle);
dir->__handle = new_dir;
}
InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE,
dir->__handle, NULL);
status = NtOpenFile (&new_dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
&attr, &io, wincap.shared (),
FILE_SYNCHRONOUS_IO_NONALERT
| FILE_OPEN_FOR_BACKUP_INTENT
| FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (stat))
debug_printf ("Unable to reopen dir %s, NT error: 0x%08x, "
"win32: %lu", get_name (), status,
RtlNtStatusToDosError (status));
else
{
CloseHandle (dir->__handle);
dir->__handle = new_dir;
}
}
else if (dir->__handle != INVALID_HANDLE_VALUE)
{
if (dir->__handle)
FindClose (dir->__handle);
dir->__handle = INVALID_HANDLE_VALUE;
}
dir->__d_position = 0;
d_mounts (dir)->rewind ();
}
@@ -2033,18 +1879,10 @@ fhandler_disk_file::closedir (DIR *dir)
set_errno (EBADF);
res = -1;
}
else
else if (!NtClose (dir->__handle))
{
BOOL winres;
if (wincap.is_winnt ())
winres = CloseHandle (dir->__handle);
else
winres = FindClose (dir->__handle);
if (!winres)
{
__seterrno ();
res = -1;
}
__seterrno ();
res = -1;
}
syscall_printf ("%d = closedir (%p, %s)", res, dir, get_name ());
return res;