⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 av.c

📁 这是一本学习 window编程的很好的参考教材
💻 C
字号:
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// $Id: av.c,v 1.2 2003/05/13 12:47:39 dev Exp $
/** @addtogroup common
 *@{
 */

/**
 * @file av.c
 * Implementation of functions to work with list of argument-value (av) pairs
 */

#include <ntddk.h>

#include "av.h"
#include "except.h"
#include "memtrack.h"

/** entry contains key-value pair and its type */
struct av_entry {
	struct		av_entry *next;		/**< next entry */
	const void	*key;				/**< key of value to search */
	int			type;				/**< type of pair for search */
	void		*value;				/**< some transparent value */
};

/** number of hash buckets */
#define HASH_SIZE	0x1000
/** get hash by some key */
#define CALC_HASH(key)  (((ULONG)(key) >> 5) % HASH_SIZE)

/** hash for av-pairs */
static struct av_entry **g_av_hash;
/** guard spinlock for hash */
KSPIN_LOCK	g_av_hash_guard;

NTSTATUS
init_av(void)
{
	g_av_hash = (struct av_entry **)malloc_np(sizeof(struct av_entry *) * HASH_SIZE);
	if (g_av_hash == NULL) {
		KdPrint(("[ndis_hk] init_av: malloc_np!\n"));
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	memset(g_av_hash, 0, sizeof(struct av_entry *) * HASH_SIZE);

	KeInitializeSpinLock(&g_av_hash_guard);

	return STATUS_SUCCESS;
}

void
free_av(void)
{
	ULONG hash;
	struct av_entry *av, *av_next;
	KIRQL irql;
	NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;

	KeAcquireSpinLock(&g_av_hash_guard, &irql);

	for (hash = 0; hash < HASH_SIZE; hash++) {
		for (av = g_av_hash[hash]; av != NULL;) {
			av_next = av->next;
				
			if (av->value != NULL && av->type > 0)
				free(av->value);
			free(av);

			av = av_next;
		}
	}

	free(g_av_hash);
	g_av_hash = NULL;

	KeReleaseSpinLock(&g_av_hash_guard, irql);
}

NTSTATUS
add_av(const void *key, void *value, int type, BOOLEAN no_guard)
{
	ULONG hash = CALC_HASH(key);
	KIRQL irql;
	struct av_entry *av;
	NTSTATUS status;

	if (!no_guard)
		KeAcquireSpinLock(&g_av_hash_guard, &irql);

	__try {

		for (av = g_av_hash[hash]; av != NULL; av = av->next)
			if (av->key == key && av->type == type)
				break;

		if (av == NULL) {

			av = (struct av_entry *)malloc_np(sizeof(*av));
			if (av == NULL) {
				KdPrint(("[ndis_hk] add_av: malloc_np!\n"));
				status = STATUS_INSUFFICIENT_RESOURCES;
				__leave;
			}

			av->next = g_av_hash[hash];
			av->key = key;
			av->value = value;
			av->type = type;

			g_av_hash[hash] = av;

		} else {
			KdPrint(("[ndis_hk] add_av: reuse of key 0x%x type %d\n", key, type));

			// change value for av
			if (av->value != NULL && av->type > 0)
				free(av->value);
			av->value = value;
		}

		status = STATUS_SUCCESS;
	
	} __except((status = GetExceptionCode(), EXCEPTION_EXECUTE_HANDLER)) {
		KdPrint(("[ndis_hk] add_av: exception 0x%x!\n", status));
	}

	if (!no_guard)
		KeReleaseSpinLock(&g_av_hash_guard, irql);

	return status;
}

void *
get_av(const void *key, int type, KIRQL *irql)
{
	ULONG hash = CALC_HASH(key);
	struct av_entry *av;

	if (irql != NULL)
		KeAcquireSpinLock(&g_av_hash_guard, irql);

	for (av = g_av_hash[hash]; av != NULL; av = av->next)
		if (av->key == key && av->type == type)
			return av->value;

	if (irql != NULL)
		KeReleaseSpinLock(&g_av_hash_guard, *irql);
	
	return NULL;
}

NTSTATUS
del_av(const void *key, int type, BOOLEAN no_guard)
{
	ULONG hash = CALC_HASH(key);
	struct av_entry *av, *av_next;
	KIRQL irql;
	NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;

	if (!no_guard)
		KeAcquireSpinLock(&g_av_hash_guard, &irql);

	av_next = NULL;
	for (av = g_av_hash[hash]; av != NULL; av = av->next) {
		if (av->key == key && av->type == type) {
			
			if (av_next != NULL)
				av_next->next = av->next;
			else
				g_av_hash[hash] = av->next;

			if (av->value != NULL && av->type > 0)
				free(av->value);
			free(av);

			status = STATUS_SUCCESS;
			break;
		}

		av_next = av;
	}

	if (!no_guard)
		KeReleaseSpinLock(&g_av_hash_guard, irql);
	
	return status;
}
/*@}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -