mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
- Implement KsMergeAutomationTables
svn path=/trunk/; revision=42397
This commit is contained in:
parent
fb559b8ef2
commit
4703287161
1 changed files with 483 additions and 3 deletions
|
@ -1936,8 +1936,299 @@ KsIsBusEnumChildDevice(
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
ULONG
|
||||
KspCountMethodSets(
|
||||
IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL)
|
||||
{
|
||||
ULONG Index, SubIndex, Count;
|
||||
BOOL bFound;
|
||||
|
||||
if (!AutomationTableA)
|
||||
return AutomationTableB->MethodSetsCount;
|
||||
|
||||
if (!AutomationTableB)
|
||||
return AutomationTableA->MethodSetsCount;
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(AutomationTableA->MethodItemSize == AutomationTableB->MethodItemSize);
|
||||
|
||||
/* now iterate all property sets and compare their guids */
|
||||
Count = AutomationTableA->MethodSetsCount;
|
||||
|
||||
for(Index = 0; Index < AutomationTableB->MethodSetsCount; Index++)
|
||||
{
|
||||
/* set found to false */
|
||||
bFound = FALSE;
|
||||
|
||||
for(SubIndex = 0; SubIndex < AutomationTableA->MethodSetsCount; SubIndex++)
|
||||
{
|
||||
if (IsEqualGUIDAligned(AutomationTableB->MethodSets[Index].Set, AutomationTableA->MethodSets[SubIndex].Set))
|
||||
{
|
||||
/* same property set found */
|
||||
bFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
Count++;
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
ULONG
|
||||
KspCountEventSets(
|
||||
IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL)
|
||||
{
|
||||
ULONG Index, SubIndex, Count;
|
||||
BOOL bFound;
|
||||
|
||||
if (!AutomationTableA)
|
||||
return AutomationTableB->EventSetsCount;
|
||||
|
||||
if (!AutomationTableB)
|
||||
return AutomationTableA->EventSetsCount;
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize);
|
||||
|
||||
/* now iterate all Event sets and compare their guids */
|
||||
Count = AutomationTableA->EventSetsCount;
|
||||
|
||||
for(Index = 0; Index < AutomationTableB->EventSetsCount; Index++)
|
||||
{
|
||||
/* set found to false */
|
||||
bFound = FALSE;
|
||||
|
||||
for(SubIndex = 0; SubIndex < AutomationTableA->EventSetsCount; SubIndex++)
|
||||
{
|
||||
if (IsEqualGUIDAligned(AutomationTableB->EventSets[Index].Set, AutomationTableA->EventSets[SubIndex].Set))
|
||||
{
|
||||
/* same Event set found */
|
||||
bFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
Count++;
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
KspCountPropertySets(
|
||||
IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL)
|
||||
{
|
||||
ULONG Index, SubIndex, Count;
|
||||
BOOL bFound;
|
||||
|
||||
if (!AutomationTableA)
|
||||
return AutomationTableB->PropertySetsCount;
|
||||
|
||||
if (!AutomationTableB)
|
||||
return AutomationTableA->PropertySetsCount;
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize);
|
||||
|
||||
/* now iterate all property sets and compare their guids */
|
||||
Count = AutomationTableA->PropertySetsCount;
|
||||
|
||||
for(Index = 0; Index < AutomationTableB->PropertySetsCount; Index++)
|
||||
{
|
||||
/* set found to false */
|
||||
bFound = FALSE;
|
||||
|
||||
for(SubIndex = 0; SubIndex < AutomationTableA->PropertySetsCount; SubIndex++)
|
||||
{
|
||||
if (IsEqualGUIDAligned(AutomationTableB->PropertySets[Index].Set, AutomationTableA->PropertySets[SubIndex].Set))
|
||||
{
|
||||
/* same property set found */
|
||||
bFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
Count++;
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
KspCopyMethodSets(
|
||||
OUT PKSAUTOMATION_TABLE Table,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL)
|
||||
{
|
||||
ULONG Index, SubIndex, Count;
|
||||
BOOL bFound;
|
||||
|
||||
if (!AutomationTableA)
|
||||
{
|
||||
/* copy of property set */
|
||||
RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, Table->MethodItemSize * AutomationTableB->MethodSetsCount);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (!AutomationTableB)
|
||||
{
|
||||
/* copy of property set */
|
||||
RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, Table->MethodItemSize * AutomationTableA->MethodSetsCount);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* first copy all property items from dominant table */
|
||||
RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, Table->MethodItemSize * AutomationTableA->MethodSetsCount);
|
||||
/* set counter */
|
||||
Count = AutomationTableA->MethodSetsCount;
|
||||
|
||||
/* now copy entries which arent available in the dominant table */
|
||||
for(Index = 0; Index < AutomationTableB->MethodSetsCount; Index++)
|
||||
{
|
||||
/* set found to false */
|
||||
bFound = FALSE;
|
||||
|
||||
for(SubIndex = 0; SubIndex < AutomationTableA->MethodSetsCount; SubIndex++)
|
||||
{
|
||||
if (IsEqualGUIDAligned(AutomationTableB->MethodSets[Index].Set, AutomationTableA->MethodSets[SubIndex].Set))
|
||||
{
|
||||
/* same property set found */
|
||||
bFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
/* copy new property item set */
|
||||
RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], Table->MethodItemSize);
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
KspCopyPropertySets(
|
||||
OUT PKSAUTOMATION_TABLE Table,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL)
|
||||
{
|
||||
ULONG Index, SubIndex, Count;
|
||||
BOOL bFound;
|
||||
|
||||
if (!AutomationTableA)
|
||||
{
|
||||
/* copy of property set */
|
||||
RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, Table->PropertyItemSize * AutomationTableB->PropertySetsCount);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (!AutomationTableB)
|
||||
{
|
||||
/* copy of property set */
|
||||
RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, Table->PropertyItemSize * AutomationTableA->PropertySetsCount);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* first copy all property items from dominant table */
|
||||
RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, Table->PropertyItemSize * AutomationTableA->PropertySetsCount);
|
||||
/* set counter */
|
||||
Count = AutomationTableA->PropertySetsCount;
|
||||
|
||||
/* now copy entries which arent available in the dominant table */
|
||||
for(Index = 0; Index < AutomationTableB->PropertySetsCount; Index++)
|
||||
{
|
||||
/* set found to false */
|
||||
bFound = FALSE;
|
||||
|
||||
for(SubIndex = 0; SubIndex < AutomationTableA->PropertySetsCount; SubIndex++)
|
||||
{
|
||||
if (IsEqualGUIDAligned(AutomationTableB->PropertySets[Index].Set, AutomationTableA->PropertySets[SubIndex].Set))
|
||||
{
|
||||
/* same property set found */
|
||||
bFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
/* copy new property item set */
|
||||
RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], Table->PropertyItemSize);
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
KspCopyEventSets(
|
||||
OUT PKSAUTOMATION_TABLE Table,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
|
||||
IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL)
|
||||
{
|
||||
ULONG Index, SubIndex, Count;
|
||||
BOOL bFound;
|
||||
|
||||
if (!AutomationTableA)
|
||||
{
|
||||
/* copy of Event set */
|
||||
RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, Table->EventItemSize * AutomationTableB->EventSetsCount);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (!AutomationTableB)
|
||||
{
|
||||
/* copy of Event set */
|
||||
RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, Table->EventItemSize * AutomationTableA->EventSetsCount);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* first copy all Event items from dominant table */
|
||||
RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, Table->EventItemSize * AutomationTableA->EventSetsCount);
|
||||
/* set counter */
|
||||
Count = AutomationTableA->EventSetsCount;
|
||||
|
||||
/* now copy entries which arent available in the dominant table */
|
||||
for(Index = 0; Index < AutomationTableB->EventSetsCount; Index++)
|
||||
{
|
||||
/* set found to false */
|
||||
bFound = FALSE;
|
||||
|
||||
for(SubIndex = 0; SubIndex < AutomationTableA->EventSetsCount; SubIndex++)
|
||||
{
|
||||
if (IsEqualGUIDAligned(AutomationTableB->EventSets[Index].Set, AutomationTableA->EventSets[SubIndex].Set))
|
||||
{
|
||||
/* same Event set found */
|
||||
bFound = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFound)
|
||||
{
|
||||
/* copy new Event item set */
|
||||
RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], Table->EventItemSize);
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@unimplemented
|
||||
@implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
@ -1947,8 +2238,197 @@ KsMergeAutomationTables(
|
|||
IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL,
|
||||
IN KSOBJECT_BAG Bag OPTIONAL)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
PKSAUTOMATION_TABLE Table;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
if (!AutomationTableA && !AutomationTableB)
|
||||
{
|
||||
/* nothing to merge */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* allocate an automation table */
|
||||
Table = AllocateItem(NonPagedPool, sizeof(KSAUTOMATION_TABLE));
|
||||
if (!Table)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
if (Bag)
|
||||
{
|
||||
/* add table to object bag */
|
||||
Status = KsAddItemToObjectBag(Bag, Table, NULL);
|
||||
/* check for success */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* free table */
|
||||
FreeItem(Table);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* count property sets */
|
||||
Table->PropertySetsCount = KspCountPropertySets(AutomationTableA, AutomationTableB);
|
||||
|
||||
if (Table->PropertySetsCount)
|
||||
{
|
||||
if (AutomationTableA)
|
||||
{
|
||||
/* use item size from dominant automation table */
|
||||
Table->PropertyItemSize = AutomationTableA->PropertyItemSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use item size from 2nd automation table */
|
||||
Table->PropertyItemSize = AutomationTableB->PropertyItemSize;
|
||||
}
|
||||
|
||||
/* now allocate the property sets */
|
||||
Table->PropertySets = AllocateItem(NonPagedPool, Table->PropertyItemSize * Table->PropertySetsCount);
|
||||
|
||||
if (!Table->PropertySets)
|
||||
{
|
||||
/* not enough memory */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (Bag)
|
||||
{
|
||||
/* add set to property bag */
|
||||
Status = KsAddItemToObjectBag(Bag, (PVOID)Table->PropertySets, NULL);
|
||||
/* check for success */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* cleanup table */
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* now copy the property sets */
|
||||
Status = KspCopyPropertySets(Table, AutomationTableA, AutomationTableB);
|
||||
if(!NT_SUCCESS(Status))
|
||||
goto cleanup;
|
||||
|
||||
}
|
||||
|
||||
/* now count the method sets */
|
||||
Table->MethodSetsCount = KspCountMethodSets(AutomationTableA, AutomationTableB);
|
||||
|
||||
if (Table->MethodSetsCount)
|
||||
{
|
||||
if (AutomationTableA)
|
||||
{
|
||||
/* use item size from dominant automation table */
|
||||
Table->MethodItemSize = AutomationTableA->MethodItemSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use item size from 2nd automation table */
|
||||
Table->MethodItemSize = AutomationTableB->MethodItemSize;
|
||||
}
|
||||
|
||||
/* now allocate the property sets */
|
||||
Table->MethodSets = AllocateItem(NonPagedPool, Table->MethodItemSize * Table->MethodSetsCount);
|
||||
|
||||
if (!Table->MethodSets)
|
||||
{
|
||||
/* not enough memory */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (Bag)
|
||||
{
|
||||
/* add set to property bag */
|
||||
Status = KsAddItemToObjectBag(Bag, (PVOID)Table->MethodSets, NULL);
|
||||
/* check for success */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* cleanup table */
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* now copy the property sets */
|
||||
Status = KspCopyMethodSets(Table, AutomationTableA, AutomationTableB);
|
||||
if(!NT_SUCCESS(Status))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/* now count the event sets */
|
||||
Table->EventSetsCount = KspCountEventSets(AutomationTableA, AutomationTableB);
|
||||
|
||||
if (Table->EventSetsCount)
|
||||
{
|
||||
if (AutomationTableA)
|
||||
{
|
||||
/* use item size from dominant automation table */
|
||||
Table->EventItemSize = AutomationTableA->EventItemSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use item size from 2nd automation table */
|
||||
Table->EventItemSize = AutomationTableB->EventItemSize;
|
||||
}
|
||||
|
||||
/* now allocate the property sets */
|
||||
Table->EventSets = AllocateItem(NonPagedPool, Table->EventItemSize * Table->EventSetsCount);
|
||||
|
||||
if (!Table->EventSets)
|
||||
{
|
||||
/* not enough memory */
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (Bag)
|
||||
{
|
||||
/* add set to property bag */
|
||||
Status = KsAddItemToObjectBag(Bag, (PVOID)Table->EventSets, NULL);
|
||||
/* check for success */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* cleanup table */
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
/* now copy the property sets */
|
||||
Status = KspCopyEventSets(Table, AutomationTableA, AutomationTableB);
|
||||
if(!NT_SUCCESS(Status))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* store result */
|
||||
*AutomationTableAB = Table;
|
||||
|
||||
return Status;
|
||||
|
||||
|
||||
cleanup:
|
||||
|
||||
if (Table)
|
||||
{
|
||||
if (Table->PropertySets)
|
||||
{
|
||||
/* clean property sets */
|
||||
if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->PropertySets, TRUE)))
|
||||
FreeItem((PVOID)Table->PropertySets);
|
||||
}
|
||||
|
||||
if (Table->MethodSets)
|
||||
{
|
||||
/* clean property sets */
|
||||
if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->MethodSets, TRUE)))
|
||||
FreeItem((PVOID)Table->MethodSets);
|
||||
}
|
||||
|
||||
if (Table->EventSets)
|
||||
{
|
||||
/* clean property sets */
|
||||
if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->EventSets, TRUE)))
|
||||
FreeItem((PVOID)Table->EventSets);
|
||||
}
|
||||
|
||||
if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, Table, TRUE)))
|
||||
FreeItem(Table);
|
||||
}
|
||||
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue