1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/* 2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * 4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Use of this source code is governed by a BSD-style license 5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * in the file PATENTS. All contributing project authors may 8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */ 10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/win32.h" 12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 13f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <winsock2.h> 14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <ws2tcpip.h> 15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <algorithm> 16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 175237aaf243d29732f59557361b7a993c0a18cf0etfarina#include "webrtc/base/arraysize.h" 18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/basictypes.h" 19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/byteorder.h" 20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/common.h" 21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/logging.h" 22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc { 24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Helper function declarations for inet_ntop/inet_pton. 26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic const char* inet_ntop_v4(const void* src, char* dst, socklen_t size); 27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic const char* inet_ntop_v6(const void* src, char* dst, socklen_t size); 28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int inet_pton_v4(const char* src, void* dst); 29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int inet_pton_v6(const char* src, void* dst); 30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Implementation of inet_ntop (create a printable representation of an 32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// ip address). XP doesn't have its own inet_ntop, and 33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// WSAAddressToString requires both IPv6 to be installed and for Winsock 34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// to be initialized. 35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char* win32_inet_ntop(int af, const void *src, 36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char* dst, socklen_t size) { 37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!src || !dst) { 38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return NULL; 39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org switch (af) { 41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case AF_INET: { 42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return inet_ntop_v4(src, dst, size); 43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org case AF_INET6: { 45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return inet_ntop_v6(src, dst, size); 46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return NULL; 49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// As above, but for inet_pton. Implements inet_pton for v4 and v6. 52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Note that our inet_ntop will output normal 'dotted' v4 addresses only. 53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint win32_inet_pton(int af, const char* src, void* dst) { 54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!src || !dst) { 55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (af == AF_INET) { 58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return inet_pton_v4(src, dst); 59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (af == AF_INET6) { 60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return inet_pton_v6(src, dst); 61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return -1; 63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Helper function for inet_ntop for IPv4 addresses. 66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Outputs "dotted-quad" decimal notation. 67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char* inet_ntop_v4(const void* src, char* dst, socklen_t size) { 68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (size < INET_ADDRSTRLEN) { 69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return NULL; 70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const struct in_addr* as_in_addr = 72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<const struct in_addr*>(src); 73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org rtc::sprintfn(dst, size, "%d.%d.%d.%d", 74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org as_in_addr->S_un.S_un_b.s_b1, 75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org as_in_addr->S_un.S_un_b.s_b2, 76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org as_in_addr->S_un.S_un_b.s_b3, 77f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org as_in_addr->S_un.S_un_b.s_b4); 78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return dst; 79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Helper function for inet_ntop for IPv6 addresses. 82f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgconst char* inet_ntop_v6(const void* src, char* dst, socklen_t size) { 83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (size < INET6_ADDRSTRLEN) { 84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return NULL; 85f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 860c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström const uint16_t* as_shorts = reinterpret_cast<const uint16_t*>(src); 87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int runpos[8]; 88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int current = 1; 89b08f4045ec78e9be7d8f637faf71074ed80fc6c9guoweis@webrtc.org int max = 0; 90f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int maxpos = -1; 915237aaf243d29732f59557361b7a993c0a18cf0etfarina int run_array_size = arraysize(runpos); 92f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Run over the address marking runs of 0s. 93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org for (int i = 0; i < run_array_size; ++i) { 94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (as_shorts[i] == 0) { 95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org runpos[i] = current; 96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (current > max) { 97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org maxpos = i; 98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org max = current; 99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++current; 101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org runpos[i] = -1; 103b08f4045ec78e9be7d8f637faf71074ed80fc6c9guoweis@webrtc.org current = 1; 104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 107b08f4045ec78e9be7d8f637faf71074ed80fc6c9guoweis@webrtc.org if (max > 0) { 108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int tmpmax = maxpos; 109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Run back through, setting -1 for all but the longest run. 110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org for (int i = run_array_size - 1; i >= 0; i--) { 111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (i > tmpmax) { 112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org runpos[i] = -1; 113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (runpos[i] == -1) { 114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // We're less than maxpos, we hit a -1, so the 'good' run is done. 115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Setting tmpmax -1 means all remaining positions get set to -1. 116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org tmpmax = -1; 117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char* cursor = dst; 122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Print IPv4 compatible and IPv4 mapped addresses using the IPv4 helper. 123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // These addresses have an initial run of either eight zero-bytes followed 124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // by 0xFFFF, or an initial run of ten zero-bytes. 125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (runpos[0] == 1 && (maxpos == 5 || 126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org (maxpos == 4 && as_shorts[5] == 0xFFFF))) { 127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *cursor++ = ':'; 128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *cursor++ = ':'; 129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (maxpos == 4) { 130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org cursor += rtc::sprintfn(cursor, INET6_ADDRSTRLEN - 2, "ffff:"); 131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const struct in_addr* as_v4 = 133f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<const struct in_addr*>(&(as_shorts[6])); 134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org inet_ntop_v4(as_v4, cursor, 135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<socklen_t>(INET6_ADDRSTRLEN - (cursor - dst))); 136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org for (int i = 0; i < run_array_size; ++i) { 138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (runpos[i] == -1) { 139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org cursor += rtc::sprintfn(cursor, 140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org INET6_ADDRSTRLEN - (cursor - dst), 141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org "%x", NetworkToHost16(as_shorts[i])); 142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (i != 7 && runpos[i + 1] != 1) { 143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *cursor++ = ':'; 144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (runpos[i] == 1) { 146f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Entered the run; print the colons and skip the run. 147f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *cursor++ = ':'; 148f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *cursor++ = ':'; 149f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org i += (max - 1); 150f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 151f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 152f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return dst; 154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Helper function for inet_pton for IPv4 addresses. 157f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// |src| points to a character string containing an IPv4 network address in 158f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// dotted-decimal format, "ddd.ddd.ddd.ddd", where ddd is a decimal number 159f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// of up to three digits in the range 0 to 255. 160f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// The address is converted and copied to dst, 161f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// which must be sizeof(struct in_addr) (4) bytes (32 bits) long. 162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint inet_pton_v4(const char* src, void* dst) { 163f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const int kIpv4AddressSize = 4; 164f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int found = 0; 165f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* src_pos = src; 166f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org unsigned char result[kIpv4AddressSize] = {0}; 167f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 168f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while (*src_pos != '\0') { 169f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // strtol won't treat whitespace characters in the begining as an error, 170f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // so check to ensure this is started with digit before passing to strtol. 171f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!isdigit(*src_pos)) { 172f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 173f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 174f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char* end_pos; 175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org long value = strtol(src_pos, &end_pos, 10); 176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (value < 0 || value > 255 || src_pos == end_pos) { 177f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++found; 180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (found > kIpv4AddressSize) { 181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org result[found - 1] = static_cast<unsigned char>(value); 184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org src_pos = end_pos; 185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*src_pos == '.') { 186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // There's more. 187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++src_pos; 188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (*src_pos != '\0') { 189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // If it's neither '.' nor '\0' then return fail. 190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (found != kIpv4AddressSize) { 194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(dst, result, sizeof(result)); 197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 1; 198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Helper function for inet_pton for IPv6 addresses. 201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint inet_pton_v6(const char* src, void* dst) { 202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // sscanf will pick any other invalid chars up, but it parses 0xnnnn as hex. 203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Check for literal x in the input string. 204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* readcursor = src; 205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char c = *readcursor++; 206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while (c) { 207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (c == 'x') { 208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org c = *readcursor++; 211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org readcursor = src; 213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org struct in6_addr an_addr; 215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memset(&an_addr, 0, sizeof(an_addr)); 216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 2170c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint16_t* addr_cursor = reinterpret_cast<uint16_t*>(&an_addr.s6_addr[0]); 2180c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint16_t* addr_end = reinterpret_cast<uint16_t*>(&an_addr.s6_addr[16]); 219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool seencompressed = false; 220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Addresses that start with "::" (i.e., a run of initial zeros) or 222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // "::ffff:" can potentially be IPv4 mapped or compatibility addresses. 223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // These have dotted-style IPv4 addresses on the end (e.g. "::192.168.7.1"). 224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*readcursor == ':' && *(readcursor+1) == ':' && 225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *(readcursor + 2) != 0) { 226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Check for periods, which we'll take as a sign of v4 addresses. 227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* addrstart = readcursor + 2; 228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (rtc::strchr(addrstart, ".")) { 229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* colon = rtc::strchr(addrstart, "::"); 230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (colon) { 2310c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint16_t a_short; 232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int bytesread = 0; 233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (sscanf(addrstart, "%hx%n", &a_short, &bytesread) != 1 || 234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org a_short != 0xFFFF || bytesread != 4) { 235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Colons + periods means has to be ::ffff:a.b.c.d. But it wasn't. 236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org an_addr.s6_addr[10] = 0xFF; 239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org an_addr.s6_addr[11] = 0xFF; 240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org addrstart = colon + 1; 241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org struct in_addr v4; 244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (inet_pton_v4(addrstart, &v4.s_addr)) { 245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(&an_addr.s6_addr[12], &v4, sizeof(v4)); 246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(dst, &an_addr, sizeof(an_addr)); 247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 1; 248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Invalid v4 address. 250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // For addresses without a trailing IPv4 component ('normal' IPv6 addresses). 256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while (*readcursor != 0 && addr_cursor < addr_end) { 257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*readcursor == ':') { 258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*(readcursor + 1) == ':') { 259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (seencompressed) { 260f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Can only have one compressed run of zeroes ("::") per address. 261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Hit a compressed run. Count colons to figure out how much of the 264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // address is skipped. 265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org readcursor += 2; 266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const char* coloncounter = readcursor; 267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int coloncount = 0; 268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*coloncounter == 0) { 269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Special case - trailing ::. 270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org addr_cursor = addr_end; 271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org while (*coloncounter) { 273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*coloncounter == ':') { 274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++coloncount; 275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++coloncounter; 277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // (coloncount + 1) is the number of shorts left in the address. 279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org addr_cursor = addr_end - (coloncount + 1); 280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org seencompressed = true; 281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 283f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++readcursor; 284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 285f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 2860c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint16_t word; 287f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int bytesread = 0; 288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (sscanf(readcursor, "%hx%n", &word, &bytesread) != 1) { 289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 290f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *addr_cursor = HostToNetwork16(word); 292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ++addr_cursor; 293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org readcursor += bytesread; 294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*readcursor != ':' && *readcursor != '\0') { 295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (*readcursor != '\0' || addr_cursor < addr_end) { 302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Catches addresses too short or too long. 303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 0; 304f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 305f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(dst, &an_addr, sizeof(an_addr)); 306f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 1; 307f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 310f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Unix time is in seconds relative to 1/1/1970. So we compute the windows 311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// FILETIME of that time/date, then we add/subtract in appropriate units to 312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// convert to/from unix time. 313f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// The units of FILETIME are 100ns intervals, so by multiplying by or dividing 314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// by 10000000, we can convert to/from seconds. 315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// FileTime = UnixTime*10000000 + FileTime(1970) 317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// UnixTime = (FileTime-FileTime(1970))/10000000 318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// 319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid FileTimeToUnixTime(const FILETIME& ft, time_t* ut) { 321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(NULL != ut); 322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // FILETIME has an earlier date base than time_t (1/1/1970), so subtract off 324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // the difference. 325f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SYSTEMTIME base_st; 326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memset(&base_st, 0, sizeof(base_st)); 327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org base_st.wDay = 1; 328f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org base_st.wMonth = 1; 329f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org base_st.wYear = 1970; 330f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 331f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org FILETIME base_ft; 332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SystemTimeToFileTime(&base_st, &base_ft); 333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ULARGE_INTEGER base_ul, current_ul; 335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(&base_ul, &base_ft, sizeof(FILETIME)); 336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(¤t_ul, &ft, sizeof(FILETIME)); 337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Divide by big number to convert to seconds, then subtract out the 1970 339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // base date value. 340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const ULONGLONG RATIO = 10000000; 341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *ut = static_cast<time_t>((current_ul.QuadPart - base_ul.QuadPart) / RATIO); 342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid UnixTimeToFileTime(const time_t& ut, FILETIME* ft) { 345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(NULL != ft); 346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // FILETIME has an earlier date base than time_t (1/1/1970), so add in 348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // the difference. 349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SYSTEMTIME base_st; 350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memset(&base_st, 0, sizeof(base_st)); 351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org base_st.wDay = 1; 352f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org base_st.wMonth = 1; 353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org base_st.wYear = 1970; 354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org FILETIME base_ft; 356f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SystemTimeToFileTime(&base_st, &base_ft); 357f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 358f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ULARGE_INTEGER base_ul; 359f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(&base_ul, &base_ft, sizeof(FILETIME)); 360f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 361f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Multiply by big number to convert to 100ns units, then add in the 1970 362f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // base date value. 363f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const ULONGLONG RATIO = 10000000; 364f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ULARGE_INTEGER current_ul; 3650c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström current_ul.QuadPart = base_ul.QuadPart + static_cast<int64_t>(ut) * RATIO; 366f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(ft, ¤t_ul, sizeof(FILETIME)); 367f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 368f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 369f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool Utf8ToWindowsFilename(const std::string& utf8, std::wstring* filename) { 370f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Integrate into fileutils.h 371f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Handle wide and non-wide cases via TCHAR? 372f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Skip \\?\ processing if the length is not > MAX_PATH? 373f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // TODO: Write unittests 374f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 375f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Convert to Utf16 376f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int wlen = ::MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), 377f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(utf8.length() + 1), NULL, 378f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 0); 379f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (0 == wlen) { 380f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 381f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 382f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wchar_t* wfilename = STACK_ARRAY(wchar_t, wlen); 383f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (0 == ::MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), 384f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<int>(utf8.length() + 1), 385f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wfilename, wlen)) { 386f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 387f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 388f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Replace forward slashes with backslashes 389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org std::replace(wfilename, wfilename + wlen, L'/', L'\\'); 390f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Convert to complete filename 391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DWORD full_len = ::GetFullPathName(wfilename, 0, NULL, NULL); 392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (0 == full_len) { 393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 395f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wchar_t* filepart = NULL; 396f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wchar_t* full_filename = STACK_ARRAY(wchar_t, full_len + 6); 397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org wchar_t* start = full_filename + 6; 398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (0 == ::GetFullPathName(wfilename, full_len, start, &filepart)) { 399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Add long-path prefix 402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const wchar_t kLongPathPrefix[] = L"\\\\?\\UNC"; 403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if ((start[0] != L'\\') || (start[1] != L'\\')) { 404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Non-unc path: <pathname> 405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Becomes: \\?\<pathname> 406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org start -= 4; 407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(start >= full_filename); 408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(start, kLongPathPrefix, 4 * sizeof(wchar_t)); 409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else if (start[2] != L'?') { 410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Unc path: \\<server>\<pathname> 411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Becomes: \\?\UNC\<server>\<pathname> 412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org start -= 6; 413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT(start >= full_filename); 414f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org memcpy(start, kLongPathPrefix, 7 * sizeof(wchar_t)); 415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } else { 416f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Already in long-path form. 417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org filename->assign(start); 419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return true; 420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool GetOsVersion(int* major, int* minor, int* build) { 423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org OSVERSIONINFO info = {0}; 424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org info.dwOSVersionInfoSize = sizeof(info); 425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (GetVersionEx(&info)) { 426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (major) *major = info.dwMajorVersion; 427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (minor) *minor = info.dwMinorVersion; 428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (build) *build = info.dwBuildNumber; 429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return true; 430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return false; 432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool GetCurrentProcessIntegrityLevel(int* level) { 435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool ret = false; 436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org HANDLE process = ::GetCurrentProcess(), token; 437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (OpenProcessToken(process, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &token)) { 438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DWORD size; 439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &size) && 440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org GetLastError() == ERROR_INSUFFICIENT_BUFFER) { 441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org char* buf = STACK_ARRAY(char, size); 443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org TOKEN_MANDATORY_LABEL* til = 444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org reinterpret_cast<TOKEN_MANDATORY_LABEL*>(buf); 445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (GetTokenInformation(token, TokenIntegrityLevel, til, size, &size)) { 446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org DWORD count = *GetSidSubAuthorityCount(til->Label.Sid); 448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *level = *GetSidSubAuthority(til->Label.Sid, count - 1); 449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ret = true; 450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CloseHandle(token); 453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return ret; 455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 4565ec998511c5ac8e0602fe3373f214fcc3ef33a24AndrĂ© Susano Pinto 457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} // namespace rtc 458