内核中的字符串操作

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

 

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

/*
	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: %Z\n", &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;
}

 

发表评论

您必须登录 才能进行评论。