void TestLookaside() { KdPrint(("enter TestLookaside ......\n")); PAGED_LOOKASIDE_LIST tLookaside; ExInitializePagedLookasideList(&tLookaside,NULL,NULL,0,sizeof(MyListNode),'1234',0); MyListNode* MyList[10] = {0}; for(int i=0; i<10; i++) { MyList[i] = (MyListNode*)ExAllocateFromPagedLookasideList(&tLookaside); if(MyList[i] == NULL) { KdPrint(("i f**k ..\n")); continue; } MyList[i]->data = i; } for(int k=0; k<10; k++) { if(MyList[k] == NULL) { KdPrint(("i f**k too \n")); continue; } KdPrint(("%d ",MyList[k]->data)); ExFreeToPagedLookasideList(&tLookaside,MyList[k]); MyList[k] = NULL; } ExDeletePagedLookasideList(&tLookaside); KdPrint(("leave TestLookaside ......\n")); }
NTSTATUS InsertMatchExpression(__in WCHAR Expression[], __in ULONG ExpressionLength) { NTSTATUS status = CheckMatchExpression(Expression, ExpressionLength); if (NT_SUCCESS(status)) { KdPrint(("[ISISandBox] InsertMatchExpression STATUS_ALIAS_EXISTS Expression : %S.\n", Expression)); return STATUS_ALIAS_EXISTS; } PMATCH_EXPRESSION element = (PMATCH_EXPRESSION)ExAllocateFromPagedLookasideList(&MatchExpressionList.PageList); if (element == NULL) { KdPrint(("[ISISandBox] InsertProtectProcess STATUS_MEMORY_NOT_ALLOCATED.\n")); return STATUS_MEMORY_NOT_ALLOCATED; } RtlZeroMemory(element, sizeof(MATCH_EXPRESSION)); RtlCopyMemory(element->Expression, Expression, sizeof(WCHAR) * ExpressionLength); element->Length = ExpressionLength * sizeof(WCHAR); InsertTailList(&MatchExpressionList.HeadList, &element->ListEntry); KdPrint(("[ISISandBox] InsertMatchExpression Expression : %S.\n", Expression)); return STATUS_SUCCESS; }
/* * @implemented */ VOID NTAPI FsRtlInitializeBaseMcb(IN PBASE_MCB OpaqueMcb, IN POOL_TYPE PoolType) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; if (PoolType == PagedPool) { Mcb->Mapping = ExAllocateFromPagedLookasideList(&FsRtlFirstMappingLookasideList); } else { Mcb->Mapping = ExAllocatePoolWithTag(PoolType | POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(LARGE_MCB_MAPPING), 'FSBC'); } Mcb->PoolType = PoolType; Mcb->PairCount = 0; Mcb->MaximumPairCount = MAXIMUM_PAIR_COUNT; RtlInitializeGenericTable(&Mcb->Mapping->Table, McbMappingCompare, McbMappingAllocate, McbMappingFree, Mcb); }
NTSTATUS RegSetValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex, IN ULONG Type, IN PVOID Data, IN ULONG DataSize ) { WCHAR szFullPath[MAXPATHLEN] = {0}; PVOID pKeyObj = NULL; ULONG ulRet = 0; PUNICODE_STRING fullUniName = NULL; int i; ULONG nAllowd = 1; WCHAR szValueName[256] = {0}; WCHAR szValue[512] = {0}; if(FALSE == IsGuardStart()) goto allowed; if(STATUS_SUCCESS == ObReferenceObjectByHandle(KeyHandle, 0, NULL, KernelMode, &pKeyObj, NULL)) { PINNERPACK_LIST pList; LONG nSubType = 0; fullUniName = ExAllocateFromPagedLookasideList(&gRegMonLooaside); if(NULL == fullUniName) goto allowed; fullUniName->MaximumLength = MAXPATHLEN * 2; ObQueryNameString(pKeyObj, (POBJECT_NAME_INFORMATION)fullUniName, MAXPATHLEN, &ulRet); ObDereferenceObject(pKeyObj); // 转换路径 ConvertKeyPath(szFullPath, fullUniName->Buffer, MAXPATHLEN); ExFreeToPagedLookasideList(&gRegMonLooaside, fullUniName); // 复制路径 wcsncpy(szValueName, (NULL != ValueName)?ValueName->Buffer:L"" , (NULL != ValueName)?ValueName->Length:0); // 比较路径 if(FALSE == IsRegGuardPath(szFullPath, szValueName, &nSubType)) goto allowed; if(REG_SZ == Type) { wcsncpy(szValue, Data, arrayof(szValueName)); } // 到用户求请 if(FALSE != CheckRequestIsAllowed(MAKEGUARDTYPE(MASK_GUARDLITE_REGMON, nSubType) , szFullPath, szValueName, szValue)) { goto allowed; } } return STATUS_ACCESS_DENIED; allowed: return RealRegSetValueKey(KeyHandle, ValueName, TitleIndex, Type, Data, DataSize); }
VOID ExDeletePagedLookasideList ( IN PPAGED_LOOKASIDE_LIST Lookaside ) /*++ Routine Description: This function removes a paged lookaside structure from the system paged lookaside list and frees any entries specified by the lookaside structure. Arguments: Lookaside - Supplies a pointer to a paged lookaside list structure. Return Value: None. --*/ { PVOID Entry; KIRQL OldIrql; // // Acquire the paged system lookaside list lock and remove the // specified lookaside list structure from the list. // ExAcquireSpinLock(&ExPagedLookasideLock, &OldIrql); RemoveEntryList(&Lookaside->L.ListEntry); ExReleaseSpinLock(&ExPagedLookasideLock, OldIrql); // // Remove all pool entries from the specified lookaside structure // and free them. // Lookaside->L.Allocate = ExpDummyAllocate; while ((Entry = ExAllocateFromPagedLookasideList(Lookaside)) != NULL) { (Lookaside->L.Free)(Entry); } return; }
/* * @implemented */ PFILE_LOCK NTAPI FsRtlAllocateFileLock(IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL) { PFILE_LOCK FileLock; /* Try to allocate it */ FileLock = ExAllocateFromPagedLookasideList(&FsRtlFileLockLookasideList); if (FileLock) { /* Initialize it */ FsRtlInitializeFileLock(FileLock, CompleteLockIrpRoutine, UnlockRoutine); } /* Return the lock */ return FileLock; }
void * kmem_cache_alloc (kmem_cache_t *cachep, int flags) { void *tmp; #ifdef USE_NONPAGED_MEMORY tmp = ExAllocateFromNPagedLookasideList(&cachep->lookaside); #else tmp = ExAllocateFromPagedLookasideList(&cachep->lookaside); #endif if (tmp == NULL) { printk("kmem_cache: %s: ALLOCATION FAILED\n", cachep->name); return NULL; } #if DBG cachep->objects_allocated++; printk("kmem_cache: %s: objects: %d [+]\n", cachep->name, cachep->objects_allocated); #endif if (tmp && cachep->ctor != NULL) cachep->ctor(tmp, cachep, flags); return tmp; }
NTSTATUS InsertProtectProcess(__in HANDLE ProcessId) { NTSTATUS status = CheckProtectProcess(ProcessId); if (NT_SUCCESS(status)) { KdPrint(("[ISISandBox] InsertProtectProcess STATUS_ALIAS_EXISTS ProcessId : %u.\n", ProcessId)); return STATUS_ALIAS_EXISTS; } PPROTECT_PROCESS element = (PPROTECT_PROCESS)ExAllocateFromPagedLookasideList(&ProtectProcessList.PageList); if (element == NULL) { KdPrint(("[ISISandBox] InsertProtectProcess STATUS_MEMORY_NOT_ALLOCATED.\n")); return STATUS_MEMORY_NOT_ALLOCATED; } element->ProcessId = ProcessId; InsertTailList(&ProtectProcessList.HeadList, &element->ListEntry); KdPrint(("[ISISandBox] InsertProtectProcess ProcessId : %u.\n", element->ProcessId)); return STATUS_SUCCESS; }
PFFS_MCB FFSAllocateMcb( PFFS_VCB Vcb, PUNICODE_STRING FileName, ULONG FileAttr) { PFFS_MCB Mcb = NULL; PLIST_ENTRY List = NULL; ULONG Extra = 0; #define MCB_NUM_SHIFT 0x04 if (FFSGlobal->McbAllocated > (FFSGlobal->MaxDepth << MCB_NUM_SHIFT)) Extra = FFSGlobal->McbAllocated - (FFSGlobal->MaxDepth << MCB_NUM_SHIFT) + FFSGlobal->MaxDepth; FFSPrint((DBG_INFO, "FFSAllocateMcb: CurrDepth=%xh/%xh/%xh FileName=%S\n", FFSGlobal->McbAllocated, FFSGlobal->MaxDepth << MCB_NUM_SHIFT, FFSGlobal->FcbAllocated, FileName->Buffer)); List = Vcb->McbList.Flink; while ((List != &(Vcb->McbList)) && (Extra > 0)) { Mcb = CONTAINING_RECORD(List, FFS_MCB, Link); List = List->Flink; if ((Mcb->Inode != 2) && (Mcb->Child == NULL) && (Mcb->FFSFcb == NULL) && (!IsMcbUsed(Mcb))) { FFSPrint((DBG_INFO, "FFSAllocateMcb: Mcb %S will be freed.\n", Mcb->ShortName.Buffer)); if (FFSDeleteMcbNode(Vcb, Vcb->McbTree, Mcb)) { FFSFreeMcb(Mcb); Extra--; } } } ExAcquireResourceExclusiveLite( &FFSGlobal->LAResource, TRUE); Mcb = (PFFS_MCB)(ExAllocateFromPagedLookasideList( &(FFSGlobal->FFSMcbLookasideList))); ExReleaseResourceForThreadLite( &FFSGlobal->LAResource, ExGetCurrentResourceThread()); if (Mcb == NULL) { Mcb = (PFFS_MCB)ExAllocatePool(PagedPool, sizeof(FFS_MCB)); RtlZeroMemory(Mcb, sizeof(FFS_MCB)); SetFlag(Mcb->Flags, MCB_FROM_POOL); } else { RtlZeroMemory(Mcb, sizeof(FFS_MCB)); } if (!Mcb) { return NULL; } Mcb->Identifier.Type = FFSMCB; Mcb->Identifier.Size = sizeof(FFS_MCB); if (FileName && FileName->Length) { Mcb->ShortName.Length = FileName->Length; Mcb->ShortName.MaximumLength = Mcb->ShortName.Length + 2; Mcb->ShortName.Buffer = ExAllocatePool(PagedPool, Mcb->ShortName.MaximumLength); if (!Mcb->ShortName.Buffer) goto errorout; RtlZeroMemory(Mcb->ShortName.Buffer, Mcb->ShortName.MaximumLength); RtlCopyMemory(Mcb->ShortName.Buffer, FileName->Buffer, Mcb->ShortName.Length); } Mcb->FileAttr = FileAttr; ExAcquireResourceExclusiveLite( &FFSGlobal->CountResource, TRUE); FFSGlobal->McbAllocated++; ExReleaseResourceForThreadLite( &FFSGlobal->CountResource, ExGetCurrentResourceThread()); return Mcb; errorout: if (Mcb) { if (Mcb->ShortName.Buffer) ExFreePool(Mcb->ShortName.Buffer); if (FlagOn(Mcb->Flags, MCB_FROM_POOL)) { ExFreePool(Mcb); } else { ExAcquireResourceExclusiveLite( &FFSGlobal->LAResource, TRUE); ExFreeToPagedLookasideList(&(FFSGlobal->FFSMcbLookasideList), Mcb); ExReleaseResourceForThreadLite( &FFSGlobal->LAResource, ExGetCurrentResourceThread()); } } return NULL; }
// // Функция обработки запроса на запись. // NTSTATUS DispatchWrite(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION pIrpStack; ULONG info = 0; OpenFileEntry *entry; char* str; char* str1; PLIST_ENTRY link; int len; ANSI_STRING f; BOOLEAN FileNonExist = TRUE; int l; char *inputBuffer; int i; pIrpStack = IoGetCurrentIrpStackLocation(pIrp); if (pDeviceObject->Flags & DO_BUFFERED_IO) { // если для устройства определён буферизованный ввод/вывод, // то записываем данные в системный буфер inputBuffer = (char*)pIrp->AssociatedIrp.SystemBuffer; } else { // иначе непосредственно в пользовательский буфер inputBuffer = (char*)pIrp->UserBuffer; } // выделяем память для нового элемента и вставляем его в конец списка entry = (OpenFileEntry*)ExAllocateFromPagedLookasideList(&glPagedList); InsertTailList(&glOpenFiles, &entry->link); // копируем имя файла в созданный элемент RtlUnicodeStringToAnsiString(&entry->fileName, &pIrpStack->FileObject->FileName, TRUE); len = strlen(entry->fileName.Buffer) + 1; do str = ExAllocatePool(NonPagedPool, len); while (str == NULL); strcpy(str, entry->fileName.Buffer); if (strstr(str, "??") != NULL){ do str1 = ExAllocatePool(NonPagedPool, len - 4); while (str1 == NULL); strcpy(str1, &str[4]); do entry->fullName.Buffer = AnsiToUnicode(str1); while (entry->fullName.Buffer == NULL); ExFreePool(str1); } else entry->fullName.Buffer = AnsiToUnicode(str); //если ввели "ddd" отчищаем весь список хукнутых файлов if (strstr(str, "ddd") != NULL){ while (!IsListEmpty(&glOpenFiles)) { PLIST_ENTRY pLink = RemoveHeadList(&glOpenFiles); entry = CONTAINING_RECORD(pLink, OpenFileEntry, link); RtlFreeAnsiString(&entry->fileName); RtlFreeUnicodeString(&entry->fullName); ExFreeToPagedLookasideList(&glPagedList, entry); } } ExFreePool(str); return CompleteIrp(pIrp, status, info); }
VOID FsRtlAddToTunnelCache ( IN PTUNNEL Cache, IN ULONGLONG DirKey, IN PUNICODE_STRING ShortName, IN PUNICODE_STRING LongName, IN BOOLEAN KeyByShortName, IN ULONG DataLength, IN PVOID Data ) /*++ Routine Description: Adds an entry to the tunnel cache keyed by DirectoryKey ## (KeyByShortName ? ShortName : LongName) ShortName, LongName, and Data are copied and stored in the tunnel. As a side effect, if there are too many entries in the tunnel cache, this routine will initiate expiration in the tunnel cache. Arguments: Cache - a tunnel cache initialized by FsRtlInitializeTunnelCache() DirKey - the key value of the directory the name appeared in ShortName - (optional if !KeyByShortName) the 8.3 name of the file LongName - (optional if KeyByShortName) the long name of the file KeyByShortName - specifies which name is keyed in the tunnel cache DataLength - specifies the length of the opaque data segment (file system specific) which contains the tunnelling information for this file Data - pointer to the opaque tunneling data segment Return Value: None --*/ { LONG Compare; ULONG NodeSize; PUNICODE_STRING NameKey; PRTL_SPLAY_LINKS *Links; LIST_ENTRY FreePoolList; PTUNNEL_NODE Node = NULL; PTUNNEL_NODE NewNode = NULL; BOOLEAN FreeOldNode = FALSE; BOOLEAN AllocatedFromPool = FALSE; PAGED_CODE(); // // If MaxEntries is 0 then tunneling is disabled. // if (TunnelMaxEntries == 0) return; InitializeListHead(&FreePoolList); // // Grab a new node for this data // NodeSize = sizeof(TUNNEL_NODE) + ShortName->Length + LongName->Length + DataLength; if (LOOKASIDE_NODE_SIZE >= NodeSize) { NewNode = ExAllocateFromPagedLookasideList(&TunnelLookasideList); } if (NewNode == NULL) { // // Data doesn't fit in lookaside nodes // NewNode = ExAllocatePoolWithTag(PagedPool, NodeSize, 'PnuT'); if (NewNode == NULL) { // // Give up tunneling this entry // return; } AllocatedFromPool = TRUE; } // // Traverse the cache to find our insertion point // NameKey = (KeyByShortName ? ShortName : LongName); ExAcquireFastMutex(&Cache->Mutex); Links = &Cache->Cache; while (*Links) { Node = CONTAINING_RECORD(*Links, TUNNEL_NODE, CacheLinks); Compare = FsRtlCompareNodeAndKey(Node, DirKey, NameKey); if (Compare > 0) { Links = &RtlLeftChild(&Node->CacheLinks); } else { if (Compare < 0) { Links = &RtlRightChild(&Node->CacheLinks); } else { break; } } } // // Thread new data into the splay tree // RtlInitializeSplayLinks(&NewNode->CacheLinks); if (Node) { // // Not inserting first node in tree // if (*Links) { // // Entry exists in the cache, so replace by swapping all splay links // RtlRightChild(&NewNode->CacheLinks) = RtlRightChild(*Links); RtlLeftChild(&NewNode->CacheLinks) = RtlLeftChild(*Links); if (RtlRightChild(*Links)) RtlParent(RtlRightChild(*Links)) = &NewNode->CacheLinks; if (RtlLeftChild(*Links)) RtlParent(RtlLeftChild(*Links)) = &NewNode->CacheLinks; if (!RtlIsRoot(*Links)) { // // Change over the parent links. Note that we've messed with *Links now // since it is pointing at the parent member. // RtlParent(&NewNode->CacheLinks) = RtlParent(*Links); if (RtlIsLeftChild(*Links)) { RtlLeftChild(RtlParent(*Links)) = &NewNode->CacheLinks; } else { RtlRightChild(RtlParent(*Links)) = &NewNode->CacheLinks; } } else { // // Set root of the cache // Cache->Cache = &NewNode->CacheLinks; } // // Free old node // RemoveEntryList(&Node->ListLinks); FsRtlFreeTunnelNode(Node, &FreePoolList); Cache->NumEntries--; } else { // // Simple insertion as a leaf // NewNode->CacheLinks.Parent = &Node->CacheLinks; *Links = &NewNode->CacheLinks; } } else { Cache->Cache = &NewNode->CacheLinks; } // // Thread onto the timer list // FsRtlQueryNormalizedSystemTime(&NewNode->CreateTime); InsertTailList(&Cache->TimerQueue, &NewNode->ListLinks); Cache->NumEntries++; // // Stash tunneling information // NewNode->DirKey = DirKey; if (KeyByShortName) { NewNode->Flags = TUNNEL_FLAG_KEY_SHORT; } else { NewNode->Flags = 0; } // // Initialize the internal UNICODE_STRINGS to point at the buffer segments. For various // reasons (UNICODE APIs are incomplete, we're avoiding calling any allocate routine more // than once, UNICODE strings are not guaranteed to be null terminated) we have to do a lot // of this by hand. // // The data is layed out like this in the allocated block: // // ----------------------------------------------------------------------------------- // | TUNNEL_NODE | Node->ShortName.Buffer | Node->LongName.Buffer | Node->TunnelData | // ----------------------------------------------------------------------------------- // NewNode->ShortName.Buffer = (PWCHAR)((PCHAR)NewNode + sizeof(TUNNEL_NODE)); NewNode->LongName.Buffer = (PWCHAR)((PCHAR)NewNode + sizeof(TUNNEL_NODE) + ShortName->Length); NewNode->ShortName.Length = NewNode->ShortName.MaximumLength = ShortName->Length; NewNode->LongName.Length = NewNode->LongName.MaximumLength = LongName->Length; if (ShortName->Length) { RtlCopyMemory(NewNode->ShortName.Buffer, ShortName->Buffer, ShortName->Length); } if (LongName->Length) { RtlCopyMemory(NewNode->LongName.Buffer, LongName->Buffer, LongName->Length); } NewNode->TunnelData = (PVOID)((PCHAR)NewNode + sizeof(TUNNEL_NODE) + ShortName->Length + LongName->Length); NewNode->TunnelDataLength = DataLength; RtlCopyMemory(NewNode->TunnelData, Data, DataLength); if (AllocatedFromPool) { SetFlag(NewNode->Flags, TUNNEL_FLAG_NON_LOOKASIDE); } #if defined(TUNNELTEST) || defined (KEYVIEW) DbgPrint("FsRtlAddToTunnelCache:\n"); DumpNode(NewNode, 1); #ifndef KEYVIEW DumpTunnel(Cache); #endif #endif // TUNNELTEST // // Clean out the cache, release, and then drop any pool memory we need to // FsRtlPruneTunnelCache(Cache, &FreePoolList); ExReleaseFastMutex(&Cache->Mutex); FsRtlEmptyFreePoolList(&FreePoolList); return; }
NTSTATUS EnumServices() { //_asm int 3 NTSTATUS status = STATUS_SUCCESS; ULONG SubKeyIndex, ResultLength, ulSize; HANDLE i, HandleRegKey = NULL; UNICODE_STRING RegistryKeyName, KeyValue; UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; PLIST_ENTRY pListHead = NULL, pListCur = NULL; PLDR_DATA_TABLE_ENTRY pLdrDataTable = NULL; PSERVICES_INFO pServicesInfo = NULL,\ pPreServicesInfo = NULL; PKEY_BASIC_INFORMATION pKeyBasicInfo = NULL; PKEY_FULL_INFORMATION pKeyFullInfo = NULL; /************************************************************************/ /* User-mode Handle Corresponding Object Name HKEY_LOCAL_MACHINE \Registry\Machine HKEY_USERS \Registry\User HKEY_CLASSES_ROOT No kernel-mode equivalent HKEY_CURRENT_USER No simple kernel-mode equivalent, but see Registry Run-Time Library Routines */ /************************************************************************/ WCHAR ServiceRegisterPath[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"; //pListHead = ((PLIST_ENTRY)pDriverObj->DriverSection)->Flink; //pListCur = pListHead; __try { FreePagedLookasideListForServices(); ExInitializePagedLookasideList(&g_PageListServices, NULL, NULL, 0, sizeof(SERVICES_INFO), NULL, 0); RtlInitUnicodeString(&RegistryKeyName, ServiceRegisterPath); InitializeObjectAttributes(&ObjectAttributes, &RegistryKeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, // handle NULL); status = ZwOpenKey(&HandleRegKey, KEY_READ, &ObjectAttributes); // 第一次调用是为了获取需要的长度 ZwQueryKey(HandleRegKey, KeyFullInformation, NULL, 0, &ulSize); pKeyFullInfo = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize); // 第二次调用是为了获取数据 ZwQueryKey(HandleRegKey, KeyFullInformation, pKeyFullInfo, ulSize, &ulSize); //循环遍历各个子项 for (SubKeyIndex = 0; SubKeyIndex <pKeyFullInfo->SubKeys; SubKeyIndex++) { ZwEnumerateKey(HandleRegKey, SubKeyIndex, KeyBasicInformation, NULL, 0, &ulSize); pKeyBasicInfo = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulSize); //获取第I个子项的数据 ZwEnumerateKey(HandleRegKey, SubKeyIndex, KeyBasicInformation, pKeyBasicInfo, ulSize, &ulSize); pServicesInfo = (PSERVICES_INFO)ExAllocateFromPagedLookasideList(&g_PageListServices); RtlZeroMemory(pServicesInfo, sizeof(SERVICES_INFO)); //服务的名称 RtlCopyMemory(pServicesInfo->lpwzSrvName, pKeyBasicInfo->Name, pKeyBasicInfo->NameLength); KeyName.Buffer = (PWCH)ExAllocatePool(PagedPool, RegistryKeyName.Length + pKeyBasicInfo->NameLength); KeyName.Length = RegistryKeyName.Length + pKeyBasicInfo->NameLength; KeyName.MaximumLength = KeyName.Length; RtlZeroMemory(KeyName.Buffer, KeyName.Length); RtlCopyMemory(KeyName.Buffer, RegistryKeyName.Buffer, RegistryKeyName.Length); RtlCopyMemory((PUCHAR)KeyName.Buffer + RegistryKeyName.Length, pKeyBasicInfo->Name, pKeyBasicInfo->NameLength); if (!QueryServiceRunType(&KeyName, pServicesInfo)) { if (NULL != pServicesInfo) { ExFreeToPagedLookasideList(&g_PageListServices, pServicesInfo); pServicesInfo = NULL; } } else { pServicesInfo->next = NULL; if (g_pServicesInfo == NULL) { g_pServicesInfo = pServicesInfo; pPreServicesInfo = pServicesInfo; } else { pPreServicesInfo->next = pServicesInfo; pPreServicesInfo = pServicesInfo; } } if (KeyName.Buffer != NULL) { ExFreePool(KeyName.Buffer); KeyName.Buffer = NULL; } if (pKeyBasicInfo != NULL) { ExFreePool(pKeyBasicInfo); pKeyBasicInfo = NULL; } } } __except(EXCEPTION_EXECUTE_HANDLER) { FreePagedLookasideListForServices(); KdPrint(("Services:EnumServices failed!")); status = STATUS_UNSUCCESSFUL; } if (NULL != HandleRegKey) { ZwClose(HandleRegKey); HandleRegKey = NULL; } if (pKeyBasicInfo != NULL) { ExFreePool(pKeyBasicInfo); pKeyBasicInfo = NULL; } if (pKeyFullInfo != NULL) { ExFreePool(pKeyFullInfo); pKeyFullInfo = NULL; } return status; }
EXTERN_C NTSTATUS EnumDirectory( char *lpDirName ) { NTSTATUS status, fStatus; ULONG dwBytesReturned; OBJECT_ATTRIBUTES objectAttributes; PDEVICE_OBJECT lpDeviceObject; IO_STACK_LOCATION iost; PIO_STACK_LOCATION lpsp; IO_STATUS_BLOCK IoStatus; HANDLE hFile = NULL; PFILE_DIRECTORY_INFORMATION lpInformation; PDIRECTORY_INFO lpDirInfo = NULL, lpPreDirInfo = NULL; PFILE_OBJECT lpFileObject = NULL; UNICODE_STRING unFileName; ANSI_STRING anFileName; HANDLE eventHandle = NULL; CHAR buffer[1024]; PUCHAR lpNext; dwBytesReturned = 0; status = STATUS_UNSUCCESSFUL; RtlZeroMemory(buffer,1024); strcpy(buffer,"\\DosDevices\\"); strcat(buffer,lpDirName); RtlInitAnsiString(&anFileName,buffer); RtlAnsiStringToUnicodeString(&unFileName,&anFileName,TRUE); InitializeObjectAttributes(&objectAttributes,&unFileName,OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,NULL,NULL); __try { //打开文件 fStatus = ZwOpenFile(&hFile,\ FILE_LIST_DIRECTORY | SYNCHRONIZE | FILE_ANY_ACCESS,\ &objectAttributes,\ &IoStatus,\ FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ObReferenceObjectByHandle(hFile, FILE_LIST_DIRECTORY | SYNCHRONIZE, 0, KernelMode, (PVOID *)&lpFileObject, NULL); status = ZwCreateEvent(&eventHandle, GENERIC_ALL, 0, NotificationEvent, FALSE); lpInformation = (PFILE_DIRECTORY_INFORMATION)ExAllocatePool(PagedPool, 655350); status = ZwQueryDirectoryFile(hFile, eventHandle,0, 0, &IoStatus, lpInformation, 655350, FileDirectoryInformation, FALSE, NULL, FALSE ); if (!NT_SUCCESS(status) && status != STATUS_PENDING) { goto LeaveBefore; } if (status == STATUS_PENDING) { KeWaitForSingleObject(eventHandle, Executive, KernelMode, TRUE, 0); } FreePagedLookasideListForDirectory(); g_pPageListDirectory = (PPAGED_LOOKASIDE_LIST)ExAllocatePool(PagedPool, sizeof(PAGED_LOOKASIDE_LIST)); ExInitializePagedLookasideList(g_pPageListDirectory, NULL, NULL, 0, sizeof(DIRECTORY_INFO), NULL, 0); while(1) { lpDirInfo = (PDIRECTORY_INFO)ExAllocateFromPagedLookasideList(g_pPageListDirectory); RtlZeroMemory(lpDirInfo, sizeof(DIRECTORY_INFO)); RtlCopyMemory(lpDirInfo->FileName, lpInformation->FileName, lpInformation->FileNameLength); lpDirInfo->AllocationSize = lpInformation->AllocationSize; lpDirInfo->FileAttributes = lpInformation->FileAttributes; RtlTimeToTimeFields(&(lpInformation->CreationTime), &(lpDirInfo->CreationTime)); RtlTimeToTimeFields(&(lpInformation->LastAccessTime), &(lpDirInfo->LastAccessTime)); RtlTimeToTimeFields(&(lpInformation->LastWriteTime), &(lpDirInfo->LastWriteTime)); RtlTimeToTimeFields(&(lpInformation->ChangeTime), &(lpDirInfo->ChangeTime)); lpDirInfo->next = NULL; if (NULL == g_pDirectoryInfo) { g_pDirectoryInfo = lpDirInfo; lpPreDirInfo = lpDirInfo; } else { lpPreDirInfo->next = lpDirInfo; lpPreDirInfo = lpDirInfo; } if(!lpInformation->NextEntryOffset) { break; } lpInformation = (PFILE_DIRECTORY_INFORMATION)((PUCHAR)lpInformation + lpInformation->NextEntryOffset); } LeaveBefore: ; } __finally { if (NT_SUCCESS(fStatus)) { ZwClose(hFile); } if (NULL != lpFileObject) { ObDereferenceObject(lpFileObject); lpFileObject = NULL; } if (NULL != eventHandle) { ZwClose(eventHandle); eventHandle = NULL; } } return status; }