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