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.

232 lines
5.4 KiB

  1. /* Copyright (c) 1992-1998 Microsoft Corporation */
  2. // Linked list code -- approximates the VMM linked list API's
  3. #include <windows.h>
  4. #include "mmsystem.h"
  5. #include "mmsys.h"
  6. #include "list.h"
  7. #include "mciseq.h"
  8. List arrayOfLists[MAXLISTS]; // array of lists
  9. /**************************** PRIVATE FUNCTIONS *************************/
  10. #define UNICODE
  11. #ifdef DEBUG
  12. PRIVATE BOOL NEAR PASCAL ListHandleBad(ListHandle lh)
  13. {
  14. if ((lh >= MAXLISTS) || arrayOfLists[lh].nodeSize == 0)
  15. {
  16. dprintf(("*** Bad List Handle ***")); // Must display before Break call
  17. DebugBreak();
  18. return TRUE;
  19. }
  20. else
  21. return FALSE;
  22. }
  23. #else
  24. #define ListHandleBad(lh) FALSE
  25. #endif
  26. /**************************** PUBLIC FUNCTIONS *************************/
  27. PUBLIC ListHandle FAR PASCAL List_Create(DWORD nodeSize, DWORD flags) //
  28. //size must be non-zero
  29. {
  30. int i;
  31. for(i = 0; ((i < MAXLISTS) && (arrayOfLists[i].nodeSize)); i++)
  32. ;
  33. if (i >= MAXLISTS)
  34. return NULLLIST;
  35. else
  36. {
  37. arrayOfLists[i].nodeSize = nodeSize;
  38. return i; // return array index as "listHandle"
  39. }
  40. }
  41. PUBLIC NPSTR FAR PASCAL List_Allocate(ListHandle lh)
  42. {
  43. Node *myNode;
  44. DWORD size;
  45. HLOCAL hMemory;
  46. if (ListHandleBad(lh))
  47. return NULL;
  48. size = (arrayOfLists[lh].nodeSize + NODEHDRSIZE + 3) & 0xFFFFFFFC;
  49. /* the above line serves to compute the total size, rounded up to
  50. next longword boundary */
  51. /* if (size > 65535)
  52. error(LISTALLOCTOOBIG); */
  53. if (hMemory = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (int) size)) // make room for it
  54. {
  55. if (myNode = (Node *) LocalLock(hMemory)) // lock and get abs ptr to it
  56. {
  57. myNode->handle = hMemory;
  58. myNode->next = NULL;
  59. return (NPSTR) myNode->data; // return pointer (success!)
  60. }
  61. else // couldn't lock
  62. {
  63. LocalFree(myNode->handle); // undo the alloc
  64. return NULL; // fail
  65. }
  66. }
  67. else // couldn't alloc
  68. return NULL; // fail
  69. }
  70. PUBLIC void FAR PASCAL List_Deallocate(ListHandle lh, NPSTR node)
  71. {
  72. Node *myNode;
  73. Node *prevNode;
  74. NPSTR prevElement = NULL;
  75. NPSTR element;
  76. if (ListHandleBad(lh))
  77. return ;
  78. List_Lock(lh);
  79. for(element = List_Get_First(lh); // traverse 'till found or exausted
  80. ((element) && (element != node)) ;
  81. element = List_Get_Next(lh, element) )
  82. prevElement = element;
  83. if (element) // not exausted, must've found it
  84. {
  85. myNode = (Node *) (((LPBYTE) element) - NODEHDRSIZE);
  86. // if was previous element in list, make it point over this one
  87. if (prevElement)
  88. {
  89. prevNode = (Node *) (((LPBYTE) prevElement) - NODEHDRSIZE);
  90. prevNode->next = myNode->next;
  91. }
  92. //make sure this node doesn't remain "first" or "next" node in list
  93. if (arrayOfLists[lh].firstNode == myNode)
  94. arrayOfLists[lh].firstNode = myNode->next;
  95. LocalFree(myNode->handle); // free it
  96. }
  97. List_Unlock(lh);
  98. }
  99. PUBLIC VOID FAR PASCAL List_Destroy(ListHandle lh)
  100. {
  101. Node *myNode;
  102. Node *nextNode;
  103. if (ListHandleBad(lh))
  104. return ;
  105. List_Lock(lh);
  106. myNode = arrayOfLists[lh].firstNode;
  107. while (myNode != NULL) // free each node in list
  108. {
  109. nextNode = myNode->next;
  110. LocalFree(myNode->handle);
  111. myNode = nextNode;
  112. }
  113. arrayOfLists[lh].firstNode = NULL; // forget that you had the list
  114. arrayOfLists[lh].nodeSize = 0L;
  115. List_Unlock(lh);
  116. }
  117. PUBLIC VOID FAR PASCAL List_Attach_Tail(ListHandle lh, NPSTR node)
  118. /* warning--this "node" is ptr to data. true node starts 10 bytes earlier */
  119. {
  120. Node *myNode;
  121. Node *nodeToInsert;
  122. if (ListHandleBad(lh))
  123. return ;
  124. List_Lock(lh);
  125. nodeToInsert = (Node *) (((LPBYTE) node) - NODEHDRSIZE);
  126. myNode = arrayOfLists[lh].firstNode;
  127. if (!myNode) // if list empty, make it first
  128. arrayOfLists[lh].firstNode = nodeToInsert;
  129. else
  130. {
  131. for ( ;(myNode->next != NULL); myNode = myNode->next); // traverse to end
  132. myNode->next = nodeToInsert; // and put it there
  133. }
  134. nodeToInsert->next = NULL; // make sure not pointing to outer space
  135. List_Unlock(lh);
  136. }
  137. PUBLIC NPSTR FAR PASCAL List_Get_First(ListHandle lh)
  138. {
  139. Node *thisNode;
  140. NPSTR retValue;
  141. if (ListHandleBad(lh))
  142. return NULL;
  143. if (thisNode = arrayOfLists[lh].firstNode)
  144. retValue = (NPSTR)thisNode + NODEHDRSIZE;
  145. else
  146. retValue = NULL;
  147. return retValue;
  148. }
  149. PUBLIC NPSTR FAR PASCAL List_Get_Next(ListHandle lh, VOID* node)
  150. {
  151. Node* npNext;
  152. if (ListHandleBad(lh))
  153. return NULL;
  154. if (!node)
  155. return NULL;
  156. npNext = ((Node*)((NPSTR)node - NODEHDRSIZE))->next;
  157. if (npNext)
  158. return (NPSTR)npNext + NODEHDRSIZE;
  159. else
  160. return NULL;
  161. }
  162. #ifdef DEBUG
  163. PUBLIC VOID FAR PASCAL List_Lock(ListHandle lh)
  164. {
  165. if (arrayOfLists[lh].fLocked)
  166. {
  167. dprintf(("**** List code reentered *****"));
  168. DebugBreak();
  169. }
  170. arrayOfLists[lh].fLocked++;
  171. }
  172. PUBLIC VOID FAR PASCAL List_Unlock(ListHandle lh)
  173. {
  174. if (!arrayOfLists[lh].fLocked)
  175. {
  176. dprintf(("**** List code not locked!! HELP!! *****"));
  177. DebugBreak();
  178. }
  179. arrayOfLists[lh].fLocked--;
  180. }
  181. #endif