Source code of Windows XP (NT5)
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.

129 lines
2.9 KiB

  1. /*
  2. File ConfigQ.c
  3. Defines a mechanism for queueing configuration changes. This is
  4. needed because some ipxcp pnp re-config has to be delayed until
  5. there are zero connected clients.
  6. */
  7. #include "precomp.h"
  8. #pragma hdrstop
  9. typedef struct _ConfigQNode {
  10. DWORD dwCode;
  11. DWORD dwDataSize;
  12. LPVOID pvData;
  13. struct _ConfigQNode * pNext;
  14. } ConfigQNode;
  15. typedef struct _ConfigQueue {
  16. ConfigQNode * pHead;
  17. } ConfigQueue;
  18. //
  19. // Create a new configuration queue
  20. //
  21. DWORD CQCreate (HANDLE * phQueue) {
  22. ConfigQueue * pQueue = GlobalAlloc(GPTR, sizeof(ConfigQueue));
  23. if (pQueue == NULL)
  24. return ERROR_NOT_ENOUGH_MEMORY;
  25. *phQueue = (HANDLE)pQueue;
  26. return NO_ERROR;
  27. }
  28. //
  29. // Cleanup a queue
  30. //
  31. DWORD CQCleanup (HANDLE hQueue) {
  32. ConfigQueue * pQueue = (ConfigQueue *)hQueue;
  33. DWORD dwErr;
  34. if ((dwErr = CQRemoveAll (hQueue)) != NO_ERROR)
  35. return dwErr;
  36. GlobalFree (pQueue);
  37. return NO_ERROR;
  38. }
  39. //
  40. // Remove all elements from a queue
  41. //
  42. DWORD CQRemoveAll (HANDLE hQueue) {
  43. ConfigQueue * pQueue = (ConfigQueue *)hQueue;
  44. ConfigQNode * pNode = pQueue->pHead, * pTemp;
  45. while (pNode) {
  46. pTemp = pNode;
  47. pNode = pNode->pNext;
  48. if (pTemp->pvData)
  49. GlobalFree (pTemp->pvData);
  50. GlobalFree (pTemp);
  51. }
  52. pQueue->pHead = NULL;
  53. return NO_ERROR;
  54. }
  55. //
  56. // Add an element to a queue -- overwriting it if
  57. // it already exists.
  58. //
  59. DWORD CQAdd (HANDLE hQueue, DWORD dwCode, LPVOID pvData, DWORD dwDataSize) {
  60. ConfigQueue * pQueue = (ConfigQueue *)hQueue;
  61. ConfigQNode * pNode = pQueue->pHead;
  62. // Find the node in the queue
  63. while (pNode) {
  64. if (pNode->dwCode == dwCode)
  65. break;
  66. pNode = pNode->pNext;
  67. }
  68. // Allocate a new node if it wasn't found
  69. // in the list.
  70. if (pNode == NULL) {
  71. pNode = GlobalAlloc (GPTR, sizeof (ConfigQNode));
  72. if (pNode == NULL)
  73. return ERROR_NOT_ENOUGH_MEMORY;
  74. pNode->pNext = pQueue->pHead;
  75. pQueue->pHead = pNode;
  76. }
  77. // Free any old memory
  78. if (pNode->pvData)
  79. GlobalFree (pNode->pvData);
  80. // Assign the values
  81. pNode->pvData = GlobalAlloc(GPTR, dwDataSize);
  82. if (! pNode->pvData)
  83. return ERROR_NOT_ENOUGH_MEMORY;
  84. CopyMemory (pNode->pvData, pvData, dwDataSize);
  85. pNode->dwCode = dwCode;
  86. pNode->dwDataSize = dwDataSize;
  87. return NO_ERROR;
  88. }
  89. //
  90. // Enumerate queue values. Enumeration continues until the
  91. // given enumeration function returns TRUE or until there are
  92. // no more elements in the queue.
  93. //
  94. DWORD CQEnum (HANDLE hQueue, CQENUMFUNCPTR pFunc, ULONG_PTR ulpUser) {
  95. ConfigQueue * pQueue = (ConfigQueue *)hQueue;
  96. ConfigQNode * pNode = pQueue->pHead;
  97. // Find the node in the queue
  98. while (pNode) {
  99. if ((*pFunc)(pNode->dwCode, pNode->pvData, pNode->dwDataSize, ulpUser))
  100. break;
  101. pNode = pNode->pNext;
  102. }
  103. return NO_ERROR;
  104. }