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.

907 lines
33 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLCONV_H__
  11. #define __ATLCONV_H__
  12. #ifndef __cplusplus
  13. #error ATL requires C++ compilation (use a .cpp suffix)
  14. #endif
  15. #include <atldef.h>
  16. #ifndef _INC_MALLOC
  17. #include <malloc.h>
  18. #endif // _INC_MALLOC
  19. #pragma pack(push,8)
  20. namespace ATL
  21. {
  22. namespace _ATL_SAFE_ALLOCA_IMPL
  23. {
  24. // Following code is to avoid alloca causing a stack overflow.
  25. // It is intended for use from the _ATL_SAFE_ALLOCA macros
  26. // or Conversion macros.
  27. __declspec(selectany) DWORD _Atlosplatform = 0;
  28. inline BOOL _AtlGetVersionEx()
  29. {
  30. OSVERSIONINFO osi;
  31. memset(&osi, 0, sizeof(OSVERSIONINFO));
  32. osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  33. GetVersionEx(&osi);
  34. _Atlosplatform = osi.dwPlatformId;
  35. return TRUE;
  36. }
  37. // From VC7 CRT sources.
  38. #define _ATL_MIN_STACK_REQ_WIN9X 0x11000
  39. #define _ATL_MIN_STACK_REQ_WINNT 0x2000
  40. /***
  41. * void _resetstkoflw(void) - Recovers from Stack Overflow
  42. *
  43. * Purpose:
  44. * Sets the guard page to its position before the stack overflow.
  45. *
  46. * Exit:
  47. * Returns nonzero on success, zero on failure
  48. *
  49. *******************************************************************************/
  50. inline int _Atlresetstkoflw(void)
  51. {
  52. static BOOL bTemp = _AtlGetVersionEx();
  53. LPBYTE pStack, pGuard, pStackBase, pMaxGuard, pMinGuard;
  54. MEMORY_BASIC_INFORMATION mbi;
  55. SYSTEM_INFO si;
  56. DWORD PageSize;
  57. DWORD flNewProtect;
  58. DWORD flOldProtect;
  59. // Use _alloca() to get the current stack pointer
  60. pStack = (LPBYTE)_alloca(1);
  61. // Find the base of the stack.
  62. if (VirtualQuery(pStack, &mbi, sizeof mbi) == 0)
  63. return 0;
  64. pStackBase = (LPBYTE)mbi.AllocationBase;
  65. // Find the page just below where the stack pointer currently points.
  66. // This is the highest potential guard page.
  67. GetSystemInfo(&si);
  68. PageSize = si.dwPageSize;
  69. pMaxGuard = (LPBYTE) (((DWORD_PTR)pStack & ~(DWORD_PTR)(PageSize - 1))
  70. - PageSize);
  71. // If the potential guard page is too close to the start of the stack
  72. // region, abandon the reset effort for lack of space. Win9x has a
  73. // larger reserved stack requirement.
  74. pMinGuard = pStackBase + ((_Atlosplatform == VER_PLATFORM_WIN32_WINDOWS)
  75. ? _ATL_MIN_STACK_REQ_WIN9X
  76. : _ATL_MIN_STACK_REQ_WINNT);
  77. if (pMaxGuard < pMinGuard)
  78. return 0;
  79. // On a non-Win9x system, do nothing if a guard page is already present,
  80. // else set up the guard page to the bottom of the committed range.
  81. // For Win9x, just set guard page below the current stack page.
  82. if (_Atlosplatform != VER_PLATFORM_WIN32_WINDOWS) {
  83. // Find first block of committed memory in the stack region
  84. pGuard = pStackBase;
  85. do {
  86. if (VirtualQuery(pGuard, &mbi, sizeof mbi) == 0)
  87. return 0;
  88. pGuard = pGuard + mbi.RegionSize;
  89. } while ((mbi.State & MEM_COMMIT) == 0);
  90. pGuard = (LPBYTE)mbi.BaseAddress;
  91. // If first committed block is already marked as a guard page,
  92. // there is nothing that needs to be done, so return success.
  93. if (mbi.Protect & PAGE_GUARD)
  94. return 1;
  95. // Fail if the first committed block is above the highest potential
  96. // guard page. Should never happen.
  97. if (pMaxGuard < pGuard)
  98. return 0;
  99. // Make sure to leave enough room so the next overflow will have
  100. // the proper reserved stack requirement available.
  101. if (pGuard < pMinGuard)
  102. pGuard = pMinGuard;
  103. VirtualAlloc(pGuard, PageSize, MEM_COMMIT, PAGE_READWRITE);
  104. }
  105. else {
  106. pGuard = pMaxGuard;
  107. }
  108. // Enable the new guard page.
  109. flNewProtect = _Atlosplatform == VER_PLATFORM_WIN32_WINDOWS
  110. ? PAGE_NOACCESS
  111. : PAGE_READWRITE | PAGE_GUARD;
  112. return VirtualProtect(pGuard, PageSize, flNewProtect, &flOldProtect);
  113. }
  114. #ifndef _ATL_STACK_MARGIN
  115. #define _ATL_STACK_MARGIN 0x2000 // Minimum stack space available after allocaiton with _ATL_SAFE_ALLOCA
  116. #endif
  117. // Verifies if sufficient space is available on the stack.
  118. inline bool _AtlVerifyStackAvailable(SIZE_T Size)
  119. {
  120. bool bStackAvailable = true;
  121. __try
  122. {
  123. PVOID p = _alloca(Size + _ATL_STACK_MARGIN);
  124. p;
  125. }
  126. __except ((EXCEPTION_STACK_OVERFLOW == GetExceptionCode()) ?
  127. EXCEPTION_EXECUTE_HANDLER :
  128. EXCEPTION_CONTINUE_SEARCH)
  129. {
  130. bStackAvailable = false;
  131. _Atlresetstkoflw();
  132. }
  133. return bStackAvailable;
  134. }
  135. // Helper Classes to manage heap buffers for _ATL_SAFE_ALLOCA
  136. // Default allocator used by ATL
  137. class _CCRTAllocator
  138. {
  139. public :
  140. static void * Allocate(SIZE_T nRequestedSize)
  141. {
  142. return malloc(nRequestedSize);
  143. }
  144. static void Free(void* p)
  145. {
  146. free(p);
  147. }
  148. };
  149. template < class Allocator>
  150. class CAtlSafeAllocBufferManager
  151. {
  152. private :
  153. struct CAtlSafeAllocBufferNode
  154. {
  155. CAtlSafeAllocBufferNode* m_pNext;
  156. #ifdef _WIN64
  157. BYTE _pad[8];
  158. #else
  159. BYTE _pad[4];
  160. #endif
  161. void* GetData()
  162. {
  163. return (this + 1);
  164. }
  165. };
  166. CAtlSafeAllocBufferNode* m_pHead;
  167. public :
  168. CAtlSafeAllocBufferManager() : m_pHead(NULL) {};
  169. void* Allocate(SIZE_T nRequestedSize)
  170. {
  171. CAtlSafeAllocBufferNode *p = (CAtlSafeAllocBufferNode*)Allocator::Allocate(nRequestedSize + sizeof(CAtlSafeAllocBufferNode));
  172. if (p == NULL)
  173. return NULL;
  174. // Add buffer to the list
  175. p->m_pNext = m_pHead;
  176. m_pHead = p;
  177. return p->GetData();
  178. }
  179. ~CAtlSafeAllocBufferManager()
  180. {
  181. // Walk the list and free the buffers
  182. while (m_pHead != NULL)
  183. {
  184. CAtlSafeAllocBufferNode* p = m_pHead;
  185. m_pHead = m_pHead->m_pNext;
  186. Allocator::Free(p);
  187. }
  188. }
  189. };
  190. // Use one of the following macros before using _ATL_SAFE_ALLOCA
  191. // EX version allows specifying a different heap allocator
  192. #define USES_ATL_SAFE_ALLOCA_EX(x) ATL::_ATL_SAFE_ALLOCA_IMPL::CAtlSafeAllocBufferManager<x> _AtlSafeAllocaManager
  193. #ifndef USES_ATL_SAFE_ALLOCA
  194. #define USES_ATL_SAFE_ALLOCA USES_ATL_SAFE_ALLOCA_EX(ATL::_ATL_SAFE_ALLOCA_IMPL::_CCRTAllocator)
  195. #endif
  196. // nRequestedSize - requested size in bytes
  197. // nThreshold - size in bytes beyond which memory is allocated from the heap.
  198. // Defining _ATL_SAFE_ALLOCA_ALWAYS_ALLOCATE_THRESHOLD_SIZE always allocates the size specified
  199. // for threshold if the stack space is available irrespective of requested size.
  200. // This available for testing purposes. It will help determine the max stack usage due to _alloca's
  201. #ifdef _ATL_SAFE_ALLOCA_ALWAYS_ALLOCATE_THRESHOLD_SIZE
  202. #define _ATL_SAFE_ALLOCA(nRequestedSize, nThreshold) \
  203. (((nRequestedSize) <= (nThreshold) && ATL::_ATL_SAFE_ALLOCA_IMPL::_AtlVerifyStackAvailable(nThreshold) ) ? \
  204. _alloca(nThreshold) : \
  205. ((ATL::_ATL_SAFE_ALLOCA_IMPL::_AtlVerifyStackAvailable(nThreshold)) ? _alloca(nThreshold) : 0), \
  206. _AtlSafeAllocaManager.Allocate(nRequestedSize))
  207. #else
  208. #define _ATL_SAFE_ALLOCA(nRequestedSize, nThreshold) \
  209. (((nRequestedSize) <= (nThreshold) && ATL::_ATL_SAFE_ALLOCA_IMPL::_AtlVerifyStackAvailable(nRequestedSize) ) ? \
  210. _alloca(nRequestedSize) : \
  211. _AtlSafeAllocaManager.Allocate(nRequestedSize))
  212. #endif
  213. // Use 1024 bytes as the default threshold in ATL
  214. #ifndef _ATL_SAFE_ALLOCA_DEF_THRESHOLD
  215. #define _ATL_SAFE_ALLOCA_DEF_THRESHOLD 1024
  216. #endif
  217. } // namespace _ATL_SAFE_ALLOCA_IMPL
  218. } // namespace ATL
  219. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  220. #ifdef _CONVERSION_USES_THREAD_LOCALE
  221. #ifndef _DEBUG
  222. #define USES_CONVERSION int _convert; _convert; UINT _acp = GetACP(); _acp; LPCWSTR _lpw; _lpw; LPCSTR _lpa; _lpa
  223. #else
  224. #define USES_CONVERSION int _convert = 0; _convert; UINT _acp = GetACP(); _acp; LPCWSTR _lpw = NULL; _lpw; LPCSTR _lpa = NULL; _lpa
  225. #endif
  226. #else
  227. #ifndef _DEBUG
  228. #define USES_CONVERSION int _convert; _convert; UINT _acp = CP_ACP; _acp; LPCWSTR _lpw; _lpw; LPCSTR _lpa; _lpa
  229. #else
  230. #define USES_CONVERSION int _convert = 0; _convert; UINT _acp = CP_ACP; _acp; LPCWSTR _lpw = NULL; _lpw; LPCSTR _lpa = NULL; _lpa
  231. #endif
  232. #endif
  233. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  234. #ifdef _CONVERSION_USES_THREAD_LOCALE
  235. #ifndef _DEBUG
  236. #define USES_CONVERSION_EX int _convert_ex; _convert_ex; UINT _acp_ex = GetACP(); _acp_ex; LPCWSTR _lpw_ex; _lpw_ex; LPCSTR _lpa_ex; _lpa_ex; USES_ATL_SAFE_ALLOCA
  237. #else
  238. #define USES_CONVERSION_EX int _convert_ex = 0; _convert_ex; UINT _acp_ex = GetACP(); _acp_ex; LPCWSTR _lpw_ex = NULL; _lpw_ex; LPCSTR _lpa_ex = NULL; _lpa_ex; USES_ATL_SAFE_ALLOCA
  239. #endif
  240. #else
  241. #ifndef _DEBUG
  242. #define USES_CONVERSION_EX int _convert_ex; _convert_ex; UINT _acp_ex = CP_ACP; _acp_ex; LPCWSTR _lpw_ex; _lpw_ex; LPCSTR _lpa_ex; _lpa_ex; USES_ATL_SAFE_ALLOCA
  243. #else
  244. #define USES_CONVERSION_EX int _convert_ex = 0; _convert_ex; UINT _acp_ex = CP_ACP; _acp_ex; LPCWSTR _lpw_ex = NULL; _lpw_ex; LPCSTR _lpa_ex = NULL; _lpa_ex; USES_ATL_SAFE_ALLOCA
  245. #endif
  246. #endif
  247. #ifdef _WINGDI_
  248. ATLAPI_(LPDEVMODEA) AtlDevModeW2A(LPDEVMODEA lpDevModeA, LPDEVMODEW lpDevModeW);
  249. #endif
  250. /////////////////////////////////////////////////////////////////////////////
  251. // Global UNICODE<>ANSI translation helpers
  252. inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars, UINT acp)
  253. {
  254. ATLASSERT(lpa != NULL);
  255. ATLASSERT(lpw != NULL);
  256. if (lpw == NULL || lpa == NULL)
  257. return NULL;
  258. // verify that no illegal character present
  259. // since lpw was allocated based on the size of lpa
  260. // don't worry about the number of chars
  261. lpw[0] = '\0';
  262. int ret = MultiByteToWideChar(acp, 0, lpa, -1, lpw, nChars);
  263. if(ret == 0)
  264. {
  265. ATLASSERT(FALSE);
  266. return NULL;
  267. }
  268. return lpw;
  269. }
  270. inline LPSTR WINAPI AtlW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars, UINT acp)
  271. {
  272. ATLASSERT(lpw != NULL);
  273. ATLASSERT(lpa != NULL);
  274. if (lpa == NULL || lpw == NULL)
  275. return NULL;
  276. // verify that no illegal character present
  277. // since lpa was allocated based on the size of lpw
  278. // don't worry about the number of chars
  279. lpa[0] = '\0';
  280. int ret = WideCharToMultiByte(acp, 0, lpw, -1, lpa, nChars, NULL, NULL);
  281. if(ret == 0)
  282. {
  283. ATLASSERT(FALSE);
  284. return NULL;
  285. }
  286. return lpa;
  287. }
  288. inline LPWSTR WINAPI AtlA2WHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
  289. {
  290. return AtlA2WHelper(lpw, lpa, nChars, CP_ACP);
  291. }
  292. inline LPSTR WINAPI AtlW2AHelper(LPSTR lpa, LPCWSTR lpw, int nChars)
  293. {
  294. return AtlW2AHelper(lpa, lpw, nChars, CP_ACP);
  295. }
  296. #ifdef _CONVERSION_USES_THREAD_LOCALE
  297. #ifdef ATLA2WHELPER
  298. #undef ATLA2WHELPER
  299. #undef ATLW2AHELPER
  300. #endif
  301. #define ATLA2WHELPER AtlA2WHelper
  302. #define ATLW2AHELPER AtlW2AHelper
  303. #else
  304. #ifndef ATLA2WHELPER
  305. #define ATLA2WHELPER AtlA2WHelper
  306. #define ATLW2AHELPER AtlW2AHelper
  307. #endif
  308. #endif
  309. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  310. #ifdef _CONVERSION_USES_THREAD_LOCALE
  311. #define A2W(lpa) (\
  312. ((_lpa = lpa) == NULL) ? NULL : (\
  313. _convert = (lstrlenA(_lpa)+1),\
  314. ATLA2WHELPER((LPWSTR)alloca(_convert*2), _lpa, _convert, _acp)))
  315. #else
  316. #define A2W(lpa) (\
  317. ((_lpa = lpa) == NULL) ? NULL : (\
  318. _convert = (lstrlenA(_lpa)+1),\
  319. ATLA2WHELPER((LPWSTR)alloca(_convert*2), _lpa, _convert)))
  320. #endif
  321. #ifdef _CONVERSION_USES_THREAD_LOCALE
  322. #define W2A(lpw) (\
  323. ((_lpw = lpw) == NULL) ? NULL : (\
  324. _convert = (lstrlenW(_lpw)+1)*2,\
  325. ATLW2AHELPER((LPSTR)alloca(_convert) , _lpw, _convert, _acp)))
  326. #else
  327. #define W2A(lpw) (\
  328. ((_lpw = lpw) == NULL) ? NULL : (\
  329. _convert = (lstrlenW(_lpw)+1)*2,\
  330. ATLW2AHELPER((LPSTR)alloca(_convert), _lpw, _convert)))
  331. #endif
  332. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  333. // The call to _alloca will not cause stack overflow if _AtlVerifyStackAvailable returns TRUE.
  334. #ifdef _CONVERSION_USES_THREAD_LOCALE
  335. #define A2W_EX(lpa, nThreshold) (\
  336. ((_lpa_ex = lpa) == NULL) ? NULL : (\
  337. _convert_ex = (lstrlenA(_lpa_ex)+1),\
  338. ATLA2WHELPER( \
  339. (LPWSTR)_ATL_SAFE_ALLOCA(_convert_ex * sizeof(WCHAR), nThreshold), \
  340. _lpa_ex, \
  341. _convert_ex, \
  342. _acp_ex)))
  343. #else
  344. #define A2W_EX(lpa, nThreshold) (\
  345. ((_lpa_ex = lpa) == NULL) ? NULL : (\
  346. _convert_ex = (lstrlenA(_lpa_ex)+1),\
  347. ATLA2WHELPER( \
  348. (LPWSTR)_ATL_SAFE_ALLOCA(_convert_ex * sizeof(WCHAR), nThreshold), \
  349. _lpa_ex, \
  350. _convert_ex)))
  351. #endif
  352. #ifdef _CONVERSION_USES_THREAD_LOCALE
  353. #define W2A_EX(lpw, nThreshold) (\
  354. ((_lpw_ex = lpw) == NULL) ? NULL : (\
  355. _convert_ex = (lstrlenW(_lpw_ex)+1) * sizeof(WCHAR),\
  356. ATLW2AHELPER( \
  357. (LPSTR)_ATL_SAFE_ALLOCA(_convert_ex, nThreshold), \
  358. _lpw_ex, \
  359. _convert_ex, \
  360. _acp_ex)))
  361. #else
  362. #define W2A_EX(lpw, nThreshold) (\
  363. ((_lpw_ex = lpw) == NULL) ? NULL : (\
  364. _convert_ex = (lstrlenW(_lpw_ex)+1) * sizeof(WCHAR),\
  365. ATLW2AHELPER( \
  366. (LPSTR)_ATL_SAFE_ALLOCA(_convert_ex, nThreshold), \
  367. _lpw_ex, \
  368. _convert_ex)))
  369. #endif
  370. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  371. #define A2CW(lpa) ((LPCWSTR)A2W(lpa))
  372. #define W2CA(lpw) ((LPCSTR)W2A(lpw))
  373. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  374. #define A2CW_EX(lpa, nChar) ((LPCWSTR)A2W_EX(lpa, nChar))
  375. #define W2CA_EX(lpw, nChar) ((LPCSTR)W2A_EX(lpw, nChar))
  376. #if defined(_UNICODE)
  377. // in these cases the default (TCHAR) is the same as OLECHAR
  378. inline int ocslen(LPCOLESTR x) { return lstrlenW(x); }
  379. inline OLECHAR* ocscpy(LPOLESTR dest, LPCOLESTR src) { return lstrcpyW(dest, src); }
  380. inline OLECHAR* ocscat(LPOLESTR dest, LPCOLESTR src) { return lstrcatW(dest, src); }
  381. inline LPCOLESTR T2COLE_EX(LPCTSTR lp, UINT) { return lp; }
  382. inline LPCTSTR OLE2CT_EX(LPCOLESTR lp, UINT) { return lp; }
  383. inline LPOLESTR T2OLE_EX(LPTSTR lp, UINT) { return lp; }
  384. inline LPTSTR OLE2T_EX(LPOLESTR lp, UINT) { return lp; }
  385. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  386. inline LPCOLESTR T2COLE(LPCTSTR lp) { return lp; }
  387. inline LPCTSTR OLE2CT(LPCOLESTR lp) { return lp; }
  388. inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
  389. inline LPTSTR OLE2T(LPOLESTR lp) { return lp; }
  390. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  391. inline LPOLESTR CharNextO(LPCOLESTR lp) {return CharNextW(lp);}
  392. #elif defined(OLE2ANSI)
  393. // in these cases the default (TCHAR) is the same as OLECHAR
  394. inline int ocslen(LPCOLESTR x) { return lstrlen(x); }
  395. inline OLECHAR* ocscpy(LPOLESTR dest, LPCOLESTR src) { return lstrcpy(dest, src); }
  396. inline OLECHAR* ocscat(LPOLESTR dest, LPCOLESTR src) { return ocscpy(dest+ocslen(dest), src); }
  397. inline LPCOLESTR T2COLE_EX(LPCTSTR lp, UINT) { return lp; }
  398. inline LPCTSTR OLE2CT_EX(LPCOLESTR lp, UINT) { return lp; }
  399. inline LPOLESTR T2OLE_EX(LPTSTR lp, UINT) { return lp; }
  400. inline LPTSTR OLE2T_EX(LPOLESTR lp, UINT) { return lp; }
  401. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  402. inline LPCOLESTR T2COLE(LPCTSTR lp) { return lp; }
  403. inline LPCTSTR OLE2CT(LPCOLESTR lp) { return lp; }
  404. inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
  405. inline LPTSTR OLE2T(LPOLESTR lp) { return lp; }
  406. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  407. inline LPOLESTR CharNextO(LPCOLESTR lp) {return CharNext(lp);}
  408. #else
  409. inline int ocslen(LPCOLESTR x) { return lstrlenW(x); }
  410. //lstrcpyW doesn't work on Win95, so we do this
  411. inline OLECHAR* ocscpy(LPOLESTR dest, LPCOLESTR src)
  412. {return (LPOLESTR) memcpy(dest, src, (lstrlenW(src)+1)*sizeof(WCHAR));}
  413. inline OLECHAR* ocscat(LPOLESTR dest, LPCOLESTR src) { return ocscpy(dest+ocslen(dest), src); }
  414. //CharNextW doesn't work on Win95 so we use this
  415. #define T2COLE_EX(lpa, nChar) A2CW_EX(lpa, nChar)
  416. #define T2OLE_EX(lpa, nChar) A2W_EX(lpa, nChar)
  417. #define OLE2CT_EX(lpo, nChar) W2CA_EX(lpo, nChar)
  418. #define OLE2T_EX(lpo, nChar) W2A_EX(lpo, nChar)
  419. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  420. #define T2COLE(lpa) A2CW(lpa)
  421. #define T2OLE(lpa) A2W(lpa)
  422. #define OLE2CT(lpo) W2CA(lpo)
  423. #define OLE2T(lpo) W2A(lpo)
  424. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  425. inline LPOLESTR CharNextO(LPCOLESTR lp) {return (LPOLESTR) ((*lp) ? (lp+1) : lp);}
  426. #endif
  427. #ifdef OLE2ANSI
  428. inline LPOLESTR A2OLE_EX(LPSTR lp, UINT) { return lp;}
  429. inline LPSTR OLE2A_EX(LPOLESTR lp, UINT) { return lp;}
  430. #define W2OLE_EX W2A_EX
  431. #define OLE2W_EX A2W_EX
  432. inline LPCOLESTR A2COLE_EX(LPCSTR lp, UINT) { return lp;}
  433. inline LPCSTR OLE2CA_EX(LPCOLESTR lp, UINT) { return lp;}
  434. #define W2COLE_EX W2CA_EX
  435. #define OLE2CW_EX A2CW_EX
  436. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  437. inline LPOLESTR A2OLE(LPSTR lp) { return lp;}
  438. inline LPSTR OLE2A(LPOLESTR lp) { return lp;}
  439. #define W2OLE W2A
  440. #define OLE2W A2W
  441. inline LPCOLESTR A2COLE(LPCSTR lp) { return lp;}
  442. inline LPCSTR OLE2CA(LPCOLESTR lp) { return lp;}
  443. #define W2COLE W2CA
  444. #define OLE2CW A2CW
  445. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  446. #else
  447. inline LPOLESTR W2OLE_EX(LPWSTR lp, UINT) { return lp; }
  448. inline LPWSTR OLE2W_EX(LPOLESTR lp, UINT) { return lp; }
  449. #define A2OLE_EX A2W_EX
  450. #define OLE2A_EX W2A_EX
  451. inline LPCOLESTR W2COLE_EX(LPCWSTR lp, UINT) { return lp; }
  452. inline LPCWSTR OLE2CW_EX(LPCOLESTR lp, UINT) { return lp; }
  453. #define A2COLE_EX A2CW_EX
  454. #define OLE2CA_EX W2CA_EX
  455. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  456. inline LPOLESTR W2OLE(LPWSTR lp) { return lp; }
  457. inline LPWSTR OLE2W(LPOLESTR lp) { return lp; }
  458. #define A2OLE A2W
  459. #define OLE2A W2A
  460. inline LPCOLESTR W2COLE(LPCWSTR lp) { return lp; }
  461. inline LPCWSTR OLE2CW(LPCOLESTR lp) { return lp; }
  462. #define A2COLE A2CW
  463. #define OLE2CA W2CA
  464. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  465. #endif
  466. #ifdef _UNICODE
  467. #define T2A_EX W2A_EX
  468. #define A2T_EX A2W_EX
  469. inline LPWSTR T2W_EX(LPTSTR lp, UINT) { return lp; }
  470. inline LPTSTR W2T_EX(LPWSTR lp, UINT) { return lp; }
  471. #define T2CA_EX W2CA_EX
  472. #define A2CT_EX A2CW_EX
  473. inline LPCWSTR T2CW_EX(LPCTSTR lp, UINT) { return lp; }
  474. inline LPCTSTR W2CT_EX(LPCWSTR lp, UINT) { return lp; }
  475. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  476. #define T2A W2A
  477. #define A2T A2W
  478. inline LPWSTR T2W(LPTSTR lp) { return lp; }
  479. inline LPTSTR W2T(LPWSTR lp) { return lp; }
  480. #define T2CA W2CA
  481. #define A2CT A2CW
  482. inline LPCWSTR T2CW(LPCTSTR lp) { return lp; }
  483. inline LPCTSTR W2CT(LPCWSTR lp) { return lp; }
  484. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  485. #else
  486. #define T2W_EX A2W_EX
  487. #define W2T_EX W2A_EX
  488. inline LPSTR T2A_EX(LPTSTR lp, UINT) { return lp; }
  489. inline LPTSTR A2T_EX(LPSTR lp, UINT) { return lp; }
  490. #define T2CW_EX A2CW_EX
  491. #define W2CT_EX W2CA_EX
  492. inline LPCSTR T2CA_EX(LPCTSTR lp, UINT) { return lp; }
  493. inline LPCTSTR A2CT_EX(LPCSTR lp, UINT) { return lp; }
  494. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  495. #define T2W A2W
  496. #define W2T W2A
  497. inline LPSTR T2A(LPTSTR lp) { return lp; }
  498. inline LPTSTR A2T(LPSTR lp) { return lp; }
  499. #define T2CW A2CW
  500. #define W2CT W2CA
  501. inline LPCSTR T2CA(LPCTSTR lp) { return lp; }
  502. inline LPCTSTR A2CT(LPCSTR lp) { return lp; }
  503. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  504. #endif
  505. inline BSTR A2WBSTR(LPCSTR lp, int nLen = -1)
  506. {
  507. if (lp == NULL || nLen == 0)
  508. return NULL;
  509. USES_CONVERSION_EX;
  510. BSTR str = NULL;
  511. int nConvertedLen = MultiByteToWideChar(_acp_ex, 0, lp,
  512. nLen, NULL, NULL);
  513. int nAllocLen = nConvertedLen;
  514. if (nLen == -1)
  515. nAllocLen -= 1; // Don't allocate terminating '\0'
  516. str = ::SysAllocStringLen(NULL, nAllocLen);
  517. if (str != NULL)
  518. {
  519. int nResult;
  520. nResult = MultiByteToWideChar(_acp_ex, 0, lp, nLen, str, nConvertedLen);
  521. ATLASSERT(nResult == nConvertedLen);
  522. if(nResult != nConvertedLen)
  523. {
  524. SysFreeString(str);
  525. return NULL;
  526. }
  527. }
  528. return str;
  529. }
  530. inline BSTR OLE2BSTR(LPCOLESTR lp) {return ::SysAllocString(lp);}
  531. #if defined(_UNICODE)
  532. // in these cases the default (TCHAR) is the same as OLECHAR
  533. inline BSTR T2BSTR_EX(LPCTSTR lp) {return ::SysAllocString(lp);}
  534. inline BSTR A2BSTR_EX(LPCSTR lp) {return A2WBSTR(lp);}
  535. inline BSTR W2BSTR_EX(LPCWSTR lp) {return ::SysAllocString(lp);}
  536. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  537. inline BSTR T2BSTR(LPCTSTR lp) {return T2BSTR_EX(lp); }
  538. inline BSTR A2BSTR(LPCSTR lp) {return A2BSTR_EX(lp); }
  539. inline BSTR W2BSTR(LPCWSTR lp) {return W2BSTR_EX(lp); }
  540. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  541. #elif defined(OLE2ANSI)
  542. // in these cases the default (TCHAR) is the same as OLECHAR
  543. inline BSTR T2BSTR_EX(LPCTSTR lp) {return ::SysAllocString(lp);}
  544. inline BSTR A2BSTR_EX(LPCSTR lp) {return ::SysAllocString(lp);}
  545. inline BSTR W2BSTR_EX(LPCWSTR lp) {USES_CONVERSION_EX; return ::SysAllocString(W2COLE_EX(lp));}
  546. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  547. inline BSTR T2BSTR(LPCTSTR lp) {return T2BSTR_EX(lp); }
  548. inline BSTR A2BSTR(LPCSTR lp) {return A2BSTR_EX(lp); }
  549. inline BSTR W2BSTR(LPCWSTR lp) {USES_CONVERSION; return ::SysAllocString(W2COLE(lp));}
  550. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  551. #else
  552. inline BSTR T2BSTR_EX(LPCTSTR lp) {return A2WBSTR(lp);}
  553. inline BSTR A2BSTR_EX(LPCSTR lp) {return A2WBSTR(lp);}
  554. inline BSTR W2BSTR_EX(LPCWSTR lp) {return ::SysAllocString(lp);}
  555. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  556. inline BSTR T2BSTR(LPCTSTR lp) {return T2BSTR_EX(lp); }
  557. inline BSTR A2BSTR(LPCSTR lp) {return A2BSTR_EX(lp); }
  558. inline BSTR W2BSTR(LPCWSTR lp) {return W2BSTR_EX(lp); }
  559. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  560. #endif
  561. #ifdef _WINGDI_
  562. /////////////////////////////////////////////////////////////////////////////
  563. // Global UNICODE<>ANSI translation helpers
  564. inline LPDEVMODEW AtlDevModeA2W(LPDEVMODEW lpDevModeW, LPDEVMODEA lpDevModeA)
  565. {
  566. USES_CONVERSION_EX;
  567. ATLASSERT(lpDevModeW != NULL);
  568. if (lpDevModeA == NULL || lpDevModeW == NULL)
  569. return NULL;
  570. AtlA2WHelper(lpDevModeW->dmDeviceName, (LPCSTR)lpDevModeA->dmDeviceName, 32, _acp_ex);
  571. memcpy(&lpDevModeW->dmSpecVersion, &lpDevModeA->dmSpecVersion,
  572. offsetof(DEVMODEW, dmFormName) - offsetof(DEVMODEW, dmSpecVersion));
  573. AtlA2WHelper(lpDevModeW->dmFormName, (LPCSTR)lpDevModeA->dmFormName, 32, _acp_ex);
  574. memcpy(&lpDevModeW->dmLogPixels, &lpDevModeA->dmLogPixels,
  575. sizeof(DEVMODEW) - offsetof(DEVMODEW, dmLogPixels));
  576. if (lpDevModeA->dmDriverExtra != 0)
  577. memcpy(lpDevModeW+1, lpDevModeA+1, lpDevModeA->dmDriverExtra);
  578. lpDevModeW->dmSize = sizeof(DEVMODEW);
  579. return lpDevModeW;
  580. }
  581. inline LPTEXTMETRICW AtlTextMetricA2W(LPTEXTMETRICW lptmW, LPTEXTMETRICA lptmA)
  582. {
  583. USES_CONVERSION_EX;
  584. ATLASSERT(lptmW != NULL);
  585. if (lptmA == NULL || lptmW == NULL)
  586. return NULL;
  587. memcpy(lptmW, lptmA, sizeof(LONG) * 11);
  588. memcpy(&lptmW->tmItalic, &lptmA->tmItalic, sizeof(BYTE) * 5);
  589. if(MultiByteToWideChar(_acp_ex, 0, (LPCSTR)&lptmA->tmFirstChar, 1, &lptmW->tmFirstChar, 1) == 0)
  590. {
  591. ATLASSERT(FALSE);
  592. return NULL;
  593. }
  594. if(MultiByteToWideChar(_acp_ex, 0, (LPCSTR)&lptmA->tmLastChar, 1, &lptmW->tmLastChar, 1) == 0)
  595. {
  596. ATLASSERT(FALSE);
  597. return NULL;
  598. }
  599. if(MultiByteToWideChar(_acp_ex, 0, (LPCSTR)&lptmA->tmDefaultChar, 1, &lptmW->tmDefaultChar, 1)== 0)
  600. {
  601. ATLASSERT(FALSE);
  602. return NULL;
  603. }
  604. if(MultiByteToWideChar(_acp_ex, 0, (LPCSTR)&lptmA->tmBreakChar, 1, &lptmW->tmBreakChar, 1) == 0)
  605. {
  606. ATLASSERT(FALSE);
  607. return NULL;
  608. }
  609. return lptmW;
  610. }
  611. inline LPTEXTMETRICA AtlTextMetricW2A(LPTEXTMETRICA lptmA, LPTEXTMETRICW lptmW)
  612. {
  613. USES_CONVERSION_EX;
  614. ATLASSERT(lptmA != NULL);
  615. if (lptmW == NULL || lptmA == NULL)
  616. return NULL;
  617. memcpy(lptmA, lptmW, sizeof(LONG) * 11);
  618. memcpy(&lptmA->tmItalic, &lptmW->tmItalic, sizeof(BYTE) * 5);
  619. if(WideCharToMultiByte(_acp_ex, 0, &lptmW->tmFirstChar, 1, (LPSTR)&lptmA->tmFirstChar, 1, NULL, NULL) == 0)
  620. {
  621. ATLASSERT(FALSE);
  622. return NULL;
  623. }
  624. if(WideCharToMultiByte(_acp_ex, 0, &lptmW->tmLastChar, 1, (LPSTR)&lptmA->tmLastChar, 1, NULL, NULL) == 0)
  625. {
  626. ATLASSERT(FALSE);
  627. return NULL;
  628. }
  629. if(WideCharToMultiByte(_acp_ex, 0, &lptmW->tmDefaultChar, 1, (LPSTR)&lptmA->tmDefaultChar, 1, NULL, NULL) == 0)
  630. {
  631. ATLASSERT(FALSE);
  632. return NULL;
  633. }
  634. if(WideCharToMultiByte(_acp_ex, 0, &lptmW->tmBreakChar, 1, (LPSTR)&lptmA->tmBreakChar, 1, NULL, NULL) == 0)
  635. {
  636. ATLASSERT(FALSE);
  637. return NULL;
  638. }
  639. return lptmA;
  640. }
  641. #ifndef ATLDEVMODEA2W
  642. #define ATLDEVMODEA2W AtlDevModeA2W
  643. #define ATLDEVMODEW2A AtlDevModeW2A
  644. #define ATLTEXTMETRICA2W AtlTextMetricA2W
  645. #define ATLTEXTMETRICW2A AtlTextMetricW2A
  646. #endif
  647. // Requires USES_CONVERSION_EX or USES_ATL_SAFE_ALLOCA macro before using the _EX versions of the macros
  648. #define DEVMODEW2A_EX(lpw)\
  649. ((lpw == NULL) ? NULL : ATLDEVMODEW2A((LPDEVMODEA)_ATL_SAFE_ALLOCA(sizeof(DEVMODEA)+lpw->dmDriverExtra, _ATL_SAFE_ALLOCA_DEF_THRESHOLD), lpw))
  650. #define DEVMODEA2W_EX(lpa)\
  651. ((lpa == NULL) ? NULL : ATLDEVMODEA2W((LPDEVMODEW)_ATL_SAFE_ALLOCA(sizeof(DEVMODEW)+lpa->dmDriverExtra, _ATL_SAFE_ALLOCA_DEF_THRESHOLD), lpa))
  652. #define TEXTMETRICW2A_EX(lptmw)\
  653. ((lptmw == NULL) ? NULL : ATLTEXTMETRICW2A((LPTEXTMETRICA)_ATL_SAFE_ALLOCA(sizeof(TEXTMETRICA), _ATL_SAFE_ALLOCA_DEF_THRESHOLD), lptmw))
  654. #define TEXTMETRICA2W_EX(lptma)\
  655. ((lptma == NULL) ? NULL : ATLTEXTMETRICA2W((LPTEXTMETRICW)_ATL_SAFE_ALLOCA(sizeof(TEXTMETRICW), _ATL_SAFE_ALLOCA_DEF_THRESHOLD), lptma))
  656. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  657. #define DEVMODEW2A(lpw)\
  658. ((lpw == NULL) ? NULL : ATLDEVMODEW2A((LPDEVMODEA)alloca(sizeof(DEVMODEA)+lpw->dmDriverExtra), lpw))
  659. #define DEVMODEA2W(lpa)\
  660. ((lpa == NULL) ? NULL : ATLDEVMODEA2W((LPDEVMODEW)alloca(sizeof(DEVMODEW)+lpa->dmDriverExtra), lpa))
  661. #define TEXTMETRICW2A(lptmw)\
  662. ((lptmw == NULL) ? NULL : ATLTEXTMETRICW2A((LPTEXTMETRICA)alloca(sizeof(TEXTMETRICA)), lptmw))
  663. #define TEXTMETRICA2W(lptma)\
  664. ((lptma == NULL) ? NULL : ATLTEXTMETRICA2W((LPTEXTMETRICW)alloca(sizeof(TEXTMETRICW)), lptma))
  665. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  666. #ifdef OLE2ANSI
  667. #define DEVMODEOLE DEVMODEA
  668. #define LPDEVMODEOLE LPDEVMODEA
  669. #define TEXTMETRICOLE TEXTMETRICA
  670. #define LPTEXTMETRICOLE LPTEXTMETRICA
  671. #else
  672. #define DEVMODEOLE DEVMODEW
  673. #define LPDEVMODEOLE LPDEVMODEW
  674. #define TEXTMETRICOLE TEXTMETRICW
  675. #define LPTEXTMETRICOLE LPTEXTMETRICW
  676. #endif
  677. #if defined(_UNICODE)
  678. // in these cases the default (TCHAR) is the same as OLECHAR
  679. inline LPDEVMODEW DEVMODEOLE2T_EX(LPDEVMODEOLE lp) { return lp; }
  680. inline LPDEVMODEOLE DEVMODET2OLE_EX(LPDEVMODEW lp) { return lp; }
  681. inline LPTEXTMETRICW TEXTMETRICOLE2T_EX(LPTEXTMETRICOLE lp) { return lp; }
  682. inline LPTEXTMETRICOLE TEXTMETRICT2OLE_EX(LPTEXTMETRICW lp) { return lp; }
  683. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  684. inline LPDEVMODEW DEVMODEOLE2T(LPDEVMODEOLE lp) { return lp; }
  685. inline LPDEVMODEOLE DEVMODET2OLE(LPDEVMODEW lp) { return lp; }
  686. inline LPTEXTMETRICW TEXTMETRICOLE2T(LPTEXTMETRICOLE lp) { return lp; }
  687. inline LPTEXTMETRICOLE TEXTMETRICT2OLE(LPTEXTMETRICW lp) { return lp; }
  688. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  689. #elif defined(OLE2ANSI)
  690. // in these cases the default (TCHAR) is the same as OLECHAR
  691. inline LPDEVMODE DEVMODEOLE2T_EX(LPDEVMODEOLE lp) { return lp; }
  692. inline LPDEVMODEOLE DEVMODET2OLE_EX(LPDEVMODE lp) { return lp; }
  693. inline LPTEXTMETRIC TEXTMETRICOLE2T_EX(LPTEXTMETRICOLE lp) { return lp; }
  694. inline LPTEXTMETRICOLE TEXTMETRICT2OLE_EX(LPTEXTMETRIC lp) { return lp; }
  695. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  696. inline LPDEVMODE DEVMODEOLE2T(LPDEVMODEOLE lp) { return lp; }
  697. inline LPDEVMODEOLE DEVMODET2OLE(LPDEVMODE lp) { return lp; }
  698. inline LPTEXTMETRIC TEXTMETRICOLE2T(LPTEXTMETRICOLE lp) { return lp; }
  699. inline LPTEXTMETRICOLE TEXTMETRICT2OLE(LPTEXTMETRIC lp) { return lp; }
  700. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  701. #else
  702. #define DEVMODEOLE2T_EX(lpo) DEVMODEW2A_EX(lpo)
  703. #define DEVMODET2OLE_EX(lpa) DEVMODEA2W_EX(lpa)
  704. #define TEXTMETRICOLE2T_EX(lptmw) TEXTMETRICW2A_EX(lptmw)
  705. #define TEXTMETRICT2OLE_EX(lptma) TEXTMETRICA2W_EX(lptma)
  706. #ifndef _ATL_EX_CONVERSION_MACROS_ONLY
  707. #define DEVMODEOLE2T(lpo) DEVMODEW2A(lpo)
  708. #define DEVMODET2OLE(lpa) DEVMODEA2W(lpa)
  709. #define TEXTMETRICOLE2T(lptmw) TEXTMETRICW2A(lptmw)
  710. #define TEXTMETRICT2OLE(lptma) TEXTMETRICA2W(lptma)
  711. #endif // _ATL_EX_CONVERSION_MACROS_ONLY
  712. #endif
  713. #endif //_WINGDI_
  714. #pragma pack(pop)
  715. #ifndef _ATL_DLL_IMPL
  716. #ifndef _ATL_DLL
  717. #define _ATLCONV_IMPL
  718. #endif
  719. #endif
  720. #endif // __ATLCONV_H__
  721. /////////////////////////////////////////////////////////////////////////////
  722. #ifdef _ATLCONV_IMPL
  723. #ifdef _WINGDI_
  724. ATLINLINE ATLAPI_(LPDEVMODEA) AtlDevModeW2A(LPDEVMODEA lpDevModeA, LPDEVMODEW lpDevModeW)
  725. {
  726. USES_CONVERSION_EX;
  727. ATLASSERT(lpDevModeA != NULL);
  728. if (lpDevModeW == NULL || lpDevModeA == NULL)
  729. return NULL;
  730. AtlW2AHelper((LPSTR)lpDevModeA->dmDeviceName, lpDevModeW->dmDeviceName, 32, _acp_ex);
  731. memcpy(&lpDevModeA->dmSpecVersion, &lpDevModeW->dmSpecVersion,
  732. offsetof(DEVMODEA, dmFormName) - offsetof(DEVMODEA, dmSpecVersion));
  733. AtlW2AHelper((LPSTR)lpDevModeA->dmFormName, lpDevModeW->dmFormName, 32, _acp_ex);
  734. memcpy(&lpDevModeA->dmLogPixels, &lpDevModeW->dmLogPixels,
  735. sizeof(DEVMODEA) - offsetof(DEVMODEA, dmLogPixels));
  736. if (lpDevModeW->dmDriverExtra != 0)
  737. memcpy(lpDevModeA+1, lpDevModeW+1, lpDevModeW->dmDriverExtra);
  738. lpDevModeA->dmSize = sizeof(DEVMODEA);
  739. return lpDevModeA;
  740. }
  741. #endif //_WINGDI
  742. //Prevent pulling in second time
  743. #undef _ATLCONV_IMPL
  744. #endif // _ATLCONV_IMPL