* fhandler_proc.cc (format_proc_partitions): Simplify code and enable

partition layout printing for non-privileged users.
This commit is contained in:
Corinna Vinschen 2010-08-26 10:59:13 +00:00
parent ec7bb66c7a
commit 46059af75c
2 changed files with 54 additions and 85 deletions

View File

@ -1,3 +1,8 @@
2010-08-26 Corinna Vinschen <corinna@vinschen.de>
* fhandler_proc.cc (format_proc_partitions): Simplify code and enable
partition layout printing for non-privileged users.
2010-08-25 Corinna Vinschen <corinna@vinschen.de>
* mount.cc (fs_info::update): Fix comments.

View File

@ -1097,31 +1097,28 @@ format_proc_partitions (void *, char *&destbuf)
|| dbi->ObjectName.Length < 18
|| !isdigit (devname[8]))
continue;
/* Construct path name for partition 0, which is the whole disk,
and try to open. */
/* Construct path name for partitions, starting with 0, which is the
whole disk, and try to open. Let's assume we never have more than
99 partitions per disk for now... */
for (int part_num = 0; part_num < 99; ++part_num)
{
wcscpy (wpath, dbi->ObjectName.Buffer);
wcscpy (wpath + dbi->ObjectName.Length / 2, L"\\Partition0");
__small_swprintf (wpath + dbi->ObjectName.Length / 2,
L"\\Partition%d", part_num);
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,
FILE_SHARE_VALID_FLAGS, 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,
FILE_SHARE_VALID_FLAGS, 0);
if (!NT_SUCCESS (status))
{
if (status == STATUS_OBJECT_NAME_NOT_FOUND
|| status == STATUS_OBJECT_PATH_NOT_FOUND)
break;
debug_printf ("NtOpenFile(%s), status %p", devname, status);
continue;
}
}
/* Use a buffer since some ioctl buffers aren't fixed size. */
char buf[256];
@ -1161,47 +1158,14 @@ format_proc_partitions (void *, char *&destbuf)
else
{
device dev;
dev.parsedisk (drive_number, 0);
dev.parsedisk (drive_number, part_num);
bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s\n",
dev.major, dev.minor,
size >> 10, dev.name + 5);
}
size_t buf_size = 8192;
while (true)
{
char buf[buf_size];
if (DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL, 0, (DRIVE_LAYOUT_INFORMATION *) buf,
buf_size, &bytes, NULL))
/* fall through */;
else if (GetLastError () == ERROR_INSUFFICIENT_BUFFER)
{
buf_size *= 2;
continue;
}
else
{
debug_printf ("DeviceIoControl %E");
break;
}
DRIVE_LAYOUT_INFORMATION *dli = (DRIVE_LAYOUT_INFORMATION *) buf;
for (unsigned part = 0; part < dli->PartitionCount; part++)
{
if (!dli->PartitionEntry[part].PartitionLength.QuadPart
|| !dli->PartitionEntry[part].RecognizedPartition)
continue;
device dev;
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,
size, dev.name + 5);
}
break;
}
NtClose (devhdl);
}
}
NtClose (dirhdl);
destbuf = (char *) crealloc_abort (destbuf, bufptr - buf);