reactos/dll/win32/kernel32/file/cnotify.c
Sylvain Petreolle e2b7eacdd5 [CMAKE]
Sync trunk up to r50477.

svn path=/branches/cmake-bringup/; revision=50504
2011-01-26 22:19:12 +00:00

256 lines
5.4 KiB
C

/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/find.c
* PURPOSE: Find functions
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
* UPDATE HISTORY:
* Created 01/11/98
*/
#include <k32.h>
#define NDEBUG
#include <debug.h>
/*
* @implemented
*/
BOOL WINAPI
FindCloseChangeNotification (HANDLE hChangeHandle)
{
NTSTATUS Status = NtClose(hChangeHandle);
if(!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
HANDLE
WINAPI
FindFirstChangeNotificationA (
LPCSTR lpPathName,
BOOL bWatchSubtree,
DWORD dwNotifyFilter
)
{
PWCHAR PathNameW;
if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
return INVALID_HANDLE_VALUE;
return FindFirstChangeNotificationW (PathNameW ,
bWatchSubtree,
dwNotifyFilter);
}
/*
* @implemented
*/
HANDLE
WINAPI
FindFirstChangeNotificationW (
LPCWSTR lpPathName,
BOOL bWatchSubtree,
DWORD dwNotifyFilter
)
{
NTSTATUS Status;
UNICODE_STRING NtPathU;
IO_STATUS_BLOCK IoStatus;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hDir;
if (!RtlDosPathNameToNtPathName_U (lpPathName,
&NtPathU,
NULL,
NULL))
{
SetLastErrorByStatus(STATUS_OBJECT_PATH_SYNTAX_BAD);
return INVALID_HANDLE_VALUE;
}
InitializeObjectAttributes (&ObjectAttributes,
&NtPathU,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtOpenFile (&hDir,
SYNCHRONIZE|FILE_LIST_DIRECTORY,
&ObjectAttributes,
&IoStatus,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT);
RtlFreeHeap(RtlGetProcessHeap(),
0,
NtPathU.Buffer);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
Status = NtNotifyChangeDirectoryFile(hDir,
NULL,
NULL,
NULL,
&IoStatus,
NULL,//Buffer,
0,//BufferLength,
dwNotifyFilter,
(BOOLEAN)bWatchSubtree);
if (!NT_SUCCESS(Status))
{
NtClose(hDir);
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
return hDir;
}
/*
* @implemented
*/
BOOL
WINAPI
FindNextChangeNotification (
HANDLE hChangeHandle
)
{
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
Status = NtNotifyChangeDirectoryFile(hChangeHandle,
NULL,
NULL,
NULL,
&IoStatus,
NULL,//Buffer,
0,//BufferLength,
FILE_NOTIFY_CHANGE_SECURITY,//meaningless/ignored for subsequent calls, but must contain a valid flag
0 //meaningless/ignored for subsequent calls
);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
extern VOID
(WINAPI ApcRoutine)(PVOID ApcContext,
struct _IO_STATUS_BLOCK* IoStatusBlock,
ULONG Reserved);
/*
* @implemented
*/
BOOL
WINAPI
ReadDirectoryChangesW(
HANDLE hDirectory,
LPVOID lpBuffer OPTIONAL,
DWORD nBufferLength,
BOOL bWatchSubtree,
DWORD dwNotifyFilter,
LPDWORD lpBytesReturned, /* undefined for asych. operations */
LPOVERLAPPED lpOverlapped OPTIONAL,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine /* OPTIONAL???????? */
)
{
PVOID CompletionRoutine;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
HANDLE EventHandle;
PIO_APC_ROUTINE IoApcRoutine;
if (lpOverlapped )
{
if (lpCompletionRoutine)
{
CompletionRoutine = (PVOID) lpCompletionRoutine;
EventHandle = NULL;
IoApcRoutine = ApcRoutine;
}
else
{
if (((ULONG_PTR) lpOverlapped->hEvent & 1) == 0)
CompletionRoutine = (PVOID) lpOverlapped;
else
CompletionRoutine = NULL;
EventHandle = lpOverlapped->hEvent;
IoApcRoutine = NULL;
}
lpOverlapped->Internal = STATUS_PENDING;
}
else
{
EventHandle = NULL;
IoApcRoutine = NULL;
CompletionRoutine = NULL;
}
Status = NtNotifyChangeDirectoryFile(
hDirectory,
EventHandle,
IoApcRoutine,
CompletionRoutine, /* ApcContext */
lpOverlapped ? (PIO_STATUS_BLOCK) lpOverlapped : &IoStatus,
lpBuffer,
nBufferLength,
dwNotifyFilter,
(BOOLEAN)bWatchSubtree
);
if ((Status == STATUS_PENDING) && (!lpOverlapped))
{
Status = NtWaitForSingleObject(hDirectory, FALSE, NULL);
if (NT_SUCCESS(Status))
{
Status = IoStatus.Status;
}
}
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
/* NOTE: lpBytesReturned is undefined for asynch. operations */
*lpBytesReturned = IoStatus.Information;
return TRUE;
}
/* EOF */