[WININET]
authorAmine Khaldi <amine.khaldi@reactos.org>
Thu, 25 Sep 2014 15:31:21 +0000 (15:31 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Thu, 25 Sep 2014 15:31:21 +0000 (15:31 +0000)
* Sync with Wine 1.7.27.
CORE-8540

svn path=/trunk/; revision=64276

reactos/dll/win32/wininet/CMakeLists.txt
reactos/dll/win32/wininet/cookie.c
reactos/dll/win32/wininet/ftp.c
reactos/dll/win32/wininet/http.c
reactos/dll/win32/wininet/internet.c
reactos/dll/win32/wininet/internet.h
reactos/dll/win32/wininet/netconnection.c
reactos/dll/win32/wininet/urlcache.c
reactos/dll/win32/wininet/wininet_main.c [deleted file]
reactos/media/doc/README.WINE

index dfdc55f..18d831b 100644 (file)
@@ -19,7 +19,6 @@ list(APPEND SOURCE
     netconnection.c
     urlcache.c
     utility.c
-    wininet_main.c
     internet.h)
 
 add_library(wininet SHARED
index 7595495..ddbc92a 100644 (file)
  *     Cookies could use A LOT OF MEMORY. We need some kind of memory management here!
  */
 
-typedef struct _cookie_domain cookie_domain;
-typedef struct _cookie cookie;
+struct _cookie_domain_t;
+struct _cookie_container_t;
 
-struct _cookie
-{
+typedef struct _cookie_t {
     struct list entry;
 
-    struct _cookie_domain *parent;
+    struct _cookie_container_t *container;
 
-    LPWSTR lpCookieName;
-    LPWSTR lpCookieData;
+    WCHAR *name;
+    WCHAR *data;
     DWORD flags;
     FILETIME expiry;
     FILETIME create;
-};
+} cookie_t;
 
-struct _cookie_domain
-{
+typedef struct _cookie_container_t {
     struct list entry;
 
-    LPWSTR lpCookieDomain;
-    LPWSTR lpCookiePath;
+    WCHAR *path;
+    struct _cookie_domain_t *domain;
+
     struct list cookie_list;
-};
+} cookie_container_t;
+
+typedef struct _cookie_domain_t {
+    struct list entry;
+
+    WCHAR *domain;
+    unsigned subdomain_len;
+
+    struct _cookie_domain_t *parent;
+    struct list subdomain_list;
+
+    /* List of stored paths sorted by length of the path. */
+    struct list path_list;
+} cookie_domain_t;
 
 static CRITICAL_SECTION cookie_cs;
 static CRITICAL_SECTION_DEBUG cookie_cs_debug =
@@ -63,14 +75,172 @@ static CRITICAL_SECTION_DEBUG cookie_cs_debug =
 static CRITICAL_SECTION cookie_cs = { &cookie_cs_debug, -1, 0, 0, 0, 0 };
 static struct list domain_list = LIST_INIT(domain_list);
 
-static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data,
-        FILETIME expiry, FILETIME create, DWORD flags);
-static cookie *COOKIE_findCookie(cookie_domain *domain, LPCWSTR lpszCookieName);
-static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain);
-static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path);
-static void COOKIE_deleteDomain(cookie_domain *deadDomain);
-static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath,
-        cookie_domain *searchDomain, BOOL allow_partial);
+static cookie_domain_t *get_cookie_domain(const WCHAR *domain, BOOL create)
+{
+    const WCHAR *ptr = domain + strlenW(domain), *ptr_end, *subdomain_ptr;
+    cookie_domain_t *iter, *current_domain, *prev_domain = NULL;
+    struct list *current_list = &domain_list;
+
+    while(1) {
+        for(ptr_end = ptr--; ptr > domain && *ptr != '.'; ptr--);
+        subdomain_ptr = *ptr == '.' ? ptr+1 : ptr;
+
+        current_domain = NULL;
+        LIST_FOR_EACH_ENTRY(iter, current_list, cookie_domain_t, entry) {
+            if(ptr_end-subdomain_ptr == iter->subdomain_len && !memcmp(subdomain_ptr, iter->domain, iter->subdomain_len)) {
+                current_domain = iter;
+                break;
+            }
+        }
+
+        if(!current_domain) {
+            if(!create)
+                return prev_domain;
+
+            current_domain = heap_alloc(sizeof(*current_domain));
+            if(!current_domain)
+                return NULL;
+
+            current_domain->domain = heap_strdupW(subdomain_ptr);
+            if(!current_domain->domain) {
+                heap_free(current_domain);
+                return NULL;
+            }
+
+            current_domain->subdomain_len = ptr_end-subdomain_ptr;
+
+            current_domain->parent = prev_domain;
+            list_init(&current_domain->path_list);
+            list_init(&current_domain->subdomain_list);
+
+            list_add_tail(current_list, &current_domain->entry);
+        }
+
+        if(ptr == domain)
+            return current_domain;
+
+        prev_domain = current_domain;
+        current_list = &current_domain->subdomain_list;
+    }
+}
+
+static cookie_container_t *get_cookie_container(const WCHAR *domain, const WCHAR *path, BOOL create)
+{
+    cookie_domain_t *cookie_domain;
+    cookie_container_t *cookie_container, *iter;
+    size_t path_len, len;
+
+    cookie_domain = get_cookie_domain(domain, create);
+    if(!cookie_domain)
+        return NULL;
+
+    path_len = strlenW(path);
+
+    LIST_FOR_EACH_ENTRY(cookie_container, &cookie_domain->path_list, cookie_container_t, entry) {
+        len = strlenW(cookie_container->path);
+        if(len < path_len)
+            break;
+
+        if(!strcmpiW(cookie_container->path, path))
+            return cookie_container;
+    }
+
+    if(!create)
+        return NULL;
+
+    cookie_container = heap_alloc(sizeof(*cookie_container));
+    if(!cookie_container)
+        return NULL;
+
+    cookie_container->path = heap_strdupW(path);
+    if(!cookie_container->path) {
+        heap_free(cookie_container);
+        return NULL;
+    }
+
+    cookie_container->domain = cookie_domain;
+    list_init(&cookie_container->cookie_list);
+
+
+    LIST_FOR_EACH_ENTRY(iter, &cookie_domain->path_list, cookie_container_t, entry) {
+        if(strlenW(iter->path) <= path_len) {
+            list_add_before(&iter->entry, &cookie_container->entry);
+            return cookie_container;
+        }
+    }
+
+    list_add_tail(&cookie_domain->path_list, &cookie_container->entry);
+    return cookie_container;
+}
+
+static void delete_cookie(cookie_t *cookie)
+{
+    list_remove(&cookie->entry);
+
+    heap_free(cookie->name);
+    heap_free(cookie->data);
+    heap_free(cookie);
+}
+
+static cookie_t *alloc_cookie(const WCHAR *name, const WCHAR *data, FILETIME expiry, FILETIME create_time, DWORD flags)
+{
+    cookie_t *new_cookie;
+
+    new_cookie = heap_alloc(sizeof(*new_cookie));
+    if(!new_cookie)
+        return NULL;
+
+    new_cookie->expiry = expiry;
+    new_cookie->create = create_time;
+    new_cookie->flags = flags;
+    list_init(&new_cookie->entry);
+
+    new_cookie->name = heap_strdupW(name);
+    new_cookie->data = heap_strdupW(data);
+    if((name && !new_cookie->name) || (data && !new_cookie->data)) {
+        delete_cookie(new_cookie);
+        return NULL;
+    }
+
+    return new_cookie;
+}
+
+static cookie_t *find_cookie(cookie_container_t *container, const WCHAR *name)
+{
+    cookie_t *iter;
+
+    LIST_FOR_EACH_ENTRY(iter, &container->cookie_list, cookie_t, entry) {
+        if(!strcmpiW(iter->name, name))
+            return iter;
+    }
+
+    return NULL;
+}
+
+static void add_cookie(cookie_container_t *container, cookie_t *new_cookie)
+{
+    TRACE("Adding %s=%s to %s %s\n", debugstr_w(new_cookie->name), debugstr_w(new_cookie->data),
+          debugstr_w(container->domain->domain), debugstr_w(container->path));
+
+    list_add_tail(&container->cookie_list, &new_cookie->entry);
+    new_cookie->container = container;
+}
+
+static void replace_cookie(cookie_container_t *container, cookie_t *new_cookie)
+{
+    cookie_t *old_cookie;
+
+    old_cookie = find_cookie(container, new_cookie->name);
+    if(old_cookie)
+        delete_cookie(old_cookie);
+
+    add_cookie(container, new_cookie);
+}
+
+static BOOL cookie_match_path(cookie_container_t *container, const WCHAR *path)
+{
+    return !strncmpiW(container->path, path, strlenW(container->path));
+}
 
 static BOOL create_cookie_url(LPCWSTR domain, LPCWSTR path, WCHAR *buf, DWORD buf_len)
 {
@@ -120,9 +290,8 @@ static BOOL create_cookie_url(LPCWSTR domain, LPCWSTR path, WCHAR *buf, DWORD bu
 static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
 {
     INTERNET_CACHE_ENTRY_INFOW *info;
-    cookie_domain *domain_container = NULL;
-    cookie *old_cookie;
-    struct list *iter;
+    cookie_container_t *cookie_container;
+    cookie_t *new_cookie;
     WCHAR cookie_url[MAX_PATH];
     HANDLE cookie;
     char *str = NULL, *pbeg, *pend;
@@ -154,19 +323,9 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
     str[size] = 0;
     UnlockUrlCacheEntryStream(cookie, 0);
 
-    LIST_FOR_EACH(iter, &domain_list)
-    {
-        domain_container = LIST_ENTRY(iter, cookie_domain, entry);
-        if(COOKIE_matchDomain(domain, path, domain_container, FALSE))
-            break;
-        domain_container = NULL;
-    }
-    if(!domain_container)
-        domain_container = COOKIE_addDomain(domain, path);
-    if(!domain_container) {
-        heap_free(str);
+    cookie_container = get_cookie_container(domain, path, TRUE);
+    if(!cookie_container)
         return FALSE;
-    }
 
     GetSystemTimeAsFileTime(&time);
     for(pbeg=str; pbeg && *pbeg; name=data=NULL) {
@@ -202,12 +361,18 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
             break;
 
         if(CompareFileTime(&time, &expiry) <= 0) {
-            if((old_cookie = COOKIE_findCookie(domain_container, name)))
-                COOKIE_deleteCookie(old_cookie, FALSE);
-            COOKIE_addCookie(domain_container, name, data, expiry, create, flags);
+            new_cookie = alloc_cookie(NULL, NULL, expiry, create, flags);
+            if(!new_cookie)
+                break;
+
+            new_cookie->name = name;
+            new_cookie->data = data;
+
+            replace_cookie(cookie_container, new_cookie);
+        }else {
+            heap_free(name);
+            heap_free(data);
         }
-        heap_free(name);
-        heap_free(data);
     }
     heap_free(str);
     heap_free(name);
@@ -216,28 +381,28 @@ static BOOL load_persistent_cookie(LPCWSTR domain, LPCWSTR path)
     return TRUE;
 }
 
-static BOOL save_persistent_cookie(cookie_domain *domain)
+static BOOL save_persistent_cookie(cookie_container_t *container)
 {
     static const WCHAR txtW[] = {'t','x','t',0};
 
     WCHAR cookie_url[MAX_PATH], cookie_file[MAX_PATH];
     HANDLE cookie_handle;
-    cookie *cookie_container = NULL, *cookie_iter;
+    cookie_t *cookie_container = NULL, *cookie_iter;
     BOOL do_save = FALSE;
     char buf[64], *dyn_buf;
     FILETIME time;
-    DWORD dwBytesWritten;
+    DWORD bytes_written;
 
-    if (!create_cookie_url(domain->lpCookieDomain, domain->lpCookiePath, cookie_url, sizeof(cookie_url)/sizeof(cookie_url[0])))
+    if (!create_cookie_url(container->domain->domain, container->path, cookie_url, sizeof(cookie_url)/sizeof(cookie_url[0])))
         return FALSE;
 
     /* check if there's anything to save */
     GetSystemTimeAsFileTime(&time);
-    LIST_FOR_EACH_ENTRY_SAFE(cookie_container, cookie_iter, &domain->cookie_list, cookie, entry)
+    LIST_FOR_EACH_ENTRY_SAFE(cookie_container, cookie_iter, &container->cookie_list, cookie_t, entry)
     {
         if((cookie_container->expiry.dwLowDateTime || cookie_container->expiry.dwHighDateTime)
                 && CompareFileTime(&time, &cookie_container->expiry) > 0) {
-            COOKIE_deleteCookie(cookie_container, FALSE);
+            delete_cookie(cookie_container);
             continue;
         }
 
@@ -259,45 +424,45 @@ static BOOL save_persistent_cookie(cookie_domain *domain)
         return FALSE;
     }
 
-    LIST_FOR_EACH_ENTRY(cookie_container, &domain->cookie_list, cookie, entry)
+    LIST_FOR_EACH_ENTRY(cookie_container, &container->cookie_list, cookie_t, entry)
     {
         if(cookie_container->flags & INTERNET_COOKIE_IS_SESSION)
             continue;
 
-        dyn_buf = heap_strdupWtoA(cookie_container->lpCookieName);
-        if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &dwBytesWritten, NULL)) {
+        dyn_buf = heap_strdupWtoA(cookie_container->name);
+        if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
             heap_free(dyn_buf);
             do_save = FALSE;
             break;
         }
         heap_free(dyn_buf);
-        if(!WriteFile(cookie_handle, "\n", 1, &dwBytesWritten, NULL)) {
+        if(!WriteFile(cookie_handle, "\n", 1, &bytes_written, NULL)) {
             do_save = FALSE;
             break;
         }
 
-        dyn_buf = heap_strdupWtoA(cookie_container->lpCookieData);
-        if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &dwBytesWritten, NULL)) {
+        dyn_buf = heap_strdupWtoA(cookie_container->data);
+        if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
             heap_free(dyn_buf);
             do_save = FALSE;
             break;
         }
         heap_free(dyn_buf);
-        if(!WriteFile(cookie_handle, "\n", 1, &dwBytesWritten, NULL)) {
+        if(!WriteFile(cookie_handle, "\n", 1, &bytes_written, NULL)) {
             do_save = FALSE;
             break;
         }
 
-        dyn_buf = heap_strdupWtoA(domain->lpCookieDomain);
-        if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &dwBytesWritten, NULL)) {
+        dyn_buf = heap_strdupWtoA(container->domain->domain);
+        if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
             heap_free(dyn_buf);
             do_save = FALSE;
             break;
         }
         heap_free(dyn_buf);
 
-        dyn_buf = heap_strdupWtoA(domain->lpCookiePath);
-        if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &dwBytesWritten, NULL)) {
+        dyn_buf = heap_strdupWtoA(container->path);
+        if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
             heap_free(dyn_buf);
             do_save = FALSE;
             break;
@@ -307,7 +472,7 @@ static BOOL save_persistent_cookie(cookie_domain *domain)
         sprintf(buf, "\n%u\n%u\n%u\n%u\n%u\n*\n", cookie_container->flags,
                 cookie_container->expiry.dwLowDateTime, cookie_container->expiry.dwHighDateTime,
                 cookie_container->create.dwLowDateTime, cookie_container->create.dwHighDateTime);
-        if(!WriteFile(cookie_handle, buf, strlen(buf), &dwBytesWritten, NULL)) {
+        if(!WriteFile(cookie_handle, buf, strlen(buf), &bytes_written, NULL)) {
             do_save = FALSE;
             break;
         }
@@ -324,90 +489,6 @@ static BOOL save_persistent_cookie(cookie_domain *domain)
     return CommitUrlCacheEntryW(cookie_url, cookie_file, time, time, 0, NULL, 0, txtW, 0);
 }
 
-/* adds a cookie to the domain */
-static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data,
-        FILETIME expiry, FILETIME create, DWORD flags)
-{
-    cookie *newCookie = heap_alloc(sizeof(cookie));
-    if (!newCookie)
-        return NULL;
-
-    newCookie->lpCookieName = heap_strdupW(name);
-    newCookie->lpCookieData = heap_strdupW(data);
-
-    if (!newCookie->lpCookieName || !newCookie->lpCookieData)
-    {
-        heap_free(newCookie->lpCookieName);
-        heap_free(newCookie->lpCookieData);
-        heap_free(newCookie);
-
-        return NULL;
-    }
-
-    newCookie->flags = flags;
-    newCookie->expiry = expiry;
-    newCookie->create = create;
-
-    TRACE("added cookie %p (data is %s)\n", newCookie, debugstr_w(data) );
-
-    list_add_tail(&domain->cookie_list, &newCookie->entry);
-    newCookie->parent = domain;
-    return newCookie;
-}
-
-
-/* finds a cookie in the domain matching the cookie name */
-static cookie *COOKIE_findCookie(cookie_domain *domain, LPCWSTR lpszCookieName)
-{
-    struct list * cursor;
-    TRACE("(%p, %s)\n", domain, debugstr_w(lpszCookieName));
-
-    LIST_FOR_EACH(cursor, &domain->cookie_list)
-    {
-        cookie *searchCookie = LIST_ENTRY(cursor, cookie, entry);
-       BOOL candidate = TRUE;
-       if (candidate && lpszCookieName)
-       {
-           if (candidate && !searchCookie->lpCookieName)
-               candidate = FALSE;
-           if (candidate && strcmpW(lpszCookieName, searchCookie->lpCookieName) != 0)
-                candidate = FALSE;
-       }
-       if (candidate)
-           return searchCookie;
-    }
-    return NULL;
-}
-
-/* removes a cookie from the list, if its the last cookie we also remove the domain */
-static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain)
-{
-    heap_free(deadCookie->lpCookieName);
-    heap_free(deadCookie->lpCookieData);
-    list_remove(&deadCookie->entry);
-
-    /* special case: last cookie, lets remove the domain to save memory */
-    if (list_empty(&deadCookie->parent->cookie_list) && deleteDomain)
-        COOKIE_deleteDomain(deadCookie->parent);
-    heap_free(deadCookie);
-}
-
-/* allocates a domain and adds it to the end */
-static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path)
-{
-    cookie_domain *newDomain = heap_alloc(sizeof(cookie_domain));
-
-    list_init(&newDomain->entry);
-    list_init(&newDomain->cookie_list);
-    newDomain->lpCookieDomain = heap_strdupW(domain);
-    newDomain->lpCookiePath = heap_strdupW(path);
-
-    list_add_tail(&domain_list, &newDomain->entry);
-
-    TRACE("Adding domain: %p\n", newDomain);
-    return newDomain;
-}
-
 static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostNameLen, LPWSTR path, int pathLen)
 {
     URL_COMPONENTSW UrlComponents;
@@ -449,78 +530,27 @@ static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostName
     return TRUE;
 }
 
-/* match a domain. domain must match if the domain is not NULL. path must match if the path is not NULL */
-static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath,
-                               cookie_domain *searchDomain, BOOL allow_partial)
-{
-    TRACE("searching on domain %p\n", searchDomain);
-       if (lpszCookieDomain)
-       {
-           if (!searchDomain->lpCookieDomain)
-            return FALSE;
-
-           TRACE("comparing domain %s with %s\n",
-            debugstr_w(lpszCookieDomain),
-            debugstr_w(searchDomain->lpCookieDomain));
-
-        if (allow_partial && !strstrW(lpszCookieDomain, searchDomain->lpCookieDomain))
-            return FALSE;
-        else if (!allow_partial && lstrcmpW(lpszCookieDomain, searchDomain->lpCookieDomain) != 0)
-            return FALSE;
-       }
-    if (lpszCookiePath)
-    {
-        INT len;
-        TRACE("comparing paths: %s with %s\n", debugstr_w(lpszCookiePath), debugstr_w(searchDomain->lpCookiePath));
-        /* paths match at the beginning.  so a path of  /foo would match
-         * /foobar and /foo/bar
-         */
-        if (!searchDomain->lpCookiePath)
-            return FALSE;
-        if (allow_partial)
-        {
-            len = lstrlenW(searchDomain->lpCookiePath);
-            if (strncmpiW(searchDomain->lpCookiePath, lpszCookiePath, len)!=0)
-                return FALSE;
-        }
-        else if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath))
-            return FALSE;
+typedef struct {
+    cookie_t **cookies;
+    unsigned cnt;
+    unsigned size;
 
-       }
-       return TRUE;
-}
+    unsigned string_len;
+} cookie_set_t;
 
-/* remove a domain from the list and delete it */
-static void COOKIE_deleteDomain(cookie_domain *deadDomain)
-{
-    struct list * cursor;
-    while ((cursor = list_tail(&deadDomain->cookie_list)))
-    {
-        COOKIE_deleteCookie(LIST_ENTRY(cursor, cookie, entry), FALSE);
-        list_remove(cursor);
-    }
-    heap_free(deadDomain->lpCookieDomain);
-    heap_free(deadDomain->lpCookiePath);
-
-    list_remove(&deadDomain->entry);
-
-    heap_free(deadDomain);
-}
-
-DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD *size)
+static DWORD get_cookie(const WCHAR *host, const WCHAR *path, DWORD flags, cookie_set_t *res)
 {
     static const WCHAR empty_path[] = { '/',0 };
 
-    unsigned cnt = 0, len, name_len, domain_count = 0, cookie_count = 0;
     WCHAR *ptr, subpath[INTERNET_MAX_PATH_LENGTH];
     const WCHAR *p;
-    cookie_domain *domain;
+    cookie_domain_t *domain;
+    cookie_container_t *container;
+    unsigned len;
     FILETIME tm;
 
     GetSystemTimeAsFileTime(&tm);
 
-    EnterCriticalSection(&cookie_cs);
-
     len = strlenW(host);
     p = host+len;
     while(p>host && p[-1]!='.') p--;
@@ -544,88 +574,139 @@ DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD
         while(ptr>subpath && ptr[-1]!='/') ptr--;
     }while(ptr != subpath);
 
-    ptr = cookie_data;
-    LIST_FOR_EACH_ENTRY(domain, &domain_list, cookie_domain, entry) {
-        struct list *cursor, *cursor2;
+    domain = get_cookie_domain(host, FALSE);
+    if(!domain) {
+        TRACE("Unknown host %s\n", debugstr_w(host));
+        return ERROR_NO_MORE_ITEMS;
+    }
 
-        if(!COOKIE_matchDomain(host, path, domain, TRUE))
-            continue;
+    for(domain = get_cookie_domain(host, FALSE); domain; domain = domain->parent) {
+        TRACE("Trying %s domain...\n", debugstr_w(domain->domain));
 
-        domain_count++;
-        TRACE("found domain %p\n", domain);
+        LIST_FOR_EACH_ENTRY(container, &domain->path_list, cookie_container_t, entry) {
+            struct list *cursor, *cursor2;
 
-        LIST_FOR_EACH_SAFE(cursor, cursor2, &domain->cookie_list) {
-            cookie *cookie_iter = LIST_ENTRY(cursor, cookie, entry);
+            TRACE("path %s\n", debugstr_w(container->path));
 
-            /* check for expiry */
-            if((cookie_iter->expiry.dwLowDateTime != 0 || cookie_iter->expiry.dwHighDateTime != 0)
-                && CompareFileTime(&tm, &cookie_iter->expiry)  > 0)
-            {
-                TRACE("Found expired cookie. deleting\n");
-                COOKIE_deleteCookie(cookie_iter, FALSE);
+            if(!cookie_match_path(container, path))
                 continue;
-            }
-
-            if (cookie_count)
-                cnt += 2; /* '; ' */
-            cnt += name_len = strlenW(cookie_iter->lpCookieName);
-            if ((len = strlenW(cookie_iter->lpCookieData))) {
-                cnt += 1; /* = */
-                cnt += len;
-            }
 
-            if(ptr) {
-                if(*size > cnt) {
-                    if(cookie_count) {
-                        *ptr++ = ';';
-                        *ptr++ = ' ';
-                    }
+            TRACE("found domain %p\n", domain->domain);
 
-                    memcpy(ptr, cookie_iter->lpCookieName, name_len*sizeof(WCHAR));
-                    ptr += name_len;
+            LIST_FOR_EACH_SAFE(cursor, cursor2, &container->cookie_list) {
+                cookie_t *cookie_iter = LIST_ENTRY(cursor, cookie_t, entry);
 
-                    if(len) {
-                        *ptr++ = '=';
-                        memcpy(ptr, cookie_iter->lpCookieData, len*sizeof(WCHAR));
-                        ptr += len;
-                    }
+                /* check for expiry */
+                if((cookie_iter->expiry.dwLowDateTime != 0 || cookie_iter->expiry.dwHighDateTime != 0)
+                    && CompareFileTime(&tm, &cookie_iter->expiry)  > 0) {
+                    TRACE("Found expired cookie. deleting\n");
+                    delete_cookie(cookie_iter);
+                    continue;
+                }
 
-                    assert(cookie_data+cnt == ptr);
-                    TRACE("Cookie: %s\n", debugstr_wn(cookie_data, cnt));
-                }else {
-                    /* Stop writing data, just compute the size */
-                    ptr = NULL;
+                if((cookie_iter->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY))
+                    continue;
+
+
+                if(!res->size) {
+                    res->cookies = heap_alloc(4*sizeof(*res->cookies));
+                    if(!res->cookies)
+                        continue;
+                    res->size = 4;
+                }else if(res->cnt == res->size) {
+                    cookie_t **new_cookies = heap_realloc(res->cookies, res->size*2*sizeof(*res->cookies));
+                    if(!new_cookies)
+                        continue;
+                    res->cookies = new_cookies;
+                    res->size *= 2;
                 }
-            }
 
-            cookie_count++;
+                if(res->cnt)
+                    res->string_len += 2; /* '; ' */
+                res->cookies[res->cnt++] = cookie_iter;
+
+                res->string_len += strlenW(cookie_iter->name);
+                if(*cookie_iter->data)
+                    res->string_len += 1 /* = */ + strlenW(cookie_iter->data);
+            }
         }
     }
 
-    LeaveCriticalSection(&cookie_cs);
+    return ERROR_SUCCESS;
+}
 
-    if(ptr)
-        *ptr = 0;
+static void cookie_set_to_string(const cookie_set_t *cookie_set, WCHAR *str)
+{
+    WCHAR *ptr = str;
+    unsigned i, len;
 
-    if (!cnt) {
-        TRACE("no cookies found for %s\n", debugstr_w(host));
-        return ERROR_NO_MORE_ITEMS;
+    for(i=0; i<cookie_set->cnt; i++) {
+        if(i) {
+            *ptr++ = ';';
+            *ptr++ = ' ';
+        }
+
+        len = strlenW(cookie_set->cookies[i]->name);
+        memcpy(ptr, cookie_set->cookies[i]->name, len*sizeof(WCHAR));
+        ptr += len;
+
+        if(*cookie_set->cookies[i]->data) {
+            *ptr++ = '=';
+            len = strlenW(cookie_set->cookies[i]->data);
+            memcpy(ptr, cookie_set->cookies[i]->data, len*sizeof(WCHAR));
+            ptr += len;
+        }
     }
 
-    if(!cookie_data || !ptr) {
-        *size = (cnt + 1) * sizeof(WCHAR);
-        TRACE("returning %u\n", *size);
-        return cookie_data ? ERROR_INSUFFICIENT_BUFFER : ERROR_SUCCESS;
+    assert(ptr-str == cookie_set->string_len);
+    TRACE("%s\n", debugstr_wn(str, ptr-str));
+}
+
+DWORD get_cookie_header(const WCHAR *host, const WCHAR *path, WCHAR **ret)
+{
+    cookie_set_t cookie_set = {0};
+    DWORD res;
+
+    static const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' '};
+
+    EnterCriticalSection(&cookie_cs);
+
+    res = get_cookie(host, path, INTERNET_COOKIE_HTTPONLY, &cookie_set);
+    if(res != ERROR_SUCCESS) {
+        LeaveCriticalSection(&cookie_cs);
+        return res;
     }
 
-    *size = cnt + 1;
+    if(cookie_set.cnt) {
+        WCHAR *header, *ptr;
+
+        ptr = header = heap_alloc(sizeof(cookieW) + (cookie_set.string_len + 3 /* crlf0 */) * sizeof(WCHAR));
+        if(header) {
+            memcpy(ptr, cookieW, sizeof(cookieW));
+            ptr += sizeof(cookieW)/sizeof(*cookieW);
 
-    TRACE("Returning %u (from %u domains): %s\n", cnt, domain_count, debugstr_w(cookie_data));
+            cookie_set_to_string(&cookie_set, ptr);
+            heap_free(cookie_set.cookies);
+            ptr += cookie_set.string_len;
+
+            *ptr++ = '\r';
+            *ptr++ = '\n';
+            *ptr++ = 0;
+
+            *ret = header;
+        }else {
+            res = ERROR_NOT_ENOUGH_MEMORY;
+        }
+    }else {
+        *ret = NULL;
+    }
+
+    LeaveCriticalSection(&cookie_cs);
     return ERROR_SUCCESS;
 }
 
 /***********************************************************************
- *           InternetGetCookieW (WININET.@)
+ *           InternetGetCookieExW (WININET.@)
  *
  * Retrieve cookie from the specified url
  *
@@ -637,14 +718,18 @@ DWORD get_cookie(const WCHAR *host, const WCHAR *path, WCHAR *cookie_data, DWORD
  *    FALSE on failure
  *
  */
-BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
-    LPWSTR lpCookieData, LPDWORD lpdwSize)
+BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
+        LPWSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
 {
     WCHAR host[INTERNET_MAX_HOST_NAME_LENGTH], path[INTERNET_MAX_PATH_LENGTH];
+    cookie_set_t cookie_set = {0};
     DWORD res;
     BOOL ret;
 
-    TRACE("(%s, %s, %p, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName), lpCookieData, lpdwSize);
+    TRACE("(%s, %s, %p, %p, %x, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName), lpCookieData, lpdwSize, flags, reserved);
+
+    if (flags)
+        FIXME("flags 0x%08x not supported\n", flags);
 
     if (!lpszUrl)
     {
@@ -659,15 +744,53 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
         return FALSE;
     }
 
-    res = get_cookie(host, path, lpCookieData, lpdwSize);
-    if(res != ERROR_SUCCESS)
+    EnterCriticalSection(&cookie_cs);
+
+    res = get_cookie(host, path, flags, &cookie_set);
+    if(res != ERROR_SUCCESS) {
+        LeaveCriticalSection(&cookie_cs);
         SetLastError(res);
-    return res == ERROR_SUCCESS;
+        return FALSE;
+    }
+
+    if(cookie_set.cnt) {
+        if(!lpCookieData || cookie_set.string_len+1 > *lpdwSize) {
+            *lpdwSize = (cookie_set.string_len + 1) * sizeof(WCHAR);
+            TRACE("returning %u\n", *lpdwSize);
+            if(lpCookieData) {
+                SetLastError(ERROR_INSUFFICIENT_BUFFER);
+                ret = FALSE;
+            }
+        }else {
+            *lpdwSize = cookie_set.string_len + 1;
+            cookie_set_to_string(&cookie_set, lpCookieData);
+            lpCookieData[cookie_set.string_len] = 0;
+        }
+    }else {
+        TRACE("no cookies found for %s\n", debugstr_w(host));
+        SetLastError(ERROR_NO_MORE_ITEMS);
+        ret = FALSE;
+    }
+
+    heap_free(cookie_set.cookies);
+    LeaveCriticalSection(&cookie_cs);
+    return ret;
 }
 
+/***********************************************************************
+ *           InternetGetCookieW (WININET.@)
+ *
+ * Retrieve cookie for the specified URL.
+ */
+BOOL WINAPI InternetGetCookieW(const WCHAR *url, const WCHAR *name, WCHAR *data, DWORD *size)
+{
+    TRACE("(%s, %s, %s, %p)\n", debugstr_w(url), debugstr_w(name), debugstr_w(data), size);
+
+    return InternetGetCookieExW(url, name, data, size, 0, NULL);
+}
 
 /***********************************************************************
- *           InternetGetCookieA (WININET.@)
+ *           InternetGetCookieExA (WININET.@)
  *
  * Retrieve cookie from the specified url
  *
@@ -676,20 +799,20 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
  *    FALSE on failure
  *
  */
-BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
-    LPSTR lpCookieData, LPDWORD lpdwSize)
+BOOL WINAPI InternetGetCookieExA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
+        LPSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
 {
     WCHAR *url, *name;
     DWORD len, size;
     BOOL r;
 
-    TRACE("(%s %s %p %p(%u))\n", debugstr_a(lpszUrl), debugstr_a(lpszCookieName),
-          lpCookieData, lpdwSize, lpdwSize ? *lpdwSize : 0);
+    TRACE("(%s %s %p %p(%u) %x %p)\n", debugstr_a(lpszUrl), debugstr_a(lpszCookieName),
+          lpCookieData, lpdwSize, lpdwSize ? *lpdwSize : 0, flags, reserved);
 
     url = heap_strdupAtoW(lpszUrl);
     name = heap_strdupAtoW(lpszCookieName);
 
-    r = InternetGetCookieW( url, name, NULL, &len );
+    r = InternetGetCookieExW( url, name, NULL, &len, flags, reserved );
     if( r )
     {
         WCHAR *szCookieData;
@@ -701,7 +824,7 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
         }
         else
         {
-            r = InternetGetCookieW( url, name, szCookieData, &len );
+            r = InternetGetCookieExW( url, name, szCookieData, &len, flags, reserved );
 
             if(r) {
                 size = WideCharToMultiByte( CP_ACP, 0, szCookieData, len, NULL, 0, NULL, NULL);
@@ -724,6 +847,17 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
     return r;
 }
 
+/***********************************************************************
+ *           InternetGetCookieA (WININET.@)
+ *
+ * See InternetGetCookieW.
+ */
+BOOL WINAPI InternetGetCookieA(const char *url, const char *name, char *data, DWORD *size)
+{
+    TRACE("(%s, %s, %s, %p)\n", debugstr_a(url), debugstr_a(name), debugstr_a(data), size);
+
+    return InternetGetCookieExA(url, name, data, size, 0, NULL);
+}
 
 /***********************************************************************
  *           IsDomainLegalCookieDomainW (WININET.@)
@@ -761,22 +895,23 @@ BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 )
     return TRUE;
 }
 
-BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWSTR cookie_data)
+DWORD set_cookie(const WCHAR *domain, const WCHAR *path, const WCHAR *cookie_name, const WCHAR *cookie_data, DWORD flags)
 {
-    cookie_domain *thisCookieDomain = NULL;
-    cookie *thisCookie;
-    struct list *cursor;
+    cookie_container_t *container;
+    cookie_t *thisCookie;
     LPWSTR data, value;
     WCHAR *ptr;
     FILETIME expiry, create;
     BOOL expired = FALSE, update_persistent = FALSE;
-    DWORD flags = 0;
+    DWORD cookie_flags = 0;
+
+    TRACE("%s %s %s=%s %x\n", debugstr_w(domain), debugstr_w(path), debugstr_w(cookie_name), debugstr_w(cookie_data), flags);
 
     value = data = heap_strdupW(cookie_data);
     if (!data)
     {
         ERR("could not allocate the cookie data buffer\n");
-        return FALSE;
+        return COOKIE_STATE_UNKNOWN;
     }
 
     memset(&expiry,0,sizeof(expiry));
@@ -802,7 +937,7 @@ BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWSTR cooki
         {
             heap_free(data);
             ERR("could not allocate the cookie value buffer\n");
-            return FALSE;
+            return COOKIE_STATE_UNKNOWN;
         }
         strcpyW(value, data);
 
@@ -824,7 +959,7 @@ BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWSTR cooki
                 if(value != data)
                     heap_free(value);
                 heap_free(data);
-                return FALSE;
+                return COOKIE_STATE_UNKNOWN;
             }
 
             if(end_ptr)
@@ -861,7 +996,15 @@ BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWSTR cooki
         }
         else if (strncmpiW(ptr, szHttpOnly, 8) == 0)
         {
-            FIXME("httponly not handled (%s)\n",debugstr_w(ptr));
+            if(!(flags & INTERNET_COOKIE_HTTPONLY)) {
+                WARN("HTTP only cookie added without INTERNET_COOKIE_HTTPONLY flag\n");
+                heap_free(data);
+                if (value != data) heap_free(value);
+                SetLastError(ERROR_INVALID_OPERATION);
+                return COOKIE_STATE_REJECT;
+            }
+
+            cookie_flags |= INTERNET_COOKIE_HTTPONLY;
             ptr += strlenW(szHttpOnly);
         }
         else if (*ptr)
@@ -875,99 +1018,99 @@ BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWSTR cooki
 
     load_persistent_cookie(domain, path);
 
-    LIST_FOR_EACH(cursor, &domain_list)
-    {
-        thisCookieDomain = LIST_ENTRY(cursor, cookie_domain, entry);
-        if (COOKIE_matchDomain(domain, path, thisCookieDomain, FALSE))
-            break;
-        thisCookieDomain = NULL;
-    }
-
-    if (!thisCookieDomain)
-    {
-        if (!expired)
-            thisCookieDomain = COOKIE_addDomain(domain, path);
-        else
-        {
-            heap_free(data);
-            if (value != data) heap_free(value);
-            LeaveCriticalSection(&cookie_cs);
-            return TRUE;
-        }
+    container = get_cookie_container(domain, path, !expired);
+    if(!container) {
+        heap_free(data);
+        if (value != data) heap_free(value);
+        LeaveCriticalSection(&cookie_cs);
+        return COOKIE_STATE_ACCEPT;
     }
 
     if(!expiry.dwLowDateTime && !expiry.dwHighDateTime)
-        flags |= INTERNET_COOKIE_IS_SESSION;
+        cookie_flags |= INTERNET_COOKIE_IS_SESSION;
     else
         update_persistent = TRUE;
 
-    if ((thisCookie = COOKIE_findCookie(thisCookieDomain, cookie_name)))
+    if ((thisCookie = find_cookie(container, cookie_name)))
     {
+        if ((thisCookie->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY)) {
+            WARN("An attempt to override httponly cookie\n");
+            SetLastError(ERROR_INVALID_OPERATION);
+            heap_free(data);
+            if (value != data) heap_free(value);
+            return COOKIE_STATE_REJECT;
+        }
+
         if (!(thisCookie->flags & INTERNET_COOKIE_IS_SESSION))
             update_persistent = TRUE;
-        COOKIE_deleteCookie(thisCookie, FALSE);
+        delete_cookie(thisCookie);
     }
 
     TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_w(cookie_name),
-          debugstr_w(value), debugstr_w(thisCookieDomain->lpCookieDomain),debugstr_w(thisCookieDomain->lpCookiePath));
+          debugstr_w(value), debugstr_w(container->domain->domain),debugstr_w(container->path));
 
-    if (!expired && !COOKIE_addCookie(thisCookieDomain, cookie_name, value, expiry, create, flags))
-    {
-        heap_free(data);
-        if (value != data) heap_free(value);
-        LeaveCriticalSection(&cookie_cs);
-        return FALSE;
+    if (!expired) {
+        cookie_t *new_cookie;
+
+        new_cookie = alloc_cookie(cookie_name, value, expiry, create, cookie_flags);
+        if(!new_cookie) {
+            heap_free(data);
+            if (value != data) heap_free(value);
+            LeaveCriticalSection(&cookie_cs);
+            return COOKIE_STATE_UNKNOWN;
+        }
+
+        add_cookie(container, new_cookie);
     }
     heap_free(data);
     if (value != data) heap_free(value);
 
-    if (!update_persistent || save_persistent_cookie(thisCookieDomain))
+    if (!update_persistent || save_persistent_cookie(container))
     {
         LeaveCriticalSection(&cookie_cs);
-        return TRUE;
+        return COOKIE_STATE_ACCEPT;
     }
     LeaveCriticalSection(&cookie_cs);
-    return FALSE;
+    return COOKIE_STATE_UNKNOWN;
 }
 
 /***********************************************************************
- *           InternetSetCookieW (WININET.@)
+ *           InternetSetCookieExW (WININET.@)
  *
  * Sets cookie for the specified url
- *
- * RETURNS
- *    TRUE  on success
- *    FALSE on failure
- *
  */
-BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
-    LPCWSTR lpCookieData)
+DWORD WINAPI InternetSetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
+        LPCWSTR lpCookieData, DWORD flags, DWORD_PTR reserved)
 {
     BOOL ret;
     WCHAR hostName[INTERNET_MAX_HOST_NAME_LENGTH], path[INTERNET_MAX_PATH_LENGTH];
 
-    TRACE("(%s,%s,%s)\n", debugstr_w(lpszUrl),
-        debugstr_w(lpszCookieName), debugstr_w(lpCookieData));
+    TRACE("(%s, %s, %s, %x, %lx)\n", debugstr_w(lpszUrl), debugstr_w(lpszCookieName),
+          debugstr_w(lpCookieData), flags, reserved);
+
+    if (flags & ~INTERNET_COOKIE_HTTPONLY)
+        FIXME("flags %x not supported\n", flags);
 
     if (!lpszUrl || !lpCookieData)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
+        return COOKIE_STATE_UNKNOWN;
     }
 
     hostName[0] = 0;
     ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0]));
-    if (!ret || !hostName[0]) return FALSE;
+    if (!ret || !hostName[0]) return COOKIE_STATE_UNKNOWN;
 
     if (!lpszCookieName)
     {
         WCHAR *cookie, *data;
+        DWORD res;
 
         cookie = heap_strdupW(lpCookieData);
         if (!cookie)
         {
             SetLastError(ERROR_OUTOFMEMORY);
-            return FALSE;
+            return COOKIE_STATE_UNKNOWN;
         }
 
         /* some apps (or is it us??) try to add a cookie with no cookie name, but
@@ -976,14 +1119,25 @@ BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
         if (!(data = strchrW(cookie, '='))) data = cookie + strlenW(cookie);
         else *data++ = 0;
 
-        ret = set_cookie(hostName, path, cookie, data);
+        res = set_cookie(hostName, path, cookie, data, flags);
 
         heap_free(cookie);
-        return ret;
+        return res;
     }
-    return set_cookie(hostName, path, lpszCookieName, lpCookieData);
+    return set_cookie(hostName, path, lpszCookieName, lpCookieData, flags);
 }
 
+/***********************************************************************
+ *           InternetSetCookieW (WININET.@)
+ *
+ * Sets a cookie for the specified URL.
+ */
+BOOL WINAPI InternetSetCookieW(const WCHAR *url, const WCHAR *name, const WCHAR *data)
+{
+    TRACE("(%s, %s, %s)\n", debugstr_w(url), debugstr_w(name), debugstr_w(data));
+
+    return InternetSetCookieExW(url, name, data, 0, 0) == COOKIE_STATE_ACCEPT;
+}
 
 /***********************************************************************
  *           InternetSetCookieA (WININET.@)
@@ -1024,70 +1178,22 @@ BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
 DWORD WINAPI InternetSetCookieExA( LPCSTR lpszURL, LPCSTR lpszCookieName, LPCSTR lpszCookieData,
                                    DWORD dwFlags, DWORD_PTR dwReserved)
 {
-    TRACE("(%s, %s, %s, 0x%08x, 0x%08lx)\n",
-          debugstr_a(lpszURL), debugstr_a(lpszCookieName), debugstr_a(lpszCookieData),
-          dwFlags, dwReserved);
-
-    if (dwFlags) FIXME("flags 0x%08x not supported\n", dwFlags);
-    return InternetSetCookieA(lpszURL, lpszCookieName, lpszCookieData);
-}
-
-/***********************************************************************
- *           InternetSetCookieExW (WININET.@)
- *
- * Sets a cookie for the specified URL.
- *
- * RETURNS
- *    TRUE  on success
- *    FALSE on failure
- *
- */
-DWORD WINAPI InternetSetCookieExW( LPCWSTR lpszURL, LPCWSTR lpszCookieName, LPCWSTR lpszCookieData,
-                                   DWORD dwFlags, DWORD_PTR dwReserved)
-{
-    TRACE("(%s, %s, %s, 0x%08x, 0x%08lx)\n",
-          debugstr_w(lpszURL), debugstr_w(lpszCookieName), debugstr_w(lpszCookieData),
-          dwFlags, dwReserved);
+    WCHAR *data, *url, *name;
+    DWORD r;
 
-    if (dwFlags) FIXME("flags 0x%08x not supported\n", dwFlags);
-    return InternetSetCookieW(lpszURL, lpszCookieName, lpszCookieData);
-}
+    TRACE("(%s, %s, %s, %x, %lx)\n", debugstr_a(lpszURL), debugstr_a(lpszCookieName),
+          debugstr_a(lpszCookieData), dwFlags, dwReserved);
 
-/***********************************************************************
- *           InternetGetCookieExA (WININET.@)
- *
- * See InternetGetCookieExW.
- */
-BOOL WINAPI InternetGetCookieExA( LPCSTR pchURL, LPCSTR pchCookieName, LPSTR pchCookieData,
-                                  LPDWORD pcchCookieData, DWORD dwFlags, LPVOID lpReserved)
-{
-    TRACE("(%s, %s, %s, %p, 0x%08x, %p)\n",
-          debugstr_a(pchURL), debugstr_a(pchCookieName), debugstr_a(pchCookieData),
-          pcchCookieData, dwFlags, lpReserved);
-
-    if (dwFlags) FIXME("flags 0x%08x not supported\n", dwFlags);
-    return InternetGetCookieA(pchURL, pchCookieName, pchCookieData, pcchCookieData);
-}
+    url = heap_strdupAtoW(lpszURL);
+    name = heap_strdupAtoW(lpszCookieName);
+    data = heap_strdupAtoW(lpszCookieData);
 
-/***********************************************************************
- *           InternetGetCookieExW (WININET.@)
- *
- * Retrieve cookie for the specified URL.
- *
- * RETURNS
- *    TRUE  on success
- *    FALSE on failure
- *
- */
-BOOL WINAPI InternetGetCookieExW( LPCWSTR pchURL, LPCWSTR pchCookieName, LPWSTR pchCookieData,
-                                  LPDWORD pcchCookieData, DWORD dwFlags, LPVOID lpReserved)
-{
-    TRACE("(%s, %s, %s, %p, 0x%08x, %p)\n",
-          debugstr_w(pchURL), debugstr_w(pchCookieName), debugstr_w(pchCookieData),
-          pcchCookieData, dwFlags, lpReserved);
+    r = InternetSetCookieExW(url, name, data, dwFlags, dwReserved);
 
-    if (dwFlags) FIXME("flags 0x%08x not supported\n", dwFlags);
-    return InternetGetCookieW(pchURL, pchCookieName, pchCookieData, pcchCookieData);
+    heap_free( data );
+    heap_free( name );
+    heap_free( url );
+    return r;
 }
 
 /***********************************************************************
index df7becf..d3b97a9 100644 (file)
@@ -1153,7 +1153,7 @@ static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DW
         return ERROR_INTERNET_DISCONNECTED;
 
     /* FIXME: FTP should use NETCON_ stuff */
-    res = recv(file->nDataSocket, buffer, size, MSG_WAITALL);
+    res = sock_recv(file->nDataSocket, buffer, size, MSG_WAITALL);
     *read = res>0 ? res : 0;
 
     error = res >= 0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME */
@@ -1178,7 +1178,7 @@ static DWORD FTPFILE_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
     ftp_file_t *lpwh = (ftp_file_t*) hdr;
     int res;
 
-    res = send(lpwh->nDataSocket, buffer, size, 0);
+    res = sock_send(lpwh->nDataSocket, buffer, size, 0);
 
     *written = res>0 ? res : 0;
     return res >= 0 ? ERROR_SUCCESS : sock_get_error(errno);
@@ -1192,7 +1192,7 @@ static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif)
 
     TRACE("%p\n", file);
 
-    available = recv(file->nDataSocket, buffer, sizeof(buffer), MSG_PEEK);
+    available = sock_recv(file->nDataSocket, buffer, sizeof(buffer), MSG_PEEK);
 
     if(available != -1) {
         iar.dwResult = (DWORD_PTR)file->hdr.hInternet;
@@ -1235,7 +1235,7 @@ static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available,
 
         *available = 0;
 
-        retval = recv(file->nDataSocket, &byte, 1, MSG_PEEK);
+        retval = sock_recv(file->nDataSocket, &byte, 1, MSG_PEEK);
         if(retval > 0) {
             task_header_t *task;
 
@@ -2274,7 +2274,7 @@ BOOL WINAPI FtpCommandW( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags
     TRACE("Sending (%s) len(%d)\n", cmd, len);
     while ((nBytesSent < len) && (nRC != -1))
     {
-        nRC = send(lpwfs->sndSocket, cmd + nBytesSent, len - nBytesSent, 0);
+        nRC = sock_send(lpwfs->sndSocket, cmd + nBytesSent, len - nBytesSent, 0);
         if (nRC != -1)
         {
             nBytesSent += nRC;
@@ -2641,7 +2641,7 @@ static BOOL FTP_SendCommandA(INT nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam,
        TRACE("Sending (%s) len(%d)\n", buf, len);
        while((nBytesSent < len) && (nRC != -1))
        {
-               nRC = send(nSocket, buf+nBytesSent, len - nBytesSent, 0);
+               nRC = sock_send(nSocket, buf+nBytesSent, len - nBytesSent, 0);
                nBytesSent += nRC;
        }
     heap_free(buf);
@@ -3221,7 +3221,7 @@ static BOOL FTP_SendData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile)
 
         nLen = DATA_PACKET_SIZE < nBytesToSend ?
             DATA_PACKET_SIZE : nBytesToSend;
-        nRC  = send(nDataSocket, lpszBuffer, nLen, 0);
+        nRC  = sock_send(nDataSocket, lpszBuffer, nLen, 0);
 
         if (nRC != -1)
         {
@@ -3326,7 +3326,7 @@ static BOOL FTP_RetrieveFileData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE h
 
     while (nRC != -1)
     {
-        nRC = recv(nDataSocket, lpszBuffer, DATA_PACKET_SIZE, 0);
+        nRC = sock_recv(nDataSocket, lpszBuffer, DATA_PACKET_SIZE, 0);
         if (nRC != -1)
         {
             /* other side closed socket. */
index 714c4a6..e472d3e 100644 (file)
@@ -299,7 +299,11 @@ BOOL collect_connections(collect_type_t collect_type)
     BOOL remaining = FALSE;
     DWORD64 now;
 
+#ifdef __REACTOS__
     now = GetTickCount();
+#else
+    now = GetTickCount64();
+#endif
 
     LIST_FOR_EACH_ENTRY_SAFE(server, server_safe, &connection_pool, server_t, entry) {
         LIST_FOR_EACH_ENTRY_SAFE(netconn, netconn_safe, &server->conn_pool, netconn_t, pool_entry) {
@@ -740,7 +744,7 @@ static void HTTP_ProcessCookies( http_request_t *request )
             continue;
 
         data++;
-        set_cookie(host->lpszValue, request->path, name, data);
+        set_cookie(host->lpszValue, request->path, name, data, INTERNET_COOKIE_HTTPONLY);
         heap_free(name);
     }
 }
@@ -1300,7 +1304,7 @@ BOOL WINAPI HttpAddRequestHeadersW(HINTERNET hHttpRequest,
 
     TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_wn(lpszHeader, dwHeaderLength), dwHeaderLength, dwModifier);
 
-    if (!lpszHeader)
+    if (!lpszHeader) 
       return TRUE;
 
     request = (http_request_t*) get_handle_object( hHttpRequest );
@@ -1951,7 +1955,7 @@ static void http_release_netconn(http_request_t *req, BOOL reuse)
         return;
     }
 #else
-    // silence unused function warning
+    /* Silence unused function warning */
     (void)collect_connections_proc;
 #endif
 
@@ -2859,10 +2863,11 @@ static const data_stream_vtbl_t chunked_stream_vtbl = {
 static DWORD set_content_length(http_request_t *request)
 {
     static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0};
+    static const WCHAR headW[] = {'H','E','A','D',0};
     WCHAR encoding[20];
     DWORD size;
 
-    if(request->status_code == HTTP_STATUS_NO_CONTENT) {
+    if(request->status_code == HTTP_STATUS_NO_CONTENT || !strcmpW(request->verb, headW)) {
         request->contentLength = request->netconn_stream.content_length = 0;
         return ERROR_SUCCESS;
     }
@@ -3346,9 +3351,6 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
 
     HTTP_ProcessHeader(request, hostW, request->server->canon_host_port, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDHDR_FLAG_REQ);
 
-    if (session->hostPort == INTERNET_INVALID_PORT_NUMBER)
-        session->hostPort = INTERNET_DEFAULT_HTTP_PORT;
-
     if (hIC->proxy && hIC->proxy[0] && !HTTP_ShouldBypassProxy(hIC, session->hostName))
         HTTP_DealWithProxy( hIC, session, request );
 
@@ -3673,8 +3675,6 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
         return ERROR_HTTP_HEADER_NOT_FOUND;
     }
 
-    if (lpdwIndex) (*lpdwIndex)++;
-
     /* coalesce value to requested type */
     if (dwInfoLevel & HTTP_QUERY_FLAG_NUMBER && lpBuffer)
     {
@@ -3720,6 +3720,7 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t *request, DWORD dwInfoLevel,
         }
         *lpdwBufferLength = len - sizeof(WCHAR);
     }
+    if (lpdwIndex) (*lpdwIndex)++;
     return ERROR_SUCCESS;
 }
 
@@ -3842,13 +3843,13 @@ BOOL WINAPI HttpQueryInfoW(HINTERNET hHttpRequest, DWORD dwInfoLevel,
                info_mod &= ~ modifier_flags[i].val;
            }
        }
-
+       
        if (info_mod) {
            TRACE(" Unknown (%08x)", info_mod);
        }
        TRACE("\n");
     }
-
+    
     request = (http_request_t*) get_handle_object( hHttpRequest );
     if (NULL == request ||  request->hdr.htype != WH_HHTTPREQ)
     {
@@ -3955,9 +3956,9 @@ static LPWSTR HTTP_GetRedirectURL(http_request_t *request, LPCWSTR lpszUrl)
     urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
     urlComponents.lpszScheme = (request->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp;
     urlComponents.dwSchemeLength = 0;
-    urlComponents.lpszHostName = session->hostName;
+    urlComponents.lpszHostName = request->server->name;
     urlComponents.dwHostNameLength = 0;
-    urlComponents.nPort = session->hostPort;
+    urlComponents.nPort = request->server->port;
     urlComponents.lpszUserName = session->userName;
     urlComponents.dwUserNameLength = 0;
     urlComponents.lpszPassword = NULL;
@@ -4082,6 +4083,7 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
         }
         else
             session->hostName = heap_strdupW(hostName);
+        session->hostPort = urlComponents.nPort;
 
         HTTP_ProcessHeader(request, hostW, session->hostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ);
 
@@ -4154,68 +4156,17 @@ static LPWSTR HTTP_build_req( LPCWSTR *list, int len )
     return str;
 }
 
-static DWORD HTTP_SecureProxyConnect(http_request_t *request)
-{
-    server_t *server = request->server;
-    LPWSTR requestString;
-    INT len;
-    INT cnt;
-    INT responseLen;
-    char *ascii_req;
-    DWORD res;
-
-    static const WCHAR connectW[] = {'C','O','N','N','E','C','T',0};
-
-    TRACE("\n");
-
-    requestString = build_request_header( request, connectW, server->host_port, g_szHttp1_1, TRUE );
-
-    len = WideCharToMultiByte( CP_ACP, 0, requestString, -1,
-                                NULL, 0, NULL, NULL );
-    len--; /* the nul terminator isn't needed */
-    ascii_req = heap_alloc(len);
-    WideCharToMultiByte( CP_ACP, 0, requestString, -1, ascii_req, len, NULL, NULL );
-    heap_free( requestString );
-
-    TRACE("full request -> %s\n", debugstr_an( ascii_req, len ) );
-
-    NETCON_set_timeout( request->netconn, TRUE, request->send_timeout );
-    res = NETCON_send( request->netconn, ascii_req, len, 0, &cnt );
-    heap_free( ascii_req );
-    if (res != ERROR_SUCCESS)
-        return res;
-
-    if (HTTP_GetResponseHeaders( request, &responseLen ) || !responseLen)
-        return ERROR_HTTP_INVALID_HEADER;
-
-    return ERROR_SUCCESS;
-}
-
 static void HTTP_InsertCookies(http_request_t *request)
 {
-    DWORD cookie_size, size, cnt = 0;
-    HTTPHEADERW *host;
     WCHAR *cookies;
+    DWORD res;
 
-    static const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' ',0};
-
-    host = HTTP_GetHeader(request, hostW);
-    if(!host)
-        return;
-
-    if(get_cookie(host->lpszValue, request->path, NULL, &cookie_size) != ERROR_SUCCESS)
-        return;
-
-    size = sizeof(cookieW) + cookie_size * sizeof(WCHAR) + sizeof(szCrLf);
-    if(!(cookies = heap_alloc(size)))
+    res = get_cookie_header(request->server->name, request->path, &cookies);
+    if(res != ERROR_SUCCESS || !cookies)
         return;
 
-    cnt += sprintfW(cookies, cookieW);
-    get_cookie(host->lpszValue, request->path, cookies+cnt, &cookie_size);
-    strcatW(cookies, szCrLf);
-
+    get_cookie_header(request->server->name, request->path, &cookies);
     HTTP_HttpAddRequestHeadersW(request, cookies, strlenW(cookies), HTTP_ADDREQ_FLAG_REPLACE);
-
     heap_free(cookies);
 }
 
@@ -4815,29 +4766,24 @@ static DWORD open_http_connection(http_request_t *request, BOOL *reusing)
             INTERNET_STATUS_CONNECTED_TO_SERVER,
             request->server->addr_str, strlen(request->server->addr_str)+1);
 
-    if(is_https) {
-        /* Note: we differ from Microsoft's WinINet here. they seem to have
-         * a bug that causes no status callbacks to be sent when starting
-         * a tunnel to a proxy server using the CONNECT verb. i believe our
-         * behaviour to be more correct and to not cause any incompatibilities
-         * because using a secure connection through a proxy server is a rare
-         * case that would be hard for anyone to depend on */
-        if(request->proxy)
-            res = HTTP_SecureProxyConnect(request);
-        if(res == ERROR_SUCCESS)
-            res = NETCON_secure_connect(request->netconn, request->server);
-    }
-
-    if(res != ERROR_SUCCESS) {
-        http_release_netconn(request, FALSE);
-        return res;
-    }
-
     *reusing = FALSE;
     TRACE("Created connection to %s: %p\n", debugstr_w(request->server->name), netconn);
     return ERROR_SUCCESS;
 }
 
+static char *build_ascii_request( const WCHAR *str, void *data, DWORD data_len, DWORD *out_len )
+{
+    int len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
+    char *ret;
+
+    if (!(ret = heap_alloc( len + data_len ))) return NULL;
+    WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
+    if (data_len) memcpy( ret + len - 1, data, data_len );
+    *out_len = len + data_len - 1;
+    ret[*out_len] = 0;
+    return ret;
+}
+
 /***********************************************************************
  *           HTTP_HttpSendRequestW (internal)
  *
@@ -4852,13 +4798,11 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
        DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength,
        DWORD dwContentLength, BOOL bEndRequest)
 {
-    INT cnt;
-    BOOL redirected = FALSE;
-    LPWSTR requestString = NULL;
-    INT responseLen;
-    BOOL loop_next;
     static const WCHAR szContentLength[] =
         { 'C','o','n','t','e','n','t','-','L','e','n','g','t','h',':',' ','%','l','i','\r','\n',0 };
+    BOOL redirected = FALSE, secure_proxy_connect = FALSE, loop_next;
+    LPWSTR requestString = NULL;
+    INT responseLen, cnt;
     WCHAR contentLengthStr[sizeof szContentLength/2 /* includes \r\n */ + 20 /* int */ ];
     DWORD res;
 
@@ -4873,7 +4817,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
     if (dwContentLength || strcmpW(request->verb, szGET))
     {
         sprintfW(contentLengthStr, szContentLength, dwContentLength);
-        HTTP_HttpAddRequestHeadersW(request, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_REPLACE);
+        HTTP_HttpAddRequestHeadersW(request, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_ADD_IF_NEW);
         request->bytesToWrite = dwContentLength;
     }
     if (request->session->appInfo->agent)
@@ -4907,7 +4851,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
 
     do
     {
-        DWORD len;
+        DWORD len, data_len = dwOptionalLength;
         BOOL reusing_connection;
         char *ascii_req;
 
@@ -4935,7 +4879,31 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
         if (!(request->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES))
             HTTP_InsertCookies(request);
 
-        if (request->proxy)
+        res = open_http_connection(request, &reusing_connection);
+        if (res != ERROR_SUCCESS)
+            break;
+
+        if (!reusing_connection && (request->hdr.dwFlags & INTERNET_FLAG_SECURE))
+        {
+            if (request->proxy) secure_proxy_connect = TRUE;
+            else
+            {
+                res = NETCON_secure_connect(request->netconn, request->server);
+                if (res != ERROR_SUCCESS)
+                {
+                    WARN("failed to upgrade to secure connection\n");
+                    http_release_netconn(request, FALSE);
+                    break;
+                }
+            }
+        }
+        if (secure_proxy_connect)
+        {
+            static const WCHAR connectW[] = {'C','O','N','N','E','C','T',0};
+            const WCHAR *target = request->server->host_port;
+            requestString = build_request_header(request, connectW, target, g_szHttp1_1, TRUE);
+        }
+        else if (request->proxy && !(request->hdr.dwFlags & INTERNET_FLAG_SECURE))
         {
             WCHAR *url = build_proxy_path_url(request);
             requestString = build_request_header(request, request->verb, url, request->version, TRUE);
@@ -4944,25 +4912,13 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
         else
             requestString = build_request_header(request, request->verb, request->path, request->version, TRUE);
 
-
         TRACE("Request header -> %s\n", debugstr_w(requestString) );
 
-        res = open_http_connection(request, &reusing_connection);
-        if (res != ERROR_SUCCESS)
-            break;
-
         /* send the request as ASCII, tack on the optional data */
-        if (!lpOptional || redirected)
-            dwOptionalLength = 0;
-        len = WideCharToMultiByte( CP_ACP, 0, requestString, -1,
-                                   NULL, 0, NULL, NULL );
-        ascii_req = heap_alloc(len + dwOptionalLength);
-        WideCharToMultiByte( CP_ACP, 0, requestString, -1,
-                             ascii_req, len, NULL, NULL );
-        if( lpOptional )
-            memcpy( &ascii_req[len-1], lpOptional, dwOptionalLength );
-        len = (len + dwOptionalLength - 1);
-        ascii_req[len] = 0;
+        if (!lpOptional || redirected || secure_proxy_connect)
+            data_len = 0;
+
+        ascii_req = build_ascii_request( requestString, lpOptional, data_len, &len );
         TRACE("full request -> %s\n", debugstr_a(ascii_req) );
 
         INTERNET_SendCallback(&request->hdr, request->hdr.dwContext,
@@ -4980,7 +4936,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
             continue;
         }
 
-        request->bytesWritten = dwOptionalLength;
+        request->bytesWritten = data_len;
 
         INTERNET_SendCallback(&request->hdr, request->hdr.dwContext,
                               INTERNET_STATUS_REQUEST_SENT,
@@ -4992,7 +4948,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
 
             INTERNET_SendCallback(&request->hdr, request->hdr.dwContext,
                                 INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
-
+    
             if (HTTP_GetResponseHeaders(request, &responseLen))
             {
                 http_release_netconn(request, FALSE);
@@ -5117,6 +5073,25 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
                     }
                 }
             }
+            if (secure_proxy_connect && request->status_code == HTTP_STATUS_OK)
+            {
+                int index;
+
+                res = NETCON_secure_connect(request->netconn, request->server);
+                if (res != ERROR_SUCCESS)
+                {
+                    WARN("failed to upgrade to secure proxy connection\n");
+                    http_release_netconn( request, FALSE );
+                    break;
+                }
+                index = HTTP_GetCustomHeaderIndex(request, szProxy_Authorization, 0, TRUE);
+                if (index != -1) HTTP_DeleteCustomHeader(request, index);
+                destroy_authinfo(request->proxyAuthInfo);
+                request->proxyAuthInfo = NULL;
+
+                secure_proxy_connect = FALSE;
+                loop_next = TRUE;
+            }
         }
         else
             res = ERROR_SUCCESS;
@@ -6039,7 +6014,7 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR
     /* REPLACE wins out over ADD */
     if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE)
         dwModifier &= ~HTTP_ADDHDR_FLAG_ADD;
-
+    
     if (dwModifier & HTTP_ADDHDR_FLAG_ADD)
         index = -1;
     else
index b78e44f..8eb4fa5 100644 (file)
@@ -57,6 +57,8 @@ typedef struct
     DWORD  proxyEnabled;
     LPWSTR proxy;
     LPWSTR proxyBypass;
+    LPWSTR proxyUsername;
+    LPWSTR proxyPassword;
 } proxyinfo_t;
 
 static ULONG max_conns = 2, max_1_0_conns = 4;
@@ -245,9 +247,11 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
             if (g_dwTlsErrIndex == TLS_OUT_OF_INDEXES)
                 return FALSE;
 
-#ifndef __REACTOS__
-            URLCacheContainers_CreateDefaults();
-#endif
+            if(!init_urlcache())
+            {
+                TlsFree(g_dwTlsErrIndex);
+                return FALSE;
+            }
 
             WININET_hModule = hinstDLL;
             break;
@@ -279,6 +283,15 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     return TRUE;
 }
 
+/***********************************************************************
+ *             DllInstall (WININET.@)
+ */
+HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
+{
+    FIXME("(%x %s): stub\n", bInstall, debugstr_w(cmdline));
+    return S_OK;
+}
+
 /***********************************************************************
  *           INTERNET_SaveProxySettings
  *
@@ -454,6 +467,8 @@ static void FreeProxyInfo( proxyinfo_t *lpwpi )
 {
     heap_free(lpwpi->proxy);
     heap_free(lpwpi->proxyBypass);
+    heap_free(lpwpi->proxyUsername);
+    heap_free(lpwpi->proxyPassword);
 }
 
 static proxyinfo_t *global_proxy;
@@ -469,6 +484,50 @@ static void free_global_proxy( void )
     LeaveCriticalSection( &WININET_cs );
 }
 
+static BOOL parse_proxy_url( proxyinfo_t *info, const WCHAR *url )
+{
+    static const WCHAR fmt[] = {'%','s',':','%','u',0};
+    WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH] = {0};
+    WCHAR username[INTERNET_MAX_USER_NAME_LENGTH] = {0};
+    WCHAR password[INTERNET_MAX_PASSWORD_LENGTH] = {0};
+    URL_COMPONENTSW uc;
+
+    memset( &uc, 0, sizeof(uc) );
+    uc.dwStructSize      = sizeof(uc);
+    uc.lpszHostName      = hostname;
+    uc.dwHostNameLength  = INTERNET_MAX_HOST_NAME_LENGTH;
+    uc.lpszUserName      = username;
+    uc.dwUserNameLength  = INTERNET_MAX_USER_NAME_LENGTH;
+    uc.lpszPassword      = password;
+    uc.dwPasswordLength  = INTERNET_MAX_PASSWORD_LENGTH;
+
+    if (!InternetCrackUrlW( url, 0, 0, &uc )) return FALSE;
+    if (!hostname[0])
+    {
+        if (!(info->proxy = heap_strdupW( url ))) return FALSE;
+        info->proxyUsername = NULL;
+        info->proxyPassword = NULL;
+        return TRUE;
+    }
+    if (!(info->proxy = heap_alloc( (strlenW(hostname) + 12) * sizeof(WCHAR) ))) return FALSE;
+    sprintfW( info->proxy, fmt, hostname, uc.nPort );
+
+    if (!username[0]) info->proxyUsername = NULL;
+    else if (!(info->proxyUsername = heap_strdupW( username )))
+    {
+        heap_free( info->proxy );
+        return FALSE;
+    }
+    if (!password[0]) info->proxyPassword = NULL;
+    else if (!(info->proxyPassword = heap_strdupW( password )))
+    {
+        heap_free( info->proxyUsername );
+        heap_free( info->proxy );
+        return FALSE;
+    }
+    return TRUE;
+}
+
 /***********************************************************************
  *          INTERNET_LoadProxySettings
  *
@@ -488,6 +547,8 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
     LPCSTR envproxy;
     LONG ret;
 
+    memset( lpwpi, 0, sizeof(*lpwpi) );
+
     EnterCriticalSection( &WININET_cs );
     if (global_proxy)
     {
@@ -498,7 +559,10 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
     LeaveCriticalSection( &WININET_cs );
 
     if ((ret = RegOpenKeyW( HKEY_CURRENT_USER, szInternetSettings, &key )))
+    {
+        FreeProxyInfo( lpwpi );
         return ret;
+    }
 
     len = sizeof(DWORD);
     if (RegQueryValueExW( key, szProxyEnable, NULL, &type, (BYTE *)&lpwpi->proxyEnabled, &len ) || type != REG_DWORD)
@@ -506,6 +570,7 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
         lpwpi->proxyEnabled = 0;
         if((ret = RegSetValueExW( key, szProxyEnable, 0, REG_DWORD, (BYTE *)&lpwpi->proxyEnabled, sizeof(DWORD) )))
         {
+            FreeProxyInfo( lpwpi );
             RegCloseKey( key );
             return ret;
         }
@@ -513,8 +578,6 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
 
     if (!(envproxy = getenv( "http_proxy" )) || lpwpi->proxyEnabled)
     {
-        TRACE("Proxy is enabled.\n");
-
         /* figure out how much memory the proxy setting takes */
         if (!RegQueryValueExW( key, szProxyServer, NULL, &type, NULL, &len ) && len && (type == REG_SZ))
         {
@@ -524,6 +587,7 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
             if (!(szProxy = heap_alloc(len)))
             {
                 RegCloseKey( key );
+                FreeProxyInfo( lpwpi );
                 return ERROR_OUTOFMEMORY;
             }
             RegQueryValueExW( key, szProxyServer, NULL, &type, (BYTE*)szProxy, &len );
@@ -535,17 +599,21 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
                 p += lstrlenW( szHttp );
                 lstrcpyW( szProxy, p );
             }
-            p = strchrW( szProxy, ' ' );
+            p = strchrW( szProxy, ';' );
             if (p) *p = 0;
 
+            FreeProxyInfo( lpwpi );
             lpwpi->proxy = szProxy;
+            lpwpi->proxyBypass = NULL;
 
-            TRACE("http proxy = %s\n", debugstr_w(lpwpi->proxy));
+            TRACE("http proxy (from registry) = %s\n", debugstr_w(lpwpi->proxy));
         }
         else
         {
             TRACE("No proxy server settings in registry.\n");
+            FreeProxyInfo( lpwpi );
             lpwpi->proxy = NULL;
+            lpwpi->proxyBypass = NULL;
         }
     }
     else if (envproxy)
@@ -554,18 +622,33 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
 
         len = MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, NULL, 0 );
         if (!(envproxyW = heap_alloc(len * sizeof(WCHAR))))
+        {
+            RegCloseKey( key );
             return ERROR_OUTOFMEMORY;
+        }
         MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, envproxyW, len );
 
-        lpwpi->proxyEnabled = 1;
-        lpwpi->proxy = envproxyW;
-
-        TRACE("http proxy (from environment) = %s\n", debugstr_w(lpwpi->proxy));
+        FreeProxyInfo( lpwpi );
+        if (parse_proxy_url( lpwpi, envproxyW ))
+        {
+            TRACE("http proxy (from environment) = %s\n", debugstr_w(lpwpi->proxy));
+            lpwpi->proxyEnabled = 1;
+            lpwpi->proxyBypass = NULL;
+        }
+        else
+        {
+            WARN("failed to parse http_proxy value %s\n", debugstr_w(envproxyW));
+            lpwpi->proxyEnabled = 0;
+            lpwpi->proxy = NULL;
+            lpwpi->proxyBypass = NULL;
+        }
+        heap_free( envproxyW );
     }
 
-    lpwpi->proxyBypass = NULL;
     if (lpwpi->proxyEnabled)
     {
+        TRACE("Proxy is enabled.\n");
+
         if (!(envproxy = getenv( "no_proxy" )))
         {
             /* figure out how much memory the proxy setting takes */
@@ -580,32 +663,40 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
                 }
                 RegQueryValueExW( key, szProxyOverride, NULL, &type, (BYTE*)szProxy, &len );
 
+                heap_free( lpwpi->proxyBypass );
                 lpwpi->proxyBypass = szProxy;
 
-                TRACE("http proxy bypass = %s\n", debugstr_w(lpwpi->proxyBypass));
+                TRACE("http proxy bypass (from registry) = %s\n", debugstr_w(lpwpi->proxyBypass));
             }
             else
             {
+                heap_free( lpwpi->proxyBypass );
+                lpwpi->proxyBypass = NULL;
+
                 TRACE("No proxy bypass server settings in registry.\n");
             }
         }
-        else if (envproxy)
+        else
         {
             WCHAR *envproxyW;
 
             len = MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, NULL, 0 );
             if (!(envproxyW = heap_alloc(len * sizeof(WCHAR))))
+            {
+                RegCloseKey( key );
                 return ERROR_OUTOFMEMORY;
+            }
             MultiByteToWideChar( CP_UNIXCP, 0, envproxy, -1, envproxyW, len );
 
+            heap_free( lpwpi->proxyBypass );
             lpwpi->proxyBypass = envproxyW;
 
             TRACE("http proxy bypass (from environment) = %s\n", debugstr_w(lpwpi->proxyBypass));
         }
     }
+    else TRACE("Proxy is disabled.\n");
 
     RegCloseKey( key );
-
     return ERROR_SUCCESS;
 }
 
@@ -614,56 +705,21 @@ static LONG INTERNET_LoadProxySettings( proxyinfo_t *lpwpi )
  */
 static BOOL INTERNET_ConfigureProxy( appinfo_t *lpwai )
 {
-    proxyinfo_t wpi = {0};
+    proxyinfo_t wpi;
 
     if (INTERNET_LoadProxySettings( &wpi ))
         return FALSE;
 
     if (wpi.proxyEnabled)
     {
-        WCHAR proxyurl[INTERNET_MAX_URL_LENGTH];
-        WCHAR username[INTERNET_MAX_USER_NAME_LENGTH];
-        WCHAR password[INTERNET_MAX_PASSWORD_LENGTH];
-        WCHAR hostname[INTERNET_MAX_HOST_NAME_LENGTH];
-        URL_COMPONENTSW UrlComponents;
-
-        UrlComponents.dwStructSize = sizeof UrlComponents;
-        UrlComponents.dwSchemeLength = 0;
-        UrlComponents.lpszHostName = hostname;
-        UrlComponents.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH;
-        UrlComponents.lpszUserName = username;
-        UrlComponents.dwUserNameLength = INTERNET_MAX_USER_NAME_LENGTH;
-        UrlComponents.lpszPassword = password;
-        UrlComponents.dwPasswordLength = INTERNET_MAX_PASSWORD_LENGTH;
-        UrlComponents.dwUrlPathLength = 0;
-        UrlComponents.dwExtraInfoLength = 0;
-
-        if(InternetCrackUrlW(wpi.proxy, 0, 0, &UrlComponents))
-        {
-            static const WCHAR szFormat[] = { 'h','t','t','p',':','/','/','%','s',':','%','u',0 };
-
-            if(UrlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
-                UrlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT;
-            sprintfW(proxyurl, szFormat, hostname, UrlComponents.nPort);
-
-            lpwai->accessType = INTERNET_OPEN_TYPE_PROXY;
-            lpwai->proxy = heap_strdupW(proxyurl);
-            lpwai->proxyBypass = heap_strdupW(wpi.proxyBypass);
-            if (UrlComponents.dwUserNameLength)
-            {
-                lpwai->proxyUsername = heap_strdupW(UrlComponents.lpszUserName);
-                lpwai->proxyPassword = heap_strdupW(UrlComponents.lpszPassword);
-            }
+        TRACE("http proxy = %s bypass = %s\n", debugstr_w(lpwai->proxy), debugstr_w(lpwai->proxyBypass));
 
-            TRACE("http proxy = %s bypass = %s\n", debugstr_w(lpwai->proxy), debugstr_w(lpwai->proxyBypass));
-            FreeProxyInfo(&wpi);
-            return TRUE;
-        }
-        else
-        {
-            TRACE("Failed to parse proxy: %s\n", debugstr_w(wpi.proxy));
-            lpwai->proxy = NULL;
-        }
+        lpwai->accessType    = INTERNET_OPEN_TYPE_PROXY;
+        lpwai->proxy         = wpi.proxy;
+        lpwai->proxyBypass   = wpi.proxyBypass;
+        lpwai->proxyUsername = wpi.proxyUsername;
+        lpwai->proxyPassword = wpi.proxyPassword;
+        return TRUE;
     }
 
     lpwai->accessType = INTERNET_OPEN_TYPE_DIRECT;
@@ -1198,11 +1254,10 @@ BOOL WINAPI InternetGetConnectedStateExA(LPDWORD lpdwStatus, LPSTR lpszConnectio
     rc = InternetGetConnectedStateExW(lpdwStatus,lpwszConnectionName, dwNameLen,
                                       dwReserved);
     if (rc && lpwszConnectionName)
-    {
         WideCharToMultiByte(CP_ACP,0,lpwszConnectionName,-1,lpszConnectionName,
                             dwNameLen, NULL, NULL);
-        heap_free(lpwszConnectionName);
-    }
+
+    heap_free(lpwszConnectionName);
     return rc;
 }
 
@@ -2008,7 +2063,7 @@ BOOL WINAPI InternetCanonicalizeUrlA(LPCSTR lpszUrl, LPSTR lpszBuffer,
 {
     HRESULT hr;
 
-    TRACE("(%s, %p, %p, 0x%08x) bufferlength: %d\n", debugstr_a(lpszUrl), lpszBuffer,
+    TRACE("(%s, %p, %p, 0x%08x) buffer length: %d\n", debugstr_a(lpszUrl), lpszBuffer,
         lpdwBufferLength, dwFlags, lpdwBufferLength ? *lpdwBufferLength : -1);
 
     dwFlags = convert_url_canonicalization_flags(dwFlags);
@@ -2034,7 +2089,7 @@ BOOL WINAPI InternetCanonicalizeUrlW(LPCWSTR lpszUrl, LPWSTR lpszBuffer,
 {
     HRESULT hr;
 
-    TRACE("(%s, %p, %p, 0x%08x) bufferlength: %d\n", debugstr_w(lpszUrl), lpszBuffer,
+    TRACE("(%s, %p, %p, 0x%08x) buffer length: %d\n", debugstr_w(lpszUrl), lpszBuffer,
           lpdwBufferLength, dwFlags, lpdwBufferLength ? *lpdwBufferLength : -1);
 
     dwFlags = convert_url_canonicalization_flags(dwFlags);
@@ -2302,6 +2357,34 @@ BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer,
     return res == ERROR_SUCCESS;
 }
 
+static BOOL get_proxy_autoconfig_url( char *buf, DWORD buflen )
+{
+#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+
+    CFDictionaryRef settings = CFNetworkCopySystemProxySettings();
+    const void *ref;
+    BOOL ret = FALSE;
+
+    if (!settings) return FALSE;
+
+    if (!(ref = CFDictionaryGetValue( settings, kCFNetworkProxiesProxyAutoConfigURLString )))
+    {
+        CFRelease( settings );
+        return FALSE;
+    }
+    if (CFStringGetCString( ref, buf, buflen, kCFStringEncodingASCII ))
+    {
+        TRACE( "returning %s\n", debugstr_a(buf) );
+        ret = TRUE;
+    }
+    CFRelease( settings );
+    return ret;
+#else
+    FIXME( "no support on this platform\n" );
+    return FALSE;
+#endif
+}
+
 static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL unicode)
 {
     /* FIXME: This function currently handles more options than it should. Options requiring
@@ -2385,16 +2468,20 @@ static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL u
     }
 
     case INTERNET_OPTION_PER_CONNECTION_OPTION: {
+        char url[INTERNET_MAX_URL_LENGTH + 1];
         INTERNET_PER_CONN_OPTION_LISTW *con = buffer;
         INTERNET_PER_CONN_OPTION_LISTA *conA = buffer;
         DWORD res = ERROR_SUCCESS, i;
         proxyinfo_t pi;
+        BOOL have_url;
         LONG ret;
 
         TRACE("Getting global proxy info\n");
         if((ret = INTERNET_LoadProxySettings(&pi)))
             return ret;
 
+        have_url = get_proxy_autoconfig_url(url, sizeof(url));
+
         FIXME("INTERNET_OPTION_PER_CONNECTION_OPTION stub\n");
 
         if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) {
@@ -2412,6 +2499,9 @@ static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL u
                     optionW->Value.dwValue = PROXY_TYPE_PROXY;
                 else
                     optionW->Value.dwValue = PROXY_TYPE_DIRECT;
+                if (have_url)
+                    /* native includes PROXY_TYPE_DIRECT even if PROXY_TYPE_PROXY is set */
+                    optionW->Value.dwValue |= PROXY_TYPE_DIRECT|PROXY_TYPE_AUTO_PROXY_URL;
                 break;
 
             case INTERNET_PER_CONN_PROXY_SERVER:
@@ -2429,7 +2519,18 @@ static DWORD query_global_option(DWORD option, void *buffer, DWORD *size, BOOL u
                 break;
 
             case INTERNET_PER_CONN_AUTOCONFIG_URL:
+                if (!have_url)
+                    optionW->Value.pszValue = NULL;
+                else if (unicode)
+                    optionW->Value.pszValue = heap_strdupAtoW(url);
+                else
+                    optionA->Value.pszValue = heap_strdupA(url);
+                break;
+
             case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
+                optionW->Value.dwValue = AUTO_PROXY_FLAG_ALWAYS_DETECT;
+                break;
+
             case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
             case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
             case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME:
@@ -2848,7 +2949,7 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
         unsigned int i;
         proxyinfo_t pi;
 
-        INTERNET_LoadProxySettings(&pi);
+        if (INTERNET_LoadProxySettings(&pi)) return FALSE;
 
         for (i = 0; i < con->dwOptionCount; i++) {
             INTERNET_PER_CONN_OPTIONW *option = con->pOptions + i;
@@ -3772,7 +3873,7 @@ LPSTR INTERNET_GetResponseBuffer(void)
 
 LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen)
 {
-    // ReactOS: use select instead of poll
+    /* ReactOS: use select instead of poll */
     fd_set infd;
     struct timeval tv;
     BOOL bSuccess = FALSE;
@@ -3790,7 +3891,7 @@ LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen)
     {
         if (select(0, &infd, NULL, NULL, &tv) > 0)
         {
-            if (recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0)
+            if (sock_recv(nSocket, &lpszBuffer[nRecv], 1, 0) <= 0)
             {
                 INTERNET_SetLastError(ERROR_FTP_TRANSFER_IN_PROGRESS);
                 goto lend;
index 08a0ccf..6bafbfa 100644 (file)
@@ -458,8 +458,8 @@ DWORD HTTP_Connect(appinfo_t*,LPCWSTR,
 BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
        struct sockaddr *psa, socklen_t *sa_len) DECLSPEC_HIDDEN;
 
-DWORD get_cookie(const WCHAR*,const WCHAR*,WCHAR*,DWORD*) DECLSPEC_HIDDEN;
-BOOL set_cookie(const WCHAR*,const WCHAR*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
+DWORD get_cookie_header(const WCHAR*,const WCHAR*,WCHAR**) DECLSPEC_HIDDEN;
+DWORD set_cookie(const WCHAR*,const WCHAR*,const WCHAR*,const WCHAR*,DWORD) DECLSPEC_HIDDEN;
 
 void INTERNET_SetLastError(DWORD dwError) DECLSPEC_HIDDEN;
 DWORD INTERNET_GetLastError(void) DECLSPEC_HIDDEN;
@@ -497,6 +497,7 @@ DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC
 #ifndef __REACTOS__
 int sock_get_error(int) DECLSPEC_HIDDEN;
 #else
+
 #define sock_get_error(x) WSAGetLastError()
 const char *inet_ntop(int, const void *, char *, socklen_t);
 
@@ -517,7 +518,11 @@ static inline int unix_getsockopt(int socket, int level, int option_name, void *
     return getsockopt(socket, level, option_name, option_value, option_len);
 }
 #define getsockopt unix_getsockopt
-#endif
+
+#endif /* !__REACTOS__ */
+
+int sock_send(int fd, const void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
+int sock_recv(int fd, void *msg, size_t len, int flags) DECLSPEC_HIDDEN;
 
 server_t *get_server(const WCHAR*,INTERNET_PORT,BOOL,BOOL);
 
index f58c553..5366c60 100644 (file)
@@ -267,7 +267,7 @@ static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD t
         if(result == -1)
         {
             if (sock_get_error(errno) == WSAEINPROGRESS) {
-                // ReactOS: use select instead of poll
+                /* ReactOS: use select instead of poll */
                 fd_set outfd;
                 struct timeval tv;
                 int res;
@@ -280,6 +280,7 @@ static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD t
                 if (!res)
                 {
                     closesocket(netconn->socket);
+                    netconn->socket = -1;
                     return ERROR_INTERNET_CANNOT_CONNECT;
                 }
                 else if (res > 0)
@@ -449,7 +450,29 @@ int sock_get_error( int err )
 #endif
     return err;
 }
-#endif
+#endif /* !__REACTOS__ */
+
+int sock_send(int fd, const void *msg, size_t len, int flags)
+{
+    int ret;
+    do
+    {
+        ret = send(fd, msg, len, flags);
+    }
+    while(ret == -1 && errno == EINTR);
+    return ret;
+}
+
+int sock_recv(int fd, void *msg, size_t len, int flags)
+{
+    int ret;
+    do
+    {
+        ret = recv(fd, msg, len, flags);
+    }
+    while(ret == -1 && errno == EINTR);
+    return ret;
+}
 
 static void set_socket_blocking(int socket, blocking_mode_t mode)
 {
@@ -501,7 +524,7 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode
 
             TRACE("sending %u bytes\n", out_buf.cbBuffer);
 
-            size = send(connection->socket, out_buf.pvBuffer, out_buf.cbBuffer, 0);
+            size = sock_send(connection->socket, out_buf.pvBuffer, out_buf.cbBuffer, 0);
             if(size != out_buf.cbBuffer) {
                 ERR("send failed\n");
                 status = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
@@ -540,7 +563,7 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode
             read_buf_size += 1024;
         }
 
-        size = recv(connection->socket, read_buf+in_bufs[0].cbBuffer, read_buf_size-in_bufs[0].cbBuffer, 0);
+        size = sock_recv(connection->socket, read_buf+in_bufs[0].cbBuffer, read_buf_size-in_bufs[0].cbBuffer, 0);
         if(size < 1) {
             WARN("recv error\n");
             res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
@@ -591,6 +614,8 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode
         }
     }
 
+    heap_free(read_buf);
+
     if(status != SEC_E_OK || res != ERROR_SUCCESS) {
         WARN("Failed to establish SSL connection: %08x (%u)\n", status, res);
         heap_free(connection->ssl_buf);
@@ -671,7 +696,7 @@ static BOOL send_ssl_chunk(netconn_t *conn, const void *msg, size_t size)
         return FALSE;
     }
 
-    if(send(conn->socket, conn->ssl_buf, bufs[0].cbBuffer+bufs[1].cbBuffer+bufs[2].cbBuffer, 0) < 1) {
+    if(sock_send(conn->socket, conn->ssl_buf, bufs[0].cbBuffer+bufs[1].cbBuffer+bufs[2].cbBuffer, 0) < 1) {
         WARN("send failed\n");
         return FALSE;
     }
@@ -689,7 +714,7 @@ DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
 {
     if(!connection->secure)
     {
-       *sent = send(connection->socket, msg, len, flags);
+       *sent = sock_send(connection->socket, msg, len, flags);
        if (*sent == -1)
            return sock_get_error(errno);
         return ERROR_SUCCESS;
@@ -741,7 +766,7 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking
 
     tmp_mode = buf_len ? BLOCKING_DISALLOW : mode;
     set_socket_blocking(conn->socket, tmp_mode);
-    size = recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, tmp_mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT);
+    size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, tmp_mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT);
     if(size < 0) {
         if(!buf_len) {
             if(errno == EAGAIN || errno == EWOULDBLOCK) {
@@ -782,7 +807,7 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking
             assert(buf_len < ssl_buf_size);
 
             set_socket_blocking(conn->socket, mode);
-            size = recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT);
+            size = sock_recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT);
             if(size < 1) {
                 if(size < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
                     TRACE("would block\n");
@@ -866,7 +891,7 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t
         }
 
         set_socket_blocking(connection->socket, mode);
-       *recvd = recv(connection->socket, buf, len, flags);
+       *recvd = sock_recv(connection->socket, buf, len, flags);
        return *recvd == -1 ? sock_get_error(errno) :  ERROR_SUCCESS;
     }
     else
@@ -954,7 +979,7 @@ BOOL NETCON_is_alive(netconn_t *netconn)
     ssize_t len;
     BYTE b;
 
-    len = recv(netconn->socket, &b, 1, MSG_PEEK|MSG_DONTWAIT);
+    len = sock_recv(netconn->socket, &b, 1, MSG_PEEK|MSG_DONTWAIT);
     return len == 1 || (len == -1 && errno == EWOULDBLOCK);
 #elif defined(__MINGW32__) || defined(_MSC_VER)
     ULONG mode;
@@ -965,7 +990,7 @@ BOOL NETCON_is_alive(netconn_t *netconn)
     if(!ioctlsocket(netconn->socket, FIONBIO, &mode))
         return FALSE;
 
-    len = recv(netconn->socket, &b, 1, MSG_PEEK);
+    len = sock_recv(netconn->socket, &b, 1, MSG_PEEK);
 
     mode = 0;
     if(!ioctlsocket(netconn->socket, FIONBIO, &mode))
index 0a5c844..f39aa2c 100644 (file)
@@ -179,7 +179,7 @@ typedef struct
 
 /* List of all containers available */
 static struct list UrlContainers = LIST_INIT(UrlContainers);
-// ReactOS r54992
+/* ReactOS r54992 */
 BOOL bDefaultContainersAdded = FALSE;
 
 static inline char *heap_strdupWtoUTF8(LPCWSTR str)
@@ -731,7 +731,7 @@ static void cache_containers_init(void)
     static const WCHAR UrlSuffix[] = {'C','o','n','t','e','n','t','.','I','E','5',0};
     static const WCHAR HistorySuffix[] = {'H','i','s','t','o','r','y','.','I','E','5',0};
     static const WCHAR CookieSuffix[] = {0};
-    // ReactOS r50916
+    /* ReactOS r50916 */
     static const WCHAR UserProfile[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
     static const struct
     {
@@ -747,7 +747,7 @@ static void cache_containers_init(void)
     };
     DWORD i;
 
-    // ReactOS r50916
+    /* ReactOS r50916 */
     if (GetEnvironmentVariableW(UserProfile, NULL, 0) == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND)
     {
         TRACE("Environment variable 'USERPROFILE' does not exist!\n");
@@ -823,7 +823,7 @@ static DWORD cache_containers_find(const char *url, cache_container **ret)
     if(!url)
         return ERROR_INVALID_PARAMETER;
 
-    // ReactOS r54992
+    /* ReactOS r54992 */
     if (!bDefaultContainersAdded)
         cache_containers_init();
 
@@ -853,7 +853,7 @@ static BOOL cache_containers_enum(char *search_pattern, DWORD index, cache_conta
     if (search_pattern && index > 0)
         return FALSE;
 
-    // ReactOS r54992
+    /* ReactOS r54992 */
     if (!bDefaultContainersAdded)
         cache_containers_init();
 
@@ -1477,7 +1477,7 @@ static DWORD urlcache_hash_key(LPCSTR lpszKey)
     for (i = 0; i < sizeof(key) / sizeof(key[0]); i++)
         key[i] = lookupTable[(*lpszKey + i) & 0xFF];
 
-    for (lpszKey++; *lpszKey && ((lpszKey[0] != '/') || (lpszKey[1] != 0)); lpszKey++)
+    for (lpszKey++; *lpszKey; lpszKey++)
     {
         for (i = 0; i < sizeof(key) / sizeof(key[0]); i++)
             key[i] = lookupTable[*lpszKey ^ key[i]];
diff --git a/reactos/dll/win32/wininet/wininet_main.c b/reactos/dll/win32/wininet/wininet_main.c
deleted file mode 100644 (file)
index be0517f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * WinInet
- *
- * Copyright (c) 2000 Patrik Stridvall
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "internet.h"
-
-/***********************************************************************
- *             DllInstall (WININET.@)
- */
-HRESULT WINAPI DllInstall(BOOL bInstall, LPCWSTR cmdline)
-{
-  FIXME("(%s, %s): stub\n", bInstall?"TRUE":"FALSE",
-       debugstr_w(cmdline));
-
-  return S_OK;
-}
index eb63bca..0f73c5f 100644 (file)
@@ -211,7 +211,7 @@ reactos/dll/win32/windowscodecsext    # Synced to Wine-1.7.17
 reactos/dll/win32/winemp3.acm         # Synced to Wine-1.7.17
 reactos/dll/win32/wing32              # Out of sync
 reactos/dll/win32/winhttp             # Synced to Wine-1.7.27
-reactos/dll/win32/wininet             # Synced to Wine-1.7.17
+reactos/dll/win32/wininet             # Synced to Wine-1.7.27
 reactos/dll/win32/winmm               # Forked at Wine-20050628
 reactos/dll/win32/winmm/midimap       # Forked at Wine-20050628
 reactos/dll/win32/winmm/wavemap       # Forked at Wine-20050628