Home | History | Annotate | Download | only in c-ares
      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