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.

327 lines
7.9 KiB

  1. /*++
  2. Copyright (c) 2000-2001, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. util.c
  5. Abstract:
  6. Several utility functions we need are thrown in here for kicks.
  7. MiniAtoI
  8. CpgFromLocale
  9. CbPerChOfCpg
  10. GetKernelHandle
  11. GetUserHandle
  12. GetAdvapiHandle
  13. GetRasHandle
  14. GetOtherRasHandle
  15. GetComDlgHandle
  16. cchUnicodeMultiSz
  17. cbAnsiMultiSz
  18. Revision History:
  19. 17 Mar 2001 v-michka Created.
  20. --*/
  21. #include "precomp.h"
  22. // forward declares
  23. void LoadLibrarySafe(HMODULE * phMod, char * Library);
  24. // our remembered handles for various DLLs we dynamically load from
  25. // CONSIDER: Maybe we could free up the one handle we have for each
  26. // library? We cannot do this in DllMain according to PSDK
  27. // docs, but maybe it is worth doing if we are being
  28. // unloaded anyway by the caller?
  29. static HMODULE m_hModGB18030 = 0;
  30. static HMODULE m_hModComDlg = 0;
  31. static HMODULE m_hModOtherRas = 0;
  32. static HMODULE m_hModRas = 0;
  33. static HMODULE m_hModAdvapi = 0;
  34. static HMODULE m_hModUser = 0;
  35. static HMODULE m_hModKernel = 0;
  36. static HMODULE m_hModSensapi = 0;
  37. static HMODULE m_hModOleAcc = 0;
  38. /*-------------------------------
  39. CpgFromLocale
  40. Given a locale, returns the appropriate codepage to use
  41. for conversions
  42. -------------------------------*/
  43. UINT CpgFromLocale(LCID Locale)
  44. {
  45. char lpLCData[6]; // Max of this param, per PSDK docs
  46. if (GetLocaleInfoA(Locale, LOCALE_IDEFAULTANSICODEPAGE, lpLCData, 6))
  47. return(MiniAtoI(lpLCData));
  48. return(g_acp);
  49. }
  50. /*-------------------------------
  51. CpgOemFromLocale
  52. Given a locale, returns the appropriate OEM codepage to use
  53. for conversions
  54. -------------------------------*/
  55. UINT CpgOemFromLocale(LCID Locale)
  56. {
  57. char lpLCData[6]; // Max of this param, per PSDK docs
  58. if (GetLocaleInfoA(Locale, LOCALE_IDEFAULTCODEPAGE, lpLCData, 6))
  59. return(MiniAtoI(lpLCData));
  60. return(g_oemcp);
  61. }
  62. #pragma intrinsic (strlen)
  63. /*-------------------------------
  64. MiniAtoI
  65. Our baby version of the atoi function. Since we know that we always have
  66. full digits with no white space, we can be nicer about this than the
  67. VC runtime version is (since they have so many special cases).
  68. -------------------------------*/
  69. UINT MiniAtoI(const char * lpsz)
  70. {
  71. size_t cch = (lpsz ? strlen(lpsz) : 0);
  72. UINT RetVal = 0;
  73. UINT mod = 1;
  74. UINT ich;
  75. char ch;
  76. for(ich = 1 ; ich <= cch ; ich++)
  77. {
  78. ch = lpsz[cch - ich];
  79. RetVal += ((ch - '0') * mod);
  80. mod *= 10;
  81. }
  82. return(RetVal);
  83. }
  84. /*-------------------------------
  85. CbPerChOfCpg
  86. Given a code page, returns the maximum number of bytes
  87. that can be needed for a single character.
  88. -------------------------------*/
  89. UINT CbPerChOfCpg(UINT cpg)
  90. {
  91. CPINFO cpi;
  92. if(GetCPInfo(cpg, &cpi))
  93. return(cpi.MaxCharSize);
  94. // We should not fail here, but if we do, default to requiring a big
  95. // buffer, just to be safe.
  96. return(2);
  97. }
  98. /*-------------------------------
  99. CpgFromHdc
  100. Given a device context handle, returns the code page to
  101. use. This is something that a lot of GDI functions do.
  102. -------------------------------*/
  103. UINT CpgFromHdc(HDC hdc)
  104. {
  105. int chs;
  106. CHARSETINFO csi;
  107. chs = GetTextCharset(hdc);
  108. if(TranslateCharsetInfo(&(DWORD)chs, &csi, TCI_SRCCHARSET))
  109. return(csi.ciACP);
  110. else
  111. return(g_acp);
  112. }
  113. /*-------------------------------
  114. GetUserHandle
  115. -------------------------------*/
  116. HMODULE GetUserHandle(void)
  117. {
  118. if (!m_hModUser)
  119. {
  120. m_hModUser = GetModuleHandleA("user32");
  121. if (!m_hModUser)
  122. LoadLibrarySafe(&m_hModUser, "user32");
  123. }
  124. return(m_hModUser);
  125. }
  126. /*-------------------------------
  127. GetComDlgHandle
  128. -------------------------------*/
  129. HMODULE GetComDlgHandle(void)
  130. {
  131. if (!m_hModComDlg)
  132. LoadLibrarySafe(&m_hModComDlg, "comdlg32.dll");
  133. return m_hModComDlg;
  134. }
  135. /*-------------------------------
  136. GetGB18030Handle
  137. -------------------------------*/
  138. HMODULE GetGB18030Handle(void)
  139. {
  140. if (!m_hModGB18030)
  141. LoadLibrarySafe(&m_hModGB18030, "c_gb18030.dll");
  142. return m_hModGB18030;
  143. }
  144. /*-------------------------------
  145. GetKernelProc
  146. We do not need to call LoadLibrary since we are sure it is
  147. loaded (it is loaded into every process!)
  148. -------------------------------*/
  149. FARPROC GetKernelProc(LPCSTR Function)
  150. {
  151. if (!m_hModKernel)
  152. m_hModKernel = GetModuleHandleA("kernel32");
  153. return(GetProcAddress(m_hModKernel, Function));
  154. }
  155. /*-------------------------------
  156. GetUserProc
  157. -------------------------------*/
  158. FARPROC GetUserProc(LPCSTR Function)
  159. {
  160. return(GetProcAddress(GetUserHandle(), Function));
  161. }
  162. /*-------------------------------
  163. GetAdvapiProc
  164. -------------------------------*/
  165. FARPROC GetAdvapiProc(LPCSTR Function)
  166. {
  167. if (!m_hModAdvapi)
  168. {
  169. m_hModAdvapi = GetModuleHandleA("advapi32");
  170. if (!m_hModAdvapi)
  171. LoadLibrarySafe(&m_hModAdvapi, "advapi32");
  172. }
  173. return(GetProcAddress(m_hModAdvapi, Function));
  174. }
  175. /*-------------------------------
  176. GetOleAccProc
  177. -------------------------------*/
  178. FARPROC GetOleAccProc(LPCSTR Function)
  179. {
  180. if (!m_hModOleAcc)
  181. LoadLibrarySafe(&m_hModOleAcc, "oleacc.dll");
  182. return(GetProcAddress(m_hModOleAcc, Function));
  183. }
  184. /*-------------------------------
  185. GetSensApiProc
  186. -------------------------------*/
  187. FARPROC GetSensApiProc(LPCSTR Function)
  188. {
  189. if (!m_hModSensapi)
  190. LoadLibrarySafe(&m_hModSensapi, "sensapi.dll");
  191. return(GetProcAddress(m_hModSensapi, Function));
  192. }
  193. /*-------------------------------
  194. GetRasProc
  195. All RAS procs are in some DLL but we do not know
  196. which one; therefore, we use this wrapper to get
  197. the procs
  198. -------------------------------*/
  199. FARPROC GetRasProc(LPCSTR Function)
  200. {
  201. FARPROC RetVal;
  202. if (!m_hModRas)
  203. LoadLibrarySafe(&m_hModRas, "rasapi32.dll");
  204. RetVal = GetProcAddress(m_hModRas, Function);
  205. if(RetVal==0)
  206. {
  207. if (!m_hModOtherRas)
  208. LoadLibrarySafe(&m_hModOtherRas, "rnaph.dll");
  209. RetVal = GetProcAddress(m_hModOtherRas, Function);
  210. }
  211. return(RetVal);
  212. }
  213. /*-------------------------------
  214. LoadLibrarySafe
  215. Keeps us from ever LoadLibrarying more than one
  216. time in multithreaded scenarios.
  217. -------------------------------*/
  218. void LoadLibrarySafe(HMODULE * phMod, char * Library)
  219. {
  220. HMODULE hModT = LoadLibraryA(Library);
  221. if(InterlockedExchange((LPLONG)&(*phMod), (LONG)hModT) != 0)
  222. {
  223. // Some other thread beat us to it, lets unload our instance
  224. FreeLibrary(hModT);
  225. }
  226. }
  227. //----------------------------------------------------------------------------
  228. // There are strings which are blocks of strings end to end with a trailing '\0'
  229. // to indicate the true end. These strings are used with the REG_MULTI_SZ
  230. // option of the Reg... routines and the lpstrFilter field of the OPENFILENAME
  231. // structure used in the GetOpenFileName and GetSaveFileName routines. To help
  232. // in converting these strings here are two routines which calculate the size
  233. // of the Unicode and ANSI versions (including all '\0's!):
  234. // Stolen from VSANSI
  235. //----------------------------------------------------------------
  236. // Return size of WCHAR string list in WCHARs.
  237. size_t cchUnicodeMultiSz(LPCWSTR lpsz)
  238. {
  239. LPCWSTR pch = lpsz;
  240. for (;;)
  241. {
  242. if (*pch)
  243. pch++;
  244. else
  245. {
  246. pch++;
  247. if (!*pch)
  248. break;
  249. }
  250. }
  251. return 1 + (pch - lpsz);
  252. }
  253. //----------------------------------------------------------------
  254. // Return size of ANSI string list in bytes.
  255. size_t cbAnsiMultiSz(LPCSTR lpsz)
  256. {
  257. LPCSTR pch = lpsz;
  258. for (;;)
  259. {
  260. if (*pch)
  261. pch++;
  262. else
  263. {
  264. pch++;
  265. // Break if we've reached the double Null
  266. if (!*pch)
  267. break;
  268. }
  269. }
  270. return 1 + (pch - lpsz);
  271. }