4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-21 16:26:12 +08:00

* autoload.cc (NtClose): Define.

(NtOpenDirectoryObject): Define.
	(NtQueryDirectoryObject): Define.
	* fhandler_proc.cc: Include ctype.h and wchar.h.
	(format_proc_partitions): Revamp loop over existing harddisks by
	scanning the NT native \Device object directory and looking for
	Harddisk entries.
	* ntdll.h: Rearrange system call declarations alphabetically.
	(DIRECTORY_QUERY): Define.
	(struct _DIRECTORY_BASIC_INFORMATION): Define.
	(NtOpenDirectoryObject): Declare.
	(NtQueryDirectoryObject): Declare.
This commit is contained in:
Corinna Vinschen 2006-03-09 09:01:08 +00:00
parent 4db3b4496e
commit e9c8cb3193
4 changed files with 172 additions and 108 deletions

View File

@ -1,3 +1,18 @@
2006-03-09 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (NtClose): Define.
(NtOpenDirectoryObject): Define.
(NtQueryDirectoryObject): Define.
* fhandler_proc.cc: Include ctype.h and wchar.h.
(format_proc_partitions): Revamp loop over existing harddisks by
scanning the NT native \Device object directory and looking for
Harddisk entries.
* ntdll.h: Rearrange system call declarations alphabetically.
(DIRECTORY_QUERY): Define.
(struct _DIRECTORY_BASIC_INFORMATION): Define.
(NtOpenDirectoryObject): Declare.
(NtQueryDirectoryObject): Declare.
2006-03-08 Christopher Faylor <cgf@timesys.com>
* cygtls.h (_cygtls::retaddr): New method.

View File

@ -378,13 +378,16 @@ LoadDLLfunc (NetUserGetGroups, 28, netapi32)
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)
LoadDLLfuncEx (NtClose, 4, ntdll, 1)
LoadDLLfuncEx (NtCreateFile, 44, ntdll, 1)
LoadDLLfuncEx (NtCreateSection, 28, ntdll, 1)
LoadDLLfuncEx (NtCreateToken, 52, ntdll, 1)
LoadDLLfuncEx (NtLockVirtualMemory, 16, ntdll, 1)
LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
LoadDLLfuncEx (NtOpenDirectoryObject, 12, ntdll, 1)
LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1)
LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
LoadDLLfuncEx (NtQueryDirectoryObject, 28, ntdll, 1)
LoadDLLfuncEx2 (NtQueryDirectoryFile, 44, ntdll, 1, 1)
LoadDLLfuncEx2 (NtQueryInformationFile, 20, ntdll, 1, 1)
LoadDLLfuncEx (NtQueryInformationProcess, 20, ntdll, 1)

View File

@ -26,7 +26,9 @@ details. */
#include <sys/utsname.h>
#include <sys/param.h>
#include "ntdll.h"
#include <ctype.h>
#include <winioctl.h>
#include <wchar.h>
#include "cpuid.h"
#define _COMPILING_NEWLIB
@ -952,61 +954,101 @@ format_proc_partitions (char *destbuf, size_t maxsize)
char *bufptr = destbuf;
print ("major minor #blocks name\n\n");
if (wincap.is_winnt ())
if (!wincap.is_winnt ())
return bufptr - destbuf;
char devname[CYG_MAX_PATH];
OBJECT_ATTRIBUTES attr;
HANDLE dirhdl, devhdl;
IO_STATUS_BLOCK io;
NTSTATUS status;
/* Open \Device object directory. */
wchar_t wpath[CYG_MAX_PATH] = L"\\Device";
UNICODE_STRING upath = {14, 16, wpath};
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtOpenDirectoryObject (&dirhdl, DIRECTORY_QUERY, &attr);
if (!NT_SUCCESS (status))
{
for (int drive_number=0; ; drive_number++)
{
CHAR szDriveName[CYG_MAX_PATH];
__small_sprintf (szDriveName, "\\\\.\\PHYSICALDRIVE%d", drive_number);
HANDLE hDevice;
hDevice = CreateFile (szDriveName, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
if (GetLastError () == ERROR_PATH_NOT_FOUND)
break;
__seterrno ();
debug_printf ("CreateFile %d %E", GetLastError ());
break;
debug_printf ("NtOpenDirectoryObject %x", status);
return bufptr - destbuf;
}
else
/* Traverse \Device directory ... */
PDIRECTORY_BASIC_INFORMATION dbi = (PDIRECTORY_BASIC_INFORMATION)
alloca (640);
BOOLEAN restart = TRUE;
ULONG context = 0;
while (NT_SUCCESS (NtQueryDirectoryObject (dirhdl, dbi, 640, TRUE, restart,
&context, NULL)))
{
DWORD dwBytesReturned;
restart = FALSE;
sys_wcstombs (devname, CYG_MAX_PATH - 1, dbi->ObjectName.Buffer,
dbi->ObjectName.Length / 2);
/* ... and check for a "Harddisk[0-9]*" entry. */
if (!strncasematch (devname, "Harddisk", 8)
|| dbi->ObjectName.Length < 18
|| !isdigit (devname[8]))
continue;
/* Construct path name for partition 0, which is the whole disk,
and try to open. */
wcscpy (wpath, dbi->ObjectName.Buffer);
wcscpy (wpath + dbi->ObjectName.Length / 2, L"\\Partition0");
upath.Length = 22 + dbi->ObjectName.Length;
upath.MaximumLength = upath.Length + 2;
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
dirhdl, NULL);
status = NtOpenFile (&devhdl, READ_CONTROL | FILE_READ_DATA, &attr, &io,
wincap.shared (), 0);
if (!NT_SUCCESS (status))
{
/* Retry with READ_CONTROL only for non-privileged users. This
at least prints the Partition0 info, but it doesn't allow access
to the drive's layout information. It beats me, though, why
a non-privileged user shouldn't get read access to the drive
layout information. */
status = NtOpenFile (&devhdl, READ_CONTROL, &attr, &io,
wincap.shared (), 0);
if (!NT_SUCCESS (status))
{
debug_printf ("NtOpenFile(%s) %x", devname, status);
continue;
}
}
/* Use a buffer since some ioctl buffers aren't fixed size. */
char buf[256];
PARTITION_INFORMATION *pi = NULL;
PARTITION_INFORMATION_EX *pix = NULL;
DISK_GEOMETRY *dg = NULL;
unsigned long long drive_size;
DWORD bytes;
unsigned long drive_number = strtoul (devname + 8, NULL, 10);
unsigned long long size;
if (wincap.has_disk_ex_ioctls ()
&& DeviceIoControl (hDevice, IOCTL_DISK_GET_PARTITION_INFO_EX,
NULL, 0, buf, 256, &dwBytesReturned,
NULL))
&& DeviceIoControl (devhdl, IOCTL_DISK_GET_PARTITION_INFO_EX,
NULL, 0, buf, 256, &bytes, NULL))
{
pix = (PARTITION_INFORMATION_EX *) buf;
drive_size = pix->PartitionLength.QuadPart;
size = pix->PartitionLength.QuadPart;
}
else if (DeviceIoControl (hDevice, IOCTL_DISK_GET_PARTITION_INFO,
NULL, 0, buf, 256, &dwBytesReturned,
NULL))
else if (DeviceIoControl (devhdl, IOCTL_DISK_GET_PARTITION_INFO,
NULL, 0, buf, 256, &bytes, NULL))
{
pi = (PARTITION_INFORMATION *) buf;
drive_size = pi->PartitionLength.QuadPart;
size = pi->PartitionLength.QuadPart;
}
else if (DeviceIoControl (hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL, 0, buf, 256, &dwBytesReturned,
NULL))
else if (DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL, 0, buf, 256, &bytes, NULL))
{
dg = (DISK_GEOMETRY *) buf;
drive_size = (unsigned long long) dg->Cylinders.QuadPart
size = (unsigned long long) dg->Cylinders.QuadPart
* dg->TracksPerCylinder
* dg->SectorsPerTrack
* dg->BytesPerSector;
}
else
drive_size = 0;
size = 0;
if (!pi && !pix && !dg)
debug_printf ("DeviceIoControl %E");
else
@ -1015,19 +1057,15 @@ format_proc_partitions (char *destbuf, size_t maxsize)
dev.parsedisk (drive_number, 0);
bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s\n",
dev.major, dev.minor,
drive_size >> 10,
dev.name + 5);
size >> 10, dev.name + 5);
}
size_t buf_size = 8192;
DWORD rc;
while (1)
while (true)
{
char buf[buf_size];
memset (buf, 0, buf_size);
rc = DeviceIoControl (hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT,
if (DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL, 0, (DRIVE_LAYOUT_INFORMATION *) buf,
buf_size, &dwBytesReturned, NULL);
if (rc)
buf_size, &bytes, NULL))
/* fall through */;
else if (GetLastError () == ERROR_INSUFFICIENT_BUFFER)
{
@ -1040,30 +1078,25 @@ format_proc_partitions (char *destbuf, size_t maxsize)
break;
}
DRIVE_LAYOUT_INFORMATION *dli = (DRIVE_LAYOUT_INFORMATION *) buf;
for (unsigned partition = 0; partition < dli->PartitionCount; partition++)
for (unsigned part = 0; part < dli->PartitionCount; part++)
{
if (!dli->PartitionEntry[partition].PartitionLength.QuadPart
|| !dli->PartitionEntry[partition].RecognizedPartition)
if (!dli->PartitionEntry[part].PartitionLength.QuadPart
|| !dli->PartitionEntry[part].RecognizedPartition)
continue;
device dev;
dev.parsedisk (drive_number, dli->PartitionEntry[partition].PartitionNumber);
dev.parsedisk (drive_number,
dli->PartitionEntry[part].PartitionNumber);
size = dli->PartitionEntry[part].PartitionLength.QuadPart >> 10;
bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s\n",
dev.major, dev.minor,
(long long)(dli->PartitionEntry[partition].PartitionLength.QuadPart >> 10),
dev.name + 5);
size, dev.name + 5);
}
break;
}
CloseHandle (hDevice);
}
}
}
else
{
// not worth the effort
// you need a 16 bit thunk DLL to access the partition table on Win9x
// and then you have to decode it yourself
NtClose (devhdl);
}
NtClose (dirhdl);
return bufptr - destbuf;
}

View File

@ -116,6 +116,8 @@ typedef struct _FILE_ID_BOTH_DIR_INFORMATION
#define LOCK_VM_IN_WSL 1
#define LOCK_VM_IN_RAM 2
#define DIRECTORY_QUERY 1
typedef ULONG KAFFINITY;
typedef enum _SYSTEM_INFORMATION_CLASS
@ -552,10 +554,17 @@ typedef struct _OBJECT_NAME_INFORMATION
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION;
typedef struct _DIRECTORY_BASIC_INFORMATION
{
UNICODE_STRING ObjectName;
UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;
/* Function declarations for ntdll.dll. These don't appear in any
standard Win32 header. */
extern "C"
{
NTSTATUS NTAPI NtClose (HANDLE);
NTSTATUS NTAPI NtCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,
ULONG, ULONG, PVOID, ULONG);
@ -570,9 +579,17 @@ extern "C"
NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG,
PLARGE_INTEGER, PULONG, SECTION_INHERIT,
ULONG, ULONG);
NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK,
POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG);
NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtQueryDirectoryFile(HANDLE, HANDLE, PVOID, PVOID,
PIO_STATUS_BLOCK, PVOID, ULONG,
FILE_INFORMATION_CLASS, BOOLEAN,
PUNICODE_STRING, BOOLEAN);
NTSTATUS NTAPI NtQueryDirectoryObject (HANDLE, PVOID, ULONG, BOOLEAN,
BOOLEAN, PULONG, PULONG);
NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
ULONG, FILE_INFORMATION_CLASS);
NTSTATUS NTAPI NtQueryInformationProcess (HANDLE, PROCESSINFOCLASS,
@ -593,10 +610,6 @@ extern "C"
NTSTATUS NTAPI NtUnlockVirtualMemory (HANDLE, PVOID *, ULONG *, ULONG);
NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID);
VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
ULONG NTAPI RtlIsDosDeviceName_U (PCWSTR);
ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
ULONG WINAPI RtlIsDosDeviceName_U (PCWSTR);
NTSTATUS NTAPI NtQueryDirectoryFile(HANDLE, HANDLE, PVOID, PVOID, PIO_STATUS_BLOCK,
PVOID, ULONG, FILE_INFORMATION_CLASS, BOOLEAN,
PUNICODE_STRING, BOOLEAN);
NTSTATUS NTAPI NtClose (HANDLE);
}