ReactOS  0.4.15-dev-2534-geba00d1
cookie.c
Go to the documentation of this file.
1 #ifdef __REACTOS__
2 #include "precomp.h"
3 #else
4 /*
5  * Wininet - cookie handling stuff
6  *
7  * Copyright 2002 TransGaming Technologies Inc.
8  *
9  * David Hammerton
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include "ws2tcpip.h"
27 
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33 #include <wchar.h>
34 
35 #include "windef.h"
36 #include "winbase.h"
37 #include "wininet.h"
38 #include "lmcons.h"
39 #include "winerror.h"
40 
41 #include "wine/debug.h"
42 #include "internet.h"
43 #endif /* defined(__REACTOS__) */
44 
45 #define RESPONSE_TIMEOUT 30 /* FROM internet.c */
46 
47 
49 
50 /* FIXME
51  * Cookies could use A LOT OF MEMORY. We need some kind of memory management here!
52  */
53 
54 struct _cookie_domain_t;
55 struct _cookie_container_t;
56 
57 typedef struct _cookie_t {
58  struct list entry;
59 
61 
67 } cookie_t;
68 
69 typedef struct _cookie_container_t {
70  struct list entry;
71 
75 
76  struct list cookie_list;
78 
79 typedef struct _cookie_domain_t {
80  struct list entry;
81 
83  unsigned subdomain_len;
84 
87 
88  /* List of stored paths sorted by length of the path. */
89  struct list path_list;
91 
94 {
95  0, 0, &cookie_cs,
97  0, 0, { (DWORD_PTR)(__FILE__ ": cookie_cs") }
98 };
99 static CRITICAL_SECTION cookie_cs = { &cookie_cs_debug, -1, 0, 0, 0, 0 };
101 
103 {
104  const WCHAR *ptr = domain.str + domain.len, *ptr_end, *subdomain_ptr;
105  cookie_domain_t *iter, *current_domain, *prev_domain = NULL;
106  struct list *current_list = &domain_list;
107 
108  while(1) {
109  for(ptr_end = ptr--; ptr > domain.str && *ptr != '.'; ptr--);
110  subdomain_ptr = *ptr == '.' ? ptr+1 : ptr;
111 
112  current_domain = NULL;
113  LIST_FOR_EACH_ENTRY(iter, current_list, cookie_domain_t, entry) {
114  if(ptr_end-subdomain_ptr == iter->subdomain_len
115  && !memcmp(subdomain_ptr, iter->domain, iter->subdomain_len*sizeof(WCHAR))) {
116  current_domain = iter;
117  break;
118  }
119  }
120 
121  if(!current_domain) {
122  if(!create)
123  return prev_domain;
124 
125  current_domain = heap_alloc(sizeof(*current_domain));
126  if(!current_domain)
127  return NULL;
128 
129  current_domain->domain = heap_strndupW(subdomain_ptr, domain.str + domain.len - subdomain_ptr);
130  if(!current_domain->domain) {
131  heap_free(current_domain);
132  return NULL;
133  }
134 
135  current_domain->subdomain_len = ptr_end-subdomain_ptr;
136 
137  current_domain->parent = prev_domain;
138  list_init(&current_domain->path_list);
139  list_init(&current_domain->subdomain_list);
140 
141  list_add_tail(current_list, &current_domain->entry);
142  }
143 
144  if(ptr == domain.str)
145  return current_domain;
146 
147  prev_domain = current_domain;
148  current_list = &current_domain->subdomain_list;
149  }
150 }
151 
153 {
154  WCHAR *p, *url;
155  DWORD len, user_len, i;
156 
157  static const WCHAR cookie_prefix[] = {'C','o','o','k','i','e',':'};
158 
159  user_len = 0;
161  return NULL;
162 
163  /* user_len already accounts for terminating NULL */
164  len = ARRAY_SIZE(cookie_prefix) + user_len + 1 /* @ */ + domain.len + path.len;
165  url = heap_alloc(len * sizeof(WCHAR));
166  if(!url)
167  return NULL;
168 
169  memcpy(url, cookie_prefix, sizeof(cookie_prefix));
170  p = url + ARRAY_SIZE(cookie_prefix);
171 
172  if(!GetUserNameW(p, &user_len)) {
173  heap_free(url);
174  return NULL;
175  }
176  p += user_len;
177 
178  *(p - 1) = '@';
179 
180  memcpy(p, domain.str, domain.len*sizeof(WCHAR));
181  p += domain.len;
182 
183  for(i=0; i < path.len; i++)
184  p[i] = towlower(path.str[i]);
185  p[path.len] = 0;
186 
187  ret_path->str = p;
188  ret_path->len = path.len;
189  return url;
190 }
191 
193 {
194  cookie_domain_t *cookie_domain;
195  cookie_container_t *cookie_container, *iter;
196 
197  cookie_domain = get_cookie_domain(domain, create);
198  if(!cookie_domain)
199  return NULL;
200 
201  LIST_FOR_EACH_ENTRY(cookie_container, &cookie_domain->path_list, cookie_container_t, entry) {
202  if(cookie_container->path.len < path.len)
203  break;
204 
205  if(path.len == cookie_container->path.len && !wcsnicmp(cookie_container->path.str, path.str, path.len))
206  return cookie_container;
207  }
208 
209  if(!create)
210  return NULL;
211 
212  cookie_container = heap_alloc(sizeof(*cookie_container));
213  if(!cookie_container)
214  return NULL;
215 
216  cookie_container->cookie_url = create_cookie_url(substrz(cookie_domain->domain), path, &cookie_container->path);
217  if(!cookie_container->cookie_url) {
218  heap_free(cookie_container);
219  return NULL;
220  }
221 
222  cookie_container->domain = cookie_domain;
223  list_init(&cookie_container->cookie_list);
224 
225  LIST_FOR_EACH_ENTRY(iter, &cookie_domain->path_list, cookie_container_t, entry) {
226  if(iter->path.len <= path.len) {
227  list_add_before(&iter->entry, &cookie_container->entry);
228  return cookie_container;
229  }
230  }
231 
232  list_add_tail(&cookie_domain->path_list, &cookie_container->entry);
233  return cookie_container;
234 }
235 
237 {
239 
241  heap_free(cookie->data);
242  heap_free(cookie);
243 }
244 
246 {
247  cookie_t *new_cookie;
248 
249  new_cookie = heap_alloc_zero(sizeof(*new_cookie));
250  if(!new_cookie)
251  return NULL;
252 
253  new_cookie->expiry = expiry;
254  new_cookie->create = create_time;
255  new_cookie->flags = flags;
256  list_init(&new_cookie->entry);
257 
258  if(name.str && !(new_cookie->name = heap_strndupW(name.str, name.len))) {
259  delete_cookie(new_cookie);
260  return NULL;
261  }
262 
263  if(data.str && !(new_cookie->data = heap_strndupW(data.str, data.len))) {
264  delete_cookie(new_cookie);
265  return NULL;
266  }
267 
268  return new_cookie;
269 }
270 
272 {
273  cookie_t *iter;
274 
275  LIST_FOR_EACH_ENTRY(iter, &container->cookie_list, cookie_t, entry) {
276  if(lstrlenW(iter->name) == name.len && !wcsnicmp(iter->name, name.str, name.len))
277  return iter;
278  }
279 
280  return NULL;
281 }
282 
284 {
285  TRACE("Adding %s=%s to %s\n", debugstr_w(new_cookie->name), debugstr_w(new_cookie->data),
286  debugstr_w(container->cookie_url));
287 
288  list_add_tail(&container->cookie_list, &new_cookie->entry);
289  new_cookie->container = container;
290 }
291 
293 {
294  cookie_t *old_cookie;
295 
296  old_cookie = find_cookie(container, substrz(new_cookie->name));
297  if(old_cookie)
298  delete_cookie(old_cookie);
299 
300  add_cookie(container, new_cookie);
301 }
302 
304 {
305  return path.len >= container->path.len && !wcsnicmp(container->path.str, path.str, container->path.len);
306 }
307 
309 {
311  cookie_container_t *cookie_container;
312  cookie_t *new_cookie;
313  HANDLE cookie;
314  char *str = NULL, *pbeg, *pend;
315  DWORD size, flags;
316  WCHAR *name, *data;
317  FILETIME expiry, create, time;
318 
319  cookie_container = get_cookie_container(domain, path, TRUE);
320  if(!cookie_container)
321  return FALSE;
322 
323  size = 0;
324  RetrieveUrlCacheEntryStreamW(cookie_container->cookie_url, NULL, &size, FALSE, 0);
326  return TRUE;
327  info = heap_alloc(size);
328  if(!info)
329  return FALSE;
330  cookie = RetrieveUrlCacheEntryStreamW(cookie_container->cookie_url, info, &size, FALSE, 0);
331  size = info->dwSizeLow;
332  heap_free(info);
333  if(!cookie)
334  return FALSE;
335 
336  if(!(str = heap_alloc(size+1)) || !ReadUrlCacheEntryStream(cookie, 0, str, &size, 0)) {
338  heap_free(str);
339  return FALSE;
340  }
341  str[size] = 0;
343 
345  for(pbeg=str; pbeg && *pbeg; name=data=NULL) {
346  pend = strchr(pbeg, '\n');
347  if(!pend)
348  break;
349  *pend = 0;
350  name = heap_strdupAtoW(pbeg);
351 
352  pbeg = pend+1;
353  pend = strchr(pbeg, '\n');
354  if(!pend)
355  break;
356  *pend = 0;
357  data = heap_strdupAtoW(pbeg);
358 
359  pbeg = strchr(pend+1, '\n');
360  if(!pbeg)
361  break;
362  sscanf(pbeg, "%u %u %u %u %u", &flags, &expiry.dwLowDateTime, &expiry.dwHighDateTime,
363  &create.dwLowDateTime, &create.dwHighDateTime);
364 
365  /* skip "*\n" */
366  pbeg = strchr(pbeg, '*');
367  if(pbeg) {
368  pbeg++;
369  if(*pbeg)
370  pbeg++;
371  }
372 
373  if(!name || !data)
374  break;
375 
376  if(CompareFileTime(&time, &expiry) <= 0) {
377  new_cookie = alloc_cookie(substr(NULL, 0), substr(NULL, 0), expiry, create, flags);
378  if(!new_cookie)
379  break;
380 
381  new_cookie->name = name;
382  new_cookie->data = data;
383 
384  replace_cookie(cookie_container, new_cookie);
385  }else {
386  heap_free(name);
387  heap_free(data);
388  }
389  }
390  heap_free(str);
391  heap_free(name);
392  heap_free(data);
393 
394  return TRUE;
395 }
396 
398 {
399  WCHAR cookie_file[MAX_PATH];
400  HANDLE cookie_handle;
401  cookie_t *cookie_container = NULL, *cookie_iter;
402  BOOL do_save = FALSE;
403  char buf[64], *dyn_buf;
404  FILETIME time;
405  DWORD bytes_written;
406  size_t len;
407 
408  /* check if there's anything to save */
410  LIST_FOR_EACH_ENTRY_SAFE(cookie_container, cookie_iter, &container->cookie_list, cookie_t, entry)
411  {
412  if((cookie_container->expiry.dwLowDateTime || cookie_container->expiry.dwHighDateTime)
413  && CompareFileTime(&time, &cookie_container->expiry) > 0) {
414  delete_cookie(cookie_container);
415  continue;
416  }
417 
418  if(!(cookie_container->flags & INTERNET_COOKIE_IS_SESSION)) {
419  do_save = TRUE;
420  break;
421  }
422  }
423 
424  if(!do_save) {
425  DeleteUrlCacheEntryW(container->cookie_url);
426  return TRUE;
427  }
428 
429  if(!CreateUrlCacheEntryW(container->cookie_url, 0, L"txt", cookie_file, 0))
430  return FALSE;
431 
432  cookie_handle = CreateFileW(cookie_file, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
433  if(cookie_handle == INVALID_HANDLE_VALUE) {
434  DeleteFileW(cookie_file);
435  return FALSE;
436  }
437 
438  LIST_FOR_EACH_ENTRY(cookie_container, &container->cookie_list, cookie_t, entry)
439  {
440  if(cookie_container->flags & INTERNET_COOKIE_IS_SESSION)
441  continue;
442 
443  dyn_buf = heap_strdupWtoA(cookie_container->name);
444  if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
445  heap_free(dyn_buf);
446  do_save = FALSE;
447  break;
448  }
449  heap_free(dyn_buf);
450  if(!WriteFile(cookie_handle, "\n", 1, &bytes_written, NULL)) {
451  do_save = FALSE;
452  break;
453  }
454 
455  dyn_buf = heap_strdupWtoA(cookie_container->data);
456  if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
457  heap_free(dyn_buf);
458  do_save = FALSE;
459  break;
460  }
461  heap_free(dyn_buf);
462  if(!WriteFile(cookie_handle, "\n", 1, &bytes_written, NULL)) {
463  do_save = FALSE;
464  break;
465  }
466 
467  dyn_buf = heap_strdupWtoA(container->domain->domain);
468  if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
469  heap_free(dyn_buf);
470  do_save = FALSE;
471  break;
472  }
473  heap_free(dyn_buf);
474 
475  len = WideCharToMultiByte(CP_ACP, 0, container->path.str, container->path.len, NULL, 0, NULL, NULL);
476  dyn_buf = heap_alloc(len+1);
477  if(dyn_buf) {
478  WideCharToMultiByte(CP_ACP, 0, container->path.str, container->path.len, dyn_buf, len, NULL, NULL);
479  dyn_buf[len] = 0;
480  }
481  if(!dyn_buf || !WriteFile(cookie_handle, dyn_buf, strlen(dyn_buf), &bytes_written, NULL)) {
482  heap_free(dyn_buf);
483  do_save = FALSE;
484  break;
485  }
486  heap_free(dyn_buf);
487 
488  sprintf(buf, "\n%u\n%u\n%u\n%u\n%u\n*\n", cookie_container->flags,
489  cookie_container->expiry.dwLowDateTime, cookie_container->expiry.dwHighDateTime,
490  cookie_container->create.dwLowDateTime, cookie_container->create.dwHighDateTime);
491  if(!WriteFile(cookie_handle, buf, strlen(buf), &bytes_written, NULL)) {
492  do_save = FALSE;
493  break;
494  }
495  }
496 
497  CloseHandle(cookie_handle);
498  if(!do_save) {
499  ERR("error saving cookie file\n");
500  DeleteFileW(cookie_file);
501  return FALSE;
502  }
503 
504  memset(&time, 0, sizeof(time));
505  return CommitUrlCacheEntryW(container->cookie_url, cookie_file, time, time, 0, NULL, 0, L"txt", 0);
506 }
507 
509 {
510  URL_COMPONENTSW comp = { sizeof(comp) };
511 
512  comp.dwHostNameLength = 1;
513  comp.dwUrlPathLength = 1;
514 
515  if(!InternetCrackUrlW(url, 0, 0, &comp) || !comp.dwHostNameLength)
516  return FALSE;
517 
518  /* discard the webpage off the end of the path */
519  while(comp.dwUrlPathLength && comp.lpszUrlPath[comp.dwUrlPathLength-1] != '/')
520  comp.dwUrlPathLength--;
521 
522  *host = substr(comp.lpszHostName, comp.dwHostNameLength);
523  *path = comp.dwUrlPathLength ? substr(comp.lpszUrlPath, comp.dwUrlPathLength) : substr(L"/", 1);
524  return TRUE;
525 }
526 
527 typedef struct {
529  unsigned cnt;
530  unsigned size;
531 
532  unsigned string_len;
533 } cookie_set_t;
534 
536 {
537  const WCHAR *p;
540  FILETIME tm;
541 
543 
544  p = host.str + host.len;
545  while(p > host.str && p[-1] != '.') p--;
546  while(p != host.str) {
547  p--;
548  while(p > host.str && p[-1] != '.') p--;
549  if(p == host.str) break;
550 
551  load_persistent_cookie(substr(p, host.str+host.len-p), substr(L"/", 1));
552  }
553 
554  p = path.str + path.len;
555  do {
557 
558  p--;
559  while(p > path.str && p[-1] != '/') p--;
560  }while(p != path.str);
561 
563  if(!domain) {
564  TRACE("Unknown host %s\n", debugstr_wn(host.str, host.len));
565  return ERROR_NO_MORE_ITEMS;
566  }
567 
568  for(domain = get_cookie_domain(host, FALSE); domain; domain = domain->parent) {
570  struct list *cursor, *cursor2;
571 
573  continue;
574 
575  LIST_FOR_EACH_SAFE(cursor, cursor2, &container->cookie_list) {
576  cookie_t *cookie_iter = LIST_ENTRY(cursor, cookie_t, entry);
577 
578  /* check for expiry */
579  if((cookie_iter->expiry.dwLowDateTime != 0 || cookie_iter->expiry.dwHighDateTime != 0)
580  && CompareFileTime(&tm, &cookie_iter->expiry) > 0) {
581  TRACE("Found expired cookie. deleting\n");
582  delete_cookie(cookie_iter);
583  continue;
584  }
585 
586  if((cookie_iter->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY))
587  continue;
588 
589  if(!res->size) {
590  res->cookies = heap_alloc(4*sizeof(*res->cookies));
591  if(!res->cookies)
592  continue;
593  res->size = 4;
594  }else if(res->cnt == res->size) {
595  cookie_t **new_cookies = heap_realloc(res->cookies, res->size*2*sizeof(*res->cookies));
596  if(!new_cookies)
597  continue;
598  res->cookies = new_cookies;
599  res->size *= 2;
600  }
601 
602  TRACE("%s = %s domain %s path %s\n", debugstr_w(cookie_iter->name), debugstr_w(cookie_iter->data),
603  debugstr_w(domain->domain), debugstr_wn(container->path.str, container->path.len));
604 
605  if(res->cnt)
606  res->string_len += 2; /* '; ' */
607  res->cookies[res->cnt++] = cookie_iter;
608 
609  res->string_len += lstrlenW(cookie_iter->name);
610  if(*cookie_iter->data)
611  res->string_len += 1 /* = */ + lstrlenW(cookie_iter->data);
612  }
613  }
614  }
615 
616  return ERROR_SUCCESS;
617 }
618 
619 static void cookie_set_to_string(const cookie_set_t *cookie_set, WCHAR *str)
620 {
621  WCHAR *ptr = str;
622  unsigned i, len;
623 
624  for(i=0; i<cookie_set->cnt; i++) {
625  if(i) {
626  *ptr++ = ';';
627  *ptr++ = ' ';
628  }
629 
630  len = lstrlenW(cookie_set->cookies[i]->name);
631  memcpy(ptr, cookie_set->cookies[i]->name, len*sizeof(WCHAR));
632  ptr += len;
633 
634  if(*cookie_set->cookies[i]->data) {
635  *ptr++ = '=';
636  len = lstrlenW(cookie_set->cookies[i]->data);
637  memcpy(ptr, cookie_set->cookies[i]->data, len*sizeof(WCHAR));
638  ptr += len;
639  }
640  }
641 
642  assert(ptr-str == cookie_set->string_len);
643  TRACE("%s\n", debugstr_wn(str, ptr-str));
644 }
645 
647 {
648  cookie_set_t cookie_set = {0};
649  DWORD res;
650 
651  static const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' '};
652 
654 
656  if(res != ERROR_SUCCESS) {
658  return res;
659  }
660 
661  if(cookie_set.cnt) {
662  WCHAR *header, *ptr;
663 
664  ptr = header = heap_alloc(sizeof(cookieW) + (cookie_set.string_len + 3 /* crlf0 */) * sizeof(WCHAR));
665  if(header) {
666  memcpy(ptr, cookieW, sizeof(cookieW));
667  ptr += ARRAY_SIZE(cookieW);
668 
669  cookie_set_to_string(&cookie_set, ptr);
670  heap_free(cookie_set.cookies);
671  ptr += cookie_set.string_len;
672 
673  *ptr++ = '\r';
674  *ptr++ = '\n';
675  *ptr++ = 0;
676 
677  *ret = header;
678  }else {
680  }
681  }else {
682  *ret = NULL;
683  }
684 
686  return res;
687 }
688 
689 static void free_cookie_domain_list(struct list *list)
690 {
693 
694  while(!list_empty(list)) {
696 
697  free_cookie_domain_list(&domain->subdomain_list);
698 
699  while(!list_empty(&domain->path_list)) {
701 
702  while(!list_empty(&container->cookie_list))
704 
705  heap_free(container->cookie_url);
708  }
709 
710  heap_free(domain->domain);
712  heap_free(domain);
713  }
714 }
715 
716 /***********************************************************************
717  * InternetGetCookieExW (WININET.@)
718  *
719  * Retrieve cookie from the specified url
720  *
721  * It should be noted that on windows the lpszCookieName parameter is "not implemented".
722  * So it won't be implemented here.
723  *
724  * RETURNS
725  * TRUE on success
726  * FALSE on failure
727  *
728  */
730  LPWSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
731 {
732  cookie_set_t cookie_set = {0};
733  substr_t host, path;
734  DWORD res;
735  BOOL ret;
736 
737  TRACE("(%s, %s, %p, %p, %x, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName), lpCookieData, lpdwSize, flags, reserved);
738 
740  FIXME("flags 0x%08x not supported\n", flags);
741 
742  if (!lpszUrl)
743  {
745  return FALSE;
746  }
747 
748  ret = cookie_parse_url(lpszUrl, &host, &path);
749  if (!ret) {
751  return FALSE;
752  }
753 
755 
756  res = get_cookie(host, path, flags, &cookie_set);
757  if(res != ERROR_SUCCESS) {
759  SetLastError(res);
760  return FALSE;
761  }
762 
763  if(cookie_set.cnt) {
764  if(!lpCookieData || cookie_set.string_len+1 > *lpdwSize) {
765  *lpdwSize = (cookie_set.string_len + 1) * sizeof(WCHAR);
766  TRACE("returning %u\n", *lpdwSize);
767  if(lpCookieData) {
769  ret = FALSE;
770  }
771  }else {
772  *lpdwSize = cookie_set.string_len + 1;
773  cookie_set_to_string(&cookie_set, lpCookieData);
774  lpCookieData[cookie_set.string_len] = 0;
775  }
776  }else {
777  TRACE("no cookies found for %s\n", debugstr_wn(host.str, host.len));
779  ret = FALSE;
780  }
781 
782  heap_free(cookie_set.cookies);
784  return ret;
785 }
786 
787 /***********************************************************************
788  * InternetGetCookieW (WININET.@)
789  *
790  * Retrieve cookie for the specified URL.
791  */
793 {
794  TRACE("(%s, %s, %s, %p)\n", debugstr_w(url), debugstr_w(name), debugstr_w(data), size);
795 
796  return InternetGetCookieExW(url, name, data, size, 0, NULL);
797 }
798 
799 /***********************************************************************
800  * InternetGetCookieExA (WININET.@)
801  *
802  * Retrieve cookie from the specified url
803  *
804  * RETURNS
805  * TRUE on success
806  * FALSE on failure
807  *
808  */
809 BOOL WINAPI InternetGetCookieExA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
810  LPSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
811 {
812  WCHAR *url, *name;
813  DWORD len, size = 0;
814  BOOL r;
815 
816  TRACE("(%s %s %p %p(%u) %x %p)\n", debugstr_a(lpszUrl), debugstr_a(lpszCookieName),
817  lpCookieData, lpdwSize, lpdwSize ? *lpdwSize : 0, flags, reserved);
818 
819  url = heap_strdupAtoW(lpszUrl);
820  name = heap_strdupAtoW(lpszCookieName);
821 
823  if( r )
824  {
825  WCHAR *szCookieData;
826 
827  szCookieData = heap_alloc(len * sizeof(WCHAR));
828  if( !szCookieData )
829  {
830  r = FALSE;
831  }
832  else
833  {
834  r = InternetGetCookieExW( url, name, szCookieData, &len, flags, reserved );
835 
836  if(r) {
837  size = WideCharToMultiByte( CP_ACP, 0, szCookieData, len, NULL, 0, NULL, NULL);
838  if(lpCookieData) {
839  if(*lpdwSize >= size) {
840  WideCharToMultiByte( CP_ACP, 0, szCookieData, len, lpCookieData, *lpdwSize, NULL, NULL);
841  }else {
843  r = FALSE;
844  }
845  }
846  }
847 
848  heap_free( szCookieData );
849  }
850  }
851  *lpdwSize = size;
852  heap_free( name );
853  heap_free( url );
854  return r;
855 }
856 
857 /***********************************************************************
858  * InternetGetCookieA (WININET.@)
859  *
860  * See InternetGetCookieW.
861  */
862 BOOL WINAPI InternetGetCookieA(const char *url, const char *name, char *data, DWORD *size)
863 {
864  TRACE("(%s, %s, %p, %p)\n", debugstr_a(url), debugstr_a(name), data, size);
865 
866  return InternetGetCookieExA(url, name, data, size, 0, NULL);
867 }
868 
870 {
871  const WCHAR *ptr;
872 
873  if(!domain.len || *domain.str == '.' || !full_domain.len || *full_domain.str == '.') {
875  return FALSE;
876  }
877 
878  if(domain.len > full_domain.len || !wmemchr(domain.str, '.', domain.len) || !wmemchr(full_domain.str, '.', full_domain.len))
879  return FALSE;
880 
881  ptr = full_domain.str + full_domain.len - domain.len;
882  if (wcsnicmp(domain.str, ptr, domain.len) || (full_domain.len > domain.len && ptr[-1] != '.')) {
884  return FALSE;
885  }
886 
887  return TRUE;
888 }
889 
890 /***********************************************************************
891  * IsDomainLegalCookieDomainW (WININET.@)
892  */
894 {
895  FIXME("(%s, %s) semi-stub\n", debugstr_w(domain), debugstr_w(full_domain));
896 
897  if (!domain || !full_domain) {
899  return FALSE;
900  }
901 
902  return is_domain_legal_for_cookie(substrz(domain), substrz(full_domain));
903 }
904 
905 static void substr_skip(substr_t *str, size_t len)
906 {
907  assert(str->len >= len);
908  str->str += len;
909  str->len -= len;
910 }
911 
913 {
915  cookie_t *thisCookie;
916  substr_t value;
917  const WCHAR *end_ptr;
918  FILETIME expiry, create;
919  BOOL expired = FALSE, update_persistent = FALSE;
920  DWORD cookie_flags = 0, len;
921 
922  TRACE("%s %s %s=%s %x\n", debugstr_wn(domain.str, domain.len), debugstr_wn(path.str, path.len),
923  debugstr_wn(name.str, name.len), debugstr_wn(data.str, data.len), flags);
924 
925  memset(&expiry,0,sizeof(expiry));
927 
928  /* lots of information can be parsed out of the cookie value */
929 
930  if(!(end_ptr = wmemchr(data.str, ';', data.len)))
931  end_ptr = data.str + data.len;
932  value = substr(data.str, end_ptr-data.str);
933  data.str += value.len;
934  data.len -= value.len;
935 
936  for(;;) {
937  static const WCHAR szDomain[] = {'d','o','m','a','i','n','='};
938  static const WCHAR szPath[] = {'p','a','t','h','='};
939  static const WCHAR szExpires[] = {'e','x','p','i','r','e','s','='};
940  static const WCHAR szSecure[] = {'s','e','c','u','r','e'};
941  static const WCHAR szHttpOnly[] = {'h','t','t','p','o','n','l','y'};
942  static const WCHAR szVersion[] = {'v','e','r','s','i','o','n','='};
943  static const WCHAR max_ageW[] = {'m','a','x','-','a','g','e','='};
944 
945  /* Skip ';' */
946  if(data.len)
947  substr_skip(&data, 1);
948 
949  while(data.len && *data.str == ' ')
950  substr_skip(&data, 1);
951 
952  if(!data.len)
953  break;
954 
955  if(!(end_ptr = wmemchr(data.str, ';', data.len)))
956  end_ptr = data.str + data.len;
957 
958  if(data.len >= (len = ARRAY_SIZE(szDomain)) && !wcsnicmp(data.str, szDomain, len)) {
959  substr_skip(&data, len);
960 
961  if(data.len && *data.str == '.')
962  substr_skip(&data, 1);
963 
964  if(!is_domain_legal_for_cookie(substr(data.str, end_ptr-data.str), domain))
965  return COOKIE_STATE_UNKNOWN;
966 
967  domain = substr(data.str, end_ptr-data.str);
968  TRACE("Parsing new domain %s\n", debugstr_wn(domain.str, domain.len));
969  }else if(data.len >= (len = ARRAY_SIZE(szPath)) && !wcsnicmp(data.str, szPath, len)) {
970  substr_skip(&data, len);
971  path = substr(data.str, end_ptr - data.str);
972  TRACE("Parsing new path %s\n", debugstr_wn(path.str, path.len));
973  }else if(data.len >= (len = ARRAY_SIZE(szExpires)) && !wcsnicmp(data.str, szExpires, len)) {
974  SYSTEMTIME st;
975  WCHAR buf[128];
976 
977  substr_skip(&data, len);
978 
979  if(end_ptr > data.str && (end_ptr - data.str < ARRAY_SIZE(buf) - 1)) {
980  memcpy(buf, data.str, data.len*sizeof(WCHAR));
981  buf[data.len] = 0;
982 
983  if (InternetTimeToSystemTimeW(data.str, &st, 0)) {
984  SystemTimeToFileTime(&st, &expiry);
985 
986  if (CompareFileTime(&create,&expiry) > 0) {
987  TRACE("Cookie already expired.\n");
988  expired = TRUE;
989  }
990  }
991  }
992  }else if(data.len >= (len = ARRAY_SIZE(szSecure)) && !wcsnicmp(data.str, szSecure, len)) {
993  substr_skip(&data, len);
994  FIXME("secure not handled\n");
995  }else if(data.len >= (len = ARRAY_SIZE(szHttpOnly)) && !wcsnicmp(data.str, szHttpOnly, len)) {
996  substr_skip(&data, len);
997 
999  WARN("HTTP only cookie added without INTERNET_COOKIE_HTTPONLY flag\n");
1001  return COOKIE_STATE_REJECT;
1002  }
1003 
1004  cookie_flags |= INTERNET_COOKIE_HTTPONLY;
1005  }else if(data.len >= (len = ARRAY_SIZE(szVersion)) && !wcsnicmp(data.str, szVersion, len)) {
1006  substr_skip(&data, len);
1007 
1008  FIXME("version not handled (%s)\n",debugstr_wn(data.str, data.len));
1009  }else if(data.len >= (len = ARRAY_SIZE(max_ageW)) && !wcsnicmp(data.str, max_ageW, len)) {
1010  /* Native doesn't support Max-Age attribute. */
1011  WARN("Max-Age ignored\n");
1012  }else if(data.len) {
1013  FIXME("Unknown additional option %s\n", debugstr_wn(data.str, data.len));
1014  }
1015 
1016  substr_skip(&data, end_ptr - data.str);
1017  }
1018 
1020 
1022 
1023  container = get_cookie_container(domain, path, !expired);
1024  if(!container) {
1026  return COOKIE_STATE_ACCEPT;
1027  }
1028 
1029  if(!expiry.dwLowDateTime && !expiry.dwHighDateTime)
1030  cookie_flags |= INTERNET_COOKIE_IS_SESSION;
1031  else
1032  update_persistent = TRUE;
1033 
1034  if ((thisCookie = find_cookie(container, name))) {
1035  if ((thisCookie->flags & INTERNET_COOKIE_HTTPONLY) && !(flags & INTERNET_COOKIE_HTTPONLY)) {
1036  WARN("An attempt to override httponly cookie\n");
1039  return COOKIE_STATE_REJECT;
1040  }
1041 
1042  if (!(thisCookie->flags & INTERNET_COOKIE_IS_SESSION))
1043  update_persistent = TRUE;
1044  delete_cookie(thisCookie);
1045  }
1046 
1047  TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_wn(name.str, name.len),
1048  debugstr_wn(value.str, value.len), debugstr_w(container->domain->domain),
1049  debugstr_wn(container->path.str, container->path.len));
1050 
1051  if (!expired) {
1052  cookie_t *new_cookie;
1053 
1054  new_cookie = alloc_cookie(name, value, expiry, create, cookie_flags);
1055  if(!new_cookie) {
1057  return COOKIE_STATE_UNKNOWN;
1058  }
1059 
1060  add_cookie(container, new_cookie);
1061  }
1062 
1063  if (!update_persistent || save_persistent_cookie(container))
1064  {
1066  return COOKIE_STATE_ACCEPT;
1067  }
1069  return COOKIE_STATE_UNKNOWN;
1070 }
1071 
1072 /***********************************************************************
1073  * InternetSetCookieExW (WININET.@)
1074  *
1075  * Sets cookie for the specified url
1076  */
1078  LPCWSTR lpCookieData, DWORD flags, DWORD_PTR reserved)
1079 {
1080  substr_t host, path, name, data;
1081  BOOL ret;
1082 
1083  TRACE("(%s, %s, %s, %x, %lx)\n", debugstr_w(lpszUrl), debugstr_w(lpszCookieName),
1084  debugstr_w(lpCookieData), flags, reserved);
1085 
1087  FIXME("flags %x not supported\n", flags);
1088 
1089  if (!lpszUrl || !lpCookieData)
1090  {
1092  return COOKIE_STATE_UNKNOWN;
1093  }
1094 
1095  ret = cookie_parse_url(lpszUrl, &host, &path);
1096  if (!ret || !host.len) return COOKIE_STATE_UNKNOWN;
1097 
1098  if (!lpszCookieName) {
1099  const WCHAR *ptr;
1100 
1101  /* some apps (or is it us??) try to add a cookie with no cookie name, but
1102  * the cookie data in the form of name[=data].
1103  */
1104  if (!(ptr = wcschr(lpCookieData, '=')))
1105  ptr = lpCookieData + lstrlenW(lpCookieData);
1106 
1107  name = substr(lpCookieData, ptr - lpCookieData);
1108  data = substrz(*ptr == '=' ? ptr+1 : ptr);
1109  }else {
1110  name = substrz(lpszCookieName);
1111  data = substrz(lpCookieData);
1112  }
1113 
1114  return set_cookie(host, path, name, data, flags);
1115 }
1116 
1117 /***********************************************************************
1118  * InternetSetCookieW (WININET.@)
1119  *
1120  * Sets a cookie for the specified URL.
1121  */
1123 {
1124  TRACE("(%s, %s, %s)\n", debugstr_w(url), debugstr_w(name), debugstr_w(data));
1125 
1127 }
1128 
1129 /***********************************************************************
1130  * InternetSetCookieA (WININET.@)
1131  *
1132  * Sets cookie for the specified url
1133  *
1134  * RETURNS
1135  * TRUE on success
1136  * FALSE on failure
1137  *
1138  */
1139 BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
1140  LPCSTR lpCookieData)
1141 {
1142  LPWSTR data, url, name;
1143  BOOL r;
1144 
1145  TRACE("(%s,%s,%s)\n", debugstr_a(lpszUrl),
1146  debugstr_a(lpszCookieName), debugstr_a(lpCookieData));
1147 
1148  url = heap_strdupAtoW(lpszUrl);
1149  name = heap_strdupAtoW(lpszCookieName);
1150  data = heap_strdupAtoW(lpCookieData);
1151 
1152  r = InternetSetCookieW( url, name, data );
1153 
1154  heap_free( data );
1155  heap_free( name );
1156  heap_free( url );
1157  return r;
1158 }
1159 
1160 /***********************************************************************
1161  * InternetSetCookieExA (WININET.@)
1162  *
1163  * See InternetSetCookieExW.
1164  */
1165 DWORD WINAPI InternetSetCookieExA( LPCSTR lpszURL, LPCSTR lpszCookieName, LPCSTR lpszCookieData,
1167 {
1168  WCHAR *data, *url, *name;
1169  DWORD r;
1170 
1171  TRACE("(%s, %s, %s, %x, %lx)\n", debugstr_a(lpszURL), debugstr_a(lpszCookieName),
1172  debugstr_a(lpszCookieData), dwFlags, dwReserved);
1173 
1174  url = heap_strdupAtoW(lpszURL);
1175  name = heap_strdupAtoW(lpszCookieName);
1176  data = heap_strdupAtoW(lpszCookieData);
1177 
1179 
1180  heap_free( data );
1181  heap_free( name );
1182  heap_free( url );
1183  return r;
1184 }
1185 
1186 /***********************************************************************
1187  * InternetClearAllPerSiteCookieDecisions (WININET.@)
1188  *
1189  * Clears all per-site decisions about cookies.
1190  *
1191  * RETURNS
1192  * TRUE on success
1193  * FALSE on failure
1194  *
1195  */
1197 {
1198  FIXME("stub\n");
1199  return TRUE;
1200 }
1201 
1202 /***********************************************************************
1203  * InternetEnumPerSiteCookieDecisionA (WININET.@)
1204  *
1205  * See InternetEnumPerSiteCookieDecisionW.
1206  */
1208  ULONG *pdwDecision, ULONG dwIndex )
1209 {
1210  FIXME("(%s, %p, %p, 0x%08x) stub\n",
1211  debugstr_a(pszSiteName), pcSiteNameSize, pdwDecision, dwIndex);
1212  return FALSE;
1213 }
1214 
1215 /***********************************************************************
1216  * InternetEnumPerSiteCookieDecisionW (WININET.@)
1217  *
1218  * Enumerates all per-site decisions about cookies.
1219  *
1220  * RETURNS
1221  * TRUE on success
1222  * FALSE on failure
1223  *
1224  */
1226  ULONG *pdwDecision, ULONG dwIndex )
1227 {
1228  FIXME("(%s, %p, %p, 0x%08x) stub\n",
1229  debugstr_w(pszSiteName), pcSiteNameSize, pdwDecision, dwIndex);
1230  return FALSE;
1231 }
1232 
1233 /***********************************************************************
1234  * InternetGetPerSiteCookieDecisionA (WININET.@)
1235  */
1237 {
1238  FIXME("(%s, %p) stub\n", debugstr_a(pwchHostName), pResult);
1239  return FALSE;
1240 }
1241 
1242 /***********************************************************************
1243  * InternetGetPerSiteCookieDecisionW (WININET.@)
1244  */
1246 {
1247  FIXME("(%s, %p) stub\n", debugstr_w(pwchHostName), pResult);
1248  return FALSE;
1249 }
1250 
1251 /***********************************************************************
1252  * InternetSetPerSiteCookieDecisionA (WININET.@)
1253  */
1255 {
1256  FIXME("(%s, 0x%08x) stub\n", debugstr_a(pchHostName), dwDecision);
1257  return FALSE;
1258 }
1259 
1260 /***********************************************************************
1261  * InternetSetPerSiteCookieDecisionW (WININET.@)
1262  */
1264 {
1265  FIXME("(%s, 0x%08x) stub\n", debugstr_w(pchHostName), dwDecision);
1266  return FALSE;
1267 }
1268 
1269 void free_cookie(void)
1270 {
1272 
1274 
1276 }
BOOL WINAPI CreateUrlCacheEntryW(LPCWSTR lpszUrlName, DWORD dwExpectedFileSize, LPCWSTR lpszFileExtension, LPWSTR lpszFileName, DWORD dwReserved)
Definition: urlcache.c:2815
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
BOOL WINAPI InternetGetCookieW(const WCHAR *url, const WCHAR *name, WCHAR *data, DWORD *size)
Definition: cookie.c:792
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static cookie_container_t * get_cookie_container(substr_t domain, substr_t path, BOOL create)
Definition: cookie.c:192
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
struct _cookie_t cookie_t
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
Definition: pdh_main.c:93
#define CloseHandle
Definition: compat.h:598
BOOL WINAPI InternetGetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, LPWSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
Definition: cookie.c:729
static LPWSTR heap_strndupW(LPCWSTR str, unsigned len)
#define INTERNET_COOKIE_IS_SESSION
Definition: wininet.h:1819
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
struct list entry
Definition: metafile.c:154
BOOL WINAPI InternetGetCookieExA(LPCSTR lpszUrl, LPCSTR lpszCookieName, LPSTR lpCookieData, LPDWORD lpdwSize, DWORD flags, void *reserved)
Definition: cookie.c:809
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DWORD_PTR
Definition: treelist.c:76
#define WideCharToMultiByte
Definition: compat.h:111
static BOOL is_domain_legal_for_cookie(substr_t domain, substr_t full_domain)
Definition: cookie.c:869
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static void substr_skip(substr_t *str, size_t len)
Definition: cookie.c:905
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
static substr_t substrz(const WCHAR *str)
Definition: internet.h:209
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
BOOL WINAPI InternetClearAllPerSiteCookieDecisions(VOID)
Definition: cookie.c:1196
#define TRUE
Definition: types.h:120
GLsizei const GLchar ** path
Definition: glext.h:7234
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define CP_ACP
Definition: compat.h:109
#define WARN(fmt,...)
Definition: debug.h:112
static time_t create_time
Definition: mkdosfs.c:525
char * host
Definition: whois.c:55
static void free_cookie_domain_list(struct list *list)
Definition: cookie.c:689
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
WCHAR * name
Definition: cookie.c:36
struct _cookie_domain_t cookie_domain_t
__u16 time
Definition: mkdosfs.c:366
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
char * LPSTR
Definition: xmlstorage.h:182
#define lstrlenW
Definition: compat.h:609
LPWSTR lpszHostName
Definition: wininet.h:215
_CONST_RETURN wchar_t *__cdecl wmemchr(_In_reads_(_N) const wchar_t *_S, _In_ wchar_t _C, _In_ size_t _N)
Definition: wchar.h:2537
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
BOOL WINAPI IsDomainLegalCookieDomainW(const WCHAR *domain, const WCHAR *full_domain)
Definition: cookie.c:893
BOOL WINAPI InternetGetPerSiteCookieDecisionW(LPCWSTR pwchHostName, ULONG *pResult)
Definition: cookie.c:1245
__WINE_SERVER_LIST_INLINE struct list * list_head(const struct list *list)
Definition: list.h:131
DWORD WINAPI InternetSetCookieExW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, LPCWSTR lpCookieData, DWORD flags, DWORD_PTR reserved)
Definition: cookie.c:1077
Definition: cookie.c:41
WINE_DEFAULT_DEBUG_CHANNEL(winhttp)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static DWORD get_cookie(substr_t host, substr_t path, DWORD flags, cookie_set_t *res)
Definition: cookie.c:535
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
struct container container
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void cookie_set_to_string(const cookie_set_t *cookie_set, WCHAR *str)
Definition: cookie.c:619
DWORD dwHighDateTime
Definition: mapidefs.h:66
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
static BOOL cookie_match_path(cookie_container_t *container, substr_t path)
Definition: cookie.c:303
#define FALSE
Definition: types.h:117
static void replace_cookie(cookie_container_t *container, cookie_t *new_cookie)
Definition: cookie.c:292
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED _In_opt_ LPTRANSMIT_FILE_BUFFERS _In_ DWORD dwReserved
Definition: mswsock.h:90
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GENERIC_WRITE
Definition: nt_native.h:90
#define debugstr_w
Definition: kernel32.h:32
BOOL WINAPI ReadUrlCacheEntryStream(IN HANDLE hUrlCacheStream, IN DWORD dwLocation, IN OUT LPVOID lpBuffer, IN OUT LPDWORD lpdwLen, IN DWORD dwReserved)
Definition: urlcache.c:3133
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
r reserved
Definition: btrfs.c:2940
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
const WCHAR * str
static cookie_domain_t * get_cookie_domain(substr_t domain, BOOL create)
Definition: cookie.c:102
DWORD WINAPI InternetSetCookieExA(LPCSTR lpszURL, LPCSTR lpszCookieName, LPCSTR lpszCookieData, DWORD dwFlags, DWORD_PTR dwReserved)
Definition: cookie.c:1165
BOOL WINAPI InternetSetPerSiteCookieDecisionA(LPCSTR pchHostName, DWORD dwDecision)
Definition: cookie.c:1254
static BOOL save_persistent_cookie(cookie_container_t *container)
Definition: cookie.c:397
DWORD get_cookie_header(const WCHAR *host, const WCHAR *path, WCHAR **ret)
Definition: cookie.c:646
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
const char * LPCSTR
Definition: xmlstorage.h:183
static void delete_cookie(cookie_t *cookie)
Definition: cookie.c:236
static WCHAR * heap_strdupAtoW(const char *str)
Definition: appwiz.h:80
#define OPEN_EXISTING
Definition: compat.h:634
static CRITICAL_SECTION cookie_cs
Definition: cookie.c:92
static cookie_t * find_cookie(cookie_container_t *container, substr_t name)
Definition: cookie.c:271
static struct list domain_list
Definition: cookie.c:100
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
Definition: misc.c:291
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
BOOL WINAPI InternetEnumPerSiteCookieDecisionW(LPWSTR pszSiteName, ULONG *pcSiteNameSize, ULONG *pdwDecision, ULONG dwIndex)
Definition: cookie.c:1225
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
Definition: time.c:106
BOOL WINAPI UnlockUrlCacheEntryStream(IN HANDLE hUrlCacheStream, IN DWORD dwReserved)
Definition: urlcache.c:3265
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
BOOL WINAPI CommitUrlCacheEntryW(LPCWSTR lpszUrlName, LPCWSTR lpszLocalFileName, FILETIME ExpireTime, FILETIME LastModifiedTime, DWORD CacheEntryType, LPWSTR lpHeaderInfo, DWORD dwHeaderSize, LPCWSTR lpszFileExtension, LPCWSTR lpszOriginalUrl)
Definition: urlcache.c:3085
#define LIST_INIT(head)
Definition: queue.h:197
__wchar_t WCHAR
Definition: xmlstorage.h:180
HANDLE WINAPI RetrieveUrlCacheEntryStreamW(LPCWSTR lpszUrlName, LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo, LPDWORD lpdwCacheEntryInfoBufferSize, BOOL fRandomRead, DWORD dwReserved)
Definition: urlcache.c:3211
#define debugstr_a
Definition: kernel32.h:31
BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName, LPCSTR lpCookieData)
Definition: cookie.c:1139
static const WCHAR url[]
Definition: encode.c:1432
static char * heap_strdupWtoA(const WCHAR *str)
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
BOOL WINAPI InternetEnumPerSiteCookieDecisionA(LPSTR pszSiteName, ULONG *pcSiteNameSize, ULONG *pdwDecision, ULONG dwIndex)
Definition: cookie.c:1207
unsigned long DWORD
Definition: ntddk_ex.h:95
static WCHAR * create_cookie_url(substr_t domain, substr_t path, substr_t *ret_path)
Definition: cookie.c:152
#define SetLastError(x)
Definition: compat.h:611
BOOL WINAPI InternetGetCookieA(const char *url, const char *name, char *data, DWORD *size)
Definition: cookie.c:862
BOOL WINAPI InternetSetCookieW(const WCHAR *url, const WCHAR *name, const WCHAR *data)
Definition: cookie.c:1122
cookie_t ** cookies
Definition: cookie.c:528
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
static BOOL cookie_parse_url(const WCHAR *url, substr_t *host, substr_t *path)
Definition: cookie.c:508
DWORD dwHostNameLength
Definition: wininet.h:216
struct _test_info info[]
Definition: SetCursorPos.c:19
static LPCWSTR szVersion
Definition: asmcache.c:748
int ret
#define wcsnicmp
Definition: compat.h:14
const WCHAR * str
Definition: internet.h:199
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
LPWSTR lpszUrlPath
Definition: wininet.h:222
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
Definition: _list.h:228
GLsizei const GLfloat * value
Definition: glext.h:6069
Definition: time.h:76
DWORD set_cookie(substr_t domain, substr_t path, substr_t name, substr_t data, DWORD flags)
Definition: cookie.c:912
LIST_ENTRY ProcessLocksList
Definition: winbase.h:877
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define debugstr_wn
Definition: kernel32.h:33
static DWORD LPSTR PDWORD lpdwSize
Definition: process.c:72
void free_cookie(void)
Definition: cookie.c:1269
DWORD dwUrlPathLength
Definition: wininet.h:223
#define ERR(fmt,...)
Definition: debug.h:110
static void add_cookie(cookie_container_t *container, cookie_t *new_cookie)
Definition: cookie.c:283
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
struct _cookie_container_t cookie_container_t
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
const char cursor[]
Definition: icontest.c:13
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct list entry
Definition: cookie.c:43
LPCWSTR szPath
Definition: env.c:37
#define ARRAY_SIZE(a)
Definition: main.h:24
Definition: cookie.c:33
#define NULL
Definition: types.h:112
unsigned string_len
Definition: cookie.c:532
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:87
#define ERROR_INVALID_OPERATION
Definition: winerror.h:1261
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define CreateFileW
Definition: compat.h:600
static BOOL load_persistent_cookie(substr_t domain, substr_t path)
Definition: cookie.c:308
size_t len
Definition: internet.h:200
BOOL WINAPI InternetCrackUrlW(const WCHAR *lpszUrl, DWORD dwUrlLength, DWORD dwFlags, URL_COMPONENTSW *lpUC)
Definition: internet.c:1625
struct list entry
Definition: cookie.c:35
Definition: name.c:38
unsigned size
Definition: cookie.c:530
GLuint res
Definition: glext.h:9613
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
uint32_t * LPDWORD
Definition: typedefs.h:59
unsigned cnt
Definition: cookie.c:529
unsigned int ULONG
Definition: retypes.h:1
#define towlower(c)
Definition: wctype.h:97
#define ERROR_INVALID_NAME
Definition: compat.h:103
static CRITICAL_SECTION_DEBUG cookie_cs_debug
Definition: cookie.c:93
static substr_t substr(const WCHAR *str, size_t len)
Definition: internet.h:203
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define INTERNET_COOKIE_HTTPONLY
Definition: wininet.h:1828
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI InternetTimeToSystemTimeW(LPCWSTR string, SYSTEMTIME *time, DWORD reserved)
Definition: internet.c:3378
#define LIST_ENTRY(type)
Definition: queue.h:175
BOOL WINAPI InternetGetPerSiteCookieDecisionA(LPCSTR pwchHostName, ULONG *pResult)
Definition: cookie.c:1236
#define memset(x, y, z)
Definition: compat.h:39
static const struct access_res create[16]
Definition: package.c:7720
static cookie_t * alloc_cookie(substr_t name, substr_t data, FILETIME expiry, FILETIME create_time, DWORD flags)
Definition: cookie.c:245
struct CFHEADER header
Definition: fdi.c:101
DWORD dwLowDateTime
Definition: mapidefs.h:65
BOOL WINAPI InternetSetPerSiteCookieDecisionW(LPCWSTR pchHostName, DWORD dwDecision)
Definition: cookie.c:1263
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
BOOL WINAPI DeleteUrlCacheEntryW(LPCWSTR lpszUrlName)
Definition: urlcache.c:3344
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
GLuint const GLchar * name
Definition: glext.h:6031
Definition: wininet.h:2127