130 lines
2.9 KiB
C
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;
|
||
|
}
|