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.

312 lines
8.9 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] = _T("");
  83. BOOL retval = FALSE;
  84. if (GetModuleFileName(NULL, atszImagePath, MAX_PATH))
  85. {
  86. TCHAR * pch;
  87. LONG len=0; // length of exe name after last separator
  88. LONG N; // length of lpszIn
  89. // Get last component of path
  90. //
  91. // Find the end of the string and determine the string length.
  92. //
  93. for (pch=atszImagePath; *pch; pch++);
  94. DecLpch (atszImagePath, pch); // pch now points to the last real char
  95. while (!IsPathSeparator(*pch)) {
  96. DecLpch (atszImagePath, pch);
  97. len++;
  98. }
  99. // we're at the last separator.
  100. // we want to do an lstrNcmpi (found cases where there was a non-null
  101. // char at the end of the exe name eg. "WINWORD.EXE>#")
  102. N = lstrlen(lpszIn);
  103. if (len > N) { // simulate lstrNcmpi (don't have one available)
  104. //pch+1 is the 0th char after the separator
  105. TCHAR saveChar = *(pch+1+N); // save N+1 th char
  106. *(pch+1+N) = 0;
  107. if (!lstrcmpi(pch+1, lpszIn))
  108. retval = TRUE;
  109. *(pch+1+N) = saveChar; // restore N+1 th char
  110. }
  111. else if (!lstrcmpi(pch+1, lpszIn)) {
  112. retval = TRUE;
  113. }
  114. }
  115. return retval;
  116. }
  117. //+---------------------------------------------------------------------------
  118. //
  119. // Function: TlsThkInitialize
  120. //
  121. // Synopsis: allocates thread data and initialize slot
  122. //
  123. // Returns: Appropriate status code
  124. //
  125. // History: 5-18-94 JohannP (Johann Posch) Created
  126. // 7-14-97 Gopalk Added compatiblity flags
  127. // based on the image name
  128. //
  129. //----------------------------------------------------------------------------
  130. HRESULT TlsThkInitialize(void)
  131. {
  132. PThreadData pThreaddata;
  133. TCHAR pwszImagePath[MAX_PATH];
  134. TCHAR *pch;
  135. thkDebugOut((DEB_THUNKMGR, "In TlsThkInitialize\n"));
  136. thkAssert(dwTlsThkIndex != UNINITIALIZED_INDEX &&
  137. "Tls slot not allocated.");
  138. // We must be uninitialized to call this routine
  139. thkAssert(TlsGetValue(dwTlsThkIndex) == 0);
  140. pThreaddata = (PThreadData) LocalAlloc(LPTR, sizeof (ThreadData));
  141. if(pThreaddata != NULL)
  142. {
  143. // Force construction since we allocated with LocalAlloc
  144. pThreaddata->sa16.CStackAllocator::
  145. CStackAllocator(&mmodel16Owned, 1024, 2);
  146. pThreaddata->sa32.CStackAllocator::
  147. CStackAllocator(&mmodel32, 8192, 8);
  148. pThreaddata->pCThkMgr = 0;
  149. pThreaddata->dwAppCompatFlags = 0;
  150. pThreaddata->pAggHolderList = 0;
  151. if (IsTaskName(TEXT("WINWORD.EXE")) ||
  152. IsTaskName(TEXT("MSWORKS.EXE")) ||
  153. IsTaskName(TEXT("WPWIN61.EXE")) ||
  154. IsTaskName(TEXT("QPW.EXE")) ||
  155. IsTaskName(TEXT("PDOXWIN.EXE")) )
  156. {
  157. thkDebugOut((DEB_WARN, "OleIsCurrentClipBoard hack enabled\n"));
  158. pThreaddata->dwAppCompatFlags |= OACF_WORKSCLIPOBJ;
  159. }
  160. else if (IsTaskName(TEXT("CORELPNT.EXE")))
  161. {
  162. thkDebugOut((DEB_WARN, "CorelPaint 5.0 hack enabled\n"));
  163. pThreaddata->dwAppCompatFlags |= OACF_CRLPNTPERSIST;
  164. }
  165. else if (IsTaskName(TEXT("TEXTART.EXE")))
  166. {
  167. thkDebugOut((DEB_WARN, "TextArt DAHolder::DAdvise hack enabled\n"));
  168. pThreaddata->dwAppCompatFlags |= OACF_TEXTARTDOBJ;
  169. }
  170. TlsSetValue(dwTlsThkIndex, pThreaddata);
  171. }
  172. thkDebugOut((DEB_THUNKMGR, "Out TlsThkInitialize\n"));
  173. return (pThreaddata != NULL) ? NOERROR : E_OUTOFMEMORY;
  174. }
  175. //+---------------------------------------------------------------------------
  176. //
  177. // Function: TlsThkUninitialize
  178. //
  179. // Synopsis: frees thread data and set it to NULL
  180. //
  181. // History: 5-18-94 JohannP (Johann Posch) Created
  182. //
  183. //----------------------------------------------------------------------------
  184. void TlsThkUninitialize(void)
  185. {
  186. thkDebugOut((DEB_TLSTHK, "In TlsThkUninitialize\n"));
  187. // Asserts if data is NULL
  188. PThreadData pThreaddata = TlsThkGetData();
  189. // We should assert that the things in the ThreadData
  190. // are freed up
  191. if (pThreaddata != NULL)
  192. {
  193. // Stack allocators are cleaned up elsewhere
  194. // because they require special treatment
  195. if (pThreaddata->pDelayedRegs != NULL)
  196. {
  197. delete pThreaddata->pDelayedRegs;
  198. }
  199. LocalFree(pThreaddata);
  200. }
  201. TlsSetValue(dwTlsThkIndex, NULL);
  202. thkDebugOut((DEB_TLSTHK, "Out TlsThkUninitialize\n"));
  203. }
  204. //+---------------------------------------------------------------------------
  205. //
  206. // Function: TlsThkFree
  207. //
  208. // Synopsis: frees slot
  209. //
  210. // History: 5-18-94 JohannP (Johann Posch) Created
  211. //
  212. //----------------------------------------------------------------------------
  213. void TlsThkFree(void)
  214. {
  215. thkAssert(dwTlsThkIndex != UNINITIALIZED_INDEX);
  216. TlsFree( dwTlsThkIndex );
  217. // We must set this to an invalid value so any further uses of the
  218. // TLS slot will return NULL
  219. dwTlsThkIndex = UNINITIALIZED_INDEX;
  220. }
  221. //+---------------------------------------------------------------------------
  222. //
  223. // Function: TlsThkLinkAggHolder
  224. //
  225. // Synopsis: Links ProxyHolder node into a list in TLS (used in Aggregation)
  226. //
  227. // History: 2-11-98 MPrabhu Created
  228. //
  229. //----------------------------------------------------------------------------
  230. void TlsThkLinkAggHolder(SAggHolder *pNode)
  231. {
  232. SAggHolder *head = TlsThkGetAggHolderList();
  233. pNode->next = head;
  234. TlsThkSetAggHolderList(pNode);
  235. }
  236. //+---------------------------------------------------------------------------
  237. //
  238. // Function: TlsThkGetAggHolder
  239. //
  240. // Synopsis: Gets the last ProxyHolder node that was linked into TLS list
  241. //
  242. // History: 2-11-98 MPrabhu Created
  243. //
  244. //----------------------------------------------------------------------------
  245. SAggHolder* TlsThkGetAggHolder(void)
  246. {
  247. SAggHolder *head = TlsThkGetAggHolderList();
  248. thkAssert(head);
  249. return head;
  250. }
  251. //+---------------------------------------------------------------------------
  252. //
  253. // Function: TlsThkGetAggHolder
  254. //
  255. // Synopsis: Unlinks the last ProxyHolder node that was linked into TLS list
  256. //
  257. // History: 2-11-98 MPrabhu Created
  258. //
  259. //----------------------------------------------------------------------------
  260. void TlsThkUnlinkAggHolder(void)
  261. {
  262. SAggHolder *head = TlsThkGetAggHolderList();
  263. thkAssert(head);
  264. TlsThkSetAggHolderList(head->next);
  265. }