内核下面操作字符串也不外乎就是初始化, 然后增,删,改,连接, 撒的. 和Win32下面没有太大的区别, 只是需要更多的耐心. 因为操作的是一个结构! 操作结构比操作以0结尾的字符串总是要难些的. 不过还好了. Windows里面已经提供了非常多的字符串方面操作的函数. 一般情况下也差不多够用了!

 

关于这个字符串操作没有什么好说的. 就是混个眼熟. 下回就会用了…  上代码. 还是:

  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
/*
	Windows内核下操作字符串!
	编译方法参见makefile.
*/
#include <ntddk.h>
#define  BUFFER_SIZE 1024
#include <ntstrsafe.h>
//===========================================================================
//ANSI_STRING结构和UNICODE_STRING结构的使用
#pragma  code_seg( "INIT" )
NTSTATUS StringTest() {
	ANSI_STRING AStString = {0};
	UNICODE_STRING UStString2 = {0};
	UNICODE_STRING UStString3 = RTL_CONSTANT_STRING( L"Initialization string directly!" );
	CHAR* SzHello = "hello";
	WCHAR* WSzHello = L"hello";

	//初始化ANSI_STRING字符串的做法
	RtlInitAnsiString( &AStString, SzHello );
	//%Z打印ANSI的结构字符串
	KdPrint(( "StringTest->ANSI_STRING: %Z\n", &AStString ));

	SzHello[0] = 'H';
	SzHello[1] = 'E';
	SzHello[2] = 'L';
	SzHello[3] = 'L';
	SzHello[4] = 'O';
	SzHello[5] = '\0';

	//改变SzHello, 结构也会发生改变, ANSI\_STRING里面拥有的只是指针
	KdPrint(( "ANSI_STRING: %Zn", &AStString ));

	//手工初始化字符串
	UStString2.MaximumLength = BUFFER_SIZE;		//最大缓冲区

	//分配内存, 在分页内存中
	UStString2.Buffer = (PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);

	//设置字符长度,因为是宽字符,所以是字符长度的2倍
	UStString2.Length = 2 * wcslen(WSzHello);

	//保证缓冲区足够大, 否则程序终止
	ASSERT( UStString2.MaximumLength >= UStString2.Length );

	//内存COPY, Copy的长度就是Unicode字符串的长度
	RtlCopyMemory( UStString2.Buffer, WSzHello, UStString2.Length );

	//打印UnicodeString的方法%wZ
	KdPrint(( "StringTest->UStString2:%wZ\n",&UStString2 ));
	KdPrint(( "StringTest->UStString3:%wZ\n",&UStString3 ));

	//清理内存
	ExFreePool( UStString2.Buffer );
	UStString2.Buffer = NULL;
	UStString2.Length = UStString2.MaximumLength = 0;

	return STATUS_SUCCESS;
}
//===========================================================================
//字符串测试2, 字符串之间的Copy
#pragma  code_seg( "INIT" )
NTSTATUS StringCopyTest() {

	UNICODE_STRING UStString1 = {0};
	UNICODE_STRING UStString2 = {0};

	//RtlInitUnicodeString不用释放
	RtlInitUnicodeString( &UStString1, L"Hello World" );

	//这样也是可以初始化的, 不过要记得释放
	UStString2.Buffer = (PWSTR)ExAllocatePool( PagedPool,BUFFER_SIZE );

	//Copy字符串之前必须先填写最大长度
	UStString2.MaximumLength = BUFFER_SIZE;

	//将初始化UStString2拷贝到UStString1
	RtlCopyUnicodeString( &UStString2,&UStString1 );

	//分别显示UnicodeString1和UnicodeString2
	KdPrint(( "StringCopyTest->UnicodeString1:%wZ!\n",&UStString1 ));
	KdPrint(( "StringCopyTest->UnicodeString2:%wZ!\n",&UStString2 ));

	//字符串的连接
	RtlUnicodeStringCat( &UStString2, &UStString1 );
	KdPrint(( "StringCopyTest->UnicodeString2:%wZ!\n",&UStString2 ));

	//销毁UnicodeString2 注意!!UnicodeString1不用销毁
	RtlFreeUnicodeString( &UStString2 );

	return STATUS_SUCCESS;
}
//===========================================================================
//字符串的比较试验
#pragma code_seg( "INIT" )
VOID StringCompareTest()
{
	LONG dwFlags;
	UNICODE_STRING UStString1;
	UNICODE_STRING UStString2;

	RtlInitUnicodeString(&UStString1, L"Hello World" );
	RtlInitUnicodeString(&UStString2, L"Hello WorlD" );

	//比较字符串, 区分大小写(FALSE), 相等返回True
	if (RtlEqualUnicodeString(&UStString1,&UStString2, FALSE )) {
		KdPrint(( "StringCompareTest->UStString1 and UStString2 are equal\n" ));
	}else {
		KdPrint(( "StringCompareTest->UStString1 and UStString2 are NOT equal\n" ));
	}

	//比较字符串 不区分大小写(TRUE), 相等返回TRUE
	RtlInitUnicodeString(&UStString2, L"Hello World" );
	if (RtlEqualUnicodeString(&UStString1,&UStString2, FALSE )) {
		KdPrint(( "StringCompareTest->UStString1 and UStString2 are equal\n" ));
	}else {
		KdPrint(( "StringCompareTest->UStString1 and UStString2 are NOT equal\n" ));
	}

	//比较字符串 不区分大小写(TRUE), 相等返回TRUE
	RtlInitUnicodeString(&UStString2, L"Hello" );
	if (RtlEqualUnicodeString(&UStString1,&UStString2, TRUE )) {
		KdPrint(( "StringCompareTest->UStString1 and UStString2 are equal\n" ));
	}else {
		KdPrint(( "StringCompareTest->UStString1 and UStString2 are NOT equal\n" ));
	}

	//比较字符串大小, 不区分大小写(TRUE)
	dwFlags = RtlCompareUnicodeString( &UStString1, &UStString2, TRUE );
	if ( dwFlags == 0 ) {
		KdPrint(( "StringCompareTest->UStString1 == UStString2\n" ));
	}else if( dwFlags > 0 ){
		KdPrint(( "StringCompareTest->UStString1 > UStString2\n" ));
	}else {
		KdPrint(( "StringCompareTest->UStString1 < UStString2\n" ));
	}
}
//===========================================================================
	//字符串转整数型试验
#pragma code_seg( "INIT" )
VOID StringToIntegerTest()
{
	ULONG uValue;
	NTSTATUS nStatus;
	UNICODE_STRING UStString1 = RTL_CONSTANT_STRING( L"-100" );
	UNICODE_STRING UStString2={0};

	//转换正常的十进制数字
	nStatus = RtlUnicodeStringToInteger(&UStString1,10,&uValue);
	if ( NT_SUCCESS(nStatus) ) {
		KdPrint(("StringToIntegerTest->Conver to integer succussfully!\n"));
		KdPrint(("Result:%d\n",uValue));
	}else {
		KdPrint(("StringToIntegerTest->Conver to integer unsuccessfully!\n"));
	}

	//转换16进制数据
	RtlInitUnicodeString( &UStString1, L"100" );
	nStatus = RtlUnicodeStringToInteger(&UStString1,16,&uValue);
	if ( NT_SUCCESS(nStatus) ) {
		KdPrint(("StringToIntegerTest->Conver to integer succussfully! " ));
		KdPrint(("Result:%u 0x%X \n",uValue,uValue ));
	}else {
		KdPrint(("StringToIntegerTest->Conver to integer unsuccessfully!\n"));
	}

	//数字转换成字符串,初始化UnicodeString2
	UStString2.Buffer = (PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
	UStString2.MaximumLength = BUFFER_SIZE;
	nStatus = RtlIntegerToUnicodeString( 200, 10, &UStString2  );
	if ( NT_SUCCESS(nStatus) ) {
		KdPrint(("StringToIntegerTest->Conver to string succussfully! "));
		KdPrint(("Result:%wZ\n",&UStString2 ));
	}else {
		KdPrint(("StringToIntegerTest->Conver to string unsuccessfully!\n"));
	}

	//16进制数字转字符串
	nStatus = RtlIntegerToUnicodeString( 300,16, &UStString2  );
	if ( NT_SUCCESS(nStatus) ) {
		KdPrint(("StringToIntegerTest->Conver to string succussfully! "));
		KdPrint(("Result:%wZ\n",&UStString2 ));
	}else {
		KdPrint(("StringToIntegerTest->Conver to string unsuccessfully!\n"));
	}

	//UStString2,注意!!UStString1 不用销毁
	RtlFreeUnicodeString( &UStString2 );

}
//===========================================================================
//字符串变大写实验
#pragma code_seg( "INIT" )
VOID StringToUpperTest() {
	UNICODE_STRING UStString1 = RTL_CONSTANT_STRING( L"Hello World" );

	//变化前
	KdPrint(("StringToUpperTest->UnicodeString1:%wZ\n", &UStString1 ));

	//变大写
	RtlUpcaseUnicodeString( &UStString1,&UStString1,FALSE );

	//变化后
	KdPrint(("StringToUpperTest->UnicodeString1:%wZ\n", &UStString1 ));
}
//===========================================================================
//ANSI_STRING字符串和UNICODE_STRING之间的转换
#pragma code_seg( "INIT" )
VOID StringConverTest()
{
	ANSI_STRING StString1 = {0};
	UNICODE_STRING UStString2 = {0};
	ANSI_STRING StString2 = RTL_CONSTANT_STRING( "Hello World" );
	UNICODE_STRING UStString1 = RTL_CONSTANT_STRING( L"Hello World" );

	//(1)将UNICODE_STRING字符串转换成ANSI_STRING字符串
	NTSTATUS nStatus = RtlUnicodeStringToAnsiString(&StString1,&UStString1,TRUE );
	if ( NT_SUCCESS(nStatus)) {
		KdPrint(("Conver succussfully! "));
		KdPrint(("Result:%Z\n",&StString1));
	}else {
		KdPrint(("Conver unsuccessfully!\n"));
	}

	//销毁AnsiString1
	RtlFreeAnsiString(&StString1 );

	//(2)将ANSI_STRING字符串转换成UNICODE_STRING字符串初始化AnsiString2
	nStatus = RtlAnsiStringToUnicodeString( &UStString2, &StString2,TRUE );
	if ( NT_SUCCESS(nStatus)) {
		KdPrint(( "Conver succussfully!\n" ));
		KdPrint(( "Result:%wZ\n",&UStString2 ));
	}else{
		KdPrint(( "Conver unsuccessfully!\n" ));
	}
	//销毁UnicodeString2
	RtlFreeUnicodeString( &UStString2 );
}

NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pUSzReg ) {
	StringTest();			//字符串初始化试验
	StringCopyTest();		//字符串Copy试验
	StringCompareTest();		//字符串的比较试验
	StringToIntegerTest();		//字符串转整数型试验
	StringToUpperTest();		//字符串变大写实验
	StringConverTest();		//ANSI和UNICODE之间的转换
	return -1;
}