内核中的注册表操作和Win32下面是没有什么区别的. 最多来说就是函数的名字稍微换了下. 都是一个套路. 所以说学习新东西啊, 都是建立在旧东西的基础之上.而且内核中好像有一些比Win32更加好用的注册表操作函数. 一句话就可以实现很多功能. 真是舒服. 这些东西的话, 其实没有什么好说的,直接上代码吧, 代码能够说明一切.

内核中对注册表也就是那么个操作套路, 增删改查.遍历撒的. 好像很多都是只是换了个名称, 而且本来他们本来就是一个套路, Win32函数调用的时候进入内核也是调用那么些函数. 所以这些东西不需要多说了!!

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
/*
	Windows内核下注册表的操作!
	编译方法参见makefile. TAB = 8
	HKEY_LOCAL_MACHINE	= \\Registry\\Machine
	HKEY_USERS		= \\Registry\\User
	HKEY_CURRENT_CONFIG	= \\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Hardware\\Profiles\\Current
	HKEY_CLASSES_ROOT	= \\Registry\\Machine\\SOFTWARE\\Classes\\
*/
#include <ntddk.h>
#include <ntstrsafe.h>
#define  REG_SOFTWARE_KEY_NAME		L"\\Registry\\Machine\\Software\\JoenRegister"
#define  REG_SOFTWARE_VALUE_NAME	L"SubItem"
//===========================================================================
//创建新键值
#pragma  code_seg( "INIT" )
NTSTATUS CreateNewKey( ) {
	HANDLE		hKey;
	HANDLE		hKey2;
	ULONG		ulResult;
	OBJECT_ATTRIBUTES Obj_Attr;
	NTSTATUS Status;
	UNICODE_STRING UStKeyName = RTL_CONSTANT_STRING( REG_SOFTWARE_KEY_NAME );
	UNICODE_STRING UStValueName = RTL_CONSTANT_STRING( REG_SOFTWARE_VALUE_NAME );
	
	
	InitializeObjectAttributes(&Obj_Attr, &UStKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
	
	//创建或带开注册表项目
	Status = ZwCreateKey( &hKey,KEY_ALL_ACCESS,&Obj_Attr,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult );
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "创建/打开\\Registry\\Machine\\Software\\JoenRegister注册表失败!\n" ));
		return Status;
	}else {
		//判断是被新创建,还是已经被创建
		if( ulResult == REG_CREATED_NEW_KEY ) {
			KdPrint(("创建\\Registry\\Machine\\Software\\JoenRegister键值成功\n"));
		}else if( ulResult == REG_OPENED_EXISTING_KEY )	{
			KdPrint(("打开\\Registry\\Machine\\Software\\JoenRegister键值成功\n"));
		}
	}
	
	//打开一个注册表句柄下的一个子项目
	InitializeObjectAttributes( &Obj_Attr, &UStValueName, OBJ_CASE_INSENSITIVE, hKey, NULL );
	
	//创建/打开一个注册表句柄下的另一个句柄
	Status = ZwCreateKey( &hKey2,KEY_ALL_ACCESS,&Obj_Attr,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult);
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "创建打开子句柄SubItem失败!\n" ));
		return Status;
	}else {
		//判断是被新创建,还是已经被创建
		if( ulResult == REG_CREATED_NEW_KEY ) {
			KdPrint(("创建子句柄SubItem成功\n"));
		}else if( ulResult == REG_OPENED_EXISTING_KEY )	{
			KdPrint(("打开子句柄SubItem成功\n"));
		}
	}
	
	ZwClose( hKey2 );
	ZwClose( hKey );
//----------------------------------------------------------------------------	
	InitializeObjectAttributes( &Obj_Attr, &UStKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );

	//只是打开注册表项目, 如果不存在返回失败
	Status = ZwOpenKey( &hKey,KEY_ALL_ACCESS, &Obj_Attr );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "打开\\Registry\\Machine\\Software\\JoenRegister失败\n" ));
			return Status;
		}else {
			KdPrint(( "打开\\Registry\\Machine\\Software\\JoenRegister成功\n" ));
	}
	ZwClose( hKey );
	return Status;
}
//===========================================================================
//设置键值试验, 设置键值可以覆盖原来的值.
#pragma  code_seg( "INIT" )
NTSTATUS SetKeyValue() {
	HANDLE		hKey = 0;
	ULONG		ulResult;
	ULONG		ulValue;
	NTSTATUS	Status;
	CHAR byArr\[8\]	= {0};
	OBJECT_ATTRIBUTES Obj_Attr;
	UNICODE_STRING UStValueKey = RTL_CONSTANT_STRING( L"Reg_Sz" );
	UNICODE_STRING UStKeyName = RTL_CONSTANT_STRING( REG_SOFTWARE_KEY_NAME );
	InitializeObjectAttributes(&Obj_Attr, &UStKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );

	//创建或带开注册表项目
	Status = ZwCreateKey( &hKey,KEY_ALL_ACCESS,&Obj_Attr,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult );
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "创建/打开\\Registry\\Machine\\Software\\JoenRegister注册表失败!\n" ));
		return Status;
	}else {
		//判断是被新创建,还是已经被创建
		if( ulResult == REG_CREATED_NEW_KEY ) {
			KdPrint(("创建\\Registry\\Machine\\Software\\JoenRegister键值成功\n"));
		}else if( ulResult == REG_OPENED_EXISTING_KEY )	{
			KdPrint(("打开\\Registry\\Machine\\Software\\JoenRegister键值成功\n"));
		}
	}

	do {
		//设置默认键值
		Status = ZwSetValueKey(hKey, (PUNICODE_STRING)byArr, 0,REG_SZ, L"Hello",sizeof(L"hello")+2);
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "设置默认键值失败\n" ));
			break;
		}

		//设置某个键的键值
		Status = ZwSetValueKey(hKey, &UStValueKey, 0, REG_SZ, L"String", sizeof(L"String")+2 );
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "设置Reg_Sz键值失败\n" ));
			break;
		}
		
		//设置某个键的键值 DWORD类型
		ulValue = 100;
		RtlInitUnicodeString(&UStValueKey, L"Reg_Dword" );
		Status = ZwSetValueKey(hKey, &UStValueKey, 0, REG_DWORD, &ulValue, sizeof(ulValue));
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "设置Reg_Sz键值失败\n" ));
			break;
		}
	} while ( FALSE );
	
	if ( hKey ) {
		ZwClose(hKey);
	}
	return Status;
}
//===========================================================================
//查询键值试验, 这个查询键值ZwQueryValueKey 和那个ZwQuery, 注意区分
#pragma  code_seg( "INIT" )
NTSTATUS QueryValueInfo() {
	HANDLE		hKey = 0;
	ULONG		ulResult;
	ULONG		ulSize;
	NTSTATUS	Status;
	OBJECT_ATTRIBUTES Obj_Attr;
	UNICODE_STRING UStValueKey = RTL_CONSTANT_STRING( L"Reg_Dword" );
	UNICODE_STRING UStKeyName = RTL_CONSTANT_STRING( REG_SOFTWARE_KEY_NAME );
	PKEY_VALUE_PARTIAL_INFORMATION pKeyPartialInfo = NULL;

	InitializeObjectAttributes(&Obj_Attr, &UStKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL );
	
	//创建或带开注册表项目
	Status = ZwCreateKey( &hKey,KEY_ALL_ACCESS,&Obj_Attr,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult );
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "创建/打开\\Registry\\Machine\\Software\\JoenRegister注册表失败!\n" ));
		return Status;
	}else {
		//判断是被新创建,还是已经被创建
		if( ulResult == REG_CREATED_NEW_KEY ) {
			KdPrint(("创建\\Registry\\Machine\\Software\\JoenRegister键值成功\n"));
		}else if( ulResult == REG_OPENED_EXISTING_KEY )	{
			KdPrint(("打开\\Registry\\Machine\\Software\\JoenRegister键值成功\n"));
		}
	}
	
	do {
		//读取REG_DWORD子键, 这里只是尝试着搞一下
		Status = ZwQueryValueKey( hKey, &UStValueKey, KeyValuePartialInformation,NULL,0,&ulSize);
		if ( Status == STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0 ) {
			KdPrint(("Reg_Dword子键不存在\n"));
			break;
		}
		
		//分配结构需要的内存
		pKeyPartialInfo = ExAllocatePool(PagedPool,ulSize);
		if ( !pKeyPartialInfo ) {
			KdPrint(( "pKeyPartialInfo内存分配失败\n" ));
			break;
		}
		
		//这次才是真正的查询
		Status = ZwQueryValueKey(hKey, &UStValueKey,KeyValuePartialInformation,
				pKeyPartialInfo,ulSize,&ulSize);
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(("读取Reg_Dword子键失败\n"));
			break;
		}

		//判断是否为REG_DWORD类型
		if (pKeyPartialInfo->Type==REG_DWORD && pKeyPartialInfo->DataLength==sizeof(ULONG))
		{
			KdPrint(("查询子键 Reg_Dword:%d\n", \*((PULONG)pKeyPartialInfo->Data)) );
		}
		
		if ( pKeyPartialInfo ) {
			ExFreePool( pKeyPartialInfo );
			pKeyPartialInfo = NULL;
		}
//---------------------------------------------------------------------------
		RtlInitUnicodeString( &UStValueKey, L"Reg_Sz" );
		//读取REG_SZ子键
		Status = ZwQueryValueKey(hKey,&UStValueKey,KeyValuePartialInformation,NULL,0,&ulSize);
		if ( Status == STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0 ) {
			KdPrint(("Reg_Sz子键不存在!\n"));
			break;
		}
		
		//分配结构需要的内存
		pKeyPartialInfo = ExAllocatePool(PagedPool,ulSize);
		if ( !pKeyPartialInfo ) {
			KdPrint(( "pKeyPartialInfo内存分配失败\n" ));
			break;
		}
		
		//这次才是真正的查询
		Status = ZwQueryValueKey(hKey, &UStValueKey,KeyValuePartialInformation,
			pKeyPartialInfo,ulSize,&ulSize);
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(("读取Reg_Sz子键失败\n"));
			break;
		}

		//判断是否为REG_SZ类型
		if (pKeyPartialInfo->Type==REG_SZ ){
			KdPrint(("Reg_Sz值为:%ws\n",pKeyPartialInfo->Data) );
		}
	} while ( FALSE );
//---------------------------------------------------------------------------
	if ( hKey ) {
		ZwClose(hKey);
	}
	if ( pKeyPartialInfo ) {
		ExFreePool( pKeyPartialInfo );
	}
	return Status;
}
//===========================================================================
//枚举子项中的键值, 键值哈. 
//pUSzRegPath	:要枚举的子项目名称
#pragma  code_seg( "INIT" )
VOID EnumerateSubValue( const PUNICODE_STRING pUSzRegPath ) {
	HANDLE		hKey = 0;
	ULONG		ulSize;
	ULONG		i;
	NTSTATUS	Status;
	UNICODE_STRING	UStKeyName;
	OBJECT_ATTRIBUTES Obj_Attr;
	PKEY_FULL_INFORMATION pKeyFullInfo = NULL;
	PKEY_VALUE_BASIC_INFORMATION pKeyValueBasicInfo = NULL;

	//初始化objectAttributes
	InitializeObjectAttributes( &Obj_Attr, pUSzRegPath,OBJ_CASE_INSENSITIVE,NULL,NULL);

	//打开注册表
	Status = ZwOpenKey( &hKey, KEY_ALL_ACCESS,&Obj_Attr );
	if (!NT_SUCCESS(Status)){
		return;
	}
	
	//首次尝试查询子项信息
	ZwQueryKey( hKey,KeyFullInformation,NULL,0, &ulSize );
	
	pKeyFullInfo = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool,ulSize);
	if ( !pKeyFullInfo ) {
		return;
	}

	//再次查询子项信息
	Status = ZwQueryKey( hKey, KeyFullInformation, pKeyFullInfo, ulSize, &ulSize );
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "查询子项信息失败!\n" ));
	}

	for ( i=0; i< pKeyFullInfo->Values; i++ ) {

		//枚举键值信息
		ZwEnumerateValueKey( hKey,i, KeyValueBasicInformation, NULL, 0, &ulSize );
		
		pKeyValueBasicInfo =(PKEY_VALUE_BASIC_INFORMATION)ExAllocatePool(PagedPool,ulSize);
		if ( !pKeyValueBasicInfo ) {
			KdPrint(( "内存申请失败!\n" ));
			break;
		}

		Status = ZwEnumerateValueKey(hKey,i,KeyValueBasicInformation,pKeyValueBasicInfo,
			ulSize,&ulSize);
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "枚举键值失败!\n" ));
		}
		
		UStKeyName.Length = UStKeyName.MaximumLength =(USHORT)pKeyValueBasicInfo->NameLength;
		UStKeyName.Buffer = pKeyValueBasicInfo->Name;
		
		KdPrint(("\t子项%d名称:%wZ\t",i,&UStKeyName));
		
		if (pKeyValueBasicInfo->Type==REG_SZ ){
			KdPrint(( "REG_SZ\n" ));

		}else if (pKeyValueBasicInfo->Type==REG_MULTI_SZ ){
			KdPrint(( "REG_MULTI_SZ\n" )); 

		}else if (pKeyValueBasicInfo->Type==REG_DWORD ){
			KdPrint(( "REG_DWORD\n" )); 

		}else if (pKeyValueBasicInfo->Type==REG_BINARY ){
			KdPrint(( "REG_BINARY\n" )); 
		}
		
		if ( pKeyValueBasicInfo ) {
			ExFreePool(pKeyValueBasicInfo);
			pKeyValueBasicInfo = NULL;
		}
	}
//---------------------------------------------------------------------------
	if ( pKeyFullInfo ) {
		ExFreePool(pKeyFullInfo);
	}
	if ( hKey ) {
		ZwClose(hKey);
	}
}
//===========================================================================
//枚举键值和子项测试, 删除只能从最底层开始删除.
#pragma  code_seg( "INIT" )
NTSTATUS EnumerateKeyValue() {
	HANDLE		hKey = 0;
	ULONG		ulSize;
	ULONG		i;
	NTSTATUS	Status;
	UNICODE_STRING UStKeyName;
	UNICODE_STRING UStSubKeyName;
	OBJECT_ATTRIBUTES Obj_Attr;
	PKEY_FULL_INFORMATION pKeyFullInfo = NULL;
	PKEY_BASIC_INFORMATION pKeyBasicInfo = NULL;
	UNICODE_STRING UStItemName = RTL_CONSTANT_STRING( L"\\Registry\\Machine\\Software\\" );
	

	//初始化objectAttributes
	InitializeObjectAttributes(&Obj_Attr,&UStItemName,OBJ_CASE_INSENSITIVE,NULL,NULL );

	//打开注册表
	Status = ZwOpenKey( &hKey,KEY_ALL_ACCESS,&Obj_Attr);
	if ( NT_SUCCESS( Status )) {
		KdPrint(( "打开注册表\\Registry\\Machine\\Software\\成功, 准备枚举\n" ));
	}else {
		KdPrint(( "打开注册表成功失败\n" ));
	}
	
	do {
		//第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度
		Status = ZwQueryKey(hKey,KeyFullInformation,NULL,0,&ulSize );
		
		pKeyFullInfo = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool,ulSize);
		if ( !pKeyFullInfo ) {
			KdPrint(( "内存分配失败\n" ));
			break;
		}

		//第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据
		Status = ZwQueryKey(hKey,KeyFullInformation,pKeyFullInfo,ulSize,&ulSize);
		if ( !NT_SUCCESS(Status) ) {
			KdPrint(( "二次查询子键信息失败\n" ));
			break;
		}
//---------------------------------------------------------------------------
		for (i=0; i < pKeyFullInfo->SubKeys; i++ )	{

			//第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度
			ZwEnumerateKey(hKey,i,KeyBasicInformation,NULL,0,&ulSize);
			
			pKeyBasicInfo = ExAllocatePool(PagedPool,ulSize);
			if ( !pKeyBasicInfo ) {
				break;
			}

			//第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据
			Status = ZwEnumerateKey( hKey,i,KeyBasicInformation,pKeyBasicInfo,ulSize,&ulSize);
			if ( !NT_SUCCESS(Status) ) {
				KdPrint(( "枚举子键的时候遇到错误\n" ));
				break;
			}

			//填写名称信息
			UStKeyName.Length = UStKeyName.MaximumLength = (USHORT)pKeyBasicInfo->NameLength;
			UStKeyName.Buffer = pKeyBasicInfo->Name;
			
			KdPrint(("第 %d 项的名称是: %wZ\n",i,&UStKeyName));
			
			//给子字符串分配内存
			UStSubKeyName.Buffer = (PWSTR)ExAllocatePool( PagedPool, \\
			sizeof(L"\\Registry\\Machine\\Software\\") + wcslen(UStKeyName.Buffer)\*2+2 );

			UStSubKeyName.MaximumLength = sizeof(L"\\Registry\\Machine\\Software\\") 
					+ wcslen(UStKeyName.Buffer)\*2+2;

			RtlCopyUnicodeString( &UStSubKeyName, &UStItemName );
			RtlUnicodeStringCat( &UStSubKeyName, &UStKeyName);

			//枚举子键值.
			EnumerateSubValue( &UStSubKeyName );

			if ( pKeyBasicInfo ) {
				ExFreePool( pKeyBasicInfo );
				pKeyBasicInfo = NULL;
			}
			RtlFreeUnicodeString( &UStSubKeyName );
		}

		if ( pKeyBasicInfo ) {
			ExFreePool(pKeyBasicInfo);
		}
	 } while ( FALSE );
//---------------------------------------------------------------------------
	if ( pKeyFullInfo ) {
		ExFreePool(pKeyFullInfo);
	}
	if ( hKey ) {
		ZwClose(hKey);
	}
	return Status;
}
//===========================================================================
//删除子项试验
#pragma  code_seg( "INIT" )
NTSTATUS DeleteKey() {
	HANDLE hKey = 0;
	NTSTATUS Status;
	OBJECT_ATTRIBUTES ObjAttr;
	UNICODE_STRING UStKeyName = 
		RTL_CONSTANT_STRING( L"\\Registry\\Machine\\Software\\JoenRegister\\SubItem");

	
	//初始化objectAttributes
	InitializeObjectAttributes(&ObjAttr,&UStKeyName,OBJ_CASE_INSENSITIVE,NULL,NULL );

	//打开注册表
	Status = ZwOpenKey( &hKey, KEY_ALL_ACCESS,&ObjAttr );
	if ( !NT_SUCCESS(Status) ){
		KdPrint(( "打开注册表失败!\n" ));
		return Status;
	}
	
	//删除键
	Status = ZwDeleteKey( hKey );

	if ( NT_SUCCESS(Status) ){
		KdPrint(("删除\\Registry\\Machine\\Software\\JoenRegister\\SubItem成功!\n"));

	}else if( Status == STATUS_ACCESS_DENIED ){
		KdPrint(("权限不够\n"));
		
	}else if( Status == STATUS_INVALID_HANDLE ){
		KdPrint(("句柄无效\n"));
	}else{
		KdPrint(("无法删除\n"));
	}
	
	if ( hKey ) {
		ZwClose( hKey);
	}
	return Status;
}
//===========================================================================
//Rtl系列函数试验
#pragma  code_seg( "INIT" )
NTSTATUS RtlRegister() {
	ULONG		ulValue;
	NTSTATUS	Status;
	ULONG		ulDefaultData=0;
	ULONG		ulQueryValue;
	PWCHAR		SzString = L"Sz_Hello";
	RTL_QUERY_REGISTRY_TABLE RtlQueryTab\[2\] = {0};

	//按照绝对路径创建一个键
	Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,REG_SOFTWARE_KEY_NAME );
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "创建子键失败!\n" ));
		return Status;
	}else {
		KdPrint(( "创建子键成功!\n" ));
	}
	
	//检查某项是否存在
	Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, REG_SOFTWARE_KEY_NAME );
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "子键不存在!\n" ));
		return Status;
	}else {
		KdPrint(( "子键存在!\n" ));
	}
	
	//写入REG_DWORD的数据
	ulValue = 100;
	Status = RtlWriteRegistryValue( RTL_REGISTRY_ABSOLUTE, REG_SOFTWARE_KEY_NAME,
		L"DWORD_Value",REG_DWORD, &ulValue, sizeof(ulValue) );
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "写入子键失败!\n" ));
		return Status;
	}else {
		KdPrint(( "写入子键成功!\n" ));
	}
	
	//写入一个字符串
	Status = RtlWriteRegistryValue( RTL_REGISTRY_ABSOLUTE,REG_SOFTWARE_KEY_NAME,
		L"SZ_Value",REG_SZ, SzString, wcslen(SzString)\*2+2 );
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "写入字符串失败!\n" ));
		return Status;
	}else {
		KdPrint(( "写入字符串成功!\n" ));
	}

	//查询REG_DWORD的数据
	RtlQueryTab\[0\].Flags		= RTL_QUERY_REGISTRY_DIRECT;
	RtlQueryTab\[0\].Name		= L"DWORD_Value";
	RtlQueryTab\[0\].EntryContext	= &ulQueryValue;
	RtlQueryTab\[0\].DefaultType	= REG_DWORD;
	RtlQueryTab\[0\].DefaultData	= &ulDefaultData;
	RtlQueryTab\[0\].DefaultLength	= sizeof(ULONG);
	
	Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,REG_SOFTWARE_KEY_NAME,
				RtlQueryTab,NULL,NULL);
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "查询失败!\n" ));
		return Status;
	}else {
		KdPrint(( "查询成功, 值为%d!\n", ulQueryValue ));
	}
	
	//删除子键
	Status = RtlDeleteRegistryValue(RTL_REGISTRY_ABSOLUTE, REG_SOFTWARE_KEY_NAME,L"DWORD_Value");
	if ( !NT_SUCCESS(Status) ) {
		KdPrint(( "删除子键失败!\n" ));
		return Status;
	}else {
		KdPrint(( "删除子键成功!\n" ));
	}
	return Status;
}
//===========================================================================
#pragma  code_seg( "INIT" )
NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUStrPath ) {
	
	CreateNewKey();		//创建新键值试验
	SetKeyValue();		//设置键值试验
	QueryValueInfo();	//查询键值试验
	EnumerateKeyValue();	//枚举键值和项测试
	DeleteKey();		//删除子项试验
	RtlRegister();		//Rtl系列函数试验
	return -2;
}