- Remove LIST_FOR_EACH and LIST_FOR_EACH_SAFE from the kernel

- Fix a bug in KeStartProfile (a missing negation) which caused us to either free buffer when we shouldn't, or leak it

svn path=/trunk/; revision=35633
This commit is contained in:
Stefan Ginsberg 2008-08-25 18:21:19 +00:00
parent 016e911156
commit f3b92fa090
3 changed files with 100 additions and 21 deletions

View File

@ -350,14 +350,22 @@ IoCreateDriverList(VOID)
NTSTATUS INIT_FUNCTION NTSTATUS INIT_FUNCTION
IoDestroyDriverList(VOID) IoDestroyDriverList(VOID)
{ {
PSERVICE_GROUP CurrentGroup, tmp1; PSERVICE_GROUP CurrentGroup;
PSERVICE CurrentService, tmp2; PSERVICE CurrentService;
PLIST_ENTRY NextEntry, TempEntry;
DPRINT("IoDestroyDriverList() called\n"); DPRINT("IoDestroyDriverList() called\n");
/* Destroy the Group List */ /* Destroy the Group List */
LIST_FOR_EACH_SAFE(CurrentGroup, tmp1, &GroupListHead, SERVICE_GROUP, GroupListEntry) for (NextEntry = GroupListHead.Flink, TempEntry = NextEntry->Flink;
NextEntry != &GroupListHead;
NextEntry = TempEntry, TempEntry = NextEntry->Flink)
{ {
/* Get the entry */
CurrentGroup = CONTAINING_RECORD(NextEntry,
SERVICE_GROUP,
GroupListEntry);
/* Remove it from the list */ /* Remove it from the list */
RemoveEntryList(&CurrentGroup->GroupListEntry); RemoveEntryList(&CurrentGroup->GroupListEntry);
@ -369,8 +377,15 @@ IoDestroyDriverList(VOID)
} }
/* Destroy the Service List */ /* Destroy the Service List */
LIST_FOR_EACH_SAFE(CurrentService, tmp2, &ServiceListHead, SERVICE, ServiceListEntry) for (NextEntry = ServiceListHead.Flink, TempEntry = NextEntry->Flink;
NextEntry != &ServiceListHead;
NextEntry = TempEntry, TempEntry = NextEntry->Flink)
{ {
/* Get the entry */
CurrentService = CONTAINING_RECORD(NextEntry,
SERVICE,
ServiceListEntry);
/* Remove it from the list */ /* Remove it from the list */
RemoveEntryList(&CurrentService->ServiceListEntry); RemoveEntryList(&CurrentService->ServiceListEntry);
@ -448,21 +463,35 @@ IopInitializeSystemDrivers(VOID)
PSERVICE CurrentService; PSERVICE CurrentService;
NTSTATUS Status; NTSTATUS Status;
ULONG i; ULONG i;
PLIST_ENTRY NextGroupEntry, NextServiceEntry;
DPRINT("IopInitializeSystemDrivers()\n"); DPRINT("IopInitializeSystemDrivers()\n");
/* Loop the list */ /* Start looping */
LIST_FOR_EACH(CurrentGroup, &GroupListHead, SERVICE_GROUP, GroupListEntry) for (NextGroupEntry = GroupListHead.Flink;
NextGroupEntry != &GroupListHead;
NextGroupEntry = NextGroupEntry->Flink)
{ {
/* Get the entry */
CurrentGroup = CONTAINING_RECORD(NextGroupEntry,
SERVICE_GROUP,
GroupListEntry);
DPRINT("Group: %wZ\n", &CurrentGroup->GroupName); DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);
/* Load all drivers with a valid tag */ /* Load all drivers with a valid tag */
for (i = 0; i < CurrentGroup->TagCount; i++) for (i = 0; i < CurrentGroup->TagCount; i++)
{ {
/* Loop the list */ /* Start looping */
LIST_FOR_EACH(CurrentService, &ServiceListHead, SERVICE, ServiceListEntry) for (NextServiceEntry = ServiceListHead.Flink;
NextServiceEntry != &ServiceListHead;
NextServiceEntry = NextServiceEntry->Flink)
{ {
/* Get the entry */
CurrentService = CONTAINING_RECORD(NextServiceEntry,
SERVICE,
ServiceListEntry);
if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName, if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName,
&CurrentService->ServiceGroup, &CurrentService->ServiceGroup,
TRUE)) && TRUE)) &&
@ -477,8 +506,15 @@ IopInitializeSystemDrivers(VOID)
} }
/* Load all drivers without a tag or with an invalid tag */ /* Load all drivers without a tag or with an invalid tag */
LIST_FOR_EACH(CurrentService, &ServiceListHead, SERVICE, ServiceListEntry) for (NextServiceEntry = ServiceListHead.Flink;
NextServiceEntry != &ServiceListHead;
NextServiceEntry = NextServiceEntry->Flink)
{ {
/* Get the entry */
CurrentService = CONTAINING_RECORD(NextServiceEntry,
SERVICE,
ServiceListEntry);
if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName, if ((!RtlCompareUnicodeString(&CurrentGroup->GroupName,
&CurrentService->ServiceGroup, &CurrentService->ServiceGroup,
TRUE)) && TRUE)) &&

View File

@ -99,14 +99,20 @@ LocateChildDevice(
{ {
PPNPROOT_DEVICE Device; PPNPROOT_DEVICE Device;
UNICODE_STRING DeviceIdU, InstanceIdU; UNICODE_STRING DeviceIdU, InstanceIdU;
PLIST_ENTRY NextEntry;
/* Initialize the strings to compare */ /* Initialize the strings to compare */
RtlInitUnicodeString(&DeviceIdU, DeviceId); RtlInitUnicodeString(&DeviceIdU, DeviceId);
RtlInitUnicodeString(&InstanceIdU, InstanceId); RtlInitUnicodeString(&InstanceIdU, InstanceId);
/* Start looping */ /* Start looping */
LIST_FOR_EACH(Device, &DeviceExtension->DeviceListHead, PNPROOT_DEVICE, ListEntry) for (NextEntry = DeviceExtension->DeviceListHead.Flink;
NextEntry != &DeviceExtension->DeviceListHead;
NextEntry = NextEntry->Flink)
{ {
/* Get the entry */
Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
/* See if the strings match */ /* See if the strings match */
if (RtlEqualUnicodeString(&DeviceIdU, &Device->DeviceID, TRUE) && if (RtlEqualUnicodeString(&DeviceIdU, &Device->DeviceID, TRUE) &&
RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE)) RtlEqualUnicodeString(&InstanceIdU, &Device->InstanceID, TRUE))
@ -521,6 +527,7 @@ PnpRootQueryDeviceRelations(
PPNPROOT_DEVICE Device = NULL; PPNPROOT_DEVICE Device = NULL;
ULONG Size; ULONG Size;
NTSTATUS Status; NTSTATUS Status;
PLIST_ENTRY NextEntry;
DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp); DPRINT("PnpRootQueryDeviceRelations(FDO %p, Irp %p)\n", DeviceObject, Irp);
@ -556,8 +563,15 @@ PnpRootQueryDeviceRelations(
} }
KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock); KeAcquireGuardedMutex(&DeviceExtension->DeviceListLock);
LIST_FOR_EACH(Device, &DeviceExtension->DeviceListHead, PNPROOT_DEVICE, ListEntry)
/* Start looping */
for (NextEntry = DeviceExtension->DeviceListHead.Flink;
NextEntry != &DeviceExtension->DeviceListHead;
NextEntry = NextEntry->Flink)
{ {
/* Get the entry */
Device = CONTAINING_RECORD(NextEntry, PNPROOT_DEVICE, ListEntry);
if (!Device->Pdo) if (!Device->Pdo)
{ {
/* Create a physical device object for the /* Create a physical device object for the

View File

@ -54,8 +54,9 @@ KeStartProfile(PKPROFILE Profile,
KIRQL OldIrql; KIRQL OldIrql;
PKPROFILE_SOURCE_OBJECT SourceBuffer; PKPROFILE_SOURCE_OBJECT SourceBuffer;
PKPROFILE_SOURCE_OBJECT CurrentSource; PKPROFILE_SOURCE_OBJECT CurrentSource;
BOOLEAN FreeBuffer = TRUE; BOOLEAN FreeBuffer = TRUE, SourceFound = FALSE;;
PKPROCESS ProfileProcess; PKPROCESS ProfileProcess;
PLIST_ENTRY NextEntry;
/* Allocate a buffer first, before we raise IRQL */ /* Allocate a buffer first, before we raise IRQL */
SourceBuffer = ExAllocatePoolWithTag(NonPagedPool, SourceBuffer = ExAllocatePoolWithTag(NonPagedPool,
@ -89,18 +90,27 @@ KeStartProfile(PKPROFILE Profile,
InsertTailList(&KiProfileListHead, &Profile->ProfileListEntry); InsertTailList(&KiProfileListHead, &Profile->ProfileListEntry);
} }
/* Check if this type of profile (source) is already running */ /* Start looping */
LIST_FOR_EACH(CurrentSource, &KiProfileSourceListHead, KPROFILE_SOURCE_OBJECT, ListEntry) for (NextEntry = KiProfileSourceListHead.Flink;
NextEntry != &KiProfileSourceListHead;
NextEntry = NextEntry->Flink)
{ {
/* Get the entry */
CurrentSource = CONTAINING_RECORD(NextEntry,
KPROFILE_SOURCE_OBJECT,
ListEntry);
/* Check if it's the same as the one being requested now */ /* Check if it's the same as the one being requested now */
if (CurrentSource->Source == Profile->Source) if (CurrentSource->Source == Profile->Source)
{ {
/* It is, break out */
SourceFound = TRUE;
break; break;
} }
} }
/* See if the loop found something */ /* See if the loop found something */
if (!CurrentSource) if (!SourceFound)
{ {
/* Nothing found, use our allocated buffer */ /* Nothing found, use our allocated buffer */
CurrentSource = SourceBuffer; CurrentSource = SourceBuffer;
@ -122,7 +132,7 @@ KeStartProfile(PKPROFILE Profile,
//HalStartProfileInterrupt(Profile->Source); //HalStartProfileInterrupt(Profile->Source);
/* Free the pool */ /* Free the pool */
if (!FreeBuffer) ExFreePool(SourceBuffer); if (FreeBuffer) ExFreePool(SourceBuffer);
} }
BOOLEAN BOOLEAN
@ -131,6 +141,8 @@ KeStopProfile(PKPROFILE Profile)
{ {
KIRQL OldIrql; KIRQL OldIrql;
PKPROFILE_SOURCE_OBJECT CurrentSource = NULL; PKPROFILE_SOURCE_OBJECT CurrentSource = NULL;
PLIST_ENTRY NextEntry;
BOOLEAN SourceFound = FALSE;
/* Raise to PROFILE_LEVEL and acquire spinlock */ /* Raise to PROFILE_LEVEL and acquire spinlock */
KeRaiseIrql(PROFILE_LEVEL, &OldIrql); KeRaiseIrql(PROFILE_LEVEL, &OldIrql);
@ -143,12 +155,23 @@ KeStopProfile(PKPROFILE Profile)
RemoveEntryList(&Profile->ProfileListEntry); RemoveEntryList(&Profile->ProfileListEntry);
Profile->Started = FALSE; Profile->Started = FALSE;
/* Find the Source Object */ /* Start looping */
LIST_FOR_EACH(CurrentSource, &KiProfileSourceListHead, KPROFILE_SOURCE_OBJECT, ListEntry) for (NextEntry = KiProfileSourceListHead.Flink;
NextEntry != &KiProfileSourceListHead;
NextEntry = NextEntry->Flink)
{ {
/* Get the entry */
CurrentSource = CONTAINING_RECORD(NextEntry,
KPROFILE_SOURCE_OBJECT,
ListEntry);
/* Check if this is the Source Object */
if (CurrentSource->Source == Profile->Source) if (CurrentSource->Source == Profile->Source)
{ {
/* Remove it */ /* Remember we found one */
SourceFound = TRUE;
/* Remove it and break out */
RemoveEntryList(&CurrentSource->ListEntry); RemoveEntryList(&CurrentSource->ListEntry);
break; break;
} }
@ -164,7 +187,7 @@ KeStopProfile(PKPROFILE Profile)
//HalStopProfileInterrupt(Profile->Source); //HalStopProfileInterrupt(Profile->Source);
/* Free the Source Object */ /* Free the Source Object */
if (CurrentSource) ExFreePool(CurrentSource); if (SourceFound) ExFreePool(CurrentSource);
/* FIXME */ /* FIXME */
return FALSE; return FALSE;
@ -231,10 +254,16 @@ KiParseProfileList(IN PKTRAP_FRAME TrapFrame,
{ {
PULONG BucketValue; PULONG BucketValue;
PKPROFILE Profile; PKPROFILE Profile;
PLIST_ENTRY NextEntry;
/* Loop the List */ /* Loop the List */
LIST_FOR_EACH(Profile, ListHead, KPROFILE, ProfileListEntry) for (NextEntry = ListHead->Flink;
NextEntry != ListHead;
NextEntry = NextEntry->Flink)
{ {
/* Get the entry */
Profile = CONTAINING_RECORD(NextEntry, KPROFILE, ProfileListEntry);
/* Check if the source is good, and if it's within the range */ /* Check if the source is good, and if it's within the range */
#ifdef _M_IX86 #ifdef _M_IX86
if ((Profile->Source != Source) || if ((Profile->Source != Source) ||