Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

rtnotify.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1992 Microsoft Corporation 00004 00005 Module Name: 00006 00007 rtnotify.c 00008 00009 Abstract: 00010 00011 NT level registry test program, basic non-error paths. 00012 00013 Wait for notification. 00014 00015 This program tests waiting for notification on a change to 00016 a registry node. It can wait synchronously, for an event, 00017 for for an Apc. It can use any filter. 00018 00019 Only the first letter of option control are significant. 00020 00021 rtnotify <keyname> {key|tree|event|Apc|hold|name|write|security|prop|*} 00022 00023 key = key only [default] (last of these two wins) 00024 tree = subtree 00025 00026 event = wait on an event (overrides hold) 00027 Apc = use an Apc (overrides hold) 00028 hold = be synchronous [default] (overrides event and Apc) 00029 00030 name = watch for create/delete of children 00031 write = last set change 00032 security = acl change 00033 prop = any attr == security change 00034 * = all 00035 00036 00037 00038 Example: 00039 00040 rtflush \REGISTRY\MACHINE\TEST\bigkey 00041 00042 Author: 00043 00044 Bryan Willman (bryanwi) 10-Jan-92 00045 00046 Revision History: 00047 00048 --*/ 00049 00050 #include "cmp.h" 00051 #include <stdio.h> 00052 #include <stdlib.h> 00053 #include <string.h> 00054 00055 #define WORK_SIZE 1024 00056 00057 void main(); 00058 void processargs(); 00059 00060 ULONG CallCount = 0L; 00061 00062 VOID 00063 ApcTest( 00064 PVOID ApcContext, 00065 PIO_STATUS_BLOCK IoStatusBlock 00066 ); 00067 00068 UNICODE_STRING KeyName; 00069 WCHAR workbuffer[WORK_SIZE]; 00070 BOOLEAN WatchTree; 00071 BOOLEAN UseEvent; 00072 BOOLEAN UseApc; 00073 BOOLEAN ApcSeen; 00074 BOOLEAN Hold; 00075 BOOLEAN Filter; 00076 IO_STATUS_BLOCK RtIoStatusBlock; 00077 00078 00079 void 00080 main( 00081 int argc, 00082 char *argv[] 00083 ) 00084 { 00085 NTSTATUS status; 00086 OBJECT_ATTRIBUTES ObjectAttributes; 00087 HANDLE BaseHandle; 00088 HANDLE EventHandle; 00089 PIO_APC_ROUTINE ApcRoutine; 00090 00091 // 00092 // Process args 00093 // 00094 00095 KeyName.MaximumLength = WORK_SIZE; 00096 KeyName.Length = 0L; 00097 KeyName.Buffer = &(workbuffer[0]); 00098 00099 processargs(argc, argv); 00100 00101 // 00102 // Set up and open KeyPath 00103 // 00104 00105 printf("rtnotify: starting\n"); 00106 00107 InitializeObjectAttributes( 00108 &ObjectAttributes, 00109 &KeyName, 00110 0, 00111 (HANDLE)NULL, 00112 NULL 00113 ); 00114 ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; 00115 00116 status = NtOpenKey( 00117 &BaseHandle, 00118 KEY_NOTIFY, 00119 &ObjectAttributes 00120 ); 00121 if (!NT_SUCCESS(status)) { 00122 printf("rtnotify: t0: %08lx\n", status); 00123 exit(1); 00124 } 00125 00126 EventHandle = (HANDLE)NULL; 00127 if (UseEvent == TRUE) { 00128 status = NtCreateEvent( 00129 &EventHandle, 00130 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 00131 NULL, 00132 NotificationEvent, 00133 FALSE 00134 ); 00135 if (!NT_SUCCESS(status)) { 00136 printf("rtnotify: t1: %08lx\n", status); 00137 exit(1); 00138 } 00139 } 00140 00141 ApcRoutine = NULL; 00142 if (UseApc) { 00143 ApcRoutine = ApcTest; 00144 } 00145 00146 printf("rtnotify:\n"); 00147 printf("\tUseEvent = %08lx\n", UseEvent); 00148 printf("\tApcRoutine = %08lx\n", ApcRoutine); 00149 printf("\tHold = %08lx\n", Hold); 00150 printf("\tFilter = %08lx\n", Filter); 00151 printf("\tWatchTree = %08lx\n", WatchTree); 00152 00153 while (TRUE) { 00154 ApcSeen = FALSE; 00155 printf("\nCallCount = %dt\n", CallCount); 00156 CallCount++; 00157 status = NtNotifyChangeKey( 00158 BaseHandle, 00159 EventHandle, 00160 ApcRoutine, 00161 (PVOID)1992, // arbitrary context value 00162 &RtIoStatusBlock, 00163 Filter, 00164 WatchTree, 00165 NULL, 00166 0, 00167 ! Hold 00168 ); 00169 00170 exit(0); 00171 00172 if ( ! NT_SUCCESS(status)) { 00173 printf("rtnotify: t2: %08lx\n", status); 00174 exit(1); 00175 } 00176 00177 if (Hold) { 00178 printf("rtnotify: Synchronous Status = %08lx\n", RtIoStatusBlock.Status); 00179 } 00180 00181 if (UseEvent) { 00182 status = NtWaitForSingleObject( 00183 EventHandle, 00184 TRUE, 00185 NULL 00186 ); 00187 if (!NT_SUCCESS(status)) { 00188 printf("rtnotify: t3: status = %08lx\n", status); 00189 exit(1); 00190 } 00191 printf("rtnotify: Event Status = %08lx\n", RtIoStatusBlock.Status); 00192 } 00193 00194 if (UseApc) { 00195 while ((volatile)ApcSeen == FALSE) { 00196 NtTestAlert(); 00197 } 00198 } 00199 } 00200 00201 NtClose(BaseHandle); 00202 exit(0); 00203 } 00204 00205 00206 VOID 00207 ApcTest( 00208 PVOID ApcContext, 00209 PIO_STATUS_BLOCK IoStatusBlock 00210 ) 00211 { 00212 ApcSeen = TRUE; 00213 00214 if (ApcContext != (PVOID)1992) { 00215 printf("rtnotify: Apc: Apccontext is wrong %08lx\n", ApcContext); 00216 exit(1); 00217 } 00218 if (IoStatusBlock != &RtIoStatusBlock) { 00219 printf("rtnotify: Apc: IoStatusBlock is wrong %08ln", IoStatusBlock); 00220 exit(1); 00221 } 00222 00223 00224 printf("rtnotify: Apc status = %08lx\n", IoStatusBlock->Status); 00225 return; 00226 } 00227 00228 00229 void 00230 processargs( 00231 int argc, 00232 char *argv[] 00233 ) 00234 { 00235 ANSI_STRING temp; 00236 ULONG i; 00237 00238 if (argc < 2) { 00239 goto Usage; 00240 } 00241 00242 // 00243 // name 00244 // 00245 RtlInitAnsiString( 00246 &temp, 00247 argv[1] 00248 ); 00249 00250 RtlAnsiStringToUnicodeString( 00251 &KeyName, 00252 &temp, 00253 FALSE 00254 ); 00255 00256 WatchTree = FALSE; 00257 UseEvent = FALSE; 00258 UseApc = FALSE; 00259 Hold = TRUE; 00260 Filter = 0; 00261 00262 // 00263 // switches 00264 // 00265 for (i = 2; i < (ULONG)argc; i++) { 00266 switch (*argv[i]) { 00267 00268 case 'a': // Apc 00269 case 'A': 00270 Hold = FALSE; 00271 UseApc = TRUE; 00272 break; 00273 00274 case 'e': // event 00275 case 'E': 00276 Hold = FALSE; 00277 UseEvent = TRUE; 00278 break; 00279 00280 case 'h': // hold 00281 case 'H': 00282 UseApc = FALSE; 00283 UseEvent = FALSE; 00284 Hold = TRUE; 00285 break; 00286 00287 case 'k': // key only 00288 case 'K': 00289 WatchTree = FALSE; 00290 break; 00291 00292 case 'n': 00293 case 'N': 00294 Filter |= REG_NOTIFY_CHANGE_NAME; 00295 break; 00296 00297 case 'p': 00298 case 'P': 00299 Filter |= REG_NOTIFY_CHANGE_ATTRIBUTES; 00300 break; 00301 00302 case 's': 00303 case 'S': 00304 Filter |= REG_NOTIFY_CHANGE_SECURITY; 00305 break; 00306 00307 case 't': // subtree 00308 case 'T': 00309 WatchTree = TRUE; 00310 break; 00311 00312 case 'w': 00313 case 'W': 00314 Filter |= REG_NOTIFY_CHANGE_LAST_SET; 00315 break; 00316 00317 case '*': 00318 Filter = REG_LEGAL_CHANGE_FILTER; 00319 break; 00320 00321 default: 00322 goto Usage; 00323 break; 00324 } 00325 } 00326 if (Filter == 0) { 00327 Filter = REG_LEGAL_CHANGE_FILTER; 00328 } 00329 return; 00330 00331 Usage: 00332 printf("Usage: %s <KeyPath> {key|tree|event|Apc|sync|name|write|security|attribute|*}\n", 00333 argv[0]); 00334 exit(1); 00335 } 00336 

Generated on Sat May 15 19:41:41 2004 for test by doxygen 1.3.7