LookasideList 分为分页和非分页操作, 下面列出. API都不同, 用起来不方便, 不方便记忆, 看着眼晕~
分页API
ExInitializePagedLookasideList
ExAllocateFromPagedLookasideList
ExFreeToPagedLookasideList
ExDeletePagedLookasideList
非分页API
ExInitializeNPagedLookasideList
ExAllocateFromNPagedLookasideList
ExFreeToNPagedLookasideList
ExDeleteNPagedLookasideList
封装了4个API, 看着清爽.
/// @fn LookasideListInit /// @brief 初始化LookAsideList /// @param BOOLEAN bpage, TRUE = 分页内存, FALSE = 非分页内存 /// @param void ** ppLookAsideList, ppLookAsideList2级指针, 函数内部用到的 /// 时候强转类型 /// @param size_t nBufSize, 每次从LookAsideList中可以分配的内存大小 /// @return NTSTATUS, 调用方使用 NT_SUCCESS 宏来判断是否成功 NTSTATUS LookasideListInit(BOOLEAN bpage, void ** ppLookAsideList, size_t nBufSize); /// @fn LookasideListAllocate /// @param 从LookAsideList中分配一块内存 /// @param BOOLEAN bpage, TRUE = 分页内存, FALSE = 非分页内存 /// @param void ** ppLookAsideList, ppLookAsideList2级指针, 函数内部用到的 /// 时候强转类型 /// @param void ** ppNodeOut, 传出分配后的内存2级指针 /// @return NTSTATUS, 调用方使用 NT_SUCCESS 宏来判断是否成功 NTSTATUS LookasideListAllocate(BOOLEAN bpage, void * pLookAsideList, void ** ppNodeOut); /// @fn LookasideListFree /// @param 从LookAsideList中释放一块内存 /// @param BOOLEAN bpage, TRUE = 分页内存, FALSE = 非分页内存 /// @param void ** ppLookAsideList, ppLookAsideList2级指针, 函数内部用到的 /// 时候强转类型 /// @param void ** ppNodeOut, 曾经分配好的的内存2级指针 /// @return NTSTATUS, 调用方使用 NT_SUCCESS 宏来判断是否成功 NTSTATUS LookasideListFree(BOOLEAN bpage, void * pLookAsideList, void ** ppNodeOut); /// @fn LookasideListDelete /// @brief 释放LookasideList /// @param BOOLEAN bpage, TRUE = 分页内存, FALSE = 非分页内存 /// @return NTSTATUS, 调用方使用 NT_SUCCESS 宏来判断是否成功 NTSTATUS LookasideListDelete(BOOLEAN bpage, void ** ppLookAsideList);
>> DriverEntry on DriverEntry, KeGetCurrentIrql() = 0 >> testLookasideListPage, KeGetCurrentIrql() = 0 testTag[0] testTag[1] testTag[2] << testLookasideListPage >> testLookasideListNPage, KeGetCurrentIrql() = 0 testTag[0] testTag[1] testTag[2] << testLookasideListNPage << DriverEntry
/// the code on DriverEntry testLookasideListPage(); testLookasideListNPage();
void testLookasideListPage() { size_t nPos = 0; PTEST testTag[NMAX]; PAGED_LOOKASIDE_LIST PageLookasideList; PAGED_LOOKASIDE_LIST * pPageLookasideList = &PageLookasideList; DbgPrint(">> testLookasideListPage, KeGetCurrentIrql() = %d\r\n", KeGetCurrentIrql()); PAGED_CODE(); /// 初始化 LookasideList LookasideListInit(TRUE, &pPageLookasideList, sizeof(TEST)); /// 从 exp_LookasideList 请求内存 for (nPos = 0; nPos < NMAX; nPos++) { testTag[nPos] = NULL; if (!NT_SUCCESS(LookasideListAllocate(TRUE, pPageLookasideList, &testTag[nPos]))) { DbgPrint("LookasideListAllocate(TRUE) error, nPos = %d\r\n", nPos); } } /// use testTag do something ... for (nPos = 0; nPos < NMAX; nPos++) { if (NULL != testTag[nPos]) { RtlStringCchPrintfW(testTag[nPos]->cMsg, sizeof(testTag[nPos]->cMsg) / sizeof(wchar_t), L"testTag[%d]", (ULONG)nPos); DbgPrint("%ws\r\n", testTag[nPos]->cMsg); } } /// 释放 exp_LookasideList 先前分配好的内存 for (nPos = 0; nPos < NMAX; nPos++) { if (!NT_SUCCESS(LookasideListFree(TRUE, pPageLookasideList, &testTag[nPos]))) { DbgPrint("LookasideListFree(TRUE) error, nPos = %d\r\n", nPos); } testTag[nPos] = NULL; } /// 反初始化 LookasideList LookasideListDelete(TRUE, &pPageLookasideList); DbgPrint("<< testLookasideListPage\r\n"); } VOID ThreadTestLookasideListPage(IN PVOID pContext) { } void testLookasideListNPage() { size_t nPos = 0; PTEST testTag[NMAX]; NPAGED_LOOKASIDE_LIST NPageLookasideList; NPAGED_LOOKASIDE_LIST * pNPageLookasideList = &NPageLookasideList; DbgPrint(">> testLookasideListNPage, KeGetCurrentIrql() = %d\r\n", KeGetCurrentIrql()); /// 初始化 LookasideList LookasideListInit(FALSE, &pNPageLookasideList, sizeof(TEST)); /// 从 exp_LookasideList 请求内存 for (nPos = 0; nPos < NMAX; nPos++) { testTag[nPos] = NULL; if (!NT_SUCCESS(LookasideListAllocate(FALSE, pNPageLookasideList, &testTag[nPos]))) { DbgPrint("LookasideListAllocate(TRUE) error, nPos = %d\r\n", nPos); } } /// use testTag do something ... for (nPos = 0; nPos < NMAX; nPos++) { if (NULL != testTag[nPos]) { RtlStringCchPrintfW(testTag[nPos]->cMsg, sizeof(testTag[nPos]->cMsg) / sizeof(wchar_t), L"testTag[%d]", (ULONG)nPos); DbgPrint("%ws\r\n", testTag[nPos]->cMsg); } } /// 释放 exp_LookasideList 先前分配好的内存 for (nPos = 0; nPos < NMAX; nPos++) { if (!NT_SUCCESS(LookasideListFree( FALSE, pNPageLookasideList, &testTag[nPos]))) { DbgPrint("LookasideListFree(TRUE) error, nPos = %d\r\n", nPos); } testTag[nPos] = NULL; } /// 反初始化 LookasideList LookasideListDelete(FALSE, &pNPageLookasideList); DbgPrint("<< testLookasideListNPage\r\n"); }
/// @file LookasideListOpt.h /// @brief LookasideList 封装 #ifndef __LOOK_A_SIDE_LIST_OPT_H__ #define __LOOK_A_SIDE_LIST_OPT_H__ #include <ntddk.h> #include <WINDEF.H> /// operate LookasideList #define LOOK_A_SIDE_LIST_POOL_TAG_NAME 'lasl' ///< 内存分配标记 /// @fn LookasideListInit /// @brief 初始化LookAsideList /// @param BOOLEAN bpage, TRUE = 分页内存, FALSE = 非分页内存 /// @param void ** ppLookAsideList, ppLookAsideList2级指针, 函数内部用到的 /// 时候强转类型 /// @param size_t nBufSize, 每次从LookAsideList中可以分配的内存大小 /// @return NTSTATUS, 调用方使用 NT_SUCCESS 宏来判断是否成功 NTSTATUS LookasideListInit(BOOLEAN bpage, void ** ppLookAsideList, size_t nBufSize); /// @fn LookasideListAllocate /// @param 从LookAsideList中分配一块内存 /// @param BOOLEAN bpage, TRUE = 分页内存, FALSE = 非分页内存 /// @param void ** ppLookAsideList, ppLookAsideList2级指针, 函数内部用到的 /// 时候强转类型 /// @param void ** ppNodeOut, 传出分配后的内存2级指针 /// @return NTSTATUS, 调用方使用 NT_SUCCESS 宏来判断是否成功 NTSTATUS LookasideListAllocate(BOOLEAN bpage, void * pLookAsideList, void ** ppNodeOut); /// @fn LookasideListFree /// @param 从LookAsideList中释放一块内存 /// @param BOOLEAN bpage, TRUE = 分页内存, FALSE = 非分页内存 /// @param void ** ppLookAsideList, ppLookAsideList2级指针, 函数内部用到的 /// 时候强转类型 /// @param void ** ppNodeOut, 曾经分配好的的内存2级指针 /// @return NTSTATUS, 调用方使用 NT_SUCCESS 宏来判断是否成功 NTSTATUS LookasideListFree(BOOLEAN bpage, void * pLookAsideList, void ** ppNodeOut); /// @fn LookasideListDelete /// @brief 释放LookasideList /// @param BOOLEAN bpage, TRUE = 分页内存, FALSE = 非分页内存 /// @return NTSTATUS, 调用方使用 NT_SUCCESS 宏来判断是否成功 NTSTATUS LookasideListDelete(BOOLEAN bpage, void ** ppLookAsideList); /// 内部函数 NTSTATUS LookasideListInit_Page(void ** ppLookAsideList, size_t nBufSize); NTSTATUS LookasideListInit_NPage(void ** ppLookAsideList, size_t nBufSize); NTSTATUS LookasideListAllocate_Page(void * pLookAsideList, void ** ppNodeOut); NTSTATUS LookasideListAllocate_NPage(void * pLookAsideList, void ** ppNodeOut); NTSTATUS LookasideListFree_Page(void * pLookAsideList, void ** ppNodeOut); NTSTATUS LookasideListFree_NPage(void * pLookAsideList, void ** ppNodeOut); NTSTATUS LookasideListDelete_Page(void ** ppLookAsideList); NTSTATUS LookasideListDelete_NPage(void ** ppLookAsideList); #endif // #ifndef __LOOK_A_SIDE_LIST_OPT_H__
/// @file LookasideListOpt.c /// @brief ... #include "LookasideListOpt.h" NTSTATUS LookasideListInit(BOOLEAN bpage, void ** ppLookAsideList, size_t nBufSize) { if (NULL == ppLookAsideList) return STATUS_INVALID_PARAMETER; if (bpage) return LookasideListInit_Page(ppLookAsideList, nBufSize); else return LookasideListInit_NPage(ppLookAsideList, nBufSize); } NTSTATUS LookasideListAllocate(BOOLEAN bpage, void * pLookAsideList, void ** ppNodeOut) { if ((NULL == pLookAsideList) || (NULL == ppNodeOut)) return STATUS_INVALID_PARAMETER; if (bpage) return LookasideListAllocate_Page(pLookAsideList, ppNodeOut); else return LookasideListAllocate_NPage(pLookAsideList, ppNodeOut); } NTSTATUS LookasideListFree(BOOLEAN bpage, void * pLookAsideList, void ** ppNodeOut) { if ((NULL == pLookAsideList) || (NULL == ppNodeOut) || (NULL == *ppNodeOut)) return STATUS_INVALID_PARAMETER; if (bpage) return LookasideListFree_Page(pLookAsideList, ppNodeOut); else return LookasideListFree_NPage(pLookAsideList, ppNodeOut); } NTSTATUS LookasideListDelete(BOOLEAN bpage, void ** ppLookAsideList) { if ((NULL == ppLookAsideList) || (NULL == *ppLookAsideList)) return STATUS_INVALID_PARAMETER; if (bpage) return LookasideListDelete_Page(ppLookAsideList); else return LookasideListDelete_NPage(ppLookAsideList); } ////////////////////////////////////////////////////////////////////////// /// 内部函数 ////////////////////////////////////////////////////////////////////////// NTSTATUS LookasideListInit_Page(void ** ppLookAsideList, size_t nBufSize) { PPAGED_LOOKASIDE_LIST pLookaside = NULL;; NT_ASSERT(NULL != ppLookAsideList); NT_ASSERT(NULL != *ppLookAsideList); PAGED_CODE(); pLookaside = *((PAGED_LOOKASIDE_LIST **)ppLookAsideList); ExInitializePagedLookasideList(pLookaside, NULL, NULL, 0, nBufSize, LOOK_A_SIDE_LIST_POOL_TAG_NAME, 0 ); *ppLookAsideList = pLookaside; return (NULL != pLookaside) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES; } NTSTATUS LookasideListInit_NPage(void ** ppLookAsideList, size_t nBufSize) { PNPAGED_LOOKASIDE_LIST pLookaside = NULL; NT_ASSERT(NULL != ppLookAsideList); NT_ASSERT(NULL != *ppLookAsideList); pLookaside = *((NPAGED_LOOKASIDE_LIST **)ppLookAsideList); ExInitializeNPagedLookasideList(pLookaside, NULL, NULL, 0, nBufSize, LOOK_A_SIDE_LIST_POOL_TAG_NAME, 0 ); *ppLookAsideList = pLookaside; return (NULL != pLookaside) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES; } NTSTATUS LookasideListAllocate_Page(void * pLookAsideList, void ** ppNodeOut) { PAGED_CODE(); *ppNodeOut = ExAllocateFromPagedLookasideList( (PPAGED_LOOKASIDE_LIST)pLookAsideList); return (NULL != *ppNodeOut) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES; } NTSTATUS LookasideListAllocate_NPage(void * pLookAsideList, void ** ppNodeOut) { *ppNodeOut = ExAllocateFromNPagedLookasideList( (PNPAGED_LOOKASIDE_LIST)pLookAsideList); return (NULL != *ppNodeOut) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES; } NTSTATUS LookasideListFree_Page(void * pLookAsideList, void ** ppNodeOut) { PAGED_CODE(); ExFreeToPagedLookasideList((PPAGED_LOOKASIDE_LIST)pLookAsideList, *ppNodeOut); *ppNodeOut = NULL; return STATUS_SUCCESS; } NTSTATUS LookasideListFree_NPage(void * pLookAsideList, void ** ppNodeOut) { ExFreeToNPagedLookasideList((PNPAGED_LOOKASIDE_LIST)pLookAsideList, *ppNodeOut); *ppNodeOut = NULL; return STATUS_SUCCESS; } NTSTATUS LookasideListDelete_Page(void ** ppLookAsideList) { PPAGED_LOOKASIDE_LIST pLookAsideList = *ppLookAsideList; PAGED_CODE(); ExDeletePagedLookasideList(pLookAsideList); *ppLookAsideList = NULL; return STATUS_SUCCESS; } NTSTATUS LookasideListDelete_NPage(void ** ppLookAsideList) { PNPAGED_LOOKASIDE_LIST pLookAsideList = *ppLookAsideList; ExDeleteNPagedLookasideList(pLookAsideList); *ppLookAsideList = NULL; return STATUS_SUCCESS; }