Example #1
1
std::wstring GetAppDataPath()
{
  if (appDataPath.empty())
  {
    if (IsWindowsVistaOrLater())
    {
      WCHAR* pathBuffer;
      if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, 0, &pathBuffer)))
        throw std::runtime_error("Unable to find app data directory");
      appDataPath.assign(pathBuffer);
      CoTaskMemFree(pathBuffer);
    }
    else
    {
      std::auto_ptr<wchar_t> pathBuffer(new wchar_t[MAX_PATH]);
      if (!SHGetSpecialFolderPathW(0, pathBuffer.get(), CSIDL_LOCAL_APPDATA, true))
        throw std::runtime_error("Unable to find app data directory");
      appDataPath.assign(pathBuffer.get());
    }
    appDataPath += L"\\Adblock Plus for IE";

    // Ignore errors here, this isn't a critical operation
    ::CreateDirectoryW(appDataPath.c_str(), NULL);
  }
  return appDataPath;
}
bool HasIPv6Enabled() {
#ifndef WIN32
  // We only need to check this for Windows XP (so far).
  return true;
#else
  if (IsWindowsVistaOrLater()) {
    return true;
  }
  if (!IsWindowsXpOrLater()) {
    return false;
  }
  DWORD protbuff_size = 4096;
  scoped_array<char> protocols;
  LPWSAPROTOCOL_INFOW protocol_infos = NULL;
  int requested_protocols[2] = {AF_INET6, 0};

  int err = 0;
  int ret = 0;
  // Check for protocols in a do-while loop until we provide a buffer large
  // enough. (WSCEnumProtocols sets protbuff_size to its desired value).
  // It is extremely unlikely that this will loop more than once.
  do {
    protocols.reset(new char[protbuff_size]);
    protocol_infos = reinterpret_cast<LPWSAPROTOCOL_INFOW>(protocols.get());
    ret = WSCEnumProtocols(requested_protocols, protocol_infos,
                           &protbuff_size, &err);
  } while (ret == SOCKET_ERROR && err == WSAENOBUFS);

  if (ret == SOCKET_ERROR) {
    return false;
  }

  // Even if ret is positive, check specifically for IPv6.
  // Non-IPv6 enabled WinXP will still return a RAW protocol.
  for (int i = 0; i < ret; ++i) {
    if (protocol_infos[i].iAddressFamily == AF_INET6) {
      return true;
    }
  }
  return false;
#endif
}
/* Get the friendly name for the given GUID */
char *
get_interface_friendly_name_from_device_guid(__in GUID *guid)
{
    HMODULE hIPHlpApi;
    HRESULT status;
    WCHAR wName[NDIS_IF_MAX_STRING_SIZE + 1];
    HRESULT hr;
    gboolean fallbackToUnpublishedApi=TRUE;
    gboolean haveInterfaceFriendlyName=FALSE;
    int size;
    char *name;

    /* Load the ip helper api DLL */
    hIPHlpApi = LoadLibrary(TEXT("iphlpapi.dll"));
    if (hIPHlpApi == NULL) {
        /* Load failed - DLL should always be available in XP+*/
        return NULL;
    }

    /* Need to convert an Interface GUID to the interface friendly name (e.g. "Local Area Connection")
    * The functions required to do this all reside within iphlpapi.dll
    * - The preferred approach is to use published API functions (Available since Windows Vista)
    * - We do however fallback to trying undocumented API if the published API is not available (Windows XP/2k3 scenario)
    */

    if(IsWindowsVistaOrLater()){
        /* Published API function prototypes (for Windows Vista/Windows Server 2008+) */
        typedef NETIO_STATUS (WINAPI *ProcAddr_CIG2L) (__in CONST GUID *InterfaceGuid, __out PNET_LUID InterfaceLuid);
        typedef NETIO_STATUS (WINAPI *ProcAddr_CIL2A) ( __in CONST NET_LUID *InterfaceLuid,__out_ecount(Length) PWSTR InterfaceAlias, __in SIZE_T Length);

        /* Attempt to do the conversion using Published API functions */
        ProcAddr_CIG2L proc_ConvertInterfaceGuidToLuid=(ProcAddr_CIG2L) GetProcAddress(hIPHlpApi, "ConvertInterfaceGuidToLuid");
        if(proc_ConvertInterfaceGuidToLuid!=NULL){
            ProcAddr_CIL2A Proc_ConvertInterfaceLuidToAlias=(ProcAddr_CIL2A) GetProcAddress(hIPHlpApi, "ConvertInterfaceLuidToAlias");
            if(Proc_ConvertInterfaceLuidToAlias!=NULL){
                /* we have our functions ready to go, attempt to convert interface guid->luid->friendlyname */
                NET_LUID InterfaceLuid;
                hr = proc_ConvertInterfaceGuidToLuid(guid, &InterfaceLuid);
                if(hr==NO_ERROR){
                    /* guid->luid success */
                    hr = Proc_ConvertInterfaceLuidToAlias(&InterfaceLuid, wName, NDIS_IF_MAX_STRING_SIZE+1);

                    if(hr==NO_ERROR){
                        /* luid->friendly name success */
                        haveInterfaceFriendlyName=TRUE; /* success */
                    }else{
                        /* luid->friendly name failed */
                        fallbackToUnpublishedApi=FALSE;
                    }
                }else{
                    fallbackToUnpublishedApi=FALSE;
                }

            }
        }
    }


    if(fallbackToUnpublishedApi && !haveInterfaceFriendlyName){
        /* Didn't manage to get the friendly name using published api functions
        * (most likely cause wireshark is running on Windows XP/Server 2003)
        * Retry using nhGetInterfaceNameFromGuid (an older unpublished API function) */
        typedef HRESULT (WINAPI *ProcAddr_nhGINFG) (__in GUID *InterfaceGuid, __out PCWSTR InterfaceAlias, __inout DWORD *LengthAddress, wchar_t *a4, wchar_t *a5);

        ProcAddr_nhGINFG Proc_nhGetInterfaceNameFromGuid = NULL;
        Proc_nhGetInterfaceNameFromGuid = (ProcAddr_nhGINFG) GetProcAddress(hIPHlpApi, "NhGetInterfaceNameFromGuid");
        if (Proc_nhGetInterfaceNameFromGuid!= NULL) {
            wchar_t *p4=NULL, *p5=NULL;
            DWORD NameSize;

            /* testing of nhGetInterfaceNameFromGuid indicates the unpublished API function expects the 3rd parameter
            * to be the available space in bytes (as compared to wchar's) available in the second parameter buffer
            * to receive the friendly name (in unicode format) including the space for the nul termination.*/
            NameSize = sizeof(wName);

            /* do the guid->friendlyname lookup */
            status = Proc_nhGetInterfaceNameFromGuid(guid, wName, &NameSize, p4, p5);

            if(status==0){
                haveInterfaceFriendlyName=TRUE; /* success */
            }
        }
    }

    /* we have finished with iphlpapi.dll - release it */
    FreeLibrary(hIPHlpApi);

    if(!haveInterfaceFriendlyName){
        /* failed to get the friendly name, nothing further to do */
        return NULL;
    }

    /* Get the required buffer size, and then convert the string
    * from UTF-16 to UTF-8. */
    size=WideCharToMultiByte(CP_UTF8, 0, wName, -1, NULL, 0, NULL, NULL);
    name=(char *) g_malloc(size);
    if (name == NULL){
        return NULL;
    }
    size=WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, size, NULL, NULL);
    if(size==0){
        /* bytes written == 0, indicating some form of error*/
        g_free(name);
        return NULL;
    }
    return name;
}