windows-nt/Source/XPSP1/NT/net/rras/ras/ppp/rasipxcp/configq.c
2020-09-26 16:20:57 +08:00

130 lines
2.9 KiB
C

/*
File ConfigQ.c
Defines a mechanism for queueing configuration changes. This is
needed because some ipxcp pnp re-config has to be delayed until
there are zero connected clients.
*/
#include "precomp.h"
#pragma hdrstop
typedef struct _ConfigQNode {
DWORD dwCode;
DWORD dwDataSize;
LPVOID pvData;
struct _ConfigQNode * pNext;
} ConfigQNode;
typedef struct _ConfigQueue {
ConfigQNode * pHead;
} ConfigQueue;
//
// Create a new configuration queue
//
DWORD CQCreate (HANDLE * phQueue) {
ConfigQueue * pQueue = GlobalAlloc(GPTR, sizeof(ConfigQueue));
if (pQueue == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
*phQueue = (HANDLE)pQueue;
return NO_ERROR;
}
//
// Cleanup a queue
//
DWORD CQCleanup (HANDLE hQueue) {
ConfigQueue * pQueue = (ConfigQueue *)hQueue;
DWORD dwErr;
if ((dwErr = CQRemoveAll (hQueue)) != NO_ERROR)
return dwErr;
GlobalFree (pQueue);
return NO_ERROR;
}
//
// Remove all elements from a queue
//
DWORD CQRemoveAll (HANDLE hQueue) {
ConfigQueue * pQueue = (ConfigQueue *)hQueue;
ConfigQNode * pNode = pQueue->pHead, * pTemp;
while (pNode) {
pTemp = pNode;
pNode = pNode->pNext;
if (pTemp->pvData)
GlobalFree (pTemp->pvData);
GlobalFree (pTemp);
}
pQueue->pHead = NULL;
return NO_ERROR;
}
//
// Add an element to a queue -- overwriting it if
// it already exists.
//
DWORD CQAdd (HANDLE hQueue, DWORD dwCode, LPVOID pvData, DWORD dwDataSize) {
ConfigQueue * pQueue = (ConfigQueue *)hQueue;
ConfigQNode * pNode = pQueue->pHead;
// Find the node in the queue
while (pNode) {
if (pNode->dwCode == dwCode)
break;
pNode = pNode->pNext;
}
// Allocate a new node if it wasn't found
// in the list.
if (pNode == NULL) {
pNode = GlobalAlloc (GPTR, sizeof (ConfigQNode));
if (pNode == NULL)
return ERROR_NOT_ENOUGH_MEMORY;
pNode->pNext = pQueue->pHead;
pQueue->pHead = pNode;
}
// Free any old memory
if (pNode->pvData)
GlobalFree (pNode->pvData);
// Assign the values
pNode->pvData = GlobalAlloc(GPTR, dwDataSize);
if (! pNode->pvData)
return ERROR_NOT_ENOUGH_MEMORY;
CopyMemory (pNode->pvData, pvData, dwDataSize);
pNode->dwCode = dwCode;
pNode->dwDataSize = dwDataSize;
return NO_ERROR;
}
//
// Enumerate queue values. Enumeration continues until the
// given enumeration function returns TRUE or until there are
// no more elements in the queue.
//
DWORD CQEnum (HANDLE hQueue, CQENUMFUNCPTR pFunc, ULONG_PTR ulpUser) {
ConfigQueue * pQueue = (ConfigQueue *)hQueue;
ConfigQNode * pNode = pQueue->pHead;
// Find the node in the queue
while (pNode) {
if ((*pFunc)(pNode->dwCode, pNode->pvData, pNode->dwDataSize, ulpUser))
break;
pNode = pNode->pNext;
}
return NO_ERROR;
}