ares_library_init.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* Copyright 1998 by the Massachusetts Institute of Technology.
  2. * Copyright (C) 2004-2009 by Daniel Stenberg
  3. *
  4. * Permission to use, copy, modify, and distribute this
  5. * software and its documentation for any purpose and without
  6. * fee is hereby granted, provided that the above copyright
  7. * notice appear in all copies and that both that copyright
  8. * notice and this permission notice appear in supporting
  9. * documentation, and that the name of M.I.T. not be used in
  10. * advertising or publicity pertaining to distribution of the
  11. * software without specific, written prior permission.
  12. * M.I.T. makes no representations about the suitability of
  13. * this software for any purpose. It is provided "as is"
  14. * without express or implied warranty.
  15. */
  16. #include "ares_setup.h"
  17. #include "ares.h"
  18. #include "ares_library_init.h"
  19. #include "ares_private.h"
  20. #include "atomic.h"
  21. /* library-private global and unique instance vars */
  22. #ifdef USE_WINSOCK
  23. fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL;
  24. fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL;
  25. fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL;
  26. fpGetBestRoute2_t ares_fpGetBestRoute2 = ZERO_NULL;
  27. #endif
  28. #if defined(ANDROID) || defined(__ANDROID__)
  29. #include "ares_android.h"
  30. #endif
  31. /* library-private global vars with source visibility restricted to this file */
  32. static atomic_t ares_init_lock;
  33. static unsigned int ares_initialized;
  34. static int ares_init_flags;
  35. /* library-private global vars with visibility across the whole library */
  36. #if defined(WIN32)
  37. /* We need indirections to handle Windows DLL rules. */
  38. static void *default_malloc(size_t size) { return malloc(size); }
  39. static void *default_realloc(void *p, size_t size) { return realloc(p, size); }
  40. static void default_free(void *p) { free(p); }
  41. #else
  42. # define default_malloc malloc
  43. # define default_realloc realloc
  44. # define default_free free
  45. #endif
  46. void *(*ares_malloc)(size_t size) = default_malloc;
  47. void *(*ares_realloc)(void *ptr, size_t size) = default_realloc;
  48. void (*ares_free)(void *ptr) = default_free;
  49. #ifdef USE_WINSOCK
  50. static HMODULE hnd_iphlpapi;
  51. static HMODULE hnd_advapi32;
  52. #endif
  53. static int ares_win32_init(void)
  54. {
  55. #ifdef USE_WINSOCK
  56. hnd_iphlpapi = 0;
  57. hnd_iphlpapi = LoadLibraryW(L"iphlpapi.dll");
  58. if (!hnd_iphlpapi)
  59. return ARES_ELOADIPHLPAPI;
  60. ares_fpGetNetworkParams = (fpGetNetworkParams_t)
  61. GetProcAddress(hnd_iphlpapi, "GetNetworkParams");
  62. if (!ares_fpGetNetworkParams)
  63. {
  64. FreeLibrary(hnd_iphlpapi);
  65. return ARES_EADDRGETNETWORKPARAMS;
  66. }
  67. ares_fpGetAdaptersAddresses = (fpGetAdaptersAddresses_t)
  68. GetProcAddress(hnd_iphlpapi, "GetAdaptersAddresses");
  69. if (!ares_fpGetAdaptersAddresses)
  70. {
  71. /* This can happen on clients before WinXP, I don't
  72. think it should be an error, unless we don't want to
  73. support Windows 2000 anymore */
  74. }
  75. ares_fpGetBestRoute2 = (fpGetBestRoute2_t)
  76. GetProcAddress(hnd_iphlpapi, "GetBestRoute2");
  77. if (!ares_fpGetBestRoute2)
  78. {
  79. /* This can happen on clients before Vista, I don't
  80. think it should be an error, unless we don't want to
  81. support Windows XP anymore */
  82. }
  83. /*
  84. * When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036,
  85. * also known as RtlGenRandom, which is the case for Windows versions prior
  86. * to WinXP then c-ares uses portable rand() function. Then don't error here.
  87. */
  88. hnd_advapi32 = 0;
  89. hnd_advapi32 = LoadLibraryW(L"advapi32.dll");
  90. if (hnd_advapi32)
  91. {
  92. ares_fpSystemFunction036 = (fpSystemFunction036_t)
  93. GetProcAddress(hnd_advapi32, "SystemFunction036");
  94. }
  95. #endif
  96. return ARES_SUCCESS;
  97. }
  98. static void ares_win32_cleanup(void)
  99. {
  100. #ifdef USE_WINSOCK
  101. if (hnd_advapi32)
  102. FreeLibrary(hnd_advapi32);
  103. if (hnd_iphlpapi)
  104. FreeLibrary(hnd_iphlpapi);
  105. #endif
  106. }
  107. int ares_library_init(int flags)
  108. {
  109. int res = ARES_SUCCESS;
  110. acquire_lock(&ares_init_lock);
  111. ares_initialized++;
  112. if (ares_initialized == 1)
  113. {
  114. if (flags & ARES_LIB_INIT_WIN32)
  115. res = ares_win32_init();
  116. if (res == ARES_SUCCESS)
  117. ares_init_flags = flags;
  118. }
  119. release_lock(&ares_init_lock);
  120. return res;
  121. }
  122. int ares_library_init_mem(int flags,
  123. void *(*amalloc)(size_t size),
  124. void (*afree)(void *ptr),
  125. void *(*arealloc)(void *ptr, size_t size))
  126. {
  127. if (amalloc)
  128. ares_malloc = amalloc;
  129. if (arealloc)
  130. ares_realloc = arealloc;
  131. if (afree)
  132. ares_free = afree;
  133. return ares_library_init(flags);
  134. }
  135. void ares_library_cleanup(void)
  136. {
  137. acquire_lock(&ares_init_lock);
  138. if (ares_initialized)
  139. {
  140. ares_initialized--;
  141. if (!ares_initialized)
  142. {
  143. if (ares_init_flags & ARES_LIB_INIT_WIN32)
  144. ares_win32_cleanup();
  145. #if defined(ANDROID) || defined(__ANDROID__)
  146. ares_library_cleanup_android();
  147. #endif
  148. ares_init_flags = ARES_LIB_INIT_NONE;
  149. ares_malloc = malloc;
  150. ares_realloc = realloc;
  151. ares_free = free;
  152. }
  153. }
  154. release_lock(&ares_init_lock);
  155. }
  156. int ares_library_initialized(void)
  157. {
  158. #ifdef USE_WINSOCK
  159. if (!ares_initialized)
  160. return ARES_ENOTINITIALIZED;
  161. #endif
  162. return ARES_SUCCESS;
  163. }