00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
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 = 0
L;
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
00093
00094
00095
KeyName.MaximumLength =
WORK_SIZE;
00096
KeyName.Length = 0
L;
00097
KeyName.Buffer = &(
workbuffer[0]);
00098
00099
processargs(argc, argv);
00100
00101
00102
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,
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
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
00264
00265
for (i = 2; i < (ULONG)argc; i++) {
00266
switch (*argv[i]) {
00267
00268
case 'a':
00269
case 'A':
00270
Hold =
FALSE;
00271
UseApc =
TRUE;
00272
break;
00273
00274
case 'e':
00275
case 'E':
00276
Hold =
FALSE;
00277
UseEvent =
TRUE;
00278
break;
00279
00280
case 'h':
00281
case 'H':
00282
UseApc =
FALSE;
00283
UseEvent =
FALSE;
00284
Hold =
TRUE;
00285
break;
00286
00287
case 'k':
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':
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