Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

355 lines
6.3 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
list.c
Abstract:
This module implements a simple list management package
Author:
Dave Hastings (daveh) 04-Nov-1992
Revision History:
--*/
#include <windows.h>
#include <malloc.h>
#include <memory.h>
#include "list.h"
typedef struct _ListEntry {
struct _ListEntry *Flink;
struct _ListEntry *Blink;
UCHAR Data[1];
} LISTENTRY, *PLISTENTRY;
typedef struct _List {
ULONG DataSize;
COMPAREFUNCTION Compare;
LISTENTRY List;
} LIST, *PLIST;
PVOID
CreateList(
ULONG DataSize,
COMPAREFUNCTION Compare
)
/*++
Routine Description:
This function creates a list.
Arguments:
DataSize -- Supplies the size of the data for elements in this list
CompareFunction -- Supplies the comparison function for items in the list
Return Value:
Pointer to the created list.
--*/
{
PLIST List;
if ((DataSize == NULL) || (Compare == NULL)) {
return NULL;
}
List = malloc(sizeof(LIST));
if (List != NULL) {
List->DataSize = DataSize;
List->Compare = Compare;
List->List.Flink = &(List->List);
List->List.Blink = &(List->List);
}
return List;
}
PVOID
InsertDataInList(
PVOID List,
PVOID Data
)
/*++
Routine Description:
This routine inserts a data item in the list
Arguments:
List -- Supplies a pointer to the list
Data -- Supplies a pointer to the data
Return Value:
Pointer to the list item
--*/
{
PLIST ListPointer;
PLISTENTRY ListEntry, CurrentEntry;
if ((List == NULL) || (Data == NULL)) {
return NULL;
}
//
// Create the new list entry
//
ListPointer = List;
ListEntry = malloc(sizeof(LISTENTRY) + ListPointer->DataSize);
if (ListEntry != NULL) {
//
// Put the data into the list entry
//
memcpy(&(ListEntry->Data), Data, ListPointer->DataSize);
//
// Find the appropriate spot in the list
//
CurrentEntry = ListPointer->List.Flink;
while (CurrentEntry->Flink != &(((PLIST)List)->List)) {
if ((*(((PLIST)List)->Compare))(CurrentEntry->Data,Data) < 0) {
break;
}
CurrentEntry = CurrentEntry->Flink;
}
//
// Insert the item into the list
//
if ((CurrentEntry != &(((PLIST)List)->List)) &&
((*(((PLIST)List)->Compare))(CurrentEntry->Data,Data) >= 0)
) {
//
// Only one item in the list, and we need to insert in front of it
//
CurrentEntry = CurrentEntry->Blink;
}
ListEntry->Flink = CurrentEntry->Flink;
ListEntry->Blink = CurrentEntry;
CurrentEntry->Flink->Blink = ListEntry;
CurrentEntry->Flink = ListEntry;
}
return ListEntry;
}
BOOL
RemoveDataFromList(
PVOID List,
PVOID Data,
PVOID ListItem
)
/*++
Routine Description:
This routine removes a item from the list, either by value, or by
pointer to list entry
Arguments:
List -- Supplies a pointer to the list
Data -- Supplies a pointer to the data to remove (optional)
ListItem -- Supplies a pointer to the list item (optional)
Return Value:
TRUE if successful
--*/
{
PLISTENTRY Entry;
if ((List == NULL) || ((Data == NULL) && (ListItem == NULL))) {
return FALSE;
}
//
// Figure out which item to delete
//
if (ListItem == NULL) {
Entry = FindDataInList(
List,
Data
);
} else {
Entry = ListItem;
}
if (Entry == NULL) {
return FALSE;
}
//
// Remove the entry and free the memory
//
Entry->Blink->Flink = Entry->Flink;
Entry->Flink->Blink = Entry->Blink;
free(Entry);
return TRUE;
}
PVOID
GetDataFromListItem(
PVOID List,
PVOID ListItem
)
/*++
Routine Description:
This function returns a pointer to the data in a list item
Arguments:
List -- Supplies the list
ListItem -- Supplies the list item
Return Value:
Pointer to the data
--*/
{
if (ListItem != NULL) {
return &(((PLISTENTRY)ListItem)->Data);
} else {
return NULL;
}
}
PVOID
TraverseList(
PVOID List,
PVOID ListItem
)
/*++
Routine Description:
This routine traverses a list one element at a time. If ListItem is
null, we start at the begining of the list.
Arguments:
List -- Supplies a pointer to the list
ListItem -- Supplies a pointer to an item in the list
Return Value:
Pointer to the next item in the list
--*/
{
PLISTENTRY Entry;
if (List == NULL) {
return NULL;
}
if (ListItem == NULL) {
Entry = ((PLIST)List)->List.Flink;
} else {
Entry = ((PLISTENTRY)ListItem)->Flink;
}
if (Entry == &(((PLIST)List)->List)) {
return NULL;
} else {
return Entry;
}
}
PVOID
FindDataInList(
PVOID List,
PVOID Key
)
/*++
Routine Description:
This routine locates an item of data in a list. Note: the key is
expected to be as large as a data item, but only the lookup field(s) have
to be specified.
Arguments:
List -- Supplies the list
Key -- Supplies the data to look for
Return Value:
Pointer to the list entry
--*/
{
PLISTENTRY CurrentEntry;
if ((List == NULL) || (Key == NULL)) {
return NULL;
}
CurrentEntry = ((PLIST)List)->List.Flink;
while (CurrentEntry->Flink != &(((PLIST)List)->List)) {
if ((*(((PLIST)List)->Compare))(CurrentEntry->Data,Key) == 0) {
return CurrentEntry;
}
CurrentEntry = CurrentEntry->Flink;
}
//
// In case there is only one item in the list
//
if ((CurrentEntry != &(((PLIST)List)->List)) &&
((*(((PLIST)List)->Compare))(CurrentEntry->Data,Key) == 0)
) {
return CurrentEntry;
}
return NULL;
}
BOOL
DestroyList(
PVOID List
)
/*++
Routine Description:
This routine destroys a list and deallocates its associated memory
Arguments:
List -- Supplies the list
Return Value:
TRUE if successfull
--*/
{
if (List == NULL) {
return FALSE;
}
while (RemoveDataFromList(List, NULL, ((PLIST)List)->List.Flink)) {
}
free(List);
return TRUE;
}