mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
6.0 KiB
231 lines
6.0 KiB
/*++
|
|
|
|
Copyright (c) 1991-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Watch.c
|
|
|
|
Abstract:
|
|
|
|
This is a stand-alone test program. It tries the
|
|
NtNotifyChangeDirectoryFile API.
|
|
|
|
Author:
|
|
|
|
Madan Appiah sometime in 1991
|
|
|
|
Environment:
|
|
|
|
Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
|
|
Requires ANSI C extensions: slash-slash comments, long external names.
|
|
|
|
Revision History:
|
|
|
|
??-???-1991 MadanA
|
|
Created.
|
|
28-Nov-1992 JohnRo
|
|
Repl should use filesystem change notify.
|
|
Work with stdcall.
|
|
Added this block of comments.
|
|
Random changes.
|
|
28-Jun-1993 JohnRo
|
|
Allow dir name to be command-line option.
|
|
Work better in free builds.
|
|
28-Jun-1993 JohnRo
|
|
Use WaitForMultipleObjects(), to be just like the replicator service.
|
|
10-Aug-1993 JohnRo
|
|
RAID 17010: Implement per-first-level-directory change notify.
|
|
|
|
--*/
|
|
|
|
|
|
|
|
// These must be included first:
|
|
|
|
#include <windows.h> // LPVOID, etc.
|
|
#include <lmcons.h> // NET_API_STATUS.
|
|
|
|
// These may be included in any order:
|
|
|
|
#include <assert.h> // assert().
|
|
#include <chngnot.h> // ReplSetupChangeNotify, REPL_CHANGE_NOTIFY_HANDLE, etc
|
|
#include <lmapibuf.h> // NetApiBufferFree().
|
|
#include <netdebug.h> // DBGSTATIC, FORMAT_ equates, etc.
|
|
#include <repldefs.h> // ReplGlobalTrace, REPL_DEBUG_ flags.
|
|
#include <stdio.h> // printf(), etc.
|
|
#include <stdlib.h> // EXIT_FAILURE, EXIT_SUCCESS, _CRTAPI1.
|
|
#include <tstring.h> // NetpAlloc{type}from{type} functions.
|
|
#include <winerror.h> // NO_ERROR, ERROR_ equates.
|
|
|
|
|
|
DBGSTATIC VOID
|
|
Usage(
|
|
IN char * ProgName
|
|
)
|
|
{
|
|
assert( ProgName != NULL );
|
|
assert( (*ProgName) != '\0' );
|
|
assert( (*ProgName) != '\n' );
|
|
(VOID) printf(
|
|
"Repl change notify test program...\n"
|
|
"Authors: JR (John Rogers, JohnRo@Microsoft) (modifications)\n"
|
|
" Madan Appiah (MadanA@Microsoft) (original)\n\n"
|
|
"Usage: %s [options] srcPath\n\n"
|
|
"Options:\n"
|
|
" -r recursive (tree extent)\n"
|
|
" -v verbose\n",
|
|
ProgName);
|
|
|
|
} // Usage()
|
|
|
|
|
|
int _CRTAPI1
|
|
main(
|
|
IN int argc,
|
|
IN char *argv[]
|
|
)
|
|
{
|
|
NET_API_STATUS ApiStatus;
|
|
int ArgNumber;
|
|
LPWSTR DirName = NULL;
|
|
BOOL DoTree = FALSE;
|
|
LPREPL_CHANGE_NOTIFY_HANDLE ReplHandle = NULL;
|
|
BOOL Verbose = FALSE;
|
|
HANDLE WaitHandles[1];
|
|
DWORD WaitStatus;
|
|
|
|
|
|
//
|
|
// Process command-line arguments.
|
|
//
|
|
for (ArgNumber = 1; ArgNumber < argc; ArgNumber++) {
|
|
if ((*argv[ArgNumber] == '-') || (*argv[ArgNumber] == '/')) {
|
|
switch (tolower(*(argv[ArgNumber]+1))) // Process switches
|
|
{
|
|
|
|
case 'r' :
|
|
DoTree = TRUE;
|
|
break;
|
|
|
|
case 'v' :
|
|
ReplGlobalTrace = REPL_DEBUG_ALL;
|
|
Verbose = TRUE;
|
|
break;
|
|
|
|
default :
|
|
Usage( argv[0] );
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
|
|
} // switch
|
|
|
|
} else { // not an argument
|
|
|
|
if (DirName != NULL) {
|
|
Usage( argv[0] );
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
DirName = NetpAllocWStrFromStr( argv[ArgNumber] );
|
|
assert( DirName != NULL );
|
|
}
|
|
}
|
|
if (DirName == NULL) {
|
|
Usage( argv[0] );
|
|
ApiStatus = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
//
|
|
// Get ready to watch changes.
|
|
//
|
|
|
|
ApiStatus = ReplSetupChangeNotify(
|
|
(LPCTSTR) DirName,
|
|
DoTree, // TRUE for entire tree
|
|
& ReplHandle );
|
|
(VOID) printf( "watch: got " FORMAT_API_STATUS
|
|
" from ReplSetupChangeNotify.\n", ApiStatus );
|
|
assert( ApiStatus == NO_ERROR );
|
|
|
|
WaitHandles[0] = ReplGetWaitableChangeNotifyHandle( ReplHandle );
|
|
assert( WaitHandles[0] != INVALID_HANDLE_VALUE );
|
|
|
|
//
|
|
// Tell user what's up and how to get out of it.
|
|
//
|
|
|
|
(VOID) printf(
|
|
"This program will loop forever, being notified about each change in\n"
|
|
"'" FORMAT_LPWSTR "'. Press ^C (control-C) to cancel this program.\n",
|
|
DirName );
|
|
|
|
//
|
|
// Loop until we get control-C.
|
|
//
|
|
|
|
while (TRUE) {
|
|
|
|
//
|
|
// Enable this pass...
|
|
//
|
|
|
|
ApiStatus = ReplEnableChangeNotify( ReplHandle );
|
|
(VOID) printf( "watch: got " FORMAT_API_STATUS
|
|
" from ReplEnableChangeNotify.\n", ApiStatus );
|
|
assert( ApiStatus == NO_ERROR );
|
|
|
|
|
|
//
|
|
// OK, now wait for other changes.
|
|
//
|
|
|
|
(VOID) printf( "watch: waiting...\n" );
|
|
|
|
WaitStatus = WaitForMultipleObjects(
|
|
1, // handle count
|
|
WaitHandles,
|
|
FALSE, // don't wait for all handles
|
|
(DWORD) -1); // wait forever...
|
|
|
|
if (Verbose) {
|
|
(VOID) printf( "watch: back from wait.\n" );
|
|
}
|
|
|
|
if (WaitStatus != 0) { // anything but 0 (index of first) is wrong!
|
|
|
|
ApiStatus = GetLastError();
|
|
(VOID) printf(
|
|
"WaitForMultipleObjects failed, returned " FORMAT_DWORD
|
|
", error code is " FORMAT_API_STATUS ".\n",
|
|
WaitStatus, ApiStatus );
|
|
assert( ApiStatus != NO_ERROR );
|
|
goto Cleanup;
|
|
}
|
|
|
|
ApiStatus = ReplGetChangeNotifyStatus( ReplHandle );
|
|
(VOID) printf(
|
|
"watch: after wait, got status " FORMAT_API_STATUS ".\n",
|
|
ApiStatus );
|
|
|
|
} // forever...
|
|
|
|
Cleanup:
|
|
|
|
if (DirName != NULL) {
|
|
(VOID) NetApiBufferFree( DirName );
|
|
}
|
|
|
|
if (ReplHandle != NULL) {
|
|
(VOID) ReplCloseChangeNotify( ReplHandle );
|
|
}
|
|
|
|
if (ApiStatus == NO_ERROR) {
|
|
return (EXIT_SUCCESS);
|
|
} else {
|
|
return (EXIT_FAILURE);
|
|
}
|
|
|
|
} // main()
|