/**
 * Windows API header module
 *
 * Translated from MinGW Windows headers
 *
 * Authors: Stewart Gordon
 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
 * Source: $(DRUNTIMESRC core/sys/windows/_wininet.d)
 */
module core.sys.windows.wininet;
version (Windows):

version (ANSI) {} else version = Unicode;
pragma(lib, "wininet");

// FIXME: check types and grouping of constants

import core.sys.windows.winbase, core.sys.windows.windef;

// From Winineti.h
enum {
    INTERNET_FLAG_BGUPDATE         = 0x00000008,
}

enum {
    INTERNET_INVALID_PORT_NUMBER =    0,
    INTERNET_DEFAULT_FTP_PORT    =   21,
    INTERNET_DEFAULT_GOPHER_PORT =   70,
    INTERNET_DEFAULT_HTTP_PORT   =   80,
    INTERNET_DEFAULT_HTTPS_PORT  =  443,
    INTERNET_DEFAULT_SOCKS_PORT  = 1080
}

enum size_t
    MAX_CACHE_ENTRY_INFO_SIZE       =  4096,
    INTERNET_MAX_HOST_NAME_LENGTH   =   256,
    INTERNET_MAX_USER_NAME_LENGTH   =   128,
    INTERNET_MAX_PASSWORD_LENGTH    =   128,
    INTERNET_MAX_PORT_NUMBER_LENGTH =     5,
    INTERNET_MAX_PORT_NUMBER_VALUE  = 65535,
    INTERNET_MAX_PATH_LENGTH        =  2048,
    INTERNET_MAX_SCHEME_LENGTH      =    32,
    INTERNET_MAX_URL_LENGTH         = INTERNET_MAX_SCHEME_LENGTH
                                      + "://".length
                                      + INTERNET_MAX_PATH_LENGTH;

enum : DWORD {
    INTERNET_KEEP_ALIVE_UNKNOWN  = DWORD.max,
    INTERNET_KEEP_ALIVE_DISABLED = 0,
    INTERNET_KEEP_ALIVE_ENABLED
}

enum {
    INTERNET_REQFLAG_FROM_CACHE           = 0x00000001,
    INTERNET_REQFLAG_ASYNC                = 0x00000002,
    INTERNET_REQFLAG_VIA_PROXY            = 0x00000004,
    INTERNET_REQFLAG_NO_HEADERS           = 0x00000008,
    INTERNET_REQFLAG_PASSIVE              = 0x00000010,
    INTERNET_REQFLAG_CACHE_WRITE_DISABLED = 0x00000040,
    INTERNET_REQFLAG_NET_TIMEOUT          = 0x00000080,
}

enum {
    INTERNET_FLAG_IDN_DIRECT = 0x00000001,
    INTERNET_FLAG_IDN_PROXY  = 0x00000002
}

enum DWORD
    INTERNET_FLAG_RELOAD                   = 0x80000000,
    INTERNET_FLAG_RAW_DATA                 = 0x40000000,
    INTERNET_FLAG_EXISTING_CONNECT         = 0x20000000,
    INTERNET_FLAG_ASYNC                    = 0x10000000,
    INTERNET_FLAG_PASSIVE                  = 0x08000000,
    INTERNET_FLAG_NO_CACHE_WRITE           = 0x04000000,
    INTERNET_FLAG_DONT_CACHE               = INTERNET_FLAG_NO_CACHE_WRITE,
    INTERNET_FLAG_MAKE_PERSISTENT          = 0x02000000,
    INTERNET_FLAG_FROM_CACHE               = 0x01000000,
    INTERNET_FLAG_OFFLINE                  = INTERNET_FLAG_FROM_CACHE,
    INTERNET_FLAG_SECURE                   = 0x00800000,
    INTERNET_FLAG_KEEP_CONNECTION          = 0x00400000,
    INTERNET_FLAG_NO_AUTO_REDIRECT         = 0x00200000,
    INTERNET_FLAG_READ_PREFETCH            = 0x00100000,
    INTERNET_FLAG_NO_COOKIES               = 0x00080000,
    INTERNET_FLAG_NO_AUTH                  = 0x00040000,
    INTERNET_FLAG_RESTRICTED_ZONE          = 0x00020000,
    INTERNET_FLAG_CACHE_IF_NET_FAIL        = 0x00010000,
    INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP  = 0x00008000,
    INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS = 0x00004000,
    INTERNET_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000,
    INTERNET_FLAG_IGNORE_CERT_CN_INVALID   = 0x00001000,
    INTERNET_FLAG_RESYNCHRONIZE            = 0x00000800,
    INTERNET_FLAG_HYPERLINK                = 0x00000400,
    INTERNET_FLAG_NO_UI                    = 0x00000200,
    INTERNET_FLAG_PRAGMA_NOCACHE           = 0x00000100,
    INTERNET_FLAG_CACHE_ASYNC              = 0x00000080,
    INTERNET_FLAG_FORMS_SUBMIT             = 0x00000040,
    INTERNET_FLAG_FWD_BACK                 = 0x00000020,
    INTERNET_FLAG_NEED_FILE                = 0x00000010,
    INTERNET_FLAG_MUST_CACHE_REQUEST       = INTERNET_FLAG_NEED_FILE,
    INTERNET_FLAG_TRANSFER_ASCII           = FTP_TRANSFER_TYPE_ASCII,
    INTERNET_FLAG_TRANSFER_BINARY          = FTP_TRANSFER_TYPE_BINARY,

    SECURITY_INTERNET_MASK                 = INTERNET_FLAG_IGNORE_CERT_CN_INVALID   |
                                             INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
                                             INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS |
                                             INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP,

    SECURITY_SET_MASK                      = SECURITY_INTERNET_MASK,

    INTERNET_FLAGS_MASK                    = INTERNET_FLAG_RELOAD
                                            | INTERNET_FLAG_RAW_DATA
                                            | INTERNET_FLAG_EXISTING_CONNECT
                                            | INTERNET_FLAG_ASYNC
                                            | INTERNET_FLAG_PASSIVE
                                            | INTERNET_FLAG_NO_CACHE_WRITE
                                            | INTERNET_FLAG_MAKE_PERSISTENT
                                            | INTERNET_FLAG_FROM_CACHE
                                            | INTERNET_FLAG_SECURE
                                            | INTERNET_FLAG_KEEP_CONNECTION
                                            | INTERNET_FLAG_NO_AUTO_REDIRECT
                                            | INTERNET_FLAG_READ_PREFETCH
                                            | INTERNET_FLAG_NO_COOKIES
                                            | INTERNET_FLAG_NO_AUTH
                                            | INTERNET_FLAG_CACHE_IF_NET_FAIL
                                            | SECURITY_INTERNET_MASK
                                            | INTERNET_FLAG_RESYNCHRONIZE
                                            | INTERNET_FLAG_HYPERLINK
                                            | INTERNET_FLAG_NO_UI
                                            | INTERNET_FLAG_PRAGMA_NOCACHE
                                            | INTERNET_FLAG_CACHE_ASYNC
                                            | INTERNET_FLAG_FORMS_SUBMIT
                                            | INTERNET_FLAG_NEED_FILE
                                            | INTERNET_FLAG_RESTRICTED_ZONE
                                            | INTERNET_FLAG_TRANSFER_BINARY
                                            | INTERNET_FLAG_TRANSFER_ASCII
                                            | INTERNET_FLAG_FWD_BACK
                                            | INTERNET_FLAG_BGUPDATE,

    INTERNET_ERROR_MASK_INSERT_CDROM                      = 0x1,
    INTERNET_ERROR_MASK_COMBINED_SEC_CERT                 = 0x2,
    INTERNET_ERROR_MASK_NEED_MSN_SSPI_PKG                 = 0X4,
    INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY = 0x8,

    INTERNET_OPTIONS_MASK                  = ~INTERNET_FLAGS_MASK;

enum INTERNET_NO_CALLBACK = 0;
enum INTERNET_RFC1123_FORMAT = 0;
enum size_t INTERNET_RFC1123_BUFSIZE = 30;

enum DWORD
    ICU_ESCAPE             = 0x80000000,
    ICU_USERNAME           = 0x40000000,
    ICU_NO_ENCODE          = 0x20000000,
    ICU_DECODE             = 0x10000000,
    ICU_NO_META            = 0x08000000,
    ICU_ENCODE_SPACES_ONLY = 0x04000000,
    ICU_BROWSER_MODE       = 0x02000000;

enum {
    INTERNET_OPEN_TYPE_PRECONFIG = 0,
    INTERNET_OPEN_TYPE_DIRECT    = 1,
    INTERNET_OPEN_TYPE_PROXY     = 3,
    PRE_CONFIG_INTERNET_ACCESS   = INTERNET_OPEN_TYPE_PRECONFIG,
    LOCAL_INTERNET_ACCESS        = INTERNET_OPEN_TYPE_DIRECT,
    GATEWAY_INTERNET_ACCESS      = 2,
    CERN_PROXY_INTERNET_ACCESS   = INTERNET_OPEN_TYPE_PROXY,
}

enum ISO_GLOBAL      = 1;
enum ISO_REGISTRY    = 2;
enum ISO_VALID_FLAGS = ISO_GLOBAL | ISO_REGISTRY;

enum {
    INTERNET_OPTION_CALLBACK                    =  1,
    INTERNET_OPTION_CONNECT_TIMEOUT,
    INTERNET_OPTION_CONNECT_RETRIES,
    INTERNET_OPTION_CONNECT_BACKOFF,
    INTERNET_OPTION_SEND_TIMEOUT,
    INTERNET_OPTION_CONTROL_SEND_TIMEOUT        = INTERNET_OPTION_SEND_TIMEOUT,
    INTERNET_OPTION_RECEIVE_TIMEOUT,
    INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT  = INTERNET_OPTION_RECEIVE_TIMEOUT,
    INTERNET_OPTION_DATA_SEND_TIMEOUT,
    INTERNET_OPTION_DATA_RECEIVE_TIMEOUT,
    INTERNET_OPTION_HANDLE_TYPE                 = 9,
    INTERNET_OPTION_LISTEN_TIMEOUT              = 11,
    INTERNET_OPTION_READ_BUFFER_SIZE,
    INTERNET_OPTION_WRITE_BUFFER_SIZE,       // = 13
    INTERNET_OPTION_ASYNC_ID                    = 15,
    INTERNET_OPTION_ASYNC_PRIORITY,          // = 16
    INTERNET_OPTION_PARENT_HANDLE               = 21,
    INTERNET_OPTION_KEEP_CONNECTION,
    INTERNET_OPTION_REQUEST_FLAGS,
    INTERNET_OPTION_EXTENDED_ERROR,          // = 24
    INTERNET_OPTION_OFFLINE_MODE                = 26,
    INTERNET_OPTION_CACHE_STREAM_HANDLE,
    INTERNET_OPTION_USERNAME,
    INTERNET_OPTION_PASSWORD,
    INTERNET_OPTION_ASYNC,
    INTERNET_OPTION_SECURITY_FLAGS,
    INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT,
    INTERNET_OPTION_DATAFILE_NAME,
    INTERNET_OPTION_URL,
    INTERNET_OPTION_SECURITY_CERTIFICATE,
    INTERNET_OPTION_SECURITY_KEY_BITNESS,
    INTERNET_OPTION_REFRESH,
    INTERNET_OPTION_PROXY,
    INTERNET_OPTION_SETTINGS_CHANGED,
    INTERNET_OPTION_VERSION,
    INTERNET_OPTION_USER_AGENT,
    INTERNET_OPTION_END_BROWSER_SESSION,
    INTERNET_OPTION_PROXY_USERNAME,
    INTERNET_OPTION_PROXY_PASSWORD,          // = 44
    INTERNET_OPTION_CONTEXT_VALUE          = 45,
    INTERNET_OPTION_CONNECT_LIMIT          = 46,
    INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT= 47,
    INTERNET_OPTION_POLICY                 = 48,
    INTERNET_OPTION_DISCONNECTED_TIMEOUT   = 49,
    INTERNET_OPTION_CONNECTED_STATE        = 50,
    INTERNET_OPTION_IDLE_STATE             = 51,
    INTERNET_OPTION_OFFLINE_SEMANTICS      = 52,
    INTERNET_OPTION_SECONDARY_CACHE_KEY    = 53,
    INTERNET_OPTION_CALLBACK_FILTER        = 54,
    INTERNET_OPTION_CONNECT_TIME           = 55,
    INTERNET_OPTION_SEND_THROUGHPUT        = 56,
    INTERNET_OPTION_RECEIVE_THROUGHPUT     = 57,
    INTERNET_OPTION_REQUEST_PRIORITY       = 58,
    INTERNET_OPTION_HTTP_VERSION           = 59,
    INTERNET_OPTION_RESET_URLCACHE_SESSION = 60,
    INTERNET_OPTION_ERROR_MASK             = 62,
    INTERNET_OPTION_FROM_CACHE_TIMEOUT     = 63,
    INTERNET_OPTION_BYPASS_EDITED_ENTRY    = 64,
    INTERNET_OPTION_HTTP_DECODING          = 65,
    INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO = 67,
    INTERNET_OPTION_CODEPAGE               = 68,
    INTERNET_OPTION_CACHE_TIMESTAMPS       = 69,
    INTERNET_OPTION_DISABLE_AUTODIAL       = 70,
    INTERNET_OPTION_MAX_CONNS_PER_SERVER    = 73,
    INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER= 74,
    INTERNET_OPTION_PER_CONNECTION_OPTION  = 75,
    INTERNET_OPTION_DIGEST_AUTH_UNLOAD            = 76,
    INTERNET_OPTION_IGNORE_OFFLINE          = 77,
    INTERNET_OPTION_IDENTITY                = 78,
    INTERNET_OPTION_REMOVE_IDENTITY         = 79,
    INTERNET_OPTION_ALTER_IDENTITY          = 80,
    INTERNET_OPTION_SUPPRESS_BEHAVIOR       = 81,
    INTERNET_OPTION_AUTODIAL_MODE           = 82,
    INTERNET_OPTION_AUTODIAL_CONNECTION     = 83,
    INTERNET_OPTION_CLIENT_CERT_CONTEXT     = 84,
    INTERNET_OPTION_AUTH_FLAGS              = 85,
    INTERNET_OPTION_COOKIES_3RD_PARTY       = 86,
    INTERNET_OPTION_DISABLE_PASSPORT_AUTH   = 87,
    INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY        = 88,
    INTERNET_OPTION_EXEMPT_CONNECTION_LIMIT = 89,
    INTERNET_OPTION_ENABLE_PASSPORT_AUTH    = 90,
    INTERNET_OPTION_HIBERNATE_INACTIVE_WORKER_THREADS      = 91,
    INTERNET_OPTION_ACTIVATE_WORKER_THREADS                = 92,
    INTERNET_OPTION_RESTORE_WORKER_THREAD_DEFAULTS         = 93,
    INTERNET_OPTION_SOCKET_SEND_BUFFER_LENGTH              = 94,
    INTERNET_OPTION_PROXY_SETTINGS_CHANGED                 = 95,
    INTERNET_OPTION_DATAFILE_EXT                           = 96,
    INTERNET_OPTION_CODEPAGE_PATH               = 100,
    INTERNET_OPTION_CODEPAGE_EXTRA              = 101,
    INTERNET_OPTION_IDN                         = 102,
    INTERNET_OPTION_MAX_CONNS_PER_PROXY         = 103,
    INTERNET_OPTION_SUPPRESS_SERVER_AUTH        = 104,
    INTERNET_OPTION_SERVER_CERT_CHAIN_CONTEXT   = 105,
    INTERNET_OPTION_ENABLE_REDIRECT_CACHE_READ  = 122,
    INTERNET_OPTION_COMPRESSED_CONTENT_LENGTH   = 147,
    INTERNET_OPTION_ENABLE_HTTP_PROTOCOL        = 148,
    INTERNET_OPTION_HTTP_PROTOCOL_USED          = 149,
    INTERNET_OPTION_ENCODE_EXTRA                = 155,
    INTERNET_OPTION_HSTS                        = 157,
    INTERNET_OPTION_ENTERPRISE_CONTEXT          = 159,
    INTERNET_OPTION_CONNECTION_FILTER           = 162,
    INTERNET_OPTION_REFERER_TOKEN_BINDING_HOSTNAME         = 163,
    INTERNET_OPTION_TOKEN_BINDING_PUBLIC_KEY    = 181,
    INTERNET_OPTION_COOKIES_SAME_SITE_LEVEL     = 187,
    INTERNET_FIRST_OPTION                  = INTERNET_OPTION_CALLBACK,
    INTERNET_LAST_OPTION                   = INTERNET_OPTION_COOKIES_SAME_SITE_LEVEL,
}

enum INTERNET_PRIORITY_FOREGROUND = 1000;

enum {
    INTERNET_HANDLE_TYPE_INTERNET = 1,
    INTERNET_HANDLE_TYPE_CONNECT_FTP,
    INTERNET_HANDLE_TYPE_CONNECT_GOPHER,
    INTERNET_HANDLE_TYPE_CONNECT_HTTP,
    INTERNET_HANDLE_TYPE_FTP_FIND,
    INTERNET_HANDLE_TYPE_FTP_FIND_HTML,
    INTERNET_HANDLE_TYPE_FTP_FILE,
    INTERNET_HANDLE_TYPE_FTP_FILE_HTML,
    INTERNET_HANDLE_TYPE_GOPHER_FIND,
    INTERNET_HANDLE_TYPE_GOPHER_FIND_HTML,
    INTERNET_HANDLE_TYPE_GOPHER_FILE,
    INTERNET_HANDLE_TYPE_GOPHER_FILE_HTML,
    INTERNET_HANDLE_TYPE_HTTP_REQUEST
}

enum DWORD
    SECURITY_FLAG_SECURE                   = 0x00000001,
    SECURITY_FLAG_SSL                      = 0x00000002,
    SECURITY_FLAG_SSL3                     = 0x00000004,
    SECURITY_FLAG_PCT                      = 0x00000008,
    SECURITY_FLAG_PCT4                     = 0x00000010,
    SECURITY_FLAG_IETFSSL4                 = 0x00000020,
    SECURITY_FLAG_IGNORE_REVOCATION        = 0x00000080,
    SECURITY_FLAG_IGNORE_UNKNOWN_CA        = 0x00000100,
    SECURITY_FLAG_IGNORE_WRONG_USAGE       = 0x00000200,
    SECURITY_FLAG_40BIT                    = 0x10000000,
    SECURITY_FLAG_128BIT                   = 0x20000000,
    SECURITY_FLAG_56BIT                    = 0x40000000,
    SECURITY_FLAG_UNKNOWNBIT               = 0x80000000,
    SECURITY_FLAG_NORMALBITNESS            = SECURITY_FLAG_40BIT,
    SECURITY_FLAG_IGNORE_CERT_CN_INVALID   = INTERNET_FLAG_IGNORE_CERT_CN_INVALID,
    SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = INTERNET_FLAG_IGNORE_CERT_DATE_INVALID,
    SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTPS = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS,
    SECURITY_FLAG_IGNORE_REDIRECT_TO_HTTP  = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP;

enum {
    INTERNET_SERVICE_FTP = 1,
    INTERNET_SERVICE_GOPHER,
    INTERNET_SERVICE_HTTP
}

enum {
    INTERNET_STATUS_RESOLVING_NAME        =  10,
    INTERNET_STATUS_NAME_RESOLVED         =  11,
    INTERNET_STATUS_CONNECTING_TO_SERVER  =  20,
    INTERNET_STATUS_CONNECTED_TO_SERVER   =  21,
    INTERNET_STATUS_SENDING_REQUEST       =  30,
    INTERNET_STATUS_REQUEST_SENT          =  31,
    INTERNET_STATUS_RECEIVING_RESPONSE    =  40,
    INTERNET_STATUS_RESPONSE_RECEIVED     =  41,
    INTERNET_STATUS_CTL_RESPONSE_RECEIVED =  42,
    INTERNET_STATUS_PREFETCH              =  43,
    INTERNET_STATUS_CLOSING_CONNECTION    =  50,
    INTERNET_STATUS_CONNECTION_CLOSED     =  51,
    INTERNET_STATUS_HANDLE_CREATED        =  60,
    INTERNET_STATUS_HANDLE_CLOSING        =  70,
    INTERNET_STATUS_REQUEST_COMPLETE      = 100,
    INTERNET_STATUS_REDIRECT              = 110
}

enum {
    FTP_TRANSFER_TYPE_UNKNOWN = 0,
    FTP_TRANSFER_TYPE_ASCII   = 1,
    FTP_TRANSFER_TYPE_BINARY  = 2,
    FTP_TRANSFER_TYPE_MASK    = 3
}

enum size_t
    MAX_GOPHER_DISPLAY_TEXT   = 128,
    MAX_GOPHER_SELECTOR_TEXT  = 256,
    MAX_GOPHER_HOST_NAME      = INTERNET_MAX_HOST_NAME_LENGTH,
    MAX_GOPHER_LOCATOR_LENGTH
      = 1 + MAX_GOPHER_DISPLAY_TEXT + 1 + MAX_GOPHER_SELECTOR_TEXT + 1
        + MAX_GOPHER_HOST_NAME + 1 + INTERNET_MAX_PORT_NUMBER_LENGTH + 4;

enum DWORD
    GOPHER_TYPE_TEXT_FILE      = 0x00000001,
    GOPHER_TYPE_DIRECTORY      = 0x00000002,
    GOPHER_TYPE_CSO            = 0x00000004,
    GOPHER_TYPE_ERROR          = 0x00000008,
    GOPHER_TYPE_MAC_BINHEX     = 0x00000010,
    GOPHER_TYPE_DOS_ARCHIVE    = 0x00000020,
    GOPHER_TYPE_UNIX_UUENCODED = 0x00000040,
    GOPHER_TYPE_INDEX_SERVER   = 0x00000080,
    GOPHER_TYPE_TELNET         = 0x00000100,
    GOPHER_TYPE_BINARY         = 0x00000200,
    GOPHER_TYPE_REDUNDANT      = 0x00000400,
    GOPHER_TYPE_TN3270         = 0x00000800,
    GOPHER_TYPE_GIF            = 0x00001000,
    GOPHER_TYPE_IMAGE          = 0x00002000,
    GOPHER_TYPE_BITMAP         = 0x00004000,
    GOPHER_TYPE_MOVIE          = 0x00008000,
    GOPHER_TYPE_SOUND          = 0x00010000,
    GOPHER_TYPE_HTML           = 0x00020000,
    GOPHER_TYPE_PDF            = 0x00040000,
    GOPHER_TYPE_CALENDAR       = 0x00080000,
    GOPHER_TYPE_INLINE         = 0x00100000,
    GOPHER_TYPE_UNKNOWN        = 0x20000000,
    GOPHER_TYPE_ASK            = 0x40000000,
    GOPHER_TYPE_GOPHER_PLUS    = 0x80000000,
    GOPHER_TYPE_FILE_MASK      = 0x001FF271;

BOOL IS_GOPHER_FILE(DWORD t) {
    return !!(t & GOPHER_TYPE_FILE_MASK);
}

BOOL IS_GOPHER_DIRECTORY(DWORD t) {
    return !!(t & GOPHER_TYPE_DIRECTORY);
}

BOOL IS_GOPHER_PHONE_SERVER(DWORD t) {
    return !!(t & GOPHER_TYPE_CSO);
}

BOOL IS_GOPHER_ERROR(DWORD t) {
    return !!(t & GOPHER_TYPE_ERROR);
}

BOOL IS_GOPHER_INDEX_SERVER(DWORD t) {
    return !!(t & GOPHER_TYPE_INDEX_SERVER);
}

BOOL IS_GOPHER_TELNET_SESSION(DWORD t) {
    return !!(t & GOPHER_TYPE_TELNET);
}

BOOL IS_GOPHER_BACKUP_SERVER(DWORD t) {
    return !!(t & GOPHER_TYPE_REDUNDANT);
}

BOOL IS_GOPHER_TN3270_SESSION(DWORD t) {
    return !!(t & GOPHER_TYPE_TN3270);
}

BOOL IS_GOPHER_ASK(DWORD t) {
    return !!(t & GOPHER_TYPE_ASK);
}

BOOL IS_GOPHER_PLUS(DWORD t) {
    return !!(t & GOPHER_TYPE_GOPHER_PLUS);
}

BOOL IS_GOPHER_TYPE_KNOWN(DWORD t) {
    return !(t & GOPHER_TYPE_UNKNOWN);
}

enum size_t
    MAX_GOPHER_CATEGORY_NAME    = 128,
    MAX_GOPHER_ATTRIBUTE_NAME   = 128,
    MIN_GOPHER_ATTRIBUTE_LENGTH = 256;

const TCHAR[]
    GOPHER_INFO_CATEGORY      = "+INFO",
    GOPHER_ADMIN_CATEGORY     = "+ADMIN",
    GOPHER_VIEWS_CATEGORY     = "+VIEWS",
    GOPHER_ABSTRACT_CATEGORY  = "+ABSTRACT",
    GOPHER_VERONICA_CATEGORY  = "+VERONICA",
    GOPHER_ADMIN_ATTRIBUTE    = "Admin",
    GOPHER_MOD_DATE_ATTRIBUTE = "Mod-Date",
    GOPHER_TTL_ATTRIBUTE      = "TTL",
    GOPHER_SCORE_ATTRIBUTE    = "Score",
    GOPHER_RANGE_ATTRIBUTE    = "Score-range",
    GOPHER_SITE_ATTRIBUTE     = "Site",
    GOPHER_ORG_ATTRIBUTE      = "Org",
    GOPHER_LOCATION_ATTRIBUTE = "Loc",
    GOPHER_GEOG_ATTRIBUTE     = "Geog",
    GOPHER_TIMEZONE_ATTRIBUTE = "TZ",
    GOPHER_PROVIDER_ATTRIBUTE = "Provider",
    GOPHER_VERSION_ATTRIBUTE  = "Version",
    GOPHER_ABSTRACT_ATTRIBUTE = "Abstract",
    GOPHER_VIEW_ATTRIBUTE     = "View",
    GOPHER_TREEWALK_ATTRIBUTE = "treewalk";

enum : DWORD {
    GOPHER_ATTRIBUTE_ID_BASE = 0xABCCCC00,
    GOPHER_CATEGORY_ID_ALL,
    GOPHER_CATEGORY_ID_INFO,
    GOPHER_CATEGORY_ID_ADMIN,
    GOPHER_CATEGORY_ID_VIEWS,
    GOPHER_CATEGORY_ID_ABSTRACT,
    GOPHER_CATEGORY_ID_VERONICA,
    GOPHER_CATEGORY_ID_ASK,
    GOPHER_CATEGORY_ID_UNKNOWN,
    GOPHER_ATTRIBUTE_ID_ALL,
    GOPHER_ATTRIBUTE_ID_ADMIN,
    GOPHER_ATTRIBUTE_ID_MOD_DATE,
    GOPHER_ATTRIBUTE_ID_TTL,
    GOPHER_ATTRIBUTE_ID_SCORE,
    GOPHER_ATTRIBUTE_ID_RANGE,
    GOPHER_ATTRIBUTE_ID_SITE,
    GOPHER_ATTRIBUTE_ID_ORG,
    GOPHER_ATTRIBUTE_ID_LOCATION,
    GOPHER_ATTRIBUTE_ID_GEOG,
    GOPHER_ATTRIBUTE_ID_TIMEZONE,
    GOPHER_ATTRIBUTE_ID_PROVIDER,
    GOPHER_ATTRIBUTE_ID_VERSION,
    GOPHER_ATTRIBUTE_ID_ABSTRACT,
    GOPHER_ATTRIBUTE_ID_VIEW,
    GOPHER_ATTRIBUTE_ID_TREEWALK,
    GOPHER_ATTRIBUTE_ID_UNKNOWN
}

enum HTTP_MAJOR_VERSION   = 1;
enum HTTP_MINOR_VERSION   = 0;
const TCHAR[] HTTP_VERSION = "HTTP/1.0";

enum : DWORD {
    HTTP_QUERY_MIME_VERSION,
    HTTP_QUERY_CONTENT_TYPE,
    HTTP_QUERY_CONTENT_TRANSFER_ENCODING,
    HTTP_QUERY_CONTENT_ID,
    HTTP_QUERY_CONTENT_DESCRIPTION,
    HTTP_QUERY_CONTENT_LENGTH,
    HTTP_QUERY_CONTENT_LANGUAGE,
    HTTP_QUERY_ALLOW,
    HTTP_QUERY_PUBLIC,
    HTTP_QUERY_DATE,
    HTTP_QUERY_EXPIRES,
    HTTP_QUERY_LAST_MODIFIED,
    HTTP_QUERY_MESSAGE_ID,
    HTTP_QUERY_URI,
    HTTP_QUERY_DERIVED_FROM,
    HTTP_QUERY_COST,
    HTTP_QUERY_LINK,
    HTTP_QUERY_PRAGMA,
    HTTP_QUERY_VERSION,
    HTTP_QUERY_STATUS_CODE,
    HTTP_QUERY_STATUS_TEXT,
    HTTP_QUERY_RAW_HEADERS,
    HTTP_QUERY_RAW_HEADERS_CRLF,
    HTTP_QUERY_CONNECTION,
    HTTP_QUERY_ACCEPT,
    HTTP_QUERY_ACCEPT_CHARSET,
    HTTP_QUERY_ACCEPT_ENCODING,
    HTTP_QUERY_ACCEPT_LANGUAGE,
    HTTP_QUERY_AUTHORIZATION,
    HTTP_QUERY_CONTENT_ENCODING,
    HTTP_QUERY_FORWARDED,
    HTTP_QUERY_FROM,
    HTTP_QUERY_IF_MODIFIED_SINCE,
    HTTP_QUERY_LOCATION,
    HTTP_QUERY_ORIG_URI,
    HTTP_QUERY_REFERER,
    HTTP_QUERY_RETRY_AFTER,
    HTTP_QUERY_SERVER,
    HTTP_QUERY_TITLE,
    HTTP_QUERY_USER_AGENT,
    HTTP_QUERY_WWW_AUTHENTICATE,
    HTTP_QUERY_PROXY_AUTHENTICATE,
    HTTP_QUERY_ACCEPT_RANGES,
    HTTP_QUERY_SET_COOKIE,
    HTTP_QUERY_COOKIE,
    HTTP_QUERY_REQUEST_METHOD,
    HTTP_QUERY_MAX    = 45,
    HTTP_QUERY_CUSTOM = 65535
}

enum DWORD
    HTTP_QUERY_FLAG_REQUEST_HEADERS = 0x80000000,
    HTTP_QUERY_FLAG_SYSTEMTIME      = 0x40000000,
    HTTP_QUERY_FLAG_NUMBER          = 0x20000000,
    HTTP_QUERY_FLAG_COALESCE        = 0x10000000,
    HTTP_QUERY_MODIFIER_FLAGS_MASK  = 0xF0000000,
    HTTP_QUERY_HEADER_MASK          = ~HTTP_QUERY_MODIFIER_FLAGS_MASK;

enum {
    HTTP_STATUS_OK                 = 200,
    HTTP_STATUS_CREATED,
    HTTP_STATUS_ACCEPTED,
    HTTP_STATUS_PARTIAL,
    HTTP_STATUS_NO_CONTENT,     // = 204
    HTTP_STATUS_AMBIGUOUS          = 300,
    HTTP_STATUS_MOVED,
    HTTP_STATUS_REDIRECT,
    HTTP_STATUS_REDIRECT_METHOD,
    HTTP_STATUS_NOT_MODIFIED,   // = 304
    HTTP_STATUS_BAD_REQUEST        = 400,
    HTTP_STATUS_DENIED,
    HTTP_STATUS_PAYMENT_REQ,
    HTTP_STATUS_FORBIDDEN,
    HTTP_STATUS_NOT_FOUND,
    HTTP_STATUS_BAD_METHOD,
    HTTP_STATUS_NONE_ACCEPTABLE,
    HTTP_STATUS_PROXY_AUTH_REQ,
    HTTP_STATUS_REQUEST_TIMEOUT,
    HTTP_STATUS_CONFLICT,
    HTTP_STATUS_GONE,
    HTTP_STATUS_AUTH_REFUSED,   // = 411
    HTTP_STATUS_SERVER_ERROR       = 500,
    HTTP_STATUS_NOT_SUPPORTED,
    HTTP_STATUS_BAD_GATEWAY,
    HTTP_STATUS_SERVICE_UNAVAIL,
    HTTP_STATUS_GATEWAY_TIMEOUT // = 504
}

enum {
    INTERNET_PREFETCH_PROGRESS,
    INTERNET_PREFETCH_COMPLETE,
    INTERNET_PREFETCH_ABORTED
}

enum FLAGS_ERROR_UI_FILTER_FOR_ERRORS    = 0x01;
enum FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS = 0x02;
enum FLAGS_ERROR_UI_FLAGS_GENERATE_DATA  = 0x04;
enum FLAGS_ERROR_UI_FLAGS_NO_UI          = 0x08;

enum DWORD
    HTTP_ADDREQ_INDEX_MASK                   = 0x0000FFFF,
    HTTP_ADDREQ_FLAGS_MASK                   = 0xFFFF0000,
    HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = 0x01000000,
    HTTP_ADDREQ_FLAG_ADD_IF_NEW              = 0x10000000,
    HTTP_ADDREQ_FLAG_ADD                     = 0x20000000,
    HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA     = 0x40000000,
    HTTP_ADDREQ_FLAG_COALESCE          = HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA,
    HTTP_ADDREQ_FLAG_REPLACE                 = 0x80000000;

enum {
    INTERNET_ERROR_BASE                       = 12000,
    ERROR_INTERNET_OUT_OF_HANDLES,
    ERROR_INTERNET_TIMEOUT,
    ERROR_INTERNET_EXTENDED_ERROR,
    ERROR_INTERNET_INTERNAL_ERROR,
    ERROR_INTERNET_INVALID_URL,
    ERROR_INTERNET_UNRECOGNIZED_SCHEME,
    ERROR_INTERNET_NAME_NOT_RESOLVED,
    ERROR_INTERNET_PROTOCOL_NOT_FOUND,
    ERROR_INTERNET_INVALID_OPTION,
    ERROR_INTERNET_BAD_OPTION_LENGTH,
    ERROR_INTERNET_OPTION_NOT_SETTABLE,
    ERROR_INTERNET_SHUTDOWN,
    ERROR_INTERNET_INCORRECT_USER_NAME,
    ERROR_INTERNET_INCORRECT_PASSWORD,
    ERROR_INTERNET_LOGIN_FAILURE,
    ERROR_INTERNET_INVALID_OPERATION,
    ERROR_INTERNET_OPERATION_CANCELLED,
    ERROR_INTERNET_INCORRECT_HANDLE_TYPE,
    ERROR_INTERNET_INCORRECT_HANDLE_STATE,
    ERROR_INTERNET_NOT_PROXY_REQUEST,
    ERROR_INTERNET_REGISTRY_VALUE_NOT_FOUND,
    ERROR_INTERNET_BAD_REGISTRY_PARAMETER,
    ERROR_INTERNET_NO_DIRECT_ACCESS,
    ERROR_INTERNET_NO_CONTEXT,
    ERROR_INTERNET_NO_CALLBACK,
    ERROR_INTERNET_REQUEST_PENDING,
    ERROR_INTERNET_INCORRECT_FORMAT,
    ERROR_INTERNET_ITEM_NOT_FOUND,
    ERROR_INTERNET_CANNOT_CONNECT,
    ERROR_INTERNET_CONNECTION_ABORTED,
    ERROR_INTERNET_CONNECTION_RESET,
    ERROR_INTERNET_FORCE_RETRY,
    ERROR_INTERNET_INVALID_PROXY_REQUEST,
    ERROR_INTERNET_NEED_UI,                // = INTERNET_ERROR_BASE +  34
    ERROR_INTERNET_HANDLE_EXISTS              = INTERNET_ERROR_BASE +  36,
    ERROR_INTERNET_SEC_CERT_DATE_INVALID,
    ERROR_INTERNET_SEC_CERT_CN_INVALID,
    ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR,
    ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR,
    ERROR_INTERNET_MIXED_SECURITY,
    ERROR_INTERNET_CHG_POST_IS_NON_SECURE,
    ERROR_INTERNET_POST_IS_NON_SECURE,
    ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED,
    ERROR_INTERNET_INVALID_CA,
    ERROR_INTERNET_CLIENT_AUTH_NOT_SETUP,
    ERROR_INTERNET_ASYNC_THREAD_FAILED,
    ERROR_INTERNET_REDIRECT_SCHEME_CHANGE, // = INTERNET_ERROR_BASE +  48

    ERROR_FTP_TRANSFER_IN_PROGRESS            = INTERNET_ERROR_BASE + 110,
    ERROR_FTP_DROPPED,                     // = INTERNET_ERROR_BASE + 111
    ERROR_GOPHER_PROTOCOL_ERROR               = INTERNET_ERROR_BASE + 130,
    ERROR_GOPHER_NOT_FILE,
    ERROR_GOPHER_DATA_ERROR,
    ERROR_GOPHER_END_OF_DATA,
    ERROR_GOPHER_INVALID_LOCATOR,
    ERROR_GOPHER_INCORRECT_LOCATOR_TYPE,
    ERROR_GOPHER_NOT_GOPHER_PLUS,
    ERROR_GOPHER_ATTRIBUTE_NOT_FOUND,
    ERROR_GOPHER_UNKNOWN_LOCATOR,          // = INTERNET_ERROR_BASE + 138,
    ERROR_HTTP_HEADER_NOT_FOUND               = INTERNET_ERROR_BASE + 150,
    ERROR_HTTP_DOWNLEVEL_SERVER,
    ERROR_HTTP_INVALID_SERVER_RESPONSE,
    ERROR_HTTP_INVALID_HEADER,
    ERROR_HTTP_INVALID_QUERY_REQUEST,
    ERROR_HTTP_HEADER_ALREADY_EXISTS,
    ERROR_HTTP_REDIRECT_FAILED,
    ERROR_INTERNET_SECURITY_CHANNEL_ERROR,
    ERROR_INTERNET_UNABLE_TO_CACHE_FILE,
    ERROR_INTERNET_TCPIP_NOT_INSTALLED,
    ERROR_HTTP_NOT_REDIRECTED,             // = INTERNET_ERROR_BASE + 160
    // why?
    INTERNET_ERROR_LAST                  = ERROR_INTERNET_TCPIP_NOT_INSTALLED
}


enum NORMAL_CACHE_ENTRY     = 0x000001;
enum STABLE_CACHE_ENTRY     = 0x000002;
enum STICKY_CACHE_ENTRY     = 0x000004;
enum SPARSE_CACHE_ENTRY     = 0x010000;
enum OCX_CACHE_ENTRY        = 0x020000;
enum COOKIE_CACHE_ENTRY     = 0x100000;
enum URLHISTORY_CACHE_ENTRY = 0x200000;

enum CACHE_ENTRY_ATTRIBUTE_FC  = 0x0004;
enum CACHE_ENTRY_HITRATE_FC    = 0x0010;
enum CACHE_ENTRY_MODTIME_FC    = 0x0040;
enum CACHE_ENTRY_EXPTIME_FC    = 0x0080;
enum CACHE_ENTRY_ACCTIME_FC    = 0x0100;
enum CACHE_ENTRY_SYNCTIME_FC   = 0x0200;
enum CACHE_ENTRY_HEADERINFO_FC = 0x0400;

enum {
    WININET_API_FLAG_ASYNC       = 1,
    WININET_API_FLAG_SYNC        = 4,
    WININET_API_FLAG_USE_CONTEXT = 8
}

// FIXME: how should these really be grouped?
enum {
    IRF_ASYNC       = WININET_API_FLAG_ASYNC,
    IRF_SYNC        = WININET_API_FLAG_SYNC,
    IRF_USE_CONTEXT = WININET_API_FLAG_USE_CONTEXT,
}
enum IRF_NO_WAIT = 8;

enum {
    HSR_ASYNC = WININET_API_FLAG_ASYNC,
    HSR_SYNC = WININET_API_FLAG_SYNC,
    HSR_USE_CONTEXT = WININET_API_FLAG_USE_CONTEXT,
}

enum HSR_INITIATE =  8;
enum HSR_DOWNLOAD = 16;
enum HSR_CHUNKED  = 32;

enum INTERNET_DIAL_UNATTENDED              = 0x8000;
enum INTERNET_DIALSTATE_DISCONNECTED       = 1;
enum INTERENT_GOONLINE_REFRESH             = 1;
enum INTERENT_GOONLINE_MASK                = 1;
enum INTERNET_AUTODIAL_FORCE_ONLINE        = 1;
enum INTERNET_AUTODIAL_FORCE_UNATTENDED    = 2;
enum INTERNET_AUTODIAL_FAILIFSECURITYCHECK = 4;
enum INTERNET_CONNECTION_MODEM             = 0x01;
enum INTERNET_CONNECTION_LAN               = 0x02;
enum INTERNET_CONNECTION_PROXY             = 0x04;
enum INTERNET_CONNECTION_MODEM_BUSY        = 0x08;
enum INTERNET_RAS_INSTALLED                = 0x10;
enum INTERNET_CONNECTION_OFFLINE           = 0x20;
enum INTERNET_CONNECTION_CONFIGURED        = 0x40;

enum {
    CACHEGROUP_SEARCH_ALL   = 0,
    CACHEGROUP_SEARCH_BYURL = 1
}

enum {
    INTERNET_CACHE_GROUP_ADD    = 0,
    INTERNET_CACHE_GROUP_REMOVE = 1
}

alias HINTERNET = HANDLE;
// mixin DECLARE_HANDLE!("HINTERNET"); // doesn't work - bug
/*struct HINTERNET {
    HANDLE h;
    alias h this;
}*/
alias LPHINTERNET = HINTERNET*;

alias GROUPID = LONGLONG;
alias INTERNET_PORT = WORD;
alias LPINTERNET_PORT = WORD*;

enum INTERNET_SCHEME {
    INTERNET_SCHEME_PARTIAL = -2,
    INTERNET_SCHEME_UNKNOWN,
    INTERNET_SCHEME_DEFAULT,
    INTERNET_SCHEME_FTP,
    INTERNET_SCHEME_GOPHER,
    INTERNET_SCHEME_HTTP,
    INTERNET_SCHEME_HTTPS,
    INTERNET_SCHEME_FILE,
    INTERNET_SCHEME_NEWS,
    INTERNET_SCHEME_MAILTO,
    INTERNET_SCHEME_SOCKS,
    INTERNET_SCHEME_JAVASCRIPT,
    INTERNET_SCHEME_VBSCRIPT,
    INTERNET_SCHEME_RES,
    INTERNET_SCHEME_FIRST = INTERNET_SCHEME_FTP,
    INTERNET_SCHEME_LAST = INTERNET_SCHEME_RES
}
alias LPINTERNET_SCHEME = INTERNET_SCHEME*;

struct INTERNET_ASYNC_RESULT {
    DWORD_PTR dwResult;
    DWORD dwError;
}
alias LPINTERNET_ASYNC_RESULT = INTERNET_ASYNC_RESULT*;

struct INTERNET_DIAGNOSTIC_SOCKET_INFO {
    DWORD_PTR Socket;
    DWORD     SourcePort;
    DWORD     DestPort;
    DWORD     Flags;
}
alias LPINTERNET_DIAGNOSTIC_SOCKET_INFO = INTERNET_DIAGNOSTIC_SOCKET_INFO*;

struct INTERNET_PREFETCH_STATUS {
    DWORD dwStatus;
    DWORD dwSize;
}
alias LPINTERNET_PREFETCH_STATUS = INTERNET_PREFETCH_STATUS*;

struct INTERNET_PROXY_INFO {
    DWORD dwAccessType;
    LPCTSTR lpszProxy;
    LPCTSTR lpszProxyBypass;
}
alias LPINTERNET_PROXY_INFO = INTERNET_PROXY_INFO*;

struct INTERNET_PER_CONN_OPTIONA {
    DWORD   dwOption;
    union {
        DWORD    dwValue;
        LPSTR    pszValue;
        FILETIME ftValue;
    }
}
alias LPINTERNET_PER_CONN_OPTIONA = INTERNET_PER_CONN_OPTIONA*;

struct INTERNET_PER_CONN_OPTIONW {
    DWORD   dwOption;
    union {
        DWORD    dwValue;
        LPWSTR   pszValue;
        FILETIME ftValue;
    }
}
alias LPINTERNET_PER_CONN_OPTIONW = INTERNET_PER_CONN_OPTIONW*;

struct INTERNET_PER_CONN_OPTION_LISTA {
    DWORD   dwSize;
    LPSTR   pszConnection;
    DWORD   dwOptionCount;
    DWORD   dwOptionError;
    LPINTERNET_PER_CONN_OPTIONA  pOptions;
}
alias LPINTERNET_PER_CONN_OPTION_LISTA = INTERNET_PER_CONN_OPTION_LISTA*;

struct INTERNET_PER_CONN_OPTION_LISTW {
    DWORD   dwSize;
    LPWSTR  pszConnection;
    DWORD   dwOptionCount;
    DWORD   dwOptionError;
    LPINTERNET_PER_CONN_OPTIONW  pOptions;
}
alias LPINTERNET_PER_CONN_OPTION_LISTW = INTERNET_PER_CONN_OPTION_LISTW*;

enum {
    INTERNET_PER_CONN_FLAGS                        = 1,
    INTERNET_PER_CONN_PROXY_SERVER                 = 2,
    INTERNET_PER_CONN_PROXY_BYPASS                 = 3,
    INTERNET_PER_CONN_AUTOCONFIG_URL               = 4,
    INTERNET_PER_CONN_AUTODISCOVERY_FLAGS          = 5,
    INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL     = 6,
    INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS = 7,
    INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME  = 8,
    INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL   = 9,
    INTERNET_PER_CONN_FLAGS_UI                     = 10,
}

enum {
    PROXY_TYPE_DIRECT                              = 0x00000001,
    PROXY_TYPE_PROXY                               = 0x00000002,
    PROXY_TYPE_AUTO_PROXY_URL                      = 0x00000004,
    PROXY_TYPE_AUTO_DETECT                         = 0x00000008,
}

enum {
    AUTO_PROXY_FLAG_USER_SET                       = 0x00000001,
    AUTO_PROXY_FLAG_ALWAYS_DETECT                  = 0x00000002,
    AUTO_PROXY_FLAG_DETECTION_RUN                  = 0x00000004,
    AUTO_PROXY_FLAG_MIGRATED                       = 0x00000008,
    AUTO_PROXY_FLAG_DONT_CACHE_PROXY_RESULT        = 0x00000010,
    AUTO_PROXY_FLAG_CACHE_INIT_RUN                 = 0x00000020,
    AUTO_PROXY_FLAG_DETECTION_SUSPECT              = 0x00000040,
}

struct INTERNET_VERSION_INFO {
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
}
alias LPINTERNET_VERSION_INFO = INTERNET_VERSION_INFO*;

struct URL_COMPONENTSA {
    DWORD           dwStructSize = URL_COMPONENTSA.sizeof;
    LPSTR           lpszScheme;
    DWORD           dwSchemeLength;
    INTERNET_SCHEME nScheme;
    LPSTR           lpszHostName;
    DWORD           dwHostNameLength;
    INTERNET_PORT   nPort;
    LPSTR           lpszUserName;
    DWORD           dwUserNameLength;
    LPSTR           lpszPassword;
    DWORD           dwPasswordLength;
    LPSTR           lpszUrlPath;
    DWORD           dwUrlPathLength;
    LPSTR           lpszExtraInfo;
    DWORD           dwExtraInfoLength;
}
alias LPURL_COMPONENTSA = URL_COMPONENTSA*;

struct URL_COMPONENTSW {
    DWORD  dwStructSize = URL_COMPONENTSW.sizeof;
    LPWSTR lpszScheme;
    DWORD  dwSchemeLength;
    INTERNET_SCHEME nScheme;
    LPWSTR lpszHostName;
    DWORD  dwHostNameLength;
    INTERNET_PORT nPort;
    LPWSTR lpszUserName;
    DWORD  dwUserNameLength;
    LPWSTR lpszPassword;
    DWORD  dwPasswordLength;
    LPWSTR lpszUrlPath;
    DWORD  dwUrlPathLength;
    LPWSTR lpszExtraInfo;
    DWORD  dwExtraInfoLength;
}
alias LPURL_COMPONENTSW = URL_COMPONENTSW*;

struct INTERNET_CERTIFICATE_INFO {
    FILETIME ftExpiry;
    FILETIME ftStart;
    LPTSTR   lpszSubjectInfo;
    LPTSTR   lpszIssuerInfo;
    LPTSTR   lpszProtocolName;
    LPTSTR   lpszSignatureAlgName;
    LPTSTR   lpszEncryptionAlgName;
    DWORD    dwKeySize;
}
alias LPINTERNET_CERTIFICATE_INFO = INTERNET_CERTIFICATE_INFO*;

extern (Windows) alias INTERNET_STATUS_CALLBACK = void function(HINTERNET, DWORD_PTR, DWORD, PVOID, DWORD);
alias LPINTERNET_STATUS_CALLBACK = INTERNET_STATUS_CALLBACK*;

enum INTERNET_INVALID_STATUS_CALLBACK
  = cast(INTERNET_STATUS_CALLBACK) -1;

struct GOPHER_FIND_DATAA {
    CHAR[MAX_GOPHER_DISPLAY_TEXT+1] DisplayString = 0;
    DWORD    GopherType;
    DWORD    SizeLow;
    DWORD    SizeHigh;
    FILETIME LastModificationTime;
    CHAR[MAX_GOPHER_LOCATOR_LENGTH+1] Locator = 0;
}
alias LPGOPHER_FIND_DATAA = GOPHER_FIND_DATAA*;

struct GOPHER_FIND_DATAW {
    WCHAR[MAX_GOPHER_DISPLAY_TEXT+1] DisplayString = 0;
    DWORD    GopherType;
    DWORD    SizeLow;
    DWORD    SizeHigh;
    FILETIME LastModificationTime;
    WCHAR[MAX_GOPHER_LOCATOR_LENGTH+1] Locator = 0;
}
alias LPGOPHER_FIND_DATAW = GOPHER_FIND_DATAW*;

struct GOPHER_ADMIN_ATTRIBUTE_TYPE {
    LPCTSTR Comment;
    LPCTSTR EmailAddress;
}
alias LPGOPHER_ADMIN_ATTRIBUTE_TYPE = GOPHER_ADMIN_ATTRIBUTE_TYPE*;

struct GOPHER_MOD_DATE_ATTRIBUTE_TYPE {
    FILETIME DateAndTime;
}
alias LPGOPHER_MOD_DATE_ATTRIBUTE_TYPE = GOPHER_MOD_DATE_ATTRIBUTE_TYPE*;

struct GOPHER_TTL_ATTRIBUTE_TYPE {
    DWORD Ttl;
}
alias LPGOPHER_TTL_ATTRIBUTE_TYPE = GOPHER_TTL_ATTRIBUTE_TYPE*;

struct GOPHER_SCORE_ATTRIBUTE_TYPE {
    INT Score;
}
alias LPGOPHER_SCORE_ATTRIBUTE_TYPE = GOPHER_SCORE_ATTRIBUTE_TYPE*;

struct GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE {
    INT LowerBound;
    INT UpperBound;
}
alias LPGOPHER_SCORE_RANGE_ATTRIBUTE_TYPE = GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE*;

struct GOPHER_SITE_ATTRIBUTE_TYPE {
    LPCTSTR Site;
}
alias LPGOPHER_SITE_ATTRIBUTE_TYPE = GOPHER_SITE_ATTRIBUTE_TYPE*;

struct GOPHER_ORGANIZATION_ATTRIBUTE_TYPE {
    LPCTSTR Organization;
}
alias LPGOPHER_ORGANIZATION_ATTRIBUTE_TYPE = GOPHER_ORGANIZATION_ATTRIBUTE_TYPE*;

struct GOPHER_LOCATION_ATTRIBUTE_TYPE {
    LPCTSTR Location;
}
alias LPGOPHER_LOCATION_ATTRIBUTE_TYPE = GOPHER_LOCATION_ATTRIBUTE_TYPE*;

struct GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE {
    INT DegreesNorth;
    INT MinutesNorth;
    INT SecondsNorth;
    INT DegreesEast;
    INT MinutesEast;
    INT SecondsEast;
}
alias LPGOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE = GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE*;

struct GOPHER_TIMEZONE_ATTRIBUTE_TYPE {
    INT Zone;
}
alias LPGOPHER_TIMEZONE_ATTRIBUTE_TYPE = GOPHER_TIMEZONE_ATTRIBUTE_TYPE*;

struct GOPHER_PROVIDER_ATTRIBUTE_TYPE {
    LPCTSTR Provider;
}
alias LPGOPHER_PROVIDER_ATTRIBUTE_TYPE = GOPHER_PROVIDER_ATTRIBUTE_TYPE*;

struct GOPHER_VERSION_ATTRIBUTE_TYPE {
    LPCTSTR Version;
}
alias LPGOPHER_VERSION_ATTRIBUTE_TYPE = GOPHER_VERSION_ATTRIBUTE_TYPE*;

struct GOPHER_ABSTRACT_ATTRIBUTE_TYPE {
    LPCTSTR ShortAbstract;
    LPCTSTR AbstractFile;
}
alias LPGOPHER_ABSTRACT_ATTRIBUTE_TYPE = GOPHER_ABSTRACT_ATTRIBUTE_TYPE*;

struct GOPHER_VIEW_ATTRIBUTE_TYPE {
    LPCTSTR ContentType;
    LPCTSTR Language;
    DWORD   Size;
}
alias LPGOPHER_VIEW_ATTRIBUTE_TYPE = GOPHER_VIEW_ATTRIBUTE_TYPE*;

struct GOPHER_VERONICA_ATTRIBUTE_TYPE {
    BOOL TreeWalk;
}
alias LPGOPHER_VERONICA_ATTRIBUTE_TYPE = GOPHER_VERONICA_ATTRIBUTE_TYPE*;

struct GOPHER_ASK_ATTRIBUTE_TYPE {
    LPCTSTR QuestionType;
    LPCTSTR QuestionText;
}
alias LPGOPHER_ASK_ATTRIBUTE_TYPE = GOPHER_ASK_ATTRIBUTE_TYPE*;

struct GOPHER_UNKNOWN_ATTRIBUTE_TYPE {
    LPCTSTR Text;
}
alias LPGOPHER_UNKNOWN_ATTRIBUTE_TYPE = GOPHER_UNKNOWN_ATTRIBUTE_TYPE*;

struct GOPHER_ATTRIBUTE_TYPE {
    DWORD CategoryId;
    DWORD AttributeId;
    union {
        GOPHER_ADMIN_ATTRIBUTE_TYPE                 Admin;
        GOPHER_MOD_DATE_ATTRIBUTE_TYPE              ModDate;
        GOPHER_TTL_ATTRIBUTE_TYPE                   Ttl;
        GOPHER_SCORE_ATTRIBUTE_TYPE                 Score;
        GOPHER_SCORE_RANGE_ATTRIBUTE_TYPE           ScoreRange;
        GOPHER_SITE_ATTRIBUTE_TYPE                  Site;
        GOPHER_ORGANIZATION_ATTRIBUTE_TYPE          Organization;
        GOPHER_LOCATION_ATTRIBUTE_TYPE              Location;
        GOPHER_GEOGRAPHICAL_LOCATION_ATTRIBUTE_TYPE GeographicalLocation;
        GOPHER_TIMEZONE_ATTRIBUTE_TYPE              TimeZone;
        GOPHER_PROVIDER_ATTRIBUTE_TYPE              Provider;
        GOPHER_VERSION_ATTRIBUTE_TYPE               Version;
        GOPHER_ABSTRACT_ATTRIBUTE_TYPE              Abstract;
        GOPHER_VIEW_ATTRIBUTE_TYPE                  View;
        GOPHER_VERONICA_ATTRIBUTE_TYPE              Veronica;
        GOPHER_ASK_ATTRIBUTE_TYPE                   Ask;
        GOPHER_UNKNOWN_ATTRIBUTE_TYPE               Unknown;
    } /+AttributeType;+/
}
alias LPGOPHER_ATTRIBUTE_TYPE = GOPHER_ATTRIBUTE_TYPE*;

extern (Windows)
alias GOPHER_ATTRIBUTE_ENUMERATOR = BOOL function(LPGOPHER_ATTRIBUTE_TYPE, DWORD);

struct INTERNET_CACHE_ENTRY_INFOA {
    DWORD    dwStructSize = INTERNET_CACHE_ENTRY_INFOA.sizeof;
    LPSTR    lpszSourceUrlName;
    LPSTR    lpszLocalFileName;
    DWORD    CacheEntryType;
    DWORD    dwUseCount;
    DWORD    dwHitRate;
    DWORD    dwSizeLow;
    DWORD    dwSizeHigh;
    FILETIME LastModifiedTime;
    FILETIME ExpireTime;
    FILETIME LastAccessTime;
    FILETIME LastSyncTime;
    PBYTE    lpHeaderInfo;
    DWORD    dwHeaderInfoSize;
    LPSTR    lpszFileExtension;
    DWORD    dwReserved;
}
alias LPINTERNET_CACHE_ENTRY_INFOA = INTERNET_CACHE_ENTRY_INFOA*;

struct INTERNET_CACHE_ENTRY_INFOW {
    DWORD    dwStructSize = INTERNET_CACHE_ENTRY_INFOW.sizeof;
    LPWSTR   lpszSourceUrlName;
    LPWSTR   lpszLocalFileName;
    DWORD    CacheEntryType;
    DWORD    dwUseCount;
    DWORD    dwHitRate;
    DWORD    dwSizeLow;
    DWORD    dwSizeHigh;
    FILETIME LastModifiedTime;
    FILETIME ExpireTime;
    FILETIME LastAccessTime;
    FILETIME LastSyncTime;
    PBYTE    lpHeaderInfo;
    DWORD    dwHeaderInfoSize;
    LPWSTR   lpszFileExtension;
    DWORD    dwReserved;
}
alias LPINTERNET_CACHE_ENTRY_INFOW = INTERNET_CACHE_ENTRY_INFOW*;

struct INTERNET_BUFFERSA {
    DWORD              dwStructSize = INTERNET_BUFFERSA.sizeof;
    INTERNET_BUFFERSA* Next;
    LPCSTR             lpcszHeader;
    DWORD              dwHeadersLength;
    DWORD              dwHeadersTotal;
    LPVOID             lpvBuffer;
    DWORD              dwBufferLength;
    DWORD              dwBufferTotal;
    DWORD              dwOffsetLow;
    DWORD              dwOffsetHigh;
}
alias LPINTERNET_BUFFERSA = INTERNET_BUFFERSA*;

struct INTERNET_BUFFERSW {
    DWORD              dwStructSize = INTERNET_BUFFERSW.sizeof;
    INTERNET_BUFFERSW* Next;
    LPCWSTR            lpcszHeader;
    DWORD              dwHeadersLength;
    DWORD              dwHeadersTotal;
    LPVOID             lpvBuffer;
    DWORD              dwBufferLength;
    DWORD              dwBufferTotal;
    DWORD              dwOffsetLow;
    DWORD              dwOffsetHigh;
}
alias LPINTERNET_BUFFERSW = INTERNET_BUFFERSW*;

enum size_t
    GROUP_OWNER_STORAGE_SIZE =   4,
    GROUPNAME_MAX_LENGTH     = 120;

struct INTERNET_CACHE_GROUP_INFOA {
    DWORD dwGroupSize;
    DWORD dwGroupFlags;
    DWORD dwGroupType;
    DWORD dwDiskUsage;
    DWORD dwDiskQuota;
    DWORD[GROUP_OWNER_STORAGE_SIZE] dwOwnerStorage;
    CHAR[GROUPNAME_MAX_LENGTH]      szGroupName = 0;
}
alias LPINTERNET_CACHE_GROUP_INFOA = INTERNET_CACHE_GROUP_INFOA*;

struct INTERNET_CACHE_GROUP_INFOW {
    DWORD dwGroupSize;
    DWORD dwGroupFlags;
    DWORD dwGroupType;
    DWORD dwDiskUsage;
    DWORD dwDiskQuota;
    DWORD[GROUP_OWNER_STORAGE_SIZE] dwOwnerStorage;
    WCHAR[GROUPNAME_MAX_LENGTH]     szGroupName = 0;
}
alias LPINTERNET_CACHE_GROUP_INFOW = INTERNET_CACHE_GROUP_INFOW*;

extern (Windows) {
    BOOL InternetTimeFromSystemTime(SYSTEMTIME*, DWORD, LPSTR, DWORD);
    BOOL InternetTimeToSystemTime(LPCSTR, SYSTEMTIME*, DWORD);
    BOOL InternetDebugGetLocalTime(SYSTEMTIME*, PDWORD);
    BOOL InternetCrackUrlA(LPCSTR, DWORD, DWORD, LPURL_COMPONENTSA);
    BOOL InternetCrackUrlW(LPCWSTR, DWORD, DWORD, LPURL_COMPONENTSW);
    BOOL InternetCreateUrlA(LPURL_COMPONENTSA, DWORD, LPSTR, PDWORD);
    BOOL InternetCreateUrlW(LPURL_COMPONENTSW, DWORD, LPWSTR, PDWORD);
    BOOL InternetCanonicalizeUrlA(LPCSTR, LPSTR, PDWORD, DWORD);
    BOOL InternetCanonicalizeUrlW(LPCWSTR, LPWSTR, PDWORD, DWORD);
    BOOL InternetCheckConnectionA(LPCSTR, DWORD, DWORD);
    BOOL InternetCheckConnectionW(LPCWSTR, DWORD, DWORD);
    BOOL InternetCombineUrlA(LPCSTR, LPCSTR, LPSTR, PDWORD, DWORD);
    BOOL InternetCombineUrlW(LPCWSTR, LPCWSTR, LPWSTR, PDWORD, DWORD);
    HINTERNET InternetOpenA(LPCSTR, DWORD, LPCSTR, LPCSTR, DWORD);
    HINTERNET InternetOpenW(LPCWSTR, DWORD, LPCWSTR, LPCWSTR, DWORD);
    BOOL InternetCloseHandle(HINTERNET);
    HINTERNET InternetConnectA(HINTERNET, LPCSTR, INTERNET_PORT, LPCSTR,
      LPCSTR, DWORD, DWORD, DWORD_PTR);
    HINTERNET InternetConnectW(HINTERNET, LPCWSTR, INTERNET_PORT, LPCWSTR,
      LPCWSTR, DWORD, DWORD, DWORD_PTR);
    HINTERNET InternetOpenUrlA(HINTERNET, LPCSTR, LPCSTR, DWORD, DWORD,
      DWORD_PTR);
    HINTERNET InternetOpenUrlW(HINTERNET, LPCWSTR, LPCWSTR, DWORD, DWORD,
      DWORD_PTR);
    BOOL InternetReadFile(HINTERNET, PVOID, DWORD, PDWORD);
    DWORD InternetSetFilePointer(HINTERNET, LONG, PVOID, DWORD, DWORD_PTR);
    BOOL InternetWriteFile(HINTERNET, LPCVOID, DWORD, PDWORD);
    BOOL InternetQueryDataAvailable(HINTERNET, PDWORD, DWORD, DWORD_PTR);
    BOOL InternetFindNextFileA(HINTERNET, PVOID);
    BOOL InternetFindNextFileW(HINTERNET, PVOID);
    BOOL InternetQueryOptionA(HINTERNET, DWORD, PVOID, PDWORD);
    BOOL InternetQueryOptionW(HINTERNET, DWORD, PVOID, PDWORD);
    BOOL InternetSetOptionA(HINTERNET, DWORD, PVOID, DWORD);
    BOOL InternetSetOptionW(HINTERNET, DWORD, PVOID, DWORD);
    BOOL InternetSetOptionExA(HINTERNET, DWORD, PVOID, DWORD, DWORD);
    BOOL InternetSetOptionExW(HINTERNET, DWORD, PVOID, DWORD, DWORD);
    BOOL InternetGetLastResponseInfoA(PDWORD, LPSTR, PDWORD);
    BOOL InternetGetLastResponseInfoW(PDWORD, LPWSTR, PDWORD);
    INTERNET_STATUS_CALLBACK InternetSetStatusCallback(HINTERNET,
      INTERNET_STATUS_CALLBACK);
    DWORD FtpGetFileSize(HINTERNET, LPDWORD);
    HINTERNET FtpFindFirstFileA(HINTERNET, LPCSTR, LPWIN32_FIND_DATAA, DWORD,
      DWORD_PTR);
    HINTERNET FtpFindFirstFileW(HINTERNET, LPCWSTR, LPWIN32_FIND_DATAW, DWORD,
      DWORD_PTR);
    BOOL FtpGetFileA(HINTERNET, LPCSTR, LPCSTR, BOOL, DWORD, DWORD, DWORD_PTR);
    BOOL FtpGetFileW(HINTERNET, LPCWSTR, LPCWSTR, BOOL, DWORD, DWORD, DWORD_PTR);
    BOOL FtpPutFileA(HINTERNET, LPCSTR, LPCSTR, DWORD, DWORD_PTR);
    BOOL FtpPutFileW(HINTERNET, LPCWSTR, LPCWSTR, DWORD, DWORD_PTR);
    BOOL FtpDeleteFileA(HINTERNET, LPCSTR);
    BOOL FtpDeleteFileW(HINTERNET, LPCWSTR);
    BOOL FtpRenameFileA(HINTERNET, LPCSTR, LPCSTR);
    BOOL FtpRenameFileW(HINTERNET, LPCWSTR, LPCWSTR);
    HINTERNET FtpOpenFileA(HINTERNET, LPCSTR, DWORD, DWORD, DWORD_PTR);
    HINTERNET FtpOpenFileW(HINTERNET, LPCWSTR, DWORD, DWORD, DWORD_PTR);
    BOOL FtpCreateDirectoryA(HINTERNET, LPCSTR);
    BOOL FtpCreateDirectoryW(HINTERNET, LPCWSTR);
    BOOL FtpRemoveDirectoryA(HINTERNET, LPCSTR);
    BOOL FtpRemoveDirectoryW(HINTERNET, LPCWSTR);
    BOOL FtpSetCurrentDirectoryA(HINTERNET, LPCSTR);
    BOOL FtpSetCurrentDirectoryW(HINTERNET, LPCWSTR);
    BOOL FtpGetCurrentDirectoryA(HINTERNET, LPSTR, PDWORD);
    BOOL FtpGetCurrentDirectoryW(HINTERNET, LPWSTR, PDWORD);
    BOOL FtpCommandA(HINTERNET, BOOL, DWORD, LPCSTR, DWORD_PTR, HINTERNET*);
    BOOL FtpCommandW(HINTERNET, BOOL, DWORD, LPCWSTR, DWORD_PTR, HINTERNET*);
    BOOL GopherCreateLocatorA(LPCSTR, INTERNET_PORT, LPCSTR, LPCSTR, DWORD,
      LPSTR, PDWORD);
    BOOL GopherCreateLocatorW(LPCWSTR, INTERNET_PORT, LPCWSTR, LPCWSTR, DWORD,
      LPWSTR, PDWORD);
    BOOL GopherGetLocatorTypeA(LPCSTR, PDWORD);
    BOOL GopherGetLocatorTypeW(LPCWSTR, PDWORD);
    HINTERNET GopherFindFirstFileA(HINTERNET, LPCSTR, LPCSTR,
      LPGOPHER_FIND_DATAA, DWORD, DWORD_PTR);
    HINTERNET GopherFindFirstFileW(HINTERNET, LPCWSTR, LPCWSTR,
      LPGOPHER_FIND_DATAW, DWORD, DWORD_PTR);
    HINTERNET GopherOpenFileA(HINTERNET, LPCSTR, LPCSTR, DWORD, DWORD_PTR);
    HINTERNET GopherOpenFileW(HINTERNET, LPCWSTR, LPCWSTR, DWORD, DWORD_PTR);
    BOOL GopherGetAttributeA(HINTERNET, LPCSTR, LPCSTR, LPBYTE, DWORD,
      PDWORD, GOPHER_ATTRIBUTE_ENUMERATOR, DWORD_PTR);
    BOOL GopherGetAttributeW(HINTERNET, LPCWSTR, LPCWSTR, LPBYTE, DWORD,
      PDWORD, GOPHER_ATTRIBUTE_ENUMERATOR, DWORD_PTR);
    HINTERNET HttpOpenRequestA(HINTERNET, LPCSTR, LPCSTR, LPCSTR, LPCSTR,
      LPCSTR*, DWORD, DWORD_PTR);
    HINTERNET HttpOpenRequestW(HINTERNET, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR,
      LPCWSTR*, DWORD, DWORD_PTR);
    BOOL HttpAddRequestHeadersA(HINTERNET, LPCSTR, DWORD, DWORD);
    BOOL HttpAddRequestHeadersW(HINTERNET, LPCWSTR, DWORD, DWORD);
    BOOL HttpSendRequestA(HINTERNET, LPCSTR, DWORD, PVOID, DWORD);
    BOOL HttpSendRequestW(HINTERNET, LPCWSTR, DWORD, PVOID, DWORD);
    BOOL HttpQueryInfoA(HINTERNET, DWORD, PVOID, PDWORD, PDWORD);
    BOOL HttpQueryInfoW(HINTERNET, DWORD, PVOID, PDWORD, PDWORD);
    BOOL InternetSetCookieA(LPCSTR, LPCSTR, LPCSTR);
    BOOL InternetSetCookieW(LPCWSTR, LPCWSTR, LPCWSTR);
    BOOL InternetGetCookieA(LPCSTR, LPCSTR, LPSTR, PDWORD);
    BOOL InternetGetCookieW(LPCWSTR, LPCWSTR, LPWSTR, PDWORD);
    DWORD InternetAttemptConnect(DWORD);
    DWORD InternetErrorDlg(HWND, HINTERNET, DWORD, DWORD, PVOID*);
    DWORD InternetConfirmZoneCrossing(HWND, LPSTR, LPSTR, BOOL);
    BOOL CreateUrlCacheEntryA(LPCSTR, DWORD, LPCSTR, LPSTR, DWORD);
    BOOL CreateUrlCacheEntryW(LPCWSTR, DWORD, LPCWSTR, LPWSTR, DWORD);
    BOOL CommitUrlCacheEntryA(LPCSTR, LPCSTR, FILETIME, FILETIME, DWORD,
      LPBYTE, DWORD, LPCSTR, DWORD);
    BOOL CommitUrlCacheEntryW(LPCWSTR, LPCWSTR, FILETIME, FILETIME, DWORD,
      LPBYTE, DWORD, LPCWSTR, DWORD);
    BOOL RetrieveUrlCacheEntryFileA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA,
      PDWORD, DWORD);
    BOOL RetrieveUrlCacheEntryFileW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW,
      PDWORD, DWORD);
    BOOL UnlockUrlCacheEntryFile(LPCSTR, DWORD);
    HANDLE RetrieveUrlCacheEntryStreamA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA,
      PDWORD, BOOL, DWORD);
    HANDLE RetrieveUrlCacheEntryStreamW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW,
      PDWORD, BOOL, DWORD);
    BOOL ReadUrlCacheEntryStream(HANDLE, DWORD, PVOID, PDWORD, DWORD);
    BOOL UnlockUrlCacheEntryStream(HANDLE, DWORD);
    BOOL GetUrlCacheEntryInfoA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA, PDWORD);
    BOOL GetUrlCacheEntryInfoW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW, PDWORD);
    BOOL SetUrlCacheEntryInfoA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA, DWORD);
    BOOL SetUrlCacheEntryInfoW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW, DWORD);
    HANDLE FindFirstUrlCacheEntryA(LPCSTR, LPINTERNET_CACHE_ENTRY_INFOA,
      PDWORD);
    HANDLE FindFirstUrlCacheEntryW(LPCWSTR, LPINTERNET_CACHE_ENTRY_INFOW,
      PDWORD);
    BOOL FindNextUrlCacheEntryA(HANDLE, LPINTERNET_CACHE_ENTRY_INFOA, PDWORD);
    BOOL FindNextUrlCacheEntryW(HANDLE, LPINTERNET_CACHE_ENTRY_INFOW, PDWORD);
    BOOL FindCloseUrlCache(HANDLE);
    BOOL DeleteUrlCacheEntry(LPCSTR);
    DWORD AuthenticateUser(PVOID*, LPSTR, LPSTR, DWORD, LPSTR, DWORD, LPSTR,
      LPSTR);
    BOOL HttpSendRequestExA(HINTERNET, LPINTERNET_BUFFERSA,
      LPINTERNET_BUFFERSA, DWORD, DWORD_PTR);
    BOOL HttpSendRequestExW(HINTERNET, LPINTERNET_BUFFERSW,
      LPINTERNET_BUFFERSW, DWORD, DWORD_PTR);
    BOOL HttpEndRequestA(HINTERNET, LPINTERNET_BUFFERSA, DWORD, DWORD_PTR);
    BOOL HttpEndRequestW(HINTERNET, LPINTERNET_BUFFERSW, DWORD, DWORD_PTR);
    DWORD InternetDial(HWND, LPTSTR, DWORD, LPDWORD, DWORD);
    DWORD InternetHangUp(DWORD_PTR, DWORD);
    BOOL InternetGoOnline(LPTSTR, HWND, DWORD);
    BOOL InternetAutodial(DWORD, DWORD);
    BOOL InternetAutodialHangup(DWORD);
    BOOL InternetGetConnectedState(LPDWORD, DWORD);
    BOOL InternetSetDialState(LPCTSTR, DWORD, DWORD);
    BOOL InternetReadFileExA(HINTERNET, LPINTERNET_BUFFERSA, DWORD, DWORD_PTR);
    BOOL InternetReadFileExW(HINTERNET, LPINTERNET_BUFFERSW, DWORD, DWORD_PTR);
    GROUPID CreateUrlCacheGroup(DWORD, LPVOID);
    BOOL DeleteUrlCacheGroup(GROUPID, DWORD, LPVOID);
    HANDLE FindFirstUrlCacheGroup(DWORD, DWORD, LPVOID, DWORD, GROUPID*,
      LPVOID);
    BOOL FindNextUrlCacheGroup(HANDLE, GROUPID*, LPVOID);
    BOOL GetUrlCacheGroupAttributeA(GROUPID, DWORD, DWORD,
      LPINTERNET_CACHE_GROUP_INFOA, LPDWORD, LPVOID);
    BOOL GetUrlCacheGroupAttributeW(GROUPID, DWORD, DWORD,
      LPINTERNET_CACHE_GROUP_INFOW, LPDWORD, LPVOID);
    BOOL SetUrlCacheGroupAttributeA(GROUPID, DWORD, DWORD,
      LPINTERNET_CACHE_GROUP_INFOA, LPVOID);
    BOOL SetUrlCacheGroupAttributeW(GROUPID, DWORD, DWORD,
      LPINTERNET_CACHE_GROUP_INFOW, LPVOID);
}

version (Unicode) {
    alias INTERNET_PER_CONN_OPTION = INTERNET_PER_CONN_OPTIONW;
    alias LPINTERNET_PER_CONN_OPTION = LPINTERNET_PER_CONN_OPTIONW;
    alias INTERNET_PER_CONN_OPTION_LIST = INTERNET_PER_CONN_OPTION_LISTW;
    alias LPINTERNET_PER_CONN_OPTION_LIST = LPINTERNET_PER_CONN_OPTION_LISTW;
    alias URL_COMPONENTS = URL_COMPONENTSW;
    alias LPURL_COMPONENTS = LPURL_COMPONENTSW;
    alias GOPHER_FIND_DATA = GOPHER_FIND_DATAW;
    alias LPGOPHER_FIND_DATA = LPGOPHER_FIND_DATAW;
    alias INTERNET_CACHE_ENTRY_INFO = INTERNET_CACHE_ENTRY_INFOW;
    alias LPINTERNET_CACHE_ENTRY_INFO = LPINTERNET_CACHE_ENTRY_INFOW;
    alias INTERNET_BUFFERS = INTERNET_BUFFERSW;
    alias INTERNET_CACHE_GROUP_INFO = INTERNET_CACHE_GROUP_INFOW;
    alias LPINTERNET_CACHE_GROUP_INFO = LPINTERNET_CACHE_GROUP_INFOW;
    alias InternetCrackUrl = InternetCrackUrlW;
    alias InternetCreateUrl = InternetCreateUrlW;
    alias InternetCanonicalizeUrl = InternetCanonicalizeUrlW;
    alias InternetCheckConnection = InternetCheckConnectionW;
    alias InternetCombineUrl = InternetCombineUrlW;
    alias InternetOpen = InternetOpenW;
    alias InternetConnect = InternetConnectW;
    alias InternetOpenUrl = InternetOpenUrlW;
    alias InternetFindNextFile = InternetFindNextFileW;
    alias InternetQueryOption = InternetQueryOptionW;
    alias InternetSetOption = InternetSetOptionW;
    alias InternetSetOptionEx = InternetSetOptionExW;
    alias InternetGetLastResponseInfo = InternetGetLastResponseInfoW;
    alias InternetReadFileEx = InternetReadFileExW;
    alias FtpFindFirstFile = FtpFindFirstFileW;
    alias FtpGetFile = FtpGetFileW;
    alias FtpPutFile = FtpPutFileW;
    alias FtpDeleteFile = FtpDeleteFileW;
    alias FtpRenameFile = FtpRenameFileW;
    alias FtpOpenFile = FtpOpenFileW;
    alias FtpCreateDirectory = FtpCreateDirectoryW;
    alias FtpRemoveDirectory = FtpRemoveDirectoryW;
    alias FtpSetCurrentDirectory = FtpSetCurrentDirectoryW;
    alias FtpGetCurrentDirectory = FtpGetCurrentDirectoryW;
    alias FtpCommand = FtpCommandW;
    alias GopherGetLocatorType = GopherGetLocatorTypeW;
    alias GopherCreateLocator = GopherCreateLocatorW;
    alias GopherFindFirstFile = GopherFindFirstFileW;
    alias GopherOpenFile = GopherOpenFileW;
    alias GopherGetAttribute = GopherGetAttributeW;
    alias HttpSendRequest = HttpSendRequestW;
    alias HttpOpenRequest = HttpOpenRequestW;
    alias HttpAddRequestHeaders = HttpAddRequestHeadersW;
    alias HttpQueryInfo = HttpQueryInfoW;
    alias InternetSetCookie = InternetSetCookieW;
    alias InternetGetCookie = InternetGetCookieW;
    alias CreateUrlCacheEntry = CreateUrlCacheEntryW;
    alias RetrieveUrlCacheEntryStream = RetrieveUrlCacheEntryStreamW;
    alias FindNextUrlCacheEntry = FindNextUrlCacheEntryW;
    alias CommitUrlCacheEntry = CommitUrlCacheEntryW;
    alias GetUrlCacheEntryInfo = GetUrlCacheEntryInfoW;
    alias SetUrlCacheEntryInfo = SetUrlCacheEntryInfoW;
    alias FindFirstUrlCacheEntry = FindFirstUrlCacheEntryW;
    alias RetrieveUrlCacheEntryFile = RetrieveUrlCacheEntryFileW;
    alias HttpSendRequestEx = HttpSendRequestExW;
    alias HttpEndRequest = HttpEndRequestW;
    alias GetUrlCacheGroupAttribute = GetUrlCacheGroupAttributeW;
    alias SetUrlCacheGroupAttribute = SetUrlCacheGroupAttributeW;
} else {
    alias INTERNET_PER_CONN_OPTION = INTERNET_PER_CONN_OPTIONA;
    alias LPINTERNET_PER_CONN_OPTION = LPINTERNET_PER_CONN_OPTIONA;
    alias INTERNET_PER_CONN_OPTION_LIST = INTERNET_PER_CONN_OPTION_LISTA;
    alias LPINTERNET_PER_CONN_OPTION_LIST = LPINTERNET_PER_CONN_OPTION_LISTA;
    alias URL_COMPONENTS = URL_COMPONENTSA;
    alias LPURL_COMPONENTS = LPURL_COMPONENTSA;
    alias GOPHER_FIND_DATA = GOPHER_FIND_DATAA;
    alias LPGOPHER_FIND_DATA = LPGOPHER_FIND_DATAA;
    alias INTERNET_CACHE_ENTRY_INFO = INTERNET_CACHE_ENTRY_INFOA;
    alias LPINTERNET_CACHE_ENTRY_INFO = LPINTERNET_CACHE_ENTRY_INFOA;
    alias INTERNET_BUFFERS = INTERNET_BUFFERSA;
    alias INTERNET_CACHE_GROUP_INFO = INTERNET_CACHE_GROUP_INFOA;
    alias LPINTERNET_CACHE_GROUP_INFO = LPINTERNET_CACHE_GROUP_INFOA;
    alias GopherGetAttribute = GopherGetAttributeA;
    alias InternetCrackUrl = InternetCrackUrlA;
    alias InternetCreateUrl = InternetCreateUrlA;
    alias InternetCanonicalizeUrl = InternetCanonicalizeUrlA;
    alias InternetCheckConnection = InternetCheckConnectionA;
    alias InternetCombineUrl = InternetCombineUrlA;
    alias InternetOpen = InternetOpenA;
    alias InternetConnect = InternetConnectA;
    alias InternetOpenUrl = InternetOpenUrlA;
    alias InternetFindNextFile = InternetFindNextFileA;
    alias InternetQueryOption = InternetQueryOptionA;
    alias InternetSetOption = InternetSetOptionA;
    alias InternetSetOptionEx = InternetSetOptionExA;
    alias InternetGetLastResponseInfo = InternetGetLastResponseInfoA;
    alias InternetReadFileEx = InternetReadFileExA;
    alias FtpFindFirstFile = FtpFindFirstFileA;
    alias FtpGetFile = FtpGetFileA;
    alias FtpPutFile = FtpPutFileA;
    alias FtpDeleteFile = FtpDeleteFileA;
    alias FtpRenameFile = FtpRenameFileA;
    alias FtpOpenFile = FtpOpenFileA;
    alias FtpCreateDirectory = FtpCreateDirectoryA;
    alias FtpRemoveDirectory = FtpRemoveDirectoryA;
    alias FtpSetCurrentDirectory = FtpSetCurrentDirectoryA;
    alias FtpGetCurrentDirectory = FtpGetCurrentDirectoryA;
    alias FtpCommand = FtpCommandA;
    alias GopherGetLocatorType = GopherGetLocatorTypeA;
    alias GopherCreateLocator = GopherCreateLocatorA;
    alias GopherFindFirstFile = GopherFindFirstFileA;
    alias GopherOpenFile = GopherOpenFileA;
    alias HttpSendRequest = HttpSendRequestA;
    alias HttpOpenRequest = HttpOpenRequestA;
    alias HttpAddRequestHeaders = HttpAddRequestHeadersA;
    alias HttpQueryInfo = HttpQueryInfoA;
    alias InternetSetCookie = InternetSetCookieA;
    alias InternetGetCookie = InternetGetCookieA;
    alias CreateUrlCacheEntry = CreateUrlCacheEntryA;
    alias RetrieveUrlCacheEntryStream = RetrieveUrlCacheEntryStreamA;
    alias FindNextUrlCacheEntry = FindNextUrlCacheEntryA;
    alias CommitUrlCacheEntry = CommitUrlCacheEntryA;
    alias GetUrlCacheEntryInfo = GetUrlCacheEntryInfoA;
    alias SetUrlCacheEntryInfo = SetUrlCacheEntryInfoA;
    alias FindFirstUrlCacheEntry = FindFirstUrlCacheEntryA;
    alias RetrieveUrlCacheEntryFile = RetrieveUrlCacheEntryFileA;
    alias HttpSendRequestEx = HttpSendRequestExA;
    alias HttpEndRequest = HttpEndRequestA;
    alias GetUrlCacheGroupAttribute = GetUrlCacheGroupAttributeA;
    alias SetUrlCacheGroupAttribute = SetUrlCacheGroupAttributeA;
}

alias LPINTERNET_BUFFERS = INTERNET_BUFFERS*;
