Leaked source code of windows server 2003
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.
 
 
 
 
 
 

362 lines
6.2 KiB

/*++
Copyright (C) Microsoft Corporation, 1997 - 1999
Module Name:
linklist.cxx
Abstract:
Implements a linked list for Destination Reachability.
Author:
Gopal Parupudi <GopalP>
[Notes:]
optional-notes
Revision History:
GopalP 10/30/1997 Start.
--*/
#include <precomp.hxx>
#define WCHAR_Y ((WCHAR) 'Y')
#define WCHAR_N ((WCHAR) 'N')
#define WCHAR_X ((WCHAR) '-')
NODE::NODE()
{
Next = NULL;
Prev = NULL;
Destination = NULL;
SubId = ~0;
cRef = 1;
State = UNTRIED;
}
NODE::NODE(DWORD Id, PWCHAR Dest, PDWORD pdwStatus)
{
*pdwStatus = ERROR_SUCCESS;
Next = NULL;
Prev = NULL;
// Make a copy of the Destination name
size_t size = wcslen(Dest) + 1;
Destination = (PWCHAR) new WCHAR[size];
if (Destination != NULL)
{
StringCchCopyW(Destination, size, Dest);
}
else
{
*pdwStatus = ERROR_OUTOFMEMORY;
}
SubId = Id;
cRef = 1;
State = UNTRIED;
}
NODE::~NODE()
{
if (Destination != NULL)
{
delete Destination;
}
}
LIST::LIST()
{
pHead = NULL;
cElements = 0;
InitializeCriticalSection(&ListLock);
}
LIST::~LIST()
{
DeleteAll();
DeleteCriticalSection(&ListLock);
}
DWORD
LIST::Insert(
PNODE pNew
)
{
ASSERT(pNew != NULL);
ASSERT(pNew->Destination != NULL);
RequestLock();
//
// See if it is already present. Find() will add a reference to the
// destination if it is already present in the list.
//
if (NULL != Find(pNew->Destination, TRUE))
{
ReleaseLock();
Print();
return ERROR_ALREADY_EXISTS;
}
pNew->Next = pHead;
if (pHead != NULL)
{
pHead->Prev = pNew;
}
pHead = pNew;
cElements++;
ReleaseLock();
Print();
return ERROR_SUCCESS;
}
DWORD
LIST::InsertByDest(
PWCHAR lpszDest
)
{
DWORD dwStatus = ERROR_SUCCESS;
PNODE pNode = NULL;
// Insert into the global list
pNode = new NODE(99, lpszDest, &dwStatus);
if ( (dwStatus != ERROR_SUCCESS)
|| (pNode == NULL))
{
if (pNode)
{
delete pNode;
}
return ERROR_OUTOFMEMORY;
}
dwStatus = Insert(pNode);
if (ERROR_ALREADY_EXISTS == dwStatus)
{
delete pNode;
}
return dwStatus;
}
inline void
LIST::Delete(
PNODE pDelete
)
{
// Should be always called with the ListLock held.
if (0 != pDelete->Release())
{
Print();
return;
}
if (pDelete->Next != NULL)
{
pDelete->Next->Prev = pDelete->Prev;
}
if (pDelete->Prev != NULL)
{
pDelete->Prev->Next = pDelete->Next;
}
if (pDelete == pHead)
{
pHead = pDelete->Next;
}
delete pDelete;
cElements--;
Print();
}
BOOL
LIST::DeleteByDest(
PWCHAR lpszDest
)
{
PNODE pTemp = NULL;
RequestLock();
pTemp = pHead;
while (pTemp != NULL)
{
if (wcscmp(pTemp->Destination, lpszDest) == 0)
{
Delete(pTemp);
ReleaseLock();
return TRUE;
}
pTemp = pTemp->Next;
}
ReleaseLock();
return FALSE;
}
BOOL
LIST::DeleteById(
DWORD Id
)
{
PNODE pTemp = NULL;
RequestLock();
pTemp = pHead;
while (pTemp != NULL)
{
if (pTemp->SubId == Id)
{
Delete(pTemp);
ReleaseLock();
return TRUE;
}
pTemp = pTemp->Next;
}
ReleaseLock();
return FALSE;
}
void
LIST::DeleteAll(
void
)
{
PNODE pTemp, pDelete;
RequestLock();
pTemp = pHead;
while (pTemp != NULL)
{
pDelete = pTemp;
pTemp = pTemp->Next;
delete pDelete;
cElements--;
}
ASSERT(cElements == 0);
ReleaseLock();
}
PNODE
LIST::Find(
PWCHAR lpszDest,
BOOL bAddReference
)
{
PNODE pTemp = NULL;
RequestLock();
pTemp = pHead;
while (pTemp != NULL)
{
if (wcscmp(pTemp->Destination, lpszDest) == 0)
{
if (TRUE == bAddReference)
{
pTemp->AddRef();
}
ReleaseLock();
return pTemp;
}
pTemp = pTemp->Next;
}
ReleaseLock();
return NULL;
}
BOOL
LIST::IsEmpty(
void
)
{
RequestLock();
if (pHead == NULL)
{
ASSERT(cElements == 0);
ReleaseLock();
return TRUE;
}
ReleaseLock();
return FALSE;
}
void
LIST::Print(
void
)
{
#ifdef DBG
PNODE pTemp;
SensPrintA(SENS_INFO, ("\n\t|----------------------------------------------------------|\n"));
SensPrintA(SENS_INFO, ("\t| R E A C H A B I L I T Y L I S T |\n"));
SensPrintA(SENS_INFO, ("\t|----------------------------------------------------------|\n"));
SensPrintA(SENS_INFO, ("\t|----------------------------------------------------------|\n"));
SensPrintA(SENS_INFO, ("\t| cRef | Reachable | Destination |\n"));
SensPrintA(SENS_INFO, ("\t|----------------------------------------------------------|\n"));
RequestLock();
pTemp = pHead;
while (pTemp != NULL)
{
SensPrintW(SENS_INFO, (L"\t| %3d | %c | %s\n",
pTemp->cRef,
(pTemp->State == REACHABLE) ? WCHAR_Y : ((pTemp->State == UNTRIED) ? WCHAR_X : WCHAR_N),
pTemp->Destination ? pTemp->Destination : L"<NULL>")
);
pTemp = pTemp->Next;
}
ReleaseLock();
SensPrintA(SENS_INFO, ("\t|----------------------------------------------------------|\n\n"));
#else
// Nothing
#endif // DBG
}