自己封装了Windows内核String

Posted 冰翔不败传说

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自己封装了Windows内核String相关的知识,希望对你有一定的参考价值。

#ifndef __WKSTRING_H__
#define __WKSTRING_H__

#include <ntdef.h>

#define UULogInfo(x,...) WKString::log(__FILE__,__LINE__,__FUNCTION__,x,__VA_ARGS__)

/*
	内核String封装, WCHAR*类型,必须以\\0结尾
*/
class WKString
{
private:
	WCHAR* value_;
	int length_;
	int capacity_;
private:
	void initMem(int size);
	bool ensureCapacity(int minimumCapacity);
public:
	WKString();
	WKString(int capacity);
	WKString(const PUNICODE_STRING str);
	~WKString();	
	WKString& append(const PUNICODE_STRING str);
	WKString& append(const WCHAR* buf);
	WKString& append(const char* buf);
	WKString& append(int num);
	void printf();
	const WCHAR* getBuf();
	const UNICODE_STRING getUnicodeString();
	bool equalsIgnoreCase(const WCHAR* other) const;
	bool equalsIgnoreCase(const PUNICODE_STRING other) const;
public:
	//打印日志 对DbgPrint封装
	static void log(char* fileName, int line, char* function, LPCSTR  fmt, ...);
};

#endif // !__WKSTRING_H__


#include "WKString.h"
#include <ntddk.h>
#include <stdio.h>
#include <stdarg.h>

WKString::WKString()
{
	initMem(0);

}
WKString::WKString(int capacity)
{
	initMem(capacity);
}

WKString::WKString(const PUNICODE_STRING str)
{
	if (str == NULL)
	{
		initMem(0);
	}
	else
	{
		int length = str->Length / sizeof(WCHAR);
		if (length <= 0)
		{
			initMem(0);
		}
		else
		{
			initMem(length + 1);
			append(str);
		}
	}
}

WKString::~WKString()
{
	if (value_ != NULL)
		ExFreePool(value_);
	value_ = NULL;
	capacity_ = 0;
	length_ = 0;
}
void WKString::initMem(int size)
{
	capacity_ = 0;
	length_ = 0;
	value_ = NULL;	
	if (size <= 0)
		return;

	value_ = (WCHAR*)ExAllocatePool(NonPagedPool, size * sizeof(WCHAR));
	if (value_ != NULL)
	{
		RtlZeroMemory(value_, size * sizeof(WCHAR));
		length_ = 0;
		capacity_ = size;
	}	
	else
	{
		UULogInfo("初始化内存失败 size=%d",size);
	}
}

WKString& WKString::append(const PUNICODE_STRING str)
{
	if (str->Buffer == NULL)
		return *this;

	if (str->Length == 0)
		return *this;

	int length = str->Length / sizeof(WCHAR);
	if (!ensureCapacity(length + length_ + 1))
	{
		return *this;
	}
	memcpy((void*)(value_ + length_), (void*)(str->Buffer), str->Length);
	length_ += length;
	return *this;	
}

WKString& WKString::append(const WCHAR* buf)
{
	if (buf == NULL)
		return *this;

	int length = wcslen(buf);
	if (length == 0)
		return *this;
	
	if (!ensureCapacity(length + length_ + 1))
	{
		return *this;
	}
	memcpy((void*)(value_ + length_), (void*)(buf), length * sizeof(WCHAR));
	length_ += length;
	return *this;
}

WKString& WKString::append(const char* buf)
{
	if (buf == NULL)
		return *this;

	int length = strlen(buf);
	if (length == 0)
		return *this;

	ANSI_STRING ansiString;
	RtlInitAnsiString(&ansiString, buf);
	UNICODE_STRING unicodeString;
	NTSTATUS status = RtlAnsiStringToUnicodeString(&unicodeString, &ansiString, true);
	if (status == STATUS_SUCCESS)
	{
		append(&unicodeString);
		RtlFreeUnicodeString(&unicodeString);
	}
	else
	{
		UULogInfo("RtlAnsiStringToUnicodeString转化失败:%s", buf);
	}	
	return *this;
}

WKString& WKString::append(int num)
{
	char buf[20] = { 0 };
	sprintf_s(buf, 20, "%d", num);
	return append(buf);
}

void WKString::printf()
{
	if (value_ != NULL)
	{
		DbgPrint("[WKLog] %ws length=%d capacity=%d\\n", value_,length_,capacity_);
	}
	else
	{
		DbgPrint("[WKLog] value == NULL\\n");		
	}		
}

const WCHAR* WKString::getBuf()
{
	if (value_ == NULL)
		return L"";
	return value_;
}

const UNICODE_STRING WKString::getUnicodeString()
{
	UNICODE_STRING string;
	if (value_ == NULL)
	{
		RtlInitUnicodeString(&string, L"");
	}
	else
	{
		string.Buffer = value_;
		string.Length = length_ * sizeof(WCHAR);
		string.MaximumLength = capacity_ * sizeof(WCHAR);
	}	
	return string;
}



bool WKString::equalsIgnoreCase(const WCHAR* other) const
{
	if (other == NULL)
		return false;
	if (length_ != wcslen(other))
		return false;
	return _wcsnicmp(this->value_, other, length_) == 0;	
}

bool WKString::equalsIgnoreCase(const PUNICODE_STRING other) const
{
	WKString s(other);
	return equalsIgnoreCase(s.getBuf());
}

void WKString::log(char* fileName, int line, char* function, LPCSTR fmt, ...)
{
	va_list	va;
	va_start(va, fmt);

	int bufLen = strlen(fmt) + 50;
	int iLen = bufLen;
	char* pCursor = (char*)fmt;

	for (int i = 0; i < bufLen; i++)
	{
		char c = *pCursor;
		if (c == L'%')
		{
			char c1 = *(pCursor + 1);
			char c2 = -1;
			if (i + 2 < bufLen)
			{
				c2 = *(pCursor + 2);
			}
			if (c1 == L's')
			{
				char* pChar = (char*)va_arg(va, char*);
				int n = strlen(pChar);
				iLen += n;
			}
			else if (c1 == L'S')
			{
				WCHAR* pChar = (WCHAR*)va_arg(va, char*);
				int n = wcslen(pChar) * sizeof(WCHAR);
				//DbgPrint("[WKLog] S %d\\n", n);
				iLen += n;
			}
			else if (c1 == L'w' && c2 == L's')
			{
				WCHAR* pChar = (WCHAR*)va_arg(va, char*);
				int n = wcslen(pChar) * sizeof(WCHAR);
				//DbgPrint("[WKLog] ws %d\\n", n);
				iLen += n;
			}
			else if (c1 == L'w' && c2 == L'Z')
			{
				PUNICODE_STRING pChar = (PUNICODE_STRING)va_arg(va, char*);
				int n = pChar->MaximumLength + 1;
				iLen += n;
				//DbgPrint("[WKLog] wZ %d %d\\n", pChar->Length, pChar->MaximumLength);
			}
			else if (c1 == L'd')
			{
				int n1 = (int)va_arg(va, int);
				iLen += 10;
			}
			else if (c1 == 0)
			{
				//什么都不做,结束
			}
			else
			{
				int n1 = (int)va_arg(va, int);
				iLen += 10;
			}
		}
		pCursor++;
	}

	va_start(va, fmt);
	char* pBuf = (char*)ExAllocatePool(NonPagedPool, iLen);
	if (pBuf == NULL)
	{
		va_end(va);
		return;
	}
	memset(pBuf, 0, sizeof(char) * iLen);
	vsprintf_s(pBuf, iLen, (const char*)fmt, va);
	va_end(va);
	int len = strlen(pBuf);
	DbgPrint("[WKLog] [%s] [%s] [No.%d] [内存=%d,长度=%d]\\n", fileName, function, line,iLen,len);
	DbgPrint("[WKLog] %s\\n",pBuf);
	ExFreePool(pBuf);
	pBuf = NULL;
}

bool WKString::ensureCapacity(int minimumCapacity)
{
	if (capacity_ >= minimumCapacity)
		return true;
	int newCapacity = minimumCapacity;
	
	WCHAR* newBuf = (WCHAR*)ExAllocatePool(NonPagedPool, newCapacity * sizeof(WCHAR));
	if (newBuf == NULL)
	{
		UULogInfo("初始化内存失败 size=%d", newCapacity);
		return false;
	}
	RtlZeroMemory(newBuf, newCapacity * sizeof(WCHAR));	
	memcpy((void*)newBuf, (void*)value_, length_ * sizeof(WCHAR));
	if (value_ != NULL)
		ExFreePool(value_);
	value_ = newBuf;
	capacity_ = newCapacity;
	return true;
}

以上是关于自己封装了Windows内核String的主要内容,如果未能解决你的问题,请参考以下文章

Java 封装

Java 封装

Java 封装

Java 封装

Java 封装

Java 封装