[ROSTESTS]
[reactos.git] / rostests / win32 / kernel32 / notificationtest / notificationtest.c
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
19 void RefreshDirectory(LPTSTR);
20 void RefreshTree(LPTSTR);
21 void WatchDirectory(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
36 void WatchDirectory(LPTSTR lpDir)
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");
59 ExitProcess(GetLastError());
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");
72 ExitProcess(GetLastError());
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");
81 ExitProcess(GetLastError());
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");
107 ExitProcess(GetLastError());
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");
120 ExitProcess(GetLastError());
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");
136 ExitProcess(GetLastError());
137 break;
138 }
139 }
140 }
141
142 void RefreshDirectory(LPTSTR lpDir)
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 }