ReactOS  0.4.14-dev-57-g333b8f1
notificationtest.c
Go to the documentation of this file.
1 /*
2  * FILE: notificationtest.c
3  * PURPOSE: Files notifications testing
4  * NOTES: MSDN code from: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365261%28v=vs.85%29.aspx
5  */
6 
7 #include <windows.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <tchar.h>
11 
12 #if defined(_tsplitpath) && !defined(_tsplitpath_s)
13 #define _tsplitpath_s(f, d,dl, p,pl, n,nl, e,el) _tsplitpath(f, d, p, n, e)
14 #else
15 #define _wsplitpath_s(f, d,dl, p,pl, n,nl, e,el) _wsplitpath(f, d, p, n, e)
16 #define _splitpath_s(f, d,dl, p,pl, n,nl, e,el) _splitpath(f, d, p, n, e)
17 #endif
18 
20 void RefreshTree(LPTSTR);
22 
23 int _tmain(int argc, TCHAR *argv[])
24 {
25  if(argc != 2)
26  {
27  _tprintf(TEXT("Usage: %s <dir>\n"), argv[0]);
28  return -1;
29  }
30 
31  WatchDirectory(argv[1]);
32 
33  return 0;
34 }
35 
37 {
38  DWORD dwWaitStatus;
39  HANDLE dwChangeHandles[2];
40  TCHAR lpDrive[4];
41  TCHAR lpFile[_MAX_FNAME];
42  TCHAR lpExt[_MAX_EXT];
43 
44  _tsplitpath_s(lpDir, lpDrive, 4, NULL, 0, lpFile, _MAX_FNAME, lpExt, _MAX_EXT);
45 
46  lpDrive[2] = (TCHAR)'\\';
47  lpDrive[3] = (TCHAR)'\0';
48 
49 // Watch the directory for file creation and deletion.
50 
51  dwChangeHandles[0] = FindFirstChangeNotification(
52  lpDir, // directory to watch
53  FALSE, // do not watch subtree
54  FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes
55 
56  if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
57  {
58  printf("\n ERROR: FindFirstChangeNotification function failed.\n");
60  }
61 
62 // Watch the subtree for directory creation and deletion.
63 
64  dwChangeHandles[1] = FindFirstChangeNotification(
65  lpDrive, // directory to watch
66  TRUE, // watch the subtree
67  FILE_NOTIFY_CHANGE_DIR_NAME); // watch dir name changes
68 
69  if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
70  {
71  printf("\n ERROR: FindFirstChangeNotification function failed.\n");
73  }
74 
75 
76 // Make a final validation check on our handles.
77 
78  if ((dwChangeHandles[0] == NULL) || (dwChangeHandles[1] == NULL))
79  {
80  printf("\n ERROR: Unexpected NULL from FindFirstChangeNotification.\n");
82  }
83 
84 // Change notification is set. Now wait on both notification
85 // handles and refresh accordingly.
86 
87  while (TRUE)
88  {
89  // Wait for notification.
90 
91  printf("\nWaiting for notification...\n");
92 
93  dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,
94  FALSE, INFINITE);
95 
96  switch (dwWaitStatus)
97  {
98  case WAIT_OBJECT_0:
99 
100  // A file was created, renamed, or deleted in the directory.
101  // Refresh this directory and restart the notification.
102 
103  RefreshDirectory(lpDir);
104  if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE )
105  {
106  printf("\n ERROR: FindNextChangeNotification function failed.\n");
108  }
109  break;
110 
111  case WAIT_OBJECT_0 + 1:
112 
113  // A directory was created, renamed, or deleted.
114  // Refresh the tree and restart the notification.
115 
116  RefreshTree(lpDrive);
117  if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE )
118  {
119  printf("\n ERROR: FindNextChangeNotification function failed.\n");
121  }
122  break;
123 
124  case WAIT_TIMEOUT:
125 
126  // A timeout occurred, this would happen if some value other
127  // than INFINITE is used in the Wait call and no changes occur.
128  // In a single-threaded environment you might not want an
129  // INFINITE wait.
130 
131  printf("\nNo changes in the timeout period.\n");
132  break;
133 
134  default:
135  printf("\n ERROR: Unhandled dwWaitStatus.\n");
137  break;
138  }
139  }
140 }
141 
143 {
144  // This is where you might place code to refresh your
145  // directory listing, but not the subtree because it
146  // would not be necessary.
147 
148  _tprintf(TEXT("Directory (%s) changed.\n"), lpDir);
149 }
150 
151 void RefreshTree(LPTSTR lpDrive)
152 {
153  // This is where you might place code to refresh your
154  // directory listing, including the subtree.
155 
156  _tprintf(TEXT("Directory tree (%s) changed.\n"), lpDrive);
157 }
static int argc
Definition: ServiceArgs.c:12
#define _tprintf
Definition: tchar.h:506
#define TRUE
Definition: types.h:120
#define _tsplitpath_s
Definition: tchar.h:687
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define FILE_NOTIFY_CHANGE_FILE_NAME
#define argv
Definition: mplay32.c:18
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
#define FILE_NOTIFY_CHANGE_DIR_NAME
#define _MAX_FNAME
Definition: utility.h:74
CHAR * LPTSTR
Definition: xmlstorage.h:192
smooth NULL
Definition: ftsmooth.c:416
char TCHAR
Definition: xmlstorage.h:189
#define WAIT_OBJECT_0
Definition: winbase.h:387
void RefreshDirectory(LPTSTR)
BOOL WINAPI FindNextChangeNotification(IN HANDLE hChangeHandle)
Definition: cnotify.c:223
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_TIMEOUT
Definition: dderror.h:14
void WatchDirectory(LPTSTR)
#define _MAX_EXT
Definition: utility.h:76
int _tmain(int argc, TCHAR *argv[])
#define TEXT(s)
Definition: k32.h:26
void RefreshTree(LPTSTR)
#define INFINITE
Definition: serial.h:102
#define FindFirstChangeNotification
Definition: winbase.h:3598
#define printf
Definition: config.h:203