NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG, ULONG,
PLARGE_INTEGER, PULONG, SECTION_INHERIT,
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,
POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG);
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,
PIO_STATUS_BLOCK, PVOID, ULONG,
FILE_INFORMATION_CLASS, BOOLEAN,
BOOLEAN, PULONG, PULONG);
NTSTATUS NTAPI NtQueryEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN);
- NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
- PFILE_BASIC_INFORMATION);
NTSTATUS NTAPI NtQueryFullAttributesFile (POBJECT_ATTRIBUTES,
PFILE_NETWORK_OPEN_INFORMATION);
NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
int etc::curr_ix = 0;
/* Note that the first elements of the below arrays are unused */
bool etc::change_possible[MAX_ETC_FILES + 1];
-const char *etc::fn[MAX_ETC_FILES + 1];
-FILETIME etc::last_modified[MAX_ETC_FILES + 1];
+OBJECT_ATTRIBUTES etc::fn[MAX_ETC_FILES + 1];
+LARGE_INTEGER etc::last_modified[MAX_ETC_FILES + 1];
int
-etc::init (int n, const char *etc_fn)
+etc::init (int n, PUNICODE_STRING etc_fn)
{
if (n > 0)
/* ok */;
else
api_fatal ("internal error");
- fn[n] = etc_fn;
+ InitializeObjectAttributes (&fn[n], etc_fn, OBJ_CASE_INSENSITIVE, NULL, NULL);
change_possible[n] = false;
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;
}
bool
etc::test_file_change (int n)
{
- HANDLE h;
- WIN32_FIND_DATA data;
+ NTSTATUS status;
+ FILE_NETWORK_OPEN_INFORMATION fnoi;
bool res;
- if ((h = FindFirstFile (fn[n], &data)) == INVALID_HANDLE_VALUE)
+ status = NtQueryFullAttributesFile (&fn[n], &fnoi);
+ if (!NT_SUCCESS (status))
{
res = true;
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
{
- FindClose (h);
- res = CompareFileTime (&data.ftLastWriteTime, last_modified + n) > 0;
- last_modified[n] = data.ftLastWriteTime;
- debug_printf ("FindFirstFile succeeded");
+ res = CompareFileTime ((FILETIME *) &fnoi.LastWriteTime,
+ (FILETIME *) last_modified + n) > 0;
+ last_modified[n].QuadPart = fnoi.LastWriteTime.QuadPart;
}
- 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;
}
if (!change_possible[n])
{
static HANDLE changed_h NO_COPY;
+ NTSTATUS status;
+ IO_STATUS_BLOCK io;
if (!changed_h)
{
- path_conv pwd ("/etc");
- changed_h = FindFirstChangeNotification (pwd.get_win32 (), FALSE,
- FILE_NOTIFY_CHANGE_LAST_WRITE
- | FILE_NOTIFY_CHANGE_FILE_NAME);
+ OBJECT_ATTRIBUTES attr;
+
+ path_conv dir ("/etc");
+ 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
+ system_printf ("NtOpenFile (%S) failed, %p",
+ dir.get_nt_native_path (), status);
+#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
- if (changed_h == INVALID_HANDLE_VALUE)
- system_printf ("Can't open %s for checking, %E", (char *) pwd);
+ system_printf ("NtNotifyChangeDirectoryFile (1) failed, %p",
+ status);
#endif
+ NtClose (changed_h);
+ changed_h = INVALID_HANDLE_VALUE;
+ }
+ }
memset (change_possible, true, sizeof (change_possible));
}
change_possible[n] = true;
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);
}
}
- 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];
}
if (dir_changed (n) && test_file_change (n))
res = true;
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;
}