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.

300 lines
9.0 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: winprop.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * This module contains routines having to do with window properties.
  7. *
  8. * History:
  9. * 11-13-90 DarrinM Created.
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. /***************************************************************************\
  14. * InternalSetProp
  15. *
  16. * SetProp searches the linked-list of window property structures for the
  17. * specified key. If found, the existing property structure is changed to
  18. * hold the new hData handle. If no property is found with the specified key
  19. * a new property structure is created and initialized.
  20. *
  21. * Since property keys are retained as atoms, we convert the incoming pszKey
  22. * to an atom before lookup or storage. pszKey might actually be an atom
  23. * already, so we keep a flag, PROPF_STRING, so we know whether the atom was
  24. * created by the system or whether it was passed in. This way we know
  25. * whether we should destroy it when the property is destroyed.
  26. *
  27. * Several property values are for User's private use. These properties are
  28. * denoted with the flag PROPF_INTERNAL. Depending on the fInternal flag,
  29. * either internal (User) or external (application) properties are set/get/
  30. * removed/enumerated, etc.
  31. *
  32. * History:
  33. * 11-14-90 darrinm Rewrote from scratch with new data structures and
  34. * algorithms.
  35. \***************************************************************************/
  36. BOOL InternalSetProp(
  37. PWND pwnd,
  38. LPWSTR pszKey,
  39. HANDLE hData,
  40. DWORD dwFlags)
  41. {
  42. PPROP pprop;
  43. if (pszKey == NULL) {
  44. RIPERR0(ERROR_INVALID_PARAMETER,
  45. RIP_WARNING,
  46. "Invalid parameter \"pszKey\" (NULL) to InternalSetProp");
  47. return FALSE;
  48. }
  49. /*
  50. * If no property list exists for this window, create one.
  51. */
  52. pprop = _FindProp(pwnd, pszKey, dwFlags & PROPF_INTERNAL);
  53. if (pprop == NULL) {
  54. /*
  55. * pszKey must be an atom within the server.
  56. */
  57. UserAssert(!IS_PTR(pszKey));
  58. /*
  59. * CreateProp allocates the property and links it into the window's
  60. * property list.
  61. */
  62. pprop = CreateProp(pwnd);
  63. if (pprop == NULL)
  64. return FALSE;
  65. pprop->atomKey = PTR_TO_ID(pszKey);
  66. pprop->fs = (WORD)dwFlags;
  67. }
  68. pprop->hData = hData;
  69. return TRUE;
  70. }
  71. /***************************************************************************\
  72. * InternalRemoveProp
  73. *
  74. * Remove the specified property from the specified window's property list.
  75. * The property's hData handle is returned to the caller who can then free
  76. * it or whatever. NOTE: This also applies to internal properties as well --
  77. * InternalRemoveProp will free the property structure and atom (if created
  78. * by User) but will not free the hData itself.
  79. *
  80. * History:
  81. * 11-14-90 darrinm Rewrote from scratch with new data structures and
  82. * algorithms.
  83. \***************************************************************************/
  84. HANDLE InternalRemoveProp(
  85. PWND pwnd,
  86. LPWSTR pszKey,
  87. BOOL fInternal)
  88. {
  89. PPROP pprop;
  90. PPROP ppropLast;
  91. HANDLE hT;
  92. /*
  93. * Find the property to be removed.
  94. */
  95. pprop = _FindProp(pwnd, pszKey, fInternal);
  96. if (pprop == NULL)
  97. return NULL;
  98. /*
  99. * Remember what it was pointing at.
  100. */
  101. hT = pprop->hData;
  102. /*
  103. * Move the property at the end of the list into this slot.
  104. */
  105. pwnd->ppropList->iFirstFree--;
  106. ppropLast = &pwnd->ppropList->aprop[pwnd->ppropList->iFirstFree];
  107. *pprop = *ppropLast;
  108. RtlZeroMemory(ppropLast, sizeof(*ppropLast));
  109. return hT;
  110. }
  111. /***************************************************************************\
  112. * _BuildPropList
  113. *
  114. * This is a unique client/server routine - it builds a list of Props and
  115. * returns it to the client. Unique since the client doesn't know how
  116. * big the list is ahead of time.
  117. *
  118. * 29-Jan-1992 JohnC Created.
  119. \***************************************************************************/
  120. NTSTATUS _BuildPropList(
  121. PWND pwnd,
  122. PROPSET aPropSet[],
  123. UINT cPropMax,
  124. PUINT pcPropNeeded)
  125. {
  126. UINT i;
  127. PPROPLIST ppropList;
  128. PPROP pProp;
  129. DWORD iRetCnt = 0; // The number of Props returned
  130. DWORD iProp = 0;
  131. PPROPSET pPropSetLast = (aPropSet + cPropMax - 1);
  132. NTSTATUS Status;
  133. /*
  134. * If the Window does not have a property list then we're done
  135. */
  136. ppropList = pwnd->ppropList;
  137. if (ppropList == NULL) {
  138. *pcPropNeeded = 0;
  139. return STATUS_SUCCESS;
  140. }
  141. /*
  142. * For each element in the property list enumerate it.
  143. * (only if it is not internal!)
  144. */
  145. Status = STATUS_SUCCESS;
  146. pProp = ppropList->aprop;
  147. for (i = ppropList->iFirstFree; i > 0; i--) {
  148. /*
  149. * if we run out of space in shared memory return
  150. * STATUS_BUFFER_TOO_SMALL
  151. */
  152. if (&aPropSet[iProp] > pPropSetLast) {
  153. /*
  154. * Reset to the beginning of the output
  155. * buffer so we can continue and compute
  156. * the needed space.
  157. */
  158. iProp = 0;
  159. Status = STATUS_BUFFER_TOO_SMALL;
  160. }
  161. if (!(pProp->fs & PROPF_INTERNAL)) {
  162. aPropSet[iProp].hData = pProp->hData;
  163. aPropSet[iProp].atom = pProp->atomKey;
  164. iProp++;
  165. iRetCnt++;
  166. }
  167. pProp++;
  168. }
  169. /*
  170. * Return the number of PROPLISTs given back to the client
  171. */
  172. *pcPropNeeded = iRetCnt;
  173. return Status;
  174. }
  175. /***************************************************************************\
  176. * CreateProp
  177. *
  178. * Create a property structure and link it at the head of the specified
  179. * window's property list.
  180. *
  181. * History:
  182. * 11-14-90 darrinm Rewrote from scratch with new data structures and
  183. * algorithms.
  184. \***************************************************************************/
  185. PPROP CreateProp(
  186. PWND pwnd)
  187. {
  188. PPROPLIST ppropList;
  189. PPROP pprop;
  190. if (pwnd->ppropList == NULL) {
  191. pwnd->ppropList = (PPROPLIST)DesktopAlloc(pwnd->head.rpdesk,
  192. sizeof(PROPLIST),
  193. DTAG_PROPLIST);
  194. if (pwnd->ppropList == NULL) {
  195. return NULL;
  196. }
  197. pwnd->ppropList->cEntries = 1;
  198. } else if (pwnd->ppropList->iFirstFree == pwnd->ppropList->cEntries) {
  199. ppropList = (PPROPLIST)DesktopAlloc(pwnd->head.rpdesk,
  200. sizeof(PROPLIST) + pwnd->ppropList->cEntries * sizeof(PROP),
  201. DTAG_PROPLIST);
  202. if (ppropList == NULL) {
  203. return NULL;
  204. }
  205. RtlCopyMemory(ppropList, pwnd->ppropList, sizeof(PROPLIST) + (pwnd->ppropList->cEntries - 1) * sizeof(PROP));
  206. DesktopFree(pwnd->head.rpdesk, pwnd->ppropList);
  207. pwnd->ppropList = ppropList;
  208. pwnd->ppropList->cEntries++;
  209. }
  210. pprop = &pwnd->ppropList->aprop[pwnd->ppropList->iFirstFree];
  211. pwnd->ppropList->iFirstFree++;
  212. return pprop;
  213. }
  214. /***************************************************************************\
  215. * DeleteProperties
  216. *
  217. * When a window is destroyed we want to destroy all its accompanying
  218. * properties. DestroyProperties does this, including destroying any hData
  219. * that was allocated by User for internal properties. Any atoms created
  220. * along with the properties are destroyed as well. hData in application
  221. * properties are not destroyed automatically; we assume the application
  222. * is taking care of that itself (in its WM_DESTROY handler or similar).
  223. *
  224. * History:
  225. * 11-14-90 darrinm Rewrote from scratch with new data structures and
  226. * algorithms.
  227. \***************************************************************************/
  228. void DeleteProperties(
  229. PWND pwnd)
  230. {
  231. PPROP pprop;
  232. UINT i;
  233. UserAssert(pwnd->ppropList);
  234. /*
  235. * Loop through the whole list of properties on this window.
  236. */
  237. pprop = pwnd->ppropList->aprop;
  238. for (i = pwnd->ppropList->iFirstFree; i > 0; i--) {
  239. /*
  240. * Is this an internal property? If so, free any data we allocated
  241. * for it.
  242. */
  243. if ((pprop->fs & PROPF_INTERNAL) && !(pprop->fs & PROPF_NOPOOL)) {
  244. UserFreePool(pprop->hData);
  245. }
  246. /*
  247. * Advance to the next property in the list.
  248. */
  249. pprop++;
  250. }
  251. /*
  252. * All properties gone, free the property list and clear out the
  253. * window's property list pointer.
  254. */
  255. DesktopFree(pwnd->head.rpdesk, pwnd->ppropList);
  256. pwnd->ppropList = NULL;
  257. }