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.

315 lines
9.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: tlsthk.cxx
  7. //
  8. // Contents: Utility routines for logical thread data
  9. //
  10. // History: 5-18-94 JohannP (Johann Posch) Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "headers.cxx"
  14. #pragma hdrstop
  15. #define UNINITIALIZED_INDEX (0xffffffff)
  16. DWORD dwTlsThkIndex = UNINITIALIZED_INDEX;
  17. //+---------------------------------------------------------------------------
  18. //
  19. // Function: TlsThkGetData
  20. //
  21. // Synopsis: returns pointer to thread data
  22. //
  23. // Returns: pointer to threaddata
  24. //
  25. // History: 5-18-94 JohannP (Johann Posch) Created
  26. //
  27. //----------------------------------------------------------------------------
  28. #if DBG == 1
  29. PThreadData TlsThkGetData(void)
  30. {
  31. if (dwTlsThkIndex == UNINITIALIZED_INDEX)
  32. {
  33. thkDebugOut((DEB_WARN, "WARNING: TLS slot used when uninitialized\n"));
  34. }
  35. PThreadData pThreaddata = (PThreadData) TlsGetValue(dwTlsThkIndex);
  36. return pThreaddata;
  37. }
  38. #endif
  39. //+---------------------------------------------------------------------------
  40. //
  41. // Function: TlsThkAlloc
  42. //
  43. // Synopsis: allocates a slot for thread data
  44. //
  45. // Returns: BOOL
  46. //
  47. // History: 5-18-94 JohannP (Johann Posch) Created
  48. //
  49. //----------------------------------------------------------------------------
  50. BOOL TlsThkAlloc(void)
  51. {
  52. thkDebugOut((DEB_THUNKMGR, "In TlsThkAlloc\n"));
  53. // We must be uninitialized to call this routine
  54. thkAssert(dwTlsThkIndex == UNINITIALIZED_INDEX);
  55. dwTlsThkIndex = TlsAlloc();
  56. if (dwTlsThkIndex == UNINITIALIZED_INDEX)
  57. {
  58. return FALSE;
  59. }
  60. thkDebugOut((DEB_THUNKMGR, "Out TlsThkAlloc\n"));
  61. return TRUE;
  62. }
  63. //+-------------------------------------------------------------------------
  64. //
  65. // Function: GetTaskName
  66. //
  67. // Synopsis: Obtain the 16-bit task name
  68. //
  69. // Author: July 14,97 Gopalk Created
  70. //
  71. //--------------------------------------------------------------------------
  72. // these 2 from com\inc\ole2int.h
  73. #define IncLpch(sz) ((sz)=CharNext ((sz)))
  74. #define DecLpch(szStart, sz) ((sz)=CharPrev ((szStart),(sz)))
  75. // Helper function for IsTaskName
  76. inline BOOL IsPathSeparator( WCHAR ch )
  77. {
  78. return (ch == TCHAR('\\') || ch == TCHAR('/') || ch == TCHAR(':'));
  79. }
  80. FARINTERNAL_(BOOL) IsTaskName(LPCTSTR lpszIn)
  81. {
  82. TCHAR atszImagePath[MAX_PATH+1] = _T("");
  83. BOOL retval = FALSE;
  84. int cChars = GetModuleFileName(NULL, atszImagePath, sizeof(atszImagePath)/sizeof(atszImagePath[0]));
  85. atszImagePath[sizeof(atszImagePath)/sizeof(atszImagePath[0])-1] = _T('\0');
  86. if (cChars != 0 && cChars != MAX_PATH)
  87. {
  88. TCHAR * pch;
  89. LONG len=0; // length of exe name after last separator
  90. LONG N; // length of lpszIn
  91. // Get last component of path
  92. //
  93. // Find the end of the string and determine the string length.
  94. //
  95. for (pch=atszImagePath; *pch; pch++);
  96. DecLpch (atszImagePath, pch); // pch now points to the last real char
  97. while (!IsPathSeparator(*pch)) {
  98. DecLpch (atszImagePath, pch);
  99. len++;
  100. }
  101. // we're at the last separator.
  102. // we want to do an lstrNcmpi (found cases where there was a non-null
  103. // char at the end of the exe name eg. "WINWORD.EXE>#")
  104. N = lstrlen(lpszIn);
  105. if (len > N) { // simulate lstrNcmpi (don't have one available)
  106. //pch+1 is the 0th char after the separator
  107. TCHAR saveChar = *(pch+1+N); // save N+1 th char
  108. *(pch+1+N) = 0;
  109. if (!lstrcmpi(pch+1, lpszIn))
  110. retval = TRUE;
  111. *(pch+1+N) = saveChar; // restore N+1 th char
  112. }
  113. else if (!lstrcmpi(pch+1, lpszIn)) {
  114. retval = TRUE;
  115. }
  116. }
  117. return retval;
  118. }
  119. //+---------------------------------------------------------------------------
  120. //
  121. // Function: TlsThkInitialize
  122. //
  123. // Synopsis: allocates thread data and initialize slot
  124. //
  125. // Returns: Appropriate status code
  126. //
  127. // History: 5-18-94 JohannP (Johann Posch) Created
  128. // 7-14-97 Gopalk Added compatiblity flags
  129. // based on the image name
  130. //
  131. //----------------------------------------------------------------------------
  132. HRESULT TlsThkInitialize(void)
  133. {
  134. PThreadData pThreaddata;
  135. TCHAR *pch;
  136. thkDebugOut((DEB_THUNKMGR, "In TlsThkInitialize\n"));
  137. thkAssert(dwTlsThkIndex != UNINITIALIZED_INDEX &&
  138. "Tls slot not allocated.");
  139. // We must be uninitialized to call this routine
  140. thkAssert(TlsGetValue(dwTlsThkIndex) == 0);
  141. pThreaddata = (PThreadData) LocalAlloc(LPTR, sizeof (ThreadData));
  142. if(pThreaddata != NULL)
  143. {
  144. // Force construction since we allocated with LocalAlloc
  145. pThreaddata->sa16.CStackAllocator::
  146. CStackAllocator(&mmodel16Owned, 1024, 2);
  147. pThreaddata->sa32.CStackAllocator::
  148. CStackAllocator(&mmodel32, 8192, 8);
  149. pThreaddata->pCThkMgr = 0;
  150. pThreaddata->dwAppCompatFlags = 0;
  151. pThreaddata->pAggHolderList = 0;
  152. if (IsTaskName(TEXT("WINWORD.EXE")) ||
  153. IsTaskName(TEXT("MSWORKS.EXE")) ||
  154. IsTaskName(TEXT("WPWIN61.EXE")) ||
  155. IsTaskName(TEXT("QPW.EXE")) ||
  156. IsTaskName(TEXT("PDOXWIN.EXE")) )
  157. {
  158. thkDebugOut((DEB_WARN, "OleIsCurrentClipBoard hack enabled\n"));
  159. pThreaddata->dwAppCompatFlags |= OACF_WORKSCLIPOBJ;
  160. }
  161. else if (IsTaskName(TEXT("CORELPNT.EXE")))
  162. {
  163. thkDebugOut((DEB_WARN, "CorelPaint 5.0 hack enabled\n"));
  164. pThreaddata->dwAppCompatFlags |= OACF_CRLPNTPERSIST;
  165. }
  166. else if (IsTaskName(TEXT("TEXTART.EXE")))
  167. {
  168. thkDebugOut((DEB_WARN, "TextArt DAHolder::DAdvise hack enabled\n"));
  169. pThreaddata->dwAppCompatFlags |= OACF_TEXTARTDOBJ;
  170. }
  171. TlsSetValue(dwTlsThkIndex, pThreaddata);
  172. }
  173. thkDebugOut((DEB_THUNKMGR, "Out TlsThkInitialize\n"));
  174. return (pThreaddata != NULL) ? NOERROR : E_OUTOFMEMORY;
  175. }
  176. //+---------------------------------------------------------------------------
  177. //
  178. // Function: TlsThkUninitialize
  179. //
  180. // Synopsis: frees thread data and set it to NULL
  181. //
  182. // History: 5-18-94 JohannP (Johann Posch) Created
  183. //
  184. //----------------------------------------------------------------------------
  185. void TlsThkUninitialize(void)
  186. {
  187. thkDebugOut((DEB_TLSTHK, "In TlsThkUninitialize\n"));
  188. // Asserts if data is NULL
  189. PThreadData pThreaddata = TlsThkGetData();
  190. // We should assert that the things in the ThreadData
  191. // are freed up
  192. if (pThreaddata != NULL)
  193. {
  194. // Stack allocators are cleaned up elsewhere
  195. // because they require special treatment
  196. if (pThreaddata->pDelayedRegs != NULL)
  197. {
  198. delete pThreaddata->pDelayedRegs;
  199. }
  200. LocalFree(pThreaddata);
  201. }
  202. TlsSetValue(dwTlsThkIndex, NULL);
  203. thkDebugOut((DEB_TLSTHK, "Out TlsThkUninitialize\n"));
  204. }
  205. //+---------------------------------------------------------------------------
  206. //
  207. // Function: TlsThkFree
  208. //
  209. // Synopsis: frees slot
  210. //
  211. // History: 5-18-94 JohannP (Johann Posch) Created
  212. //
  213. //----------------------------------------------------------------------------
  214. void TlsThkFree(void)
  215. {
  216. thkAssert(dwTlsThkIndex != UNINITIALIZED_INDEX);
  217. TlsFree( dwTlsThkIndex );
  218. // We must set this to an invalid value so any further uses of the
  219. // TLS slot will return NULL
  220. dwTlsThkIndex = UNINITIALIZED_INDEX;
  221. }
  222. //+---------------------------------------------------------------------------
  223. //
  224. // Function: TlsThkLinkAggHolder
  225. //
  226. // Synopsis: Links ProxyHolder node into a list in TLS (used in Aggregation)
  227. //
  228. // History: 2-11-98 MPrabhu Created
  229. //
  230. //----------------------------------------------------------------------------
  231. void TlsThkLinkAggHolder(SAggHolder *pNode)
  232. {
  233. SAggHolder *head = TlsThkGetAggHolderList();
  234. pNode->next = head;
  235. TlsThkSetAggHolderList(pNode);
  236. }
  237. //+---------------------------------------------------------------------------
  238. //
  239. // Function: TlsThkGetAggHolder
  240. //
  241. // Synopsis: Gets the last ProxyHolder node that was linked into TLS list
  242. //
  243. // History: 2-11-98 MPrabhu Created
  244. //
  245. //----------------------------------------------------------------------------
  246. SAggHolder* TlsThkGetAggHolder(void)
  247. {
  248. SAggHolder *head = TlsThkGetAggHolderList();
  249. thkAssert(head);
  250. return head;
  251. }
  252. //+---------------------------------------------------------------------------
  253. //
  254. // Function: TlsThkGetAggHolder
  255. //
  256. // Synopsis: Unlinks the last ProxyHolder node that was linked into TLS list
  257. //
  258. // History: 2-11-98 MPrabhu Created
  259. //
  260. //----------------------------------------------------------------------------
  261. void TlsThkUnlinkAggHolder(void)
  262. {
  263. SAggHolder *head = TlsThkGetAggHolderList();
  264. thkAssert(head);
  265. TlsThkSetAggHolderList(head->next);
  266. }