mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 18:35:41 +00:00
[SETUPAPI] Improve the range list implementation.
- SEH-protect the range list validation and move it into a separate function. - Use a mutex to synchronize access to the range list. - Implement CM_First_Range and parts of CM_Add_Range.
This commit is contained in:
parent
faee3753ea
commit
3ad5c7fd84
1 changed files with 150 additions and 12 deletions
|
@ -69,17 +69,18 @@ typedef struct _NOTIFY_DATA
|
||||||
#define NOTIFY_MAGIC 0x44556677
|
#define NOTIFY_MAGIC 0x44556677
|
||||||
|
|
||||||
|
|
||||||
typedef struct _INTERNAL_RANGE_ELEMENT
|
typedef struct _INTERNAL_RANGE
|
||||||
{
|
{
|
||||||
struct _INTERNAL_RANGE_ELEMENT *Next;
|
LIST_ENTRY ListEntry;
|
||||||
ULONG ulDummy;
|
DWORDLONG ullStart;
|
||||||
} INTERNAL_RANGE_ELEMENT, *PINTERNAL_RANGE_ELEMENT;
|
DWORDLONG ullEnd;
|
||||||
|
} INTERNAL_RANGE, *PINTERNAL_RANGE;
|
||||||
|
|
||||||
typedef struct _INTERNAL_RANGE_LIST
|
typedef struct _INTERNAL_RANGE_LIST
|
||||||
{
|
{
|
||||||
ULONG ulMagic;
|
ULONG ulMagic;
|
||||||
PINTERNAL_RANGE_ELEMENT Current;
|
HANDLE hMutex;
|
||||||
PINTERNAL_RANGE_ELEMENT First;
|
LIST_ENTRY ListHead;
|
||||||
} INTERNAL_RANGE_LIST, *PINTERNAL_RANGE_LIST;
|
} INTERNAL_RANGE_LIST, *PINTERNAL_RANGE_LIST;
|
||||||
|
|
||||||
#define RANGE_LIST_MAGIC 0x33445566
|
#define RANGE_LIST_MAGIC 0x33445566
|
||||||
|
@ -338,6 +339,30 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
IsValidRangeList(
|
||||||
|
_In_ PINTERNAL_RANGE_LIST pRangeList)
|
||||||
|
{
|
||||||
|
BOOL bValid = TRUE;
|
||||||
|
|
||||||
|
if (pRangeList == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
if (pRangeList->ulMagic != RANGE_LIST_MAGIC)
|
||||||
|
bValid = FALSE;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
bValid = FALSE;
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
return bValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* CMP_GetBlockedDriverInfo [SETUPAPI.@]
|
* CMP_GetBlockedDriverInfo [SETUPAPI.@]
|
||||||
*/
|
*/
|
||||||
|
@ -950,9 +975,53 @@ CM_Add_Range(
|
||||||
_In_ RANGE_LIST rlh,
|
_In_ RANGE_LIST rlh,
|
||||||
_In_ ULONG ulFlags)
|
_In_ ULONG ulFlags)
|
||||||
{
|
{
|
||||||
|
PINTERNAL_RANGE_LIST pRangeList;
|
||||||
|
PINTERNAL_RANGE pRange;
|
||||||
|
CONFIGRET ret = CR_SUCCESS;
|
||||||
|
|
||||||
FIXME("CM_Add_Range(%I64u %I64u %p %lx)\n",
|
FIXME("CM_Add_Range(%I64u %I64u %p %lx)\n",
|
||||||
ullStartValue, ullEndValue, rlh, ulFlags);
|
ullStartValue, ullEndValue, rlh, ulFlags);
|
||||||
return CR_CALL_NOT_IMPLEMENTED;
|
|
||||||
|
pRangeList = (PINTERNAL_RANGE_LIST)rlh;
|
||||||
|
|
||||||
|
if (!IsValidRangeList(pRangeList))
|
||||||
|
return CR_INVALID_RANGE_LIST;
|
||||||
|
|
||||||
|
if (ulFlags & ~CM_ADD_RANGE_BITS)
|
||||||
|
return CR_INVALID_FLAG;
|
||||||
|
|
||||||
|
if (ullEndValue < ullStartValue)
|
||||||
|
return CR_INVALID_RANGE;
|
||||||
|
|
||||||
|
/* Lock the range list */
|
||||||
|
WaitForSingleObject(pRangeList->hMutex, INFINITE);
|
||||||
|
|
||||||
|
/* Allocate the new range */
|
||||||
|
pRange = HeapAlloc(GetProcessHeap(), 0, sizeof(INTERNAL_RANGE));
|
||||||
|
if (pRange == NULL)
|
||||||
|
{
|
||||||
|
ret = CR_OUT_OF_MEMORY;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRange->ullStart = ullStartValue;
|
||||||
|
pRange->ullEnd = ullEndValue;
|
||||||
|
|
||||||
|
/* Insert the range */
|
||||||
|
if (IsListEmpty(&pRangeList->ListHead))
|
||||||
|
{
|
||||||
|
InsertTailList(&pRangeList->ListHead, &pRange->ListEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* Unlock the range list */
|
||||||
|
ReleaseMutex(pRangeList->hMutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1266,13 +1335,23 @@ CM_Create_Range_List(
|
||||||
if (prlh == NULL)
|
if (prlh == NULL)
|
||||||
return CR_INVALID_POINTER;
|
return CR_INVALID_POINTER;
|
||||||
|
|
||||||
|
/* Allocate the range list */
|
||||||
pRangeList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(INTERNAL_RANGE_LIST));
|
pRangeList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(INTERNAL_RANGE_LIST));
|
||||||
if (pRangeList == NULL)
|
if (pRangeList == NULL)
|
||||||
return CR_OUT_OF_MEMORY;
|
return CR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
/* Set the magic value */
|
||||||
pRangeList->ulMagic = RANGE_LIST_MAGIC;
|
pRangeList->ulMagic = RANGE_LIST_MAGIC;
|
||||||
|
|
||||||
// TODO: More initialization
|
/* Initialize the mutex for synchonized access */
|
||||||
|
pRangeList->hMutex = CreateMutex(NULL, FALSE, NULL);
|
||||||
|
if (pRangeList->hMutex == NULL)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, pRangeList);
|
||||||
|
return CR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeListHead(&pRangeList->ListHead);
|
||||||
|
|
||||||
*prlh = (RANGE_LIST)pRangeList;
|
*prlh = (RANGE_LIST)pRangeList;
|
||||||
|
|
||||||
|
@ -1814,9 +1893,49 @@ CM_First_Range(
|
||||||
_Out_ PRANGE_ELEMENT preElement,
|
_Out_ PRANGE_ELEMENT preElement,
|
||||||
_In_ ULONG ulFlags)
|
_In_ ULONG ulFlags)
|
||||||
{
|
{
|
||||||
|
PINTERNAL_RANGE_LIST pRangeList;
|
||||||
|
PINTERNAL_RANGE pRange;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
CONFIGRET ret = CR_SUCCESS;
|
||||||
|
|
||||||
FIXME("CM_First_Range(%p %p %p %p %lx)\n",
|
FIXME("CM_First_Range(%p %p %p %p %lx)\n",
|
||||||
rlh, pullStart, pullEnd, preElement, ulFlags);
|
rlh, pullStart, pullEnd, preElement, ulFlags);
|
||||||
return CR_CALL_NOT_IMPLEMENTED;
|
|
||||||
|
pRangeList = (PINTERNAL_RANGE_LIST)rlh;
|
||||||
|
|
||||||
|
if (!IsValidRangeList(pRangeList))
|
||||||
|
return CR_INVALID_RANGE_LIST;
|
||||||
|
|
||||||
|
if (pullStart == NULL || pullEnd == NULL || preElement == NULL)
|
||||||
|
return CR_INVALID_POINTER;
|
||||||
|
|
||||||
|
if (ulFlags != 0)
|
||||||
|
return CR_INVALID_FLAG;
|
||||||
|
|
||||||
|
/* Lock the range list */
|
||||||
|
WaitForSingleObject(pRangeList->hMutex, INFINITE);
|
||||||
|
|
||||||
|
/* Fail, if the list is empty */
|
||||||
|
if (IsListEmpty(&pRangeList->ListHead))
|
||||||
|
{
|
||||||
|
ret = CR_FAILURE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the first range */
|
||||||
|
ListEntry = pRangeList->ListHead.Flink;
|
||||||
|
pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
|
||||||
|
|
||||||
|
/* Return the range data */
|
||||||
|
*pullStart = pRange->ullStart;
|
||||||
|
*pullEnd = pRange->ullEnd;
|
||||||
|
*preElement = (RANGE_ELEMENT)pRange;
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* Unlock the range list */
|
||||||
|
ReleaseMutex(pRangeList->hMutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1920,19 +2039,38 @@ CM_Free_Range_List(
|
||||||
_In_ ULONG ulFlags)
|
_In_ ULONG ulFlags)
|
||||||
{
|
{
|
||||||
PINTERNAL_RANGE_LIST pRangeList;
|
PINTERNAL_RANGE_LIST pRangeList;
|
||||||
|
PINTERNAL_RANGE pRange;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
|
||||||
FIXME("CM_Free_Range_List(%p %lx)\n", RangeList, ulFlags);
|
FIXME("CM_Free_Range_List(%p %lx)\n",
|
||||||
|
RangeList, ulFlags);
|
||||||
|
|
||||||
pRangeList = (PINTERNAL_RANGE_LIST)RangeList;
|
pRangeList = (PINTERNAL_RANGE_LIST)RangeList;
|
||||||
|
|
||||||
if (pRangeList == NULL || pRangeList->ulMagic != RANGE_LIST_MAGIC)
|
if (!IsValidRangeList(pRangeList))
|
||||||
return CR_INVALID_RANGE_LIST;
|
return CR_INVALID_RANGE_LIST;
|
||||||
|
|
||||||
if (ulFlags != 0)
|
if (ulFlags != 0)
|
||||||
return CR_INVALID_FLAG;
|
return CR_INVALID_FLAG;
|
||||||
|
|
||||||
// TODO: Free the list of ranges
|
/* Lock the range list */
|
||||||
|
WaitForSingleObject(pRangeList->hMutex, INFINITE);
|
||||||
|
|
||||||
|
/* Free the list of ranges */
|
||||||
|
while (!IsListEmpty(&pRangeList->ListHead))
|
||||||
|
{
|
||||||
|
ListEntry = RemoveHeadList(&pRangeList->ListHead);
|
||||||
|
pRange = CONTAINING_RECORD(ListEntry, INTERNAL_RANGE, ListEntry);
|
||||||
|
HeapFree(GetProcessHeap(), 0, pRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the range list */
|
||||||
|
ReleaseMutex(pRangeList->hMutex);
|
||||||
|
|
||||||
|
/* Close the mutex */
|
||||||
|
CloseHandle(pRangeList->hMutex);
|
||||||
|
|
||||||
|
/* Free the range list */
|
||||||
HeapFree(GetProcessHeap(), 0, pRangeList);
|
HeapFree(GetProcessHeap(), 0, pRangeList);
|
||||||
|
|
||||||
return CR_SUCCESS;
|
return CR_SUCCESS;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue