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.

288 lines
6.8 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
  4. //
  5. // Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
  6. //
  7. // Other brand and product names used herein are trademarks of their respective owners.
  8. //
  9. // The entire program and user interface including the structure, sequence, selection,
  10. // and arrangement of the dialog, the exclusively "yes" and "no" choices represented
  11. // by "1" and "2," and each dialog message are protected by copyrights registered in
  12. // the United States and by international treaties.
  13. //
  14. // Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
  15. // 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
  16. //
  17. // Active Voice Corporation
  18. // Seattle, Washington
  19. // USA
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////////////
  22. ////
  23. // stack.c - stack functions
  24. ////
  25. #include "winlocal.h"
  26. #include "stack.h"
  27. #include "list.h"
  28. #include "mem.h"
  29. #include "trace.h"
  30. ////
  31. // private definitions
  32. ////
  33. // stack
  34. //
  35. typedef struct STACK
  36. {
  37. DWORD dwVersion;
  38. HINSTANCE hInst;
  39. HTASK hTask;
  40. HLIST hList;
  41. } STACK, FAR *LPSTACK;
  42. // helper functions
  43. //
  44. static LPSTACK StackGetPtr(HSTACK hStack);
  45. static HSTACK StackGetHandle(LPSTACK lpStack);
  46. ////
  47. // public functions
  48. ////
  49. ////
  50. // stack constructor and destructor functions
  51. ////
  52. // StackCreate - stack constructor
  53. // <dwVersion> (i) must be STACK_VERSION
  54. // <hInst> (i) instance handle of calling module
  55. // return new stack handle (NULL if error)
  56. //
  57. HSTACK DLLEXPORT WINAPI StackCreate(DWORD dwVersion, HINSTANCE hInst)
  58. {
  59. BOOL fSuccess = TRUE;
  60. LPSTACK lpStack = NULL;
  61. if (dwVersion != STACK_VERSION)
  62. fSuccess = TraceFALSE(NULL);
  63. else if (hInst == NULL)
  64. fSuccess = TraceFALSE(NULL);
  65. else if ((lpStack = (LPSTACK) MemAlloc(NULL, sizeof(STACK), 0)) == NULL)
  66. fSuccess = TraceFALSE(NULL);
  67. else if ((lpStack->hList = ListCreate(LIST_VERSION, hInst)) == NULL)
  68. fSuccess = TraceFALSE(NULL);
  69. else
  70. {
  71. // initially the stack is empty
  72. //
  73. lpStack->dwVersion = dwVersion;
  74. lpStack->hInst = hInst;
  75. lpStack->hTask = GetCurrentTask();
  76. }
  77. if (!fSuccess)
  78. {
  79. StackDestroy(StackGetHandle(lpStack));
  80. lpStack = NULL;
  81. }
  82. return fSuccess ? StackGetHandle(lpStack) : NULL;
  83. }
  84. // StackDestroy - stack destructor
  85. // <hStack> (i) handle returned from StackCreate
  86. // return 0 if success
  87. //
  88. int DLLEXPORT WINAPI StackDestroy(HSTACK hStack)
  89. {
  90. BOOL fSuccess = TRUE;
  91. LPSTACK lpStack;
  92. if ((lpStack = StackGetPtr(hStack)) == NULL)
  93. fSuccess = TraceFALSE(NULL);
  94. else if (ListDestroy(lpStack->hList) != 0)
  95. fSuccess = TraceFALSE(NULL);
  96. else if ((lpStack = MemFree(NULL, lpStack)) != NULL)
  97. fSuccess = TraceFALSE(NULL);
  98. return fSuccess ? 0 : -1;
  99. }
  100. ////
  101. // stack status functions
  102. ////
  103. // StackGetCount - return count of nodes in stack
  104. // <hStack> (i) handle returned from StackCreate
  105. // return node count (-1 if error)
  106. //
  107. long DLLEXPORT WINAPI StackGetCount(HSTACK hStack)
  108. {
  109. BOOL fSuccess = TRUE;
  110. LPSTACK lpStack;
  111. long cNodes;
  112. if ((lpStack = StackGetPtr(hStack)) == NULL)
  113. fSuccess = TraceFALSE(NULL);
  114. else if ((cNodes = ListGetCount(lpStack->hList)) < 0)
  115. fSuccess = TraceFALSE(NULL);
  116. return fSuccess ? cNodes : -1;
  117. }
  118. // StackIsEmpty - return TRUE if stack has no nodes
  119. // <hStack> (i) handle returned from StackCreate
  120. // return TRUE or FALSE
  121. //
  122. BOOL DLLEXPORT WINAPI StackIsEmpty(HSTACK hStack)
  123. {
  124. BOOL fSuccess = TRUE;
  125. LPSTACK lpStack;
  126. if ((lpStack = StackGetPtr(hStack)) == NULL)
  127. fSuccess = TraceFALSE(NULL);
  128. return fSuccess ? ListIsEmpty(lpStack->hList) : TRUE;
  129. }
  130. ////
  131. // stack element insertion functions
  132. ////
  133. // StackPush - add new node with data <elem> to bottom of stack
  134. // <hStack> (i) handle returned from StackCreate
  135. // <elem> (i) new data element
  136. // returns 0 if success
  137. //
  138. int DLLEXPORT WINAPI StackPush(HSTACK hStack, STACKELEM elem)
  139. {
  140. BOOL fSuccess = TRUE;
  141. LPSTACK lpStack;
  142. if ((lpStack = StackGetPtr(hStack)) == NULL)
  143. fSuccess = TraceFALSE(NULL);
  144. else if (ListAddHead(lpStack->hList, elem) == NULL)
  145. fSuccess = TraceFALSE(NULL);
  146. return fSuccess ? 0 : -1;
  147. }
  148. ////
  149. // stack element removal functions
  150. ////
  151. // StackPop - remove node from bottom of stack
  152. // <hStack> (i) handle returned from StackCreate
  153. // returns removed data element (NULL of error or empty)
  154. //
  155. STACKELEM DLLEXPORT WINAPI StackPop(HSTACK hStack)
  156. {
  157. BOOL fSuccess = TRUE;
  158. LPSTACK lpStack;
  159. if ((lpStack = StackGetPtr(hStack)) == NULL)
  160. fSuccess = TraceFALSE(NULL);
  161. else if (ListIsEmpty(lpStack->hList))
  162. fSuccess = TraceFALSE(NULL);
  163. return fSuccess ? (STACKELEM) ListRemoveHead(lpStack->hList) : NULL;
  164. }
  165. // StackRemoveAll - remove all nodes from stack
  166. // <hStack> (i) handle returned from StackCreate
  167. // return 0 if success
  168. //
  169. int DLLEXPORT WINAPI StackRemoveAll(HSTACK hStack)
  170. {
  171. BOOL fSuccess = TRUE;
  172. LPSTACK lpStack;
  173. if ((lpStack = StackGetPtr(hStack)) == NULL)
  174. fSuccess = TraceFALSE(NULL);
  175. else if (ListRemoveAll(lpStack->hList) != 0)
  176. fSuccess = TraceFALSE(NULL);
  177. return fSuccess ? 0 : -1;
  178. }
  179. ////
  180. // stack element get value functions
  181. ////
  182. // StackPeek - return node from bottom of stack, but leave it on stack
  183. // <hStack> (i) handle returned from StackCreate
  184. // returns data element (NULL if error or empty)
  185. //
  186. STACKELEM DLLEXPORT WINAPI StackPeek(HSTACK hStack)
  187. {
  188. BOOL fSuccess = TRUE;
  189. LPSTACK lpStack;
  190. if ((lpStack = StackGetPtr(hStack)) == NULL)
  191. fSuccess = TraceFALSE(NULL);
  192. else if (ListIsEmpty(lpStack->hList))
  193. fSuccess = TraceFALSE(NULL);
  194. return fSuccess ? (STACKELEM) ListGetHead(lpStack->hList) : NULL;
  195. }
  196. ////
  197. // private functions
  198. ////
  199. // StackGetPtr - verify that stack handle is valid,
  200. // <hStack> (i) handle returned from StackCreate
  201. // return corresponding stack pointer (NULL if error)
  202. //
  203. static LPSTACK StackGetPtr(HSTACK hStack)
  204. {
  205. BOOL fSuccess = TRUE;
  206. LPSTACK lpStack;
  207. if ((lpStack = (LPSTACK) hStack) == NULL)
  208. fSuccess = TraceFALSE(NULL);
  209. else if (IsBadWritePtr(lpStack, sizeof(STACK)))
  210. fSuccess = TraceFALSE(NULL);
  211. #ifdef CHECKTASK
  212. // make sure current task owns the stack handle
  213. //
  214. else if (lpStack->hTask != GetCurrentTask())
  215. fSuccess = TraceFALSE(NULL);
  216. #endif
  217. return fSuccess ? lpStack : NULL;
  218. }
  219. // StackGetHandle - verify that stack pointer is valid,
  220. // <lpStack> (i) pointer to STACK struct
  221. // return corresponding stack handle (NULL if error)
  222. //
  223. static HSTACK StackGetHandle(LPSTACK lpStack)
  224. {
  225. BOOL fSuccess = TRUE;
  226. HSTACK hStack;
  227. if ((hStack = (HSTACK) lpStack) == NULL)
  228. fSuccess = TraceFALSE(NULL);
  229. return fSuccess ? hStack : NULL;
  230. }