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.

278 lines
7.9 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: util.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * DDE Manager general utility functions (and some JANUS stuff).
  7. *
  8. * Created: 11/3/91 Sanford Staab
  9. \***************************************************************************/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. /***************************************************************************\
  13. * AddLink
  14. *
  15. * Description:
  16. * Adds an advise link to the conversation's info.
  17. *
  18. * History:
  19. * 11-19-91 sanfords Created.
  20. \***************************************************************************/
  21. BOOL
  22. AddLink(
  23. PCONV_INFO pcoi,
  24. GATOM gaItem,
  25. WORD wFmt,
  26. WORD wType)
  27. {
  28. PADVISE_LINK aLinkNew;
  29. int cLinks;
  30. LATOM la;
  31. PCL_INSTANCE_INFO pcii;
  32. /*
  33. * if the link already exists, update its flags, otherwise create a
  34. * new one.
  35. */
  36. aLinkNew = pcoi->aLinks;
  37. cLinks = pcoi->cLinks;
  38. la = GlobalToLocalAtom(gaItem); // aLinkNew copy
  39. while (cLinks) {
  40. if (aLinkNew->laItem == la && aLinkNew->wFmt == wFmt) {
  41. aLinkNew->wType = wType;
  42. aLinkNew->state = 0;
  43. DeleteAtom(la);
  44. return TRUE;
  45. }
  46. aLinkNew++;
  47. cLinks--;
  48. }
  49. if (pcoi->aLinks == NULL) {
  50. aLinkNew = (PADVISE_LINK)DDEMLAlloc(sizeof(ADVISE_LINK));
  51. } else {
  52. aLinkNew = (PADVISE_LINK)DDEMLReAlloc(pcoi->aLinks,
  53. sizeof(ADVISE_LINK) * (pcoi->cLinks + 1));
  54. }
  55. if (aLinkNew == NULL) {
  56. SetLastDDEMLError(pcoi->pcii, DMLERR_MEMORY_ERROR);
  57. DeleteAtom(la);
  58. return FALSE;
  59. }
  60. pcoi->aLinks = aLinkNew;
  61. aLinkNew += pcoi->cLinks;
  62. pcoi->cLinks++;
  63. aLinkNew->laItem = la;
  64. aLinkNew->wFmt = wFmt;
  65. aLinkNew->wType = wType;
  66. aLinkNew->state = 0;
  67. if (!(pcoi->state & ST_CLIENT)) {
  68. /*
  69. * Add count for this link
  70. */
  71. pcii = pcoi->pcii;
  72. for (aLinkNew->pLinkCount = pcii->pLinkCount;
  73. aLinkNew->pLinkCount;
  74. aLinkNew->pLinkCount = aLinkNew->pLinkCount->next) {
  75. if (aLinkNew->pLinkCount->laTopic == pcoi->laTopic &&
  76. aLinkNew->pLinkCount->gaItem == gaItem &&
  77. aLinkNew->pLinkCount->wFmt == wFmt) {
  78. aLinkNew->pLinkCount->Total++;
  79. return(TRUE);
  80. }
  81. }
  82. /*
  83. * Not found - add an entry
  84. */
  85. aLinkNew->pLinkCount = (PLINK_COUNT)DDEMLAlloc(sizeof(LINK_COUNT));
  86. if (aLinkNew->pLinkCount == NULL) {
  87. SetLastDDEMLError(pcoi->pcii, DMLERR_MEMORY_ERROR);
  88. return FALSE;
  89. }
  90. aLinkNew->pLinkCount->next = pcii->pLinkCount;
  91. pcii->pLinkCount = aLinkNew->pLinkCount;
  92. aLinkNew->pLinkCount->laTopic = IncLocalAtomCount(pcoi->laTopic); // LinkCount copy
  93. aLinkNew->pLinkCount->gaItem = IncGlobalAtomCount(gaItem); // LinkCount copy
  94. aLinkNew->pLinkCount->laItem = IncLocalAtomCount(la); // LinkCount copy
  95. aLinkNew->pLinkCount->wFmt = wFmt;
  96. aLinkNew->pLinkCount->Total = 1;
  97. // doesn't matter: aLinkNew->pLinkCount->Count = 0;
  98. }
  99. return TRUE;
  100. }
  101. /*
  102. * The LinkCount array is a list of all active links grouped by topic
  103. * and item. The Total field is the number of active links total for
  104. * that particular topic/item pair for the entire instance. The count
  105. * field is used to properly set up the links to go field of the XTYP_ADVREQ
  106. * callback. Whenever links are added or removed, DeleteLinkCount or
  107. * AddLink need to be called to keep thses counts correct.
  108. */
  109. VOID
  110. DeleteLinkCount(
  111. PCL_INSTANCE_INFO pcii,
  112. PLINK_COUNT pLinkCountDelete)
  113. {
  114. PLINK_COUNT pLinkCount, pLinkCountPrev;
  115. if (--pLinkCountDelete->Total != 0) {
  116. return;
  117. }
  118. pLinkCountPrev = NULL;
  119. pLinkCount = pcii->pLinkCount;
  120. while (pLinkCount) {
  121. if (pLinkCount == pLinkCountDelete) {
  122. GlobalDeleteAtom(pLinkCount->gaItem);
  123. DeleteAtom(pLinkCount->laItem);
  124. DeleteAtom(pLinkCount->laTopic);
  125. if (pLinkCountPrev == NULL) {
  126. pcii->pLinkCount = pLinkCount->next;
  127. } else {
  128. pLinkCountPrev->next = pLinkCount->next;
  129. }
  130. DDEMLFree(pLinkCount);
  131. return;
  132. }
  133. pLinkCountPrev = pLinkCount;
  134. pLinkCount = pLinkCount->next;
  135. }
  136. }
  137. /***************************************************************************\
  138. * GetTokenHandle
  139. *
  140. * Get handle of token for current thread.
  141. \***************************************************************************/
  142. BOOL
  143. GetTokenHandle(
  144. PHANDLE pTokenHandle)
  145. {
  146. if (!OpenThreadToken(GetCurrentThread(),
  147. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  148. TRUE,
  149. pTokenHandle)) {
  150. if (GetLastError() == ERROR_NO_TOKEN) {
  151. /*
  152. * This means we are not impersonating anybody. Instead, let's
  153. * get the token out of the process.
  154. */
  155. if (!OpenProcessToken(GetCurrentProcess(),
  156. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  157. pTokenHandle)) {
  158. return FALSE;
  159. }
  160. } else {
  161. return FALSE;
  162. }
  163. }
  164. return TRUE;
  165. }
  166. /***************************************************************************\
  167. * GetUserSid
  168. *
  169. * Well, actually it gets a pointer to a newly allocated TOKEN_USER,
  170. * which contains a SID, somewhere.
  171. * Caller must remember to free it when it's been used.
  172. *
  173. * History:
  174. * 10-16-98 Chienho stole from spooler
  175. *
  176. \***************************************************************************/
  177. BOOL
  178. GetUserSid(
  179. PTOKEN_USER *ppTokenUser)
  180. {
  181. HANDLE TokenHandle;
  182. PTOKEN_USER pTokenUser = NULL;
  183. DWORD cbTokenUser = 0;
  184. DWORD cbNeeded;
  185. BOOL bRet = FALSE;
  186. if (!GetTokenHandle(&TokenHandle)) {
  187. return FALSE;
  188. }
  189. bRet = GetTokenInformation(TokenHandle,
  190. TokenUser,
  191. pTokenUser,
  192. cbTokenUser,
  193. &cbNeeded);
  194. /*
  195. * We've passed a NULL pointer and 0 for the amount of memory
  196. * allocated. We expect to fail with bRet = FALSE and
  197. * GetLastError = ERROR_INSUFFICIENT_BUFFER. If we do not
  198. * have these conditions we will return FALSE.
  199. */
  200. if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
  201. pTokenUser = UserLocalAlloc(HEAP_ZERO_MEMORY, cbNeeded);
  202. if (pTokenUser == NULL) {
  203. goto GetUserSidDone;
  204. }
  205. cbTokenUser = cbNeeded;
  206. bRet = GetTokenInformation(TokenHandle,
  207. TokenUser,
  208. pTokenUser,
  209. cbTokenUser,
  210. &cbNeeded);
  211. } else {
  212. /*
  213. * Any other case -- return FALSE.
  214. */
  215. bRet = FALSE;
  216. }
  217. GetUserSidDone:
  218. if (bRet == TRUE) {
  219. *ppTokenUser = pTokenUser;
  220. } else if (pTokenUser != NULL) {
  221. UserLocalFree(pTokenUser);
  222. }
  223. CloseHandle(TokenHandle);
  224. return bRet;
  225. }
  226. BOOL
  227. GetCurrentProcessName(
  228. WCHAR *pszProcessName,
  229. int cch)
  230. {
  231. BOOL bRetVal;
  232. if (GetModuleFileName(NULL, pszProcessName, MAX_PATH)) {
  233. WCHAR *pwcs = wcsrchr(pszProcessName, TEXT('\\'));
  234. if (pwcs != NULL) {
  235. ++pwcs;
  236. lstrcpy(pszProcessName, pwcs);
  237. }
  238. bRetVal = TRUE;
  239. } else {
  240. LoadString(hmodUser, STR_UNKNOWN, pszProcessName, cch);
  241. bRetVal = FALSE;
  242. }
  243. return bRetVal;
  244. }