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