* ntdll.h (NtNotifyChangeDirectoryFile): Declare.

(NtQueryAttributesFile): Move to maintain alphabetical order of
	declarations.  Add comment to note that timestamp information returned
	by NtQueryAttributesFile is unreliable.
	* path.h (etc::changed_h): Move here.
	(etc::fn): Change type to OBJECT_ATTRIBUTES.
	(etc::last_modified): Change type to LARGE_INTEGER.
	(etc::init): Take PUNICODE_STRING as second argument.
	* path.cc: Accomodate above changes.
	(etc::test_file_change): Use NT native functions.
	(etc::dir_changed): Ditto.
	* uinfo.cc (pwdgrp::load): Call etc::init with NT native path.
This commit is contained in:
Corinna Vinschen 2007-08-21 12:37:40 +00:00
parent 66e36b7987
commit 1b61bf152b
5 changed files with 91 additions and 29 deletions

View File

@ -1,3 +1,18 @@
2007-08-21 Corinna Vinschen <corinna@vinschen.de>
* ntdll.h (NtNotifyChangeDirectoryFile): Declare.
(NtQueryAttributesFile): Move to maintain alphabetical order of
declarations. Add comment to note that timestamp information returned
by NtQueryAttributesFile is unreliable.
* path.h (etc::changed_h): Move here.
(etc::fn): Change type to OBJECT_ATTRIBUTES.
(etc::last_modified): Change type to LARGE_INTEGER.
(etc::init): Take PUNICODE_STRING as second argument.
* path.cc: Accomodate above changes.
(etc::test_file_change): Use NT native functions.
(etc::dir_changed): Ditto.
* uinfo.cc (pwdgrp::load): Call etc::init with NT native path.
2007-08-21 Corinna Vinschen <corinna@vinschen.de> 2007-08-21 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc: Change debugging output througout to print * fhandler_disk_file.cc: Change debugging output througout to print

View File

@ -779,11 +779,19 @@ extern "C"
NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG, NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG,
PLARGE_INTEGER, PULONG, SECTION_INHERIT, PLARGE_INTEGER, PULONG, SECTION_INHERIT,
ULONG, ULONG); ULONG, ULONG);
NTSTATUS NTAPI NtNotifyChangeDirectoryFile (HANDLE, HANDLE, PIO_APC_ROUTINE,
PVOID, PIO_STATUS_BLOCK,
PFILE_NOTIFY_INFORMATION, ULONG,
ULONG, BOOLEAN);
NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK, NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK,
POBJECT_ATTRIBUTES); POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG); PIO_STATUS_BLOCK, ULONG, ULONG);
NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES); NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
/* WARNING! Don't rely on the timestamp information returned by
NtQueryAttributesFile. Only the DOS file attribute info is reliable. */
NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
PFILE_BASIC_INFORMATION);
NTSTATUS NTAPI NtQueryDirectoryFile(HANDLE, HANDLE, PVOID, PVOID, NTSTATUS NTAPI NtQueryDirectoryFile(HANDLE, HANDLE, PVOID, PVOID,
PIO_STATUS_BLOCK, PVOID, ULONG, PIO_STATUS_BLOCK, PVOID, ULONG,
FILE_INFORMATION_CLASS, BOOLEAN, FILE_INFORMATION_CLASS, BOOLEAN,
@ -792,8 +800,6 @@ extern "C"
BOOLEAN, PULONG, PULONG); BOOLEAN, PULONG, PULONG);
NTSTATUS NTAPI NtQueryEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, NTSTATUS NTAPI NtQueryEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN); BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN);
NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
PFILE_BASIC_INFORMATION);
NTSTATUS NTAPI NtQueryFullAttributesFile (POBJECT_ATTRIBUTES, NTSTATUS NTAPI NtQueryFullAttributesFile (POBJECT_ATTRIBUTES,
PFILE_NETWORK_OPEN_INFORMATION); PFILE_NETWORK_OPEN_INFORMATION);
NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,

View File

@ -4456,11 +4456,11 @@ out:
int etc::curr_ix = 0; int etc::curr_ix = 0;
/* Note that the first elements of the below arrays are unused */ /* Note that the first elements of the below arrays are unused */
bool etc::change_possible[MAX_ETC_FILES + 1]; bool etc::change_possible[MAX_ETC_FILES + 1];
const char *etc::fn[MAX_ETC_FILES + 1]; OBJECT_ATTRIBUTES etc::fn[MAX_ETC_FILES + 1];
FILETIME etc::last_modified[MAX_ETC_FILES + 1]; LARGE_INTEGER etc::last_modified[MAX_ETC_FILES + 1];
int int
etc::init (int n, const char *etc_fn) etc::init (int n, PUNICODE_STRING etc_fn)
{ {
if (n > 0) if (n > 0)
/* ok */; /* ok */;
@ -4469,35 +4469,36 @@ etc::init (int n, const char *etc_fn)
else else
api_fatal ("internal error"); api_fatal ("internal error");
fn[n] = etc_fn; InitializeObjectAttributes (&fn[n], etc_fn, OBJ_CASE_INSENSITIVE, NULL, NULL);
change_possible[n] = false; change_possible[n] = false;
test_file_change (n); test_file_change (n);
paranoid_printf ("fn[%d] %s, curr_ix %d", n, fn[n], curr_ix); paranoid_printf ("fn[%d] %S, curr_ix %d", n, fn[n].ObjectName, curr_ix);
return n; return n;
} }
bool bool
etc::test_file_change (int n) etc::test_file_change (int n)
{ {
HANDLE h; NTSTATUS status;
WIN32_FIND_DATA data; FILE_NETWORK_OPEN_INFORMATION fnoi;
bool res; bool res;
if ((h = FindFirstFile (fn[n], &data)) == INVALID_HANDLE_VALUE) status = NtQueryFullAttributesFile (&fn[n], &fnoi);
if (!NT_SUCCESS (status))
{ {
res = true; res = true;
memset (last_modified + n, 0, sizeof (last_modified[n])); memset (last_modified + n, 0, sizeof (last_modified[n]));
debug_printf ("FindFirstFile failed, %E"); debug_printf ("NtQueryFullAttributesFile (%S) failed, %p",
fn[n].ObjectName, status);
} }
else else
{ {
FindClose (h); res = CompareFileTime ((FILETIME *) &fnoi.LastWriteTime,
res = CompareFileTime (&data.ftLastWriteTime, last_modified + n) > 0; (FILETIME *) last_modified + n) > 0;
last_modified[n] = data.ftLastWriteTime; last_modified[n].QuadPart = fnoi.LastWriteTime.QuadPart;
debug_printf ("FindFirstFile succeeded");
} }
paranoid_printf ("fn[%d] %s res %d", n, fn[n], res); paranoid_printf ("fn[%d] %S res %d", n, fn[n].ObjectName, res);
return res; return res;
} }
@ -4507,17 +4508,42 @@ etc::dir_changed (int n)
if (!change_possible[n]) if (!change_possible[n])
{ {
static HANDLE changed_h NO_COPY; static HANDLE changed_h NO_COPY;
NTSTATUS status;
IO_STATUS_BLOCK io;
if (!changed_h) if (!changed_h)
{ {
path_conv pwd ("/etc"); OBJECT_ATTRIBUTES attr;
changed_h = FindFirstChangeNotification (pwd.get_win32 (), FALSE,
FILE_NOTIFY_CHANGE_LAST_WRITE path_conv dir ("/etc");
| FILE_NOTIFY_CHANGE_FILE_NAME); status = NtOpenFile (&changed_h, SYNCHRONIZE | FILE_LIST_DIRECTORY,
dir.get_object_attr (attr, sec_none_nih), &io,
FILE_SHARE_VALID_FLAGS, FILE_DIRECTORY_FILE);
if (!NT_SUCCESS (status))
{
#ifdef DEBUGGING #ifdef DEBUGGING
if (changed_h == INVALID_HANDLE_VALUE) system_printf ("NtOpenFile (%S) failed, %p",
system_printf ("Can't open %s for checking, %E", (char *) pwd); dir.get_nt_native_path (), status);
#endif #endif
changed_h = INVALID_HANDLE_VALUE;
}
else
{
status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL,
NULL, &io, NULL, 0,
FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_FILE_NAME,
FALSE);
if (!NT_SUCCESS (status))
{
#ifdef DEBUGGING
system_printf ("NtNotifyChangeDirectoryFile (1) failed, %p",
status);
#endif
NtClose (changed_h);
changed_h = INVALID_HANDLE_VALUE;
}
}
memset (change_possible, true, sizeof (change_possible)); memset (change_possible, true, sizeof (change_possible));
} }
@ -4525,12 +4551,26 @@ etc::dir_changed (int n)
change_possible[n] = true; change_possible[n] = true;
else if (WaitForSingleObject (changed_h, 0) == WAIT_OBJECT_0) else if (WaitForSingleObject (changed_h, 0) == WAIT_OBJECT_0)
{ {
FindNextChangeNotification (changed_h); status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL,
NULL, &io, NULL, 0,
FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_FILE_NAME,
FALSE);
if (!NT_SUCCESS (status))
{
#ifdef DEBUGGING
system_printf ("NtNotifyChangeDirectoryFile (2) failed, %p",
status);
#endif
NtClose (changed_h);
changed_h = INVALID_HANDLE_VALUE;
}
memset (change_possible, true, sizeof change_possible); memset (change_possible, true, sizeof change_possible);
} }
} }
paranoid_printf ("fn[%d] %s change_possible %d", n, fn[n], change_possible[n]); paranoid_printf ("fn[%d] %S change_possible %d",
n, fn[n].ObjectName, change_possible[n]);
return change_possible[n]; return change_possible[n];
} }
@ -4541,7 +4581,7 @@ etc::file_changed (int n)
if (dir_changed (n) && test_file_change (n)) if (dir_changed (n) && test_file_change (n))
res = true; res = true;
change_possible[n] = false; /* Change is no longer possible */ change_possible[n] = false; /* Change is no longer possible */
paranoid_printf ("fn[%d] %s res %d", n, fn[n], res); paranoid_printf ("fn[%d] %S res %d", n, fn[n].ObjectName, res);
return res; return res;
} }

View File

@ -336,11 +336,12 @@ class etc
{ {
friend class dtable; friend class dtable;
static int curr_ix; static int curr_ix;
static HANDLE changed_h;
static bool change_possible[MAX_ETC_FILES + 1]; static bool change_possible[MAX_ETC_FILES + 1];
static const char *fn[MAX_ETC_FILES + 1]; static OBJECT_ATTRIBUTES fn[MAX_ETC_FILES + 1];
static FILETIME last_modified[MAX_ETC_FILES + 1]; static LARGE_INTEGER last_modified[MAX_ETC_FILES + 1];
static bool dir_changed (int); static bool dir_changed (int);
static int init (int, const char *); static int init (int, PUNICODE_STRING);
static bool file_changed (int); static bool file_changed (int);
static bool test_file_change (int); static bool test_file_change (int);
friend class pwdgrp; friend class pwdgrp;

View File

@ -518,7 +518,7 @@ pwdgrp::load (const char *posix_fname)
curr_lines = 0; curr_lines = 0;
pc.check (posix_fname); pc.check (posix_fname);
etc_ix = etc::init (etc_ix, pc.get_win32 ()); etc_ix = etc::init (etc_ix, pc.get_nt_native_path ());
paranoid_printf ("%s", posix_fname); paranoid_printf ("%s", posix_fname);